xref: /openbsd-src/usr.bin/ssh/servconf.c (revision b725ae7711052a2233e31a66fefb8a752c388d7a)
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.132 2004/05/08 00:01:37 deraadt 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->banner = NULL;
93 	options->use_dns = -1;
94 	options->client_alive_interval = -1;
95 	options->client_alive_count_max = -1;
96 	options->authorized_keys_file = NULL;
97 	options->authorized_keys_file2 = NULL;
98 	options->num_accept_env = 0;
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, sAcceptEnv,
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 	{ "acceptenv", sAcceptEnv },
335 	{ NULL, sBadOption }
336 };
337 
338 /*
339  * Returns the number of the token pointed to by cp or sBadOption.
340  */
341 
342 static ServerOpCodes
343 parse_token(const char *cp, const char *filename,
344 	    int linenum)
345 {
346 	u_int i;
347 
348 	for (i = 0; keywords[i].name; i++)
349 		if (strcasecmp(cp, keywords[i].name) == 0)
350 			return keywords[i].opcode;
351 
352 	error("%s: line %d: Bad configuration option: %s",
353 	    filename, linenum, cp);
354 	return sBadOption;
355 }
356 
357 static void
358 add_listen_addr(ServerOptions *options, char *addr, u_short port)
359 {
360 	int i;
361 
362 	if (options->num_ports == 0)
363 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
364 	if (port == 0)
365 		for (i = 0; i < options->num_ports; i++)
366 			add_one_listen_addr(options, addr, options->ports[i]);
367 	else
368 		add_one_listen_addr(options, addr, port);
369 }
370 
371 static void
372 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
373 {
374 	struct addrinfo hints, *ai, *aitop;
375 	char strport[NI_MAXSERV];
376 	int gaierr;
377 
378 	memset(&hints, 0, sizeof(hints));
379 	hints.ai_family = IPv4or6;
380 	hints.ai_socktype = SOCK_STREAM;
381 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
382 	snprintf(strport, sizeof strport, "%u", port);
383 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
384 		fatal("bad addr or host: %s (%s)",
385 		    addr ? addr : "<NULL>",
386 		    gai_strerror(gaierr));
387 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
388 		;
389 	ai->ai_next = options->listen_addrs;
390 	options->listen_addrs = aitop;
391 }
392 
393 int
394 process_server_config_line(ServerOptions *options, char *line,
395     const char *filename, int linenum)
396 {
397 	char *cp, **charptr, *arg, *p;
398 	int *intptr, value, i, n;
399 	ServerOpCodes opcode;
400 
401 	cp = line;
402 	arg = strdelim(&cp);
403 	/* Ignore leading whitespace */
404 	if (*arg == '\0')
405 		arg = strdelim(&cp);
406 	if (!arg || !*arg || *arg == '#')
407 		return 0;
408 	intptr = NULL;
409 	charptr = NULL;
410 	opcode = parse_token(arg, filename, linenum);
411 	switch (opcode) {
412 	case sBadOption:
413 		return -1;
414 	case sPort:
415 		/* ignore ports from configfile if cmdline specifies ports */
416 		if (options->ports_from_cmdline)
417 			return 0;
418 		if (options->listen_addrs != NULL)
419 			fatal("%s line %d: ports must be specified before "
420 			    "ListenAddress.", filename, linenum);
421 		if (options->num_ports >= MAX_PORTS)
422 			fatal("%s line %d: too many ports.",
423 			    filename, linenum);
424 		arg = strdelim(&cp);
425 		if (!arg || *arg == '\0')
426 			fatal("%s line %d: missing port number.",
427 			    filename, linenum);
428 		options->ports[options->num_ports++] = a2port(arg);
429 		if (options->ports[options->num_ports-1] == 0)
430 			fatal("%s line %d: Badly formatted port number.",
431 			    filename, linenum);
432 		break;
433 
434 	case sServerKeyBits:
435 		intptr = &options->server_key_bits;
436 parse_int:
437 		arg = strdelim(&cp);
438 		if (!arg || *arg == '\0')
439 			fatal("%s line %d: missing integer value.",
440 			    filename, linenum);
441 		value = atoi(arg);
442 		if (*intptr == -1)
443 			*intptr = value;
444 		break;
445 
446 	case sLoginGraceTime:
447 		intptr = &options->login_grace_time;
448 parse_time:
449 		arg = strdelim(&cp);
450 		if (!arg || *arg == '\0')
451 			fatal("%s line %d: missing time value.",
452 			    filename, linenum);
453 		if ((value = convtime(arg)) == -1)
454 			fatal("%s line %d: invalid time value.",
455 			    filename, linenum);
456 		if (*intptr == -1)
457 			*intptr = value;
458 		break;
459 
460 	case sKeyRegenerationTime:
461 		intptr = &options->key_regeneration_time;
462 		goto parse_time;
463 
464 	case sListenAddress:
465 		arg = strdelim(&cp);
466 		if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
467 			fatal("%s line %d: missing inet addr.",
468 			    filename, linenum);
469 		if (*arg == '[') {
470 			if ((p = strchr(arg, ']')) == NULL)
471 				fatal("%s line %d: bad ipv6 inet addr usage.",
472 				    filename, linenum);
473 			arg++;
474 			memmove(p, p+1, strlen(p+1)+1);
475 		} else if (((p = strchr(arg, ':')) == NULL) ||
476 			    (strchr(p+1, ':') != NULL)) {
477 			add_listen_addr(options, arg, 0);
478 			break;
479 		}
480 		if (*p == ':') {
481 			u_short port;
482 
483 			p++;
484 			if (*p == '\0')
485 				fatal("%s line %d: bad inet addr:port usage.",
486 				    filename, linenum);
487 			else {
488 				*(p-1) = '\0';
489 				if ((port = a2port(p)) == 0)
490 					fatal("%s line %d: bad port number.",
491 					    filename, linenum);
492 				add_listen_addr(options, arg, port);
493 			}
494 		} else if (*p == '\0')
495 			add_listen_addr(options, arg, 0);
496 		else
497 			fatal("%s line %d: bad inet addr usage.",
498 			    filename, linenum);
499 		break;
500 
501 	case sHostKeyFile:
502 		intptr = &options->num_host_key_files;
503 		if (*intptr >= MAX_HOSTKEYS)
504 			fatal("%s line %d: too many host keys specified (max %d).",
505 			    filename, linenum, MAX_HOSTKEYS);
506 		charptr = &options->host_key_files[*intptr];
507 parse_filename:
508 		arg = strdelim(&cp);
509 		if (!arg || *arg == '\0')
510 			fatal("%s line %d: missing file name.",
511 			    filename, linenum);
512 		if (*charptr == NULL) {
513 			*charptr = tilde_expand_filename(arg, getuid());
514 			/* increase optional counter */
515 			if (intptr != NULL)
516 				*intptr = *intptr + 1;
517 		}
518 		break;
519 
520 	case sPidFile:
521 		charptr = &options->pid_file;
522 		goto parse_filename;
523 
524 	case sPermitRootLogin:
525 		intptr = &options->permit_root_login;
526 		arg = strdelim(&cp);
527 		if (!arg || *arg == '\0')
528 			fatal("%s line %d: missing yes/"
529 			    "without-password/forced-commands-only/no "
530 			    "argument.", filename, linenum);
531 		value = 0;	/* silence compiler */
532 		if (strcmp(arg, "without-password") == 0)
533 			value = PERMIT_NO_PASSWD;
534 		else if (strcmp(arg, "forced-commands-only") == 0)
535 			value = PERMIT_FORCED_ONLY;
536 		else if (strcmp(arg, "yes") == 0)
537 			value = PERMIT_YES;
538 		else if (strcmp(arg, "no") == 0)
539 			value = PERMIT_NO;
540 		else
541 			fatal("%s line %d: Bad yes/"
542 			    "without-password/forced-commands-only/no "
543 			    "argument: %s", filename, linenum, arg);
544 		if (*intptr == -1)
545 			*intptr = value;
546 		break;
547 
548 	case sIgnoreRhosts:
549 		intptr = &options->ignore_rhosts;
550 parse_flag:
551 		arg = strdelim(&cp);
552 		if (!arg || *arg == '\0')
553 			fatal("%s line %d: missing yes/no argument.",
554 			    filename, linenum);
555 		value = 0;	/* silence compiler */
556 		if (strcmp(arg, "yes") == 0)
557 			value = 1;
558 		else if (strcmp(arg, "no") == 0)
559 			value = 0;
560 		else
561 			fatal("%s line %d: Bad yes/no argument: %s",
562 				filename, linenum, arg);
563 		if (*intptr == -1)
564 			*intptr = value;
565 		break;
566 
567 	case sIgnoreUserKnownHosts:
568 		intptr = &options->ignore_user_known_hosts;
569 		goto parse_flag;
570 
571 	case sRhostsRSAAuthentication:
572 		intptr = &options->rhosts_rsa_authentication;
573 		goto parse_flag;
574 
575 	case sHostbasedAuthentication:
576 		intptr = &options->hostbased_authentication;
577 		goto parse_flag;
578 
579 	case sHostbasedUsesNameFromPacketOnly:
580 		intptr = &options->hostbased_uses_name_from_packet_only;
581 		goto parse_flag;
582 
583 	case sRSAAuthentication:
584 		intptr = &options->rsa_authentication;
585 		goto parse_flag;
586 
587 	case sPubkeyAuthentication:
588 		intptr = &options->pubkey_authentication;
589 		goto parse_flag;
590 
591 	case sKerberosAuthentication:
592 		intptr = &options->kerberos_authentication;
593 		goto parse_flag;
594 
595 	case sKerberosOrLocalPasswd:
596 		intptr = &options->kerberos_or_local_passwd;
597 		goto parse_flag;
598 
599 	case sKerberosTicketCleanup:
600 		intptr = &options->kerberos_ticket_cleanup;
601 		goto parse_flag;
602 
603 	case sKerberosGetAFSToken:
604 		intptr = &options->kerberos_get_afs_token;
605 		goto parse_flag;
606 
607 	case sGssAuthentication:
608 		intptr = &options->gss_authentication;
609 		goto parse_flag;
610 
611 	case sGssCleanupCreds:
612 		intptr = &options->gss_cleanup_creds;
613 		goto parse_flag;
614 
615 	case sPasswordAuthentication:
616 		intptr = &options->password_authentication;
617 		goto parse_flag;
618 
619 	case sKbdInteractiveAuthentication:
620 		intptr = &options->kbd_interactive_authentication;
621 		goto parse_flag;
622 
623 	case sChallengeResponseAuthentication:
624 		intptr = &options->challenge_response_authentication;
625 		goto parse_flag;
626 
627 	case sPrintMotd:
628 		intptr = &options->print_motd;
629 		goto parse_flag;
630 
631 	case sPrintLastLog:
632 		intptr = &options->print_lastlog;
633 		goto parse_flag;
634 
635 	case sX11Forwarding:
636 		intptr = &options->x11_forwarding;
637 		goto parse_flag;
638 
639 	case sX11DisplayOffset:
640 		intptr = &options->x11_display_offset;
641 		goto parse_int;
642 
643 	case sX11UseLocalhost:
644 		intptr = &options->x11_use_localhost;
645 		goto parse_flag;
646 
647 	case sXAuthLocation:
648 		charptr = &options->xauth_location;
649 		goto parse_filename;
650 
651 	case sStrictModes:
652 		intptr = &options->strict_modes;
653 		goto parse_flag;
654 
655 	case sTCPKeepAlive:
656 		intptr = &options->tcp_keep_alive;
657 		goto parse_flag;
658 
659 	case sEmptyPasswd:
660 		intptr = &options->permit_empty_passwd;
661 		goto parse_flag;
662 
663 	case sPermitUserEnvironment:
664 		intptr = &options->permit_user_env;
665 		goto parse_flag;
666 
667 	case sUseLogin:
668 		intptr = &options->use_login;
669 		goto parse_flag;
670 
671 	case sCompression:
672 		intptr = &options->compression;
673 		goto parse_flag;
674 
675 	case sGatewayPorts:
676 		intptr = &options->gateway_ports;
677 		goto parse_flag;
678 
679 	case sUseDNS:
680 		intptr = &options->use_dns;
681 		goto parse_flag;
682 
683 	case sLogFacility:
684 		intptr = (int *) &options->log_facility;
685 		arg = strdelim(&cp);
686 		value = log_facility_number(arg);
687 		if (value == SYSLOG_FACILITY_NOT_SET)
688 			fatal("%.200s line %d: unsupported log facility '%s'",
689 			    filename, linenum, arg ? arg : "<NONE>");
690 		if (*intptr == -1)
691 			*intptr = (SyslogFacility) value;
692 		break;
693 
694 	case sLogLevel:
695 		intptr = (int *) &options->log_level;
696 		arg = strdelim(&cp);
697 		value = log_level_number(arg);
698 		if (value == SYSLOG_LEVEL_NOT_SET)
699 			fatal("%.200s line %d: unsupported log level '%s'",
700 			    filename, linenum, arg ? arg : "<NONE>");
701 		if (*intptr == -1)
702 			*intptr = (LogLevel) value;
703 		break;
704 
705 	case sAllowTcpForwarding:
706 		intptr = &options->allow_tcp_forwarding;
707 		goto parse_flag;
708 
709 	case sUsePrivilegeSeparation:
710 		intptr = &use_privsep;
711 		goto parse_flag;
712 
713 	case sAllowUsers:
714 		while ((arg = strdelim(&cp)) && *arg != '\0') {
715 			if (options->num_allow_users >= MAX_ALLOW_USERS)
716 				fatal("%s line %d: too many allow users.",
717 				    filename, linenum);
718 			options->allow_users[options->num_allow_users++] =
719 			    xstrdup(arg);
720 		}
721 		break;
722 
723 	case sDenyUsers:
724 		while ((arg = strdelim(&cp)) && *arg != '\0') {
725 			if (options->num_deny_users >= MAX_DENY_USERS)
726 				fatal( "%s line %d: too many deny users.",
727 				    filename, linenum);
728 			options->deny_users[options->num_deny_users++] =
729 			    xstrdup(arg);
730 		}
731 		break;
732 
733 	case sAllowGroups:
734 		while ((arg = strdelim(&cp)) && *arg != '\0') {
735 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
736 				fatal("%s line %d: too many allow groups.",
737 				    filename, linenum);
738 			options->allow_groups[options->num_allow_groups++] =
739 			    xstrdup(arg);
740 		}
741 		break;
742 
743 	case sDenyGroups:
744 		while ((arg = strdelim(&cp)) && *arg != '\0') {
745 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
746 				fatal("%s line %d: too many deny groups.",
747 				    filename, linenum);
748 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
749 		}
750 		break;
751 
752 	case sCiphers:
753 		arg = strdelim(&cp);
754 		if (!arg || *arg == '\0')
755 			fatal("%s line %d: Missing argument.", filename, linenum);
756 		if (!ciphers_valid(arg))
757 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
758 			    filename, linenum, arg ? arg : "<NONE>");
759 		if (options->ciphers == NULL)
760 			options->ciphers = xstrdup(arg);
761 		break;
762 
763 	case sMacs:
764 		arg = strdelim(&cp);
765 		if (!arg || *arg == '\0')
766 			fatal("%s line %d: Missing argument.", filename, linenum);
767 		if (!mac_valid(arg))
768 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
769 			    filename, linenum, arg ? arg : "<NONE>");
770 		if (options->macs == NULL)
771 			options->macs = xstrdup(arg);
772 		break;
773 
774 	case sProtocol:
775 		intptr = &options->protocol;
776 		arg = strdelim(&cp);
777 		if (!arg || *arg == '\0')
778 			fatal("%s line %d: Missing argument.", filename, linenum);
779 		value = proto_spec(arg);
780 		if (value == SSH_PROTO_UNKNOWN)
781 			fatal("%s line %d: Bad protocol spec '%s'.",
782 			    filename, linenum, arg ? arg : "<NONE>");
783 		if (*intptr == SSH_PROTO_UNKNOWN)
784 			*intptr = value;
785 		break;
786 
787 	case sSubsystem:
788 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
789 			fatal("%s line %d: too many subsystems defined.",
790 			    filename, linenum);
791 		}
792 		arg = strdelim(&cp);
793 		if (!arg || *arg == '\0')
794 			fatal("%s line %d: Missing subsystem name.",
795 			    filename, linenum);
796 		for (i = 0; i < options->num_subsystems; i++)
797 			if (strcmp(arg, options->subsystem_name[i]) == 0)
798 				fatal("%s line %d: Subsystem '%s' already defined.",
799 				    filename, linenum, arg);
800 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
801 		arg = strdelim(&cp);
802 		if (!arg || *arg == '\0')
803 			fatal("%s line %d: Missing subsystem command.",
804 			    filename, linenum);
805 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
806 		options->num_subsystems++;
807 		break;
808 
809 	case sMaxStartups:
810 		arg = strdelim(&cp);
811 		if (!arg || *arg == '\0')
812 			fatal("%s line %d: Missing MaxStartups spec.",
813 			    filename, linenum);
814 		if ((n = sscanf(arg, "%d:%d:%d",
815 		    &options->max_startups_begin,
816 		    &options->max_startups_rate,
817 		    &options->max_startups)) == 3) {
818 			if (options->max_startups_begin >
819 			    options->max_startups ||
820 			    options->max_startups_rate > 100 ||
821 			    options->max_startups_rate < 1)
822 				fatal("%s line %d: Illegal MaxStartups spec.",
823 				    filename, linenum);
824 		} else if (n != 1)
825 			fatal("%s line %d: Illegal MaxStartups spec.",
826 			    filename, linenum);
827 		else
828 			options->max_startups = options->max_startups_begin;
829 		break;
830 
831 	case sBanner:
832 		charptr = &options->banner;
833 		goto parse_filename;
834 	/*
835 	 * These options can contain %X options expanded at
836 	 * connect time, so that you can specify paths like:
837 	 *
838 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
839 	 */
840 	case sAuthorizedKeysFile:
841 	case sAuthorizedKeysFile2:
842 		charptr = (opcode == sAuthorizedKeysFile ) ?
843 		    &options->authorized_keys_file :
844 		    &options->authorized_keys_file2;
845 		goto parse_filename;
846 
847 	case sClientAliveInterval:
848 		intptr = &options->client_alive_interval;
849 		goto parse_time;
850 
851 	case sClientAliveCountMax:
852 		intptr = &options->client_alive_count_max;
853 		goto parse_int;
854 
855 	case sAcceptEnv:
856 		while ((arg = strdelim(&cp)) && *arg != '\0') {
857 			if (strchr(arg, '=') != NULL)
858 				fatal("%s line %d: Invalid environment name.",
859 				    filename, linenum);
860 			if (options->num_accept_env >= MAX_ACCEPT_ENV)
861 				fatal("%s line %d: too many allow env.",
862 				    filename, linenum);
863 			options->accept_env[options->num_accept_env++] =
864 			    xstrdup(arg);
865 		}
866 		break;
867 
868 	case sDeprecated:
869 		logit("%s line %d: Deprecated option %s",
870 		    filename, linenum, arg);
871 		while (arg)
872 		    arg = strdelim(&cp);
873 		break;
874 
875 	case sUnsupported:
876 		logit("%s line %d: Unsupported option %s",
877 		    filename, linenum, arg);
878 		while (arg)
879 		    arg = strdelim(&cp);
880 		break;
881 
882 	default:
883 		fatal("%s line %d: Missing handler for opcode %s (%d)",
884 		    filename, linenum, arg, opcode);
885 	}
886 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
887 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
888 		    filename, linenum, arg);
889 	return 0;
890 }
891 
892 /* Reads the server configuration file. */
893 
894 void
895 read_server_config(ServerOptions *options, const char *filename)
896 {
897 	int linenum, bad_options = 0;
898 	char line[1024];
899 	FILE *f;
900 
901 	debug2("read_server_config: filename %s", filename);
902 	f = fopen(filename, "r");
903 	if (!f) {
904 		perror(filename);
905 		exit(1);
906 	}
907 	linenum = 0;
908 	while (fgets(line, sizeof(line), f)) {
909 		/* Update line number counter. */
910 		linenum++;
911 		if (process_server_config_line(options, line, filename, linenum) != 0)
912 			bad_options++;
913 	}
914 	fclose(f);
915 	if (bad_options > 0)
916 		fatal("%s: terminating, %d bad configuration options",
917 		    filename, bad_options);
918 }
919