xref: /freebsd/crypto/openssh/servconf.c (revision d056fa046c6a91b90cd98165face0e42a33a5173)
1 /*
2  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3  *                    All rights reserved
4  *
5  * As far as I am concerned, the code I have written for this software
6  * can be used freely for any purpose.  Any derived versions of this
7  * software must be clearly marked as such, and if the derived work is
8  * incompatible with the protocol description in the RFC file, it must be
9  * called by a name other than "ssh" or "Secure Shell".
10  */
11 
12 #include "includes.h"
13 RCSID("$OpenBSD: servconf.c,v 1.146 2005/12/08 18:34:11 reyk Exp $");
14 RCSID("$FreeBSD$");
15 
16 #include "ssh.h"
17 #include "log.h"
18 #include "servconf.h"
19 #include "xmalloc.h"
20 #include "compat.h"
21 #include "pathnames.h"
22 #include "misc.h"
23 #include "cipher.h"
24 #include "kex.h"
25 #include "mac.h"
26 
27 static void add_listen_addr(ServerOptions *, char *, u_short);
28 static void add_one_listen_addr(ServerOptions *, char *, u_short);
29 
30 /* Use of privilege separation or not */
31 extern int use_privsep;
32 
33 /* Initializes the server options to their default values. */
34 
35 void
36 initialize_server_options(ServerOptions *options)
37 {
38 	memset(options, 0, sizeof(*options));
39 
40 	/* Portable-specific options */
41 	options->use_pam = -1;
42 
43 	/* Standard Options */
44 	options->num_ports = 0;
45 	options->ports_from_cmdline = 0;
46 	options->listen_addrs = NULL;
47 	options->address_family = -1;
48 	options->num_host_key_files = 0;
49 	options->pid_file = NULL;
50 	options->server_key_bits = -1;
51 	options->login_grace_time = -1;
52 	options->key_regeneration_time = -1;
53 	options->permit_root_login = PERMIT_NOT_SET;
54 	options->ignore_rhosts = -1;
55 	options->ignore_user_known_hosts = -1;
56 	options->print_motd = -1;
57 	options->print_lastlog = -1;
58 	options->x11_forwarding = -1;
59 	options->x11_display_offset = -1;
60 	options->x11_use_localhost = -1;
61 	options->xauth_location = NULL;
62 	options->strict_modes = -1;
63 	options->tcp_keep_alive = -1;
64 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
65 	options->log_level = SYSLOG_LEVEL_NOT_SET;
66 	options->rhosts_rsa_authentication = -1;
67 	options->hostbased_authentication = -1;
68 	options->hostbased_uses_name_from_packet_only = -1;
69 	options->rsa_authentication = -1;
70 	options->pubkey_authentication = -1;
71 	options->kerberos_authentication = -1;
72 	options->kerberos_or_local_passwd = -1;
73 	options->kerberos_ticket_cleanup = -1;
74 	options->kerberos_get_afs_token = -1;
75 	options->gss_authentication=-1;
76 	options->gss_cleanup_creds = -1;
77 	options->password_authentication = -1;
78 	options->kbd_interactive_authentication = -1;
79 	options->challenge_response_authentication = -1;
80 	options->permit_empty_passwd = -1;
81 	options->permit_user_env = -1;
82 	options->use_login = -1;
83 	options->compression = -1;
84 	options->allow_tcp_forwarding = -1;
85 	options->num_allow_users = 0;
86 	options->num_deny_users = 0;
87 	options->num_allow_groups = 0;
88 	options->num_deny_groups = 0;
89 	options->ciphers = NULL;
90 	options->macs = NULL;
91 	options->protocol = SSH_PROTO_UNKNOWN;
92 	options->gateway_ports = -1;
93 	options->num_subsystems = 0;
94 	options->max_startups_begin = -1;
95 	options->max_startups_rate = -1;
96 	options->max_startups = -1;
97 	options->max_authtries = -1;
98 	options->banner = NULL;
99 	options->use_dns = -1;
100 	options->client_alive_interval = -1;
101 	options->client_alive_count_max = -1;
102 	options->authorized_keys_file = NULL;
103 	options->authorized_keys_file2 = NULL;
104 	options->num_accept_env = 0;
105 	options->permit_tun = -1;
106 
107 	/* Needs to be accessable in many places */
108 	use_privsep = -1;
109 }
110 
111 void
112 fill_default_server_options(ServerOptions *options)
113 {
114 	/* Portable-specific options */
115 	if (options->use_pam == -1)
116 		options->use_pam = 1;
117 
118 	/* Standard Options */
119 	if (options->protocol == SSH_PROTO_UNKNOWN)
120 		options->protocol = SSH_PROTO_2;
121 	if (options->num_host_key_files == 0) {
122 		/* fill default hostkeys for protocols */
123 		if (options->protocol & SSH_PROTO_1)
124 			options->host_key_files[options->num_host_key_files++] =
125 			    _PATH_HOST_KEY_FILE;
126 		if (options->protocol & SSH_PROTO_2) {
127 			options->host_key_files[options->num_host_key_files++] =
128 			    _PATH_HOST_DSA_KEY_FILE;
129 		}
130 	}
131 	if (options->num_ports == 0)
132 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
133 	if (options->listen_addrs == NULL)
134 		add_listen_addr(options, NULL, 0);
135 	if (options->pid_file == NULL)
136 		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
137 	if (options->server_key_bits == -1)
138 		options->server_key_bits = 768;
139 	if (options->login_grace_time == -1)
140 		options->login_grace_time = 120;
141 	if (options->key_regeneration_time == -1)
142 		options->key_regeneration_time = 3600;
143 	if (options->permit_root_login == PERMIT_NOT_SET)
144 		options->permit_root_login = PERMIT_NO;
145 	if (options->ignore_rhosts == -1)
146 		options->ignore_rhosts = 1;
147 	if (options->ignore_user_known_hosts == -1)
148 		options->ignore_user_known_hosts = 0;
149 	if (options->print_motd == -1)
150 		options->print_motd = 1;
151 	if (options->print_lastlog == -1)
152 		options->print_lastlog = 1;
153 	if (options->x11_forwarding == -1)
154 		options->x11_forwarding = 1;
155 	if (options->x11_display_offset == -1)
156 		options->x11_display_offset = 10;
157 	if (options->x11_use_localhost == -1)
158 		options->x11_use_localhost = 1;
159 	if (options->xauth_location == NULL)
160 		options->xauth_location = _PATH_XAUTH;
161 	if (options->strict_modes == -1)
162 		options->strict_modes = 1;
163 	if (options->tcp_keep_alive == -1)
164 		options->tcp_keep_alive = 1;
165 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
166 		options->log_facility = SYSLOG_FACILITY_AUTH;
167 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
168 		options->log_level = SYSLOG_LEVEL_INFO;
169 	if (options->rhosts_rsa_authentication == -1)
170 		options->rhosts_rsa_authentication = 0;
171 	if (options->hostbased_authentication == -1)
172 		options->hostbased_authentication = 0;
173 	if (options->hostbased_uses_name_from_packet_only == -1)
174 		options->hostbased_uses_name_from_packet_only = 0;
175 	if (options->rsa_authentication == -1)
176 		options->rsa_authentication = 1;
177 	if (options->pubkey_authentication == -1)
178 		options->pubkey_authentication = 1;
179 	if (options->kerberos_authentication == -1)
180 		options->kerberos_authentication = 0;
181 	if (options->kerberos_or_local_passwd == -1)
182 		options->kerberos_or_local_passwd = 1;
183 	if (options->kerberos_ticket_cleanup == -1)
184 		options->kerberos_ticket_cleanup = 1;
185 	if (options->kerberos_get_afs_token == -1)
186 		options->kerberos_get_afs_token = 0;
187 	if (options->gss_authentication == -1)
188 		options->gss_authentication = 0;
189 	if (options->gss_cleanup_creds == -1)
190 		options->gss_cleanup_creds = 1;
191 	if (options->password_authentication == -1)
192 #ifdef USE_PAM
193 		options->password_authentication = 0;
194 #else
195 		options->password_authentication = 1;
196 #endif
197 	if (options->kbd_interactive_authentication == -1)
198 		options->kbd_interactive_authentication = 0;
199 	if (options->challenge_response_authentication == -1)
200 		options->challenge_response_authentication = 1;
201 	if (options->permit_empty_passwd == -1)
202 		options->permit_empty_passwd = 0;
203 	if (options->permit_user_env == -1)
204 		options->permit_user_env = 0;
205 	if (options->use_login == -1)
206 		options->use_login = 0;
207 	if (options->compression == -1)
208 		options->compression = COMP_DELAYED;
209 	if (options->allow_tcp_forwarding == -1)
210 		options->allow_tcp_forwarding = 1;
211 	if (options->gateway_ports == -1)
212 		options->gateway_ports = 0;
213 	if (options->max_startups == -1)
214 		options->max_startups = 10;
215 	if (options->max_startups_rate == -1)
216 		options->max_startups_rate = 100;		/* 100% */
217 	if (options->max_startups_begin == -1)
218 		options->max_startups_begin = options->max_startups;
219 	if (options->max_authtries == -1)
220 		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
221 	if (options->use_dns == -1)
222 		options->use_dns = 1;
223 	if (options->client_alive_interval == -1)
224 		options->client_alive_interval = 0;
225 	if (options->client_alive_count_max == -1)
226 		options->client_alive_count_max = 3;
227 	if (options->authorized_keys_file2 == NULL) {
228 		/* authorized_keys_file2 falls back to authorized_keys_file */
229 		if (options->authorized_keys_file != NULL)
230 			options->authorized_keys_file2 = options->authorized_keys_file;
231 		else
232 			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
233 	}
234 	if (options->authorized_keys_file == NULL)
235 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
236 	if (options->permit_tun == -1)
237 		options->permit_tun = SSH_TUNMODE_NO;
238 
239 	/* Turn privilege separation on by default */
240 	if (use_privsep == -1)
241 		use_privsep = 1;
242 
243 #ifndef HAVE_MMAP
244 	if (use_privsep && options->compression == 1) {
245 		error("This platform does not support both privilege "
246 		    "separation and compression");
247 		error("Compression disabled");
248 		options->compression = 0;
249 	}
250 #endif
251 
252 }
253 
254 /* Keyword tokens. */
255 typedef enum {
256 	sBadOption,		/* == unknown option */
257 	/* Portable-specific options */
258 	sUsePAM,
259 	/* Standard Options */
260 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
261 	sPermitRootLogin, sLogFacility, sLogLevel,
262 	sRhostsRSAAuthentication, sRSAAuthentication,
263 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
264 	sKerberosGetAFSToken,
265 	sKerberosTgtPassing, sChallengeResponseAuthentication,
266 	sPasswordAuthentication, sKbdInteractiveAuthentication,
267 	sListenAddress, sAddressFamily,
268 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
269 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
270 	sStrictModes, sEmptyPasswd, sTCPKeepAlive,
271 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
272 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
273 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
274 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
275 	sMaxStartups, sMaxAuthTries,
276 	sBanner, sUseDNS, sHostbasedAuthentication,
277 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
278 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
279 	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
280 	sUsePrivilegeSeparation,
281 	sVersionAddendum,
282 	sDeprecated, sUnsupported
283 } ServerOpCodes;
284 
285 /* Textual representation of the tokens. */
286 static struct {
287 	const char *name;
288 	ServerOpCodes opcode;
289 } keywords[] = {
290 	/* Portable-specific options */
291 #ifdef USE_PAM
292 	{ "usepam", sUsePAM },
293 #else
294 	{ "usepam", sUnsupported },
295 #endif
296 	{ "pamauthenticationviakbdint", sDeprecated },
297 	/* Standard Options */
298 	{ "port", sPort },
299 	{ "hostkey", sHostKeyFile },
300 	{ "hostdsakey", sHostKeyFile },					/* alias */
301 	{ "pidfile", sPidFile },
302 	{ "serverkeybits", sServerKeyBits },
303 	{ "logingracetime", sLoginGraceTime },
304 	{ "keyregenerationinterval", sKeyRegenerationTime },
305 	{ "permitrootlogin", sPermitRootLogin },
306 	{ "syslogfacility", sLogFacility },
307 	{ "loglevel", sLogLevel },
308 	{ "rhostsauthentication", sDeprecated },
309 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
310 	{ "hostbasedauthentication", sHostbasedAuthentication },
311 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
312 	{ "rsaauthentication", sRSAAuthentication },
313 	{ "pubkeyauthentication", sPubkeyAuthentication },
314 	{ "dsaauthentication", sPubkeyAuthentication },			/* alias */
315 #ifdef KRB5
316 	{ "kerberosauthentication", sKerberosAuthentication },
317 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
318 	{ "kerberosticketcleanup", sKerberosTicketCleanup },
319 #ifdef USE_AFS
320 	{ "kerberosgetafstoken", sKerberosGetAFSToken },
321 #else
322 	{ "kerberosgetafstoken", sUnsupported },
323 #endif
324 #else
325 	{ "kerberosauthentication", sUnsupported },
326 	{ "kerberosorlocalpasswd", sUnsupported },
327 	{ "kerberosticketcleanup", sUnsupported },
328 	{ "kerberosgetafstoken", sUnsupported },
329 #endif
330 	{ "kerberostgtpassing", sUnsupported },
331 	{ "afstokenpassing", sUnsupported },
332 #ifdef GSSAPI
333 	{ "gssapiauthentication", sGssAuthentication },
334 	{ "gssapicleanupcredentials", sGssCleanupCreds },
335 #else
336 	{ "gssapiauthentication", sUnsupported },
337 	{ "gssapicleanupcredentials", sUnsupported },
338 #endif
339 	{ "passwordauthentication", sPasswordAuthentication },
340 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
341 	{ "challengeresponseauthentication", sChallengeResponseAuthentication },
342 	{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
343 	{ "checkmail", sDeprecated },
344 	{ "listenaddress", sListenAddress },
345 	{ "addressfamily", sAddressFamily },
346 	{ "printmotd", sPrintMotd },
347 	{ "printlastlog", sPrintLastLog },
348 	{ "ignorerhosts", sIgnoreRhosts },
349 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
350 	{ "x11forwarding", sX11Forwarding },
351 	{ "x11displayoffset", sX11DisplayOffset },
352 	{ "x11uselocalhost", sX11UseLocalhost },
353 	{ "xauthlocation", sXAuthLocation },
354 	{ "strictmodes", sStrictModes },
355 	{ "permitemptypasswords", sEmptyPasswd },
356 	{ "permituserenvironment", sPermitUserEnvironment },
357 	{ "uselogin", sUseLogin },
358 	{ "compression", sCompression },
359 	{ "tcpkeepalive", sTCPKeepAlive },
360 	{ "keepalive", sTCPKeepAlive },				/* obsolete alias */
361 	{ "allowtcpforwarding", sAllowTcpForwarding },
362 	{ "allowusers", sAllowUsers },
363 	{ "denyusers", sDenyUsers },
364 	{ "allowgroups", sAllowGroups },
365 	{ "denygroups", sDenyGroups },
366 	{ "ciphers", sCiphers },
367 	{ "macs", sMacs },
368 	{ "protocol", sProtocol },
369 	{ "gatewayports", sGatewayPorts },
370 	{ "subsystem", sSubsystem },
371 	{ "maxstartups", sMaxStartups },
372 	{ "maxauthtries", sMaxAuthTries },
373 	{ "banner", sBanner },
374 	{ "usedns", sUseDNS },
375 	{ "verifyreversemapping", sDeprecated },
376 	{ "reversemappingcheck", sDeprecated },
377 	{ "clientaliveinterval", sClientAliveInterval },
378 	{ "clientalivecountmax", sClientAliveCountMax },
379 	{ "authorizedkeysfile", sAuthorizedKeysFile },
380 	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
381 	{ "useprivilegeseparation", sUsePrivilegeSeparation},
382 	{ "acceptenv", sAcceptEnv },
383 	{ "permittunnel", sPermitTunnel },
384 	{ "versionaddendum", sVersionAddendum },
385 	{ NULL, sBadOption }
386 };
387 
388 /*
389  * Returns the number of the token pointed to by cp or sBadOption.
390  */
391 
392 static ServerOpCodes
393 parse_token(const char *cp, const char *filename,
394 	    int linenum)
395 {
396 	u_int i;
397 
398 	for (i = 0; keywords[i].name; i++)
399 		if (strcasecmp(cp, keywords[i].name) == 0)
400 			return keywords[i].opcode;
401 
402 	error("%s: line %d: Bad configuration option: %s",
403 	    filename, linenum, cp);
404 	return sBadOption;
405 }
406 
407 static void
408 add_listen_addr(ServerOptions *options, char *addr, u_short port)
409 {
410 	u_int i;
411 
412 	if (options->num_ports == 0)
413 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
414 	if (options->address_family == -1)
415 		options->address_family = AF_UNSPEC;
416 	if (port == 0)
417 		for (i = 0; i < options->num_ports; i++)
418 			add_one_listen_addr(options, addr, options->ports[i]);
419 	else
420 		add_one_listen_addr(options, addr, port);
421 }
422 
423 static void
424 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
425 {
426 	struct addrinfo hints, *ai, *aitop;
427 	char strport[NI_MAXSERV];
428 	int gaierr;
429 
430 	memset(&hints, 0, sizeof(hints));
431 	hints.ai_family = options->address_family;
432 	hints.ai_socktype = SOCK_STREAM;
433 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
434 	snprintf(strport, sizeof strport, "%u", port);
435 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
436 		fatal("bad addr or host: %s (%s)",
437 		    addr ? addr : "<NULL>",
438 		    gai_strerror(gaierr));
439 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
440 		;
441 	ai->ai_next = options->listen_addrs;
442 	options->listen_addrs = aitop;
443 }
444 
445 int
446 process_server_config_line(ServerOptions *options, char *line,
447     const char *filename, int linenum)
448 {
449 	char *cp, **charptr, *arg, *p;
450 	int *intptr, value, n;
451 	ServerOpCodes opcode;
452 	u_short port;
453 	u_int i;
454 
455 	cp = line;
456 	arg = strdelim(&cp);
457 	/* Ignore leading whitespace */
458 	if (*arg == '\0')
459 		arg = strdelim(&cp);
460 	if (!arg || !*arg || *arg == '#')
461 		return 0;
462 	intptr = NULL;
463 	charptr = NULL;
464 	opcode = parse_token(arg, filename, linenum);
465 	switch (opcode) {
466 	/* Portable-specific options */
467 	case sUsePAM:
468 		intptr = &options->use_pam;
469 		goto parse_flag;
470 
471 	/* Standard Options */
472 	case sBadOption:
473 		return -1;
474 	case sPort:
475 		/* ignore ports from configfile if cmdline specifies ports */
476 		if (options->ports_from_cmdline)
477 			return 0;
478 		if (options->listen_addrs != NULL)
479 			fatal("%s line %d: ports must be specified before "
480 			    "ListenAddress.", filename, linenum);
481 		if (options->num_ports >= MAX_PORTS)
482 			fatal("%s line %d: too many ports.",
483 			    filename, linenum);
484 		arg = strdelim(&cp);
485 		if (!arg || *arg == '\0')
486 			fatal("%s line %d: missing port number.",
487 			    filename, linenum);
488 		options->ports[options->num_ports++] = a2port(arg);
489 		if (options->ports[options->num_ports-1] == 0)
490 			fatal("%s line %d: Badly formatted port number.",
491 			    filename, linenum);
492 		break;
493 
494 	case sServerKeyBits:
495 		intptr = &options->server_key_bits;
496 parse_int:
497 		arg = strdelim(&cp);
498 		if (!arg || *arg == '\0')
499 			fatal("%s line %d: missing integer value.",
500 			    filename, linenum);
501 		value = atoi(arg);
502 		if (*intptr == -1)
503 			*intptr = value;
504 		break;
505 
506 	case sLoginGraceTime:
507 		intptr = &options->login_grace_time;
508 parse_time:
509 		arg = strdelim(&cp);
510 		if (!arg || *arg == '\0')
511 			fatal("%s line %d: missing time value.",
512 			    filename, linenum);
513 		if ((value = convtime(arg)) == -1)
514 			fatal("%s line %d: invalid time value.",
515 			    filename, linenum);
516 		if (*intptr == -1)
517 			*intptr = value;
518 		break;
519 
520 	case sKeyRegenerationTime:
521 		intptr = &options->key_regeneration_time;
522 		goto parse_time;
523 
524 	case sListenAddress:
525 		arg = strdelim(&cp);
526 		if (arg == NULL || *arg == '\0')
527 			fatal("%s line %d: missing address",
528 			    filename, linenum);
529 		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
530 		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
531 		    && strchr(p+1, ':') != NULL) {
532 			add_listen_addr(options, arg, 0);
533 			break;
534 		}
535 		p = hpdelim(&arg);
536 		if (p == NULL)
537 			fatal("%s line %d: bad address:port usage",
538 			    filename, linenum);
539 		p = cleanhostname(p);
540 		if (arg == NULL)
541 			port = 0;
542 		else if ((port = a2port(arg)) == 0)
543 			fatal("%s line %d: bad port number", filename, linenum);
544 
545 		add_listen_addr(options, p, port);
546 
547 		break;
548 
549 	case sAddressFamily:
550 		arg = strdelim(&cp);
551 		if (!arg || *arg == '\0')
552 			fatal("%s line %d: missing address family.",
553 			    filename, linenum);
554 		intptr = &options->address_family;
555 		if (options->listen_addrs != NULL)
556 			fatal("%s line %d: address family must be specified before "
557 			    "ListenAddress.", filename, linenum);
558 		if (strcasecmp(arg, "inet") == 0)
559 			value = AF_INET;
560 		else if (strcasecmp(arg, "inet6") == 0)
561 			value = AF_INET6;
562 		else if (strcasecmp(arg, "any") == 0)
563 			value = AF_UNSPEC;
564 		else
565 			fatal("%s line %d: unsupported address family \"%s\".",
566 			    filename, linenum, arg);
567 		if (*intptr == -1)
568 			*intptr = value;
569 		break;
570 
571 	case sHostKeyFile:
572 		intptr = &options->num_host_key_files;
573 		if (*intptr >= MAX_HOSTKEYS)
574 			fatal("%s line %d: too many host keys specified (max %d).",
575 			    filename, linenum, MAX_HOSTKEYS);
576 		charptr = &options->host_key_files[*intptr];
577 parse_filename:
578 		arg = strdelim(&cp);
579 		if (!arg || *arg == '\0')
580 			fatal("%s line %d: missing file name.",
581 			    filename, linenum);
582 		if (*charptr == NULL) {
583 			*charptr = tilde_expand_filename(arg, getuid());
584 			/* increase optional counter */
585 			if (intptr != NULL)
586 				*intptr = *intptr + 1;
587 		}
588 		break;
589 
590 	case sPidFile:
591 		charptr = &options->pid_file;
592 		goto parse_filename;
593 
594 	case sPermitRootLogin:
595 		intptr = &options->permit_root_login;
596 		arg = strdelim(&cp);
597 		if (!arg || *arg == '\0')
598 			fatal("%s line %d: missing yes/"
599 			    "without-password/forced-commands-only/no "
600 			    "argument.", filename, linenum);
601 		value = 0;	/* silence compiler */
602 		if (strcmp(arg, "without-password") == 0)
603 			value = PERMIT_NO_PASSWD;
604 		else if (strcmp(arg, "forced-commands-only") == 0)
605 			value = PERMIT_FORCED_ONLY;
606 		else if (strcmp(arg, "yes") == 0)
607 			value = PERMIT_YES;
608 		else if (strcmp(arg, "no") == 0)
609 			value = PERMIT_NO;
610 		else
611 			fatal("%s line %d: Bad yes/"
612 			    "without-password/forced-commands-only/no "
613 			    "argument: %s", filename, linenum, arg);
614 		if (*intptr == -1)
615 			*intptr = value;
616 		break;
617 
618 	case sIgnoreRhosts:
619 		intptr = &options->ignore_rhosts;
620 parse_flag:
621 		arg = strdelim(&cp);
622 		if (!arg || *arg == '\0')
623 			fatal("%s line %d: missing yes/no argument.",
624 			    filename, linenum);
625 		value = 0;	/* silence compiler */
626 		if (strcmp(arg, "yes") == 0)
627 			value = 1;
628 		else if (strcmp(arg, "no") == 0)
629 			value = 0;
630 		else
631 			fatal("%s line %d: Bad yes/no argument: %s",
632 				filename, linenum, arg);
633 		if (*intptr == -1)
634 			*intptr = value;
635 		break;
636 
637 	case sIgnoreUserKnownHosts:
638 		intptr = &options->ignore_user_known_hosts;
639 		goto parse_flag;
640 
641 	case sRhostsRSAAuthentication:
642 		intptr = &options->rhosts_rsa_authentication;
643 		goto parse_flag;
644 
645 	case sHostbasedAuthentication:
646 		intptr = &options->hostbased_authentication;
647 		goto parse_flag;
648 
649 	case sHostbasedUsesNameFromPacketOnly:
650 		intptr = &options->hostbased_uses_name_from_packet_only;
651 		goto parse_flag;
652 
653 	case sRSAAuthentication:
654 		intptr = &options->rsa_authentication;
655 		goto parse_flag;
656 
657 	case sPubkeyAuthentication:
658 		intptr = &options->pubkey_authentication;
659 		goto parse_flag;
660 
661 	case sKerberosAuthentication:
662 		intptr = &options->kerberos_authentication;
663 		goto parse_flag;
664 
665 	case sKerberosOrLocalPasswd:
666 		intptr = &options->kerberos_or_local_passwd;
667 		goto parse_flag;
668 
669 	case sKerberosTicketCleanup:
670 		intptr = &options->kerberos_ticket_cleanup;
671 		goto parse_flag;
672 
673 	case sKerberosGetAFSToken:
674 		intptr = &options->kerberos_get_afs_token;
675 		goto parse_flag;
676 
677 	case sGssAuthentication:
678 		intptr = &options->gss_authentication;
679 		goto parse_flag;
680 
681 	case sGssCleanupCreds:
682 		intptr = &options->gss_cleanup_creds;
683 		goto parse_flag;
684 
685 	case sPasswordAuthentication:
686 		intptr = &options->password_authentication;
687 		goto parse_flag;
688 
689 	case sKbdInteractiveAuthentication:
690 		intptr = &options->kbd_interactive_authentication;
691 		goto parse_flag;
692 
693 	case sChallengeResponseAuthentication:
694 		intptr = &options->challenge_response_authentication;
695 		goto parse_flag;
696 
697 	case sPrintMotd:
698 		intptr = &options->print_motd;
699 		goto parse_flag;
700 
701 	case sPrintLastLog:
702 		intptr = &options->print_lastlog;
703 		goto parse_flag;
704 
705 	case sX11Forwarding:
706 		intptr = &options->x11_forwarding;
707 		goto parse_flag;
708 
709 	case sX11DisplayOffset:
710 		intptr = &options->x11_display_offset;
711 		goto parse_int;
712 
713 	case sX11UseLocalhost:
714 		intptr = &options->x11_use_localhost;
715 		goto parse_flag;
716 
717 	case sXAuthLocation:
718 		charptr = &options->xauth_location;
719 		goto parse_filename;
720 
721 	case sStrictModes:
722 		intptr = &options->strict_modes;
723 		goto parse_flag;
724 
725 	case sTCPKeepAlive:
726 		intptr = &options->tcp_keep_alive;
727 		goto parse_flag;
728 
729 	case sEmptyPasswd:
730 		intptr = &options->permit_empty_passwd;
731 		goto parse_flag;
732 
733 	case sPermitUserEnvironment:
734 		intptr = &options->permit_user_env;
735 		goto parse_flag;
736 
737 	case sUseLogin:
738 		intptr = &options->use_login;
739 		goto parse_flag;
740 
741 	case sCompression:
742 		intptr = &options->compression;
743 		arg = strdelim(&cp);
744 		if (!arg || *arg == '\0')
745 			fatal("%s line %d: missing yes/no/delayed "
746 			    "argument.", filename, linenum);
747 		value = 0;	/* silence compiler */
748 		if (strcmp(arg, "delayed") == 0)
749 			value = COMP_DELAYED;
750 		else if (strcmp(arg, "yes") == 0)
751 			value = COMP_ZLIB;
752 		else if (strcmp(arg, "no") == 0)
753 			value = COMP_NONE;
754 		else
755 			fatal("%s line %d: Bad yes/no/delayed "
756 			    "argument: %s", filename, linenum, arg);
757 		if (*intptr == -1)
758 			*intptr = value;
759 		break;
760 
761 	case sGatewayPorts:
762 		intptr = &options->gateway_ports;
763 		arg = strdelim(&cp);
764 		if (!arg || *arg == '\0')
765 			fatal("%s line %d: missing yes/no/clientspecified "
766 			    "argument.", filename, linenum);
767 		value = 0;	/* silence compiler */
768 		if (strcmp(arg, "clientspecified") == 0)
769 			value = 2;
770 		else if (strcmp(arg, "yes") == 0)
771 			value = 1;
772 		else if (strcmp(arg, "no") == 0)
773 			value = 0;
774 		else
775 			fatal("%s line %d: Bad yes/no/clientspecified "
776 			    "argument: %s", filename, linenum, arg);
777 		if (*intptr == -1)
778 			*intptr = value;
779 		break;
780 
781 	case sUseDNS:
782 		intptr = &options->use_dns;
783 		goto parse_flag;
784 
785 	case sLogFacility:
786 		intptr = (int *) &options->log_facility;
787 		arg = strdelim(&cp);
788 		value = log_facility_number(arg);
789 		if (value == SYSLOG_FACILITY_NOT_SET)
790 			fatal("%.200s line %d: unsupported log facility '%s'",
791 			    filename, linenum, arg ? arg : "<NONE>");
792 		if (*intptr == -1)
793 			*intptr = (SyslogFacility) value;
794 		break;
795 
796 	case sLogLevel:
797 		intptr = (int *) &options->log_level;
798 		arg = strdelim(&cp);
799 		value = log_level_number(arg);
800 		if (value == SYSLOG_LEVEL_NOT_SET)
801 			fatal("%.200s line %d: unsupported log level '%s'",
802 			    filename, linenum, arg ? arg : "<NONE>");
803 		if (*intptr == -1)
804 			*intptr = (LogLevel) value;
805 		break;
806 
807 	case sAllowTcpForwarding:
808 		intptr = &options->allow_tcp_forwarding;
809 		goto parse_flag;
810 
811 	case sUsePrivilegeSeparation:
812 		intptr = &use_privsep;
813 		goto parse_flag;
814 
815 	case sAllowUsers:
816 		while ((arg = strdelim(&cp)) && *arg != '\0') {
817 			if (options->num_allow_users >= MAX_ALLOW_USERS)
818 				fatal("%s line %d: too many allow users.",
819 				    filename, linenum);
820 			options->allow_users[options->num_allow_users++] =
821 			    xstrdup(arg);
822 		}
823 		break;
824 
825 	case sDenyUsers:
826 		while ((arg = strdelim(&cp)) && *arg != '\0') {
827 			if (options->num_deny_users >= MAX_DENY_USERS)
828 				fatal( "%s line %d: too many deny users.",
829 				    filename, linenum);
830 			options->deny_users[options->num_deny_users++] =
831 			    xstrdup(arg);
832 		}
833 		break;
834 
835 	case sAllowGroups:
836 		while ((arg = strdelim(&cp)) && *arg != '\0') {
837 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
838 				fatal("%s line %d: too many allow groups.",
839 				    filename, linenum);
840 			options->allow_groups[options->num_allow_groups++] =
841 			    xstrdup(arg);
842 		}
843 		break;
844 
845 	case sDenyGroups:
846 		while ((arg = strdelim(&cp)) && *arg != '\0') {
847 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
848 				fatal("%s line %d: too many deny groups.",
849 				    filename, linenum);
850 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
851 		}
852 		break;
853 
854 	case sCiphers:
855 		arg = strdelim(&cp);
856 		if (!arg || *arg == '\0')
857 			fatal("%s line %d: Missing argument.", filename, linenum);
858 		if (!ciphers_valid(arg))
859 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
860 			    filename, linenum, arg ? arg : "<NONE>");
861 		if (options->ciphers == NULL)
862 			options->ciphers = xstrdup(arg);
863 		break;
864 
865 	case sMacs:
866 		arg = strdelim(&cp);
867 		if (!arg || *arg == '\0')
868 			fatal("%s line %d: Missing argument.", filename, linenum);
869 		if (!mac_valid(arg))
870 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
871 			    filename, linenum, arg ? arg : "<NONE>");
872 		if (options->macs == NULL)
873 			options->macs = xstrdup(arg);
874 		break;
875 
876 	case sProtocol:
877 		intptr = &options->protocol;
878 		arg = strdelim(&cp);
879 		if (!arg || *arg == '\0')
880 			fatal("%s line %d: Missing argument.", filename, linenum);
881 		value = proto_spec(arg);
882 		if (value == SSH_PROTO_UNKNOWN)
883 			fatal("%s line %d: Bad protocol spec '%s'.",
884 			    filename, linenum, arg ? arg : "<NONE>");
885 		if (*intptr == SSH_PROTO_UNKNOWN)
886 			*intptr = value;
887 		break;
888 
889 	case sSubsystem:
890 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
891 			fatal("%s line %d: too many subsystems defined.",
892 			    filename, linenum);
893 		}
894 		arg = strdelim(&cp);
895 		if (!arg || *arg == '\0')
896 			fatal("%s line %d: Missing subsystem name.",
897 			    filename, linenum);
898 		for (i = 0; i < options->num_subsystems; i++)
899 			if (strcmp(arg, options->subsystem_name[i]) == 0)
900 				fatal("%s line %d: Subsystem '%s' already defined.",
901 				    filename, linenum, arg);
902 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
903 		arg = strdelim(&cp);
904 		if (!arg || *arg == '\0')
905 			fatal("%s line %d: Missing subsystem command.",
906 			    filename, linenum);
907 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
908 		options->num_subsystems++;
909 		break;
910 
911 	case sMaxStartups:
912 		arg = strdelim(&cp);
913 		if (!arg || *arg == '\0')
914 			fatal("%s line %d: Missing MaxStartups spec.",
915 			    filename, linenum);
916 		if ((n = sscanf(arg, "%d:%d:%d",
917 		    &options->max_startups_begin,
918 		    &options->max_startups_rate,
919 		    &options->max_startups)) == 3) {
920 			if (options->max_startups_begin >
921 			    options->max_startups ||
922 			    options->max_startups_rate > 100 ||
923 			    options->max_startups_rate < 1)
924 				fatal("%s line %d: Illegal MaxStartups spec.",
925 				    filename, linenum);
926 		} else if (n != 1)
927 			fatal("%s line %d: Illegal MaxStartups spec.",
928 			    filename, linenum);
929 		else
930 			options->max_startups = options->max_startups_begin;
931 		break;
932 
933 	case sMaxAuthTries:
934 		intptr = &options->max_authtries;
935 		goto parse_int;
936 
937 	case sBanner:
938 		charptr = &options->banner;
939 		goto parse_filename;
940 	/*
941 	 * These options can contain %X options expanded at
942 	 * connect time, so that you can specify paths like:
943 	 *
944 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
945 	 */
946 	case sAuthorizedKeysFile:
947 	case sAuthorizedKeysFile2:
948 		charptr = (opcode == sAuthorizedKeysFile ) ?
949 		    &options->authorized_keys_file :
950 		    &options->authorized_keys_file2;
951 		goto parse_filename;
952 
953 	case sClientAliveInterval:
954 		intptr = &options->client_alive_interval;
955 		goto parse_time;
956 
957 	case sClientAliveCountMax:
958 		intptr = &options->client_alive_count_max;
959 		goto parse_int;
960 
961 	case sAcceptEnv:
962 		while ((arg = strdelim(&cp)) && *arg != '\0') {
963 			if (strchr(arg, '=') != NULL)
964 				fatal("%s line %d: Invalid environment name.",
965 				    filename, linenum);
966 			if (options->num_accept_env >= MAX_ACCEPT_ENV)
967 				fatal("%s line %d: too many allow env.",
968 				    filename, linenum);
969 			options->accept_env[options->num_accept_env++] =
970 			    xstrdup(arg);
971 		}
972 		break;
973 
974 	case sPermitTunnel:
975 		intptr = &options->permit_tun;
976 		arg = strdelim(&cp);
977 		if (!arg || *arg == '\0')
978 			fatal("%s line %d: Missing yes/point-to-point/"
979 			    "ethernet/no argument.", filename, linenum);
980 		value = 0;	/* silence compiler */
981 		if (strcasecmp(arg, "ethernet") == 0)
982 			value = SSH_TUNMODE_ETHERNET;
983 		else if (strcasecmp(arg, "point-to-point") == 0)
984 			value = SSH_TUNMODE_POINTOPOINT;
985 		else if (strcasecmp(arg, "yes") == 0)
986 			value = SSH_TUNMODE_YES;
987 		else if (strcasecmp(arg, "no") == 0)
988 			value = SSH_TUNMODE_NO;
989 		else
990 			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
991 			    "no argument: %s", filename, linenum, arg);
992 		if (*intptr == -1)
993 			*intptr = value;
994 		break;
995 
996 	case sVersionAddendum:
997                 ssh_version_set_addendum(strtok(cp, "\n"));
998                 do {
999                         arg = strdelim(&cp);
1000                 } while (arg != NULL && *arg != '\0');
1001 		break;
1002 
1003 	case sDeprecated:
1004 		logit("%s line %d: Deprecated option %s",
1005 		    filename, linenum, arg);
1006 		while (arg)
1007 		    arg = strdelim(&cp);
1008 		break;
1009 
1010 	case sUnsupported:
1011 		logit("%s line %d: Unsupported option %s",
1012 		    filename, linenum, arg);
1013 		while (arg)
1014 		    arg = strdelim(&cp);
1015 		break;
1016 
1017 	default:
1018 		fatal("%s line %d: Missing handler for opcode %s (%d)",
1019 		    filename, linenum, arg, opcode);
1020 	}
1021 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1022 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
1023 		    filename, linenum, arg);
1024 	return 0;
1025 }
1026 
1027 /* Reads the server configuration file. */
1028 
1029 void
1030 load_server_config(const char *filename, Buffer *conf)
1031 {
1032 	char line[1024], *cp;
1033 	FILE *f;
1034 
1035 	debug2("%s: filename %s", __func__, filename);
1036 	if ((f = fopen(filename, "r")) == NULL) {
1037 		perror(filename);
1038 		exit(1);
1039 	}
1040 	buffer_clear(conf);
1041 	while (fgets(line, sizeof(line), f)) {
1042 		/*
1043 		 * Trim out comments and strip whitespace
1044 		 * NB - preserve newlines, they are needed to reproduce
1045 		 * line numbers later for error messages
1046 		 */
1047 		if ((cp = strchr(line, '#')) != NULL)
1048 			memcpy(cp, "\n", 2);
1049 		cp = line + strspn(line, " \t\r");
1050 
1051 		buffer_append(conf, cp, strlen(cp));
1052 	}
1053 	buffer_append(conf, "\0", 1);
1054 	fclose(f);
1055 	debug2("%s: done config len = %d", __func__, buffer_len(conf));
1056 }
1057 
1058 void
1059 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
1060 {
1061 	int linenum, bad_options = 0;
1062 	char *cp, *obuf, *cbuf;
1063 
1064 	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1065 
1066 	obuf = cbuf = xstrdup(buffer_ptr(conf));
1067 	linenum = 1;
1068 	while ((cp = strsep(&cbuf, "\n")) != NULL) {
1069 		if (process_server_config_line(options, cp, filename,
1070 		    linenum++) != 0)
1071 			bad_options++;
1072 	}
1073 	xfree(obuf);
1074 	if (bad_options > 0)
1075 		fatal("%s: terminating, %d bad configuration options",
1076 		    filename, bad_options);
1077 }
1078