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.127 2003/09/01 18:15:50 markus Exp $");
20 #include "pathnames.h"
21 #include "tildexpand.h"
27 static void add_listen_addr(ServerOptions *, char *, u_short);
28 static void add_one_listen_addr(ServerOptions *, char *, u_short);
30 /* AF_UNSPEC or AF_INET or AF_INET6 */
32 /* Use of privilege separation or not */
33 extern int use_privsep;
35 /* Initializes the server options to their default values. */
38 initialize_server_options(ServerOptions *options)
40 memset(options, 0, sizeof(*options));
42 /* Portable-specific options */
43 options->use_pam = -1;
45 /* Standard Options */
46 options->num_ports = 0;
47 options->ports_from_cmdline = 0;
48 options->listen_addrs = NULL;
49 options->num_host_key_files = 0;
50 options->pid_file = NULL;
51 options->server_key_bits = -1;
52 options->login_grace_time = -1;
53 options->key_regeneration_time = -1;
54 options->permit_root_login = PERMIT_NOT_SET;
55 options->ignore_rhosts = -1;
56 options->ignore_user_known_hosts = -1;
57 options->print_motd = -1;
58 options->print_lastlog = -1;
59 options->x11_forwarding = -1;
60 options->x11_display_offset = -1;
61 options->x11_use_localhost = -1;
62 options->xauth_location = NULL;
63 options->strict_modes = -1;
64 options->keepalives = -1;
65 options->log_facility = SYSLOG_FACILITY_NOT_SET;
66 options->log_level = SYSLOG_LEVEL_NOT_SET;
67 options->rhosts_rsa_authentication = -1;
68 options->hostbased_authentication = -1;
69 options->hostbased_uses_name_from_packet_only = -1;
70 options->rsa_authentication = -1;
71 options->pubkey_authentication = -1;
72 options->kerberos_authentication = -1;
73 options->kerberos_or_local_passwd = -1;
74 options->kerberos_ticket_cleanup = -1;
75 options->gss_authentication=-1;
76 options->gss_cleanup_creds = -1;
77 options->password_authentication = -1;
78 options->kbd_interactive_authentication = -1;
79 options->challenge_response_authentication = -1;
80 options->permit_empty_passwd = -1;
81 options->permit_user_env = -1;
82 options->use_login = -1;
83 options->compression = -1;
84 options->allow_tcp_forwarding = -1;
85 options->num_allow_users = 0;
86 options->num_deny_users = 0;
87 options->num_allow_groups = 0;
88 options->num_deny_groups = 0;
89 options->ciphers = NULL;
91 options->protocol = SSH_PROTO_UNKNOWN;
92 options->gateway_ports = -1;
93 options->num_subsystems = 0;
94 options->max_startups_begin = -1;
95 options->max_startups_rate = -1;
96 options->max_startups = -1;
97 options->banner = NULL;
98 options->use_dns = -1;
99 options->client_alive_interval = -1;
100 options->client_alive_count_max = -1;
101 options->authorized_keys_file = NULL;
102 options->authorized_keys_file2 = NULL;
104 /* Needs to be accessable in many places */
109 fill_default_server_options(ServerOptions *options)
111 /* Portable-specific options */
112 if (options->use_pam == -1)
113 options->use_pam = 0;
115 /* Standard Options */
116 if (options->protocol == SSH_PROTO_UNKNOWN)
117 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
118 if (options->num_host_key_files == 0) {
119 /* fill default hostkeys for protocols */
120 if (options->protocol & SSH_PROTO_1)
121 options->host_key_files[options->num_host_key_files++] =
123 if (options->protocol & SSH_PROTO_2) {
124 options->host_key_files[options->num_host_key_files++] =
125 _PATH_HOST_RSA_KEY_FILE;
126 options->host_key_files[options->num_host_key_files++] =
127 _PATH_HOST_DSA_KEY_FILE;
130 if (options->num_ports == 0)
131 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
132 if (options->listen_addrs == NULL)
133 add_listen_addr(options, NULL, 0);
134 if (options->pid_file == NULL)
135 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
136 if (options->server_key_bits == -1)
137 options->server_key_bits = 768;
138 if (options->login_grace_time == -1)
139 options->login_grace_time = 120;
140 if (options->key_regeneration_time == -1)
141 options->key_regeneration_time = 3600;
142 if (options->permit_root_login == PERMIT_NOT_SET)
143 options->permit_root_login = PERMIT_YES;
144 if (options->ignore_rhosts == -1)
145 options->ignore_rhosts = 1;
146 if (options->ignore_user_known_hosts == -1)
147 options->ignore_user_known_hosts = 0;
148 if (options->print_motd == -1)
149 options->print_motd = 1;
150 if (options->print_lastlog == -1)
151 options->print_lastlog = 1;
152 if (options->x11_forwarding == -1)
153 options->x11_forwarding = 0;
154 if (options->x11_display_offset == -1)
155 options->x11_display_offset = 10;
156 if (options->x11_use_localhost == -1)
157 options->x11_use_localhost = 1;
158 if (options->xauth_location == NULL)
159 options->xauth_location = _PATH_XAUTH;
160 if (options->strict_modes == -1)
161 options->strict_modes = 1;
162 if (options->keepalives == -1)
163 options->keepalives = 1;
164 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
165 options->log_facility = SYSLOG_FACILITY_AUTH;
166 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
167 options->log_level = SYSLOG_LEVEL_INFO;
168 if (options->rhosts_rsa_authentication == -1)
169 options->rhosts_rsa_authentication = 0;
170 if (options->hostbased_authentication == -1)
171 options->hostbased_authentication = 0;
172 if (options->hostbased_uses_name_from_packet_only == -1)
173 options->hostbased_uses_name_from_packet_only = 0;
174 if (options->rsa_authentication == -1)
175 options->rsa_authentication = 1;
176 if (options->pubkey_authentication == -1)
177 options->pubkey_authentication = 1;
178 if (options->kerberos_authentication == -1)
179 options->kerberos_authentication = 0;
180 if (options->kerberos_or_local_passwd == -1)
181 options->kerberos_or_local_passwd = 1;
182 if (options->kerberos_ticket_cleanup == -1)
183 options->kerberos_ticket_cleanup = 1;
184 if (options->gss_authentication == -1)
185 options->gss_authentication = 0;
186 if (options->gss_cleanup_creds == -1)
187 options->gss_cleanup_creds = 1;
188 if (options->password_authentication == -1)
189 options->password_authentication = 1;
190 if (options->kbd_interactive_authentication == -1)
191 options->kbd_interactive_authentication = 0;
192 if (options->challenge_response_authentication == -1)
193 options->challenge_response_authentication = 1;
194 if (options->permit_empty_passwd == -1)
195 options->permit_empty_passwd = 0;
196 if (options->permit_user_env == -1)
197 options->permit_user_env = 0;
198 if (options->use_login == -1)
199 options->use_login = 0;
200 if (options->compression == -1)
201 options->compression = 1;
202 if (options->allow_tcp_forwarding == -1)
203 options->allow_tcp_forwarding = 1;
204 if (options->gateway_ports == -1)
205 options->gateway_ports = 0;
206 if (options->max_startups == -1)
207 options->max_startups = 10;
208 if (options->max_startups_rate == -1)
209 options->max_startups_rate = 100; /* 100% */
210 if (options->max_startups_begin == -1)
211 options->max_startups_begin = options->max_startups;
212 if (options->use_dns == -1)
213 options->use_dns = 1;
214 if (options->client_alive_interval == -1)
215 options->client_alive_interval = 0;
216 if (options->client_alive_count_max == -1)
217 options->client_alive_count_max = 3;
218 if (options->authorized_keys_file2 == NULL) {
219 /* authorized_keys_file2 falls back to authorized_keys_file */
220 if (options->authorized_keys_file != NULL)
221 options->authorized_keys_file2 = options->authorized_keys_file;
223 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
225 if (options->authorized_keys_file == NULL)
226 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
228 /* Turn privilege separation on by default */
229 if (use_privsep == -1)
233 if (use_privsep && options->compression == 1) {
234 error("This platform does not support both privilege "
235 "separation and compression");
236 error("Compression disabled");
237 options->compression = 0;
243 /* Keyword tokens. */
245 sBadOption, /* == unknown option */
246 /* Portable-specific options */
248 /* Standard Options */
249 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
250 sPermitRootLogin, sLogFacility, sLogLevel,
251 sRhostsRSAAuthentication, sRSAAuthentication,
252 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
253 sKerberosTgtPassing, sChallengeResponseAuthentication,
254 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
255 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
256 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
257 sStrictModes, sEmptyPasswd, sKeepAlives,
258 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
259 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
260 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
261 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
262 sBanner, sUseDNS, sHostbasedAuthentication,
263 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
264 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
265 sGssAuthentication, sGssCleanupCreds,
266 sUsePrivilegeSeparation,
267 sDeprecated, sUnsupported
270 /* Textual representation of the tokens. */
273 ServerOpCodes opcode;
275 /* Portable-specific options */
277 { "usepam", sUsePAM },
279 { "usepam", sUnsupported },
281 { "pamauthenticationviakbdint", sDeprecated },
282 /* Standard Options */
284 { "hostkey", sHostKeyFile },
285 { "hostdsakey", sHostKeyFile }, /* alias */
286 { "pidfile", sPidFile },
287 { "serverkeybits", sServerKeyBits },
288 { "logingracetime", sLoginGraceTime },
289 { "keyregenerationinterval", sKeyRegenerationTime },
290 { "permitrootlogin", sPermitRootLogin },
291 { "syslogfacility", sLogFacility },
292 { "loglevel", sLogLevel },
293 { "rhostsauthentication", sDeprecated },
294 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
295 { "hostbasedauthentication", sHostbasedAuthentication },
296 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
297 { "rsaauthentication", sRSAAuthentication },
298 { "pubkeyauthentication", sPubkeyAuthentication },
299 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
301 { "kerberosauthentication", sKerberosAuthentication },
302 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
303 { "kerberosticketcleanup", sKerberosTicketCleanup },
305 { "kerberosauthentication", sUnsupported },
306 { "kerberosorlocalpasswd", sUnsupported },
307 { "kerberosticketcleanup", sUnsupported },
309 { "kerberostgtpassing", sUnsupported },
310 { "afstokenpassing", sUnsupported },
312 { "gssapiauthentication", sGssAuthentication },
313 { "gssapicleanupcreds", sGssCleanupCreds },
315 { "gssapiauthentication", sUnsupported },
316 { "gssapicleanupcreds", sUnsupported },
318 { "passwordauthentication", sPasswordAuthentication },
319 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
320 { "challengeresponseauthentication", sChallengeResponseAuthentication },
321 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
322 { "checkmail", sDeprecated },
323 { "listenaddress", sListenAddress },
324 { "printmotd", sPrintMotd },
325 { "printlastlog", sPrintLastLog },
326 { "ignorerhosts", sIgnoreRhosts },
327 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
328 { "x11forwarding", sX11Forwarding },
329 { "x11displayoffset", sX11DisplayOffset },
330 { "x11uselocalhost", sX11UseLocalhost },
331 { "xauthlocation", sXAuthLocation },
332 { "strictmodes", sStrictModes },
333 { "permitemptypasswords", sEmptyPasswd },
334 { "permituserenvironment", sPermitUserEnvironment },
335 { "uselogin", sUseLogin },
336 { "compression", sCompression },
337 { "keepalive", sKeepAlives },
338 { "allowtcpforwarding", sAllowTcpForwarding },
339 { "allowusers", sAllowUsers },
340 { "denyusers", sDenyUsers },
341 { "allowgroups", sAllowGroups },
342 { "denygroups", sDenyGroups },
343 { "ciphers", sCiphers },
345 { "protocol", sProtocol },
346 { "gatewayports", sGatewayPorts },
347 { "subsystem", sSubsystem },
348 { "maxstartups", sMaxStartups },
349 { "banner", sBanner },
350 { "usedns", sUseDNS },
351 { "verifyreversemapping", sDeprecated },
352 { "reversemappingcheck", sDeprecated },
353 { "clientaliveinterval", sClientAliveInterval },
354 { "clientalivecountmax", sClientAliveCountMax },
355 { "authorizedkeysfile", sAuthorizedKeysFile },
356 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
357 { "useprivilegeseparation", sUsePrivilegeSeparation},
362 * Returns the number of the token pointed to by cp or sBadOption.
366 parse_token(const char *cp, const char *filename,
371 for (i = 0; keywords[i].name; i++)
372 if (strcasecmp(cp, keywords[i].name) == 0)
373 return keywords[i].opcode;
375 error("%s: line %d: Bad configuration option: %s",
376 filename, linenum, cp);
381 add_listen_addr(ServerOptions *options, char *addr, u_short port)
385 if (options->num_ports == 0)
386 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
388 for (i = 0; i < options->num_ports; i++)
389 add_one_listen_addr(options, addr, options->ports[i]);
391 add_one_listen_addr(options, addr, port);
395 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
397 struct addrinfo hints, *ai, *aitop;
398 char strport[NI_MAXSERV];
401 memset(&hints, 0, sizeof(hints));
402 hints.ai_family = IPv4or6;
403 hints.ai_socktype = SOCK_STREAM;
404 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
405 snprintf(strport, sizeof strport, "%u", port);
406 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
407 fatal("bad addr or host: %s (%s)",
408 addr ? addr : "<NULL>",
409 gai_strerror(gaierr));
410 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
412 ai->ai_next = options->listen_addrs;
413 options->listen_addrs = aitop;
417 process_server_config_line(ServerOptions *options, char *line,
418 const char *filename, int linenum)
420 char *cp, **charptr, *arg, *p;
421 int *intptr, value, i, n;
422 ServerOpCodes opcode;
426 /* Ignore leading whitespace */
429 if (!arg || !*arg || *arg == '#')
433 opcode = parse_token(arg, filename, linenum);
435 /* Portable-specific options */
437 intptr = &options->use_pam;
440 /* Standard Options */
444 /* ignore ports from configfile if cmdline specifies ports */
445 if (options->ports_from_cmdline)
447 if (options->listen_addrs != NULL)
448 fatal("%s line %d: ports must be specified before "
449 "ListenAddress.", filename, linenum);
450 if (options->num_ports >= MAX_PORTS)
451 fatal("%s line %d: too many ports.",
454 if (!arg || *arg == '\0')
455 fatal("%s line %d: missing port number.",
457 options->ports[options->num_ports++] = a2port(arg);
458 if (options->ports[options->num_ports-1] == 0)
459 fatal("%s line %d: Badly formatted port number.",
464 intptr = &options->server_key_bits;
467 if (!arg || *arg == '\0')
468 fatal("%s line %d: missing integer value.",
475 case sLoginGraceTime:
476 intptr = &options->login_grace_time;
479 if (!arg || *arg == '\0')
480 fatal("%s line %d: missing time value.",
482 if ((value = convtime(arg)) == -1)
483 fatal("%s line %d: invalid time value.",
489 case sKeyRegenerationTime:
490 intptr = &options->key_regeneration_time;
495 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
496 fatal("%s line %d: missing inet addr.",
499 if ((p = strchr(arg, ']')) == NULL)
500 fatal("%s line %d: bad ipv6 inet addr usage.",
503 memmove(p, p+1, strlen(p+1)+1);
504 } else if (((p = strchr(arg, ':')) == NULL) ||
505 (strchr(p+1, ':') != NULL)) {
506 add_listen_addr(options, arg, 0);
514 fatal("%s line %d: bad inet addr:port usage.",
518 if ((port = a2port(p)) == 0)
519 fatal("%s line %d: bad port number.",
521 add_listen_addr(options, arg, port);
523 } else if (*p == '\0')
524 add_listen_addr(options, arg, 0);
526 fatal("%s line %d: bad inet addr usage.",
531 intptr = &options->num_host_key_files;
532 if (*intptr >= MAX_HOSTKEYS)
533 fatal("%s line %d: too many host keys specified (max %d).",
534 filename, linenum, MAX_HOSTKEYS);
535 charptr = &options->host_key_files[*intptr];
538 if (!arg || *arg == '\0')
539 fatal("%s line %d: missing file name.",
541 if (*charptr == NULL) {
542 *charptr = tilde_expand_filename(arg, getuid());
543 /* increase optional counter */
545 *intptr = *intptr + 1;
550 charptr = &options->pid_file;
553 case sPermitRootLogin:
554 intptr = &options->permit_root_login;
556 if (!arg || *arg == '\0')
557 fatal("%s line %d: missing yes/"
558 "without-password/forced-commands-only/no "
559 "argument.", filename, linenum);
560 value = 0; /* silence compiler */
561 if (strcmp(arg, "without-password") == 0)
562 value = PERMIT_NO_PASSWD;
563 else if (strcmp(arg, "forced-commands-only") == 0)
564 value = PERMIT_FORCED_ONLY;
565 else if (strcmp(arg, "yes") == 0)
567 else if (strcmp(arg, "no") == 0)
570 fatal("%s line %d: Bad yes/"
571 "without-password/forced-commands-only/no "
572 "argument: %s", filename, linenum, arg);
578 intptr = &options->ignore_rhosts;
581 if (!arg || *arg == '\0')
582 fatal("%s line %d: missing yes/no argument.",
584 value = 0; /* silence compiler */
585 if (strcmp(arg, "yes") == 0)
587 else if (strcmp(arg, "no") == 0)
590 fatal("%s line %d: Bad yes/no argument: %s",
591 filename, linenum, arg);
596 case sIgnoreUserKnownHosts:
597 intptr = &options->ignore_user_known_hosts;
600 case sRhostsRSAAuthentication:
601 intptr = &options->rhosts_rsa_authentication;
604 case sHostbasedAuthentication:
605 intptr = &options->hostbased_authentication;
608 case sHostbasedUsesNameFromPacketOnly:
609 intptr = &options->hostbased_uses_name_from_packet_only;
612 case sRSAAuthentication:
613 intptr = &options->rsa_authentication;
616 case sPubkeyAuthentication:
617 intptr = &options->pubkey_authentication;
620 case sKerberosAuthentication:
621 intptr = &options->kerberos_authentication;
624 case sKerberosOrLocalPasswd:
625 intptr = &options->kerberos_or_local_passwd;
628 case sKerberosTicketCleanup:
629 intptr = &options->kerberos_ticket_cleanup;
632 case sGssAuthentication:
633 intptr = &options->gss_authentication;
636 case sGssCleanupCreds:
637 intptr = &options->gss_cleanup_creds;
640 case sPasswordAuthentication:
641 intptr = &options->password_authentication;
644 case sKbdInteractiveAuthentication:
645 intptr = &options->kbd_interactive_authentication;
648 case sChallengeResponseAuthentication:
649 intptr = &options->challenge_response_authentication;
653 intptr = &options->print_motd;
657 intptr = &options->print_lastlog;
661 intptr = &options->x11_forwarding;
664 case sX11DisplayOffset:
665 intptr = &options->x11_display_offset;
668 case sX11UseLocalhost:
669 intptr = &options->x11_use_localhost;
673 charptr = &options->xauth_location;
677 intptr = &options->strict_modes;
681 intptr = &options->keepalives;
685 intptr = &options->permit_empty_passwd;
688 case sPermitUserEnvironment:
689 intptr = &options->permit_user_env;
693 intptr = &options->use_login;
697 intptr = &options->compression;
701 intptr = &options->gateway_ports;
705 intptr = &options->use_dns;
709 intptr = (int *) &options->log_facility;
711 value = log_facility_number(arg);
712 if (value == SYSLOG_FACILITY_NOT_SET)
713 fatal("%.200s line %d: unsupported log facility '%s'",
714 filename, linenum, arg ? arg : "<NONE>");
716 *intptr = (SyslogFacility) value;
720 intptr = (int *) &options->log_level;
722 value = log_level_number(arg);
723 if (value == SYSLOG_LEVEL_NOT_SET)
724 fatal("%.200s line %d: unsupported log level '%s'",
725 filename, linenum, arg ? arg : "<NONE>");
727 *intptr = (LogLevel) value;
730 case sAllowTcpForwarding:
731 intptr = &options->allow_tcp_forwarding;
734 case sUsePrivilegeSeparation:
735 intptr = &use_privsep;
739 while ((arg = strdelim(&cp)) && *arg != '\0') {
740 if (options->num_allow_users >= MAX_ALLOW_USERS)
741 fatal("%s line %d: too many allow users.",
743 options->allow_users[options->num_allow_users++] =
749 while ((arg = strdelim(&cp)) && *arg != '\0') {
750 if (options->num_deny_users >= MAX_DENY_USERS)
751 fatal( "%s line %d: too many deny users.",
753 options->deny_users[options->num_deny_users++] =
759 while ((arg = strdelim(&cp)) && *arg != '\0') {
760 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
761 fatal("%s line %d: too many allow groups.",
763 options->allow_groups[options->num_allow_groups++] =
769 while ((arg = strdelim(&cp)) && *arg != '\0') {
770 if (options->num_deny_groups >= MAX_DENY_GROUPS)
771 fatal("%s line %d: too many deny groups.",
773 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
779 if (!arg || *arg == '\0')
780 fatal("%s line %d: Missing argument.", filename, linenum);
781 if (!ciphers_valid(arg))
782 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
783 filename, linenum, arg ? arg : "<NONE>");
784 if (options->ciphers == NULL)
785 options->ciphers = xstrdup(arg);
790 if (!arg || *arg == '\0')
791 fatal("%s line %d: Missing argument.", filename, linenum);
793 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
794 filename, linenum, arg ? arg : "<NONE>");
795 if (options->macs == NULL)
796 options->macs = xstrdup(arg);
800 intptr = &options->protocol;
802 if (!arg || *arg == '\0')
803 fatal("%s line %d: Missing argument.", filename, linenum);
804 value = proto_spec(arg);
805 if (value == SSH_PROTO_UNKNOWN)
806 fatal("%s line %d: Bad protocol spec '%s'.",
807 filename, linenum, arg ? arg : "<NONE>");
808 if (*intptr == SSH_PROTO_UNKNOWN)
813 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
814 fatal("%s line %d: too many subsystems defined.",
818 if (!arg || *arg == '\0')
819 fatal("%s line %d: Missing subsystem name.",
821 for (i = 0; i < options->num_subsystems; i++)
822 if (strcmp(arg, options->subsystem_name[i]) == 0)
823 fatal("%s line %d: Subsystem '%s' already defined.",
824 filename, linenum, arg);
825 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
827 if (!arg || *arg == '\0')
828 fatal("%s line %d: Missing subsystem command.",
830 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
831 options->num_subsystems++;
836 if (!arg || *arg == '\0')
837 fatal("%s line %d: Missing MaxStartups spec.",
839 if ((n = sscanf(arg, "%d:%d:%d",
840 &options->max_startups_begin,
841 &options->max_startups_rate,
842 &options->max_startups)) == 3) {
843 if (options->max_startups_begin >
844 options->max_startups ||
845 options->max_startups_rate > 100 ||
846 options->max_startups_rate < 1)
847 fatal("%s line %d: Illegal MaxStartups spec.",
850 fatal("%s line %d: Illegal MaxStartups spec.",
853 options->max_startups = options->max_startups_begin;
857 charptr = &options->banner;
860 * These options can contain %X options expanded at
861 * connect time, so that you can specify paths like:
863 * AuthorizedKeysFile /etc/ssh_keys/%u
865 case sAuthorizedKeysFile:
866 case sAuthorizedKeysFile2:
867 charptr = (opcode == sAuthorizedKeysFile ) ?
868 &options->authorized_keys_file :
869 &options->authorized_keys_file2;
872 case sClientAliveInterval:
873 intptr = &options->client_alive_interval;
876 case sClientAliveCountMax:
877 intptr = &options->client_alive_count_max;
881 logit("%s line %d: Deprecated option %s",
882 filename, linenum, arg);
888 logit("%s line %d: Unsupported option %s",
889 filename, linenum, arg);
895 fatal("%s line %d: Missing handler for opcode %s (%d)",
896 filename, linenum, arg, opcode);
898 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
899 fatal("%s line %d: garbage at end of line; \"%.200s\".",
900 filename, linenum, arg);
904 /* Reads the server configuration file. */
907 read_server_config(ServerOptions *options, const char *filename)
909 int linenum, bad_options = 0;
913 debug2("read_server_config: filename %s", filename);
914 f = fopen(filename, "r");
920 while (fgets(line, sizeof(line), f)) {
921 /* Update line number counter. */
923 if (process_server_config_line(options, line, filename, linenum) != 0)
928 fatal("%s: terminating, %d bad configuration options",
929 filename, bad_options);