1 /* $OpenBSD: servconf.c,v 1.177 2008/02/10 10:54:28 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>
33 #include "pathnames.h"
41 #include "groupaccess.h"
43 static void add_listen_addr(ServerOptions *, char *, u_short);
44 static void add_one_listen_addr(ServerOptions *, char *, u_short);
46 /* Use of privilege separation or not */
47 extern int use_privsep;
50 /* Initializes the server options to their default values. */
53 initialize_server_options(ServerOptions *options)
55 memset(options, 0, sizeof(*options));
57 /* Portable-specific options */
58 options->use_pam = -1;
60 /* Standard Options */
61 options->num_ports = 0;
62 options->ports_from_cmdline = 0;
63 options->listen_addrs = NULL;
64 options->address_family = -1;
65 options->num_host_key_files = 0;
66 options->pid_file = NULL;
67 options->server_key_bits = -1;
68 options->login_grace_time = -1;
69 options->key_regeneration_time = -1;
70 options->permit_root_login = PERMIT_NOT_SET;
71 options->ignore_rhosts = -1;
72 options->ignore_user_known_hosts = -1;
73 options->print_motd = -1;
74 options->print_lastlog = -1;
75 options->x11_forwarding = -1;
76 options->x11_display_offset = -1;
77 options->x11_use_localhost = -1;
78 options->xauth_location = NULL;
79 options->strict_modes = -1;
80 options->tcp_keep_alive = -1;
81 options->log_facility = SYSLOG_FACILITY_NOT_SET;
82 options->log_level = SYSLOG_LEVEL_NOT_SET;
83 options->rhosts_rsa_authentication = -1;
84 options->hostbased_authentication = -1;
85 options->hostbased_uses_name_from_packet_only = -1;
86 options->rsa_authentication = -1;
87 options->pubkey_authentication = -1;
88 options->kerberos_authentication = -1;
89 options->kerberos_or_local_passwd = -1;
90 options->kerberos_ticket_cleanup = -1;
91 options->kerberos_get_afs_token = -1;
92 options->gss_authentication=-1;
93 options->gss_cleanup_creds = -1;
94 options->password_authentication = -1;
95 options->kbd_interactive_authentication = -1;
96 options->challenge_response_authentication = -1;
97 options->permit_empty_passwd = -1;
98 options->permit_user_env = -1;
99 options->use_login = -1;
100 options->compression = -1;
101 options->allow_tcp_forwarding = -1;
102 options->num_allow_users = 0;
103 options->num_deny_users = 0;
104 options->num_allow_groups = 0;
105 options->num_deny_groups = 0;
106 options->ciphers = NULL;
107 options->macs = NULL;
108 options->protocol = SSH_PROTO_UNKNOWN;
109 options->gateway_ports = -1;
110 options->num_subsystems = 0;
111 options->max_startups_begin = -1;
112 options->max_startups_rate = -1;
113 options->max_startups = -1;
114 options->max_authtries = -1;
115 options->banner = NULL;
116 options->use_dns = -1;
117 options->client_alive_interval = -1;
118 options->client_alive_count_max = -1;
119 options->authorized_keys_file = NULL;
120 options->authorized_keys_file2 = NULL;
121 options->num_accept_env = 0;
122 options->permit_tun = -1;
123 options->num_permitted_opens = -1;
124 options->adm_forced_command = NULL;
125 options->chroot_directory = NULL;
129 fill_default_server_options(ServerOptions *options)
131 /* Portable-specific options */
132 if (options->use_pam == -1)
133 options->use_pam = 0;
135 /* Standard Options */
136 if (options->protocol == SSH_PROTO_UNKNOWN)
137 options->protocol = SSH_PROTO_1|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_RSA_KEY_FILE;
146 options->host_key_files[options->num_host_key_files++] =
147 _PATH_HOST_DSA_KEY_FILE;
150 if (options->num_ports == 0)
151 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
152 if (options->listen_addrs == NULL)
153 add_listen_addr(options, NULL, 0);
154 if (options->pid_file == NULL)
155 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
156 if (options->server_key_bits == -1)
157 options->server_key_bits = 768;
158 if (options->login_grace_time == -1)
159 options->login_grace_time = 120;
160 if (options->key_regeneration_time == -1)
161 options->key_regeneration_time = 3600;
162 if (options->permit_root_login == PERMIT_NOT_SET)
163 options->permit_root_login = PERMIT_YES;
164 if (options->ignore_rhosts == -1)
165 options->ignore_rhosts = 1;
166 if (options->ignore_user_known_hosts == -1)
167 options->ignore_user_known_hosts = 0;
168 if (options->print_motd == -1)
169 options->print_motd = 1;
170 if (options->print_lastlog == -1)
171 options->print_lastlog = 1;
172 if (options->x11_forwarding == -1)
173 options->x11_forwarding = 0;
174 if (options->x11_display_offset == -1)
175 options->x11_display_offset = 10;
176 if (options->x11_use_localhost == -1)
177 options->x11_use_localhost = 1;
178 if (options->xauth_location == NULL)
179 options->xauth_location = _PATH_XAUTH;
180 if (options->strict_modes == -1)
181 options->strict_modes = 1;
182 if (options->tcp_keep_alive == -1)
183 options->tcp_keep_alive = 1;
184 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
185 options->log_facility = SYSLOG_FACILITY_AUTH;
186 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
187 options->log_level = SYSLOG_LEVEL_INFO;
188 if (options->rhosts_rsa_authentication == -1)
189 options->rhosts_rsa_authentication = 0;
190 if (options->hostbased_authentication == -1)
191 options->hostbased_authentication = 0;
192 if (options->hostbased_uses_name_from_packet_only == -1)
193 options->hostbased_uses_name_from_packet_only = 0;
194 if (options->rsa_authentication == -1)
195 options->rsa_authentication = 1;
196 if (options->pubkey_authentication == -1)
197 options->pubkey_authentication = 1;
198 if (options->kerberos_authentication == -1)
199 options->kerberos_authentication = 0;
200 if (options->kerberos_or_local_passwd == -1)
201 options->kerberos_or_local_passwd = 1;
202 if (options->kerberos_ticket_cleanup == -1)
203 options->kerberos_ticket_cleanup = 1;
204 if (options->kerberos_get_afs_token == -1)
205 options->kerberos_get_afs_token = 0;
206 if (options->gss_authentication == -1)
207 options->gss_authentication = 0;
208 if (options->gss_cleanup_creds == -1)
209 options->gss_cleanup_creds = 1;
210 if (options->password_authentication == -1)
211 options->password_authentication = 1;
212 if (options->kbd_interactive_authentication == -1)
213 options->kbd_interactive_authentication = 0;
214 if (options->challenge_response_authentication == -1)
215 options->challenge_response_authentication = 1;
216 if (options->permit_empty_passwd == -1)
217 options->permit_empty_passwd = 0;
218 if (options->permit_user_env == -1)
219 options->permit_user_env = 0;
220 if (options->use_login == -1)
221 options->use_login = 0;
222 if (options->compression == -1)
223 options->compression = COMP_DELAYED;
224 if (options->allow_tcp_forwarding == -1)
225 options->allow_tcp_forwarding = 1;
226 if (options->gateway_ports == -1)
227 options->gateway_ports = 0;
228 if (options->max_startups == -1)
229 options->max_startups = 10;
230 if (options->max_startups_rate == -1)
231 options->max_startups_rate = 100; /* 100% */
232 if (options->max_startups_begin == -1)
233 options->max_startups_begin = options->max_startups;
234 if (options->max_authtries == -1)
235 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
236 if (options->use_dns == -1)
237 options->use_dns = 1;
238 if (options->client_alive_interval == -1)
239 options->client_alive_interval = 0;
240 if (options->client_alive_count_max == -1)
241 options->client_alive_count_max = 3;
242 if (options->authorized_keys_file2 == NULL) {
243 /* authorized_keys_file2 falls back to authorized_keys_file */
244 if (options->authorized_keys_file != NULL)
245 options->authorized_keys_file2 = options->authorized_keys_file;
247 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
249 if (options->authorized_keys_file == NULL)
250 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
251 if (options->permit_tun == -1)
252 options->permit_tun = SSH_TUNMODE_NO;
254 /* Turn privilege separation on by default */
255 if (use_privsep == -1)
259 if (use_privsep && options->compression == 1) {
260 error("This platform does not support both privilege "
261 "separation and compression");
262 error("Compression disabled");
263 options->compression = 0;
269 /* Keyword tokens. */
271 sBadOption, /* == unknown option */
272 /* Portable-specific options */
274 /* Standard Options */
275 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
276 sPermitRootLogin, sLogFacility, sLogLevel,
277 sRhostsRSAAuthentication, sRSAAuthentication,
278 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
279 sKerberosGetAFSToken,
280 sKerberosTgtPassing, sChallengeResponseAuthentication,
281 sPasswordAuthentication, sKbdInteractiveAuthentication,
282 sListenAddress, sAddressFamily,
283 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
284 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
285 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
286 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
287 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
288 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
289 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
290 sMaxStartups, sMaxAuthTries,
291 sBanner, sUseDNS, sHostbasedAuthentication,
292 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
293 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
294 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
295 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
296 sUsePrivilegeSeparation,
297 sDeprecated, sUnsupported
300 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
301 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
302 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
304 /* Textual representation of the tokens. */
307 ServerOpCodes opcode;
310 /* Portable-specific options */
312 { "usepam", sUsePAM, SSHCFG_GLOBAL },
314 { "usepam", sUnsupported, SSHCFG_GLOBAL },
316 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
317 /* Standard Options */
318 { "port", sPort, SSHCFG_GLOBAL },
319 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
320 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
321 { "pidfile", sPidFile, SSHCFG_GLOBAL },
322 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
323 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
324 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
325 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
326 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
327 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
328 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
329 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
330 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
331 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
332 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
333 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
334 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
336 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
337 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
338 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
340 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
342 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
345 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
346 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
347 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
348 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
350 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
351 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
353 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
354 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
356 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
357 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
359 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
360 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
361 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
362 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
363 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
364 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
365 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
366 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
367 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
368 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
369 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
370 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
371 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
372 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
373 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
374 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
375 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
376 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
377 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
378 { "compression", sCompression, SSHCFG_GLOBAL },
379 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
380 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
381 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
382 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
383 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
384 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
385 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
386 { "ciphers", sCiphers, SSHCFG_GLOBAL },
387 { "macs", sMacs, SSHCFG_GLOBAL },
388 { "protocol", sProtocol, SSHCFG_GLOBAL },
389 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
390 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
391 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
392 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
393 { "banner", sBanner, SSHCFG_ALL },
394 { "usedns", sUseDNS, SSHCFG_GLOBAL },
395 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
396 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
397 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
398 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
399 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
400 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
401 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
402 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
403 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
404 { "match", sMatch, SSHCFG_ALL },
405 { "permitopen", sPermitOpen, SSHCFG_ALL },
406 { "forcecommand", sForceCommand, SSHCFG_ALL },
407 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
408 { NULL, sBadOption, 0 }
412 * Returns the number of the token pointed to by cp or sBadOption.
416 parse_token(const char *cp, const char *filename,
417 int linenum, u_int *flags)
421 for (i = 0; keywords[i].name; i++)
422 if (strcasecmp(cp, keywords[i].name) == 0) {
423 *flags = keywords[i].flags;
424 return keywords[i].opcode;
427 error("%s: line %d: Bad configuration option: %s",
428 filename, linenum, cp);
433 add_listen_addr(ServerOptions *options, char *addr, u_short port)
437 if (options->num_ports == 0)
438 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
439 if (options->address_family == -1)
440 options->address_family = AF_UNSPEC;
442 for (i = 0; i < options->num_ports; i++)
443 add_one_listen_addr(options, addr, options->ports[i]);
445 add_one_listen_addr(options, addr, port);
449 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
451 struct addrinfo hints, *ai, *aitop;
452 char strport[NI_MAXSERV];
455 memset(&hints, 0, sizeof(hints));
456 hints.ai_family = options->address_family;
457 hints.ai_socktype = SOCK_STREAM;
458 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
459 snprintf(strport, sizeof strport, "%u", port);
460 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
461 fatal("bad addr or host: %s (%s)",
462 addr ? addr : "<NULL>",
463 ssh_gai_strerror(gaierr));
464 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
466 ai->ai_next = options->listen_addrs;
467 options->listen_addrs = aitop;
471 * The strategy for the Match blocks is that the config file is parsed twice.
473 * The first time is at startup. activep is initialized to 1 and the
474 * directives in the global context are processed and acted on. Hitting a
475 * Match directive unsets activep and the directives inside the block are
476 * checked for syntax only.
478 * The second time is after a connection has been established but before
479 * authentication. activep is initialized to 2 and global config directives
480 * are ignored since they have already been processed. If the criteria in a
481 * Match block is met, activep is set and the subsequent directives
482 * processed and actioned until EOF or another Match block unsets it. Any
483 * options set are copied into the main server config.
485 * Potential additions/improvements:
486 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
488 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
489 * Match Address 192.168.0.*
494 * AllowTcpForwarding yes
495 * GatewayPorts clientspecified
498 * - Add a PermittedChannelRequests directive
500 * PermittedChannelRequests session,forwarded-tcpip
504 match_cfg_line_group(const char *grps, int line, const char *user)
508 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
512 * Even if we do not have a user yet, we still need to check for
515 arg = cp = xstrdup(grps);
516 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
517 if (ngrps >= MAX_MATCH_GROUPS) {
518 error("line %d: too many groups in Match Group", line);
522 grplist[ngrps++] = p;
528 if ((pw = getpwnam(user)) == NULL) {
529 debug("Can't match group at line %d because user %.100s does "
530 "not exist", line, user);
531 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
532 debug("Can't Match group because user %.100s not in any group "
533 "at line %d", user, line);
534 } else if (ga_match(grplist, ngrps) != 1) {
535 debug("user %.100s does not match group %.100s at line %d",
538 debug("user %.100s matched group %.100s at line %d", user,
549 match_cfg_line(char **condition, int line, const char *user, const char *host,
553 char *arg, *attrib, *cp = *condition;
557 debug3("checking syntax for 'Match %s'", cp);
559 debug3("checking match for '%s' user %s host %s addr %s", cp,
560 user ? user : "(null)", host ? host : "(null)",
561 address ? address : "(null)");
563 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
564 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
565 error("Missing Match criteria for %s", attrib);
569 if (strcasecmp(attrib, "user") == 0) {
574 if (match_pattern_list(user, arg, len, 0) != 1)
577 debug("user %.100s matched 'User %.100s' at "
578 "line %d", user, arg, line);
579 } else if (strcasecmp(attrib, "group") == 0) {
580 switch (match_cfg_line_group(arg, line, user)) {
586 } else if (strcasecmp(attrib, "host") == 0) {
591 if (match_hostname(host, arg, len) != 1)
594 debug("connection from %.100s matched 'Host "
595 "%.100s' at line %d", host, arg, line);
596 } else if (strcasecmp(attrib, "address") == 0) {
601 if (match_hostname(address, arg, len) != 1)
604 debug("connection from %.100s matched 'Address "
605 "%.100s' at line %d", address, arg, line);
607 error("Unsupported Match attribute %s", attrib);
612 debug3("match %sfound", result ? "" : "not ");
617 #define WHITESPACE " \t\r\n"
620 process_server_config_line(ServerOptions *options, char *line,
621 const char *filename, int linenum, int *activep, const char *user,
622 const char *host, const char *address)
624 char *cp, **charptr, *arg, *p;
625 int cmdline = 0, *intptr, value, n;
626 SyslogFacility *log_facility_ptr;
627 LogLevel *log_level_ptr;
628 ServerOpCodes opcode;
634 if ((arg = strdelim(&cp)) == NULL)
636 /* Ignore leading whitespace */
639 if (!arg || !*arg || *arg == '#')
643 opcode = parse_token(arg, filename, linenum, &flags);
645 if (activep == NULL) { /* We are processing a command line directive */
649 if (*activep && opcode != sMatch)
650 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
651 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
653 fatal("%s line %d: Directive '%s' is not allowed "
654 "within a Match block", filename, linenum, arg);
655 } else { /* this is a directive we have already processed */
663 /* Portable-specific options */
665 intptr = &options->use_pam;
668 /* Standard Options */
672 /* ignore ports from configfile if cmdline specifies ports */
673 if (options->ports_from_cmdline)
675 if (options->listen_addrs != NULL)
676 fatal("%s line %d: ports must be specified before "
677 "ListenAddress.", filename, linenum);
678 if (options->num_ports >= MAX_PORTS)
679 fatal("%s line %d: too many ports.",
682 if (!arg || *arg == '\0')
683 fatal("%s line %d: missing port number.",
685 options->ports[options->num_ports++] = a2port(arg);
686 if (options->ports[options->num_ports-1] == 0)
687 fatal("%s line %d: Badly formatted port number.",
692 intptr = &options->server_key_bits;
695 if (!arg || *arg == '\0')
696 fatal("%s line %d: missing integer value.",
699 if (*activep && *intptr == -1)
703 case sLoginGraceTime:
704 intptr = &options->login_grace_time;
707 if (!arg || *arg == '\0')
708 fatal("%s line %d: missing time value.",
710 if ((value = convtime(arg)) == -1)
711 fatal("%s line %d: invalid time value.",
717 case sKeyRegenerationTime:
718 intptr = &options->key_regeneration_time;
723 if (arg == NULL || *arg == '\0')
724 fatal("%s line %d: missing address",
726 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
727 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
728 && strchr(p+1, ':') != NULL) {
729 add_listen_addr(options, arg, 0);
734 fatal("%s line %d: bad address:port usage",
736 p = cleanhostname(p);
739 else if ((port = a2port(arg)) == 0)
740 fatal("%s line %d: bad port number", filename, linenum);
742 add_listen_addr(options, p, port);
748 if (!arg || *arg == '\0')
749 fatal("%s line %d: missing address family.",
751 intptr = &options->address_family;
752 if (options->listen_addrs != NULL)
753 fatal("%s line %d: address family must be specified before "
754 "ListenAddress.", filename, linenum);
755 if (strcasecmp(arg, "inet") == 0)
757 else if (strcasecmp(arg, "inet6") == 0)
759 else if (strcasecmp(arg, "any") == 0)
762 fatal("%s line %d: unsupported address family \"%s\".",
763 filename, linenum, arg);
769 intptr = &options->num_host_key_files;
770 if (*intptr >= MAX_HOSTKEYS)
771 fatal("%s line %d: too many host keys specified (max %d).",
772 filename, linenum, MAX_HOSTKEYS);
773 charptr = &options->host_key_files[*intptr];
776 if (!arg || *arg == '\0')
777 fatal("%s line %d: missing file name.",
779 if (*activep && *charptr == NULL) {
780 *charptr = tilde_expand_filename(arg, getuid());
781 /* increase optional counter */
783 *intptr = *intptr + 1;
788 charptr = &options->pid_file;
791 case sPermitRootLogin:
792 intptr = &options->permit_root_login;
794 if (!arg || *arg == '\0')
795 fatal("%s line %d: missing yes/"
796 "without-password/forced-commands-only/no "
797 "argument.", filename, linenum);
798 value = 0; /* silence compiler */
799 if (strcmp(arg, "without-password") == 0)
800 value = PERMIT_NO_PASSWD;
801 else if (strcmp(arg, "forced-commands-only") == 0)
802 value = PERMIT_FORCED_ONLY;
803 else if (strcmp(arg, "yes") == 0)
805 else if (strcmp(arg, "no") == 0)
808 fatal("%s line %d: Bad yes/"
809 "without-password/forced-commands-only/no "
810 "argument: %s", filename, linenum, arg);
811 if (*activep && *intptr == -1)
816 intptr = &options->ignore_rhosts;
819 if (!arg || *arg == '\0')
820 fatal("%s line %d: missing yes/no argument.",
822 value = 0; /* silence compiler */
823 if (strcmp(arg, "yes") == 0)
825 else if (strcmp(arg, "no") == 0)
828 fatal("%s line %d: Bad yes/no argument: %s",
829 filename, linenum, arg);
830 if (*activep && *intptr == -1)
834 case sIgnoreUserKnownHosts:
835 intptr = &options->ignore_user_known_hosts;
838 case sRhostsRSAAuthentication:
839 intptr = &options->rhosts_rsa_authentication;
842 case sHostbasedAuthentication:
843 intptr = &options->hostbased_authentication;
846 case sHostbasedUsesNameFromPacketOnly:
847 intptr = &options->hostbased_uses_name_from_packet_only;
850 case sRSAAuthentication:
851 intptr = &options->rsa_authentication;
854 case sPubkeyAuthentication:
855 intptr = &options->pubkey_authentication;
858 case sKerberosAuthentication:
859 intptr = &options->kerberos_authentication;
862 case sKerberosOrLocalPasswd:
863 intptr = &options->kerberos_or_local_passwd;
866 case sKerberosTicketCleanup:
867 intptr = &options->kerberos_ticket_cleanup;
870 case sKerberosGetAFSToken:
871 intptr = &options->kerberos_get_afs_token;
874 case sGssAuthentication:
875 intptr = &options->gss_authentication;
878 case sGssCleanupCreds:
879 intptr = &options->gss_cleanup_creds;
882 case sPasswordAuthentication:
883 intptr = &options->password_authentication;
886 case sKbdInteractiveAuthentication:
887 intptr = &options->kbd_interactive_authentication;
890 case sChallengeResponseAuthentication:
891 intptr = &options->challenge_response_authentication;
895 intptr = &options->print_motd;
899 intptr = &options->print_lastlog;
903 intptr = &options->x11_forwarding;
906 case sX11DisplayOffset:
907 intptr = &options->x11_display_offset;
910 case sX11UseLocalhost:
911 intptr = &options->x11_use_localhost;
915 charptr = &options->xauth_location;
919 intptr = &options->strict_modes;
923 intptr = &options->tcp_keep_alive;
927 intptr = &options->permit_empty_passwd;
930 case sPermitUserEnvironment:
931 intptr = &options->permit_user_env;
935 intptr = &options->use_login;
939 intptr = &options->compression;
941 if (!arg || *arg == '\0')
942 fatal("%s line %d: missing yes/no/delayed "
943 "argument.", filename, linenum);
944 value = 0; /* silence compiler */
945 if (strcmp(arg, "delayed") == 0)
946 value = COMP_DELAYED;
947 else if (strcmp(arg, "yes") == 0)
949 else if (strcmp(arg, "no") == 0)
952 fatal("%s line %d: Bad yes/no/delayed "
953 "argument: %s", filename, linenum, arg);
959 intptr = &options->gateway_ports;
961 if (!arg || *arg == '\0')
962 fatal("%s line %d: missing yes/no/clientspecified "
963 "argument.", filename, linenum);
964 value = 0; /* silence compiler */
965 if (strcmp(arg, "clientspecified") == 0)
967 else if (strcmp(arg, "yes") == 0)
969 else if (strcmp(arg, "no") == 0)
972 fatal("%s line %d: Bad yes/no/clientspecified "
973 "argument: %s", filename, linenum, arg);
974 if (*activep && *intptr == -1)
979 intptr = &options->use_dns;
983 log_facility_ptr = &options->log_facility;
985 value = log_facility_number(arg);
986 if (value == SYSLOG_FACILITY_NOT_SET)
987 fatal("%.200s line %d: unsupported log facility '%s'",
988 filename, linenum, arg ? arg : "<NONE>");
989 if (*log_facility_ptr == -1)
990 *log_facility_ptr = (SyslogFacility) value;
994 log_level_ptr = &options->log_level;
996 value = log_level_number(arg);
997 if (value == SYSLOG_LEVEL_NOT_SET)
998 fatal("%.200s line %d: unsupported log level '%s'",
999 filename, linenum, arg ? arg : "<NONE>");
1000 if (*log_level_ptr == -1)
1001 *log_level_ptr = (LogLevel) value;
1004 case sAllowTcpForwarding:
1005 intptr = &options->allow_tcp_forwarding;
1008 case sUsePrivilegeSeparation:
1009 intptr = &use_privsep;
1013 while ((arg = strdelim(&cp)) && *arg != '\0') {
1014 if (options->num_allow_users >= MAX_ALLOW_USERS)
1015 fatal("%s line %d: too many allow users.",
1017 options->allow_users[options->num_allow_users++] =
1023 while ((arg = strdelim(&cp)) && *arg != '\0') {
1024 if (options->num_deny_users >= MAX_DENY_USERS)
1025 fatal("%s line %d: too many deny users.",
1027 options->deny_users[options->num_deny_users++] =
1033 while ((arg = strdelim(&cp)) && *arg != '\0') {
1034 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1035 fatal("%s line %d: too many allow groups.",
1037 options->allow_groups[options->num_allow_groups++] =
1043 while ((arg = strdelim(&cp)) && *arg != '\0') {
1044 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1045 fatal("%s line %d: too many deny groups.",
1047 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1052 arg = strdelim(&cp);
1053 if (!arg || *arg == '\0')
1054 fatal("%s line %d: Missing argument.", filename, linenum);
1055 if (!ciphers_valid(arg))
1056 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1057 filename, linenum, arg ? arg : "<NONE>");
1058 if (options->ciphers == NULL)
1059 options->ciphers = xstrdup(arg);
1063 arg = strdelim(&cp);
1064 if (!arg || *arg == '\0')
1065 fatal("%s line %d: Missing argument.", filename, linenum);
1066 if (!mac_valid(arg))
1067 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1068 filename, linenum, arg ? arg : "<NONE>");
1069 if (options->macs == NULL)
1070 options->macs = xstrdup(arg);
1074 intptr = &options->protocol;
1075 arg = strdelim(&cp);
1076 if (!arg || *arg == '\0')
1077 fatal("%s line %d: Missing argument.", filename, linenum);
1078 value = proto_spec(arg);
1079 if (value == SSH_PROTO_UNKNOWN)
1080 fatal("%s line %d: Bad protocol spec '%s'.",
1081 filename, linenum, arg ? arg : "<NONE>");
1082 if (*intptr == SSH_PROTO_UNKNOWN)
1087 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1088 fatal("%s line %d: too many subsystems defined.",
1091 arg = strdelim(&cp);
1092 if (!arg || *arg == '\0')
1093 fatal("%s line %d: Missing subsystem name.",
1096 arg = strdelim(&cp);
1099 for (i = 0; i < options->num_subsystems; i++)
1100 if (strcmp(arg, options->subsystem_name[i]) == 0)
1101 fatal("%s line %d: Subsystem '%s' already defined.",
1102 filename, linenum, arg);
1103 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1104 arg = strdelim(&cp);
1105 if (!arg || *arg == '\0')
1106 fatal("%s line %d: Missing subsystem command.",
1108 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1110 /* Collect arguments (separate to executable) */
1112 len = strlen(p) + 1;
1113 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1114 len += 1 + strlen(arg);
1115 p = xrealloc(p, 1, len);
1116 strlcat(p, " ", len);
1117 strlcat(p, arg, len);
1119 options->subsystem_args[options->num_subsystems] = p;
1120 options->num_subsystems++;
1124 arg = strdelim(&cp);
1125 if (!arg || *arg == '\0')
1126 fatal("%s line %d: Missing MaxStartups spec.",
1128 if ((n = sscanf(arg, "%d:%d:%d",
1129 &options->max_startups_begin,
1130 &options->max_startups_rate,
1131 &options->max_startups)) == 3) {
1132 if (options->max_startups_begin >
1133 options->max_startups ||
1134 options->max_startups_rate > 100 ||
1135 options->max_startups_rate < 1)
1136 fatal("%s line %d: Illegal MaxStartups spec.",
1139 fatal("%s line %d: Illegal MaxStartups spec.",
1142 options->max_startups = options->max_startups_begin;
1146 intptr = &options->max_authtries;
1150 charptr = &options->banner;
1151 goto parse_filename;
1154 * These options can contain %X options expanded at
1155 * connect time, so that you can specify paths like:
1157 * AuthorizedKeysFile /etc/ssh_keys/%u
1159 case sAuthorizedKeysFile:
1160 case sAuthorizedKeysFile2:
1161 charptr = (opcode == sAuthorizedKeysFile) ?
1162 &options->authorized_keys_file :
1163 &options->authorized_keys_file2;
1164 goto parse_filename;
1166 case sClientAliveInterval:
1167 intptr = &options->client_alive_interval;
1170 case sClientAliveCountMax:
1171 intptr = &options->client_alive_count_max;
1175 while ((arg = strdelim(&cp)) && *arg != '\0') {
1176 if (strchr(arg, '=') != NULL)
1177 fatal("%s line %d: Invalid environment name.",
1179 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1180 fatal("%s line %d: too many allow env.",
1184 options->accept_env[options->num_accept_env++] =
1190 intptr = &options->permit_tun;
1191 arg = strdelim(&cp);
1192 if (!arg || *arg == '\0')
1193 fatal("%s line %d: Missing yes/point-to-point/"
1194 "ethernet/no argument.", filename, linenum);
1195 value = 0; /* silence compiler */
1196 if (strcasecmp(arg, "ethernet") == 0)
1197 value = SSH_TUNMODE_ETHERNET;
1198 else if (strcasecmp(arg, "point-to-point") == 0)
1199 value = SSH_TUNMODE_POINTOPOINT;
1200 else if (strcasecmp(arg, "yes") == 0)
1201 value = SSH_TUNMODE_YES;
1202 else if (strcasecmp(arg, "no") == 0)
1203 value = SSH_TUNMODE_NO;
1205 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1206 "no argument: %s", filename, linenum, arg);
1213 fatal("Match directive not supported as a command-line "
1215 value = match_cfg_line(&cp, linenum, user, host, address);
1217 fatal("%s line %d: Bad Match condition", filename,
1223 arg = strdelim(&cp);
1224 if (!arg || *arg == '\0')
1225 fatal("%s line %d: missing PermitOpen specification",
1227 n = options->num_permitted_opens; /* modified later */
1228 if (strcmp(arg, "any") == 0) {
1229 if (*activep && n == -1) {
1230 channel_clear_adm_permitted_opens();
1231 options->num_permitted_opens = 0;
1235 if (*activep && n == -1)
1236 channel_clear_adm_permitted_opens();
1237 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1240 fatal("%s line %d: missing host in PermitOpen",
1242 p = cleanhostname(p);
1243 if (arg == NULL || (port = a2port(arg)) == 0)
1244 fatal("%s line %d: bad port number in "
1245 "PermitOpen", filename, linenum);
1246 if (*activep && n == -1)
1247 options->num_permitted_opens =
1248 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 sChrootDirectory:
1262 charptr = &options->chroot_directory;
1264 arg = strdelim(&cp);
1265 if (!arg || *arg == '\0')
1266 fatal("%s line %d: missing file name.",
1268 if (*activep && *charptr == NULL)
1269 *charptr = xstrdup(arg);
1273 logit("%s line %d: Deprecated option %s",
1274 filename, linenum, arg);
1276 arg = strdelim(&cp);
1280 logit("%s line %d: Unsupported option %s",
1281 filename, linenum, arg);
1283 arg = strdelim(&cp);
1287 fatal("%s line %d: Missing handler for opcode %s (%d)",
1288 filename, linenum, arg, opcode);
1290 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1291 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1292 filename, linenum, arg);
1296 /* Reads the server configuration file. */
1299 load_server_config(const char *filename, Buffer *conf)
1301 char line[1024], *cp;
1304 debug2("%s: filename %s", __func__, filename);
1305 if ((f = fopen(filename, "r")) == NULL) {
1310 while (fgets(line, sizeof(line), f)) {
1312 * Trim out comments and strip whitespace
1313 * NB - preserve newlines, they are needed to reproduce
1314 * line numbers later for error messages
1316 if ((cp = strchr(line, '#')) != NULL)
1317 memcpy(cp, "\n", 2);
1318 cp = line + strspn(line, " \t\r");
1320 buffer_append(conf, cp, strlen(cp));
1322 buffer_append(conf, "\0", 1);
1324 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1328 parse_server_match_config(ServerOptions *options, const char *user,
1329 const char *host, const char *address)
1333 initialize_server_options(&mo);
1334 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1335 copy_set_server_options(options, &mo, 0);
1339 #define M_CP_INTOPT(n) do {\
1343 #define M_CP_STROPT(n) do {\
1344 if (src->n != NULL) { \
1345 if (dst->n != NULL) \
1352 * Copy any supported values that are set.
1354 * If the preauth flag is set, we do not bother copying the the string or
1355 * array values that are not used pre-authentication, because any that we
1356 * do use must be explictly sent in mm_getpwnamallow().
1359 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1361 M_CP_INTOPT(password_authentication);
1362 M_CP_INTOPT(gss_authentication);
1363 M_CP_INTOPT(rsa_authentication);
1364 M_CP_INTOPT(pubkey_authentication);
1365 M_CP_INTOPT(kerberos_authentication);
1366 M_CP_INTOPT(hostbased_authentication);
1367 M_CP_INTOPT(kbd_interactive_authentication);
1368 M_CP_INTOPT(permit_root_login);
1370 M_CP_INTOPT(allow_tcp_forwarding);
1371 M_CP_INTOPT(gateway_ports);
1372 M_CP_INTOPT(x11_display_offset);
1373 M_CP_INTOPT(x11_forwarding);
1374 M_CP_INTOPT(x11_use_localhost);
1376 M_CP_STROPT(banner);
1379 M_CP_STROPT(adm_forced_command);
1380 M_CP_STROPT(chroot_directory);
1387 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1388 const char *user, const char *host, const char *address)
1390 int active, linenum, bad_options = 0;
1391 char *cp, *obuf, *cbuf;
1393 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1395 obuf = cbuf = xstrdup(buffer_ptr(conf));
1396 active = user ? 0 : 1;
1398 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1399 if (process_server_config_line(options, cp, filename,
1400 linenum++, &active, user, host, address) != 0)
1404 if (bad_options > 0)
1405 fatal("%s: terminating, %d bad configuration options",
1406 filename, bad_options);