1 /* $OpenBSD: servconf.c,v 1.172 2007/04/23 10:15:39 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>
33 #include "pathnames.h"
41 #include "groupaccess.h"
43 static void add_listen_addr(ServerOptions *, char *, u_short);
44 static void add_one_listen_addr(ServerOptions *, char *, u_short);
46 /* Use of privilege separation or not */
47 extern int use_privsep;
50 /* Initializes the server options to their default values. */
53 initialize_server_options(ServerOptions *options)
55 memset(options, 0, sizeof(*options));
57 /* Portable-specific options */
58 options->use_pam = -1;
60 /* Standard Options */
61 options->num_ports = 0;
62 options->ports_from_cmdline = 0;
63 options->listen_addrs = NULL;
64 options->address_family = -1;
65 options->num_host_key_files = 0;
66 options->pid_file = NULL;
67 options->server_key_bits = -1;
68 options->login_grace_time = -1;
69 options->key_regeneration_time = -1;
70 options->permit_root_login = PERMIT_NOT_SET;
71 options->ignore_rhosts = -1;
72 options->ignore_user_known_hosts = -1;
73 options->print_motd = -1;
74 options->print_lastlog = -1;
75 options->x11_forwarding = -1;
76 options->x11_display_offset = -1;
77 options->x11_use_localhost = -1;
78 options->xauth_location = NULL;
79 options->strict_modes = -1;
80 options->tcp_keep_alive = -1;
81 options->log_facility = SYSLOG_FACILITY_NOT_SET;
82 options->log_level = SYSLOG_LEVEL_NOT_SET;
83 options->rhosts_rsa_authentication = -1;
84 options->hostbased_authentication = -1;
85 options->hostbased_uses_name_from_packet_only = -1;
86 options->rsa_authentication = -1;
87 options->pubkey_authentication = -1;
88 options->kerberos_authentication = -1;
89 options->kerberos_or_local_passwd = -1;
90 options->kerberos_ticket_cleanup = -1;
91 options->kerberos_get_afs_token = -1;
92 options->gss_authentication=-1;
93 options->gss_cleanup_creds = -1;
94 options->password_authentication = -1;
95 options->kbd_interactive_authentication = -1;
96 options->challenge_response_authentication = -1;
97 options->permit_empty_passwd = -1;
98 options->permit_user_env = -1;
99 options->use_login = -1;
100 options->compression = -1;
101 options->allow_tcp_forwarding = -1;
102 options->num_allow_users = 0;
103 options->num_deny_users = 0;
104 options->num_allow_groups = 0;
105 options->num_deny_groups = 0;
106 options->ciphers = NULL;
107 options->macs = NULL;
108 options->protocol = SSH_PROTO_UNKNOWN;
109 options->gateway_ports = -1;
110 options->num_subsystems = 0;
111 options->max_startups_begin = -1;
112 options->max_startups_rate = -1;
113 options->max_startups = -1;
114 options->max_authtries = -1;
115 options->banner = NULL;
116 options->use_dns = -1;
117 options->client_alive_interval = -1;
118 options->client_alive_count_max = -1;
119 options->authorized_keys_file = NULL;
120 options->authorized_keys_file2 = NULL;
121 options->num_accept_env = 0;
122 options->permit_tun = -1;
123 options->num_permitted_opens = -1;
124 options->adm_forced_command = NULL;
128 fill_default_server_options(ServerOptions *options)
130 /* Portable-specific options */
131 if (options->use_pam == -1)
132 options->use_pam = 0;
134 /* Standard Options */
135 if (options->protocol == SSH_PROTO_UNKNOWN)
136 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
137 if (options->num_host_key_files == 0) {
138 /* fill default hostkeys for protocols */
139 if (options->protocol & SSH_PROTO_1)
140 options->host_key_files[options->num_host_key_files++] =
142 if (options->protocol & SSH_PROTO_2) {
143 options->host_key_files[options->num_host_key_files++] =
144 _PATH_HOST_RSA_KEY_FILE;
145 options->host_key_files[options->num_host_key_files++] =
146 _PATH_HOST_DSA_KEY_FILE;
149 if (options->num_ports == 0)
150 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
151 if (options->listen_addrs == NULL)
152 add_listen_addr(options, NULL, 0);
153 if (options->pid_file == NULL)
154 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
155 if (options->server_key_bits == -1)
156 options->server_key_bits = 768;
157 if (options->login_grace_time == -1)
158 options->login_grace_time = 120;
159 if (options->key_regeneration_time == -1)
160 options->key_regeneration_time = 3600;
161 if (options->permit_root_login == PERMIT_NOT_SET)
162 options->permit_root_login = PERMIT_YES;
163 if (options->ignore_rhosts == -1)
164 options->ignore_rhosts = 1;
165 if (options->ignore_user_known_hosts == -1)
166 options->ignore_user_known_hosts = 0;
167 if (options->print_motd == -1)
168 options->print_motd = 1;
169 if (options->print_lastlog == -1)
170 options->print_lastlog = 1;
171 if (options->x11_forwarding == -1)
172 options->x11_forwarding = 0;
173 if (options->x11_display_offset == -1)
174 options->x11_display_offset = 10;
175 if (options->x11_use_localhost == -1)
176 options->x11_use_localhost = 1;
177 if (options->xauth_location == NULL)
178 options->xauth_location = _PATH_XAUTH;
179 if (options->strict_modes == -1)
180 options->strict_modes = 1;
181 if (options->tcp_keep_alive == -1)
182 options->tcp_keep_alive = 1;
183 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
184 options->log_facility = SYSLOG_FACILITY_AUTH;
185 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
186 options->log_level = SYSLOG_LEVEL_INFO;
187 if (options->rhosts_rsa_authentication == -1)
188 options->rhosts_rsa_authentication = 0;
189 if (options->hostbased_authentication == -1)
190 options->hostbased_authentication = 0;
191 if (options->hostbased_uses_name_from_packet_only == -1)
192 options->hostbased_uses_name_from_packet_only = 0;
193 if (options->rsa_authentication == -1)
194 options->rsa_authentication = 1;
195 if (options->pubkey_authentication == -1)
196 options->pubkey_authentication = 1;
197 if (options->kerberos_authentication == -1)
198 options->kerberos_authentication = 0;
199 if (options->kerberos_or_local_passwd == -1)
200 options->kerberos_or_local_passwd = 1;
201 if (options->kerberos_ticket_cleanup == -1)
202 options->kerberos_ticket_cleanup = 1;
203 if (options->kerberos_get_afs_token == -1)
204 options->kerberos_get_afs_token = 0;
205 if (options->gss_authentication == -1)
206 options->gss_authentication = 0;
207 if (options->gss_cleanup_creds == -1)
208 options->gss_cleanup_creds = 1;
209 if (options->password_authentication == -1)
210 options->password_authentication = 1;
211 if (options->kbd_interactive_authentication == -1)
212 options->kbd_interactive_authentication = 0;
213 if (options->challenge_response_authentication == -1)
214 options->challenge_response_authentication = 1;
215 if (options->permit_empty_passwd == -1)
216 options->permit_empty_passwd = 0;
217 if (options->permit_user_env == -1)
218 options->permit_user_env = 0;
219 if (options->use_login == -1)
220 options->use_login = 0;
221 if (options->compression == -1)
222 options->compression = COMP_DELAYED;
223 if (options->allow_tcp_forwarding == -1)
224 options->allow_tcp_forwarding = 1;
225 if (options->gateway_ports == -1)
226 options->gateway_ports = 0;
227 if (options->max_startups == -1)
228 options->max_startups = 10;
229 if (options->max_startups_rate == -1)
230 options->max_startups_rate = 100; /* 100% */
231 if (options->max_startups_begin == -1)
232 options->max_startups_begin = options->max_startups;
233 if (options->max_authtries == -1)
234 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
235 if (options->use_dns == -1)
236 options->use_dns = 1;
237 if (options->client_alive_interval == -1)
238 options->client_alive_interval = 0;
239 if (options->client_alive_count_max == -1)
240 options->client_alive_count_max = 3;
241 if (options->authorized_keys_file2 == NULL) {
242 /* authorized_keys_file2 falls back to authorized_keys_file */
243 if (options->authorized_keys_file != NULL)
244 options->authorized_keys_file2 = options->authorized_keys_file;
246 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
248 if (options->authorized_keys_file == NULL)
249 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
250 if (options->permit_tun == -1)
251 options->permit_tun = SSH_TUNMODE_NO;
253 /* Turn privilege separation on by default */
254 if (use_privsep == -1)
258 if (use_privsep && options->compression == 1) {
259 error("This platform does not support both privilege "
260 "separation and compression");
261 error("Compression disabled");
262 options->compression = 0;
268 /* Keyword tokens. */
270 sBadOption, /* == unknown option */
271 /* Portable-specific options */
273 /* Standard Options */
274 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
275 sPermitRootLogin, sLogFacility, sLogLevel,
276 sRhostsRSAAuthentication, sRSAAuthentication,
277 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
278 sKerberosGetAFSToken,
279 sKerberosTgtPassing, sChallengeResponseAuthentication,
280 sPasswordAuthentication, sKbdInteractiveAuthentication,
281 sListenAddress, sAddressFamily,
282 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
283 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
284 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
285 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
286 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
287 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
288 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
289 sMaxStartups, sMaxAuthTries,
290 sBanner, sUseDNS, sHostbasedAuthentication,
291 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
292 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
293 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
294 sMatch, sPermitOpen, sForceCommand,
295 sUsePrivilegeSeparation,
296 sDeprecated, sUnsupported
299 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
300 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
301 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
303 /* Textual representation of the tokens. */
306 ServerOpCodes opcode;
309 /* Portable-specific options */
311 { "usepam", sUsePAM, SSHCFG_GLOBAL },
313 { "usepam", sUnsupported, SSHCFG_GLOBAL },
315 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
316 /* Standard Options */
317 { "port", sPort, SSHCFG_GLOBAL },
318 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
319 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
320 { "pidfile", sPidFile, SSHCFG_GLOBAL },
321 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
322 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
323 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
324 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
325 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
326 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
327 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
328 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
329 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
330 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
331 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
332 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
333 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
335 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
336 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
337 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
339 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
341 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
344 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
345 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
346 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
347 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
349 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
350 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
352 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
353 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
355 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
356 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
358 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
359 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
360 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
361 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
362 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
363 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
364 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
365 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
366 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
367 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
368 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
369 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
370 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
371 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
372 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
373 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
374 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
375 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
376 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
377 { "compression", sCompression, SSHCFG_GLOBAL },
378 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
379 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
380 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
381 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
382 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
383 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
384 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
385 { "ciphers", sCiphers, SSHCFG_GLOBAL },
386 { "macs", sMacs, SSHCFG_GLOBAL },
387 { "protocol", sProtocol, SSHCFG_GLOBAL },
388 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
389 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
390 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
391 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
392 { "banner", sBanner, SSHCFG_ALL },
393 { "usedns", sUseDNS, SSHCFG_GLOBAL },
394 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
395 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
396 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
397 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
398 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
399 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
400 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
401 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
402 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
403 { "match", sMatch, SSHCFG_ALL },
404 { "permitopen", sPermitOpen, SSHCFG_ALL },
405 { "forcecommand", sForceCommand, SSHCFG_ALL },
406 { NULL, sBadOption, 0 }
410 * Returns the number of the token pointed to by cp or sBadOption.
414 parse_token(const char *cp, const char *filename,
415 int linenum, u_int *flags)
419 for (i = 0; keywords[i].name; i++)
420 if (strcasecmp(cp, keywords[i].name) == 0) {
421 *flags = keywords[i].flags;
422 return keywords[i].opcode;
425 error("%s: line %d: Bad configuration option: %s",
426 filename, linenum, cp);
431 add_listen_addr(ServerOptions *options, char *addr, u_short port)
435 if (options->num_ports == 0)
436 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
437 if (options->address_family == -1)
438 options->address_family = AF_UNSPEC;
440 for (i = 0; i < options->num_ports; i++)
441 add_one_listen_addr(options, addr, options->ports[i]);
443 add_one_listen_addr(options, addr, port);
447 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
449 struct addrinfo hints, *ai, *aitop;
450 char strport[NI_MAXSERV];
453 memset(&hints, 0, sizeof(hints));
454 hints.ai_family = options->address_family;
455 hints.ai_socktype = SOCK_STREAM;
456 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
457 snprintf(strport, sizeof strport, "%u", port);
458 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
459 fatal("bad addr or host: %s (%s)",
460 addr ? addr : "<NULL>",
461 gai_strerror(gaierr));
462 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
464 ai->ai_next = options->listen_addrs;
465 options->listen_addrs = aitop;
469 * The strategy for the Match blocks is that the config file is parsed twice.
471 * The first time is at startup. activep is initialized to 1 and the
472 * directives in the global context are processed and acted on. Hitting a
473 * Match directive unsets activep and the directives inside the block are
474 * checked for syntax only.
476 * The second time is after a connection has been established but before
477 * authentication. activep is initialized to 2 and global config directives
478 * are ignored since they have already been processed. If the criteria in a
479 * Match block is met, activep is set and the subsequent directives
480 * processed and actioned until EOF or another Match block unsets it. Any
481 * options set are copied into the main server config.
483 * Potential additions/improvements:
484 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
486 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
487 * Match Address 192.168.0.*
492 * AllowTcpForwarding yes
493 * GatewayPorts clientspecified
496 * - Add a PermittedChannelRequests directive
498 * PermittedChannelRequests session,forwarded-tcpip
502 match_cfg_line_group(const char *grps, int line, const char *user)
506 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
510 * Even if we do not have a user yet, we still need to check for
513 arg = cp = xstrdup(grps);
514 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
515 if (ngrps >= MAX_MATCH_GROUPS) {
516 error("line %d: too many groups in Match Group", line);
520 grplist[ngrps++] = p;
526 if ((pw = getpwnam(user)) == NULL) {
527 debug("Can't match group at line %d because user %.100s does "
528 "not exist", line, user);
529 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
530 debug("Can't Match group because user %.100s not in any group "
531 "at line %d", user, line);
532 } else if (ga_match(grplist, ngrps) != 1) {
533 debug("user %.100s does not match group %.100s at line %d",
536 debug("user %.100s matched group %.100s at line %d", user,
547 match_cfg_line(char **condition, int line, const char *user, const char *host,
551 char *arg, *attrib, *cp = *condition;
555 debug3("checking syntax for 'Match %s'", cp);
557 debug3("checking match for '%s' user %s host %s addr %s", cp,
558 user ? user : "(null)", host ? host : "(null)",
559 address ? address : "(null)");
561 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
562 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
563 error("Missing Match criteria for %s", attrib);
567 if (strcasecmp(attrib, "user") == 0) {
572 if (match_pattern_list(user, arg, len, 0) != 1)
575 debug("user %.100s matched 'User %.100s' at "
576 "line %d", user, arg, line);
577 } else if (strcasecmp(attrib, "group") == 0) {
578 switch (match_cfg_line_group(arg, line, user)) {
584 } else if (strcasecmp(attrib, "host") == 0) {
589 if (match_hostname(host, arg, len) != 1)
592 debug("connection from %.100s matched 'Host "
593 "%.100s' at line %d", host, arg, line);
594 } else if (strcasecmp(attrib, "address") == 0) {
599 if (match_hostname(address, arg, len) != 1)
602 debug("connection from %.100s matched 'Address "
603 "%.100s' at line %d", address, arg, line);
605 error("Unsupported Match attribute %s", attrib);
610 debug3("match %sfound", result ? "" : "not ");
615 #define WHITESPACE " \t\r\n"
618 process_server_config_line(ServerOptions *options, char *line,
619 const char *filename, int linenum, int *activep, const char *user,
620 const char *host, const char *address)
622 char *cp, **charptr, *arg, *p;
623 int cmdline = 0, *intptr, value, n;
624 ServerOpCodes opcode;
630 if ((arg = strdelim(&cp)) == NULL)
632 /* Ignore leading whitespace */
635 if (!arg || !*arg || *arg == '#')
639 opcode = parse_token(arg, filename, linenum, &flags);
641 if (activep == NULL) { /* We are processing a command line directive */
645 if (*activep && opcode != sMatch)
646 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
647 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
649 fatal("%s line %d: Directive '%s' is not allowed "
650 "within a Match block", filename, linenum, arg);
651 } else { /* this is a directive we have already processed */
659 /* Portable-specific options */
661 intptr = &options->use_pam;
664 /* Standard Options */
668 /* ignore ports from configfile if cmdline specifies ports */
669 if (options->ports_from_cmdline)
671 if (options->listen_addrs != NULL)
672 fatal("%s line %d: ports must be specified before "
673 "ListenAddress.", filename, linenum);
674 if (options->num_ports >= MAX_PORTS)
675 fatal("%s line %d: too many ports.",
678 if (!arg || *arg == '\0')
679 fatal("%s line %d: missing port number.",
681 options->ports[options->num_ports++] = a2port(arg);
682 if (options->ports[options->num_ports-1] == 0)
683 fatal("%s line %d: Badly formatted port number.",
688 intptr = &options->server_key_bits;
691 if (!arg || *arg == '\0')
692 fatal("%s line %d: missing integer value.",
695 if (*activep && *intptr == -1)
699 case sLoginGraceTime:
700 intptr = &options->login_grace_time;
703 if (!arg || *arg == '\0')
704 fatal("%s line %d: missing time value.",
706 if ((value = convtime(arg)) == -1)
707 fatal("%s line %d: invalid time value.",
713 case sKeyRegenerationTime:
714 intptr = &options->key_regeneration_time;
719 if (arg == NULL || *arg == '\0')
720 fatal("%s line %d: missing address",
722 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
723 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
724 && strchr(p+1, ':') != NULL) {
725 add_listen_addr(options, arg, 0);
730 fatal("%s line %d: bad address:port usage",
732 p = cleanhostname(p);
735 else if ((port = a2port(arg)) == 0)
736 fatal("%s line %d: bad port number", filename, linenum);
738 add_listen_addr(options, p, port);
744 if (!arg || *arg == '\0')
745 fatal("%s line %d: missing address family.",
747 intptr = &options->address_family;
748 if (options->listen_addrs != NULL)
749 fatal("%s line %d: address family must be specified before "
750 "ListenAddress.", filename, linenum);
751 if (strcasecmp(arg, "inet") == 0)
753 else if (strcasecmp(arg, "inet6") == 0)
755 else if (strcasecmp(arg, "any") == 0)
758 fatal("%s line %d: unsupported address family \"%s\".",
759 filename, linenum, arg);
765 intptr = &options->num_host_key_files;
766 if (*intptr >= MAX_HOSTKEYS)
767 fatal("%s line %d: too many host keys specified (max %d).",
768 filename, linenum, MAX_HOSTKEYS);
769 charptr = &options->host_key_files[*intptr];
772 if (!arg || *arg == '\0')
773 fatal("%s line %d: missing file name.",
775 if (*activep && *charptr == NULL) {
776 *charptr = tilde_expand_filename(arg, getuid());
777 /* increase optional counter */
779 *intptr = *intptr + 1;
784 charptr = &options->pid_file;
787 case sPermitRootLogin:
788 intptr = &options->permit_root_login;
790 if (!arg || *arg == '\0')
791 fatal("%s line %d: missing yes/"
792 "without-password/forced-commands-only/no "
793 "argument.", filename, linenum);
794 value = 0; /* silence compiler */
795 if (strcmp(arg, "without-password") == 0)
796 value = PERMIT_NO_PASSWD;
797 else if (strcmp(arg, "forced-commands-only") == 0)
798 value = PERMIT_FORCED_ONLY;
799 else if (strcmp(arg, "yes") == 0)
801 else if (strcmp(arg, "no") == 0)
804 fatal("%s line %d: Bad yes/"
805 "without-password/forced-commands-only/no "
806 "argument: %s", filename, linenum, arg);
812 intptr = &options->ignore_rhosts;
815 if (!arg || *arg == '\0')
816 fatal("%s line %d: missing yes/no argument.",
818 value = 0; /* silence compiler */
819 if (strcmp(arg, "yes") == 0)
821 else if (strcmp(arg, "no") == 0)
824 fatal("%s line %d: Bad yes/no argument: %s",
825 filename, linenum, arg);
826 if (*activep && *intptr == -1)
830 case sIgnoreUserKnownHosts:
831 intptr = &options->ignore_user_known_hosts;
834 case sRhostsRSAAuthentication:
835 intptr = &options->rhosts_rsa_authentication;
838 case sHostbasedAuthentication:
839 intptr = &options->hostbased_authentication;
842 case sHostbasedUsesNameFromPacketOnly:
843 intptr = &options->hostbased_uses_name_from_packet_only;
846 case sRSAAuthentication:
847 intptr = &options->rsa_authentication;
850 case sPubkeyAuthentication:
851 intptr = &options->pubkey_authentication;
854 case sKerberosAuthentication:
855 intptr = &options->kerberos_authentication;
858 case sKerberosOrLocalPasswd:
859 intptr = &options->kerberos_or_local_passwd;
862 case sKerberosTicketCleanup:
863 intptr = &options->kerberos_ticket_cleanup;
866 case sKerberosGetAFSToken:
867 intptr = &options->kerberos_get_afs_token;
870 case sGssAuthentication:
871 intptr = &options->gss_authentication;
874 case sGssCleanupCreds:
875 intptr = &options->gss_cleanup_creds;
878 case sPasswordAuthentication:
879 intptr = &options->password_authentication;
882 case sKbdInteractiveAuthentication:
883 intptr = &options->kbd_interactive_authentication;
886 case sChallengeResponseAuthentication:
887 intptr = &options->challenge_response_authentication;
891 intptr = &options->print_motd;
895 intptr = &options->print_lastlog;
899 intptr = &options->x11_forwarding;
902 case sX11DisplayOffset:
903 intptr = &options->x11_display_offset;
906 case sX11UseLocalhost:
907 intptr = &options->x11_use_localhost;
911 charptr = &options->xauth_location;
915 intptr = &options->strict_modes;
919 intptr = &options->tcp_keep_alive;
923 intptr = &options->permit_empty_passwd;
926 case sPermitUserEnvironment:
927 intptr = &options->permit_user_env;
931 intptr = &options->use_login;
935 intptr = &options->compression;
937 if (!arg || *arg == '\0')
938 fatal("%s line %d: missing yes/no/delayed "
939 "argument.", filename, linenum);
940 value = 0; /* silence compiler */
941 if (strcmp(arg, "delayed") == 0)
942 value = COMP_DELAYED;
943 else if (strcmp(arg, "yes") == 0)
945 else if (strcmp(arg, "no") == 0)
948 fatal("%s line %d: Bad yes/no/delayed "
949 "argument: %s", filename, linenum, arg);
955 intptr = &options->gateway_ports;
957 if (!arg || *arg == '\0')
958 fatal("%s line %d: missing yes/no/clientspecified "
959 "argument.", filename, linenum);
960 value = 0; /* silence compiler */
961 if (strcmp(arg, "clientspecified") == 0)
963 else if (strcmp(arg, "yes") == 0)
965 else if (strcmp(arg, "no") == 0)
968 fatal("%s line %d: Bad yes/no/clientspecified "
969 "argument: %s", filename, linenum, arg);
970 if (*activep && *intptr == -1)
975 intptr = &options->use_dns;
979 intptr = (int *) &options->log_facility;
981 value = log_facility_number(arg);
982 if (value == SYSLOG_FACILITY_NOT_SET)
983 fatal("%.200s line %d: unsupported log facility '%s'",
984 filename, linenum, arg ? arg : "<NONE>");
986 *intptr = (SyslogFacility) value;
990 intptr = (int *) &options->log_level;
992 value = log_level_number(arg);
993 if (value == SYSLOG_LEVEL_NOT_SET)
994 fatal("%.200s line %d: unsupported log level '%s'",
995 filename, linenum, arg ? arg : "<NONE>");
997 *intptr = (LogLevel) value;
1000 case sAllowTcpForwarding:
1001 intptr = &options->allow_tcp_forwarding;
1004 case sUsePrivilegeSeparation:
1005 intptr = &use_privsep;
1009 while ((arg = strdelim(&cp)) && *arg != '\0') {
1010 if (options->num_allow_users >= MAX_ALLOW_USERS)
1011 fatal("%s line %d: too many allow users.",
1013 options->allow_users[options->num_allow_users++] =
1019 while ((arg = strdelim(&cp)) && *arg != '\0') {
1020 if (options->num_deny_users >= MAX_DENY_USERS)
1021 fatal("%s line %d: too many deny users.",
1023 options->deny_users[options->num_deny_users++] =
1029 while ((arg = strdelim(&cp)) && *arg != '\0') {
1030 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1031 fatal("%s line %d: too many allow groups.",
1033 options->allow_groups[options->num_allow_groups++] =
1039 while ((arg = strdelim(&cp)) && *arg != '\0') {
1040 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1041 fatal("%s line %d: too many deny groups.",
1043 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1048 arg = strdelim(&cp);
1049 if (!arg || *arg == '\0')
1050 fatal("%s line %d: Missing argument.", filename, linenum);
1051 if (!ciphers_valid(arg))
1052 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1053 filename, linenum, arg ? arg : "<NONE>");
1054 if (options->ciphers == NULL)
1055 options->ciphers = xstrdup(arg);
1059 arg = strdelim(&cp);
1060 if (!arg || *arg == '\0')
1061 fatal("%s line %d: Missing argument.", filename, linenum);
1062 if (!mac_valid(arg))
1063 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1064 filename, linenum, arg ? arg : "<NONE>");
1065 if (options->macs == NULL)
1066 options->macs = xstrdup(arg);
1070 intptr = &options->protocol;
1071 arg = strdelim(&cp);
1072 if (!arg || *arg == '\0')
1073 fatal("%s line %d: Missing argument.", filename, linenum);
1074 value = proto_spec(arg);
1075 if (value == SSH_PROTO_UNKNOWN)
1076 fatal("%s line %d: Bad protocol spec '%s'.",
1077 filename, linenum, arg ? arg : "<NONE>");
1078 if (*intptr == SSH_PROTO_UNKNOWN)
1083 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1084 fatal("%s line %d: too many subsystems defined.",
1087 arg = strdelim(&cp);
1088 if (!arg || *arg == '\0')
1089 fatal("%s line %d: Missing subsystem name.",
1092 arg = strdelim(&cp);
1095 for (i = 0; i < options->num_subsystems; i++)
1096 if (strcmp(arg, options->subsystem_name[i]) == 0)
1097 fatal("%s line %d: Subsystem '%s' already defined.",
1098 filename, linenum, arg);
1099 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1100 arg = strdelim(&cp);
1101 if (!arg || *arg == '\0')
1102 fatal("%s line %d: Missing subsystem command.",
1104 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1106 /* Collect arguments (separate to executable) */
1108 len = strlen(p) + 1;
1109 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1110 len += 1 + strlen(arg);
1111 p = xrealloc(p, 1, len);
1112 strlcat(p, " ", len);
1113 strlcat(p, arg, len);
1115 options->subsystem_args[options->num_subsystems] = p;
1116 options->num_subsystems++;
1120 arg = strdelim(&cp);
1121 if (!arg || *arg == '\0')
1122 fatal("%s line %d: Missing MaxStartups spec.",
1124 if ((n = sscanf(arg, "%d:%d:%d",
1125 &options->max_startups_begin,
1126 &options->max_startups_rate,
1127 &options->max_startups)) == 3) {
1128 if (options->max_startups_begin >
1129 options->max_startups ||
1130 options->max_startups_rate > 100 ||
1131 options->max_startups_rate < 1)
1132 fatal("%s line %d: Illegal MaxStartups spec.",
1135 fatal("%s line %d: Illegal MaxStartups spec.",
1138 options->max_startups = options->max_startups_begin;
1142 intptr = &options->max_authtries;
1146 charptr = &options->banner;
1147 goto parse_filename;
1149 * These options can contain %X options expanded at
1150 * connect time, so that you can specify paths like:
1152 * AuthorizedKeysFile /etc/ssh_keys/%u
1154 case sAuthorizedKeysFile:
1155 case sAuthorizedKeysFile2:
1156 charptr = (opcode == sAuthorizedKeysFile) ?
1157 &options->authorized_keys_file :
1158 &options->authorized_keys_file2;
1159 goto parse_filename;
1161 case sClientAliveInterval:
1162 intptr = &options->client_alive_interval;
1165 case sClientAliveCountMax:
1166 intptr = &options->client_alive_count_max;
1170 while ((arg = strdelim(&cp)) && *arg != '\0') {
1171 if (strchr(arg, '=') != NULL)
1172 fatal("%s line %d: Invalid environment name.",
1174 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1175 fatal("%s line %d: too many allow env.",
1179 options->accept_env[options->num_accept_env++] =
1185 intptr = &options->permit_tun;
1186 arg = strdelim(&cp);
1187 if (!arg || *arg == '\0')
1188 fatal("%s line %d: Missing yes/point-to-point/"
1189 "ethernet/no argument.", filename, linenum);
1190 value = 0; /* silence compiler */
1191 if (strcasecmp(arg, "ethernet") == 0)
1192 value = SSH_TUNMODE_ETHERNET;
1193 else if (strcasecmp(arg, "point-to-point") == 0)
1194 value = SSH_TUNMODE_POINTOPOINT;
1195 else if (strcasecmp(arg, "yes") == 0)
1196 value = SSH_TUNMODE_YES;
1197 else if (strcasecmp(arg, "no") == 0)
1198 value = SSH_TUNMODE_NO;
1200 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1201 "no argument: %s", filename, linenum, arg);
1208 fatal("Match directive not supported as a command-line "
1210 value = match_cfg_line(&cp, linenum, user, host, address);
1212 fatal("%s line %d: Bad Match condition", filename,
1218 arg = strdelim(&cp);
1219 if (!arg || *arg == '\0')
1220 fatal("%s line %d: missing PermitOpen specification",
1222 n = options->num_permitted_opens; /* modified later */
1223 if (strcmp(arg, "any") == 0) {
1224 if (*activep && n == -1) {
1225 channel_clear_adm_permitted_opens();
1226 options->num_permitted_opens = 0;
1230 if (*activep && n == -1)
1231 channel_clear_adm_permitted_opens();
1232 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1235 fatal("%s line %d: missing host in PermitOpen",
1237 p = cleanhostname(p);
1238 if (arg == NULL || (port = a2port(arg)) == 0)
1239 fatal("%s line %d: bad port number in "
1240 "PermitOpen", filename, linenum);
1241 if (*activep && n == -1)
1242 options->num_permitted_opens =
1243 channel_add_adm_permitted_opens(p, port);
1249 fatal("%.200s line %d: Missing argument.", filename,
1251 len = strspn(cp, WHITESPACE);
1252 if (*activep && options->adm_forced_command == NULL)
1253 options->adm_forced_command = xstrdup(cp + len);
1257 logit("%s line %d: Deprecated option %s",
1258 filename, linenum, arg);
1260 arg = strdelim(&cp);
1264 logit("%s line %d: Unsupported option %s",
1265 filename, linenum, arg);
1267 arg = strdelim(&cp);
1271 fatal("%s line %d: Missing handler for opcode %s (%d)",
1272 filename, linenum, arg, opcode);
1274 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1275 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1276 filename, linenum, arg);
1280 /* Reads the server configuration file. */
1283 load_server_config(const char *filename, Buffer *conf)
1285 char line[1024], *cp;
1288 debug2("%s: filename %s", __func__, filename);
1289 if ((f = fopen(filename, "r")) == NULL) {
1294 while (fgets(line, sizeof(line), f)) {
1296 * Trim out comments and strip whitespace
1297 * NB - preserve newlines, they are needed to reproduce
1298 * line numbers later for error messages
1300 if ((cp = strchr(line, '#')) != NULL)
1301 memcpy(cp, "\n", 2);
1302 cp = line + strspn(line, " \t\r");
1304 buffer_append(conf, cp, strlen(cp));
1306 buffer_append(conf, "\0", 1);
1308 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1312 parse_server_match_config(ServerOptions *options, const char *user,
1313 const char *host, const char *address)
1317 initialize_server_options(&mo);
1318 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1319 copy_set_server_options(options, &mo, 0);
1323 #define M_CP_INTOPT(n) do {\
1327 #define M_CP_STROPT(n) do {\
1328 if (src->n != NULL) { \
1329 if (dst->n != NULL) \
1336 * Copy any supported values that are set.
1338 * If the preauth flag is set, we do not bother copying the the string or
1339 * array values that are not used pre-authentication, because any that we
1340 * do use must be explictly sent in mm_getpwnamallow().
1343 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1345 M_CP_INTOPT(password_authentication);
1346 M_CP_INTOPT(gss_authentication);
1347 M_CP_INTOPT(rsa_authentication);
1348 M_CP_INTOPT(pubkey_authentication);
1349 M_CP_INTOPT(kerberos_authentication);
1350 M_CP_INTOPT(hostbased_authentication);
1351 M_CP_INTOPT(kbd_interactive_authentication);
1353 M_CP_INTOPT(allow_tcp_forwarding);
1354 M_CP_INTOPT(gateway_ports);
1355 M_CP_INTOPT(x11_display_offset);
1356 M_CP_INTOPT(x11_forwarding);
1357 M_CP_INTOPT(x11_use_localhost);
1359 M_CP_STROPT(banner);
1362 M_CP_STROPT(adm_forced_command);
1369 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1370 const char *user, const char *host, const char *address)
1372 int active, linenum, bad_options = 0;
1373 char *cp, *obuf, *cbuf;
1375 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1377 obuf = cbuf = xstrdup(buffer_ptr(conf));
1378 active = user ? 0 : 1;
1380 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1381 if (process_server_config_line(options, cp, filename,
1382 linenum++, &active, user, host, address) != 0)
1386 if (bad_options > 0)
1387 fatal("%s: terminating, %d bad configuration options",
1388 filename, bad_options);