servconf.c revision 149753
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.144 2005/08/06 10:03:12 dtucker Exp $");
14RCSID("$FreeBSD: head/crypto/openssh/servconf.c 149753 2005-09-03 07:04:25Z 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 = COMP_DELAYED;
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	u_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, n;
447	ServerOpCodes opcode;
448	u_short port;
449	u_int i;
450
451	cp = line;
452	arg = strdelim(&cp);
453	/* Ignore leading whitespace */
454	if (*arg == '\0')
455		arg = strdelim(&cp);
456	if (!arg || !*arg || *arg == '#')
457		return 0;
458	intptr = NULL;
459	charptr = NULL;
460	opcode = parse_token(arg, filename, linenum);
461	switch (opcode) {
462	/* Portable-specific options */
463	case sUsePAM:
464		intptr = &options->use_pam;
465		goto parse_flag;
466
467	/* Standard Options */
468	case sBadOption:
469		return -1;
470	case sPort:
471		/* ignore ports from configfile if cmdline specifies ports */
472		if (options->ports_from_cmdline)
473			return 0;
474		if (options->listen_addrs != NULL)
475			fatal("%s line %d: ports must be specified before "
476			    "ListenAddress.", filename, linenum);
477		if (options->num_ports >= MAX_PORTS)
478			fatal("%s line %d: too many ports.",
479			    filename, linenum);
480		arg = strdelim(&cp);
481		if (!arg || *arg == '\0')
482			fatal("%s line %d: missing port number.",
483			    filename, linenum);
484		options->ports[options->num_ports++] = a2port(arg);
485		if (options->ports[options->num_ports-1] == 0)
486			fatal("%s line %d: Badly formatted port number.",
487			    filename, linenum);
488		break;
489
490	case sServerKeyBits:
491		intptr = &options->server_key_bits;
492parse_int:
493		arg = strdelim(&cp);
494		if (!arg || *arg == '\0')
495			fatal("%s line %d: missing integer value.",
496			    filename, linenum);
497		value = atoi(arg);
498		if (*intptr == -1)
499			*intptr = value;
500		break;
501
502	case sLoginGraceTime:
503		intptr = &options->login_grace_time;
504parse_time:
505		arg = strdelim(&cp);
506		if (!arg || *arg == '\0')
507			fatal("%s line %d: missing time value.",
508			    filename, linenum);
509		if ((value = convtime(arg)) == -1)
510			fatal("%s line %d: invalid time value.",
511			    filename, linenum);
512		if (*intptr == -1)
513			*intptr = value;
514		break;
515
516	case sKeyRegenerationTime:
517		intptr = &options->key_regeneration_time;
518		goto parse_time;
519
520	case sListenAddress:
521		arg = strdelim(&cp);
522		if (arg == NULL || *arg == '\0')
523			fatal("%s line %d: missing address",
524			    filename, linenum);
525		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
526		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
527		    && strchr(p+1, ':') != NULL) {
528			add_listen_addr(options, arg, 0);
529			break;
530		}
531		p = hpdelim(&arg);
532		if (p == NULL)
533			fatal("%s line %d: bad address:port usage",
534			    filename, linenum);
535		p = cleanhostname(p);
536		if (arg == NULL)
537			port = 0;
538		else if ((port = a2port(arg)) == 0)
539			fatal("%s line %d: bad port number", filename, linenum);
540
541		add_listen_addr(options, p, port);
542
543		break;
544
545	case sAddressFamily:
546		arg = strdelim(&cp);
547		if (!arg || *arg == '\0')
548			fatal("%s line %d: missing address family.",
549			    filename, linenum);
550		intptr = &options->address_family;
551		if (options->listen_addrs != NULL)
552			fatal("%s line %d: address family must be specified before "
553			    "ListenAddress.", filename, linenum);
554		if (strcasecmp(arg, "inet") == 0)
555			value = AF_INET;
556		else if (strcasecmp(arg, "inet6") == 0)
557			value = AF_INET6;
558		else if (strcasecmp(arg, "any") == 0)
559			value = AF_UNSPEC;
560		else
561			fatal("%s line %d: unsupported address family \"%s\".",
562			    filename, linenum, arg);
563		if (*intptr == -1)
564			*intptr = value;
565		break;
566
567	case sHostKeyFile:
568		intptr = &options->num_host_key_files;
569		if (*intptr >= MAX_HOSTKEYS)
570			fatal("%s line %d: too many host keys specified (max %d).",
571			    filename, linenum, MAX_HOSTKEYS);
572		charptr = &options->host_key_files[*intptr];
573parse_filename:
574		arg = strdelim(&cp);
575		if (!arg || *arg == '\0')
576			fatal("%s line %d: missing file name.",
577			    filename, linenum);
578		if (*charptr == NULL) {
579			*charptr = tilde_expand_filename(arg, getuid());
580			/* increase optional counter */
581			if (intptr != NULL)
582				*intptr = *intptr + 1;
583		}
584		break;
585
586	case sPidFile:
587		charptr = &options->pid_file;
588		goto parse_filename;
589
590	case sPermitRootLogin:
591		intptr = &options->permit_root_login;
592		arg = strdelim(&cp);
593		if (!arg || *arg == '\0')
594			fatal("%s line %d: missing yes/"
595			    "without-password/forced-commands-only/no "
596			    "argument.", filename, linenum);
597		value = 0;	/* silence compiler */
598		if (strcmp(arg, "without-password") == 0)
599			value = PERMIT_NO_PASSWD;
600		else if (strcmp(arg, "forced-commands-only") == 0)
601			value = PERMIT_FORCED_ONLY;
602		else if (strcmp(arg, "yes") == 0)
603			value = PERMIT_YES;
604		else if (strcmp(arg, "no") == 0)
605			value = PERMIT_NO;
606		else
607			fatal("%s line %d: Bad yes/"
608			    "without-password/forced-commands-only/no "
609			    "argument: %s", filename, linenum, arg);
610		if (*intptr == -1)
611			*intptr = value;
612		break;
613
614	case sIgnoreRhosts:
615		intptr = &options->ignore_rhosts;
616parse_flag:
617		arg = strdelim(&cp);
618		if (!arg || *arg == '\0')
619			fatal("%s line %d: missing yes/no argument.",
620			    filename, linenum);
621		value = 0;	/* silence compiler */
622		if (strcmp(arg, "yes") == 0)
623			value = 1;
624		else if (strcmp(arg, "no") == 0)
625			value = 0;
626		else
627			fatal("%s line %d: Bad yes/no argument: %s",
628				filename, linenum, arg);
629		if (*intptr == -1)
630			*intptr = value;
631		break;
632
633	case sIgnoreUserKnownHosts:
634		intptr = &options->ignore_user_known_hosts;
635		goto parse_flag;
636
637	case sRhostsRSAAuthentication:
638		intptr = &options->rhosts_rsa_authentication;
639		goto parse_flag;
640
641	case sHostbasedAuthentication:
642		intptr = &options->hostbased_authentication;
643		goto parse_flag;
644
645	case sHostbasedUsesNameFromPacketOnly:
646		intptr = &options->hostbased_uses_name_from_packet_only;
647		goto parse_flag;
648
649	case sRSAAuthentication:
650		intptr = &options->rsa_authentication;
651		goto parse_flag;
652
653	case sPubkeyAuthentication:
654		intptr = &options->pubkey_authentication;
655		goto parse_flag;
656
657	case sKerberosAuthentication:
658		intptr = &options->kerberos_authentication;
659		goto parse_flag;
660
661	case sKerberosOrLocalPasswd:
662		intptr = &options->kerberos_or_local_passwd;
663		goto parse_flag;
664
665	case sKerberosTicketCleanup:
666		intptr = &options->kerberos_ticket_cleanup;
667		goto parse_flag;
668
669	case sKerberosGetAFSToken:
670		intptr = &options->kerberos_get_afs_token;
671		goto parse_flag;
672
673	case sGssAuthentication:
674		intptr = &options->gss_authentication;
675		goto parse_flag;
676
677	case sGssCleanupCreds:
678		intptr = &options->gss_cleanup_creds;
679		goto parse_flag;
680
681	case sPasswordAuthentication:
682		intptr = &options->password_authentication;
683		goto parse_flag;
684
685	case sKbdInteractiveAuthentication:
686		intptr = &options->kbd_interactive_authentication;
687		goto parse_flag;
688
689	case sChallengeResponseAuthentication:
690		intptr = &options->challenge_response_authentication;
691		goto parse_flag;
692
693	case sPrintMotd:
694		intptr = &options->print_motd;
695		goto parse_flag;
696
697	case sPrintLastLog:
698		intptr = &options->print_lastlog;
699		goto parse_flag;
700
701	case sX11Forwarding:
702		intptr = &options->x11_forwarding;
703		goto parse_flag;
704
705	case sX11DisplayOffset:
706		intptr = &options->x11_display_offset;
707		goto parse_int;
708
709	case sX11UseLocalhost:
710		intptr = &options->x11_use_localhost;
711		goto parse_flag;
712
713	case sXAuthLocation:
714		charptr = &options->xauth_location;
715		goto parse_filename;
716
717	case sStrictModes:
718		intptr = &options->strict_modes;
719		goto parse_flag;
720
721	case sTCPKeepAlive:
722		intptr = &options->tcp_keep_alive;
723		goto parse_flag;
724
725	case sEmptyPasswd:
726		intptr = &options->permit_empty_passwd;
727		goto parse_flag;
728
729	case sPermitUserEnvironment:
730		intptr = &options->permit_user_env;
731		goto parse_flag;
732
733	case sUseLogin:
734		intptr = &options->use_login;
735		goto parse_flag;
736
737	case sCompression:
738		intptr = &options->compression;
739		arg = strdelim(&cp);
740		if (!arg || *arg == '\0')
741			fatal("%s line %d: missing yes/no/delayed "
742			    "argument.", filename, linenum);
743		value = 0;	/* silence compiler */
744		if (strcmp(arg, "delayed") == 0)
745			value = COMP_DELAYED;
746		else if (strcmp(arg, "yes") == 0)
747			value = COMP_ZLIB;
748		else if (strcmp(arg, "no") == 0)
749			value = COMP_NONE;
750		else
751			fatal("%s line %d: Bad yes/no/delayed "
752			    "argument: %s", filename, linenum, arg);
753		if (*intptr == -1)
754			*intptr = value;
755		break;
756
757	case sGatewayPorts:
758		intptr = &options->gateway_ports;
759		arg = strdelim(&cp);
760		if (!arg || *arg == '\0')
761			fatal("%s line %d: missing yes/no/clientspecified "
762			    "argument.", filename, linenum);
763		value = 0;	/* silence compiler */
764		if (strcmp(arg, "clientspecified") == 0)
765			value = 2;
766		else if (strcmp(arg, "yes") == 0)
767			value = 1;
768		else if (strcmp(arg, "no") == 0)
769			value = 0;
770		else
771			fatal("%s line %d: Bad yes/no/clientspecified "
772			    "argument: %s", filename, linenum, arg);
773		if (*intptr == -1)
774			*intptr = value;
775		break;
776
777	case sUseDNS:
778		intptr = &options->use_dns;
779		goto parse_flag;
780
781	case sLogFacility:
782		intptr = (int *) &options->log_facility;
783		arg = strdelim(&cp);
784		value = log_facility_number(arg);
785		if (value == SYSLOG_FACILITY_NOT_SET)
786			fatal("%.200s line %d: unsupported log facility '%s'",
787			    filename, linenum, arg ? arg : "<NONE>");
788		if (*intptr == -1)
789			*intptr = (SyslogFacility) value;
790		break;
791
792	case sLogLevel:
793		intptr = (int *) &options->log_level;
794		arg = strdelim(&cp);
795		value = log_level_number(arg);
796		if (value == SYSLOG_LEVEL_NOT_SET)
797			fatal("%.200s line %d: unsupported log level '%s'",
798			    filename, linenum, arg ? arg : "<NONE>");
799		if (*intptr == -1)
800			*intptr = (LogLevel) value;
801		break;
802
803	case sAllowTcpForwarding:
804		intptr = &options->allow_tcp_forwarding;
805		goto parse_flag;
806
807	case sUsePrivilegeSeparation:
808		intptr = &use_privsep;
809		goto parse_flag;
810
811	case sAllowUsers:
812		while ((arg = strdelim(&cp)) && *arg != '\0') {
813			if (options->num_allow_users >= MAX_ALLOW_USERS)
814				fatal("%s line %d: too many allow users.",
815				    filename, linenum);
816			options->allow_users[options->num_allow_users++] =
817			    xstrdup(arg);
818		}
819		break;
820
821	case sDenyUsers:
822		while ((arg = strdelim(&cp)) && *arg != '\0') {
823			if (options->num_deny_users >= MAX_DENY_USERS)
824				fatal( "%s line %d: too many deny users.",
825				    filename, linenum);
826			options->deny_users[options->num_deny_users++] =
827			    xstrdup(arg);
828		}
829		break;
830
831	case sAllowGroups:
832		while ((arg = strdelim(&cp)) && *arg != '\0') {
833			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
834				fatal("%s line %d: too many allow groups.",
835				    filename, linenum);
836			options->allow_groups[options->num_allow_groups++] =
837			    xstrdup(arg);
838		}
839		break;
840
841	case sDenyGroups:
842		while ((arg = strdelim(&cp)) && *arg != '\0') {
843			if (options->num_deny_groups >= MAX_DENY_GROUPS)
844				fatal("%s line %d: too many deny groups.",
845				    filename, linenum);
846			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
847		}
848		break;
849
850	case sCiphers:
851		arg = strdelim(&cp);
852		if (!arg || *arg == '\0')
853			fatal("%s line %d: Missing argument.", filename, linenum);
854		if (!ciphers_valid(arg))
855			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
856			    filename, linenum, arg ? arg : "<NONE>");
857		if (options->ciphers == NULL)
858			options->ciphers = xstrdup(arg);
859		break;
860
861	case sMacs:
862		arg = strdelim(&cp);
863		if (!arg || *arg == '\0')
864			fatal("%s line %d: Missing argument.", filename, linenum);
865		if (!mac_valid(arg))
866			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
867			    filename, linenum, arg ? arg : "<NONE>");
868		if (options->macs == NULL)
869			options->macs = xstrdup(arg);
870		break;
871
872	case sProtocol:
873		intptr = &options->protocol;
874		arg = strdelim(&cp);
875		if (!arg || *arg == '\0')
876			fatal("%s line %d: Missing argument.", filename, linenum);
877		value = proto_spec(arg);
878		if (value == SSH_PROTO_UNKNOWN)
879			fatal("%s line %d: Bad protocol spec '%s'.",
880			    filename, linenum, arg ? arg : "<NONE>");
881		if (*intptr == SSH_PROTO_UNKNOWN)
882			*intptr = value;
883		break;
884
885	case sSubsystem:
886		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
887			fatal("%s line %d: too many subsystems defined.",
888			    filename, linenum);
889		}
890		arg = strdelim(&cp);
891		if (!arg || *arg == '\0')
892			fatal("%s line %d: Missing subsystem name.",
893			    filename, linenum);
894		for (i = 0; i < options->num_subsystems; i++)
895			if (strcmp(arg, options->subsystem_name[i]) == 0)
896				fatal("%s line %d: Subsystem '%s' already defined.",
897				    filename, linenum, arg);
898		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
899		arg = strdelim(&cp);
900		if (!arg || *arg == '\0')
901			fatal("%s line %d: Missing subsystem command.",
902			    filename, linenum);
903		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
904		options->num_subsystems++;
905		break;
906
907	case sMaxStartups:
908		arg = strdelim(&cp);
909		if (!arg || *arg == '\0')
910			fatal("%s line %d: Missing MaxStartups spec.",
911			    filename, linenum);
912		if ((n = sscanf(arg, "%d:%d:%d",
913		    &options->max_startups_begin,
914		    &options->max_startups_rate,
915		    &options->max_startups)) == 3) {
916			if (options->max_startups_begin >
917			    options->max_startups ||
918			    options->max_startups_rate > 100 ||
919			    options->max_startups_rate < 1)
920				fatal("%s line %d: Illegal MaxStartups spec.",
921				    filename, linenum);
922		} else if (n != 1)
923			fatal("%s line %d: Illegal MaxStartups spec.",
924			    filename, linenum);
925		else
926			options->max_startups = options->max_startups_begin;
927		break;
928
929	case sMaxAuthTries:
930		intptr = &options->max_authtries;
931		goto parse_int;
932
933	case sBanner:
934		charptr = &options->banner;
935		goto parse_filename;
936	/*
937	 * These options can contain %X options expanded at
938	 * connect time, so that you can specify paths like:
939	 *
940	 * AuthorizedKeysFile	/etc/ssh_keys/%u
941	 */
942	case sAuthorizedKeysFile:
943	case sAuthorizedKeysFile2:
944		charptr = (opcode == sAuthorizedKeysFile ) ?
945		    &options->authorized_keys_file :
946		    &options->authorized_keys_file2;
947		goto parse_filename;
948
949	case sClientAliveInterval:
950		intptr = &options->client_alive_interval;
951		goto parse_time;
952
953	case sClientAliveCountMax:
954		intptr = &options->client_alive_count_max;
955		goto parse_int;
956
957	case sAcceptEnv:
958		while ((arg = strdelim(&cp)) && *arg != '\0') {
959			if (strchr(arg, '=') != NULL)
960				fatal("%s line %d: Invalid environment name.",
961				    filename, linenum);
962			if (options->num_accept_env >= MAX_ACCEPT_ENV)
963				fatal("%s line %d: too many allow env.",
964				    filename, linenum);
965			options->accept_env[options->num_accept_env++] =
966			    xstrdup(arg);
967		}
968		break;
969
970	case sVersionAddendum:
971                ssh_version_set_addendum(strtok(cp, "\n"));
972                do {
973                        arg = strdelim(&cp);
974                } while (arg != NULL && *arg != '\0');
975		break;
976
977	case sDeprecated:
978		logit("%s line %d: Deprecated option %s",
979		    filename, linenum, arg);
980		while (arg)
981		    arg = strdelim(&cp);
982		break;
983
984	case sUnsupported:
985		logit("%s line %d: Unsupported option %s",
986		    filename, linenum, arg);
987		while (arg)
988		    arg = strdelim(&cp);
989		break;
990
991	default:
992		fatal("%s line %d: Missing handler for opcode %s (%d)",
993		    filename, linenum, arg, opcode);
994	}
995	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
996		fatal("%s line %d: garbage at end of line; \"%.200s\".",
997		    filename, linenum, arg);
998	return 0;
999}
1000
1001/* Reads the server configuration file. */
1002
1003void
1004load_server_config(const char *filename, Buffer *conf)
1005{
1006	char line[1024], *cp;
1007	FILE *f;
1008
1009	debug2("%s: filename %s", __func__, filename);
1010	if ((f = fopen(filename, "r")) == NULL) {
1011		perror(filename);
1012		exit(1);
1013	}
1014	buffer_clear(conf);
1015	while (fgets(line, sizeof(line), f)) {
1016		/*
1017		 * Trim out comments and strip whitespace
1018		 * NB - preserve newlines, they are needed to reproduce
1019		 * line numbers later for error messages
1020		 */
1021		if ((cp = strchr(line, '#')) != NULL)
1022			memcpy(cp, "\n", 2);
1023		cp = line + strspn(line, " \t\r");
1024
1025		buffer_append(conf, cp, strlen(cp));
1026	}
1027	buffer_append(conf, "\0", 1);
1028	fclose(f);
1029	debug2("%s: done config len = %d", __func__, buffer_len(conf));
1030}
1031
1032void
1033parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
1034{
1035	int linenum, bad_options = 0;
1036	char *cp, *obuf, *cbuf;
1037
1038	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1039
1040	obuf = cbuf = xstrdup(buffer_ptr(conf));
1041	linenum = 1;
1042	while ((cp = strsep(&cbuf, "\n")) != NULL) {
1043		if (process_server_config_line(options, cp, filename,
1044		    linenum++) != 0)
1045			bad_options++;
1046	}
1047	xfree(obuf);
1048	if (bad_options > 0)
1049		fatal("%s: terminating, %d bad configuration options",
1050		    filename, bad_options);
1051}
1052