1 /* $OpenBSD: servconf.c,v 1.170 2007/03/01 10:28:02 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_keyex = -1;
94 options->gss_cleanup_creds = -1;
95 options->gss_strict_acceptor = -1;
96 options->password_authentication = -1;
97 options->kbd_interactive_authentication = -1;
98 options->challenge_response_authentication = -1;
99 options->permit_empty_passwd = -1;
100 options->permit_user_env = -1;
101 options->use_login = -1;
102 options->compression = -1;
103 options->allow_tcp_forwarding = -1;
104 options->num_allow_users = 0;
105 options->num_deny_users = 0;
106 options->num_allow_groups = 0;
107 options->num_deny_groups = 0;
108 options->ciphers = NULL;
109 options->macs = NULL;
110 options->protocol = SSH_PROTO_UNKNOWN;
111 options->gateway_ports = -1;
112 options->num_subsystems = 0;
113 options->max_startups_begin = -1;
114 options->max_startups_rate = -1;
115 options->max_startups = -1;
116 options->max_authtries = -1;
117 options->banner = NULL;
118 options->use_dns = -1;
119 options->client_alive_interval = -1;
120 options->client_alive_count_max = -1;
121 options->authorized_keys_file = NULL;
122 options->authorized_keys_file2 = NULL;
123 options->num_accept_env = 0;
124 options->permit_tun = -1;
125 options->num_permitted_opens = -1;
126 options->adm_forced_command = NULL;
130 fill_default_server_options(ServerOptions *options)
132 /* Portable-specific options */
133 if (options->use_pam == -1)
134 options->use_pam = 0;
136 /* Standard Options */
137 if (options->protocol == SSH_PROTO_UNKNOWN)
138 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
139 if (options->num_host_key_files == 0) {
140 /* fill default hostkeys for protocols */
141 if (options->protocol & SSH_PROTO_1)
142 options->host_key_files[options->num_host_key_files++] =
144 if (options->protocol & SSH_PROTO_2) {
145 options->host_key_files[options->num_host_key_files++] =
146 _PATH_HOST_RSA_KEY_FILE;
147 options->host_key_files[options->num_host_key_files++] =
148 _PATH_HOST_DSA_KEY_FILE;
151 if (options->num_ports == 0)
152 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
153 if (options->listen_addrs == NULL)
154 add_listen_addr(options, NULL, 0);
155 if (options->pid_file == NULL)
156 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
157 if (options->server_key_bits == -1)
158 options->server_key_bits = 768;
159 if (options->login_grace_time == -1)
160 options->login_grace_time = 120;
161 if (options->key_regeneration_time == -1)
162 options->key_regeneration_time = 3600;
163 if (options->permit_root_login == PERMIT_NOT_SET)
164 options->permit_root_login = PERMIT_YES;
165 if (options->ignore_rhosts == -1)
166 options->ignore_rhosts = 1;
167 if (options->ignore_user_known_hosts == -1)
168 options->ignore_user_known_hosts = 0;
169 if (options->print_motd == -1)
170 options->print_motd = 1;
171 if (options->print_lastlog == -1)
172 options->print_lastlog = 1;
173 if (options->x11_forwarding == -1)
174 options->x11_forwarding = 0;
175 if (options->x11_display_offset == -1)
176 options->x11_display_offset = 10;
177 if (options->x11_use_localhost == -1)
178 options->x11_use_localhost = 1;
179 if (options->xauth_location == NULL)
180 options->xauth_location = _PATH_XAUTH;
181 if (options->strict_modes == -1)
182 options->strict_modes = 1;
183 if (options->tcp_keep_alive == -1)
184 options->tcp_keep_alive = 1;
185 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
186 options->log_facility = SYSLOG_FACILITY_AUTH;
187 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
188 options->log_level = SYSLOG_LEVEL_INFO;
189 if (options->rhosts_rsa_authentication == -1)
190 options->rhosts_rsa_authentication = 0;
191 if (options->hostbased_authentication == -1)
192 options->hostbased_authentication = 0;
193 if (options->hostbased_uses_name_from_packet_only == -1)
194 options->hostbased_uses_name_from_packet_only = 0;
195 if (options->rsa_authentication == -1)
196 options->rsa_authentication = 1;
197 if (options->pubkey_authentication == -1)
198 options->pubkey_authentication = 1;
199 if (options->kerberos_authentication == -1)
200 options->kerberos_authentication = 0;
201 if (options->kerberos_or_local_passwd == -1)
202 options->kerberos_or_local_passwd = 1;
203 if (options->kerberos_ticket_cleanup == -1)
204 options->kerberos_ticket_cleanup = 1;
205 if (options->kerberos_get_afs_token == -1)
206 options->kerberos_get_afs_token = 0;
207 if (options->gss_authentication == -1)
208 options->gss_authentication = 0;
209 if (options->gss_keyex == -1)
210 options->gss_keyex = 0;
211 if (options->gss_cleanup_creds == -1)
212 options->gss_cleanup_creds = 1;
213 if (options->gss_strict_acceptor == -1)
214 options->gss_strict_acceptor = 1;
215 if (options->password_authentication == -1)
216 options->password_authentication = 1;
217 if (options->kbd_interactive_authentication == -1)
218 options->kbd_interactive_authentication = 0;
219 if (options->challenge_response_authentication == -1)
220 options->challenge_response_authentication = 1;
221 if (options->permit_empty_passwd == -1)
222 options->permit_empty_passwd = 0;
223 if (options->permit_user_env == -1)
224 options->permit_user_env = 0;
225 if (options->use_login == -1)
226 options->use_login = 0;
227 if (options->compression == -1)
228 options->compression = COMP_DELAYED;
229 if (options->allow_tcp_forwarding == -1)
230 options->allow_tcp_forwarding = 1;
231 if (options->gateway_ports == -1)
232 options->gateway_ports = 0;
233 if (options->max_startups == -1)
234 options->max_startups = 10;
235 if (options->max_startups_rate == -1)
236 options->max_startups_rate = 100; /* 100% */
237 if (options->max_startups_begin == -1)
238 options->max_startups_begin = options->max_startups;
239 if (options->max_authtries == -1)
240 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
241 if (options->use_dns == -1)
242 options->use_dns = 1;
243 if (options->client_alive_interval == -1)
244 options->client_alive_interval = 0;
245 if (options->client_alive_count_max == -1)
246 options->client_alive_count_max = 3;
247 if (options->authorized_keys_file2 == NULL) {
248 /* authorized_keys_file2 falls back to authorized_keys_file */
249 if (options->authorized_keys_file != NULL)
250 options->authorized_keys_file2 = options->authorized_keys_file;
252 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
254 if (options->authorized_keys_file == NULL)
255 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
256 if (options->permit_tun == -1)
257 options->permit_tun = SSH_TUNMODE_NO;
259 /* Turn privilege separation on by default */
260 if (use_privsep == -1)
264 if (use_privsep && options->compression == 1) {
265 error("This platform does not support both privilege "
266 "separation and compression");
267 error("Compression disabled");
268 options->compression = 0;
274 /* Keyword tokens. */
276 sBadOption, /* == unknown option */
277 /* Portable-specific options */
279 /* Standard Options */
280 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
281 sPermitRootLogin, sLogFacility, sLogLevel,
282 sRhostsRSAAuthentication, sRSAAuthentication,
283 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
284 sKerberosGetAFSToken,
285 sKerberosTgtPassing, sChallengeResponseAuthentication,
286 sPasswordAuthentication, sKbdInteractiveAuthentication,
287 sListenAddress, sAddressFamily,
288 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
289 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
290 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
291 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
292 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
293 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
294 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
295 sMaxStartups, sMaxAuthTries,
296 sBanner, sUseDNS, sHostbasedAuthentication,
297 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
298 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
299 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
301 sAcceptEnv, sPermitTunnel,
302 sMatch, sPermitOpen, sForceCommand,
303 sUsePrivilegeSeparation,
304 sDeprecated, sUnsupported
307 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
308 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
309 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
311 /* Textual representation of the tokens. */
314 ServerOpCodes opcode;
317 /* Portable-specific options */
319 { "usepam", sUsePAM, SSHCFG_GLOBAL },
321 { "usepam", sUnsupported, SSHCFG_GLOBAL },
323 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
324 /* Standard Options */
325 { "port", sPort, SSHCFG_GLOBAL },
326 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
327 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
328 { "pidfile", sPidFile, SSHCFG_GLOBAL },
329 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
330 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
331 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
332 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
333 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
334 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
335 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
336 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
337 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
338 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
339 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
340 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
341 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
343 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
344 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
345 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
347 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
349 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
352 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
353 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
354 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
355 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
357 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
358 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
360 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
361 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
362 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
363 { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
365 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
366 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
367 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
368 { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
370 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
371 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
372 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
373 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
374 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
375 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
376 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
377 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
378 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
379 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
380 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
381 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
382 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
383 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
384 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
385 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
386 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
387 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
388 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
389 { "compression", sCompression, SSHCFG_GLOBAL },
390 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
391 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
392 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
393 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
394 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
395 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
396 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
397 { "ciphers", sCiphers, SSHCFG_GLOBAL },
398 { "macs", sMacs, SSHCFG_GLOBAL },
399 { "protocol", sProtocol, SSHCFG_GLOBAL },
400 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
401 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
402 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
403 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
404 { "banner", sBanner, SSHCFG_ALL },
405 { "usedns", sUseDNS, SSHCFG_GLOBAL },
406 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
407 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
408 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
409 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
410 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
411 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
412 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
413 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
414 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
415 { "match", sMatch, SSHCFG_ALL },
416 { "permitopen", sPermitOpen, SSHCFG_ALL },
417 { "forcecommand", sForceCommand, SSHCFG_ALL },
418 { NULL, sBadOption, 0 }
422 * Returns the number of the token pointed to by cp or sBadOption.
426 parse_token(const char *cp, const char *filename,
427 int linenum, u_int *flags)
431 for (i = 0; keywords[i].name; i++)
432 if (strcasecmp(cp, keywords[i].name) == 0) {
433 *flags = keywords[i].flags;
434 return keywords[i].opcode;
437 error("%s: line %d: Bad configuration option: %s",
438 filename, linenum, cp);
443 add_listen_addr(ServerOptions *options, char *addr, u_short port)
447 if (options->num_ports == 0)
448 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
449 if (options->address_family == -1)
450 options->address_family = AF_UNSPEC;
452 for (i = 0; i < options->num_ports; i++)
453 add_one_listen_addr(options, addr, options->ports[i]);
455 add_one_listen_addr(options, addr, port);
459 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
461 struct addrinfo hints, *ai, *aitop;
462 char strport[NI_MAXSERV];
465 memset(&hints, 0, sizeof(hints));
466 hints.ai_family = options->address_family;
467 hints.ai_socktype = SOCK_STREAM;
468 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
469 snprintf(strport, sizeof strport, "%u", port);
470 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
471 fatal("bad addr or host: %s (%s)",
472 addr ? addr : "<NULL>",
473 gai_strerror(gaierr));
474 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
476 ai->ai_next = options->listen_addrs;
477 options->listen_addrs = aitop;
481 * The strategy for the Match blocks is that the config file is parsed twice.
483 * The first time is at startup. activep is initialized to 1 and the
484 * directives in the global context are processed and acted on. Hitting a
485 * Match directive unsets activep and the directives inside the block are
486 * checked for syntax only.
488 * The second time is after a connection has been established but before
489 * authentication. activep is initialized to 2 and global config directives
490 * are ignored since they have already been processed. If the criteria in a
491 * Match block is met, activep is set and the subsequent directives
492 * processed and actioned until EOF or another Match block unsets it. Any
493 * options set are copied into the main server config.
495 * Potential additions/improvements:
496 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
498 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
499 * Match Address 192.168.0.*
504 * AllowTcpForwarding yes
505 * GatewayPorts clientspecified
508 * - Add a PermittedChannelRequests directive
510 * PermittedChannelRequests session,forwarded-tcpip
514 match_cfg_line_group(const char *grps, int line, const char *user)
518 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
522 * Even if we do not have a user yet, we still need to check for
525 arg = cp = xstrdup(grps);
526 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
527 if (ngrps >= MAX_MATCH_GROUPS) {
528 error("line %d: too many groups in Match Group", line);
532 grplist[ngrps++] = p;
538 if ((pw = getpwnam(user)) == NULL) {
539 debug("Can't match group at line %d because user %.100s does "
540 "not exist", line, user);
541 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
542 debug("Can't Match group because user %.100s not in any group "
543 "at line %d", user, line);
544 } else if (ga_match(grplist, ngrps) != 1) {
545 debug("user %.100s does not match group %.100s at line %d",
548 debug("user %.100s matched group %.100s at line %d", user,
559 match_cfg_line(char **condition, int line, const char *user, const char *host,
563 char *arg, *attrib, *cp = *condition;
567 debug3("checking syntax for 'Match %s'", cp);
569 debug3("checking match for '%s' user %s host %s addr %s", cp,
570 user ? user : "(null)", host ? host : "(null)",
571 address ? address : "(null)");
573 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
574 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
575 error("Missing Match criteria for %s", attrib);
579 if (strcasecmp(attrib, "user") == 0) {
584 if (match_pattern_list(user, arg, len, 0) != 1)
587 debug("user %.100s matched 'User %.100s' at "
588 "line %d", user, arg, line);
589 } else if (strcasecmp(attrib, "group") == 0) {
590 switch (match_cfg_line_group(arg, line, user)) {
596 } else if (strcasecmp(attrib, "host") == 0) {
601 if (match_hostname(host, arg, len) != 1)
604 debug("connection from %.100s matched 'Host "
605 "%.100s' at line %d", host, arg, line);
606 } else if (strcasecmp(attrib, "address") == 0) {
607 debug("address '%s' arg '%s'", address, arg);
612 if (match_hostname(address, arg, len) != 1)
615 debug("connection from %.100s matched 'Address "
616 "%.100s' at line %d", address, arg, line);
618 error("Unsupported Match attribute %s", attrib);
623 debug3("match %sfound", result ? "" : "not ");
628 #define WHITESPACE " \t\r\n"
631 process_server_config_line(ServerOptions *options, char *line,
632 const char *filename, int linenum, int *activep, const char *user,
633 const char *host, const char *address)
635 char *cp, **charptr, *arg, *p;
636 int cmdline = 0, *intptr, value, n;
637 ServerOpCodes opcode;
643 if ((arg = strdelim(&cp)) == NULL)
645 /* Ignore leading whitespace */
648 if (!arg || !*arg || *arg == '#')
652 opcode = parse_token(arg, filename, linenum, &flags);
654 if (activep == NULL) { /* We are processing a command line directive */
658 if (*activep && opcode != sMatch)
659 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
660 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
662 fatal("%s line %d: Directive '%s' is not allowed "
663 "within a Match block", filename, linenum, arg);
664 } else { /* this is a directive we have already processed */
672 /* Portable-specific options */
674 intptr = &options->use_pam;
677 /* Standard Options */
681 /* ignore ports from configfile if cmdline specifies ports */
682 if (options->ports_from_cmdline)
684 if (options->listen_addrs != NULL)
685 fatal("%s line %d: ports must be specified before "
686 "ListenAddress.", filename, linenum);
687 if (options->num_ports >= MAX_PORTS)
688 fatal("%s line %d: too many ports.",
691 if (!arg || *arg == '\0')
692 fatal("%s line %d: missing port number.",
694 options->ports[options->num_ports++] = a2port(arg);
695 if (options->ports[options->num_ports-1] == 0)
696 fatal("%s line %d: Badly formatted port number.",
701 intptr = &options->server_key_bits;
704 if (!arg || *arg == '\0')
705 fatal("%s line %d: missing integer value.",
708 if (*activep && *intptr == -1)
712 case sLoginGraceTime:
713 intptr = &options->login_grace_time;
716 if (!arg || *arg == '\0')
717 fatal("%s line %d: missing time value.",
719 if ((value = convtime(arg)) == -1)
720 fatal("%s line %d: invalid time value.",
726 case sKeyRegenerationTime:
727 intptr = &options->key_regeneration_time;
732 if (arg == NULL || *arg == '\0')
733 fatal("%s line %d: missing address",
735 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
736 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
737 && strchr(p+1, ':') != NULL) {
738 add_listen_addr(options, arg, 0);
743 fatal("%s line %d: bad address:port usage",
745 p = cleanhostname(p);
748 else if ((port = a2port(arg)) == 0)
749 fatal("%s line %d: bad port number", filename, linenum);
751 add_listen_addr(options, p, port);
757 if (!arg || *arg == '\0')
758 fatal("%s line %d: missing address family.",
760 intptr = &options->address_family;
761 if (options->listen_addrs != NULL)
762 fatal("%s line %d: address family must be specified before "
763 "ListenAddress.", filename, linenum);
764 if (strcasecmp(arg, "inet") == 0)
766 else if (strcasecmp(arg, "inet6") == 0)
768 else if (strcasecmp(arg, "any") == 0)
771 fatal("%s line %d: unsupported address family \"%s\".",
772 filename, linenum, arg);
778 intptr = &options->num_host_key_files;
779 if (*intptr >= MAX_HOSTKEYS)
780 fatal("%s line %d: too many host keys specified (max %d).",
781 filename, linenum, MAX_HOSTKEYS);
782 charptr = &options->host_key_files[*intptr];
785 if (!arg || *arg == '\0')
786 fatal("%s line %d: missing file name.",
788 if (*activep && *charptr == NULL) {
789 *charptr = tilde_expand_filename(arg, getuid());
790 /* increase optional counter */
792 *intptr = *intptr + 1;
797 charptr = &options->pid_file;
800 case sPermitRootLogin:
801 intptr = &options->permit_root_login;
803 if (!arg || *arg == '\0')
804 fatal("%s line %d: missing yes/"
805 "without-password/forced-commands-only/no "
806 "argument.", filename, linenum);
807 value = 0; /* silence compiler */
808 if (strcmp(arg, "without-password") == 0)
809 value = PERMIT_NO_PASSWD;
810 else if (strcmp(arg, "forced-commands-only") == 0)
811 value = PERMIT_FORCED_ONLY;
812 else if (strcmp(arg, "yes") == 0)
814 else if (strcmp(arg, "no") == 0)
817 fatal("%s line %d: Bad yes/"
818 "without-password/forced-commands-only/no "
819 "argument: %s", filename, linenum, arg);
825 intptr = &options->ignore_rhosts;
828 if (!arg || *arg == '\0')
829 fatal("%s line %d: missing yes/no argument.",
831 value = 0; /* silence compiler */
832 if (strcmp(arg, "yes") == 0)
834 else if (strcmp(arg, "no") == 0)
837 fatal("%s line %d: Bad yes/no argument: %s",
838 filename, linenum, arg);
839 if (*activep && *intptr == -1)
843 case sIgnoreUserKnownHosts:
844 intptr = &options->ignore_user_known_hosts;
847 case sRhostsRSAAuthentication:
848 intptr = &options->rhosts_rsa_authentication;
851 case sHostbasedAuthentication:
852 intptr = &options->hostbased_authentication;
855 case sHostbasedUsesNameFromPacketOnly:
856 intptr = &options->hostbased_uses_name_from_packet_only;
859 case sRSAAuthentication:
860 intptr = &options->rsa_authentication;
863 case sPubkeyAuthentication:
864 intptr = &options->pubkey_authentication;
867 case sKerberosAuthentication:
868 intptr = &options->kerberos_authentication;
871 case sKerberosOrLocalPasswd:
872 intptr = &options->kerberos_or_local_passwd;
875 case sKerberosTicketCleanup:
876 intptr = &options->kerberos_ticket_cleanup;
879 case sKerberosGetAFSToken:
880 intptr = &options->kerberos_get_afs_token;
883 case sGssAuthentication:
884 intptr = &options->gss_authentication;
888 intptr = &options->gss_keyex;
891 case sGssCleanupCreds:
892 intptr = &options->gss_cleanup_creds;
895 case sGssStrictAcceptor:
896 intptr = &options->gss_strict_acceptor;
899 case sPasswordAuthentication:
900 intptr = &options->password_authentication;
903 case sKbdInteractiveAuthentication:
904 intptr = &options->kbd_interactive_authentication;
907 case sChallengeResponseAuthentication:
908 intptr = &options->challenge_response_authentication;
912 intptr = &options->print_motd;
916 intptr = &options->print_lastlog;
920 intptr = &options->x11_forwarding;
923 case sX11DisplayOffset:
924 intptr = &options->x11_display_offset;
927 case sX11UseLocalhost:
928 intptr = &options->x11_use_localhost;
932 charptr = &options->xauth_location;
936 intptr = &options->strict_modes;
940 intptr = &options->tcp_keep_alive;
944 intptr = &options->permit_empty_passwd;
947 case sPermitUserEnvironment:
948 intptr = &options->permit_user_env;
952 intptr = &options->use_login;
956 intptr = &options->compression;
958 if (!arg || *arg == '\0')
959 fatal("%s line %d: missing yes/no/delayed "
960 "argument.", filename, linenum);
961 value = 0; /* silence compiler */
962 if (strcmp(arg, "delayed") == 0)
963 value = COMP_DELAYED;
964 else if (strcmp(arg, "yes") == 0)
966 else if (strcmp(arg, "no") == 0)
969 fatal("%s line %d: Bad yes/no/delayed "
970 "argument: %s", filename, linenum, arg);
976 intptr = &options->gateway_ports;
978 if (!arg || *arg == '\0')
979 fatal("%s line %d: missing yes/no/clientspecified "
980 "argument.", filename, linenum);
981 value = 0; /* silence compiler */
982 if (strcmp(arg, "clientspecified") == 0)
984 else if (strcmp(arg, "yes") == 0)
986 else if (strcmp(arg, "no") == 0)
989 fatal("%s line %d: Bad yes/no/clientspecified "
990 "argument: %s", filename, linenum, arg);
991 if (*activep && *intptr == -1)
996 intptr = &options->use_dns;
1000 intptr = (int *) &options->log_facility;
1001 arg = strdelim(&cp);
1002 value = log_facility_number(arg);
1003 if (value == SYSLOG_FACILITY_NOT_SET)
1004 fatal("%.200s line %d: unsupported log facility '%s'",
1005 filename, linenum, arg ? arg : "<NONE>");
1007 *intptr = (SyslogFacility) value;
1011 intptr = (int *) &options->log_level;
1012 arg = strdelim(&cp);
1013 value = log_level_number(arg);
1014 if (value == SYSLOG_LEVEL_NOT_SET)
1015 fatal("%.200s line %d: unsupported log level '%s'",
1016 filename, linenum, arg ? arg : "<NONE>");
1018 *intptr = (LogLevel) value;
1021 case sAllowTcpForwarding:
1022 intptr = &options->allow_tcp_forwarding;
1025 case sUsePrivilegeSeparation:
1026 intptr = &use_privsep;
1030 while ((arg = strdelim(&cp)) && *arg != '\0') {
1031 if (options->num_allow_users >= MAX_ALLOW_USERS)
1032 fatal("%s line %d: too many allow users.",
1034 options->allow_users[options->num_allow_users++] =
1040 while ((arg = strdelim(&cp)) && *arg != '\0') {
1041 if (options->num_deny_users >= MAX_DENY_USERS)
1042 fatal("%s line %d: too many deny users.",
1044 options->deny_users[options->num_deny_users++] =
1050 while ((arg = strdelim(&cp)) && *arg != '\0') {
1051 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1052 fatal("%s line %d: too many allow groups.",
1054 options->allow_groups[options->num_allow_groups++] =
1060 while ((arg = strdelim(&cp)) && *arg != '\0') {
1061 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1062 fatal("%s line %d: too many deny groups.",
1064 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1069 arg = strdelim(&cp);
1070 if (!arg || *arg == '\0')
1071 fatal("%s line %d: Missing argument.", filename, linenum);
1072 if (!ciphers_valid(arg))
1073 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1074 filename, linenum, arg ? arg : "<NONE>");
1075 if (options->ciphers == NULL)
1076 options->ciphers = xstrdup(arg);
1080 arg = strdelim(&cp);
1081 if (!arg || *arg == '\0')
1082 fatal("%s line %d: Missing argument.", filename, linenum);
1083 if (!mac_valid(arg))
1084 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1085 filename, linenum, arg ? arg : "<NONE>");
1086 if (options->macs == NULL)
1087 options->macs = xstrdup(arg);
1091 intptr = &options->protocol;
1092 arg = strdelim(&cp);
1093 if (!arg || *arg == '\0')
1094 fatal("%s line %d: Missing argument.", filename, linenum);
1095 value = proto_spec(arg);
1096 if (value == SSH_PROTO_UNKNOWN)
1097 fatal("%s line %d: Bad protocol spec '%s'.",
1098 filename, linenum, arg ? arg : "<NONE>");
1099 if (*intptr == SSH_PROTO_UNKNOWN)
1104 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1105 fatal("%s line %d: too many subsystems defined.",
1108 arg = strdelim(&cp);
1109 if (!arg || *arg == '\0')
1110 fatal("%s line %d: Missing subsystem name.",
1113 arg = strdelim(&cp);
1116 for (i = 0; i < options->num_subsystems; i++)
1117 if (strcmp(arg, options->subsystem_name[i]) == 0)
1118 fatal("%s line %d: Subsystem '%s' already defined.",
1119 filename, linenum, arg);
1120 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1121 arg = strdelim(&cp);
1122 if (!arg || *arg == '\0')
1123 fatal("%s line %d: Missing subsystem command.",
1125 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1127 /* Collect arguments (separate to executable) */
1129 len = strlen(p) + 1;
1130 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1131 len += 1 + strlen(arg);
1132 p = xrealloc(p, 1, len);
1133 strlcat(p, " ", len);
1134 strlcat(p, arg, len);
1136 options->subsystem_args[options->num_subsystems] = p;
1137 options->num_subsystems++;
1141 arg = strdelim(&cp);
1142 if (!arg || *arg == '\0')
1143 fatal("%s line %d: Missing MaxStartups spec.",
1145 if ((n = sscanf(arg, "%d:%d:%d",
1146 &options->max_startups_begin,
1147 &options->max_startups_rate,
1148 &options->max_startups)) == 3) {
1149 if (options->max_startups_begin >
1150 options->max_startups ||
1151 options->max_startups_rate > 100 ||
1152 options->max_startups_rate < 1)
1153 fatal("%s line %d: Illegal MaxStartups spec.",
1156 fatal("%s line %d: Illegal MaxStartups spec.",
1159 options->max_startups = options->max_startups_begin;
1163 intptr = &options->max_authtries;
1167 charptr = &options->banner;
1168 goto parse_filename;
1170 * These options can contain %X options expanded at
1171 * connect time, so that you can specify paths like:
1173 * AuthorizedKeysFile /etc/ssh_keys/%u
1175 case sAuthorizedKeysFile:
1176 case sAuthorizedKeysFile2:
1177 charptr = (opcode == sAuthorizedKeysFile) ?
1178 &options->authorized_keys_file :
1179 &options->authorized_keys_file2;
1180 goto parse_filename;
1182 case sClientAliveInterval:
1183 intptr = &options->client_alive_interval;
1186 case sClientAliveCountMax:
1187 intptr = &options->client_alive_count_max;
1191 while ((arg = strdelim(&cp)) && *arg != '\0') {
1192 if (strchr(arg, '=') != NULL)
1193 fatal("%s line %d: Invalid environment name.",
1195 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1196 fatal("%s line %d: too many allow env.",
1200 options->accept_env[options->num_accept_env++] =
1206 intptr = &options->permit_tun;
1207 arg = strdelim(&cp);
1208 if (!arg || *arg == '\0')
1209 fatal("%s line %d: Missing yes/point-to-point/"
1210 "ethernet/no argument.", filename, linenum);
1211 value = 0; /* silence compiler */
1212 if (strcasecmp(arg, "ethernet") == 0)
1213 value = SSH_TUNMODE_ETHERNET;
1214 else if (strcasecmp(arg, "point-to-point") == 0)
1215 value = SSH_TUNMODE_POINTOPOINT;
1216 else if (strcasecmp(arg, "yes") == 0)
1217 value = SSH_TUNMODE_YES;
1218 else if (strcasecmp(arg, "no") == 0)
1219 value = SSH_TUNMODE_NO;
1221 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1222 "no argument: %s", filename, linenum, arg);
1229 fatal("Match directive not supported as a command-line "
1231 value = match_cfg_line(&cp, linenum, user, host, address);
1233 fatal("%s line %d: Bad Match condition", filename,
1239 arg = strdelim(&cp);
1240 if (!arg || *arg == '\0')
1241 fatal("%s line %d: missing PermitOpen specification",
1243 n = options->num_permitted_opens; /* modified later */
1244 if (strcmp(arg, "any") == 0) {
1245 if (*activep && n == -1) {
1246 channel_clear_adm_permitted_opens();
1247 options->num_permitted_opens = 0;
1251 if (*activep && n == -1)
1252 channel_clear_adm_permitted_opens();
1253 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1256 fatal("%s line %d: missing host in PermitOpen",
1258 p = cleanhostname(p);
1259 if (arg == NULL || (port = a2port(arg)) == 0)
1260 fatal("%s line %d: bad port number in "
1261 "PermitOpen", filename, linenum);
1262 if (*activep && n == -1)
1263 options->num_permitted_opens =
1264 channel_add_adm_permitted_opens(p, port);
1270 fatal("%.200s line %d: Missing argument.", filename,
1272 len = strspn(cp, WHITESPACE);
1273 if (*activep && options->adm_forced_command == NULL)
1274 options->adm_forced_command = xstrdup(cp + len);
1278 logit("%s line %d: Deprecated option %s",
1279 filename, linenum, arg);
1281 arg = strdelim(&cp);
1285 logit("%s line %d: Unsupported option %s",
1286 filename, linenum, arg);
1288 arg = strdelim(&cp);
1292 fatal("%s line %d: Missing handler for opcode %s (%d)",
1293 filename, linenum, arg, opcode);
1295 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1296 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1297 filename, linenum, arg);
1301 /* Reads the server configuration file. */
1304 load_server_config(const char *filename, Buffer *conf)
1306 char line[1024], *cp;
1309 debug2("%s: filename %s", __func__, filename);
1310 if ((f = fopen(filename, "r")) == NULL) {
1315 while (fgets(line, sizeof(line), f)) {
1317 * Trim out comments and strip whitespace
1318 * NB - preserve newlines, they are needed to reproduce
1319 * line numbers later for error messages
1321 if ((cp = strchr(line, '#')) != NULL)
1322 memcpy(cp, "\n", 2);
1323 cp = line + strspn(line, " \t\r");
1325 buffer_append(conf, cp, strlen(cp));
1327 buffer_append(conf, "\0", 1);
1329 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1333 parse_server_match_config(ServerOptions *options, const char *user,
1334 const char *host, const char *address)
1338 initialize_server_options(&mo);
1339 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1340 copy_set_server_options(options, &mo, 0);
1344 #define M_CP_INTOPT(n) do {\
1348 #define M_CP_STROPT(n) do {\
1349 if (src->n != NULL) { \
1350 if (dst->n != NULL) \
1357 * Copy any supported values that are set.
1359 * If the preauth flag is set, we do not bother copying the the string or
1360 * array values that are not used pre-authentication, because any that we
1361 * do use must be explictly sent in mm_getpwnamallow().
1364 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1366 M_CP_INTOPT(password_authentication);
1367 M_CP_INTOPT(gss_authentication);
1368 M_CP_INTOPT(rsa_authentication);
1369 M_CP_INTOPT(pubkey_authentication);
1370 M_CP_INTOPT(kerberos_authentication);
1371 M_CP_INTOPT(hostbased_authentication);
1372 M_CP_INTOPT(kbd_interactive_authentication);
1374 M_CP_INTOPT(allow_tcp_forwarding);
1375 M_CP_INTOPT(gateway_ports);
1376 M_CP_INTOPT(x11_display_offset);
1377 M_CP_INTOPT(x11_forwarding);
1378 M_CP_INTOPT(x11_use_localhost);
1380 M_CP_STROPT(banner);
1383 M_CP_STROPT(adm_forced_command);
1390 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1391 const char *user, const char *host, const char *address)
1393 int active, linenum, bad_options = 0;
1394 char *cp, *obuf, *cbuf;
1396 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1398 obuf = cbuf = xstrdup(buffer_ptr(conf));
1399 active = user ? 0 : 1;
1401 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1402 if (process_server_config_line(options, cp, filename,
1403 linenum++, &active, user, host, address) != 0)
1407 if (bad_options > 0)
1408 fatal("%s: terminating, %d bad configuration options",
1409 filename, bad_options);
1411 /* challenge-response is implemented via keyboard interactive */
1412 if (options->challenge_response_authentication == 1)
1413 options->kbd_interactive_authentication = 1;