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