xref: /freebsd/crypto/openssh/servconf.c (revision b74df5b26fa43e05a034a6ce662dcf286a1ffdd9)
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"
13b74df5b2SDag-Erling Smørgrav RCSID("$OpenBSD: servconf.c,v 1.146 2005/12/08 18:34:11 reyk 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;
105b74df5b2SDag-Erling Smørgrav 	options->permit_tun = -1;
10680628bacSDag-Erling Smørgrav 
10780628bacSDag-Erling Smørgrav 	/* Needs to be accessable in many places */
10880628bacSDag-Erling Smørgrav 	use_privsep = -1;
109511b41d2SMark Murray }
110511b41d2SMark Murray 
111511b41d2SMark Murray void
112511b41d2SMark Murray fill_default_server_options(ServerOptions *options)
113511b41d2SMark Murray {
114989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
115cf2b5f3bSDag-Erling Smørgrav 	if (options->use_pam == -1)
116f0477b26SDag-Erling Smørgrav 		options->use_pam = 1;
117989dd127SDag-Erling Smørgrav 
118989dd127SDag-Erling Smørgrav 	/* Standard Options */
119ca3176e7SBrian Feldman 	if (options->protocol == SSH_PROTO_UNKNOWN)
120028c324aSDag-Erling Smørgrav 		options->protocol = SSH_PROTO_2;
121ca3176e7SBrian Feldman 	if (options->num_host_key_files == 0) {
122ca3176e7SBrian Feldman 		/* fill default hostkeys for protocols */
123ca3176e7SBrian Feldman 		if (options->protocol & SSH_PROTO_1)
124af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
125af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_KEY_FILE;
126af12a3e7SDag-Erling Smørgrav 		if (options->protocol & SSH_PROTO_2) {
127af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
128af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_DSA_KEY_FILE;
129af12a3e7SDag-Erling Smørgrav 		}
130ca3176e7SBrian Feldman 	}
131511b41d2SMark Murray 	if (options->num_ports == 0)
132511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
133511b41d2SMark Murray 	if (options->listen_addrs == NULL)
134ca3176e7SBrian Feldman 		add_listen_addr(options, NULL, 0);
135e8aafc91SKris Kennaway 	if (options->pid_file == NULL)
136ca3176e7SBrian Feldman 		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
137511b41d2SMark Murray 	if (options->server_key_bits == -1)
138511b41d2SMark Murray 		options->server_key_bits = 768;
139511b41d2SMark Murray 	if (options->login_grace_time == -1)
140975616f0SDag-Erling Smørgrav 		options->login_grace_time = 120;
141511b41d2SMark Murray 	if (options->key_regeneration_time == -1)
142511b41d2SMark Murray 		options->key_regeneration_time = 3600;
143ca3176e7SBrian Feldman 	if (options->permit_root_login == PERMIT_NOT_SET)
144975616f0SDag-Erling Smørgrav 		options->permit_root_login = PERMIT_NO;
145511b41d2SMark Murray 	if (options->ignore_rhosts == -1)
146fe5fd017SMark Murray 		options->ignore_rhosts = 1;
147511b41d2SMark Murray 	if (options->ignore_user_known_hosts == -1)
148511b41d2SMark Murray 		options->ignore_user_known_hosts = 0;
149511b41d2SMark Murray 	if (options->print_motd == -1)
150511b41d2SMark Murray 		options->print_motd = 1;
151ca3176e7SBrian Feldman 	if (options->print_lastlog == -1)
152ca3176e7SBrian Feldman 		options->print_lastlog = 1;
153511b41d2SMark Murray 	if (options->x11_forwarding == -1)
154975616f0SDag-Erling Smørgrav 		options->x11_forwarding = 1;
155511b41d2SMark Murray 	if (options->x11_display_offset == -1)
156fe5fd017SMark Murray 		options->x11_display_offset = 10;
157af12a3e7SDag-Erling Smørgrav 	if (options->x11_use_localhost == -1)
158af12a3e7SDag-Erling Smørgrav 		options->x11_use_localhost = 1;
159c2d3a559SKris Kennaway 	if (options->xauth_location == NULL)
160af12a3e7SDag-Erling Smørgrav 		options->xauth_location = _PATH_XAUTH;
161511b41d2SMark Murray 	if (options->strict_modes == -1)
162511b41d2SMark Murray 		options->strict_modes = 1;
1631ec0d754SDag-Erling Smørgrav 	if (options->tcp_keep_alive == -1)
1641ec0d754SDag-Erling Smørgrav 		options->tcp_keep_alive = 1;
165af12a3e7SDag-Erling Smørgrav 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
166511b41d2SMark Murray 		options->log_facility = SYSLOG_FACILITY_AUTH;
167af12a3e7SDag-Erling Smørgrav 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
168511b41d2SMark Murray 		options->log_level = SYSLOG_LEVEL_INFO;
169511b41d2SMark Murray 	if (options->rhosts_rsa_authentication == -1)
170fe5fd017SMark Murray 		options->rhosts_rsa_authentication = 0;
171ca3176e7SBrian Feldman 	if (options->hostbased_authentication == -1)
172ca3176e7SBrian Feldman 		options->hostbased_authentication = 0;
173ca3176e7SBrian Feldman 	if (options->hostbased_uses_name_from_packet_only == -1)
174ca3176e7SBrian Feldman 		options->hostbased_uses_name_from_packet_only = 0;
175511b41d2SMark Murray 	if (options->rsa_authentication == -1)
176511b41d2SMark Murray 		options->rsa_authentication = 1;
177ca3176e7SBrian Feldman 	if (options->pubkey_authentication == -1)
178ca3176e7SBrian Feldman 		options->pubkey_authentication = 1;
179989dd127SDag-Erling Smørgrav 	if (options->kerberos_authentication == -1)
180cf2b5f3bSDag-Erling Smørgrav 		options->kerberos_authentication = 0;
181af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_or_local_passwd == -1)
182af12a3e7SDag-Erling Smørgrav 		options->kerberos_or_local_passwd = 1;
183af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_ticket_cleanup == -1)
184af12a3e7SDag-Erling Smørgrav 		options->kerberos_ticket_cleanup = 1;
1851ec0d754SDag-Erling Smørgrav 	if (options->kerberos_get_afs_token == -1)
1861ec0d754SDag-Erling Smørgrav 		options->kerberos_get_afs_token = 0;
187cf2b5f3bSDag-Erling Smørgrav 	if (options->gss_authentication == -1)
188cf2b5f3bSDag-Erling Smørgrav 		options->gss_authentication = 0;
189cf2b5f3bSDag-Erling Smørgrav 	if (options->gss_cleanup_creds == -1)
190cf2b5f3bSDag-Erling Smørgrav 		options->gss_cleanup_creds = 1;
191511b41d2SMark Murray 	if (options->password_authentication == -1)
192b909c84bSDag-Erling Smørgrav #ifdef USE_PAM
193b909c84bSDag-Erling Smørgrav 		options->password_authentication = 0;
194b909c84bSDag-Erling Smørgrav #else
195511b41d2SMark Murray 		options->password_authentication = 1;
196b909c84bSDag-Erling Smørgrav #endif
19709958426SBrian Feldman 	if (options->kbd_interactive_authentication == -1)
19809958426SBrian Feldman 		options->kbd_interactive_authentication = 0;
199af12a3e7SDag-Erling Smørgrav 	if (options->challenge_response_authentication == -1)
20080241871SDag-Erling Smørgrav 		options->challenge_response_authentication = 1;
201511b41d2SMark Murray 	if (options->permit_empty_passwd == -1)
202fe5fd017SMark Murray 		options->permit_empty_passwd = 0;
203f388f5efSDag-Erling Smørgrav 	if (options->permit_user_env == -1)
204f388f5efSDag-Erling Smørgrav 		options->permit_user_env = 0;
205511b41d2SMark Murray 	if (options->use_login == -1)
206511b41d2SMark Murray 		options->use_login = 0;
20780628bacSDag-Erling Smørgrav 	if (options->compression == -1)
208d4ecd108SDag-Erling Smørgrav 		options->compression = COMP_DELAYED;
20909958426SBrian Feldman 	if (options->allow_tcp_forwarding == -1)
21009958426SBrian Feldman 		options->allow_tcp_forwarding = 1;
211e8aafc91SKris Kennaway 	if (options->gateway_ports == -1)
212e8aafc91SKris Kennaway 		options->gateway_ports = 0;
213c2d3a559SKris Kennaway 	if (options->max_startups == -1)
214c2d3a559SKris Kennaway 		options->max_startups = 10;
215c2d3a559SKris Kennaway 	if (options->max_startups_rate == -1)
216c2d3a559SKris Kennaway 		options->max_startups_rate = 100;		/* 100% */
217c2d3a559SKris Kennaway 	if (options->max_startups_begin == -1)
218c2d3a559SKris Kennaway 		options->max_startups_begin = options->max_startups;
21921e764dfSDag-Erling Smørgrav 	if (options->max_authtries == -1)
22021e764dfSDag-Erling Smørgrav 		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
221cf2b5f3bSDag-Erling Smørgrav 	if (options->use_dns == -1)
222cf2b5f3bSDag-Erling Smørgrav 		options->use_dns = 1;
223ca3176e7SBrian Feldman 	if (options->client_alive_interval == -1)
224ca3176e7SBrian Feldman 		options->client_alive_interval = 0;
225ca3176e7SBrian Feldman 	if (options->client_alive_count_max == -1)
226ca3176e7SBrian Feldman 		options->client_alive_count_max = 3;
227af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file2 == NULL) {
228af12a3e7SDag-Erling Smørgrav 		/* authorized_keys_file2 falls back to authorized_keys_file */
229af12a3e7SDag-Erling Smørgrav 		if (options->authorized_keys_file != NULL)
230af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = options->authorized_keys_file;
231af12a3e7SDag-Erling Smørgrav 		else
232af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
233af12a3e7SDag-Erling Smørgrav 	}
234af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file == NULL)
235af12a3e7SDag-Erling Smørgrav 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
236b74df5b2SDag-Erling Smørgrav 	if (options->permit_tun == -1)
237b74df5b2SDag-Erling Smørgrav 		options->permit_tun = SSH_TUNMODE_NO;
23880628bacSDag-Erling Smørgrav 
239989dd127SDag-Erling Smørgrav 	/* Turn privilege separation on by default */
24080628bacSDag-Erling Smørgrav 	if (use_privsep == -1)
241989dd127SDag-Erling Smørgrav 		use_privsep = 1;
242989dd127SDag-Erling Smørgrav 
243f388f5efSDag-Erling Smørgrav #ifndef HAVE_MMAP
244989dd127SDag-Erling Smørgrav 	if (use_privsep && options->compression == 1) {
245989dd127SDag-Erling Smørgrav 		error("This platform does not support both privilege "
246989dd127SDag-Erling Smørgrav 		    "separation and compression");
247989dd127SDag-Erling Smørgrav 		error("Compression disabled");
248989dd127SDag-Erling Smørgrav 		options->compression = 0;
249989dd127SDag-Erling Smørgrav 	}
250989dd127SDag-Erling Smørgrav #endif
251989dd127SDag-Erling Smørgrav 
252511b41d2SMark Murray }
253511b41d2SMark Murray 
254511b41d2SMark Murray /* Keyword tokens. */
255511b41d2SMark Murray typedef enum {
256511b41d2SMark Murray 	sBadOption,		/* == unknown option */
257989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
258cf2b5f3bSDag-Erling Smørgrav 	sUsePAM,
259989dd127SDag-Erling Smørgrav 	/* Standard Options */
260511b41d2SMark Murray 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
261511b41d2SMark Murray 	sPermitRootLogin, sLogFacility, sLogLevel,
262cf2b5f3bSDag-Erling Smørgrav 	sRhostsRSAAuthentication, sRSAAuthentication,
263af12a3e7SDag-Erling Smørgrav 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
2641ec0d754SDag-Erling Smørgrav 	sKerberosGetAFSToken,
265cf2b5f3bSDag-Erling Smørgrav 	sKerberosTgtPassing, sChallengeResponseAuthentication,
266aa49c926SDag-Erling Smørgrav 	sPasswordAuthentication, sKbdInteractiveAuthentication,
267aa49c926SDag-Erling Smørgrav 	sListenAddress, sAddressFamily,
268ca3176e7SBrian Feldman 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
269af12a3e7SDag-Erling Smørgrav 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
2701ec0d754SDag-Erling Smørgrav 	sStrictModes, sEmptyPasswd, sTCPKeepAlive,
271f388f5efSDag-Erling Smørgrav 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
27209958426SBrian Feldman 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
273ca3176e7SBrian Feldman 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
27421e764dfSDag-Erling Smørgrav 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
27521e764dfSDag-Erling Smørgrav 	sMaxStartups, sMaxAuthTries,
276cf2b5f3bSDag-Erling Smørgrav 	sBanner, sUseDNS, sHostbasedAuthentication,
277ca3176e7SBrian Feldman 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
278af12a3e7SDag-Erling Smørgrav 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
279b74df5b2SDag-Erling Smørgrav 	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
28080628bacSDag-Erling Smørgrav 	sUsePrivilegeSeparation,
281db58a8e4SDag-Erling Smørgrav 	sVersionAddendum,
282cf2b5f3bSDag-Erling Smørgrav 	sDeprecated, sUnsupported
283511b41d2SMark Murray } ServerOpCodes;
284511b41d2SMark Murray 
285511b41d2SMark Murray /* Textual representation of the tokens. */
286511b41d2SMark Murray static struct {
287511b41d2SMark Murray 	const char *name;
288511b41d2SMark Murray 	ServerOpCodes opcode;
289511b41d2SMark Murray } keywords[] = {
290989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
291cf2b5f3bSDag-Erling Smørgrav #ifdef USE_PAM
292cf2b5f3bSDag-Erling Smørgrav 	{ "usepam", sUsePAM },
293cf2b5f3bSDag-Erling Smørgrav #else
294cf2b5f3bSDag-Erling Smørgrav 	{ "usepam", sUnsupported },
295975616f0SDag-Erling Smørgrav #endif
296cf2b5f3bSDag-Erling Smørgrav 	{ "pamauthenticationviakbdint", sDeprecated },
297989dd127SDag-Erling Smørgrav 	/* Standard Options */
298511b41d2SMark Murray 	{ "port", sPort },
299511b41d2SMark Murray 	{ "hostkey", sHostKeyFile },
300ca3176e7SBrian Feldman 	{ "hostdsakey", sHostKeyFile },					/* alias */
301e8aafc91SKris Kennaway 	{ "pidfile", sPidFile },
302511b41d2SMark Murray 	{ "serverkeybits", sServerKeyBits },
303511b41d2SMark Murray 	{ "logingracetime", sLoginGraceTime },
304511b41d2SMark Murray 	{ "keyregenerationinterval", sKeyRegenerationTime },
305511b41d2SMark Murray 	{ "permitrootlogin", sPermitRootLogin },
306511b41d2SMark Murray 	{ "syslogfacility", sLogFacility },
307511b41d2SMark Murray 	{ "loglevel", sLogLevel },
308cf2b5f3bSDag-Erling Smørgrav 	{ "rhostsauthentication", sDeprecated },
309511b41d2SMark Murray 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
310ca3176e7SBrian Feldman 	{ "hostbasedauthentication", sHostbasedAuthentication },
311ca3176e7SBrian Feldman 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
312af12a3e7SDag-Erling Smørgrav 	{ "rsaauthentication", sRSAAuthentication },
313ca3176e7SBrian Feldman 	{ "pubkeyauthentication", sPubkeyAuthentication },
314ca3176e7SBrian Feldman 	{ "dsaauthentication", sPubkeyAuthentication },			/* alias */
315cf2b5f3bSDag-Erling Smørgrav #ifdef KRB5
316cb96ab36SAssar Westerlund 	{ "kerberosauthentication", sKerberosAuthentication },
317af12a3e7SDag-Erling Smørgrav 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
318af12a3e7SDag-Erling Smørgrav 	{ "kerberosticketcleanup", sKerberosTicketCleanup },
3191ec0d754SDag-Erling Smørgrav #ifdef USE_AFS
3201ec0d754SDag-Erling Smørgrav 	{ "kerberosgetafstoken", sKerberosGetAFSToken },
3211ec0d754SDag-Erling Smørgrav #else
3221ec0d754SDag-Erling Smørgrav 	{ "kerberosgetafstoken", sUnsupported },
3231ec0d754SDag-Erling Smørgrav #endif
324cf2b5f3bSDag-Erling Smørgrav #else
325cf2b5f3bSDag-Erling Smørgrav 	{ "kerberosauthentication", sUnsupported },
326cf2b5f3bSDag-Erling Smørgrav 	{ "kerberosorlocalpasswd", sUnsupported },
327cf2b5f3bSDag-Erling Smørgrav 	{ "kerberosticketcleanup", sUnsupported },
3281ec0d754SDag-Erling Smørgrav 	{ "kerberosgetafstoken", sUnsupported },
329cb96ab36SAssar Westerlund #endif
330cf2b5f3bSDag-Erling Smørgrav 	{ "kerberostgtpassing", sUnsupported },
331cf2b5f3bSDag-Erling Smørgrav 	{ "afstokenpassing", sUnsupported },
332cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
333cf2b5f3bSDag-Erling Smørgrav 	{ "gssapiauthentication", sGssAuthentication },
3341ec0d754SDag-Erling Smørgrav 	{ "gssapicleanupcredentials", sGssCleanupCreds },
335cf2b5f3bSDag-Erling Smørgrav #else
336cf2b5f3bSDag-Erling Smørgrav 	{ "gssapiauthentication", sUnsupported },
3371ec0d754SDag-Erling Smørgrav 	{ "gssapicleanupcredentials", sUnsupported },
338511b41d2SMark Murray #endif
339511b41d2SMark Murray 	{ "passwordauthentication", sPasswordAuthentication },
34009958426SBrian Feldman 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
341ca3176e7SBrian Feldman 	{ "challengeresponseauthentication", sChallengeResponseAuthentication },
342ca3176e7SBrian Feldman 	{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
343989dd127SDag-Erling Smørgrav 	{ "checkmail", sDeprecated },
344511b41d2SMark Murray 	{ "listenaddress", sListenAddress },
345aa49c926SDag-Erling Smørgrav 	{ "addressfamily", sAddressFamily },
346511b41d2SMark Murray 	{ "printmotd", sPrintMotd },
347ca3176e7SBrian Feldman 	{ "printlastlog", sPrintLastLog },
348511b41d2SMark Murray 	{ "ignorerhosts", sIgnoreRhosts },
349511b41d2SMark Murray 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
350511b41d2SMark Murray 	{ "x11forwarding", sX11Forwarding },
351511b41d2SMark Murray 	{ "x11displayoffset", sX11DisplayOffset },
352af12a3e7SDag-Erling Smørgrav 	{ "x11uselocalhost", sX11UseLocalhost },
353c2d3a559SKris Kennaway 	{ "xauthlocation", sXAuthLocation },
354511b41d2SMark Murray 	{ "strictmodes", sStrictModes },
355511b41d2SMark Murray 	{ "permitemptypasswords", sEmptyPasswd },
356f388f5efSDag-Erling Smørgrav 	{ "permituserenvironment", sPermitUserEnvironment },
357511b41d2SMark Murray 	{ "uselogin", sUseLogin },
35880628bacSDag-Erling Smørgrav 	{ "compression", sCompression },
3591ec0d754SDag-Erling Smørgrav 	{ "tcpkeepalive", sTCPKeepAlive },
3601ec0d754SDag-Erling Smørgrav 	{ "keepalive", sTCPKeepAlive },				/* obsolete alias */
36109958426SBrian Feldman 	{ "allowtcpforwarding", sAllowTcpForwarding },
362511b41d2SMark Murray 	{ "allowusers", sAllowUsers },
363511b41d2SMark Murray 	{ "denyusers", sDenyUsers },
364511b41d2SMark Murray 	{ "allowgroups", sAllowGroups },
365511b41d2SMark Murray 	{ "denygroups", sDenyGroups },
366e8aafc91SKris Kennaway 	{ "ciphers", sCiphers },
367ca3176e7SBrian Feldman 	{ "macs", sMacs },
368e8aafc91SKris Kennaway 	{ "protocol", sProtocol },
369e8aafc91SKris Kennaway 	{ "gatewayports", sGatewayPorts },
370c2d3a559SKris Kennaway 	{ "subsystem", sSubsystem },
371c2d3a559SKris Kennaway 	{ "maxstartups", sMaxStartups },
37221e764dfSDag-Erling Smørgrav 	{ "maxauthtries", sMaxAuthTries },
373ca3176e7SBrian Feldman 	{ "banner", sBanner },
374cf2b5f3bSDag-Erling Smørgrav 	{ "usedns", sUseDNS },
375cf2b5f3bSDag-Erling Smørgrav 	{ "verifyreversemapping", sDeprecated },
376cf2b5f3bSDag-Erling Smørgrav 	{ "reversemappingcheck", sDeprecated },
377ca3176e7SBrian Feldman 	{ "clientaliveinterval", sClientAliveInterval },
378ca3176e7SBrian Feldman 	{ "clientalivecountmax", sClientAliveCountMax },
379af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile", sAuthorizedKeysFile },
380af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
38180628bacSDag-Erling Smørgrav 	{ "useprivilegeseparation", sUsePrivilegeSeparation},
38221e764dfSDag-Erling Smørgrav 	{ "acceptenv", sAcceptEnv },
383b74df5b2SDag-Erling Smørgrav 	{ "permittunnel", sPermitTunnel },
384db58a8e4SDag-Erling Smørgrav 	{ "versionaddendum", sVersionAddendum },
385af12a3e7SDag-Erling Smørgrav 	{ NULL, sBadOption }
386511b41d2SMark Murray };
387511b41d2SMark Murray 
388511b41d2SMark Murray /*
389ca3176e7SBrian Feldman  * Returns the number of the token pointed to by cp or sBadOption.
390511b41d2SMark Murray  */
391511b41d2SMark Murray 
392511b41d2SMark Murray static ServerOpCodes
393511b41d2SMark Murray parse_token(const char *cp, const char *filename,
394511b41d2SMark Murray 	    int linenum)
395511b41d2SMark Murray {
396ca3176e7SBrian Feldman 	u_int i;
397511b41d2SMark Murray 
398511b41d2SMark Murray 	for (i = 0; keywords[i].name; i++)
399511b41d2SMark Murray 		if (strcasecmp(cp, keywords[i].name) == 0)
400511b41d2SMark Murray 			return keywords[i].opcode;
401511b41d2SMark Murray 
402ca3176e7SBrian Feldman 	error("%s: line %d: Bad configuration option: %s",
403511b41d2SMark Murray 	    filename, linenum, cp);
404511b41d2SMark Murray 	return sBadOption;
405511b41d2SMark Murray }
406511b41d2SMark Murray 
407af12a3e7SDag-Erling Smørgrav static void
408ca3176e7SBrian Feldman add_listen_addr(ServerOptions *options, char *addr, u_short port)
409511b41d2SMark Murray {
410d4ecd108SDag-Erling Smørgrav 	u_int i;
411511b41d2SMark Murray 
412511b41d2SMark Murray 	if (options->num_ports == 0)
413511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
414aa49c926SDag-Erling Smørgrav 	if (options->address_family == -1)
415aa49c926SDag-Erling Smørgrav 		options->address_family = AF_UNSPEC;
416ca3176e7SBrian Feldman 	if (port == 0)
417ca3176e7SBrian Feldman 		for (i = 0; i < options->num_ports; i++)
418ca3176e7SBrian Feldman 			add_one_listen_addr(options, addr, options->ports[i]);
419ca3176e7SBrian Feldman 	else
420ca3176e7SBrian Feldman 		add_one_listen_addr(options, addr, port);
421ca3176e7SBrian Feldman }
422ca3176e7SBrian Feldman 
423af12a3e7SDag-Erling Smørgrav static void
424ca3176e7SBrian Feldman add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
425ca3176e7SBrian Feldman {
426ca3176e7SBrian Feldman 	struct addrinfo hints, *ai, *aitop;
427ca3176e7SBrian Feldman 	char strport[NI_MAXSERV];
428ca3176e7SBrian Feldman 	int gaierr;
429ca3176e7SBrian Feldman 
430511b41d2SMark Murray 	memset(&hints, 0, sizeof(hints));
431aa49c926SDag-Erling Smørgrav 	hints.ai_family = options->address_family;
432511b41d2SMark Murray 	hints.ai_socktype = SOCK_STREAM;
433511b41d2SMark Murray 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
434a82e551fSDag-Erling Smørgrav 	snprintf(strport, sizeof strport, "%u", port);
435511b41d2SMark Murray 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
436ca3176e7SBrian Feldman 		fatal("bad addr or host: %s (%s)",
437511b41d2SMark Murray 		    addr ? addr : "<NULL>",
438511b41d2SMark Murray 		    gai_strerror(gaierr));
439511b41d2SMark Murray 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
440511b41d2SMark Murray 		;
441511b41d2SMark Murray 	ai->ai_next = options->listen_addrs;
442511b41d2SMark Murray 	options->listen_addrs = aitop;
443511b41d2SMark Murray }
444511b41d2SMark Murray 
445af12a3e7SDag-Erling Smørgrav int
446af12a3e7SDag-Erling Smørgrav process_server_config_line(ServerOptions *options, char *line,
447af12a3e7SDag-Erling Smørgrav     const char *filename, int linenum)
448511b41d2SMark Murray {
449ca3176e7SBrian Feldman 	char *cp, **charptr, *arg, *p;
450d4ecd108SDag-Erling Smørgrav 	int *intptr, value, n;
451511b41d2SMark Murray 	ServerOpCodes opcode;
452aa49c926SDag-Erling Smørgrav 	u_short port;
453d4ecd108SDag-Erling Smørgrav 	u_int i;
454511b41d2SMark Murray 
455c2d3a559SKris Kennaway 	cp = line;
456c2d3a559SKris Kennaway 	arg = strdelim(&cp);
457c2d3a559SKris Kennaway 	/* Ignore leading whitespace */
458c2d3a559SKris Kennaway 	if (*arg == '\0')
459c2d3a559SKris Kennaway 		arg = strdelim(&cp);
460ca3176e7SBrian Feldman 	if (!arg || !*arg || *arg == '#')
461af12a3e7SDag-Erling Smørgrav 		return 0;
462ca3176e7SBrian Feldman 	intptr = NULL;
463ca3176e7SBrian Feldman 	charptr = NULL;
464c2d3a559SKris Kennaway 	opcode = parse_token(arg, filename, linenum);
465511b41d2SMark Murray 	switch (opcode) {
466989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
467cf2b5f3bSDag-Erling Smørgrav 	case sUsePAM:
468cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->use_pam;
469989dd127SDag-Erling Smørgrav 		goto parse_flag;
470989dd127SDag-Erling Smørgrav 
471989dd127SDag-Erling Smørgrav 	/* Standard Options */
472511b41d2SMark Murray 	case sBadOption:
473af12a3e7SDag-Erling Smørgrav 		return -1;
474511b41d2SMark Murray 	case sPort:
475511b41d2SMark Murray 		/* ignore ports from configfile if cmdline specifies ports */
476511b41d2SMark Murray 		if (options->ports_from_cmdline)
477af12a3e7SDag-Erling Smørgrav 			return 0;
478511b41d2SMark Murray 		if (options->listen_addrs != NULL)
479511b41d2SMark Murray 			fatal("%s line %d: ports must be specified before "
480af12a3e7SDag-Erling Smørgrav 			    "ListenAddress.", filename, linenum);
481511b41d2SMark Murray 		if (options->num_ports >= MAX_PORTS)
482ca3176e7SBrian Feldman 			fatal("%s line %d: too many ports.",
483511b41d2SMark Murray 			    filename, linenum);
484c2d3a559SKris Kennaway 		arg = strdelim(&cp);
485c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
486ca3176e7SBrian Feldman 			fatal("%s line %d: missing port number.",
487511b41d2SMark Murray 			    filename, linenum);
488ca3176e7SBrian Feldman 		options->ports[options->num_ports++] = a2port(arg);
489ca3176e7SBrian Feldman 		if (options->ports[options->num_ports-1] == 0)
490ca3176e7SBrian Feldman 			fatal("%s line %d: Badly formatted port number.",
491ca3176e7SBrian Feldman 			    filename, linenum);
492511b41d2SMark Murray 		break;
493511b41d2SMark Murray 
494511b41d2SMark Murray 	case sServerKeyBits:
495511b41d2SMark Murray 		intptr = &options->server_key_bits;
496511b41d2SMark Murray parse_int:
497c2d3a559SKris Kennaway 		arg = strdelim(&cp);
498ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
499ca3176e7SBrian Feldman 			fatal("%s line %d: missing integer value.",
500511b41d2SMark Murray 			    filename, linenum);
501c2d3a559SKris Kennaway 		value = atoi(arg);
502511b41d2SMark Murray 		if (*intptr == -1)
503511b41d2SMark Murray 			*intptr = value;
504511b41d2SMark Murray 		break;
505511b41d2SMark Murray 
506511b41d2SMark Murray 	case sLoginGraceTime:
507511b41d2SMark Murray 		intptr = &options->login_grace_time;
508af12a3e7SDag-Erling Smørgrav parse_time:
509af12a3e7SDag-Erling Smørgrav 		arg = strdelim(&cp);
510af12a3e7SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
511af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: missing time value.",
512af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
513af12a3e7SDag-Erling Smørgrav 		if ((value = convtime(arg)) == -1)
514af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: invalid time value.",
515af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
516af12a3e7SDag-Erling Smørgrav 		if (*intptr == -1)
517af12a3e7SDag-Erling Smørgrav 			*intptr = value;
518af12a3e7SDag-Erling Smørgrav 		break;
519511b41d2SMark Murray 
520511b41d2SMark Murray 	case sKeyRegenerationTime:
521511b41d2SMark Murray 		intptr = &options->key_regeneration_time;
522af12a3e7SDag-Erling Smørgrav 		goto parse_time;
523511b41d2SMark Murray 
524511b41d2SMark Murray 	case sListenAddress:
525c2d3a559SKris Kennaway 		arg = strdelim(&cp);
526aa49c926SDag-Erling Smørgrav 		if (arg == NULL || *arg == '\0')
527aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: missing address",
528511b41d2SMark Murray 			    filename, linenum);
529d4ecd108SDag-Erling Smørgrav 		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
530d4ecd108SDag-Erling Smørgrav 		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
531d4ecd108SDag-Erling Smørgrav 		    && strchr(p+1, ':') != NULL) {
532d4ecd108SDag-Erling Smørgrav 			add_listen_addr(options, arg, 0);
533d4ecd108SDag-Erling Smørgrav 			break;
534d4ecd108SDag-Erling Smørgrav 		}
535aa49c926SDag-Erling Smørgrav 		p = hpdelim(&arg);
536aa49c926SDag-Erling Smørgrav 		if (p == NULL)
537aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: bad address:port usage",
538ca3176e7SBrian Feldman 			    filename, linenum);
539aa49c926SDag-Erling Smørgrav 		p = cleanhostname(p);
540aa49c926SDag-Erling Smørgrav 		if (arg == NULL)
541aa49c926SDag-Erling Smørgrav 			port = 0;
542aa49c926SDag-Erling Smørgrav 		else if ((port = a2port(arg)) == 0)
543aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: bad port number", filename, linenum);
544ca3176e7SBrian Feldman 
545aa49c926SDag-Erling Smørgrav 		add_listen_addr(options, p, port);
546aa49c926SDag-Erling Smørgrav 
547aa49c926SDag-Erling Smørgrav 		break;
548aa49c926SDag-Erling Smørgrav 
549aa49c926SDag-Erling Smørgrav 	case sAddressFamily:
550aa49c926SDag-Erling Smørgrav 		arg = strdelim(&cp);
551d4ecd108SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
552d4ecd108SDag-Erling Smørgrav 			fatal("%s line %d: missing address family.",
553d4ecd108SDag-Erling Smørgrav 			    filename, linenum);
554aa49c926SDag-Erling Smørgrav 		intptr = &options->address_family;
555aa49c926SDag-Erling Smørgrav 		if (options->listen_addrs != NULL)
556aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: address family must be specified before "
557aa49c926SDag-Erling Smørgrav 			    "ListenAddress.", filename, linenum);
558aa49c926SDag-Erling Smørgrav 		if (strcasecmp(arg, "inet") == 0)
559aa49c926SDag-Erling Smørgrav 			value = AF_INET;
560aa49c926SDag-Erling Smørgrav 		else if (strcasecmp(arg, "inet6") == 0)
561aa49c926SDag-Erling Smørgrav 			value = AF_INET6;
562aa49c926SDag-Erling Smørgrav 		else if (strcasecmp(arg, "any") == 0)
563aa49c926SDag-Erling Smørgrav 			value = AF_UNSPEC;
564ca3176e7SBrian Feldman 		else
565aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: unsupported address family \"%s\".",
566aa49c926SDag-Erling Smørgrav 			    filename, linenum, arg);
567aa49c926SDag-Erling Smørgrav 		if (*intptr == -1)
568aa49c926SDag-Erling Smørgrav 			*intptr = value;
569511b41d2SMark Murray 		break;
570511b41d2SMark Murray 
571511b41d2SMark Murray 	case sHostKeyFile:
572ca3176e7SBrian Feldman 		intptr = &options->num_host_key_files;
573ca3176e7SBrian Feldman 		if (*intptr >= MAX_HOSTKEYS)
574ca3176e7SBrian Feldman 			fatal("%s line %d: too many host keys specified (max %d).",
575ca3176e7SBrian Feldman 			    filename, linenum, MAX_HOSTKEYS);
576ca3176e7SBrian Feldman 		charptr = &options->host_key_files[*intptr];
577c2d3a559SKris Kennaway parse_filename:
578c2d3a559SKris Kennaway 		arg = strdelim(&cp);
579ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
580ca3176e7SBrian Feldman 			fatal("%s line %d: missing file name.",
581e8aafc91SKris Kennaway 			    filename, linenum);
582ca3176e7SBrian Feldman 		if (*charptr == NULL) {
583c2d3a559SKris Kennaway 			*charptr = tilde_expand_filename(arg, getuid());
584ca3176e7SBrian Feldman 			/* increase optional counter */
585ca3176e7SBrian Feldman 			if (intptr != NULL)
586ca3176e7SBrian Feldman 				*intptr = *intptr + 1;
587ca3176e7SBrian Feldman 		}
588e8aafc91SKris Kennaway 		break;
589e8aafc91SKris Kennaway 
590e8aafc91SKris Kennaway 	case sPidFile:
591e8aafc91SKris Kennaway 		charptr = &options->pid_file;
592c2d3a559SKris Kennaway 		goto parse_filename;
593511b41d2SMark Murray 
594511b41d2SMark Murray 	case sPermitRootLogin:
595511b41d2SMark Murray 		intptr = &options->permit_root_login;
596c2d3a559SKris Kennaway 		arg = strdelim(&cp);
597ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
598ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/"
599ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
600ca3176e7SBrian Feldman 			    "argument.", filename, linenum);
601ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
602c2d3a559SKris Kennaway 		if (strcmp(arg, "without-password") == 0)
603ca3176e7SBrian Feldman 			value = PERMIT_NO_PASSWD;
604ca3176e7SBrian Feldman 		else if (strcmp(arg, "forced-commands-only") == 0)
605ca3176e7SBrian Feldman 			value = PERMIT_FORCED_ONLY;
606c2d3a559SKris Kennaway 		else if (strcmp(arg, "yes") == 0)
607ca3176e7SBrian Feldman 			value = PERMIT_YES;
608c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
609ca3176e7SBrian Feldman 			value = PERMIT_NO;
610ca3176e7SBrian Feldman 		else
611ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/"
612ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
613ca3176e7SBrian Feldman 			    "argument: %s", filename, linenum, arg);
614511b41d2SMark Murray 		if (*intptr == -1)
615511b41d2SMark Murray 			*intptr = value;
616511b41d2SMark Murray 		break;
617511b41d2SMark Murray 
618511b41d2SMark Murray 	case sIgnoreRhosts:
619511b41d2SMark Murray 		intptr = &options->ignore_rhosts;
620511b41d2SMark Murray parse_flag:
621c2d3a559SKris Kennaway 		arg = strdelim(&cp);
622ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
623ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/no argument.",
624511b41d2SMark Murray 			    filename, linenum);
625ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
626c2d3a559SKris Kennaway 		if (strcmp(arg, "yes") == 0)
627511b41d2SMark Murray 			value = 1;
628c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
629511b41d2SMark Murray 			value = 0;
630ca3176e7SBrian Feldman 		else
631ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/no argument: %s",
632c2d3a559SKris Kennaway 				filename, linenum, arg);
633511b41d2SMark Murray 		if (*intptr == -1)
634511b41d2SMark Murray 			*intptr = value;
635511b41d2SMark Murray 		break;
636511b41d2SMark Murray 
637511b41d2SMark Murray 	case sIgnoreUserKnownHosts:
638511b41d2SMark Murray 		intptr = &options->ignore_user_known_hosts;
639962a3f4eSSheldon Hearn 		goto parse_flag;
640511b41d2SMark Murray 
641511b41d2SMark Murray 	case sRhostsRSAAuthentication:
642511b41d2SMark Murray 		intptr = &options->rhosts_rsa_authentication;
643511b41d2SMark Murray 		goto parse_flag;
644511b41d2SMark Murray 
645ca3176e7SBrian Feldman 	case sHostbasedAuthentication:
646ca3176e7SBrian Feldman 		intptr = &options->hostbased_authentication;
647ca3176e7SBrian Feldman 		goto parse_flag;
648ca3176e7SBrian Feldman 
649ca3176e7SBrian Feldman 	case sHostbasedUsesNameFromPacketOnly:
650ca3176e7SBrian Feldman 		intptr = &options->hostbased_uses_name_from_packet_only;
651ca3176e7SBrian Feldman 		goto parse_flag;
652ca3176e7SBrian Feldman 
653511b41d2SMark Murray 	case sRSAAuthentication:
654511b41d2SMark Murray 		intptr = &options->rsa_authentication;
655511b41d2SMark Murray 		goto parse_flag;
656511b41d2SMark Murray 
657ca3176e7SBrian Feldman 	case sPubkeyAuthentication:
658ca3176e7SBrian Feldman 		intptr = &options->pubkey_authentication;
659e8aafc91SKris Kennaway 		goto parse_flag;
660cf2b5f3bSDag-Erling Smørgrav 
661cb96ab36SAssar Westerlund 	case sKerberosAuthentication:
662cb96ab36SAssar Westerlund 		intptr = &options->kerberos_authentication;
663511b41d2SMark Murray 		goto parse_flag;
664511b41d2SMark Murray 
665af12a3e7SDag-Erling Smørgrav 	case sKerberosOrLocalPasswd:
666af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_or_local_passwd;
667511b41d2SMark Murray 		goto parse_flag;
668511b41d2SMark Murray 
669af12a3e7SDag-Erling Smørgrav 	case sKerberosTicketCleanup:
670af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_ticket_cleanup;
671511b41d2SMark Murray 		goto parse_flag;
672cf2b5f3bSDag-Erling Smørgrav 
6731ec0d754SDag-Erling Smørgrav 	case sKerberosGetAFSToken:
6741ec0d754SDag-Erling Smørgrav 		intptr = &options->kerberos_get_afs_token;
6751ec0d754SDag-Erling Smørgrav 		goto parse_flag;
6761ec0d754SDag-Erling Smørgrav 
677cf2b5f3bSDag-Erling Smørgrav 	case sGssAuthentication:
678cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->gss_authentication;
679fe5fd017SMark Murray 		goto parse_flag;
680cf2b5f3bSDag-Erling Smørgrav 
681cf2b5f3bSDag-Erling Smørgrav 	case sGssCleanupCreds:
682cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->gss_cleanup_creds;
683511b41d2SMark Murray 		goto parse_flag;
684511b41d2SMark Murray 
685511b41d2SMark Murray 	case sPasswordAuthentication:
686511b41d2SMark Murray 		intptr = &options->password_authentication;
687511b41d2SMark Murray 		goto parse_flag;
688511b41d2SMark Murray 
68909958426SBrian Feldman 	case sKbdInteractiveAuthentication:
69009958426SBrian Feldman 		intptr = &options->kbd_interactive_authentication;
69109958426SBrian Feldman 		goto parse_flag;
69209958426SBrian Feldman 
693ca3176e7SBrian Feldman 	case sChallengeResponseAuthentication:
694af12a3e7SDag-Erling Smørgrav 		intptr = &options->challenge_response_authentication;
695511b41d2SMark Murray 		goto parse_flag;
696511b41d2SMark Murray 
697511b41d2SMark Murray 	case sPrintMotd:
698511b41d2SMark Murray 		intptr = &options->print_motd;
699511b41d2SMark Murray 		goto parse_flag;
700511b41d2SMark Murray 
701ca3176e7SBrian Feldman 	case sPrintLastLog:
702ca3176e7SBrian Feldman 		intptr = &options->print_lastlog;
703ca3176e7SBrian Feldman 		goto parse_flag;
704ca3176e7SBrian Feldman 
705511b41d2SMark Murray 	case sX11Forwarding:
706511b41d2SMark Murray 		intptr = &options->x11_forwarding;
707511b41d2SMark Murray 		goto parse_flag;
708511b41d2SMark Murray 
709511b41d2SMark Murray 	case sX11DisplayOffset:
710511b41d2SMark Murray 		intptr = &options->x11_display_offset;
711511b41d2SMark Murray 		goto parse_int;
712511b41d2SMark Murray 
713af12a3e7SDag-Erling Smørgrav 	case sX11UseLocalhost:
714af12a3e7SDag-Erling Smørgrav 		intptr = &options->x11_use_localhost;
715af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
716af12a3e7SDag-Erling Smørgrav 
717c2d3a559SKris Kennaway 	case sXAuthLocation:
718c2d3a559SKris Kennaway 		charptr = &options->xauth_location;
719c2d3a559SKris Kennaway 		goto parse_filename;
720c2d3a559SKris Kennaway 
721511b41d2SMark Murray 	case sStrictModes:
722511b41d2SMark Murray 		intptr = &options->strict_modes;
723511b41d2SMark Murray 		goto parse_flag;
724511b41d2SMark Murray 
7251ec0d754SDag-Erling Smørgrav 	case sTCPKeepAlive:
7261ec0d754SDag-Erling Smørgrav 		intptr = &options->tcp_keep_alive;
727511b41d2SMark Murray 		goto parse_flag;
728511b41d2SMark Murray 
729511b41d2SMark Murray 	case sEmptyPasswd:
730511b41d2SMark Murray 		intptr = &options->permit_empty_passwd;
731511b41d2SMark Murray 		goto parse_flag;
732511b41d2SMark Murray 
733f388f5efSDag-Erling Smørgrav 	case sPermitUserEnvironment:
734f388f5efSDag-Erling Smørgrav 		intptr = &options->permit_user_env;
735f388f5efSDag-Erling Smørgrav 		goto parse_flag;
736f388f5efSDag-Erling Smørgrav 
737511b41d2SMark Murray 	case sUseLogin:
738511b41d2SMark Murray 		intptr = &options->use_login;
739511b41d2SMark Murray 		goto parse_flag;
740511b41d2SMark Murray 
74180628bacSDag-Erling Smørgrav 	case sCompression:
74280628bacSDag-Erling Smørgrav 		intptr = &options->compression;
743d4ecd108SDag-Erling Smørgrav 		arg = strdelim(&cp);
744d4ecd108SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
745d4ecd108SDag-Erling Smørgrav 			fatal("%s line %d: missing yes/no/delayed "
746d4ecd108SDag-Erling Smørgrav 			    "argument.", filename, linenum);
747d4ecd108SDag-Erling Smørgrav 		value = 0;	/* silence compiler */
748d4ecd108SDag-Erling Smørgrav 		if (strcmp(arg, "delayed") == 0)
749d4ecd108SDag-Erling Smørgrav 			value = COMP_DELAYED;
750d4ecd108SDag-Erling Smørgrav 		else if (strcmp(arg, "yes") == 0)
751d4ecd108SDag-Erling Smørgrav 			value = COMP_ZLIB;
752d4ecd108SDag-Erling Smørgrav 		else if (strcmp(arg, "no") == 0)
753d4ecd108SDag-Erling Smørgrav 			value = COMP_NONE;
754d4ecd108SDag-Erling Smørgrav 		else
755d4ecd108SDag-Erling Smørgrav 			fatal("%s line %d: Bad yes/no/delayed "
756d4ecd108SDag-Erling Smørgrav 			    "argument: %s", filename, linenum, arg);
757d4ecd108SDag-Erling Smørgrav 		if (*intptr == -1)
758d4ecd108SDag-Erling Smørgrav 			*intptr = value;
759d4ecd108SDag-Erling Smørgrav 		break;
76080628bacSDag-Erling Smørgrav 
761e8aafc91SKris Kennaway 	case sGatewayPorts:
762e8aafc91SKris Kennaway 		intptr = &options->gateway_ports;
763aa49c926SDag-Erling Smørgrav 		arg = strdelim(&cp);
764aa49c926SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
765aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: missing yes/no/clientspecified "
766aa49c926SDag-Erling Smørgrav 			    "argument.", filename, linenum);
767aa49c926SDag-Erling Smørgrav 		value = 0;	/* silence compiler */
768aa49c926SDag-Erling Smørgrav 		if (strcmp(arg, "clientspecified") == 0)
769aa49c926SDag-Erling Smørgrav 			value = 2;
770aa49c926SDag-Erling Smørgrav 		else if (strcmp(arg, "yes") == 0)
771aa49c926SDag-Erling Smørgrav 			value = 1;
772aa49c926SDag-Erling Smørgrav 		else if (strcmp(arg, "no") == 0)
773aa49c926SDag-Erling Smørgrav 			value = 0;
774aa49c926SDag-Erling Smørgrav 		else
775aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: Bad yes/no/clientspecified "
776aa49c926SDag-Erling Smørgrav 			    "argument: %s", filename, linenum, arg);
777aa49c926SDag-Erling Smørgrav 		if (*intptr == -1)
778aa49c926SDag-Erling Smørgrav 			*intptr = value;
779aa49c926SDag-Erling Smørgrav 		break;
780e8aafc91SKris Kennaway 
781cf2b5f3bSDag-Erling Smørgrav 	case sUseDNS:
782cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->use_dns;
783ca3176e7SBrian Feldman 		goto parse_flag;
784ca3176e7SBrian Feldman 
785511b41d2SMark Murray 	case sLogFacility:
786511b41d2SMark Murray 		intptr = (int *) &options->log_facility;
787c2d3a559SKris Kennaway 		arg = strdelim(&cp);
788c2d3a559SKris Kennaway 		value = log_facility_number(arg);
789af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_FACILITY_NOT_SET)
790ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log facility '%s'",
791c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
792511b41d2SMark Murray 		if (*intptr == -1)
793511b41d2SMark Murray 			*intptr = (SyslogFacility) value;
794511b41d2SMark Murray 		break;
795511b41d2SMark Murray 
796511b41d2SMark Murray 	case sLogLevel:
797511b41d2SMark Murray 		intptr = (int *) &options->log_level;
798c2d3a559SKris Kennaway 		arg = strdelim(&cp);
799c2d3a559SKris Kennaway 		value = log_level_number(arg);
800af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_LEVEL_NOT_SET)
801ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log level '%s'",
802c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
803511b41d2SMark Murray 		if (*intptr == -1)
804511b41d2SMark Murray 			*intptr = (LogLevel) value;
805511b41d2SMark Murray 		break;
806511b41d2SMark Murray 
80709958426SBrian Feldman 	case sAllowTcpForwarding:
80809958426SBrian Feldman 		intptr = &options->allow_tcp_forwarding;
80909958426SBrian Feldman 		goto parse_flag;
81009958426SBrian Feldman 
81180628bacSDag-Erling Smørgrav 	case sUsePrivilegeSeparation:
81280628bacSDag-Erling Smørgrav 		intptr = &use_privsep;
81380628bacSDag-Erling Smørgrav 		goto parse_flag;
81480628bacSDag-Erling Smørgrav 
815511b41d2SMark Murray 	case sAllowUsers:
816c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
81742f71286SMark Murray 			if (options->num_allow_users >= MAX_ALLOW_USERS)
818af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow users.",
819e8aafc91SKris Kennaway 				    filename, linenum);
820a82e551fSDag-Erling Smørgrav 			options->allow_users[options->num_allow_users++] =
821a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
822511b41d2SMark Murray 		}
823511b41d2SMark Murray 		break;
824511b41d2SMark Murray 
825511b41d2SMark Murray 	case sDenyUsers:
826c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
8272803b77eSBrian Feldman 			if (options->num_deny_users >= MAX_DENY_USERS)
828af12a3e7SDag-Erling Smørgrav 				fatal( "%s line %d: too many deny users.",
829e8aafc91SKris Kennaway 				    filename, linenum);
830a82e551fSDag-Erling Smørgrav 			options->deny_users[options->num_deny_users++] =
831a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
832511b41d2SMark Murray 		}
833511b41d2SMark Murray 		break;
834511b41d2SMark Murray 
835511b41d2SMark Murray 	case sAllowGroups:
836c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
83742f71286SMark Murray 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
838af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow groups.",
839e8aafc91SKris Kennaway 				    filename, linenum);
840a82e551fSDag-Erling Smørgrav 			options->allow_groups[options->num_allow_groups++] =
841a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
842511b41d2SMark Murray 		}
843511b41d2SMark Murray 		break;
844511b41d2SMark Murray 
845511b41d2SMark Murray 	case sDenyGroups:
846c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
84742f71286SMark Murray 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
848af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many deny groups.",
849e8aafc91SKris Kennaway 				    filename, linenum);
850c2d3a559SKris Kennaway 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
851511b41d2SMark Murray 		}
852511b41d2SMark Murray 		break;
853511b41d2SMark Murray 
854e8aafc91SKris Kennaway 	case sCiphers:
855c2d3a559SKris Kennaway 		arg = strdelim(&cp);
856c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
857c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
858c2d3a559SKris Kennaway 		if (!ciphers_valid(arg))
859e8aafc91SKris Kennaway 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
860c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
861e8aafc91SKris Kennaway 		if (options->ciphers == NULL)
862c2d3a559SKris Kennaway 			options->ciphers = xstrdup(arg);
863e8aafc91SKris Kennaway 		break;
864e8aafc91SKris Kennaway 
865ca3176e7SBrian Feldman 	case sMacs:
866ca3176e7SBrian Feldman 		arg = strdelim(&cp);
867ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
868ca3176e7SBrian Feldman 			fatal("%s line %d: Missing argument.", filename, linenum);
869ca3176e7SBrian Feldman 		if (!mac_valid(arg))
870ca3176e7SBrian Feldman 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
871ca3176e7SBrian Feldman 			    filename, linenum, arg ? arg : "<NONE>");
872ca3176e7SBrian Feldman 		if (options->macs == NULL)
873ca3176e7SBrian Feldman 			options->macs = xstrdup(arg);
874ca3176e7SBrian Feldman 		break;
875ca3176e7SBrian Feldman 
876e8aafc91SKris Kennaway 	case sProtocol:
877e8aafc91SKris Kennaway 		intptr = &options->protocol;
878c2d3a559SKris Kennaway 		arg = strdelim(&cp);
879c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
880c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
881c2d3a559SKris Kennaway 		value = proto_spec(arg);
882e8aafc91SKris Kennaway 		if (value == SSH_PROTO_UNKNOWN)
883e8aafc91SKris Kennaway 			fatal("%s line %d: Bad protocol spec '%s'.",
884c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
885e8aafc91SKris Kennaway 		if (*intptr == SSH_PROTO_UNKNOWN)
886e8aafc91SKris Kennaway 			*intptr = value;
887e8aafc91SKris Kennaway 		break;
888e8aafc91SKris Kennaway 
889c2d3a559SKris Kennaway 	case sSubsystem:
890c2d3a559SKris Kennaway 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
891c2d3a559SKris Kennaway 			fatal("%s line %d: too many subsystems defined.",
892c2d3a559SKris Kennaway 			    filename, linenum);
893c2d3a559SKris Kennaway 		}
894c2d3a559SKris Kennaway 		arg = strdelim(&cp);
895c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
896c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem name.",
897c2d3a559SKris Kennaway 			    filename, linenum);
898c2d3a559SKris Kennaway 		for (i = 0; i < options->num_subsystems; i++)
899c2d3a559SKris Kennaway 			if (strcmp(arg, options->subsystem_name[i]) == 0)
900c2d3a559SKris Kennaway 				fatal("%s line %d: Subsystem '%s' already defined.",
901c2d3a559SKris Kennaway 				    filename, linenum, arg);
902c2d3a559SKris Kennaway 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
903c2d3a559SKris Kennaway 		arg = strdelim(&cp);
904c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
905c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem command.",
906c2d3a559SKris Kennaway 			    filename, linenum);
907c2d3a559SKris Kennaway 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
908c2d3a559SKris Kennaway 		options->num_subsystems++;
909c2d3a559SKris Kennaway 		break;
910c2d3a559SKris Kennaway 
911c2d3a559SKris Kennaway 	case sMaxStartups:
912c2d3a559SKris Kennaway 		arg = strdelim(&cp);
913c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
914c2d3a559SKris Kennaway 			fatal("%s line %d: Missing MaxStartups spec.",
915c2d3a559SKris Kennaway 			    filename, linenum);
916af12a3e7SDag-Erling Smørgrav 		if ((n = sscanf(arg, "%d:%d:%d",
917c2d3a559SKris Kennaway 		    &options->max_startups_begin,
918c2d3a559SKris Kennaway 		    &options->max_startups_rate,
919af12a3e7SDag-Erling Smørgrav 		    &options->max_startups)) == 3) {
920c2d3a559SKris Kennaway 			if (options->max_startups_begin >
921c2d3a559SKris Kennaway 			    options->max_startups ||
922c2d3a559SKris Kennaway 			    options->max_startups_rate > 100 ||
923c2d3a559SKris Kennaway 			    options->max_startups_rate < 1)
924c2d3a559SKris Kennaway 				fatal("%s line %d: Illegal MaxStartups spec.",
925c2d3a559SKris Kennaway 				    filename, linenum);
926af12a3e7SDag-Erling Smørgrav 		} else if (n != 1)
927af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: Illegal MaxStartups spec.",
928af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
929af12a3e7SDag-Erling Smørgrav 		else
930af12a3e7SDag-Erling Smørgrav 			options->max_startups = options->max_startups_begin;
931933ca70fSBrian Feldman 		break;
932933ca70fSBrian Feldman 
93321e764dfSDag-Erling Smørgrav 	case sMaxAuthTries:
93421e764dfSDag-Erling Smørgrav 		intptr = &options->max_authtries;
93521e764dfSDag-Erling Smørgrav 		goto parse_int;
93621e764dfSDag-Erling Smørgrav 
937ca3176e7SBrian Feldman 	case sBanner:
938ca3176e7SBrian Feldman 		charptr = &options->banner;
939ca3176e7SBrian Feldman 		goto parse_filename;
940af12a3e7SDag-Erling Smørgrav 	/*
941af12a3e7SDag-Erling Smørgrav 	 * These options can contain %X options expanded at
942af12a3e7SDag-Erling Smørgrav 	 * connect time, so that you can specify paths like:
943af12a3e7SDag-Erling Smørgrav 	 *
944af12a3e7SDag-Erling Smørgrav 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
945af12a3e7SDag-Erling Smørgrav 	 */
946af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile:
947af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile2:
948af12a3e7SDag-Erling Smørgrav 		charptr = (opcode == sAuthorizedKeysFile ) ?
949af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file :
950af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file2;
951af12a3e7SDag-Erling Smørgrav 		goto parse_filename;
952af12a3e7SDag-Erling Smørgrav 
953ca3176e7SBrian Feldman 	case sClientAliveInterval:
954ca3176e7SBrian Feldman 		intptr = &options->client_alive_interval;
955af12a3e7SDag-Erling Smørgrav 		goto parse_time;
956af12a3e7SDag-Erling Smørgrav 
957ca3176e7SBrian Feldman 	case sClientAliveCountMax:
958ca3176e7SBrian Feldman 		intptr = &options->client_alive_count_max;
959ca3176e7SBrian Feldman 		goto parse_int;
960af12a3e7SDag-Erling Smørgrav 
96121e764dfSDag-Erling Smørgrav 	case sAcceptEnv:
96221e764dfSDag-Erling Smørgrav 		while ((arg = strdelim(&cp)) && *arg != '\0') {
96321e764dfSDag-Erling Smørgrav 			if (strchr(arg, '=') != NULL)
96421e764dfSDag-Erling Smørgrav 				fatal("%s line %d: Invalid environment name.",
96521e764dfSDag-Erling Smørgrav 				    filename, linenum);
96621e764dfSDag-Erling Smørgrav 			if (options->num_accept_env >= MAX_ACCEPT_ENV)
96721e764dfSDag-Erling Smørgrav 				fatal("%s line %d: too many allow env.",
96821e764dfSDag-Erling Smørgrav 				    filename, linenum);
96921e764dfSDag-Erling Smørgrav 			options->accept_env[options->num_accept_env++] =
97021e764dfSDag-Erling Smørgrav 			    xstrdup(arg);
97121e764dfSDag-Erling Smørgrav 		}
97221e764dfSDag-Erling Smørgrav 		break;
97321e764dfSDag-Erling Smørgrav 
974b74df5b2SDag-Erling Smørgrav 	case sPermitTunnel:
975b74df5b2SDag-Erling Smørgrav 		intptr = &options->permit_tun;
976b74df5b2SDag-Erling Smørgrav 		arg = strdelim(&cp);
977b74df5b2SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
978b74df5b2SDag-Erling Smørgrav 			fatal("%s line %d: Missing yes/point-to-point/"
979b74df5b2SDag-Erling Smørgrav 			    "ethernet/no argument.", filename, linenum);
980b74df5b2SDag-Erling Smørgrav 		value = 0;	/* silence compiler */
981b74df5b2SDag-Erling Smørgrav 		if (strcasecmp(arg, "ethernet") == 0)
982b74df5b2SDag-Erling Smørgrav 			value = SSH_TUNMODE_ETHERNET;
983b74df5b2SDag-Erling Smørgrav 		else if (strcasecmp(arg, "point-to-point") == 0)
984b74df5b2SDag-Erling Smørgrav 			value = SSH_TUNMODE_POINTOPOINT;
985b74df5b2SDag-Erling Smørgrav 		else if (strcasecmp(arg, "yes") == 0)
986b74df5b2SDag-Erling Smørgrav 			value = SSH_TUNMODE_YES;
987b74df5b2SDag-Erling Smørgrav 		else if (strcasecmp(arg, "no") == 0)
988b74df5b2SDag-Erling Smørgrav 			value = SSH_TUNMODE_NO;
989b74df5b2SDag-Erling Smørgrav 		else
990b74df5b2SDag-Erling Smørgrav 			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
991b74df5b2SDag-Erling Smørgrav 			    "no argument: %s", filename, linenum, arg);
992b74df5b2SDag-Erling Smørgrav 		if (*intptr == -1)
993b74df5b2SDag-Erling Smørgrav 			*intptr = value;
994b74df5b2SDag-Erling Smørgrav 		break;
995b74df5b2SDag-Erling Smørgrav 
996db58a8e4SDag-Erling Smørgrav 	case sVersionAddendum:
997db58a8e4SDag-Erling Smørgrav                 ssh_version_set_addendum(strtok(cp, "\n"));
998db58a8e4SDag-Erling Smørgrav                 do {
999db58a8e4SDag-Erling Smørgrav                         arg = strdelim(&cp);
1000db58a8e4SDag-Erling Smørgrav                 } while (arg != NULL && *arg != '\0');
1001db58a8e4SDag-Erling Smørgrav 		break;
1002db58a8e4SDag-Erling Smørgrav 
1003af12a3e7SDag-Erling Smørgrav 	case sDeprecated:
1004cf2b5f3bSDag-Erling Smørgrav 		logit("%s line %d: Deprecated option %s",
1005cf2b5f3bSDag-Erling Smørgrav 		    filename, linenum, arg);
1006cf2b5f3bSDag-Erling Smørgrav 		while (arg)
1007cf2b5f3bSDag-Erling Smørgrav 		    arg = strdelim(&cp);
1008cf2b5f3bSDag-Erling Smørgrav 		break;
1009cf2b5f3bSDag-Erling Smørgrav 
1010cf2b5f3bSDag-Erling Smørgrav 	case sUnsupported:
1011cf2b5f3bSDag-Erling Smørgrav 		logit("%s line %d: Unsupported option %s",
1012af12a3e7SDag-Erling Smørgrav 		    filename, linenum, arg);
1013af12a3e7SDag-Erling Smørgrav 		while (arg)
1014af12a3e7SDag-Erling Smørgrav 		    arg = strdelim(&cp);
1015af12a3e7SDag-Erling Smørgrav 		break;
1016af12a3e7SDag-Erling Smørgrav 
101742f71286SMark Murray 	default:
1018af12a3e7SDag-Erling Smørgrav 		fatal("%s line %d: Missing handler for opcode %s (%d)",
1019c2d3a559SKris Kennaway 		    filename, linenum, arg, opcode);
1020511b41d2SMark Murray 	}
1021ca3176e7SBrian Feldman 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1022ca3176e7SBrian Feldman 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
1023c2d3a559SKris Kennaway 		    filename, linenum, arg);
1024af12a3e7SDag-Erling Smørgrav 	return 0;
1025af12a3e7SDag-Erling Smørgrav }
1026af12a3e7SDag-Erling Smørgrav 
1027af12a3e7SDag-Erling Smørgrav /* Reads the server configuration file. */
1028af12a3e7SDag-Erling Smørgrav 
1029af12a3e7SDag-Erling Smørgrav void
103021e764dfSDag-Erling Smørgrav load_server_config(const char *filename, Buffer *conf)
1031af12a3e7SDag-Erling Smørgrav {
103221e764dfSDag-Erling Smørgrav 	char line[1024], *cp;
1033a82e551fSDag-Erling Smørgrav 	FILE *f;
1034af12a3e7SDag-Erling Smørgrav 
103521e764dfSDag-Erling Smørgrav 	debug2("%s: filename %s", __func__, filename);
103621e764dfSDag-Erling Smørgrav 	if ((f = fopen(filename, "r")) == NULL) {
1037af12a3e7SDag-Erling Smørgrav 		perror(filename);
1038af12a3e7SDag-Erling Smørgrav 		exit(1);
1039af12a3e7SDag-Erling Smørgrav 	}
104021e764dfSDag-Erling Smørgrav 	buffer_clear(conf);
1041af12a3e7SDag-Erling Smørgrav 	while (fgets(line, sizeof(line), f)) {
104221e764dfSDag-Erling Smørgrav 		/*
104321e764dfSDag-Erling Smørgrav 		 * Trim out comments and strip whitespace
104421e764dfSDag-Erling Smørgrav 		 * NB - preserve newlines, they are needed to reproduce
104521e764dfSDag-Erling Smørgrav 		 * line numbers later for error messages
104621e764dfSDag-Erling Smørgrav 		 */
104721e764dfSDag-Erling Smørgrav 		if ((cp = strchr(line, '#')) != NULL)
104821e764dfSDag-Erling Smørgrav 			memcpy(cp, "\n", 2);
104921e764dfSDag-Erling Smørgrav 		cp = line + strspn(line, " \t\r");
105021e764dfSDag-Erling Smørgrav 
105121e764dfSDag-Erling Smørgrav 		buffer_append(conf, cp, strlen(cp));
105221e764dfSDag-Erling Smørgrav 	}
105321e764dfSDag-Erling Smørgrav 	buffer_append(conf, "\0", 1);
105421e764dfSDag-Erling Smørgrav 	fclose(f);
105521e764dfSDag-Erling Smørgrav 	debug2("%s: done config len = %d", __func__, buffer_len(conf));
105621e764dfSDag-Erling Smørgrav }
105721e764dfSDag-Erling Smørgrav 
105821e764dfSDag-Erling Smørgrav void
105921e764dfSDag-Erling Smørgrav parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
106021e764dfSDag-Erling Smørgrav {
106121e764dfSDag-Erling Smørgrav 	int linenum, bad_options = 0;
106221e764dfSDag-Erling Smørgrav 	char *cp, *obuf, *cbuf;
106321e764dfSDag-Erling Smørgrav 
106421e764dfSDag-Erling Smørgrav 	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
106521e764dfSDag-Erling Smørgrav 
106621e764dfSDag-Erling Smørgrav 	obuf = cbuf = xstrdup(buffer_ptr(conf));
106721e764dfSDag-Erling Smørgrav 	linenum = 1;
106821e764dfSDag-Erling Smørgrav 	while ((cp = strsep(&cbuf, "\n")) != NULL) {
106921e764dfSDag-Erling Smørgrav 		if (process_server_config_line(options, cp, filename,
107021e764dfSDag-Erling Smørgrav 		    linenum++) != 0)
1071af12a3e7SDag-Erling Smørgrav 			bad_options++;
1072511b41d2SMark Murray 	}
107321e764dfSDag-Erling Smørgrav 	xfree(obuf);
1074ca3176e7SBrian Feldman 	if (bad_options > 0)
1075af12a3e7SDag-Erling Smørgrav 		fatal("%s: terminating, %d bad configuration options",
1076511b41d2SMark Murray 		    filename, bad_options);
1077511b41d2SMark Murray }
1078