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.94 2001/12/06 13:30:05 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->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++] = _PATH_HOST_KEY_FILE;
128 if (options->protocol & SSH_PROTO_2)
129 options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE;
131 if (options->num_ports == 0)
132 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
133 if (options->listen_addrs == NULL)
134 add_listen_addr(options, NULL, 0);
135 if (options->pid_file == NULL)
136 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
137 if (options->server_key_bits == -1)
138 options->server_key_bits = 768;
139 if (options->login_grace_time == -1)
140 options->login_grace_time = 600;
141 if (options->key_regeneration_time == -1)
142 options->key_regeneration_time = 3600;
143 if (options->permit_root_login == PERMIT_NOT_SET)
144 options->permit_root_login = PERMIT_YES;
145 if (options->ignore_rhosts == -1)
146 options->ignore_rhosts = 1;
147 if (options->ignore_user_known_hosts == -1)
148 options->ignore_user_known_hosts = 0;
149 if (options->print_motd == -1)
150 options->print_motd = 1;
151 if (options->print_lastlog == -1)
152 options->print_lastlog = 1;
153 if (options->x11_forwarding == -1)
154 options->x11_forwarding = 0;
155 if (options->x11_display_offset == -1)
156 options->x11_display_offset = 10;
158 if (options->xauth_location == NULL)
159 options->xauth_location = _PATH_XAUTH;
161 if (options->strict_modes == -1)
162 options->strict_modes = 1;
163 if (options->keepalives == -1)
164 options->keepalives = 1;
165 if (options->log_facility == (SyslogFacility) (-1))
166 options->log_facility = SYSLOG_FACILITY_AUTH;
167 if (options->log_level == (LogLevel) (-1))
168 options->log_level = SYSLOG_LEVEL_INFO;
169 if (options->rhosts_authentication == -1)
170 options->rhosts_authentication = 0;
171 if (options->rhosts_rsa_authentication == -1)
172 options->rhosts_rsa_authentication = 0;
173 if (options->hostbased_authentication == -1)
174 options->hostbased_authentication = 0;
175 if (options->hostbased_uses_name_from_packet_only == -1)
176 options->hostbased_uses_name_from_packet_only = 0;
177 if (options->rsa_authentication == -1)
178 options->rsa_authentication = 1;
179 if (options->pubkey_authentication == -1)
180 options->pubkey_authentication = 1;
181 #if defined(KRB4) || defined(KRB5)
182 if (options->kerberos_authentication == -1)
183 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
184 if (options->kerberos_or_local_passwd == -1)
185 options->kerberos_or_local_passwd = 1;
186 if (options->kerberos_ticket_cleanup == -1)
187 options->kerberos_ticket_cleanup = 1;
189 #if defined(AFS) || defined(KRB5)
190 if (options->kerberos_tgt_passing == -1)
191 options->kerberos_tgt_passing = 0;
194 if (options->afs_token_passing == -1)
195 options->afs_token_passing = k_hasafs();
197 if (options->password_authentication == -1)
198 options->password_authentication = 1;
199 if (options->kbd_interactive_authentication == -1)
200 options->kbd_interactive_authentication = 0;
201 if (options->challenge_response_authentication == -1)
202 options->challenge_response_authentication = 1;
203 if (options->permit_empty_passwd == -1)
204 options->permit_empty_passwd = 0;
205 if (options->use_login == -1)
206 options->use_login = 0;
207 if (options->allow_tcp_forwarding == -1)
208 options->allow_tcp_forwarding = 1;
209 if (options->gateway_ports == -1)
210 options->gateway_ports = 0;
211 if (options->max_startups == -1)
212 options->max_startups = 10;
213 if (options->max_startups_rate == -1)
214 options->max_startups_rate = 100; /* 100% */
215 if (options->max_startups_begin == -1)
216 options->max_startups_begin = options->max_startups;
217 if (options->reverse_mapping_check == -1)
218 options->reverse_mapping_check = 0;
219 if (options->client_alive_interval == -1)
220 options->client_alive_interval = 0;
221 if (options->client_alive_count_max == -1)
222 options->client_alive_count_max = 3;
223 if (options->authorized_keys_file2 == NULL) {
224 /* authorized_keys_file2 falls back to authorized_keys_file */
225 if (options->authorized_keys_file != NULL)
226 options->authorized_keys_file2 = options->authorized_keys_file;
228 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
230 if (options->authorized_keys_file == NULL)
231 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
234 /* Keyword tokens. */
236 sBadOption, /* == unknown option */
237 /* Portable-specific options */
238 sPAMAuthenticationViaKbdInt,
239 /* Standard Options */
240 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
241 sPermitRootLogin, sLogFacility, sLogLevel,
242 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
243 #if defined(KRB4) || defined(KRB5)
244 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
246 #if defined(AFS) || defined(KRB5)
252 sChallengeResponseAuthentication,
253 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
254 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
255 sX11Forwarding, sX11DisplayOffset,
256 sStrictModes, sEmptyPasswd, sKeepAlives,
257 sUseLogin, sAllowTcpForwarding,
258 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
259 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
260 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
261 sBanner, sReverseMappingCheck, sHostbasedAuthentication,
262 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
263 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
267 /* Textual representation of the tokens. */
270 ServerOpCodes opcode;
272 /* Portable-specific options */
273 { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt },
274 /* Standard Options */
276 { "hostkey", sHostKeyFile },
277 { "hostdsakey", sHostKeyFile }, /* alias */
278 { "pidfile", sPidFile },
279 { "serverkeybits", sServerKeyBits },
280 { "logingracetime", sLoginGraceTime },
281 { "keyregenerationinterval", sKeyRegenerationTime },
282 { "permitrootlogin", sPermitRootLogin },
283 { "syslogfacility", sLogFacility },
284 { "loglevel", sLogLevel },
285 { "rhostsauthentication", sRhostsAuthentication },
286 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
287 { "hostbasedauthentication", sHostbasedAuthentication },
288 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
289 { "rsaauthentication", sRSAAuthentication },
290 { "pubkeyauthentication", sPubkeyAuthentication },
291 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
292 #if defined(KRB4) || defined(KRB5)
293 { "kerberosauthentication", sKerberosAuthentication },
294 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
295 { "kerberosticketcleanup", sKerberosTicketCleanup },
297 #if defined(AFS) || defined(KRB5)
298 { "kerberostgtpassing", sKerberosTgtPassing },
301 { "afstokenpassing", sAFSTokenPassing },
303 { "passwordauthentication", sPasswordAuthentication },
304 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
305 { "challengeresponseauthentication", sChallengeResponseAuthentication },
306 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
307 { "checkmail", sDeprecated },
308 { "listenaddress", sListenAddress },
309 { "printmotd", sPrintMotd },
310 { "printlastlog", sPrintLastLog },
311 { "ignorerhosts", sIgnoreRhosts },
312 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
313 { "x11forwarding", sX11Forwarding },
314 { "x11displayoffset", sX11DisplayOffset },
315 { "xauthlocation", sXAuthLocation },
316 { "strictmodes", sStrictModes },
317 { "permitemptypasswords", sEmptyPasswd },
318 { "uselogin", sUseLogin },
319 { "keepalive", sKeepAlives },
320 { "allowtcpforwarding", sAllowTcpForwarding },
321 { "allowusers", sAllowUsers },
322 { "denyusers", sDenyUsers },
323 { "allowgroups", sAllowGroups },
324 { "denygroups", sDenyGroups },
325 { "ciphers", sCiphers },
327 { "protocol", sProtocol },
328 { "gatewayports", sGatewayPorts },
329 { "subsystem", sSubsystem },
330 { "maxstartups", sMaxStartups },
331 { "banner", sBanner },
332 { "reversemappingcheck", sReverseMappingCheck },
333 { "clientaliveinterval", sClientAliveInterval },
334 { "clientalivecountmax", sClientAliveCountMax },
335 { "authorizedkeysfile", sAuthorizedKeysFile },
336 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
341 * Returns the number of the token pointed to by cp or sBadOption.
345 parse_token(const char *cp, const char *filename,
350 for (i = 0; keywords[i].name; i++)
351 if (strcasecmp(cp, keywords[i].name) == 0)
352 return keywords[i].opcode;
354 error("%s: line %d: Bad configuration option: %s",
355 filename, linenum, cp);
360 add_listen_addr(ServerOptions *options, char *addr, u_short port)
364 if (options->num_ports == 0)
365 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
367 for (i = 0; i < options->num_ports; i++)
368 add_one_listen_addr(options, addr, options->ports[i]);
370 add_one_listen_addr(options, addr, port);
374 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
376 struct addrinfo hints, *ai, *aitop;
377 char strport[NI_MAXSERV];
380 memset(&hints, 0, sizeof(hints));
381 hints.ai_family = IPv4or6;
382 hints.ai_socktype = SOCK_STREAM;
383 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
384 snprintf(strport, sizeof strport, "%d", port);
385 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
386 fatal("bad addr or host: %s (%s)",
387 addr ? addr : "<NULL>",
388 gai_strerror(gaierr));
389 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
391 ai->ai_next = options->listen_addrs;
392 options->listen_addrs = aitop;
396 process_server_config_line(ServerOptions *options, char *line,
397 const char *filename, int linenum)
399 char *cp, **charptr, *arg, *p;
401 ServerOpCodes opcode;
406 /* Ignore leading whitespace */
409 if (!arg || !*arg || *arg == '#')
413 opcode = parse_token(arg, filename, linenum);
415 /* Portable-specific options */
416 case sPAMAuthenticationViaKbdInt:
417 intptr = &options->pam_authentication_via_kbd_int;
420 /* Standard Options */
424 /* ignore ports from configfile if cmdline specifies ports */
425 if (options->ports_from_cmdline)
427 if (options->listen_addrs != NULL)
428 fatal("%s line %d: ports must be specified before "
429 "ListenAdress.", filename, linenum);
430 if (options->num_ports >= MAX_PORTS)
431 fatal("%s line %d: too many ports.",
434 if (!arg || *arg == '\0')
435 fatal("%s line %d: missing port number.",
437 options->ports[options->num_ports++] = a2port(arg);
438 if (options->ports[options->num_ports-1] == 0)
439 fatal("%s line %d: Badly formatted port number.",
444 intptr = &options->server_key_bits;
447 if (!arg || *arg == '\0')
448 fatal("%s line %d: missing integer value.",
455 case sLoginGraceTime:
456 intptr = &options->login_grace_time;
459 if (!arg || *arg == '\0')
460 fatal("%s line %d: missing time value.",
462 if ((value = convtime(arg)) == -1)
463 fatal("%s line %d: invalid time value.",
469 case sKeyRegenerationTime:
470 intptr = &options->key_regeneration_time;
475 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
476 fatal("%s line %d: missing inet addr.",
479 if ((p = strchr(arg, ']')) == NULL)
480 fatal("%s line %d: bad ipv6 inet addr usage.",
483 memmove(p, p+1, strlen(p+1)+1);
484 } else if (((p = strchr(arg, ':')) == NULL) ||
485 (strchr(p+1, ':') != NULL)) {
486 add_listen_addr(options, arg, 0);
494 fatal("%s line %d: bad inet addr:port usage.",
498 if ((port = a2port(p)) == 0)
499 fatal("%s line %d: bad port number.",
501 add_listen_addr(options, arg, port);
503 } else if (*p == '\0')
504 add_listen_addr(options, arg, 0);
506 fatal("%s line %d: bad inet addr usage.",
511 intptr = &options->num_host_key_files;
512 if (*intptr >= MAX_HOSTKEYS)
513 fatal("%s line %d: too many host keys specified (max %d).",
514 filename, linenum, MAX_HOSTKEYS);
515 charptr = &options->host_key_files[*intptr];
518 if (!arg || *arg == '\0')
519 fatal("%s line %d: missing file name.",
521 if (*charptr == NULL) {
522 *charptr = tilde_expand_filename(arg, getuid());
523 /* increase optional counter */
525 *intptr = *intptr + 1;
530 charptr = &options->pid_file;
533 case sPermitRootLogin:
534 intptr = &options->permit_root_login;
536 if (!arg || *arg == '\0')
537 fatal("%s line %d: missing yes/"
538 "without-password/forced-commands-only/no "
539 "argument.", filename, linenum);
540 value = 0; /* silence compiler */
541 if (strcmp(arg, "without-password") == 0)
542 value = PERMIT_NO_PASSWD;
543 else if (strcmp(arg, "forced-commands-only") == 0)
544 value = PERMIT_FORCED_ONLY;
545 else if (strcmp(arg, "yes") == 0)
547 else if (strcmp(arg, "no") == 0)
550 fatal("%s line %d: Bad yes/"
551 "without-password/forced-commands-only/no "
552 "argument: %s", filename, linenum, arg);
558 intptr = &options->ignore_rhosts;
561 if (!arg || *arg == '\0')
562 fatal("%s line %d: missing yes/no argument.",
564 value = 0; /* silence compiler */
565 if (strcmp(arg, "yes") == 0)
567 else if (strcmp(arg, "no") == 0)
570 fatal("%s line %d: Bad yes/no argument: %s",
571 filename, linenum, arg);
576 case sIgnoreUserKnownHosts:
577 intptr = &options->ignore_user_known_hosts;
580 case sRhostsAuthentication:
581 intptr = &options->rhosts_authentication;
584 case sRhostsRSAAuthentication:
585 intptr = &options->rhosts_rsa_authentication;
588 case sHostbasedAuthentication:
589 intptr = &options->hostbased_authentication;
592 case sHostbasedUsesNameFromPacketOnly:
593 intptr = &options->hostbased_uses_name_from_packet_only;
596 case sRSAAuthentication:
597 intptr = &options->rsa_authentication;
600 case sPubkeyAuthentication:
601 intptr = &options->pubkey_authentication;
603 #if defined(KRB4) || defined(KRB5)
604 case sKerberosAuthentication:
605 intptr = &options->kerberos_authentication;
608 case sKerberosOrLocalPasswd:
609 intptr = &options->kerberos_or_local_passwd;
612 case sKerberosTicketCleanup:
613 intptr = &options->kerberos_ticket_cleanup;
616 #if defined(AFS) || defined(KRB5)
617 case sKerberosTgtPassing:
618 intptr = &options->kerberos_tgt_passing;
622 case sAFSTokenPassing:
623 intptr = &options->afs_token_passing;
627 case sPasswordAuthentication:
628 intptr = &options->password_authentication;
631 case sKbdInteractiveAuthentication:
632 intptr = &options->kbd_interactive_authentication;
635 case sChallengeResponseAuthentication:
636 intptr = &options->challenge_response_authentication;
640 intptr = &options->print_motd;
644 intptr = &options->print_lastlog;
648 intptr = &options->x11_forwarding;
651 case sX11DisplayOffset:
652 intptr = &options->x11_display_offset;
656 charptr = &options->xauth_location;
660 intptr = &options->strict_modes;
664 intptr = &options->keepalives;
668 intptr = &options->permit_empty_passwd;
672 intptr = &options->use_login;
676 intptr = &options->gateway_ports;
679 case sReverseMappingCheck:
680 intptr = &options->reverse_mapping_check;
684 intptr = (int *) &options->log_facility;
686 value = log_facility_number(arg);
687 if (value == (SyslogFacility) - 1)
688 fatal("%.200s line %d: unsupported log facility '%s'",
689 filename, linenum, arg ? arg : "<NONE>");
691 *intptr = (SyslogFacility) value;
695 intptr = (int *) &options->log_level;
697 value = log_level_number(arg);
698 if (value == (LogLevel) - 1)
699 fatal("%.200s line %d: unsupported log level '%s'",
700 filename, linenum, arg ? arg : "<NONE>");
702 *intptr = (LogLevel) value;
705 case sAllowTcpForwarding:
706 intptr = &options->allow_tcp_forwarding;
710 while ((arg = strdelim(&cp)) && *arg != '\0') {
711 if (options->num_allow_users >= MAX_ALLOW_USERS)
712 fatal("%s line %d: too many allow users.",
714 options->allow_users[options->num_allow_users++] = xstrdup(arg);
719 while ((arg = strdelim(&cp)) && *arg != '\0') {
720 if (options->num_deny_users >= MAX_DENY_USERS)
721 fatal( "%s line %d: too many deny users.",
723 options->deny_users[options->num_deny_users++] = xstrdup(arg);
728 while ((arg = strdelim(&cp)) && *arg != '\0') {
729 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
730 fatal("%s line %d: too many allow groups.",
732 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
737 while ((arg = strdelim(&cp)) && *arg != '\0') {
738 if (options->num_deny_groups >= MAX_DENY_GROUPS)
739 fatal("%s line %d: too many deny groups.",
741 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
747 if (!arg || *arg == '\0')
748 fatal("%s line %d: Missing argument.", filename, linenum);
749 if (!ciphers_valid(arg))
750 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
751 filename, linenum, arg ? arg : "<NONE>");
752 if (options->ciphers == NULL)
753 options->ciphers = xstrdup(arg);
758 if (!arg || *arg == '\0')
759 fatal("%s line %d: Missing argument.", filename, linenum);
761 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
762 filename, linenum, arg ? arg : "<NONE>");
763 if (options->macs == NULL)
764 options->macs = xstrdup(arg);
768 intptr = &options->protocol;
770 if (!arg || *arg == '\0')
771 fatal("%s line %d: Missing argument.", filename, linenum);
772 value = proto_spec(arg);
773 if (value == SSH_PROTO_UNKNOWN)
774 fatal("%s line %d: Bad protocol spec '%s'.",
775 filename, linenum, arg ? arg : "<NONE>");
776 if (*intptr == SSH_PROTO_UNKNOWN)
781 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
782 fatal("%s line %d: too many subsystems defined.",
786 if (!arg || *arg == '\0')
787 fatal("%s line %d: Missing subsystem name.",
789 for (i = 0; i < options->num_subsystems; i++)
790 if (strcmp(arg, options->subsystem_name[i]) == 0)
791 fatal("%s line %d: Subsystem '%s' already defined.",
792 filename, linenum, arg);
793 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
795 if (!arg || *arg == '\0')
796 fatal("%s line %d: Missing subsystem command.",
798 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
799 options->num_subsystems++;
804 if (!arg || *arg == '\0')
805 fatal("%s line %d: Missing MaxStartups spec.",
807 if ((n = sscanf(arg, "%d:%d:%d",
808 &options->max_startups_begin,
809 &options->max_startups_rate,
810 &options->max_startups)) == 3) {
811 if (options->max_startups_begin >
812 options->max_startups ||
813 options->max_startups_rate > 100 ||
814 options->max_startups_rate < 1)
815 fatal("%s line %d: Illegal MaxStartups spec.",
818 fatal("%s line %d: Illegal MaxStartups spec.",
821 options->max_startups = options->max_startups_begin;
825 charptr = &options->banner;
828 * These options can contain %X options expanded at
829 * connect time, so that you can specify paths like:
831 * AuthorizedKeysFile /etc/ssh_keys/%u
833 case sAuthorizedKeysFile:
834 case sAuthorizedKeysFile2:
835 charptr = (opcode == sAuthorizedKeysFile ) ?
836 &options->authorized_keys_file :
837 &options->authorized_keys_file2;
840 case sClientAliveInterval:
841 intptr = &options->client_alive_interval;
844 case sClientAliveCountMax:
845 intptr = &options->client_alive_count_max;
849 log("%s line %d: Deprecated option %s",
850 filename, linenum, arg);
856 fatal("%s line %d: Missing handler for opcode %s (%d)",
857 filename, linenum, arg, opcode);
859 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
860 fatal("%s line %d: garbage at end of line; \"%.200s\".",
861 filename, linenum, arg);
865 /* Reads the server configuration file. */
868 read_server_config(ServerOptions *options, const char *filename)
875 f = fopen(filename, "r");
881 while (fgets(line, sizeof(line), f)) {
882 /* Update line number counter. */
884 if (process_server_config_line(options, line, filename, linenum) != 0)
889 fatal("%s: terminating, %d bad configuration options",
890 filename, bad_options);