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