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