1 /* $OpenBSD: servconf.c,v 1.165 2006/08/14 12:40:25 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_GLOBAL },
329 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
330 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
331 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
332 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
333 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
335 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
336 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
337 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
339 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
341 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
344 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
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_GLOBAL },
353 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
355 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
356 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
358 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
359 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
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_GLOBAL },
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) {
595 debug("address '%s' arg '%s'", address, arg);
600 if (match_hostname(address, arg, len) != 1)
603 debug("connection from %.100s matched 'Address "
604 "%.100s' at line %d", address, arg, line);
606 error("Unsupported Match attribute %s", attrib);
611 debug3("match %sfound", result ? "" : "not ");
616 #define WHITESPACE " \t\r\n"
619 process_server_config_line(ServerOptions *options, char *line,
620 const char *filename, int linenum, int *activep, const char *user,
621 const char *host, const char *address)
623 char *cp, **charptr, *arg, *p;
624 int cmdline = 0, *intptr, value, n;
625 ServerOpCodes opcode;
631 if ((arg = strdelim(&cp)) == NULL)
633 /* Ignore leading whitespace */
636 if (!arg || !*arg || *arg == '#')
640 opcode = parse_token(arg, filename, linenum, &flags);
642 if (activep == NULL) { /* We are processing a command line directive */
646 if (*activep && opcode != sMatch)
647 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
648 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
650 fatal("%s line %d: Directive '%s' is not allowed "
651 "within a Match block", filename, linenum, arg);
652 } else { /* this is a directive we have already processed */
660 /* Portable-specific options */
662 intptr = &options->use_pam;
665 /* Standard Options */
669 /* ignore ports from configfile if cmdline specifies ports */
670 if (options->ports_from_cmdline)
672 if (options->listen_addrs != NULL)
673 fatal("%s line %d: ports must be specified before "
674 "ListenAddress.", filename, linenum);
675 if (options->num_ports >= MAX_PORTS)
676 fatal("%s line %d: too many ports.",
679 if (!arg || *arg == '\0')
680 fatal("%s line %d: missing port number.",
682 options->ports[options->num_ports++] = a2port(arg);
683 if (options->ports[options->num_ports-1] == 0)
684 fatal("%s line %d: Badly formatted port number.",
689 intptr = &options->server_key_bits;
692 if (!arg || *arg == '\0')
693 fatal("%s line %d: missing integer value.",
696 if (*activep && *intptr == -1)
700 case sLoginGraceTime:
701 intptr = &options->login_grace_time;
704 if (!arg || *arg == '\0')
705 fatal("%s line %d: missing time value.",
707 if ((value = convtime(arg)) == -1)
708 fatal("%s line %d: invalid time value.",
714 case sKeyRegenerationTime:
715 intptr = &options->key_regeneration_time;
720 if (arg == NULL || *arg == '\0')
721 fatal("%s line %d: missing address",
723 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
724 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
725 && strchr(p+1, ':') != NULL) {
726 add_listen_addr(options, arg, 0);
731 fatal("%s line %d: bad address:port usage",
733 p = cleanhostname(p);
736 else if ((port = a2port(arg)) == 0)
737 fatal("%s line %d: bad port number", filename, linenum);
739 add_listen_addr(options, p, port);
745 if (!arg || *arg == '\0')
746 fatal("%s line %d: missing address family.",
748 intptr = &options->address_family;
749 if (options->listen_addrs != NULL)
750 fatal("%s line %d: address family must be specified before "
751 "ListenAddress.", filename, linenum);
752 if (strcasecmp(arg, "inet") == 0)
754 else if (strcasecmp(arg, "inet6") == 0)
756 else if (strcasecmp(arg, "any") == 0)
759 fatal("%s line %d: unsupported address family \"%s\".",
760 filename, linenum, arg);
766 intptr = &options->num_host_key_files;
767 if (*intptr >= MAX_HOSTKEYS)
768 fatal("%s line %d: too many host keys specified (max %d).",
769 filename, linenum, MAX_HOSTKEYS);
770 charptr = &options->host_key_files[*intptr];
773 if (!arg || *arg == '\0')
774 fatal("%s line %d: missing file name.",
776 if (*activep && *charptr == NULL) {
777 *charptr = tilde_expand_filename(arg, getuid());
778 /* increase optional counter */
780 *intptr = *intptr + 1;
785 charptr = &options->pid_file;
788 case sPermitRootLogin:
789 intptr = &options->permit_root_login;
791 if (!arg || *arg == '\0')
792 fatal("%s line %d: missing yes/"
793 "without-password/forced-commands-only/no "
794 "argument.", filename, linenum);
795 value = 0; /* silence compiler */
796 if (strcmp(arg, "without-password") == 0)
797 value = PERMIT_NO_PASSWD;
798 else if (strcmp(arg, "forced-commands-only") == 0)
799 value = PERMIT_FORCED_ONLY;
800 else if (strcmp(arg, "yes") == 0)
802 else if (strcmp(arg, "no") == 0)
805 fatal("%s line %d: Bad yes/"
806 "without-password/forced-commands-only/no "
807 "argument: %s", filename, linenum, arg);
813 intptr = &options->ignore_rhosts;
816 if (!arg || *arg == '\0')
817 fatal("%s line %d: missing yes/no argument.",
819 value = 0; /* silence compiler */
820 if (strcmp(arg, "yes") == 0)
822 else if (strcmp(arg, "no") == 0)
825 fatal("%s line %d: Bad yes/no argument: %s",
826 filename, linenum, arg);
827 if (*activep && *intptr == -1)
831 case sIgnoreUserKnownHosts:
832 intptr = &options->ignore_user_known_hosts;
835 case sRhostsRSAAuthentication:
836 intptr = &options->rhosts_rsa_authentication;
839 case sHostbasedAuthentication:
840 intptr = &options->hostbased_authentication;
843 case sHostbasedUsesNameFromPacketOnly:
844 intptr = &options->hostbased_uses_name_from_packet_only;
847 case sRSAAuthentication:
848 intptr = &options->rsa_authentication;
851 case sPubkeyAuthentication:
852 intptr = &options->pubkey_authentication;
855 case sKerberosAuthentication:
856 intptr = &options->kerberos_authentication;
859 case sKerberosOrLocalPasswd:
860 intptr = &options->kerberos_or_local_passwd;
863 case sKerberosTicketCleanup:
864 intptr = &options->kerberos_ticket_cleanup;
867 case sKerberosGetAFSToken:
868 intptr = &options->kerberos_get_afs_token;
871 case sGssAuthentication:
872 intptr = &options->gss_authentication;
875 case sGssCleanupCreds:
876 intptr = &options->gss_cleanup_creds;
879 case sPasswordAuthentication:
880 intptr = &options->password_authentication;
883 case sKbdInteractiveAuthentication:
884 intptr = &options->kbd_interactive_authentication;
887 case sChallengeResponseAuthentication:
888 intptr = &options->challenge_response_authentication;
892 intptr = &options->print_motd;
896 intptr = &options->print_lastlog;
900 intptr = &options->x11_forwarding;
903 case sX11DisplayOffset:
904 intptr = &options->x11_display_offset;
907 case sX11UseLocalhost:
908 intptr = &options->x11_use_localhost;
912 charptr = &options->xauth_location;
916 intptr = &options->strict_modes;
920 intptr = &options->tcp_keep_alive;
924 intptr = &options->permit_empty_passwd;
927 case sPermitUserEnvironment:
928 intptr = &options->permit_user_env;
932 intptr = &options->use_login;
936 intptr = &options->compression;
938 if (!arg || *arg == '\0')
939 fatal("%s line %d: missing yes/no/delayed "
940 "argument.", filename, linenum);
941 value = 0; /* silence compiler */
942 if (strcmp(arg, "delayed") == 0)
943 value = COMP_DELAYED;
944 else if (strcmp(arg, "yes") == 0)
946 else if (strcmp(arg, "no") == 0)
949 fatal("%s line %d: Bad yes/no/delayed "
950 "argument: %s", filename, linenum, arg);
956 intptr = &options->gateway_ports;
958 if (!arg || *arg == '\0')
959 fatal("%s line %d: missing yes/no/clientspecified "
960 "argument.", filename, linenum);
961 value = 0; /* silence compiler */
962 if (strcmp(arg, "clientspecified") == 0)
964 else if (strcmp(arg, "yes") == 0)
966 else if (strcmp(arg, "no") == 0)
969 fatal("%s line %d: Bad yes/no/clientspecified "
970 "argument: %s", filename, linenum, arg);
976 intptr = &options->use_dns;
980 intptr = (int *) &options->log_facility;
982 value = log_facility_number(arg);
983 if (value == SYSLOG_FACILITY_NOT_SET)
984 fatal("%.200s line %d: unsupported log facility '%s'",
985 filename, linenum, arg ? arg : "<NONE>");
987 *intptr = (SyslogFacility) value;
991 intptr = (int *) &options->log_level;
993 value = log_level_number(arg);
994 if (value == SYSLOG_LEVEL_NOT_SET)
995 fatal("%.200s line %d: unsupported log level '%s'",
996 filename, linenum, arg ? arg : "<NONE>");
998 *intptr = (LogLevel) value;
1001 case sAllowTcpForwarding:
1002 intptr = &options->allow_tcp_forwarding;
1005 case sUsePrivilegeSeparation:
1006 intptr = &use_privsep;
1010 while ((arg = strdelim(&cp)) && *arg != '\0') {
1011 if (options->num_allow_users >= MAX_ALLOW_USERS)
1012 fatal("%s line %d: too many allow users.",
1014 options->allow_users[options->num_allow_users++] =
1020 while ((arg = strdelim(&cp)) && *arg != '\0') {
1021 if (options->num_deny_users >= MAX_DENY_USERS)
1022 fatal("%s line %d: too many deny users.",
1024 options->deny_users[options->num_deny_users++] =
1030 while ((arg = strdelim(&cp)) && *arg != '\0') {
1031 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1032 fatal("%s line %d: too many allow groups.",
1034 options->allow_groups[options->num_allow_groups++] =
1040 while ((arg = strdelim(&cp)) && *arg != '\0') {
1041 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1042 fatal("%s line %d: too many deny groups.",
1044 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1049 arg = strdelim(&cp);
1050 if (!arg || *arg == '\0')
1051 fatal("%s line %d: Missing argument.", filename, linenum);
1052 if (!ciphers_valid(arg))
1053 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1054 filename, linenum, arg ? arg : "<NONE>");
1055 if (options->ciphers == NULL)
1056 options->ciphers = xstrdup(arg);
1060 arg = strdelim(&cp);
1061 if (!arg || *arg == '\0')
1062 fatal("%s line %d: Missing argument.", filename, linenum);
1063 if (!mac_valid(arg))
1064 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1065 filename, linenum, arg ? arg : "<NONE>");
1066 if (options->macs == NULL)
1067 options->macs = xstrdup(arg);
1071 intptr = &options->protocol;
1072 arg = strdelim(&cp);
1073 if (!arg || *arg == '\0')
1074 fatal("%s line %d: Missing argument.", filename, linenum);
1075 value = proto_spec(arg);
1076 if (value == SSH_PROTO_UNKNOWN)
1077 fatal("%s line %d: Bad protocol spec '%s'.",
1078 filename, linenum, arg ? arg : "<NONE>");
1079 if (*intptr == SSH_PROTO_UNKNOWN)
1084 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1085 fatal("%s line %d: too many subsystems defined.",
1088 arg = strdelim(&cp);
1089 if (!arg || *arg == '\0')
1090 fatal("%s line %d: Missing subsystem name.",
1093 arg = strdelim(&cp);
1096 for (i = 0; i < options->num_subsystems; i++)
1097 if (strcmp(arg, options->subsystem_name[i]) == 0)
1098 fatal("%s line %d: Subsystem '%s' already defined.",
1099 filename, linenum, arg);
1100 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1101 arg = strdelim(&cp);
1102 if (!arg || *arg == '\0')
1103 fatal("%s line %d: Missing subsystem command.",
1105 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1107 /* Collect arguments (separate to executable) */
1109 len = strlen(p) + 1;
1110 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1111 len += 1 + strlen(arg);
1112 p = xrealloc(p, 1, len);
1113 strlcat(p, " ", len);
1114 strlcat(p, arg, len);
1116 options->subsystem_args[options->num_subsystems] = p;
1117 options->num_subsystems++;
1121 arg = strdelim(&cp);
1122 if (!arg || *arg == '\0')
1123 fatal("%s line %d: Missing MaxStartups spec.",
1125 if ((n = sscanf(arg, "%d:%d:%d",
1126 &options->max_startups_begin,
1127 &options->max_startups_rate,
1128 &options->max_startups)) == 3) {
1129 if (options->max_startups_begin >
1130 options->max_startups ||
1131 options->max_startups_rate > 100 ||
1132 options->max_startups_rate < 1)
1133 fatal("%s line %d: Illegal MaxStartups spec.",
1136 fatal("%s line %d: Illegal MaxStartups spec.",
1139 options->max_startups = options->max_startups_begin;
1143 intptr = &options->max_authtries;
1147 charptr = &options->banner;
1148 goto parse_filename;
1150 * These options can contain %X options expanded at
1151 * connect time, so that you can specify paths like:
1153 * AuthorizedKeysFile /etc/ssh_keys/%u
1155 case sAuthorizedKeysFile:
1156 case sAuthorizedKeysFile2:
1157 charptr = (opcode == sAuthorizedKeysFile) ?
1158 &options->authorized_keys_file :
1159 &options->authorized_keys_file2;
1160 goto parse_filename;
1162 case sClientAliveInterval:
1163 intptr = &options->client_alive_interval;
1166 case sClientAliveCountMax:
1167 intptr = &options->client_alive_count_max;
1171 while ((arg = strdelim(&cp)) && *arg != '\0') {
1172 if (strchr(arg, '=') != NULL)
1173 fatal("%s line %d: Invalid environment name.",
1175 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1176 fatal("%s line %d: too many allow env.",
1180 options->accept_env[options->num_accept_env++] =
1186 intptr = &options->permit_tun;
1187 arg = strdelim(&cp);
1188 if (!arg || *arg == '\0')
1189 fatal("%s line %d: Missing yes/point-to-point/"
1190 "ethernet/no argument.", filename, linenum);
1191 value = 0; /* silence compiler */
1192 if (strcasecmp(arg, "ethernet") == 0)
1193 value = SSH_TUNMODE_ETHERNET;
1194 else if (strcasecmp(arg, "point-to-point") == 0)
1195 value = SSH_TUNMODE_POINTOPOINT;
1196 else if (strcasecmp(arg, "yes") == 0)
1197 value = SSH_TUNMODE_YES;
1198 else if (strcasecmp(arg, "no") == 0)
1199 value = SSH_TUNMODE_NO;
1201 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1202 "no argument: %s", filename, linenum, arg);
1209 fatal("Match directive not supported as a command-line "
1211 value = match_cfg_line(&cp, linenum, user, host, address);
1213 fatal("%s line %d: Bad Match condition", filename,
1219 arg = strdelim(&cp);
1220 if (!arg || *arg == '\0')
1221 fatal("%s line %d: missing PermitOpen specification",
1223 if (strcmp(arg, "any") == 0) {
1225 channel_clear_adm_permitted_opens();
1226 options->num_permitted_opens = 0;
1230 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1233 fatal("%s line %d: missing host in PermitOpen",
1235 p = cleanhostname(p);
1236 if (arg == NULL || (port = a2port(arg)) == 0)
1237 fatal("%s line %d: bad port number in "
1238 "PermitOpen", filename, linenum);
1239 if (*activep && options->num_permitted_opens == -1) {
1240 channel_clear_adm_permitted_opens();
1241 options->num_permitted_opens =
1242 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);
1322 /* Copy any (supported) values that are set */
1324 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1326 if (src->allow_tcp_forwarding != -1)
1327 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1328 if (src->gateway_ports != -1)
1329 dst->gateway_ports = src->gateway_ports;
1330 if (src->adm_forced_command != NULL) {
1331 if (dst->adm_forced_command != NULL)
1332 xfree(dst->adm_forced_command);
1333 dst->adm_forced_command = src->adm_forced_command;
1335 if (src->x11_display_offset != -1)
1336 dst->x11_display_offset = src->x11_display_offset;
1337 if (src->x11_forwarding != -1)
1338 dst->x11_forwarding = src->x11_forwarding;
1339 if (src->x11_use_localhost != -1)
1340 dst->x11_use_localhost = src->x11_use_localhost;
1344 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1345 const char *user, const char *host, const char *address)
1347 int active, linenum, bad_options = 0;
1348 char *cp, *obuf, *cbuf;
1350 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1352 obuf = cbuf = xstrdup(buffer_ptr(conf));
1353 active = user ? 0 : 1;
1355 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1356 if (process_server_config_line(options, cp, filename,
1357 linenum++, &active, user, host, address) != 0)
1361 if (bad_options > 0)
1362 fatal("%s: terminating, %d bad configuration options",
1363 filename, bad_options);