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