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.101 2002/02/04 12:15:25 markus 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->x11_use_localhost = -1;
67 options->xauth_location = NULL;
68 options->strict_modes = -1;
69 options->keepalives = -1;
70 options->log_facility = SYSLOG_FACILITY_NOT_SET;
71 options->log_level = SYSLOG_LEVEL_NOT_SET;
72 options->rhosts_authentication = -1;
73 options->rhosts_rsa_authentication = -1;
74 options->hostbased_authentication = -1;
75 options->hostbased_uses_name_from_packet_only = -1;
76 options->rsa_authentication = -1;
77 options->pubkey_authentication = -1;
78 #if defined(KRB4) || defined(KRB5)
79 options->kerberos_authentication = -1;
80 options->kerberos_or_local_passwd = -1;
81 options->kerberos_ticket_cleanup = -1;
83 #if defined(AFS) || defined(KRB5)
84 options->kerberos_tgt_passing = -1;
87 options->afs_token_passing = -1;
89 options->password_authentication = -1;
90 options->kbd_interactive_authentication = -1;
91 options->challenge_response_authentication = -1;
92 options->permit_empty_passwd = -1;
93 options->use_login = -1;
94 options->allow_tcp_forwarding = -1;
95 options->num_allow_users = 0;
96 options->num_deny_users = 0;
97 options->num_allow_groups = 0;
98 options->num_deny_groups = 0;
99 options->ciphers = NULL;
100 options->macs = NULL;
101 options->protocol = SSH_PROTO_UNKNOWN;
102 options->gateway_ports = -1;
103 options->num_subsystems = 0;
104 options->max_startups_begin = -1;
105 options->max_startups_rate = -1;
106 options->max_startups = -1;
107 options->banner = NULL;
108 options->verify_reverse_mapping = -1;
109 options->client_alive_interval = -1;
110 options->client_alive_count_max = -1;
111 options->authorized_keys_file = NULL;
112 options->authorized_keys_file2 = NULL;
116 fill_default_server_options(ServerOptions *options)
118 /* Portable-specific options */
119 if (options->pam_authentication_via_kbd_int == -1)
120 options->pam_authentication_via_kbd_int = 0;
122 /* Standard Options */
123 if (options->protocol == SSH_PROTO_UNKNOWN)
124 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
125 if (options->num_host_key_files == 0) {
126 /* fill default hostkeys for protocols */
127 if (options->protocol & SSH_PROTO_1)
128 options->host_key_files[options->num_host_key_files++] =
130 if (options->protocol & SSH_PROTO_2) {
131 options->host_key_files[options->num_host_key_files++] =
132 _PATH_HOST_RSA_KEY_FILE;
133 options->host_key_files[options->num_host_key_files++] =
134 _PATH_HOST_DSA_KEY_FILE;
137 if (options->num_ports == 0)
138 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
139 if (options->listen_addrs == NULL)
140 add_listen_addr(options, NULL, 0);
141 if (options->pid_file == NULL)
142 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
143 if (options->server_key_bits == -1)
144 options->server_key_bits = 768;
145 if (options->login_grace_time == -1)
146 options->login_grace_time = 600;
147 if (options->key_regeneration_time == -1)
148 options->key_regeneration_time = 3600;
149 if (options->permit_root_login == PERMIT_NOT_SET)
150 options->permit_root_login = PERMIT_YES;
151 if (options->ignore_rhosts == -1)
152 options->ignore_rhosts = 1;
153 if (options->ignore_user_known_hosts == -1)
154 options->ignore_user_known_hosts = 0;
155 if (options->print_motd == -1)
156 options->print_motd = 1;
157 if (options->print_lastlog == -1)
158 options->print_lastlog = 1;
159 if (options->x11_forwarding == -1)
160 options->x11_forwarding = 0;
161 if (options->x11_display_offset == -1)
162 options->x11_display_offset = 10;
163 if (options->x11_use_localhost == -1)
164 options->x11_use_localhost = 1;
165 if (options->xauth_location == NULL)
166 options->xauth_location = _PATH_XAUTH;
167 if (options->strict_modes == -1)
168 options->strict_modes = 1;
169 if (options->keepalives == -1)
170 options->keepalives = 1;
171 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
172 options->log_facility = SYSLOG_FACILITY_AUTH;
173 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
174 options->log_level = SYSLOG_LEVEL_INFO;
175 if (options->rhosts_authentication == -1)
176 options->rhosts_authentication = 0;
177 if (options->rhosts_rsa_authentication == -1)
178 options->rhosts_rsa_authentication = 0;
179 if (options->hostbased_authentication == -1)
180 options->hostbased_authentication = 0;
181 if (options->hostbased_uses_name_from_packet_only == -1)
182 options->hostbased_uses_name_from_packet_only = 0;
183 if (options->rsa_authentication == -1)
184 options->rsa_authentication = 1;
185 if (options->pubkey_authentication == -1)
186 options->pubkey_authentication = 1;
187 #if defined(KRB4) || defined(KRB5)
188 if (options->kerberos_authentication == -1)
189 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
190 if (options->kerberos_or_local_passwd == -1)
191 options->kerberos_or_local_passwd = 1;
192 if (options->kerberos_ticket_cleanup == -1)
193 options->kerberos_ticket_cleanup = 1;
195 #if defined(AFS) || defined(KRB5)
196 if (options->kerberos_tgt_passing == -1)
197 options->kerberos_tgt_passing = 0;
200 if (options->afs_token_passing == -1)
201 options->afs_token_passing = k_hasafs();
203 if (options->password_authentication == -1)
204 options->password_authentication = 1;
205 if (options->kbd_interactive_authentication == -1)
206 options->kbd_interactive_authentication = 0;
207 if (options->challenge_response_authentication == -1)
208 options->challenge_response_authentication = 1;
209 if (options->permit_empty_passwd == -1)
210 options->permit_empty_passwd = 0;
211 if (options->use_login == -1)
212 options->use_login = 0;
213 if (options->allow_tcp_forwarding == -1)
214 options->allow_tcp_forwarding = 1;
215 if (options->gateway_ports == -1)
216 options->gateway_ports = 0;
217 if (options->max_startups == -1)
218 options->max_startups = 10;
219 if (options->max_startups_rate == -1)
220 options->max_startups_rate = 100; /* 100% */
221 if (options->max_startups_begin == -1)
222 options->max_startups_begin = options->max_startups;
223 if (options->verify_reverse_mapping == -1)
224 options->verify_reverse_mapping = 0;
225 if (options->client_alive_interval == -1)
226 options->client_alive_interval = 0;
227 if (options->client_alive_count_max == -1)
228 options->client_alive_count_max = 3;
229 if (options->authorized_keys_file2 == NULL) {
230 /* authorized_keys_file2 falls back to authorized_keys_file */
231 if (options->authorized_keys_file != NULL)
232 options->authorized_keys_file2 = options->authorized_keys_file;
234 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
236 if (options->authorized_keys_file == NULL)
237 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
240 /* Keyword tokens. */
242 sBadOption, /* == unknown option */
243 /* Portable-specific options */
244 sPAMAuthenticationViaKbdInt,
245 /* Standard Options */
246 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
247 sPermitRootLogin, sLogFacility, sLogLevel,
248 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
249 #if defined(KRB4) || defined(KRB5)
250 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
252 #if defined(AFS) || defined(KRB5)
258 sChallengeResponseAuthentication,
259 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
260 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
261 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
262 sStrictModes, sEmptyPasswd, sKeepAlives,
263 sUseLogin, sAllowTcpForwarding,
264 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
265 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
266 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
267 sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
268 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
269 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
273 /* Textual representation of the tokens. */
276 ServerOpCodes opcode;
278 /* Portable-specific options */
279 { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt },
280 /* Standard Options */
282 { "hostkey", sHostKeyFile },
283 { "hostdsakey", sHostKeyFile }, /* alias */
284 { "pidfile", sPidFile },
285 { "serverkeybits", sServerKeyBits },
286 { "logingracetime", sLoginGraceTime },
287 { "keyregenerationinterval", sKeyRegenerationTime },
288 { "permitrootlogin", sPermitRootLogin },
289 { "syslogfacility", sLogFacility },
290 { "loglevel", sLogLevel },
291 { "rhostsauthentication", sRhostsAuthentication },
292 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
293 { "hostbasedauthentication", sHostbasedAuthentication },
294 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
295 { "rsaauthentication", sRSAAuthentication },
296 { "pubkeyauthentication", sPubkeyAuthentication },
297 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
298 #if defined(KRB4) || defined(KRB5)
299 { "kerberosauthentication", sKerberosAuthentication },
300 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
301 { "kerberosticketcleanup", sKerberosTicketCleanup },
303 #if defined(AFS) || defined(KRB5)
304 { "kerberostgtpassing", sKerberosTgtPassing },
307 { "afstokenpassing", sAFSTokenPassing },
309 { "passwordauthentication", sPasswordAuthentication },
310 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
311 { "challengeresponseauthentication", sChallengeResponseAuthentication },
312 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
313 { "checkmail", sDeprecated },
314 { "listenaddress", sListenAddress },
315 { "printmotd", sPrintMotd },
316 { "printlastlog", sPrintLastLog },
317 { "ignorerhosts", sIgnoreRhosts },
318 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
319 { "x11forwarding", sX11Forwarding },
320 { "x11displayoffset", sX11DisplayOffset },
321 { "x11uselocalhost", sX11UseLocalhost },
322 { "xauthlocation", sXAuthLocation },
323 { "strictmodes", sStrictModes },
324 { "permitemptypasswords", sEmptyPasswd },
325 { "uselogin", sUseLogin },
326 { "keepalive", sKeepAlives },
327 { "allowtcpforwarding", sAllowTcpForwarding },
328 { "allowusers", sAllowUsers },
329 { "denyusers", sDenyUsers },
330 { "allowgroups", sAllowGroups },
331 { "denygroups", sDenyGroups },
332 { "ciphers", sCiphers },
334 { "protocol", sProtocol },
335 { "gatewayports", sGatewayPorts },
336 { "subsystem", sSubsystem },
337 { "maxstartups", sMaxStartups },
338 { "banner", sBanner },
339 { "verifyreversemapping", sVerifyReverseMapping },
340 { "reversemappingcheck", sVerifyReverseMapping },
341 { "clientaliveinterval", sClientAliveInterval },
342 { "clientalivecountmax", sClientAliveCountMax },
343 { "authorizedkeysfile", sAuthorizedKeysFile },
344 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
349 * Returns the number of the token pointed to by cp or sBadOption.
353 parse_token(const char *cp, const char *filename,
358 for (i = 0; keywords[i].name; i++)
359 if (strcasecmp(cp, keywords[i].name) == 0)
360 return keywords[i].opcode;
362 error("%s: line %d: Bad configuration option: %s",
363 filename, linenum, cp);
368 add_listen_addr(ServerOptions *options, char *addr, u_short port)
372 if (options->num_ports == 0)
373 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
375 for (i = 0; i < options->num_ports; i++)
376 add_one_listen_addr(options, addr, options->ports[i]);
378 add_one_listen_addr(options, addr, port);
382 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
384 struct addrinfo hints, *ai, *aitop;
385 char strport[NI_MAXSERV];
388 memset(&hints, 0, sizeof(hints));
389 hints.ai_family = IPv4or6;
390 hints.ai_socktype = SOCK_STREAM;
391 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
392 snprintf(strport, sizeof strport, "%d", port);
393 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
394 fatal("bad addr or host: %s (%s)",
395 addr ? addr : "<NULL>",
396 gai_strerror(gaierr));
397 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
399 ai->ai_next = options->listen_addrs;
400 options->listen_addrs = aitop;
404 process_server_config_line(ServerOptions *options, char *line,
405 const char *filename, int linenum)
407 char *cp, **charptr, *arg, *p;
409 ServerOpCodes opcode;
414 /* Ignore leading whitespace */
417 if (!arg || !*arg || *arg == '#')
421 opcode = parse_token(arg, filename, linenum);
423 /* Portable-specific options */
424 case sPAMAuthenticationViaKbdInt:
425 intptr = &options->pam_authentication_via_kbd_int;
428 /* Standard Options */
432 /* ignore ports from configfile if cmdline specifies ports */
433 if (options->ports_from_cmdline)
435 if (options->listen_addrs != NULL)
436 fatal("%s line %d: ports must be specified before "
437 "ListenAddress.", filename, linenum);
438 if (options->num_ports >= MAX_PORTS)
439 fatal("%s line %d: too many ports.",
442 if (!arg || *arg == '\0')
443 fatal("%s line %d: missing port number.",
445 options->ports[options->num_ports++] = a2port(arg);
446 if (options->ports[options->num_ports-1] == 0)
447 fatal("%s line %d: Badly formatted port number.",
452 intptr = &options->server_key_bits;
455 if (!arg || *arg == '\0')
456 fatal("%s line %d: missing integer value.",
463 case sLoginGraceTime:
464 intptr = &options->login_grace_time;
467 if (!arg || *arg == '\0')
468 fatal("%s line %d: missing time value.",
470 if ((value = convtime(arg)) == -1)
471 fatal("%s line %d: invalid time value.",
477 case sKeyRegenerationTime:
478 intptr = &options->key_regeneration_time;
483 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
484 fatal("%s line %d: missing inet addr.",
487 if ((p = strchr(arg, ']')) == NULL)
488 fatal("%s line %d: bad ipv6 inet addr usage.",
491 memmove(p, p+1, strlen(p+1)+1);
492 } else if (((p = strchr(arg, ':')) == NULL) ||
493 (strchr(p+1, ':') != NULL)) {
494 add_listen_addr(options, arg, 0);
502 fatal("%s line %d: bad inet addr:port usage.",
506 if ((port = a2port(p)) == 0)
507 fatal("%s line %d: bad port number.",
509 add_listen_addr(options, arg, port);
511 } else if (*p == '\0')
512 add_listen_addr(options, arg, 0);
514 fatal("%s line %d: bad inet addr usage.",
519 intptr = &options->num_host_key_files;
520 if (*intptr >= MAX_HOSTKEYS)
521 fatal("%s line %d: too many host keys specified (max %d).",
522 filename, linenum, MAX_HOSTKEYS);
523 charptr = &options->host_key_files[*intptr];
526 if (!arg || *arg == '\0')
527 fatal("%s line %d: missing file name.",
529 if (*charptr == NULL) {
530 *charptr = tilde_expand_filename(arg, getuid());
531 /* increase optional counter */
533 *intptr = *intptr + 1;
538 charptr = &options->pid_file;
541 case sPermitRootLogin:
542 intptr = &options->permit_root_login;
544 if (!arg || *arg == '\0')
545 fatal("%s line %d: missing yes/"
546 "without-password/forced-commands-only/no "
547 "argument.", filename, linenum);
548 value = 0; /* silence compiler */
549 if (strcmp(arg, "without-password") == 0)
550 value = PERMIT_NO_PASSWD;
551 else if (strcmp(arg, "forced-commands-only") == 0)
552 value = PERMIT_FORCED_ONLY;
553 else if (strcmp(arg, "yes") == 0)
555 else if (strcmp(arg, "no") == 0)
558 fatal("%s line %d: Bad yes/"
559 "without-password/forced-commands-only/no "
560 "argument: %s", filename, linenum, arg);
566 intptr = &options->ignore_rhosts;
569 if (!arg || *arg == '\0')
570 fatal("%s line %d: missing yes/no argument.",
572 value = 0; /* silence compiler */
573 if (strcmp(arg, "yes") == 0)
575 else if (strcmp(arg, "no") == 0)
578 fatal("%s line %d: Bad yes/no argument: %s",
579 filename, linenum, arg);
584 case sIgnoreUserKnownHosts:
585 intptr = &options->ignore_user_known_hosts;
588 case sRhostsAuthentication:
589 intptr = &options->rhosts_authentication;
592 case sRhostsRSAAuthentication:
593 intptr = &options->rhosts_rsa_authentication;
596 case sHostbasedAuthentication:
597 intptr = &options->hostbased_authentication;
600 case sHostbasedUsesNameFromPacketOnly:
601 intptr = &options->hostbased_uses_name_from_packet_only;
604 case sRSAAuthentication:
605 intptr = &options->rsa_authentication;
608 case sPubkeyAuthentication:
609 intptr = &options->pubkey_authentication;
611 #if defined(KRB4) || defined(KRB5)
612 case sKerberosAuthentication:
613 intptr = &options->kerberos_authentication;
616 case sKerberosOrLocalPasswd:
617 intptr = &options->kerberos_or_local_passwd;
620 case sKerberosTicketCleanup:
621 intptr = &options->kerberos_ticket_cleanup;
624 #if defined(AFS) || defined(KRB5)
625 case sKerberosTgtPassing:
626 intptr = &options->kerberos_tgt_passing;
630 case sAFSTokenPassing:
631 intptr = &options->afs_token_passing;
635 case sPasswordAuthentication:
636 intptr = &options->password_authentication;
639 case sKbdInteractiveAuthentication:
640 intptr = &options->kbd_interactive_authentication;
643 case sChallengeResponseAuthentication:
644 intptr = &options->challenge_response_authentication;
648 intptr = &options->print_motd;
652 intptr = &options->print_lastlog;
656 intptr = &options->x11_forwarding;
659 case sX11DisplayOffset:
660 intptr = &options->x11_display_offset;
663 case sX11UseLocalhost:
664 intptr = &options->x11_use_localhost;
668 charptr = &options->xauth_location;
672 intptr = &options->strict_modes;
676 intptr = &options->keepalives;
680 intptr = &options->permit_empty_passwd;
684 intptr = &options->use_login;
688 intptr = &options->gateway_ports;
691 case sVerifyReverseMapping:
692 intptr = &options->verify_reverse_mapping;
696 intptr = (int *) &options->log_facility;
698 value = log_facility_number(arg);
699 if (value == SYSLOG_FACILITY_NOT_SET)
700 fatal("%.200s line %d: unsupported log facility '%s'",
701 filename, linenum, arg ? arg : "<NONE>");
703 *intptr = (SyslogFacility) value;
707 intptr = (int *) &options->log_level;
709 value = log_level_number(arg);
710 if (value == SYSLOG_LEVEL_NOT_SET)
711 fatal("%.200s line %d: unsupported log level '%s'",
712 filename, linenum, arg ? arg : "<NONE>");
714 *intptr = (LogLevel) value;
717 case sAllowTcpForwarding:
718 intptr = &options->allow_tcp_forwarding;
722 while ((arg = strdelim(&cp)) && *arg != '\0') {
723 if (options->num_allow_users >= MAX_ALLOW_USERS)
724 fatal("%s line %d: too many allow users.",
726 options->allow_users[options->num_allow_users++] = xstrdup(arg);
731 while ((arg = strdelim(&cp)) && *arg != '\0') {
732 if (options->num_deny_users >= MAX_DENY_USERS)
733 fatal( "%s line %d: too many deny users.",
735 options->deny_users[options->num_deny_users++] = xstrdup(arg);
740 while ((arg = strdelim(&cp)) && *arg != '\0') {
741 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
742 fatal("%s line %d: too many allow groups.",
744 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
749 while ((arg = strdelim(&cp)) && *arg != '\0') {
750 if (options->num_deny_groups >= MAX_DENY_GROUPS)
751 fatal("%s line %d: too many deny groups.",
753 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
759 if (!arg || *arg == '\0')
760 fatal("%s line %d: Missing argument.", filename, linenum);
761 if (!ciphers_valid(arg))
762 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
763 filename, linenum, arg ? arg : "<NONE>");
764 if (options->ciphers == NULL)
765 options->ciphers = xstrdup(arg);
770 if (!arg || *arg == '\0')
771 fatal("%s line %d: Missing argument.", filename, linenum);
773 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
774 filename, linenum, arg ? arg : "<NONE>");
775 if (options->macs == NULL)
776 options->macs = xstrdup(arg);
780 intptr = &options->protocol;
782 if (!arg || *arg == '\0')
783 fatal("%s line %d: Missing argument.", filename, linenum);
784 value = proto_spec(arg);
785 if (value == SSH_PROTO_UNKNOWN)
786 fatal("%s line %d: Bad protocol spec '%s'.",
787 filename, linenum, arg ? arg : "<NONE>");
788 if (*intptr == SSH_PROTO_UNKNOWN)
793 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
794 fatal("%s line %d: too many subsystems defined.",
798 if (!arg || *arg == '\0')
799 fatal("%s line %d: Missing subsystem name.",
801 for (i = 0; i < options->num_subsystems; i++)
802 if (strcmp(arg, options->subsystem_name[i]) == 0)
803 fatal("%s line %d: Subsystem '%s' already defined.",
804 filename, linenum, arg);
805 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
807 if (!arg || *arg == '\0')
808 fatal("%s line %d: Missing subsystem command.",
810 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
811 options->num_subsystems++;
816 if (!arg || *arg == '\0')
817 fatal("%s line %d: Missing MaxStartups spec.",
819 if ((n = sscanf(arg, "%d:%d:%d",
820 &options->max_startups_begin,
821 &options->max_startups_rate,
822 &options->max_startups)) == 3) {
823 if (options->max_startups_begin >
824 options->max_startups ||
825 options->max_startups_rate > 100 ||
826 options->max_startups_rate < 1)
827 fatal("%s line %d: Illegal MaxStartups spec.",
830 fatal("%s line %d: Illegal MaxStartups spec.",
833 options->max_startups = options->max_startups_begin;
837 charptr = &options->banner;
840 * These options can contain %X options expanded at
841 * connect time, so that you can specify paths like:
843 * AuthorizedKeysFile /etc/ssh_keys/%u
845 case sAuthorizedKeysFile:
846 case sAuthorizedKeysFile2:
847 charptr = (opcode == sAuthorizedKeysFile ) ?
848 &options->authorized_keys_file :
849 &options->authorized_keys_file2;
852 case sClientAliveInterval:
853 intptr = &options->client_alive_interval;
856 case sClientAliveCountMax:
857 intptr = &options->client_alive_count_max;
861 log("%s line %d: Deprecated option %s",
862 filename, linenum, arg);
868 fatal("%s line %d: Missing handler for opcode %s (%d)",
869 filename, linenum, arg, opcode);
871 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
872 fatal("%s line %d: garbage at end of line; \"%.200s\".",
873 filename, linenum, arg);
877 /* Reads the server configuration file. */
880 read_server_config(ServerOptions *options, const char *filename)
887 f = fopen(filename, "r");
893 while (fgets(line, sizeof(line), f)) {
894 /* Update line number counter. */
896 if (process_server_config_line(options, line, filename, linenum) != 0)
901 fatal("%s: terminating, %d bad configuration options",
902 filename, bad_options);