1 /* $OpenBSD: servconf.c,v 1.156 2006/07/17 12:06:00 dtucker 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"
36 static void add_listen_addr(ServerOptions *, char *, u_short);
37 static void add_one_listen_addr(ServerOptions *, char *, u_short);
39 /* Use of privilege separation or not */
40 extern int use_privsep;
43 /* Initializes the server options to their default values. */
46 initialize_server_options(ServerOptions *options)
48 memset(options, 0, sizeof(*options));
50 /* Portable-specific options */
51 options->use_pam = -1;
53 /* Standard Options */
54 options->num_ports = 0;
55 options->ports_from_cmdline = 0;
56 options->listen_addrs = NULL;
57 options->address_family = -1;
58 options->num_host_key_files = 0;
59 options->pid_file = NULL;
60 options->server_key_bits = -1;
61 options->login_grace_time = -1;
62 options->key_regeneration_time = -1;
63 options->permit_root_login = PERMIT_NOT_SET;
64 options->ignore_rhosts = -1;
65 options->ignore_user_known_hosts = -1;
66 options->print_motd = -1;
67 options->print_lastlog = -1;
68 options->x11_forwarding = -1;
69 options->x11_display_offset = -1;
70 options->x11_use_localhost = -1;
71 options->xauth_location = NULL;
72 options->strict_modes = -1;
73 options->tcp_keep_alive = -1;
74 options->log_facility = SYSLOG_FACILITY_NOT_SET;
75 options->log_level = SYSLOG_LEVEL_NOT_SET;
76 options->rhosts_rsa_authentication = -1;
77 options->hostbased_authentication = -1;
78 options->hostbased_uses_name_from_packet_only = -1;
79 options->rsa_authentication = -1;
80 options->pubkey_authentication = -1;
81 options->kerberos_authentication = -1;
82 options->kerberos_or_local_passwd = -1;
83 options->kerberos_ticket_cleanup = -1;
84 options->kerberos_get_afs_token = -1;
85 options->gss_authentication=-1;
86 options->gss_cleanup_creds = -1;
87 options->password_authentication = -1;
88 options->kbd_interactive_authentication = -1;
89 options->challenge_response_authentication = -1;
90 options->permit_empty_passwd = -1;
91 options->permit_user_env = -1;
92 options->use_login = -1;
93 options->compression = -1;
94 options->allow_tcp_forwarding = -1;
95 options->num_allow_users = 0;
96 options->num_deny_users = 0;
97 options->num_allow_groups = 0;
98 options->num_deny_groups = 0;
99 options->ciphers = NULL;
100 options->macs = NULL;
101 options->protocol = SSH_PROTO_UNKNOWN;
102 options->gateway_ports = -1;
103 options->num_subsystems = 0;
104 options->max_startups_begin = -1;
105 options->max_startups_rate = -1;
106 options->max_startups = -1;
107 options->max_authtries = -1;
108 options->banner = NULL;
109 options->use_dns = -1;
110 options->client_alive_interval = -1;
111 options->client_alive_count_max = -1;
112 options->authorized_keys_file = NULL;
113 options->authorized_keys_file2 = NULL;
114 options->num_accept_env = 0;
115 options->permit_tun = -1;
119 fill_default_server_options(ServerOptions *options)
121 /* Portable-specific options */
122 if (options->use_pam == -1)
123 options->use_pam = 0;
125 /* Standard Options */
126 if (options->protocol == SSH_PROTO_UNKNOWN)
127 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
128 if (options->num_host_key_files == 0) {
129 /* fill default hostkeys for protocols */
130 if (options->protocol & SSH_PROTO_1)
131 options->host_key_files[options->num_host_key_files++] =
133 if (options->protocol & SSH_PROTO_2) {
134 options->host_key_files[options->num_host_key_files++] =
135 _PATH_HOST_RSA_KEY_FILE;
136 options->host_key_files[options->num_host_key_files++] =
137 _PATH_HOST_DSA_KEY_FILE;
140 if (options->num_ports == 0)
141 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
142 if (options->listen_addrs == NULL)
143 add_listen_addr(options, NULL, 0);
144 if (options->pid_file == NULL)
145 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
146 if (options->server_key_bits == -1)
147 options->server_key_bits = 768;
148 if (options->login_grace_time == -1)
149 options->login_grace_time = 120;
150 if (options->key_regeneration_time == -1)
151 options->key_regeneration_time = 3600;
152 if (options->permit_root_login == PERMIT_NOT_SET)
153 options->permit_root_login = PERMIT_YES;
154 if (options->ignore_rhosts == -1)
155 options->ignore_rhosts = 1;
156 if (options->ignore_user_known_hosts == -1)
157 options->ignore_user_known_hosts = 0;
158 if (options->print_motd == -1)
159 options->print_motd = 1;
160 if (options->print_lastlog == -1)
161 options->print_lastlog = 1;
162 if (options->x11_forwarding == -1)
163 options->x11_forwarding = 0;
164 if (options->x11_display_offset == -1)
165 options->x11_display_offset = 10;
166 if (options->x11_use_localhost == -1)
167 options->x11_use_localhost = 1;
168 if (options->xauth_location == NULL)
169 options->xauth_location = _PATH_XAUTH;
170 if (options->strict_modes == -1)
171 options->strict_modes = 1;
172 if (options->tcp_keep_alive == -1)
173 options->tcp_keep_alive = 1;
174 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
175 options->log_facility = SYSLOG_FACILITY_AUTH;
176 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
177 options->log_level = SYSLOG_LEVEL_INFO;
178 if (options->rhosts_rsa_authentication == -1)
179 options->rhosts_rsa_authentication = 0;
180 if (options->hostbased_authentication == -1)
181 options->hostbased_authentication = 0;
182 if (options->hostbased_uses_name_from_packet_only == -1)
183 options->hostbased_uses_name_from_packet_only = 0;
184 if (options->rsa_authentication == -1)
185 options->rsa_authentication = 1;
186 if (options->pubkey_authentication == -1)
187 options->pubkey_authentication = 1;
188 if (options->kerberos_authentication == -1)
189 options->kerberos_authentication = 0;
190 if (options->kerberos_or_local_passwd == -1)
191 options->kerberos_or_local_passwd = 1;
192 if (options->kerberos_ticket_cleanup == -1)
193 options->kerberos_ticket_cleanup = 1;
194 if (options->kerberos_get_afs_token == -1)
195 options->kerberos_get_afs_token = 0;
196 if (options->gss_authentication == -1)
197 options->gss_authentication = 0;
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,
271 sPasswordAuthentication, sKbdInteractiveAuthentication,
272 sListenAddress, sAddressFamily,
273 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
274 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
275 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
276 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
277 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
278 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
279 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
280 sMaxStartups, sMaxAuthTries,
281 sBanner, sUseDNS, sHostbasedAuthentication,
282 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
283 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
284 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
286 sUsePrivilegeSeparation,
287 sDeprecated, sUnsupported
290 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
291 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
292 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
294 /* Textual representation of the tokens. */
297 ServerOpCodes opcode;
300 /* Portable-specific options */
302 { "usepam", sUsePAM, SSHCFG_GLOBAL },
304 { "usepam", sUnsupported, SSHCFG_GLOBAL },
306 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
307 /* Standard Options */
308 { "port", sPort, SSHCFG_GLOBAL },
309 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
310 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
311 { "pidfile", sPidFile, SSHCFG_GLOBAL },
312 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
313 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
314 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
315 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
316 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
317 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
318 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
319 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
320 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
321 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
322 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
323 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
324 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
326 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
327 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
328 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
330 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
332 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
335 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
336 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
337 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
338 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
340 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
341 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
343 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
344 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
346 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
347 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
349 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
350 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
351 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
352 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
353 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
354 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
355 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
356 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
357 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
358 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
359 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
360 { "x11forwarding", sX11Forwarding, SSHCFG_GLOBAL },
361 { "x11displayoffset", sX11DisplayOffset, SSHCFG_GLOBAL },
362 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_GLOBAL },
363 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
364 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
365 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
366 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
367 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
368 { "compression", sCompression, SSHCFG_GLOBAL },
369 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
370 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
371 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
372 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
373 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
374 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
375 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
376 { "ciphers", sCiphers, SSHCFG_GLOBAL },
377 { "macs", sMacs, SSHCFG_GLOBAL },
378 { "protocol", sProtocol, SSHCFG_GLOBAL },
379 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
380 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
381 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
382 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
383 { "banner", sBanner, SSHCFG_GLOBAL },
384 { "usedns", sUseDNS, SSHCFG_GLOBAL },
385 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
386 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
387 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
388 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
389 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
390 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
391 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
392 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
393 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
394 { "match", sMatch, SSHCFG_ALL },
395 { "permitopen", sPermitOpen, SSHCFG_ALL },
396 { NULL, sBadOption, 0 }
400 * Returns the number of the token pointed to by cp or sBadOption.
404 parse_token(const char *cp, const char *filename,
405 int linenum, u_int *flags)
409 for (i = 0; keywords[i].name; i++)
410 if (strcasecmp(cp, keywords[i].name) == 0) {
411 *flags = keywords[i].flags;
412 return keywords[i].opcode;
415 error("%s: line %d: Bad configuration option: %s",
416 filename, linenum, cp);
421 add_listen_addr(ServerOptions *options, char *addr, u_short port)
425 if (options->num_ports == 0)
426 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
427 if (options->address_family == -1)
428 options->address_family = AF_UNSPEC;
430 for (i = 0; i < options->num_ports; i++)
431 add_one_listen_addr(options, addr, options->ports[i]);
433 add_one_listen_addr(options, addr, port);
437 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
439 struct addrinfo hints, *ai, *aitop;
440 char strport[NI_MAXSERV];
443 memset(&hints, 0, sizeof(hints));
444 hints.ai_family = options->address_family;
445 hints.ai_socktype = SOCK_STREAM;
446 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
447 snprintf(strport, sizeof strport, "%u", port);
448 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
449 fatal("bad addr or host: %s (%s)",
450 addr ? addr : "<NULL>",
451 gai_strerror(gaierr));
452 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
454 ai->ai_next = options->listen_addrs;
455 options->listen_addrs = aitop;
459 * The strategy for the Match blocks is that the config file is parsed twice.
461 * The first time is at startup. activep is initialized to 1 and the
462 * directives in the global context are processed and acted on. Hitting a
463 * Match directive unsets activep and the directives inside the block are
464 * checked for syntax only.
466 * The second time is after a connection has been established but before
467 * authentication. activep is initialized to 2 and global config directives
468 * are ignored since they have already been processed. If the criteria in a
469 * Match block is met, activep is set and the subsequent directives
470 * processed and actioned until EOF or another Match block unsets it. Any
471 * options set are copied into the main server config.
473 * Potential additions/improvements:
474 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
476 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
477 * Match Address 192.168.0.*
482 * AllowTcpForwarding yes
483 * GatewayPorts clientspecified
486 * - Add a PermittedChannelRequests directive
488 * PermittedChannelRequests session,forwarded-tcpip
492 match_cfg_line(char **condition, int line, const char *user, const char *host,
496 char *arg, *attrib, *cp = *condition;
500 debug3("checking syntax for 'Match %s'", cp);
502 debug3("checking match for '%s' user %s host %s addr %s", cp,
503 user ? user : "(null)", host ? host : "(null)",
504 address ? address : "(null)");
506 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
507 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
508 error("Missing Match criteria for %s", attrib);
512 if (strcasecmp(attrib, "user") == 0) {
517 if (match_pattern_list(user, arg, len, 0) != 1)
520 debug("user %.100s matched 'User %.100s' at "
521 "line %d", user, arg, line);
522 } else if (strcasecmp(attrib, "host") == 0) {
527 if (match_hostname(host, arg, len) != 1)
530 debug("connection from %.100s matched 'Host "
531 "%.100s' at line %d", host, arg, line);
532 } else if (strcasecmp(attrib, "address") == 0) {
533 debug("address '%s' arg '%s'", address, arg);
538 if (match_hostname(address, arg, len) != 1)
541 debug("connection from %.100s matched 'Address "
542 "%.100s' at line %d", address, arg, line);
544 error("Unsupported Match attribute %s", attrib);
549 debug3("match %sfound", result ? "" : "not ");
555 process_server_config_line(ServerOptions *options, char *line,
556 const char *filename, int linenum, int *activep, const char *user,
557 const char *host, const char *address)
559 char *cp, **charptr, *arg, *p;
560 int cmdline = 0, *intptr, value, n;
561 ServerOpCodes opcode;
567 if ((arg = strdelim(&cp)) == NULL)
569 /* Ignore leading whitespace */
572 if (!arg || !*arg || *arg == '#')
576 opcode = parse_token(arg, filename, linenum, &flags);
578 if (activep == NULL) { /* We are processing a command line directive */
582 if (*activep && opcode != sMatch)
583 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
584 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
586 fatal("%s line %d: Directive '%s' is not allowed "
587 "within a Match block", filename, linenum, arg);
588 } else { /* this is a directive we have already processed */
596 /* Portable-specific options */
598 intptr = &options->use_pam;
601 /* Standard Options */
605 /* ignore ports from configfile if cmdline specifies ports */
606 if (options->ports_from_cmdline)
608 if (options->listen_addrs != NULL)
609 fatal("%s line %d: ports must be specified before "
610 "ListenAddress.", filename, linenum);
611 if (options->num_ports >= MAX_PORTS)
612 fatal("%s line %d: too many ports.",
615 if (!arg || *arg == '\0')
616 fatal("%s line %d: missing port number.",
618 options->ports[options->num_ports++] = a2port(arg);
619 if (options->ports[options->num_ports-1] == 0)
620 fatal("%s line %d: Badly formatted port number.",
625 intptr = &options->server_key_bits;
628 if (!arg || *arg == '\0')
629 fatal("%s line %d: missing integer value.",
632 if (*activep && *intptr == -1)
636 case sLoginGraceTime:
637 intptr = &options->login_grace_time;
640 if (!arg || *arg == '\0')
641 fatal("%s line %d: missing time value.",
643 if ((value = convtime(arg)) == -1)
644 fatal("%s line %d: invalid time value.",
650 case sKeyRegenerationTime:
651 intptr = &options->key_regeneration_time;
656 if (arg == NULL || *arg == '\0')
657 fatal("%s line %d: missing address",
659 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
660 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
661 && strchr(p+1, ':') != NULL) {
662 add_listen_addr(options, arg, 0);
667 fatal("%s line %d: bad address:port usage",
669 p = cleanhostname(p);
672 else if ((port = a2port(arg)) == 0)
673 fatal("%s line %d: bad port number", filename, linenum);
675 add_listen_addr(options, p, port);
681 if (!arg || *arg == '\0')
682 fatal("%s line %d: missing address family.",
684 intptr = &options->address_family;
685 if (options->listen_addrs != NULL)
686 fatal("%s line %d: address family must be specified before "
687 "ListenAddress.", filename, linenum);
688 if (strcasecmp(arg, "inet") == 0)
690 else if (strcasecmp(arg, "inet6") == 0)
692 else if (strcasecmp(arg, "any") == 0)
695 fatal("%s line %d: unsupported address family \"%s\".",
696 filename, linenum, arg);
702 intptr = &options->num_host_key_files;
703 if (*intptr >= MAX_HOSTKEYS)
704 fatal("%s line %d: too many host keys specified (max %d).",
705 filename, linenum, MAX_HOSTKEYS);
706 charptr = &options->host_key_files[*intptr];
709 if (!arg || *arg == '\0')
710 fatal("%s line %d: missing file name.",
712 if (*activep && *charptr == NULL) {
713 *charptr = tilde_expand_filename(arg, getuid());
714 /* increase optional counter */
716 *intptr = *intptr + 1;
721 charptr = &options->pid_file;
724 case sPermitRootLogin:
725 intptr = &options->permit_root_login;
727 if (!arg || *arg == '\0')
728 fatal("%s line %d: missing yes/"
729 "without-password/forced-commands-only/no "
730 "argument.", filename, linenum);
731 value = 0; /* silence compiler */
732 if (strcmp(arg, "without-password") == 0)
733 value = PERMIT_NO_PASSWD;
734 else if (strcmp(arg, "forced-commands-only") == 0)
735 value = PERMIT_FORCED_ONLY;
736 else if (strcmp(arg, "yes") == 0)
738 else if (strcmp(arg, "no") == 0)
741 fatal("%s line %d: Bad yes/"
742 "without-password/forced-commands-only/no "
743 "argument: %s", filename, linenum, arg);
749 intptr = &options->ignore_rhosts;
752 if (!arg || *arg == '\0')
753 fatal("%s line %d: missing yes/no argument.",
755 value = 0; /* silence compiler */
756 if (strcmp(arg, "yes") == 0)
758 else if (strcmp(arg, "no") == 0)
761 fatal("%s line %d: Bad yes/no argument: %s",
762 filename, linenum, arg);
763 if (*activep && *intptr == -1)
767 case sIgnoreUserKnownHosts:
768 intptr = &options->ignore_user_known_hosts;
771 case sRhostsRSAAuthentication:
772 intptr = &options->rhosts_rsa_authentication;
775 case sHostbasedAuthentication:
776 intptr = &options->hostbased_authentication;
779 case sHostbasedUsesNameFromPacketOnly:
780 intptr = &options->hostbased_uses_name_from_packet_only;
783 case sRSAAuthentication:
784 intptr = &options->rsa_authentication;
787 case sPubkeyAuthentication:
788 intptr = &options->pubkey_authentication;
791 case sKerberosAuthentication:
792 intptr = &options->kerberos_authentication;
795 case sKerberosOrLocalPasswd:
796 intptr = &options->kerberos_or_local_passwd;
799 case sKerberosTicketCleanup:
800 intptr = &options->kerberos_ticket_cleanup;
803 case sKerberosGetAFSToken:
804 intptr = &options->kerberos_get_afs_token;
807 case sGssAuthentication:
808 intptr = &options->gss_authentication;
811 case sGssCleanupCreds:
812 intptr = &options->gss_cleanup_creds;
815 case sPasswordAuthentication:
816 intptr = &options->password_authentication;
819 case sKbdInteractiveAuthentication:
820 intptr = &options->kbd_interactive_authentication;
823 case sChallengeResponseAuthentication:
824 intptr = &options->challenge_response_authentication;
828 intptr = &options->print_motd;
832 intptr = &options->print_lastlog;
836 intptr = &options->x11_forwarding;
839 case sX11DisplayOffset:
840 intptr = &options->x11_display_offset;
843 case sX11UseLocalhost:
844 intptr = &options->x11_use_localhost;
848 charptr = &options->xauth_location;
852 intptr = &options->strict_modes;
856 intptr = &options->tcp_keep_alive;
860 intptr = &options->permit_empty_passwd;
863 case sPermitUserEnvironment:
864 intptr = &options->permit_user_env;
868 intptr = &options->use_login;
872 intptr = &options->compression;
874 if (!arg || *arg == '\0')
875 fatal("%s line %d: missing yes/no/delayed "
876 "argument.", filename, linenum);
877 value = 0; /* silence compiler */
878 if (strcmp(arg, "delayed") == 0)
879 value = COMP_DELAYED;
880 else if (strcmp(arg, "yes") == 0)
882 else if (strcmp(arg, "no") == 0)
885 fatal("%s line %d: Bad yes/no/delayed "
886 "argument: %s", filename, linenum, arg);
892 intptr = &options->gateway_ports;
894 if (!arg || *arg == '\0')
895 fatal("%s line %d: missing yes/no/clientspecified "
896 "argument.", filename, linenum);
897 value = 0; /* silence compiler */
898 if (strcmp(arg, "clientspecified") == 0)
900 else if (strcmp(arg, "yes") == 0)
902 else if (strcmp(arg, "no") == 0)
905 fatal("%s line %d: Bad yes/no/clientspecified "
906 "argument: %s", filename, linenum, arg);
912 intptr = &options->use_dns;
916 intptr = (int *) &options->log_facility;
918 value = log_facility_number(arg);
919 if (value == SYSLOG_FACILITY_NOT_SET)
920 fatal("%.200s line %d: unsupported log facility '%s'",
921 filename, linenum, arg ? arg : "<NONE>");
923 *intptr = (SyslogFacility) value;
927 intptr = (int *) &options->log_level;
929 value = log_level_number(arg);
930 if (value == SYSLOG_LEVEL_NOT_SET)
931 fatal("%.200s line %d: unsupported log level '%s'",
932 filename, linenum, arg ? arg : "<NONE>");
934 *intptr = (LogLevel) value;
937 case sAllowTcpForwarding:
938 intptr = &options->allow_tcp_forwarding;
941 case sUsePrivilegeSeparation:
942 intptr = &use_privsep;
946 while ((arg = strdelim(&cp)) && *arg != '\0') {
947 if (options->num_allow_users >= MAX_ALLOW_USERS)
948 fatal("%s line %d: too many allow users.",
950 options->allow_users[options->num_allow_users++] =
956 while ((arg = strdelim(&cp)) && *arg != '\0') {
957 if (options->num_deny_users >= MAX_DENY_USERS)
958 fatal( "%s line %d: too many deny users.",
960 options->deny_users[options->num_deny_users++] =
966 while ((arg = strdelim(&cp)) && *arg != '\0') {
967 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
968 fatal("%s line %d: too many allow groups.",
970 options->allow_groups[options->num_allow_groups++] =
976 while ((arg = strdelim(&cp)) && *arg != '\0') {
977 if (options->num_deny_groups >= MAX_DENY_GROUPS)
978 fatal("%s line %d: too many deny groups.",
980 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
986 if (!arg || *arg == '\0')
987 fatal("%s line %d: Missing argument.", filename, linenum);
988 if (!ciphers_valid(arg))
989 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
990 filename, linenum, arg ? arg : "<NONE>");
991 if (options->ciphers == NULL)
992 options->ciphers = xstrdup(arg);
997 if (!arg || *arg == '\0')
998 fatal("%s line %d: Missing argument.", filename, linenum);
1000 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1001 filename, linenum, arg ? arg : "<NONE>");
1002 if (options->macs == NULL)
1003 options->macs = xstrdup(arg);
1007 intptr = &options->protocol;
1008 arg = strdelim(&cp);
1009 if (!arg || *arg == '\0')
1010 fatal("%s line %d: Missing argument.", filename, linenum);
1011 value = proto_spec(arg);
1012 if (value == SSH_PROTO_UNKNOWN)
1013 fatal("%s line %d: Bad protocol spec '%s'.",
1014 filename, linenum, arg ? arg : "<NONE>");
1015 if (*intptr == SSH_PROTO_UNKNOWN)
1020 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1021 fatal("%s line %d: too many subsystems defined.",
1024 arg = strdelim(&cp);
1025 if (!arg || *arg == '\0')
1026 fatal("%s line %d: Missing subsystem name.",
1029 arg = strdelim(&cp);
1032 for (i = 0; i < options->num_subsystems; i++)
1033 if (strcmp(arg, options->subsystem_name[i]) == 0)
1034 fatal("%s line %d: Subsystem '%s' already defined.",
1035 filename, linenum, arg);
1036 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1037 arg = strdelim(&cp);
1038 if (!arg || *arg == '\0')
1039 fatal("%s line %d: Missing subsystem command.",
1041 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1043 /* Collect arguments (separate to executable) */
1045 len = strlen(p) + 1;
1046 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1047 len += 1 + strlen(arg);
1048 p = xrealloc(p, 1, len);
1049 strlcat(p, " ", len);
1050 strlcat(p, arg, len);
1052 options->subsystem_args[options->num_subsystems] = p;
1053 options->num_subsystems++;
1057 arg = strdelim(&cp);
1058 if (!arg || *arg == '\0')
1059 fatal("%s line %d: Missing MaxStartups spec.",
1061 if ((n = sscanf(arg, "%d:%d:%d",
1062 &options->max_startups_begin,
1063 &options->max_startups_rate,
1064 &options->max_startups)) == 3) {
1065 if (options->max_startups_begin >
1066 options->max_startups ||
1067 options->max_startups_rate > 100 ||
1068 options->max_startups_rate < 1)
1069 fatal("%s line %d: Illegal MaxStartups spec.",
1072 fatal("%s line %d: Illegal MaxStartups spec.",
1075 options->max_startups = options->max_startups_begin;
1079 intptr = &options->max_authtries;
1083 charptr = &options->banner;
1084 goto parse_filename;
1086 * These options can contain %X options expanded at
1087 * connect time, so that you can specify paths like:
1089 * AuthorizedKeysFile /etc/ssh_keys/%u
1091 case sAuthorizedKeysFile:
1092 case sAuthorizedKeysFile2:
1093 charptr = (opcode == sAuthorizedKeysFile ) ?
1094 &options->authorized_keys_file :
1095 &options->authorized_keys_file2;
1096 goto parse_filename;
1098 case sClientAliveInterval:
1099 intptr = &options->client_alive_interval;
1102 case sClientAliveCountMax:
1103 intptr = &options->client_alive_count_max;
1107 while ((arg = strdelim(&cp)) && *arg != '\0') {
1108 if (strchr(arg, '=') != NULL)
1109 fatal("%s line %d: Invalid environment name.",
1111 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1112 fatal("%s line %d: too many allow env.",
1116 options->accept_env[options->num_accept_env++] =
1122 intptr = &options->permit_tun;
1123 arg = strdelim(&cp);
1124 if (!arg || *arg == '\0')
1125 fatal("%s line %d: Missing yes/point-to-point/"
1126 "ethernet/no argument.", filename, linenum);
1127 value = 0; /* silence compiler */
1128 if (strcasecmp(arg, "ethernet") == 0)
1129 value = SSH_TUNMODE_ETHERNET;
1130 else if (strcasecmp(arg, "point-to-point") == 0)
1131 value = SSH_TUNMODE_POINTOPOINT;
1132 else if (strcasecmp(arg, "yes") == 0)
1133 value = SSH_TUNMODE_YES;
1134 else if (strcasecmp(arg, "no") == 0)
1135 value = SSH_TUNMODE_NO;
1137 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1138 "no argument: %s", filename, linenum, arg);
1145 fatal("Match directive not supported as a command-line "
1147 value = match_cfg_line(&cp, linenum, user, host, address);
1149 fatal("%s line %d: Bad Match condition", filename,
1155 arg = strdelim(&cp);
1156 if (!arg || *arg == '\0')
1157 fatal("%s line %d: missing PermitOpen specification",
1159 if (strcmp(arg, "any") == 0) {
1161 channel_clear_adm_permitted_opens();
1166 fatal("%s line %d: missing host in PermitOpen",
1168 p = cleanhostname(p);
1169 if (arg == NULL || (port = a2port(arg)) == 0)
1170 fatal("%s line %d: bad port number in PermitOpen",
1173 channel_add_adm_permitted_opens(p, port);
1177 logit("%s line %d: Deprecated option %s",
1178 filename, linenum, arg);
1180 arg = strdelim(&cp);
1184 logit("%s line %d: Unsupported option %s",
1185 filename, linenum, arg);
1187 arg = strdelim(&cp);
1191 fatal("%s line %d: Missing handler for opcode %s (%d)",
1192 filename, linenum, arg, opcode);
1194 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1195 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1196 filename, linenum, arg);
1200 /* Reads the server configuration file. */
1203 load_server_config(const char *filename, Buffer *conf)
1205 char line[1024], *cp;
1208 debug2("%s: filename %s", __func__, filename);
1209 if ((f = fopen(filename, "r")) == NULL) {
1214 while (fgets(line, sizeof(line), f)) {
1216 * Trim out comments and strip whitespace
1217 * NB - preserve newlines, they are needed to reproduce
1218 * line numbers later for error messages
1220 if ((cp = strchr(line, '#')) != NULL)
1221 memcpy(cp, "\n", 2);
1222 cp = line + strspn(line, " \t\r");
1224 buffer_append(conf, cp, strlen(cp));
1226 buffer_append(conf, "\0", 1);
1228 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1232 parse_server_match_config(ServerOptions *options, const char *user,
1233 const char *host, const char *address)
1237 initialize_server_options(&mo);
1238 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1239 copy_set_server_options(options, &mo);
1242 /* Copy any (supported) values that are set */
1244 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1246 if (src->allow_tcp_forwarding != -1)
1247 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1248 if (src->gateway_ports != -1)
1249 dst->gateway_ports = src->gateway_ports;
1253 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1254 const char *user, const char *host, const char *address)
1256 int active, linenum, bad_options = 0;
1257 char *cp, *obuf, *cbuf;
1259 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1261 obuf = cbuf = xstrdup(buffer_ptr(conf));
1262 active = user ? 0 : 1;
1264 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1265 if (process_server_config_line(options, cp, filename,
1266 linenum++, &active, user, host, address) != 0)
1270 if (bad_options > 0)
1271 fatal("%s: terminating, %d bad configuration options",
1272 filename, bad_options);