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.99 2002/01/27 14:57:46 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->x11_use_localhost = -1;
67 options->xauth_location = NULL;
68 options->strict_modes = -1;
69 options->keepalives = -1;
70 options->log_facility = (SyslogFacility) - 1;
71 options->log_level = (LogLevel) - 1;
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->reverse_mapping_check = -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 == (SyslogFacility) (-1))
172 options->log_facility = SYSLOG_FACILITY_AUTH;
173 if (options->log_level == (LogLevel) (-1))
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->reverse_mapping_check == -1)
224 options->reverse_mapping_check = 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, sReverseMappingCheck, 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 { "reversemappingcheck", sReverseMappingCheck },
340 { "clientaliveinterval", sClientAliveInterval },
341 { "clientalivecountmax", sClientAliveCountMax },
342 { "authorizedkeysfile", sAuthorizedKeysFile },
343 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
348 * Returns the number of the token pointed to by cp or sBadOption.
352 parse_token(const char *cp, const char *filename,
357 for (i = 0; keywords[i].name; i++)
358 if (strcasecmp(cp, keywords[i].name) == 0)
359 return keywords[i].opcode;
361 error("%s: line %d: Bad configuration option: %s",
362 filename, linenum, cp);
367 add_listen_addr(ServerOptions *options, char *addr, u_short port)
371 if (options->num_ports == 0)
372 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
374 for (i = 0; i < options->num_ports; i++)
375 add_one_listen_addr(options, addr, options->ports[i]);
377 add_one_listen_addr(options, addr, port);
381 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
383 struct addrinfo hints, *ai, *aitop;
384 char strport[NI_MAXSERV];
387 memset(&hints, 0, sizeof(hints));
388 hints.ai_family = IPv4or6;
389 hints.ai_socktype = SOCK_STREAM;
390 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
391 snprintf(strport, sizeof strport, "%d", port);
392 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
393 fatal("bad addr or host: %s (%s)",
394 addr ? addr : "<NULL>",
395 gai_strerror(gaierr));
396 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
398 ai->ai_next = options->listen_addrs;
399 options->listen_addrs = aitop;
403 process_server_config_line(ServerOptions *options, char *line,
404 const char *filename, int linenum)
406 char *cp, **charptr, *arg, *p;
408 ServerOpCodes opcode;
413 /* Ignore leading whitespace */
416 if (!arg || !*arg || *arg == '#')
420 opcode = parse_token(arg, filename, linenum);
422 /* Portable-specific options */
423 case sPAMAuthenticationViaKbdInt:
424 intptr = &options->pam_authentication_via_kbd_int;
427 /* Standard Options */
431 /* ignore ports from configfile if cmdline specifies ports */
432 if (options->ports_from_cmdline)
434 if (options->listen_addrs != NULL)
435 fatal("%s line %d: ports must be specified before "
436 "ListenAddress.", filename, linenum);
437 if (options->num_ports >= MAX_PORTS)
438 fatal("%s line %d: too many ports.",
441 if (!arg || *arg == '\0')
442 fatal("%s line %d: missing port number.",
444 options->ports[options->num_ports++] = a2port(arg);
445 if (options->ports[options->num_ports-1] == 0)
446 fatal("%s line %d: Badly formatted port number.",
451 intptr = &options->server_key_bits;
454 if (!arg || *arg == '\0')
455 fatal("%s line %d: missing integer value.",
462 case sLoginGraceTime:
463 intptr = &options->login_grace_time;
466 if (!arg || *arg == '\0')
467 fatal("%s line %d: missing time value.",
469 if ((value = convtime(arg)) == -1)
470 fatal("%s line %d: invalid time value.",
476 case sKeyRegenerationTime:
477 intptr = &options->key_regeneration_time;
482 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
483 fatal("%s line %d: missing inet addr.",
486 if ((p = strchr(arg, ']')) == NULL)
487 fatal("%s line %d: bad ipv6 inet addr usage.",
490 memmove(p, p+1, strlen(p+1)+1);
491 } else if (((p = strchr(arg, ':')) == NULL) ||
492 (strchr(p+1, ':') != NULL)) {
493 add_listen_addr(options, arg, 0);
501 fatal("%s line %d: bad inet addr:port usage.",
505 if ((port = a2port(p)) == 0)
506 fatal("%s line %d: bad port number.",
508 add_listen_addr(options, arg, port);
510 } else if (*p == '\0')
511 add_listen_addr(options, arg, 0);
513 fatal("%s line %d: bad inet addr usage.",
518 intptr = &options->num_host_key_files;
519 if (*intptr >= MAX_HOSTKEYS)
520 fatal("%s line %d: too many host keys specified (max %d).",
521 filename, linenum, MAX_HOSTKEYS);
522 charptr = &options->host_key_files[*intptr];
525 if (!arg || *arg == '\0')
526 fatal("%s line %d: missing file name.",
528 if (*charptr == NULL) {
529 *charptr = tilde_expand_filename(arg, getuid());
530 /* increase optional counter */
532 *intptr = *intptr + 1;
537 charptr = &options->pid_file;
540 case sPermitRootLogin:
541 intptr = &options->permit_root_login;
543 if (!arg || *arg == '\0')
544 fatal("%s line %d: missing yes/"
545 "without-password/forced-commands-only/no "
546 "argument.", filename, linenum);
547 value = 0; /* silence compiler */
548 if (strcmp(arg, "without-password") == 0)
549 value = PERMIT_NO_PASSWD;
550 else if (strcmp(arg, "forced-commands-only") == 0)
551 value = PERMIT_FORCED_ONLY;
552 else if (strcmp(arg, "yes") == 0)
554 else if (strcmp(arg, "no") == 0)
557 fatal("%s line %d: Bad yes/"
558 "without-password/forced-commands-only/no "
559 "argument: %s", filename, linenum, arg);
565 intptr = &options->ignore_rhosts;
568 if (!arg || *arg == '\0')
569 fatal("%s line %d: missing yes/no argument.",
571 value = 0; /* silence compiler */
572 if (strcmp(arg, "yes") == 0)
574 else if (strcmp(arg, "no") == 0)
577 fatal("%s line %d: Bad yes/no argument: %s",
578 filename, linenum, arg);
583 case sIgnoreUserKnownHosts:
584 intptr = &options->ignore_user_known_hosts;
587 case sRhostsAuthentication:
588 intptr = &options->rhosts_authentication;
591 case sRhostsRSAAuthentication:
592 intptr = &options->rhosts_rsa_authentication;
595 case sHostbasedAuthentication:
596 intptr = &options->hostbased_authentication;
599 case sHostbasedUsesNameFromPacketOnly:
600 intptr = &options->hostbased_uses_name_from_packet_only;
603 case sRSAAuthentication:
604 intptr = &options->rsa_authentication;
607 case sPubkeyAuthentication:
608 intptr = &options->pubkey_authentication;
610 #if defined(KRB4) || defined(KRB5)
611 case sKerberosAuthentication:
612 intptr = &options->kerberos_authentication;
615 case sKerberosOrLocalPasswd:
616 intptr = &options->kerberos_or_local_passwd;
619 case sKerberosTicketCleanup:
620 intptr = &options->kerberos_ticket_cleanup;
623 #if defined(AFS) || defined(KRB5)
624 case sKerberosTgtPassing:
625 intptr = &options->kerberos_tgt_passing;
629 case sAFSTokenPassing:
630 intptr = &options->afs_token_passing;
634 case sPasswordAuthentication:
635 intptr = &options->password_authentication;
638 case sKbdInteractiveAuthentication:
639 intptr = &options->kbd_interactive_authentication;
642 case sChallengeResponseAuthentication:
643 intptr = &options->challenge_response_authentication;
647 intptr = &options->print_motd;
651 intptr = &options->print_lastlog;
655 intptr = &options->x11_forwarding;
658 case sX11DisplayOffset:
659 intptr = &options->x11_display_offset;
662 case sX11UseLocalhost:
663 intptr = &options->x11_use_localhost;
667 charptr = &options->xauth_location;
671 intptr = &options->strict_modes;
675 intptr = &options->keepalives;
679 intptr = &options->permit_empty_passwd;
683 intptr = &options->use_login;
687 intptr = &options->gateway_ports;
690 case sReverseMappingCheck:
691 intptr = &options->reverse_mapping_check;
695 intptr = (int *) &options->log_facility;
697 value = log_facility_number(arg);
698 if (value == (SyslogFacility) - 1)
699 fatal("%.200s line %d: unsupported log facility '%s'",
700 filename, linenum, arg ? arg : "<NONE>");
702 *intptr = (SyslogFacility) value;
706 intptr = (int *) &options->log_level;
708 value = log_level_number(arg);
709 if (value == (LogLevel) - 1)
710 fatal("%.200s line %d: unsupported log level '%s'",
711 filename, linenum, arg ? arg : "<NONE>");
713 *intptr = (LogLevel) value;
716 case sAllowTcpForwarding:
717 intptr = &options->allow_tcp_forwarding;
721 while ((arg = strdelim(&cp)) && *arg != '\0') {
722 if (options->num_allow_users >= MAX_ALLOW_USERS)
723 fatal("%s line %d: too many allow users.",
725 options->allow_users[options->num_allow_users++] = xstrdup(arg);
730 while ((arg = strdelim(&cp)) && *arg != '\0') {
731 if (options->num_deny_users >= MAX_DENY_USERS)
732 fatal( "%s line %d: too many deny users.",
734 options->deny_users[options->num_deny_users++] = xstrdup(arg);
739 while ((arg = strdelim(&cp)) && *arg != '\0') {
740 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
741 fatal("%s line %d: too many allow groups.",
743 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
748 while ((arg = strdelim(&cp)) && *arg != '\0') {
749 if (options->num_deny_groups >= MAX_DENY_GROUPS)
750 fatal("%s line %d: too many deny groups.",
752 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
758 if (!arg || *arg == '\0')
759 fatal("%s line %d: Missing argument.", filename, linenum);
760 if (!ciphers_valid(arg))
761 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
762 filename, linenum, arg ? arg : "<NONE>");
763 if (options->ciphers == NULL)
764 options->ciphers = xstrdup(arg);
769 if (!arg || *arg == '\0')
770 fatal("%s line %d: Missing argument.", filename, linenum);
772 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
773 filename, linenum, arg ? arg : "<NONE>");
774 if (options->macs == NULL)
775 options->macs = xstrdup(arg);
779 intptr = &options->protocol;
781 if (!arg || *arg == '\0')
782 fatal("%s line %d: Missing argument.", filename, linenum);
783 value = proto_spec(arg);
784 if (value == SSH_PROTO_UNKNOWN)
785 fatal("%s line %d: Bad protocol spec '%s'.",
786 filename, linenum, arg ? arg : "<NONE>");
787 if (*intptr == SSH_PROTO_UNKNOWN)
792 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
793 fatal("%s line %d: too many subsystems defined.",
797 if (!arg || *arg == '\0')
798 fatal("%s line %d: Missing subsystem name.",
800 for (i = 0; i < options->num_subsystems; i++)
801 if (strcmp(arg, options->subsystem_name[i]) == 0)
802 fatal("%s line %d: Subsystem '%s' already defined.",
803 filename, linenum, arg);
804 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
806 if (!arg || *arg == '\0')
807 fatal("%s line %d: Missing subsystem command.",
809 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
810 options->num_subsystems++;
815 if (!arg || *arg == '\0')
816 fatal("%s line %d: Missing MaxStartups spec.",
818 if ((n = sscanf(arg, "%d:%d:%d",
819 &options->max_startups_begin,
820 &options->max_startups_rate,
821 &options->max_startups)) == 3) {
822 if (options->max_startups_begin >
823 options->max_startups ||
824 options->max_startups_rate > 100 ||
825 options->max_startups_rate < 1)
826 fatal("%s line %d: Illegal MaxStartups spec.",
829 fatal("%s line %d: Illegal MaxStartups spec.",
832 options->max_startups = options->max_startups_begin;
836 charptr = &options->banner;
839 * These options can contain %X options expanded at
840 * connect time, so that you can specify paths like:
842 * AuthorizedKeysFile /etc/ssh_keys/%u
844 case sAuthorizedKeysFile:
845 case sAuthorizedKeysFile2:
846 charptr = (opcode == sAuthorizedKeysFile ) ?
847 &options->authorized_keys_file :
848 &options->authorized_keys_file2;
851 case sClientAliveInterval:
852 intptr = &options->client_alive_interval;
855 case sClientAliveCountMax:
856 intptr = &options->client_alive_count_max;
860 log("%s line %d: Deprecated option %s",
861 filename, linenum, arg);
867 fatal("%s line %d: Missing handler for opcode %s (%d)",
868 filename, linenum, arg, opcode);
870 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
871 fatal("%s line %d: garbage at end of line; \"%.200s\".",
872 filename, linenum, arg);
876 /* Reads the server configuration file. */
879 read_server_config(ServerOptions *options, const char *filename)
886 f = fopen(filename, "r");
892 while (fgets(line, sizeof(line), f)) {
893 /* Update line number counter. */
895 if (process_server_config_line(options, line, filename, linenum) != 0)
900 fatal("%s: terminating, %d bad configuration options",
901 filename, bad_options);