1 /* $OpenBSD: servconf.c,v 1.162 2006/08/01 23:22:47 stevesk 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>
29 #include "pathnames.h"
37 static void add_listen_addr(ServerOptions *, char *, u_short);
38 static void add_one_listen_addr(ServerOptions *, char *, u_short);
40 /* Use of privilege separation or not */
41 extern int use_privsep;
44 /* Initializes the server options to their default values. */
47 initialize_server_options(ServerOptions *options)
49 memset(options, 0, sizeof(*options));
51 /* Portable-specific options */
52 options->use_pam = -1;
54 /* Standard Options */
55 options->num_ports = 0;
56 options->ports_from_cmdline = 0;
57 options->listen_addrs = NULL;
58 options->address_family = -1;
59 options->num_host_key_files = 0;
60 options->pid_file = NULL;
61 options->server_key_bits = -1;
62 options->login_grace_time = -1;
63 options->key_regeneration_time = -1;
64 options->permit_root_login = PERMIT_NOT_SET;
65 options->ignore_rhosts = -1;
66 options->ignore_user_known_hosts = -1;
67 options->print_motd = -1;
68 options->print_lastlog = -1;
69 options->x11_forwarding = -1;
70 options->x11_display_offset = -1;
71 options->x11_use_localhost = -1;
72 options->xauth_location = NULL;
73 options->strict_modes = -1;
74 options->tcp_keep_alive = -1;
75 options->log_facility = SYSLOG_FACILITY_NOT_SET;
76 options->log_level = SYSLOG_LEVEL_NOT_SET;
77 options->rhosts_rsa_authentication = -1;
78 options->hostbased_authentication = -1;
79 options->hostbased_uses_name_from_packet_only = -1;
80 options->rsa_authentication = -1;
81 options->pubkey_authentication = -1;
82 options->kerberos_authentication = -1;
83 options->kerberos_or_local_passwd = -1;
84 options->kerberos_ticket_cleanup = -1;
85 options->kerberos_get_afs_token = -1;
86 options->gss_authentication=-1;
87 options->gss_cleanup_creds = -1;
88 options->password_authentication = -1;
89 options->kbd_interactive_authentication = -1;
90 options->challenge_response_authentication = -1;
91 options->permit_empty_passwd = -1;
92 options->permit_user_env = -1;
93 options->use_login = -1;
94 options->compression = -1;
95 options->allow_tcp_forwarding = -1;
96 options->num_allow_users = 0;
97 options->num_deny_users = 0;
98 options->num_allow_groups = 0;
99 options->num_deny_groups = 0;
100 options->ciphers = NULL;
101 options->macs = NULL;
102 options->protocol = SSH_PROTO_UNKNOWN;
103 options->gateway_ports = -1;
104 options->num_subsystems = 0;
105 options->max_startups_begin = -1;
106 options->max_startups_rate = -1;
107 options->max_startups = -1;
108 options->max_authtries = -1;
109 options->banner = NULL;
110 options->use_dns = -1;
111 options->client_alive_interval = -1;
112 options->client_alive_count_max = -1;
113 options->authorized_keys_file = NULL;
114 options->authorized_keys_file2 = NULL;
115 options->num_accept_env = 0;
116 options->permit_tun = -1;
117 options->num_permitted_opens = -1;
118 options->adm_forced_command = NULL;
122 fill_default_server_options(ServerOptions *options)
124 /* Portable-specific options */
125 if (options->use_pam == -1)
126 options->use_pam = 0;
128 /* Standard Options */
129 if (options->protocol == SSH_PROTO_UNKNOWN)
130 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
131 if (options->num_host_key_files == 0) {
132 /* fill default hostkeys for protocols */
133 if (options->protocol & SSH_PROTO_1)
134 options->host_key_files[options->num_host_key_files++] =
136 if (options->protocol & SSH_PROTO_2) {
137 options->host_key_files[options->num_host_key_files++] =
138 _PATH_HOST_RSA_KEY_FILE;
139 options->host_key_files[options->num_host_key_files++] =
140 _PATH_HOST_DSA_KEY_FILE;
143 if (options->num_ports == 0)
144 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
145 if (options->listen_addrs == NULL)
146 add_listen_addr(options, NULL, 0);
147 if (options->pid_file == NULL)
148 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
149 if (options->server_key_bits == -1)
150 options->server_key_bits = 768;
151 if (options->login_grace_time == -1)
152 options->login_grace_time = 120;
153 if (options->key_regeneration_time == -1)
154 options->key_regeneration_time = 3600;
155 if (options->permit_root_login == PERMIT_NOT_SET)
156 options->permit_root_login = PERMIT_YES;
157 if (options->ignore_rhosts == -1)
158 options->ignore_rhosts = 1;
159 if (options->ignore_user_known_hosts == -1)
160 options->ignore_user_known_hosts = 0;
161 if (options->print_motd == -1)
162 options->print_motd = 1;
163 if (options->print_lastlog == -1)
164 options->print_lastlog = 1;
165 if (options->x11_forwarding == -1)
166 options->x11_forwarding = 0;
167 if (options->x11_display_offset == -1)
168 options->x11_display_offset = 10;
169 if (options->x11_use_localhost == -1)
170 options->x11_use_localhost = 1;
171 if (options->xauth_location == NULL)
172 options->xauth_location = _PATH_XAUTH;
173 if (options->strict_modes == -1)
174 options->strict_modes = 1;
175 if (options->tcp_keep_alive == -1)
176 options->tcp_keep_alive = 1;
177 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
178 options->log_facility = SYSLOG_FACILITY_AUTH;
179 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
180 options->log_level = SYSLOG_LEVEL_INFO;
181 if (options->rhosts_rsa_authentication == -1)
182 options->rhosts_rsa_authentication = 0;
183 if (options->hostbased_authentication == -1)
184 options->hostbased_authentication = 0;
185 if (options->hostbased_uses_name_from_packet_only == -1)
186 options->hostbased_uses_name_from_packet_only = 0;
187 if (options->rsa_authentication == -1)
188 options->rsa_authentication = 1;
189 if (options->pubkey_authentication == -1)
190 options->pubkey_authentication = 1;
191 if (options->kerberos_authentication == -1)
192 options->kerberos_authentication = 0;
193 if (options->kerberos_or_local_passwd == -1)
194 options->kerberos_or_local_passwd = 1;
195 if (options->kerberos_ticket_cleanup == -1)
196 options->kerberos_ticket_cleanup = 1;
197 if (options->kerberos_get_afs_token == -1)
198 options->kerberos_get_afs_token = 0;
199 if (options->gss_authentication == -1)
200 options->gss_authentication = 0;
201 if (options->gss_cleanup_creds == -1)
202 options->gss_cleanup_creds = 1;
203 if (options->password_authentication == -1)
204 options->password_authentication = 1;
205 if (options->kbd_interactive_authentication == -1)
206 options->kbd_interactive_authentication = 0;
207 if (options->challenge_response_authentication == -1)
208 options->challenge_response_authentication = 1;
209 if (options->permit_empty_passwd == -1)
210 options->permit_empty_passwd = 0;
211 if (options->permit_user_env == -1)
212 options->permit_user_env = 0;
213 if (options->use_login == -1)
214 options->use_login = 0;
215 if (options->compression == -1)
216 options->compression = COMP_DELAYED;
217 if (options->allow_tcp_forwarding == -1)
218 options->allow_tcp_forwarding = 1;
219 if (options->gateway_ports == -1)
220 options->gateway_ports = 0;
221 if (options->max_startups == -1)
222 options->max_startups = 10;
223 if (options->max_startups_rate == -1)
224 options->max_startups_rate = 100; /* 100% */
225 if (options->max_startups_begin == -1)
226 options->max_startups_begin = options->max_startups;
227 if (options->max_authtries == -1)
228 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
229 if (options->use_dns == -1)
230 options->use_dns = 1;
231 if (options->client_alive_interval == -1)
232 options->client_alive_interval = 0;
233 if (options->client_alive_count_max == -1)
234 options->client_alive_count_max = 3;
235 if (options->authorized_keys_file2 == NULL) {
236 /* authorized_keys_file2 falls back to authorized_keys_file */
237 if (options->authorized_keys_file != NULL)
238 options->authorized_keys_file2 = options->authorized_keys_file;
240 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
242 if (options->authorized_keys_file == NULL)
243 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
244 if (options->permit_tun == -1)
245 options->permit_tun = SSH_TUNMODE_NO;
247 /* Turn privilege separation on by default */
248 if (use_privsep == -1)
252 if (use_privsep && options->compression == 1) {
253 error("This platform does not support both privilege "
254 "separation and compression");
255 error("Compression disabled");
256 options->compression = 0;
262 /* Keyword tokens. */
264 sBadOption, /* == unknown option */
265 /* Portable-specific options */
267 /* Standard Options */
268 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
269 sPermitRootLogin, sLogFacility, sLogLevel,
270 sRhostsRSAAuthentication, sRSAAuthentication,
271 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
272 sKerberosGetAFSToken,
273 sKerberosTgtPassing, sChallengeResponseAuthentication,
274 sPasswordAuthentication, sKbdInteractiveAuthentication,
275 sListenAddress, sAddressFamily,
276 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
277 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
278 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
279 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
280 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
281 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
282 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
283 sMaxStartups, sMaxAuthTries,
284 sBanner, sUseDNS, sHostbasedAuthentication,
285 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
286 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
287 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
288 sMatch, sPermitOpen, sForceCommand,
289 sUsePrivilegeSeparation,
290 sDeprecated, sUnsupported
293 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
294 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
295 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
297 /* Textual representation of the tokens. */
300 ServerOpCodes opcode;
303 /* Portable-specific options */
305 { "usepam", sUsePAM, SSHCFG_GLOBAL },
307 { "usepam", sUnsupported, SSHCFG_GLOBAL },
309 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
310 /* Standard Options */
311 { "port", sPort, SSHCFG_GLOBAL },
312 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
313 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
314 { "pidfile", sPidFile, SSHCFG_GLOBAL },
315 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
316 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
317 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
318 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
319 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
320 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
321 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
322 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
323 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
324 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
325 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
326 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
327 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
329 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
330 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
331 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
333 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
335 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
338 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
339 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
340 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
341 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
343 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
344 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
346 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
347 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
349 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
350 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
352 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
353 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
354 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
355 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
356 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
357 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
358 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
359 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
360 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
361 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
362 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
363 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
364 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
365 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
366 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
367 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
368 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
369 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
370 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
371 { "compression", sCompression, SSHCFG_GLOBAL },
372 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
373 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
374 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
375 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
376 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
377 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
378 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
379 { "ciphers", sCiphers, SSHCFG_GLOBAL },
380 { "macs", sMacs, SSHCFG_GLOBAL },
381 { "protocol", sProtocol, SSHCFG_GLOBAL },
382 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
383 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
384 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
385 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
386 { "banner", sBanner, SSHCFG_GLOBAL },
387 { "usedns", sUseDNS, SSHCFG_GLOBAL },
388 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
389 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
390 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
391 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
392 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
393 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
394 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
395 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
396 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
397 { "match", sMatch, SSHCFG_ALL },
398 { "permitopen", sPermitOpen, SSHCFG_ALL },
399 { "forcecommand", sForceCommand, SSHCFG_ALL },
400 { NULL, sBadOption, 0 }
404 * Returns the number of the token pointed to by cp or sBadOption.
408 parse_token(const char *cp, const char *filename,
409 int linenum, u_int *flags)
413 for (i = 0; keywords[i].name; i++)
414 if (strcasecmp(cp, keywords[i].name) == 0) {
415 *flags = keywords[i].flags;
416 return keywords[i].opcode;
419 error("%s: line %d: Bad configuration option: %s",
420 filename, linenum, cp);
425 add_listen_addr(ServerOptions *options, char *addr, u_short port)
429 if (options->num_ports == 0)
430 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
431 if (options->address_family == -1)
432 options->address_family = AF_UNSPEC;
434 for (i = 0; i < options->num_ports; i++)
435 add_one_listen_addr(options, addr, options->ports[i]);
437 add_one_listen_addr(options, addr, port);
441 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
443 struct addrinfo hints, *ai, *aitop;
444 char strport[NI_MAXSERV];
447 memset(&hints, 0, sizeof(hints));
448 hints.ai_family = options->address_family;
449 hints.ai_socktype = SOCK_STREAM;
450 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
451 snprintf(strport, sizeof strport, "%u", port);
452 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
453 fatal("bad addr or host: %s (%s)",
454 addr ? addr : "<NULL>",
455 gai_strerror(gaierr));
456 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
458 ai->ai_next = options->listen_addrs;
459 options->listen_addrs = aitop;
463 * The strategy for the Match blocks is that the config file is parsed twice.
465 * The first time is at startup. activep is initialized to 1 and the
466 * directives in the global context are processed and acted on. Hitting a
467 * Match directive unsets activep and the directives inside the block are
468 * checked for syntax only.
470 * The second time is after a connection has been established but before
471 * authentication. activep is initialized to 2 and global config directives
472 * are ignored since they have already been processed. If the criteria in a
473 * Match block is met, activep is set and the subsequent directives
474 * processed and actioned until EOF or another Match block unsets it. Any
475 * options set are copied into the main server config.
477 * Potential additions/improvements:
478 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
480 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
481 * Match Address 192.168.0.*
486 * AllowTcpForwarding yes
487 * GatewayPorts clientspecified
490 * - Add a PermittedChannelRequests directive
492 * PermittedChannelRequests session,forwarded-tcpip
496 match_cfg_line(char **condition, int line, const char *user, const char *host,
500 char *arg, *attrib, *cp = *condition;
504 debug3("checking syntax for 'Match %s'", cp);
506 debug3("checking match for '%s' user %s host %s addr %s", cp,
507 user ? user : "(null)", host ? host : "(null)",
508 address ? address : "(null)");
510 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
511 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
512 error("Missing Match criteria for %s", attrib);
516 if (strcasecmp(attrib, "user") == 0) {
521 if (match_pattern_list(user, arg, len, 0) != 1)
524 debug("user %.100s matched 'User %.100s' at "
525 "line %d", user, arg, line);
526 } else if (strcasecmp(attrib, "host") == 0) {
531 if (match_hostname(host, arg, len) != 1)
534 debug("connection from %.100s matched 'Host "
535 "%.100s' at line %d", host, arg, line);
536 } else if (strcasecmp(attrib, "address") == 0) {
537 debug("address '%s' arg '%s'", address, arg);
542 if (match_hostname(address, arg, len) != 1)
545 debug("connection from %.100s matched 'Address "
546 "%.100s' at line %d", address, arg, line);
548 error("Unsupported Match attribute %s", attrib);
553 debug3("match %sfound", result ? "" : "not ");
558 #define WHITESPACE " \t\r\n"
561 process_server_config_line(ServerOptions *options, char *line,
562 const char *filename, int linenum, int *activep, const char *user,
563 const char *host, const char *address)
565 char *cp, **charptr, *arg, *p;
566 int cmdline = 0, *intptr, value, n;
567 ServerOpCodes opcode;
573 if ((arg = strdelim(&cp)) == NULL)
575 /* Ignore leading whitespace */
578 if (!arg || !*arg || *arg == '#')
582 opcode = parse_token(arg, filename, linenum, &flags);
584 if (activep == NULL) { /* We are processing a command line directive */
588 if (*activep && opcode != sMatch)
589 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
590 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
592 fatal("%s line %d: Directive '%s' is not allowed "
593 "within a Match block", filename, linenum, arg);
594 } else { /* this is a directive we have already processed */
602 /* Portable-specific options */
604 intptr = &options->use_pam;
607 /* Standard Options */
611 /* ignore ports from configfile if cmdline specifies ports */
612 if (options->ports_from_cmdline)
614 if (options->listen_addrs != NULL)
615 fatal("%s line %d: ports must be specified before "
616 "ListenAddress.", filename, linenum);
617 if (options->num_ports >= MAX_PORTS)
618 fatal("%s line %d: too many ports.",
621 if (!arg || *arg == '\0')
622 fatal("%s line %d: missing port number.",
624 options->ports[options->num_ports++] = a2port(arg);
625 if (options->ports[options->num_ports-1] == 0)
626 fatal("%s line %d: Badly formatted port number.",
631 intptr = &options->server_key_bits;
634 if (!arg || *arg == '\0')
635 fatal("%s line %d: missing integer value.",
638 if (*activep && *intptr == -1)
642 case sLoginGraceTime:
643 intptr = &options->login_grace_time;
646 if (!arg || *arg == '\0')
647 fatal("%s line %d: missing time value.",
649 if ((value = convtime(arg)) == -1)
650 fatal("%s line %d: invalid time value.",
656 case sKeyRegenerationTime:
657 intptr = &options->key_regeneration_time;
662 if (arg == NULL || *arg == '\0')
663 fatal("%s line %d: missing address",
665 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
666 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
667 && strchr(p+1, ':') != NULL) {
668 add_listen_addr(options, arg, 0);
673 fatal("%s line %d: bad address:port usage",
675 p = cleanhostname(p);
678 else if ((port = a2port(arg)) == 0)
679 fatal("%s line %d: bad port number", filename, linenum);
681 add_listen_addr(options, p, port);
687 if (!arg || *arg == '\0')
688 fatal("%s line %d: missing address family.",
690 intptr = &options->address_family;
691 if (options->listen_addrs != NULL)
692 fatal("%s line %d: address family must be specified before "
693 "ListenAddress.", filename, linenum);
694 if (strcasecmp(arg, "inet") == 0)
696 else if (strcasecmp(arg, "inet6") == 0)
698 else if (strcasecmp(arg, "any") == 0)
701 fatal("%s line %d: unsupported address family \"%s\".",
702 filename, linenum, arg);
708 intptr = &options->num_host_key_files;
709 if (*intptr >= MAX_HOSTKEYS)
710 fatal("%s line %d: too many host keys specified (max %d).",
711 filename, linenum, MAX_HOSTKEYS);
712 charptr = &options->host_key_files[*intptr];
715 if (!arg || *arg == '\0')
716 fatal("%s line %d: missing file name.",
718 if (*activep && *charptr == NULL) {
719 *charptr = tilde_expand_filename(arg, getuid());
720 /* increase optional counter */
722 *intptr = *intptr + 1;
727 charptr = &options->pid_file;
730 case sPermitRootLogin:
731 intptr = &options->permit_root_login;
733 if (!arg || *arg == '\0')
734 fatal("%s line %d: missing yes/"
735 "without-password/forced-commands-only/no "
736 "argument.", filename, linenum);
737 value = 0; /* silence compiler */
738 if (strcmp(arg, "without-password") == 0)
739 value = PERMIT_NO_PASSWD;
740 else if (strcmp(arg, "forced-commands-only") == 0)
741 value = PERMIT_FORCED_ONLY;
742 else if (strcmp(arg, "yes") == 0)
744 else if (strcmp(arg, "no") == 0)
747 fatal("%s line %d: Bad yes/"
748 "without-password/forced-commands-only/no "
749 "argument: %s", filename, linenum, arg);
755 intptr = &options->ignore_rhosts;
758 if (!arg || *arg == '\0')
759 fatal("%s line %d: missing yes/no argument.",
761 value = 0; /* silence compiler */
762 if (strcmp(arg, "yes") == 0)
764 else if (strcmp(arg, "no") == 0)
767 fatal("%s line %d: Bad yes/no argument: %s",
768 filename, linenum, arg);
769 if (*activep && *intptr == -1)
773 case sIgnoreUserKnownHosts:
774 intptr = &options->ignore_user_known_hosts;
777 case sRhostsRSAAuthentication:
778 intptr = &options->rhosts_rsa_authentication;
781 case sHostbasedAuthentication:
782 intptr = &options->hostbased_authentication;
785 case sHostbasedUsesNameFromPacketOnly:
786 intptr = &options->hostbased_uses_name_from_packet_only;
789 case sRSAAuthentication:
790 intptr = &options->rsa_authentication;
793 case sPubkeyAuthentication:
794 intptr = &options->pubkey_authentication;
797 case sKerberosAuthentication:
798 intptr = &options->kerberos_authentication;
801 case sKerberosOrLocalPasswd:
802 intptr = &options->kerberos_or_local_passwd;
805 case sKerberosTicketCleanup:
806 intptr = &options->kerberos_ticket_cleanup;
809 case sKerberosGetAFSToken:
810 intptr = &options->kerberos_get_afs_token;
813 case sGssAuthentication:
814 intptr = &options->gss_authentication;
817 case sGssCleanupCreds:
818 intptr = &options->gss_cleanup_creds;
821 case sPasswordAuthentication:
822 intptr = &options->password_authentication;
825 case sKbdInteractiveAuthentication:
826 intptr = &options->kbd_interactive_authentication;
829 case sChallengeResponseAuthentication:
830 intptr = &options->challenge_response_authentication;
834 intptr = &options->print_motd;
838 intptr = &options->print_lastlog;
842 intptr = &options->x11_forwarding;
845 case sX11DisplayOffset:
846 intptr = &options->x11_display_offset;
849 case sX11UseLocalhost:
850 intptr = &options->x11_use_localhost;
854 charptr = &options->xauth_location;
858 intptr = &options->strict_modes;
862 intptr = &options->tcp_keep_alive;
866 intptr = &options->permit_empty_passwd;
869 case sPermitUserEnvironment:
870 intptr = &options->permit_user_env;
874 intptr = &options->use_login;
878 intptr = &options->compression;
880 if (!arg || *arg == '\0')
881 fatal("%s line %d: missing yes/no/delayed "
882 "argument.", filename, linenum);
883 value = 0; /* silence compiler */
884 if (strcmp(arg, "delayed") == 0)
885 value = COMP_DELAYED;
886 else if (strcmp(arg, "yes") == 0)
888 else if (strcmp(arg, "no") == 0)
891 fatal("%s line %d: Bad yes/no/delayed "
892 "argument: %s", filename, linenum, arg);
898 intptr = &options->gateway_ports;
900 if (!arg || *arg == '\0')
901 fatal("%s line %d: missing yes/no/clientspecified "
902 "argument.", filename, linenum);
903 value = 0; /* silence compiler */
904 if (strcmp(arg, "clientspecified") == 0)
906 else if (strcmp(arg, "yes") == 0)
908 else if (strcmp(arg, "no") == 0)
911 fatal("%s line %d: Bad yes/no/clientspecified "
912 "argument: %s", filename, linenum, arg);
918 intptr = &options->use_dns;
922 intptr = (int *) &options->log_facility;
924 value = log_facility_number(arg);
925 if (value == SYSLOG_FACILITY_NOT_SET)
926 fatal("%.200s line %d: unsupported log facility '%s'",
927 filename, linenum, arg ? arg : "<NONE>");
929 *intptr = (SyslogFacility) value;
933 intptr = (int *) &options->log_level;
935 value = log_level_number(arg);
936 if (value == SYSLOG_LEVEL_NOT_SET)
937 fatal("%.200s line %d: unsupported log level '%s'",
938 filename, linenum, arg ? arg : "<NONE>");
940 *intptr = (LogLevel) value;
943 case sAllowTcpForwarding:
944 intptr = &options->allow_tcp_forwarding;
947 case sUsePrivilegeSeparation:
948 intptr = &use_privsep;
952 while ((arg = strdelim(&cp)) && *arg != '\0') {
953 if (options->num_allow_users >= MAX_ALLOW_USERS)
954 fatal("%s line %d: too many allow users.",
956 options->allow_users[options->num_allow_users++] =
962 while ((arg = strdelim(&cp)) && *arg != '\0') {
963 if (options->num_deny_users >= MAX_DENY_USERS)
964 fatal( "%s line %d: too many deny users.",
966 options->deny_users[options->num_deny_users++] =
972 while ((arg = strdelim(&cp)) && *arg != '\0') {
973 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
974 fatal("%s line %d: too many allow groups.",
976 options->allow_groups[options->num_allow_groups++] =
982 while ((arg = strdelim(&cp)) && *arg != '\0') {
983 if (options->num_deny_groups >= MAX_DENY_GROUPS)
984 fatal("%s line %d: too many deny groups.",
986 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
992 if (!arg || *arg == '\0')
993 fatal("%s line %d: Missing argument.", filename, linenum);
994 if (!ciphers_valid(arg))
995 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
996 filename, linenum, arg ? arg : "<NONE>");
997 if (options->ciphers == NULL)
998 options->ciphers = xstrdup(arg);
1002 arg = strdelim(&cp);
1003 if (!arg || *arg == '\0')
1004 fatal("%s line %d: Missing argument.", filename, linenum);
1005 if (!mac_valid(arg))
1006 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1007 filename, linenum, arg ? arg : "<NONE>");
1008 if (options->macs == NULL)
1009 options->macs = xstrdup(arg);
1013 intptr = &options->protocol;
1014 arg = strdelim(&cp);
1015 if (!arg || *arg == '\0')
1016 fatal("%s line %d: Missing argument.", filename, linenum);
1017 value = proto_spec(arg);
1018 if (value == SSH_PROTO_UNKNOWN)
1019 fatal("%s line %d: Bad protocol spec '%s'.",
1020 filename, linenum, arg ? arg : "<NONE>");
1021 if (*intptr == SSH_PROTO_UNKNOWN)
1026 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1027 fatal("%s line %d: too many subsystems defined.",
1030 arg = strdelim(&cp);
1031 if (!arg || *arg == '\0')
1032 fatal("%s line %d: Missing subsystem name.",
1035 arg = strdelim(&cp);
1038 for (i = 0; i < options->num_subsystems; i++)
1039 if (strcmp(arg, options->subsystem_name[i]) == 0)
1040 fatal("%s line %d: Subsystem '%s' already defined.",
1041 filename, linenum, arg);
1042 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1043 arg = strdelim(&cp);
1044 if (!arg || *arg == '\0')
1045 fatal("%s line %d: Missing subsystem command.",
1047 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1049 /* Collect arguments (separate to executable) */
1051 len = strlen(p) + 1;
1052 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1053 len += 1 + strlen(arg);
1054 p = xrealloc(p, 1, len);
1055 strlcat(p, " ", len);
1056 strlcat(p, arg, len);
1058 options->subsystem_args[options->num_subsystems] = p;
1059 options->num_subsystems++;
1063 arg = strdelim(&cp);
1064 if (!arg || *arg == '\0')
1065 fatal("%s line %d: Missing MaxStartups spec.",
1067 if ((n = sscanf(arg, "%d:%d:%d",
1068 &options->max_startups_begin,
1069 &options->max_startups_rate,
1070 &options->max_startups)) == 3) {
1071 if (options->max_startups_begin >
1072 options->max_startups ||
1073 options->max_startups_rate > 100 ||
1074 options->max_startups_rate < 1)
1075 fatal("%s line %d: Illegal MaxStartups spec.",
1078 fatal("%s line %d: Illegal MaxStartups spec.",
1081 options->max_startups = options->max_startups_begin;
1085 intptr = &options->max_authtries;
1089 charptr = &options->banner;
1090 goto parse_filename;
1092 * These options can contain %X options expanded at
1093 * connect time, so that you can specify paths like:
1095 * AuthorizedKeysFile /etc/ssh_keys/%u
1097 case sAuthorizedKeysFile:
1098 case sAuthorizedKeysFile2:
1099 charptr = (opcode == sAuthorizedKeysFile ) ?
1100 &options->authorized_keys_file :
1101 &options->authorized_keys_file2;
1102 goto parse_filename;
1104 case sClientAliveInterval:
1105 intptr = &options->client_alive_interval;
1108 case sClientAliveCountMax:
1109 intptr = &options->client_alive_count_max;
1113 while ((arg = strdelim(&cp)) && *arg != '\0') {
1114 if (strchr(arg, '=') != NULL)
1115 fatal("%s line %d: Invalid environment name.",
1117 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1118 fatal("%s line %d: too many allow env.",
1122 options->accept_env[options->num_accept_env++] =
1128 intptr = &options->permit_tun;
1129 arg = strdelim(&cp);
1130 if (!arg || *arg == '\0')
1131 fatal("%s line %d: Missing yes/point-to-point/"
1132 "ethernet/no argument.", filename, linenum);
1133 value = 0; /* silence compiler */
1134 if (strcasecmp(arg, "ethernet") == 0)
1135 value = SSH_TUNMODE_ETHERNET;
1136 else if (strcasecmp(arg, "point-to-point") == 0)
1137 value = SSH_TUNMODE_POINTOPOINT;
1138 else if (strcasecmp(arg, "yes") == 0)
1139 value = SSH_TUNMODE_YES;
1140 else if (strcasecmp(arg, "no") == 0)
1141 value = SSH_TUNMODE_NO;
1143 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1144 "no argument: %s", filename, linenum, arg);
1151 fatal("Match directive not supported as a command-line "
1153 value = match_cfg_line(&cp, linenum, user, host, address);
1155 fatal("%s line %d: Bad Match condition", filename,
1161 arg = strdelim(&cp);
1162 if (!arg || *arg == '\0')
1163 fatal("%s line %d: missing PermitOpen specification",
1165 if (strcmp(arg, "any") == 0) {
1167 channel_clear_adm_permitted_opens();
1168 options->num_permitted_opens = 0;
1172 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1175 fatal("%s line %d: missing host in PermitOpen",
1177 p = cleanhostname(p);
1178 if (arg == NULL || (port = a2port(arg)) == 0)
1179 fatal("%s line %d: bad port number in "
1180 "PermitOpen", filename, linenum);
1181 if (*activep && options->num_permitted_opens == -1) {
1182 channel_clear_adm_permitted_opens();
1183 options->num_permitted_opens =
1184 channel_add_adm_permitted_opens(p, port);
1191 fatal("%.200s line %d: Missing argument.", filename,
1193 len = strspn(cp, WHITESPACE);
1194 if (*activep && options->adm_forced_command == NULL)
1195 options->adm_forced_command = xstrdup(cp + len);
1199 logit("%s line %d: Deprecated option %s",
1200 filename, linenum, arg);
1202 arg = strdelim(&cp);
1206 logit("%s line %d: Unsupported option %s",
1207 filename, linenum, arg);
1209 arg = strdelim(&cp);
1213 fatal("%s line %d: Missing handler for opcode %s (%d)",
1214 filename, linenum, arg, opcode);
1216 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1217 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1218 filename, linenum, arg);
1222 /* Reads the server configuration file. */
1225 load_server_config(const char *filename, Buffer *conf)
1227 char line[1024], *cp;
1230 debug2("%s: filename %s", __func__, filename);
1231 if ((f = fopen(filename, "r")) == NULL) {
1236 while (fgets(line, sizeof(line), f)) {
1238 * Trim out comments and strip whitespace
1239 * NB - preserve newlines, they are needed to reproduce
1240 * line numbers later for error messages
1242 if ((cp = strchr(line, '#')) != NULL)
1243 memcpy(cp, "\n", 2);
1244 cp = line + strspn(line, " \t\r");
1246 buffer_append(conf, cp, strlen(cp));
1248 buffer_append(conf, "\0", 1);
1250 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1254 parse_server_match_config(ServerOptions *options, const char *user,
1255 const char *host, const char *address)
1259 initialize_server_options(&mo);
1260 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1261 copy_set_server_options(options, &mo);
1264 /* Copy any (supported) values that are set */
1266 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1268 if (src->allow_tcp_forwarding != -1)
1269 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1270 if (src->gateway_ports != -1)
1271 dst->gateway_ports = src->gateway_ports;
1272 if (src->adm_forced_command != NULL) {
1273 if (dst->adm_forced_command != NULL)
1274 xfree(dst->adm_forced_command);
1275 dst->adm_forced_command = src->adm_forced_command;
1277 if (src->x11_display_offset != -1)
1278 dst->x11_display_offset = src->x11_display_offset;
1279 if (src->x11_forwarding != -1)
1280 dst->x11_forwarding = src->x11_forwarding;
1281 if (src->x11_use_localhost != -1)
1282 dst->x11_use_localhost = src->x11_use_localhost;
1286 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1287 const char *user, const char *host, const char *address)
1289 int active, linenum, bad_options = 0;
1290 char *cp, *obuf, *cbuf;
1292 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1294 obuf = cbuf = xstrdup(buffer_ptr(conf));
1295 active = user ? 0 : 1;
1297 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1298 if (process_server_config_line(options, cp, filename,
1299 linenum++, &active, user, host, address) != 0)
1303 if (bad_options > 0)
1304 fatal("%s: terminating, %d bad configuration options",
1305 filename, bad_options);