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.146 2005/12/08 18:34:11 reyk 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;
110 options->permit_tun = -1;
112 /* Needs to be accessable in many places */
117 fill_default_server_options(ServerOptions *options)
119 /* Portable-specific options */
120 if (options->use_pam == -1)
121 options->use_pam = 0;
123 /* Standard Options */
124 if (options->protocol == SSH_PROTO_UNKNOWN)
125 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
126 if (options->num_host_key_files == 0) {
127 /* fill default hostkeys for protocols */
128 if (options->protocol & SSH_PROTO_1)
129 options->host_key_files[options->num_host_key_files++] =
131 if (options->protocol & SSH_PROTO_2) {
132 options->host_key_files[options->num_host_key_files++] =
133 _PATH_HOST_RSA_KEY_FILE;
134 options->host_key_files[options->num_host_key_files++] =
135 _PATH_HOST_DSA_KEY_FILE;
138 if (options->num_ports == 0)
139 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
140 if (options->listen_addrs == NULL)
141 add_listen_addr(options, NULL, 0);
142 if (options->pid_file == NULL)
143 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
144 if (options->server_key_bits == -1)
145 options->server_key_bits = 768;
146 if (options->login_grace_time == -1)
147 options->login_grace_time = 120;
148 if (options->key_regeneration_time == -1)
149 options->key_regeneration_time = 3600;
150 if (options->permit_root_login == PERMIT_NOT_SET)
151 options->permit_root_login = PERMIT_YES;
152 if (options->ignore_rhosts == -1)
153 options->ignore_rhosts = 1;
154 if (options->ignore_user_known_hosts == -1)
155 options->ignore_user_known_hosts = 0;
156 if (options->print_motd == -1)
157 options->print_motd = 1;
158 if (options->print_lastlog == -1)
159 options->print_lastlog = 1;
160 if (options->x11_forwarding == -1)
161 options->x11_forwarding = 0;
162 if (options->x11_display_offset == -1)
163 options->x11_display_offset = 10;
164 if (options->x11_use_localhost == -1)
165 options->x11_use_localhost = 1;
166 if (options->xauth_location == NULL)
167 options->xauth_location = _PATH_XAUTH;
168 if (options->strict_modes == -1)
169 options->strict_modes = 1;
170 if (options->tcp_keep_alive == -1)
171 options->tcp_keep_alive = 1;
172 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
173 options->log_facility = SYSLOG_FACILITY_AUTH;
174 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
175 options->log_level = SYSLOG_LEVEL_INFO;
176 if (options->rhosts_rsa_authentication == -1)
177 options->rhosts_rsa_authentication = 0;
178 if (options->hostbased_authentication == -1)
179 options->hostbased_authentication = 0;
180 if (options->hostbased_uses_name_from_packet_only == -1)
181 options->hostbased_uses_name_from_packet_only = 0;
182 if (options->rsa_authentication == -1)
183 options->rsa_authentication = 1;
184 if (options->pubkey_authentication == -1)
185 options->pubkey_authentication = 1;
186 if (options->kerberos_authentication == -1)
187 options->kerberos_authentication = 0;
188 if (options->kerberos_or_local_passwd == -1)
189 options->kerberos_or_local_passwd = 1;
190 if (options->kerberos_ticket_cleanup == -1)
191 options->kerberos_ticket_cleanup = 1;
192 if (options->kerberos_get_afs_token == -1)
193 options->kerberos_get_afs_token = 0;
194 if (options->gss_authentication == -1)
195 options->gss_authentication = 1;
196 if (options->gss_keyex == -1)
197 options->gss_keyex = 1;
198 if (options->gss_cleanup_creds == -1)
199 options->gss_cleanup_creds = 1;
200 if (options->password_authentication == -1)
201 options->password_authentication = 1;
202 if (options->kbd_interactive_authentication == -1)
203 options->kbd_interactive_authentication = 0;
204 if (options->challenge_response_authentication == -1)
205 options->challenge_response_authentication = 1;
206 if (options->permit_empty_passwd == -1)
207 options->permit_empty_passwd = 0;
208 if (options->permit_user_env == -1)
209 options->permit_user_env = 0;
210 if (options->use_login == -1)
211 options->use_login = 0;
212 if (options->compression == -1)
213 options->compression = COMP_DELAYED;
214 if (options->allow_tcp_forwarding == -1)
215 options->allow_tcp_forwarding = 1;
216 if (options->gateway_ports == -1)
217 options->gateway_ports = 0;
218 if (options->max_startups == -1)
219 options->max_startups = 10;
220 if (options->max_startups_rate == -1)
221 options->max_startups_rate = 100; /* 100% */
222 if (options->max_startups_begin == -1)
223 options->max_startups_begin = options->max_startups;
224 if (options->max_authtries == -1)
225 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
226 if (options->use_dns == -1)
227 options->use_dns = 1;
228 if (options->client_alive_interval == -1)
229 options->client_alive_interval = 0;
230 if (options->client_alive_count_max == -1)
231 options->client_alive_count_max = 3;
232 if (options->authorized_keys_file2 == NULL) {
233 /* authorized_keys_file2 falls back to authorized_keys_file */
234 if (options->authorized_keys_file != NULL)
235 options->authorized_keys_file2 = options->authorized_keys_file;
237 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
239 if (options->authorized_keys_file == NULL)
240 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
241 if (options->permit_tun == -1)
242 options->permit_tun = SSH_TUNMODE_NO;
244 /* Turn privilege separation on by default */
245 if (use_privsep == -1)
249 if (use_privsep && options->compression == 1) {
250 error("This platform does not support both privilege "
251 "separation and compression");
252 error("Compression disabled");
253 options->compression = 0;
259 /* Keyword tokens. */
261 sBadOption, /* == unknown option */
262 /* Portable-specific options */
264 /* Standard Options */
265 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
266 sPermitRootLogin, sLogFacility, sLogLevel,
267 sRhostsRSAAuthentication, sRSAAuthentication,
268 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
269 sKerberosGetAFSToken,
270 sKerberosTgtPassing, sChallengeResponseAuthentication,
272 sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
274 sPasswordAuthentication, sKbdInteractiveAuthentication,
275 sListenAddress, sAddressFamily,
276 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
277 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
278 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
279 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
280 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
281 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
282 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
283 sMaxStartups, sMaxAuthTries,
284 sBanner, sUseDNS, sHostbasedAuthentication,
285 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
286 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
288 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
289 sUsePrivilegeSeparation,
290 sDeprecated, sUnsupported
293 /* Textual representation of the tokens. */
296 ServerOpCodes opcode;
298 /* Portable-specific options */
300 { "usepam", sUsePAM },
302 { "usepam", sUnsupported },
304 { "pamauthenticationviakbdint", sDeprecated },
305 /* Standard Options */
307 { "hostkey", sHostKeyFile },
308 { "hostdsakey", sHostKeyFile }, /* alias */
309 { "pidfile", sPidFile },
310 { "serverkeybits", sServerKeyBits },
311 { "logingracetime", sLoginGraceTime },
312 { "keyregenerationinterval", sKeyRegenerationTime },
313 { "permitrootlogin", sPermitRootLogin },
314 { "syslogfacility", sLogFacility },
315 { "loglevel", sLogLevel },
316 { "rhostsauthentication", sDeprecated },
317 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
318 { "hostbasedauthentication", sHostbasedAuthentication },
319 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
320 { "rsaauthentication", sRSAAuthentication },
321 { "pubkeyauthentication", sPubkeyAuthentication },
322 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
324 { "kerberosauthentication", sKerberosAuthentication },
325 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
326 { "kerberosticketcleanup", sKerberosTicketCleanup },
328 { "kerberosgetafstoken", sKerberosGetAFSToken },
330 { "kerberosgetafstoken", sUnsupported },
333 { "kerberosauthentication", sUnsupported },
334 { "kerberosorlocalpasswd", sUnsupported },
335 { "kerberosticketcleanup", sUnsupported },
336 { "kerberosgetafstoken", sUnsupported },
338 { "kerberostgtpassing", sUnsupported },
339 { "afstokenpassing", sUnsupported },
341 { "gssapiauthentication", sGssAuthentication },
342 { "gssapikeyexchange", sGssKeyEx },
343 { "gssapicleanupcredentials", sGssCleanupCreds },
345 { "gssapiauthentication", sUnsupported },
346 { "gssapikeyexchange", sUnsupported },
347 { "gssapicleanupcredentials", sUnsupported },
350 { "allowsessionhooks", sAllowSessionHooks },
351 { "sessionhookstartupcmd", sSessionHookStartupCmd },
352 { "sessionhookshutdowncmd", sSessionHookShutdownCmd },
354 { "passwordauthentication", sPasswordAuthentication },
355 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
356 { "challengeresponseauthentication", sChallengeResponseAuthentication },
357 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
358 { "checkmail", sDeprecated },
359 { "listenaddress", sListenAddress },
360 { "addressfamily", sAddressFamily },
361 { "printmotd", sPrintMotd },
362 { "printlastlog", sPrintLastLog },
363 { "ignorerhosts", sIgnoreRhosts },
364 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
365 { "x11forwarding", sX11Forwarding },
366 { "x11displayoffset", sX11DisplayOffset },
367 { "x11uselocalhost", sX11UseLocalhost },
368 { "xauthlocation", sXAuthLocation },
369 { "strictmodes", sStrictModes },
370 { "permitemptypasswords", sEmptyPasswd },
371 { "permituserenvironment", sPermitUserEnvironment },
372 { "uselogin", sUseLogin },
373 { "compression", sCompression },
374 { "tcpkeepalive", sTCPKeepAlive },
375 { "keepalive", sTCPKeepAlive }, /* obsolete alias */
376 { "allowtcpforwarding", sAllowTcpForwarding },
377 { "allowusers", sAllowUsers },
378 { "denyusers", sDenyUsers },
379 { "allowgroups", sAllowGroups },
380 { "denygroups", sDenyGroups },
381 { "ciphers", sCiphers },
383 { "protocol", sProtocol },
384 { "gatewayports", sGatewayPorts },
385 { "subsystem", sSubsystem },
386 { "maxstartups", sMaxStartups },
387 { "maxauthtries", sMaxAuthTries },
388 { "banner", sBanner },
389 { "usedns", sUseDNS },
390 { "verifyreversemapping", sDeprecated },
391 { "reversemappingcheck", sDeprecated },
392 { "clientaliveinterval", sClientAliveInterval },
393 { "clientalivecountmax", sClientAliveCountMax },
394 { "authorizedkeysfile", sAuthorizedKeysFile },
395 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
396 { "useprivilegeseparation", sUsePrivilegeSeparation},
397 { "acceptenv", sAcceptEnv },
398 { "permittunnel", sPermitTunnel },
403 * Returns the number of the token pointed to by cp or sBadOption.
407 parse_token(const char *cp, const char *filename,
412 for (i = 0; keywords[i].name; i++)
413 if (strcasecmp(cp, keywords[i].name) == 0)
414 return keywords[i].opcode;
416 error("%s: line %d: Bad configuration option: %s",
417 filename, linenum, cp);
422 add_listen_addr(ServerOptions *options, char *addr, u_short port)
426 if (options->num_ports == 0)
427 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
428 if (options->address_family == -1)
429 options->address_family = AF_UNSPEC;
431 for (i = 0; i < options->num_ports; i++)
432 add_one_listen_addr(options, addr, options->ports[i]);
434 add_one_listen_addr(options, addr, port);
438 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
440 struct addrinfo hints, *ai, *aitop;
441 char strport[NI_MAXSERV];
444 memset(&hints, 0, sizeof(hints));
445 hints.ai_family = options->address_family;
446 hints.ai_socktype = SOCK_STREAM;
447 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
448 snprintf(strport, sizeof strport, "%u", port);
449 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
450 fatal("bad addr or host: %s (%s)",
451 addr ? addr : "<NULL>",
452 gai_strerror(gaierr));
453 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
455 ai->ai_next = options->listen_addrs;
456 options->listen_addrs = aitop;
460 process_server_config_line(ServerOptions *options, char *line,
461 const char *filename, int linenum)
463 char *cp, **charptr, *arg, *p;
464 int *intptr, value, n;
465 ServerOpCodes opcode;
471 /* Ignore leading whitespace */
474 if (!arg || !*arg || *arg == '#')
478 opcode = parse_token(arg, filename, linenum);
480 /* Portable-specific options */
482 intptr = &options->use_pam;
485 /* Standard Options */
489 /* ignore ports from configfile if cmdline specifies ports */
490 if (options->ports_from_cmdline)
492 if (options->listen_addrs != NULL)
493 fatal("%s line %d: ports must be specified before "
494 "ListenAddress.", filename, linenum);
495 if (options->num_ports >= MAX_PORTS)
496 fatal("%s line %d: too many ports.",
499 if (!arg || *arg == '\0')
500 fatal("%s line %d: missing port number.",
502 options->ports[options->num_ports++] = a2port(arg);
503 if (options->ports[options->num_ports-1] == 0)
504 fatal("%s line %d: Badly formatted port number.",
509 intptr = &options->server_key_bits;
512 if (!arg || *arg == '\0')
513 fatal("%s line %d: missing integer value.",
520 case sLoginGraceTime:
521 intptr = &options->login_grace_time;
524 if (!arg || *arg == '\0')
525 fatal("%s line %d: missing time value.",
527 if ((value = convtime(arg)) == -1)
528 fatal("%s line %d: invalid time value.",
534 case sKeyRegenerationTime:
535 intptr = &options->key_regeneration_time;
540 if (arg == NULL || *arg == '\0')
541 fatal("%s line %d: missing address",
543 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
544 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
545 && strchr(p+1, ':') != NULL) {
546 add_listen_addr(options, arg, 0);
551 fatal("%s line %d: bad address:port usage",
553 p = cleanhostname(p);
556 else if ((port = a2port(arg)) == 0)
557 fatal("%s line %d: bad port number", filename, linenum);
559 add_listen_addr(options, p, port);
565 if (!arg || *arg == '\0')
566 fatal("%s line %d: missing address family.",
568 intptr = &options->address_family;
569 if (options->listen_addrs != NULL)
570 fatal("%s line %d: address family must be specified before "
571 "ListenAddress.", filename, linenum);
572 if (strcasecmp(arg, "inet") == 0)
574 else if (strcasecmp(arg, "inet6") == 0)
576 else if (strcasecmp(arg, "any") == 0)
579 fatal("%s line %d: unsupported address family \"%s\".",
580 filename, linenum, arg);
586 intptr = &options->num_host_key_files;
587 if (*intptr >= MAX_HOSTKEYS)
588 fatal("%s line %d: too many host keys specified (max %d).",
589 filename, linenum, MAX_HOSTKEYS);
590 charptr = &options->host_key_files[*intptr];
593 if (!arg || *arg == '\0')
594 fatal("%s line %d: missing file name.",
596 if (*charptr == NULL) {
597 *charptr = tilde_expand_filename(arg, getuid());
598 /* increase optional counter */
600 *intptr = *intptr + 1;
605 charptr = &options->pid_file;
608 case sPermitRootLogin:
609 intptr = &options->permit_root_login;
611 if (!arg || *arg == '\0')
612 fatal("%s line %d: missing yes/"
613 "without-password/forced-commands-only/no "
614 "argument.", filename, linenum);
615 value = 0; /* silence compiler */
616 if (strcmp(arg, "without-password") == 0)
617 value = PERMIT_NO_PASSWD;
618 else if (strcmp(arg, "forced-commands-only") == 0)
619 value = PERMIT_FORCED_ONLY;
620 else if (strcmp(arg, "yes") == 0)
622 else if (strcmp(arg, "no") == 0)
625 fatal("%s line %d: Bad yes/"
626 "without-password/forced-commands-only/no "
627 "argument: %s", filename, linenum, arg);
633 intptr = &options->ignore_rhosts;
636 if (!arg || *arg == '\0')
637 fatal("%s line %d: missing yes/no argument.",
639 value = 0; /* silence compiler */
640 if (strcmp(arg, "yes") == 0)
642 else if (strcmp(arg, "no") == 0)
645 fatal("%s line %d: Bad yes/no argument: %s",
646 filename, linenum, arg);
651 case sIgnoreUserKnownHosts:
652 intptr = &options->ignore_user_known_hosts;
655 case sRhostsRSAAuthentication:
656 intptr = &options->rhosts_rsa_authentication;
659 case sHostbasedAuthentication:
660 intptr = &options->hostbased_authentication;
663 case sHostbasedUsesNameFromPacketOnly:
664 intptr = &options->hostbased_uses_name_from_packet_only;
667 case sRSAAuthentication:
668 intptr = &options->rsa_authentication;
671 case sPubkeyAuthentication:
672 intptr = &options->pubkey_authentication;
675 case sKerberosAuthentication:
676 intptr = &options->kerberos_authentication;
679 case sKerberosOrLocalPasswd:
680 intptr = &options->kerberos_or_local_passwd;
683 case sKerberosTicketCleanup:
684 intptr = &options->kerberos_ticket_cleanup;
687 case sKerberosGetAFSToken:
688 intptr = &options->kerberos_get_afs_token;
691 case sGssAuthentication:
692 intptr = &options->gss_authentication;
696 intptr = &options->gss_keyex;
699 case sGssCleanupCreds:
700 intptr = &options->gss_cleanup_creds;
704 case sAllowSessionHooks:
705 intptr = &options->session_hooks_allow;
707 case sSessionHookStartupCmd:
708 case sSessionHookShutdownCmd:
710 if (!arg || *arg == '\0')
711 fatal("%s line %d: empty session hook command",
713 if (opcode==sSessionHookStartupCmd)
714 options->session_hooks_startup_cmd = strdup(arg);
716 options->session_hooks_shutdown_cmd = strdup(arg);
720 case sPasswordAuthentication:
721 intptr = &options->password_authentication;
724 case sKbdInteractiveAuthentication:
725 intptr = &options->kbd_interactive_authentication;
728 case sChallengeResponseAuthentication:
729 intptr = &options->challenge_response_authentication;
733 intptr = &options->print_motd;
737 intptr = &options->print_lastlog;
741 intptr = &options->x11_forwarding;
744 case sX11DisplayOffset:
745 intptr = &options->x11_display_offset;
748 case sX11UseLocalhost:
749 intptr = &options->x11_use_localhost;
753 charptr = &options->xauth_location;
757 intptr = &options->strict_modes;
761 intptr = &options->tcp_keep_alive;
765 intptr = &options->permit_empty_passwd;
768 case sPermitUserEnvironment:
769 intptr = &options->permit_user_env;
773 intptr = &options->use_login;
777 intptr = &options->compression;
779 if (!arg || *arg == '\0')
780 fatal("%s line %d: missing yes/no/delayed "
781 "argument.", filename, linenum);
782 value = 0; /* silence compiler */
783 if (strcmp(arg, "delayed") == 0)
784 value = COMP_DELAYED;
785 else if (strcmp(arg, "yes") == 0)
787 else if (strcmp(arg, "no") == 0)
790 fatal("%s line %d: Bad yes/no/delayed "
791 "argument: %s", filename, linenum, arg);
797 intptr = &options->gateway_ports;
799 if (!arg || *arg == '\0')
800 fatal("%s line %d: missing yes/no/clientspecified "
801 "argument.", filename, linenum);
802 value = 0; /* silence compiler */
803 if (strcmp(arg, "clientspecified") == 0)
805 else if (strcmp(arg, "yes") == 0)
807 else if (strcmp(arg, "no") == 0)
810 fatal("%s line %d: Bad yes/no/clientspecified "
811 "argument: %s", filename, linenum, arg);
817 intptr = &options->use_dns;
821 intptr = (int *) &options->log_facility;
823 value = log_facility_number(arg);
824 if (value == SYSLOG_FACILITY_NOT_SET)
825 fatal("%.200s line %d: unsupported log facility '%s'",
826 filename, linenum, arg ? arg : "<NONE>");
828 *intptr = (SyslogFacility) value;
832 intptr = (int *) &options->log_level;
834 value = log_level_number(arg);
835 if (value == SYSLOG_LEVEL_NOT_SET)
836 fatal("%.200s line %d: unsupported log level '%s'",
837 filename, linenum, arg ? arg : "<NONE>");
839 *intptr = (LogLevel) value;
842 case sAllowTcpForwarding:
843 intptr = &options->allow_tcp_forwarding;
846 case sUsePrivilegeSeparation:
847 intptr = &use_privsep;
851 while ((arg = strdelim(&cp)) && *arg != '\0') {
852 if (options->num_allow_users >= MAX_ALLOW_USERS)
853 fatal("%s line %d: too many allow users.",
855 options->allow_users[options->num_allow_users++] =
861 while ((arg = strdelim(&cp)) && *arg != '\0') {
862 if (options->num_deny_users >= MAX_DENY_USERS)
863 fatal( "%s line %d: too many deny users.",
865 options->deny_users[options->num_deny_users++] =
871 while ((arg = strdelim(&cp)) && *arg != '\0') {
872 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
873 fatal("%s line %d: too many allow groups.",
875 options->allow_groups[options->num_allow_groups++] =
881 while ((arg = strdelim(&cp)) && *arg != '\0') {
882 if (options->num_deny_groups >= MAX_DENY_GROUPS)
883 fatal("%s line %d: too many deny groups.",
885 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
891 if (!arg || *arg == '\0')
892 fatal("%s line %d: Missing argument.", filename, linenum);
893 if (!ciphers_valid(arg))
894 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
895 filename, linenum, arg ? arg : "<NONE>");
896 if (options->ciphers == NULL)
897 options->ciphers = xstrdup(arg);
902 if (!arg || *arg == '\0')
903 fatal("%s line %d: Missing argument.", filename, linenum);
905 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
906 filename, linenum, arg ? arg : "<NONE>");
907 if (options->macs == NULL)
908 options->macs = xstrdup(arg);
912 intptr = &options->protocol;
914 if (!arg || *arg == '\0')
915 fatal("%s line %d: Missing argument.", filename, linenum);
916 value = proto_spec(arg);
917 if (value == SSH_PROTO_UNKNOWN)
918 fatal("%s line %d: Bad protocol spec '%s'.",
919 filename, linenum, arg ? arg : "<NONE>");
920 if (*intptr == SSH_PROTO_UNKNOWN)
925 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
926 fatal("%s line %d: too many subsystems defined.",
930 if (!arg || *arg == '\0')
931 fatal("%s line %d: Missing subsystem name.",
933 for (i = 0; i < options->num_subsystems; i++)
934 if (strcmp(arg, options->subsystem_name[i]) == 0)
935 fatal("%s line %d: Subsystem '%s' already defined.",
936 filename, linenum, arg);
937 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
939 if (!arg || *arg == '\0')
940 fatal("%s line %d: Missing subsystem command.",
942 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
943 options->num_subsystems++;
948 if (!arg || *arg == '\0')
949 fatal("%s line %d: Missing MaxStartups spec.",
951 if ((n = sscanf(arg, "%d:%d:%d",
952 &options->max_startups_begin,
953 &options->max_startups_rate,
954 &options->max_startups)) == 3) {
955 if (options->max_startups_begin >
956 options->max_startups ||
957 options->max_startups_rate > 100 ||
958 options->max_startups_rate < 1)
959 fatal("%s line %d: Illegal MaxStartups spec.",
962 fatal("%s line %d: Illegal MaxStartups spec.",
965 options->max_startups = options->max_startups_begin;
969 intptr = &options->max_authtries;
973 charptr = &options->banner;
976 * These options can contain %X options expanded at
977 * connect time, so that you can specify paths like:
979 * AuthorizedKeysFile /etc/ssh_keys/%u
981 case sAuthorizedKeysFile:
982 case sAuthorizedKeysFile2:
983 charptr = (opcode == sAuthorizedKeysFile ) ?
984 &options->authorized_keys_file :
985 &options->authorized_keys_file2;
988 case sClientAliveInterval:
989 intptr = &options->client_alive_interval;
992 case sClientAliveCountMax:
993 intptr = &options->client_alive_count_max;
997 while ((arg = strdelim(&cp)) && *arg != '\0') {
998 if (strchr(arg, '=') != NULL)
999 fatal("%s line %d: Invalid environment name.",
1001 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1002 fatal("%s line %d: too many allow env.",
1004 options->accept_env[options->num_accept_env++] =
1010 intptr = &options->permit_tun;
1011 arg = strdelim(&cp);
1012 if (!arg || *arg == '\0')
1013 fatal("%s line %d: Missing yes/point-to-point/"
1014 "ethernet/no argument.", filename, linenum);
1015 value = 0; /* silence compiler */
1016 if (strcasecmp(arg, "ethernet") == 0)
1017 value = SSH_TUNMODE_ETHERNET;
1018 else if (strcasecmp(arg, "point-to-point") == 0)
1019 value = SSH_TUNMODE_POINTOPOINT;
1020 else if (strcasecmp(arg, "yes") == 0)
1021 value = SSH_TUNMODE_YES;
1022 else if (strcasecmp(arg, "no") == 0)
1023 value = SSH_TUNMODE_NO;
1025 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1026 "no argument: %s", filename, linenum, arg);
1032 logit("%s line %d: Deprecated option %s",
1033 filename, linenum, arg);
1035 arg = strdelim(&cp);
1039 logit("%s line %d: Unsupported option %s",
1040 filename, linenum, arg);
1042 arg = strdelim(&cp);
1046 fatal("%s line %d: Missing handler for opcode %s (%d)",
1047 filename, linenum, arg, opcode);
1049 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1050 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1051 filename, linenum, arg);
1055 /* Reads the server configuration file. */
1058 load_server_config(const char *filename, Buffer *conf)
1060 char line[1024], *cp;
1063 debug2("%s: filename %s", __func__, filename);
1064 if ((f = fopen(filename, "r")) == NULL) {
1069 while (fgets(line, sizeof(line), f)) {
1071 * Trim out comments and strip whitespace
1072 * NB - preserve newlines, they are needed to reproduce
1073 * line numbers later for error messages
1075 if ((cp = strchr(line, '#')) != NULL)
1076 memcpy(cp, "\n", 2);
1077 cp = line + strspn(line, " \t\r");
1079 buffer_append(conf, cp, strlen(cp));
1081 buffer_append(conf, "\0", 1);
1083 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1087 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
1089 int linenum, bad_options = 0;
1090 char *cp, *obuf, *cbuf;
1092 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1094 obuf = cbuf = xstrdup(buffer_ptr(conf));
1096 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1097 if (process_server_config_line(options, cp, filename,
1102 if (bad_options > 0)
1103 fatal("%s: terminating, %d bad configuration options",
1104 filename, bad_options);