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