1 /* $OpenBSD: servconf.c,v 1.180 2008/05/08 12:21:16 djm 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>
27 #include "openbsd-compat/sys-queue.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->allow_agent_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->max_sessions = -1;
118 options->banner = NULL;
119 options->use_dns = -1;
120 options->client_alive_interval = -1;
121 options->client_alive_count_max = -1;
122 options->authorized_keys_file = NULL;
123 options->authorized_keys_file2 = NULL;
124 options->num_accept_env = 0;
125 options->permit_tun = -1;
126 options->num_permitted_opens = -1;
127 options->adm_forced_command = NULL;
128 options->chroot_directory = NULL;
132 fill_default_server_options(ServerOptions *options)
134 /* Portable-specific options */
135 if (options->use_pam == -1)
136 options->use_pam = 0;
138 /* Standard Options */
139 if (options->protocol == SSH_PROTO_UNKNOWN)
140 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
141 if (options->num_host_key_files == 0) {
142 /* fill default hostkeys for protocols */
143 if (options->protocol & SSH_PROTO_1)
144 options->host_key_files[options->num_host_key_files++] =
146 if (options->protocol & SSH_PROTO_2) {
147 options->host_key_files[options->num_host_key_files++] =
148 _PATH_HOST_RSA_KEY_FILE;
149 options->host_key_files[options->num_host_key_files++] =
150 _PATH_HOST_DSA_KEY_FILE;
153 if (options->num_ports == 0)
154 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
155 if (options->listen_addrs == NULL)
156 add_listen_addr(options, NULL, 0);
157 if (options->pid_file == NULL)
158 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
159 if (options->server_key_bits == -1)
160 options->server_key_bits = 768;
161 if (options->login_grace_time == -1)
162 options->login_grace_time = 120;
163 if (options->key_regeneration_time == -1)
164 options->key_regeneration_time = 3600;
165 if (options->permit_root_login == PERMIT_NOT_SET)
166 options->permit_root_login = PERMIT_YES;
167 if (options->ignore_rhosts == -1)
168 options->ignore_rhosts = 1;
169 if (options->ignore_user_known_hosts == -1)
170 options->ignore_user_known_hosts = 0;
171 if (options->print_motd == -1)
172 options->print_motd = 1;
173 if (options->print_lastlog == -1)
174 options->print_lastlog = 1;
175 if (options->x11_forwarding == -1)
176 options->x11_forwarding = 0;
177 if (options->x11_display_offset == -1)
178 options->x11_display_offset = 10;
179 if (options->x11_use_localhost == -1)
180 options->x11_use_localhost = 1;
181 if (options->xauth_location == NULL)
182 options->xauth_location = _PATH_XAUTH;
183 if (options->strict_modes == -1)
184 options->strict_modes = 1;
185 if (options->tcp_keep_alive == -1)
186 options->tcp_keep_alive = 1;
187 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
188 options->log_facility = SYSLOG_FACILITY_AUTH;
189 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
190 options->log_level = SYSLOG_LEVEL_INFO;
191 if (options->rhosts_rsa_authentication == -1)
192 options->rhosts_rsa_authentication = 0;
193 if (options->hostbased_authentication == -1)
194 options->hostbased_authentication = 0;
195 if (options->hostbased_uses_name_from_packet_only == -1)
196 options->hostbased_uses_name_from_packet_only = 0;
197 if (options->rsa_authentication == -1)
198 options->rsa_authentication = 1;
199 if (options->pubkey_authentication == -1)
200 options->pubkey_authentication = 1;
201 if (options->kerberos_authentication == -1)
202 options->kerberos_authentication = 0;
203 if (options->kerberos_or_local_passwd == -1)
204 options->kerberos_or_local_passwd = 1;
205 if (options->kerberos_ticket_cleanup == -1)
206 options->kerberos_ticket_cleanup = 1;
207 if (options->kerberos_get_afs_token == -1)
208 options->kerberos_get_afs_token = 0;
209 if (options->gss_authentication == -1)
210 options->gss_authentication = 0;
211 if (options->gss_cleanup_creds == -1)
212 options->gss_cleanup_creds = 1;
213 if (options->password_authentication == -1)
214 options->password_authentication = 1;
215 if (options->kbd_interactive_authentication == -1)
216 options->kbd_interactive_authentication = 0;
217 if (options->challenge_response_authentication == -1)
218 options->challenge_response_authentication = 1;
219 if (options->permit_empty_passwd == -1)
220 options->permit_empty_passwd = 0;
221 if (options->permit_user_env == -1)
222 options->permit_user_env = 0;
223 if (options->use_login == -1)
224 options->use_login = 0;
225 if (options->compression == -1)
226 options->compression = COMP_DELAYED;
227 if (options->allow_tcp_forwarding == -1)
228 options->allow_tcp_forwarding = 1;
229 if (options->allow_agent_forwarding == -1)
230 options->allow_agent_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->max_sessions == -1)
242 options->max_sessions = DEFAULT_SESSIONS_MAX;
243 if (options->use_dns == -1)
244 options->use_dns = 1;
245 if (options->client_alive_interval == -1)
246 options->client_alive_interval = 0;
247 if (options->client_alive_count_max == -1)
248 options->client_alive_count_max = 3;
249 if (options->authorized_keys_file2 == NULL) {
250 /* authorized_keys_file2 falls back to authorized_keys_file */
251 if (options->authorized_keys_file != NULL)
252 options->authorized_keys_file2 = options->authorized_keys_file;
254 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
256 if (options->authorized_keys_file == NULL)
257 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
258 if (options->permit_tun == -1)
259 options->permit_tun = SSH_TUNMODE_NO;
261 /* Turn privilege separation on by default */
262 if (use_privsep == -1)
266 if (use_privsep && options->compression == 1) {
267 error("This platform does not support both privilege "
268 "separation and compression");
269 error("Compression disabled");
270 options->compression = 0;
276 /* Keyword tokens. */
278 sBadOption, /* == unknown option */
279 /* Portable-specific options */
281 /* Standard Options */
282 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
283 sPermitRootLogin, sLogFacility, sLogLevel,
284 sRhostsRSAAuthentication, sRSAAuthentication,
285 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
286 sKerberosGetAFSToken,
287 sKerberosTgtPassing, sChallengeResponseAuthentication,
288 sPasswordAuthentication, sKbdInteractiveAuthentication,
289 sListenAddress, sAddressFamily,
290 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
291 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
292 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
293 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
294 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
295 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
296 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
297 sMaxStartups, sMaxAuthTries, sMaxSessions,
298 sBanner, sUseDNS, sHostbasedAuthentication,
299 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
300 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
301 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
302 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
303 sUsePrivilegeSeparation, sAllowAgentForwarding,
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_ALL },
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 },
363 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
364 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
366 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
367 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
368 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
369 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
370 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
371 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
372 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
373 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
374 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
375 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
376 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
377 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
378 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
379 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
380 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
381 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
382 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
383 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
384 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
385 { "compression", sCompression, SSHCFG_GLOBAL },
386 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
387 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
388 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
389 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
390 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
391 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
392 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
393 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
394 { "ciphers", sCiphers, SSHCFG_GLOBAL },
395 { "macs", sMacs, SSHCFG_GLOBAL },
396 { "protocol", sProtocol, SSHCFG_GLOBAL },
397 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
398 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
399 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
400 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
401 { "maxsessions", sMaxSessions, SSHCFG_ALL },
402 { "banner", sBanner, SSHCFG_ALL },
403 { "usedns", sUseDNS, SSHCFG_GLOBAL },
404 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
405 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
406 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
407 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
408 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
409 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
410 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
411 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
412 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
413 { "match", sMatch, SSHCFG_ALL },
414 { "permitopen", sPermitOpen, SSHCFG_ALL },
415 { "forcecommand", sForceCommand, SSHCFG_ALL },
416 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
417 { NULL, sBadOption, 0 }
421 * Returns the number of the token pointed to by cp or sBadOption.
425 parse_token(const char *cp, const char *filename,
426 int linenum, u_int *flags)
430 for (i = 0; keywords[i].name; i++)
431 if (strcasecmp(cp, keywords[i].name) == 0) {
432 *flags = keywords[i].flags;
433 return keywords[i].opcode;
436 error("%s: line %d: Bad configuration option: %s",
437 filename, linenum, cp);
442 add_listen_addr(ServerOptions *options, char *addr, u_short port)
446 if (options->num_ports == 0)
447 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
448 if (options->address_family == -1)
449 options->address_family = AF_UNSPEC;
451 for (i = 0; i < options->num_ports; i++)
452 add_one_listen_addr(options, addr, options->ports[i]);
454 add_one_listen_addr(options, addr, port);
458 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
460 struct addrinfo hints, *ai, *aitop;
461 char strport[NI_MAXSERV];
464 memset(&hints, 0, sizeof(hints));
465 hints.ai_family = options->address_family;
466 hints.ai_socktype = SOCK_STREAM;
467 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
468 snprintf(strport, sizeof strport, "%u", port);
469 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
470 fatal("bad addr or host: %s (%s)",
471 addr ? addr : "<NULL>",
472 ssh_gai_strerror(gaierr));
473 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
475 ai->ai_next = options->listen_addrs;
476 options->listen_addrs = aitop;
480 * The strategy for the Match blocks is that the config file is parsed twice.
482 * The first time is at startup. activep is initialized to 1 and the
483 * directives in the global context are processed and acted on. Hitting a
484 * Match directive unsets activep and the directives inside the block are
485 * checked for syntax only.
487 * The second time is after a connection has been established but before
488 * authentication. activep is initialized to 2 and global config directives
489 * are ignored since they have already been processed. If the criteria in a
490 * Match block is met, activep is set and the subsequent directives
491 * processed and actioned until EOF or another Match block unsets it. Any
492 * options set are copied into the main server config.
494 * Potential additions/improvements:
495 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
497 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
498 * Match Address 192.168.0.*
503 * AllowTcpForwarding yes
504 * GatewayPorts clientspecified
507 * - Add a PermittedChannelRequests directive
509 * PermittedChannelRequests session,forwarded-tcpip
513 match_cfg_line_group(const char *grps, int line, const char *user)
517 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
521 * Even if we do not have a user yet, we still need to check for
524 arg = cp = xstrdup(grps);
525 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
526 if (ngrps >= MAX_MATCH_GROUPS) {
527 error("line %d: too many groups in Match Group", line);
531 grplist[ngrps++] = p;
537 if ((pw = getpwnam(user)) == NULL) {
538 debug("Can't match group at line %d because user %.100s does "
539 "not exist", line, user);
540 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
541 debug("Can't Match group because user %.100s not in any group "
542 "at line %d", user, line);
543 } else if (ga_match(grplist, ngrps) != 1) {
544 debug("user %.100s does not match group %.100s at line %d",
547 debug("user %.100s matched group %.100s at line %d", user,
558 match_cfg_line(char **condition, int line, const char *user, const char *host,
562 char *arg, *attrib, *cp = *condition;
566 debug3("checking syntax for 'Match %s'", cp);
568 debug3("checking match for '%s' user %s host %s addr %s", cp,
569 user ? user : "(null)", host ? host : "(null)",
570 address ? address : "(null)");
572 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
573 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
574 error("Missing Match criteria for %s", attrib);
578 if (strcasecmp(attrib, "user") == 0) {
583 if (match_pattern_list(user, arg, len, 0) != 1)
586 debug("user %.100s matched 'User %.100s' at "
587 "line %d", user, arg, line);
588 } else if (strcasecmp(attrib, "group") == 0) {
589 switch (match_cfg_line_group(arg, line, user)) {
595 } else if (strcasecmp(attrib, "host") == 0) {
600 if (match_hostname(host, arg, len) != 1)
603 debug("connection from %.100s matched 'Host "
604 "%.100s' at line %d", host, arg, line);
605 } else if (strcasecmp(attrib, "address") == 0) {
610 if (match_hostname(address, arg, len) != 1)
613 debug("connection from %.100s matched 'Address "
614 "%.100s' at line %d", address, arg, line);
616 error("Unsupported Match attribute %s", attrib);
621 debug3("match %sfound", result ? "" : "not ");
626 #define WHITESPACE " \t\r\n"
629 process_server_config_line(ServerOptions *options, char *line,
630 const char *filename, int linenum, int *activep, const char *user,
631 const char *host, const char *address)
633 char *cp, **charptr, *arg, *p;
634 int cmdline = 0, *intptr, value, n;
635 SyslogFacility *log_facility_ptr;
636 LogLevel *log_level_ptr;
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);
820 if (*activep && *intptr == -1)
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;
887 case sGssCleanupCreds:
888 intptr = &options->gss_cleanup_creds;
891 case sPasswordAuthentication:
892 intptr = &options->password_authentication;
895 case sKbdInteractiveAuthentication:
896 intptr = &options->kbd_interactive_authentication;
899 case sChallengeResponseAuthentication:
900 intptr = &options->challenge_response_authentication;
904 intptr = &options->print_motd;
908 intptr = &options->print_lastlog;
912 intptr = &options->x11_forwarding;
915 case sX11DisplayOffset:
916 intptr = &options->x11_display_offset;
919 case sX11UseLocalhost:
920 intptr = &options->x11_use_localhost;
924 charptr = &options->xauth_location;
928 intptr = &options->strict_modes;
932 intptr = &options->tcp_keep_alive;
936 intptr = &options->permit_empty_passwd;
939 case sPermitUserEnvironment:
940 intptr = &options->permit_user_env;
944 intptr = &options->use_login;
948 intptr = &options->compression;
950 if (!arg || *arg == '\0')
951 fatal("%s line %d: missing yes/no/delayed "
952 "argument.", filename, linenum);
953 value = 0; /* silence compiler */
954 if (strcmp(arg, "delayed") == 0)
955 value = COMP_DELAYED;
956 else if (strcmp(arg, "yes") == 0)
958 else if (strcmp(arg, "no") == 0)
961 fatal("%s line %d: Bad yes/no/delayed "
962 "argument: %s", filename, linenum, arg);
968 intptr = &options->gateway_ports;
970 if (!arg || *arg == '\0')
971 fatal("%s line %d: missing yes/no/clientspecified "
972 "argument.", filename, linenum);
973 value = 0; /* silence compiler */
974 if (strcmp(arg, "clientspecified") == 0)
976 else if (strcmp(arg, "yes") == 0)
978 else if (strcmp(arg, "no") == 0)
981 fatal("%s line %d: Bad yes/no/clientspecified "
982 "argument: %s", filename, linenum, arg);
983 if (*activep && *intptr == -1)
988 intptr = &options->use_dns;
992 log_facility_ptr = &options->log_facility;
994 value = log_facility_number(arg);
995 if (value == SYSLOG_FACILITY_NOT_SET)
996 fatal("%.200s line %d: unsupported log facility '%s'",
997 filename, linenum, arg ? arg : "<NONE>");
998 if (*log_facility_ptr == -1)
999 *log_facility_ptr = (SyslogFacility) value;
1003 log_level_ptr = &options->log_level;
1004 arg = strdelim(&cp);
1005 value = log_level_number(arg);
1006 if (value == SYSLOG_LEVEL_NOT_SET)
1007 fatal("%.200s line %d: unsupported log level '%s'",
1008 filename, linenum, arg ? arg : "<NONE>");
1009 if (*log_level_ptr == -1)
1010 *log_level_ptr = (LogLevel) value;
1013 case sAllowTcpForwarding:
1014 intptr = &options->allow_tcp_forwarding;
1017 case sAllowAgentForwarding:
1018 intptr = &options->allow_agent_forwarding;
1021 case sUsePrivilegeSeparation:
1022 intptr = &use_privsep;
1026 while ((arg = strdelim(&cp)) && *arg != '\0') {
1027 if (options->num_allow_users >= MAX_ALLOW_USERS)
1028 fatal("%s line %d: too many allow users.",
1030 options->allow_users[options->num_allow_users++] =
1036 while ((arg = strdelim(&cp)) && *arg != '\0') {
1037 if (options->num_deny_users >= MAX_DENY_USERS)
1038 fatal("%s line %d: too many deny users.",
1040 options->deny_users[options->num_deny_users++] =
1046 while ((arg = strdelim(&cp)) && *arg != '\0') {
1047 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1048 fatal("%s line %d: too many allow groups.",
1050 options->allow_groups[options->num_allow_groups++] =
1056 while ((arg = strdelim(&cp)) && *arg != '\0') {
1057 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1058 fatal("%s line %d: too many deny groups.",
1060 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1065 arg = strdelim(&cp);
1066 if (!arg || *arg == '\0')
1067 fatal("%s line %d: Missing argument.", filename, linenum);
1068 if (!ciphers_valid(arg))
1069 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1070 filename, linenum, arg ? arg : "<NONE>");
1071 if (options->ciphers == NULL)
1072 options->ciphers = xstrdup(arg);
1076 arg = strdelim(&cp);
1077 if (!arg || *arg == '\0')
1078 fatal("%s line %d: Missing argument.", filename, linenum);
1079 if (!mac_valid(arg))
1080 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1081 filename, linenum, arg ? arg : "<NONE>");
1082 if (options->macs == NULL)
1083 options->macs = xstrdup(arg);
1087 intptr = &options->protocol;
1088 arg = strdelim(&cp);
1089 if (!arg || *arg == '\0')
1090 fatal("%s line %d: Missing argument.", filename, linenum);
1091 value = proto_spec(arg);
1092 if (value == SSH_PROTO_UNKNOWN)
1093 fatal("%s line %d: Bad protocol spec '%s'.",
1094 filename, linenum, arg ? arg : "<NONE>");
1095 if (*intptr == SSH_PROTO_UNKNOWN)
1100 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1101 fatal("%s line %d: too many subsystems defined.",
1104 arg = strdelim(&cp);
1105 if (!arg || *arg == '\0')
1106 fatal("%s line %d: Missing subsystem name.",
1109 arg = strdelim(&cp);
1112 for (i = 0; i < options->num_subsystems; i++)
1113 if (strcmp(arg, options->subsystem_name[i]) == 0)
1114 fatal("%s line %d: Subsystem '%s' already defined.",
1115 filename, linenum, arg);
1116 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1117 arg = strdelim(&cp);
1118 if (!arg || *arg == '\0')
1119 fatal("%s line %d: Missing subsystem command.",
1121 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1123 /* Collect arguments (separate to executable) */
1125 len = strlen(p) + 1;
1126 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1127 len += 1 + strlen(arg);
1128 p = xrealloc(p, 1, len);
1129 strlcat(p, " ", len);
1130 strlcat(p, arg, len);
1132 options->subsystem_args[options->num_subsystems] = p;
1133 options->num_subsystems++;
1137 arg = strdelim(&cp);
1138 if (!arg || *arg == '\0')
1139 fatal("%s line %d: Missing MaxStartups spec.",
1141 if ((n = sscanf(arg, "%d:%d:%d",
1142 &options->max_startups_begin,
1143 &options->max_startups_rate,
1144 &options->max_startups)) == 3) {
1145 if (options->max_startups_begin >
1146 options->max_startups ||
1147 options->max_startups_rate > 100 ||
1148 options->max_startups_rate < 1)
1149 fatal("%s line %d: Illegal MaxStartups spec.",
1152 fatal("%s line %d: Illegal MaxStartups spec.",
1155 options->max_startups = options->max_startups_begin;
1159 intptr = &options->max_authtries;
1163 intptr = &options->max_sessions;
1167 charptr = &options->banner;
1168 goto parse_filename;
1171 * These options can contain %X options expanded at
1172 * connect time, so that you can specify paths like:
1174 * AuthorizedKeysFile /etc/ssh_keys/%u
1176 case sAuthorizedKeysFile:
1177 case sAuthorizedKeysFile2:
1178 charptr = (opcode == sAuthorizedKeysFile) ?
1179 &options->authorized_keys_file :
1180 &options->authorized_keys_file2;
1181 goto parse_filename;
1183 case sClientAliveInterval:
1184 intptr = &options->client_alive_interval;
1187 case sClientAliveCountMax:
1188 intptr = &options->client_alive_count_max;
1192 while ((arg = strdelim(&cp)) && *arg != '\0') {
1193 if (strchr(arg, '=') != NULL)
1194 fatal("%s line %d: Invalid environment name.",
1196 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1197 fatal("%s line %d: too many allow env.",
1201 options->accept_env[options->num_accept_env++] =
1207 intptr = &options->permit_tun;
1208 arg = strdelim(&cp);
1209 if (!arg || *arg == '\0')
1210 fatal("%s line %d: Missing yes/point-to-point/"
1211 "ethernet/no argument.", filename, linenum);
1212 value = 0; /* silence compiler */
1213 if (strcasecmp(arg, "ethernet") == 0)
1214 value = SSH_TUNMODE_ETHERNET;
1215 else if (strcasecmp(arg, "point-to-point") == 0)
1216 value = SSH_TUNMODE_POINTOPOINT;
1217 else if (strcasecmp(arg, "yes") == 0)
1218 value = SSH_TUNMODE_YES;
1219 else if (strcasecmp(arg, "no") == 0)
1220 value = SSH_TUNMODE_NO;
1222 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1223 "no argument: %s", filename, linenum, arg);
1230 fatal("Match directive not supported as a command-line "
1232 value = match_cfg_line(&cp, linenum, user, host, address);
1234 fatal("%s line %d: Bad Match condition", filename,
1240 arg = strdelim(&cp);
1241 if (!arg || *arg == '\0')
1242 fatal("%s line %d: missing PermitOpen specification",
1244 n = options->num_permitted_opens; /* modified later */
1245 if (strcmp(arg, "any") == 0) {
1246 if (*activep && n == -1) {
1247 channel_clear_adm_permitted_opens();
1248 options->num_permitted_opens = 0;
1252 if (*activep && n == -1)
1253 channel_clear_adm_permitted_opens();
1254 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1257 fatal("%s line %d: missing host in PermitOpen",
1259 p = cleanhostname(p);
1260 if (arg == NULL || (port = a2port(arg)) == 0)
1261 fatal("%s line %d: bad port number in "
1262 "PermitOpen", filename, linenum);
1263 if (*activep && n == -1)
1264 options->num_permitted_opens =
1265 channel_add_adm_permitted_opens(p, port);
1271 fatal("%.200s line %d: Missing argument.", filename,
1273 len = strspn(cp, WHITESPACE);
1274 if (*activep && options->adm_forced_command == NULL)
1275 options->adm_forced_command = xstrdup(cp + len);
1278 case sChrootDirectory:
1279 charptr = &options->chroot_directory;
1281 arg = strdelim(&cp);
1282 if (!arg || *arg == '\0')
1283 fatal("%s line %d: missing file name.",
1285 if (*activep && *charptr == NULL)
1286 *charptr = xstrdup(arg);
1290 logit("%s line %d: Deprecated option %s",
1291 filename, linenum, arg);
1293 arg = strdelim(&cp);
1297 logit("%s line %d: Unsupported option %s",
1298 filename, linenum, arg);
1300 arg = strdelim(&cp);
1304 fatal("%s line %d: Missing handler for opcode %s (%d)",
1305 filename, linenum, arg, opcode);
1307 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1308 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1309 filename, linenum, arg);
1313 /* Reads the server configuration file. */
1316 load_server_config(const char *filename, Buffer *conf)
1318 char line[1024], *cp;
1321 debug2("%s: filename %s", __func__, filename);
1322 if ((f = fopen(filename, "r")) == NULL) {
1327 while (fgets(line, sizeof(line), f)) {
1329 * Trim out comments and strip whitespace
1330 * NB - preserve newlines, they are needed to reproduce
1331 * line numbers later for error messages
1333 if ((cp = strchr(line, '#')) != NULL)
1334 memcpy(cp, "\n", 2);
1335 cp = line + strspn(line, " \t\r");
1337 buffer_append(conf, cp, strlen(cp));
1339 buffer_append(conf, "\0", 1);
1341 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1345 parse_server_match_config(ServerOptions *options, const char *user,
1346 const char *host, const char *address)
1350 initialize_server_options(&mo);
1351 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1352 copy_set_server_options(options, &mo, 0);
1356 #define M_CP_INTOPT(n) do {\
1360 #define M_CP_STROPT(n) do {\
1361 if (src->n != NULL) { \
1362 if (dst->n != NULL) \
1369 * Copy any supported values that are set.
1371 * If the preauth flag is set, we do not bother copying the the string or
1372 * array values that are not used pre-authentication, because any that we
1373 * do use must be explictly sent in mm_getpwnamallow().
1376 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1378 M_CP_INTOPT(password_authentication);
1379 M_CP_INTOPT(gss_authentication);
1380 M_CP_INTOPT(rsa_authentication);
1381 M_CP_INTOPT(pubkey_authentication);
1382 M_CP_INTOPT(kerberos_authentication);
1383 M_CP_INTOPT(hostbased_authentication);
1384 M_CP_INTOPT(kbd_interactive_authentication);
1385 M_CP_INTOPT(permit_root_login);
1387 M_CP_INTOPT(allow_tcp_forwarding);
1388 M_CP_INTOPT(allow_agent_forwarding);
1389 M_CP_INTOPT(gateway_ports);
1390 M_CP_INTOPT(x11_display_offset);
1391 M_CP_INTOPT(x11_forwarding);
1392 M_CP_INTOPT(x11_use_localhost);
1393 M_CP_INTOPT(max_sessions);
1395 M_CP_STROPT(banner);
1398 M_CP_STROPT(adm_forced_command);
1399 M_CP_STROPT(chroot_directory);
1406 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1407 const char *user, const char *host, const char *address)
1409 int active, linenum, bad_options = 0;
1410 char *cp, *obuf, *cbuf;
1412 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1414 obuf = cbuf = xstrdup(buffer_ptr(conf));
1415 active = user ? 0 : 1;
1417 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1418 if (process_server_config_line(options, cp, filename,
1419 linenum++, &active, user, host, address) != 0)
1423 if (bad_options > 0)
1424 fatal("%s: terminating, %d bad configuration options",
1425 filename, bad_options);