servconf.c revision 147005
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.140 2005/03/10 22:01:05 deraadt Exp $");
14RCSID("$FreeBSD: head/crypto/openssh/servconf.c 147005 2005-06-05 15:46:09Z 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 "misc.h"
23#include "cipher.h"
24#include "kex.h"
25#include "mac.h"
26
27static void add_listen_addr(ServerOptions *, char *, u_short);
28static void add_one_listen_addr(ServerOptions *, char *, u_short);
29
30/* Use of privilege separation or not */
31extern int use_privsep;
32
33/* Initializes the server options to their default values. */
34
35void
36initialize_server_options(ServerOptions *options)
37{
38	memset(options, 0, sizeof(*options));
39
40	/* Portable-specific options */
41	options->use_pam = -1;
42
43	/* Standard Options */
44	options->num_ports = 0;
45	options->ports_from_cmdline = 0;
46	options->listen_addrs = NULL;
47	options->address_family = -1;
48	options->num_host_key_files = 0;
49	options->pid_file = NULL;
50	options->server_key_bits = -1;
51	options->login_grace_time = -1;
52	options->key_regeneration_time = -1;
53	options->permit_root_login = PERMIT_NOT_SET;
54	options->ignore_rhosts = -1;
55	options->ignore_user_known_hosts = -1;
56	options->print_motd = -1;
57	options->print_lastlog = -1;
58	options->x11_forwarding = -1;
59	options->x11_display_offset = -1;
60	options->x11_use_localhost = -1;
61	options->xauth_location = NULL;
62	options->strict_modes = -1;
63	options->tcp_keep_alive = -1;
64	options->log_facility = SYSLOG_FACILITY_NOT_SET;
65	options->log_level = SYSLOG_LEVEL_NOT_SET;
66	options->rhosts_rsa_authentication = -1;
67	options->hostbased_authentication = -1;
68	options->hostbased_uses_name_from_packet_only = -1;
69	options->rsa_authentication = -1;
70	options->pubkey_authentication = -1;
71	options->kerberos_authentication = -1;
72	options->kerberos_or_local_passwd = -1;
73	options->kerberos_ticket_cleanup = -1;
74	options->kerberos_get_afs_token = -1;
75	options->gss_authentication=-1;
76	options->gss_cleanup_creds = -1;
77	options->password_authentication = -1;
78	options->kbd_interactive_authentication = -1;
79	options->challenge_response_authentication = -1;
80	options->permit_empty_passwd = -1;
81	options->permit_user_env = -1;
82	options->use_login = -1;
83	options->compression = -1;
84	options->allow_tcp_forwarding = -1;
85	options->num_allow_users = 0;
86	options->num_deny_users = 0;
87	options->num_allow_groups = 0;
88	options->num_deny_groups = 0;
89	options->ciphers = NULL;
90	options->macs = NULL;
91	options->protocol = SSH_PROTO_UNKNOWN;
92	options->gateway_ports = -1;
93	options->num_subsystems = 0;
94	options->max_startups_begin = -1;
95	options->max_startups_rate = -1;
96	options->max_startups = -1;
97	options->max_authtries = -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	options->num_accept_env = 0;
105
106	/* Needs to be accessable in many places */
107	use_privsep = -1;
108}
109
110void
111fill_default_server_options(ServerOptions *options)
112{
113	/* Portable-specific options */
114	if (options->use_pam == -1)
115		options->use_pam = 1;
116
117	/* Standard Options */
118	if (options->protocol == SSH_PROTO_UNKNOWN)
119		options->protocol = SSH_PROTO_2;
120	if (options->num_host_key_files == 0) {
121		/* fill default hostkeys for protocols */
122		if (options->protocol & SSH_PROTO_1)
123			options->host_key_files[options->num_host_key_files++] =
124			    _PATH_HOST_KEY_FILE;
125		if (options->protocol & SSH_PROTO_2) {
126			options->host_key_files[options->num_host_key_files++] =
127			    _PATH_HOST_DSA_KEY_FILE;
128		}
129	}
130	if (options->num_ports == 0)
131		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
132	if (options->listen_addrs == NULL)
133		add_listen_addr(options, NULL, 0);
134	if (options->pid_file == NULL)
135		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
136	if (options->server_key_bits == -1)
137		options->server_key_bits = 768;
138	if (options->login_grace_time == -1)
139		options->login_grace_time = 120;
140	if (options->key_regeneration_time == -1)
141		options->key_regeneration_time = 3600;
142	if (options->permit_root_login == PERMIT_NOT_SET)
143		options->permit_root_login = PERMIT_NO;
144	if (options->ignore_rhosts == -1)
145		options->ignore_rhosts = 1;
146	if (options->ignore_user_known_hosts == -1)
147		options->ignore_user_known_hosts = 0;
148	if (options->print_motd == -1)
149		options->print_motd = 1;
150	if (options->print_lastlog == -1)
151		options->print_lastlog = 1;
152	if (options->x11_forwarding == -1)
153		options->x11_forwarding = 1;
154	if (options->x11_display_offset == -1)
155		options->x11_display_offset = 10;
156	if (options->x11_use_localhost == -1)
157		options->x11_use_localhost = 1;
158	if (options->xauth_location == NULL)
159		options->xauth_location = _PATH_XAUTH;
160	if (options->strict_modes == -1)
161		options->strict_modes = 1;
162	if (options->tcp_keep_alive == -1)
163		options->tcp_keep_alive = 1;
164	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
165		options->log_facility = SYSLOG_FACILITY_AUTH;
166	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
167		options->log_level = SYSLOG_LEVEL_INFO;
168	if (options->rhosts_rsa_authentication == -1)
169		options->rhosts_rsa_authentication = 0;
170	if (options->hostbased_authentication == -1)
171		options->hostbased_authentication = 0;
172	if (options->hostbased_uses_name_from_packet_only == -1)
173		options->hostbased_uses_name_from_packet_only = 0;
174	if (options->rsa_authentication == -1)
175		options->rsa_authentication = 1;
176	if (options->pubkey_authentication == -1)
177		options->pubkey_authentication = 1;
178	if (options->kerberos_authentication == -1)
179		options->kerberos_authentication = 0;
180	if (options->kerberos_or_local_passwd == -1)
181		options->kerberos_or_local_passwd = 1;
182	if (options->kerberos_ticket_cleanup == -1)
183		options->kerberos_ticket_cleanup = 1;
184	if (options->kerberos_get_afs_token == -1)
185		options->kerberos_get_afs_token = 0;
186	if (options->gss_authentication == -1)
187		options->gss_authentication = 0;
188	if (options->gss_cleanup_creds == -1)
189		options->gss_cleanup_creds = 1;
190	if (options->password_authentication == -1)
191#ifdef USE_PAM
192		options->password_authentication = 0;
193#else
194		options->password_authentication = 1;
195#endif
196	if (options->kbd_interactive_authentication == -1)
197		options->kbd_interactive_authentication = 0;
198	if (options->challenge_response_authentication == -1)
199		options->challenge_response_authentication = 1;
200	if (options->permit_empty_passwd == -1)
201		options->permit_empty_passwd = 0;
202	if (options->permit_user_env == -1)
203		options->permit_user_env = 0;
204	if (options->use_login == -1)
205		options->use_login = 0;
206	if (options->compression == -1)
207		options->compression = 1;
208	if (options->allow_tcp_forwarding == -1)
209		options->allow_tcp_forwarding = 1;
210	if (options->gateway_ports == -1)
211		options->gateway_ports = 0;
212	if (options->max_startups == -1)
213		options->max_startups = 10;
214	if (options->max_startups_rate == -1)
215		options->max_startups_rate = 100;		/* 100% */
216	if (options->max_startups_begin == -1)
217		options->max_startups_begin = options->max_startups;
218	if (options->max_authtries == -1)
219		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
220	if (options->use_dns == -1)
221		options->use_dns = 1;
222	if (options->client_alive_interval == -1)
223		options->client_alive_interval = 0;
224	if (options->client_alive_count_max == -1)
225		options->client_alive_count_max = 3;
226	if (options->authorized_keys_file2 == NULL) {
227		/* authorized_keys_file2 falls back to authorized_keys_file */
228		if (options->authorized_keys_file != NULL)
229			options->authorized_keys_file2 = options->authorized_keys_file;
230		else
231			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
232	}
233	if (options->authorized_keys_file == NULL)
234		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
235
236	/* Turn privilege separation on by default */
237	if (use_privsep == -1)
238		use_privsep = 1;
239
240#ifndef HAVE_MMAP
241	if (use_privsep && options->compression == 1) {
242		error("This platform does not support both privilege "
243		    "separation and compression");
244		error("Compression disabled");
245		options->compression = 0;
246	}
247#endif
248
249}
250
251/* Keyword tokens. */
252typedef enum {
253	sBadOption,		/* == unknown option */
254	/* Portable-specific options */
255	sUsePAM,
256	/* Standard Options */
257	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
258	sPermitRootLogin, sLogFacility, sLogLevel,
259	sRhostsRSAAuthentication, sRSAAuthentication,
260	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
261	sKerberosGetAFSToken,
262	sKerberosTgtPassing, sChallengeResponseAuthentication,
263	sPasswordAuthentication, sKbdInteractiveAuthentication,
264	sListenAddress, sAddressFamily,
265	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
266	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
267	sStrictModes, sEmptyPasswd, sTCPKeepAlive,
268	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
269	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
270	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
271	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
272	sMaxStartups, sMaxAuthTries,
273	sBanner, sUseDNS, sHostbasedAuthentication,
274	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
275	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
276	sGssAuthentication, sGssCleanupCreds, sAcceptEnv,
277	sUsePrivilegeSeparation,
278	sVersionAddendum,
279	sDeprecated, sUnsupported
280} ServerOpCodes;
281
282/* Textual representation of the tokens. */
283static struct {
284	const char *name;
285	ServerOpCodes opcode;
286} keywords[] = {
287	/* Portable-specific options */
288#ifdef USE_PAM
289	{ "usepam", sUsePAM },
290#else
291	{ "usepam", sUnsupported },
292#endif
293	{ "pamauthenticationviakbdint", sDeprecated },
294	/* Standard Options */
295	{ "port", sPort },
296	{ "hostkey", sHostKeyFile },
297	{ "hostdsakey", sHostKeyFile },					/* alias */
298	{ "pidfile", sPidFile },
299	{ "serverkeybits", sServerKeyBits },
300	{ "logingracetime", sLoginGraceTime },
301	{ "keyregenerationinterval", sKeyRegenerationTime },
302	{ "permitrootlogin", sPermitRootLogin },
303	{ "syslogfacility", sLogFacility },
304	{ "loglevel", sLogLevel },
305	{ "rhostsauthentication", sDeprecated },
306	{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
307	{ "hostbasedauthentication", sHostbasedAuthentication },
308	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
309	{ "rsaauthentication", sRSAAuthentication },
310	{ "pubkeyauthentication", sPubkeyAuthentication },
311	{ "dsaauthentication", sPubkeyAuthentication },			/* alias */
312#ifdef KRB5
313	{ "kerberosauthentication", sKerberosAuthentication },
314	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
315	{ "kerberosticketcleanup", sKerberosTicketCleanup },
316#ifdef USE_AFS
317	{ "kerberosgetafstoken", sKerberosGetAFSToken },
318#else
319	{ "kerberosgetafstoken", sUnsupported },
320#endif
321#else
322	{ "kerberosauthentication", sUnsupported },
323	{ "kerberosorlocalpasswd", sUnsupported },
324	{ "kerberosticketcleanup", sUnsupported },
325	{ "kerberosgetafstoken", sUnsupported },
326#endif
327	{ "kerberostgtpassing", sUnsupported },
328	{ "afstokenpassing", sUnsupported },
329#ifdef GSSAPI
330	{ "gssapiauthentication", sGssAuthentication },
331	{ "gssapicleanupcredentials", sGssCleanupCreds },
332#else
333	{ "gssapiauthentication", sUnsupported },
334	{ "gssapicleanupcredentials", sUnsupported },
335#endif
336	{ "passwordauthentication", sPasswordAuthentication },
337	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
338	{ "challengeresponseauthentication", sChallengeResponseAuthentication },
339	{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
340	{ "checkmail", sDeprecated },
341	{ "listenaddress", sListenAddress },
342	{ "addressfamily", sAddressFamily },
343	{ "printmotd", sPrintMotd },
344	{ "printlastlog", sPrintLastLog },
345	{ "ignorerhosts", sIgnoreRhosts },
346	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
347	{ "x11forwarding", sX11Forwarding },
348	{ "x11displayoffset", sX11DisplayOffset },
349	{ "x11uselocalhost", sX11UseLocalhost },
350	{ "xauthlocation", sXAuthLocation },
351	{ "strictmodes", sStrictModes },
352	{ "permitemptypasswords", sEmptyPasswd },
353	{ "permituserenvironment", sPermitUserEnvironment },
354	{ "uselogin", sUseLogin },
355	{ "compression", sCompression },
356	{ "tcpkeepalive", sTCPKeepAlive },
357	{ "keepalive", sTCPKeepAlive },				/* obsolete alias */
358	{ "allowtcpforwarding", sAllowTcpForwarding },
359	{ "allowusers", sAllowUsers },
360	{ "denyusers", sDenyUsers },
361	{ "allowgroups", sAllowGroups },
362	{ "denygroups", sDenyGroups },
363	{ "ciphers", sCiphers },
364	{ "macs", sMacs },
365	{ "protocol", sProtocol },
366	{ "gatewayports", sGatewayPorts },
367	{ "subsystem", sSubsystem },
368	{ "maxstartups", sMaxStartups },
369	{ "maxauthtries", sMaxAuthTries },
370	{ "banner", sBanner },
371	{ "usedns", sUseDNS },
372	{ "verifyreversemapping", sDeprecated },
373	{ "reversemappingcheck", sDeprecated },
374	{ "clientaliveinterval", sClientAliveInterval },
375	{ "clientalivecountmax", sClientAliveCountMax },
376	{ "authorizedkeysfile", sAuthorizedKeysFile },
377	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
378	{ "useprivilegeseparation", sUsePrivilegeSeparation},
379	{ "acceptenv", sAcceptEnv },
380	{ "versionaddendum", sVersionAddendum },
381	{ NULL, sBadOption }
382};
383
384/*
385 * Returns the number of the token pointed to by cp or sBadOption.
386 */
387
388static ServerOpCodes
389parse_token(const char *cp, const char *filename,
390	    int linenum)
391{
392	u_int i;
393
394	for (i = 0; keywords[i].name; i++)
395		if (strcasecmp(cp, keywords[i].name) == 0)
396			return keywords[i].opcode;
397
398	error("%s: line %d: Bad configuration option: %s",
399	    filename, linenum, cp);
400	return sBadOption;
401}
402
403static void
404add_listen_addr(ServerOptions *options, char *addr, u_short port)
405{
406	int i;
407
408	if (options->num_ports == 0)
409		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
410	if (options->address_family == -1)
411		options->address_family = AF_UNSPEC;
412	if (port == 0)
413		for (i = 0; i < options->num_ports; i++)
414			add_one_listen_addr(options, addr, options->ports[i]);
415	else
416		add_one_listen_addr(options, addr, port);
417}
418
419static void
420add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
421{
422	struct addrinfo hints, *ai, *aitop;
423	char strport[NI_MAXSERV];
424	int gaierr;
425
426	memset(&hints, 0, sizeof(hints));
427	hints.ai_family = options->address_family;
428	hints.ai_socktype = SOCK_STREAM;
429	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
430	snprintf(strport, sizeof strport, "%u", port);
431	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
432		fatal("bad addr or host: %s (%s)",
433		    addr ? addr : "<NULL>",
434		    gai_strerror(gaierr));
435	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
436		;
437	ai->ai_next = options->listen_addrs;
438	options->listen_addrs = aitop;
439}
440
441int
442process_server_config_line(ServerOptions *options, char *line,
443    const char *filename, int linenum)
444{
445	char *cp, **charptr, *arg, *p;
446	int *intptr, value, i, n;
447	ServerOpCodes opcode;
448	u_short port;
449
450	cp = line;
451	arg = strdelim(&cp);
452	/* Ignore leading whitespace */
453	if (*arg == '\0')
454		arg = strdelim(&cp);
455	if (!arg || !*arg || *arg == '#')
456		return 0;
457	intptr = NULL;
458	charptr = NULL;
459	opcode = parse_token(arg, filename, linenum);
460	switch (opcode) {
461	/* Portable-specific options */
462	case sUsePAM:
463		intptr = &options->use_pam;
464		goto parse_flag;
465
466	/* Standard Options */
467	case sBadOption:
468		return -1;
469	case sPort:
470		/* ignore ports from configfile if cmdline specifies ports */
471		if (options->ports_from_cmdline)
472			return 0;
473		if (options->listen_addrs != NULL)
474			fatal("%s line %d: ports must be specified before "
475			    "ListenAddress.", filename, linenum);
476		if (options->num_ports >= MAX_PORTS)
477			fatal("%s line %d: too many ports.",
478			    filename, linenum);
479		arg = strdelim(&cp);
480		if (!arg || *arg == '\0')
481			fatal("%s line %d: missing port number.",
482			    filename, linenum);
483		options->ports[options->num_ports++] = a2port(arg);
484		if (options->ports[options->num_ports-1] == 0)
485			fatal("%s line %d: Badly formatted port number.",
486			    filename, linenum);
487		break;
488
489	case sServerKeyBits:
490		intptr = &options->server_key_bits;
491parse_int:
492		arg = strdelim(&cp);
493		if (!arg || *arg == '\0')
494			fatal("%s line %d: missing integer value.",
495			    filename, linenum);
496		value = atoi(arg);
497		if (*intptr == -1)
498			*intptr = value;
499		break;
500
501	case sLoginGraceTime:
502		intptr = &options->login_grace_time;
503parse_time:
504		arg = strdelim(&cp);
505		if (!arg || *arg == '\0')
506			fatal("%s line %d: missing time value.",
507			    filename, linenum);
508		if ((value = convtime(arg)) == -1)
509			fatal("%s line %d: invalid time value.",
510			    filename, linenum);
511		if (*intptr == -1)
512			*intptr = value;
513		break;
514
515	case sKeyRegenerationTime:
516		intptr = &options->key_regeneration_time;
517		goto parse_time;
518
519	case sListenAddress:
520		arg = strdelim(&cp);
521		if (arg == NULL || *arg == '\0')
522			fatal("%s line %d: missing address",
523			    filename, linenum);
524		p = hpdelim(&arg);
525		if (p == NULL)
526			fatal("%s line %d: bad address:port usage",
527			    filename, linenum);
528		p = cleanhostname(p);
529		if (arg == NULL)
530			port = 0;
531		else if ((port = a2port(arg)) == 0)
532			fatal("%s line %d: bad port number", filename, linenum);
533
534		add_listen_addr(options, p, port);
535
536		break;
537
538	case sAddressFamily:
539		arg = strdelim(&cp);
540		intptr = &options->address_family;
541		if (options->listen_addrs != NULL)
542			fatal("%s line %d: address family must be specified before "
543			    "ListenAddress.", filename, linenum);
544		if (strcasecmp(arg, "inet") == 0)
545			value = AF_INET;
546		else if (strcasecmp(arg, "inet6") == 0)
547			value = AF_INET6;
548		else if (strcasecmp(arg, "any") == 0)
549			value = AF_UNSPEC;
550		else
551			fatal("%s line %d: unsupported address family \"%s\".",
552			    filename, linenum, arg);
553		if (*intptr == -1)
554			*intptr = value;
555		break;
556
557	case sHostKeyFile:
558		intptr = &options->num_host_key_files;
559		if (*intptr >= MAX_HOSTKEYS)
560			fatal("%s line %d: too many host keys specified (max %d).",
561			    filename, linenum, MAX_HOSTKEYS);
562		charptr = &options->host_key_files[*intptr];
563parse_filename:
564		arg = strdelim(&cp);
565		if (!arg || *arg == '\0')
566			fatal("%s line %d: missing file name.",
567			    filename, linenum);
568		if (*charptr == NULL) {
569			*charptr = tilde_expand_filename(arg, getuid());
570			/* increase optional counter */
571			if (intptr != NULL)
572				*intptr = *intptr + 1;
573		}
574		break;
575
576	case sPidFile:
577		charptr = &options->pid_file;
578		goto parse_filename;
579
580	case sPermitRootLogin:
581		intptr = &options->permit_root_login;
582		arg = strdelim(&cp);
583		if (!arg || *arg == '\0')
584			fatal("%s line %d: missing yes/"
585			    "without-password/forced-commands-only/no "
586			    "argument.", filename, linenum);
587		value = 0;	/* silence compiler */
588		if (strcmp(arg, "without-password") == 0)
589			value = PERMIT_NO_PASSWD;
590		else if (strcmp(arg, "forced-commands-only") == 0)
591			value = PERMIT_FORCED_ONLY;
592		else if (strcmp(arg, "yes") == 0)
593			value = PERMIT_YES;
594		else if (strcmp(arg, "no") == 0)
595			value = PERMIT_NO;
596		else
597			fatal("%s line %d: Bad yes/"
598			    "without-password/forced-commands-only/no "
599			    "argument: %s", filename, linenum, arg);
600		if (*intptr == -1)
601			*intptr = value;
602		break;
603
604	case sIgnoreRhosts:
605		intptr = &options->ignore_rhosts;
606parse_flag:
607		arg = strdelim(&cp);
608		if (!arg || *arg == '\0')
609			fatal("%s line %d: missing yes/no argument.",
610			    filename, linenum);
611		value = 0;	/* silence compiler */
612		if (strcmp(arg, "yes") == 0)
613			value = 1;
614		else if (strcmp(arg, "no") == 0)
615			value = 0;
616		else
617			fatal("%s line %d: Bad yes/no argument: %s",
618				filename, linenum, arg);
619		if (*intptr == -1)
620			*intptr = value;
621		break;
622
623	case sIgnoreUserKnownHosts:
624		intptr = &options->ignore_user_known_hosts;
625		goto parse_flag;
626
627	case sRhostsRSAAuthentication:
628		intptr = &options->rhosts_rsa_authentication;
629		goto parse_flag;
630
631	case sHostbasedAuthentication:
632		intptr = &options->hostbased_authentication;
633		goto parse_flag;
634
635	case sHostbasedUsesNameFromPacketOnly:
636		intptr = &options->hostbased_uses_name_from_packet_only;
637		goto parse_flag;
638
639	case sRSAAuthentication:
640		intptr = &options->rsa_authentication;
641		goto parse_flag;
642
643	case sPubkeyAuthentication:
644		intptr = &options->pubkey_authentication;
645		goto parse_flag;
646
647	case sKerberosAuthentication:
648		intptr = &options->kerberos_authentication;
649		goto parse_flag;
650
651	case sKerberosOrLocalPasswd:
652		intptr = &options->kerberos_or_local_passwd;
653		goto parse_flag;
654
655	case sKerberosTicketCleanup:
656		intptr = &options->kerberos_ticket_cleanup;
657		goto parse_flag;
658
659	case sKerberosGetAFSToken:
660		intptr = &options->kerberos_get_afs_token;
661		goto parse_flag;
662
663	case sGssAuthentication:
664		intptr = &options->gss_authentication;
665		goto parse_flag;
666
667	case sGssCleanupCreds:
668		intptr = &options->gss_cleanup_creds;
669		goto parse_flag;
670
671	case sPasswordAuthentication:
672		intptr = &options->password_authentication;
673		goto parse_flag;
674
675	case sKbdInteractiveAuthentication:
676		intptr = &options->kbd_interactive_authentication;
677		goto parse_flag;
678
679	case sChallengeResponseAuthentication:
680		intptr = &options->challenge_response_authentication;
681		goto parse_flag;
682
683	case sPrintMotd:
684		intptr = &options->print_motd;
685		goto parse_flag;
686
687	case sPrintLastLog:
688		intptr = &options->print_lastlog;
689		goto parse_flag;
690
691	case sX11Forwarding:
692		intptr = &options->x11_forwarding;
693		goto parse_flag;
694
695	case sX11DisplayOffset:
696		intptr = &options->x11_display_offset;
697		goto parse_int;
698
699	case sX11UseLocalhost:
700		intptr = &options->x11_use_localhost;
701		goto parse_flag;
702
703	case sXAuthLocation:
704		charptr = &options->xauth_location;
705		goto parse_filename;
706
707	case sStrictModes:
708		intptr = &options->strict_modes;
709		goto parse_flag;
710
711	case sTCPKeepAlive:
712		intptr = &options->tcp_keep_alive;
713		goto parse_flag;
714
715	case sEmptyPasswd:
716		intptr = &options->permit_empty_passwd;
717		goto parse_flag;
718
719	case sPermitUserEnvironment:
720		intptr = &options->permit_user_env;
721		goto parse_flag;
722
723	case sUseLogin:
724		intptr = &options->use_login;
725		goto parse_flag;
726
727	case sCompression:
728		intptr = &options->compression;
729		goto parse_flag;
730
731	case sGatewayPorts:
732		intptr = &options->gateway_ports;
733		arg = strdelim(&cp);
734		if (!arg || *arg == '\0')
735			fatal("%s line %d: missing yes/no/clientspecified "
736			    "argument.", filename, linenum);
737		value = 0;	/* silence compiler */
738		if (strcmp(arg, "clientspecified") == 0)
739			value = 2;
740		else if (strcmp(arg, "yes") == 0)
741			value = 1;
742		else if (strcmp(arg, "no") == 0)
743			value = 0;
744		else
745			fatal("%s line %d: Bad yes/no/clientspecified "
746			    "argument: %s", filename, linenum, arg);
747		if (*intptr == -1)
748			*intptr = value;
749		break;
750
751	case sUseDNS:
752		intptr = &options->use_dns;
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 sMaxAuthTries:
904		intptr = &options->max_authtries;
905		goto parse_int;
906
907	case sBanner:
908		charptr = &options->banner;
909		goto parse_filename;
910	/*
911	 * These options can contain %X options expanded at
912	 * connect time, so that you can specify paths like:
913	 *
914	 * AuthorizedKeysFile	/etc/ssh_keys/%u
915	 */
916	case sAuthorizedKeysFile:
917	case sAuthorizedKeysFile2:
918		charptr = (opcode == sAuthorizedKeysFile ) ?
919		    &options->authorized_keys_file :
920		    &options->authorized_keys_file2;
921		goto parse_filename;
922
923	case sClientAliveInterval:
924		intptr = &options->client_alive_interval;
925		goto parse_time;
926
927	case sClientAliveCountMax:
928		intptr = &options->client_alive_count_max;
929		goto parse_int;
930
931	case sAcceptEnv:
932		while ((arg = strdelim(&cp)) && *arg != '\0') {
933			if (strchr(arg, '=') != NULL)
934				fatal("%s line %d: Invalid environment name.",
935				    filename, linenum);
936			if (options->num_accept_env >= MAX_ACCEPT_ENV)
937				fatal("%s line %d: too many allow env.",
938				    filename, linenum);
939			options->accept_env[options->num_accept_env++] =
940			    xstrdup(arg);
941		}
942		break;
943
944	case sVersionAddendum:
945                ssh_version_set_addendum(strtok(cp, "\n"));
946                do {
947                        arg = strdelim(&cp);
948                } while (arg != NULL && *arg != '\0');
949		break;
950
951	case sDeprecated:
952		logit("%s line %d: Deprecated option %s",
953		    filename, linenum, arg);
954		while (arg)
955		    arg = strdelim(&cp);
956		break;
957
958	case sUnsupported:
959		logit("%s line %d: Unsupported option %s",
960		    filename, linenum, arg);
961		while (arg)
962		    arg = strdelim(&cp);
963		break;
964
965	default:
966		fatal("%s line %d: Missing handler for opcode %s (%d)",
967		    filename, linenum, arg, opcode);
968	}
969	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
970		fatal("%s line %d: garbage at end of line; \"%.200s\".",
971		    filename, linenum, arg);
972	return 0;
973}
974
975/* Reads the server configuration file. */
976
977void
978load_server_config(const char *filename, Buffer *conf)
979{
980	char line[1024], *cp;
981	FILE *f;
982
983	debug2("%s: filename %s", __func__, filename);
984	if ((f = fopen(filename, "r")) == NULL) {
985		perror(filename);
986		exit(1);
987	}
988	buffer_clear(conf);
989	while (fgets(line, sizeof(line), f)) {
990		/*
991		 * Trim out comments and strip whitespace
992		 * NB - preserve newlines, they are needed to reproduce
993		 * line numbers later for error messages
994		 */
995		if ((cp = strchr(line, '#')) != NULL)
996			memcpy(cp, "\n", 2);
997		cp = line + strspn(line, " \t\r");
998
999		buffer_append(conf, cp, strlen(cp));
1000	}
1001	buffer_append(conf, "\0", 1);
1002	fclose(f);
1003	debug2("%s: done config len = %d", __func__, buffer_len(conf));
1004}
1005
1006void
1007parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
1008{
1009	int linenum, bad_options = 0;
1010	char *cp, *obuf, *cbuf;
1011
1012	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1013
1014	obuf = cbuf = xstrdup(buffer_ptr(conf));
1015	linenum = 1;
1016	while ((cp = strsep(&cbuf, "\n")) != NULL) {
1017		if (process_server_config_line(options, cp, filename,
1018		    linenum++) != 0)
1019			bad_options++;
1020	}
1021	xfree(obuf);
1022	if (bad_options > 0)
1023		fatal("%s: terminating, %d bad configuration options",
1024		    filename, bad_options);
1025}
1026