xref: /freebsd/crypto/openssh/servconf.c (revision aa49c9264c97095f0d273288be7cb0b4b06658ab)
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"
13aa49c926SDag-Erling Smørgrav RCSID("$OpenBSD: servconf.c,v 1.140 2005/03/10 22:01:05 deraadt Exp $");
14975616f0SDag-Erling Smørgrav RCSID("$FreeBSD$");
15511b41d2SMark Murray 
16511b41d2SMark Murray #include "ssh.h"
17ca3176e7SBrian Feldman #include "log.h"
18511b41d2SMark Murray #include "servconf.h"
19511b41d2SMark Murray #include "xmalloc.h"
20e8aafc91SKris Kennaway #include "compat.h"
21ca3176e7SBrian Feldman #include "pathnames.h"
22ca3176e7SBrian Feldman #include "misc.h"
23ca3176e7SBrian Feldman #include "cipher.h"
24ca3176e7SBrian Feldman #include "kex.h"
25ca3176e7SBrian Feldman #include "mac.h"
26511b41d2SMark Murray 
27af12a3e7SDag-Erling Smørgrav static void add_listen_addr(ServerOptions *, char *, u_short);
28af12a3e7SDag-Erling Smørgrav static void add_one_listen_addr(ServerOptions *, char *, u_short);
29ca3176e7SBrian Feldman 
3080628bacSDag-Erling Smørgrav /* Use of privilege separation or not */
3180628bacSDag-Erling Smørgrav extern int use_privsep;
32511b41d2SMark Murray 
33511b41d2SMark Murray /* Initializes the server options to their default values. */
34511b41d2SMark Murray 
35511b41d2SMark Murray void
36511b41d2SMark Murray initialize_server_options(ServerOptions *options)
37511b41d2SMark Murray {
38511b41d2SMark Murray 	memset(options, 0, sizeof(*options));
39989dd127SDag-Erling Smørgrav 
40989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
41cf2b5f3bSDag-Erling Smørgrav 	options->use_pam = -1;
42989dd127SDag-Erling Smørgrav 
43989dd127SDag-Erling Smørgrav 	/* Standard Options */
44511b41d2SMark Murray 	options->num_ports = 0;
45511b41d2SMark Murray 	options->ports_from_cmdline = 0;
46511b41d2SMark Murray 	options->listen_addrs = NULL;
47aa49c926SDag-Erling Smørgrav 	options->address_family = -1;
48ca3176e7SBrian Feldman 	options->num_host_key_files = 0;
49e8aafc91SKris Kennaway 	options->pid_file = NULL;
50511b41d2SMark Murray 	options->server_key_bits = -1;
51511b41d2SMark Murray 	options->login_grace_time = -1;
52511b41d2SMark Murray 	options->key_regeneration_time = -1;
53ca3176e7SBrian Feldman 	options->permit_root_login = PERMIT_NOT_SET;
54511b41d2SMark Murray 	options->ignore_rhosts = -1;
55511b41d2SMark Murray 	options->ignore_user_known_hosts = -1;
56511b41d2SMark Murray 	options->print_motd = -1;
57ca3176e7SBrian Feldman 	options->print_lastlog = -1;
58511b41d2SMark Murray 	options->x11_forwarding = -1;
59511b41d2SMark Murray 	options->x11_display_offset = -1;
60af12a3e7SDag-Erling Smørgrav 	options->x11_use_localhost = -1;
61c2d3a559SKris Kennaway 	options->xauth_location = NULL;
62511b41d2SMark Murray 	options->strict_modes = -1;
631ec0d754SDag-Erling Smørgrav 	options->tcp_keep_alive = -1;
64af12a3e7SDag-Erling Smørgrav 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
65af12a3e7SDag-Erling Smørgrav 	options->log_level = SYSLOG_LEVEL_NOT_SET;
66511b41d2SMark Murray 	options->rhosts_rsa_authentication = -1;
67ca3176e7SBrian Feldman 	options->hostbased_authentication = -1;
68ca3176e7SBrian Feldman 	options->hostbased_uses_name_from_packet_only = -1;
69511b41d2SMark Murray 	options->rsa_authentication = -1;
70ca3176e7SBrian Feldman 	options->pubkey_authentication = -1;
71cb96ab36SAssar Westerlund 	options->kerberos_authentication = -1;
72af12a3e7SDag-Erling Smørgrav 	options->kerberos_or_local_passwd = -1;
73af12a3e7SDag-Erling Smørgrav 	options->kerberos_ticket_cleanup = -1;
741ec0d754SDag-Erling Smørgrav 	options->kerberos_get_afs_token = -1;
75cf2b5f3bSDag-Erling Smørgrav 	options->gss_authentication=-1;
76cf2b5f3bSDag-Erling Smørgrav 	options->gss_cleanup_creds = -1;
77511b41d2SMark Murray 	options->password_authentication = -1;
7809958426SBrian Feldman 	options->kbd_interactive_authentication = -1;
79af12a3e7SDag-Erling Smørgrav 	options->challenge_response_authentication = -1;
80511b41d2SMark Murray 	options->permit_empty_passwd = -1;
81f388f5efSDag-Erling Smørgrav 	options->permit_user_env = -1;
82511b41d2SMark Murray 	options->use_login = -1;
8380628bacSDag-Erling Smørgrav 	options->compression = -1;
8409958426SBrian Feldman 	options->allow_tcp_forwarding = -1;
85511b41d2SMark Murray 	options->num_allow_users = 0;
86511b41d2SMark Murray 	options->num_deny_users = 0;
87511b41d2SMark Murray 	options->num_allow_groups = 0;
88511b41d2SMark Murray 	options->num_deny_groups = 0;
89e8aafc91SKris Kennaway 	options->ciphers = NULL;
90ca3176e7SBrian Feldman 	options->macs = NULL;
91e8aafc91SKris Kennaway 	options->protocol = SSH_PROTO_UNKNOWN;
92e8aafc91SKris Kennaway 	options->gateway_ports = -1;
93c2d3a559SKris Kennaway 	options->num_subsystems = 0;
94c2d3a559SKris Kennaway 	options->max_startups_begin = -1;
95c2d3a559SKris Kennaway 	options->max_startups_rate = -1;
96c2d3a559SKris Kennaway 	options->max_startups = -1;
9721e764dfSDag-Erling Smørgrav 	options->max_authtries = -1;
98ca3176e7SBrian Feldman 	options->banner = NULL;
99cf2b5f3bSDag-Erling Smørgrav 	options->use_dns = -1;
100ca3176e7SBrian Feldman 	options->client_alive_interval = -1;
101ca3176e7SBrian Feldman 	options->client_alive_count_max = -1;
102af12a3e7SDag-Erling Smørgrav 	options->authorized_keys_file = NULL;
103af12a3e7SDag-Erling Smørgrav 	options->authorized_keys_file2 = NULL;
10421e764dfSDag-Erling Smørgrav 	options->num_accept_env = 0;
10580628bacSDag-Erling Smørgrav 
10680628bacSDag-Erling Smørgrav 	/* Needs to be accessable in many places */
10780628bacSDag-Erling Smørgrav 	use_privsep = -1;
108511b41d2SMark Murray }
109511b41d2SMark Murray 
110511b41d2SMark Murray void
111511b41d2SMark Murray fill_default_server_options(ServerOptions *options)
112511b41d2SMark Murray {
113989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
114cf2b5f3bSDag-Erling Smørgrav 	if (options->use_pam == -1)
115f0477b26SDag-Erling Smørgrav 		options->use_pam = 1;
116989dd127SDag-Erling Smørgrav 
117989dd127SDag-Erling Smørgrav 	/* Standard Options */
118ca3176e7SBrian Feldman 	if (options->protocol == SSH_PROTO_UNKNOWN)
119028c324aSDag-Erling Smørgrav 		options->protocol = SSH_PROTO_2;
120ca3176e7SBrian Feldman 	if (options->num_host_key_files == 0) {
121ca3176e7SBrian Feldman 		/* fill default hostkeys for protocols */
122ca3176e7SBrian Feldman 		if (options->protocol & SSH_PROTO_1)
123af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
124af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_KEY_FILE;
125af12a3e7SDag-Erling Smørgrav 		if (options->protocol & SSH_PROTO_2) {
126af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
127af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_DSA_KEY_FILE;
128af12a3e7SDag-Erling Smørgrav 		}
129ca3176e7SBrian Feldman 	}
130511b41d2SMark Murray 	if (options->num_ports == 0)
131511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
132511b41d2SMark Murray 	if (options->listen_addrs == NULL)
133ca3176e7SBrian Feldman 		add_listen_addr(options, NULL, 0);
134e8aafc91SKris Kennaway 	if (options->pid_file == NULL)
135ca3176e7SBrian Feldman 		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
136511b41d2SMark Murray 	if (options->server_key_bits == -1)
137511b41d2SMark Murray 		options->server_key_bits = 768;
138511b41d2SMark Murray 	if (options->login_grace_time == -1)
139975616f0SDag-Erling Smørgrav 		options->login_grace_time = 120;
140511b41d2SMark Murray 	if (options->key_regeneration_time == -1)
141511b41d2SMark Murray 		options->key_regeneration_time = 3600;
142ca3176e7SBrian Feldman 	if (options->permit_root_login == PERMIT_NOT_SET)
143975616f0SDag-Erling Smørgrav 		options->permit_root_login = PERMIT_NO;
144511b41d2SMark Murray 	if (options->ignore_rhosts == -1)
145fe5fd017SMark Murray 		options->ignore_rhosts = 1;
146511b41d2SMark Murray 	if (options->ignore_user_known_hosts == -1)
147511b41d2SMark Murray 		options->ignore_user_known_hosts = 0;
148511b41d2SMark Murray 	if (options->print_motd == -1)
149511b41d2SMark Murray 		options->print_motd = 1;
150ca3176e7SBrian Feldman 	if (options->print_lastlog == -1)
151ca3176e7SBrian Feldman 		options->print_lastlog = 1;
152511b41d2SMark Murray 	if (options->x11_forwarding == -1)
153975616f0SDag-Erling Smørgrav 		options->x11_forwarding = 1;
154511b41d2SMark Murray 	if (options->x11_display_offset == -1)
155fe5fd017SMark Murray 		options->x11_display_offset = 10;
156af12a3e7SDag-Erling Smørgrav 	if (options->x11_use_localhost == -1)
157af12a3e7SDag-Erling Smørgrav 		options->x11_use_localhost = 1;
158c2d3a559SKris Kennaway 	if (options->xauth_location == NULL)
159af12a3e7SDag-Erling Smørgrav 		options->xauth_location = _PATH_XAUTH;
160511b41d2SMark Murray 	if (options->strict_modes == -1)
161511b41d2SMark Murray 		options->strict_modes = 1;
1621ec0d754SDag-Erling Smørgrav 	if (options->tcp_keep_alive == -1)
1631ec0d754SDag-Erling Smørgrav 		options->tcp_keep_alive = 1;
164af12a3e7SDag-Erling Smørgrav 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
165511b41d2SMark Murray 		options->log_facility = SYSLOG_FACILITY_AUTH;
166af12a3e7SDag-Erling Smørgrav 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
167511b41d2SMark Murray 		options->log_level = SYSLOG_LEVEL_INFO;
168511b41d2SMark Murray 	if (options->rhosts_rsa_authentication == -1)
169fe5fd017SMark Murray 		options->rhosts_rsa_authentication = 0;
170ca3176e7SBrian Feldman 	if (options->hostbased_authentication == -1)
171ca3176e7SBrian Feldman 		options->hostbased_authentication = 0;
172ca3176e7SBrian Feldman 	if (options->hostbased_uses_name_from_packet_only == -1)
173ca3176e7SBrian Feldman 		options->hostbased_uses_name_from_packet_only = 0;
174511b41d2SMark Murray 	if (options->rsa_authentication == -1)
175511b41d2SMark Murray 		options->rsa_authentication = 1;
176ca3176e7SBrian Feldman 	if (options->pubkey_authentication == -1)
177ca3176e7SBrian Feldman 		options->pubkey_authentication = 1;
178989dd127SDag-Erling Smørgrav 	if (options->kerberos_authentication == -1)
179cf2b5f3bSDag-Erling Smørgrav 		options->kerberos_authentication = 0;
180af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_or_local_passwd == -1)
181af12a3e7SDag-Erling Smørgrav 		options->kerberos_or_local_passwd = 1;
182af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_ticket_cleanup == -1)
183af12a3e7SDag-Erling Smørgrav 		options->kerberos_ticket_cleanup = 1;
1841ec0d754SDag-Erling Smørgrav 	if (options->kerberos_get_afs_token == -1)
1851ec0d754SDag-Erling Smørgrav 		options->kerberos_get_afs_token = 0;
186cf2b5f3bSDag-Erling Smørgrav 	if (options->gss_authentication == -1)
187cf2b5f3bSDag-Erling Smørgrav 		options->gss_authentication = 0;
188cf2b5f3bSDag-Erling Smørgrav 	if (options->gss_cleanup_creds == -1)
189cf2b5f3bSDag-Erling Smørgrav 		options->gss_cleanup_creds = 1;
190511b41d2SMark Murray 	if (options->password_authentication == -1)
191b909c84bSDag-Erling Smørgrav #ifdef USE_PAM
192b909c84bSDag-Erling Smørgrav 		options->password_authentication = 0;
193b909c84bSDag-Erling Smørgrav #else
194511b41d2SMark Murray 		options->password_authentication = 1;
195b909c84bSDag-Erling Smørgrav #endif
19609958426SBrian Feldman 	if (options->kbd_interactive_authentication == -1)
19709958426SBrian Feldman 		options->kbd_interactive_authentication = 0;
198af12a3e7SDag-Erling Smørgrav 	if (options->challenge_response_authentication == -1)
19980241871SDag-Erling Smørgrav 		options->challenge_response_authentication = 1;
200511b41d2SMark Murray 	if (options->permit_empty_passwd == -1)
201fe5fd017SMark Murray 		options->permit_empty_passwd = 0;
202f388f5efSDag-Erling Smørgrav 	if (options->permit_user_env == -1)
203f388f5efSDag-Erling Smørgrav 		options->permit_user_env = 0;
204511b41d2SMark Murray 	if (options->use_login == -1)
205511b41d2SMark Murray 		options->use_login = 0;
20680628bacSDag-Erling Smørgrav 	if (options->compression == -1)
20780628bacSDag-Erling Smørgrav 		options->compression = 1;
20809958426SBrian Feldman 	if (options->allow_tcp_forwarding == -1)
20909958426SBrian Feldman 		options->allow_tcp_forwarding = 1;
210e8aafc91SKris Kennaway 	if (options->gateway_ports == -1)
211e8aafc91SKris Kennaway 		options->gateway_ports = 0;
212c2d3a559SKris Kennaway 	if (options->max_startups == -1)
213c2d3a559SKris Kennaway 		options->max_startups = 10;
214c2d3a559SKris Kennaway 	if (options->max_startups_rate == -1)
215c2d3a559SKris Kennaway 		options->max_startups_rate = 100;		/* 100% */
216c2d3a559SKris Kennaway 	if (options->max_startups_begin == -1)
217c2d3a559SKris Kennaway 		options->max_startups_begin = options->max_startups;
21821e764dfSDag-Erling Smørgrav 	if (options->max_authtries == -1)
21921e764dfSDag-Erling Smørgrav 		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
220cf2b5f3bSDag-Erling Smørgrav 	if (options->use_dns == -1)
221cf2b5f3bSDag-Erling Smørgrav 		options->use_dns = 1;
222ca3176e7SBrian Feldman 	if (options->client_alive_interval == -1)
223ca3176e7SBrian Feldman 		options->client_alive_interval = 0;
224ca3176e7SBrian Feldman 	if (options->client_alive_count_max == -1)
225ca3176e7SBrian Feldman 		options->client_alive_count_max = 3;
226af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file2 == NULL) {
227af12a3e7SDag-Erling Smørgrav 		/* authorized_keys_file2 falls back to authorized_keys_file */
228af12a3e7SDag-Erling Smørgrav 		if (options->authorized_keys_file != NULL)
229af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = options->authorized_keys_file;
230af12a3e7SDag-Erling Smørgrav 		else
231af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
232af12a3e7SDag-Erling Smørgrav 	}
233af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file == NULL)
234af12a3e7SDag-Erling Smørgrav 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
23580628bacSDag-Erling Smørgrav 
236989dd127SDag-Erling Smørgrav 	/* Turn privilege separation on by default */
23780628bacSDag-Erling Smørgrav 	if (use_privsep == -1)
238989dd127SDag-Erling Smørgrav 		use_privsep = 1;
239989dd127SDag-Erling Smørgrav 
240f388f5efSDag-Erling Smørgrav #ifndef HAVE_MMAP
241989dd127SDag-Erling Smørgrav 	if (use_privsep && options->compression == 1) {
242989dd127SDag-Erling Smørgrav 		error("This platform does not support both privilege "
243989dd127SDag-Erling Smørgrav 		    "separation and compression");
244989dd127SDag-Erling Smørgrav 		error("Compression disabled");
245989dd127SDag-Erling Smørgrav 		options->compression = 0;
246989dd127SDag-Erling Smørgrav 	}
247989dd127SDag-Erling Smørgrav #endif
248989dd127SDag-Erling Smørgrav 
249511b41d2SMark Murray }
250511b41d2SMark Murray 
251511b41d2SMark Murray /* Keyword tokens. */
252511b41d2SMark Murray typedef enum {
253511b41d2SMark Murray 	sBadOption,		/* == unknown option */
254989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
255cf2b5f3bSDag-Erling Smørgrav 	sUsePAM,
256989dd127SDag-Erling Smørgrav 	/* Standard Options */
257511b41d2SMark Murray 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
258511b41d2SMark Murray 	sPermitRootLogin, sLogFacility, sLogLevel,
259cf2b5f3bSDag-Erling Smørgrav 	sRhostsRSAAuthentication, sRSAAuthentication,
260af12a3e7SDag-Erling Smørgrav 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
2611ec0d754SDag-Erling Smørgrav 	sKerberosGetAFSToken,
262cf2b5f3bSDag-Erling Smørgrav 	sKerberosTgtPassing, sChallengeResponseAuthentication,
263aa49c926SDag-Erling Smørgrav 	sPasswordAuthentication, sKbdInteractiveAuthentication,
264aa49c926SDag-Erling Smørgrav 	sListenAddress, sAddressFamily,
265ca3176e7SBrian Feldman 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
266af12a3e7SDag-Erling Smørgrav 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
2671ec0d754SDag-Erling Smørgrav 	sStrictModes, sEmptyPasswd, sTCPKeepAlive,
268f388f5efSDag-Erling Smørgrav 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
26909958426SBrian Feldman 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
270ca3176e7SBrian Feldman 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
27121e764dfSDag-Erling Smørgrav 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
27221e764dfSDag-Erling Smørgrav 	sMaxStartups, sMaxAuthTries,
273cf2b5f3bSDag-Erling Smørgrav 	sBanner, sUseDNS, sHostbasedAuthentication,
274ca3176e7SBrian Feldman 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
275af12a3e7SDag-Erling Smørgrav 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
27621e764dfSDag-Erling Smørgrav 	sGssAuthentication, sGssCleanupCreds, sAcceptEnv,
27780628bacSDag-Erling Smørgrav 	sUsePrivilegeSeparation,
278db58a8e4SDag-Erling Smørgrav 	sVersionAddendum,
279cf2b5f3bSDag-Erling Smørgrav 	sDeprecated, sUnsupported
280511b41d2SMark Murray } ServerOpCodes;
281511b41d2SMark Murray 
282511b41d2SMark Murray /* Textual representation of the tokens. */
283511b41d2SMark Murray static struct {
284511b41d2SMark Murray 	const char *name;
285511b41d2SMark Murray 	ServerOpCodes opcode;
286511b41d2SMark Murray } keywords[] = {
287989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
288cf2b5f3bSDag-Erling Smørgrav #ifdef USE_PAM
289cf2b5f3bSDag-Erling Smørgrav 	{ "usepam", sUsePAM },
290cf2b5f3bSDag-Erling Smørgrav #else
291cf2b5f3bSDag-Erling Smørgrav 	{ "usepam", sUnsupported },
292975616f0SDag-Erling Smørgrav #endif
293cf2b5f3bSDag-Erling Smørgrav 	{ "pamauthenticationviakbdint", sDeprecated },
294989dd127SDag-Erling Smørgrav 	/* Standard Options */
295511b41d2SMark Murray 	{ "port", sPort },
296511b41d2SMark Murray 	{ "hostkey", sHostKeyFile },
297ca3176e7SBrian Feldman 	{ "hostdsakey", sHostKeyFile },					/* alias */
298e8aafc91SKris Kennaway 	{ "pidfile", sPidFile },
299511b41d2SMark Murray 	{ "serverkeybits", sServerKeyBits },
300511b41d2SMark Murray 	{ "logingracetime", sLoginGraceTime },
301511b41d2SMark Murray 	{ "keyregenerationinterval", sKeyRegenerationTime },
302511b41d2SMark Murray 	{ "permitrootlogin", sPermitRootLogin },
303511b41d2SMark Murray 	{ "syslogfacility", sLogFacility },
304511b41d2SMark Murray 	{ "loglevel", sLogLevel },
305cf2b5f3bSDag-Erling Smørgrav 	{ "rhostsauthentication", sDeprecated },
306511b41d2SMark Murray 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
307ca3176e7SBrian Feldman 	{ "hostbasedauthentication", sHostbasedAuthentication },
308ca3176e7SBrian Feldman 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
309af12a3e7SDag-Erling Smørgrav 	{ "rsaauthentication", sRSAAuthentication },
310ca3176e7SBrian Feldman 	{ "pubkeyauthentication", sPubkeyAuthentication },
311ca3176e7SBrian Feldman 	{ "dsaauthentication", sPubkeyAuthentication },			/* alias */
312cf2b5f3bSDag-Erling Smørgrav #ifdef KRB5
313cb96ab36SAssar Westerlund 	{ "kerberosauthentication", sKerberosAuthentication },
314af12a3e7SDag-Erling Smørgrav 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
315af12a3e7SDag-Erling Smørgrav 	{ "kerberosticketcleanup", sKerberosTicketCleanup },
3161ec0d754SDag-Erling Smørgrav #ifdef USE_AFS
3171ec0d754SDag-Erling Smørgrav 	{ "kerberosgetafstoken", sKerberosGetAFSToken },
3181ec0d754SDag-Erling Smørgrav #else
3191ec0d754SDag-Erling Smørgrav 	{ "kerberosgetafstoken", sUnsupported },
3201ec0d754SDag-Erling Smørgrav #endif
321cf2b5f3bSDag-Erling Smørgrav #else
322cf2b5f3bSDag-Erling Smørgrav 	{ "kerberosauthentication", sUnsupported },
323cf2b5f3bSDag-Erling Smørgrav 	{ "kerberosorlocalpasswd", sUnsupported },
324cf2b5f3bSDag-Erling Smørgrav 	{ "kerberosticketcleanup", sUnsupported },
3251ec0d754SDag-Erling Smørgrav 	{ "kerberosgetafstoken", sUnsupported },
326cb96ab36SAssar Westerlund #endif
327cf2b5f3bSDag-Erling Smørgrav 	{ "kerberostgtpassing", sUnsupported },
328cf2b5f3bSDag-Erling Smørgrav 	{ "afstokenpassing", sUnsupported },
329cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
330cf2b5f3bSDag-Erling Smørgrav 	{ "gssapiauthentication", sGssAuthentication },
3311ec0d754SDag-Erling Smørgrav 	{ "gssapicleanupcredentials", sGssCleanupCreds },
332cf2b5f3bSDag-Erling Smørgrav #else
333cf2b5f3bSDag-Erling Smørgrav 	{ "gssapiauthentication", sUnsupported },
3341ec0d754SDag-Erling Smørgrav 	{ "gssapicleanupcredentials", sUnsupported },
335511b41d2SMark Murray #endif
336511b41d2SMark Murray 	{ "passwordauthentication", sPasswordAuthentication },
33709958426SBrian Feldman 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
338ca3176e7SBrian Feldman 	{ "challengeresponseauthentication", sChallengeResponseAuthentication },
339ca3176e7SBrian Feldman 	{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
340989dd127SDag-Erling Smørgrav 	{ "checkmail", sDeprecated },
341511b41d2SMark Murray 	{ "listenaddress", sListenAddress },
342aa49c926SDag-Erling Smørgrav 	{ "addressfamily", sAddressFamily },
343511b41d2SMark Murray 	{ "printmotd", sPrintMotd },
344ca3176e7SBrian Feldman 	{ "printlastlog", sPrintLastLog },
345511b41d2SMark Murray 	{ "ignorerhosts", sIgnoreRhosts },
346511b41d2SMark Murray 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
347511b41d2SMark Murray 	{ "x11forwarding", sX11Forwarding },
348511b41d2SMark Murray 	{ "x11displayoffset", sX11DisplayOffset },
349af12a3e7SDag-Erling Smørgrav 	{ "x11uselocalhost", sX11UseLocalhost },
350c2d3a559SKris Kennaway 	{ "xauthlocation", sXAuthLocation },
351511b41d2SMark Murray 	{ "strictmodes", sStrictModes },
352511b41d2SMark Murray 	{ "permitemptypasswords", sEmptyPasswd },
353f388f5efSDag-Erling Smørgrav 	{ "permituserenvironment", sPermitUserEnvironment },
354511b41d2SMark Murray 	{ "uselogin", sUseLogin },
35580628bacSDag-Erling Smørgrav 	{ "compression", sCompression },
3561ec0d754SDag-Erling Smørgrav 	{ "tcpkeepalive", sTCPKeepAlive },
3571ec0d754SDag-Erling Smørgrav 	{ "keepalive", sTCPKeepAlive },				/* obsolete alias */
35809958426SBrian Feldman 	{ "allowtcpforwarding", sAllowTcpForwarding },
359511b41d2SMark Murray 	{ "allowusers", sAllowUsers },
360511b41d2SMark Murray 	{ "denyusers", sDenyUsers },
361511b41d2SMark Murray 	{ "allowgroups", sAllowGroups },
362511b41d2SMark Murray 	{ "denygroups", sDenyGroups },
363e8aafc91SKris Kennaway 	{ "ciphers", sCiphers },
364ca3176e7SBrian Feldman 	{ "macs", sMacs },
365e8aafc91SKris Kennaway 	{ "protocol", sProtocol },
366e8aafc91SKris Kennaway 	{ "gatewayports", sGatewayPorts },
367c2d3a559SKris Kennaway 	{ "subsystem", sSubsystem },
368c2d3a559SKris Kennaway 	{ "maxstartups", sMaxStartups },
36921e764dfSDag-Erling Smørgrav 	{ "maxauthtries", sMaxAuthTries },
370ca3176e7SBrian Feldman 	{ "banner", sBanner },
371cf2b5f3bSDag-Erling Smørgrav 	{ "usedns", sUseDNS },
372cf2b5f3bSDag-Erling Smørgrav 	{ "verifyreversemapping", sDeprecated },
373cf2b5f3bSDag-Erling Smørgrav 	{ "reversemappingcheck", sDeprecated },
374ca3176e7SBrian Feldman 	{ "clientaliveinterval", sClientAliveInterval },
375ca3176e7SBrian Feldman 	{ "clientalivecountmax", sClientAliveCountMax },
376af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile", sAuthorizedKeysFile },
377af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
37880628bacSDag-Erling Smørgrav 	{ "useprivilegeseparation", sUsePrivilegeSeparation},
37921e764dfSDag-Erling Smørgrav 	{ "acceptenv", sAcceptEnv },
380db58a8e4SDag-Erling Smørgrav 	{ "versionaddendum", sVersionAddendum },
381af12a3e7SDag-Erling Smørgrav 	{ NULL, sBadOption }
382511b41d2SMark Murray };
383511b41d2SMark Murray 
384511b41d2SMark Murray /*
385ca3176e7SBrian Feldman  * Returns the number of the token pointed to by cp or sBadOption.
386511b41d2SMark Murray  */
387511b41d2SMark Murray 
388511b41d2SMark Murray static ServerOpCodes
389511b41d2SMark Murray parse_token(const char *cp, const char *filename,
390511b41d2SMark Murray 	    int linenum)
391511b41d2SMark Murray {
392ca3176e7SBrian Feldman 	u_int i;
393511b41d2SMark Murray 
394511b41d2SMark Murray 	for (i = 0; keywords[i].name; i++)
395511b41d2SMark Murray 		if (strcasecmp(cp, keywords[i].name) == 0)
396511b41d2SMark Murray 			return keywords[i].opcode;
397511b41d2SMark Murray 
398ca3176e7SBrian Feldman 	error("%s: line %d: Bad configuration option: %s",
399511b41d2SMark Murray 	    filename, linenum, cp);
400511b41d2SMark Murray 	return sBadOption;
401511b41d2SMark Murray }
402511b41d2SMark Murray 
403af12a3e7SDag-Erling Smørgrav static void
404ca3176e7SBrian Feldman add_listen_addr(ServerOptions *options, char *addr, u_short port)
405511b41d2SMark Murray {
406511b41d2SMark Murray 	int i;
407511b41d2SMark Murray 
408511b41d2SMark Murray 	if (options->num_ports == 0)
409511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
410aa49c926SDag-Erling Smørgrav 	if (options->address_family == -1)
411aa49c926SDag-Erling Smørgrav 		options->address_family = AF_UNSPEC;
412ca3176e7SBrian Feldman 	if (port == 0)
413ca3176e7SBrian Feldman 		for (i = 0; i < options->num_ports; i++)
414ca3176e7SBrian Feldman 			add_one_listen_addr(options, addr, options->ports[i]);
415ca3176e7SBrian Feldman 	else
416ca3176e7SBrian Feldman 		add_one_listen_addr(options, addr, port);
417ca3176e7SBrian Feldman }
418ca3176e7SBrian Feldman 
419af12a3e7SDag-Erling Smørgrav static void
420ca3176e7SBrian Feldman add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
421ca3176e7SBrian Feldman {
422ca3176e7SBrian Feldman 	struct addrinfo hints, *ai, *aitop;
423ca3176e7SBrian Feldman 	char strport[NI_MAXSERV];
424ca3176e7SBrian Feldman 	int gaierr;
425ca3176e7SBrian Feldman 
426511b41d2SMark Murray 	memset(&hints, 0, sizeof(hints));
427aa49c926SDag-Erling Smørgrav 	hints.ai_family = options->address_family;
428511b41d2SMark Murray 	hints.ai_socktype = SOCK_STREAM;
429511b41d2SMark Murray 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
430a82e551fSDag-Erling Smørgrav 	snprintf(strport, sizeof strport, "%u", port);
431511b41d2SMark Murray 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
432ca3176e7SBrian Feldman 		fatal("bad addr or host: %s (%s)",
433511b41d2SMark Murray 		    addr ? addr : "<NULL>",
434511b41d2SMark Murray 		    gai_strerror(gaierr));
435511b41d2SMark Murray 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
436511b41d2SMark Murray 		;
437511b41d2SMark Murray 	ai->ai_next = options->listen_addrs;
438511b41d2SMark Murray 	options->listen_addrs = aitop;
439511b41d2SMark Murray }
440511b41d2SMark Murray 
441af12a3e7SDag-Erling Smørgrav int
442af12a3e7SDag-Erling Smørgrav process_server_config_line(ServerOptions *options, char *line,
443af12a3e7SDag-Erling Smørgrav     const char *filename, int linenum)
444511b41d2SMark Murray {
445ca3176e7SBrian Feldman 	char *cp, **charptr, *arg, *p;
446a82e551fSDag-Erling Smørgrav 	int *intptr, value, i, n;
447511b41d2SMark Murray 	ServerOpCodes opcode;
448aa49c926SDag-Erling Smørgrav 	u_short port;
449511b41d2SMark Murray 
450c2d3a559SKris Kennaway 	cp = line;
451c2d3a559SKris Kennaway 	arg = strdelim(&cp);
452c2d3a559SKris Kennaway 	/* Ignore leading whitespace */
453c2d3a559SKris Kennaway 	if (*arg == '\0')
454c2d3a559SKris Kennaway 		arg = strdelim(&cp);
455ca3176e7SBrian Feldman 	if (!arg || !*arg || *arg == '#')
456af12a3e7SDag-Erling Smørgrav 		return 0;
457ca3176e7SBrian Feldman 	intptr = NULL;
458ca3176e7SBrian Feldman 	charptr = NULL;
459c2d3a559SKris Kennaway 	opcode = parse_token(arg, filename, linenum);
460511b41d2SMark Murray 	switch (opcode) {
461989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
462cf2b5f3bSDag-Erling Smørgrav 	case sUsePAM:
463cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->use_pam;
464989dd127SDag-Erling Smørgrav 		goto parse_flag;
465989dd127SDag-Erling Smørgrav 
466989dd127SDag-Erling Smørgrav 	/* Standard Options */
467511b41d2SMark Murray 	case sBadOption:
468af12a3e7SDag-Erling Smørgrav 		return -1;
469511b41d2SMark Murray 	case sPort:
470511b41d2SMark Murray 		/* ignore ports from configfile if cmdline specifies ports */
471511b41d2SMark Murray 		if (options->ports_from_cmdline)
472af12a3e7SDag-Erling Smørgrav 			return 0;
473511b41d2SMark Murray 		if (options->listen_addrs != NULL)
474511b41d2SMark Murray 			fatal("%s line %d: ports must be specified before "
475af12a3e7SDag-Erling Smørgrav 			    "ListenAddress.", filename, linenum);
476511b41d2SMark Murray 		if (options->num_ports >= MAX_PORTS)
477ca3176e7SBrian Feldman 			fatal("%s line %d: too many ports.",
478511b41d2SMark Murray 			    filename, linenum);
479c2d3a559SKris Kennaway 		arg = strdelim(&cp);
480c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
481ca3176e7SBrian Feldman 			fatal("%s line %d: missing port number.",
482511b41d2SMark Murray 			    filename, linenum);
483ca3176e7SBrian Feldman 		options->ports[options->num_ports++] = a2port(arg);
484ca3176e7SBrian Feldman 		if (options->ports[options->num_ports-1] == 0)
485ca3176e7SBrian Feldman 			fatal("%s line %d: Badly formatted port number.",
486ca3176e7SBrian Feldman 			    filename, linenum);
487511b41d2SMark Murray 		break;
488511b41d2SMark Murray 
489511b41d2SMark Murray 	case sServerKeyBits:
490511b41d2SMark Murray 		intptr = &options->server_key_bits;
491511b41d2SMark Murray parse_int:
492c2d3a559SKris Kennaway 		arg = strdelim(&cp);
493ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
494ca3176e7SBrian Feldman 			fatal("%s line %d: missing integer value.",
495511b41d2SMark Murray 			    filename, linenum);
496c2d3a559SKris Kennaway 		value = atoi(arg);
497511b41d2SMark Murray 		if (*intptr == -1)
498511b41d2SMark Murray 			*intptr = value;
499511b41d2SMark Murray 		break;
500511b41d2SMark Murray 
501511b41d2SMark Murray 	case sLoginGraceTime:
502511b41d2SMark Murray 		intptr = &options->login_grace_time;
503af12a3e7SDag-Erling Smørgrav parse_time:
504af12a3e7SDag-Erling Smørgrav 		arg = strdelim(&cp);
505af12a3e7SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
506af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: missing time value.",
507af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
508af12a3e7SDag-Erling Smørgrav 		if ((value = convtime(arg)) == -1)
509af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: invalid time value.",
510af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
511af12a3e7SDag-Erling Smørgrav 		if (*intptr == -1)
512af12a3e7SDag-Erling Smørgrav 			*intptr = value;
513af12a3e7SDag-Erling Smørgrav 		break;
514511b41d2SMark Murray 
515511b41d2SMark Murray 	case sKeyRegenerationTime:
516511b41d2SMark Murray 		intptr = &options->key_regeneration_time;
517af12a3e7SDag-Erling Smørgrav 		goto parse_time;
518511b41d2SMark Murray 
519511b41d2SMark Murray 	case sListenAddress:
520c2d3a559SKris Kennaway 		arg = strdelim(&cp);
521aa49c926SDag-Erling Smørgrav 		if (arg == NULL || *arg == '\0')
522aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: missing address",
523511b41d2SMark Murray 			    filename, linenum);
524aa49c926SDag-Erling Smørgrav 		p = hpdelim(&arg);
525aa49c926SDag-Erling Smørgrav 		if (p == NULL)
526aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: bad address:port usage",
527ca3176e7SBrian Feldman 			    filename, linenum);
528aa49c926SDag-Erling Smørgrav 		p = cleanhostname(p);
529aa49c926SDag-Erling Smørgrav 		if (arg == NULL)
530aa49c926SDag-Erling Smørgrav 			port = 0;
531aa49c926SDag-Erling Smørgrav 		else if ((port = a2port(arg)) == 0)
532aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: bad port number", filename, linenum);
533ca3176e7SBrian Feldman 
534aa49c926SDag-Erling Smørgrav 		add_listen_addr(options, p, port);
535aa49c926SDag-Erling Smørgrav 
536aa49c926SDag-Erling Smørgrav 		break;
537aa49c926SDag-Erling Smørgrav 
538aa49c926SDag-Erling Smørgrav 	case sAddressFamily:
539aa49c926SDag-Erling Smørgrav 		arg = strdelim(&cp);
540aa49c926SDag-Erling Smørgrav 		intptr = &options->address_family;
541aa49c926SDag-Erling Smørgrav 		if (options->listen_addrs != NULL)
542aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: address family must be specified before "
543aa49c926SDag-Erling Smørgrav 			    "ListenAddress.", filename, linenum);
544aa49c926SDag-Erling Smørgrav 		if (strcasecmp(arg, "inet") == 0)
545aa49c926SDag-Erling Smørgrav 			value = AF_INET;
546aa49c926SDag-Erling Smørgrav 		else if (strcasecmp(arg, "inet6") == 0)
547aa49c926SDag-Erling Smørgrav 			value = AF_INET6;
548aa49c926SDag-Erling Smørgrav 		else if (strcasecmp(arg, "any") == 0)
549aa49c926SDag-Erling Smørgrav 			value = AF_UNSPEC;
550ca3176e7SBrian Feldman 		else
551aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: unsupported address family \"%s\".",
552aa49c926SDag-Erling Smørgrav 			    filename, linenum, arg);
553aa49c926SDag-Erling Smørgrav 		if (*intptr == -1)
554aa49c926SDag-Erling Smørgrav 			*intptr = value;
555511b41d2SMark Murray 		break;
556511b41d2SMark Murray 
557511b41d2SMark Murray 	case sHostKeyFile:
558ca3176e7SBrian Feldman 		intptr = &options->num_host_key_files;
559ca3176e7SBrian Feldman 		if (*intptr >= MAX_HOSTKEYS)
560ca3176e7SBrian Feldman 			fatal("%s line %d: too many host keys specified (max %d).",
561ca3176e7SBrian Feldman 			    filename, linenum, MAX_HOSTKEYS);
562ca3176e7SBrian Feldman 		charptr = &options->host_key_files[*intptr];
563c2d3a559SKris Kennaway parse_filename:
564c2d3a559SKris Kennaway 		arg = strdelim(&cp);
565ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
566ca3176e7SBrian Feldman 			fatal("%s line %d: missing file name.",
567e8aafc91SKris Kennaway 			    filename, linenum);
568ca3176e7SBrian Feldman 		if (*charptr == NULL) {
569c2d3a559SKris Kennaway 			*charptr = tilde_expand_filename(arg, getuid());
570ca3176e7SBrian Feldman 			/* increase optional counter */
571ca3176e7SBrian Feldman 			if (intptr != NULL)
572ca3176e7SBrian Feldman 				*intptr = *intptr + 1;
573ca3176e7SBrian Feldman 		}
574e8aafc91SKris Kennaway 		break;
575e8aafc91SKris Kennaway 
576e8aafc91SKris Kennaway 	case sPidFile:
577e8aafc91SKris Kennaway 		charptr = &options->pid_file;
578c2d3a559SKris Kennaway 		goto parse_filename;
579511b41d2SMark Murray 
580511b41d2SMark Murray 	case sPermitRootLogin:
581511b41d2SMark Murray 		intptr = &options->permit_root_login;
582c2d3a559SKris Kennaway 		arg = strdelim(&cp);
583ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
584ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/"
585ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
586ca3176e7SBrian Feldman 			    "argument.", filename, linenum);
587ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
588c2d3a559SKris Kennaway 		if (strcmp(arg, "without-password") == 0)
589ca3176e7SBrian Feldman 			value = PERMIT_NO_PASSWD;
590ca3176e7SBrian Feldman 		else if (strcmp(arg, "forced-commands-only") == 0)
591ca3176e7SBrian Feldman 			value = PERMIT_FORCED_ONLY;
592c2d3a559SKris Kennaway 		else if (strcmp(arg, "yes") == 0)
593ca3176e7SBrian Feldman 			value = PERMIT_YES;
594c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
595ca3176e7SBrian Feldman 			value = PERMIT_NO;
596ca3176e7SBrian Feldman 		else
597ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/"
598ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
599ca3176e7SBrian Feldman 			    "argument: %s", filename, linenum, arg);
600511b41d2SMark Murray 		if (*intptr == -1)
601511b41d2SMark Murray 			*intptr = value;
602511b41d2SMark Murray 		break;
603511b41d2SMark Murray 
604511b41d2SMark Murray 	case sIgnoreRhosts:
605511b41d2SMark Murray 		intptr = &options->ignore_rhosts;
606511b41d2SMark Murray parse_flag:
607c2d3a559SKris Kennaway 		arg = strdelim(&cp);
608ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
609ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/no argument.",
610511b41d2SMark Murray 			    filename, linenum);
611ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
612c2d3a559SKris Kennaway 		if (strcmp(arg, "yes") == 0)
613511b41d2SMark Murray 			value = 1;
614c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
615511b41d2SMark Murray 			value = 0;
616ca3176e7SBrian Feldman 		else
617ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/no argument: %s",
618c2d3a559SKris Kennaway 				filename, linenum, arg);
619511b41d2SMark Murray 		if (*intptr == -1)
620511b41d2SMark Murray 			*intptr = value;
621511b41d2SMark Murray 		break;
622511b41d2SMark Murray 
623511b41d2SMark Murray 	case sIgnoreUserKnownHosts:
624511b41d2SMark Murray 		intptr = &options->ignore_user_known_hosts;
625962a3f4eSSheldon Hearn 		goto parse_flag;
626511b41d2SMark Murray 
627511b41d2SMark Murray 	case sRhostsRSAAuthentication:
628511b41d2SMark Murray 		intptr = &options->rhosts_rsa_authentication;
629511b41d2SMark Murray 		goto parse_flag;
630511b41d2SMark Murray 
631ca3176e7SBrian Feldman 	case sHostbasedAuthentication:
632ca3176e7SBrian Feldman 		intptr = &options->hostbased_authentication;
633ca3176e7SBrian Feldman 		goto parse_flag;
634ca3176e7SBrian Feldman 
635ca3176e7SBrian Feldman 	case sHostbasedUsesNameFromPacketOnly:
636ca3176e7SBrian Feldman 		intptr = &options->hostbased_uses_name_from_packet_only;
637ca3176e7SBrian Feldman 		goto parse_flag;
638ca3176e7SBrian Feldman 
639511b41d2SMark Murray 	case sRSAAuthentication:
640511b41d2SMark Murray 		intptr = &options->rsa_authentication;
641511b41d2SMark Murray 		goto parse_flag;
642511b41d2SMark Murray 
643ca3176e7SBrian Feldman 	case sPubkeyAuthentication:
644ca3176e7SBrian Feldman 		intptr = &options->pubkey_authentication;
645e8aafc91SKris Kennaway 		goto parse_flag;
646cf2b5f3bSDag-Erling Smørgrav 
647cb96ab36SAssar Westerlund 	case sKerberosAuthentication:
648cb96ab36SAssar Westerlund 		intptr = &options->kerberos_authentication;
649511b41d2SMark Murray 		goto parse_flag;
650511b41d2SMark Murray 
651af12a3e7SDag-Erling Smørgrav 	case sKerberosOrLocalPasswd:
652af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_or_local_passwd;
653511b41d2SMark Murray 		goto parse_flag;
654511b41d2SMark Murray 
655af12a3e7SDag-Erling Smørgrav 	case sKerberosTicketCleanup:
656af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_ticket_cleanup;
657511b41d2SMark Murray 		goto parse_flag;
658cf2b5f3bSDag-Erling Smørgrav 
6591ec0d754SDag-Erling Smørgrav 	case sKerberosGetAFSToken:
6601ec0d754SDag-Erling Smørgrav 		intptr = &options->kerberos_get_afs_token;
6611ec0d754SDag-Erling Smørgrav 		goto parse_flag;
6621ec0d754SDag-Erling Smørgrav 
663cf2b5f3bSDag-Erling Smørgrav 	case sGssAuthentication:
664cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->gss_authentication;
665fe5fd017SMark Murray 		goto parse_flag;
666cf2b5f3bSDag-Erling Smørgrav 
667cf2b5f3bSDag-Erling Smørgrav 	case sGssCleanupCreds:
668cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->gss_cleanup_creds;
669511b41d2SMark Murray 		goto parse_flag;
670511b41d2SMark Murray 
671511b41d2SMark Murray 	case sPasswordAuthentication:
672511b41d2SMark Murray 		intptr = &options->password_authentication;
673511b41d2SMark Murray 		goto parse_flag;
674511b41d2SMark Murray 
67509958426SBrian Feldman 	case sKbdInteractiveAuthentication:
67609958426SBrian Feldman 		intptr = &options->kbd_interactive_authentication;
67709958426SBrian Feldman 		goto parse_flag;
67809958426SBrian Feldman 
679ca3176e7SBrian Feldman 	case sChallengeResponseAuthentication:
680af12a3e7SDag-Erling Smørgrav 		intptr = &options->challenge_response_authentication;
681511b41d2SMark Murray 		goto parse_flag;
682511b41d2SMark Murray 
683511b41d2SMark Murray 	case sPrintMotd:
684511b41d2SMark Murray 		intptr = &options->print_motd;
685511b41d2SMark Murray 		goto parse_flag;
686511b41d2SMark Murray 
687ca3176e7SBrian Feldman 	case sPrintLastLog:
688ca3176e7SBrian Feldman 		intptr = &options->print_lastlog;
689ca3176e7SBrian Feldman 		goto parse_flag;
690ca3176e7SBrian Feldman 
691511b41d2SMark Murray 	case sX11Forwarding:
692511b41d2SMark Murray 		intptr = &options->x11_forwarding;
693511b41d2SMark Murray 		goto parse_flag;
694511b41d2SMark Murray 
695511b41d2SMark Murray 	case sX11DisplayOffset:
696511b41d2SMark Murray 		intptr = &options->x11_display_offset;
697511b41d2SMark Murray 		goto parse_int;
698511b41d2SMark Murray 
699af12a3e7SDag-Erling Smørgrav 	case sX11UseLocalhost:
700af12a3e7SDag-Erling Smørgrav 		intptr = &options->x11_use_localhost;
701af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
702af12a3e7SDag-Erling Smørgrav 
703c2d3a559SKris Kennaway 	case sXAuthLocation:
704c2d3a559SKris Kennaway 		charptr = &options->xauth_location;
705c2d3a559SKris Kennaway 		goto parse_filename;
706c2d3a559SKris Kennaway 
707511b41d2SMark Murray 	case sStrictModes:
708511b41d2SMark Murray 		intptr = &options->strict_modes;
709511b41d2SMark Murray 		goto parse_flag;
710511b41d2SMark Murray 
7111ec0d754SDag-Erling Smørgrav 	case sTCPKeepAlive:
7121ec0d754SDag-Erling Smørgrav 		intptr = &options->tcp_keep_alive;
713511b41d2SMark Murray 		goto parse_flag;
714511b41d2SMark Murray 
715511b41d2SMark Murray 	case sEmptyPasswd:
716511b41d2SMark Murray 		intptr = &options->permit_empty_passwd;
717511b41d2SMark Murray 		goto parse_flag;
718511b41d2SMark Murray 
719f388f5efSDag-Erling Smørgrav 	case sPermitUserEnvironment:
720f388f5efSDag-Erling Smørgrav 		intptr = &options->permit_user_env;
721f388f5efSDag-Erling Smørgrav 		goto parse_flag;
722f388f5efSDag-Erling Smørgrav 
723511b41d2SMark Murray 	case sUseLogin:
724511b41d2SMark Murray 		intptr = &options->use_login;
725511b41d2SMark Murray 		goto parse_flag;
726511b41d2SMark Murray 
72780628bacSDag-Erling Smørgrav 	case sCompression:
72880628bacSDag-Erling Smørgrav 		intptr = &options->compression;
72980628bacSDag-Erling Smørgrav 		goto parse_flag;
73080628bacSDag-Erling Smørgrav 
731e8aafc91SKris Kennaway 	case sGatewayPorts:
732e8aafc91SKris Kennaway 		intptr = &options->gateway_ports;
733aa49c926SDag-Erling Smørgrav 		arg = strdelim(&cp);
734aa49c926SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
735aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: missing yes/no/clientspecified "
736aa49c926SDag-Erling Smørgrav 			    "argument.", filename, linenum);
737aa49c926SDag-Erling Smørgrav 		value = 0;	/* silence compiler */
738aa49c926SDag-Erling Smørgrav 		if (strcmp(arg, "clientspecified") == 0)
739aa49c926SDag-Erling Smørgrav 			value = 2;
740aa49c926SDag-Erling Smørgrav 		else if (strcmp(arg, "yes") == 0)
741aa49c926SDag-Erling Smørgrav 			value = 1;
742aa49c926SDag-Erling Smørgrav 		else if (strcmp(arg, "no") == 0)
743aa49c926SDag-Erling Smørgrav 			value = 0;
744aa49c926SDag-Erling Smørgrav 		else
745aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: Bad yes/no/clientspecified "
746aa49c926SDag-Erling Smørgrav 			    "argument: %s", filename, linenum, arg);
747aa49c926SDag-Erling Smørgrav 		if (*intptr == -1)
748aa49c926SDag-Erling Smørgrav 			*intptr = value;
749aa49c926SDag-Erling Smørgrav 		break;
750e8aafc91SKris Kennaway 
751cf2b5f3bSDag-Erling Smørgrav 	case sUseDNS:
752cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->use_dns;
753ca3176e7SBrian Feldman 		goto parse_flag;
754ca3176e7SBrian Feldman 
755511b41d2SMark Murray 	case sLogFacility:
756511b41d2SMark Murray 		intptr = (int *) &options->log_facility;
757c2d3a559SKris Kennaway 		arg = strdelim(&cp);
758c2d3a559SKris Kennaway 		value = log_facility_number(arg);
759af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_FACILITY_NOT_SET)
760ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log facility '%s'",
761c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
762511b41d2SMark Murray 		if (*intptr == -1)
763511b41d2SMark Murray 			*intptr = (SyslogFacility) value;
764511b41d2SMark Murray 		break;
765511b41d2SMark Murray 
766511b41d2SMark Murray 	case sLogLevel:
767511b41d2SMark Murray 		intptr = (int *) &options->log_level;
768c2d3a559SKris Kennaway 		arg = strdelim(&cp);
769c2d3a559SKris Kennaway 		value = log_level_number(arg);
770af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_LEVEL_NOT_SET)
771ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log level '%s'",
772c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
773511b41d2SMark Murray 		if (*intptr == -1)
774511b41d2SMark Murray 			*intptr = (LogLevel) value;
775511b41d2SMark Murray 		break;
776511b41d2SMark Murray 
77709958426SBrian Feldman 	case sAllowTcpForwarding:
77809958426SBrian Feldman 		intptr = &options->allow_tcp_forwarding;
77909958426SBrian Feldman 		goto parse_flag;
78009958426SBrian Feldman 
78180628bacSDag-Erling Smørgrav 	case sUsePrivilegeSeparation:
78280628bacSDag-Erling Smørgrav 		intptr = &use_privsep;
78380628bacSDag-Erling Smørgrav 		goto parse_flag;
78480628bacSDag-Erling Smørgrav 
785511b41d2SMark Murray 	case sAllowUsers:
786c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
78742f71286SMark Murray 			if (options->num_allow_users >= MAX_ALLOW_USERS)
788af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow users.",
789e8aafc91SKris Kennaway 				    filename, linenum);
790a82e551fSDag-Erling Smørgrav 			options->allow_users[options->num_allow_users++] =
791a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
792511b41d2SMark Murray 		}
793511b41d2SMark Murray 		break;
794511b41d2SMark Murray 
795511b41d2SMark Murray 	case sDenyUsers:
796c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
7972803b77eSBrian Feldman 			if (options->num_deny_users >= MAX_DENY_USERS)
798af12a3e7SDag-Erling Smørgrav 				fatal( "%s line %d: too many deny users.",
799e8aafc91SKris Kennaway 				    filename, linenum);
800a82e551fSDag-Erling Smørgrav 			options->deny_users[options->num_deny_users++] =
801a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
802511b41d2SMark Murray 		}
803511b41d2SMark Murray 		break;
804511b41d2SMark Murray 
805511b41d2SMark Murray 	case sAllowGroups:
806c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
80742f71286SMark Murray 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
808af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow groups.",
809e8aafc91SKris Kennaway 				    filename, linenum);
810a82e551fSDag-Erling Smørgrav 			options->allow_groups[options->num_allow_groups++] =
811a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
812511b41d2SMark Murray 		}
813511b41d2SMark Murray 		break;
814511b41d2SMark Murray 
815511b41d2SMark Murray 	case sDenyGroups:
816c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
81742f71286SMark Murray 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
818af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many deny groups.",
819e8aafc91SKris Kennaway 				    filename, linenum);
820c2d3a559SKris Kennaway 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
821511b41d2SMark Murray 		}
822511b41d2SMark Murray 		break;
823511b41d2SMark Murray 
824e8aafc91SKris Kennaway 	case sCiphers:
825c2d3a559SKris Kennaway 		arg = strdelim(&cp);
826c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
827c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
828c2d3a559SKris Kennaway 		if (!ciphers_valid(arg))
829e8aafc91SKris Kennaway 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
830c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
831e8aafc91SKris Kennaway 		if (options->ciphers == NULL)
832c2d3a559SKris Kennaway 			options->ciphers = xstrdup(arg);
833e8aafc91SKris Kennaway 		break;
834e8aafc91SKris Kennaway 
835ca3176e7SBrian Feldman 	case sMacs:
836ca3176e7SBrian Feldman 		arg = strdelim(&cp);
837ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
838ca3176e7SBrian Feldman 			fatal("%s line %d: Missing argument.", filename, linenum);
839ca3176e7SBrian Feldman 		if (!mac_valid(arg))
840ca3176e7SBrian Feldman 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
841ca3176e7SBrian Feldman 			    filename, linenum, arg ? arg : "<NONE>");
842ca3176e7SBrian Feldman 		if (options->macs == NULL)
843ca3176e7SBrian Feldman 			options->macs = xstrdup(arg);
844ca3176e7SBrian Feldman 		break;
845ca3176e7SBrian Feldman 
846e8aafc91SKris Kennaway 	case sProtocol:
847e8aafc91SKris Kennaway 		intptr = &options->protocol;
848c2d3a559SKris Kennaway 		arg = strdelim(&cp);
849c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
850c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
851c2d3a559SKris Kennaway 		value = proto_spec(arg);
852e8aafc91SKris Kennaway 		if (value == SSH_PROTO_UNKNOWN)
853e8aafc91SKris Kennaway 			fatal("%s line %d: Bad protocol spec '%s'.",
854c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
855e8aafc91SKris Kennaway 		if (*intptr == SSH_PROTO_UNKNOWN)
856e8aafc91SKris Kennaway 			*intptr = value;
857e8aafc91SKris Kennaway 		break;
858e8aafc91SKris Kennaway 
859c2d3a559SKris Kennaway 	case sSubsystem:
860c2d3a559SKris Kennaway 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
861c2d3a559SKris Kennaway 			fatal("%s line %d: too many subsystems defined.",
862c2d3a559SKris Kennaway 			    filename, linenum);
863c2d3a559SKris Kennaway 		}
864c2d3a559SKris Kennaway 		arg = strdelim(&cp);
865c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
866c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem name.",
867c2d3a559SKris Kennaway 			    filename, linenum);
868c2d3a559SKris Kennaway 		for (i = 0; i < options->num_subsystems; i++)
869c2d3a559SKris Kennaway 			if (strcmp(arg, options->subsystem_name[i]) == 0)
870c2d3a559SKris Kennaway 				fatal("%s line %d: Subsystem '%s' already defined.",
871c2d3a559SKris Kennaway 				    filename, linenum, arg);
872c2d3a559SKris Kennaway 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
873c2d3a559SKris Kennaway 		arg = strdelim(&cp);
874c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
875c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem command.",
876c2d3a559SKris Kennaway 			    filename, linenum);
877c2d3a559SKris Kennaway 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
878c2d3a559SKris Kennaway 		options->num_subsystems++;
879c2d3a559SKris Kennaway 		break;
880c2d3a559SKris Kennaway 
881c2d3a559SKris Kennaway 	case sMaxStartups:
882c2d3a559SKris Kennaway 		arg = strdelim(&cp);
883c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
884c2d3a559SKris Kennaway 			fatal("%s line %d: Missing MaxStartups spec.",
885c2d3a559SKris Kennaway 			    filename, linenum);
886af12a3e7SDag-Erling Smørgrav 		if ((n = sscanf(arg, "%d:%d:%d",
887c2d3a559SKris Kennaway 		    &options->max_startups_begin,
888c2d3a559SKris Kennaway 		    &options->max_startups_rate,
889af12a3e7SDag-Erling Smørgrav 		    &options->max_startups)) == 3) {
890c2d3a559SKris Kennaway 			if (options->max_startups_begin >
891c2d3a559SKris Kennaway 			    options->max_startups ||
892c2d3a559SKris Kennaway 			    options->max_startups_rate > 100 ||
893c2d3a559SKris Kennaway 			    options->max_startups_rate < 1)
894c2d3a559SKris Kennaway 				fatal("%s line %d: Illegal MaxStartups spec.",
895c2d3a559SKris Kennaway 				    filename, linenum);
896af12a3e7SDag-Erling Smørgrav 		} else if (n != 1)
897af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: Illegal MaxStartups spec.",
898af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
899af12a3e7SDag-Erling Smørgrav 		else
900af12a3e7SDag-Erling Smørgrav 			options->max_startups = options->max_startups_begin;
901933ca70fSBrian Feldman 		break;
902933ca70fSBrian Feldman 
90321e764dfSDag-Erling Smørgrav 	case sMaxAuthTries:
90421e764dfSDag-Erling Smørgrav 		intptr = &options->max_authtries;
90521e764dfSDag-Erling Smørgrav 		goto parse_int;
90621e764dfSDag-Erling Smørgrav 
907ca3176e7SBrian Feldman 	case sBanner:
908ca3176e7SBrian Feldman 		charptr = &options->banner;
909ca3176e7SBrian Feldman 		goto parse_filename;
910af12a3e7SDag-Erling Smørgrav 	/*
911af12a3e7SDag-Erling Smørgrav 	 * These options can contain %X options expanded at
912af12a3e7SDag-Erling Smørgrav 	 * connect time, so that you can specify paths like:
913af12a3e7SDag-Erling Smørgrav 	 *
914af12a3e7SDag-Erling Smørgrav 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
915af12a3e7SDag-Erling Smørgrav 	 */
916af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile:
917af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile2:
918af12a3e7SDag-Erling Smørgrav 		charptr = (opcode == sAuthorizedKeysFile ) ?
919af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file :
920af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file2;
921af12a3e7SDag-Erling Smørgrav 		goto parse_filename;
922af12a3e7SDag-Erling Smørgrav 
923ca3176e7SBrian Feldman 	case sClientAliveInterval:
924ca3176e7SBrian Feldman 		intptr = &options->client_alive_interval;
925af12a3e7SDag-Erling Smørgrav 		goto parse_time;
926af12a3e7SDag-Erling Smørgrav 
927ca3176e7SBrian Feldman 	case sClientAliveCountMax:
928ca3176e7SBrian Feldman 		intptr = &options->client_alive_count_max;
929ca3176e7SBrian Feldman 		goto parse_int;
930af12a3e7SDag-Erling Smørgrav 
93121e764dfSDag-Erling Smørgrav 	case sAcceptEnv:
93221e764dfSDag-Erling Smørgrav 		while ((arg = strdelim(&cp)) && *arg != '\0') {
93321e764dfSDag-Erling Smørgrav 			if (strchr(arg, '=') != NULL)
93421e764dfSDag-Erling Smørgrav 				fatal("%s line %d: Invalid environment name.",
93521e764dfSDag-Erling Smørgrav 				    filename, linenum);
93621e764dfSDag-Erling Smørgrav 			if (options->num_accept_env >= MAX_ACCEPT_ENV)
93721e764dfSDag-Erling Smørgrav 				fatal("%s line %d: too many allow env.",
93821e764dfSDag-Erling Smørgrav 				    filename, linenum);
93921e764dfSDag-Erling Smørgrav 			options->accept_env[options->num_accept_env++] =
94021e764dfSDag-Erling Smørgrav 			    xstrdup(arg);
94121e764dfSDag-Erling Smørgrav 		}
94221e764dfSDag-Erling Smørgrav 		break;
94321e764dfSDag-Erling Smørgrav 
944db58a8e4SDag-Erling Smørgrav 	case sVersionAddendum:
945db58a8e4SDag-Erling Smørgrav                 ssh_version_set_addendum(strtok(cp, "\n"));
946db58a8e4SDag-Erling Smørgrav                 do {
947db58a8e4SDag-Erling Smørgrav                         arg = strdelim(&cp);
948db58a8e4SDag-Erling Smørgrav                 } while (arg != NULL && *arg != '\0');
949db58a8e4SDag-Erling Smørgrav 		break;
950db58a8e4SDag-Erling Smørgrav 
951af12a3e7SDag-Erling Smørgrav 	case sDeprecated:
952cf2b5f3bSDag-Erling Smørgrav 		logit("%s line %d: Deprecated option %s",
953cf2b5f3bSDag-Erling Smørgrav 		    filename, linenum, arg);
954cf2b5f3bSDag-Erling Smørgrav 		while (arg)
955cf2b5f3bSDag-Erling Smørgrav 		    arg = strdelim(&cp);
956cf2b5f3bSDag-Erling Smørgrav 		break;
957cf2b5f3bSDag-Erling Smørgrav 
958cf2b5f3bSDag-Erling Smørgrav 	case sUnsupported:
959cf2b5f3bSDag-Erling Smørgrav 		logit("%s line %d: Unsupported option %s",
960af12a3e7SDag-Erling Smørgrav 		    filename, linenum, arg);
961af12a3e7SDag-Erling Smørgrav 		while (arg)
962af12a3e7SDag-Erling Smørgrav 		    arg = strdelim(&cp);
963af12a3e7SDag-Erling Smørgrav 		break;
964af12a3e7SDag-Erling Smørgrav 
96542f71286SMark Murray 	default:
966af12a3e7SDag-Erling Smørgrav 		fatal("%s line %d: Missing handler for opcode %s (%d)",
967c2d3a559SKris Kennaway 		    filename, linenum, arg, opcode);
968511b41d2SMark Murray 	}
969ca3176e7SBrian Feldman 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
970ca3176e7SBrian Feldman 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
971c2d3a559SKris Kennaway 		    filename, linenum, arg);
972af12a3e7SDag-Erling Smørgrav 	return 0;
973af12a3e7SDag-Erling Smørgrav }
974af12a3e7SDag-Erling Smørgrav 
975af12a3e7SDag-Erling Smørgrav /* Reads the server configuration file. */
976af12a3e7SDag-Erling Smørgrav 
977af12a3e7SDag-Erling Smørgrav void
97821e764dfSDag-Erling Smørgrav load_server_config(const char *filename, Buffer *conf)
979af12a3e7SDag-Erling Smørgrav {
98021e764dfSDag-Erling Smørgrav 	char line[1024], *cp;
981a82e551fSDag-Erling Smørgrav 	FILE *f;
982af12a3e7SDag-Erling Smørgrav 
98321e764dfSDag-Erling Smørgrav 	debug2("%s: filename %s", __func__, filename);
98421e764dfSDag-Erling Smørgrav 	if ((f = fopen(filename, "r")) == NULL) {
985af12a3e7SDag-Erling Smørgrav 		perror(filename);
986af12a3e7SDag-Erling Smørgrav 		exit(1);
987af12a3e7SDag-Erling Smørgrav 	}
98821e764dfSDag-Erling Smørgrav 	buffer_clear(conf);
989af12a3e7SDag-Erling Smørgrav 	while (fgets(line, sizeof(line), f)) {
99021e764dfSDag-Erling Smørgrav 		/*
99121e764dfSDag-Erling Smørgrav 		 * Trim out comments and strip whitespace
99221e764dfSDag-Erling Smørgrav 		 * NB - preserve newlines, they are needed to reproduce
99321e764dfSDag-Erling Smørgrav 		 * line numbers later for error messages
99421e764dfSDag-Erling Smørgrav 		 */
99521e764dfSDag-Erling Smørgrav 		if ((cp = strchr(line, '#')) != NULL)
99621e764dfSDag-Erling Smørgrav 			memcpy(cp, "\n", 2);
99721e764dfSDag-Erling Smørgrav 		cp = line + strspn(line, " \t\r");
99821e764dfSDag-Erling Smørgrav 
99921e764dfSDag-Erling Smørgrav 		buffer_append(conf, cp, strlen(cp));
100021e764dfSDag-Erling Smørgrav 	}
100121e764dfSDag-Erling Smørgrav 	buffer_append(conf, "\0", 1);
100221e764dfSDag-Erling Smørgrav 	fclose(f);
100321e764dfSDag-Erling Smørgrav 	debug2("%s: done config len = %d", __func__, buffer_len(conf));
100421e764dfSDag-Erling Smørgrav }
100521e764dfSDag-Erling Smørgrav 
100621e764dfSDag-Erling Smørgrav void
100721e764dfSDag-Erling Smørgrav parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
100821e764dfSDag-Erling Smørgrav {
100921e764dfSDag-Erling Smørgrav 	int linenum, bad_options = 0;
101021e764dfSDag-Erling Smørgrav 	char *cp, *obuf, *cbuf;
101121e764dfSDag-Erling Smørgrav 
101221e764dfSDag-Erling Smørgrav 	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
101321e764dfSDag-Erling Smørgrav 
101421e764dfSDag-Erling Smørgrav 	obuf = cbuf = xstrdup(buffer_ptr(conf));
101521e764dfSDag-Erling Smørgrav 	linenum = 1;
101621e764dfSDag-Erling Smørgrav 	while ((cp = strsep(&cbuf, "\n")) != NULL) {
101721e764dfSDag-Erling Smørgrav 		if (process_server_config_line(options, cp, filename,
101821e764dfSDag-Erling Smørgrav 		    linenum++) != 0)
1019af12a3e7SDag-Erling Smørgrav 			bad_options++;
1020511b41d2SMark Murray 	}
102121e764dfSDag-Erling Smørgrav 	xfree(obuf);
1022ca3176e7SBrian Feldman 	if (bad_options > 0)
1023af12a3e7SDag-Erling Smørgrav 		fatal("%s: terminating, %d bad configuration options",
1024511b41d2SMark Murray 		    filename, bad_options);
1025511b41d2SMark Murray }
1026