2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * As far as I am concerned, the code I have written for this software
6 * can be used freely for any purpose. Any derived versions of this
7 * software must be clearly marked as such, and if the derived work is
8 * incompatible with the protocol description in the RFC file, it must be
9 * called by a name other than "ssh" or "Secure Shell".
13 RCSID("$OpenBSD: servconf.c,v 1.97 2002/01/04 18:14:16 stevesk Exp $");
15 #if defined(KRB4) || defined(KRB5)
27 #include "pathnames.h"
28 #include "tildexpand.h"
34 static void add_listen_addr(ServerOptions *, char *, u_short);
35 static void add_one_listen_addr(ServerOptions *, char *, u_short);
37 /* AF_UNSPEC or AF_INET or AF_INET6 */
40 /* Initializes the server options to their default values. */
43 initialize_server_options(ServerOptions *options)
45 memset(options, 0, sizeof(*options));
47 /* Portable-specific options */
48 options->pam_authentication_via_kbd_int = -1;
50 /* Standard Options */
51 options->num_ports = 0;
52 options->ports_from_cmdline = 0;
53 options->listen_addrs = NULL;
54 options->num_host_key_files = 0;
55 options->pid_file = NULL;
56 options->server_key_bits = -1;
57 options->login_grace_time = -1;
58 options->key_regeneration_time = -1;
59 options->permit_root_login = PERMIT_NOT_SET;
60 options->ignore_rhosts = -1;
61 options->ignore_user_known_hosts = -1;
62 options->print_motd = -1;
63 options->print_lastlog = -1;
64 options->x11_forwarding = -1;
65 options->x11_display_offset = -1;
66 options->xauth_location = NULL;
67 options->strict_modes = -1;
68 options->keepalives = -1;
69 options->log_facility = (SyslogFacility) - 1;
70 options->log_level = (LogLevel) - 1;
71 options->rhosts_authentication = -1;
72 options->rhosts_rsa_authentication = -1;
73 options->hostbased_authentication = -1;
74 options->hostbased_uses_name_from_packet_only = -1;
75 options->rsa_authentication = -1;
76 options->pubkey_authentication = -1;
77 #if defined(KRB4) || defined(KRB5)
78 options->kerberos_authentication = -1;
79 options->kerberos_or_local_passwd = -1;
80 options->kerberos_ticket_cleanup = -1;
82 #if defined(AFS) || defined(KRB5)
83 options->kerberos_tgt_passing = -1;
86 options->afs_token_passing = -1;
88 options->password_authentication = -1;
89 options->kbd_interactive_authentication = -1;
90 options->challenge_response_authentication = -1;
91 options->permit_empty_passwd = -1;
92 options->use_login = -1;
93 options->allow_tcp_forwarding = -1;
94 options->num_allow_users = 0;
95 options->num_deny_users = 0;
96 options->num_allow_groups = 0;
97 options->num_deny_groups = 0;
98 options->ciphers = NULL;
100 options->protocol = SSH_PROTO_UNKNOWN;
101 options->gateway_ports = -1;
102 options->num_subsystems = 0;
103 options->max_startups_begin = -1;
104 options->max_startups_rate = -1;
105 options->max_startups = -1;
106 options->banner = NULL;
107 options->reverse_mapping_check = -1;
108 options->client_alive_interval = -1;
109 options->client_alive_count_max = -1;
110 options->authorized_keys_file = NULL;
111 options->authorized_keys_file2 = NULL;
115 fill_default_server_options(ServerOptions *options)
117 /* Portable-specific options */
118 if (options->pam_authentication_via_kbd_int == -1)
119 options->pam_authentication_via_kbd_int = 0;
121 /* Standard Options */
122 if (options->protocol == SSH_PROTO_UNKNOWN)
123 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
124 if (options->num_host_key_files == 0) {
125 /* fill default hostkeys for protocols */
126 if (options->protocol & SSH_PROTO_1)
127 options->host_key_files[options->num_host_key_files++] =
129 if (options->protocol & SSH_PROTO_2) {
130 options->host_key_files[options->num_host_key_files++] =
131 _PATH_HOST_RSA_KEY_FILE;
132 options->host_key_files[options->num_host_key_files++] =
133 _PATH_HOST_DSA_KEY_FILE;
136 if (options->num_ports == 0)
137 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
138 if (options->listen_addrs == NULL)
139 add_listen_addr(options, NULL, 0);
140 if (options->pid_file == NULL)
141 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
142 if (options->server_key_bits == -1)
143 options->server_key_bits = 768;
144 if (options->login_grace_time == -1)
145 options->login_grace_time = 600;
146 if (options->key_regeneration_time == -1)
147 options->key_regeneration_time = 3600;
148 if (options->permit_root_login == PERMIT_NOT_SET)
149 options->permit_root_login = PERMIT_YES;
150 if (options->ignore_rhosts == -1)
151 options->ignore_rhosts = 1;
152 if (options->ignore_user_known_hosts == -1)
153 options->ignore_user_known_hosts = 0;
154 if (options->print_motd == -1)
155 options->print_motd = 1;
156 if (options->print_lastlog == -1)
157 options->print_lastlog = 1;
158 if (options->x11_forwarding == -1)
159 options->x11_forwarding = 0;
160 if (options->x11_display_offset == -1)
161 options->x11_display_offset = 10;
162 if (options->xauth_location == NULL)
163 options->xauth_location = _PATH_XAUTH;
164 if (options->strict_modes == -1)
165 options->strict_modes = 1;
166 if (options->keepalives == -1)
167 options->keepalives = 1;
168 if (options->log_facility == (SyslogFacility) (-1))
169 options->log_facility = SYSLOG_FACILITY_AUTH;
170 if (options->log_level == (LogLevel) (-1))
171 options->log_level = SYSLOG_LEVEL_INFO;
172 if (options->rhosts_authentication == -1)
173 options->rhosts_authentication = 0;
174 if (options->rhosts_rsa_authentication == -1)
175 options->rhosts_rsa_authentication = 0;
176 if (options->hostbased_authentication == -1)
177 options->hostbased_authentication = 0;
178 if (options->hostbased_uses_name_from_packet_only == -1)
179 options->hostbased_uses_name_from_packet_only = 0;
180 if (options->rsa_authentication == -1)
181 options->rsa_authentication = 1;
182 if (options->pubkey_authentication == -1)
183 options->pubkey_authentication = 1;
184 #if defined(KRB4) || defined(KRB5)
185 if (options->kerberos_authentication == -1)
186 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
187 if (options->kerberos_or_local_passwd == -1)
188 options->kerberos_or_local_passwd = 1;
189 if (options->kerberos_ticket_cleanup == -1)
190 options->kerberos_ticket_cleanup = 1;
192 #if defined(AFS) || defined(KRB5)
193 if (options->kerberos_tgt_passing == -1)
194 options->kerberos_tgt_passing = 0;
197 if (options->afs_token_passing == -1)
198 options->afs_token_passing = k_hasafs();
200 if (options->password_authentication == -1)
201 options->password_authentication = 1;
202 if (options->kbd_interactive_authentication == -1)
203 options->kbd_interactive_authentication = 0;
204 if (options->challenge_response_authentication == -1)
205 options->challenge_response_authentication = 1;
206 if (options->permit_empty_passwd == -1)
207 options->permit_empty_passwd = 0;
208 if (options->use_login == -1)
209 options->use_login = 0;
210 if (options->allow_tcp_forwarding == -1)
211 options->allow_tcp_forwarding = 1;
212 if (options->gateway_ports == -1)
213 options->gateway_ports = 0;
214 if (options->max_startups == -1)
215 options->max_startups = 10;
216 if (options->max_startups_rate == -1)
217 options->max_startups_rate = 100; /* 100% */
218 if (options->max_startups_begin == -1)
219 options->max_startups_begin = options->max_startups;
220 if (options->reverse_mapping_check == -1)
221 options->reverse_mapping_check = 0;
222 if (options->client_alive_interval == -1)
223 options->client_alive_interval = 0;
224 if (options->client_alive_count_max == -1)
225 options->client_alive_count_max = 3;
226 if (options->authorized_keys_file2 == NULL) {
227 /* authorized_keys_file2 falls back to authorized_keys_file */
228 if (options->authorized_keys_file != NULL)
229 options->authorized_keys_file2 = options->authorized_keys_file;
231 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
233 if (options->authorized_keys_file == NULL)
234 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
237 /* Keyword tokens. */
239 sBadOption, /* == unknown option */
240 /* Portable-specific options */
241 sPAMAuthenticationViaKbdInt,
242 /* Standard Options */
243 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
244 sPermitRootLogin, sLogFacility, sLogLevel,
245 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
246 #if defined(KRB4) || defined(KRB5)
247 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
249 #if defined(AFS) || defined(KRB5)
255 sChallengeResponseAuthentication,
256 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
257 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
258 sX11Forwarding, sX11DisplayOffset,
259 sStrictModes, sEmptyPasswd, sKeepAlives,
260 sUseLogin, sAllowTcpForwarding,
261 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
262 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
263 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
264 sBanner, sReverseMappingCheck, sHostbasedAuthentication,
265 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
266 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
270 /* Textual representation of the tokens. */
273 ServerOpCodes opcode;
275 /* Portable-specific options */
276 { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt },
277 /* Standard Options */
279 { "hostkey", sHostKeyFile },
280 { "hostdsakey", sHostKeyFile }, /* alias */
281 { "pidfile", sPidFile },
282 { "serverkeybits", sServerKeyBits },
283 { "logingracetime", sLoginGraceTime },
284 { "keyregenerationinterval", sKeyRegenerationTime },
285 { "permitrootlogin", sPermitRootLogin },
286 { "syslogfacility", sLogFacility },
287 { "loglevel", sLogLevel },
288 { "rhostsauthentication", sRhostsAuthentication },
289 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
290 { "hostbasedauthentication", sHostbasedAuthentication },
291 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
292 { "rsaauthentication", sRSAAuthentication },
293 { "pubkeyauthentication", sPubkeyAuthentication },
294 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
295 #if defined(KRB4) || defined(KRB5)
296 { "kerberosauthentication", sKerberosAuthentication },
297 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
298 { "kerberosticketcleanup", sKerberosTicketCleanup },
300 #if defined(AFS) || defined(KRB5)
301 { "kerberostgtpassing", sKerberosTgtPassing },
304 { "afstokenpassing", sAFSTokenPassing },
306 { "passwordauthentication", sPasswordAuthentication },
307 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
308 { "challengeresponseauthentication", sChallengeResponseAuthentication },
309 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
310 { "checkmail", sDeprecated },
311 { "listenaddress", sListenAddress },
312 { "printmotd", sPrintMotd },
313 { "printlastlog", sPrintLastLog },
314 { "ignorerhosts", sIgnoreRhosts },
315 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
316 { "x11forwarding", sX11Forwarding },
317 { "x11displayoffset", sX11DisplayOffset },
318 { "xauthlocation", sXAuthLocation },
319 { "strictmodes", sStrictModes },
320 { "permitemptypasswords", sEmptyPasswd },
321 { "uselogin", sUseLogin },
322 { "keepalive", sKeepAlives },
323 { "allowtcpforwarding", sAllowTcpForwarding },
324 { "allowusers", sAllowUsers },
325 { "denyusers", sDenyUsers },
326 { "allowgroups", sAllowGroups },
327 { "denygroups", sDenyGroups },
328 { "ciphers", sCiphers },
330 { "protocol", sProtocol },
331 { "gatewayports", sGatewayPorts },
332 { "subsystem", sSubsystem },
333 { "maxstartups", sMaxStartups },
334 { "banner", sBanner },
335 { "reversemappingcheck", sReverseMappingCheck },
336 { "clientaliveinterval", sClientAliveInterval },
337 { "clientalivecountmax", sClientAliveCountMax },
338 { "authorizedkeysfile", sAuthorizedKeysFile },
339 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
344 * Returns the number of the token pointed to by cp or sBadOption.
348 parse_token(const char *cp, const char *filename,
353 for (i = 0; keywords[i].name; i++)
354 if (strcasecmp(cp, keywords[i].name) == 0)
355 return keywords[i].opcode;
357 error("%s: line %d: Bad configuration option: %s",
358 filename, linenum, cp);
363 add_listen_addr(ServerOptions *options, char *addr, u_short port)
367 if (options->num_ports == 0)
368 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
370 for (i = 0; i < options->num_ports; i++)
371 add_one_listen_addr(options, addr, options->ports[i]);
373 add_one_listen_addr(options, addr, port);
377 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
379 struct addrinfo hints, *ai, *aitop;
380 char strport[NI_MAXSERV];
383 memset(&hints, 0, sizeof(hints));
384 hints.ai_family = IPv4or6;
385 hints.ai_socktype = SOCK_STREAM;
386 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
387 snprintf(strport, sizeof strport, "%d", port);
388 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
389 fatal("bad addr or host: %s (%s)",
390 addr ? addr : "<NULL>",
391 gai_strerror(gaierr));
392 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
394 ai->ai_next = options->listen_addrs;
395 options->listen_addrs = aitop;
399 process_server_config_line(ServerOptions *options, char *line,
400 const char *filename, int linenum)
402 char *cp, **charptr, *arg, *p;
404 ServerOpCodes opcode;
409 /* Ignore leading whitespace */
412 if (!arg || !*arg || *arg == '#')
416 opcode = parse_token(arg, filename, linenum);
418 /* Portable-specific options */
419 case sPAMAuthenticationViaKbdInt:
420 intptr = &options->pam_authentication_via_kbd_int;
423 /* Standard Options */
427 /* ignore ports from configfile if cmdline specifies ports */
428 if (options->ports_from_cmdline)
430 if (options->listen_addrs != NULL)
431 fatal("%s line %d: ports must be specified before "
432 "ListenAdress.", filename, linenum);
433 if (options->num_ports >= MAX_PORTS)
434 fatal("%s line %d: too many ports.",
437 if (!arg || *arg == '\0')
438 fatal("%s line %d: missing port number.",
440 options->ports[options->num_ports++] = a2port(arg);
441 if (options->ports[options->num_ports-1] == 0)
442 fatal("%s line %d: Badly formatted port number.",
447 intptr = &options->server_key_bits;
450 if (!arg || *arg == '\0')
451 fatal("%s line %d: missing integer value.",
458 case sLoginGraceTime:
459 intptr = &options->login_grace_time;
462 if (!arg || *arg == '\0')
463 fatal("%s line %d: missing time value.",
465 if ((value = convtime(arg)) == -1)
466 fatal("%s line %d: invalid time value.",
472 case sKeyRegenerationTime:
473 intptr = &options->key_regeneration_time;
478 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
479 fatal("%s line %d: missing inet addr.",
482 if ((p = strchr(arg, ']')) == NULL)
483 fatal("%s line %d: bad ipv6 inet addr usage.",
486 memmove(p, p+1, strlen(p+1)+1);
487 } else if (((p = strchr(arg, ':')) == NULL) ||
488 (strchr(p+1, ':') != NULL)) {
489 add_listen_addr(options, arg, 0);
497 fatal("%s line %d: bad inet addr:port usage.",
501 if ((port = a2port(p)) == 0)
502 fatal("%s line %d: bad port number.",
504 add_listen_addr(options, arg, port);
506 } else if (*p == '\0')
507 add_listen_addr(options, arg, 0);
509 fatal("%s line %d: bad inet addr usage.",
514 intptr = &options->num_host_key_files;
515 if (*intptr >= MAX_HOSTKEYS)
516 fatal("%s line %d: too many host keys specified (max %d).",
517 filename, linenum, MAX_HOSTKEYS);
518 charptr = &options->host_key_files[*intptr];
521 if (!arg || *arg == '\0')
522 fatal("%s line %d: missing file name.",
524 if (*charptr == NULL) {
525 *charptr = tilde_expand_filename(arg, getuid());
526 /* increase optional counter */
528 *intptr = *intptr + 1;
533 charptr = &options->pid_file;
536 case sPermitRootLogin:
537 intptr = &options->permit_root_login;
539 if (!arg || *arg == '\0')
540 fatal("%s line %d: missing yes/"
541 "without-password/forced-commands-only/no "
542 "argument.", filename, linenum);
543 value = 0; /* silence compiler */
544 if (strcmp(arg, "without-password") == 0)
545 value = PERMIT_NO_PASSWD;
546 else if (strcmp(arg, "forced-commands-only") == 0)
547 value = PERMIT_FORCED_ONLY;
548 else if (strcmp(arg, "yes") == 0)
550 else if (strcmp(arg, "no") == 0)
553 fatal("%s line %d: Bad yes/"
554 "without-password/forced-commands-only/no "
555 "argument: %s", filename, linenum, arg);
561 intptr = &options->ignore_rhosts;
564 if (!arg || *arg == '\0')
565 fatal("%s line %d: missing yes/no argument.",
567 value = 0; /* silence compiler */
568 if (strcmp(arg, "yes") == 0)
570 else if (strcmp(arg, "no") == 0)
573 fatal("%s line %d: Bad yes/no argument: %s",
574 filename, linenum, arg);
579 case sIgnoreUserKnownHosts:
580 intptr = &options->ignore_user_known_hosts;
583 case sRhostsAuthentication:
584 intptr = &options->rhosts_authentication;
587 case sRhostsRSAAuthentication:
588 intptr = &options->rhosts_rsa_authentication;
591 case sHostbasedAuthentication:
592 intptr = &options->hostbased_authentication;
595 case sHostbasedUsesNameFromPacketOnly:
596 intptr = &options->hostbased_uses_name_from_packet_only;
599 case sRSAAuthentication:
600 intptr = &options->rsa_authentication;
603 case sPubkeyAuthentication:
604 intptr = &options->pubkey_authentication;
606 #if defined(KRB4) || defined(KRB5)
607 case sKerberosAuthentication:
608 intptr = &options->kerberos_authentication;
611 case sKerberosOrLocalPasswd:
612 intptr = &options->kerberos_or_local_passwd;
615 case sKerberosTicketCleanup:
616 intptr = &options->kerberos_ticket_cleanup;
619 #if defined(AFS) || defined(KRB5)
620 case sKerberosTgtPassing:
621 intptr = &options->kerberos_tgt_passing;
625 case sAFSTokenPassing:
626 intptr = &options->afs_token_passing;
630 case sPasswordAuthentication:
631 intptr = &options->password_authentication;
634 case sKbdInteractiveAuthentication:
635 intptr = &options->kbd_interactive_authentication;
638 case sChallengeResponseAuthentication:
639 intptr = &options->challenge_response_authentication;
643 intptr = &options->print_motd;
647 intptr = &options->print_lastlog;
651 intptr = &options->x11_forwarding;
654 case sX11DisplayOffset:
655 intptr = &options->x11_display_offset;
659 charptr = &options->xauth_location;
663 intptr = &options->strict_modes;
667 intptr = &options->keepalives;
671 intptr = &options->permit_empty_passwd;
675 intptr = &options->use_login;
679 intptr = &options->gateway_ports;
682 case sReverseMappingCheck:
683 intptr = &options->reverse_mapping_check;
687 intptr = (int *) &options->log_facility;
689 value = log_facility_number(arg);
690 if (value == (SyslogFacility) - 1)
691 fatal("%.200s line %d: unsupported log facility '%s'",
692 filename, linenum, arg ? arg : "<NONE>");
694 *intptr = (SyslogFacility) value;
698 intptr = (int *) &options->log_level;
700 value = log_level_number(arg);
701 if (value == (LogLevel) - 1)
702 fatal("%.200s line %d: unsupported log level '%s'",
703 filename, linenum, arg ? arg : "<NONE>");
705 *intptr = (LogLevel) value;
708 case sAllowTcpForwarding:
709 intptr = &options->allow_tcp_forwarding;
713 while ((arg = strdelim(&cp)) && *arg != '\0') {
714 if (options->num_allow_users >= MAX_ALLOW_USERS)
715 fatal("%s line %d: too many allow users.",
717 options->allow_users[options->num_allow_users++] = xstrdup(arg);
722 while ((arg = strdelim(&cp)) && *arg != '\0') {
723 if (options->num_deny_users >= MAX_DENY_USERS)
724 fatal( "%s line %d: too many deny users.",
726 options->deny_users[options->num_deny_users++] = xstrdup(arg);
731 while ((arg = strdelim(&cp)) && *arg != '\0') {
732 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
733 fatal("%s line %d: too many allow groups.",
735 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
740 while ((arg = strdelim(&cp)) && *arg != '\0') {
741 if (options->num_deny_groups >= MAX_DENY_GROUPS)
742 fatal("%s line %d: too many deny groups.",
744 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
750 if (!arg || *arg == '\0')
751 fatal("%s line %d: Missing argument.", filename, linenum);
752 if (!ciphers_valid(arg))
753 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
754 filename, linenum, arg ? arg : "<NONE>");
755 if (options->ciphers == NULL)
756 options->ciphers = xstrdup(arg);
761 if (!arg || *arg == '\0')
762 fatal("%s line %d: Missing argument.", filename, linenum);
764 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
765 filename, linenum, arg ? arg : "<NONE>");
766 if (options->macs == NULL)
767 options->macs = xstrdup(arg);
771 intptr = &options->protocol;
773 if (!arg || *arg == '\0')
774 fatal("%s line %d: Missing argument.", filename, linenum);
775 value = proto_spec(arg);
776 if (value == SSH_PROTO_UNKNOWN)
777 fatal("%s line %d: Bad protocol spec '%s'.",
778 filename, linenum, arg ? arg : "<NONE>");
779 if (*intptr == SSH_PROTO_UNKNOWN)
784 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
785 fatal("%s line %d: too many subsystems defined.",
789 if (!arg || *arg == '\0')
790 fatal("%s line %d: Missing subsystem name.",
792 for (i = 0; i < options->num_subsystems; i++)
793 if (strcmp(arg, options->subsystem_name[i]) == 0)
794 fatal("%s line %d: Subsystem '%s' already defined.",
795 filename, linenum, arg);
796 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
798 if (!arg || *arg == '\0')
799 fatal("%s line %d: Missing subsystem command.",
801 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
802 options->num_subsystems++;
807 if (!arg || *arg == '\0')
808 fatal("%s line %d: Missing MaxStartups spec.",
810 if ((n = sscanf(arg, "%d:%d:%d",
811 &options->max_startups_begin,
812 &options->max_startups_rate,
813 &options->max_startups)) == 3) {
814 if (options->max_startups_begin >
815 options->max_startups ||
816 options->max_startups_rate > 100 ||
817 options->max_startups_rate < 1)
818 fatal("%s line %d: Illegal MaxStartups spec.",
821 fatal("%s line %d: Illegal MaxStartups spec.",
824 options->max_startups = options->max_startups_begin;
828 charptr = &options->banner;
831 * These options can contain %X options expanded at
832 * connect time, so that you can specify paths like:
834 * AuthorizedKeysFile /etc/ssh_keys/%u
836 case sAuthorizedKeysFile:
837 case sAuthorizedKeysFile2:
838 charptr = (opcode == sAuthorizedKeysFile ) ?
839 &options->authorized_keys_file :
840 &options->authorized_keys_file2;
843 case sClientAliveInterval:
844 intptr = &options->client_alive_interval;
847 case sClientAliveCountMax:
848 intptr = &options->client_alive_count_max;
852 log("%s line %d: Deprecated option %s",
853 filename, linenum, arg);
859 fatal("%s line %d: Missing handler for opcode %s (%d)",
860 filename, linenum, arg, opcode);
862 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
863 fatal("%s line %d: garbage at end of line; \"%.200s\".",
864 filename, linenum, arg);
868 /* Reads the server configuration file. */
871 read_server_config(ServerOptions *options, const char *filename)
878 f = fopen(filename, "r");
884 while (fgets(line, sizeof(line), f)) {
885 /* Update line number counter. */
887 if (process_server_config_line(options, line, filename, linenum) != 0)
892 fatal("%s: terminating, %d bad configuration options",
893 filename, bad_options);