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.132 2004/05/08 00:01:37 deraadt Exp $");
20 #include "pathnames.h"
26 static void add_listen_addr(ServerOptions *, char *, u_short);
27 static void add_one_listen_addr(ServerOptions *, char *, u_short);
29 /* AF_UNSPEC or AF_INET or AF_INET6 */
31 /* Use of privilege separation or not */
32 extern int use_privsep;
34 /* Initializes the server options to their default values. */
37 initialize_server_options(ServerOptions *options)
39 memset(options, 0, sizeof(*options));
41 /* Portable-specific options */
42 options->use_pam = -1;
44 /* Standard Options */
45 options->num_ports = 0;
46 options->ports_from_cmdline = 0;
47 options->listen_addrs = NULL;
48 options->num_host_key_files = 0;
49 options->pid_file = NULL;
50 options->server_key_bits = -1;
51 options->login_grace_time = -1;
52 options->key_regeneration_time = -1;
53 options->permit_root_login = PERMIT_NOT_SET;
54 options->ignore_rhosts = -1;
55 options->ignore_user_known_hosts = -1;
56 options->print_motd = -1;
57 options->print_lastlog = -1;
58 options->x11_forwarding = -1;
59 options->x11_display_offset = -1;
60 options->x11_use_localhost = -1;
61 options->xauth_location = NULL;
62 options->strict_modes = -1;
63 options->tcp_keep_alive = -1;
64 options->log_facility = SYSLOG_FACILITY_NOT_SET;
65 options->log_level = SYSLOG_LEVEL_NOT_SET;
66 options->rhosts_rsa_authentication = -1;
67 options->hostbased_authentication = -1;
68 options->hostbased_uses_name_from_packet_only = -1;
69 options->rsa_authentication = -1;
70 options->pubkey_authentication = -1;
71 options->kerberos_authentication = -1;
72 options->kerberos_or_local_passwd = -1;
73 options->kerberos_ticket_cleanup = -1;
74 options->kerberos_get_afs_token = -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;
103 options->num_accept_env = 0;
105 /* Needs to be accessable in many places */
110 fill_default_server_options(ServerOptions *options)
112 /* Portable-specific options */
113 if (options->use_pam == -1)
114 options->use_pam = 0;
116 /* Standard Options */
117 if (options->protocol == SSH_PROTO_UNKNOWN)
118 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
119 if (options->num_host_key_files == 0) {
120 /* fill default hostkeys for protocols */
121 if (options->protocol & SSH_PROTO_1)
122 options->host_key_files[options->num_host_key_files++] =
124 if (options->protocol & SSH_PROTO_2) {
125 options->host_key_files[options->num_host_key_files++] =
126 _PATH_HOST_RSA_KEY_FILE;
127 options->host_key_files[options->num_host_key_files++] =
128 _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 = 120;
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->x11_use_localhost == -1)
158 options->x11_use_localhost = 1;
159 if (options->xauth_location == NULL)
160 options->xauth_location = _PATH_XAUTH;
161 if (options->strict_modes == -1)
162 options->strict_modes = 1;
163 if (options->tcp_keep_alive == -1)
164 options->tcp_keep_alive = 1;
165 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
166 options->log_facility = SYSLOG_FACILITY_AUTH;
167 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
168 options->log_level = SYSLOG_LEVEL_INFO;
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 (options->kerberos_authentication == -1)
180 options->kerberos_authentication = 0;
181 if (options->kerberos_or_local_passwd == -1)
182 options->kerberos_or_local_passwd = 1;
183 if (options->kerberos_ticket_cleanup == -1)
184 options->kerberos_ticket_cleanup = 1;
185 if (options->kerberos_get_afs_token == -1)
186 options->kerberos_get_afs_token = 0;
187 if (options->gss_authentication == -1)
188 options->gss_authentication = 0;
189 if (options->gss_cleanup_creds == -1)
190 options->gss_cleanup_creds = 1;
191 if (options->password_authentication == -1)
192 options->password_authentication = 1;
193 if (options->kbd_interactive_authentication == -1)
194 options->kbd_interactive_authentication = 0;
195 if (options->challenge_response_authentication == -1)
196 options->challenge_response_authentication = 1;
197 if (options->permit_empty_passwd == -1)
198 options->permit_empty_passwd = 0;
199 if (options->permit_user_env == -1)
200 options->permit_user_env = 0;
201 if (options->use_login == -1)
202 options->use_login = 0;
203 if (options->compression == -1)
204 options->compression = 1;
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->use_dns == -1)
216 options->use_dns = 1;
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;
231 /* Turn privilege separation on by default */
232 if (use_privsep == -1)
236 if (use_privsep && options->compression == 1) {
237 error("This platform does not support both privilege "
238 "separation and compression");
239 error("Compression disabled");
240 options->compression = 0;
246 /* Keyword tokens. */
248 sBadOption, /* == unknown option */
249 /* Portable-specific options */
251 /* Standard Options */
252 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
253 sPermitRootLogin, sLogFacility, sLogLevel,
254 sRhostsRSAAuthentication, sRSAAuthentication,
255 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
256 sKerberosGetAFSToken,
257 sKerberosTgtPassing, sChallengeResponseAuthentication,
258 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
259 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
260 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
261 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
262 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
263 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
264 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
265 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
266 sBanner, sUseDNS, sHostbasedAuthentication,
267 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
268 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
269 sGssAuthentication, sGssCleanupCreds, sAcceptEnv,
270 sUsePrivilegeSeparation,
271 sDeprecated, sUnsupported
274 /* Textual representation of the tokens. */
277 ServerOpCodes opcode;
279 /* Portable-specific options */
281 { "usepam", sUsePAM },
283 { "usepam", sUnsupported },
285 { "pamauthenticationviakbdint", sDeprecated },
286 /* Standard Options */
288 { "hostkey", sHostKeyFile },
289 { "hostdsakey", sHostKeyFile }, /* alias */
290 { "pidfile", sPidFile },
291 { "serverkeybits", sServerKeyBits },
292 { "logingracetime", sLoginGraceTime },
293 { "keyregenerationinterval", sKeyRegenerationTime },
294 { "permitrootlogin", sPermitRootLogin },
295 { "syslogfacility", sLogFacility },
296 { "loglevel", sLogLevel },
297 { "rhostsauthentication", sDeprecated },
298 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
299 { "hostbasedauthentication", sHostbasedAuthentication },
300 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
301 { "rsaauthentication", sRSAAuthentication },
302 { "pubkeyauthentication", sPubkeyAuthentication },
303 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
305 { "kerberosauthentication", sKerberosAuthentication },
306 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
307 { "kerberosticketcleanup", sKerberosTicketCleanup },
309 { "kerberosgetafstoken", sKerberosGetAFSToken },
311 { "kerberosgetafstoken", sUnsupported },
314 { "kerberosauthentication", sUnsupported },
315 { "kerberosorlocalpasswd", sUnsupported },
316 { "kerberosticketcleanup", sUnsupported },
317 { "kerberosgetafstoken", sUnsupported },
319 { "kerberostgtpassing", sUnsupported },
320 { "afstokenpassing", sUnsupported },
322 { "gssapiauthentication", sGssAuthentication },
323 { "gssapicleanupcredentials", sGssCleanupCreds },
325 { "gssapiauthentication", sUnsupported },
326 { "gssapicleanupcredentials", sUnsupported },
328 { "passwordauthentication", sPasswordAuthentication },
329 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
330 { "challengeresponseauthentication", sChallengeResponseAuthentication },
331 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
332 { "checkmail", sDeprecated },
333 { "listenaddress", sListenAddress },
334 { "printmotd", sPrintMotd },
335 { "printlastlog", sPrintLastLog },
336 { "ignorerhosts", sIgnoreRhosts },
337 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
338 { "x11forwarding", sX11Forwarding },
339 { "x11displayoffset", sX11DisplayOffset },
340 { "x11uselocalhost", sX11UseLocalhost },
341 { "xauthlocation", sXAuthLocation },
342 { "strictmodes", sStrictModes },
343 { "permitemptypasswords", sEmptyPasswd },
344 { "permituserenvironment", sPermitUserEnvironment },
345 { "uselogin", sUseLogin },
346 { "compression", sCompression },
347 { "tcpkeepalive", sTCPKeepAlive },
348 { "keepalive", sTCPKeepAlive }, /* obsolete alias */
349 { "allowtcpforwarding", sAllowTcpForwarding },
350 { "allowusers", sAllowUsers },
351 { "denyusers", sDenyUsers },
352 { "allowgroups", sAllowGroups },
353 { "denygroups", sDenyGroups },
354 { "ciphers", sCiphers },
356 { "protocol", sProtocol },
357 { "gatewayports", sGatewayPorts },
358 { "subsystem", sSubsystem },
359 { "maxstartups", sMaxStartups },
360 { "banner", sBanner },
361 { "usedns", sUseDNS },
362 { "verifyreversemapping", sDeprecated },
363 { "reversemappingcheck", sDeprecated },
364 { "clientaliveinterval", sClientAliveInterval },
365 { "clientalivecountmax", sClientAliveCountMax },
366 { "authorizedkeysfile", sAuthorizedKeysFile },
367 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
368 { "useprivilegeseparation", sUsePrivilegeSeparation},
369 { "acceptenv", sAcceptEnv },
374 * Returns the number of the token pointed to by cp or sBadOption.
378 parse_token(const char *cp, const char *filename,
383 for (i = 0; keywords[i].name; i++)
384 if (strcasecmp(cp, keywords[i].name) == 0)
385 return keywords[i].opcode;
387 error("%s: line %d: Bad configuration option: %s",
388 filename, linenum, cp);
393 add_listen_addr(ServerOptions *options, char *addr, u_short port)
397 if (options->num_ports == 0)
398 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
400 for (i = 0; i < options->num_ports; i++)
401 add_one_listen_addr(options, addr, options->ports[i]);
403 add_one_listen_addr(options, addr, port);
407 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
409 struct addrinfo hints, *ai, *aitop;
410 char strport[NI_MAXSERV];
413 memset(&hints, 0, sizeof(hints));
414 hints.ai_family = IPv4or6;
415 hints.ai_socktype = SOCK_STREAM;
416 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
417 snprintf(strport, sizeof strport, "%u", port);
418 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
419 fatal("bad addr or host: %s (%s)",
420 addr ? addr : "<NULL>",
421 gai_strerror(gaierr));
422 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
424 ai->ai_next = options->listen_addrs;
425 options->listen_addrs = aitop;
429 process_server_config_line(ServerOptions *options, char *line,
430 const char *filename, int linenum)
432 char *cp, **charptr, *arg, *p;
433 int *intptr, value, i, n;
434 ServerOpCodes opcode;
438 /* Ignore leading whitespace */
441 if (!arg || !*arg || *arg == '#')
445 opcode = parse_token(arg, filename, linenum);
447 /* Portable-specific options */
449 intptr = &options->use_pam;
452 /* Standard Options */
456 /* ignore ports from configfile if cmdline specifies ports */
457 if (options->ports_from_cmdline)
459 if (options->listen_addrs != NULL)
460 fatal("%s line %d: ports must be specified before "
461 "ListenAddress.", filename, linenum);
462 if (options->num_ports >= MAX_PORTS)
463 fatal("%s line %d: too many ports.",
466 if (!arg || *arg == '\0')
467 fatal("%s line %d: missing port number.",
469 options->ports[options->num_ports++] = a2port(arg);
470 if (options->ports[options->num_ports-1] == 0)
471 fatal("%s line %d: Badly formatted port number.",
476 intptr = &options->server_key_bits;
479 if (!arg || *arg == '\0')
480 fatal("%s line %d: missing integer value.",
487 case sLoginGraceTime:
488 intptr = &options->login_grace_time;
491 if (!arg || *arg == '\0')
492 fatal("%s line %d: missing time value.",
494 if ((value = convtime(arg)) == -1)
495 fatal("%s line %d: invalid time value.",
501 case sKeyRegenerationTime:
502 intptr = &options->key_regeneration_time;
507 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
508 fatal("%s line %d: missing inet addr.",
511 if ((p = strchr(arg, ']')) == NULL)
512 fatal("%s line %d: bad ipv6 inet addr usage.",
515 memmove(p, p+1, strlen(p+1)+1);
516 } else if (((p = strchr(arg, ':')) == NULL) ||
517 (strchr(p+1, ':') != NULL)) {
518 add_listen_addr(options, arg, 0);
526 fatal("%s line %d: bad inet addr:port usage.",
530 if ((port = a2port(p)) == 0)
531 fatal("%s line %d: bad port number.",
533 add_listen_addr(options, arg, port);
535 } else if (*p == '\0')
536 add_listen_addr(options, arg, 0);
538 fatal("%s line %d: bad inet addr usage.",
543 intptr = &options->num_host_key_files;
544 if (*intptr >= MAX_HOSTKEYS)
545 fatal("%s line %d: too many host keys specified (max %d).",
546 filename, linenum, MAX_HOSTKEYS);
547 charptr = &options->host_key_files[*intptr];
550 if (!arg || *arg == '\0')
551 fatal("%s line %d: missing file name.",
553 if (*charptr == NULL) {
554 *charptr = tilde_expand_filename(arg, getuid());
555 /* increase optional counter */
557 *intptr = *intptr + 1;
562 charptr = &options->pid_file;
565 case sPermitRootLogin:
566 intptr = &options->permit_root_login;
568 if (!arg || *arg == '\0')
569 fatal("%s line %d: missing yes/"
570 "without-password/forced-commands-only/no "
571 "argument.", filename, linenum);
572 value = 0; /* silence compiler */
573 if (strcmp(arg, "without-password") == 0)
574 value = PERMIT_NO_PASSWD;
575 else if (strcmp(arg, "forced-commands-only") == 0)
576 value = PERMIT_FORCED_ONLY;
577 else if (strcmp(arg, "yes") == 0)
579 else if (strcmp(arg, "no") == 0)
582 fatal("%s line %d: Bad yes/"
583 "without-password/forced-commands-only/no "
584 "argument: %s", filename, linenum, arg);
590 intptr = &options->ignore_rhosts;
593 if (!arg || *arg == '\0')
594 fatal("%s line %d: missing yes/no argument.",
596 value = 0; /* silence compiler */
597 if (strcmp(arg, "yes") == 0)
599 else if (strcmp(arg, "no") == 0)
602 fatal("%s line %d: Bad yes/no argument: %s",
603 filename, linenum, arg);
608 case sIgnoreUserKnownHosts:
609 intptr = &options->ignore_user_known_hosts;
612 case sRhostsRSAAuthentication:
613 intptr = &options->rhosts_rsa_authentication;
616 case sHostbasedAuthentication:
617 intptr = &options->hostbased_authentication;
620 case sHostbasedUsesNameFromPacketOnly:
621 intptr = &options->hostbased_uses_name_from_packet_only;
624 case sRSAAuthentication:
625 intptr = &options->rsa_authentication;
628 case sPubkeyAuthentication:
629 intptr = &options->pubkey_authentication;
632 case sKerberosAuthentication:
633 intptr = &options->kerberos_authentication;
636 case sKerberosOrLocalPasswd:
637 intptr = &options->kerberos_or_local_passwd;
640 case sKerberosTicketCleanup:
641 intptr = &options->kerberos_ticket_cleanup;
644 case sKerberosGetAFSToken:
645 intptr = &options->kerberos_get_afs_token;
648 case sGssAuthentication:
649 intptr = &options->gss_authentication;
652 case sGssCleanupCreds:
653 intptr = &options->gss_cleanup_creds;
656 case sPasswordAuthentication:
657 intptr = &options->password_authentication;
660 case sKbdInteractiveAuthentication:
661 intptr = &options->kbd_interactive_authentication;
664 case sChallengeResponseAuthentication:
665 intptr = &options->challenge_response_authentication;
669 intptr = &options->print_motd;
673 intptr = &options->print_lastlog;
677 intptr = &options->x11_forwarding;
680 case sX11DisplayOffset:
681 intptr = &options->x11_display_offset;
684 case sX11UseLocalhost:
685 intptr = &options->x11_use_localhost;
689 charptr = &options->xauth_location;
693 intptr = &options->strict_modes;
697 intptr = &options->tcp_keep_alive;
701 intptr = &options->permit_empty_passwd;
704 case sPermitUserEnvironment:
705 intptr = &options->permit_user_env;
709 intptr = &options->use_login;
713 intptr = &options->compression;
717 intptr = &options->gateway_ports;
721 intptr = &options->use_dns;
725 intptr = (int *) &options->log_facility;
727 value = log_facility_number(arg);
728 if (value == SYSLOG_FACILITY_NOT_SET)
729 fatal("%.200s line %d: unsupported log facility '%s'",
730 filename, linenum, arg ? arg : "<NONE>");
732 *intptr = (SyslogFacility) value;
736 intptr = (int *) &options->log_level;
738 value = log_level_number(arg);
739 if (value == SYSLOG_LEVEL_NOT_SET)
740 fatal("%.200s line %d: unsupported log level '%s'",
741 filename, linenum, arg ? arg : "<NONE>");
743 *intptr = (LogLevel) value;
746 case sAllowTcpForwarding:
747 intptr = &options->allow_tcp_forwarding;
750 case sUsePrivilegeSeparation:
751 intptr = &use_privsep;
755 while ((arg = strdelim(&cp)) && *arg != '\0') {
756 if (options->num_allow_users >= MAX_ALLOW_USERS)
757 fatal("%s line %d: too many allow users.",
759 options->allow_users[options->num_allow_users++] =
765 while ((arg = strdelim(&cp)) && *arg != '\0') {
766 if (options->num_deny_users >= MAX_DENY_USERS)
767 fatal( "%s line %d: too many deny users.",
769 options->deny_users[options->num_deny_users++] =
775 while ((arg = strdelim(&cp)) && *arg != '\0') {
776 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
777 fatal("%s line %d: too many allow groups.",
779 options->allow_groups[options->num_allow_groups++] =
785 while ((arg = strdelim(&cp)) && *arg != '\0') {
786 if (options->num_deny_groups >= MAX_DENY_GROUPS)
787 fatal("%s line %d: too many deny groups.",
789 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
795 if (!arg || *arg == '\0')
796 fatal("%s line %d: Missing argument.", filename, linenum);
797 if (!ciphers_valid(arg))
798 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
799 filename, linenum, arg ? arg : "<NONE>");
800 if (options->ciphers == NULL)
801 options->ciphers = xstrdup(arg);
806 if (!arg || *arg == '\0')
807 fatal("%s line %d: Missing argument.", filename, linenum);
809 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
810 filename, linenum, arg ? arg : "<NONE>");
811 if (options->macs == NULL)
812 options->macs = xstrdup(arg);
816 intptr = &options->protocol;
818 if (!arg || *arg == '\0')
819 fatal("%s line %d: Missing argument.", filename, linenum);
820 value = proto_spec(arg);
821 if (value == SSH_PROTO_UNKNOWN)
822 fatal("%s line %d: Bad protocol spec '%s'.",
823 filename, linenum, arg ? arg : "<NONE>");
824 if (*intptr == SSH_PROTO_UNKNOWN)
829 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
830 fatal("%s line %d: too many subsystems defined.",
834 if (!arg || *arg == '\0')
835 fatal("%s line %d: Missing subsystem name.",
837 for (i = 0; i < options->num_subsystems; i++)
838 if (strcmp(arg, options->subsystem_name[i]) == 0)
839 fatal("%s line %d: Subsystem '%s' already defined.",
840 filename, linenum, arg);
841 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
843 if (!arg || *arg == '\0')
844 fatal("%s line %d: Missing subsystem command.",
846 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
847 options->num_subsystems++;
852 if (!arg || *arg == '\0')
853 fatal("%s line %d: Missing MaxStartups spec.",
855 if ((n = sscanf(arg, "%d:%d:%d",
856 &options->max_startups_begin,
857 &options->max_startups_rate,
858 &options->max_startups)) == 3) {
859 if (options->max_startups_begin >
860 options->max_startups ||
861 options->max_startups_rate > 100 ||
862 options->max_startups_rate < 1)
863 fatal("%s line %d: Illegal MaxStartups spec.",
866 fatal("%s line %d: Illegal MaxStartups spec.",
869 options->max_startups = options->max_startups_begin;
873 charptr = &options->banner;
876 * These options can contain %X options expanded at
877 * connect time, so that you can specify paths like:
879 * AuthorizedKeysFile /etc/ssh_keys/%u
881 case sAuthorizedKeysFile:
882 case sAuthorizedKeysFile2:
883 charptr = (opcode == sAuthorizedKeysFile ) ?
884 &options->authorized_keys_file :
885 &options->authorized_keys_file2;
888 case sClientAliveInterval:
889 intptr = &options->client_alive_interval;
892 case sClientAliveCountMax:
893 intptr = &options->client_alive_count_max;
897 while ((arg = strdelim(&cp)) && *arg != '\0') {
898 if (strchr(arg, '=') != NULL)
899 fatal("%s line %d: Invalid environment name.",
901 if (options->num_accept_env >= MAX_ACCEPT_ENV)
902 fatal("%s line %d: too many allow env.",
904 options->accept_env[options->num_accept_env++] =
910 logit("%s line %d: Deprecated option %s",
911 filename, linenum, arg);
917 logit("%s line %d: Unsupported option %s",
918 filename, linenum, arg);
924 fatal("%s line %d: Missing handler for opcode %s (%d)",
925 filename, linenum, arg, opcode);
927 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
928 fatal("%s line %d: garbage at end of line; \"%.200s\".",
929 filename, linenum, arg);
933 /* Reads the server configuration file. */
936 read_server_config(ServerOptions *options, const char *filename)
938 int linenum, bad_options = 0;
942 debug2("read_server_config: filename %s", filename);
943 f = fopen(filename, "r");
949 while (fgets(line, sizeof(line), f)) {
950 /* Update line number counter. */
952 if (process_server_config_line(options, line, filename, linenum) != 0)
957 fatal("%s: terminating, %d bad configuration options",
958 filename, bad_options);