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