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