1 /* $OpenBSD: servconf.c,v 1.159 2006/07/21 12:43:36 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>
18 #if defined(HAVE_NETDB_H)
28 #include "pathnames.h"
36 static void add_listen_addr(ServerOptions *, char *, u_short);
37 static void add_one_listen_addr(ServerOptions *, char *, u_short);
39 /* Use of privilege separation or not */
40 extern int use_privsep;
43 /* Initializes the server options to their default values. */
46 initialize_server_options(ServerOptions *options)
48 memset(options, 0, sizeof(*options));
50 /* Portable-specific options */
51 options->use_pam = -1;
53 /* Standard Options */
54 options->num_ports = 0;
55 options->ports_from_cmdline = 0;
56 options->listen_addrs = NULL;
57 options->address_family = -1;
58 options->num_host_key_files = 0;
59 options->pid_file = NULL;
60 options->server_key_bits = -1;
61 options->login_grace_time = -1;
62 options->key_regeneration_time = -1;
63 options->permit_root_login = PERMIT_NOT_SET;
64 options->ignore_rhosts = -1;
65 options->ignore_user_known_hosts = -1;
66 options->print_motd = -1;
67 options->print_lastlog = -1;
68 options->x11_forwarding = -1;
69 options->x11_display_offset = -1;
70 options->x11_use_localhost = -1;
71 options->xauth_location = NULL;
72 options->strict_modes = -1;
73 options->tcp_keep_alive = -1;
74 options->log_facility = SYSLOG_FACILITY_NOT_SET;
75 options->log_level = SYSLOG_LEVEL_NOT_SET;
76 options->rhosts_rsa_authentication = -1;
77 options->hostbased_authentication = -1;
78 options->hostbased_uses_name_from_packet_only = -1;
79 options->rsa_authentication = -1;
80 options->pubkey_authentication = -1;
81 options->kerberos_authentication = -1;
82 options->kerberos_or_local_passwd = -1;
83 options->kerberos_ticket_cleanup = -1;
84 options->kerberos_get_afs_token = -1;
85 options->gss_authentication=-1;
86 options->gss_cleanup_creds = -1;
87 options->password_authentication = -1;
88 options->kbd_interactive_authentication = -1;
89 options->challenge_response_authentication = -1;
90 options->permit_empty_passwd = -1;
91 options->permit_user_env = -1;
92 options->use_login = -1;
93 options->compression = -1;
94 options->allow_tcp_forwarding = -1;
95 options->num_allow_users = 0;
96 options->num_deny_users = 0;
97 options->num_allow_groups = 0;
98 options->num_deny_groups = 0;
99 options->ciphers = NULL;
100 options->macs = NULL;
101 options->protocol = SSH_PROTO_UNKNOWN;
102 options->gateway_ports = -1;
103 options->num_subsystems = 0;
104 options->max_startups_begin = -1;
105 options->max_startups_rate = -1;
106 options->max_startups = -1;
107 options->max_authtries = -1;
108 options->banner = NULL;
109 options->use_dns = -1;
110 options->client_alive_interval = -1;
111 options->client_alive_count_max = -1;
112 options->authorized_keys_file = NULL;
113 options->authorized_keys_file2 = NULL;
114 options->num_accept_env = 0;
115 options->permit_tun = -1;
116 options->num_permitted_opens = -1;
117 options->adm_forced_command = NULL;
121 fill_default_server_options(ServerOptions *options)
123 /* Portable-specific options */
124 if (options->use_pam == -1)
125 options->use_pam = 0;
127 /* Standard Options */
128 if (options->protocol == SSH_PROTO_UNKNOWN)
129 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
130 if (options->num_host_key_files == 0) {
131 /* fill default hostkeys for protocols */
132 if (options->protocol & SSH_PROTO_1)
133 options->host_key_files[options->num_host_key_files++] =
135 if (options->protocol & SSH_PROTO_2) {
136 options->host_key_files[options->num_host_key_files++] =
137 _PATH_HOST_RSA_KEY_FILE;
138 options->host_key_files[options->num_host_key_files++] =
139 _PATH_HOST_DSA_KEY_FILE;
142 if (options->num_ports == 0)
143 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
144 if (options->listen_addrs == NULL)
145 add_listen_addr(options, NULL, 0);
146 if (options->pid_file == NULL)
147 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
148 if (options->server_key_bits == -1)
149 options->server_key_bits = 768;
150 if (options->login_grace_time == -1)
151 options->login_grace_time = 120;
152 if (options->key_regeneration_time == -1)
153 options->key_regeneration_time = 3600;
154 if (options->permit_root_login == PERMIT_NOT_SET)
155 options->permit_root_login = PERMIT_YES;
156 if (options->ignore_rhosts == -1)
157 options->ignore_rhosts = 1;
158 if (options->ignore_user_known_hosts == -1)
159 options->ignore_user_known_hosts = 0;
160 if (options->print_motd == -1)
161 options->print_motd = 1;
162 if (options->print_lastlog == -1)
163 options->print_lastlog = 1;
164 if (options->x11_forwarding == -1)
165 options->x11_forwarding = 0;
166 if (options->x11_display_offset == -1)
167 options->x11_display_offset = 10;
168 if (options->x11_use_localhost == -1)
169 options->x11_use_localhost = 1;
170 if (options->xauth_location == NULL)
171 options->xauth_location = _PATH_XAUTH;
172 if (options->strict_modes == -1)
173 options->strict_modes = 1;
174 if (options->tcp_keep_alive == -1)
175 options->tcp_keep_alive = 1;
176 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
177 options->log_facility = SYSLOG_FACILITY_AUTH;
178 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
179 options->log_level = SYSLOG_LEVEL_INFO;
180 if (options->rhosts_rsa_authentication == -1)
181 options->rhosts_rsa_authentication = 0;
182 if (options->hostbased_authentication == -1)
183 options->hostbased_authentication = 0;
184 if (options->hostbased_uses_name_from_packet_only == -1)
185 options->hostbased_uses_name_from_packet_only = 0;
186 if (options->rsa_authentication == -1)
187 options->rsa_authentication = 1;
188 if (options->pubkey_authentication == -1)
189 options->pubkey_authentication = 1;
190 if (options->kerberos_authentication == -1)
191 options->kerberos_authentication = 0;
192 if (options->kerberos_or_local_passwd == -1)
193 options->kerberos_or_local_passwd = 1;
194 if (options->kerberos_ticket_cleanup == -1)
195 options->kerberos_ticket_cleanup = 1;
196 if (options->kerberos_get_afs_token == -1)
197 options->kerberos_get_afs_token = 0;
198 if (options->gss_authentication == -1)
199 options->gss_authentication = 0;
200 if (options->gss_cleanup_creds == -1)
201 options->gss_cleanup_creds = 1;
202 if (options->password_authentication == -1)
203 options->password_authentication = 1;
204 if (options->kbd_interactive_authentication == -1)
205 options->kbd_interactive_authentication = 0;
206 if (options->challenge_response_authentication == -1)
207 options->challenge_response_authentication = 1;
208 if (options->permit_empty_passwd == -1)
209 options->permit_empty_passwd = 0;
210 if (options->permit_user_env == -1)
211 options->permit_user_env = 0;
212 if (options->use_login == -1)
213 options->use_login = 0;
214 if (options->compression == -1)
215 options->compression = COMP_DELAYED;
216 if (options->allow_tcp_forwarding == -1)
217 options->allow_tcp_forwarding = 1;
218 if (options->gateway_ports == -1)
219 options->gateway_ports = 0;
220 if (options->max_startups == -1)
221 options->max_startups = 10;
222 if (options->max_startups_rate == -1)
223 options->max_startups_rate = 100; /* 100% */
224 if (options->max_startups_begin == -1)
225 options->max_startups_begin = options->max_startups;
226 if (options->max_authtries == -1)
227 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
228 if (options->use_dns == -1)
229 options->use_dns = 1;
230 if (options->client_alive_interval == -1)
231 options->client_alive_interval = 0;
232 if (options->client_alive_count_max == -1)
233 options->client_alive_count_max = 3;
234 if (options->authorized_keys_file2 == NULL) {
235 /* authorized_keys_file2 falls back to authorized_keys_file */
236 if (options->authorized_keys_file != NULL)
237 options->authorized_keys_file2 = options->authorized_keys_file;
239 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
241 if (options->authorized_keys_file == NULL)
242 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
243 if (options->permit_tun == -1)
244 options->permit_tun = SSH_TUNMODE_NO;
246 /* Turn privilege separation on by default */
247 if (use_privsep == -1)
251 if (use_privsep && options->compression == 1) {
252 error("This platform does not support both privilege "
253 "separation and compression");
254 error("Compression disabled");
255 options->compression = 0;
261 /* Keyword tokens. */
263 sBadOption, /* == unknown option */
264 /* Portable-specific options */
266 /* Standard Options */
267 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
268 sPermitRootLogin, sLogFacility, sLogLevel,
269 sRhostsRSAAuthentication, sRSAAuthentication,
270 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
271 sKerberosGetAFSToken,
272 sKerberosTgtPassing, sChallengeResponseAuthentication,
273 sPasswordAuthentication, sKbdInteractiveAuthentication,
274 sListenAddress, sAddressFamily,
275 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
276 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
277 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
278 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
279 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
280 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
281 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
282 sMaxStartups, sMaxAuthTries,
283 sBanner, sUseDNS, sHostbasedAuthentication,
284 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
285 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
286 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
287 sMatch, sPermitOpen, sForceCommand,
288 sUsePrivilegeSeparation,
289 sDeprecated, sUnsupported
292 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
293 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
294 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
296 /* Textual representation of the tokens. */
299 ServerOpCodes opcode;
302 /* Portable-specific options */
304 { "usepam", sUsePAM, SSHCFG_GLOBAL },
306 { "usepam", sUnsupported, SSHCFG_GLOBAL },
308 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
309 /* Standard Options */
310 { "port", sPort, SSHCFG_GLOBAL },
311 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
312 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
313 { "pidfile", sPidFile, SSHCFG_GLOBAL },
314 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
315 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
316 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
317 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
318 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
319 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
320 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
321 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
322 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
323 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
324 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
325 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
326 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
328 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
329 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
330 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
332 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
334 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
337 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
338 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
339 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
340 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
342 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
343 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
345 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
346 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
348 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
349 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
351 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
352 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
353 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
354 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
355 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
356 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
357 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
358 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
359 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
360 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
361 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
362 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
363 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
364 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
365 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
366 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
367 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
368 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
369 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
370 { "compression", sCompression, SSHCFG_GLOBAL },
371 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
372 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
373 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
374 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
375 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
376 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
377 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
378 { "ciphers", sCiphers, SSHCFG_GLOBAL },
379 { "macs", sMacs, SSHCFG_GLOBAL },
380 { "protocol", sProtocol, SSHCFG_GLOBAL },
381 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
382 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
383 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
384 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
385 { "banner", sBanner, SSHCFG_GLOBAL },
386 { "usedns", sUseDNS, SSHCFG_GLOBAL },
387 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
388 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
389 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
390 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
391 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
392 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
393 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
394 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
395 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
396 { "match", sMatch, SSHCFG_ALL },
397 { "permitopen", sPermitOpen, SSHCFG_ALL },
398 { "forcecommand", sForceCommand, SSHCFG_ALL },
399 { NULL, sBadOption, 0 }
403 * Returns the number of the token pointed to by cp or sBadOption.
407 parse_token(const char *cp, const char *filename,
408 int linenum, u_int *flags)
412 for (i = 0; keywords[i].name; i++)
413 if (strcasecmp(cp, keywords[i].name) == 0) {
414 *flags = keywords[i].flags;
415 return keywords[i].opcode;
418 error("%s: line %d: Bad configuration option: %s",
419 filename, linenum, cp);
424 add_listen_addr(ServerOptions *options, char *addr, u_short port)
428 if (options->num_ports == 0)
429 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
430 if (options->address_family == -1)
431 options->address_family = AF_UNSPEC;
433 for (i = 0; i < options->num_ports; i++)
434 add_one_listen_addr(options, addr, options->ports[i]);
436 add_one_listen_addr(options, addr, port);
440 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
442 struct addrinfo hints, *ai, *aitop;
443 char strport[NI_MAXSERV];
446 memset(&hints, 0, sizeof(hints));
447 hints.ai_family = options->address_family;
448 hints.ai_socktype = SOCK_STREAM;
449 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
450 snprintf(strport, sizeof strport, "%u", port);
451 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
452 fatal("bad addr or host: %s (%s)",
453 addr ? addr : "<NULL>",
454 gai_strerror(gaierr));
455 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
457 ai->ai_next = options->listen_addrs;
458 options->listen_addrs = aitop;
462 * The strategy for the Match blocks is that the config file is parsed twice.
464 * The first time is at startup. activep is initialized to 1 and the
465 * directives in the global context are processed and acted on. Hitting a
466 * Match directive unsets activep and the directives inside the block are
467 * checked for syntax only.
469 * The second time is after a connection has been established but before
470 * authentication. activep is initialized to 2 and global config directives
471 * are ignored since they have already been processed. If the criteria in a
472 * Match block is met, activep is set and the subsequent directives
473 * processed and actioned until EOF or another Match block unsets it. Any
474 * options set are copied into the main server config.
476 * Potential additions/improvements:
477 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
479 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
480 * Match Address 192.168.0.*
485 * AllowTcpForwarding yes
486 * GatewayPorts clientspecified
489 * - Add a PermittedChannelRequests directive
491 * PermittedChannelRequests session,forwarded-tcpip
495 match_cfg_line(char **condition, int line, const char *user, const char *host,
499 char *arg, *attrib, *cp = *condition;
503 debug3("checking syntax for 'Match %s'", cp);
505 debug3("checking match for '%s' user %s host %s addr %s", cp,
506 user ? user : "(null)", host ? host : "(null)",
507 address ? address : "(null)");
509 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
510 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
511 error("Missing Match criteria for %s", attrib);
515 if (strcasecmp(attrib, "user") == 0) {
520 if (match_pattern_list(user, arg, len, 0) != 1)
523 debug("user %.100s matched 'User %.100s' at "
524 "line %d", user, arg, line);
525 } else if (strcasecmp(attrib, "host") == 0) {
530 if (match_hostname(host, arg, len) != 1)
533 debug("connection from %.100s matched 'Host "
534 "%.100s' at line %d", host, arg, line);
535 } else if (strcasecmp(attrib, "address") == 0) {
536 debug("address '%s' arg '%s'", address, arg);
541 if (match_hostname(address, arg, len) != 1)
544 debug("connection from %.100s matched 'Address "
545 "%.100s' at line %d", address, arg, line);
547 error("Unsupported Match attribute %s", attrib);
552 debug3("match %sfound", result ? "" : "not ");
557 #define WHITESPACE " \t\r\n"
560 process_server_config_line(ServerOptions *options, char *line,
561 const char *filename, int linenum, int *activep, const char *user,
562 const char *host, const char *address)
564 char *cp, **charptr, *arg, *p;
565 int cmdline = 0, *intptr, value, n;
566 ServerOpCodes opcode;
572 if ((arg = strdelim(&cp)) == NULL)
574 /* Ignore leading whitespace */
577 if (!arg || !*arg || *arg == '#')
581 opcode = parse_token(arg, filename, linenum, &flags);
583 if (activep == NULL) { /* We are processing a command line directive */
587 if (*activep && opcode != sMatch)
588 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
589 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
591 fatal("%s line %d: Directive '%s' is not allowed "
592 "within a Match block", filename, linenum, arg);
593 } else { /* this is a directive we have already processed */
601 /* Portable-specific options */
603 intptr = &options->use_pam;
606 /* Standard Options */
610 /* ignore ports from configfile if cmdline specifies ports */
611 if (options->ports_from_cmdline)
613 if (options->listen_addrs != NULL)
614 fatal("%s line %d: ports must be specified before "
615 "ListenAddress.", filename, linenum);
616 if (options->num_ports >= MAX_PORTS)
617 fatal("%s line %d: too many ports.",
620 if (!arg || *arg == '\0')
621 fatal("%s line %d: missing port number.",
623 options->ports[options->num_ports++] = a2port(arg);
624 if (options->ports[options->num_ports-1] == 0)
625 fatal("%s line %d: Badly formatted port number.",
630 intptr = &options->server_key_bits;
633 if (!arg || *arg == '\0')
634 fatal("%s line %d: missing integer value.",
637 if (*activep && *intptr == -1)
641 case sLoginGraceTime:
642 intptr = &options->login_grace_time;
645 if (!arg || *arg == '\0')
646 fatal("%s line %d: missing time value.",
648 if ((value = convtime(arg)) == -1)
649 fatal("%s line %d: invalid time value.",
655 case sKeyRegenerationTime:
656 intptr = &options->key_regeneration_time;
661 if (arg == NULL || *arg == '\0')
662 fatal("%s line %d: missing address",
664 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
665 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
666 && strchr(p+1, ':') != NULL) {
667 add_listen_addr(options, arg, 0);
672 fatal("%s line %d: bad address:port usage",
674 p = cleanhostname(p);
677 else if ((port = a2port(arg)) == 0)
678 fatal("%s line %d: bad port number", filename, linenum);
680 add_listen_addr(options, p, port);
686 if (!arg || *arg == '\0')
687 fatal("%s line %d: missing address family.",
689 intptr = &options->address_family;
690 if (options->listen_addrs != NULL)
691 fatal("%s line %d: address family must be specified before "
692 "ListenAddress.", filename, linenum);
693 if (strcasecmp(arg, "inet") == 0)
695 else if (strcasecmp(arg, "inet6") == 0)
697 else if (strcasecmp(arg, "any") == 0)
700 fatal("%s line %d: unsupported address family \"%s\".",
701 filename, linenum, arg);
707 intptr = &options->num_host_key_files;
708 if (*intptr >= MAX_HOSTKEYS)
709 fatal("%s line %d: too many host keys specified (max %d).",
710 filename, linenum, MAX_HOSTKEYS);
711 charptr = &options->host_key_files[*intptr];
714 if (!arg || *arg == '\0')
715 fatal("%s line %d: missing file name.",
717 if (*activep && *charptr == NULL) {
718 *charptr = tilde_expand_filename(arg, getuid());
719 /* increase optional counter */
721 *intptr = *intptr + 1;
726 charptr = &options->pid_file;
729 case sPermitRootLogin:
730 intptr = &options->permit_root_login;
732 if (!arg || *arg == '\0')
733 fatal("%s line %d: missing yes/"
734 "without-password/forced-commands-only/no "
735 "argument.", filename, linenum);
736 value = 0; /* silence compiler */
737 if (strcmp(arg, "without-password") == 0)
738 value = PERMIT_NO_PASSWD;
739 else if (strcmp(arg, "forced-commands-only") == 0)
740 value = PERMIT_FORCED_ONLY;
741 else if (strcmp(arg, "yes") == 0)
743 else if (strcmp(arg, "no") == 0)
746 fatal("%s line %d: Bad yes/"
747 "without-password/forced-commands-only/no "
748 "argument: %s", filename, linenum, arg);
754 intptr = &options->ignore_rhosts;
757 if (!arg || *arg == '\0')
758 fatal("%s line %d: missing yes/no argument.",
760 value = 0; /* silence compiler */
761 if (strcmp(arg, "yes") == 0)
763 else if (strcmp(arg, "no") == 0)
766 fatal("%s line %d: Bad yes/no argument: %s",
767 filename, linenum, arg);
768 if (*activep && *intptr == -1)
772 case sIgnoreUserKnownHosts:
773 intptr = &options->ignore_user_known_hosts;
776 case sRhostsRSAAuthentication:
777 intptr = &options->rhosts_rsa_authentication;
780 case sHostbasedAuthentication:
781 intptr = &options->hostbased_authentication;
784 case sHostbasedUsesNameFromPacketOnly:
785 intptr = &options->hostbased_uses_name_from_packet_only;
788 case sRSAAuthentication:
789 intptr = &options->rsa_authentication;
792 case sPubkeyAuthentication:
793 intptr = &options->pubkey_authentication;
796 case sKerberosAuthentication:
797 intptr = &options->kerberos_authentication;
800 case sKerberosOrLocalPasswd:
801 intptr = &options->kerberos_or_local_passwd;
804 case sKerberosTicketCleanup:
805 intptr = &options->kerberos_ticket_cleanup;
808 case sKerberosGetAFSToken:
809 intptr = &options->kerberos_get_afs_token;
812 case sGssAuthentication:
813 intptr = &options->gss_authentication;
816 case sGssCleanupCreds:
817 intptr = &options->gss_cleanup_creds;
820 case sPasswordAuthentication:
821 intptr = &options->password_authentication;
824 case sKbdInteractiveAuthentication:
825 intptr = &options->kbd_interactive_authentication;
828 case sChallengeResponseAuthentication:
829 intptr = &options->challenge_response_authentication;
833 intptr = &options->print_motd;
837 intptr = &options->print_lastlog;
841 intptr = &options->x11_forwarding;
844 case sX11DisplayOffset:
845 intptr = &options->x11_display_offset;
848 case sX11UseLocalhost:
849 intptr = &options->x11_use_localhost;
853 charptr = &options->xauth_location;
857 intptr = &options->strict_modes;
861 intptr = &options->tcp_keep_alive;
865 intptr = &options->permit_empty_passwd;
868 case sPermitUserEnvironment:
869 intptr = &options->permit_user_env;
873 intptr = &options->use_login;
877 intptr = &options->compression;
879 if (!arg || *arg == '\0')
880 fatal("%s line %d: missing yes/no/delayed "
881 "argument.", filename, linenum);
882 value = 0; /* silence compiler */
883 if (strcmp(arg, "delayed") == 0)
884 value = COMP_DELAYED;
885 else if (strcmp(arg, "yes") == 0)
887 else if (strcmp(arg, "no") == 0)
890 fatal("%s line %d: Bad yes/no/delayed "
891 "argument: %s", filename, linenum, arg);
897 intptr = &options->gateway_ports;
899 if (!arg || *arg == '\0')
900 fatal("%s line %d: missing yes/no/clientspecified "
901 "argument.", filename, linenum);
902 value = 0; /* silence compiler */
903 if (strcmp(arg, "clientspecified") == 0)
905 else if (strcmp(arg, "yes") == 0)
907 else if (strcmp(arg, "no") == 0)
910 fatal("%s line %d: Bad yes/no/clientspecified "
911 "argument: %s", filename, linenum, arg);
917 intptr = &options->use_dns;
921 intptr = (int *) &options->log_facility;
923 value = log_facility_number(arg);
924 if (value == SYSLOG_FACILITY_NOT_SET)
925 fatal("%.200s line %d: unsupported log facility '%s'",
926 filename, linenum, arg ? arg : "<NONE>");
928 *intptr = (SyslogFacility) value;
932 intptr = (int *) &options->log_level;
934 value = log_level_number(arg);
935 if (value == SYSLOG_LEVEL_NOT_SET)
936 fatal("%.200s line %d: unsupported log level '%s'",
937 filename, linenum, arg ? arg : "<NONE>");
939 *intptr = (LogLevel) value;
942 case sAllowTcpForwarding:
943 intptr = &options->allow_tcp_forwarding;
946 case sUsePrivilegeSeparation:
947 intptr = &use_privsep;
951 while ((arg = strdelim(&cp)) && *arg != '\0') {
952 if (options->num_allow_users >= MAX_ALLOW_USERS)
953 fatal("%s line %d: too many allow users.",
955 options->allow_users[options->num_allow_users++] =
961 while ((arg = strdelim(&cp)) && *arg != '\0') {
962 if (options->num_deny_users >= MAX_DENY_USERS)
963 fatal( "%s line %d: too many deny users.",
965 options->deny_users[options->num_deny_users++] =
971 while ((arg = strdelim(&cp)) && *arg != '\0') {
972 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
973 fatal("%s line %d: too many allow groups.",
975 options->allow_groups[options->num_allow_groups++] =
981 while ((arg = strdelim(&cp)) && *arg != '\0') {
982 if (options->num_deny_groups >= MAX_DENY_GROUPS)
983 fatal("%s line %d: too many deny groups.",
985 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
991 if (!arg || *arg == '\0')
992 fatal("%s line %d: Missing argument.", filename, linenum);
993 if (!ciphers_valid(arg))
994 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
995 filename, linenum, arg ? arg : "<NONE>");
996 if (options->ciphers == NULL)
997 options->ciphers = xstrdup(arg);
1001 arg = strdelim(&cp);
1002 if (!arg || *arg == '\0')
1003 fatal("%s line %d: Missing argument.", filename, linenum);
1004 if (!mac_valid(arg))
1005 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1006 filename, linenum, arg ? arg : "<NONE>");
1007 if (options->macs == NULL)
1008 options->macs = xstrdup(arg);
1012 intptr = &options->protocol;
1013 arg = strdelim(&cp);
1014 if (!arg || *arg == '\0')
1015 fatal("%s line %d: Missing argument.", filename, linenum);
1016 value = proto_spec(arg);
1017 if (value == SSH_PROTO_UNKNOWN)
1018 fatal("%s line %d: Bad protocol spec '%s'.",
1019 filename, linenum, arg ? arg : "<NONE>");
1020 if (*intptr == SSH_PROTO_UNKNOWN)
1025 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1026 fatal("%s line %d: too many subsystems defined.",
1029 arg = strdelim(&cp);
1030 if (!arg || *arg == '\0')
1031 fatal("%s line %d: Missing subsystem name.",
1034 arg = strdelim(&cp);
1037 for (i = 0; i < options->num_subsystems; i++)
1038 if (strcmp(arg, options->subsystem_name[i]) == 0)
1039 fatal("%s line %d: Subsystem '%s' already defined.",
1040 filename, linenum, arg);
1041 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1042 arg = strdelim(&cp);
1043 if (!arg || *arg == '\0')
1044 fatal("%s line %d: Missing subsystem command.",
1046 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1048 /* Collect arguments (separate to executable) */
1050 len = strlen(p) + 1;
1051 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1052 len += 1 + strlen(arg);
1053 p = xrealloc(p, 1, len);
1054 strlcat(p, " ", len);
1055 strlcat(p, arg, len);
1057 options->subsystem_args[options->num_subsystems] = p;
1058 options->num_subsystems++;
1062 arg = strdelim(&cp);
1063 if (!arg || *arg == '\0')
1064 fatal("%s line %d: Missing MaxStartups spec.",
1066 if ((n = sscanf(arg, "%d:%d:%d",
1067 &options->max_startups_begin,
1068 &options->max_startups_rate,
1069 &options->max_startups)) == 3) {
1070 if (options->max_startups_begin >
1071 options->max_startups ||
1072 options->max_startups_rate > 100 ||
1073 options->max_startups_rate < 1)
1074 fatal("%s line %d: Illegal MaxStartups spec.",
1077 fatal("%s line %d: Illegal MaxStartups spec.",
1080 options->max_startups = options->max_startups_begin;
1084 intptr = &options->max_authtries;
1088 charptr = &options->banner;
1089 goto parse_filename;
1091 * These options can contain %X options expanded at
1092 * connect time, so that you can specify paths like:
1094 * AuthorizedKeysFile /etc/ssh_keys/%u
1096 case sAuthorizedKeysFile:
1097 case sAuthorizedKeysFile2:
1098 charptr = (opcode == sAuthorizedKeysFile ) ?
1099 &options->authorized_keys_file :
1100 &options->authorized_keys_file2;
1101 goto parse_filename;
1103 case sClientAliveInterval:
1104 intptr = &options->client_alive_interval;
1107 case sClientAliveCountMax:
1108 intptr = &options->client_alive_count_max;
1112 while ((arg = strdelim(&cp)) && *arg != '\0') {
1113 if (strchr(arg, '=') != NULL)
1114 fatal("%s line %d: Invalid environment name.",
1116 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1117 fatal("%s line %d: too many allow env.",
1121 options->accept_env[options->num_accept_env++] =
1127 intptr = &options->permit_tun;
1128 arg = strdelim(&cp);
1129 if (!arg || *arg == '\0')
1130 fatal("%s line %d: Missing yes/point-to-point/"
1131 "ethernet/no argument.", filename, linenum);
1132 value = 0; /* silence compiler */
1133 if (strcasecmp(arg, "ethernet") == 0)
1134 value = SSH_TUNMODE_ETHERNET;
1135 else if (strcasecmp(arg, "point-to-point") == 0)
1136 value = SSH_TUNMODE_POINTOPOINT;
1137 else if (strcasecmp(arg, "yes") == 0)
1138 value = SSH_TUNMODE_YES;
1139 else if (strcasecmp(arg, "no") == 0)
1140 value = SSH_TUNMODE_NO;
1142 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1143 "no argument: %s", filename, linenum, arg);
1150 fatal("Match directive not supported as a command-line "
1152 value = match_cfg_line(&cp, linenum, user, host, address);
1154 fatal("%s line %d: Bad Match condition", filename,
1160 arg = strdelim(&cp);
1161 if (!arg || *arg == '\0')
1162 fatal("%s line %d: missing PermitOpen specification",
1164 if (strcmp(arg, "any") == 0) {
1166 channel_clear_adm_permitted_opens();
1167 options->num_permitted_opens = 0;
1171 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1174 fatal("%s line %d: missing host in PermitOpen",
1176 p = cleanhostname(p);
1177 if (arg == NULL || (port = a2port(arg)) == 0)
1178 fatal("%s line %d: bad port number in "
1179 "PermitOpen", filename, linenum);
1180 if (*activep && options->num_permitted_opens == -1) {
1181 channel_clear_adm_permitted_opens();
1182 options->num_permitted_opens =
1183 channel_add_adm_permitted_opens(p, port);
1190 fatal("%.200s line %d: Missing argument.", filename,
1192 len = strspn(cp, WHITESPACE);
1193 if (*activep && options->adm_forced_command == NULL)
1194 options->adm_forced_command = xstrdup(cp + len);
1198 logit("%s line %d: Deprecated option %s",
1199 filename, linenum, arg);
1201 arg = strdelim(&cp);
1205 logit("%s line %d: Unsupported option %s",
1206 filename, linenum, arg);
1208 arg = strdelim(&cp);
1212 fatal("%s line %d: Missing handler for opcode %s (%d)",
1213 filename, linenum, arg, opcode);
1215 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1216 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1217 filename, linenum, arg);
1221 /* Reads the server configuration file. */
1224 load_server_config(const char *filename, Buffer *conf)
1226 char line[1024], *cp;
1229 debug2("%s: filename %s", __func__, filename);
1230 if ((f = fopen(filename, "r")) == NULL) {
1235 while (fgets(line, sizeof(line), f)) {
1237 * Trim out comments and strip whitespace
1238 * NB - preserve newlines, they are needed to reproduce
1239 * line numbers later for error messages
1241 if ((cp = strchr(line, '#')) != NULL)
1242 memcpy(cp, "\n", 2);
1243 cp = line + strspn(line, " \t\r");
1245 buffer_append(conf, cp, strlen(cp));
1247 buffer_append(conf, "\0", 1);
1249 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1253 parse_server_match_config(ServerOptions *options, const char *user,
1254 const char *host, const char *address)
1258 initialize_server_options(&mo);
1259 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1260 copy_set_server_options(options, &mo);
1263 /* Copy any (supported) values that are set */
1265 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1267 if (src->allow_tcp_forwarding != -1)
1268 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1269 if (src->gateway_ports != -1)
1270 dst->gateway_ports = src->gateway_ports;
1271 if (src->adm_forced_command != NULL) {
1272 if (dst->adm_forced_command != NULL)
1273 xfree(dst->adm_forced_command);
1274 dst->adm_forced_command = src->adm_forced_command;
1276 if (src->x11_display_offset != -1)
1277 dst->x11_display_offset = src->x11_display_offset;
1278 if (src->x11_forwarding != -1)
1279 dst->x11_forwarding = src->x11_forwarding;
1280 if (src->x11_use_localhost != -1)
1281 dst->x11_use_localhost = src->x11_use_localhost;
1285 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1286 const char *user, const char *host, const char *address)
1288 int active, linenum, bad_options = 0;
1289 char *cp, *obuf, *cbuf;
1291 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1293 obuf = cbuf = xstrdup(buffer_ptr(conf));
1294 active = user ? 0 : 1;
1296 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1297 if (process_server_config_line(options, cp, filename,
1298 linenum++, &active, user, host, address) != 0)
1302 if (bad_options > 0)
1303 fatal("%s: terminating, %d bad configuration options",
1304 filename, bad_options);