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