1 /* $OpenBSD: servconf.c,v 1.154 2006/07/12 22:28:52 stevesk Exp $ */
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is
9 * incompatible with the protocol description in the RFC file, it must be
10 * called by a name other than "ssh" or "Secure Shell".
15 #include <sys/types.h>
16 #include <sys/socket.h>
18 #if defined(HAVE_NETDB_H)
27 #include "pathnames.h"
34 static void add_listen_addr(ServerOptions *, char *, u_short);
35 static void add_one_listen_addr(ServerOptions *, char *, u_short);
37 /* Use of privilege separation or not */
38 extern int use_privsep;
41 /* Initializes the server options to their default values. */
44 initialize_server_options(ServerOptions *options)
46 memset(options, 0, sizeof(*options));
48 /* Portable-specific options */
49 options->use_pam = -1;
51 /* Standard Options */
52 options->num_ports = 0;
53 options->ports_from_cmdline = 0;
54 options->listen_addrs = NULL;
55 options->address_family = -1;
56 options->num_host_key_files = 0;
57 options->pid_file = NULL;
58 options->server_key_bits = -1;
59 options->login_grace_time = -1;
60 options->key_regeneration_time = -1;
61 options->permit_root_login = PERMIT_NOT_SET;
62 options->ignore_rhosts = -1;
63 options->ignore_user_known_hosts = -1;
64 options->print_motd = -1;
65 options->print_lastlog = -1;
66 options->x11_forwarding = -1;
67 options->x11_display_offset = -1;
68 options->x11_use_localhost = -1;
69 options->xauth_location = NULL;
70 options->strict_modes = -1;
71 options->tcp_keep_alive = -1;
72 options->log_facility = SYSLOG_FACILITY_NOT_SET;
73 options->log_level = SYSLOG_LEVEL_NOT_SET;
74 options->rhosts_rsa_authentication = -1;
75 options->hostbased_authentication = -1;
76 options->hostbased_uses_name_from_packet_only = -1;
77 options->rsa_authentication = -1;
78 options->pubkey_authentication = -1;
79 options->kerberos_authentication = -1;
80 options->kerberos_or_local_passwd = -1;
81 options->kerberos_ticket_cleanup = -1;
82 options->kerberos_get_afs_token = -1;
83 options->gss_authentication=-1;
84 options->gss_cleanup_creds = -1;
85 options->password_authentication = -1;
86 options->kbd_interactive_authentication = -1;
87 options->challenge_response_authentication = -1;
88 options->permit_empty_passwd = -1;
89 options->permit_user_env = -1;
90 options->use_login = -1;
91 options->compression = -1;
92 options->allow_tcp_forwarding = -1;
93 options->num_allow_users = 0;
94 options->num_deny_users = 0;
95 options->num_allow_groups = 0;
96 options->num_deny_groups = 0;
97 options->ciphers = NULL;
99 options->protocol = SSH_PROTO_UNKNOWN;
100 options->gateway_ports = -1;
101 options->num_subsystems = 0;
102 options->max_startups_begin = -1;
103 options->max_startups_rate = -1;
104 options->max_startups = -1;
105 options->max_authtries = -1;
106 options->banner = NULL;
107 options->use_dns = -1;
108 options->client_alive_interval = -1;
109 options->client_alive_count_max = -1;
110 options->authorized_keys_file = NULL;
111 options->authorized_keys_file2 = NULL;
112 options->num_accept_env = 0;
113 options->permit_tun = -1;
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 = 0;
196 if (options->gss_cleanup_creds == -1)
197 options->gss_cleanup_creds = 1;
198 if (options->password_authentication == -1)
199 options->password_authentication = 1;
200 if (options->kbd_interactive_authentication == -1)
201 options->kbd_interactive_authentication = 0;
202 if (options->challenge_response_authentication == -1)
203 options->challenge_response_authentication = 1;
204 if (options->permit_empty_passwd == -1)
205 options->permit_empty_passwd = 0;
206 if (options->permit_user_env == -1)
207 options->permit_user_env = 0;
208 if (options->use_login == -1)
209 options->use_login = 0;
210 if (options->compression == -1)
211 options->compression = COMP_DELAYED;
212 if (options->allow_tcp_forwarding == -1)
213 options->allow_tcp_forwarding = 1;
214 if (options->gateway_ports == -1)
215 options->gateway_ports = 0;
216 if (options->max_startups == -1)
217 options->max_startups = 10;
218 if (options->max_startups_rate == -1)
219 options->max_startups_rate = 100; /* 100% */
220 if (options->max_startups_begin == -1)
221 options->max_startups_begin = options->max_startups;
222 if (options->max_authtries == -1)
223 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
224 if (options->use_dns == -1)
225 options->use_dns = 1;
226 if (options->client_alive_interval == -1)
227 options->client_alive_interval = 0;
228 if (options->client_alive_count_max == -1)
229 options->client_alive_count_max = 3;
230 if (options->authorized_keys_file2 == NULL) {
231 /* authorized_keys_file2 falls back to authorized_keys_file */
232 if (options->authorized_keys_file != NULL)
233 options->authorized_keys_file2 = options->authorized_keys_file;
235 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
237 if (options->authorized_keys_file == NULL)
238 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
239 if (options->permit_tun == -1)
240 options->permit_tun = SSH_TUNMODE_NO;
242 /* Turn privilege separation on by default */
243 if (use_privsep == -1)
247 if (use_privsep && options->compression == 1) {
248 error("This platform does not support both privilege "
249 "separation and compression");
250 error("Compression disabled");
251 options->compression = 0;
257 /* Keyword tokens. */
259 sBadOption, /* == unknown option */
260 /* Portable-specific options */
262 /* Standard Options */
263 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
264 sPermitRootLogin, sLogFacility, sLogLevel,
265 sRhostsRSAAuthentication, sRSAAuthentication,
266 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
267 sKerberosGetAFSToken,
268 sKerberosTgtPassing, sChallengeResponseAuthentication,
269 sPasswordAuthentication, sKbdInteractiveAuthentication,
270 sListenAddress, sAddressFamily,
271 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
272 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
273 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
274 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
275 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
276 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
277 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
278 sMaxStartups, sMaxAuthTries,
279 sBanner, sUseDNS, sHostbasedAuthentication,
280 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
281 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
282 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
284 sUsePrivilegeSeparation,
285 sDeprecated, sUnsupported
288 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
289 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
290 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
292 /* Textual representation of the tokens. */
295 ServerOpCodes opcode;
298 /* Portable-specific options */
300 { "usepam", sUsePAM, SSHCFG_GLOBAL },
302 { "usepam", sUnsupported, SSHCFG_GLOBAL },
304 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
305 /* Standard Options */
306 { "port", sPort, SSHCFG_GLOBAL },
307 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
308 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
309 { "pidfile", sPidFile, SSHCFG_GLOBAL },
310 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
311 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
312 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
313 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
314 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
315 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
316 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
317 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
318 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
319 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
320 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
321 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
322 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
324 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
325 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
326 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
328 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
330 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
333 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
334 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
335 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
336 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
338 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
339 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
341 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
342 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
344 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
345 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
347 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
348 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
349 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
350 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
351 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
352 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
353 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
354 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
355 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
356 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
357 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
358 { "x11forwarding", sX11Forwarding, SSHCFG_GLOBAL },
359 { "x11displayoffset", sX11DisplayOffset, SSHCFG_GLOBAL },
360 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_GLOBAL },
361 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
362 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
363 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
364 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
365 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
366 { "compression", sCompression, SSHCFG_GLOBAL },
367 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
368 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
369 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
370 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
371 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
372 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
373 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
374 { "ciphers", sCiphers, SSHCFG_GLOBAL },
375 { "macs", sMacs, SSHCFG_GLOBAL },
376 { "protocol", sProtocol, SSHCFG_GLOBAL },
377 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
378 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
379 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
380 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
381 { "banner", sBanner, SSHCFG_GLOBAL },
382 { "usedns", sUseDNS, SSHCFG_GLOBAL },
383 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
384 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
385 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
386 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
387 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
388 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
389 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
390 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
391 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
392 { NULL, sBadOption, 0 }
396 * Returns the number of the token pointed to by cp or sBadOption.
400 parse_token(const char *cp, const char *filename,
401 int linenum, u_int *flags)
405 for (i = 0; keywords[i].name; i++)
406 if (strcasecmp(cp, keywords[i].name) == 0) {
407 *flags = keywords[i].flags;
408 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 * The strategy for the Match blocks is that the config file is parsed twice.
457 * The first time is at startup. activep is initialized to 1 and the
458 * directives in the global context are processed and acted on. Hitting a
459 * Match directive unsets activep and the directives inside the block are
460 * checked for syntax only.
462 * The second time is after a connection has been established but before
463 * authentication. activep is initialized to 2 and global config directives
464 * are ignored since they have already been processed. If the criteria in a
465 * Match block is met, activep is set and the subsequent directives
466 * processed and actioned until EOF or another Match block unsets it. Any
467 * options set are copied into the main server config.
469 * Potential additions/improvements:
470 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
472 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
473 * Match Address 192.168.0.*
478 * AllowTcpForwarding yes
479 * GatewayPorts clientspecified
482 * - Add a PermittedChannelRequests directive
484 * PermittedChannelRequests session,forwarded-tcpip
488 match_cfg_line(char **condition, int line, const char *user, const char *host,
492 char *arg, *attrib, *cp = *condition;
496 debug3("checking syntax for 'Match %s'", cp);
498 debug3("checking match for '%s' user %s host %s addr %s", cp,
499 user ? user : "(null)", host ? host : "(null)",
500 address ? address : "(null)");
502 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
503 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
504 error("Missing Match criteria for %s", attrib);
508 if (strcasecmp(attrib, "user") == 0) {
513 if (match_pattern_list(user, arg, len, 0) != 1)
516 debug("user %.100s matched 'User %.100s' at "
517 "line %d", user, arg, line);
518 } else if (strcasecmp(attrib, "host") == 0) {
523 if (match_hostname(host, arg, len) != 1)
526 debug("connection from %.100s matched 'Host "
527 "%.100s' at line %d", host, arg, line);
528 } else if (strcasecmp(attrib, "address") == 0) {
529 debug("address '%s' arg '%s'", address, arg);
534 if (match_hostname(address, arg, len) != 1)
537 debug("connection from %.100s matched 'Address "
538 "%.100s' at line %d", address, arg, line);
540 error("Unsupported Match attribute %s", attrib);
545 debug3("match %sfound", result ? "" : "not ");
551 process_server_config_line(ServerOptions *options, char *line,
552 const char *filename, int linenum, int *activep, const char *user,
553 const char *host, const char *address)
555 char *cp, **charptr, *arg, *p;
556 int cmdline = 0, *intptr, value, n;
557 ServerOpCodes opcode;
563 if ((arg = strdelim(&cp)) == NULL)
565 /* Ignore leading whitespace */
568 if (!arg || !*arg || *arg == '#')
572 opcode = parse_token(arg, filename, linenum, &flags);
574 if (activep == NULL) { /* We are processing a command line directive */
578 if (*activep && opcode != sMatch)
579 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
580 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
582 fatal("%s line %d: Directive '%s' is not allowed "
583 "within a Match block", filename, linenum, arg);
584 } else { /* this is a directive we have already processed */
592 /* Portable-specific options */
594 intptr = &options->use_pam;
597 /* Standard Options */
601 /* ignore ports from configfile if cmdline specifies ports */
602 if (options->ports_from_cmdline)
604 if (options->listen_addrs != NULL)
605 fatal("%s line %d: ports must be specified before "
606 "ListenAddress.", filename, linenum);
607 if (options->num_ports >= MAX_PORTS)
608 fatal("%s line %d: too many ports.",
611 if (!arg || *arg == '\0')
612 fatal("%s line %d: missing port number.",
614 options->ports[options->num_ports++] = a2port(arg);
615 if (options->ports[options->num_ports-1] == 0)
616 fatal("%s line %d: Badly formatted port number.",
621 intptr = &options->server_key_bits;
624 if (!arg || *arg == '\0')
625 fatal("%s line %d: missing integer value.",
628 if (*activep && *intptr == -1)
632 case sLoginGraceTime:
633 intptr = &options->login_grace_time;
636 if (!arg || *arg == '\0')
637 fatal("%s line %d: missing time value.",
639 if ((value = convtime(arg)) == -1)
640 fatal("%s line %d: invalid time value.",
646 case sKeyRegenerationTime:
647 intptr = &options->key_regeneration_time;
652 if (arg == NULL || *arg == '\0')
653 fatal("%s line %d: missing address",
655 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
656 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
657 && strchr(p+1, ':') != NULL) {
658 add_listen_addr(options, arg, 0);
663 fatal("%s line %d: bad address:port usage",
665 p = cleanhostname(p);
668 else if ((port = a2port(arg)) == 0)
669 fatal("%s line %d: bad port number", filename, linenum);
671 add_listen_addr(options, p, port);
677 if (!arg || *arg == '\0')
678 fatal("%s line %d: missing address family.",
680 intptr = &options->address_family;
681 if (options->listen_addrs != NULL)
682 fatal("%s line %d: address family must be specified before "
683 "ListenAddress.", filename, linenum);
684 if (strcasecmp(arg, "inet") == 0)
686 else if (strcasecmp(arg, "inet6") == 0)
688 else if (strcasecmp(arg, "any") == 0)
691 fatal("%s line %d: unsupported address family \"%s\".",
692 filename, linenum, arg);
698 intptr = &options->num_host_key_files;
699 if (*intptr >= MAX_HOSTKEYS)
700 fatal("%s line %d: too many host keys specified (max %d).",
701 filename, linenum, MAX_HOSTKEYS);
702 charptr = &options->host_key_files[*intptr];
705 if (!arg || *arg == '\0')
706 fatal("%s line %d: missing file name.",
708 if (*activep && *charptr == NULL) {
709 *charptr = tilde_expand_filename(arg, getuid());
710 /* increase optional counter */
712 *intptr = *intptr + 1;
717 charptr = &options->pid_file;
720 case sPermitRootLogin:
721 intptr = &options->permit_root_login;
723 if (!arg || *arg == '\0')
724 fatal("%s line %d: missing yes/"
725 "without-password/forced-commands-only/no "
726 "argument.", filename, linenum);
727 value = 0; /* silence compiler */
728 if (strcmp(arg, "without-password") == 0)
729 value = PERMIT_NO_PASSWD;
730 else if (strcmp(arg, "forced-commands-only") == 0)
731 value = PERMIT_FORCED_ONLY;
732 else if (strcmp(arg, "yes") == 0)
734 else if (strcmp(arg, "no") == 0)
737 fatal("%s line %d: Bad yes/"
738 "without-password/forced-commands-only/no "
739 "argument: %s", filename, linenum, arg);
745 intptr = &options->ignore_rhosts;
748 if (!arg || *arg == '\0')
749 fatal("%s line %d: missing yes/no argument.",
751 value = 0; /* silence compiler */
752 if (strcmp(arg, "yes") == 0)
754 else if (strcmp(arg, "no") == 0)
757 fatal("%s line %d: Bad yes/no argument: %s",
758 filename, linenum, arg);
759 if (*activep && *intptr == -1)
763 case sIgnoreUserKnownHosts:
764 intptr = &options->ignore_user_known_hosts;
767 case sRhostsRSAAuthentication:
768 intptr = &options->rhosts_rsa_authentication;
771 case sHostbasedAuthentication:
772 intptr = &options->hostbased_authentication;
775 case sHostbasedUsesNameFromPacketOnly:
776 intptr = &options->hostbased_uses_name_from_packet_only;
779 case sRSAAuthentication:
780 intptr = &options->rsa_authentication;
783 case sPubkeyAuthentication:
784 intptr = &options->pubkey_authentication;
787 case sKerberosAuthentication:
788 intptr = &options->kerberos_authentication;
791 case sKerberosOrLocalPasswd:
792 intptr = &options->kerberos_or_local_passwd;
795 case sKerberosTicketCleanup:
796 intptr = &options->kerberos_ticket_cleanup;
799 case sKerberosGetAFSToken:
800 intptr = &options->kerberos_get_afs_token;
803 case sGssAuthentication:
804 intptr = &options->gss_authentication;
807 case sGssCleanupCreds:
808 intptr = &options->gss_cleanup_creds;
811 case sPasswordAuthentication:
812 intptr = &options->password_authentication;
815 case sKbdInteractiveAuthentication:
816 intptr = &options->kbd_interactive_authentication;
819 case sChallengeResponseAuthentication:
820 intptr = &options->challenge_response_authentication;
824 intptr = &options->print_motd;
828 intptr = &options->print_lastlog;
832 intptr = &options->x11_forwarding;
835 case sX11DisplayOffset:
836 intptr = &options->x11_display_offset;
839 case sX11UseLocalhost:
840 intptr = &options->x11_use_localhost;
844 charptr = &options->xauth_location;
848 intptr = &options->strict_modes;
852 intptr = &options->tcp_keep_alive;
856 intptr = &options->permit_empty_passwd;
859 case sPermitUserEnvironment:
860 intptr = &options->permit_user_env;
864 intptr = &options->use_login;
868 intptr = &options->compression;
870 if (!arg || *arg == '\0')
871 fatal("%s line %d: missing yes/no/delayed "
872 "argument.", filename, linenum);
873 value = 0; /* silence compiler */
874 if (strcmp(arg, "delayed") == 0)
875 value = COMP_DELAYED;
876 else if (strcmp(arg, "yes") == 0)
878 else if (strcmp(arg, "no") == 0)
881 fatal("%s line %d: Bad yes/no/delayed "
882 "argument: %s", filename, linenum, arg);
888 intptr = &options->gateway_ports;
890 if (!arg || *arg == '\0')
891 fatal("%s line %d: missing yes/no/clientspecified "
892 "argument.", filename, linenum);
893 value = 0; /* silence compiler */
894 if (strcmp(arg, "clientspecified") == 0)
896 else if (strcmp(arg, "yes") == 0)
898 else if (strcmp(arg, "no") == 0)
901 fatal("%s line %d: Bad yes/no/clientspecified "
902 "argument: %s", filename, linenum, arg);
908 intptr = &options->use_dns;
912 intptr = (int *) &options->log_facility;
914 value = log_facility_number(arg);
915 if (value == SYSLOG_FACILITY_NOT_SET)
916 fatal("%.200s line %d: unsupported log facility '%s'",
917 filename, linenum, arg ? arg : "<NONE>");
919 *intptr = (SyslogFacility) value;
923 intptr = (int *) &options->log_level;
925 value = log_level_number(arg);
926 if (value == SYSLOG_LEVEL_NOT_SET)
927 fatal("%.200s line %d: unsupported log level '%s'",
928 filename, linenum, arg ? arg : "<NONE>");
930 *intptr = (LogLevel) value;
933 case sAllowTcpForwarding:
934 intptr = &options->allow_tcp_forwarding;
937 case sUsePrivilegeSeparation:
938 intptr = &use_privsep;
942 while ((arg = strdelim(&cp)) && *arg != '\0') {
943 if (options->num_allow_users >= MAX_ALLOW_USERS)
944 fatal("%s line %d: too many allow users.",
946 options->allow_users[options->num_allow_users++] =
952 while ((arg = strdelim(&cp)) && *arg != '\0') {
953 if (options->num_deny_users >= MAX_DENY_USERS)
954 fatal( "%s line %d: too many deny users.",
956 options->deny_users[options->num_deny_users++] =
962 while ((arg = strdelim(&cp)) && *arg != '\0') {
963 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
964 fatal("%s line %d: too many allow groups.",
966 options->allow_groups[options->num_allow_groups++] =
972 while ((arg = strdelim(&cp)) && *arg != '\0') {
973 if (options->num_deny_groups >= MAX_DENY_GROUPS)
974 fatal("%s line %d: too many deny groups.",
976 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
982 if (!arg || *arg == '\0')
983 fatal("%s line %d: Missing argument.", filename, linenum);
984 if (!ciphers_valid(arg))
985 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
986 filename, linenum, arg ? arg : "<NONE>");
987 if (options->ciphers == NULL)
988 options->ciphers = xstrdup(arg);
993 if (!arg || *arg == '\0')
994 fatal("%s line %d: Missing argument.", filename, linenum);
996 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
997 filename, linenum, arg ? arg : "<NONE>");
998 if (options->macs == NULL)
999 options->macs = xstrdup(arg);
1003 intptr = &options->protocol;
1004 arg = strdelim(&cp);
1005 if (!arg || *arg == '\0')
1006 fatal("%s line %d: Missing argument.", filename, linenum);
1007 value = proto_spec(arg);
1008 if (value == SSH_PROTO_UNKNOWN)
1009 fatal("%s line %d: Bad protocol spec '%s'.",
1010 filename, linenum, arg ? arg : "<NONE>");
1011 if (*intptr == SSH_PROTO_UNKNOWN)
1016 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1017 fatal("%s line %d: too many subsystems defined.",
1020 arg = strdelim(&cp);
1021 if (!arg || *arg == '\0')
1022 fatal("%s line %d: Missing subsystem name.",
1025 arg = strdelim(&cp);
1028 for (i = 0; i < options->num_subsystems; i++)
1029 if (strcmp(arg, options->subsystem_name[i]) == 0)
1030 fatal("%s line %d: Subsystem '%s' already defined.",
1031 filename, linenum, arg);
1032 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1033 arg = strdelim(&cp);
1034 if (!arg || *arg == '\0')
1035 fatal("%s line %d: Missing subsystem command.",
1037 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1039 /* Collect arguments (separate to executable) */
1041 len = strlen(p) + 1;
1042 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1043 len += 1 + strlen(arg);
1044 p = xrealloc(p, 1, len);
1045 strlcat(p, " ", len);
1046 strlcat(p, arg, len);
1048 options->subsystem_args[options->num_subsystems] = p;
1049 options->num_subsystems++;
1053 arg = strdelim(&cp);
1054 if (!arg || *arg == '\0')
1055 fatal("%s line %d: Missing MaxStartups spec.",
1057 if ((n = sscanf(arg, "%d:%d:%d",
1058 &options->max_startups_begin,
1059 &options->max_startups_rate,
1060 &options->max_startups)) == 3) {
1061 if (options->max_startups_begin >
1062 options->max_startups ||
1063 options->max_startups_rate > 100 ||
1064 options->max_startups_rate < 1)
1065 fatal("%s line %d: Illegal MaxStartups spec.",
1068 fatal("%s line %d: Illegal MaxStartups spec.",
1071 options->max_startups = options->max_startups_begin;
1075 intptr = &options->max_authtries;
1079 charptr = &options->banner;
1080 goto parse_filename;
1082 * These options can contain %X options expanded at
1083 * connect time, so that you can specify paths like:
1085 * AuthorizedKeysFile /etc/ssh_keys/%u
1087 case sAuthorizedKeysFile:
1088 case sAuthorizedKeysFile2:
1089 charptr = (opcode == sAuthorizedKeysFile ) ?
1090 &options->authorized_keys_file :
1091 &options->authorized_keys_file2;
1092 goto parse_filename;
1094 case sClientAliveInterval:
1095 intptr = &options->client_alive_interval;
1098 case sClientAliveCountMax:
1099 intptr = &options->client_alive_count_max;
1103 while ((arg = strdelim(&cp)) && *arg != '\0') {
1104 if (strchr(arg, '=') != NULL)
1105 fatal("%s line %d: Invalid environment name.",
1107 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1108 fatal("%s line %d: too many allow env.",
1112 options->accept_env[options->num_accept_env++] =
1118 intptr = &options->permit_tun;
1119 arg = strdelim(&cp);
1120 if (!arg || *arg == '\0')
1121 fatal("%s line %d: Missing yes/point-to-point/"
1122 "ethernet/no argument.", filename, linenum);
1123 value = 0; /* silence compiler */
1124 if (strcasecmp(arg, "ethernet") == 0)
1125 value = SSH_TUNMODE_ETHERNET;
1126 else if (strcasecmp(arg, "point-to-point") == 0)
1127 value = SSH_TUNMODE_POINTOPOINT;
1128 else if (strcasecmp(arg, "yes") == 0)
1129 value = SSH_TUNMODE_YES;
1130 else if (strcasecmp(arg, "no") == 0)
1131 value = SSH_TUNMODE_NO;
1133 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1134 "no argument: %s", filename, linenum, arg);
1141 fatal("Match directive not supported as a command-line "
1143 value = match_cfg_line(&cp, linenum, user, host, address);
1145 fatal("%s line %d: Bad Match condition", filename,
1151 logit("%s line %d: Deprecated option %s",
1152 filename, linenum, arg);
1154 arg = strdelim(&cp);
1158 logit("%s line %d: Unsupported option %s",
1159 filename, linenum, arg);
1161 arg = strdelim(&cp);
1165 fatal("%s line %d: Missing handler for opcode %s (%d)",
1166 filename, linenum, arg, opcode);
1168 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1169 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1170 filename, linenum, arg);
1174 /* Reads the server configuration file. */
1177 load_server_config(const char *filename, Buffer *conf)
1179 char line[1024], *cp;
1182 debug2("%s: filename %s", __func__, filename);
1183 if ((f = fopen(filename, "r")) == NULL) {
1188 while (fgets(line, sizeof(line), f)) {
1190 * Trim out comments and strip whitespace
1191 * NB - preserve newlines, they are needed to reproduce
1192 * line numbers later for error messages
1194 if ((cp = strchr(line, '#')) != NULL)
1195 memcpy(cp, "\n", 2);
1196 cp = line + strspn(line, " \t\r");
1198 buffer_append(conf, cp, strlen(cp));
1200 buffer_append(conf, "\0", 1);
1202 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1206 parse_server_match_config(ServerOptions *options, const char *user,
1207 const char *host, const char *address)
1211 initialize_server_options(&mo);
1212 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1213 copy_set_server_options(options, &mo);
1216 /* Copy any (supported) values that are set */
1218 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1220 if (src->allow_tcp_forwarding != -1)
1221 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1222 if (src->gateway_ports != -1)
1223 dst->gateway_ports = src->gateway_ports;
1227 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1228 const char *user, const char *host, const char *address)
1230 int active, linenum, bad_options = 0;
1231 char *cp, *obuf, *cbuf;
1233 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1235 obuf = cbuf = xstrdup(buffer_ptr(conf));
1236 active = user ? 0 : 1;
1238 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1239 if (process_server_config_line(options, cp, filename,
1240 linenum++, &active, user, host, address) != 0)
1244 if (bad_options > 0)
1245 fatal("%s: terminating, %d bad configuration options",
1246 filename, bad_options);