1 /* $OpenBSD: servconf.c,v 1.155 2006/07/17 01:31:09 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)
28 #include "pathnames.h"
35 static void add_listen_addr(ServerOptions *, char *, u_short);
36 static void add_one_listen_addr(ServerOptions *, char *, u_short);
38 /* Use of privilege separation or not */
39 extern int use_privsep;
42 /* Initializes the server options to their default values. */
45 initialize_server_options(ServerOptions *options)
47 memset(options, 0, sizeof(*options));
49 /* Portable-specific options */
50 options->use_pam = -1;
52 /* Standard Options */
53 options->num_ports = 0;
54 options->ports_from_cmdline = 0;
55 options->listen_addrs = NULL;
56 options->address_family = -1;
57 options->num_host_key_files = 0;
58 options->pid_file = NULL;
59 options->server_key_bits = -1;
60 options->login_grace_time = -1;
61 options->key_regeneration_time = -1;
62 options->permit_root_login = PERMIT_NOT_SET;
63 options->ignore_rhosts = -1;
64 options->ignore_user_known_hosts = -1;
65 options->print_motd = -1;
66 options->print_lastlog = -1;
67 options->x11_forwarding = -1;
68 options->x11_display_offset = -1;
69 options->x11_use_localhost = -1;
70 options->xauth_location = NULL;
71 options->strict_modes = -1;
72 options->tcp_keep_alive = -1;
73 options->log_facility = SYSLOG_FACILITY_NOT_SET;
74 options->log_level = SYSLOG_LEVEL_NOT_SET;
75 options->rhosts_rsa_authentication = -1;
76 options->hostbased_authentication = -1;
77 options->hostbased_uses_name_from_packet_only = -1;
78 options->rsa_authentication = -1;
79 options->pubkey_authentication = -1;
80 options->kerberos_authentication = -1;
81 options->kerberos_or_local_passwd = -1;
82 options->kerberos_ticket_cleanup = -1;
83 options->kerberos_get_afs_token = -1;
84 options->gss_authentication=-1;
85 options->gss_cleanup_creds = -1;
86 options->password_authentication = -1;
87 options->kbd_interactive_authentication = -1;
88 options->challenge_response_authentication = -1;
89 options->permit_empty_passwd = -1;
90 options->permit_user_env = -1;
91 options->use_login = -1;
92 options->compression = -1;
93 options->allow_tcp_forwarding = -1;
94 options->num_allow_users = 0;
95 options->num_deny_users = 0;
96 options->num_allow_groups = 0;
97 options->num_deny_groups = 0;
98 options->ciphers = NULL;
100 options->protocol = SSH_PROTO_UNKNOWN;
101 options->gateway_ports = -1;
102 options->num_subsystems = 0;
103 options->max_startups_begin = -1;
104 options->max_startups_rate = -1;
105 options->max_startups = -1;
106 options->max_authtries = -1;
107 options->banner = NULL;
108 options->use_dns = -1;
109 options->client_alive_interval = -1;
110 options->client_alive_count_max = -1;
111 options->authorized_keys_file = NULL;
112 options->authorized_keys_file2 = NULL;
113 options->num_accept_env = 0;
114 options->permit_tun = -1;
118 fill_default_server_options(ServerOptions *options)
120 /* Portable-specific options */
121 if (options->use_pam == -1)
122 options->use_pam = 0;
124 /* Standard Options */
125 if (options->protocol == SSH_PROTO_UNKNOWN)
126 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
127 if (options->num_host_key_files == 0) {
128 /* fill default hostkeys for protocols */
129 if (options->protocol & SSH_PROTO_1)
130 options->host_key_files[options->num_host_key_files++] =
132 if (options->protocol & SSH_PROTO_2) {
133 options->host_key_files[options->num_host_key_files++] =
134 _PATH_HOST_RSA_KEY_FILE;
135 options->host_key_files[options->num_host_key_files++] =
136 _PATH_HOST_DSA_KEY_FILE;
139 if (options->num_ports == 0)
140 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
141 if (options->listen_addrs == NULL)
142 add_listen_addr(options, NULL, 0);
143 if (options->pid_file == NULL)
144 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
145 if (options->server_key_bits == -1)
146 options->server_key_bits = 768;
147 if (options->login_grace_time == -1)
148 options->login_grace_time = 120;
149 if (options->key_regeneration_time == -1)
150 options->key_regeneration_time = 3600;
151 if (options->permit_root_login == PERMIT_NOT_SET)
152 options->permit_root_login = PERMIT_YES;
153 if (options->ignore_rhosts == -1)
154 options->ignore_rhosts = 1;
155 if (options->ignore_user_known_hosts == -1)
156 options->ignore_user_known_hosts = 0;
157 if (options->print_motd == -1)
158 options->print_motd = 1;
159 if (options->print_lastlog == -1)
160 options->print_lastlog = 1;
161 if (options->x11_forwarding == -1)
162 options->x11_forwarding = 0;
163 if (options->x11_display_offset == -1)
164 options->x11_display_offset = 10;
165 if (options->x11_use_localhost == -1)
166 options->x11_use_localhost = 1;
167 if (options->xauth_location == NULL)
168 options->xauth_location = _PATH_XAUTH;
169 if (options->strict_modes == -1)
170 options->strict_modes = 1;
171 if (options->tcp_keep_alive == -1)
172 options->tcp_keep_alive = 1;
173 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
174 options->log_facility = SYSLOG_FACILITY_AUTH;
175 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
176 options->log_level = SYSLOG_LEVEL_INFO;
177 if (options->rhosts_rsa_authentication == -1)
178 options->rhosts_rsa_authentication = 0;
179 if (options->hostbased_authentication == -1)
180 options->hostbased_authentication = 0;
181 if (options->hostbased_uses_name_from_packet_only == -1)
182 options->hostbased_uses_name_from_packet_only = 0;
183 if (options->rsa_authentication == -1)
184 options->rsa_authentication = 1;
185 if (options->pubkey_authentication == -1)
186 options->pubkey_authentication = 1;
187 if (options->kerberos_authentication == -1)
188 options->kerberos_authentication = 0;
189 if (options->kerberos_or_local_passwd == -1)
190 options->kerberos_or_local_passwd = 1;
191 if (options->kerberos_ticket_cleanup == -1)
192 options->kerberos_ticket_cleanup = 1;
193 if (options->kerberos_get_afs_token == -1)
194 options->kerberos_get_afs_token = 0;
195 if (options->gss_authentication == -1)
196 options->gss_authentication = 0;
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;
240 if (options->permit_tun == -1)
241 options->permit_tun = SSH_TUNMODE_NO;
243 /* Turn privilege separation on by default */
244 if (use_privsep == -1)
248 if (use_privsep && options->compression == 1) {
249 error("This platform does not support both privilege "
250 "separation and compression");
251 error("Compression disabled");
252 options->compression = 0;
258 /* Keyword tokens. */
260 sBadOption, /* == unknown option */
261 /* Portable-specific options */
263 /* Standard Options */
264 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
265 sPermitRootLogin, sLogFacility, sLogLevel,
266 sRhostsRSAAuthentication, sRSAAuthentication,
267 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
268 sKerberosGetAFSToken,
269 sKerberosTgtPassing, sChallengeResponseAuthentication,
270 sPasswordAuthentication, sKbdInteractiveAuthentication,
271 sListenAddress, sAddressFamily,
272 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
273 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
274 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
275 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
276 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
277 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
278 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
279 sMaxStartups, sMaxAuthTries,
280 sBanner, sUseDNS, sHostbasedAuthentication,
281 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
282 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
283 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
285 sUsePrivilegeSeparation,
286 sDeprecated, sUnsupported
289 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
290 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
291 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
293 /* Textual representation of the tokens. */
296 ServerOpCodes opcode;
299 /* Portable-specific options */
301 { "usepam", sUsePAM, SSHCFG_GLOBAL },
303 { "usepam", sUnsupported, SSHCFG_GLOBAL },
305 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
306 /* Standard Options */
307 { "port", sPort, SSHCFG_GLOBAL },
308 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
309 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
310 { "pidfile", sPidFile, SSHCFG_GLOBAL },
311 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
312 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
313 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
314 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
315 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
316 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
317 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
318 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
319 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
320 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
321 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
322 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
323 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
325 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
326 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
327 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
329 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
331 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
334 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
335 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
336 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
337 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
339 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
340 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
342 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
343 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
345 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
346 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
348 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
349 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
350 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
351 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
352 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
353 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
354 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
355 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
356 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
357 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
358 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
359 { "x11forwarding", sX11Forwarding, SSHCFG_GLOBAL },
360 { "x11displayoffset", sX11DisplayOffset, SSHCFG_GLOBAL },
361 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_GLOBAL },
362 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
363 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
364 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
365 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
366 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
367 { "compression", sCompression, SSHCFG_GLOBAL },
368 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
369 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
370 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
371 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
372 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
373 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
374 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
375 { "ciphers", sCiphers, SSHCFG_GLOBAL },
376 { "macs", sMacs, SSHCFG_GLOBAL },
377 { "protocol", sProtocol, SSHCFG_GLOBAL },
378 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
379 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
380 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
381 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
382 { "banner", sBanner, SSHCFG_GLOBAL },
383 { "usedns", sUseDNS, SSHCFG_GLOBAL },
384 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
385 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
386 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
387 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
388 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
389 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
390 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
391 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
392 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
393 { NULL, sBadOption, 0 }
397 * Returns the number of the token pointed to by cp or sBadOption.
401 parse_token(const char *cp, const char *filename,
402 int linenum, u_int *flags)
406 for (i = 0; keywords[i].name; i++)
407 if (strcasecmp(cp, keywords[i].name) == 0) {
408 *flags = keywords[i].flags;
409 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 * The strategy for the Match blocks is that the config file is parsed twice.
458 * The first time is at startup. activep is initialized to 1 and the
459 * directives in the global context are processed and acted on. Hitting a
460 * Match directive unsets activep and the directives inside the block are
461 * checked for syntax only.
463 * The second time is after a connection has been established but before
464 * authentication. activep is initialized to 2 and global config directives
465 * are ignored since they have already been processed. If the criteria in a
466 * Match block is met, activep is set and the subsequent directives
467 * processed and actioned until EOF or another Match block unsets it. Any
468 * options set are copied into the main server config.
470 * Potential additions/improvements:
471 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
473 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
474 * Match Address 192.168.0.*
479 * AllowTcpForwarding yes
480 * GatewayPorts clientspecified
483 * - Add a PermittedChannelRequests directive
485 * PermittedChannelRequests session,forwarded-tcpip
489 match_cfg_line(char **condition, int line, const char *user, const char *host,
493 char *arg, *attrib, *cp = *condition;
497 debug3("checking syntax for 'Match %s'", cp);
499 debug3("checking match for '%s' user %s host %s addr %s", cp,
500 user ? user : "(null)", host ? host : "(null)",
501 address ? address : "(null)");
503 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
504 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
505 error("Missing Match criteria for %s", attrib);
509 if (strcasecmp(attrib, "user") == 0) {
514 if (match_pattern_list(user, arg, len, 0) != 1)
517 debug("user %.100s matched 'User %.100s' at "
518 "line %d", user, arg, line);
519 } else if (strcasecmp(attrib, "host") == 0) {
524 if (match_hostname(host, arg, len) != 1)
527 debug("connection from %.100s matched 'Host "
528 "%.100s' at line %d", host, arg, line);
529 } else if (strcasecmp(attrib, "address") == 0) {
530 debug("address '%s' arg '%s'", address, arg);
535 if (match_hostname(address, arg, len) != 1)
538 debug("connection from %.100s matched 'Address "
539 "%.100s' at line %d", address, arg, line);
541 error("Unsupported Match attribute %s", attrib);
546 debug3("match %sfound", result ? "" : "not ");
552 process_server_config_line(ServerOptions *options, char *line,
553 const char *filename, int linenum, int *activep, const char *user,
554 const char *host, const char *address)
556 char *cp, **charptr, *arg, *p;
557 int cmdline = 0, *intptr, value, n;
558 ServerOpCodes opcode;
564 if ((arg = strdelim(&cp)) == NULL)
566 /* Ignore leading whitespace */
569 if (!arg || !*arg || *arg == '#')
573 opcode = parse_token(arg, filename, linenum, &flags);
575 if (activep == NULL) { /* We are processing a command line directive */
579 if (*activep && opcode != sMatch)
580 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
581 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
583 fatal("%s line %d: Directive '%s' is not allowed "
584 "within a Match block", filename, linenum, arg);
585 } else { /* this is a directive we have already processed */
593 /* Portable-specific options */
595 intptr = &options->use_pam;
598 /* Standard Options */
602 /* ignore ports from configfile if cmdline specifies ports */
603 if (options->ports_from_cmdline)
605 if (options->listen_addrs != NULL)
606 fatal("%s line %d: ports must be specified before "
607 "ListenAddress.", filename, linenum);
608 if (options->num_ports >= MAX_PORTS)
609 fatal("%s line %d: too many ports.",
612 if (!arg || *arg == '\0')
613 fatal("%s line %d: missing port number.",
615 options->ports[options->num_ports++] = a2port(arg);
616 if (options->ports[options->num_ports-1] == 0)
617 fatal("%s line %d: Badly formatted port number.",
622 intptr = &options->server_key_bits;
625 if (!arg || *arg == '\0')
626 fatal("%s line %d: missing integer value.",
629 if (*activep && *intptr == -1)
633 case sLoginGraceTime:
634 intptr = &options->login_grace_time;
637 if (!arg || *arg == '\0')
638 fatal("%s line %d: missing time value.",
640 if ((value = convtime(arg)) == -1)
641 fatal("%s line %d: invalid time value.",
647 case sKeyRegenerationTime:
648 intptr = &options->key_regeneration_time;
653 if (arg == NULL || *arg == '\0')
654 fatal("%s line %d: missing address",
656 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
657 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
658 && strchr(p+1, ':') != NULL) {
659 add_listen_addr(options, arg, 0);
664 fatal("%s line %d: bad address:port usage",
666 p = cleanhostname(p);
669 else if ((port = a2port(arg)) == 0)
670 fatal("%s line %d: bad port number", filename, linenum);
672 add_listen_addr(options, p, port);
678 if (!arg || *arg == '\0')
679 fatal("%s line %d: missing address family.",
681 intptr = &options->address_family;
682 if (options->listen_addrs != NULL)
683 fatal("%s line %d: address family must be specified before "
684 "ListenAddress.", filename, linenum);
685 if (strcasecmp(arg, "inet") == 0)
687 else if (strcasecmp(arg, "inet6") == 0)
689 else if (strcasecmp(arg, "any") == 0)
692 fatal("%s line %d: unsupported address family \"%s\".",
693 filename, linenum, arg);
699 intptr = &options->num_host_key_files;
700 if (*intptr >= MAX_HOSTKEYS)
701 fatal("%s line %d: too many host keys specified (max %d).",
702 filename, linenum, MAX_HOSTKEYS);
703 charptr = &options->host_key_files[*intptr];
706 if (!arg || *arg == '\0')
707 fatal("%s line %d: missing file name.",
709 if (*activep && *charptr == NULL) {
710 *charptr = tilde_expand_filename(arg, getuid());
711 /* increase optional counter */
713 *intptr = *intptr + 1;
718 charptr = &options->pid_file;
721 case sPermitRootLogin:
722 intptr = &options->permit_root_login;
724 if (!arg || *arg == '\0')
725 fatal("%s line %d: missing yes/"
726 "without-password/forced-commands-only/no "
727 "argument.", filename, linenum);
728 value = 0; /* silence compiler */
729 if (strcmp(arg, "without-password") == 0)
730 value = PERMIT_NO_PASSWD;
731 else if (strcmp(arg, "forced-commands-only") == 0)
732 value = PERMIT_FORCED_ONLY;
733 else if (strcmp(arg, "yes") == 0)
735 else if (strcmp(arg, "no") == 0)
738 fatal("%s line %d: Bad yes/"
739 "without-password/forced-commands-only/no "
740 "argument: %s", filename, linenum, arg);
746 intptr = &options->ignore_rhosts;
749 if (!arg || *arg == '\0')
750 fatal("%s line %d: missing yes/no argument.",
752 value = 0; /* silence compiler */
753 if (strcmp(arg, "yes") == 0)
755 else if (strcmp(arg, "no") == 0)
758 fatal("%s line %d: Bad yes/no argument: %s",
759 filename, linenum, arg);
760 if (*activep && *intptr == -1)
764 case sIgnoreUserKnownHosts:
765 intptr = &options->ignore_user_known_hosts;
768 case sRhostsRSAAuthentication:
769 intptr = &options->rhosts_rsa_authentication;
772 case sHostbasedAuthentication:
773 intptr = &options->hostbased_authentication;
776 case sHostbasedUsesNameFromPacketOnly:
777 intptr = &options->hostbased_uses_name_from_packet_only;
780 case sRSAAuthentication:
781 intptr = &options->rsa_authentication;
784 case sPubkeyAuthentication:
785 intptr = &options->pubkey_authentication;
788 case sKerberosAuthentication:
789 intptr = &options->kerberos_authentication;
792 case sKerberosOrLocalPasswd:
793 intptr = &options->kerberos_or_local_passwd;
796 case sKerberosTicketCleanup:
797 intptr = &options->kerberos_ticket_cleanup;
800 case sKerberosGetAFSToken:
801 intptr = &options->kerberos_get_afs_token;
804 case sGssAuthentication:
805 intptr = &options->gss_authentication;
808 case sGssCleanupCreds:
809 intptr = &options->gss_cleanup_creds;
812 case sPasswordAuthentication:
813 intptr = &options->password_authentication;
816 case sKbdInteractiveAuthentication:
817 intptr = &options->kbd_interactive_authentication;
820 case sChallengeResponseAuthentication:
821 intptr = &options->challenge_response_authentication;
825 intptr = &options->print_motd;
829 intptr = &options->print_lastlog;
833 intptr = &options->x11_forwarding;
836 case sX11DisplayOffset:
837 intptr = &options->x11_display_offset;
840 case sX11UseLocalhost:
841 intptr = &options->x11_use_localhost;
845 charptr = &options->xauth_location;
849 intptr = &options->strict_modes;
853 intptr = &options->tcp_keep_alive;
857 intptr = &options->permit_empty_passwd;
860 case sPermitUserEnvironment:
861 intptr = &options->permit_user_env;
865 intptr = &options->use_login;
869 intptr = &options->compression;
871 if (!arg || *arg == '\0')
872 fatal("%s line %d: missing yes/no/delayed "
873 "argument.", filename, linenum);
874 value = 0; /* silence compiler */
875 if (strcmp(arg, "delayed") == 0)
876 value = COMP_DELAYED;
877 else if (strcmp(arg, "yes") == 0)
879 else if (strcmp(arg, "no") == 0)
882 fatal("%s line %d: Bad yes/no/delayed "
883 "argument: %s", filename, linenum, arg);
889 intptr = &options->gateway_ports;
891 if (!arg || *arg == '\0')
892 fatal("%s line %d: missing yes/no/clientspecified "
893 "argument.", filename, linenum);
894 value = 0; /* silence compiler */
895 if (strcmp(arg, "clientspecified") == 0)
897 else if (strcmp(arg, "yes") == 0)
899 else if (strcmp(arg, "no") == 0)
902 fatal("%s line %d: Bad yes/no/clientspecified "
903 "argument: %s", filename, linenum, arg);
909 intptr = &options->use_dns;
913 intptr = (int *) &options->log_facility;
915 value = log_facility_number(arg);
916 if (value == SYSLOG_FACILITY_NOT_SET)
917 fatal("%.200s line %d: unsupported log facility '%s'",
918 filename, linenum, arg ? arg : "<NONE>");
920 *intptr = (SyslogFacility) value;
924 intptr = (int *) &options->log_level;
926 value = log_level_number(arg);
927 if (value == SYSLOG_LEVEL_NOT_SET)
928 fatal("%.200s line %d: unsupported log level '%s'",
929 filename, linenum, arg ? arg : "<NONE>");
931 *intptr = (LogLevel) value;
934 case sAllowTcpForwarding:
935 intptr = &options->allow_tcp_forwarding;
938 case sUsePrivilegeSeparation:
939 intptr = &use_privsep;
943 while ((arg = strdelim(&cp)) && *arg != '\0') {
944 if (options->num_allow_users >= MAX_ALLOW_USERS)
945 fatal("%s line %d: too many allow users.",
947 options->allow_users[options->num_allow_users++] =
953 while ((arg = strdelim(&cp)) && *arg != '\0') {
954 if (options->num_deny_users >= MAX_DENY_USERS)
955 fatal( "%s line %d: too many deny users.",
957 options->deny_users[options->num_deny_users++] =
963 while ((arg = strdelim(&cp)) && *arg != '\0') {
964 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
965 fatal("%s line %d: too many allow groups.",
967 options->allow_groups[options->num_allow_groups++] =
973 while ((arg = strdelim(&cp)) && *arg != '\0') {
974 if (options->num_deny_groups >= MAX_DENY_GROUPS)
975 fatal("%s line %d: too many deny groups.",
977 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
983 if (!arg || *arg == '\0')
984 fatal("%s line %d: Missing argument.", filename, linenum);
985 if (!ciphers_valid(arg))
986 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
987 filename, linenum, arg ? arg : "<NONE>");
988 if (options->ciphers == NULL)
989 options->ciphers = xstrdup(arg);
994 if (!arg || *arg == '\0')
995 fatal("%s line %d: Missing argument.", filename, linenum);
997 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
998 filename, linenum, arg ? arg : "<NONE>");
999 if (options->macs == NULL)
1000 options->macs = xstrdup(arg);
1004 intptr = &options->protocol;
1005 arg = strdelim(&cp);
1006 if (!arg || *arg == '\0')
1007 fatal("%s line %d: Missing argument.", filename, linenum);
1008 value = proto_spec(arg);
1009 if (value == SSH_PROTO_UNKNOWN)
1010 fatal("%s line %d: Bad protocol spec '%s'.",
1011 filename, linenum, arg ? arg : "<NONE>");
1012 if (*intptr == SSH_PROTO_UNKNOWN)
1017 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1018 fatal("%s line %d: too many subsystems defined.",
1021 arg = strdelim(&cp);
1022 if (!arg || *arg == '\0')
1023 fatal("%s line %d: Missing subsystem name.",
1026 arg = strdelim(&cp);
1029 for (i = 0; i < options->num_subsystems; i++)
1030 if (strcmp(arg, options->subsystem_name[i]) == 0)
1031 fatal("%s line %d: Subsystem '%s' already defined.",
1032 filename, linenum, arg);
1033 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1034 arg = strdelim(&cp);
1035 if (!arg || *arg == '\0')
1036 fatal("%s line %d: Missing subsystem command.",
1038 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1040 /* Collect arguments (separate to executable) */
1042 len = strlen(p) + 1;
1043 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1044 len += 1 + strlen(arg);
1045 p = xrealloc(p, 1, len);
1046 strlcat(p, " ", len);
1047 strlcat(p, arg, len);
1049 options->subsystem_args[options->num_subsystems] = p;
1050 options->num_subsystems++;
1054 arg = strdelim(&cp);
1055 if (!arg || *arg == '\0')
1056 fatal("%s line %d: Missing MaxStartups spec.",
1058 if ((n = sscanf(arg, "%d:%d:%d",
1059 &options->max_startups_begin,
1060 &options->max_startups_rate,
1061 &options->max_startups)) == 3) {
1062 if (options->max_startups_begin >
1063 options->max_startups ||
1064 options->max_startups_rate > 100 ||
1065 options->max_startups_rate < 1)
1066 fatal("%s line %d: Illegal MaxStartups spec.",
1069 fatal("%s line %d: Illegal MaxStartups spec.",
1072 options->max_startups = options->max_startups_begin;
1076 intptr = &options->max_authtries;
1080 charptr = &options->banner;
1081 goto parse_filename;
1083 * These options can contain %X options expanded at
1084 * connect time, so that you can specify paths like:
1086 * AuthorizedKeysFile /etc/ssh_keys/%u
1088 case sAuthorizedKeysFile:
1089 case sAuthorizedKeysFile2:
1090 charptr = (opcode == sAuthorizedKeysFile ) ?
1091 &options->authorized_keys_file :
1092 &options->authorized_keys_file2;
1093 goto parse_filename;
1095 case sClientAliveInterval:
1096 intptr = &options->client_alive_interval;
1099 case sClientAliveCountMax:
1100 intptr = &options->client_alive_count_max;
1104 while ((arg = strdelim(&cp)) && *arg != '\0') {
1105 if (strchr(arg, '=') != NULL)
1106 fatal("%s line %d: Invalid environment name.",
1108 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1109 fatal("%s line %d: too many allow env.",
1113 options->accept_env[options->num_accept_env++] =
1119 intptr = &options->permit_tun;
1120 arg = strdelim(&cp);
1121 if (!arg || *arg == '\0')
1122 fatal("%s line %d: Missing yes/point-to-point/"
1123 "ethernet/no argument.", filename, linenum);
1124 value = 0; /* silence compiler */
1125 if (strcasecmp(arg, "ethernet") == 0)
1126 value = SSH_TUNMODE_ETHERNET;
1127 else if (strcasecmp(arg, "point-to-point") == 0)
1128 value = SSH_TUNMODE_POINTOPOINT;
1129 else if (strcasecmp(arg, "yes") == 0)
1130 value = SSH_TUNMODE_YES;
1131 else if (strcasecmp(arg, "no") == 0)
1132 value = SSH_TUNMODE_NO;
1134 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1135 "no argument: %s", filename, linenum, arg);
1142 fatal("Match directive not supported as a command-line "
1144 value = match_cfg_line(&cp, linenum, user, host, address);
1146 fatal("%s line %d: Bad Match condition", filename,
1152 logit("%s line %d: Deprecated option %s",
1153 filename, linenum, arg);
1155 arg = strdelim(&cp);
1159 logit("%s line %d: Unsupported option %s",
1160 filename, linenum, arg);
1162 arg = strdelim(&cp);
1166 fatal("%s line %d: Missing handler for opcode %s (%d)",
1167 filename, linenum, arg, opcode);
1169 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1170 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1171 filename, linenum, arg);
1175 /* Reads the server configuration file. */
1178 load_server_config(const char *filename, Buffer *conf)
1180 char line[1024], *cp;
1183 debug2("%s: filename %s", __func__, filename);
1184 if ((f = fopen(filename, "r")) == NULL) {
1189 while (fgets(line, sizeof(line), f)) {
1191 * Trim out comments and strip whitespace
1192 * NB - preserve newlines, they are needed to reproduce
1193 * line numbers later for error messages
1195 if ((cp = strchr(line, '#')) != NULL)
1196 memcpy(cp, "\n", 2);
1197 cp = line + strspn(line, " \t\r");
1199 buffer_append(conf, cp, strlen(cp));
1201 buffer_append(conf, "\0", 1);
1203 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1207 parse_server_match_config(ServerOptions *options, const char *user,
1208 const char *host, const char *address)
1212 initialize_server_options(&mo);
1213 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1214 copy_set_server_options(options, &mo);
1217 /* Copy any (supported) values that are set */
1219 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1221 if (src->allow_tcp_forwarding != -1)
1222 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1223 if (src->gateway_ports != -1)
1224 dst->gateway_ports = src->gateway_ports;
1228 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1229 const char *user, const char *host, const char *address)
1231 int active, linenum, bad_options = 0;
1232 char *cp, *obuf, *cbuf;
1234 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1236 obuf = cbuf = xstrdup(buffer_ptr(conf));
1237 active = user ? 0 : 1;
1239 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1240 if (process_server_config_line(options, cp, filename,
1241 linenum++, &active, user, host, address) != 0)
1245 if (bad_options > 0)
1246 fatal("%s: terminating, %d bad configuration options",
1247 filename, bad_options);