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