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".
16 #include <sys/types.h>
17 #include <sys/socket.h>
34 #include "pathnames.h"
42 #include "groupaccess.h"
44 static void add_listen_addr(ServerOptions *, char *, u_short);
45 static void add_one_listen_addr(ServerOptions *, char *, u_short);
47 /* Use of privilege separation or not */
48 extern int use_privsep;
51 /* Initializes the server options to their default values. */
54 initialize_server_options(ServerOptions *options)
56 memset(options, 0, sizeof(*options));
58 /* Portable-specific options */
59 options->use_pam = -1;
61 /* Standard Options */
62 options->num_ports = 0;
63 options->ports_from_cmdline = 0;
64 options->listen_addrs = NULL;
65 options->address_family = -1;
66 options->num_host_key_files = 0;
67 options->pid_file = NULL;
68 options->server_key_bits = -1;
69 options->login_grace_time = -1;
70 options->key_regeneration_time = -1;
71 options->permit_root_login = PERMIT_NOT_SET;
72 options->ignore_rhosts = -1;
73 options->ignore_user_known_hosts = -1;
74 options->print_motd = -1;
75 options->print_lastlog = -1;
76 options->x11_forwarding = -1;
77 options->x11_display_offset = -1;
78 options->x11_use_localhost = -1;
79 options->xauth_location = NULL;
80 options->strict_modes = -1;
81 options->tcp_keep_alive = -1;
82 options->log_facility = SYSLOG_FACILITY_NOT_SET;
83 options->log_level = SYSLOG_LEVEL_NOT_SET;
84 options->rhosts_rsa_authentication = -1;
85 options->hostbased_authentication = -1;
86 options->hostbased_uses_name_from_packet_only = -1;
87 options->rsa_authentication = -1;
88 options->pubkey_authentication = -1;
89 options->kerberos_authentication = -1;
90 options->kerberos_or_local_passwd = -1;
91 options->kerberos_ticket_cleanup = -1;
92 options->kerberos_get_afs_token = -1;
93 options->gss_authentication=-1;
94 options->gss_cleanup_creds = -1;
95 options->password_authentication = -1;
96 options->kbd_interactive_authentication = -1;
97 options->challenge_response_authentication = -1;
98 options->permit_empty_passwd = -1;
99 options->permit_user_env = -1;
100 options->use_login = -1;
101 options->compression = -1;
102 options->allow_tcp_forwarding = -1;
103 options->num_allow_users = 0;
104 options->num_deny_users = 0;
105 options->num_allow_groups = 0;
106 options->num_deny_groups = 0;
107 options->ciphers = NULL;
108 options->macs = NULL;
109 options->protocol = SSH_PROTO_UNKNOWN;
110 options->gateway_ports = -1;
111 options->num_subsystems = 0;
112 options->max_startups_begin = -1;
113 options->max_startups_rate = -1;
114 options->max_startups = -1;
115 options->max_authtries = -1;
116 options->banner = NULL;
117 options->use_dns = -1;
118 options->client_alive_interval = -1;
119 options->client_alive_count_max = -1;
120 options->authorized_keys_file = NULL;
121 options->authorized_keys_file2 = NULL;
122 options->num_accept_env = 0;
123 options->permit_tun = -1;
124 options->num_permitted_opens = -1;
125 options->adm_forced_command = NULL;
129 fill_default_server_options(ServerOptions *options)
131 /* Portable-specific options */
132 if (options->use_pam == -1)
133 options->use_pam = 1;
135 /* Standard Options */
136 if (options->protocol == SSH_PROTO_UNKNOWN)
137 options->protocol = SSH_PROTO_2;
138 if (options->num_host_key_files == 0) {
139 /* fill default hostkeys for protocols */
140 if (options->protocol & SSH_PROTO_1)
141 options->host_key_files[options->num_host_key_files++] =
143 if (options->protocol & SSH_PROTO_2) {
144 options->host_key_files[options->num_host_key_files++] =
145 _PATH_HOST_DSA_KEY_FILE;
148 if (options->num_ports == 0)
149 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
150 if (options->listen_addrs == NULL)
151 add_listen_addr(options, NULL, 0);
152 if (options->pid_file == NULL)
153 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
154 if (options->server_key_bits == -1)
155 options->server_key_bits = 768;
156 if (options->login_grace_time == -1)
157 options->login_grace_time = 120;
158 if (options->key_regeneration_time == -1)
159 options->key_regeneration_time = 3600;
160 if (options->permit_root_login == PERMIT_NOT_SET)
161 options->permit_root_login = PERMIT_NO;
162 if (options->ignore_rhosts == -1)
163 options->ignore_rhosts = 1;
164 if (options->ignore_user_known_hosts == -1)
165 options->ignore_user_known_hosts = 0;
166 if (options->print_motd == -1)
167 options->print_motd = 1;
168 if (options->print_lastlog == -1)
169 options->print_lastlog = 1;
170 if (options->x11_forwarding == -1)
171 options->x11_forwarding = 1;
172 if (options->x11_display_offset == -1)
173 options->x11_display_offset = 10;
174 if (options->x11_use_localhost == -1)
175 options->x11_use_localhost = 1;
176 if (options->xauth_location == NULL)
177 options->xauth_location = _PATH_XAUTH;
178 if (options->strict_modes == -1)
179 options->strict_modes = 1;
180 if (options->tcp_keep_alive == -1)
181 options->tcp_keep_alive = 1;
182 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
183 options->log_facility = SYSLOG_FACILITY_AUTH;
184 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
185 options->log_level = SYSLOG_LEVEL_INFO;
186 if (options->rhosts_rsa_authentication == -1)
187 options->rhosts_rsa_authentication = 0;
188 if (options->hostbased_authentication == -1)
189 options->hostbased_authentication = 0;
190 if (options->hostbased_uses_name_from_packet_only == -1)
191 options->hostbased_uses_name_from_packet_only = 0;
192 if (options->rsa_authentication == -1)
193 options->rsa_authentication = 1;
194 if (options->pubkey_authentication == -1)
195 options->pubkey_authentication = 1;
196 if (options->kerberos_authentication == -1)
197 options->kerberos_authentication = 0;
198 if (options->kerberos_or_local_passwd == -1)
199 options->kerberos_or_local_passwd = 1;
200 if (options->kerberos_ticket_cleanup == -1)
201 options->kerberos_ticket_cleanup = 1;
202 if (options->kerberos_get_afs_token == -1)
203 options->kerberos_get_afs_token = 0;
204 if (options->gss_authentication == -1)
205 options->gss_authentication = 0;
206 if (options->gss_cleanup_creds == -1)
207 options->gss_cleanup_creds = 1;
208 if (options->password_authentication == -1)
210 options->password_authentication = 0;
212 options->password_authentication = 1;
214 if (options->kbd_interactive_authentication == -1)
215 options->kbd_interactive_authentication = 0;
216 if (options->challenge_response_authentication == -1)
217 options->challenge_response_authentication = 1;
218 if (options->permit_empty_passwd == -1)
219 options->permit_empty_passwd = 0;
220 if (options->permit_user_env == -1)
221 options->permit_user_env = 0;
222 if (options->use_login == -1)
223 options->use_login = 0;
224 if (options->compression == -1)
225 options->compression = COMP_DELAYED;
226 if (options->allow_tcp_forwarding == -1)
227 options->allow_tcp_forwarding = 1;
228 if (options->gateway_ports == -1)
229 options->gateway_ports = 0;
230 if (options->max_startups == -1)
231 options->max_startups = 10;
232 if (options->max_startups_rate == -1)
233 options->max_startups_rate = 100; /* 100% */
234 if (options->max_startups_begin == -1)
235 options->max_startups_begin = options->max_startups;
236 if (options->max_authtries == -1)
237 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
238 if (options->use_dns == -1)
239 options->use_dns = 1;
240 if (options->client_alive_interval == -1)
241 options->client_alive_interval = 0;
242 if (options->client_alive_count_max == -1)
243 options->client_alive_count_max = 3;
244 if (options->authorized_keys_file2 == NULL) {
245 /* authorized_keys_file2 falls back to authorized_keys_file */
246 if (options->authorized_keys_file != NULL)
247 options->authorized_keys_file2 = options->authorized_keys_file;
249 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
251 if (options->authorized_keys_file == NULL)
252 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
253 if (options->permit_tun == -1)
254 options->permit_tun = SSH_TUNMODE_NO;
256 /* Turn privilege separation on by default */
257 if (use_privsep == -1)
261 if (use_privsep && options->compression == 1) {
262 error("This platform does not support both privilege "
263 "separation and compression");
264 error("Compression disabled");
265 options->compression = 0;
271 /* Keyword tokens. */
273 sBadOption, /* == unknown option */
274 /* Portable-specific options */
276 /* Standard Options */
277 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
278 sPermitRootLogin, sLogFacility, sLogLevel,
279 sRhostsRSAAuthentication, sRSAAuthentication,
280 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
281 sKerberosGetAFSToken,
282 sKerberosTgtPassing, sChallengeResponseAuthentication,
283 sPasswordAuthentication, sKbdInteractiveAuthentication,
284 sListenAddress, sAddressFamily,
285 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
286 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
287 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
288 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
289 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
290 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
291 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
292 sMaxStartups, sMaxAuthTries,
293 sBanner, sUseDNS, sHostbasedAuthentication,
294 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
295 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
296 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
297 sMatch, sPermitOpen, sForceCommand,
298 sUsePrivilegeSeparation,
300 sDeprecated, sUnsupported
303 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
304 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
305 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
307 /* Textual representation of the tokens. */
310 ServerOpCodes opcode;
313 /* Portable-specific options */
315 { "usepam", sUsePAM, SSHCFG_GLOBAL },
317 { "usepam", sUnsupported, SSHCFG_GLOBAL },
319 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
320 /* Standard Options */
321 { "port", sPort, SSHCFG_GLOBAL },
322 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
323 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
324 { "pidfile", sPidFile, SSHCFG_GLOBAL },
325 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
326 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
327 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
328 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
329 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
330 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
331 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
332 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
333 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
334 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
335 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
336 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
337 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
339 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
340 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
341 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
343 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
345 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
348 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
349 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
350 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
351 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
353 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
354 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
356 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
357 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
359 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
360 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
362 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
363 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
364 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
365 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
366 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
367 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
368 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
369 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
370 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
371 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
372 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
373 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
374 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
375 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
376 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
377 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
378 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
379 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
380 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
381 { "compression", sCompression, SSHCFG_GLOBAL },
382 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
383 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
384 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
385 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
386 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
387 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
388 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
389 { "ciphers", sCiphers, SSHCFG_GLOBAL },
390 { "macs", sMacs, SSHCFG_GLOBAL },
391 { "protocol", sProtocol, SSHCFG_GLOBAL },
392 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
393 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
394 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
395 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
396 { "banner", sBanner, SSHCFG_GLOBAL },
397 { "usedns", sUseDNS, SSHCFG_GLOBAL },
398 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
399 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
400 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
401 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
402 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
403 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
404 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
405 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
406 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
407 { "match", sMatch, SSHCFG_ALL },
408 { "permitopen", sPermitOpen, SSHCFG_ALL },
409 { "forcecommand", sForceCommand, SSHCFG_ALL },
410 { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
411 { NULL, sBadOption, 0 }
415 * Returns the number of the token pointed to by cp or sBadOption.
419 parse_token(const char *cp, const char *filename,
420 int linenum, u_int *flags)
424 for (i = 0; keywords[i].name; i++)
425 if (strcasecmp(cp, keywords[i].name) == 0) {
426 *flags = keywords[i].flags;
427 return keywords[i].opcode;
430 error("%s: line %d: Bad configuration option: %s",
431 filename, linenum, cp);
436 add_listen_addr(ServerOptions *options, char *addr, u_short port)
440 if (options->num_ports == 0)
441 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
442 if (options->address_family == -1)
443 options->address_family = AF_UNSPEC;
445 for (i = 0; i < options->num_ports; i++)
446 add_one_listen_addr(options, addr, options->ports[i]);
448 add_one_listen_addr(options, addr, port);
452 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
454 struct addrinfo hints, *ai, *aitop;
455 char strport[NI_MAXSERV];
458 memset(&hints, 0, sizeof(hints));
459 hints.ai_family = options->address_family;
460 hints.ai_socktype = SOCK_STREAM;
461 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
462 snprintf(strport, sizeof strport, "%u", port);
463 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
464 fatal("bad addr or host: %s (%s)",
465 addr ? addr : "<NULL>",
466 gai_strerror(gaierr));
467 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
469 ai->ai_next = options->listen_addrs;
470 options->listen_addrs = aitop;
474 * The strategy for the Match blocks is that the config file is parsed twice.
476 * The first time is at startup. activep is initialized to 1 and the
477 * directives in the global context are processed and acted on. Hitting a
478 * Match directive unsets activep and the directives inside the block are
479 * checked for syntax only.
481 * The second time is after a connection has been established but before
482 * authentication. activep is initialized to 2 and global config directives
483 * are ignored since they have already been processed. If the criteria in a
484 * Match block is met, activep is set and the subsequent directives
485 * processed and actioned until EOF or another Match block unsets it. Any
486 * options set are copied into the main server config.
488 * Potential additions/improvements:
489 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
491 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
492 * Match Address 192.168.0.*
497 * AllowTcpForwarding yes
498 * GatewayPorts clientspecified
501 * - Add a PermittedChannelRequests directive
503 * PermittedChannelRequests session,forwarded-tcpip
507 match_cfg_line_group(const char *grps, int line, const char *user)
511 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
515 * Even if we do not have a user yet, we still need to check for
518 arg = cp = xstrdup(grps);
519 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
520 if (ngrps >= MAX_MATCH_GROUPS) {
521 error("line %d: too many groups in Match Group", line);
525 grplist[ngrps++] = p;
531 if ((pw = getpwnam(user)) == NULL) {
532 debug("Can't match group at line %d because user %.100s does "
533 "not exist", line, user);
534 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
535 debug("Can't Match group because user %.100s not in any group "
536 "at line %d", user, line);
537 } else if (ga_match(grplist, ngrps) != 1) {
538 debug("user %.100s does not match group %.100s at line %d",
541 debug("user %.100s matched group %.100s at line %d", user,
552 match_cfg_line(char **condition, int line, const char *user, const char *host,
556 char *arg, *attrib, *cp = *condition;
560 debug3("checking syntax for 'Match %s'", cp);
562 debug3("checking match for '%s' user %s host %s addr %s", cp,
563 user ? user : "(null)", host ? host : "(null)",
564 address ? address : "(null)");
566 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
567 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
568 error("Missing Match criteria for %s", attrib);
572 if (strcasecmp(attrib, "user") == 0) {
577 if (match_pattern_list(user, arg, len, 0) != 1)
580 debug("user %.100s matched 'User %.100s' at "
581 "line %d", user, arg, line);
582 } else if (strcasecmp(attrib, "group") == 0) {
583 switch (match_cfg_line_group(arg, line, user)) {
589 } else if (strcasecmp(attrib, "host") == 0) {
594 if (match_hostname(host, arg, len) != 1)
597 debug("connection from %.100s matched 'Host "
598 "%.100s' at line %d", host, arg, line);
599 } else if (strcasecmp(attrib, "address") == 0) {
600 debug("address '%s' arg '%s'", address, arg);
605 if (match_hostname(address, arg, len) != 1)
608 debug("connection from %.100s matched 'Address "
609 "%.100s' at line %d", address, arg, line);
611 error("Unsupported Match attribute %s", attrib);
616 debug3("match %sfound", result ? "" : "not ");
621 #define WHITESPACE " \t\r\n"
624 process_server_config_line(ServerOptions *options, char *line,
625 const char *filename, int linenum, int *activep, const char *user,
626 const char *host, const char *address)
628 char *cp, **charptr, *arg, *p;
629 int cmdline = 0, *intptr, value, n;
630 ServerOpCodes opcode;
636 if ((arg = strdelim(&cp)) == NULL)
638 /* Ignore leading whitespace */
641 if (!arg || !*arg || *arg == '#')
645 opcode = parse_token(arg, filename, linenum, &flags);
647 if (activep == NULL) { /* We are processing a command line directive */
651 if (*activep && opcode != sMatch)
652 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
653 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
655 fatal("%s line %d: Directive '%s' is not allowed "
656 "within a Match block", filename, linenum, arg);
657 } else { /* this is a directive we have already processed */
665 /* Portable-specific options */
667 intptr = &options->use_pam;
670 /* Standard Options */
674 /* ignore ports from configfile if cmdline specifies ports */
675 if (options->ports_from_cmdline)
677 if (options->listen_addrs != NULL)
678 fatal("%s line %d: ports must be specified before "
679 "ListenAddress.", filename, linenum);
680 if (options->num_ports >= MAX_PORTS)
681 fatal("%s line %d: too many ports.",
684 if (!arg || *arg == '\0')
685 fatal("%s line %d: missing port number.",
687 options->ports[options->num_ports++] = a2port(arg);
688 if (options->ports[options->num_ports-1] == 0)
689 fatal("%s line %d: Badly formatted port number.",
694 intptr = &options->server_key_bits;
697 if (!arg || *arg == '\0')
698 fatal("%s line %d: missing integer value.",
701 if (*activep && *intptr == -1)
705 case sLoginGraceTime:
706 intptr = &options->login_grace_time;
709 if (!arg || *arg == '\0')
710 fatal("%s line %d: missing time value.",
712 if ((value = convtime(arg)) == -1)
713 fatal("%s line %d: invalid time value.",
719 case sKeyRegenerationTime:
720 intptr = &options->key_regeneration_time;
725 if (arg == NULL || *arg == '\0')
726 fatal("%s line %d: missing address",
728 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
729 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
730 && strchr(p+1, ':') != NULL) {
731 add_listen_addr(options, arg, 0);
736 fatal("%s line %d: bad address:port usage",
738 p = cleanhostname(p);
741 else if ((port = a2port(arg)) == 0)
742 fatal("%s line %d: bad port number", filename, linenum);
744 add_listen_addr(options, p, port);
750 if (!arg || *arg == '\0')
751 fatal("%s line %d: missing address family.",
753 intptr = &options->address_family;
754 if (options->listen_addrs != NULL)
755 fatal("%s line %d: address family must be specified before "
756 "ListenAddress.", filename, linenum);
757 if (strcasecmp(arg, "inet") == 0)
759 else if (strcasecmp(arg, "inet6") == 0)
761 else if (strcasecmp(arg, "any") == 0)
764 fatal("%s line %d: unsupported address family \"%s\".",
765 filename, linenum, arg);
771 intptr = &options->num_host_key_files;
772 if (*intptr >= MAX_HOSTKEYS)
773 fatal("%s line %d: too many host keys specified (max %d).",
774 filename, linenum, MAX_HOSTKEYS);
775 charptr = &options->host_key_files[*intptr];
778 if (!arg || *arg == '\0')
779 fatal("%s line %d: missing file name.",
781 if (*activep && *charptr == NULL) {
782 *charptr = tilde_expand_filename(arg, getuid());
783 /* increase optional counter */
785 *intptr = *intptr + 1;
790 charptr = &options->pid_file;
793 case sPermitRootLogin:
794 intptr = &options->permit_root_login;
796 if (!arg || *arg == '\0')
797 fatal("%s line %d: missing yes/"
798 "without-password/forced-commands-only/no "
799 "argument.", filename, linenum);
800 value = 0; /* silence compiler */
801 if (strcmp(arg, "without-password") == 0)
802 value = PERMIT_NO_PASSWD;
803 else if (strcmp(arg, "forced-commands-only") == 0)
804 value = PERMIT_FORCED_ONLY;
805 else if (strcmp(arg, "yes") == 0)
807 else if (strcmp(arg, "no") == 0)
810 fatal("%s line %d: Bad yes/"
811 "without-password/forced-commands-only/no "
812 "argument: %s", filename, linenum, arg);
818 intptr = &options->ignore_rhosts;
821 if (!arg || *arg == '\0')
822 fatal("%s line %d: missing yes/no argument.",
824 value = 0; /* silence compiler */
825 if (strcmp(arg, "yes") == 0)
827 else if (strcmp(arg, "no") == 0)
830 fatal("%s line %d: Bad yes/no argument: %s",
831 filename, linenum, arg);
832 if (*activep && *intptr == -1)
836 case sIgnoreUserKnownHosts:
837 intptr = &options->ignore_user_known_hosts;
840 case sRhostsRSAAuthentication:
841 intptr = &options->rhosts_rsa_authentication;
844 case sHostbasedAuthentication:
845 intptr = &options->hostbased_authentication;
848 case sHostbasedUsesNameFromPacketOnly:
849 intptr = &options->hostbased_uses_name_from_packet_only;
852 case sRSAAuthentication:
853 intptr = &options->rsa_authentication;
856 case sPubkeyAuthentication:
857 intptr = &options->pubkey_authentication;
860 case sKerberosAuthentication:
861 intptr = &options->kerberos_authentication;
864 case sKerberosOrLocalPasswd:
865 intptr = &options->kerberos_or_local_passwd;
868 case sKerberosTicketCleanup:
869 intptr = &options->kerberos_ticket_cleanup;
872 case sKerberosGetAFSToken:
873 intptr = &options->kerberos_get_afs_token;
876 case sGssAuthentication:
877 intptr = &options->gss_authentication;
880 case sGssCleanupCreds:
881 intptr = &options->gss_cleanup_creds;
884 case sPasswordAuthentication:
885 intptr = &options->password_authentication;
888 case sKbdInteractiveAuthentication:
889 intptr = &options->kbd_interactive_authentication;
892 case sChallengeResponseAuthentication:
893 intptr = &options->challenge_response_authentication;
897 intptr = &options->print_motd;
901 intptr = &options->print_lastlog;
905 intptr = &options->x11_forwarding;
908 case sX11DisplayOffset:
909 intptr = &options->x11_display_offset;
912 case sX11UseLocalhost:
913 intptr = &options->x11_use_localhost;
917 charptr = &options->xauth_location;
921 intptr = &options->strict_modes;
925 intptr = &options->tcp_keep_alive;
929 intptr = &options->permit_empty_passwd;
932 case sPermitUserEnvironment:
933 intptr = &options->permit_user_env;
937 intptr = &options->use_login;
941 intptr = &options->compression;
943 if (!arg || *arg == '\0')
944 fatal("%s line %d: missing yes/no/delayed "
945 "argument.", filename, linenum);
946 value = 0; /* silence compiler */
947 if (strcmp(arg, "delayed") == 0)
948 value = COMP_DELAYED;
949 else if (strcmp(arg, "yes") == 0)
951 else if (strcmp(arg, "no") == 0)
954 fatal("%s line %d: Bad yes/no/delayed "
955 "argument: %s", filename, linenum, arg);
961 intptr = &options->gateway_ports;
963 if (!arg || *arg == '\0')
964 fatal("%s line %d: missing yes/no/clientspecified "
965 "argument.", filename, linenum);
966 value = 0; /* silence compiler */
967 if (strcmp(arg, "clientspecified") == 0)
969 else if (strcmp(arg, "yes") == 0)
971 else if (strcmp(arg, "no") == 0)
974 fatal("%s line %d: Bad yes/no/clientspecified "
975 "argument: %s", filename, linenum, arg);
981 intptr = &options->use_dns;
985 intptr = (int *) &options->log_facility;
987 value = log_facility_number(arg);
988 if (value == SYSLOG_FACILITY_NOT_SET)
989 fatal("%.200s line %d: unsupported log facility '%s'",
990 filename, linenum, arg ? arg : "<NONE>");
992 *intptr = (SyslogFacility) value;
996 intptr = (int *) &options->log_level;
998 value = log_level_number(arg);
999 if (value == SYSLOG_LEVEL_NOT_SET)
1000 fatal("%.200s line %d: unsupported log level '%s'",
1001 filename, linenum, arg ? arg : "<NONE>");
1003 *intptr = (LogLevel) value;
1006 case sAllowTcpForwarding:
1007 intptr = &options->allow_tcp_forwarding;
1010 case sUsePrivilegeSeparation:
1011 intptr = &use_privsep;
1015 while ((arg = strdelim(&cp)) && *arg != '\0') {
1016 if (options->num_allow_users >= MAX_ALLOW_USERS)
1017 fatal("%s line %d: too many allow users.",
1019 options->allow_users[options->num_allow_users++] =
1025 while ((arg = strdelim(&cp)) && *arg != '\0') {
1026 if (options->num_deny_users >= MAX_DENY_USERS)
1027 fatal("%s line %d: too many deny users.",
1029 options->deny_users[options->num_deny_users++] =
1035 while ((arg = strdelim(&cp)) && *arg != '\0') {
1036 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1037 fatal("%s line %d: too many allow groups.",
1039 options->allow_groups[options->num_allow_groups++] =
1045 while ((arg = strdelim(&cp)) && *arg != '\0') {
1046 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1047 fatal("%s line %d: too many deny groups.",
1049 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1054 arg = strdelim(&cp);
1055 if (!arg || *arg == '\0')
1056 fatal("%s line %d: Missing argument.", filename, linenum);
1057 if (!ciphers_valid(arg))
1058 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1059 filename, linenum, arg ? arg : "<NONE>");
1060 if (options->ciphers == NULL)
1061 options->ciphers = xstrdup(arg);
1065 arg = strdelim(&cp);
1066 if (!arg || *arg == '\0')
1067 fatal("%s line %d: Missing argument.", filename, linenum);
1068 if (!mac_valid(arg))
1069 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1070 filename, linenum, arg ? arg : "<NONE>");
1071 if (options->macs == NULL)
1072 options->macs = xstrdup(arg);
1076 intptr = &options->protocol;
1077 arg = strdelim(&cp);
1078 if (!arg || *arg == '\0')
1079 fatal("%s line %d: Missing argument.", filename, linenum);
1080 value = proto_spec(arg);
1081 if (value == SSH_PROTO_UNKNOWN)
1082 fatal("%s line %d: Bad protocol spec '%s'.",
1083 filename, linenum, arg ? arg : "<NONE>");
1084 if (*intptr == SSH_PROTO_UNKNOWN)
1089 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1090 fatal("%s line %d: too many subsystems defined.",
1093 arg = strdelim(&cp);
1094 if (!arg || *arg == '\0')
1095 fatal("%s line %d: Missing subsystem name.",
1098 arg = strdelim(&cp);
1101 for (i = 0; i < options->num_subsystems; i++)
1102 if (strcmp(arg, options->subsystem_name[i]) == 0)
1103 fatal("%s line %d: Subsystem '%s' already defined.",
1104 filename, linenum, arg);
1105 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1106 arg = strdelim(&cp);
1107 if (!arg || *arg == '\0')
1108 fatal("%s line %d: Missing subsystem command.",
1110 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1112 /* Collect arguments (separate to executable) */
1114 len = strlen(p) + 1;
1115 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1116 len += 1 + strlen(arg);
1117 p = xrealloc(p, 1, len);
1118 strlcat(p, " ", len);
1119 strlcat(p, arg, len);
1121 options->subsystem_args[options->num_subsystems] = p;
1122 options->num_subsystems++;
1126 arg = strdelim(&cp);
1127 if (!arg || *arg == '\0')
1128 fatal("%s line %d: Missing MaxStartups spec.",
1130 if ((n = sscanf(arg, "%d:%d:%d",
1131 &options->max_startups_begin,
1132 &options->max_startups_rate,
1133 &options->max_startups)) == 3) {
1134 if (options->max_startups_begin >
1135 options->max_startups ||
1136 options->max_startups_rate > 100 ||
1137 options->max_startups_rate < 1)
1138 fatal("%s line %d: Illegal MaxStartups spec.",
1141 fatal("%s line %d: Illegal MaxStartups spec.",
1144 options->max_startups = options->max_startups_begin;
1148 intptr = &options->max_authtries;
1152 charptr = &options->banner;
1153 goto parse_filename;
1155 * These options can contain %X options expanded at
1156 * connect time, so that you can specify paths like:
1158 * AuthorizedKeysFile /etc/ssh_keys/%u
1160 case sAuthorizedKeysFile:
1161 case sAuthorizedKeysFile2:
1162 charptr = (opcode == sAuthorizedKeysFile) ?
1163 &options->authorized_keys_file :
1164 &options->authorized_keys_file2;
1165 goto parse_filename;
1167 case sClientAliveInterval:
1168 intptr = &options->client_alive_interval;
1171 case sClientAliveCountMax:
1172 intptr = &options->client_alive_count_max;
1176 while ((arg = strdelim(&cp)) && *arg != '\0') {
1177 if (strchr(arg, '=') != NULL)
1178 fatal("%s line %d: Invalid environment name.",
1180 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1181 fatal("%s line %d: too many allow env.",
1185 options->accept_env[options->num_accept_env++] =
1191 intptr = &options->permit_tun;
1192 arg = strdelim(&cp);
1193 if (!arg || *arg == '\0')
1194 fatal("%s line %d: Missing yes/point-to-point/"
1195 "ethernet/no argument.", filename, linenum);
1196 value = 0; /* silence compiler */
1197 if (strcasecmp(arg, "ethernet") == 0)
1198 value = SSH_TUNMODE_ETHERNET;
1199 else if (strcasecmp(arg, "point-to-point") == 0)
1200 value = SSH_TUNMODE_POINTOPOINT;
1201 else if (strcasecmp(arg, "yes") == 0)
1202 value = SSH_TUNMODE_YES;
1203 else if (strcasecmp(arg, "no") == 0)
1204 value = SSH_TUNMODE_NO;
1206 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1207 "no argument: %s", filename, linenum, arg);
1214 fatal("Match directive not supported as a command-line "
1216 value = match_cfg_line(&cp, linenum, user, host, address);
1218 fatal("%s line %d: Bad Match condition", filename,
1224 arg = strdelim(&cp);
1225 if (!arg || *arg == '\0')
1226 fatal("%s line %d: missing PermitOpen specification",
1228 if (strcmp(arg, "any") == 0) {
1230 channel_clear_adm_permitted_opens();
1231 options->num_permitted_opens = 0;
1235 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1238 fatal("%s line %d: missing host in PermitOpen",
1240 p = cleanhostname(p);
1241 if (arg == NULL || (port = a2port(arg)) == 0)
1242 fatal("%s line %d: bad port number in "
1243 "PermitOpen", filename, linenum);
1244 if (*activep && options->num_permitted_opens == -1) {
1245 channel_clear_adm_permitted_opens();
1246 options->num_permitted_opens =
1247 channel_add_adm_permitted_opens(p, port);
1254 fatal("%.200s line %d: Missing argument.", filename,
1256 len = strspn(cp, WHITESPACE);
1257 if (*activep && options->adm_forced_command == NULL)
1258 options->adm_forced_command = xstrdup(cp + len);
1261 case sVersionAddendum:
1262 ssh_version_set_addendum(strtok(cp, "\n"));
1264 arg = strdelim(&cp);
1265 } while (arg != NULL && *arg != '\0');
1269 logit("%s line %d: Deprecated option %s",
1270 filename, linenum, arg);
1272 arg = strdelim(&cp);
1276 logit("%s line %d: Unsupported option %s",
1277 filename, linenum, arg);
1279 arg = strdelim(&cp);
1283 fatal("%s line %d: Missing handler for opcode %s (%d)",
1284 filename, linenum, arg, opcode);
1286 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1287 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1288 filename, linenum, arg);
1292 /* Reads the server configuration file. */
1295 load_server_config(const char *filename, Buffer *conf)
1297 char line[1024], *cp;
1300 debug2("%s: filename %s", __func__, filename);
1301 if ((f = fopen(filename, "r")) == NULL) {
1306 while (fgets(line, sizeof(line), f)) {
1308 * Trim out comments and strip whitespace
1309 * NB - preserve newlines, they are needed to reproduce
1310 * line numbers later for error messages
1312 if ((cp = strchr(line, '#')) != NULL)
1313 memcpy(cp, "\n", 2);
1314 cp = line + strspn(line, " \t\r");
1316 buffer_append(conf, cp, strlen(cp));
1318 buffer_append(conf, "\0", 1);
1320 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1324 parse_server_match_config(ServerOptions *options, const char *user,
1325 const char *host, const char *address)
1329 initialize_server_options(&mo);
1330 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1331 copy_set_server_options(options, &mo);
1334 /* Copy any (supported) values that are set */
1336 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1338 if (src->allow_tcp_forwarding != -1)
1339 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1340 if (src->gateway_ports != -1)
1341 dst->gateway_ports = src->gateway_ports;
1342 if (src->adm_forced_command != NULL) {
1343 if (dst->adm_forced_command != NULL)
1344 xfree(dst->adm_forced_command);
1345 dst->adm_forced_command = src->adm_forced_command;
1347 if (src->x11_display_offset != -1)
1348 dst->x11_display_offset = src->x11_display_offset;
1349 if (src->x11_forwarding != -1)
1350 dst->x11_forwarding = src->x11_forwarding;
1351 if (src->x11_use_localhost != -1)
1352 dst->x11_use_localhost = src->x11_use_localhost;
1356 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1357 const char *user, const char *host, const char *address)
1359 int active, linenum, bad_options = 0;
1360 char *cp, *obuf, *cbuf;
1362 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1364 obuf = cbuf = xstrdup(buffer_ptr(conf));
1365 active = user ? 0 : 1;
1367 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1368 if (process_server_config_line(options, cp, filename,
1369 linenum++, &active, user, host, address) != 0)
1373 if (bad_options > 0)
1374 fatal("%s: terminating, %d bad configuration options",
1375 filename, bad_options);