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