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.144 2005/08/06 10:03:12 dtucker 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 /* Use of privilege separation or not */
30 extern int use_privsep;
32 /* Initializes the server options to their default values. */
35 initialize_server_options(ServerOptions *options)
37 memset(options, 0, sizeof(*options));
39 /* Portable-specific options */
40 options->use_pam = -1;
42 /* Standard Options */
43 options->num_ports = 0;
44 options->ports_from_cmdline = 0;
45 options->listen_addrs = NULL;
46 options->address_family = -1;
47 options->num_host_key_files = 0;
48 options->pid_file = NULL;
49 options->server_key_bits = -1;
50 options->login_grace_time = -1;
51 options->key_regeneration_time = -1;
52 options->permit_root_login = PERMIT_NOT_SET;
53 options->ignore_rhosts = -1;
54 options->ignore_user_known_hosts = -1;
55 options->print_motd = -1;
56 options->print_lastlog = -1;
57 options->x11_forwarding = -1;
58 options->x11_display_offset = -1;
59 options->x11_use_localhost = -1;
60 options->xauth_location = NULL;
61 options->strict_modes = -1;
62 options->tcp_keep_alive = -1;
63 options->log_facility = SYSLOG_FACILITY_NOT_SET;
64 options->log_level = SYSLOG_LEVEL_NOT_SET;
65 options->rhosts_rsa_authentication = -1;
66 options->hostbased_authentication = -1;
67 options->hostbased_uses_name_from_packet_only = -1;
68 options->rsa_authentication = -1;
69 options->pubkey_authentication = -1;
70 options->kerberos_authentication = -1;
71 options->kerberos_or_local_passwd = -1;
72 options->kerberos_ticket_cleanup = -1;
74 options->session_hooks_allow = -1;
75 options->session_hooks_startup_cmd = NULL;
76 options->session_hooks_shutdown_cmd = NULL;
78 options->kerberos_get_afs_token = -1;
79 options->gss_authentication=-1;
80 options->gss_keyex=-1;
81 options->gss_cleanup_creds = -1;
82 options->password_authentication = -1;
83 options->kbd_interactive_authentication = -1;
84 options->challenge_response_authentication = -1;
85 options->permit_empty_passwd = -1;
86 options->permit_user_env = -1;
87 options->use_login = -1;
88 options->compression = -1;
89 options->allow_tcp_forwarding = -1;
90 options->num_allow_users = 0;
91 options->num_deny_users = 0;
92 options->num_allow_groups = 0;
93 options->num_deny_groups = 0;
94 options->ciphers = NULL;
96 options->protocol = SSH_PROTO_UNKNOWN;
97 options->gateway_ports = -1;
98 options->num_subsystems = 0;
99 options->max_startups_begin = -1;
100 options->max_startups_rate = -1;
101 options->max_startups = -1;
102 options->max_authtries = -1;
103 options->banner = NULL;
104 options->use_dns = -1;
105 options->client_alive_interval = -1;
106 options->client_alive_count_max = -1;
107 options->authorized_keys_file = NULL;
108 options->authorized_keys_file2 = NULL;
109 options->num_accept_env = 0;
111 /* Needs to be accessable in many places */
116 fill_default_server_options(ServerOptions *options)
118 /* Portable-specific options */
119 if (options->use_pam == -1)
120 options->use_pam = 0;
122 /* Standard Options */
123 if (options->protocol == SSH_PROTO_UNKNOWN)
124 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
125 if (options->num_host_key_files == 0) {
126 /* fill default hostkeys for protocols */
127 if (options->protocol & SSH_PROTO_1)
128 options->host_key_files[options->num_host_key_files++] =
130 if (options->protocol & SSH_PROTO_2) {
131 options->host_key_files[options->num_host_key_files++] =
132 _PATH_HOST_RSA_KEY_FILE;
133 options->host_key_files[options->num_host_key_files++] =
134 _PATH_HOST_DSA_KEY_FILE;
137 if (options->num_ports == 0)
138 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
139 if (options->listen_addrs == NULL)
140 add_listen_addr(options, NULL, 0);
141 if (options->pid_file == NULL)
142 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
143 if (options->server_key_bits == -1)
144 options->server_key_bits = 768;
145 if (options->login_grace_time == -1)
146 options->login_grace_time = 120;
147 if (options->key_regeneration_time == -1)
148 options->key_regeneration_time = 3600;
149 if (options->permit_root_login == PERMIT_NOT_SET)
150 options->permit_root_login = PERMIT_YES;
151 if (options->ignore_rhosts == -1)
152 options->ignore_rhosts = 1;
153 if (options->ignore_user_known_hosts == -1)
154 options->ignore_user_known_hosts = 0;
155 if (options->print_motd == -1)
156 options->print_motd = 1;
157 if (options->print_lastlog == -1)
158 options->print_lastlog = 1;
159 if (options->x11_forwarding == -1)
160 options->x11_forwarding = 0;
161 if (options->x11_display_offset == -1)
162 options->x11_display_offset = 10;
163 if (options->x11_use_localhost == -1)
164 options->x11_use_localhost = 1;
165 if (options->xauth_location == NULL)
166 options->xauth_location = _PATH_XAUTH;
167 if (options->strict_modes == -1)
168 options->strict_modes = 1;
169 if (options->tcp_keep_alive == -1)
170 options->tcp_keep_alive = 1;
171 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
172 options->log_facility = SYSLOG_FACILITY_AUTH;
173 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
174 options->log_level = SYSLOG_LEVEL_INFO;
175 if (options->rhosts_rsa_authentication == -1)
176 options->rhosts_rsa_authentication = 0;
177 if (options->hostbased_authentication == -1)
178 options->hostbased_authentication = 0;
179 if (options->hostbased_uses_name_from_packet_only == -1)
180 options->hostbased_uses_name_from_packet_only = 0;
181 if (options->rsa_authentication == -1)
182 options->rsa_authentication = 1;
183 if (options->pubkey_authentication == -1)
184 options->pubkey_authentication = 1;
185 if (options->kerberos_authentication == -1)
186 options->kerberos_authentication = 0;
187 if (options->kerberos_or_local_passwd == -1)
188 options->kerberos_or_local_passwd = 1;
189 if (options->kerberos_ticket_cleanup == -1)
190 options->kerberos_ticket_cleanup = 1;
191 if (options->kerberos_get_afs_token == -1)
192 options->kerberos_get_afs_token = 0;
193 if (options->gss_authentication == -1)
194 options->gss_authentication = 1;
195 if (options->gss_keyex == -1)
196 options->gss_keyex = 1;
197 if (options->gss_cleanup_creds == -1)
198 options->gss_cleanup_creds = 1;
199 if (options->password_authentication == -1)
200 options->password_authentication = 1;
201 if (options->kbd_interactive_authentication == -1)
202 options->kbd_interactive_authentication = 0;
203 if (options->challenge_response_authentication == -1)
204 options->challenge_response_authentication = 1;
205 if (options->permit_empty_passwd == -1)
206 options->permit_empty_passwd = 0;
207 if (options->permit_user_env == -1)
208 options->permit_user_env = 0;
209 if (options->use_login == -1)
210 options->use_login = 0;
211 if (options->compression == -1)
212 options->compression = COMP_DELAYED;
213 if (options->allow_tcp_forwarding == -1)
214 options->allow_tcp_forwarding = 1;
215 if (options->gateway_ports == -1)
216 options->gateway_ports = 0;
217 if (options->max_startups == -1)
218 options->max_startups = 10;
219 if (options->max_startups_rate == -1)
220 options->max_startups_rate = 100; /* 100% */
221 if (options->max_startups_begin == -1)
222 options->max_startups_begin = options->max_startups;
223 if (options->max_authtries == -1)
224 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
225 if (options->use_dns == -1)
226 options->use_dns = 1;
227 if (options->client_alive_interval == -1)
228 options->client_alive_interval = 0;
229 if (options->client_alive_count_max == -1)
230 options->client_alive_count_max = 3;
231 if (options->authorized_keys_file2 == NULL) {
232 /* authorized_keys_file2 falls back to authorized_keys_file */
233 if (options->authorized_keys_file != NULL)
234 options->authorized_keys_file2 = options->authorized_keys_file;
236 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
238 if (options->authorized_keys_file == NULL)
239 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
241 /* Turn privilege separation on by default */
242 if (use_privsep == -1)
246 if (use_privsep && options->compression == 1) {
247 error("This platform does not support both privilege "
248 "separation and compression");
249 error("Compression disabled");
250 options->compression = 0;
256 /* Keyword tokens. */
258 sBadOption, /* == unknown option */
259 /* Portable-specific options */
261 /* Standard Options */
262 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
263 sPermitRootLogin, sLogFacility, sLogLevel,
264 sRhostsRSAAuthentication, sRSAAuthentication,
265 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
266 sKerberosGetAFSToken,
267 sKerberosTgtPassing, sChallengeResponseAuthentication,
269 sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
271 sPasswordAuthentication, sKbdInteractiveAuthentication,
272 sListenAddress, sAddressFamily,
273 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
274 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
275 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
276 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
277 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
278 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
279 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
280 sMaxStartups, sMaxAuthTries,
281 sBanner, sUseDNS, sHostbasedAuthentication,
282 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
283 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
284 sGssAuthentication, sGssCleanupCreds, sAcceptEnv,
286 sUsePrivilegeSeparation,
287 sDeprecated, sUnsupported
290 /* Textual representation of the tokens. */
293 ServerOpCodes opcode;
295 /* Portable-specific options */
297 { "usepam", sUsePAM },
299 { "usepam", sUnsupported },
301 { "pamauthenticationviakbdint", sDeprecated },
302 /* Standard Options */
304 { "hostkey", sHostKeyFile },
305 { "hostdsakey", sHostKeyFile }, /* alias */
306 { "pidfile", sPidFile },
307 { "serverkeybits", sServerKeyBits },
308 { "logingracetime", sLoginGraceTime },
309 { "keyregenerationinterval", sKeyRegenerationTime },
310 { "permitrootlogin", sPermitRootLogin },
311 { "syslogfacility", sLogFacility },
312 { "loglevel", sLogLevel },
313 { "rhostsauthentication", sDeprecated },
314 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
315 { "hostbasedauthentication", sHostbasedAuthentication },
316 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
317 { "rsaauthentication", sRSAAuthentication },
318 { "pubkeyauthentication", sPubkeyAuthentication },
319 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
321 { "kerberosauthentication", sKerberosAuthentication },
322 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
323 { "kerberosticketcleanup", sKerberosTicketCleanup },
325 { "kerberosgetafstoken", sKerberosGetAFSToken },
327 { "kerberosgetafstoken", sUnsupported },
330 { "kerberosauthentication", sUnsupported },
331 { "kerberosorlocalpasswd", sUnsupported },
332 { "kerberosticketcleanup", sUnsupported },
333 { "kerberosgetafstoken", sUnsupported },
335 { "kerberostgtpassing", sUnsupported },
336 { "afstokenpassing", sUnsupported },
338 { "gssapiauthentication", sGssAuthentication },
339 { "gssapikeyexchange", sGssKeyEx },
340 { "gssapicleanupcredentials", sGssCleanupCreds },
342 { "gssapiauthentication", sUnsupported },
343 { "gssapikeyexchange", sUnsupported },
344 { "gssapicleanupcredentials", sUnsupported },
347 { "allowsessionhooks", sAllowSessionHooks },
348 { "sessionhookstartupcmd", sSessionHookStartupCmd },
349 { "sessionhookshutdowncmd", sSessionHookShutdownCmd },
351 { "passwordauthentication", sPasswordAuthentication },
352 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
353 { "challengeresponseauthentication", sChallengeResponseAuthentication },
354 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
355 { "checkmail", sDeprecated },
356 { "listenaddress", sListenAddress },
357 { "addressfamily", sAddressFamily },
358 { "printmotd", sPrintMotd },
359 { "printlastlog", sPrintLastLog },
360 { "ignorerhosts", sIgnoreRhosts },
361 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
362 { "x11forwarding", sX11Forwarding },
363 { "x11displayoffset", sX11DisplayOffset },
364 { "x11uselocalhost", sX11UseLocalhost },
365 { "xauthlocation", sXAuthLocation },
366 { "strictmodes", sStrictModes },
367 { "permitemptypasswords", sEmptyPasswd },
368 { "permituserenvironment", sPermitUserEnvironment },
369 { "uselogin", sUseLogin },
370 { "compression", sCompression },
371 { "tcpkeepalive", sTCPKeepAlive },
372 { "keepalive", sTCPKeepAlive }, /* obsolete alias */
373 { "allowtcpforwarding", sAllowTcpForwarding },
374 { "allowusers", sAllowUsers },
375 { "denyusers", sDenyUsers },
376 { "allowgroups", sAllowGroups },
377 { "denygroups", sDenyGroups },
378 { "ciphers", sCiphers },
380 { "protocol", sProtocol },
381 { "gatewayports", sGatewayPorts },
382 { "subsystem", sSubsystem },
383 { "maxstartups", sMaxStartups },
384 { "maxauthtries", sMaxAuthTries },
385 { "banner", sBanner },
386 { "usedns", sUseDNS },
387 { "verifyreversemapping", sDeprecated },
388 { "reversemappingcheck", sDeprecated },
389 { "clientaliveinterval", sClientAliveInterval },
390 { "clientalivecountmax", sClientAliveCountMax },
391 { "authorizedkeysfile", sAuthorizedKeysFile },
392 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
393 { "useprivilegeseparation", sUsePrivilegeSeparation},
394 { "acceptenv", sAcceptEnv },
399 * Returns the number of the token pointed to by cp or sBadOption.
403 parse_token(const char *cp, const char *filename,
408 for (i = 0; keywords[i].name; i++)
409 if (strcasecmp(cp, keywords[i].name) == 0)
410 return keywords[i].opcode;
412 error("%s: line %d: Bad configuration option: %s",
413 filename, linenum, cp);
418 add_listen_addr(ServerOptions *options, char *addr, u_short port)
422 if (options->num_ports == 0)
423 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
424 if (options->address_family == -1)
425 options->address_family = AF_UNSPEC;
427 for (i = 0; i < options->num_ports; i++)
428 add_one_listen_addr(options, addr, options->ports[i]);
430 add_one_listen_addr(options, addr, port);
434 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
436 struct addrinfo hints, *ai, *aitop;
437 char strport[NI_MAXSERV];
440 memset(&hints, 0, sizeof(hints));
441 hints.ai_family = options->address_family;
442 hints.ai_socktype = SOCK_STREAM;
443 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
444 snprintf(strport, sizeof strport, "%u", port);
445 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
446 fatal("bad addr or host: %s (%s)",
447 addr ? addr : "<NULL>",
448 gai_strerror(gaierr));
449 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
451 ai->ai_next = options->listen_addrs;
452 options->listen_addrs = aitop;
456 process_server_config_line(ServerOptions *options, char *line,
457 const char *filename, int linenum)
459 char *cp, **charptr, *arg, *p;
460 int *intptr, value, n;
461 ServerOpCodes opcode;
467 /* Ignore leading whitespace */
470 if (!arg || !*arg || *arg == '#')
474 opcode = parse_token(arg, filename, linenum);
476 /* Portable-specific options */
478 intptr = &options->use_pam;
481 /* Standard Options */
485 /* ignore ports from configfile if cmdline specifies ports */
486 if (options->ports_from_cmdline)
488 if (options->listen_addrs != NULL)
489 fatal("%s line %d: ports must be specified before "
490 "ListenAddress.", filename, linenum);
491 if (options->num_ports >= MAX_PORTS)
492 fatal("%s line %d: too many ports.",
495 if (!arg || *arg == '\0')
496 fatal("%s line %d: missing port number.",
498 options->ports[options->num_ports++] = a2port(arg);
499 if (options->ports[options->num_ports-1] == 0)
500 fatal("%s line %d: Badly formatted port number.",
505 intptr = &options->server_key_bits;
508 if (!arg || *arg == '\0')
509 fatal("%s line %d: missing integer value.",
516 case sLoginGraceTime:
517 intptr = &options->login_grace_time;
520 if (!arg || *arg == '\0')
521 fatal("%s line %d: missing time value.",
523 if ((value = convtime(arg)) == -1)
524 fatal("%s line %d: invalid time value.",
530 case sKeyRegenerationTime:
531 intptr = &options->key_regeneration_time;
536 if (arg == NULL || *arg == '\0')
537 fatal("%s line %d: missing address",
539 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
540 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
541 && strchr(p+1, ':') != NULL) {
542 add_listen_addr(options, arg, 0);
547 fatal("%s line %d: bad address:port usage",
549 p = cleanhostname(p);
552 else if ((port = a2port(arg)) == 0)
553 fatal("%s line %d: bad port number", filename, linenum);
555 add_listen_addr(options, p, port);
561 if (!arg || *arg == '\0')
562 fatal("%s line %d: missing address family.",
564 intptr = &options->address_family;
565 if (options->listen_addrs != NULL)
566 fatal("%s line %d: address family must be specified before "
567 "ListenAddress.", filename, linenum);
568 if (strcasecmp(arg, "inet") == 0)
570 else if (strcasecmp(arg, "inet6") == 0)
572 else if (strcasecmp(arg, "any") == 0)
575 fatal("%s line %d: unsupported address family \"%s\".",
576 filename, linenum, arg);
582 intptr = &options->num_host_key_files;
583 if (*intptr >= MAX_HOSTKEYS)
584 fatal("%s line %d: too many host keys specified (max %d).",
585 filename, linenum, MAX_HOSTKEYS);
586 charptr = &options->host_key_files[*intptr];
589 if (!arg || *arg == '\0')
590 fatal("%s line %d: missing file name.",
592 if (*charptr == NULL) {
593 *charptr = tilde_expand_filename(arg, getuid());
594 /* increase optional counter */
596 *intptr = *intptr + 1;
601 charptr = &options->pid_file;
604 case sPermitRootLogin:
605 intptr = &options->permit_root_login;
607 if (!arg || *arg == '\0')
608 fatal("%s line %d: missing yes/"
609 "without-password/forced-commands-only/no "
610 "argument.", filename, linenum);
611 value = 0; /* silence compiler */
612 if (strcmp(arg, "without-password") == 0)
613 value = PERMIT_NO_PASSWD;
614 else if (strcmp(arg, "forced-commands-only") == 0)
615 value = PERMIT_FORCED_ONLY;
616 else if (strcmp(arg, "yes") == 0)
618 else if (strcmp(arg, "no") == 0)
621 fatal("%s line %d: Bad yes/"
622 "without-password/forced-commands-only/no "
623 "argument: %s", filename, linenum, arg);
629 intptr = &options->ignore_rhosts;
632 if (!arg || *arg == '\0')
633 fatal("%s line %d: missing yes/no argument.",
635 value = 0; /* silence compiler */
636 if (strcmp(arg, "yes") == 0)
638 else if (strcmp(arg, "no") == 0)
641 fatal("%s line %d: Bad yes/no argument: %s",
642 filename, linenum, arg);
647 case sIgnoreUserKnownHosts:
648 intptr = &options->ignore_user_known_hosts;
651 case sRhostsRSAAuthentication:
652 intptr = &options->rhosts_rsa_authentication;
655 case sHostbasedAuthentication:
656 intptr = &options->hostbased_authentication;
659 case sHostbasedUsesNameFromPacketOnly:
660 intptr = &options->hostbased_uses_name_from_packet_only;
663 case sRSAAuthentication:
664 intptr = &options->rsa_authentication;
667 case sPubkeyAuthentication:
668 intptr = &options->pubkey_authentication;
671 case sKerberosAuthentication:
672 intptr = &options->kerberos_authentication;
675 case sKerberosOrLocalPasswd:
676 intptr = &options->kerberos_or_local_passwd;
679 case sKerberosTicketCleanup:
680 intptr = &options->kerberos_ticket_cleanup;
683 case sKerberosGetAFSToken:
684 intptr = &options->kerberos_get_afs_token;
687 case sGssAuthentication:
688 intptr = &options->gss_authentication;
692 intptr = &options->gss_keyex;
695 case sGssCleanupCreds:
696 intptr = &options->gss_cleanup_creds;
700 case sAllowSessionHooks:
701 intptr = &options->session_hooks_allow;
703 case sSessionHookStartupCmd:
704 case sSessionHookShutdownCmd:
706 if (!arg || *arg == '\0')
707 fatal("%s line %d: empty session hook command",
709 if (opcode==sSessionHookStartupCmd)
710 options->session_hooks_startup_cmd = strdup(arg);
712 options->session_hooks_shutdown_cmd = strdup(arg);
716 case sPasswordAuthentication:
717 intptr = &options->password_authentication;
720 case sKbdInteractiveAuthentication:
721 intptr = &options->kbd_interactive_authentication;
724 case sChallengeResponseAuthentication:
725 intptr = &options->challenge_response_authentication;
729 intptr = &options->print_motd;
733 intptr = &options->print_lastlog;
737 intptr = &options->x11_forwarding;
740 case sX11DisplayOffset:
741 intptr = &options->x11_display_offset;
744 case sX11UseLocalhost:
745 intptr = &options->x11_use_localhost;
749 charptr = &options->xauth_location;
753 intptr = &options->strict_modes;
757 intptr = &options->tcp_keep_alive;
761 intptr = &options->permit_empty_passwd;
764 case sPermitUserEnvironment:
765 intptr = &options->permit_user_env;
769 intptr = &options->use_login;
773 intptr = &options->compression;
775 if (!arg || *arg == '\0')
776 fatal("%s line %d: missing yes/no/delayed "
777 "argument.", filename, linenum);
778 value = 0; /* silence compiler */
779 if (strcmp(arg, "delayed") == 0)
780 value = COMP_DELAYED;
781 else if (strcmp(arg, "yes") == 0)
783 else if (strcmp(arg, "no") == 0)
786 fatal("%s line %d: Bad yes/no/delayed "
787 "argument: %s", filename, linenum, arg);
793 intptr = &options->gateway_ports;
795 if (!arg || *arg == '\0')
796 fatal("%s line %d: missing yes/no/clientspecified "
797 "argument.", filename, linenum);
798 value = 0; /* silence compiler */
799 if (strcmp(arg, "clientspecified") == 0)
801 else if (strcmp(arg, "yes") == 0)
803 else if (strcmp(arg, "no") == 0)
806 fatal("%s line %d: Bad yes/no/clientspecified "
807 "argument: %s", filename, linenum, arg);
813 intptr = &options->use_dns;
817 intptr = (int *) &options->log_facility;
819 value = log_facility_number(arg);
820 if (value == SYSLOG_FACILITY_NOT_SET)
821 fatal("%.200s line %d: unsupported log facility '%s'",
822 filename, linenum, arg ? arg : "<NONE>");
824 *intptr = (SyslogFacility) value;
828 intptr = (int *) &options->log_level;
830 value = log_level_number(arg);
831 if (value == SYSLOG_LEVEL_NOT_SET)
832 fatal("%.200s line %d: unsupported log level '%s'",
833 filename, linenum, arg ? arg : "<NONE>");
835 *intptr = (LogLevel) value;
838 case sAllowTcpForwarding:
839 intptr = &options->allow_tcp_forwarding;
842 case sUsePrivilegeSeparation:
843 intptr = &use_privsep;
847 while ((arg = strdelim(&cp)) && *arg != '\0') {
848 if (options->num_allow_users >= MAX_ALLOW_USERS)
849 fatal("%s line %d: too many allow users.",
851 options->allow_users[options->num_allow_users++] =
857 while ((arg = strdelim(&cp)) && *arg != '\0') {
858 if (options->num_deny_users >= MAX_DENY_USERS)
859 fatal( "%s line %d: too many deny users.",
861 options->deny_users[options->num_deny_users++] =
867 while ((arg = strdelim(&cp)) && *arg != '\0') {
868 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
869 fatal("%s line %d: too many allow groups.",
871 options->allow_groups[options->num_allow_groups++] =
877 while ((arg = strdelim(&cp)) && *arg != '\0') {
878 if (options->num_deny_groups >= MAX_DENY_GROUPS)
879 fatal("%s line %d: too many deny groups.",
881 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
887 if (!arg || *arg == '\0')
888 fatal("%s line %d: Missing argument.", filename, linenum);
889 if (!ciphers_valid(arg))
890 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
891 filename, linenum, arg ? arg : "<NONE>");
892 if (options->ciphers == NULL)
893 options->ciphers = xstrdup(arg);
898 if (!arg || *arg == '\0')
899 fatal("%s line %d: Missing argument.", filename, linenum);
901 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
902 filename, linenum, arg ? arg : "<NONE>");
903 if (options->macs == NULL)
904 options->macs = xstrdup(arg);
908 intptr = &options->protocol;
910 if (!arg || *arg == '\0')
911 fatal("%s line %d: Missing argument.", filename, linenum);
912 value = proto_spec(arg);
913 if (value == SSH_PROTO_UNKNOWN)
914 fatal("%s line %d: Bad protocol spec '%s'.",
915 filename, linenum, arg ? arg : "<NONE>");
916 if (*intptr == SSH_PROTO_UNKNOWN)
921 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
922 fatal("%s line %d: too many subsystems defined.",
926 if (!arg || *arg == '\0')
927 fatal("%s line %d: Missing subsystem name.",
929 for (i = 0; i < options->num_subsystems; i++)
930 if (strcmp(arg, options->subsystem_name[i]) == 0)
931 fatal("%s line %d: Subsystem '%s' already defined.",
932 filename, linenum, arg);
933 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
935 if (!arg || *arg == '\0')
936 fatal("%s line %d: Missing subsystem command.",
938 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
939 options->num_subsystems++;
944 if (!arg || *arg == '\0')
945 fatal("%s line %d: Missing MaxStartups spec.",
947 if ((n = sscanf(arg, "%d:%d:%d",
948 &options->max_startups_begin,
949 &options->max_startups_rate,
950 &options->max_startups)) == 3) {
951 if (options->max_startups_begin >
952 options->max_startups ||
953 options->max_startups_rate > 100 ||
954 options->max_startups_rate < 1)
955 fatal("%s line %d: Illegal MaxStartups spec.",
958 fatal("%s line %d: Illegal MaxStartups spec.",
961 options->max_startups = options->max_startups_begin;
965 intptr = &options->max_authtries;
969 charptr = &options->banner;
972 * These options can contain %X options expanded at
973 * connect time, so that you can specify paths like:
975 * AuthorizedKeysFile /etc/ssh_keys/%u
977 case sAuthorizedKeysFile:
978 case sAuthorizedKeysFile2:
979 charptr = (opcode == sAuthorizedKeysFile ) ?
980 &options->authorized_keys_file :
981 &options->authorized_keys_file2;
984 case sClientAliveInterval:
985 intptr = &options->client_alive_interval;
988 case sClientAliveCountMax:
989 intptr = &options->client_alive_count_max;
993 while ((arg = strdelim(&cp)) && *arg != '\0') {
994 if (strchr(arg, '=') != NULL)
995 fatal("%s line %d: Invalid environment name.",
997 if (options->num_accept_env >= MAX_ACCEPT_ENV)
998 fatal("%s line %d: too many allow env.",
1000 options->accept_env[options->num_accept_env++] =
1006 logit("%s line %d: Deprecated option %s",
1007 filename, linenum, arg);
1009 arg = strdelim(&cp);
1013 logit("%s line %d: Unsupported option %s",
1014 filename, linenum, arg);
1016 arg = strdelim(&cp);
1020 fatal("%s line %d: Missing handler for opcode %s (%d)",
1021 filename, linenum, arg, opcode);
1023 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1024 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1025 filename, linenum, arg);
1029 /* Reads the server configuration file. */
1032 load_server_config(const char *filename, Buffer *conf)
1034 char line[1024], *cp;
1037 debug2("%s: filename %s", __func__, filename);
1038 if ((f = fopen(filename, "r")) == NULL) {
1043 while (fgets(line, sizeof(line), f)) {
1045 * Trim out comments and strip whitespace
1046 * NB - preserve newlines, they are needed to reproduce
1047 * line numbers later for error messages
1049 if ((cp = strchr(line, '#')) != NULL)
1050 memcpy(cp, "\n", 2);
1051 cp = line + strspn(line, " \t\r");
1053 buffer_append(conf, cp, strlen(cp));
1055 buffer_append(conf, "\0", 1);
1057 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1061 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
1063 int linenum, bad_options = 0;
1064 char *cp, *obuf, *cbuf;
1066 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1068 obuf = cbuf = xstrdup(buffer_ptr(conf));
1070 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1071 if (process_server_config_line(options, cp, filename,
1076 if (bad_options > 0)
1077 fatal("%s: terminating, %d bad configuration options",
1078 filename, bad_options);