xref: /freebsd/crypto/openssh/servconf.c (revision a82e551f0fd24a72fde2fc9145eef2c270cda9c0)
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"
13a82e551fSDag-Erling Smørgrav RCSID("$OpenBSD: servconf.c,v 1.112 2002/06/23 09:46:51 deraadt Exp $");
14975616f0SDag-Erling Smørgrav RCSID("$FreeBSD$");
15511b41d2SMark Murray 
161d9e2b0aSDag-Erling Smørgrav #if defined(KRB4)
17ca3176e7SBrian Feldman #include <krb.h>
18ca3176e7SBrian Feldman #endif
191d9e2b0aSDag-Erling Smørgrav #if defined(KRB5)
20989dd127SDag-Erling Smørgrav #ifdef HEIMDAL
21975616f0SDag-Erling Smørgrav #include <krb5.h>
22989dd127SDag-Erling Smørgrav #else
23989dd127SDag-Erling Smørgrav /* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V
24989dd127SDag-Erling Smørgrav  * keytab */
25989dd127SDag-Erling Smørgrav #define KEYFILE "/etc/krb5.keytab"
26989dd127SDag-Erling Smørgrav #endif
271d9e2b0aSDag-Erling Smørgrav #endif
28ca3176e7SBrian Feldman #ifdef AFS
29ca3176e7SBrian Feldman #include <kafs.h>
30ca3176e7SBrian Feldman #endif
31ca3176e7SBrian Feldman 
32511b41d2SMark Murray #include "ssh.h"
33ca3176e7SBrian Feldman #include "log.h"
34511b41d2SMark Murray #include "servconf.h"
35511b41d2SMark Murray #include "xmalloc.h"
36e8aafc91SKris Kennaway #include "compat.h"
37ca3176e7SBrian Feldman #include "pathnames.h"
38ca3176e7SBrian Feldman #include "tildexpand.h"
39ca3176e7SBrian Feldman #include "misc.h"
40ca3176e7SBrian Feldman #include "cipher.h"
41ca3176e7SBrian Feldman #include "kex.h"
42ca3176e7SBrian Feldman #include "mac.h"
43511b41d2SMark Murray 
44af12a3e7SDag-Erling Smørgrav static void add_listen_addr(ServerOptions *, char *, u_short);
45af12a3e7SDag-Erling Smørgrav static void add_one_listen_addr(ServerOptions *, char *, u_short);
46ca3176e7SBrian Feldman 
47ca3176e7SBrian Feldman /* AF_UNSPEC or AF_INET or AF_INET6 */
48ca3176e7SBrian Feldman extern int IPv4or6;
4980628bacSDag-Erling Smørgrav /* Use of privilege separation or not */
5080628bacSDag-Erling Smørgrav extern int use_privsep;
51511b41d2SMark Murray 
52511b41d2SMark Murray /* Initializes the server options to their default values. */
53511b41d2SMark Murray 
54511b41d2SMark Murray void
55511b41d2SMark Murray initialize_server_options(ServerOptions *options)
56511b41d2SMark Murray {
57511b41d2SMark Murray 	memset(options, 0, sizeof(*options));
58989dd127SDag-Erling Smørgrav 
59989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
60989dd127SDag-Erling Smørgrav 	options->pam_authentication_via_kbd_int = -1;
61989dd127SDag-Erling Smørgrav 
62989dd127SDag-Erling Smørgrav 	/* Standard Options */
63511b41d2SMark Murray 	options->num_ports = 0;
64511b41d2SMark Murray 	options->ports_from_cmdline = 0;
65511b41d2SMark Murray 	options->listen_addrs = NULL;
66ca3176e7SBrian Feldman 	options->num_host_key_files = 0;
67e8aafc91SKris Kennaway 	options->pid_file = NULL;
68511b41d2SMark Murray 	options->server_key_bits = -1;
69511b41d2SMark Murray 	options->login_grace_time = -1;
70511b41d2SMark Murray 	options->key_regeneration_time = -1;
71ca3176e7SBrian Feldman 	options->permit_root_login = PERMIT_NOT_SET;
72511b41d2SMark Murray 	options->ignore_rhosts = -1;
73511b41d2SMark Murray 	options->ignore_user_known_hosts = -1;
74511b41d2SMark Murray 	options->print_motd = -1;
75ca3176e7SBrian Feldman 	options->print_lastlog = -1;
76511b41d2SMark Murray 	options->x11_forwarding = -1;
77511b41d2SMark Murray 	options->x11_display_offset = -1;
78af12a3e7SDag-Erling Smørgrav 	options->x11_use_localhost = -1;
79c2d3a559SKris Kennaway 	options->xauth_location = NULL;
80511b41d2SMark Murray 	options->strict_modes = -1;
81511b41d2SMark Murray 	options->keepalives = -1;
82af12a3e7SDag-Erling Smørgrav 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
83af12a3e7SDag-Erling Smørgrav 	options->log_level = SYSLOG_LEVEL_NOT_SET;
84511b41d2SMark Murray 	options->rhosts_authentication = -1;
85511b41d2SMark Murray 	options->rhosts_rsa_authentication = -1;
86ca3176e7SBrian Feldman 	options->hostbased_authentication = -1;
87ca3176e7SBrian Feldman 	options->hostbased_uses_name_from_packet_only = -1;
88511b41d2SMark Murray 	options->rsa_authentication = -1;
89ca3176e7SBrian Feldman 	options->pubkey_authentication = -1;
90cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
91cb96ab36SAssar Westerlund 	options->kerberos_authentication = -1;
92af12a3e7SDag-Erling Smørgrav 	options->kerberos_or_local_passwd = -1;
93af12a3e7SDag-Erling Smørgrav 	options->kerberos_ticket_cleanup = -1;
94cb96ab36SAssar Westerlund #endif
95af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
96af12a3e7SDag-Erling Smørgrav 	options->kerberos_tgt_passing = -1;
97511b41d2SMark Murray #endif
98511b41d2SMark Murray #ifdef AFS
99511b41d2SMark Murray 	options->afs_token_passing = -1;
100511b41d2SMark Murray #endif
101511b41d2SMark Murray 	options->password_authentication = -1;
10209958426SBrian Feldman 	options->kbd_interactive_authentication = -1;
103af12a3e7SDag-Erling Smørgrav 	options->challenge_response_authentication = -1;
104511b41d2SMark Murray 	options->permit_empty_passwd = -1;
105511b41d2SMark Murray 	options->use_login = -1;
10680628bacSDag-Erling Smørgrav 	options->compression = -1;
10709958426SBrian Feldman 	options->allow_tcp_forwarding = -1;
108511b41d2SMark Murray 	options->num_allow_users = 0;
109511b41d2SMark Murray 	options->num_deny_users = 0;
110511b41d2SMark Murray 	options->num_allow_groups = 0;
111511b41d2SMark Murray 	options->num_deny_groups = 0;
112e8aafc91SKris Kennaway 	options->ciphers = NULL;
113ca3176e7SBrian Feldman 	options->macs = NULL;
114e8aafc91SKris Kennaway 	options->protocol = SSH_PROTO_UNKNOWN;
115e8aafc91SKris Kennaway 	options->gateway_ports = -1;
116c2d3a559SKris Kennaway 	options->num_subsystems = 0;
117c2d3a559SKris Kennaway 	options->max_startups_begin = -1;
118c2d3a559SKris Kennaway 	options->max_startups_rate = -1;
119c2d3a559SKris Kennaway 	options->max_startups = -1;
120ca3176e7SBrian Feldman 	options->banner = NULL;
121af12a3e7SDag-Erling Smørgrav 	options->verify_reverse_mapping = -1;
122ca3176e7SBrian Feldman 	options->client_alive_interval = -1;
123ca3176e7SBrian Feldman 	options->client_alive_count_max = -1;
124af12a3e7SDag-Erling Smørgrav 	options->authorized_keys_file = NULL;
125af12a3e7SDag-Erling Smørgrav 	options->authorized_keys_file2 = NULL;
12680628bacSDag-Erling Smørgrav 
12780628bacSDag-Erling Smørgrav 	/* Needs to be accessable in many places */
12880628bacSDag-Erling Smørgrav 	use_privsep = -1;
129511b41d2SMark Murray }
130511b41d2SMark Murray 
131511b41d2SMark Murray void
132511b41d2SMark Murray fill_default_server_options(ServerOptions *options)
133511b41d2SMark Murray {
134989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
135989dd127SDag-Erling Smørgrav 	if (options->pam_authentication_via_kbd_int == -1)
136989dd127SDag-Erling Smørgrav 		options->pam_authentication_via_kbd_int = 0;
137989dd127SDag-Erling Smørgrav 
138989dd127SDag-Erling Smørgrav 	/* Standard Options */
139ca3176e7SBrian Feldman 	if (options->protocol == SSH_PROTO_UNKNOWN)
140ca3176e7SBrian Feldman 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
141ca3176e7SBrian Feldman 	if (options->num_host_key_files == 0) {
142ca3176e7SBrian Feldman 		/* fill default hostkeys for protocols */
143ca3176e7SBrian Feldman 		if (options->protocol & SSH_PROTO_1)
144af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
145af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_KEY_FILE;
146af12a3e7SDag-Erling Smørgrav 		if (options->protocol & SSH_PROTO_2) {
147af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
148af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_DSA_KEY_FILE;
149af12a3e7SDag-Erling Smørgrav 		}
150ca3176e7SBrian Feldman 	}
151511b41d2SMark Murray 	if (options->num_ports == 0)
152511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
153511b41d2SMark Murray 	if (options->listen_addrs == NULL)
154ca3176e7SBrian Feldman 		add_listen_addr(options, NULL, 0);
155e8aafc91SKris Kennaway 	if (options->pid_file == NULL)
156ca3176e7SBrian Feldman 		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
157511b41d2SMark Murray 	if (options->server_key_bits == -1)
158511b41d2SMark Murray 		options->server_key_bits = 768;
159511b41d2SMark Murray 	if (options->login_grace_time == -1)
160975616f0SDag-Erling Smørgrav 		options->login_grace_time = 120;
161511b41d2SMark Murray 	if (options->key_regeneration_time == -1)
162511b41d2SMark Murray 		options->key_regeneration_time = 3600;
163ca3176e7SBrian Feldman 	if (options->permit_root_login == PERMIT_NOT_SET)
164975616f0SDag-Erling Smørgrav 		options->permit_root_login = PERMIT_NO;
165511b41d2SMark Murray 	if (options->ignore_rhosts == -1)
166fe5fd017SMark Murray 		options->ignore_rhosts = 1;
167511b41d2SMark Murray 	if (options->ignore_user_known_hosts == -1)
168511b41d2SMark Murray 		options->ignore_user_known_hosts = 0;
169511b41d2SMark Murray 	if (options->print_motd == -1)
170511b41d2SMark Murray 		options->print_motd = 1;
171ca3176e7SBrian Feldman 	if (options->print_lastlog == -1)
172ca3176e7SBrian Feldman 		options->print_lastlog = 1;
173511b41d2SMark Murray 	if (options->x11_forwarding == -1)
174975616f0SDag-Erling Smørgrav 		options->x11_forwarding = 1;
175511b41d2SMark Murray 	if (options->x11_display_offset == -1)
176fe5fd017SMark Murray 		options->x11_display_offset = 10;
177af12a3e7SDag-Erling Smørgrav 	if (options->x11_use_localhost == -1)
178af12a3e7SDag-Erling Smørgrav 		options->x11_use_localhost = 1;
179c2d3a559SKris Kennaway 	if (options->xauth_location == NULL)
180af12a3e7SDag-Erling Smørgrav 		options->xauth_location = _PATH_XAUTH;
181511b41d2SMark Murray 	if (options->strict_modes == -1)
182511b41d2SMark Murray 		options->strict_modes = 1;
183511b41d2SMark Murray 	if (options->keepalives == -1)
184511b41d2SMark Murray 		options->keepalives = 1;
185af12a3e7SDag-Erling Smørgrav 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
186511b41d2SMark Murray 		options->log_facility = SYSLOG_FACILITY_AUTH;
187af12a3e7SDag-Erling Smørgrav 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
188511b41d2SMark Murray 		options->log_level = SYSLOG_LEVEL_INFO;
189511b41d2SMark Murray 	if (options->rhosts_authentication == -1)
190511b41d2SMark Murray 		options->rhosts_authentication = 0;
191511b41d2SMark Murray 	if (options->rhosts_rsa_authentication == -1)
192fe5fd017SMark Murray 		options->rhosts_rsa_authentication = 0;
193ca3176e7SBrian Feldman 	if (options->hostbased_authentication == -1)
194ca3176e7SBrian Feldman 		options->hostbased_authentication = 0;
195ca3176e7SBrian Feldman 	if (options->hostbased_uses_name_from_packet_only == -1)
196ca3176e7SBrian Feldman 		options->hostbased_uses_name_from_packet_only = 0;
197511b41d2SMark Murray 	if (options->rsa_authentication == -1)
198511b41d2SMark Murray 		options->rsa_authentication = 1;
199ca3176e7SBrian Feldman 	if (options->pubkey_authentication == -1)
200ca3176e7SBrian Feldman 		options->pubkey_authentication = 1;
201975616f0SDag-Erling Smørgrav #if defined(KRB4) && defined(KRB5)
202989dd127SDag-Erling Smørgrav         if (options->kerberos_authentication == -1)
203975616f0SDag-Erling Smørgrav                 options->kerberos_authentication =
204975616f0SDag-Erling Smørgrav                     (access(KEYFILE, R_OK) == 0 ||
205975616f0SDag-Erling Smørgrav 		    access(krb5_defkeyname, R_OK) == 0);
206975616f0SDag-Erling Smørgrav #elif defined(KRB4)
207975616f0SDag-Erling Smørgrav         if (options->kerberos_authentication == -1)
208975616f0SDag-Erling Smørgrav                 options->kerberos_authentication =
209975616f0SDag-Erling Smørgrav 		    (access(KEYFILE, R_OK) == 0);
210975616f0SDag-Erling Smørgrav #elif defined(KRB5)
211975616f0SDag-Erling Smørgrav 	if (options->kerberos_authentication == -1)
212975616f0SDag-Erling Smørgrav                 options->kerberos_authentication =
213975616f0SDag-Erling Smørgrav                     (access(krb5_defkeyname, R_OK) == 0);
214975616f0SDag-Erling Smørgrav #endif
215975616f0SDag-Erling Smørgrav #if defined(KRB4) || defined(KRB5)
216af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_or_local_passwd == -1)
217af12a3e7SDag-Erling Smørgrav 		options->kerberos_or_local_passwd = 1;
218af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_ticket_cleanup == -1)
219af12a3e7SDag-Erling Smørgrav 		options->kerberos_ticket_cleanup = 1;
220cb96ab36SAssar Westerlund #endif
221af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
222af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_tgt_passing == -1)
223af12a3e7SDag-Erling Smørgrav 		options->kerberos_tgt_passing = 0;
224af12a3e7SDag-Erling Smørgrav #endif
225511b41d2SMark Murray #ifdef AFS
226511b41d2SMark Murray 	if (options->afs_token_passing == -1)
22780628bacSDag-Erling Smørgrav 		options->afs_token_passing = 0;
228af12a3e7SDag-Erling Smørgrav #endif
229511b41d2SMark Murray 	if (options->password_authentication == -1)
230511b41d2SMark Murray 		options->password_authentication = 1;
23109958426SBrian Feldman 	if (options->kbd_interactive_authentication == -1)
23209958426SBrian Feldman 		options->kbd_interactive_authentication = 0;
233af12a3e7SDag-Erling Smørgrav 	if (options->challenge_response_authentication == -1)
23480241871SDag-Erling Smørgrav 		options->challenge_response_authentication = 1;
235511b41d2SMark Murray 	if (options->permit_empty_passwd == -1)
236fe5fd017SMark Murray 		options->permit_empty_passwd = 0;
237511b41d2SMark Murray 	if (options->use_login == -1)
238511b41d2SMark Murray 		options->use_login = 0;
23980628bacSDag-Erling Smørgrav 	if (options->compression == -1)
24080628bacSDag-Erling Smørgrav 		options->compression = 1;
24109958426SBrian Feldman 	if (options->allow_tcp_forwarding == -1)
24209958426SBrian Feldman 		options->allow_tcp_forwarding = 1;
243e8aafc91SKris Kennaway 	if (options->gateway_ports == -1)
244e8aafc91SKris Kennaway 		options->gateway_ports = 0;
245c2d3a559SKris Kennaway 	if (options->max_startups == -1)
246c2d3a559SKris Kennaway 		options->max_startups = 10;
247c2d3a559SKris Kennaway 	if (options->max_startups_rate == -1)
248c2d3a559SKris Kennaway 		options->max_startups_rate = 100;		/* 100% */
249c2d3a559SKris Kennaway 	if (options->max_startups_begin == -1)
250c2d3a559SKris Kennaway 		options->max_startups_begin = options->max_startups;
251af12a3e7SDag-Erling Smørgrav 	if (options->verify_reverse_mapping == -1)
252af12a3e7SDag-Erling Smørgrav 		options->verify_reverse_mapping = 0;
253ca3176e7SBrian Feldman 	if (options->client_alive_interval == -1)
254ca3176e7SBrian Feldman 		options->client_alive_interval = 0;
255ca3176e7SBrian Feldman 	if (options->client_alive_count_max == -1)
256ca3176e7SBrian Feldman 		options->client_alive_count_max = 3;
257af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file2 == NULL) {
258af12a3e7SDag-Erling Smørgrav 		/* authorized_keys_file2 falls back to authorized_keys_file */
259af12a3e7SDag-Erling Smørgrav 		if (options->authorized_keys_file != NULL)
260af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = options->authorized_keys_file;
261af12a3e7SDag-Erling Smørgrav 		else
262af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
263af12a3e7SDag-Erling Smørgrav 	}
264af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file == NULL)
265af12a3e7SDag-Erling Smørgrav 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
26680628bacSDag-Erling Smørgrav 
267989dd127SDag-Erling Smørgrav 	/* Turn privilege separation on by default */
26880628bacSDag-Erling Smørgrav 	if (use_privsep == -1)
269989dd127SDag-Erling Smørgrav 		use_privsep = 1;
270989dd127SDag-Erling Smørgrav 
271a82e551fSDag-Erling Smørgrav #if !defined(HAVE_MMAP_ANON_SHARED)
272989dd127SDag-Erling Smørgrav 	if (use_privsep && options->compression == 1) {
273989dd127SDag-Erling Smørgrav 		error("This platform does not support both privilege "
274989dd127SDag-Erling Smørgrav 		    "separation and compression");
275989dd127SDag-Erling Smørgrav 		error("Compression disabled");
276989dd127SDag-Erling Smørgrav 		options->compression = 0;
277989dd127SDag-Erling Smørgrav 	}
278989dd127SDag-Erling Smørgrav #endif
279989dd127SDag-Erling Smørgrav 
280511b41d2SMark Murray }
281511b41d2SMark Murray 
282511b41d2SMark Murray /* Keyword tokens. */
283511b41d2SMark Murray typedef enum {
284511b41d2SMark Murray 	sBadOption,		/* == unknown option */
285989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
286989dd127SDag-Erling Smørgrav 	sPAMAuthenticationViaKbdInt,
287989dd127SDag-Erling Smørgrav 	/* Standard Options */
288511b41d2SMark Murray 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
289511b41d2SMark Murray 	sPermitRootLogin, sLogFacility, sLogLevel,
290511b41d2SMark Murray 	sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
291cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
292af12a3e7SDag-Erling Smørgrav 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
293cb96ab36SAssar Westerlund #endif
294af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
295af12a3e7SDag-Erling Smørgrav 	sKerberosTgtPassing,
296511b41d2SMark Murray #endif
297511b41d2SMark Murray #ifdef AFS
298af12a3e7SDag-Erling Smørgrav 	sAFSTokenPassing,
299511b41d2SMark Murray #endif
300ca3176e7SBrian Feldman 	sChallengeResponseAuthentication,
30109958426SBrian Feldman 	sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
302ca3176e7SBrian Feldman 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
303af12a3e7SDag-Erling Smørgrav 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
304af12a3e7SDag-Erling Smørgrav 	sStrictModes, sEmptyPasswd, sKeepAlives,
30580628bacSDag-Erling Smørgrav 	sUseLogin, sAllowTcpForwarding, sCompression,
30609958426SBrian Feldman 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
307ca3176e7SBrian Feldman 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
308ca3176e7SBrian Feldman 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
309af12a3e7SDag-Erling Smørgrav 	sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
310ca3176e7SBrian Feldman 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
311af12a3e7SDag-Erling Smørgrav 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
31280628bacSDag-Erling Smørgrav 	sUsePrivilegeSeparation,
313db58a8e4SDag-Erling Smørgrav 	sVersionAddendum,
314af12a3e7SDag-Erling Smørgrav 	sDeprecated
315511b41d2SMark Murray } ServerOpCodes;
316511b41d2SMark Murray 
317511b41d2SMark Murray /* Textual representation of the tokens. */
318511b41d2SMark Murray static struct {
319511b41d2SMark Murray 	const char *name;
320511b41d2SMark Murray 	ServerOpCodes opcode;
321511b41d2SMark Murray } keywords[] = {
322989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
323975616f0SDag-Erling Smørgrav #if 0
324989dd127SDag-Erling Smørgrav 	{ "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt },
325975616f0SDag-Erling Smørgrav #endif
326989dd127SDag-Erling Smørgrav 	/* Standard Options */
327511b41d2SMark Murray 	{ "port", sPort },
328511b41d2SMark Murray 	{ "hostkey", sHostKeyFile },
329ca3176e7SBrian Feldman 	{ "hostdsakey", sHostKeyFile },					/* alias */
330e8aafc91SKris Kennaway 	{ "pidfile", sPidFile },
331511b41d2SMark Murray 	{ "serverkeybits", sServerKeyBits },
332511b41d2SMark Murray 	{ "logingracetime", sLoginGraceTime },
333511b41d2SMark Murray 	{ "keyregenerationinterval", sKeyRegenerationTime },
334511b41d2SMark Murray 	{ "permitrootlogin", sPermitRootLogin },
335511b41d2SMark Murray 	{ "syslogfacility", sLogFacility },
336511b41d2SMark Murray 	{ "loglevel", sLogLevel },
337511b41d2SMark Murray 	{ "rhostsauthentication", sRhostsAuthentication },
338511b41d2SMark Murray 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
339ca3176e7SBrian Feldman 	{ "hostbasedauthentication", sHostbasedAuthentication },
340ca3176e7SBrian Feldman 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
341af12a3e7SDag-Erling Smørgrav 	{ "rsaauthentication", sRSAAuthentication },
342ca3176e7SBrian Feldman 	{ "pubkeyauthentication", sPubkeyAuthentication },
343ca3176e7SBrian Feldman 	{ "dsaauthentication", sPubkeyAuthentication },			/* alias */
344cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
345cb96ab36SAssar Westerlund 	{ "kerberosauthentication", sKerberosAuthentication },
346af12a3e7SDag-Erling Smørgrav 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
347af12a3e7SDag-Erling Smørgrav 	{ "kerberosticketcleanup", sKerberosTicketCleanup },
348cb96ab36SAssar Westerlund #endif
349af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
350af12a3e7SDag-Erling Smørgrav 	{ "kerberostgtpassing", sKerberosTgtPassing },
351511b41d2SMark Murray #endif
352511b41d2SMark Murray #ifdef AFS
353511b41d2SMark Murray 	{ "afstokenpassing", sAFSTokenPassing },
354511b41d2SMark Murray #endif
355511b41d2SMark Murray 	{ "passwordauthentication", sPasswordAuthentication },
35609958426SBrian Feldman 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
357ca3176e7SBrian Feldman 	{ "challengeresponseauthentication", sChallengeResponseAuthentication },
358ca3176e7SBrian Feldman 	{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
359989dd127SDag-Erling Smørgrav 	{ "checkmail", sDeprecated },
360511b41d2SMark Murray 	{ "listenaddress", sListenAddress },
361511b41d2SMark Murray 	{ "printmotd", sPrintMotd },
362ca3176e7SBrian Feldman 	{ "printlastlog", sPrintLastLog },
363511b41d2SMark Murray 	{ "ignorerhosts", sIgnoreRhosts },
364511b41d2SMark Murray 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
365511b41d2SMark Murray 	{ "x11forwarding", sX11Forwarding },
366511b41d2SMark Murray 	{ "x11displayoffset", sX11DisplayOffset },
367af12a3e7SDag-Erling Smørgrav 	{ "x11uselocalhost", sX11UseLocalhost },
368c2d3a559SKris Kennaway 	{ "xauthlocation", sXAuthLocation },
369511b41d2SMark Murray 	{ "strictmodes", sStrictModes },
370511b41d2SMark Murray 	{ "permitemptypasswords", sEmptyPasswd },
371511b41d2SMark Murray 	{ "uselogin", sUseLogin },
37280628bacSDag-Erling Smørgrav 	{ "compression", sCompression },
373511b41d2SMark Murray 	{ "keepalive", sKeepAlives },
37409958426SBrian Feldman 	{ "allowtcpforwarding", sAllowTcpForwarding },
375511b41d2SMark Murray 	{ "allowusers", sAllowUsers },
376511b41d2SMark Murray 	{ "denyusers", sDenyUsers },
377511b41d2SMark Murray 	{ "allowgroups", sAllowGroups },
378511b41d2SMark Murray 	{ "denygroups", sDenyGroups },
379e8aafc91SKris Kennaway 	{ "ciphers", sCiphers },
380ca3176e7SBrian Feldman 	{ "macs", sMacs },
381e8aafc91SKris Kennaway 	{ "protocol", sProtocol },
382e8aafc91SKris Kennaway 	{ "gatewayports", sGatewayPorts },
383c2d3a559SKris Kennaway 	{ "subsystem", sSubsystem },
384c2d3a559SKris Kennaway 	{ "maxstartups", sMaxStartups },
385ca3176e7SBrian Feldman 	{ "banner", sBanner },
386af12a3e7SDag-Erling Smørgrav 	{ "verifyreversemapping", sVerifyReverseMapping },
387af12a3e7SDag-Erling Smørgrav 	{ "reversemappingcheck", sVerifyReverseMapping },
388ca3176e7SBrian Feldman 	{ "clientaliveinterval", sClientAliveInterval },
389ca3176e7SBrian Feldman 	{ "clientalivecountmax", sClientAliveCountMax },
390af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile", sAuthorizedKeysFile },
391af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
39280628bacSDag-Erling Smørgrav 	{ "useprivilegeseparation", sUsePrivilegeSeparation},
393db58a8e4SDag-Erling Smørgrav 	{ "versionaddendum", sVersionAddendum },
394af12a3e7SDag-Erling Smørgrav 	{ NULL, sBadOption }
395511b41d2SMark Murray };
396511b41d2SMark Murray 
397511b41d2SMark Murray /*
398ca3176e7SBrian Feldman  * Returns the number of the token pointed to by cp or sBadOption.
399511b41d2SMark Murray  */
400511b41d2SMark Murray 
401511b41d2SMark Murray static ServerOpCodes
402511b41d2SMark Murray parse_token(const char *cp, const char *filename,
403511b41d2SMark Murray 	    int linenum)
404511b41d2SMark Murray {
405ca3176e7SBrian Feldman 	u_int i;
406511b41d2SMark Murray 
407511b41d2SMark Murray 	for (i = 0; keywords[i].name; i++)
408511b41d2SMark Murray 		if (strcasecmp(cp, keywords[i].name) == 0)
409511b41d2SMark Murray 			return keywords[i].opcode;
410511b41d2SMark Murray 
411ca3176e7SBrian Feldman 	error("%s: line %d: Bad configuration option: %s",
412511b41d2SMark Murray 	    filename, linenum, cp);
413511b41d2SMark Murray 	return sBadOption;
414511b41d2SMark Murray }
415511b41d2SMark Murray 
416af12a3e7SDag-Erling Smørgrav static void
417ca3176e7SBrian Feldman add_listen_addr(ServerOptions *options, char *addr, u_short port)
418511b41d2SMark Murray {
419511b41d2SMark Murray 	int i;
420511b41d2SMark Murray 
421511b41d2SMark Murray 	if (options->num_ports == 0)
422511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
423ca3176e7SBrian Feldman 	if (port == 0)
424ca3176e7SBrian Feldman 		for (i = 0; i < options->num_ports; i++)
425ca3176e7SBrian Feldman 			add_one_listen_addr(options, addr, options->ports[i]);
426ca3176e7SBrian Feldman 	else
427ca3176e7SBrian Feldman 		add_one_listen_addr(options, addr, port);
428ca3176e7SBrian Feldman }
429ca3176e7SBrian Feldman 
430af12a3e7SDag-Erling Smørgrav static void
431ca3176e7SBrian Feldman add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
432ca3176e7SBrian Feldman {
433ca3176e7SBrian Feldman 	struct addrinfo hints, *ai, *aitop;
434ca3176e7SBrian Feldman 	char strport[NI_MAXSERV];
435ca3176e7SBrian Feldman 	int gaierr;
436ca3176e7SBrian Feldman 
437511b41d2SMark Murray 	memset(&hints, 0, sizeof(hints));
438511b41d2SMark Murray 	hints.ai_family = IPv4or6;
439511b41d2SMark Murray 	hints.ai_socktype = SOCK_STREAM;
440511b41d2SMark Murray 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
441a82e551fSDag-Erling Smørgrav 	snprintf(strport, sizeof strport, "%u", port);
442511b41d2SMark Murray 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
443ca3176e7SBrian Feldman 		fatal("bad addr or host: %s (%s)",
444511b41d2SMark Murray 		    addr ? addr : "<NULL>",
445511b41d2SMark Murray 		    gai_strerror(gaierr));
446511b41d2SMark Murray 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
447511b41d2SMark Murray 		;
448511b41d2SMark Murray 	ai->ai_next = options->listen_addrs;
449511b41d2SMark Murray 	options->listen_addrs = aitop;
450511b41d2SMark Murray }
451511b41d2SMark Murray 
452af12a3e7SDag-Erling Smørgrav int
453af12a3e7SDag-Erling Smørgrav process_server_config_line(ServerOptions *options, char *line,
454af12a3e7SDag-Erling Smørgrav     const char *filename, int linenum)
455511b41d2SMark Murray {
456ca3176e7SBrian Feldman 	char *cp, **charptr, *arg, *p;
457a82e551fSDag-Erling Smørgrav 	int *intptr, value, i, n;
458511b41d2SMark Murray 	ServerOpCodes opcode;
459511b41d2SMark Murray 
460c2d3a559SKris Kennaway 	cp = line;
461c2d3a559SKris Kennaway 	arg = strdelim(&cp);
462c2d3a559SKris Kennaway 	/* Ignore leading whitespace */
463c2d3a559SKris Kennaway 	if (*arg == '\0')
464c2d3a559SKris Kennaway 		arg = strdelim(&cp);
465ca3176e7SBrian Feldman 	if (!arg || !*arg || *arg == '#')
466af12a3e7SDag-Erling Smørgrav 		return 0;
467ca3176e7SBrian Feldman 	intptr = NULL;
468ca3176e7SBrian Feldman 	charptr = NULL;
469c2d3a559SKris Kennaway 	opcode = parse_token(arg, filename, linenum);
470511b41d2SMark Murray 	switch (opcode) {
471989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
472989dd127SDag-Erling Smørgrav 	case sPAMAuthenticationViaKbdInt:
473989dd127SDag-Erling Smørgrav 		intptr = &options->pam_authentication_via_kbd_int;
474989dd127SDag-Erling Smørgrav 		goto parse_flag;
475989dd127SDag-Erling Smørgrav 
476989dd127SDag-Erling Smørgrav 	/* Standard Options */
477511b41d2SMark Murray 	case sBadOption:
478af12a3e7SDag-Erling Smørgrav 		return -1;
479511b41d2SMark Murray 	case sPort:
480511b41d2SMark Murray 		/* ignore ports from configfile if cmdline specifies ports */
481511b41d2SMark Murray 		if (options->ports_from_cmdline)
482af12a3e7SDag-Erling Smørgrav 			return 0;
483511b41d2SMark Murray 		if (options->listen_addrs != NULL)
484511b41d2SMark Murray 			fatal("%s line %d: ports must be specified before "
485af12a3e7SDag-Erling Smørgrav 			    "ListenAddress.", filename, linenum);
486511b41d2SMark Murray 		if (options->num_ports >= MAX_PORTS)
487ca3176e7SBrian Feldman 			fatal("%s line %d: too many ports.",
488511b41d2SMark Murray 			    filename, linenum);
489c2d3a559SKris Kennaway 		arg = strdelim(&cp);
490c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
491ca3176e7SBrian Feldman 			fatal("%s line %d: missing port number.",
492511b41d2SMark Murray 			    filename, linenum);
493ca3176e7SBrian Feldman 		options->ports[options->num_ports++] = a2port(arg);
494ca3176e7SBrian Feldman 		if (options->ports[options->num_ports-1] == 0)
495ca3176e7SBrian Feldman 			fatal("%s line %d: Badly formatted port number.",
496ca3176e7SBrian Feldman 			    filename, linenum);
497511b41d2SMark Murray 		break;
498511b41d2SMark Murray 
499511b41d2SMark Murray 	case sServerKeyBits:
500511b41d2SMark Murray 		intptr = &options->server_key_bits;
501511b41d2SMark Murray parse_int:
502c2d3a559SKris Kennaway 		arg = strdelim(&cp);
503ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
504ca3176e7SBrian Feldman 			fatal("%s line %d: missing integer value.",
505511b41d2SMark Murray 			    filename, linenum);
506c2d3a559SKris Kennaway 		value = atoi(arg);
507511b41d2SMark Murray 		if (*intptr == -1)
508511b41d2SMark Murray 			*intptr = value;
509511b41d2SMark Murray 		break;
510511b41d2SMark Murray 
511511b41d2SMark Murray 	case sLoginGraceTime:
512511b41d2SMark Murray 		intptr = &options->login_grace_time;
513af12a3e7SDag-Erling Smørgrav parse_time:
514af12a3e7SDag-Erling Smørgrav 		arg = strdelim(&cp);
515af12a3e7SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
516af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: missing time value.",
517af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
518af12a3e7SDag-Erling Smørgrav 		if ((value = convtime(arg)) == -1)
519af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: invalid time value.",
520af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
521af12a3e7SDag-Erling Smørgrav 		if (*intptr == -1)
522af12a3e7SDag-Erling Smørgrav 			*intptr = value;
523af12a3e7SDag-Erling Smørgrav 		break;
524511b41d2SMark Murray 
525511b41d2SMark Murray 	case sKeyRegenerationTime:
526511b41d2SMark Murray 		intptr = &options->key_regeneration_time;
527af12a3e7SDag-Erling Smørgrav 		goto parse_time;
528511b41d2SMark Murray 
529511b41d2SMark Murray 	case sListenAddress:
530c2d3a559SKris Kennaway 		arg = strdelim(&cp);
531ca3176e7SBrian Feldman 		if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
532ca3176e7SBrian Feldman 			fatal("%s line %d: missing inet addr.",
533511b41d2SMark Murray 			    filename, linenum);
534ca3176e7SBrian Feldman 		if (*arg == '[') {
535ca3176e7SBrian Feldman 			if ((p = strchr(arg, ']')) == NULL)
536ca3176e7SBrian Feldman 				fatal("%s line %d: bad ipv6 inet addr usage.",
537ca3176e7SBrian Feldman 				    filename, linenum);
538ca3176e7SBrian Feldman 			arg++;
539ca3176e7SBrian Feldman 			memmove(p, p+1, strlen(p+1)+1);
540ca3176e7SBrian Feldman 		} else if (((p = strchr(arg, ':')) == NULL) ||
541ca3176e7SBrian Feldman 			    (strchr(p+1, ':') != NULL)) {
542ca3176e7SBrian Feldman 			add_listen_addr(options, arg, 0);
543ca3176e7SBrian Feldman 			break;
544ca3176e7SBrian Feldman 		}
545ca3176e7SBrian Feldman 		if (*p == ':') {
546ca3176e7SBrian Feldman 			u_short port;
547ca3176e7SBrian Feldman 
548ca3176e7SBrian Feldman 			p++;
549ca3176e7SBrian Feldman 			if (*p == '\0')
550ca3176e7SBrian Feldman 				fatal("%s line %d: bad inet addr:port usage.",
551ca3176e7SBrian Feldman 				    filename, linenum);
552ca3176e7SBrian Feldman 			else {
553ca3176e7SBrian Feldman 				*(p-1) = '\0';
554ca3176e7SBrian Feldman 				if ((port = a2port(p)) == 0)
555ca3176e7SBrian Feldman 					fatal("%s line %d: bad port number.",
556ca3176e7SBrian Feldman 					    filename, linenum);
557ca3176e7SBrian Feldman 				add_listen_addr(options, arg, port);
558ca3176e7SBrian Feldman 			}
559ca3176e7SBrian Feldman 		} else if (*p == '\0')
560ca3176e7SBrian Feldman 			add_listen_addr(options, arg, 0);
561ca3176e7SBrian Feldman 		else
562ca3176e7SBrian Feldman 			fatal("%s line %d: bad inet addr usage.",
563ca3176e7SBrian Feldman 			    filename, linenum);
564511b41d2SMark Murray 		break;
565511b41d2SMark Murray 
566511b41d2SMark Murray 	case sHostKeyFile:
567ca3176e7SBrian Feldman 		intptr = &options->num_host_key_files;
568ca3176e7SBrian Feldman 		if (*intptr >= MAX_HOSTKEYS)
569ca3176e7SBrian Feldman 			fatal("%s line %d: too many host keys specified (max %d).",
570ca3176e7SBrian Feldman 			    filename, linenum, MAX_HOSTKEYS);
571ca3176e7SBrian Feldman 		charptr = &options->host_key_files[*intptr];
572c2d3a559SKris Kennaway parse_filename:
573c2d3a559SKris Kennaway 		arg = strdelim(&cp);
574ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
575ca3176e7SBrian Feldman 			fatal("%s line %d: missing file name.",
576e8aafc91SKris Kennaway 			    filename, linenum);
577ca3176e7SBrian Feldman 		if (*charptr == NULL) {
578c2d3a559SKris Kennaway 			*charptr = tilde_expand_filename(arg, getuid());
579ca3176e7SBrian Feldman 			/* increase optional counter */
580ca3176e7SBrian Feldman 			if (intptr != NULL)
581ca3176e7SBrian Feldman 				*intptr = *intptr + 1;
582ca3176e7SBrian Feldman 		}
583e8aafc91SKris Kennaway 		break;
584e8aafc91SKris Kennaway 
585e8aafc91SKris Kennaway 	case sPidFile:
586e8aafc91SKris Kennaway 		charptr = &options->pid_file;
587c2d3a559SKris Kennaway 		goto parse_filename;
588511b41d2SMark Murray 
589511b41d2SMark Murray 	case sPermitRootLogin:
590511b41d2SMark Murray 		intptr = &options->permit_root_login;
591c2d3a559SKris Kennaway 		arg = strdelim(&cp);
592ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
593ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/"
594ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
595ca3176e7SBrian Feldman 			    "argument.", filename, linenum);
596ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
597c2d3a559SKris Kennaway 		if (strcmp(arg, "without-password") == 0)
598ca3176e7SBrian Feldman 			value = PERMIT_NO_PASSWD;
599ca3176e7SBrian Feldman 		else if (strcmp(arg, "forced-commands-only") == 0)
600ca3176e7SBrian Feldman 			value = PERMIT_FORCED_ONLY;
601c2d3a559SKris Kennaway 		else if (strcmp(arg, "yes") == 0)
602ca3176e7SBrian Feldman 			value = PERMIT_YES;
603c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
604ca3176e7SBrian Feldman 			value = PERMIT_NO;
605ca3176e7SBrian Feldman 		else
606ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/"
607ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
608ca3176e7SBrian Feldman 			    "argument: %s", filename, linenum, arg);
609511b41d2SMark Murray 		if (*intptr == -1)
610511b41d2SMark Murray 			*intptr = value;
611511b41d2SMark Murray 		break;
612511b41d2SMark Murray 
613511b41d2SMark Murray 	case sIgnoreRhosts:
614511b41d2SMark Murray 		intptr = &options->ignore_rhosts;
615511b41d2SMark Murray parse_flag:
616c2d3a559SKris Kennaway 		arg = strdelim(&cp);
617ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
618ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/no argument.",
619511b41d2SMark Murray 			    filename, linenum);
620ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
621c2d3a559SKris Kennaway 		if (strcmp(arg, "yes") == 0)
622511b41d2SMark Murray 			value = 1;
623c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
624511b41d2SMark Murray 			value = 0;
625ca3176e7SBrian Feldman 		else
626ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/no argument: %s",
627c2d3a559SKris Kennaway 				filename, linenum, arg);
628511b41d2SMark Murray 		if (*intptr == -1)
629511b41d2SMark Murray 			*intptr = value;
630511b41d2SMark Murray 		break;
631511b41d2SMark Murray 
632511b41d2SMark Murray 	case sIgnoreUserKnownHosts:
633511b41d2SMark Murray 		intptr = &options->ignore_user_known_hosts;
634962a3f4eSSheldon Hearn 		goto parse_flag;
635511b41d2SMark Murray 
636511b41d2SMark Murray 	case sRhostsAuthentication:
637511b41d2SMark Murray 		intptr = &options->rhosts_authentication;
638511b41d2SMark Murray 		goto parse_flag;
639511b41d2SMark Murray 
640511b41d2SMark Murray 	case sRhostsRSAAuthentication:
641511b41d2SMark Murray 		intptr = &options->rhosts_rsa_authentication;
642511b41d2SMark Murray 		goto parse_flag;
643511b41d2SMark Murray 
644ca3176e7SBrian Feldman 	case sHostbasedAuthentication:
645ca3176e7SBrian Feldman 		intptr = &options->hostbased_authentication;
646ca3176e7SBrian Feldman 		goto parse_flag;
647ca3176e7SBrian Feldman 
648ca3176e7SBrian Feldman 	case sHostbasedUsesNameFromPacketOnly:
649ca3176e7SBrian Feldman 		intptr = &options->hostbased_uses_name_from_packet_only;
650ca3176e7SBrian Feldman 		goto parse_flag;
651ca3176e7SBrian Feldman 
652511b41d2SMark Murray 	case sRSAAuthentication:
653511b41d2SMark Murray 		intptr = &options->rsa_authentication;
654511b41d2SMark Murray 		goto parse_flag;
655511b41d2SMark Murray 
656ca3176e7SBrian Feldman 	case sPubkeyAuthentication:
657ca3176e7SBrian Feldman 		intptr = &options->pubkey_authentication;
658e8aafc91SKris Kennaway 		goto parse_flag;
659cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
660cb96ab36SAssar Westerlund 	case sKerberosAuthentication:
661cb96ab36SAssar Westerlund 		intptr = &options->kerberos_authentication;
662511b41d2SMark Murray 		goto parse_flag;
663511b41d2SMark Murray 
664af12a3e7SDag-Erling Smørgrav 	case sKerberosOrLocalPasswd:
665af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_or_local_passwd;
666511b41d2SMark Murray 		goto parse_flag;
667511b41d2SMark Murray 
668af12a3e7SDag-Erling Smørgrav 	case sKerberosTicketCleanup:
669af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_ticket_cleanup;
670511b41d2SMark Murray 		goto parse_flag;
671511b41d2SMark Murray #endif
672af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
673af12a3e7SDag-Erling Smørgrav 	case sKerberosTgtPassing:
674af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_tgt_passing;
675fe5fd017SMark Murray 		goto parse_flag;
676af12a3e7SDag-Erling Smørgrav #endif
677511b41d2SMark Murray #ifdef AFS
678511b41d2SMark Murray 	case sAFSTokenPassing:
679511b41d2SMark Murray 		intptr = &options->afs_token_passing;
680511b41d2SMark Murray 		goto parse_flag;
681511b41d2SMark Murray #endif
682511b41d2SMark Murray 
683511b41d2SMark Murray 	case sPasswordAuthentication:
684511b41d2SMark Murray 		intptr = &options->password_authentication;
685511b41d2SMark Murray 		goto parse_flag;
686511b41d2SMark Murray 
68709958426SBrian Feldman 	case sKbdInteractiveAuthentication:
68809958426SBrian Feldman 		intptr = &options->kbd_interactive_authentication;
68909958426SBrian Feldman 		goto parse_flag;
69009958426SBrian Feldman 
691ca3176e7SBrian Feldman 	case sChallengeResponseAuthentication:
692af12a3e7SDag-Erling Smørgrav 		intptr = &options->challenge_response_authentication;
693511b41d2SMark Murray 		goto parse_flag;
694511b41d2SMark Murray 
695511b41d2SMark Murray 	case sPrintMotd:
696511b41d2SMark Murray 		intptr = &options->print_motd;
697511b41d2SMark Murray 		goto parse_flag;
698511b41d2SMark Murray 
699ca3176e7SBrian Feldman 	case sPrintLastLog:
700ca3176e7SBrian Feldman 		intptr = &options->print_lastlog;
701ca3176e7SBrian Feldman 		goto parse_flag;
702ca3176e7SBrian Feldman 
703511b41d2SMark Murray 	case sX11Forwarding:
704511b41d2SMark Murray 		intptr = &options->x11_forwarding;
705511b41d2SMark Murray 		goto parse_flag;
706511b41d2SMark Murray 
707511b41d2SMark Murray 	case sX11DisplayOffset:
708511b41d2SMark Murray 		intptr = &options->x11_display_offset;
709511b41d2SMark Murray 		goto parse_int;
710511b41d2SMark Murray 
711af12a3e7SDag-Erling Smørgrav 	case sX11UseLocalhost:
712af12a3e7SDag-Erling Smørgrav 		intptr = &options->x11_use_localhost;
713af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
714af12a3e7SDag-Erling Smørgrav 
715c2d3a559SKris Kennaway 	case sXAuthLocation:
716c2d3a559SKris Kennaway 		charptr = &options->xauth_location;
717c2d3a559SKris Kennaway 		goto parse_filename;
718c2d3a559SKris Kennaway 
719511b41d2SMark Murray 	case sStrictModes:
720511b41d2SMark Murray 		intptr = &options->strict_modes;
721511b41d2SMark Murray 		goto parse_flag;
722511b41d2SMark Murray 
723511b41d2SMark Murray 	case sKeepAlives:
724511b41d2SMark Murray 		intptr = &options->keepalives;
725511b41d2SMark Murray 		goto parse_flag;
726511b41d2SMark Murray 
727511b41d2SMark Murray 	case sEmptyPasswd:
728511b41d2SMark Murray 		intptr = &options->permit_empty_passwd;
729511b41d2SMark Murray 		goto parse_flag;
730511b41d2SMark Murray 
731511b41d2SMark Murray 	case sUseLogin:
732511b41d2SMark Murray 		intptr = &options->use_login;
733511b41d2SMark Murray 		goto parse_flag;
734511b41d2SMark Murray 
73580628bacSDag-Erling Smørgrav 	case sCompression:
73680628bacSDag-Erling Smørgrav 		intptr = &options->compression;
73780628bacSDag-Erling Smørgrav 		goto parse_flag;
73880628bacSDag-Erling Smørgrav 
739e8aafc91SKris Kennaway 	case sGatewayPorts:
740e8aafc91SKris Kennaway 		intptr = &options->gateway_ports;
741e8aafc91SKris Kennaway 		goto parse_flag;
742e8aafc91SKris Kennaway 
743af12a3e7SDag-Erling Smørgrav 	case sVerifyReverseMapping:
744af12a3e7SDag-Erling Smørgrav 		intptr = &options->verify_reverse_mapping;
745ca3176e7SBrian Feldman 		goto parse_flag;
746ca3176e7SBrian Feldman 
747511b41d2SMark Murray 	case sLogFacility:
748511b41d2SMark Murray 		intptr = (int *) &options->log_facility;
749c2d3a559SKris Kennaway 		arg = strdelim(&cp);
750c2d3a559SKris Kennaway 		value = log_facility_number(arg);
751af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_FACILITY_NOT_SET)
752ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log facility '%s'",
753c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
754511b41d2SMark Murray 		if (*intptr == -1)
755511b41d2SMark Murray 			*intptr = (SyslogFacility) value;
756511b41d2SMark Murray 		break;
757511b41d2SMark Murray 
758511b41d2SMark Murray 	case sLogLevel:
759511b41d2SMark Murray 		intptr = (int *) &options->log_level;
760c2d3a559SKris Kennaway 		arg = strdelim(&cp);
761c2d3a559SKris Kennaway 		value = log_level_number(arg);
762af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_LEVEL_NOT_SET)
763ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log level '%s'",
764c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
765511b41d2SMark Murray 		if (*intptr == -1)
766511b41d2SMark Murray 			*intptr = (LogLevel) value;
767511b41d2SMark Murray 		break;
768511b41d2SMark Murray 
76909958426SBrian Feldman 	case sAllowTcpForwarding:
77009958426SBrian Feldman 		intptr = &options->allow_tcp_forwarding;
77109958426SBrian Feldman 		goto parse_flag;
77209958426SBrian Feldman 
77380628bacSDag-Erling Smørgrav 	case sUsePrivilegeSeparation:
77480628bacSDag-Erling Smørgrav 		intptr = &use_privsep;
77580628bacSDag-Erling Smørgrav 		goto parse_flag;
77680628bacSDag-Erling Smørgrav 
777511b41d2SMark Murray 	case sAllowUsers:
778c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
77942f71286SMark Murray 			if (options->num_allow_users >= MAX_ALLOW_USERS)
780af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow users.",
781e8aafc91SKris Kennaway 				    filename, linenum);
782a82e551fSDag-Erling Smørgrav 			options->allow_users[options->num_allow_users++] =
783a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
784511b41d2SMark Murray 		}
785511b41d2SMark Murray 		break;
786511b41d2SMark Murray 
787511b41d2SMark Murray 	case sDenyUsers:
788c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
7892803b77eSBrian Feldman 			if (options->num_deny_users >= MAX_DENY_USERS)
790af12a3e7SDag-Erling Smørgrav 				fatal( "%s line %d: too many deny users.",
791e8aafc91SKris Kennaway 				    filename, linenum);
792a82e551fSDag-Erling Smørgrav 			options->deny_users[options->num_deny_users++] =
793a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
794511b41d2SMark Murray 		}
795511b41d2SMark Murray 		break;
796511b41d2SMark Murray 
797511b41d2SMark Murray 	case sAllowGroups:
798c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
79942f71286SMark Murray 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
800af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow groups.",
801e8aafc91SKris Kennaway 				    filename, linenum);
802a82e551fSDag-Erling Smørgrav 			options->allow_groups[options->num_allow_groups++] =
803a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
804511b41d2SMark Murray 		}
805511b41d2SMark Murray 		break;
806511b41d2SMark Murray 
807511b41d2SMark Murray 	case sDenyGroups:
808c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
80942f71286SMark Murray 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
810af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many deny groups.",
811e8aafc91SKris Kennaway 				    filename, linenum);
812c2d3a559SKris Kennaway 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
813511b41d2SMark Murray 		}
814511b41d2SMark Murray 		break;
815511b41d2SMark Murray 
816e8aafc91SKris Kennaway 	case sCiphers:
817c2d3a559SKris Kennaway 		arg = strdelim(&cp);
818c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
819c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
820c2d3a559SKris Kennaway 		if (!ciphers_valid(arg))
821e8aafc91SKris Kennaway 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
822c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
823e8aafc91SKris Kennaway 		if (options->ciphers == NULL)
824c2d3a559SKris Kennaway 			options->ciphers = xstrdup(arg);
825e8aafc91SKris Kennaway 		break;
826e8aafc91SKris Kennaway 
827ca3176e7SBrian Feldman 	case sMacs:
828ca3176e7SBrian Feldman 		arg = strdelim(&cp);
829ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
830ca3176e7SBrian Feldman 			fatal("%s line %d: Missing argument.", filename, linenum);
831ca3176e7SBrian Feldman 		if (!mac_valid(arg))
832ca3176e7SBrian Feldman 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
833ca3176e7SBrian Feldman 			    filename, linenum, arg ? arg : "<NONE>");
834ca3176e7SBrian Feldman 		if (options->macs == NULL)
835ca3176e7SBrian Feldman 			options->macs = xstrdup(arg);
836ca3176e7SBrian Feldman 		break;
837ca3176e7SBrian Feldman 
838e8aafc91SKris Kennaway 	case sProtocol:
839e8aafc91SKris Kennaway 		intptr = &options->protocol;
840c2d3a559SKris Kennaway 		arg = strdelim(&cp);
841c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
842c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
843c2d3a559SKris Kennaway 		value = proto_spec(arg);
844e8aafc91SKris Kennaway 		if (value == SSH_PROTO_UNKNOWN)
845e8aafc91SKris Kennaway 			fatal("%s line %d: Bad protocol spec '%s'.",
846c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
847e8aafc91SKris Kennaway 		if (*intptr == SSH_PROTO_UNKNOWN)
848e8aafc91SKris Kennaway 			*intptr = value;
849e8aafc91SKris Kennaway 		break;
850e8aafc91SKris Kennaway 
851c2d3a559SKris Kennaway 	case sSubsystem:
852c2d3a559SKris Kennaway 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
853c2d3a559SKris Kennaway 			fatal("%s line %d: too many subsystems defined.",
854c2d3a559SKris Kennaway 			    filename, linenum);
855c2d3a559SKris Kennaway 		}
856c2d3a559SKris Kennaway 		arg = strdelim(&cp);
857c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
858c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem name.",
859c2d3a559SKris Kennaway 			    filename, linenum);
860c2d3a559SKris Kennaway 		for (i = 0; i < options->num_subsystems; i++)
861c2d3a559SKris Kennaway 			if (strcmp(arg, options->subsystem_name[i]) == 0)
862c2d3a559SKris Kennaway 				fatal("%s line %d: Subsystem '%s' already defined.",
863c2d3a559SKris Kennaway 				    filename, linenum, arg);
864c2d3a559SKris Kennaway 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
865c2d3a559SKris Kennaway 		arg = strdelim(&cp);
866c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
867c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem command.",
868c2d3a559SKris Kennaway 			    filename, linenum);
869c2d3a559SKris Kennaway 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
870c2d3a559SKris Kennaway 		options->num_subsystems++;
871c2d3a559SKris Kennaway 		break;
872c2d3a559SKris Kennaway 
873c2d3a559SKris Kennaway 	case sMaxStartups:
874c2d3a559SKris Kennaway 		arg = strdelim(&cp);
875c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
876c2d3a559SKris Kennaway 			fatal("%s line %d: Missing MaxStartups spec.",
877c2d3a559SKris Kennaway 			    filename, linenum);
878af12a3e7SDag-Erling Smørgrav 		if ((n = sscanf(arg, "%d:%d:%d",
879c2d3a559SKris Kennaway 		    &options->max_startups_begin,
880c2d3a559SKris Kennaway 		    &options->max_startups_rate,
881af12a3e7SDag-Erling Smørgrav 		    &options->max_startups)) == 3) {
882c2d3a559SKris Kennaway 			if (options->max_startups_begin >
883c2d3a559SKris Kennaway 			    options->max_startups ||
884c2d3a559SKris Kennaway 			    options->max_startups_rate > 100 ||
885c2d3a559SKris Kennaway 			    options->max_startups_rate < 1)
886c2d3a559SKris Kennaway 				fatal("%s line %d: Illegal MaxStartups spec.",
887c2d3a559SKris Kennaway 				    filename, linenum);
888af12a3e7SDag-Erling Smørgrav 		} else if (n != 1)
889af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: Illegal MaxStartups spec.",
890af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
891af12a3e7SDag-Erling Smørgrav 		else
892af12a3e7SDag-Erling Smørgrav 			options->max_startups = options->max_startups_begin;
893933ca70fSBrian Feldman 		break;
894933ca70fSBrian Feldman 
895ca3176e7SBrian Feldman 	case sBanner:
896ca3176e7SBrian Feldman 		charptr = &options->banner;
897ca3176e7SBrian Feldman 		goto parse_filename;
898af12a3e7SDag-Erling Smørgrav 	/*
899af12a3e7SDag-Erling Smørgrav 	 * These options can contain %X options expanded at
900af12a3e7SDag-Erling Smørgrav 	 * connect time, so that you can specify paths like:
901af12a3e7SDag-Erling Smørgrav 	 *
902af12a3e7SDag-Erling Smørgrav 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
903af12a3e7SDag-Erling Smørgrav 	 */
904af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile:
905af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile2:
906af12a3e7SDag-Erling Smørgrav 		charptr = (opcode == sAuthorizedKeysFile ) ?
907af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file :
908af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file2;
909af12a3e7SDag-Erling Smørgrav 		goto parse_filename;
910af12a3e7SDag-Erling Smørgrav 
911ca3176e7SBrian Feldman 	case sClientAliveInterval:
912ca3176e7SBrian Feldman 		intptr = &options->client_alive_interval;
913af12a3e7SDag-Erling Smørgrav 		goto parse_time;
914af12a3e7SDag-Erling Smørgrav 
915ca3176e7SBrian Feldman 	case sClientAliveCountMax:
916ca3176e7SBrian Feldman 		intptr = &options->client_alive_count_max;
917ca3176e7SBrian Feldman 		goto parse_int;
918af12a3e7SDag-Erling Smørgrav 
919db58a8e4SDag-Erling Smørgrav 	case sVersionAddendum:
920db58a8e4SDag-Erling Smørgrav                 ssh_version_set_addendum(strtok(cp, "\n"));
921db58a8e4SDag-Erling Smørgrav                 do {
922db58a8e4SDag-Erling Smørgrav                         arg = strdelim(&cp);
923db58a8e4SDag-Erling Smørgrav                 } while (arg != NULL && *arg != '\0');
924db58a8e4SDag-Erling Smørgrav 		break;
925db58a8e4SDag-Erling Smørgrav 
926af12a3e7SDag-Erling Smørgrav 	case sDeprecated:
927af12a3e7SDag-Erling Smørgrav 		log("%s line %d: Deprecated option %s",
928af12a3e7SDag-Erling Smørgrav 		    filename, linenum, arg);
929af12a3e7SDag-Erling Smørgrav 		while (arg)
930af12a3e7SDag-Erling Smørgrav 		    arg = strdelim(&cp);
931af12a3e7SDag-Erling Smørgrav 		break;
932af12a3e7SDag-Erling Smørgrav 
93342f71286SMark Murray 	default:
934af12a3e7SDag-Erling Smørgrav 		fatal("%s line %d: Missing handler for opcode %s (%d)",
935c2d3a559SKris Kennaway 		    filename, linenum, arg, opcode);
936511b41d2SMark Murray 	}
937ca3176e7SBrian Feldman 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
938ca3176e7SBrian Feldman 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
939c2d3a559SKris Kennaway 		    filename, linenum, arg);
940af12a3e7SDag-Erling Smørgrav 	return 0;
941af12a3e7SDag-Erling Smørgrav }
942af12a3e7SDag-Erling Smørgrav 
943af12a3e7SDag-Erling Smørgrav /* Reads the server configuration file. */
944af12a3e7SDag-Erling Smørgrav 
945af12a3e7SDag-Erling Smørgrav void
946af12a3e7SDag-Erling Smørgrav read_server_config(ServerOptions *options, const char *filename)
947af12a3e7SDag-Erling Smørgrav {
948a82e551fSDag-Erling Smørgrav 	int linenum, bad_options = 0;
949af12a3e7SDag-Erling Smørgrav 	char line[1024];
950a82e551fSDag-Erling Smørgrav 	FILE *f;
951af12a3e7SDag-Erling Smørgrav 
952af12a3e7SDag-Erling Smørgrav 	f = fopen(filename, "r");
953af12a3e7SDag-Erling Smørgrav 	if (!f) {
954af12a3e7SDag-Erling Smørgrav 		perror(filename);
955af12a3e7SDag-Erling Smørgrav 		exit(1);
956af12a3e7SDag-Erling Smørgrav 	}
957af12a3e7SDag-Erling Smørgrav 	linenum = 0;
958af12a3e7SDag-Erling Smørgrav 	while (fgets(line, sizeof(line), f)) {
959af12a3e7SDag-Erling Smørgrav 		/* Update line number counter. */
960af12a3e7SDag-Erling Smørgrav 		linenum++;
961af12a3e7SDag-Erling Smørgrav 		if (process_server_config_line(options, line, filename, linenum) != 0)
962af12a3e7SDag-Erling Smørgrav 			bad_options++;
963511b41d2SMark Murray 	}
964511b41d2SMark Murray 	fclose(f);
965ca3176e7SBrian Feldman 	if (bad_options > 0)
966af12a3e7SDag-Erling Smørgrav 		fatal("%s: terminating, %d bad configuration options",
967511b41d2SMark Murray 		    filename, bad_options);
968511b41d2SMark Murray }
969