servconf.c revision 113911
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.116 2003/02/21 09:05:53 markus Exp $");
14RCSID("$FreeBSD: head/crypto/openssh/servconf.c 113911 2003-04-23 17:13:13Z des $");
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
44static void add_listen_addr(ServerOptions *, char *, u_short);
45static void add_one_listen_addr(ServerOptions *, char *, u_short);
46
47/* AF_UNSPEC or AF_INET or AF_INET6 */
48extern int IPv4or6;
49/* Use of privilege separation or not */
50extern int use_privsep;
51
52/* Initializes the server options to their default values. */
53
54void
55initialize_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
132void
133fill_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. */
286typedef 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. */
321static 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
405static ServerOpCodes
406parse_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
420static void
421add_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
434static void
435add_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
456int
457process_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;
505parse_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;
517parse_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];
576parse_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;
619parse_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
953void
954read_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