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.96 2002/01/04 17:59:17 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++] = _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;
157 if (options->xauth_location == NULL)
158 options->xauth_location = _PATH_XAUTH;
159 if (options->strict_modes == -1)
160 options->strict_modes = 1;
161 if (options->keepalives == -1)
162 options->keepalives = 1;
163 if (options->log_facility == (SyslogFacility) (-1))
164 options->log_facility = SYSLOG_FACILITY_AUTH;
165 if (options->log_level == (LogLevel) (-1))
166 options->log_level = SYSLOG_LEVEL_INFO;
167 if (options->rhosts_authentication == -1)
168 options->rhosts_authentication = 0;
169 if (options->rhosts_rsa_authentication == -1)
170 options->rhosts_rsa_authentication = 0;
171 if (options->hostbased_authentication == -1)
172 options->hostbased_authentication = 0;
173 if (options->hostbased_uses_name_from_packet_only == -1)
174 options->hostbased_uses_name_from_packet_only = 0;
175 if (options->rsa_authentication == -1)
176 options->rsa_authentication = 1;
177 if (options->pubkey_authentication == -1)
178 options->pubkey_authentication = 1;
179 #if defined(KRB4) || defined(KRB5)
180 if (options->kerberos_authentication == -1)
181 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
182 if (options->kerberos_or_local_passwd == -1)
183 options->kerberos_or_local_passwd = 1;
184 if (options->kerberos_ticket_cleanup == -1)
185 options->kerberos_ticket_cleanup = 1;
187 #if defined(AFS) || defined(KRB5)
188 if (options->kerberos_tgt_passing == -1)
189 options->kerberos_tgt_passing = 0;
192 if (options->afs_token_passing == -1)
193 options->afs_token_passing = k_hasafs();
195 if (options->password_authentication == -1)
196 options->password_authentication = 1;
197 if (options->kbd_interactive_authentication == -1)
198 options->kbd_interactive_authentication = 0;
199 if (options->challenge_response_authentication == -1)
200 options->challenge_response_authentication = 1;
201 if (options->permit_empty_passwd == -1)
202 options->permit_empty_passwd = 0;
203 if (options->use_login == -1)
204 options->use_login = 0;
205 if (options->allow_tcp_forwarding == -1)
206 options->allow_tcp_forwarding = 1;
207 if (options->gateway_ports == -1)
208 options->gateway_ports = 0;
209 if (options->max_startups == -1)
210 options->max_startups = 10;
211 if (options->max_startups_rate == -1)
212 options->max_startups_rate = 100; /* 100% */
213 if (options->max_startups_begin == -1)
214 options->max_startups_begin = options->max_startups;
215 if (options->reverse_mapping_check == -1)
216 options->reverse_mapping_check = 0;
217 if (options->client_alive_interval == -1)
218 options->client_alive_interval = 0;
219 if (options->client_alive_count_max == -1)
220 options->client_alive_count_max = 3;
221 if (options->authorized_keys_file2 == NULL) {
222 /* authorized_keys_file2 falls back to authorized_keys_file */
223 if (options->authorized_keys_file != NULL)
224 options->authorized_keys_file2 = options->authorized_keys_file;
226 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
228 if (options->authorized_keys_file == NULL)
229 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
232 /* Keyword tokens. */
234 sBadOption, /* == unknown option */
235 /* Portable-specific options */
236 sPAMAuthenticationViaKbdInt,
237 /* Standard Options */
238 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
239 sPermitRootLogin, sLogFacility, sLogLevel,
240 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
241 #if defined(KRB4) || defined(KRB5)
242 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
244 #if defined(AFS) || defined(KRB5)
250 sChallengeResponseAuthentication,
251 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
252 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
253 sX11Forwarding, sX11DisplayOffset,
254 sStrictModes, sEmptyPasswd, sKeepAlives,
255 sUseLogin, sAllowTcpForwarding,
256 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
257 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
258 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
259 sBanner, sReverseMappingCheck, sHostbasedAuthentication,
260 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
261 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
265 /* Textual representation of the tokens. */
268 ServerOpCodes opcode;
270 /* Portable-specific options */
271 { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt },
272 /* Standard Options */
274 { "hostkey", sHostKeyFile },
275 { "hostdsakey", sHostKeyFile }, /* alias */
276 { "pidfile", sPidFile },
277 { "serverkeybits", sServerKeyBits },
278 { "logingracetime", sLoginGraceTime },
279 { "keyregenerationinterval", sKeyRegenerationTime },
280 { "permitrootlogin", sPermitRootLogin },
281 { "syslogfacility", sLogFacility },
282 { "loglevel", sLogLevel },
283 { "rhostsauthentication", sRhostsAuthentication },
284 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
285 { "hostbasedauthentication", sHostbasedAuthentication },
286 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
287 { "rsaauthentication", sRSAAuthentication },
288 { "pubkeyauthentication", sPubkeyAuthentication },
289 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
290 #if defined(KRB4) || defined(KRB5)
291 { "kerberosauthentication", sKerberosAuthentication },
292 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
293 { "kerberosticketcleanup", sKerberosTicketCleanup },
295 #if defined(AFS) || defined(KRB5)
296 { "kerberostgtpassing", sKerberosTgtPassing },
299 { "afstokenpassing", sAFSTokenPassing },
301 { "passwordauthentication", sPasswordAuthentication },
302 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
303 { "challengeresponseauthentication", sChallengeResponseAuthentication },
304 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
305 { "checkmail", sDeprecated },
306 { "listenaddress", sListenAddress },
307 { "printmotd", sPrintMotd },
308 { "printlastlog", sPrintLastLog },
309 { "ignorerhosts", sIgnoreRhosts },
310 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
311 { "x11forwarding", sX11Forwarding },
312 { "x11displayoffset", sX11DisplayOffset },
313 { "xauthlocation", sXAuthLocation },
314 { "strictmodes", sStrictModes },
315 { "permitemptypasswords", sEmptyPasswd },
316 { "uselogin", sUseLogin },
317 { "keepalive", sKeepAlives },
318 { "allowtcpforwarding", sAllowTcpForwarding },
319 { "allowusers", sAllowUsers },
320 { "denyusers", sDenyUsers },
321 { "allowgroups", sAllowGroups },
322 { "denygroups", sDenyGroups },
323 { "ciphers", sCiphers },
325 { "protocol", sProtocol },
326 { "gatewayports", sGatewayPorts },
327 { "subsystem", sSubsystem },
328 { "maxstartups", sMaxStartups },
329 { "banner", sBanner },
330 { "reversemappingcheck", sReverseMappingCheck },
331 { "clientaliveinterval", sClientAliveInterval },
332 { "clientalivecountmax", sClientAliveCountMax },
333 { "authorizedkeysfile", sAuthorizedKeysFile },
334 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
339 * Returns the number of the token pointed to by cp or sBadOption.
343 parse_token(const char *cp, const char *filename,
348 for (i = 0; keywords[i].name; i++)
349 if (strcasecmp(cp, keywords[i].name) == 0)
350 return keywords[i].opcode;
352 error("%s: line %d: Bad configuration option: %s",
353 filename, linenum, cp);
358 add_listen_addr(ServerOptions *options, char *addr, u_short port)
362 if (options->num_ports == 0)
363 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
365 for (i = 0; i < options->num_ports; i++)
366 add_one_listen_addr(options, addr, options->ports[i]);
368 add_one_listen_addr(options, addr, port);
372 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
374 struct addrinfo hints, *ai, *aitop;
375 char strport[NI_MAXSERV];
378 memset(&hints, 0, sizeof(hints));
379 hints.ai_family = IPv4or6;
380 hints.ai_socktype = SOCK_STREAM;
381 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
382 snprintf(strport, sizeof strport, "%d", port);
383 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
384 fatal("bad addr or host: %s (%s)",
385 addr ? addr : "<NULL>",
386 gai_strerror(gaierr));
387 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
389 ai->ai_next = options->listen_addrs;
390 options->listen_addrs = aitop;
394 process_server_config_line(ServerOptions *options, char *line,
395 const char *filename, int linenum)
397 char *cp, **charptr, *arg, *p;
399 ServerOpCodes opcode;
404 /* Ignore leading whitespace */
407 if (!arg || !*arg || *arg == '#')
411 opcode = parse_token(arg, filename, linenum);
413 /* Portable-specific options */
414 case sPAMAuthenticationViaKbdInt:
415 intptr = &options->pam_authentication_via_kbd_int;
418 /* Standard Options */
422 /* ignore ports from configfile if cmdline specifies ports */
423 if (options->ports_from_cmdline)
425 if (options->listen_addrs != NULL)
426 fatal("%s line %d: ports must be specified before "
427 "ListenAdress.", filename, linenum);
428 if (options->num_ports >= MAX_PORTS)
429 fatal("%s line %d: too many ports.",
432 if (!arg || *arg == '\0')
433 fatal("%s line %d: missing port number.",
435 options->ports[options->num_ports++] = a2port(arg);
436 if (options->ports[options->num_ports-1] == 0)
437 fatal("%s line %d: Badly formatted port number.",
442 intptr = &options->server_key_bits;
445 if (!arg || *arg == '\0')
446 fatal("%s line %d: missing integer value.",
453 case sLoginGraceTime:
454 intptr = &options->login_grace_time;
457 if (!arg || *arg == '\0')
458 fatal("%s line %d: missing time value.",
460 if ((value = convtime(arg)) == -1)
461 fatal("%s line %d: invalid time value.",
467 case sKeyRegenerationTime:
468 intptr = &options->key_regeneration_time;
473 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
474 fatal("%s line %d: missing inet addr.",
477 if ((p = strchr(arg, ']')) == NULL)
478 fatal("%s line %d: bad ipv6 inet addr usage.",
481 memmove(p, p+1, strlen(p+1)+1);
482 } else if (((p = strchr(arg, ':')) == NULL) ||
483 (strchr(p+1, ':') != NULL)) {
484 add_listen_addr(options, arg, 0);
492 fatal("%s line %d: bad inet addr:port usage.",
496 if ((port = a2port(p)) == 0)
497 fatal("%s line %d: bad port number.",
499 add_listen_addr(options, arg, port);
501 } else if (*p == '\0')
502 add_listen_addr(options, arg, 0);
504 fatal("%s line %d: bad inet addr usage.",
509 intptr = &options->num_host_key_files;
510 if (*intptr >= MAX_HOSTKEYS)
511 fatal("%s line %d: too many host keys specified (max %d).",
512 filename, linenum, MAX_HOSTKEYS);
513 charptr = &options->host_key_files[*intptr];
516 if (!arg || *arg == '\0')
517 fatal("%s line %d: missing file name.",
519 if (*charptr == NULL) {
520 *charptr = tilde_expand_filename(arg, getuid());
521 /* increase optional counter */
523 *intptr = *intptr + 1;
528 charptr = &options->pid_file;
531 case sPermitRootLogin:
532 intptr = &options->permit_root_login;
534 if (!arg || *arg == '\0')
535 fatal("%s line %d: missing yes/"
536 "without-password/forced-commands-only/no "
537 "argument.", filename, linenum);
538 value = 0; /* silence compiler */
539 if (strcmp(arg, "without-password") == 0)
540 value = PERMIT_NO_PASSWD;
541 else if (strcmp(arg, "forced-commands-only") == 0)
542 value = PERMIT_FORCED_ONLY;
543 else if (strcmp(arg, "yes") == 0)
545 else if (strcmp(arg, "no") == 0)
548 fatal("%s line %d: Bad yes/"
549 "without-password/forced-commands-only/no "
550 "argument: %s", filename, linenum, arg);
556 intptr = &options->ignore_rhosts;
559 if (!arg || *arg == '\0')
560 fatal("%s line %d: missing yes/no argument.",
562 value = 0; /* silence compiler */
563 if (strcmp(arg, "yes") == 0)
565 else if (strcmp(arg, "no") == 0)
568 fatal("%s line %d: Bad yes/no argument: %s",
569 filename, linenum, arg);
574 case sIgnoreUserKnownHosts:
575 intptr = &options->ignore_user_known_hosts;
578 case sRhostsAuthentication:
579 intptr = &options->rhosts_authentication;
582 case sRhostsRSAAuthentication:
583 intptr = &options->rhosts_rsa_authentication;
586 case sHostbasedAuthentication:
587 intptr = &options->hostbased_authentication;
590 case sHostbasedUsesNameFromPacketOnly:
591 intptr = &options->hostbased_uses_name_from_packet_only;
594 case sRSAAuthentication:
595 intptr = &options->rsa_authentication;
598 case sPubkeyAuthentication:
599 intptr = &options->pubkey_authentication;
601 #if defined(KRB4) || defined(KRB5)
602 case sKerberosAuthentication:
603 intptr = &options->kerberos_authentication;
606 case sKerberosOrLocalPasswd:
607 intptr = &options->kerberos_or_local_passwd;
610 case sKerberosTicketCleanup:
611 intptr = &options->kerberos_ticket_cleanup;
614 #if defined(AFS) || defined(KRB5)
615 case sKerberosTgtPassing:
616 intptr = &options->kerberos_tgt_passing;
620 case sAFSTokenPassing:
621 intptr = &options->afs_token_passing;
625 case sPasswordAuthentication:
626 intptr = &options->password_authentication;
629 case sKbdInteractiveAuthentication:
630 intptr = &options->kbd_interactive_authentication;
633 case sChallengeResponseAuthentication:
634 intptr = &options->challenge_response_authentication;
638 intptr = &options->print_motd;
642 intptr = &options->print_lastlog;
646 intptr = &options->x11_forwarding;
649 case sX11DisplayOffset:
650 intptr = &options->x11_display_offset;
654 charptr = &options->xauth_location;
658 intptr = &options->strict_modes;
662 intptr = &options->keepalives;
666 intptr = &options->permit_empty_passwd;
670 intptr = &options->use_login;
674 intptr = &options->gateway_ports;
677 case sReverseMappingCheck:
678 intptr = &options->reverse_mapping_check;
682 intptr = (int *) &options->log_facility;
684 value = log_facility_number(arg);
685 if (value == (SyslogFacility) - 1)
686 fatal("%.200s line %d: unsupported log facility '%s'",
687 filename, linenum, arg ? arg : "<NONE>");
689 *intptr = (SyslogFacility) value;
693 intptr = (int *) &options->log_level;
695 value = log_level_number(arg);
696 if (value == (LogLevel) - 1)
697 fatal("%.200s line %d: unsupported log level '%s'",
698 filename, linenum, arg ? arg : "<NONE>");
700 *intptr = (LogLevel) value;
703 case sAllowTcpForwarding:
704 intptr = &options->allow_tcp_forwarding;
708 while ((arg = strdelim(&cp)) && *arg != '\0') {
709 if (options->num_allow_users >= MAX_ALLOW_USERS)
710 fatal("%s line %d: too many allow users.",
712 options->allow_users[options->num_allow_users++] = xstrdup(arg);
717 while ((arg = strdelim(&cp)) && *arg != '\0') {
718 if (options->num_deny_users >= MAX_DENY_USERS)
719 fatal( "%s line %d: too many deny users.",
721 options->deny_users[options->num_deny_users++] = xstrdup(arg);
726 while ((arg = strdelim(&cp)) && *arg != '\0') {
727 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
728 fatal("%s line %d: too many allow groups.",
730 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
735 while ((arg = strdelim(&cp)) && *arg != '\0') {
736 if (options->num_deny_groups >= MAX_DENY_GROUPS)
737 fatal("%s line %d: too many deny groups.",
739 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
745 if (!arg || *arg == '\0')
746 fatal("%s line %d: Missing argument.", filename, linenum);
747 if (!ciphers_valid(arg))
748 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
749 filename, linenum, arg ? arg : "<NONE>");
750 if (options->ciphers == NULL)
751 options->ciphers = xstrdup(arg);
756 if (!arg || *arg == '\0')
757 fatal("%s line %d: Missing argument.", filename, linenum);
759 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
760 filename, linenum, arg ? arg : "<NONE>");
761 if (options->macs == NULL)
762 options->macs = xstrdup(arg);
766 intptr = &options->protocol;
768 if (!arg || *arg == '\0')
769 fatal("%s line %d: Missing argument.", filename, linenum);
770 value = proto_spec(arg);
771 if (value == SSH_PROTO_UNKNOWN)
772 fatal("%s line %d: Bad protocol spec '%s'.",
773 filename, linenum, arg ? arg : "<NONE>");
774 if (*intptr == SSH_PROTO_UNKNOWN)
779 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
780 fatal("%s line %d: too many subsystems defined.",
784 if (!arg || *arg == '\0')
785 fatal("%s line %d: Missing subsystem name.",
787 for (i = 0; i < options->num_subsystems; i++)
788 if (strcmp(arg, options->subsystem_name[i]) == 0)
789 fatal("%s line %d: Subsystem '%s' already defined.",
790 filename, linenum, arg);
791 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
793 if (!arg || *arg == '\0')
794 fatal("%s line %d: Missing subsystem command.",
796 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
797 options->num_subsystems++;
802 if (!arg || *arg == '\0')
803 fatal("%s line %d: Missing MaxStartups spec.",
805 if ((n = sscanf(arg, "%d:%d:%d",
806 &options->max_startups_begin,
807 &options->max_startups_rate,
808 &options->max_startups)) == 3) {
809 if (options->max_startups_begin >
810 options->max_startups ||
811 options->max_startups_rate > 100 ||
812 options->max_startups_rate < 1)
813 fatal("%s line %d: Illegal MaxStartups spec.",
816 fatal("%s line %d: Illegal MaxStartups spec.",
819 options->max_startups = options->max_startups_begin;
823 charptr = &options->banner;
826 * These options can contain %X options expanded at
827 * connect time, so that you can specify paths like:
829 * AuthorizedKeysFile /etc/ssh_keys/%u
831 case sAuthorizedKeysFile:
832 case sAuthorizedKeysFile2:
833 charptr = (opcode == sAuthorizedKeysFile ) ?
834 &options->authorized_keys_file :
835 &options->authorized_keys_file2;
838 case sClientAliveInterval:
839 intptr = &options->client_alive_interval;
842 case sClientAliveCountMax:
843 intptr = &options->client_alive_count_max;
847 log("%s line %d: Deprecated option %s",
848 filename, linenum, arg);
854 fatal("%s line %d: Missing handler for opcode %s (%d)",
855 filename, linenum, arg, opcode);
857 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
858 fatal("%s line %d: garbage at end of line; \"%.200s\".",
859 filename, linenum, arg);
863 /* Reads the server configuration file. */
866 read_server_config(ServerOptions *options, const char *filename)
873 f = fopen(filename, "r");
879 while (fgets(line, sizeof(line), f)) {
880 /* Update line number counter. */
882 if (process_server_config_line(options, line, filename, linenum) != 0)
887 fatal("%s: terminating, %d bad configuration options",
888 filename, bad_options);