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, sGssKeyEx, sGssCleanupCreds, sAcceptEnv,
285 sUsePrivilegeSeparation,
286 sDeprecated, sUnsupported
289 /* Textual representation of the tokens. */
292 ServerOpCodes opcode;
294 /* Portable-specific options */
296 { "usepam", sUsePAM },
298 { "usepam", sUnsupported },
300 { "pamauthenticationviakbdint", sDeprecated },
301 /* Standard Options */
303 { "hostkey", sHostKeyFile },
304 { "hostdsakey", sHostKeyFile }, /* alias */
305 { "pidfile", sPidFile },
306 { "serverkeybits", sServerKeyBits },
307 { "logingracetime", sLoginGraceTime },
308 { "keyregenerationinterval", sKeyRegenerationTime },
309 { "permitrootlogin", sPermitRootLogin },
310 { "syslogfacility", sLogFacility },
311 { "loglevel", sLogLevel },
312 { "rhostsauthentication", sDeprecated },
313 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
314 { "hostbasedauthentication", sHostbasedAuthentication },
315 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
316 { "rsaauthentication", sRSAAuthentication },
317 { "pubkeyauthentication", sPubkeyAuthentication },
318 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
320 { "kerberosauthentication", sKerberosAuthentication },
321 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
322 { "kerberosticketcleanup", sKerberosTicketCleanup },
324 { "kerberosgetafstoken", sKerberosGetAFSToken },
326 { "kerberosgetafstoken", sUnsupported },
329 { "kerberosauthentication", sUnsupported },
330 { "kerberosorlocalpasswd", sUnsupported },
331 { "kerberosticketcleanup", sUnsupported },
332 { "kerberosgetafstoken", sUnsupported },
334 { "kerberostgtpassing", sUnsupported },
335 { "afstokenpassing", sUnsupported },
337 { "gssapiauthentication", sGssAuthentication },
338 { "gssapikeyexchange", sGssKeyEx },
339 { "gssapicleanupcredentials", sGssCleanupCreds },
341 { "gssapiauthentication", sUnsupported },
342 { "gssapikeyexchange", sUnsupported },
343 { "gssapicleanupcredentials", sUnsupported },
346 { "allowsessionhooks", sAllowSessionHooks },
347 { "sessionhookstartupcmd", sSessionHookStartupCmd },
348 { "sessionhookshutdowncmd", sSessionHookShutdownCmd },
350 { "passwordauthentication", sPasswordAuthentication },
351 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
352 { "challengeresponseauthentication", sChallengeResponseAuthentication },
353 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
354 { "checkmail", sDeprecated },
355 { "listenaddress", sListenAddress },
356 { "addressfamily", sAddressFamily },
357 { "printmotd", sPrintMotd },
358 { "printlastlog", sPrintLastLog },
359 { "ignorerhosts", sIgnoreRhosts },
360 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
361 { "x11forwarding", sX11Forwarding },
362 { "x11displayoffset", sX11DisplayOffset },
363 { "x11uselocalhost", sX11UseLocalhost },
364 { "xauthlocation", sXAuthLocation },
365 { "strictmodes", sStrictModes },
366 { "permitemptypasswords", sEmptyPasswd },
367 { "permituserenvironment", sPermitUserEnvironment },
368 { "uselogin", sUseLogin },
369 { "compression", sCompression },
370 { "tcpkeepalive", sTCPKeepAlive },
371 { "keepalive", sTCPKeepAlive }, /* obsolete alias */
372 { "allowtcpforwarding", sAllowTcpForwarding },
373 { "allowusers", sAllowUsers },
374 { "denyusers", sDenyUsers },
375 { "allowgroups", sAllowGroups },
376 { "denygroups", sDenyGroups },
377 { "ciphers", sCiphers },
379 { "protocol", sProtocol },
380 { "gatewayports", sGatewayPorts },
381 { "subsystem", sSubsystem },
382 { "maxstartups", sMaxStartups },
383 { "maxauthtries", sMaxAuthTries },
384 { "banner", sBanner },
385 { "usedns", sUseDNS },
386 { "verifyreversemapping", sDeprecated },
387 { "reversemappingcheck", sDeprecated },
388 { "clientaliveinterval", sClientAliveInterval },
389 { "clientalivecountmax", sClientAliveCountMax },
390 { "authorizedkeysfile", sAuthorizedKeysFile },
391 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
392 { "useprivilegeseparation", sUsePrivilegeSeparation},
393 { "acceptenv", sAcceptEnv },
398 * Returns the number of the token pointed to by cp or sBadOption.
402 parse_token(const char *cp, const char *filename,
407 for (i = 0; keywords[i].name; i++)
408 if (strcasecmp(cp, keywords[i].name) == 0)
409 return keywords[i].opcode;
411 error("%s: line %d: Bad configuration option: %s",
412 filename, linenum, cp);
417 add_listen_addr(ServerOptions *options, char *addr, u_short port)
421 if (options->num_ports == 0)
422 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
423 if (options->address_family == -1)
424 options->address_family = AF_UNSPEC;
426 for (i = 0; i < options->num_ports; i++)
427 add_one_listen_addr(options, addr, options->ports[i]);
429 add_one_listen_addr(options, addr, port);
433 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
435 struct addrinfo hints, *ai, *aitop;
436 char strport[NI_MAXSERV];
439 memset(&hints, 0, sizeof(hints));
440 hints.ai_family = options->address_family;
441 hints.ai_socktype = SOCK_STREAM;
442 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
443 snprintf(strport, sizeof strport, "%u", port);
444 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
445 fatal("bad addr or host: %s (%s)",
446 addr ? addr : "<NULL>",
447 gai_strerror(gaierr));
448 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
450 ai->ai_next = options->listen_addrs;
451 options->listen_addrs = aitop;
455 process_server_config_line(ServerOptions *options, char *line,
456 const char *filename, int linenum)
458 char *cp, **charptr, *arg, *p;
459 int *intptr, value, n;
460 ServerOpCodes opcode;
466 /* Ignore leading whitespace */
469 if (!arg || !*arg || *arg == '#')
473 opcode = parse_token(arg, filename, linenum);
475 /* Portable-specific options */
477 intptr = &options->use_pam;
480 /* Standard Options */
484 /* ignore ports from configfile if cmdline specifies ports */
485 if (options->ports_from_cmdline)
487 if (options->listen_addrs != NULL)
488 fatal("%s line %d: ports must be specified before "
489 "ListenAddress.", filename, linenum);
490 if (options->num_ports >= MAX_PORTS)
491 fatal("%s line %d: too many ports.",
494 if (!arg || *arg == '\0')
495 fatal("%s line %d: missing port number.",
497 options->ports[options->num_ports++] = a2port(arg);
498 if (options->ports[options->num_ports-1] == 0)
499 fatal("%s line %d: Badly formatted port number.",
504 intptr = &options->server_key_bits;
507 if (!arg || *arg == '\0')
508 fatal("%s line %d: missing integer value.",
515 case sLoginGraceTime:
516 intptr = &options->login_grace_time;
519 if (!arg || *arg == '\0')
520 fatal("%s line %d: missing time value.",
522 if ((value = convtime(arg)) == -1)
523 fatal("%s line %d: invalid time value.",
529 case sKeyRegenerationTime:
530 intptr = &options->key_regeneration_time;
535 if (arg == NULL || *arg == '\0')
536 fatal("%s line %d: missing address",
538 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
539 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
540 && strchr(p+1, ':') != NULL) {
541 add_listen_addr(options, arg, 0);
546 fatal("%s line %d: bad address:port usage",
548 p = cleanhostname(p);
551 else if ((port = a2port(arg)) == 0)
552 fatal("%s line %d: bad port number", filename, linenum);
554 add_listen_addr(options, p, port);
560 if (!arg || *arg == '\0')
561 fatal("%s line %d: missing address family.",
563 intptr = &options->address_family;
564 if (options->listen_addrs != NULL)
565 fatal("%s line %d: address family must be specified before "
566 "ListenAddress.", filename, linenum);
567 if (strcasecmp(arg, "inet") == 0)
569 else if (strcasecmp(arg, "inet6") == 0)
571 else if (strcasecmp(arg, "any") == 0)
574 fatal("%s line %d: unsupported address family \"%s\".",
575 filename, linenum, arg);
581 intptr = &options->num_host_key_files;
582 if (*intptr >= MAX_HOSTKEYS)
583 fatal("%s line %d: too many host keys specified (max %d).",
584 filename, linenum, MAX_HOSTKEYS);
585 charptr = &options->host_key_files[*intptr];
588 if (!arg || *arg == '\0')
589 fatal("%s line %d: missing file name.",
591 if (*charptr == NULL) {
592 *charptr = tilde_expand_filename(arg, getuid());
593 /* increase optional counter */
595 *intptr = *intptr + 1;
600 charptr = &options->pid_file;
603 case sPermitRootLogin:
604 intptr = &options->permit_root_login;
606 if (!arg || *arg == '\0')
607 fatal("%s line %d: missing yes/"
608 "without-password/forced-commands-only/no "
609 "argument.", filename, linenum);
610 value = 0; /* silence compiler */
611 if (strcmp(arg, "without-password") == 0)
612 value = PERMIT_NO_PASSWD;
613 else if (strcmp(arg, "forced-commands-only") == 0)
614 value = PERMIT_FORCED_ONLY;
615 else if (strcmp(arg, "yes") == 0)
617 else if (strcmp(arg, "no") == 0)
620 fatal("%s line %d: Bad yes/"
621 "without-password/forced-commands-only/no "
622 "argument: %s", filename, linenum, arg);
628 intptr = &options->ignore_rhosts;
631 if (!arg || *arg == '\0')
632 fatal("%s line %d: missing yes/no argument.",
634 value = 0; /* silence compiler */
635 if (strcmp(arg, "yes") == 0)
637 else if (strcmp(arg, "no") == 0)
640 fatal("%s line %d: Bad yes/no argument: %s",
641 filename, linenum, arg);
646 case sIgnoreUserKnownHosts:
647 intptr = &options->ignore_user_known_hosts;
650 case sRhostsRSAAuthentication:
651 intptr = &options->rhosts_rsa_authentication;
654 case sHostbasedAuthentication:
655 intptr = &options->hostbased_authentication;
658 case sHostbasedUsesNameFromPacketOnly:
659 intptr = &options->hostbased_uses_name_from_packet_only;
662 case sRSAAuthentication:
663 intptr = &options->rsa_authentication;
666 case sPubkeyAuthentication:
667 intptr = &options->pubkey_authentication;
670 case sKerberosAuthentication:
671 intptr = &options->kerberos_authentication;
674 case sKerberosOrLocalPasswd:
675 intptr = &options->kerberos_or_local_passwd;
678 case sKerberosTicketCleanup:
679 intptr = &options->kerberos_ticket_cleanup;
682 case sKerberosGetAFSToken:
683 intptr = &options->kerberos_get_afs_token;
686 case sGssAuthentication:
687 intptr = &options->gss_authentication;
691 intptr = &options->gss_keyex;
694 case sGssCleanupCreds:
695 intptr = &options->gss_cleanup_creds;
699 case sAllowSessionHooks:
700 intptr = &options->session_hooks_allow;
702 case sSessionHookStartupCmd:
703 case sSessionHookShutdownCmd:
705 if (!arg || *arg == '\0')
706 fatal("%s line %d: empty session hook command",
708 if (opcode==sSessionHookStartupCmd)
709 options->session_hooks_startup_cmd = strdup(arg);
711 options->session_hooks_shutdown_cmd = strdup(arg);
715 case sPasswordAuthentication:
716 intptr = &options->password_authentication;
719 case sKbdInteractiveAuthentication:
720 intptr = &options->kbd_interactive_authentication;
723 case sChallengeResponseAuthentication:
724 intptr = &options->challenge_response_authentication;
728 intptr = &options->print_motd;
732 intptr = &options->print_lastlog;
736 intptr = &options->x11_forwarding;
739 case sX11DisplayOffset:
740 intptr = &options->x11_display_offset;
743 case sX11UseLocalhost:
744 intptr = &options->x11_use_localhost;
748 charptr = &options->xauth_location;
752 intptr = &options->strict_modes;
756 intptr = &options->tcp_keep_alive;
760 intptr = &options->permit_empty_passwd;
763 case sPermitUserEnvironment:
764 intptr = &options->permit_user_env;
768 intptr = &options->use_login;
772 intptr = &options->compression;
774 if (!arg || *arg == '\0')
775 fatal("%s line %d: missing yes/no/delayed "
776 "argument.", filename, linenum);
777 value = 0; /* silence compiler */
778 if (strcmp(arg, "delayed") == 0)
779 value = COMP_DELAYED;
780 else if (strcmp(arg, "yes") == 0)
782 else if (strcmp(arg, "no") == 0)
785 fatal("%s line %d: Bad yes/no/delayed "
786 "argument: %s", filename, linenum, arg);
792 intptr = &options->gateway_ports;
794 if (!arg || *arg == '\0')
795 fatal("%s line %d: missing yes/no/clientspecified "
796 "argument.", filename, linenum);
797 value = 0; /* silence compiler */
798 if (strcmp(arg, "clientspecified") == 0)
800 else if (strcmp(arg, "yes") == 0)
802 else if (strcmp(arg, "no") == 0)
805 fatal("%s line %d: Bad yes/no/clientspecified "
806 "argument: %s", filename, linenum, arg);
812 intptr = &options->use_dns;
816 intptr = (int *) &options->log_facility;
818 value = log_facility_number(arg);
819 if (value == SYSLOG_FACILITY_NOT_SET)
820 fatal("%.200s line %d: unsupported log facility '%s'",
821 filename, linenum, arg ? arg : "<NONE>");
823 *intptr = (SyslogFacility) value;
827 intptr = (int *) &options->log_level;
829 value = log_level_number(arg);
830 if (value == SYSLOG_LEVEL_NOT_SET)
831 fatal("%.200s line %d: unsupported log level '%s'",
832 filename, linenum, arg ? arg : "<NONE>");
834 *intptr = (LogLevel) value;
837 case sAllowTcpForwarding:
838 intptr = &options->allow_tcp_forwarding;
841 case sUsePrivilegeSeparation:
842 intptr = &use_privsep;
846 while ((arg = strdelim(&cp)) && *arg != '\0') {
847 if (options->num_allow_users >= MAX_ALLOW_USERS)
848 fatal("%s line %d: too many allow users.",
850 options->allow_users[options->num_allow_users++] =
856 while ((arg = strdelim(&cp)) && *arg != '\0') {
857 if (options->num_deny_users >= MAX_DENY_USERS)
858 fatal( "%s line %d: too many deny users.",
860 options->deny_users[options->num_deny_users++] =
866 while ((arg = strdelim(&cp)) && *arg != '\0') {
867 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
868 fatal("%s line %d: too many allow groups.",
870 options->allow_groups[options->num_allow_groups++] =
876 while ((arg = strdelim(&cp)) && *arg != '\0') {
877 if (options->num_deny_groups >= MAX_DENY_GROUPS)
878 fatal("%s line %d: too many deny groups.",
880 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
886 if (!arg || *arg == '\0')
887 fatal("%s line %d: Missing argument.", filename, linenum);
888 if (!ciphers_valid(arg))
889 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
890 filename, linenum, arg ? arg : "<NONE>");
891 if (options->ciphers == NULL)
892 options->ciphers = xstrdup(arg);
897 if (!arg || *arg == '\0')
898 fatal("%s line %d: Missing argument.", filename, linenum);
900 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
901 filename, linenum, arg ? arg : "<NONE>");
902 if (options->macs == NULL)
903 options->macs = xstrdup(arg);
907 intptr = &options->protocol;
909 if (!arg || *arg == '\0')
910 fatal("%s line %d: Missing argument.", filename, linenum);
911 value = proto_spec(arg);
912 if (value == SSH_PROTO_UNKNOWN)
913 fatal("%s line %d: Bad protocol spec '%s'.",
914 filename, linenum, arg ? arg : "<NONE>");
915 if (*intptr == SSH_PROTO_UNKNOWN)
920 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
921 fatal("%s line %d: too many subsystems defined.",
925 if (!arg || *arg == '\0')
926 fatal("%s line %d: Missing subsystem name.",
928 for (i = 0; i < options->num_subsystems; i++)
929 if (strcmp(arg, options->subsystem_name[i]) == 0)
930 fatal("%s line %d: Subsystem '%s' already defined.",
931 filename, linenum, arg);
932 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
934 if (!arg || *arg == '\0')
935 fatal("%s line %d: Missing subsystem command.",
937 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
938 options->num_subsystems++;
943 if (!arg || *arg == '\0')
944 fatal("%s line %d: Missing MaxStartups spec.",
946 if ((n = sscanf(arg, "%d:%d:%d",
947 &options->max_startups_begin,
948 &options->max_startups_rate,
949 &options->max_startups)) == 3) {
950 if (options->max_startups_begin >
951 options->max_startups ||
952 options->max_startups_rate > 100 ||
953 options->max_startups_rate < 1)
954 fatal("%s line %d: Illegal MaxStartups spec.",
957 fatal("%s line %d: Illegal MaxStartups spec.",
960 options->max_startups = options->max_startups_begin;
964 intptr = &options->max_authtries;
968 charptr = &options->banner;
971 * These options can contain %X options expanded at
972 * connect time, so that you can specify paths like:
974 * AuthorizedKeysFile /etc/ssh_keys/%u
976 case sAuthorizedKeysFile:
977 case sAuthorizedKeysFile2:
978 charptr = (opcode == sAuthorizedKeysFile ) ?
979 &options->authorized_keys_file :
980 &options->authorized_keys_file2;
983 case sClientAliveInterval:
984 intptr = &options->client_alive_interval;
987 case sClientAliveCountMax:
988 intptr = &options->client_alive_count_max;
992 while ((arg = strdelim(&cp)) && *arg != '\0') {
993 if (strchr(arg, '=') != NULL)
994 fatal("%s line %d: Invalid environment name.",
996 if (options->num_accept_env >= MAX_ACCEPT_ENV)
997 fatal("%s line %d: too many allow env.",
999 options->accept_env[options->num_accept_env++] =
1005 logit("%s line %d: Deprecated option %s",
1006 filename, linenum, arg);
1008 arg = strdelim(&cp);
1012 logit("%s line %d: Unsupported option %s",
1013 filename, linenum, arg);
1015 arg = strdelim(&cp);
1019 fatal("%s line %d: Missing handler for opcode %s (%d)",
1020 filename, linenum, arg, opcode);
1022 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1023 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1024 filename, linenum, arg);
1028 /* Reads the server configuration file. */
1031 load_server_config(const char *filename, Buffer *conf)
1033 char line[1024], *cp;
1036 debug2("%s: filename %s", __func__, filename);
1037 if ((f = fopen(filename, "r")) == NULL) {
1042 while (fgets(line, sizeof(line), f)) {
1044 * Trim out comments and strip whitespace
1045 * NB - preserve newlines, they are needed to reproduce
1046 * line numbers later for error messages
1048 if ((cp = strchr(line, '#')) != NULL)
1049 memcpy(cp, "\n", 2);
1050 cp = line + strspn(line, " \t\r");
1052 buffer_append(conf, cp, strlen(cp));
1054 buffer_append(conf, "\0", 1);
1056 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1060 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
1062 int linenum, bad_options = 0;
1063 char *cp, *obuf, *cbuf;
1065 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1067 obuf = cbuf = xstrdup(buffer_ptr(conf));
1069 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1070 if (process_server_config_line(options, cp, filename,
1075 if (bad_options > 0)
1076 fatal("%s: terminating, %d bad configuration options",
1077 filename, bad_options);