xref: /freebsd/crypto/openssh/servconf.c (revision 099584266b3a508b982965708de56eaba461bee4)
1511b41d2SMark Murray /*
2511b41d2SMark Murray  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3511b41d2SMark Murray  *                    All rights reserved
4511b41d2SMark Murray  *
5c2d3a559SKris Kennaway  * As far as I am concerned, the code I have written for this software
6c2d3a559SKris Kennaway  * can be used freely for any purpose.  Any derived versions of this
7c2d3a559SKris Kennaway  * software must be clearly marked as such, and if the derived work is
8c2d3a559SKris Kennaway  * incompatible with the protocol description in the RFC file, it must be
9c2d3a559SKris Kennaway  * called by a name other than "ssh" or "Secure Shell".
10511b41d2SMark Murray  */
11511b41d2SMark Murray 
12511b41d2SMark Murray #include "includes.h"
1309958426SBrian Feldman RCSID("$OpenBSD: servconf.c,v 1.53 2000/10/14 12:12:09 markus Exp $");
14c2d3a559SKris Kennaway RCSID("$FreeBSD$");
15511b41d2SMark Murray 
16511b41d2SMark Murray #include "ssh.h"
17511b41d2SMark Murray #include "servconf.h"
18511b41d2SMark Murray #include "xmalloc.h"
19e8aafc91SKris Kennaway #include "compat.h"
20511b41d2SMark Murray 
21511b41d2SMark Murray /* add listen address */
22511b41d2SMark Murray void add_listen_addr(ServerOptions *options, char *addr);
23511b41d2SMark Murray 
24511b41d2SMark Murray /* Initializes the server options to their default values. */
25511b41d2SMark Murray 
26511b41d2SMark Murray void
27511b41d2SMark Murray initialize_server_options(ServerOptions *options)
28511b41d2SMark Murray {
29511b41d2SMark Murray 	memset(options, 0, sizeof(*options));
30511b41d2SMark Murray 	options->num_ports = 0;
31511b41d2SMark Murray 	options->ports_from_cmdline = 0;
32511b41d2SMark Murray 	options->listen_addrs = NULL;
33511b41d2SMark Murray 	options->host_key_file = NULL;
34e8aafc91SKris Kennaway 	options->host_dsa_key_file = NULL;
35e8aafc91SKris Kennaway 	options->pid_file = NULL;
36511b41d2SMark Murray 	options->server_key_bits = -1;
37511b41d2SMark Murray 	options->login_grace_time = -1;
38511b41d2SMark Murray 	options->key_regeneration_time = -1;
39511b41d2SMark Murray 	options->permit_root_login = -1;
40511b41d2SMark Murray 	options->ignore_rhosts = -1;
41511b41d2SMark Murray 	options->ignore_user_known_hosts = -1;
42511b41d2SMark Murray 	options->print_motd = -1;
43511b41d2SMark Murray 	options->check_mail = -1;
44511b41d2SMark Murray 	options->x11_forwarding = -1;
45511b41d2SMark Murray 	options->x11_display_offset = -1;
46c2d3a559SKris Kennaway 	options->xauth_location = NULL;
47511b41d2SMark Murray 	options->strict_modes = -1;
48511b41d2SMark Murray 	options->keepalives = -1;
49511b41d2SMark Murray 	options->log_facility = (SyslogFacility) - 1;
50511b41d2SMark Murray 	options->log_level = (LogLevel) - 1;
51511b41d2SMark Murray 	options->rhosts_authentication = -1;
52511b41d2SMark Murray 	options->rhosts_rsa_authentication = -1;
53511b41d2SMark Murray 	options->rsa_authentication = -1;
54e8aafc91SKris Kennaway 	options->dsa_authentication = -1;
55511b41d2SMark Murray #ifdef KRB4
56fe5fd017SMark Murray 	options->krb4_authentication = -1;
57fe5fd017SMark Murray 	options->krb4_or_local_passwd = -1;
58fe5fd017SMark Murray 	options->krb4_ticket_cleanup = -1;
59511b41d2SMark Murray #endif
60fe5fd017SMark Murray #ifdef KRB5
61fe5fd017SMark Murray 	options->krb5_authentication = -1;
62fe5fd017SMark Murray 	options->krb5_tgt_passing = -1;
63fe5fd017SMark Murray #endif /* KRB5 */
64511b41d2SMark Murray #ifdef AFS
65fe5fd017SMark Murray 	options->krb4_tgt_passing = -1;
66511b41d2SMark Murray 	options->afs_token_passing = -1;
67511b41d2SMark Murray #endif
68511b41d2SMark Murray 	options->password_authentication = -1;
6909958426SBrian Feldman 	options->kbd_interactive_authentication = -1;
70511b41d2SMark Murray #ifdef SKEY
71511b41d2SMark Murray 	options->skey_authentication = -1;
72511b41d2SMark Murray #endif
73511b41d2SMark Murray 	options->permit_empty_passwd = -1;
74511b41d2SMark Murray 	options->use_login = -1;
7509958426SBrian Feldman 	options->allow_tcp_forwarding = -1;
76511b41d2SMark Murray 	options->num_allow_users = 0;
77511b41d2SMark Murray 	options->num_deny_users = 0;
78511b41d2SMark Murray 	options->num_allow_groups = 0;
79511b41d2SMark Murray 	options->num_deny_groups = 0;
80e8aafc91SKris Kennaway 	options->ciphers = NULL;
81e8aafc91SKris Kennaway 	options->protocol = SSH_PROTO_UNKNOWN;
82e8aafc91SKris Kennaway 	options->gateway_ports = -1;
8342f71286SMark Murray 	options->connections_per_period = 0;
8442f71286SMark Murray 	options->connections_period = 0;
85c2d3a559SKris Kennaway 	options->num_subsystems = 0;
86c2d3a559SKris Kennaway 	options->max_startups_begin = -1;
87c2d3a559SKris Kennaway 	options->max_startups_rate = -1;
88c2d3a559SKris Kennaway 	options->max_startups = -1;
89511b41d2SMark Murray }
90511b41d2SMark Murray 
91511b41d2SMark Murray void
92511b41d2SMark Murray fill_default_server_options(ServerOptions *options)
93511b41d2SMark Murray {
94511b41d2SMark Murray 	if (options->num_ports == 0)
95511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
96511b41d2SMark Murray 	if (options->listen_addrs == NULL)
97511b41d2SMark Murray 		add_listen_addr(options, NULL);
98511b41d2SMark Murray 	if (options->host_key_file == NULL)
99511b41d2SMark Murray 		options->host_key_file = HOST_KEY_FILE;
100e8aafc91SKris Kennaway 	if (options->host_dsa_key_file == NULL)
101e8aafc91SKris Kennaway 		options->host_dsa_key_file = HOST_DSA_KEY_FILE;
102e8aafc91SKris Kennaway 	if (options->pid_file == NULL)
103e8aafc91SKris Kennaway 		options->pid_file = SSH_DAEMON_PID_FILE;
104511b41d2SMark Murray 	if (options->server_key_bits == -1)
105511b41d2SMark Murray 		options->server_key_bits = 768;
106511b41d2SMark Murray 	if (options->login_grace_time == -1)
107b87db7ceSKris Kennaway 		options->login_grace_time = 120;
108511b41d2SMark Murray 	if (options->key_regeneration_time == -1)
109511b41d2SMark Murray 		options->key_regeneration_time = 3600;
110511b41d2SMark Murray 	if (options->permit_root_login == -1)
111e213d985SPeter Wemm 		options->permit_root_login = 0;			/* no */
112511b41d2SMark Murray 	if (options->ignore_rhosts == -1)
113fe5fd017SMark Murray 		options->ignore_rhosts = 1;
114511b41d2SMark Murray 	if (options->ignore_user_known_hosts == -1)
115511b41d2SMark Murray 		options->ignore_user_known_hosts = 0;
116511b41d2SMark Murray 	if (options->check_mail == -1)
117365c420eSPeter Wemm 		options->check_mail = 1;
118511b41d2SMark Murray 	if (options->print_motd == -1)
119511b41d2SMark Murray 		options->print_motd = 1;
120511b41d2SMark Murray 	if (options->x11_forwarding == -1)
1211610cd7fSKris Kennaway 		options->x11_forwarding = 1;
122511b41d2SMark Murray 	if (options->x11_display_offset == -1)
123fe5fd017SMark Murray 		options->x11_display_offset = 10;
124c2d3a559SKris Kennaway #ifdef XAUTH_PATH
125c2d3a559SKris Kennaway 	if (options->xauth_location == NULL)
126c2d3a559SKris Kennaway 		options->xauth_location = XAUTH_PATH;
127c2d3a559SKris Kennaway #endif /* XAUTH_PATH */
128511b41d2SMark Murray 	if (options->strict_modes == -1)
129511b41d2SMark Murray 		options->strict_modes = 1;
130511b41d2SMark Murray 	if (options->keepalives == -1)
131511b41d2SMark Murray 		options->keepalives = 1;
132511b41d2SMark Murray 	if (options->log_facility == (SyslogFacility) (-1))
133511b41d2SMark Murray 		options->log_facility = SYSLOG_FACILITY_AUTH;
134511b41d2SMark Murray 	if (options->log_level == (LogLevel) (-1))
135511b41d2SMark Murray 		options->log_level = SYSLOG_LEVEL_INFO;
136511b41d2SMark Murray 	if (options->rhosts_authentication == -1)
137511b41d2SMark Murray 		options->rhosts_authentication = 0;
138511b41d2SMark Murray 	if (options->rhosts_rsa_authentication == -1)
139fe5fd017SMark Murray 		options->rhosts_rsa_authentication = 0;
140511b41d2SMark Murray 	if (options->rsa_authentication == -1)
141511b41d2SMark Murray 		options->rsa_authentication = 1;
142e8aafc91SKris Kennaway 	if (options->dsa_authentication == -1)
143e8aafc91SKris Kennaway 		options->dsa_authentication = 1;
144511b41d2SMark Murray #ifdef KRB4
145fe5fd017SMark Murray 	if (options->krb4_authentication == -1)
146fe5fd017SMark Murray 		options->krb4_authentication = (access(KEYFILE, R_OK) == 0);
147fe5fd017SMark Murray 	if (options->krb4_or_local_passwd == -1)
148fe5fd017SMark Murray 		options->krb4_or_local_passwd = 1;
149fe5fd017SMark Murray 	if (options->krb4_ticket_cleanup == -1)
150fe5fd017SMark Murray 		options->krb4_ticket_cleanup = 1;
151511b41d2SMark Murray #endif /* KRB4 */
152fe5fd017SMark Murray #ifdef KRB5
153fe5fd017SMark Murray 	if (options->krb5_authentication == -1)
154fe5fd017SMark Murray 	  	options->krb5_authentication = 1;
155fe5fd017SMark Murray 	if (options->krb5_tgt_passing == -1)
156fe5fd017SMark Murray 	  	options->krb5_tgt_passing = 1;
157fe5fd017SMark Murray #endif /* KRB5 */
158511b41d2SMark Murray #ifdef AFS
159fe5fd017SMark Murray 	if (options->krb4_tgt_passing == -1)
160fe5fd017SMark Murray 		options->krb4_tgt_passing = 0;
161511b41d2SMark Murray 	if (options->afs_token_passing == -1)
162511b41d2SMark Murray 		options->afs_token_passing = k_hasafs();
163511b41d2SMark Murray #endif /* AFS */
164511b41d2SMark Murray 	if (options->password_authentication == -1)
165511b41d2SMark Murray 		options->password_authentication = 1;
16609958426SBrian Feldman 	if (options->kbd_interactive_authentication == -1)
16709958426SBrian Feldman 		options->kbd_interactive_authentication = 0;
168511b41d2SMark Murray #ifdef SKEY
169511b41d2SMark Murray 	if (options->skey_authentication == -1)
170511b41d2SMark Murray 		options->skey_authentication = 1;
171511b41d2SMark Murray #endif
172511b41d2SMark Murray 	if (options->permit_empty_passwd == -1)
173fe5fd017SMark Murray 		options->permit_empty_passwd = 0;
174511b41d2SMark Murray 	if (options->use_login == -1)
175511b41d2SMark Murray 		options->use_login = 0;
17609958426SBrian Feldman 	if (options->allow_tcp_forwarding == -1)
17709958426SBrian Feldman 		options->allow_tcp_forwarding = 1;
178e8aafc91SKris Kennaway 	if (options->protocol == SSH_PROTO_UNKNOWN)
179e8aafc91SKris Kennaway 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
180e8aafc91SKris Kennaway 	if (options->gateway_ports == -1)
181e8aafc91SKris Kennaway 		options->gateway_ports = 0;
182c2d3a559SKris Kennaway 	if (options->max_startups == -1)
183c2d3a559SKris Kennaway 		options->max_startups = 10;
184c2d3a559SKris Kennaway 	if (options->max_startups_rate == -1)
185c2d3a559SKris Kennaway 		options->max_startups_rate = 100;		/* 100% */
186c2d3a559SKris Kennaway 	if (options->max_startups_begin == -1)
187c2d3a559SKris Kennaway 		options->max_startups_begin = options->max_startups;
188511b41d2SMark Murray }
189511b41d2SMark Murray 
190511b41d2SMark Murray /* Keyword tokens. */
191511b41d2SMark Murray typedef enum {
192511b41d2SMark Murray 	sBadOption,		/* == unknown option */
193511b41d2SMark Murray 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
194511b41d2SMark Murray 	sPermitRootLogin, sLogFacility, sLogLevel,
195511b41d2SMark Murray 	sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
196511b41d2SMark Murray #ifdef KRB4
197fe5fd017SMark Murray 	sKrb4Authentication, sKrb4OrLocalPasswd, sKrb4TicketCleanup,
198511b41d2SMark Murray #endif
199fe5fd017SMark Murray #ifdef KRB5
200fe5fd017SMark Murray 	sKrb5Authentication, sKrb5TgtPassing,
201fe5fd017SMark Murray #endif /* KRB5 */
202511b41d2SMark Murray #ifdef AFS
203fe5fd017SMark Murray 	sKrb4TgtPassing, sAFSTokenPassing,
204511b41d2SMark Murray #endif
205511b41d2SMark Murray #ifdef SKEY
206511b41d2SMark Murray 	sSkeyAuthentication,
207511b41d2SMark Murray #endif
20809958426SBrian Feldman 	sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
209511b41d2SMark Murray 	sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
210511b41d2SMark Murray 	sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
21109958426SBrian Feldman 	sUseLogin, sAllowTcpForwarding,
21209958426SBrian Feldman 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
213e8aafc91SKris Kennaway 	sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
214c2d3a559SKris Kennaway 	sGatewayPorts, sDSAAuthentication, sConnectionsPerPeriod, sXAuthLocation,
215c2d3a559SKris Kennaway 	sSubsystem, sMaxStartups
216511b41d2SMark Murray } ServerOpCodes;
217511b41d2SMark Murray 
218511b41d2SMark Murray /* Textual representation of the tokens. */
219511b41d2SMark Murray static struct {
220511b41d2SMark Murray 	const char *name;
221511b41d2SMark Murray 	ServerOpCodes opcode;
222511b41d2SMark Murray } keywords[] = {
223511b41d2SMark Murray 	{ "port", sPort },
224511b41d2SMark Murray 	{ "hostkey", sHostKeyFile },
225e8aafc91SKris Kennaway 	{ "hostdsakey", sHostDSAKeyFile },
226e8aafc91SKris Kennaway  	{ "pidfile", sPidFile },
227511b41d2SMark Murray 	{ "serverkeybits", sServerKeyBits },
228511b41d2SMark Murray 	{ "logingracetime", sLoginGraceTime },
229511b41d2SMark Murray 	{ "keyregenerationinterval", sKeyRegenerationTime },
230511b41d2SMark Murray 	{ "permitrootlogin", sPermitRootLogin },
231511b41d2SMark Murray 	{ "syslogfacility", sLogFacility },
232511b41d2SMark Murray 	{ "loglevel", sLogLevel },
233511b41d2SMark Murray 	{ "rhostsauthentication", sRhostsAuthentication },
234511b41d2SMark Murray 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
235511b41d2SMark Murray 	{ "rsaauthentication", sRSAAuthentication },
236e8aafc91SKris Kennaway 	{ "dsaauthentication", sDSAAuthentication },
237511b41d2SMark Murray #ifdef KRB4
238fe5fd017SMark Murray 	{ "kerberos4authentication", sKrb4Authentication },
239fe5fd017SMark Murray 	{ "kerberos4orlocalpasswd", sKrb4OrLocalPasswd },
240fe5fd017SMark Murray 	{ "kerberos4ticketcleanup", sKrb4TicketCleanup },
241511b41d2SMark Murray #endif
242fe5fd017SMark Murray #ifdef KRB5
243fe5fd017SMark Murray 	{ "kerberos5authentication", sKrb5Authentication },
244fe5fd017SMark Murray 	{ "kerberos5tgtpassing", sKrb5TgtPassing },
245fe5fd017SMark Murray #endif /* KRB5 */
246511b41d2SMark Murray #ifdef AFS
247fe5fd017SMark Murray 	{ "kerberos4tgtpassing", sKrb4TgtPassing },
248511b41d2SMark Murray 	{ "afstokenpassing", sAFSTokenPassing },
249511b41d2SMark Murray #endif
250511b41d2SMark Murray 	{ "passwordauthentication", sPasswordAuthentication },
25109958426SBrian Feldman 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
252511b41d2SMark Murray #ifdef SKEY
253511b41d2SMark Murray 	{ "skeyauthentication", sSkeyAuthentication },
254511b41d2SMark Murray #endif
255511b41d2SMark Murray 	{ "checkmail", sCheckMail },
256511b41d2SMark Murray 	{ "listenaddress", sListenAddress },
257511b41d2SMark Murray 	{ "printmotd", sPrintMotd },
258511b41d2SMark Murray 	{ "ignorerhosts", sIgnoreRhosts },
259511b41d2SMark Murray 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
260511b41d2SMark Murray 	{ "x11forwarding", sX11Forwarding },
261511b41d2SMark Murray 	{ "x11displayoffset", sX11DisplayOffset },
262c2d3a559SKris Kennaway 	{ "xauthlocation", sXAuthLocation },
263511b41d2SMark Murray 	{ "strictmodes", sStrictModes },
264511b41d2SMark Murray 	{ "permitemptypasswords", sEmptyPasswd },
265511b41d2SMark Murray 	{ "uselogin", sUseLogin },
266511b41d2SMark Murray 	{ "randomseed", sRandomSeedFile },
267511b41d2SMark Murray 	{ "keepalive", sKeepAlives },
26809958426SBrian Feldman 	{ "allowtcpforwarding", sAllowTcpForwarding },
269511b41d2SMark Murray 	{ "allowusers", sAllowUsers },
270511b41d2SMark Murray 	{ "denyusers", sDenyUsers },
271511b41d2SMark Murray 	{ "allowgroups", sAllowGroups },
272511b41d2SMark Murray 	{ "denygroups", sDenyGroups },
273e8aafc91SKris Kennaway 	{ "ciphers", sCiphers },
274e8aafc91SKris Kennaway 	{ "protocol", sProtocol },
275e8aafc91SKris Kennaway 	{ "gatewayports", sGatewayPorts },
27642f71286SMark Murray 	{ "connectionsperperiod", sConnectionsPerPeriod },
277c2d3a559SKris Kennaway 	{ "subsystem", sSubsystem },
278c2d3a559SKris Kennaway 	{ "maxstartups", sMaxStartups },
279511b41d2SMark Murray 	{ NULL, 0 }
280511b41d2SMark Murray };
281511b41d2SMark Murray 
282511b41d2SMark Murray /*
283511b41d2SMark Murray  * Returns the number of the token pointed to by cp of length len. Never
284511b41d2SMark Murray  * returns if the token is not known.
285511b41d2SMark Murray  */
286511b41d2SMark Murray 
287511b41d2SMark Murray static ServerOpCodes
288511b41d2SMark Murray parse_token(const char *cp, const char *filename,
289511b41d2SMark Murray 	    int linenum)
290511b41d2SMark Murray {
291511b41d2SMark Murray 	unsigned int i;
292511b41d2SMark Murray 
293511b41d2SMark Murray 	for (i = 0; keywords[i].name; i++)
294511b41d2SMark Murray 		if (strcasecmp(cp, keywords[i].name) == 0)
295511b41d2SMark Murray 			return keywords[i].opcode;
296511b41d2SMark Murray 
297511b41d2SMark Murray 	fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
298511b41d2SMark Murray 		filename, linenum, cp);
299511b41d2SMark Murray 	return sBadOption;
300511b41d2SMark Murray }
301511b41d2SMark Murray 
302511b41d2SMark Murray /*
303511b41d2SMark Murray  * add listen address
304511b41d2SMark Murray  */
305511b41d2SMark Murray void
306511b41d2SMark Murray add_listen_addr(ServerOptions *options, char *addr)
307511b41d2SMark Murray {
308511b41d2SMark Murray 	extern int IPv4or6;
309511b41d2SMark Murray 	struct addrinfo hints, *ai, *aitop;
310511b41d2SMark Murray 	char strport[NI_MAXSERV];
311511b41d2SMark Murray 	int gaierr;
312511b41d2SMark Murray 	int i;
313511b41d2SMark Murray 
314511b41d2SMark Murray 	if (options->num_ports == 0)
315511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
316511b41d2SMark Murray 	for (i = 0; i < options->num_ports; i++) {
317511b41d2SMark Murray 		memset(&hints, 0, sizeof(hints));
318511b41d2SMark Murray 		hints.ai_family = IPv4or6;
319511b41d2SMark Murray 		hints.ai_socktype = SOCK_STREAM;
320511b41d2SMark Murray 		hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
321511b41d2SMark Murray 		snprintf(strport, sizeof strport, "%d", options->ports[i]);
322511b41d2SMark Murray 		if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
323511b41d2SMark Murray 			fatal("bad addr or host: %s (%s)\n",
324511b41d2SMark Murray 			    addr ? addr : "<NULL>",
325511b41d2SMark Murray 			    gai_strerror(gaierr));
326511b41d2SMark Murray 		for (ai = aitop; ai->ai_next; ai = ai->ai_next)
327511b41d2SMark Murray 			;
328511b41d2SMark Murray 		ai->ai_next = options->listen_addrs;
329511b41d2SMark Murray 		options->listen_addrs = aitop;
330511b41d2SMark Murray 	}
331511b41d2SMark Murray }
332511b41d2SMark Murray 
333511b41d2SMark Murray /* Reads the server configuration file. */
334511b41d2SMark Murray 
335511b41d2SMark Murray void
336511b41d2SMark Murray read_server_config(ServerOptions *options, const char *filename)
337511b41d2SMark Murray {
338511b41d2SMark Murray 	FILE *f;
339511b41d2SMark Murray 	char line[1024];
340c2d3a559SKris Kennaway 	char *cp, **charptr, *arg;
341511b41d2SMark Murray 	int linenum, *intptr, value;
342511b41d2SMark Murray 	int bad_options = 0;
343511b41d2SMark Murray 	ServerOpCodes opcode;
344c2d3a559SKris Kennaway 	int i;
345511b41d2SMark Murray 
346511b41d2SMark Murray 	f = fopen(filename, "r");
347511b41d2SMark Murray 	if (!f) {
348511b41d2SMark Murray 		perror(filename);
349511b41d2SMark Murray 		exit(1);
350511b41d2SMark Murray 	}
351511b41d2SMark Murray 	linenum = 0;
352511b41d2SMark Murray 	while (fgets(line, sizeof(line), f)) {
353511b41d2SMark Murray 		linenum++;
354c2d3a559SKris Kennaway 		cp = line;
355c2d3a559SKris Kennaway 		arg = strdelim(&cp);
356c2d3a559SKris Kennaway 		/* Ignore leading whitespace */
357c2d3a559SKris Kennaway 		if (*arg == '\0')
358c2d3a559SKris Kennaway 			arg = strdelim(&cp);
359c2d3a559SKris Kennaway 		if (!*arg || *arg == '#')
360511b41d2SMark Murray 			continue;
361c2d3a559SKris Kennaway 		opcode = parse_token(arg, filename, linenum);
362511b41d2SMark Murray 		switch (opcode) {
363511b41d2SMark Murray 		case sBadOption:
364511b41d2SMark Murray 			bad_options++;
365511b41d2SMark Murray 			continue;
366511b41d2SMark Murray 		case sPort:
367511b41d2SMark Murray 			/* ignore ports from configfile if cmdline specifies ports */
368511b41d2SMark Murray 			if (options->ports_from_cmdline)
369511b41d2SMark Murray 				continue;
370511b41d2SMark Murray 			if (options->listen_addrs != NULL)
371511b41d2SMark Murray 				fatal("%s line %d: ports must be specified before "
372511b41d2SMark Murray 				    "ListenAdress.\n", filename, linenum);
373511b41d2SMark Murray 			if (options->num_ports >= MAX_PORTS)
374511b41d2SMark Murray 				fatal("%s line %d: too many ports.\n",
375511b41d2SMark Murray 				    filename, linenum);
376c2d3a559SKris Kennaway 			arg = strdelim(&cp);
377c2d3a559SKris Kennaway 			if (!arg || *arg == '\0')
378511b41d2SMark Murray 				fatal("%s line %d: missing port number.\n",
379511b41d2SMark Murray 				    filename, linenum);
380c2d3a559SKris Kennaway 			options->ports[options->num_ports++] = atoi(arg);
381511b41d2SMark Murray 			break;
382511b41d2SMark Murray 
383511b41d2SMark Murray 		case sServerKeyBits:
384511b41d2SMark Murray 			intptr = &options->server_key_bits;
385511b41d2SMark Murray parse_int:
386c2d3a559SKris Kennaway 			arg = strdelim(&cp);
387c2d3a559SKris Kennaway 			if (!arg || *arg == '\0') {
388511b41d2SMark Murray 				fprintf(stderr, "%s line %d: missing integer value.\n",
389511b41d2SMark Murray 					filename, linenum);
390511b41d2SMark Murray 				exit(1);
391511b41d2SMark Murray 			}
392c2d3a559SKris Kennaway 			value = atoi(arg);
393c2d3a559SKris Kennaway 			if (value == 0) {
39442f71286SMark Murray 				fprintf(stderr, "%s line %d: invalid integer value.\n",
39542f71286SMark Murray 					filename, linenum);
39642f71286SMark Murray 				exit(1);
39742f71286SMark Murray 			}
398511b41d2SMark Murray 			if (*intptr == -1)
399511b41d2SMark Murray 				*intptr = value;
400511b41d2SMark Murray 			break;
401511b41d2SMark Murray 
402511b41d2SMark Murray 		case sLoginGraceTime:
403511b41d2SMark Murray 			intptr = &options->login_grace_time;
404511b41d2SMark Murray 			goto parse_int;
405511b41d2SMark Murray 
406511b41d2SMark Murray 		case sKeyRegenerationTime:
407511b41d2SMark Murray 			intptr = &options->key_regeneration_time;
408511b41d2SMark Murray 			goto parse_int;
409511b41d2SMark Murray 
410511b41d2SMark Murray 		case sListenAddress:
411c2d3a559SKris Kennaway 			arg = strdelim(&cp);
412c2d3a559SKris Kennaway 			if (!arg || *arg == '\0')
413511b41d2SMark Murray 				fatal("%s line %d: missing inet addr.\n",
414511b41d2SMark Murray 				    filename, linenum);
415c2d3a559SKris Kennaway 			add_listen_addr(options, arg);
416511b41d2SMark Murray 			break;
417511b41d2SMark Murray 
418511b41d2SMark Murray 		case sHostKeyFile:
419e8aafc91SKris Kennaway 		case sHostDSAKeyFile:
420e8aafc91SKris Kennaway 			charptr = (opcode == sHostKeyFile ) ?
421e8aafc91SKris Kennaway 			    &options->host_key_file : &options->host_dsa_key_file;
422c2d3a559SKris Kennaway parse_filename:
423c2d3a559SKris Kennaway 			arg = strdelim(&cp);
424c2d3a559SKris Kennaway 			if (!arg || *arg == '\0') {
425e8aafc91SKris Kennaway 				fprintf(stderr, "%s line %d: missing file name.\n",
426e8aafc91SKris Kennaway 				    filename, linenum);
427e8aafc91SKris Kennaway 				exit(1);
428e8aafc91SKris Kennaway 			}
429e8aafc91SKris Kennaway 			if (*charptr == NULL)
430c2d3a559SKris Kennaway 				*charptr = tilde_expand_filename(arg, getuid());
431e8aafc91SKris Kennaway 			break;
432e8aafc91SKris Kennaway 
433e8aafc91SKris Kennaway 		case sPidFile:
434e8aafc91SKris Kennaway 			charptr = &options->pid_file;
435c2d3a559SKris Kennaway 			goto parse_filename;
436511b41d2SMark Murray 
437511b41d2SMark Murray 		case sRandomSeedFile:
438511b41d2SMark Murray 			fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
439511b41d2SMark Murray 				filename, linenum);
440c2d3a559SKris Kennaway 			arg = strdelim(&cp);
441511b41d2SMark Murray 			break;
442511b41d2SMark Murray 
443511b41d2SMark Murray 		case sPermitRootLogin:
444511b41d2SMark Murray 			intptr = &options->permit_root_login;
445c2d3a559SKris Kennaway 			arg = strdelim(&cp);
446c2d3a559SKris Kennaway 			if (!arg || *arg == '\0') {
447511b41d2SMark Murray 				fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",
448511b41d2SMark Murray 					filename, linenum);
449511b41d2SMark Murray 				exit(1);
450511b41d2SMark Murray 			}
451c2d3a559SKris Kennaway 			if (strcmp(arg, "without-password") == 0)
452511b41d2SMark Murray 				value = 2;
453c2d3a559SKris Kennaway 			else if (strcmp(arg, "yes") == 0)
454511b41d2SMark Murray 				value = 1;
455c2d3a559SKris Kennaway 			else if (strcmp(arg, "no") == 0)
456511b41d2SMark Murray 				value = 0;
457511b41d2SMark Murray 			else {
458511b41d2SMark Murray 				fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
459c2d3a559SKris Kennaway 					filename, linenum, arg);
460511b41d2SMark Murray 				exit(1);
461511b41d2SMark Murray 			}
462511b41d2SMark Murray 			if (*intptr == -1)
463511b41d2SMark Murray 				*intptr = value;
464511b41d2SMark Murray 			break;
465511b41d2SMark Murray 
466511b41d2SMark Murray 		case sIgnoreRhosts:
467511b41d2SMark Murray 			intptr = &options->ignore_rhosts;
468511b41d2SMark Murray parse_flag:
469c2d3a559SKris Kennaway 			arg = strdelim(&cp);
470c2d3a559SKris Kennaway 			if (!arg || *arg == '\0') {
471511b41d2SMark Murray 				fprintf(stderr, "%s line %d: missing yes/no argument.\n",
472511b41d2SMark Murray 					filename, linenum);
473511b41d2SMark Murray 				exit(1);
474511b41d2SMark Murray 			}
475c2d3a559SKris Kennaway 			if (strcmp(arg, "yes") == 0)
476511b41d2SMark Murray 				value = 1;
477c2d3a559SKris Kennaway 			else if (strcmp(arg, "no") == 0)
478511b41d2SMark Murray 				value = 0;
479511b41d2SMark Murray 			else {
480511b41d2SMark Murray 				fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
481c2d3a559SKris Kennaway 					filename, linenum, arg);
482511b41d2SMark Murray 				exit(1);
483511b41d2SMark Murray 			}
484511b41d2SMark Murray 			if (*intptr == -1)
485511b41d2SMark Murray 				*intptr = value;
486511b41d2SMark Murray 			break;
487511b41d2SMark Murray 
488511b41d2SMark Murray 		case sIgnoreUserKnownHosts:
489511b41d2SMark Murray 			intptr = &options->ignore_user_known_hosts;
490962a3f4eSSheldon Hearn 			goto parse_flag;
491511b41d2SMark Murray 
492511b41d2SMark Murray 		case sRhostsAuthentication:
493511b41d2SMark Murray 			intptr = &options->rhosts_authentication;
494511b41d2SMark Murray 			goto parse_flag;
495511b41d2SMark Murray 
496511b41d2SMark Murray 		case sRhostsRSAAuthentication:
497511b41d2SMark Murray 			intptr = &options->rhosts_rsa_authentication;
498511b41d2SMark Murray 			goto parse_flag;
499511b41d2SMark Murray 
500511b41d2SMark Murray 		case sRSAAuthentication:
501511b41d2SMark Murray 			intptr = &options->rsa_authentication;
502511b41d2SMark Murray 			goto parse_flag;
503511b41d2SMark Murray 
504e8aafc91SKris Kennaway 		case sDSAAuthentication:
505e8aafc91SKris Kennaway 			intptr = &options->dsa_authentication;
506e8aafc91SKris Kennaway 			goto parse_flag;
507e8aafc91SKris Kennaway 
508511b41d2SMark Murray #ifdef KRB4
509fe5fd017SMark Murray 		case sKrb4Authentication:
510fe5fd017SMark Murray 			intptr = &options->krb4_authentication;
511511b41d2SMark Murray 			goto parse_flag;
512511b41d2SMark Murray 
513fe5fd017SMark Murray 		case sKrb4OrLocalPasswd:
514fe5fd017SMark Murray 			intptr = &options->krb4_or_local_passwd;
515511b41d2SMark Murray 			goto parse_flag;
516511b41d2SMark Murray 
517fe5fd017SMark Murray 		case sKrb4TicketCleanup:
518fe5fd017SMark Murray 			intptr = &options->krb4_ticket_cleanup;
519511b41d2SMark Murray 			goto parse_flag;
520511b41d2SMark Murray #endif
521511b41d2SMark Murray 
522fe5fd017SMark Murray #ifdef KRB5
523fe5fd017SMark Murray 		case sKrb5Authentication:
524fe5fd017SMark Murray 			intptr = &options->krb5_authentication;
525fe5fd017SMark Murray 			goto parse_flag;
526fe5fd017SMark Murray 
527fe5fd017SMark Murray 		case sKrb5TgtPassing:
528fe5fd017SMark Murray 			intptr = &options->krb5_tgt_passing;
529fe5fd017SMark Murray 			goto parse_flag;
530fe5fd017SMark Murray #endif /* KRB5 */
531fe5fd017SMark Murray 
532511b41d2SMark Murray #ifdef AFS
533fe5fd017SMark Murray 		case sKrb4TgtPassing:
534fe5fd017SMark Murray 			intptr = &options->krb4_tgt_passing;
535511b41d2SMark Murray 			goto parse_flag;
536511b41d2SMark Murray 
537511b41d2SMark Murray 		case sAFSTokenPassing:
538511b41d2SMark Murray 			intptr = &options->afs_token_passing;
539511b41d2SMark Murray 			goto parse_flag;
540511b41d2SMark Murray #endif
541511b41d2SMark Murray 
542511b41d2SMark Murray 		case sPasswordAuthentication:
543511b41d2SMark Murray 			intptr = &options->password_authentication;
544511b41d2SMark Murray 			goto parse_flag;
545511b41d2SMark Murray 
54609958426SBrian Feldman 		case sKbdInteractiveAuthentication:
54709958426SBrian Feldman 			intptr = &options->kbd_interactive_authentication;
54809958426SBrian Feldman 			goto parse_flag;
54909958426SBrian Feldman 
550511b41d2SMark Murray 		case sCheckMail:
551511b41d2SMark Murray 			intptr = &options->check_mail;
552511b41d2SMark Murray 			goto parse_flag;
553511b41d2SMark Murray 
554511b41d2SMark Murray #ifdef SKEY
555511b41d2SMark Murray 		case sSkeyAuthentication:
556511b41d2SMark Murray 			intptr = &options->skey_authentication;
557511b41d2SMark Murray 			goto parse_flag;
558511b41d2SMark Murray #endif
559511b41d2SMark Murray 
560511b41d2SMark Murray 		case sPrintMotd:
561511b41d2SMark Murray 			intptr = &options->print_motd;
562511b41d2SMark Murray 			goto parse_flag;
563511b41d2SMark Murray 
564511b41d2SMark Murray 		case sX11Forwarding:
565511b41d2SMark Murray 			intptr = &options->x11_forwarding;
566511b41d2SMark Murray 			goto parse_flag;
567511b41d2SMark Murray 
568511b41d2SMark Murray 		case sX11DisplayOffset:
569511b41d2SMark Murray 			intptr = &options->x11_display_offset;
570511b41d2SMark Murray 			goto parse_int;
571511b41d2SMark Murray 
572c2d3a559SKris Kennaway 		case sXAuthLocation:
573c2d3a559SKris Kennaway 			charptr = &options->xauth_location;
574c2d3a559SKris Kennaway 			goto parse_filename;
575c2d3a559SKris Kennaway 
576511b41d2SMark Murray 		case sStrictModes:
577511b41d2SMark Murray 			intptr = &options->strict_modes;
578511b41d2SMark Murray 			goto parse_flag;
579511b41d2SMark Murray 
580511b41d2SMark Murray 		case sKeepAlives:
581511b41d2SMark Murray 			intptr = &options->keepalives;
582511b41d2SMark Murray 			goto parse_flag;
583511b41d2SMark Murray 
584511b41d2SMark Murray 		case sEmptyPasswd:
585511b41d2SMark Murray 			intptr = &options->permit_empty_passwd;
586511b41d2SMark Murray 			goto parse_flag;
587511b41d2SMark Murray 
588511b41d2SMark Murray 		case sUseLogin:
589511b41d2SMark Murray 			intptr = &options->use_login;
590511b41d2SMark Murray 			goto parse_flag;
591511b41d2SMark Murray 
592e8aafc91SKris Kennaway 		case sGatewayPorts:
593e8aafc91SKris Kennaway 			intptr = &options->gateway_ports;
594e8aafc91SKris Kennaway 			goto parse_flag;
595e8aafc91SKris Kennaway 
596511b41d2SMark Murray 		case sLogFacility:
597511b41d2SMark Murray 			intptr = (int *) &options->log_facility;
598c2d3a559SKris Kennaway 			arg = strdelim(&cp);
599c2d3a559SKris Kennaway 			value = log_facility_number(arg);
600511b41d2SMark Murray 			if (value == (SyslogFacility) - 1)
601511b41d2SMark Murray 				fatal("%.200s line %d: unsupported log facility '%s'\n",
602c2d3a559SKris Kennaway 				    filename, linenum, arg ? arg : "<NONE>");
603511b41d2SMark Murray 			if (*intptr == -1)
604511b41d2SMark Murray 				*intptr = (SyslogFacility) value;
605511b41d2SMark Murray 			break;
606511b41d2SMark Murray 
607511b41d2SMark Murray 		case sLogLevel:
608511b41d2SMark Murray 			intptr = (int *) &options->log_level;
609c2d3a559SKris Kennaway 			arg = strdelim(&cp);
610c2d3a559SKris Kennaway 			value = log_level_number(arg);
611511b41d2SMark Murray 			if (value == (LogLevel) - 1)
612511b41d2SMark Murray 				fatal("%.200s line %d: unsupported log level '%s'\n",
613c2d3a559SKris Kennaway 				    filename, linenum, arg ? arg : "<NONE>");
614511b41d2SMark Murray 			if (*intptr == -1)
615511b41d2SMark Murray 				*intptr = (LogLevel) value;
616511b41d2SMark Murray 			break;
617511b41d2SMark Murray 
61809958426SBrian Feldman 		case sAllowTcpForwarding:
61909958426SBrian Feldman 			intptr = &options->allow_tcp_forwarding;
62009958426SBrian Feldman 			goto parse_flag;
62109958426SBrian Feldman 
622511b41d2SMark Murray 		case sAllowUsers:
623c2d3a559SKris Kennaway 			while ((arg = strdelim(&cp)) && *arg != '\0') {
62442f71286SMark Murray 				if (options->num_allow_users >= MAX_ALLOW_USERS)
625e8aafc91SKris Kennaway 					fatal("%.200s line %d: too many allow users.\n",
626e8aafc91SKris Kennaway 					    filename, linenum);
627c2d3a559SKris Kennaway 				options->allow_users[options->num_allow_users++] = xstrdup(arg);
628511b41d2SMark Murray 			}
629511b41d2SMark Murray 			break;
630511b41d2SMark Murray 
631511b41d2SMark Murray 		case sDenyUsers:
632c2d3a559SKris Kennaway 			while ((arg = strdelim(&cp)) && *arg != '\0') {
6332803b77eSBrian Feldman 				if (options->num_deny_users >= MAX_DENY_USERS)
634e8aafc91SKris Kennaway 					fatal("%.200s line %d: too many deny users.\n",
635e8aafc91SKris Kennaway 					    filename, linenum);
636c2d3a559SKris Kennaway 				options->deny_users[options->num_deny_users++] = xstrdup(arg);
637511b41d2SMark Murray 			}
638511b41d2SMark Murray 			break;
639511b41d2SMark Murray 
640511b41d2SMark Murray 		case sAllowGroups:
641c2d3a559SKris Kennaway 			while ((arg = strdelim(&cp)) && *arg != '\0') {
64242f71286SMark Murray 				if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
643e8aafc91SKris Kennaway 					fatal("%.200s line %d: too many allow groups.\n",
644e8aafc91SKris Kennaway 					    filename, linenum);
645c2d3a559SKris Kennaway 				options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
646511b41d2SMark Murray 			}
647511b41d2SMark Murray 			break;
648511b41d2SMark Murray 
649511b41d2SMark Murray 		case sDenyGroups:
650c2d3a559SKris Kennaway 			while ((arg = strdelim(&cp)) && *arg != '\0') {
65142f71286SMark Murray 				if (options->num_deny_groups >= MAX_DENY_GROUPS)
652e8aafc91SKris Kennaway 					fatal("%.200s line %d: too many deny groups.\n",
653e8aafc91SKris Kennaway 					    filename, linenum);
654c2d3a559SKris Kennaway 				options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
655511b41d2SMark Murray 			}
656511b41d2SMark Murray 			break;
657511b41d2SMark Murray 
658e8aafc91SKris Kennaway 		case sCiphers:
659c2d3a559SKris Kennaway 			arg = strdelim(&cp);
660c2d3a559SKris Kennaway 			if (!arg || *arg == '\0')
661c322fe35SKris Kennaway 				fatal("%s line %d: Missing argument.", filename, linenum);
662c2d3a559SKris Kennaway 			if (!ciphers_valid(arg))
663e8aafc91SKris Kennaway 				fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
664c2d3a559SKris Kennaway 				    filename, linenum, arg ? arg : "<NONE>");
665e8aafc91SKris Kennaway 			if (options->ciphers == NULL)
666c2d3a559SKris Kennaway 				options->ciphers = xstrdup(arg);
667e8aafc91SKris Kennaway 			break;
668e8aafc91SKris Kennaway 
669e8aafc91SKris Kennaway 		case sProtocol:
670e8aafc91SKris Kennaway 			intptr = &options->protocol;
671c2d3a559SKris Kennaway 			arg = strdelim(&cp);
672c2d3a559SKris Kennaway 			if (!arg || *arg == '\0')
673c322fe35SKris Kennaway 				fatal("%s line %d: Missing argument.", filename, linenum);
674c2d3a559SKris Kennaway 			value = proto_spec(arg);
675e8aafc91SKris Kennaway 			if (value == SSH_PROTO_UNKNOWN)
676e8aafc91SKris Kennaway 				fatal("%s line %d: Bad protocol spec '%s'.",
677c2d3a559SKris Kennaway 				      filename, linenum, arg ? arg : "<NONE>");
678e8aafc91SKris Kennaway 			if (*intptr == SSH_PROTO_UNKNOWN)
679e8aafc91SKris Kennaway 				*intptr = value;
680e8aafc91SKris Kennaway 			break;
681e8aafc91SKris Kennaway 
68242f71286SMark Murray 		case sConnectionsPerPeriod:
683c2d3a559SKris Kennaway 			arg = strdelim(&cp);
68442f71286SMark Murray 			if (cp == NULL)
68542f71286SMark Murray 				fatal("%.200s line %d: missing (>= 0) number argument.\n",
686511b41d2SMark Murray 					filename, linenum);
687c2d3a559SKris Kennaway 			if (sscanf(arg, "%u/%u", &options->connections_per_period,
68842f71286SMark Murray 			    &options->connections_period) != 2)
68942f71286SMark Murray 				fatal("%.200s line %d: invalid numerical argument(s).\n",
69042f71286SMark Murray 				    filename, linenum);
69142f71286SMark Murray 			if (options->connections_per_period != 0 &&
69242f71286SMark Murray 			    options->connections_period == 0)
69342f71286SMark Murray 				fatal("%.200s line %d: invalid connections period.\n",
69442f71286SMark Murray 				    filename, linenum);
69542f71286SMark Murray 			break;
69642f71286SMark Murray 
697c2d3a559SKris Kennaway 		case sSubsystem:
698c2d3a559SKris Kennaway 			if(options->num_subsystems >= MAX_SUBSYSTEMS) {
699c2d3a559SKris Kennaway 				fatal("%s line %d: too many subsystems defined.",
700c2d3a559SKris Kennaway 				      filename, linenum);
701c2d3a559SKris Kennaway 			}
702c2d3a559SKris Kennaway 			arg = strdelim(&cp);
703c2d3a559SKris Kennaway 			if (!arg || *arg == '\0')
704c2d3a559SKris Kennaway 				fatal("%s line %d: Missing subsystem name.",
705c2d3a559SKris Kennaway 				      filename, linenum);
706c2d3a559SKris Kennaway 			for (i = 0; i < options->num_subsystems; i++)
707c2d3a559SKris Kennaway 				if(strcmp(arg, options->subsystem_name[i]) == 0)
708c2d3a559SKris Kennaway 					fatal("%s line %d: Subsystem '%s' already defined.",
709c2d3a559SKris Kennaway 					      filename, linenum, arg);
710c2d3a559SKris Kennaway 			options->subsystem_name[options->num_subsystems] = xstrdup(arg);
711c2d3a559SKris Kennaway 			arg = strdelim(&cp);
712c2d3a559SKris Kennaway 			if (!arg || *arg == '\0')
713c2d3a559SKris Kennaway 				fatal("%s line %d: Missing subsystem command.",
714c2d3a559SKris Kennaway 				      filename, linenum);
715c2d3a559SKris Kennaway 			options->subsystem_command[options->num_subsystems] = xstrdup(arg);
716c2d3a559SKris Kennaway 			options->num_subsystems++;
717c2d3a559SKris Kennaway 			break;
718c2d3a559SKris Kennaway 
719c2d3a559SKris Kennaway 		case sMaxStartups:
720c2d3a559SKris Kennaway 			arg = strdelim(&cp);
721c2d3a559SKris Kennaway 			if (!arg || *arg == '\0')
722c2d3a559SKris Kennaway 				fatal("%s line %d: Missing MaxStartups spec.",
723c2d3a559SKris Kennaway 				      filename, linenum);
724c2d3a559SKris Kennaway 			if (sscanf(arg, "%d:%d:%d",
725c2d3a559SKris Kennaway 			    &options->max_startups_begin,
726c2d3a559SKris Kennaway 			    &options->max_startups_rate,
727c2d3a559SKris Kennaway 			    &options->max_startups) == 3) {
728c2d3a559SKris Kennaway 				if (options->max_startups_begin >
729c2d3a559SKris Kennaway 				    options->max_startups ||
730c2d3a559SKris Kennaway 				    options->max_startups_rate > 100 ||
731c2d3a559SKris Kennaway 				    options->max_startups_rate < 1)
732c2d3a559SKris Kennaway 				fatal("%s line %d: Illegal MaxStartups spec.",
733c2d3a559SKris Kennaway 				      filename, linenum);
734c2d3a559SKris Kennaway 				break;
735c2d3a559SKris Kennaway 			}
736c2d3a559SKris Kennaway 			intptr = &options->max_startups;
737c2d3a559SKris Kennaway 			goto parse_int;
738c2d3a559SKris Kennaway 
73942f71286SMark Murray 		default:
74042f71286SMark Murray 			fatal("%.200s line %d: Missing handler for opcode %s (%d)\n",
741c2d3a559SKris Kennaway 				filename, linenum,arg, opcode);
742511b41d2SMark Murray 		}
743c2d3a559SKris Kennaway 		if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
744c2d3a559SKris Kennaway 			fprintf(stderr,
745c2d3a559SKris Kennaway 				"%s line %d: garbage at end of line; \"%.200s\".\n",
746c2d3a559SKris Kennaway 				filename, linenum, arg);
747c2d3a559SKris Kennaway 			exit(1);
748e8aafc91SKris Kennaway 		}
749511b41d2SMark Murray 	}
750511b41d2SMark Murray 	fclose(f);
751e8aafc91SKris Kennaway 	if (bad_options > 0) {
75242f71286SMark Murray 		fatal("%.200s: terminating, %d bad configuration options\n",
753511b41d2SMark Murray 			filename, bad_options);
754511b41d2SMark Murray 	}
755e8aafc91SKris Kennaway }
756