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 */
39 /* Use of privilege separation or not */
40 extern int use_privsep;
42 /* Initializes the server options to their default values. */
45 initialize_server_options(ServerOptions *options)
47 memset(options, 0, sizeof(*options));
49 /* Portable-specific options */
50 options->pam_authentication_via_kbd_int = -1;
52 /* Standard Options */
53 options->num_ports = 0;
54 options->ports_from_cmdline = 0;
55 options->listen_addrs = NULL;
56 options->num_host_key_files = 0;
57 options->pid_file = NULL;
58 options->server_key_bits = -1;
59 options->login_grace_time = -1;
60 options->key_regeneration_time = -1;
61 options->permit_root_login = PERMIT_NOT_SET;
62 options->ignore_rhosts = -1;
63 options->ignore_user_known_hosts = -1;
64 options->print_motd = -1;
65 options->print_lastlog = -1;
66 options->x11_forwarding = -1;
67 options->x11_display_offset = -1;
68 options->x11_use_localhost = -1;
69 options->xauth_location = NULL;
70 options->strict_modes = -1;
71 options->keepalives = -1;
72 options->log_facility = SYSLOG_FACILITY_NOT_SET;
73 options->log_level = SYSLOG_LEVEL_NOT_SET;
74 options->rhosts_authentication = -1;
75 options->rhosts_rsa_authentication = -1;
76 options->hostbased_authentication = -1;
77 options->hostbased_uses_name_from_packet_only = -1;
78 options->rsa_authentication = -1;
79 options->pubkey_authentication = -1;
80 #if defined(KRB4) || defined(KRB5)
81 options->kerberos_authentication = -1;
82 options->kerberos_or_local_passwd = -1;
83 options->kerberos_ticket_cleanup = -1;
85 #if defined(AFS) || defined(KRB5)
86 options->kerberos_tgt_passing = -1;
89 options->afs_token_passing = -1;
91 options->password_authentication = -1;
92 options->kbd_interactive_authentication = -1;
93 options->challenge_response_authentication = -1;
94 options->permit_empty_passwd = -1;
95 options->use_login = -1;
96 options->allow_tcp_forwarding = -1;
97 options->num_allow_users = 0;
98 options->num_deny_users = 0;
99 options->num_allow_groups = 0;
100 options->num_deny_groups = 0;
101 options->ciphers = NULL;
102 options->macs = NULL;
103 options->protocol = SSH_PROTO_UNKNOWN;
104 options->gateway_ports = -1;
105 options->num_subsystems = 0;
106 options->max_startups_begin = -1;
107 options->max_startups_rate = -1;
108 options->max_startups = -1;
109 options->banner = NULL;
110 options->verify_reverse_mapping = -1;
111 options->client_alive_interval = -1;
112 options->client_alive_count_max = -1;
113 options->authorized_keys_file = NULL;
114 options->authorized_keys_file2 = NULL;
116 /* Needs to be accessable in many places */
121 fill_default_server_options(ServerOptions *options)
123 /* Portable-specific options */
124 if (options->pam_authentication_via_kbd_int == -1)
125 options->pam_authentication_via_kbd_int = 0;
127 /* Standard Options */
128 if (options->protocol == SSH_PROTO_UNKNOWN)
129 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
130 if (options->num_host_key_files == 0) {
131 /* fill default hostkeys for protocols */
132 if (options->protocol & SSH_PROTO_1)
133 options->host_key_files[options->num_host_key_files++] =
135 if (options->protocol & SSH_PROTO_2) {
136 options->host_key_files[options->num_host_key_files++] =
137 _PATH_HOST_RSA_KEY_FILE;
138 options->host_key_files[options->num_host_key_files++] =
139 _PATH_HOST_DSA_KEY_FILE;
142 if (options->num_ports == 0)
143 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
144 if (options->listen_addrs == NULL)
145 add_listen_addr(options, NULL, 0);
146 if (options->pid_file == NULL)
147 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
148 if (options->server_key_bits == -1)
149 options->server_key_bits = 768;
150 if (options->login_grace_time == -1)
151 options->login_grace_time = 600;
152 if (options->key_regeneration_time == -1)
153 options->key_regeneration_time = 3600;
154 if (options->permit_root_login == PERMIT_NOT_SET)
155 options->permit_root_login = PERMIT_YES;
156 if (options->ignore_rhosts == -1)
157 options->ignore_rhosts = 1;
158 if (options->ignore_user_known_hosts == -1)
159 options->ignore_user_known_hosts = 0;
160 if (options->print_motd == -1)
161 options->print_motd = 1;
162 if (options->print_lastlog == -1)
163 options->print_lastlog = 1;
164 if (options->x11_forwarding == -1)
165 options->x11_forwarding = 0;
166 if (options->x11_display_offset == -1)
167 options->x11_display_offset = 10;
168 if (options->x11_use_localhost == -1)
169 options->x11_use_localhost = 1;
170 if (options->xauth_location == NULL)
171 options->xauth_location = _PATH_XAUTH;
172 if (options->strict_modes == -1)
173 options->strict_modes = 1;
174 if (options->keepalives == -1)
175 options->keepalives = 1;
176 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
177 options->log_facility = SYSLOG_FACILITY_AUTH;
178 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
179 options->log_level = SYSLOG_LEVEL_INFO;
180 if (options->rhosts_authentication == -1)
181 options->rhosts_authentication = 0;
182 if (options->rhosts_rsa_authentication == -1)
183 options->rhosts_rsa_authentication = 0;
184 if (options->hostbased_authentication == -1)
185 options->hostbased_authentication = 0;
186 if (options->hostbased_uses_name_from_packet_only == -1)
187 options->hostbased_uses_name_from_packet_only = 0;
188 if (options->rsa_authentication == -1)
189 options->rsa_authentication = 1;
190 if (options->pubkey_authentication == -1)
191 options->pubkey_authentication = 1;
192 #if defined(KRB4) || defined(KRB5)
193 if (options->kerberos_authentication == -1)
194 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
195 if (options->kerberos_or_local_passwd == -1)
196 options->kerberos_or_local_passwd = 1;
197 if (options->kerberos_ticket_cleanup == -1)
198 options->kerberos_ticket_cleanup = 1;
200 #if defined(AFS) || defined(KRB5)
201 if (options->kerberos_tgt_passing == -1)
202 options->kerberos_tgt_passing = 0;
205 if (options->afs_token_passing == -1)
206 options->afs_token_passing = k_hasafs();
208 if (options->password_authentication == -1)
209 options->password_authentication = 1;
210 if (options->kbd_interactive_authentication == -1)
211 options->kbd_interactive_authentication = 0;
212 if (options->challenge_response_authentication == -1)
213 options->challenge_response_authentication = 1;
214 if (options->permit_empty_passwd == -1)
215 options->permit_empty_passwd = 0;
216 if (options->use_login == -1)
217 options->use_login = 0;
218 if (options->allow_tcp_forwarding == -1)
219 options->allow_tcp_forwarding = 1;
220 if (options->gateway_ports == -1)
221 options->gateway_ports = 0;
222 if (options->max_startups == -1)
223 options->max_startups = 10;
224 if (options->max_startups_rate == -1)
225 options->max_startups_rate = 100; /* 100% */
226 if (options->max_startups_begin == -1)
227 options->max_startups_begin = options->max_startups;
228 if (options->verify_reverse_mapping == -1)
229 options->verify_reverse_mapping = 0;
230 if (options->client_alive_interval == -1)
231 options->client_alive_interval = 0;
232 if (options->client_alive_count_max == -1)
233 options->client_alive_count_max = 3;
234 if (options->authorized_keys_file2 == NULL) {
235 /* authorized_keys_file2 falls back to authorized_keys_file */
236 if (options->authorized_keys_file != NULL)
237 options->authorized_keys_file2 = options->authorized_keys_file;
239 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
241 if (options->authorized_keys_file == NULL)
242 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
244 /* Turn privilege separation on by default */
245 if (use_privsep == -1)
249 /* Keyword tokens. */
251 sBadOption, /* == unknown option */
252 /* Portable-specific options */
253 sPAMAuthenticationViaKbdInt,
254 /* Standard Options */
255 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
256 sPermitRootLogin, sLogFacility, sLogLevel,
257 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
258 #if defined(KRB4) || defined(KRB5)
259 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
261 #if defined(AFS) || defined(KRB5)
267 sChallengeResponseAuthentication,
268 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
269 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
270 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
271 sStrictModes, sEmptyPasswd, sKeepAlives,
272 sUseLogin, sAllowTcpForwarding,
273 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
274 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
275 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
276 sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
277 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
278 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
279 sUsePrivilegeSeparation,
283 /* Textual representation of the tokens. */
286 ServerOpCodes opcode;
288 /* Portable-specific options */
289 { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt },
290 /* Standard Options */
292 { "hostkey", sHostKeyFile },
293 { "hostdsakey", sHostKeyFile }, /* alias */
294 { "pidfile", sPidFile },
295 { "serverkeybits", sServerKeyBits },
296 { "logingracetime", sLoginGraceTime },
297 { "keyregenerationinterval", sKeyRegenerationTime },
298 { "permitrootlogin", sPermitRootLogin },
299 { "syslogfacility", sLogFacility },
300 { "loglevel", sLogLevel },
301 { "rhostsauthentication", sRhostsAuthentication },
302 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
303 { "hostbasedauthentication", sHostbasedAuthentication },
304 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
305 { "rsaauthentication", sRSAAuthentication },
306 { "pubkeyauthentication", sPubkeyAuthentication },
307 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
308 #if defined(KRB4) || defined(KRB5)
309 { "kerberosauthentication", sKerberosAuthentication },
310 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
311 { "kerberosticketcleanup", sKerberosTicketCleanup },
313 #if defined(AFS) || defined(KRB5)
314 { "kerberostgtpassing", sKerberosTgtPassing },
317 { "afstokenpassing", sAFSTokenPassing },
319 { "passwordauthentication", sPasswordAuthentication },
320 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
321 { "challengeresponseauthentication", sChallengeResponseAuthentication },
322 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
323 { "checkmail", sDeprecated },
324 { "listenaddress", sListenAddress },
325 { "printmotd", sPrintMotd },
326 { "printlastlog", sPrintLastLog },
327 { "ignorerhosts", sIgnoreRhosts },
328 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
329 { "x11forwarding", sX11Forwarding },
330 { "x11displayoffset", sX11DisplayOffset },
331 { "x11uselocalhost", sX11UseLocalhost },
332 { "xauthlocation", sXAuthLocation },
333 { "strictmodes", sStrictModes },
334 { "permitemptypasswords", sEmptyPasswd },
335 { "uselogin", sUseLogin },
336 { "keepalive", sKeepAlives },
337 { "allowtcpforwarding", sAllowTcpForwarding },
338 { "allowusers", sAllowUsers },
339 { "denyusers", sDenyUsers },
340 { "allowgroups", sAllowGroups },
341 { "denygroups", sDenyGroups },
342 { "ciphers", sCiphers },
344 { "protocol", sProtocol },
345 { "gatewayports", sGatewayPorts },
346 { "subsystem", sSubsystem },
347 { "maxstartups", sMaxStartups },
348 { "banner", sBanner },
349 { "verifyreversemapping", sVerifyReverseMapping },
350 { "reversemappingcheck", sVerifyReverseMapping },
351 { "clientaliveinterval", sClientAliveInterval },
352 { "clientalivecountmax", sClientAliveCountMax },
353 { "authorizedkeysfile", sAuthorizedKeysFile },
354 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
355 { "useprivilegeseparation", sUsePrivilegeSeparation},
360 * Returns the number of the token pointed to by cp or sBadOption.
364 parse_token(const char *cp, const char *filename,
369 for (i = 0; keywords[i].name; i++)
370 if (strcasecmp(cp, keywords[i].name) == 0)
371 return keywords[i].opcode;
373 error("%s: line %d: Bad configuration option: %s",
374 filename, linenum, cp);
379 add_listen_addr(ServerOptions *options, char *addr, u_short port)
383 if (options->num_ports == 0)
384 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
386 for (i = 0; i < options->num_ports; i++)
387 add_one_listen_addr(options, addr, options->ports[i]);
389 add_one_listen_addr(options, addr, port);
393 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
395 struct addrinfo hints, *ai, *aitop;
396 char strport[NI_MAXSERV];
399 memset(&hints, 0, sizeof(hints));
400 hints.ai_family = IPv4or6;
401 hints.ai_socktype = SOCK_STREAM;
402 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
403 snprintf(strport, sizeof strport, "%d", port);
404 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
405 fatal("bad addr or host: %s (%s)",
406 addr ? addr : "<NULL>",
407 gai_strerror(gaierr));
408 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
410 ai->ai_next = options->listen_addrs;
411 options->listen_addrs = aitop;
415 process_server_config_line(ServerOptions *options, char *line,
416 const char *filename, int linenum)
418 char *cp, **charptr, *arg, *p;
420 ServerOpCodes opcode;
425 /* Ignore leading whitespace */
428 if (!arg || !*arg || *arg == '#')
432 opcode = parse_token(arg, filename, linenum);
434 /* Portable-specific options */
435 case sPAMAuthenticationViaKbdInt:
436 intptr = &options->pam_authentication_via_kbd_int;
439 /* Standard Options */
443 /* ignore ports from configfile if cmdline specifies ports */
444 if (options->ports_from_cmdline)
446 if (options->listen_addrs != NULL)
447 fatal("%s line %d: ports must be specified before "
448 "ListenAddress.", filename, linenum);
449 if (options->num_ports >= MAX_PORTS)
450 fatal("%s line %d: too many ports.",
453 if (!arg || *arg == '\0')
454 fatal("%s line %d: missing port number.",
456 options->ports[options->num_ports++] = a2port(arg);
457 if (options->ports[options->num_ports-1] == 0)
458 fatal("%s line %d: Badly formatted port number.",
463 intptr = &options->server_key_bits;
466 if (!arg || *arg == '\0')
467 fatal("%s line %d: missing integer value.",
474 case sLoginGraceTime:
475 intptr = &options->login_grace_time;
478 if (!arg || *arg == '\0')
479 fatal("%s line %d: missing time value.",
481 if ((value = convtime(arg)) == -1)
482 fatal("%s line %d: invalid time value.",
488 case sKeyRegenerationTime:
489 intptr = &options->key_regeneration_time;
494 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
495 fatal("%s line %d: missing inet addr.",
498 if ((p = strchr(arg, ']')) == NULL)
499 fatal("%s line %d: bad ipv6 inet addr usage.",
502 memmove(p, p+1, strlen(p+1)+1);
503 } else if (((p = strchr(arg, ':')) == NULL) ||
504 (strchr(p+1, ':') != NULL)) {
505 add_listen_addr(options, arg, 0);
513 fatal("%s line %d: bad inet addr:port usage.",
517 if ((port = a2port(p)) == 0)
518 fatal("%s line %d: bad port number.",
520 add_listen_addr(options, arg, port);
522 } else if (*p == '\0')
523 add_listen_addr(options, arg, 0);
525 fatal("%s line %d: bad inet addr usage.",
530 intptr = &options->num_host_key_files;
531 if (*intptr >= MAX_HOSTKEYS)
532 fatal("%s line %d: too many host keys specified (max %d).",
533 filename, linenum, MAX_HOSTKEYS);
534 charptr = &options->host_key_files[*intptr];
537 if (!arg || *arg == '\0')
538 fatal("%s line %d: missing file name.",
540 if (*charptr == NULL) {
541 *charptr = tilde_expand_filename(arg, getuid());
542 /* increase optional counter */
544 *intptr = *intptr + 1;
549 charptr = &options->pid_file;
552 case sPermitRootLogin:
553 intptr = &options->permit_root_login;
555 if (!arg || *arg == '\0')
556 fatal("%s line %d: missing yes/"
557 "without-password/forced-commands-only/no "
558 "argument.", filename, linenum);
559 value = 0; /* silence compiler */
560 if (strcmp(arg, "without-password") == 0)
561 value = PERMIT_NO_PASSWD;
562 else if (strcmp(arg, "forced-commands-only") == 0)
563 value = PERMIT_FORCED_ONLY;
564 else if (strcmp(arg, "yes") == 0)
566 else if (strcmp(arg, "no") == 0)
569 fatal("%s line %d: Bad yes/"
570 "without-password/forced-commands-only/no "
571 "argument: %s", filename, linenum, arg);
577 intptr = &options->ignore_rhosts;
580 if (!arg || *arg == '\0')
581 fatal("%s line %d: missing yes/no argument.",
583 value = 0; /* silence compiler */
584 if (strcmp(arg, "yes") == 0)
586 else if (strcmp(arg, "no") == 0)
589 fatal("%s line %d: Bad yes/no argument: %s",
590 filename, linenum, arg);
595 case sIgnoreUserKnownHosts:
596 intptr = &options->ignore_user_known_hosts;
599 case sRhostsAuthentication:
600 intptr = &options->rhosts_authentication;
603 case sRhostsRSAAuthentication:
604 intptr = &options->rhosts_rsa_authentication;
607 case sHostbasedAuthentication:
608 intptr = &options->hostbased_authentication;
611 case sHostbasedUsesNameFromPacketOnly:
612 intptr = &options->hostbased_uses_name_from_packet_only;
615 case sRSAAuthentication:
616 intptr = &options->rsa_authentication;
619 case sPubkeyAuthentication:
620 intptr = &options->pubkey_authentication;
622 #if defined(KRB4) || defined(KRB5)
623 case sKerberosAuthentication:
624 intptr = &options->kerberos_authentication;
627 case sKerberosOrLocalPasswd:
628 intptr = &options->kerberos_or_local_passwd;
631 case sKerberosTicketCleanup:
632 intptr = &options->kerberos_ticket_cleanup;
635 #if defined(AFS) || defined(KRB5)
636 case sKerberosTgtPassing:
637 intptr = &options->kerberos_tgt_passing;
641 case sAFSTokenPassing:
642 intptr = &options->afs_token_passing;
646 case sPasswordAuthentication:
647 intptr = &options->password_authentication;
650 case sKbdInteractiveAuthentication:
651 intptr = &options->kbd_interactive_authentication;
654 case sChallengeResponseAuthentication:
655 intptr = &options->challenge_response_authentication;
659 intptr = &options->print_motd;
663 intptr = &options->print_lastlog;
667 intptr = &options->x11_forwarding;
670 case sX11DisplayOffset:
671 intptr = &options->x11_display_offset;
674 case sX11UseLocalhost:
675 intptr = &options->x11_use_localhost;
679 charptr = &options->xauth_location;
683 intptr = &options->strict_modes;
687 intptr = &options->keepalives;
691 intptr = &options->permit_empty_passwd;
695 intptr = &options->use_login;
699 intptr = &options->gateway_ports;
702 case sVerifyReverseMapping:
703 intptr = &options->verify_reverse_mapping;
707 intptr = (int *) &options->log_facility;
709 value = log_facility_number(arg);
710 if (value == SYSLOG_FACILITY_NOT_SET)
711 fatal("%.200s line %d: unsupported log facility '%s'",
712 filename, linenum, arg ? arg : "<NONE>");
714 *intptr = (SyslogFacility) value;
718 intptr = (int *) &options->log_level;
720 value = log_level_number(arg);
721 if (value == SYSLOG_LEVEL_NOT_SET)
722 fatal("%.200s line %d: unsupported log level '%s'",
723 filename, linenum, arg ? arg : "<NONE>");
725 *intptr = (LogLevel) value;
728 case sAllowTcpForwarding:
729 intptr = &options->allow_tcp_forwarding;
732 case sUsePrivilegeSeparation:
733 intptr = &use_privsep;
737 while ((arg = strdelim(&cp)) && *arg != '\0') {
738 if (options->num_allow_users >= MAX_ALLOW_USERS)
739 fatal("%s line %d: too many allow users.",
741 options->allow_users[options->num_allow_users++] = xstrdup(arg);
746 while ((arg = strdelim(&cp)) && *arg != '\0') {
747 if (options->num_deny_users >= MAX_DENY_USERS)
748 fatal( "%s line %d: too many deny users.",
750 options->deny_users[options->num_deny_users++] = xstrdup(arg);
755 while ((arg = strdelim(&cp)) && *arg != '\0') {
756 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
757 fatal("%s line %d: too many allow groups.",
759 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
764 while ((arg = strdelim(&cp)) && *arg != '\0') {
765 if (options->num_deny_groups >= MAX_DENY_GROUPS)
766 fatal("%s line %d: too many deny groups.",
768 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
774 if (!arg || *arg == '\0')
775 fatal("%s line %d: Missing argument.", filename, linenum);
776 if (!ciphers_valid(arg))
777 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
778 filename, linenum, arg ? arg : "<NONE>");
779 if (options->ciphers == NULL)
780 options->ciphers = xstrdup(arg);
785 if (!arg || *arg == '\0')
786 fatal("%s line %d: Missing argument.", filename, linenum);
788 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
789 filename, linenum, arg ? arg : "<NONE>");
790 if (options->macs == NULL)
791 options->macs = xstrdup(arg);
795 intptr = &options->protocol;
797 if (!arg || *arg == '\0')
798 fatal("%s line %d: Missing argument.", filename, linenum);
799 value = proto_spec(arg);
800 if (value == SSH_PROTO_UNKNOWN)
801 fatal("%s line %d: Bad protocol spec '%s'.",
802 filename, linenum, arg ? arg : "<NONE>");
803 if (*intptr == SSH_PROTO_UNKNOWN)
808 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
809 fatal("%s line %d: too many subsystems defined.",
813 if (!arg || *arg == '\0')
814 fatal("%s line %d: Missing subsystem name.",
816 for (i = 0; i < options->num_subsystems; i++)
817 if (strcmp(arg, options->subsystem_name[i]) == 0)
818 fatal("%s line %d: Subsystem '%s' already defined.",
819 filename, linenum, arg);
820 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
822 if (!arg || *arg == '\0')
823 fatal("%s line %d: Missing subsystem command.",
825 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
826 options->num_subsystems++;
831 if (!arg || *arg == '\0')
832 fatal("%s line %d: Missing MaxStartups spec.",
834 if ((n = sscanf(arg, "%d:%d:%d",
835 &options->max_startups_begin,
836 &options->max_startups_rate,
837 &options->max_startups)) == 3) {
838 if (options->max_startups_begin >
839 options->max_startups ||
840 options->max_startups_rate > 100 ||
841 options->max_startups_rate < 1)
842 fatal("%s line %d: Illegal MaxStartups spec.",
845 fatal("%s line %d: Illegal MaxStartups spec.",
848 options->max_startups = options->max_startups_begin;
852 charptr = &options->banner;
855 * These options can contain %X options expanded at
856 * connect time, so that you can specify paths like:
858 * AuthorizedKeysFile /etc/ssh_keys/%u
860 case sAuthorizedKeysFile:
861 case sAuthorizedKeysFile2:
862 charptr = (opcode == sAuthorizedKeysFile ) ?
863 &options->authorized_keys_file :
864 &options->authorized_keys_file2;
867 case sClientAliveInterval:
868 intptr = &options->client_alive_interval;
871 case sClientAliveCountMax:
872 intptr = &options->client_alive_count_max;
876 log("%s line %d: Deprecated option %s",
877 filename, linenum, arg);
883 fatal("%s line %d: Missing handler for opcode %s (%d)",
884 filename, linenum, arg, opcode);
886 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
887 fatal("%s line %d: garbage at end of line; \"%.200s\".",
888 filename, linenum, arg);
892 /* Reads the server configuration file. */
895 read_server_config(ServerOptions *options, const char *filename)
902 f = fopen(filename, "r");
908 while (fgets(line, sizeof(line), f)) {
909 /* Update line number counter. */
911 if (process_server_config_line(options, line, filename, linenum) != 0)
916 fatal("%s: terminating, %d bad configuration options",
917 filename, bad_options);