1 /* $OpenBSD: servconf.c,v 1.153 2006/07/12 11:34:58 dtucker Exp $ */
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is
9 * incompatible with the protocol description in the RFC file, it must be
10 * called by a name other than "ssh" or "Secure Shell".
15 #include <sys/types.h>
16 #include <sys/socket.h>
23 #include "pathnames.h"
30 static void add_listen_addr(ServerOptions *, char *, u_short);
31 static void add_one_listen_addr(ServerOptions *, char *, u_short);
33 /* Use of privilege separation or not */
34 extern int use_privsep;
37 /* Initializes the server options to their default values. */
40 initialize_server_options(ServerOptions *options)
42 memset(options, 0, sizeof(*options));
44 /* Portable-specific options */
45 options->use_pam = -1;
47 /* Standard Options */
48 options->num_ports = 0;
49 options->ports_from_cmdline = 0;
50 options->listen_addrs = NULL;
51 options->address_family = -1;
52 options->num_host_key_files = 0;
53 options->pid_file = NULL;
54 options->server_key_bits = -1;
55 options->login_grace_time = -1;
56 options->key_regeneration_time = -1;
57 options->permit_root_login = PERMIT_NOT_SET;
58 options->ignore_rhosts = -1;
59 options->ignore_user_known_hosts = -1;
60 options->print_motd = -1;
61 options->print_lastlog = -1;
62 options->x11_forwarding = -1;
63 options->x11_display_offset = -1;
64 options->x11_use_localhost = -1;
65 options->xauth_location = NULL;
66 options->strict_modes = -1;
67 options->tcp_keep_alive = -1;
68 options->log_facility = SYSLOG_FACILITY_NOT_SET;
69 options->log_level = SYSLOG_LEVEL_NOT_SET;
70 options->rhosts_rsa_authentication = -1;
71 options->hostbased_authentication = -1;
72 options->hostbased_uses_name_from_packet_only = -1;
73 options->rsa_authentication = -1;
74 options->pubkey_authentication = -1;
75 options->kerberos_authentication = -1;
76 options->kerberos_or_local_passwd = -1;
77 options->kerberos_ticket_cleanup = -1;
78 options->kerberos_get_afs_token = -1;
79 options->gss_authentication=-1;
80 options->gss_cleanup_creds = -1;
81 options->password_authentication = -1;
82 options->kbd_interactive_authentication = -1;
83 options->challenge_response_authentication = -1;
84 options->permit_empty_passwd = -1;
85 options->permit_user_env = -1;
86 options->use_login = -1;
87 options->compression = -1;
88 options->allow_tcp_forwarding = -1;
89 options->num_allow_users = 0;
90 options->num_deny_users = 0;
91 options->num_allow_groups = 0;
92 options->num_deny_groups = 0;
93 options->ciphers = NULL;
95 options->protocol = SSH_PROTO_UNKNOWN;
96 options->gateway_ports = -1;
97 options->num_subsystems = 0;
98 options->max_startups_begin = -1;
99 options->max_startups_rate = -1;
100 options->max_startups = -1;
101 options->max_authtries = -1;
102 options->banner = NULL;
103 options->use_dns = -1;
104 options->client_alive_interval = -1;
105 options->client_alive_count_max = -1;
106 options->authorized_keys_file = NULL;
107 options->authorized_keys_file2 = NULL;
108 options->num_accept_env = 0;
109 options->permit_tun = -1;
113 fill_default_server_options(ServerOptions *options)
115 /* Portable-specific options */
116 if (options->use_pam == -1)
117 options->use_pam = 0;
119 /* Standard Options */
120 if (options->protocol == SSH_PROTO_UNKNOWN)
121 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
122 if (options->num_host_key_files == 0) {
123 /* fill default hostkeys for protocols */
124 if (options->protocol & SSH_PROTO_1)
125 options->host_key_files[options->num_host_key_files++] =
127 if (options->protocol & SSH_PROTO_2) {
128 options->host_key_files[options->num_host_key_files++] =
129 _PATH_HOST_RSA_KEY_FILE;
130 options->host_key_files[options->num_host_key_files++] =
131 _PATH_HOST_DSA_KEY_FILE;
134 if (options->num_ports == 0)
135 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
136 if (options->listen_addrs == NULL)
137 add_listen_addr(options, NULL, 0);
138 if (options->pid_file == NULL)
139 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
140 if (options->server_key_bits == -1)
141 options->server_key_bits = 768;
142 if (options->login_grace_time == -1)
143 options->login_grace_time = 120;
144 if (options->key_regeneration_time == -1)
145 options->key_regeneration_time = 3600;
146 if (options->permit_root_login == PERMIT_NOT_SET)
147 options->permit_root_login = PERMIT_YES;
148 if (options->ignore_rhosts == -1)
149 options->ignore_rhosts = 1;
150 if (options->ignore_user_known_hosts == -1)
151 options->ignore_user_known_hosts = 0;
152 if (options->print_motd == -1)
153 options->print_motd = 1;
154 if (options->print_lastlog == -1)
155 options->print_lastlog = 1;
156 if (options->x11_forwarding == -1)
157 options->x11_forwarding = 0;
158 if (options->x11_display_offset == -1)
159 options->x11_display_offset = 10;
160 if (options->x11_use_localhost == -1)
161 options->x11_use_localhost = 1;
162 if (options->xauth_location == NULL)
163 options->xauth_location = _PATH_XAUTH;
164 if (options->strict_modes == -1)
165 options->strict_modes = 1;
166 if (options->tcp_keep_alive == -1)
167 options->tcp_keep_alive = 1;
168 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
169 options->log_facility = SYSLOG_FACILITY_AUTH;
170 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
171 options->log_level = SYSLOG_LEVEL_INFO;
172 if (options->rhosts_rsa_authentication == -1)
173 options->rhosts_rsa_authentication = 0;
174 if (options->hostbased_authentication == -1)
175 options->hostbased_authentication = 0;
176 if (options->hostbased_uses_name_from_packet_only == -1)
177 options->hostbased_uses_name_from_packet_only = 0;
178 if (options->rsa_authentication == -1)
179 options->rsa_authentication = 1;
180 if (options->pubkey_authentication == -1)
181 options->pubkey_authentication = 1;
182 if (options->kerberos_authentication == -1)
183 options->kerberos_authentication = 0;
184 if (options->kerberos_or_local_passwd == -1)
185 options->kerberos_or_local_passwd = 1;
186 if (options->kerberos_ticket_cleanup == -1)
187 options->kerberos_ticket_cleanup = 1;
188 if (options->kerberos_get_afs_token == -1)
189 options->kerberos_get_afs_token = 0;
190 if (options->gss_authentication == -1)
191 options->gss_authentication = 0;
192 if (options->gss_cleanup_creds == -1)
193 options->gss_cleanup_creds = 1;
194 if (options->password_authentication == -1)
195 options->password_authentication = 1;
196 if (options->kbd_interactive_authentication == -1)
197 options->kbd_interactive_authentication = 0;
198 if (options->challenge_response_authentication == -1)
199 options->challenge_response_authentication = 1;
200 if (options->permit_empty_passwd == -1)
201 options->permit_empty_passwd = 0;
202 if (options->permit_user_env == -1)
203 options->permit_user_env = 0;
204 if (options->use_login == -1)
205 options->use_login = 0;
206 if (options->compression == -1)
207 options->compression = COMP_DELAYED;
208 if (options->allow_tcp_forwarding == -1)
209 options->allow_tcp_forwarding = 1;
210 if (options->gateway_ports == -1)
211 options->gateway_ports = 0;
212 if (options->max_startups == -1)
213 options->max_startups = 10;
214 if (options->max_startups_rate == -1)
215 options->max_startups_rate = 100; /* 100% */
216 if (options->max_startups_begin == -1)
217 options->max_startups_begin = options->max_startups;
218 if (options->max_authtries == -1)
219 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
220 if (options->use_dns == -1)
221 options->use_dns = 1;
222 if (options->client_alive_interval == -1)
223 options->client_alive_interval = 0;
224 if (options->client_alive_count_max == -1)
225 options->client_alive_count_max = 3;
226 if (options->authorized_keys_file2 == NULL) {
227 /* authorized_keys_file2 falls back to authorized_keys_file */
228 if (options->authorized_keys_file != NULL)
229 options->authorized_keys_file2 = options->authorized_keys_file;
231 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
233 if (options->authorized_keys_file == NULL)
234 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
235 if (options->permit_tun == -1)
236 options->permit_tun = SSH_TUNMODE_NO;
238 /* Turn privilege separation on by default */
239 if (use_privsep == -1)
243 if (use_privsep && options->compression == 1) {
244 error("This platform does not support both privilege "
245 "separation and compression");
246 error("Compression disabled");
247 options->compression = 0;
253 /* Keyword tokens. */
255 sBadOption, /* == unknown option */
256 /* Portable-specific options */
258 /* Standard Options */
259 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
260 sPermitRootLogin, sLogFacility, sLogLevel,
261 sRhostsRSAAuthentication, sRSAAuthentication,
262 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
263 sKerberosGetAFSToken,
264 sKerberosTgtPassing, sChallengeResponseAuthentication,
265 sPasswordAuthentication, sKbdInteractiveAuthentication,
266 sListenAddress, sAddressFamily,
267 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
268 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
269 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
270 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
271 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
272 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
273 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
274 sMaxStartups, sMaxAuthTries,
275 sBanner, sUseDNS, sHostbasedAuthentication,
276 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
277 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
278 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
280 sUsePrivilegeSeparation,
281 sDeprecated, sUnsupported
284 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
285 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
286 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
288 /* Textual representation of the tokens. */
291 ServerOpCodes opcode;
294 /* Portable-specific options */
296 { "usepam", sUsePAM, SSHCFG_GLOBAL },
298 { "usepam", sUnsupported, SSHCFG_GLOBAL },
300 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
301 /* Standard Options */
302 { "port", sPort, SSHCFG_GLOBAL },
303 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
304 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
305 { "pidfile", sPidFile, SSHCFG_GLOBAL },
306 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
307 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
308 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
309 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
310 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
311 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
312 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
313 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
314 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
315 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
316 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
317 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
318 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
320 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
321 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
322 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
324 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
326 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
329 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
330 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
331 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
332 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
334 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
335 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
337 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
338 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
340 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
341 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
343 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
344 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
345 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
346 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
347 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
348 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
349 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
350 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
351 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
352 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
353 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
354 { "x11forwarding", sX11Forwarding, SSHCFG_GLOBAL },
355 { "x11displayoffset", sX11DisplayOffset, SSHCFG_GLOBAL },
356 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_GLOBAL },
357 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
358 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
359 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
360 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
361 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
362 { "compression", sCompression, SSHCFG_GLOBAL },
363 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
364 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
365 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
366 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
367 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
368 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
369 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
370 { "ciphers", sCiphers, SSHCFG_GLOBAL },
371 { "macs", sMacs, SSHCFG_GLOBAL },
372 { "protocol", sProtocol, SSHCFG_GLOBAL },
373 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
374 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
375 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
376 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
377 { "banner", sBanner, SSHCFG_GLOBAL },
378 { "usedns", sUseDNS, SSHCFG_GLOBAL },
379 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
380 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
381 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
382 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
383 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
384 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
385 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
386 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
387 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
388 { NULL, sBadOption, 0 }
392 * Returns the number of the token pointed to by cp or sBadOption.
396 parse_token(const char *cp, const char *filename,
397 int linenum, u_int *flags)
401 for (i = 0; keywords[i].name; i++)
402 if (strcasecmp(cp, keywords[i].name) == 0) {
403 *flags = keywords[i].flags;
404 return keywords[i].opcode;
407 error("%s: line %d: Bad configuration option: %s",
408 filename, linenum, cp);
413 add_listen_addr(ServerOptions *options, char *addr, u_short port)
417 if (options->num_ports == 0)
418 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
419 if (options->address_family == -1)
420 options->address_family = AF_UNSPEC;
422 for (i = 0; i < options->num_ports; i++)
423 add_one_listen_addr(options, addr, options->ports[i]);
425 add_one_listen_addr(options, addr, port);
429 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
431 struct addrinfo hints, *ai, *aitop;
432 char strport[NI_MAXSERV];
435 memset(&hints, 0, sizeof(hints));
436 hints.ai_family = options->address_family;
437 hints.ai_socktype = SOCK_STREAM;
438 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
439 snprintf(strport, sizeof strport, "%u", port);
440 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
441 fatal("bad addr or host: %s (%s)",
442 addr ? addr : "<NULL>",
443 gai_strerror(gaierr));
444 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
446 ai->ai_next = options->listen_addrs;
447 options->listen_addrs = aitop;
451 * The strategy for the Match blocks is that the config file is parsed twice.
453 * The first time is at startup. activep is initialized to 1 and the
454 * directives in the global context are processed and acted on. Hitting a
455 * Match directive unsets activep and the directives inside the block are
456 * checked for syntax only.
458 * The second time is after a connection has been established but before
459 * authentication. activep is initialized to 2 and global config directives
460 * are ignored since they have already been processed. If the criteria in a
461 * Match block is met, activep is set and the subsequent directives
462 * processed and actioned until EOF or another Match block unsets it. Any
463 * options set are copied into the main server config.
465 * Potential additions/improvements:
466 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
468 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
469 * Match Address 192.168.0.*
474 * AllowTcpForwarding yes
475 * GatewayPorts clientspecified
478 * - Add a PermittedChannelRequests directive
480 * PermittedChannelRequests session,forwarded-tcpip
484 match_cfg_line(char **condition, int line, const char *user, const char *host,
488 char *arg, *attrib, *cp = *condition;
492 debug3("checking syntax for 'Match %s'", cp);
494 debug3("checking match for '%s' user %s host %s addr %s", cp,
495 user ? user : "(null)", host ? host : "(null)",
496 address ? address : "(null)");
498 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
499 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
500 error("Missing Match criteria for %s", attrib);
504 if (strcasecmp(attrib, "user") == 0) {
509 if (match_pattern_list(user, arg, len, 0) != 1)
512 debug("user %.100s matched 'User %.100s' at "
513 "line %d", user, arg, line);
514 } else if (strcasecmp(attrib, "host") == 0) {
519 if (match_hostname(host, arg, len) != 1)
522 debug("connection from %.100s matched 'Host "
523 "%.100s' at line %d", host, arg, line);
524 } else if (strcasecmp(attrib, "address") == 0) {
525 debug("address '%s' arg '%s'", address, arg);
530 if (match_hostname(address, arg, len) != 1)
533 debug("connection from %.100s matched 'Address "
534 "%.100s' at line %d", address, arg, line);
536 error("Unsupported Match attribute %s", attrib);
541 debug3("match %sfound", result ? "" : "not ");
547 process_server_config_line(ServerOptions *options, char *line,
548 const char *filename, int linenum, int *activep, const char *user,
549 const char *host, const char *address)
551 char *cp, **charptr, *arg, *p;
552 int cmdline = 0, *intptr, value, n;
553 ServerOpCodes opcode;
559 if ((arg = strdelim(&cp)) == NULL)
561 /* Ignore leading whitespace */
564 if (!arg || !*arg || *arg == '#')
568 opcode = parse_token(arg, filename, linenum, &flags);
570 if (activep == NULL) { /* We are processing a command line directive */
574 if (*activep && opcode != sMatch)
575 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
576 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
578 fatal("%s line %d: Directive '%s' is not allowed "
579 "within a Match block", filename, linenum, arg);
580 } else { /* this is a directive we have already processed */
588 /* Portable-specific options */
590 intptr = &options->use_pam;
593 /* Standard Options */
597 /* ignore ports from configfile if cmdline specifies ports */
598 if (options->ports_from_cmdline)
600 if (options->listen_addrs != NULL)
601 fatal("%s line %d: ports must be specified before "
602 "ListenAddress.", filename, linenum);
603 if (options->num_ports >= MAX_PORTS)
604 fatal("%s line %d: too many ports.",
607 if (!arg || *arg == '\0')
608 fatal("%s line %d: missing port number.",
610 options->ports[options->num_ports++] = a2port(arg);
611 if (options->ports[options->num_ports-1] == 0)
612 fatal("%s line %d: Badly formatted port number.",
617 intptr = &options->server_key_bits;
620 if (!arg || *arg == '\0')
621 fatal("%s line %d: missing integer value.",
624 if (*activep && *intptr == -1)
628 case sLoginGraceTime:
629 intptr = &options->login_grace_time;
632 if (!arg || *arg == '\0')
633 fatal("%s line %d: missing time value.",
635 if ((value = convtime(arg)) == -1)
636 fatal("%s line %d: invalid time value.",
642 case sKeyRegenerationTime:
643 intptr = &options->key_regeneration_time;
648 if (arg == NULL || *arg == '\0')
649 fatal("%s line %d: missing address",
651 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
652 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
653 && strchr(p+1, ':') != NULL) {
654 add_listen_addr(options, arg, 0);
659 fatal("%s line %d: bad address:port usage",
661 p = cleanhostname(p);
664 else if ((port = a2port(arg)) == 0)
665 fatal("%s line %d: bad port number", filename, linenum);
667 add_listen_addr(options, p, port);
673 if (!arg || *arg == '\0')
674 fatal("%s line %d: missing address family.",
676 intptr = &options->address_family;
677 if (options->listen_addrs != NULL)
678 fatal("%s line %d: address family must be specified before "
679 "ListenAddress.", filename, linenum);
680 if (strcasecmp(arg, "inet") == 0)
682 else if (strcasecmp(arg, "inet6") == 0)
684 else if (strcasecmp(arg, "any") == 0)
687 fatal("%s line %d: unsupported address family \"%s\".",
688 filename, linenum, arg);
694 intptr = &options->num_host_key_files;
695 if (*intptr >= MAX_HOSTKEYS)
696 fatal("%s line %d: too many host keys specified (max %d).",
697 filename, linenum, MAX_HOSTKEYS);
698 charptr = &options->host_key_files[*intptr];
701 if (!arg || *arg == '\0')
702 fatal("%s line %d: missing file name.",
704 if (*activep && *charptr == NULL) {
705 *charptr = tilde_expand_filename(arg, getuid());
706 /* increase optional counter */
708 *intptr = *intptr + 1;
713 charptr = &options->pid_file;
716 case sPermitRootLogin:
717 intptr = &options->permit_root_login;
719 if (!arg || *arg == '\0')
720 fatal("%s line %d: missing yes/"
721 "without-password/forced-commands-only/no "
722 "argument.", filename, linenum);
723 value = 0; /* silence compiler */
724 if (strcmp(arg, "without-password") == 0)
725 value = PERMIT_NO_PASSWD;
726 else if (strcmp(arg, "forced-commands-only") == 0)
727 value = PERMIT_FORCED_ONLY;
728 else if (strcmp(arg, "yes") == 0)
730 else if (strcmp(arg, "no") == 0)
733 fatal("%s line %d: Bad yes/"
734 "without-password/forced-commands-only/no "
735 "argument: %s", filename, linenum, arg);
741 intptr = &options->ignore_rhosts;
744 if (!arg || *arg == '\0')
745 fatal("%s line %d: missing yes/no argument.",
747 value = 0; /* silence compiler */
748 if (strcmp(arg, "yes") == 0)
750 else if (strcmp(arg, "no") == 0)
753 fatal("%s line %d: Bad yes/no argument: %s",
754 filename, linenum, arg);
755 if (*activep && *intptr == -1)
759 case sIgnoreUserKnownHosts:
760 intptr = &options->ignore_user_known_hosts;
763 case sRhostsRSAAuthentication:
764 intptr = &options->rhosts_rsa_authentication;
767 case sHostbasedAuthentication:
768 intptr = &options->hostbased_authentication;
771 case sHostbasedUsesNameFromPacketOnly:
772 intptr = &options->hostbased_uses_name_from_packet_only;
775 case sRSAAuthentication:
776 intptr = &options->rsa_authentication;
779 case sPubkeyAuthentication:
780 intptr = &options->pubkey_authentication;
783 case sKerberosAuthentication:
784 intptr = &options->kerberos_authentication;
787 case sKerberosOrLocalPasswd:
788 intptr = &options->kerberos_or_local_passwd;
791 case sKerberosTicketCleanup:
792 intptr = &options->kerberos_ticket_cleanup;
795 case sKerberosGetAFSToken:
796 intptr = &options->kerberos_get_afs_token;
799 case sGssAuthentication:
800 intptr = &options->gss_authentication;
803 case sGssCleanupCreds:
804 intptr = &options->gss_cleanup_creds;
807 case sPasswordAuthentication:
808 intptr = &options->password_authentication;
811 case sKbdInteractiveAuthentication:
812 intptr = &options->kbd_interactive_authentication;
815 case sChallengeResponseAuthentication:
816 intptr = &options->challenge_response_authentication;
820 intptr = &options->print_motd;
824 intptr = &options->print_lastlog;
828 intptr = &options->x11_forwarding;
831 case sX11DisplayOffset:
832 intptr = &options->x11_display_offset;
835 case sX11UseLocalhost:
836 intptr = &options->x11_use_localhost;
840 charptr = &options->xauth_location;
844 intptr = &options->strict_modes;
848 intptr = &options->tcp_keep_alive;
852 intptr = &options->permit_empty_passwd;
855 case sPermitUserEnvironment:
856 intptr = &options->permit_user_env;
860 intptr = &options->use_login;
864 intptr = &options->compression;
866 if (!arg || *arg == '\0')
867 fatal("%s line %d: missing yes/no/delayed "
868 "argument.", filename, linenum);
869 value = 0; /* silence compiler */
870 if (strcmp(arg, "delayed") == 0)
871 value = COMP_DELAYED;
872 else if (strcmp(arg, "yes") == 0)
874 else if (strcmp(arg, "no") == 0)
877 fatal("%s line %d: Bad yes/no/delayed "
878 "argument: %s", filename, linenum, arg);
884 intptr = &options->gateway_ports;
886 if (!arg || *arg == '\0')
887 fatal("%s line %d: missing yes/no/clientspecified "
888 "argument.", filename, linenum);
889 value = 0; /* silence compiler */
890 if (strcmp(arg, "clientspecified") == 0)
892 else if (strcmp(arg, "yes") == 0)
894 else if (strcmp(arg, "no") == 0)
897 fatal("%s line %d: Bad yes/no/clientspecified "
898 "argument: %s", filename, linenum, arg);
904 intptr = &options->use_dns;
908 intptr = (int *) &options->log_facility;
910 value = log_facility_number(arg);
911 if (value == SYSLOG_FACILITY_NOT_SET)
912 fatal("%.200s line %d: unsupported log facility '%s'",
913 filename, linenum, arg ? arg : "<NONE>");
915 *intptr = (SyslogFacility) value;
919 intptr = (int *) &options->log_level;
921 value = log_level_number(arg);
922 if (value == SYSLOG_LEVEL_NOT_SET)
923 fatal("%.200s line %d: unsupported log level '%s'",
924 filename, linenum, arg ? arg : "<NONE>");
926 *intptr = (LogLevel) value;
929 case sAllowTcpForwarding:
930 intptr = &options->allow_tcp_forwarding;
933 case sUsePrivilegeSeparation:
934 intptr = &use_privsep;
938 while ((arg = strdelim(&cp)) && *arg != '\0') {
939 if (options->num_allow_users >= MAX_ALLOW_USERS)
940 fatal("%s line %d: too many allow users.",
942 options->allow_users[options->num_allow_users++] =
948 while ((arg = strdelim(&cp)) && *arg != '\0') {
949 if (options->num_deny_users >= MAX_DENY_USERS)
950 fatal( "%s line %d: too many deny users.",
952 options->deny_users[options->num_deny_users++] =
958 while ((arg = strdelim(&cp)) && *arg != '\0') {
959 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
960 fatal("%s line %d: too many allow groups.",
962 options->allow_groups[options->num_allow_groups++] =
968 while ((arg = strdelim(&cp)) && *arg != '\0') {
969 if (options->num_deny_groups >= MAX_DENY_GROUPS)
970 fatal("%s line %d: too many deny groups.",
972 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
978 if (!arg || *arg == '\0')
979 fatal("%s line %d: Missing argument.", filename, linenum);
980 if (!ciphers_valid(arg))
981 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
982 filename, linenum, arg ? arg : "<NONE>");
983 if (options->ciphers == NULL)
984 options->ciphers = xstrdup(arg);
989 if (!arg || *arg == '\0')
990 fatal("%s line %d: Missing argument.", filename, linenum);
992 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
993 filename, linenum, arg ? arg : "<NONE>");
994 if (options->macs == NULL)
995 options->macs = xstrdup(arg);
999 intptr = &options->protocol;
1000 arg = strdelim(&cp);
1001 if (!arg || *arg == '\0')
1002 fatal("%s line %d: Missing argument.", filename, linenum);
1003 value = proto_spec(arg);
1004 if (value == SSH_PROTO_UNKNOWN)
1005 fatal("%s line %d: Bad protocol spec '%s'.",
1006 filename, linenum, arg ? arg : "<NONE>");
1007 if (*intptr == SSH_PROTO_UNKNOWN)
1012 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1013 fatal("%s line %d: too many subsystems defined.",
1016 arg = strdelim(&cp);
1017 if (!arg || *arg == '\0')
1018 fatal("%s line %d: Missing subsystem name.",
1021 arg = strdelim(&cp);
1024 for (i = 0; i < options->num_subsystems; i++)
1025 if (strcmp(arg, options->subsystem_name[i]) == 0)
1026 fatal("%s line %d: Subsystem '%s' already defined.",
1027 filename, linenum, arg);
1028 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1029 arg = strdelim(&cp);
1030 if (!arg || *arg == '\0')
1031 fatal("%s line %d: Missing subsystem command.",
1033 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1035 /* Collect arguments (separate to executable) */
1037 len = strlen(p) + 1;
1038 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1039 len += 1 + strlen(arg);
1040 p = xrealloc(p, 1, len);
1041 strlcat(p, " ", len);
1042 strlcat(p, arg, len);
1044 options->subsystem_args[options->num_subsystems] = p;
1045 options->num_subsystems++;
1049 arg = strdelim(&cp);
1050 if (!arg || *arg == '\0')
1051 fatal("%s line %d: Missing MaxStartups spec.",
1053 if ((n = sscanf(arg, "%d:%d:%d",
1054 &options->max_startups_begin,
1055 &options->max_startups_rate,
1056 &options->max_startups)) == 3) {
1057 if (options->max_startups_begin >
1058 options->max_startups ||
1059 options->max_startups_rate > 100 ||
1060 options->max_startups_rate < 1)
1061 fatal("%s line %d: Illegal MaxStartups spec.",
1064 fatal("%s line %d: Illegal MaxStartups spec.",
1067 options->max_startups = options->max_startups_begin;
1071 intptr = &options->max_authtries;
1075 charptr = &options->banner;
1076 goto parse_filename;
1078 * These options can contain %X options expanded at
1079 * connect time, so that you can specify paths like:
1081 * AuthorizedKeysFile /etc/ssh_keys/%u
1083 case sAuthorizedKeysFile:
1084 case sAuthorizedKeysFile2:
1085 charptr = (opcode == sAuthorizedKeysFile ) ?
1086 &options->authorized_keys_file :
1087 &options->authorized_keys_file2;
1088 goto parse_filename;
1090 case sClientAliveInterval:
1091 intptr = &options->client_alive_interval;
1094 case sClientAliveCountMax:
1095 intptr = &options->client_alive_count_max;
1099 while ((arg = strdelim(&cp)) && *arg != '\0') {
1100 if (strchr(arg, '=') != NULL)
1101 fatal("%s line %d: Invalid environment name.",
1103 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1104 fatal("%s line %d: too many allow env.",
1108 options->accept_env[options->num_accept_env++] =
1114 intptr = &options->permit_tun;
1115 arg = strdelim(&cp);
1116 if (!arg || *arg == '\0')
1117 fatal("%s line %d: Missing yes/point-to-point/"
1118 "ethernet/no argument.", filename, linenum);
1119 value = 0; /* silence compiler */
1120 if (strcasecmp(arg, "ethernet") == 0)
1121 value = SSH_TUNMODE_ETHERNET;
1122 else if (strcasecmp(arg, "point-to-point") == 0)
1123 value = SSH_TUNMODE_POINTOPOINT;
1124 else if (strcasecmp(arg, "yes") == 0)
1125 value = SSH_TUNMODE_YES;
1126 else if (strcasecmp(arg, "no") == 0)
1127 value = SSH_TUNMODE_NO;
1129 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1130 "no argument: %s", filename, linenum, arg);
1137 fatal("Match directive not supported as a command-line "
1139 value = match_cfg_line(&cp, linenum, user, host, address);
1141 fatal("%s line %d: Bad Match condition", filename,
1147 logit("%s line %d: Deprecated option %s",
1148 filename, linenum, arg);
1150 arg = strdelim(&cp);
1154 logit("%s line %d: Unsupported option %s",
1155 filename, linenum, arg);
1157 arg = strdelim(&cp);
1161 fatal("%s line %d: Missing handler for opcode %s (%d)",
1162 filename, linenum, arg, opcode);
1164 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1165 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1166 filename, linenum, arg);
1170 /* Reads the server configuration file. */
1173 load_server_config(const char *filename, Buffer *conf)
1175 char line[1024], *cp;
1178 debug2("%s: filename %s", __func__, filename);
1179 if ((f = fopen(filename, "r")) == NULL) {
1184 while (fgets(line, sizeof(line), f)) {
1186 * Trim out comments and strip whitespace
1187 * NB - preserve newlines, they are needed to reproduce
1188 * line numbers later for error messages
1190 if ((cp = strchr(line, '#')) != NULL)
1191 memcpy(cp, "\n", 2);
1192 cp = line + strspn(line, " \t\r");
1194 buffer_append(conf, cp, strlen(cp));
1196 buffer_append(conf, "\0", 1);
1198 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1202 parse_server_match_config(ServerOptions *options, const char *user,
1203 const char *host, const char *address)
1207 initialize_server_options(&mo);
1208 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1209 copy_set_server_options(options, &mo);
1212 /* Copy any (supported) values that are set */
1214 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1216 if (src->allow_tcp_forwarding != -1)
1217 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1218 if (src->gateway_ports != -1)
1219 dst->gateway_ports = src->gateway_ports;
1223 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1224 const char *user, const char *host, const char *address)
1226 int active, linenum, bad_options = 0;
1227 char *cp, *obuf, *cbuf;
1229 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1231 obuf = cbuf = xstrdup(buffer_ptr(conf));
1232 active = user ? 0 : 1;
1234 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1235 if (process_server_config_line(options, cp, filename,
1236 linenum++, &active, user, host, address) != 0)
1240 if (bad_options > 0)
1241 fatal("%s: terminating, %d bad configuration options",
1242 filename, bad_options);