1 /* $OpenBSD: servconf.c,v 1.164 2006/08/03 03:34:42 deraadt 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>
32 #include "pathnames.h"
41 static void add_listen_addr(ServerOptions *, char *, u_short);
42 static void add_one_listen_addr(ServerOptions *, char *, u_short);
44 /* Use of privilege separation or not */
45 extern int use_privsep;
48 /* Initializes the server options to their default values. */
51 initialize_server_options(ServerOptions *options)
53 memset(options, 0, sizeof(*options));
55 /* Portable-specific options */
56 options->use_pam = -1;
58 /* Standard Options */
59 options->num_ports = 0;
60 options->ports_from_cmdline = 0;
61 options->listen_addrs = NULL;
62 options->address_family = -1;
63 options->num_host_key_files = 0;
64 options->pid_file = NULL;
65 options->server_key_bits = -1;
66 options->login_grace_time = -1;
67 options->key_regeneration_time = -1;
68 options->permit_root_login = PERMIT_NOT_SET;
69 options->ignore_rhosts = -1;
70 options->ignore_user_known_hosts = -1;
71 options->print_motd = -1;
72 options->print_lastlog = -1;
73 options->x11_forwarding = -1;
74 options->x11_display_offset = -1;
75 options->x11_use_localhost = -1;
76 options->xauth_location = NULL;
77 options->strict_modes = -1;
78 options->tcp_keep_alive = -1;
79 options->log_facility = SYSLOG_FACILITY_NOT_SET;
80 options->log_level = SYSLOG_LEVEL_NOT_SET;
81 options->rhosts_rsa_authentication = -1;
82 options->hostbased_authentication = -1;
83 options->hostbased_uses_name_from_packet_only = -1;
84 options->rsa_authentication = -1;
85 options->pubkey_authentication = -1;
86 options->kerberos_authentication = -1;
87 options->kerberos_or_local_passwd = -1;
88 options->kerberos_ticket_cleanup = -1;
89 options->kerberos_get_afs_token = -1;
90 options->gss_authentication=-1;
91 options->gss_cleanup_creds = -1;
92 options->password_authentication = -1;
93 options->kbd_interactive_authentication = -1;
94 options->challenge_response_authentication = -1;
95 options->permit_empty_passwd = -1;
96 options->permit_user_env = -1;
97 options->use_login = -1;
98 options->compression = -1;
99 options->allow_tcp_forwarding = -1;
100 options->num_allow_users = 0;
101 options->num_deny_users = 0;
102 options->num_allow_groups = 0;
103 options->num_deny_groups = 0;
104 options->ciphers = NULL;
105 options->macs = NULL;
106 options->protocol = SSH_PROTO_UNKNOWN;
107 options->gateway_ports = -1;
108 options->num_subsystems = 0;
109 options->max_startups_begin = -1;
110 options->max_startups_rate = -1;
111 options->max_startups = -1;
112 options->max_authtries = -1;
113 options->banner = NULL;
114 options->use_dns = -1;
115 options->client_alive_interval = -1;
116 options->client_alive_count_max = -1;
117 options->authorized_keys_file = NULL;
118 options->authorized_keys_file2 = NULL;
119 options->num_accept_env = 0;
120 options->permit_tun = -1;
121 options->num_permitted_opens = -1;
122 options->adm_forced_command = NULL;
126 fill_default_server_options(ServerOptions *options)
128 /* Portable-specific options */
129 if (options->use_pam == -1)
130 options->use_pam = 0;
132 /* Standard Options */
133 if (options->protocol == SSH_PROTO_UNKNOWN)
134 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
135 if (options->num_host_key_files == 0) {
136 /* fill default hostkeys for protocols */
137 if (options->protocol & SSH_PROTO_1)
138 options->host_key_files[options->num_host_key_files++] =
140 if (options->protocol & SSH_PROTO_2) {
141 options->host_key_files[options->num_host_key_files++] =
142 _PATH_HOST_RSA_KEY_FILE;
143 options->host_key_files[options->num_host_key_files++] =
144 _PATH_HOST_DSA_KEY_FILE;
147 if (options->num_ports == 0)
148 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
149 if (options->listen_addrs == NULL)
150 add_listen_addr(options, NULL, 0);
151 if (options->pid_file == NULL)
152 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
153 if (options->server_key_bits == -1)
154 options->server_key_bits = 768;
155 if (options->login_grace_time == -1)
156 options->login_grace_time = 120;
157 if (options->key_regeneration_time == -1)
158 options->key_regeneration_time = 3600;
159 if (options->permit_root_login == PERMIT_NOT_SET)
160 options->permit_root_login = PERMIT_YES;
161 if (options->ignore_rhosts == -1)
162 options->ignore_rhosts = 1;
163 if (options->ignore_user_known_hosts == -1)
164 options->ignore_user_known_hosts = 0;
165 if (options->print_motd == -1)
166 options->print_motd = 1;
167 if (options->print_lastlog == -1)
168 options->print_lastlog = 1;
169 if (options->x11_forwarding == -1)
170 options->x11_forwarding = 0;
171 if (options->x11_display_offset == -1)
172 options->x11_display_offset = 10;
173 if (options->x11_use_localhost == -1)
174 options->x11_use_localhost = 1;
175 if (options->xauth_location == NULL)
176 options->xauth_location = _PATH_XAUTH;
177 if (options->strict_modes == -1)
178 options->strict_modes = 1;
179 if (options->tcp_keep_alive == -1)
180 options->tcp_keep_alive = 1;
181 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
182 options->log_facility = SYSLOG_FACILITY_AUTH;
183 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
184 options->log_level = SYSLOG_LEVEL_INFO;
185 if (options->rhosts_rsa_authentication == -1)
186 options->rhosts_rsa_authentication = 0;
187 if (options->hostbased_authentication == -1)
188 options->hostbased_authentication = 0;
189 if (options->hostbased_uses_name_from_packet_only == -1)
190 options->hostbased_uses_name_from_packet_only = 0;
191 if (options->rsa_authentication == -1)
192 options->rsa_authentication = 1;
193 if (options->pubkey_authentication == -1)
194 options->pubkey_authentication = 1;
195 if (options->kerberos_authentication == -1)
196 options->kerberos_authentication = 0;
197 if (options->kerberos_or_local_passwd == -1)
198 options->kerberos_or_local_passwd = 1;
199 if (options->kerberos_ticket_cleanup == -1)
200 options->kerberos_ticket_cleanup = 1;
201 if (options->kerberos_get_afs_token == -1)
202 options->kerberos_get_afs_token = 0;
203 if (options->gss_authentication == -1)
204 options->gss_authentication = 0;
205 if (options->gss_cleanup_creds == -1)
206 options->gss_cleanup_creds = 1;
207 if (options->password_authentication == -1)
208 options->password_authentication = 1;
209 if (options->kbd_interactive_authentication == -1)
210 options->kbd_interactive_authentication = 0;
211 if (options->challenge_response_authentication == -1)
212 options->challenge_response_authentication = 1;
213 if (options->permit_empty_passwd == -1)
214 options->permit_empty_passwd = 0;
215 if (options->permit_user_env == -1)
216 options->permit_user_env = 0;
217 if (options->use_login == -1)
218 options->use_login = 0;
219 if (options->compression == -1)
220 options->compression = COMP_DELAYED;
221 if (options->allow_tcp_forwarding == -1)
222 options->allow_tcp_forwarding = 1;
223 if (options->gateway_ports == -1)
224 options->gateway_ports = 0;
225 if (options->max_startups == -1)
226 options->max_startups = 10;
227 if (options->max_startups_rate == -1)
228 options->max_startups_rate = 100; /* 100% */
229 if (options->max_startups_begin == -1)
230 options->max_startups_begin = options->max_startups;
231 if (options->max_authtries == -1)
232 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
233 if (options->use_dns == -1)
234 options->use_dns = 1;
235 if (options->client_alive_interval == -1)
236 options->client_alive_interval = 0;
237 if (options->client_alive_count_max == -1)
238 options->client_alive_count_max = 3;
239 if (options->authorized_keys_file2 == NULL) {
240 /* authorized_keys_file2 falls back to authorized_keys_file */
241 if (options->authorized_keys_file != NULL)
242 options->authorized_keys_file2 = options->authorized_keys_file;
244 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
246 if (options->authorized_keys_file == NULL)
247 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
248 if (options->permit_tun == -1)
249 options->permit_tun = SSH_TUNMODE_NO;
251 /* Turn privilege separation on by default */
252 if (use_privsep == -1)
256 if (use_privsep && options->compression == 1) {
257 error("This platform does not support both privilege "
258 "separation and compression");
259 error("Compression disabled");
260 options->compression = 0;
266 /* Keyword tokens. */
268 sBadOption, /* == unknown option */
269 /* Portable-specific options */
271 /* Standard Options */
272 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
273 sPermitRootLogin, sLogFacility, sLogLevel,
274 sRhostsRSAAuthentication, sRSAAuthentication,
275 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
276 sKerberosGetAFSToken,
277 sKerberosTgtPassing, sChallengeResponseAuthentication,
278 sPasswordAuthentication, sKbdInteractiveAuthentication,
279 sListenAddress, sAddressFamily,
280 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
281 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
282 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
283 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
284 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
285 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
286 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
287 sMaxStartups, sMaxAuthTries,
288 sBanner, sUseDNS, sHostbasedAuthentication,
289 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
290 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
291 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
292 sMatch, sPermitOpen, sForceCommand,
293 sUsePrivilegeSeparation,
294 sDeprecated, sUnsupported
297 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
298 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
299 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
301 /* Textual representation of the tokens. */
304 ServerOpCodes opcode;
307 /* Portable-specific options */
309 { "usepam", sUsePAM, SSHCFG_GLOBAL },
311 { "usepam", sUnsupported, SSHCFG_GLOBAL },
313 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
314 /* Standard Options */
315 { "port", sPort, SSHCFG_GLOBAL },
316 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
317 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
318 { "pidfile", sPidFile, SSHCFG_GLOBAL },
319 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
320 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
321 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
322 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
323 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
324 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
325 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
326 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
327 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
328 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
329 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
330 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
331 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
333 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
334 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
335 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
337 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
339 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
342 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
343 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
344 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
345 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
347 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
348 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
350 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
351 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
353 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
354 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
356 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
357 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
358 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
359 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
360 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
361 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
362 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
363 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
364 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
365 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
366 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
367 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
368 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
369 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
370 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
371 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
372 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
373 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
374 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
375 { "compression", sCompression, SSHCFG_GLOBAL },
376 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
377 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
378 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
379 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
380 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
381 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
382 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
383 { "ciphers", sCiphers, SSHCFG_GLOBAL },
384 { "macs", sMacs, SSHCFG_GLOBAL },
385 { "protocol", sProtocol, SSHCFG_GLOBAL },
386 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
387 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
388 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
389 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
390 { "banner", sBanner, SSHCFG_GLOBAL },
391 { "usedns", sUseDNS, SSHCFG_GLOBAL },
392 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
393 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
394 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
395 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
396 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
397 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
398 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
399 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
400 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
401 { "match", sMatch, SSHCFG_ALL },
402 { "permitopen", sPermitOpen, SSHCFG_ALL },
403 { "forcecommand", sForceCommand, SSHCFG_ALL },
404 { NULL, sBadOption, 0 }
408 * Returns the number of the token pointed to by cp or sBadOption.
412 parse_token(const char *cp, const char *filename,
413 int linenum, u_int *flags)
417 for (i = 0; keywords[i].name; i++)
418 if (strcasecmp(cp, keywords[i].name) == 0) {
419 *flags = keywords[i].flags;
420 return keywords[i].opcode;
423 error("%s: line %d: Bad configuration option: %s",
424 filename, linenum, cp);
429 add_listen_addr(ServerOptions *options, char *addr, u_short port)
433 if (options->num_ports == 0)
434 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
435 if (options->address_family == -1)
436 options->address_family = AF_UNSPEC;
438 for (i = 0; i < options->num_ports; i++)
439 add_one_listen_addr(options, addr, options->ports[i]);
441 add_one_listen_addr(options, addr, port);
445 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
447 struct addrinfo hints, *ai, *aitop;
448 char strport[NI_MAXSERV];
451 memset(&hints, 0, sizeof(hints));
452 hints.ai_family = options->address_family;
453 hints.ai_socktype = SOCK_STREAM;
454 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
455 snprintf(strport, sizeof strport, "%u", port);
456 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
457 fatal("bad addr or host: %s (%s)",
458 addr ? addr : "<NULL>",
459 gai_strerror(gaierr));
460 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
462 ai->ai_next = options->listen_addrs;
463 options->listen_addrs = aitop;
467 * The strategy for the Match blocks is that the config file is parsed twice.
469 * The first time is at startup. activep is initialized to 1 and the
470 * directives in the global context are processed and acted on. Hitting a
471 * Match directive unsets activep and the directives inside the block are
472 * checked for syntax only.
474 * The second time is after a connection has been established but before
475 * authentication. activep is initialized to 2 and global config directives
476 * are ignored since they have already been processed. If the criteria in a
477 * Match block is met, activep is set and the subsequent directives
478 * processed and actioned until EOF or another Match block unsets it. Any
479 * options set are copied into the main server config.
481 * Potential additions/improvements:
482 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
484 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
485 * Match Address 192.168.0.*
490 * AllowTcpForwarding yes
491 * GatewayPorts clientspecified
494 * - Add a PermittedChannelRequests directive
496 * PermittedChannelRequests session,forwarded-tcpip
500 match_cfg_line(char **condition, int line, const char *user, const char *host,
504 char *arg, *attrib, *cp = *condition;
508 debug3("checking syntax for 'Match %s'", cp);
510 debug3("checking match for '%s' user %s host %s addr %s", cp,
511 user ? user : "(null)", host ? host : "(null)",
512 address ? address : "(null)");
514 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
515 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
516 error("Missing Match criteria for %s", attrib);
520 if (strcasecmp(attrib, "user") == 0) {
525 if (match_pattern_list(user, arg, len, 0) != 1)
528 debug("user %.100s matched 'User %.100s' at "
529 "line %d", user, arg, line);
530 } else if (strcasecmp(attrib, "host") == 0) {
535 if (match_hostname(host, arg, len) != 1)
538 debug("connection from %.100s matched 'Host "
539 "%.100s' at line %d", host, arg, line);
540 } else if (strcasecmp(attrib, "address") == 0) {
541 debug("address '%s' arg '%s'", address, arg);
546 if (match_hostname(address, arg, len) != 1)
549 debug("connection from %.100s matched 'Address "
550 "%.100s' at line %d", address, arg, line);
552 error("Unsupported Match attribute %s", attrib);
557 debug3("match %sfound", result ? "" : "not ");
562 #define WHITESPACE " \t\r\n"
565 process_server_config_line(ServerOptions *options, char *line,
566 const char *filename, int linenum, int *activep, const char *user,
567 const char *host, const char *address)
569 char *cp, **charptr, *arg, *p;
570 int cmdline = 0, *intptr, value, n;
571 ServerOpCodes opcode;
577 if ((arg = strdelim(&cp)) == NULL)
579 /* Ignore leading whitespace */
582 if (!arg || !*arg || *arg == '#')
586 opcode = parse_token(arg, filename, linenum, &flags);
588 if (activep == NULL) { /* We are processing a command line directive */
592 if (*activep && opcode != sMatch)
593 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
594 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
596 fatal("%s line %d: Directive '%s' is not allowed "
597 "within a Match block", filename, linenum, arg);
598 } else { /* this is a directive we have already processed */
606 /* Portable-specific options */
608 intptr = &options->use_pam;
611 /* Standard Options */
615 /* ignore ports from configfile if cmdline specifies ports */
616 if (options->ports_from_cmdline)
618 if (options->listen_addrs != NULL)
619 fatal("%s line %d: ports must be specified before "
620 "ListenAddress.", filename, linenum);
621 if (options->num_ports >= MAX_PORTS)
622 fatal("%s line %d: too many ports.",
625 if (!arg || *arg == '\0')
626 fatal("%s line %d: missing port number.",
628 options->ports[options->num_ports++] = a2port(arg);
629 if (options->ports[options->num_ports-1] == 0)
630 fatal("%s line %d: Badly formatted port number.",
635 intptr = &options->server_key_bits;
638 if (!arg || *arg == '\0')
639 fatal("%s line %d: missing integer value.",
642 if (*activep && *intptr == -1)
646 case sLoginGraceTime:
647 intptr = &options->login_grace_time;
650 if (!arg || *arg == '\0')
651 fatal("%s line %d: missing time value.",
653 if ((value = convtime(arg)) == -1)
654 fatal("%s line %d: invalid time value.",
660 case sKeyRegenerationTime:
661 intptr = &options->key_regeneration_time;
666 if (arg == NULL || *arg == '\0')
667 fatal("%s line %d: missing address",
669 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
670 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
671 && strchr(p+1, ':') != NULL) {
672 add_listen_addr(options, arg, 0);
677 fatal("%s line %d: bad address:port usage",
679 p = cleanhostname(p);
682 else if ((port = a2port(arg)) == 0)
683 fatal("%s line %d: bad port number", filename, linenum);
685 add_listen_addr(options, p, port);
691 if (!arg || *arg == '\0')
692 fatal("%s line %d: missing address family.",
694 intptr = &options->address_family;
695 if (options->listen_addrs != NULL)
696 fatal("%s line %d: address family must be specified before "
697 "ListenAddress.", filename, linenum);
698 if (strcasecmp(arg, "inet") == 0)
700 else if (strcasecmp(arg, "inet6") == 0)
702 else if (strcasecmp(arg, "any") == 0)
705 fatal("%s line %d: unsupported address family \"%s\".",
706 filename, linenum, arg);
712 intptr = &options->num_host_key_files;
713 if (*intptr >= MAX_HOSTKEYS)
714 fatal("%s line %d: too many host keys specified (max %d).",
715 filename, linenum, MAX_HOSTKEYS);
716 charptr = &options->host_key_files[*intptr];
719 if (!arg || *arg == '\0')
720 fatal("%s line %d: missing file name.",
722 if (*activep && *charptr == NULL) {
723 *charptr = tilde_expand_filename(arg, getuid());
724 /* increase optional counter */
726 *intptr = *intptr + 1;
731 charptr = &options->pid_file;
734 case sPermitRootLogin:
735 intptr = &options->permit_root_login;
737 if (!arg || *arg == '\0')
738 fatal("%s line %d: missing yes/"
739 "without-password/forced-commands-only/no "
740 "argument.", filename, linenum);
741 value = 0; /* silence compiler */
742 if (strcmp(arg, "without-password") == 0)
743 value = PERMIT_NO_PASSWD;
744 else if (strcmp(arg, "forced-commands-only") == 0)
745 value = PERMIT_FORCED_ONLY;
746 else if (strcmp(arg, "yes") == 0)
748 else if (strcmp(arg, "no") == 0)
751 fatal("%s line %d: Bad yes/"
752 "without-password/forced-commands-only/no "
753 "argument: %s", filename, linenum, arg);
759 intptr = &options->ignore_rhosts;
762 if (!arg || *arg == '\0')
763 fatal("%s line %d: missing yes/no argument.",
765 value = 0; /* silence compiler */
766 if (strcmp(arg, "yes") == 0)
768 else if (strcmp(arg, "no") == 0)
771 fatal("%s line %d: Bad yes/no argument: %s",
772 filename, linenum, arg);
773 if (*activep && *intptr == -1)
777 case sIgnoreUserKnownHosts:
778 intptr = &options->ignore_user_known_hosts;
781 case sRhostsRSAAuthentication:
782 intptr = &options->rhosts_rsa_authentication;
785 case sHostbasedAuthentication:
786 intptr = &options->hostbased_authentication;
789 case sHostbasedUsesNameFromPacketOnly:
790 intptr = &options->hostbased_uses_name_from_packet_only;
793 case sRSAAuthentication:
794 intptr = &options->rsa_authentication;
797 case sPubkeyAuthentication:
798 intptr = &options->pubkey_authentication;
801 case sKerberosAuthentication:
802 intptr = &options->kerberos_authentication;
805 case sKerberosOrLocalPasswd:
806 intptr = &options->kerberos_or_local_passwd;
809 case sKerberosTicketCleanup:
810 intptr = &options->kerberos_ticket_cleanup;
813 case sKerberosGetAFSToken:
814 intptr = &options->kerberos_get_afs_token;
817 case sGssAuthentication:
818 intptr = &options->gss_authentication;
821 case sGssCleanupCreds:
822 intptr = &options->gss_cleanup_creds;
825 case sPasswordAuthentication:
826 intptr = &options->password_authentication;
829 case sKbdInteractiveAuthentication:
830 intptr = &options->kbd_interactive_authentication;
833 case sChallengeResponseAuthentication:
834 intptr = &options->challenge_response_authentication;
838 intptr = &options->print_motd;
842 intptr = &options->print_lastlog;
846 intptr = &options->x11_forwarding;
849 case sX11DisplayOffset:
850 intptr = &options->x11_display_offset;
853 case sX11UseLocalhost:
854 intptr = &options->x11_use_localhost;
858 charptr = &options->xauth_location;
862 intptr = &options->strict_modes;
866 intptr = &options->tcp_keep_alive;
870 intptr = &options->permit_empty_passwd;
873 case sPermitUserEnvironment:
874 intptr = &options->permit_user_env;
878 intptr = &options->use_login;
882 intptr = &options->compression;
884 if (!arg || *arg == '\0')
885 fatal("%s line %d: missing yes/no/delayed "
886 "argument.", filename, linenum);
887 value = 0; /* silence compiler */
888 if (strcmp(arg, "delayed") == 0)
889 value = COMP_DELAYED;
890 else if (strcmp(arg, "yes") == 0)
892 else if (strcmp(arg, "no") == 0)
895 fatal("%s line %d: Bad yes/no/delayed "
896 "argument: %s", filename, linenum, arg);
902 intptr = &options->gateway_ports;
904 if (!arg || *arg == '\0')
905 fatal("%s line %d: missing yes/no/clientspecified "
906 "argument.", filename, linenum);
907 value = 0; /* silence compiler */
908 if (strcmp(arg, "clientspecified") == 0)
910 else if (strcmp(arg, "yes") == 0)
912 else if (strcmp(arg, "no") == 0)
915 fatal("%s line %d: Bad yes/no/clientspecified "
916 "argument: %s", filename, linenum, arg);
922 intptr = &options->use_dns;
926 intptr = (int *) &options->log_facility;
928 value = log_facility_number(arg);
929 if (value == SYSLOG_FACILITY_NOT_SET)
930 fatal("%.200s line %d: unsupported log facility '%s'",
931 filename, linenum, arg ? arg : "<NONE>");
933 *intptr = (SyslogFacility) value;
937 intptr = (int *) &options->log_level;
939 value = log_level_number(arg);
940 if (value == SYSLOG_LEVEL_NOT_SET)
941 fatal("%.200s line %d: unsupported log level '%s'",
942 filename, linenum, arg ? arg : "<NONE>");
944 *intptr = (LogLevel) value;
947 case sAllowTcpForwarding:
948 intptr = &options->allow_tcp_forwarding;
951 case sUsePrivilegeSeparation:
952 intptr = &use_privsep;
956 while ((arg = strdelim(&cp)) && *arg != '\0') {
957 if (options->num_allow_users >= MAX_ALLOW_USERS)
958 fatal("%s line %d: too many allow users.",
960 options->allow_users[options->num_allow_users++] =
966 while ((arg = strdelim(&cp)) && *arg != '\0') {
967 if (options->num_deny_users >= MAX_DENY_USERS)
968 fatal("%s line %d: too many deny users.",
970 options->deny_users[options->num_deny_users++] =
976 while ((arg = strdelim(&cp)) && *arg != '\0') {
977 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
978 fatal("%s line %d: too many allow groups.",
980 options->allow_groups[options->num_allow_groups++] =
986 while ((arg = strdelim(&cp)) && *arg != '\0') {
987 if (options->num_deny_groups >= MAX_DENY_GROUPS)
988 fatal("%s line %d: too many deny groups.",
990 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
996 if (!arg || *arg == '\0')
997 fatal("%s line %d: Missing argument.", filename, linenum);
998 if (!ciphers_valid(arg))
999 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1000 filename, linenum, arg ? arg : "<NONE>");
1001 if (options->ciphers == NULL)
1002 options->ciphers = xstrdup(arg);
1006 arg = strdelim(&cp);
1007 if (!arg || *arg == '\0')
1008 fatal("%s line %d: Missing argument.", filename, linenum);
1009 if (!mac_valid(arg))
1010 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1011 filename, linenum, arg ? arg : "<NONE>");
1012 if (options->macs == NULL)
1013 options->macs = xstrdup(arg);
1017 intptr = &options->protocol;
1018 arg = strdelim(&cp);
1019 if (!arg || *arg == '\0')
1020 fatal("%s line %d: Missing argument.", filename, linenum);
1021 value = proto_spec(arg);
1022 if (value == SSH_PROTO_UNKNOWN)
1023 fatal("%s line %d: Bad protocol spec '%s'.",
1024 filename, linenum, arg ? arg : "<NONE>");
1025 if (*intptr == SSH_PROTO_UNKNOWN)
1030 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1031 fatal("%s line %d: too many subsystems defined.",
1034 arg = strdelim(&cp);
1035 if (!arg || *arg == '\0')
1036 fatal("%s line %d: Missing subsystem name.",
1039 arg = strdelim(&cp);
1042 for (i = 0; i < options->num_subsystems; i++)
1043 if (strcmp(arg, options->subsystem_name[i]) == 0)
1044 fatal("%s line %d: Subsystem '%s' already defined.",
1045 filename, linenum, arg);
1046 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1047 arg = strdelim(&cp);
1048 if (!arg || *arg == '\0')
1049 fatal("%s line %d: Missing subsystem command.",
1051 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1053 /* Collect arguments (separate to executable) */
1055 len = strlen(p) + 1;
1056 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1057 len += 1 + strlen(arg);
1058 p = xrealloc(p, 1, len);
1059 strlcat(p, " ", len);
1060 strlcat(p, arg, len);
1062 options->subsystem_args[options->num_subsystems] = p;
1063 options->num_subsystems++;
1067 arg = strdelim(&cp);
1068 if (!arg || *arg == '\0')
1069 fatal("%s line %d: Missing MaxStartups spec.",
1071 if ((n = sscanf(arg, "%d:%d:%d",
1072 &options->max_startups_begin,
1073 &options->max_startups_rate,
1074 &options->max_startups)) == 3) {
1075 if (options->max_startups_begin >
1076 options->max_startups ||
1077 options->max_startups_rate > 100 ||
1078 options->max_startups_rate < 1)
1079 fatal("%s line %d: Illegal MaxStartups spec.",
1082 fatal("%s line %d: Illegal MaxStartups spec.",
1085 options->max_startups = options->max_startups_begin;
1089 intptr = &options->max_authtries;
1093 charptr = &options->banner;
1094 goto parse_filename;
1096 * These options can contain %X options expanded at
1097 * connect time, so that you can specify paths like:
1099 * AuthorizedKeysFile /etc/ssh_keys/%u
1101 case sAuthorizedKeysFile:
1102 case sAuthorizedKeysFile2:
1103 charptr = (opcode == sAuthorizedKeysFile) ?
1104 &options->authorized_keys_file :
1105 &options->authorized_keys_file2;
1106 goto parse_filename;
1108 case sClientAliveInterval:
1109 intptr = &options->client_alive_interval;
1112 case sClientAliveCountMax:
1113 intptr = &options->client_alive_count_max;
1117 while ((arg = strdelim(&cp)) && *arg != '\0') {
1118 if (strchr(arg, '=') != NULL)
1119 fatal("%s line %d: Invalid environment name.",
1121 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1122 fatal("%s line %d: too many allow env.",
1126 options->accept_env[options->num_accept_env++] =
1132 intptr = &options->permit_tun;
1133 arg = strdelim(&cp);
1134 if (!arg || *arg == '\0')
1135 fatal("%s line %d: Missing yes/point-to-point/"
1136 "ethernet/no argument.", filename, linenum);
1137 value = 0; /* silence compiler */
1138 if (strcasecmp(arg, "ethernet") == 0)
1139 value = SSH_TUNMODE_ETHERNET;
1140 else if (strcasecmp(arg, "point-to-point") == 0)
1141 value = SSH_TUNMODE_POINTOPOINT;
1142 else if (strcasecmp(arg, "yes") == 0)
1143 value = SSH_TUNMODE_YES;
1144 else if (strcasecmp(arg, "no") == 0)
1145 value = SSH_TUNMODE_NO;
1147 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1148 "no argument: %s", filename, linenum, arg);
1155 fatal("Match directive not supported as a command-line "
1157 value = match_cfg_line(&cp, linenum, user, host, address);
1159 fatal("%s line %d: Bad Match condition", filename,
1165 arg = strdelim(&cp);
1166 if (!arg || *arg == '\0')
1167 fatal("%s line %d: missing PermitOpen specification",
1169 if (strcmp(arg, "any") == 0) {
1171 channel_clear_adm_permitted_opens();
1172 options->num_permitted_opens = 0;
1176 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1179 fatal("%s line %d: missing host in PermitOpen",
1181 p = cleanhostname(p);
1182 if (arg == NULL || (port = a2port(arg)) == 0)
1183 fatal("%s line %d: bad port number in "
1184 "PermitOpen", filename, linenum);
1185 if (*activep && options->num_permitted_opens == -1) {
1186 channel_clear_adm_permitted_opens();
1187 options->num_permitted_opens =
1188 channel_add_adm_permitted_opens(p, port);
1195 fatal("%.200s line %d: Missing argument.", filename,
1197 len = strspn(cp, WHITESPACE);
1198 if (*activep && options->adm_forced_command == NULL)
1199 options->adm_forced_command = xstrdup(cp + len);
1203 logit("%s line %d: Deprecated option %s",
1204 filename, linenum, arg);
1206 arg = strdelim(&cp);
1210 logit("%s line %d: Unsupported option %s",
1211 filename, linenum, arg);
1213 arg = strdelim(&cp);
1217 fatal("%s line %d: Missing handler for opcode %s (%d)",
1218 filename, linenum, arg, opcode);
1220 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1221 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1222 filename, linenum, arg);
1226 /* Reads the server configuration file. */
1229 load_server_config(const char *filename, Buffer *conf)
1231 char line[1024], *cp;
1234 debug2("%s: filename %s", __func__, filename);
1235 if ((f = fopen(filename, "r")) == NULL) {
1240 while (fgets(line, sizeof(line), f)) {
1242 * Trim out comments and strip whitespace
1243 * NB - preserve newlines, they are needed to reproduce
1244 * line numbers later for error messages
1246 if ((cp = strchr(line, '#')) != NULL)
1247 memcpy(cp, "\n", 2);
1248 cp = line + strspn(line, " \t\r");
1250 buffer_append(conf, cp, strlen(cp));
1252 buffer_append(conf, "\0", 1);
1254 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1258 parse_server_match_config(ServerOptions *options, const char *user,
1259 const char *host, const char *address)
1263 initialize_server_options(&mo);
1264 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1265 copy_set_server_options(options, &mo);
1268 /* Copy any (supported) values that are set */
1270 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1272 if (src->allow_tcp_forwarding != -1)
1273 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1274 if (src->gateway_ports != -1)
1275 dst->gateway_ports = src->gateway_ports;
1276 if (src->adm_forced_command != NULL) {
1277 if (dst->adm_forced_command != NULL)
1278 xfree(dst->adm_forced_command);
1279 dst->adm_forced_command = src->adm_forced_command;
1281 if (src->x11_display_offset != -1)
1282 dst->x11_display_offset = src->x11_display_offset;
1283 if (src->x11_forwarding != -1)
1284 dst->x11_forwarding = src->x11_forwarding;
1285 if (src->x11_use_localhost != -1)
1286 dst->x11_use_localhost = src->x11_use_localhost;
1290 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1291 const char *user, const char *host, const char *address)
1293 int active, linenum, bad_options = 0;
1294 char *cp, *obuf, *cbuf;
1296 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1298 obuf = cbuf = xstrdup(buffer_ptr(conf));
1299 active = user ? 0 : 1;
1301 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1302 if (process_server_config_line(options, cp, filename,
1303 linenum++, &active, user, host, address) != 0)
1307 if (bad_options > 0)
1308 fatal("%s: terminating, %d bad configuration options",
1309 filename, bad_options);