xref: /freebsd/crypto/openssh/servconf.c (revision b909c84bf2ef895044a6fcc3f5fb85666c257d2b)
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"
13cf2b5f3bSDag-Erling Smørgrav RCSID("$OpenBSD: servconf.c,v 1.127 2003/09/01 18:15:50 markus 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 "tildexpand.h"
23ca3176e7SBrian Feldman #include "misc.h"
24ca3176e7SBrian Feldman #include "cipher.h"
25ca3176e7SBrian Feldman #include "kex.h"
26ca3176e7SBrian Feldman #include "mac.h"
27511b41d2SMark Murray 
28af12a3e7SDag-Erling Smørgrav static void add_listen_addr(ServerOptions *, char *, u_short);
29af12a3e7SDag-Erling Smørgrav static void add_one_listen_addr(ServerOptions *, char *, u_short);
30ca3176e7SBrian Feldman 
31ca3176e7SBrian Feldman /* AF_UNSPEC or AF_INET or AF_INET6 */
32ca3176e7SBrian Feldman extern int IPv4or6;
3380628bacSDag-Erling Smørgrav /* Use of privilege separation or not */
3480628bacSDag-Erling Smørgrav extern int use_privsep;
35511b41d2SMark Murray 
36511b41d2SMark Murray /* Initializes the server options to their default values. */
37511b41d2SMark Murray 
38511b41d2SMark Murray void
39511b41d2SMark Murray initialize_server_options(ServerOptions *options)
40511b41d2SMark Murray {
41511b41d2SMark Murray 	memset(options, 0, sizeof(*options));
42989dd127SDag-Erling Smørgrav 
43989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
44cf2b5f3bSDag-Erling Smørgrav 	options->use_pam = -1;
45989dd127SDag-Erling Smørgrav 
46989dd127SDag-Erling Smørgrav 	/* Standard Options */
47511b41d2SMark Murray 	options->num_ports = 0;
48511b41d2SMark Murray 	options->ports_from_cmdline = 0;
49511b41d2SMark Murray 	options->listen_addrs = NULL;
50ca3176e7SBrian Feldman 	options->num_host_key_files = 0;
51e8aafc91SKris Kennaway 	options->pid_file = NULL;
52511b41d2SMark Murray 	options->server_key_bits = -1;
53511b41d2SMark Murray 	options->login_grace_time = -1;
54511b41d2SMark Murray 	options->key_regeneration_time = -1;
55ca3176e7SBrian Feldman 	options->permit_root_login = PERMIT_NOT_SET;
56511b41d2SMark Murray 	options->ignore_rhosts = -1;
57511b41d2SMark Murray 	options->ignore_user_known_hosts = -1;
58511b41d2SMark Murray 	options->print_motd = -1;
59ca3176e7SBrian Feldman 	options->print_lastlog = -1;
60511b41d2SMark Murray 	options->x11_forwarding = -1;
61511b41d2SMark Murray 	options->x11_display_offset = -1;
62af12a3e7SDag-Erling Smørgrav 	options->x11_use_localhost = -1;
63c2d3a559SKris Kennaway 	options->xauth_location = NULL;
64511b41d2SMark Murray 	options->strict_modes = -1;
65511b41d2SMark Murray 	options->keepalives = -1;
66af12a3e7SDag-Erling Smørgrav 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
67af12a3e7SDag-Erling Smørgrav 	options->log_level = SYSLOG_LEVEL_NOT_SET;
68511b41d2SMark Murray 	options->rhosts_rsa_authentication = -1;
69ca3176e7SBrian Feldman 	options->hostbased_authentication = -1;
70ca3176e7SBrian Feldman 	options->hostbased_uses_name_from_packet_only = -1;
71511b41d2SMark Murray 	options->rsa_authentication = -1;
72ca3176e7SBrian Feldman 	options->pubkey_authentication = -1;
73cb96ab36SAssar Westerlund 	options->kerberos_authentication = -1;
74af12a3e7SDag-Erling Smørgrav 	options->kerberos_or_local_passwd = -1;
75af12a3e7SDag-Erling Smørgrav 	options->kerberos_ticket_cleanup = -1;
76cf2b5f3bSDag-Erling Smørgrav 	options->gss_authentication=-1;
77cf2b5f3bSDag-Erling Smørgrav 	options->gss_cleanup_creds = -1;
78511b41d2SMark Murray 	options->password_authentication = -1;
7909958426SBrian Feldman 	options->kbd_interactive_authentication = -1;
80af12a3e7SDag-Erling Smørgrav 	options->challenge_response_authentication = -1;
81511b41d2SMark Murray 	options->permit_empty_passwd = -1;
82f388f5efSDag-Erling Smørgrav 	options->permit_user_env = -1;
83511b41d2SMark Murray 	options->use_login = -1;
8480628bacSDag-Erling Smørgrav 	options->compression = -1;
8509958426SBrian Feldman 	options->allow_tcp_forwarding = -1;
86511b41d2SMark Murray 	options->num_allow_users = 0;
87511b41d2SMark Murray 	options->num_deny_users = 0;
88511b41d2SMark Murray 	options->num_allow_groups = 0;
89511b41d2SMark Murray 	options->num_deny_groups = 0;
90e8aafc91SKris Kennaway 	options->ciphers = NULL;
91ca3176e7SBrian Feldman 	options->macs = NULL;
92e8aafc91SKris Kennaway 	options->protocol = SSH_PROTO_UNKNOWN;
93e8aafc91SKris Kennaway 	options->gateway_ports = -1;
94c2d3a559SKris Kennaway 	options->num_subsystems = 0;
95c2d3a559SKris Kennaway 	options->max_startups_begin = -1;
96c2d3a559SKris Kennaway 	options->max_startups_rate = -1;
97c2d3a559SKris Kennaway 	options->max_startups = -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;
10480628bacSDag-Erling Smørgrav 
10580628bacSDag-Erling Smørgrav 	/* Needs to be accessable in many places */
10680628bacSDag-Erling Smørgrav 	use_privsep = -1;
107511b41d2SMark Murray }
108511b41d2SMark Murray 
109511b41d2SMark Murray void
110511b41d2SMark Murray fill_default_server_options(ServerOptions *options)
111511b41d2SMark Murray {
112989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
113cf2b5f3bSDag-Erling Smørgrav 	if (options->use_pam == -1)
114f0477b26SDag-Erling Smørgrav 		options->use_pam = 1;
115989dd127SDag-Erling Smørgrav 
116989dd127SDag-Erling Smørgrav 	/* Standard Options */
117ca3176e7SBrian Feldman 	if (options->protocol == SSH_PROTO_UNKNOWN)
118ca3176e7SBrian Feldman 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
119ca3176e7SBrian Feldman 	if (options->num_host_key_files == 0) {
120ca3176e7SBrian Feldman 		/* fill default hostkeys for protocols */
121ca3176e7SBrian Feldman 		if (options->protocol & SSH_PROTO_1)
122af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
123af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_KEY_FILE;
124af12a3e7SDag-Erling Smørgrav 		if (options->protocol & SSH_PROTO_2) {
125af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
126af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_DSA_KEY_FILE;
127af12a3e7SDag-Erling Smørgrav 		}
128ca3176e7SBrian Feldman 	}
129511b41d2SMark Murray 	if (options->num_ports == 0)
130511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
131511b41d2SMark Murray 	if (options->listen_addrs == NULL)
132ca3176e7SBrian Feldman 		add_listen_addr(options, NULL, 0);
133e8aafc91SKris Kennaway 	if (options->pid_file == NULL)
134ca3176e7SBrian Feldman 		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
135511b41d2SMark Murray 	if (options->server_key_bits == -1)
136511b41d2SMark Murray 		options->server_key_bits = 768;
137511b41d2SMark Murray 	if (options->login_grace_time == -1)
138975616f0SDag-Erling Smørgrav 		options->login_grace_time = 120;
139511b41d2SMark Murray 	if (options->key_regeneration_time == -1)
140511b41d2SMark Murray 		options->key_regeneration_time = 3600;
141ca3176e7SBrian Feldman 	if (options->permit_root_login == PERMIT_NOT_SET)
142975616f0SDag-Erling Smørgrav 		options->permit_root_login = PERMIT_NO;
143511b41d2SMark Murray 	if (options->ignore_rhosts == -1)
144fe5fd017SMark Murray 		options->ignore_rhosts = 1;
145511b41d2SMark Murray 	if (options->ignore_user_known_hosts == -1)
146511b41d2SMark Murray 		options->ignore_user_known_hosts = 0;
147511b41d2SMark Murray 	if (options->print_motd == -1)
148511b41d2SMark Murray 		options->print_motd = 1;
149ca3176e7SBrian Feldman 	if (options->print_lastlog == -1)
150ca3176e7SBrian Feldman 		options->print_lastlog = 1;
151511b41d2SMark Murray 	if (options->x11_forwarding == -1)
152975616f0SDag-Erling Smørgrav 		options->x11_forwarding = 1;
153511b41d2SMark Murray 	if (options->x11_display_offset == -1)
154fe5fd017SMark Murray 		options->x11_display_offset = 10;
155af12a3e7SDag-Erling Smørgrav 	if (options->x11_use_localhost == -1)
156af12a3e7SDag-Erling Smørgrav 		options->x11_use_localhost = 1;
157c2d3a559SKris Kennaway 	if (options->xauth_location == NULL)
158af12a3e7SDag-Erling Smørgrav 		options->xauth_location = _PATH_XAUTH;
159511b41d2SMark Murray 	if (options->strict_modes == -1)
160511b41d2SMark Murray 		options->strict_modes = 1;
161511b41d2SMark Murray 	if (options->keepalives == -1)
162511b41d2SMark Murray 		options->keepalives = 1;
163af12a3e7SDag-Erling Smørgrav 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
164511b41d2SMark Murray 		options->log_facility = SYSLOG_FACILITY_AUTH;
165af12a3e7SDag-Erling Smørgrav 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
166511b41d2SMark Murray 		options->log_level = SYSLOG_LEVEL_INFO;
167511b41d2SMark Murray 	if (options->rhosts_rsa_authentication == -1)
168fe5fd017SMark Murray 		options->rhosts_rsa_authentication = 0;
169ca3176e7SBrian Feldman 	if (options->hostbased_authentication == -1)
170ca3176e7SBrian Feldman 		options->hostbased_authentication = 0;
171ca3176e7SBrian Feldman 	if (options->hostbased_uses_name_from_packet_only == -1)
172ca3176e7SBrian Feldman 		options->hostbased_uses_name_from_packet_only = 0;
173511b41d2SMark Murray 	if (options->rsa_authentication == -1)
174511b41d2SMark Murray 		options->rsa_authentication = 1;
175ca3176e7SBrian Feldman 	if (options->pubkey_authentication == -1)
176ca3176e7SBrian Feldman 		options->pubkey_authentication = 1;
177989dd127SDag-Erling Smørgrav 	if (options->kerberos_authentication == -1)
178cf2b5f3bSDag-Erling Smørgrav 		options->kerberos_authentication = 0;
179af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_or_local_passwd == -1)
180af12a3e7SDag-Erling Smørgrav 		options->kerberos_or_local_passwd = 1;
181af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_ticket_cleanup == -1)
182af12a3e7SDag-Erling Smørgrav 		options->kerberos_ticket_cleanup = 1;
183cf2b5f3bSDag-Erling Smørgrav 	if (options->gss_authentication == -1)
184cf2b5f3bSDag-Erling Smørgrav 		options->gss_authentication = 0;
185cf2b5f3bSDag-Erling Smørgrav 	if (options->gss_cleanup_creds == -1)
186cf2b5f3bSDag-Erling Smørgrav 		options->gss_cleanup_creds = 1;
187511b41d2SMark Murray 	if (options->password_authentication == -1)
188b909c84bSDag-Erling Smørgrav #ifdef USE_PAM
189b909c84bSDag-Erling Smørgrav 		options->password_authentication = 0;
190b909c84bSDag-Erling Smørgrav #else
191511b41d2SMark Murray 		options->password_authentication = 1;
192b909c84bSDag-Erling Smørgrav #endif
19309958426SBrian Feldman 	if (options->kbd_interactive_authentication == -1)
19409958426SBrian Feldman 		options->kbd_interactive_authentication = 0;
195af12a3e7SDag-Erling Smørgrav 	if (options->challenge_response_authentication == -1)
19680241871SDag-Erling Smørgrav 		options->challenge_response_authentication = 1;
197511b41d2SMark Murray 	if (options->permit_empty_passwd == -1)
198fe5fd017SMark Murray 		options->permit_empty_passwd = 0;
199f388f5efSDag-Erling Smørgrav 	if (options->permit_user_env == -1)
200f388f5efSDag-Erling Smørgrav 		options->permit_user_env = 0;
201511b41d2SMark Murray 	if (options->use_login == -1)
202511b41d2SMark Murray 		options->use_login = 0;
20380628bacSDag-Erling Smørgrav 	if (options->compression == -1)
20480628bacSDag-Erling Smørgrav 		options->compression = 1;
20509958426SBrian Feldman 	if (options->allow_tcp_forwarding == -1)
20609958426SBrian Feldman 		options->allow_tcp_forwarding = 1;
207e8aafc91SKris Kennaway 	if (options->gateway_ports == -1)
208e8aafc91SKris Kennaway 		options->gateway_ports = 0;
209c2d3a559SKris Kennaway 	if (options->max_startups == -1)
210c2d3a559SKris Kennaway 		options->max_startups = 10;
211c2d3a559SKris Kennaway 	if (options->max_startups_rate == -1)
212c2d3a559SKris Kennaway 		options->max_startups_rate = 100;		/* 100% */
213c2d3a559SKris Kennaway 	if (options->max_startups_begin == -1)
214c2d3a559SKris Kennaway 		options->max_startups_begin = options->max_startups;
215cf2b5f3bSDag-Erling Smørgrav 	if (options->use_dns == -1)
216cf2b5f3bSDag-Erling Smørgrav 		options->use_dns = 1;
217ca3176e7SBrian Feldman 	if (options->client_alive_interval == -1)
218ca3176e7SBrian Feldman 		options->client_alive_interval = 0;
219ca3176e7SBrian Feldman 	if (options->client_alive_count_max == -1)
220ca3176e7SBrian Feldman 		options->client_alive_count_max = 3;
221af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file2 == NULL) {
222af12a3e7SDag-Erling Smørgrav 		/* authorized_keys_file2 falls back to authorized_keys_file */
223af12a3e7SDag-Erling Smørgrav 		if (options->authorized_keys_file != NULL)
224af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = options->authorized_keys_file;
225af12a3e7SDag-Erling Smørgrav 		else
226af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
227af12a3e7SDag-Erling Smørgrav 	}
228af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file == NULL)
229af12a3e7SDag-Erling Smørgrav 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
23080628bacSDag-Erling Smørgrav 
231989dd127SDag-Erling Smørgrav 	/* Turn privilege separation on by default */
23280628bacSDag-Erling Smørgrav 	if (use_privsep == -1)
233989dd127SDag-Erling Smørgrav 		use_privsep = 1;
234989dd127SDag-Erling Smørgrav 
235f388f5efSDag-Erling Smørgrav #ifndef HAVE_MMAP
236989dd127SDag-Erling Smørgrav 	if (use_privsep && options->compression == 1) {
237989dd127SDag-Erling Smørgrav 		error("This platform does not support both privilege "
238989dd127SDag-Erling Smørgrav 		    "separation and compression");
239989dd127SDag-Erling Smørgrav 		error("Compression disabled");
240989dd127SDag-Erling Smørgrav 		options->compression = 0;
241989dd127SDag-Erling Smørgrav 	}
242989dd127SDag-Erling Smørgrav #endif
243989dd127SDag-Erling Smørgrav 
244511b41d2SMark Murray }
245511b41d2SMark Murray 
246511b41d2SMark Murray /* Keyword tokens. */
247511b41d2SMark Murray typedef enum {
248511b41d2SMark Murray 	sBadOption,		/* == unknown option */
249989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
250cf2b5f3bSDag-Erling Smørgrav 	sUsePAM,
251989dd127SDag-Erling Smørgrav 	/* Standard Options */
252511b41d2SMark Murray 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
253511b41d2SMark Murray 	sPermitRootLogin, sLogFacility, sLogLevel,
254cf2b5f3bSDag-Erling Smørgrav 	sRhostsRSAAuthentication, sRSAAuthentication,
255af12a3e7SDag-Erling Smørgrav 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
256cf2b5f3bSDag-Erling Smørgrav 	sKerberosTgtPassing, sChallengeResponseAuthentication,
25709958426SBrian Feldman 	sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
258ca3176e7SBrian Feldman 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
259af12a3e7SDag-Erling Smørgrav 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
260af12a3e7SDag-Erling Smørgrav 	sStrictModes, sEmptyPasswd, sKeepAlives,
261f388f5efSDag-Erling Smørgrav 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
26209958426SBrian Feldman 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
263ca3176e7SBrian Feldman 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
264ca3176e7SBrian Feldman 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
265cf2b5f3bSDag-Erling Smørgrav 	sBanner, sUseDNS, sHostbasedAuthentication,
266ca3176e7SBrian Feldman 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
267af12a3e7SDag-Erling Smørgrav 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
268cf2b5f3bSDag-Erling Smørgrav 	sGssAuthentication, sGssCleanupCreds,
26980628bacSDag-Erling Smørgrav 	sUsePrivilegeSeparation,
270db58a8e4SDag-Erling Smørgrav 	sVersionAddendum,
271cf2b5f3bSDag-Erling Smørgrav 	sDeprecated, sUnsupported
272511b41d2SMark Murray } ServerOpCodes;
273511b41d2SMark Murray 
274511b41d2SMark Murray /* Textual representation of the tokens. */
275511b41d2SMark Murray static struct {
276511b41d2SMark Murray 	const char *name;
277511b41d2SMark Murray 	ServerOpCodes opcode;
278511b41d2SMark Murray } keywords[] = {
279989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
280cf2b5f3bSDag-Erling Smørgrav #ifdef USE_PAM
281cf2b5f3bSDag-Erling Smørgrav 	{ "usepam", sUsePAM },
282cf2b5f3bSDag-Erling Smørgrav #else
283cf2b5f3bSDag-Erling Smørgrav 	{ "usepam", sUnsupported },
284975616f0SDag-Erling Smørgrav #endif
285cf2b5f3bSDag-Erling Smørgrav 	{ "pamauthenticationviakbdint", sDeprecated },
286989dd127SDag-Erling Smørgrav 	/* Standard Options */
287511b41d2SMark Murray 	{ "port", sPort },
288511b41d2SMark Murray 	{ "hostkey", sHostKeyFile },
289ca3176e7SBrian Feldman 	{ "hostdsakey", sHostKeyFile },					/* alias */
290e8aafc91SKris Kennaway 	{ "pidfile", sPidFile },
291511b41d2SMark Murray 	{ "serverkeybits", sServerKeyBits },
292511b41d2SMark Murray 	{ "logingracetime", sLoginGraceTime },
293511b41d2SMark Murray 	{ "keyregenerationinterval", sKeyRegenerationTime },
294511b41d2SMark Murray 	{ "permitrootlogin", sPermitRootLogin },
295511b41d2SMark Murray 	{ "syslogfacility", sLogFacility },
296511b41d2SMark Murray 	{ "loglevel", sLogLevel },
297cf2b5f3bSDag-Erling Smørgrav 	{ "rhostsauthentication", sDeprecated },
298511b41d2SMark Murray 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
299ca3176e7SBrian Feldman 	{ "hostbasedauthentication", sHostbasedAuthentication },
300ca3176e7SBrian Feldman 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
301af12a3e7SDag-Erling Smørgrav 	{ "rsaauthentication", sRSAAuthentication },
302ca3176e7SBrian Feldman 	{ "pubkeyauthentication", sPubkeyAuthentication },
303ca3176e7SBrian Feldman 	{ "dsaauthentication", sPubkeyAuthentication },			/* alias */
304cf2b5f3bSDag-Erling Smørgrav #ifdef KRB5
305cb96ab36SAssar Westerlund 	{ "kerberosauthentication", sKerberosAuthentication },
306af12a3e7SDag-Erling Smørgrav 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
307af12a3e7SDag-Erling Smørgrav 	{ "kerberosticketcleanup", sKerberosTicketCleanup },
308cf2b5f3bSDag-Erling Smørgrav #else
309cf2b5f3bSDag-Erling Smørgrav 	{ "kerberosauthentication", sUnsupported },
310cf2b5f3bSDag-Erling Smørgrav 	{ "kerberosorlocalpasswd", sUnsupported },
311cf2b5f3bSDag-Erling Smørgrav 	{ "kerberosticketcleanup", sUnsupported },
312cb96ab36SAssar Westerlund #endif
313cf2b5f3bSDag-Erling Smørgrav 	{ "kerberostgtpassing", sUnsupported },
314cf2b5f3bSDag-Erling Smørgrav 	{ "afstokenpassing", sUnsupported },
315cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
316cf2b5f3bSDag-Erling Smørgrav 	{ "gssapiauthentication", sGssAuthentication },
317cf2b5f3bSDag-Erling Smørgrav 	{ "gssapicleanupcreds", sGssCleanupCreds },
318cf2b5f3bSDag-Erling Smørgrav #else
319cf2b5f3bSDag-Erling Smørgrav 	{ "gssapiauthentication", sUnsupported },
320cf2b5f3bSDag-Erling Smørgrav 	{ "gssapicleanupcreds", sUnsupported },
321511b41d2SMark Murray #endif
322511b41d2SMark Murray 	{ "passwordauthentication", sPasswordAuthentication },
32309958426SBrian Feldman 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
324ca3176e7SBrian Feldman 	{ "challengeresponseauthentication", sChallengeResponseAuthentication },
325ca3176e7SBrian Feldman 	{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
326989dd127SDag-Erling Smørgrav 	{ "checkmail", sDeprecated },
327511b41d2SMark Murray 	{ "listenaddress", sListenAddress },
328511b41d2SMark Murray 	{ "printmotd", sPrintMotd },
329ca3176e7SBrian Feldman 	{ "printlastlog", sPrintLastLog },
330511b41d2SMark Murray 	{ "ignorerhosts", sIgnoreRhosts },
331511b41d2SMark Murray 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
332511b41d2SMark Murray 	{ "x11forwarding", sX11Forwarding },
333511b41d2SMark Murray 	{ "x11displayoffset", sX11DisplayOffset },
334af12a3e7SDag-Erling Smørgrav 	{ "x11uselocalhost", sX11UseLocalhost },
335c2d3a559SKris Kennaway 	{ "xauthlocation", sXAuthLocation },
336511b41d2SMark Murray 	{ "strictmodes", sStrictModes },
337511b41d2SMark Murray 	{ "permitemptypasswords", sEmptyPasswd },
338f388f5efSDag-Erling Smørgrav 	{ "permituserenvironment", sPermitUserEnvironment },
339511b41d2SMark Murray 	{ "uselogin", sUseLogin },
34080628bacSDag-Erling Smørgrav 	{ "compression", sCompression },
341511b41d2SMark Murray 	{ "keepalive", sKeepAlives },
34209958426SBrian Feldman 	{ "allowtcpforwarding", sAllowTcpForwarding },
343511b41d2SMark Murray 	{ "allowusers", sAllowUsers },
344511b41d2SMark Murray 	{ "denyusers", sDenyUsers },
345511b41d2SMark Murray 	{ "allowgroups", sAllowGroups },
346511b41d2SMark Murray 	{ "denygroups", sDenyGroups },
347e8aafc91SKris Kennaway 	{ "ciphers", sCiphers },
348ca3176e7SBrian Feldman 	{ "macs", sMacs },
349e8aafc91SKris Kennaway 	{ "protocol", sProtocol },
350e8aafc91SKris Kennaway 	{ "gatewayports", sGatewayPorts },
351c2d3a559SKris Kennaway 	{ "subsystem", sSubsystem },
352c2d3a559SKris Kennaway 	{ "maxstartups", sMaxStartups },
353ca3176e7SBrian Feldman 	{ "banner", sBanner },
354cf2b5f3bSDag-Erling Smørgrav 	{ "usedns", sUseDNS },
355cf2b5f3bSDag-Erling Smørgrav 	{ "verifyreversemapping", sDeprecated },
356cf2b5f3bSDag-Erling Smørgrav 	{ "reversemappingcheck", sDeprecated },
357ca3176e7SBrian Feldman 	{ "clientaliveinterval", sClientAliveInterval },
358ca3176e7SBrian Feldman 	{ "clientalivecountmax", sClientAliveCountMax },
359af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile", sAuthorizedKeysFile },
360af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
36180628bacSDag-Erling Smørgrav 	{ "useprivilegeseparation", sUsePrivilegeSeparation},
362db58a8e4SDag-Erling Smørgrav 	{ "versionaddendum", sVersionAddendum },
363af12a3e7SDag-Erling Smørgrav 	{ NULL, sBadOption }
364511b41d2SMark Murray };
365511b41d2SMark Murray 
366511b41d2SMark Murray /*
367ca3176e7SBrian Feldman  * Returns the number of the token pointed to by cp or sBadOption.
368511b41d2SMark Murray  */
369511b41d2SMark Murray 
370511b41d2SMark Murray static ServerOpCodes
371511b41d2SMark Murray parse_token(const char *cp, const char *filename,
372511b41d2SMark Murray 	    int linenum)
373511b41d2SMark Murray {
374ca3176e7SBrian Feldman 	u_int i;
375511b41d2SMark Murray 
376511b41d2SMark Murray 	for (i = 0; keywords[i].name; i++)
377511b41d2SMark Murray 		if (strcasecmp(cp, keywords[i].name) == 0)
378511b41d2SMark Murray 			return keywords[i].opcode;
379511b41d2SMark Murray 
380ca3176e7SBrian Feldman 	error("%s: line %d: Bad configuration option: %s",
381511b41d2SMark Murray 	    filename, linenum, cp);
382511b41d2SMark Murray 	return sBadOption;
383511b41d2SMark Murray }
384511b41d2SMark Murray 
385af12a3e7SDag-Erling Smørgrav static void
386ca3176e7SBrian Feldman add_listen_addr(ServerOptions *options, char *addr, u_short port)
387511b41d2SMark Murray {
388511b41d2SMark Murray 	int i;
389511b41d2SMark Murray 
390511b41d2SMark Murray 	if (options->num_ports == 0)
391511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
392ca3176e7SBrian Feldman 	if (port == 0)
393ca3176e7SBrian Feldman 		for (i = 0; i < options->num_ports; i++)
394ca3176e7SBrian Feldman 			add_one_listen_addr(options, addr, options->ports[i]);
395ca3176e7SBrian Feldman 	else
396ca3176e7SBrian Feldman 		add_one_listen_addr(options, addr, port);
397ca3176e7SBrian Feldman }
398ca3176e7SBrian Feldman 
399af12a3e7SDag-Erling Smørgrav static void
400ca3176e7SBrian Feldman add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
401ca3176e7SBrian Feldman {
402ca3176e7SBrian Feldman 	struct addrinfo hints, *ai, *aitop;
403ca3176e7SBrian Feldman 	char strport[NI_MAXSERV];
404ca3176e7SBrian Feldman 	int gaierr;
405ca3176e7SBrian Feldman 
406511b41d2SMark Murray 	memset(&hints, 0, sizeof(hints));
407511b41d2SMark Murray 	hints.ai_family = IPv4or6;
408511b41d2SMark Murray 	hints.ai_socktype = SOCK_STREAM;
409511b41d2SMark Murray 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
410a82e551fSDag-Erling Smørgrav 	snprintf(strport, sizeof strport, "%u", port);
411511b41d2SMark Murray 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
412ca3176e7SBrian Feldman 		fatal("bad addr or host: %s (%s)",
413511b41d2SMark Murray 		    addr ? addr : "<NULL>",
414511b41d2SMark Murray 		    gai_strerror(gaierr));
415511b41d2SMark Murray 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
416511b41d2SMark Murray 		;
417511b41d2SMark Murray 	ai->ai_next = options->listen_addrs;
418511b41d2SMark Murray 	options->listen_addrs = aitop;
419511b41d2SMark Murray }
420511b41d2SMark Murray 
421af12a3e7SDag-Erling Smørgrav int
422af12a3e7SDag-Erling Smørgrav process_server_config_line(ServerOptions *options, char *line,
423af12a3e7SDag-Erling Smørgrav     const char *filename, int linenum)
424511b41d2SMark Murray {
425ca3176e7SBrian Feldman 	char *cp, **charptr, *arg, *p;
426a82e551fSDag-Erling Smørgrav 	int *intptr, value, i, n;
427511b41d2SMark Murray 	ServerOpCodes opcode;
428511b41d2SMark Murray 
429c2d3a559SKris Kennaway 	cp = line;
430c2d3a559SKris Kennaway 	arg = strdelim(&cp);
431c2d3a559SKris Kennaway 	/* Ignore leading whitespace */
432c2d3a559SKris Kennaway 	if (*arg == '\0')
433c2d3a559SKris Kennaway 		arg = strdelim(&cp);
434ca3176e7SBrian Feldman 	if (!arg || !*arg || *arg == '#')
435af12a3e7SDag-Erling Smørgrav 		return 0;
436ca3176e7SBrian Feldman 	intptr = NULL;
437ca3176e7SBrian Feldman 	charptr = NULL;
438c2d3a559SKris Kennaway 	opcode = parse_token(arg, filename, linenum);
439511b41d2SMark Murray 	switch (opcode) {
440989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
441cf2b5f3bSDag-Erling Smørgrav 	case sUsePAM:
442cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->use_pam;
443989dd127SDag-Erling Smørgrav 		goto parse_flag;
444989dd127SDag-Erling Smørgrav 
445989dd127SDag-Erling Smørgrav 	/* Standard Options */
446511b41d2SMark Murray 	case sBadOption:
447af12a3e7SDag-Erling Smørgrav 		return -1;
448511b41d2SMark Murray 	case sPort:
449511b41d2SMark Murray 		/* ignore ports from configfile if cmdline specifies ports */
450511b41d2SMark Murray 		if (options->ports_from_cmdline)
451af12a3e7SDag-Erling Smørgrav 			return 0;
452511b41d2SMark Murray 		if (options->listen_addrs != NULL)
453511b41d2SMark Murray 			fatal("%s line %d: ports must be specified before "
454af12a3e7SDag-Erling Smørgrav 			    "ListenAddress.", filename, linenum);
455511b41d2SMark Murray 		if (options->num_ports >= MAX_PORTS)
456ca3176e7SBrian Feldman 			fatal("%s line %d: too many ports.",
457511b41d2SMark Murray 			    filename, linenum);
458c2d3a559SKris Kennaway 		arg = strdelim(&cp);
459c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
460ca3176e7SBrian Feldman 			fatal("%s line %d: missing port number.",
461511b41d2SMark Murray 			    filename, linenum);
462ca3176e7SBrian Feldman 		options->ports[options->num_ports++] = a2port(arg);
463ca3176e7SBrian Feldman 		if (options->ports[options->num_ports-1] == 0)
464ca3176e7SBrian Feldman 			fatal("%s line %d: Badly formatted port number.",
465ca3176e7SBrian Feldman 			    filename, linenum);
466511b41d2SMark Murray 		break;
467511b41d2SMark Murray 
468511b41d2SMark Murray 	case sServerKeyBits:
469511b41d2SMark Murray 		intptr = &options->server_key_bits;
470511b41d2SMark Murray parse_int:
471c2d3a559SKris Kennaway 		arg = strdelim(&cp);
472ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
473ca3176e7SBrian Feldman 			fatal("%s line %d: missing integer value.",
474511b41d2SMark Murray 			    filename, linenum);
475c2d3a559SKris Kennaway 		value = atoi(arg);
476511b41d2SMark Murray 		if (*intptr == -1)
477511b41d2SMark Murray 			*intptr = value;
478511b41d2SMark Murray 		break;
479511b41d2SMark Murray 
480511b41d2SMark Murray 	case sLoginGraceTime:
481511b41d2SMark Murray 		intptr = &options->login_grace_time;
482af12a3e7SDag-Erling Smørgrav parse_time:
483af12a3e7SDag-Erling Smørgrav 		arg = strdelim(&cp);
484af12a3e7SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
485af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: missing time value.",
486af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
487af12a3e7SDag-Erling Smørgrav 		if ((value = convtime(arg)) == -1)
488af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: invalid time value.",
489af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
490af12a3e7SDag-Erling Smørgrav 		if (*intptr == -1)
491af12a3e7SDag-Erling Smørgrav 			*intptr = value;
492af12a3e7SDag-Erling Smørgrav 		break;
493511b41d2SMark Murray 
494511b41d2SMark Murray 	case sKeyRegenerationTime:
495511b41d2SMark Murray 		intptr = &options->key_regeneration_time;
496af12a3e7SDag-Erling Smørgrav 		goto parse_time;
497511b41d2SMark Murray 
498511b41d2SMark Murray 	case sListenAddress:
499c2d3a559SKris Kennaway 		arg = strdelim(&cp);
500ca3176e7SBrian Feldman 		if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
501ca3176e7SBrian Feldman 			fatal("%s line %d: missing inet addr.",
502511b41d2SMark Murray 			    filename, linenum);
503ca3176e7SBrian Feldman 		if (*arg == '[') {
504ca3176e7SBrian Feldman 			if ((p = strchr(arg, ']')) == NULL)
505ca3176e7SBrian Feldman 				fatal("%s line %d: bad ipv6 inet addr usage.",
506ca3176e7SBrian Feldman 				    filename, linenum);
507ca3176e7SBrian Feldman 			arg++;
508ca3176e7SBrian Feldman 			memmove(p, p+1, strlen(p+1)+1);
509ca3176e7SBrian Feldman 		} else if (((p = strchr(arg, ':')) == NULL) ||
510ca3176e7SBrian Feldman 			    (strchr(p+1, ':') != NULL)) {
511ca3176e7SBrian Feldman 			add_listen_addr(options, arg, 0);
512ca3176e7SBrian Feldman 			break;
513ca3176e7SBrian Feldman 		}
514ca3176e7SBrian Feldman 		if (*p == ':') {
515ca3176e7SBrian Feldman 			u_short port;
516ca3176e7SBrian Feldman 
517ca3176e7SBrian Feldman 			p++;
518ca3176e7SBrian Feldman 			if (*p == '\0')
519ca3176e7SBrian Feldman 				fatal("%s line %d: bad inet addr:port usage.",
520ca3176e7SBrian Feldman 				    filename, linenum);
521ca3176e7SBrian Feldman 			else {
522ca3176e7SBrian Feldman 				*(p-1) = '\0';
523ca3176e7SBrian Feldman 				if ((port = a2port(p)) == 0)
524ca3176e7SBrian Feldman 					fatal("%s line %d: bad port number.",
525ca3176e7SBrian Feldman 					    filename, linenum);
526ca3176e7SBrian Feldman 				add_listen_addr(options, arg, port);
527ca3176e7SBrian Feldman 			}
528ca3176e7SBrian Feldman 		} else if (*p == '\0')
529ca3176e7SBrian Feldman 			add_listen_addr(options, arg, 0);
530ca3176e7SBrian Feldman 		else
531ca3176e7SBrian Feldman 			fatal("%s line %d: bad inet addr usage.",
532ca3176e7SBrian Feldman 			    filename, linenum);
533511b41d2SMark Murray 		break;
534511b41d2SMark Murray 
535511b41d2SMark Murray 	case sHostKeyFile:
536ca3176e7SBrian Feldman 		intptr = &options->num_host_key_files;
537ca3176e7SBrian Feldman 		if (*intptr >= MAX_HOSTKEYS)
538ca3176e7SBrian Feldman 			fatal("%s line %d: too many host keys specified (max %d).",
539ca3176e7SBrian Feldman 			    filename, linenum, MAX_HOSTKEYS);
540ca3176e7SBrian Feldman 		charptr = &options->host_key_files[*intptr];
541c2d3a559SKris Kennaway parse_filename:
542c2d3a559SKris Kennaway 		arg = strdelim(&cp);
543ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
544ca3176e7SBrian Feldman 			fatal("%s line %d: missing file name.",
545e8aafc91SKris Kennaway 			    filename, linenum);
546ca3176e7SBrian Feldman 		if (*charptr == NULL) {
547c2d3a559SKris Kennaway 			*charptr = tilde_expand_filename(arg, getuid());
548ca3176e7SBrian Feldman 			/* increase optional counter */
549ca3176e7SBrian Feldman 			if (intptr != NULL)
550ca3176e7SBrian Feldman 				*intptr = *intptr + 1;
551ca3176e7SBrian Feldman 		}
552e8aafc91SKris Kennaway 		break;
553e8aafc91SKris Kennaway 
554e8aafc91SKris Kennaway 	case sPidFile:
555e8aafc91SKris Kennaway 		charptr = &options->pid_file;
556c2d3a559SKris Kennaway 		goto parse_filename;
557511b41d2SMark Murray 
558511b41d2SMark Murray 	case sPermitRootLogin:
559511b41d2SMark Murray 		intptr = &options->permit_root_login;
560c2d3a559SKris Kennaway 		arg = strdelim(&cp);
561ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
562ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/"
563ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
564ca3176e7SBrian Feldman 			    "argument.", filename, linenum);
565ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
566c2d3a559SKris Kennaway 		if (strcmp(arg, "without-password") == 0)
567ca3176e7SBrian Feldman 			value = PERMIT_NO_PASSWD;
568ca3176e7SBrian Feldman 		else if (strcmp(arg, "forced-commands-only") == 0)
569ca3176e7SBrian Feldman 			value = PERMIT_FORCED_ONLY;
570c2d3a559SKris Kennaway 		else if (strcmp(arg, "yes") == 0)
571ca3176e7SBrian Feldman 			value = PERMIT_YES;
572c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
573ca3176e7SBrian Feldman 			value = PERMIT_NO;
574ca3176e7SBrian Feldman 		else
575ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/"
576ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
577ca3176e7SBrian Feldman 			    "argument: %s", filename, linenum, arg);
578511b41d2SMark Murray 		if (*intptr == -1)
579511b41d2SMark Murray 			*intptr = value;
580511b41d2SMark Murray 		break;
581511b41d2SMark Murray 
582511b41d2SMark Murray 	case sIgnoreRhosts:
583511b41d2SMark Murray 		intptr = &options->ignore_rhosts;
584511b41d2SMark Murray parse_flag:
585c2d3a559SKris Kennaway 		arg = strdelim(&cp);
586ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
587ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/no argument.",
588511b41d2SMark Murray 			    filename, linenum);
589ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
590c2d3a559SKris Kennaway 		if (strcmp(arg, "yes") == 0)
591511b41d2SMark Murray 			value = 1;
592c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
593511b41d2SMark Murray 			value = 0;
594ca3176e7SBrian Feldman 		else
595ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/no argument: %s",
596c2d3a559SKris Kennaway 				filename, linenum, arg);
597511b41d2SMark Murray 		if (*intptr == -1)
598511b41d2SMark Murray 			*intptr = value;
599511b41d2SMark Murray 		break;
600511b41d2SMark Murray 
601511b41d2SMark Murray 	case sIgnoreUserKnownHosts:
602511b41d2SMark Murray 		intptr = &options->ignore_user_known_hosts;
603962a3f4eSSheldon Hearn 		goto parse_flag;
604511b41d2SMark Murray 
605511b41d2SMark Murray 	case sRhostsRSAAuthentication:
606511b41d2SMark Murray 		intptr = &options->rhosts_rsa_authentication;
607511b41d2SMark Murray 		goto parse_flag;
608511b41d2SMark Murray 
609ca3176e7SBrian Feldman 	case sHostbasedAuthentication:
610ca3176e7SBrian Feldman 		intptr = &options->hostbased_authentication;
611ca3176e7SBrian Feldman 		goto parse_flag;
612ca3176e7SBrian Feldman 
613ca3176e7SBrian Feldman 	case sHostbasedUsesNameFromPacketOnly:
614ca3176e7SBrian Feldman 		intptr = &options->hostbased_uses_name_from_packet_only;
615ca3176e7SBrian Feldman 		goto parse_flag;
616ca3176e7SBrian Feldman 
617511b41d2SMark Murray 	case sRSAAuthentication:
618511b41d2SMark Murray 		intptr = &options->rsa_authentication;
619511b41d2SMark Murray 		goto parse_flag;
620511b41d2SMark Murray 
621ca3176e7SBrian Feldman 	case sPubkeyAuthentication:
622ca3176e7SBrian Feldman 		intptr = &options->pubkey_authentication;
623e8aafc91SKris Kennaway 		goto parse_flag;
624cf2b5f3bSDag-Erling Smørgrav 
625cb96ab36SAssar Westerlund 	case sKerberosAuthentication:
626cb96ab36SAssar Westerlund 		intptr = &options->kerberos_authentication;
627511b41d2SMark Murray 		goto parse_flag;
628511b41d2SMark Murray 
629af12a3e7SDag-Erling Smørgrav 	case sKerberosOrLocalPasswd:
630af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_or_local_passwd;
631511b41d2SMark Murray 		goto parse_flag;
632511b41d2SMark Murray 
633af12a3e7SDag-Erling Smørgrav 	case sKerberosTicketCleanup:
634af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_ticket_cleanup;
635511b41d2SMark Murray 		goto parse_flag;
636cf2b5f3bSDag-Erling Smørgrav 
637cf2b5f3bSDag-Erling Smørgrav 	case sGssAuthentication:
638cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->gss_authentication;
639fe5fd017SMark Murray 		goto parse_flag;
640cf2b5f3bSDag-Erling Smørgrav 
641cf2b5f3bSDag-Erling Smørgrav 	case sGssCleanupCreds:
642cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->gss_cleanup_creds;
643511b41d2SMark Murray 		goto parse_flag;
644511b41d2SMark Murray 
645511b41d2SMark Murray 	case sPasswordAuthentication:
646511b41d2SMark Murray 		intptr = &options->password_authentication;
647511b41d2SMark Murray 		goto parse_flag;
648511b41d2SMark Murray 
64909958426SBrian Feldman 	case sKbdInteractiveAuthentication:
65009958426SBrian Feldman 		intptr = &options->kbd_interactive_authentication;
65109958426SBrian Feldman 		goto parse_flag;
65209958426SBrian Feldman 
653ca3176e7SBrian Feldman 	case sChallengeResponseAuthentication:
654af12a3e7SDag-Erling Smørgrav 		intptr = &options->challenge_response_authentication;
655511b41d2SMark Murray 		goto parse_flag;
656511b41d2SMark Murray 
657511b41d2SMark Murray 	case sPrintMotd:
658511b41d2SMark Murray 		intptr = &options->print_motd;
659511b41d2SMark Murray 		goto parse_flag;
660511b41d2SMark Murray 
661ca3176e7SBrian Feldman 	case sPrintLastLog:
662ca3176e7SBrian Feldman 		intptr = &options->print_lastlog;
663ca3176e7SBrian Feldman 		goto parse_flag;
664ca3176e7SBrian Feldman 
665511b41d2SMark Murray 	case sX11Forwarding:
666511b41d2SMark Murray 		intptr = &options->x11_forwarding;
667511b41d2SMark Murray 		goto parse_flag;
668511b41d2SMark Murray 
669511b41d2SMark Murray 	case sX11DisplayOffset:
670511b41d2SMark Murray 		intptr = &options->x11_display_offset;
671511b41d2SMark Murray 		goto parse_int;
672511b41d2SMark Murray 
673af12a3e7SDag-Erling Smørgrav 	case sX11UseLocalhost:
674af12a3e7SDag-Erling Smørgrav 		intptr = &options->x11_use_localhost;
675af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
676af12a3e7SDag-Erling Smørgrav 
677c2d3a559SKris Kennaway 	case sXAuthLocation:
678c2d3a559SKris Kennaway 		charptr = &options->xauth_location;
679c2d3a559SKris Kennaway 		goto parse_filename;
680c2d3a559SKris Kennaway 
681511b41d2SMark Murray 	case sStrictModes:
682511b41d2SMark Murray 		intptr = &options->strict_modes;
683511b41d2SMark Murray 		goto parse_flag;
684511b41d2SMark Murray 
685511b41d2SMark Murray 	case sKeepAlives:
686511b41d2SMark Murray 		intptr = &options->keepalives;
687511b41d2SMark Murray 		goto parse_flag;
688511b41d2SMark Murray 
689511b41d2SMark Murray 	case sEmptyPasswd:
690511b41d2SMark Murray 		intptr = &options->permit_empty_passwd;
691511b41d2SMark Murray 		goto parse_flag;
692511b41d2SMark Murray 
693f388f5efSDag-Erling Smørgrav 	case sPermitUserEnvironment:
694f388f5efSDag-Erling Smørgrav 		intptr = &options->permit_user_env;
695f388f5efSDag-Erling Smørgrav 		goto parse_flag;
696f388f5efSDag-Erling Smørgrav 
697511b41d2SMark Murray 	case sUseLogin:
698511b41d2SMark Murray 		intptr = &options->use_login;
699511b41d2SMark Murray 		goto parse_flag;
700511b41d2SMark Murray 
70180628bacSDag-Erling Smørgrav 	case sCompression:
70280628bacSDag-Erling Smørgrav 		intptr = &options->compression;
70380628bacSDag-Erling Smørgrav 		goto parse_flag;
70480628bacSDag-Erling Smørgrav 
705e8aafc91SKris Kennaway 	case sGatewayPorts:
706e8aafc91SKris Kennaway 		intptr = &options->gateway_ports;
707e8aafc91SKris Kennaway 		goto parse_flag;
708e8aafc91SKris Kennaway 
709cf2b5f3bSDag-Erling Smørgrav 	case sUseDNS:
710cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->use_dns;
711ca3176e7SBrian Feldman 		goto parse_flag;
712ca3176e7SBrian Feldman 
713511b41d2SMark Murray 	case sLogFacility:
714511b41d2SMark Murray 		intptr = (int *) &options->log_facility;
715c2d3a559SKris Kennaway 		arg = strdelim(&cp);
716c2d3a559SKris Kennaway 		value = log_facility_number(arg);
717af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_FACILITY_NOT_SET)
718ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log facility '%s'",
719c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
720511b41d2SMark Murray 		if (*intptr == -1)
721511b41d2SMark Murray 			*intptr = (SyslogFacility) value;
722511b41d2SMark Murray 		break;
723511b41d2SMark Murray 
724511b41d2SMark Murray 	case sLogLevel:
725511b41d2SMark Murray 		intptr = (int *) &options->log_level;
726c2d3a559SKris Kennaway 		arg = strdelim(&cp);
727c2d3a559SKris Kennaway 		value = log_level_number(arg);
728af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_LEVEL_NOT_SET)
729ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log level '%s'",
730c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
731511b41d2SMark Murray 		if (*intptr == -1)
732511b41d2SMark Murray 			*intptr = (LogLevel) value;
733511b41d2SMark Murray 		break;
734511b41d2SMark Murray 
73509958426SBrian Feldman 	case sAllowTcpForwarding:
73609958426SBrian Feldman 		intptr = &options->allow_tcp_forwarding;
73709958426SBrian Feldman 		goto parse_flag;
73809958426SBrian Feldman 
73980628bacSDag-Erling Smørgrav 	case sUsePrivilegeSeparation:
74080628bacSDag-Erling Smørgrav 		intptr = &use_privsep;
74180628bacSDag-Erling Smørgrav 		goto parse_flag;
74280628bacSDag-Erling Smørgrav 
743511b41d2SMark Murray 	case sAllowUsers:
744c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
74542f71286SMark Murray 			if (options->num_allow_users >= MAX_ALLOW_USERS)
746af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow users.",
747e8aafc91SKris Kennaway 				    filename, linenum);
748a82e551fSDag-Erling Smørgrav 			options->allow_users[options->num_allow_users++] =
749a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
750511b41d2SMark Murray 		}
751511b41d2SMark Murray 		break;
752511b41d2SMark Murray 
753511b41d2SMark Murray 	case sDenyUsers:
754c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
7552803b77eSBrian Feldman 			if (options->num_deny_users >= MAX_DENY_USERS)
756af12a3e7SDag-Erling Smørgrav 				fatal( "%s line %d: too many deny users.",
757e8aafc91SKris Kennaway 				    filename, linenum);
758a82e551fSDag-Erling Smørgrav 			options->deny_users[options->num_deny_users++] =
759a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
760511b41d2SMark Murray 		}
761511b41d2SMark Murray 		break;
762511b41d2SMark Murray 
763511b41d2SMark Murray 	case sAllowGroups:
764c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
76542f71286SMark Murray 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
766af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow groups.",
767e8aafc91SKris Kennaway 				    filename, linenum);
768a82e551fSDag-Erling Smørgrav 			options->allow_groups[options->num_allow_groups++] =
769a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
770511b41d2SMark Murray 		}
771511b41d2SMark Murray 		break;
772511b41d2SMark Murray 
773511b41d2SMark Murray 	case sDenyGroups:
774c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
77542f71286SMark Murray 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
776af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many deny groups.",
777e8aafc91SKris Kennaway 				    filename, linenum);
778c2d3a559SKris Kennaway 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
779511b41d2SMark Murray 		}
780511b41d2SMark Murray 		break;
781511b41d2SMark Murray 
782e8aafc91SKris Kennaway 	case sCiphers:
783c2d3a559SKris Kennaway 		arg = strdelim(&cp);
784c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
785c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
786c2d3a559SKris Kennaway 		if (!ciphers_valid(arg))
787e8aafc91SKris Kennaway 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
788c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
789e8aafc91SKris Kennaway 		if (options->ciphers == NULL)
790c2d3a559SKris Kennaway 			options->ciphers = xstrdup(arg);
791e8aafc91SKris Kennaway 		break;
792e8aafc91SKris Kennaway 
793ca3176e7SBrian Feldman 	case sMacs:
794ca3176e7SBrian Feldman 		arg = strdelim(&cp);
795ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
796ca3176e7SBrian Feldman 			fatal("%s line %d: Missing argument.", filename, linenum);
797ca3176e7SBrian Feldman 		if (!mac_valid(arg))
798ca3176e7SBrian Feldman 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
799ca3176e7SBrian Feldman 			    filename, linenum, arg ? arg : "<NONE>");
800ca3176e7SBrian Feldman 		if (options->macs == NULL)
801ca3176e7SBrian Feldman 			options->macs = xstrdup(arg);
802ca3176e7SBrian Feldman 		break;
803ca3176e7SBrian Feldman 
804e8aafc91SKris Kennaway 	case sProtocol:
805e8aafc91SKris Kennaway 		intptr = &options->protocol;
806c2d3a559SKris Kennaway 		arg = strdelim(&cp);
807c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
808c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
809c2d3a559SKris Kennaway 		value = proto_spec(arg);
810e8aafc91SKris Kennaway 		if (value == SSH_PROTO_UNKNOWN)
811e8aafc91SKris Kennaway 			fatal("%s line %d: Bad protocol spec '%s'.",
812c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
813e8aafc91SKris Kennaway 		if (*intptr == SSH_PROTO_UNKNOWN)
814e8aafc91SKris Kennaway 			*intptr = value;
815e8aafc91SKris Kennaway 		break;
816e8aafc91SKris Kennaway 
817c2d3a559SKris Kennaway 	case sSubsystem:
818c2d3a559SKris Kennaway 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
819c2d3a559SKris Kennaway 			fatal("%s line %d: too many subsystems defined.",
820c2d3a559SKris Kennaway 			    filename, linenum);
821c2d3a559SKris Kennaway 		}
822c2d3a559SKris Kennaway 		arg = strdelim(&cp);
823c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
824c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem name.",
825c2d3a559SKris Kennaway 			    filename, linenum);
826c2d3a559SKris Kennaway 		for (i = 0; i < options->num_subsystems; i++)
827c2d3a559SKris Kennaway 			if (strcmp(arg, options->subsystem_name[i]) == 0)
828c2d3a559SKris Kennaway 				fatal("%s line %d: Subsystem '%s' already defined.",
829c2d3a559SKris Kennaway 				    filename, linenum, arg);
830c2d3a559SKris Kennaway 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
831c2d3a559SKris Kennaway 		arg = strdelim(&cp);
832c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
833c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem command.",
834c2d3a559SKris Kennaway 			    filename, linenum);
835c2d3a559SKris Kennaway 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
836c2d3a559SKris Kennaway 		options->num_subsystems++;
837c2d3a559SKris Kennaway 		break;
838c2d3a559SKris Kennaway 
839c2d3a559SKris Kennaway 	case sMaxStartups:
840c2d3a559SKris Kennaway 		arg = strdelim(&cp);
841c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
842c2d3a559SKris Kennaway 			fatal("%s line %d: Missing MaxStartups spec.",
843c2d3a559SKris Kennaway 			    filename, linenum);
844af12a3e7SDag-Erling Smørgrav 		if ((n = sscanf(arg, "%d:%d:%d",
845c2d3a559SKris Kennaway 		    &options->max_startups_begin,
846c2d3a559SKris Kennaway 		    &options->max_startups_rate,
847af12a3e7SDag-Erling Smørgrav 		    &options->max_startups)) == 3) {
848c2d3a559SKris Kennaway 			if (options->max_startups_begin >
849c2d3a559SKris Kennaway 			    options->max_startups ||
850c2d3a559SKris Kennaway 			    options->max_startups_rate > 100 ||
851c2d3a559SKris Kennaway 			    options->max_startups_rate < 1)
852c2d3a559SKris Kennaway 				fatal("%s line %d: Illegal MaxStartups spec.",
853c2d3a559SKris Kennaway 				    filename, linenum);
854af12a3e7SDag-Erling Smørgrav 		} else if (n != 1)
855af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: Illegal MaxStartups spec.",
856af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
857af12a3e7SDag-Erling Smørgrav 		else
858af12a3e7SDag-Erling Smørgrav 			options->max_startups = options->max_startups_begin;
859933ca70fSBrian Feldman 		break;
860933ca70fSBrian Feldman 
861ca3176e7SBrian Feldman 	case sBanner:
862ca3176e7SBrian Feldman 		charptr = &options->banner;
863ca3176e7SBrian Feldman 		goto parse_filename;
864af12a3e7SDag-Erling Smørgrav 	/*
865af12a3e7SDag-Erling Smørgrav 	 * These options can contain %X options expanded at
866af12a3e7SDag-Erling Smørgrav 	 * connect time, so that you can specify paths like:
867af12a3e7SDag-Erling Smørgrav 	 *
868af12a3e7SDag-Erling Smørgrav 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
869af12a3e7SDag-Erling Smørgrav 	 */
870af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile:
871af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile2:
872af12a3e7SDag-Erling Smørgrav 		charptr = (opcode == sAuthorizedKeysFile ) ?
873af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file :
874af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file2;
875af12a3e7SDag-Erling Smørgrav 		goto parse_filename;
876af12a3e7SDag-Erling Smørgrav 
877ca3176e7SBrian Feldman 	case sClientAliveInterval:
878ca3176e7SBrian Feldman 		intptr = &options->client_alive_interval;
879af12a3e7SDag-Erling Smørgrav 		goto parse_time;
880af12a3e7SDag-Erling Smørgrav 
881ca3176e7SBrian Feldman 	case sClientAliveCountMax:
882ca3176e7SBrian Feldman 		intptr = &options->client_alive_count_max;
883ca3176e7SBrian Feldman 		goto parse_int;
884af12a3e7SDag-Erling Smørgrav 
885db58a8e4SDag-Erling Smørgrav 	case sVersionAddendum:
886db58a8e4SDag-Erling Smørgrav                 ssh_version_set_addendum(strtok(cp, "\n"));
887db58a8e4SDag-Erling Smørgrav                 do {
888db58a8e4SDag-Erling Smørgrav                         arg = strdelim(&cp);
889db58a8e4SDag-Erling Smørgrav                 } while (arg != NULL && *arg != '\0');
890db58a8e4SDag-Erling Smørgrav 		break;
891db58a8e4SDag-Erling Smørgrav 
892af12a3e7SDag-Erling Smørgrav 	case sDeprecated:
893cf2b5f3bSDag-Erling Smørgrav 		logit("%s line %d: Deprecated option %s",
894cf2b5f3bSDag-Erling Smørgrav 		    filename, linenum, arg);
895cf2b5f3bSDag-Erling Smørgrav 		while (arg)
896cf2b5f3bSDag-Erling Smørgrav 		    arg = strdelim(&cp);
897cf2b5f3bSDag-Erling Smørgrav 		break;
898cf2b5f3bSDag-Erling Smørgrav 
899cf2b5f3bSDag-Erling Smørgrav 	case sUnsupported:
900cf2b5f3bSDag-Erling Smørgrav 		logit("%s line %d: Unsupported option %s",
901af12a3e7SDag-Erling Smørgrav 		    filename, linenum, arg);
902af12a3e7SDag-Erling Smørgrav 		while (arg)
903af12a3e7SDag-Erling Smørgrav 		    arg = strdelim(&cp);
904af12a3e7SDag-Erling Smørgrav 		break;
905af12a3e7SDag-Erling Smørgrav 
90642f71286SMark Murray 	default:
907af12a3e7SDag-Erling Smørgrav 		fatal("%s line %d: Missing handler for opcode %s (%d)",
908c2d3a559SKris Kennaway 		    filename, linenum, arg, opcode);
909511b41d2SMark Murray 	}
910ca3176e7SBrian Feldman 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
911ca3176e7SBrian Feldman 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
912c2d3a559SKris Kennaway 		    filename, linenum, arg);
913af12a3e7SDag-Erling Smørgrav 	return 0;
914af12a3e7SDag-Erling Smørgrav }
915af12a3e7SDag-Erling Smørgrav 
916af12a3e7SDag-Erling Smørgrav /* Reads the server configuration file. */
917af12a3e7SDag-Erling Smørgrav 
918af12a3e7SDag-Erling Smørgrav void
919af12a3e7SDag-Erling Smørgrav read_server_config(ServerOptions *options, const char *filename)
920af12a3e7SDag-Erling Smørgrav {
921a82e551fSDag-Erling Smørgrav 	int linenum, bad_options = 0;
922af12a3e7SDag-Erling Smørgrav 	char line[1024];
923a82e551fSDag-Erling Smørgrav 	FILE *f;
924af12a3e7SDag-Erling Smørgrav 
925e73e9afaSDag-Erling Smørgrav 	debug2("read_server_config: filename %s", filename);
926af12a3e7SDag-Erling Smørgrav 	f = fopen(filename, "r");
927af12a3e7SDag-Erling Smørgrav 	if (!f) {
928af12a3e7SDag-Erling Smørgrav 		perror(filename);
929af12a3e7SDag-Erling Smørgrav 		exit(1);
930af12a3e7SDag-Erling Smørgrav 	}
931af12a3e7SDag-Erling Smørgrav 	linenum = 0;
932af12a3e7SDag-Erling Smørgrav 	while (fgets(line, sizeof(line), f)) {
933af12a3e7SDag-Erling Smørgrav 		/* Update line number counter. */
934af12a3e7SDag-Erling Smørgrav 		linenum++;
935af12a3e7SDag-Erling Smørgrav 		if (process_server_config_line(options, line, filename, linenum) != 0)
936af12a3e7SDag-Erling Smørgrav 			bad_options++;
937511b41d2SMark Murray 	}
938511b41d2SMark Murray 	fclose(f);
939ca3176e7SBrian Feldman 	if (bad_options > 0)
940af12a3e7SDag-Erling Smørgrav 		fatal("%s: terminating, %d bad configuration options",
941511b41d2SMark Murray 		    filename, bad_options);
942511b41d2SMark Murray }
943