xref: /freebsd/crypto/openssh/servconf.c (revision 80628bacb0b4bc1daaef4e038e755602c972bede)
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"
1380628bacSDag-Erling Smørgrav RCSID("$OpenBSD: servconf.c,v 1.111 2002/06/20 23:05:55 markus Exp $");
14c2d3a559SKris Kennaway 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)
201d9e2b0aSDag-Erling Smørgrav #include <krb5.h>
211d9e2b0aSDag-Erling Smørgrav #endif
22ca3176e7SBrian Feldman #ifdef AFS
23ca3176e7SBrian Feldman #include <kafs.h>
24ca3176e7SBrian Feldman #endif
25ca3176e7SBrian Feldman 
26511b41d2SMark Murray #include "ssh.h"
27ca3176e7SBrian Feldman #include "log.h"
28511b41d2SMark Murray #include "servconf.h"
29511b41d2SMark Murray #include "xmalloc.h"
30e8aafc91SKris Kennaway #include "compat.h"
31ca3176e7SBrian Feldman #include "pathnames.h"
32ca3176e7SBrian Feldman #include "tildexpand.h"
33ca3176e7SBrian Feldman #include "misc.h"
34ca3176e7SBrian Feldman #include "cipher.h"
35ca3176e7SBrian Feldman #include "kex.h"
36ca3176e7SBrian Feldman #include "mac.h"
37511b41d2SMark Murray 
38af12a3e7SDag-Erling Smørgrav static void add_listen_addr(ServerOptions *, char *, u_short);
39af12a3e7SDag-Erling Smørgrav static void add_one_listen_addr(ServerOptions *, char *, u_short);
40ca3176e7SBrian Feldman 
41ca3176e7SBrian Feldman /* AF_UNSPEC or AF_INET or AF_INET6 */
42ca3176e7SBrian Feldman extern int IPv4or6;
4380628bacSDag-Erling Smørgrav /* Use of privilege separation or not */
4480628bacSDag-Erling Smørgrav extern int use_privsep;
45511b41d2SMark Murray 
46511b41d2SMark Murray /* Initializes the server options to their default values. */
47511b41d2SMark Murray 
48511b41d2SMark Murray void
49511b41d2SMark Murray initialize_server_options(ServerOptions *options)
50511b41d2SMark Murray {
51511b41d2SMark Murray 	memset(options, 0, sizeof(*options));
52511b41d2SMark Murray 	options->num_ports = 0;
53511b41d2SMark Murray 	options->ports_from_cmdline = 0;
54511b41d2SMark Murray 	options->listen_addrs = NULL;
55ca3176e7SBrian Feldman 	options->num_host_key_files = 0;
56e8aafc91SKris Kennaway 	options->pid_file = NULL;
57511b41d2SMark Murray 	options->server_key_bits = -1;
58511b41d2SMark Murray 	options->login_grace_time = -1;
59511b41d2SMark Murray 	options->key_regeneration_time = -1;
60ca3176e7SBrian Feldman 	options->permit_root_login = PERMIT_NOT_SET;
61511b41d2SMark Murray 	options->ignore_rhosts = -1;
62511b41d2SMark Murray 	options->ignore_user_known_hosts = -1;
63511b41d2SMark Murray 	options->print_motd = -1;
64ca3176e7SBrian Feldman 	options->print_lastlog = -1;
65511b41d2SMark Murray 	options->x11_forwarding = -1;
66511b41d2SMark Murray 	options->x11_display_offset = -1;
67af12a3e7SDag-Erling Smørgrav 	options->x11_use_localhost = -1;
68c2d3a559SKris Kennaway 	options->xauth_location = NULL;
69511b41d2SMark Murray 	options->strict_modes = -1;
70511b41d2SMark Murray 	options->keepalives = -1;
71af12a3e7SDag-Erling Smørgrav 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
72af12a3e7SDag-Erling Smørgrav 	options->log_level = SYSLOG_LEVEL_NOT_SET;
73511b41d2SMark Murray 	options->rhosts_authentication = -1;
74511b41d2SMark Murray 	options->rhosts_rsa_authentication = -1;
75ca3176e7SBrian Feldman 	options->hostbased_authentication = -1;
76ca3176e7SBrian Feldman 	options->hostbased_uses_name_from_packet_only = -1;
77511b41d2SMark Murray 	options->rsa_authentication = -1;
78ca3176e7SBrian Feldman 	options->pubkey_authentication = -1;
79cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
80cb96ab36SAssar Westerlund 	options->kerberos_authentication = -1;
81af12a3e7SDag-Erling Smørgrav 	options->kerberos_or_local_passwd = -1;
82af12a3e7SDag-Erling Smørgrav 	options->kerberos_ticket_cleanup = -1;
83cb96ab36SAssar Westerlund #endif
84af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
85af12a3e7SDag-Erling Smørgrav 	options->kerberos_tgt_passing = -1;
86511b41d2SMark Murray #endif
87511b41d2SMark Murray #ifdef AFS
88511b41d2SMark Murray 	options->afs_token_passing = -1;
89511b41d2SMark Murray #endif
90511b41d2SMark Murray 	options->password_authentication = -1;
9109958426SBrian Feldman 	options->kbd_interactive_authentication = -1;
92af12a3e7SDag-Erling Smørgrav 	options->challenge_response_authentication = -1;
93511b41d2SMark Murray 	options->permit_empty_passwd = -1;
94511b41d2SMark Murray 	options->use_login = -1;
9580628bacSDag-Erling Smørgrav 	options->compression = -1;
9609958426SBrian Feldman 	options->allow_tcp_forwarding = -1;
97511b41d2SMark Murray 	options->num_allow_users = 0;
98511b41d2SMark Murray 	options->num_deny_users = 0;
99511b41d2SMark Murray 	options->num_allow_groups = 0;
100511b41d2SMark Murray 	options->num_deny_groups = 0;
101e8aafc91SKris Kennaway 	options->ciphers = NULL;
102ca3176e7SBrian Feldman 	options->macs = NULL;
103e8aafc91SKris Kennaway 	options->protocol = SSH_PROTO_UNKNOWN;
104e8aafc91SKris Kennaway 	options->gateway_ports = -1;
10542f71286SMark Murray 	options->connections_period = 0;
106c2d3a559SKris Kennaway 	options->num_subsystems = 0;
107c2d3a559SKris Kennaway 	options->max_startups_begin = -1;
108c2d3a559SKris Kennaway 	options->max_startups_rate = -1;
109c2d3a559SKris Kennaway 	options->max_startups = -1;
110ca3176e7SBrian Feldman 	options->banner = NULL;
111af12a3e7SDag-Erling Smørgrav 	options->verify_reverse_mapping = -1;
112ca3176e7SBrian Feldman 	options->client_alive_interval = -1;
113ca3176e7SBrian Feldman 	options->client_alive_count_max = -1;
114af12a3e7SDag-Erling Smørgrav 	options->authorized_keys_file = NULL;
115af12a3e7SDag-Erling Smørgrav 	options->authorized_keys_file2 = NULL;
116b36e10eeSAndrey A. Chernov 	options->check_mail = -1;
11780628bacSDag-Erling Smørgrav 
11880628bacSDag-Erling Smørgrav 	/* Needs to be accessable in many places */
11980628bacSDag-Erling Smørgrav 	use_privsep = -1;
120511b41d2SMark Murray }
121511b41d2SMark Murray 
122511b41d2SMark Murray void
123511b41d2SMark Murray fill_default_server_options(ServerOptions *options)
124511b41d2SMark Murray {
125ca3176e7SBrian Feldman 	if (options->protocol == SSH_PROTO_UNKNOWN)
126ca3176e7SBrian Feldman 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
127ca3176e7SBrian Feldman 	if (options->num_host_key_files == 0) {
128ca3176e7SBrian Feldman 		/* fill default hostkeys for protocols */
129ca3176e7SBrian Feldman 		if (options->protocol & SSH_PROTO_1)
130af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
131af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_KEY_FILE;
132af12a3e7SDag-Erling Smørgrav 		if (options->protocol & SSH_PROTO_2) {
133af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
134af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_DSA_KEY_FILE;
135af12a3e7SDag-Erling Smørgrav 		}
136ca3176e7SBrian Feldman 	}
137511b41d2SMark Murray 	if (options->num_ports == 0)
138511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
139511b41d2SMark Murray 	if (options->listen_addrs == NULL)
140ca3176e7SBrian Feldman 		add_listen_addr(options, NULL, 0);
141e8aafc91SKris Kennaway 	if (options->pid_file == NULL)
142ca3176e7SBrian Feldman 		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
143511b41d2SMark Murray 	if (options->server_key_bits == -1)
144511b41d2SMark Murray 		options->server_key_bits = 768;
145511b41d2SMark Murray 	if (options->login_grace_time == -1)
146b87db7ceSKris Kennaway 		options->login_grace_time = 120;
147511b41d2SMark Murray 	if (options->key_regeneration_time == -1)
148511b41d2SMark Murray 		options->key_regeneration_time = 3600;
149ca3176e7SBrian Feldman 	if (options->permit_root_login == PERMIT_NOT_SET)
150ca3176e7SBrian Feldman 		options->permit_root_login = PERMIT_NO;
151511b41d2SMark Murray 	if (options->ignore_rhosts == -1)
152fe5fd017SMark Murray 		options->ignore_rhosts = 1;
153511b41d2SMark Murray 	if (options->ignore_user_known_hosts == -1)
154511b41d2SMark Murray 		options->ignore_user_known_hosts = 0;
155511b41d2SMark Murray 	if (options->check_mail == -1)
156365c420eSPeter Wemm 		options->check_mail = 1;
157511b41d2SMark Murray 	if (options->print_motd == -1)
158511b41d2SMark Murray 		options->print_motd = 1;
159ca3176e7SBrian Feldman 	if (options->print_lastlog == -1)
160ca3176e7SBrian Feldman 		options->print_lastlog = 1;
161511b41d2SMark Murray 	if (options->x11_forwarding == -1)
1621610cd7fSKris Kennaway 		options->x11_forwarding = 1;
163511b41d2SMark Murray 	if (options->x11_display_offset == -1)
164fe5fd017SMark Murray 		options->x11_display_offset = 10;
165af12a3e7SDag-Erling Smørgrav 	if (options->x11_use_localhost == -1)
166af12a3e7SDag-Erling Smørgrav 		options->x11_use_localhost = 1;
167c2d3a559SKris Kennaway 	if (options->xauth_location == NULL)
168af12a3e7SDag-Erling Smørgrav 		options->xauth_location = _PATH_XAUTH;
169511b41d2SMark Murray 	if (options->strict_modes == -1)
170511b41d2SMark Murray 		options->strict_modes = 1;
171511b41d2SMark Murray 	if (options->keepalives == -1)
172511b41d2SMark Murray 		options->keepalives = 1;
173af12a3e7SDag-Erling Smørgrav 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
174511b41d2SMark Murray 		options->log_facility = SYSLOG_FACILITY_AUTH;
175af12a3e7SDag-Erling Smørgrav 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
176511b41d2SMark Murray 		options->log_level = SYSLOG_LEVEL_INFO;
177511b41d2SMark Murray 	if (options->rhosts_authentication == -1)
178511b41d2SMark Murray 		options->rhosts_authentication = 0;
179511b41d2SMark Murray 	if (options->rhosts_rsa_authentication == -1)
180fe5fd017SMark Murray 		options->rhosts_rsa_authentication = 0;
181ca3176e7SBrian Feldman 	if (options->hostbased_authentication == -1)
182ca3176e7SBrian Feldman 		options->hostbased_authentication = 0;
183ca3176e7SBrian Feldman 	if (options->hostbased_uses_name_from_packet_only == -1)
184ca3176e7SBrian Feldman 		options->hostbased_uses_name_from_packet_only = 0;
185511b41d2SMark Murray 	if (options->rsa_authentication == -1)
186511b41d2SMark Murray 		options->rsa_authentication = 1;
187ca3176e7SBrian Feldman 	if (options->pubkey_authentication == -1)
188ca3176e7SBrian Feldman 		options->pubkey_authentication = 1;
1891d9e2b0aSDag-Erling Smørgrav #if defined(KRB4) && defined(KRB5)
1901d9e2b0aSDag-Erling Smørgrav 	if (options->kerberos_authentication == -1)
1911d9e2b0aSDag-Erling Smørgrav 		options->kerberos_authentication =
1921d9e2b0aSDag-Erling Smørgrav 		    (access(KEYFILE, R_OK) == 0 ||
1937fd1ca3bSJacques Vidrine 		    (access(krb5_defkeyname, R_OK) == 0));
1941d9e2b0aSDag-Erling Smørgrav #elif defined(KRB4)
195cb96ab36SAssar Westerlund 	if (options->kerberos_authentication == -1)
196cb96ab36SAssar Westerlund 		options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
1971d9e2b0aSDag-Erling Smørgrav #elif defined(KRB5)
1981d9e2b0aSDag-Erling Smørgrav 	if (options->kerberos_authentication == -1)
1991d9e2b0aSDag-Erling Smørgrav 		options->kerberos_authentication =
2007fd1ca3bSJacques Vidrine 		    (access(krb5_defkeyname, R_OK) == 0);
2011d9e2b0aSDag-Erling Smørgrav #endif
2021d9e2b0aSDag-Erling Smørgrav #if defined(KRB4) || defined(KRB5)
203af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_or_local_passwd == -1)
204af12a3e7SDag-Erling Smørgrav 		options->kerberos_or_local_passwd = 1;
205af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_ticket_cleanup == -1)
206af12a3e7SDag-Erling Smørgrav 		options->kerberos_ticket_cleanup = 1;
207cb96ab36SAssar Westerlund #endif
208af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
209af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_tgt_passing == -1)
210af12a3e7SDag-Erling Smørgrav 		options->kerberos_tgt_passing = 0;
211af12a3e7SDag-Erling Smørgrav #endif
212511b41d2SMark Murray #ifdef AFS
213511b41d2SMark Murray 	if (options->afs_token_passing == -1)
21480628bacSDag-Erling Smørgrav 		options->afs_token_passing = 0;
215af12a3e7SDag-Erling Smørgrav #endif
216511b41d2SMark Murray 	if (options->password_authentication == -1)
217511b41d2SMark Murray 		options->password_authentication = 1;
21809958426SBrian Feldman 	if (options->kbd_interactive_authentication == -1)
21909958426SBrian Feldman 		options->kbd_interactive_authentication = 0;
220af12a3e7SDag-Erling Smørgrav 	if (options->challenge_response_authentication == -1)
22180241871SDag-Erling Smørgrav 		options->challenge_response_authentication = 1;
222511b41d2SMark Murray 	if (options->permit_empty_passwd == -1)
223fe5fd017SMark Murray 		options->permit_empty_passwd = 0;
224511b41d2SMark Murray 	if (options->use_login == -1)
225511b41d2SMark Murray 		options->use_login = 0;
22680628bacSDag-Erling Smørgrav 	if (options->compression == -1)
22780628bacSDag-Erling Smørgrav 		options->compression = 1;
22809958426SBrian Feldman 	if (options->allow_tcp_forwarding == -1)
22909958426SBrian Feldman 		options->allow_tcp_forwarding = 1;
230e8aafc91SKris Kennaway 	if (options->gateway_ports == -1)
231e8aafc91SKris Kennaway 		options->gateway_ports = 0;
232c2d3a559SKris Kennaway 	if (options->max_startups == -1)
233c2d3a559SKris Kennaway 		options->max_startups = 10;
234c2d3a559SKris Kennaway 	if (options->max_startups_rate == -1)
235c2d3a559SKris Kennaway 		options->max_startups_rate = 100;		/* 100% */
236c2d3a559SKris Kennaway 	if (options->max_startups_begin == -1)
237c2d3a559SKris Kennaway 		options->max_startups_begin = options->max_startups;
238af12a3e7SDag-Erling Smørgrav 	if (options->verify_reverse_mapping == -1)
239af12a3e7SDag-Erling Smørgrav 		options->verify_reverse_mapping = 0;
240ca3176e7SBrian Feldman 	if (options->client_alive_interval == -1)
241ca3176e7SBrian Feldman 		options->client_alive_interval = 0;
242ca3176e7SBrian Feldman 	if (options->client_alive_count_max == -1)
243ca3176e7SBrian Feldman 		options->client_alive_count_max = 3;
244af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file2 == NULL) {
245af12a3e7SDag-Erling Smørgrav 		/* authorized_keys_file2 falls back to authorized_keys_file */
246af12a3e7SDag-Erling Smørgrav 		if (options->authorized_keys_file != NULL)
247af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = options->authorized_keys_file;
248af12a3e7SDag-Erling Smørgrav 		else
249af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
250af12a3e7SDag-Erling Smørgrav 	}
251af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file == NULL)
252af12a3e7SDag-Erling Smørgrav 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
25380628bacSDag-Erling Smørgrav 
25480628bacSDag-Erling Smørgrav 	/* Turn privilege separation off by default */
25580628bacSDag-Erling Smørgrav 	if (use_privsep == -1)
25680628bacSDag-Erling Smørgrav 		use_privsep = 0;
257511b41d2SMark Murray }
258511b41d2SMark Murray 
259511b41d2SMark Murray /* Keyword tokens. */
260511b41d2SMark Murray typedef enum {
261511b41d2SMark Murray 	sBadOption,		/* == unknown option */
262511b41d2SMark Murray 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
263511b41d2SMark Murray 	sPermitRootLogin, sLogFacility, sLogLevel,
264511b41d2SMark Murray 	sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
265cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
266af12a3e7SDag-Erling Smørgrav 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
267cb96ab36SAssar Westerlund #endif
268af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
269af12a3e7SDag-Erling Smørgrav 	sKerberosTgtPassing,
270511b41d2SMark Murray #endif
271511b41d2SMark Murray #ifdef AFS
272af12a3e7SDag-Erling Smørgrav 	sAFSTokenPassing,
273511b41d2SMark Murray #endif
274ca3176e7SBrian Feldman 	sChallengeResponseAuthentication,
27509958426SBrian Feldman 	sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
276ca3176e7SBrian Feldman 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
277af12a3e7SDag-Erling Smørgrav 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
278af12a3e7SDag-Erling Smørgrav 	sStrictModes, sEmptyPasswd, sKeepAlives,
27980628bacSDag-Erling Smørgrav 	sUseLogin, sAllowTcpForwarding, sCompression,
28009958426SBrian Feldman 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
281ca3176e7SBrian Feldman 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
282ca3176e7SBrian Feldman 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
283af12a3e7SDag-Erling Smørgrav 	sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
284ca3176e7SBrian Feldman 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
285af12a3e7SDag-Erling Smørgrav 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
28680628bacSDag-Erling Smørgrav 	sUsePrivilegeSeparation,
287af12a3e7SDag-Erling Smørgrav 	sCheckMail, sVersionAddendum,
288af12a3e7SDag-Erling Smørgrav 	sDeprecated
289511b41d2SMark Murray } ServerOpCodes;
290511b41d2SMark Murray 
291511b41d2SMark Murray /* Textual representation of the tokens. */
292511b41d2SMark Murray static struct {
293511b41d2SMark Murray 	const char *name;
294511b41d2SMark Murray 	ServerOpCodes opcode;
295511b41d2SMark Murray } keywords[] = {
296511b41d2SMark Murray 	{ "port", sPort },
297511b41d2SMark Murray 	{ "hostkey", sHostKeyFile },
298ca3176e7SBrian Feldman 	{ "hostdsakey", sHostKeyFile },					/* alias */
299e8aafc91SKris Kennaway 	{ "pidfile", sPidFile },
300511b41d2SMark Murray 	{ "serverkeybits", sServerKeyBits },
301511b41d2SMark Murray 	{ "logingracetime", sLoginGraceTime },
302511b41d2SMark Murray 	{ "keyregenerationinterval", sKeyRegenerationTime },
303511b41d2SMark Murray 	{ "permitrootlogin", sPermitRootLogin },
304511b41d2SMark Murray 	{ "syslogfacility", sLogFacility },
305511b41d2SMark Murray 	{ "loglevel", sLogLevel },
306511b41d2SMark Murray 	{ "rhostsauthentication", sRhostsAuthentication },
307511b41d2SMark Murray 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
308ca3176e7SBrian Feldman 	{ "hostbasedauthentication", sHostbasedAuthentication },
309ca3176e7SBrian Feldman 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
310af12a3e7SDag-Erling Smørgrav 	{ "rsaauthentication", sRSAAuthentication },
311ca3176e7SBrian Feldman 	{ "pubkeyauthentication", sPubkeyAuthentication },
312ca3176e7SBrian Feldman 	{ "dsaauthentication", sPubkeyAuthentication },			/* alias */
313cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
314cb96ab36SAssar Westerlund 	{ "kerberosauthentication", sKerberosAuthentication },
315af12a3e7SDag-Erling Smørgrav 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
316af12a3e7SDag-Erling Smørgrav 	{ "kerberosticketcleanup", sKerberosTicketCleanup },
317cb96ab36SAssar Westerlund #endif
318af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
319af12a3e7SDag-Erling Smørgrav 	{ "kerberostgtpassing", sKerberosTgtPassing },
320511b41d2SMark Murray #endif
321511b41d2SMark Murray #ifdef AFS
322511b41d2SMark Murray 	{ "afstokenpassing", sAFSTokenPassing },
323511b41d2SMark Murray #endif
324511b41d2SMark Murray 	{ "passwordauthentication", sPasswordAuthentication },
32509958426SBrian Feldman 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
326ca3176e7SBrian Feldman 	{ "challengeresponseauthentication", sChallengeResponseAuthentication },
327ca3176e7SBrian Feldman 	{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
328511b41d2SMark Murray 	{ "listenaddress", sListenAddress },
329511b41d2SMark Murray 	{ "printmotd", sPrintMotd },
330ca3176e7SBrian Feldman 	{ "printlastlog", sPrintLastLog },
331511b41d2SMark Murray 	{ "ignorerhosts", sIgnoreRhosts },
332511b41d2SMark Murray 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
333511b41d2SMark Murray 	{ "x11forwarding", sX11Forwarding },
334511b41d2SMark Murray 	{ "x11displayoffset", sX11DisplayOffset },
335af12a3e7SDag-Erling Smørgrav 	{ "x11uselocalhost", sX11UseLocalhost },
336c2d3a559SKris Kennaway 	{ "xauthlocation", sXAuthLocation },
337511b41d2SMark Murray 	{ "strictmodes", sStrictModes },
338511b41d2SMark Murray 	{ "permitemptypasswords", sEmptyPasswd },
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 },
354af12a3e7SDag-Erling Smørgrav 	{ "verifyreversemapping", sVerifyReverseMapping },
355af12a3e7SDag-Erling Smørgrav 	{ "reversemappingcheck", sVerifyReverseMapping },
356ca3176e7SBrian Feldman 	{ "clientaliveinterval", sClientAliveInterval },
357ca3176e7SBrian Feldman 	{ "clientalivecountmax", sClientAliveCountMax },
358af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile", sAuthorizedKeysFile },
359af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
36080628bacSDag-Erling Smørgrav 	{ "useprivilegeseparation", sUsePrivilegeSeparation},
361af12a3e7SDag-Erling Smørgrav 	{ "checkmail", sCheckMail },
362af12a3e7SDag-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;
410ca3176e7SBrian Feldman 	snprintf(strport, sizeof strport, "%d", 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;
426af12a3e7SDag-Erling Smørgrav 	int *intptr, value;
427511b41d2SMark Murray 	ServerOpCodes opcode;
428af12a3e7SDag-Erling Smørgrav 	int i, n;
429511b41d2SMark Murray 
430c2d3a559SKris Kennaway 	cp = line;
431c2d3a559SKris Kennaway 	arg = strdelim(&cp);
432c2d3a559SKris Kennaway 	/* Ignore leading whitespace */
433c2d3a559SKris Kennaway 	if (*arg == '\0')
434c2d3a559SKris Kennaway 		arg = strdelim(&cp);
435ca3176e7SBrian Feldman 	if (!arg || !*arg || *arg == '#')
436af12a3e7SDag-Erling Smørgrav 		return 0;
437ca3176e7SBrian Feldman 	intptr = NULL;
438ca3176e7SBrian Feldman 	charptr = NULL;
439c2d3a559SKris Kennaway 	opcode = parse_token(arg, filename, linenum);
440511b41d2SMark Murray 	switch (opcode) {
441511b41d2SMark Murray 	case sBadOption:
442af12a3e7SDag-Erling Smørgrav 		return -1;
443511b41d2SMark Murray 	case sPort:
444511b41d2SMark Murray 		/* ignore ports from configfile if cmdline specifies ports */
445511b41d2SMark Murray 		if (options->ports_from_cmdline)
446af12a3e7SDag-Erling Smørgrav 			return 0;
447511b41d2SMark Murray 		if (options->listen_addrs != NULL)
448511b41d2SMark Murray 			fatal("%s line %d: ports must be specified before "
449af12a3e7SDag-Erling Smørgrav 			    "ListenAddress.", filename, linenum);
450511b41d2SMark Murray 		if (options->num_ports >= MAX_PORTS)
451ca3176e7SBrian Feldman 			fatal("%s line %d: too many ports.",
452511b41d2SMark Murray 			    filename, linenum);
453c2d3a559SKris Kennaway 		arg = strdelim(&cp);
454c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
455ca3176e7SBrian Feldman 			fatal("%s line %d: missing port number.",
456511b41d2SMark Murray 			    filename, linenum);
457ca3176e7SBrian Feldman 		options->ports[options->num_ports++] = a2port(arg);
458ca3176e7SBrian Feldman 		if (options->ports[options->num_ports-1] == 0)
459ca3176e7SBrian Feldman 			fatal("%s line %d: Badly formatted port number.",
460ca3176e7SBrian Feldman 			    filename, linenum);
461511b41d2SMark Murray 		break;
462511b41d2SMark Murray 
463511b41d2SMark Murray 	case sServerKeyBits:
464511b41d2SMark Murray 		intptr = &options->server_key_bits;
465511b41d2SMark Murray parse_int:
466c2d3a559SKris Kennaway 		arg = strdelim(&cp);
467ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
468ca3176e7SBrian Feldman 			fatal("%s line %d: missing integer value.",
469511b41d2SMark Murray 			    filename, linenum);
470c2d3a559SKris Kennaway 		value = atoi(arg);
471511b41d2SMark Murray 		if (*intptr == -1)
472511b41d2SMark Murray 			*intptr = value;
473511b41d2SMark Murray 		break;
474511b41d2SMark Murray 
475511b41d2SMark Murray 	case sLoginGraceTime:
476511b41d2SMark Murray 		intptr = &options->login_grace_time;
477af12a3e7SDag-Erling Smørgrav parse_time:
478af12a3e7SDag-Erling Smørgrav 		arg = strdelim(&cp);
479af12a3e7SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
480af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: missing time value.",
481af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
482af12a3e7SDag-Erling Smørgrav 		if ((value = convtime(arg)) == -1)
483af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: invalid time value.",
484af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
485af12a3e7SDag-Erling Smørgrav 		if (*intptr == -1)
486af12a3e7SDag-Erling Smørgrav 			*intptr = value;
487af12a3e7SDag-Erling Smørgrav 		break;
488511b41d2SMark Murray 
489511b41d2SMark Murray 	case sKeyRegenerationTime:
490511b41d2SMark Murray 		intptr = &options->key_regeneration_time;
491af12a3e7SDag-Erling Smørgrav 		goto parse_time;
492511b41d2SMark Murray 
493511b41d2SMark Murray 	case sListenAddress:
494c2d3a559SKris Kennaway 		arg = strdelim(&cp);
495ca3176e7SBrian Feldman 		if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
496ca3176e7SBrian Feldman 			fatal("%s line %d: missing inet addr.",
497511b41d2SMark Murray 			    filename, linenum);
498ca3176e7SBrian Feldman 		if (*arg == '[') {
499ca3176e7SBrian Feldman 			if ((p = strchr(arg, ']')) == NULL)
500ca3176e7SBrian Feldman 				fatal("%s line %d: bad ipv6 inet addr usage.",
501ca3176e7SBrian Feldman 				    filename, linenum);
502ca3176e7SBrian Feldman 			arg++;
503ca3176e7SBrian Feldman 			memmove(p, p+1, strlen(p+1)+1);
504ca3176e7SBrian Feldman 		} else if (((p = strchr(arg, ':')) == NULL) ||
505ca3176e7SBrian Feldman 			    (strchr(p+1, ':') != NULL)) {
506ca3176e7SBrian Feldman 			add_listen_addr(options, arg, 0);
507ca3176e7SBrian Feldman 			break;
508ca3176e7SBrian Feldman 		}
509ca3176e7SBrian Feldman 		if (*p == ':') {
510ca3176e7SBrian Feldman 			u_short port;
511ca3176e7SBrian Feldman 
512ca3176e7SBrian Feldman 			p++;
513ca3176e7SBrian Feldman 			if (*p == '\0')
514ca3176e7SBrian Feldman 				fatal("%s line %d: bad inet addr:port usage.",
515ca3176e7SBrian Feldman 				    filename, linenum);
516ca3176e7SBrian Feldman 			else {
517ca3176e7SBrian Feldman 				*(p-1) = '\0';
518ca3176e7SBrian Feldman 				if ((port = a2port(p)) == 0)
519ca3176e7SBrian Feldman 					fatal("%s line %d: bad port number.",
520ca3176e7SBrian Feldman 					    filename, linenum);
521ca3176e7SBrian Feldman 				add_listen_addr(options, arg, port);
522ca3176e7SBrian Feldman 			}
523ca3176e7SBrian Feldman 		} else if (*p == '\0')
524ca3176e7SBrian Feldman 			add_listen_addr(options, arg, 0);
525ca3176e7SBrian Feldman 		else
526ca3176e7SBrian Feldman 			fatal("%s line %d: bad inet addr usage.",
527ca3176e7SBrian Feldman 			    filename, linenum);
528511b41d2SMark Murray 		break;
529511b41d2SMark Murray 
530511b41d2SMark Murray 	case sHostKeyFile:
531ca3176e7SBrian Feldman 		intptr = &options->num_host_key_files;
532ca3176e7SBrian Feldman 		if (*intptr >= MAX_HOSTKEYS)
533ca3176e7SBrian Feldman 			fatal("%s line %d: too many host keys specified (max %d).",
534ca3176e7SBrian Feldman 			    filename, linenum, MAX_HOSTKEYS);
535ca3176e7SBrian Feldman 		charptr = &options->host_key_files[*intptr];
536c2d3a559SKris Kennaway parse_filename:
537c2d3a559SKris Kennaway 		arg = strdelim(&cp);
538ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
539ca3176e7SBrian Feldman 			fatal("%s line %d: missing file name.",
540e8aafc91SKris Kennaway 			    filename, linenum);
541ca3176e7SBrian Feldman 		if (*charptr == NULL) {
542c2d3a559SKris Kennaway 			*charptr = tilde_expand_filename(arg, getuid());
543ca3176e7SBrian Feldman 			/* increase optional counter */
544ca3176e7SBrian Feldman 			if (intptr != NULL)
545ca3176e7SBrian Feldman 				*intptr = *intptr + 1;
546ca3176e7SBrian Feldman 		}
547e8aafc91SKris Kennaway 		break;
548e8aafc91SKris Kennaway 
549e8aafc91SKris Kennaway 	case sPidFile:
550e8aafc91SKris Kennaway 		charptr = &options->pid_file;
551c2d3a559SKris Kennaway 		goto parse_filename;
552511b41d2SMark Murray 
553511b41d2SMark Murray 	case sPermitRootLogin:
554511b41d2SMark Murray 		intptr = &options->permit_root_login;
555c2d3a559SKris Kennaway 		arg = strdelim(&cp);
556ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
557ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/"
558ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
559ca3176e7SBrian Feldman 			    "argument.", filename, linenum);
560ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
561c2d3a559SKris Kennaway 		if (strcmp(arg, "without-password") == 0)
562ca3176e7SBrian Feldman 			value = PERMIT_NO_PASSWD;
563ca3176e7SBrian Feldman 		else if (strcmp(arg, "forced-commands-only") == 0)
564ca3176e7SBrian Feldman 			value = PERMIT_FORCED_ONLY;
565c2d3a559SKris Kennaway 		else if (strcmp(arg, "yes") == 0)
566ca3176e7SBrian Feldman 			value = PERMIT_YES;
567c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
568ca3176e7SBrian Feldman 			value = PERMIT_NO;
569ca3176e7SBrian Feldman 		else
570ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/"
571ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
572ca3176e7SBrian Feldman 			    "argument: %s", filename, linenum, arg);
573511b41d2SMark Murray 		if (*intptr == -1)
574511b41d2SMark Murray 			*intptr = value;
575511b41d2SMark Murray 		break;
576511b41d2SMark Murray 
577511b41d2SMark Murray 	case sIgnoreRhosts:
578511b41d2SMark Murray 		intptr = &options->ignore_rhosts;
579511b41d2SMark Murray parse_flag:
580c2d3a559SKris Kennaway 		arg = strdelim(&cp);
581ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
582ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/no argument.",
583511b41d2SMark Murray 			    filename, linenum);
584ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
585c2d3a559SKris Kennaway 		if (strcmp(arg, "yes") == 0)
586511b41d2SMark Murray 			value = 1;
587c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
588511b41d2SMark Murray 			value = 0;
589ca3176e7SBrian Feldman 		else
590ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/no argument: %s",
591c2d3a559SKris Kennaway 				filename, linenum, arg);
592511b41d2SMark Murray 		if (*intptr == -1)
593511b41d2SMark Murray 			*intptr = value;
594511b41d2SMark Murray 		break;
595511b41d2SMark Murray 
596511b41d2SMark Murray 	case sIgnoreUserKnownHosts:
597511b41d2SMark Murray 		intptr = &options->ignore_user_known_hosts;
598962a3f4eSSheldon Hearn 		goto parse_flag;
599511b41d2SMark Murray 
600511b41d2SMark Murray 	case sRhostsAuthentication:
601511b41d2SMark Murray 		intptr = &options->rhosts_authentication;
602511b41d2SMark Murray 		goto parse_flag;
603511b41d2SMark Murray 
604511b41d2SMark Murray 	case sRhostsRSAAuthentication:
605511b41d2SMark Murray 		intptr = &options->rhosts_rsa_authentication;
606511b41d2SMark Murray 		goto parse_flag;
607511b41d2SMark Murray 
608ca3176e7SBrian Feldman 	case sHostbasedAuthentication:
609ca3176e7SBrian Feldman 		intptr = &options->hostbased_authentication;
610ca3176e7SBrian Feldman 		goto parse_flag;
611ca3176e7SBrian Feldman 
612ca3176e7SBrian Feldman 	case sHostbasedUsesNameFromPacketOnly:
613ca3176e7SBrian Feldman 		intptr = &options->hostbased_uses_name_from_packet_only;
614ca3176e7SBrian Feldman 		goto parse_flag;
615ca3176e7SBrian Feldman 
616511b41d2SMark Murray 	case sRSAAuthentication:
617511b41d2SMark Murray 		intptr = &options->rsa_authentication;
618511b41d2SMark Murray 		goto parse_flag;
619511b41d2SMark Murray 
620ca3176e7SBrian Feldman 	case sPubkeyAuthentication:
621ca3176e7SBrian Feldman 		intptr = &options->pubkey_authentication;
622e8aafc91SKris Kennaway 		goto parse_flag;
623cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
624cb96ab36SAssar Westerlund 	case sKerberosAuthentication:
625cb96ab36SAssar Westerlund 		intptr = &options->kerberos_authentication;
626511b41d2SMark Murray 		goto parse_flag;
627511b41d2SMark Murray 
628af12a3e7SDag-Erling Smørgrav 	case sKerberosOrLocalPasswd:
629af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_or_local_passwd;
630511b41d2SMark Murray 		goto parse_flag;
631511b41d2SMark Murray 
632af12a3e7SDag-Erling Smørgrav 	case sKerberosTicketCleanup:
633af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_ticket_cleanup;
634511b41d2SMark Murray 		goto parse_flag;
635511b41d2SMark Murray #endif
636af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
637af12a3e7SDag-Erling Smørgrav 	case sKerberosTgtPassing:
638af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_tgt_passing;
639fe5fd017SMark Murray 		goto parse_flag;
640af12a3e7SDag-Erling Smørgrav #endif
641511b41d2SMark Murray #ifdef AFS
642511b41d2SMark Murray 	case sAFSTokenPassing:
643511b41d2SMark Murray 		intptr = &options->afs_token_passing;
644511b41d2SMark Murray 		goto parse_flag;
645511b41d2SMark Murray #endif
646511b41d2SMark Murray 
647511b41d2SMark Murray 	case sPasswordAuthentication:
648511b41d2SMark Murray 		intptr = &options->password_authentication;
649511b41d2SMark Murray 		goto parse_flag;
650511b41d2SMark Murray 
65109958426SBrian Feldman 	case sKbdInteractiveAuthentication:
65209958426SBrian Feldman 		intptr = &options->kbd_interactive_authentication;
65309958426SBrian Feldman 		goto parse_flag;
65409958426SBrian Feldman 
655ca3176e7SBrian Feldman 	case sChallengeResponseAuthentication:
656af12a3e7SDag-Erling Smørgrav 		intptr = &options->challenge_response_authentication;
657511b41d2SMark Murray 		goto parse_flag;
658511b41d2SMark Murray 
659511b41d2SMark Murray 	case sPrintMotd:
660511b41d2SMark Murray 		intptr = &options->print_motd;
661511b41d2SMark Murray 		goto parse_flag;
662511b41d2SMark Murray 
663ca3176e7SBrian Feldman 	case sPrintLastLog:
664ca3176e7SBrian Feldman 		intptr = &options->print_lastlog;
665ca3176e7SBrian Feldman 		goto parse_flag;
666ca3176e7SBrian Feldman 
667511b41d2SMark Murray 	case sX11Forwarding:
668511b41d2SMark Murray 		intptr = &options->x11_forwarding;
669511b41d2SMark Murray 		goto parse_flag;
670511b41d2SMark Murray 
671511b41d2SMark Murray 	case sX11DisplayOffset:
672511b41d2SMark Murray 		intptr = &options->x11_display_offset;
673511b41d2SMark Murray 		goto parse_int;
674511b41d2SMark Murray 
675af12a3e7SDag-Erling Smørgrav 	case sX11UseLocalhost:
676af12a3e7SDag-Erling Smørgrav 		intptr = &options->x11_use_localhost;
677af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
678af12a3e7SDag-Erling Smørgrav 
679c2d3a559SKris Kennaway 	case sXAuthLocation:
680c2d3a559SKris Kennaway 		charptr = &options->xauth_location;
681c2d3a559SKris Kennaway 		goto parse_filename;
682c2d3a559SKris Kennaway 
683511b41d2SMark Murray 	case sStrictModes:
684511b41d2SMark Murray 		intptr = &options->strict_modes;
685511b41d2SMark Murray 		goto parse_flag;
686511b41d2SMark Murray 
687511b41d2SMark Murray 	case sKeepAlives:
688511b41d2SMark Murray 		intptr = &options->keepalives;
689511b41d2SMark Murray 		goto parse_flag;
690511b41d2SMark Murray 
691511b41d2SMark Murray 	case sEmptyPasswd:
692511b41d2SMark Murray 		intptr = &options->permit_empty_passwd;
693511b41d2SMark Murray 		goto parse_flag;
694511b41d2SMark Murray 
695511b41d2SMark Murray 	case sUseLogin:
696511b41d2SMark Murray 		intptr = &options->use_login;
697511b41d2SMark Murray 		goto parse_flag;
698511b41d2SMark Murray 
69980628bacSDag-Erling Smørgrav 	case sCompression:
70080628bacSDag-Erling Smørgrav 		intptr = &options->compression;
70180628bacSDag-Erling Smørgrav 		goto parse_flag;
70280628bacSDag-Erling Smørgrav 
703e8aafc91SKris Kennaway 	case sGatewayPorts:
704e8aafc91SKris Kennaway 		intptr = &options->gateway_ports;
705e8aafc91SKris Kennaway 		goto parse_flag;
706e8aafc91SKris Kennaway 
707af12a3e7SDag-Erling Smørgrav 	case sVerifyReverseMapping:
708af12a3e7SDag-Erling Smørgrav 		intptr = &options->verify_reverse_mapping;
709ca3176e7SBrian Feldman 		goto parse_flag;
710ca3176e7SBrian Feldman 
711511b41d2SMark Murray 	case sLogFacility:
712511b41d2SMark Murray 		intptr = (int *) &options->log_facility;
713c2d3a559SKris Kennaway 		arg = strdelim(&cp);
714c2d3a559SKris Kennaway 		value = log_facility_number(arg);
715af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_FACILITY_NOT_SET)
716ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log facility '%s'",
717c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
718511b41d2SMark Murray 		if (*intptr == -1)
719511b41d2SMark Murray 			*intptr = (SyslogFacility) value;
720511b41d2SMark Murray 		break;
721511b41d2SMark Murray 
722511b41d2SMark Murray 	case sLogLevel:
723511b41d2SMark Murray 		intptr = (int *) &options->log_level;
724c2d3a559SKris Kennaway 		arg = strdelim(&cp);
725c2d3a559SKris Kennaway 		value = log_level_number(arg);
726af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_LEVEL_NOT_SET)
727ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log level '%s'",
728c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
729511b41d2SMark Murray 		if (*intptr == -1)
730511b41d2SMark Murray 			*intptr = (LogLevel) value;
731511b41d2SMark Murray 		break;
732511b41d2SMark Murray 
73309958426SBrian Feldman 	case sAllowTcpForwarding:
73409958426SBrian Feldman 		intptr = &options->allow_tcp_forwarding;
73509958426SBrian Feldman 		goto parse_flag;
73609958426SBrian Feldman 
73780628bacSDag-Erling Smørgrav 	case sUsePrivilegeSeparation:
73880628bacSDag-Erling Smørgrav 		intptr = &use_privsep;
73980628bacSDag-Erling Smørgrav 		goto parse_flag;
74080628bacSDag-Erling Smørgrav 
741511b41d2SMark Murray 	case sAllowUsers:
742c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
74342f71286SMark Murray 			if (options->num_allow_users >= MAX_ALLOW_USERS)
744af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow users.",
745e8aafc91SKris Kennaway 				    filename, linenum);
746c2d3a559SKris Kennaway 			options->allow_users[options->num_allow_users++] = xstrdup(arg);
747511b41d2SMark Murray 		}
748511b41d2SMark Murray 		break;
749511b41d2SMark Murray 
750511b41d2SMark Murray 	case sDenyUsers:
751c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
7522803b77eSBrian Feldman 			if (options->num_deny_users >= MAX_DENY_USERS)
753af12a3e7SDag-Erling Smørgrav 				fatal( "%s line %d: too many deny users.",
754e8aafc91SKris Kennaway 				    filename, linenum);
755c2d3a559SKris Kennaway 			options->deny_users[options->num_deny_users++] = xstrdup(arg);
756511b41d2SMark Murray 		}
757511b41d2SMark Murray 		break;
758511b41d2SMark Murray 
759511b41d2SMark Murray 	case sAllowGroups:
760c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
76142f71286SMark Murray 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
762af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow groups.",
763e8aafc91SKris Kennaway 				    filename, linenum);
764c2d3a559SKris Kennaway 			options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
765511b41d2SMark Murray 		}
766511b41d2SMark Murray 		break;
767511b41d2SMark Murray 
768511b41d2SMark Murray 	case sDenyGroups:
769c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
77042f71286SMark Murray 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
771af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many deny groups.",
772e8aafc91SKris Kennaway 				    filename, linenum);
773c2d3a559SKris Kennaway 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
774511b41d2SMark Murray 		}
775511b41d2SMark Murray 		break;
776511b41d2SMark Murray 
777e8aafc91SKris Kennaway 	case sCiphers:
778c2d3a559SKris Kennaway 		arg = strdelim(&cp);
779c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
780c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
781c2d3a559SKris Kennaway 		if (!ciphers_valid(arg))
782e8aafc91SKris Kennaway 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
783c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
784e8aafc91SKris Kennaway 		if (options->ciphers == NULL)
785c2d3a559SKris Kennaway 			options->ciphers = xstrdup(arg);
786e8aafc91SKris Kennaway 		break;
787e8aafc91SKris Kennaway 
788ca3176e7SBrian Feldman 	case sMacs:
789ca3176e7SBrian Feldman 		arg = strdelim(&cp);
790ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
791ca3176e7SBrian Feldman 			fatal("%s line %d: Missing argument.", filename, linenum);
792ca3176e7SBrian Feldman 		if (!mac_valid(arg))
793ca3176e7SBrian Feldman 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
794ca3176e7SBrian Feldman 			    filename, linenum, arg ? arg : "<NONE>");
795ca3176e7SBrian Feldman 		if (options->macs == NULL)
796ca3176e7SBrian Feldman 			options->macs = xstrdup(arg);
797ca3176e7SBrian Feldman 		break;
798ca3176e7SBrian Feldman 
799e8aafc91SKris Kennaway 	case sProtocol:
800e8aafc91SKris Kennaway 		intptr = &options->protocol;
801c2d3a559SKris Kennaway 		arg = strdelim(&cp);
802c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
803c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
804c2d3a559SKris Kennaway 		value = proto_spec(arg);
805e8aafc91SKris Kennaway 		if (value == SSH_PROTO_UNKNOWN)
806e8aafc91SKris Kennaway 			fatal("%s line %d: Bad protocol spec '%s'.",
807c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
808e8aafc91SKris Kennaway 		if (*intptr == SSH_PROTO_UNKNOWN)
809e8aafc91SKris Kennaway 			*intptr = value;
810e8aafc91SKris Kennaway 		break;
811e8aafc91SKris Kennaway 
812c2d3a559SKris Kennaway 	case sSubsystem:
813c2d3a559SKris Kennaway 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
814c2d3a559SKris Kennaway 			fatal("%s line %d: too many subsystems defined.",
815c2d3a559SKris Kennaway 			    filename, linenum);
816c2d3a559SKris Kennaway 		}
817c2d3a559SKris Kennaway 		arg = strdelim(&cp);
818c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
819c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem name.",
820c2d3a559SKris Kennaway 			    filename, linenum);
821c2d3a559SKris Kennaway 		for (i = 0; i < options->num_subsystems; i++)
822c2d3a559SKris Kennaway 			if (strcmp(arg, options->subsystem_name[i]) == 0)
823c2d3a559SKris Kennaway 				fatal("%s line %d: Subsystem '%s' already defined.",
824c2d3a559SKris Kennaway 				    filename, linenum, arg);
825c2d3a559SKris Kennaway 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
826c2d3a559SKris Kennaway 		arg = strdelim(&cp);
827c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
828c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem command.",
829c2d3a559SKris Kennaway 			    filename, linenum);
830c2d3a559SKris Kennaway 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
831c2d3a559SKris Kennaway 		options->num_subsystems++;
832c2d3a559SKris Kennaway 		break;
833c2d3a559SKris Kennaway 
834c2d3a559SKris Kennaway 	case sMaxStartups:
835c2d3a559SKris Kennaway 		arg = strdelim(&cp);
836c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
837c2d3a559SKris Kennaway 			fatal("%s line %d: Missing MaxStartups spec.",
838c2d3a559SKris Kennaway 			    filename, linenum);
839af12a3e7SDag-Erling Smørgrav 		if ((n = sscanf(arg, "%d:%d:%d",
840c2d3a559SKris Kennaway 		    &options->max_startups_begin,
841c2d3a559SKris Kennaway 		    &options->max_startups_rate,
842af12a3e7SDag-Erling Smørgrav 		    &options->max_startups)) == 3) {
843c2d3a559SKris Kennaway 			if (options->max_startups_begin >
844c2d3a559SKris Kennaway 			    options->max_startups ||
845c2d3a559SKris Kennaway 			    options->max_startups_rate > 100 ||
846c2d3a559SKris Kennaway 			    options->max_startups_rate < 1)
847c2d3a559SKris Kennaway 				fatal("%s line %d: Illegal MaxStartups spec.",
848c2d3a559SKris Kennaway 				    filename, linenum);
849af12a3e7SDag-Erling Smørgrav 		} else if (n != 1)
850af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: Illegal MaxStartups spec.",
851af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
852af12a3e7SDag-Erling Smørgrav 		else
853af12a3e7SDag-Erling Smørgrav 			options->max_startups = options->max_startups_begin;
854933ca70fSBrian Feldman 		break;
855933ca70fSBrian Feldman 
856ca3176e7SBrian Feldman 	case sBanner:
857ca3176e7SBrian Feldman 		charptr = &options->banner;
858ca3176e7SBrian Feldman 		goto parse_filename;
859af12a3e7SDag-Erling Smørgrav 	/*
860af12a3e7SDag-Erling Smørgrav 	 * These options can contain %X options expanded at
861af12a3e7SDag-Erling Smørgrav 	 * connect time, so that you can specify paths like:
862af12a3e7SDag-Erling Smørgrav 	 *
863af12a3e7SDag-Erling Smørgrav 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
864af12a3e7SDag-Erling Smørgrav 	 */
865af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile:
866af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile2:
867af12a3e7SDag-Erling Smørgrav 		charptr = (opcode == sAuthorizedKeysFile ) ?
868af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file :
869af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file2;
870af12a3e7SDag-Erling Smørgrav 		goto parse_filename;
871af12a3e7SDag-Erling Smørgrav 
872ca3176e7SBrian Feldman 	case sClientAliveInterval:
873ca3176e7SBrian Feldman 		intptr = &options->client_alive_interval;
874af12a3e7SDag-Erling Smørgrav 		goto parse_time;
875af12a3e7SDag-Erling Smørgrav 
876ca3176e7SBrian Feldman 	case sClientAliveCountMax:
877ca3176e7SBrian Feldman 		intptr = &options->client_alive_count_max;
878ca3176e7SBrian Feldman 		goto parse_int;
879af12a3e7SDag-Erling Smørgrav 
880af12a3e7SDag-Erling Smørgrav 	case sDeprecated:
881af12a3e7SDag-Erling Smørgrav 		log("%s line %d: Deprecated option %s",
882af12a3e7SDag-Erling Smørgrav 		    filename, linenum, arg);
883af12a3e7SDag-Erling Smørgrav 		while (arg)
884af12a3e7SDag-Erling Smørgrav 		    arg = strdelim(&cp);
885af12a3e7SDag-Erling Smørgrav 		break;
886af12a3e7SDag-Erling Smørgrav 
887af12a3e7SDag-Erling Smørgrav 	case sCheckMail:
888af12a3e7SDag-Erling Smørgrav 		intptr = &options->check_mail;
889af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
890af12a3e7SDag-Erling Smørgrav 
891af12a3e7SDag-Erling Smørgrav 	case sVersionAddendum:
892af12a3e7SDag-Erling Smørgrav 		ssh_version_set_addendum(strtok(cp, "\n"));
893af12a3e7SDag-Erling Smørgrav 		do {
894af12a3e7SDag-Erling Smørgrav 			arg = strdelim(&cp);
895af12a3e7SDag-Erling Smørgrav 		} while (arg != NULL && *arg != '\0');
896af12a3e7SDag-Erling Smørgrav 		break;
897af12a3e7SDag-Erling Smørgrav 
89842f71286SMark Murray 	default:
899af12a3e7SDag-Erling Smørgrav 		fatal("%s line %d: Missing handler for opcode %s (%d)",
900c2d3a559SKris Kennaway 		    filename, linenum, arg, opcode);
901511b41d2SMark Murray 	}
902ca3176e7SBrian Feldman 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
903ca3176e7SBrian Feldman 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
904c2d3a559SKris Kennaway 		    filename, linenum, arg);
905af12a3e7SDag-Erling Smørgrav 	return 0;
906af12a3e7SDag-Erling Smørgrav }
907af12a3e7SDag-Erling Smørgrav 
908af12a3e7SDag-Erling Smørgrav /* Reads the server configuration file. */
909af12a3e7SDag-Erling Smørgrav 
910af12a3e7SDag-Erling Smørgrav void
911af12a3e7SDag-Erling Smørgrav read_server_config(ServerOptions *options, const char *filename)
912af12a3e7SDag-Erling Smørgrav {
913af12a3e7SDag-Erling Smørgrav 	FILE *f;
914af12a3e7SDag-Erling Smørgrav 	char line[1024];
915af12a3e7SDag-Erling Smørgrav 	int linenum;
916af12a3e7SDag-Erling Smørgrav 	int bad_options = 0;
917af12a3e7SDag-Erling Smørgrav 
918af12a3e7SDag-Erling Smørgrav 	f = fopen(filename, "r");
919af12a3e7SDag-Erling Smørgrav 	if (!f) {
920af12a3e7SDag-Erling Smørgrav 		perror(filename);
921af12a3e7SDag-Erling Smørgrav 		exit(1);
922af12a3e7SDag-Erling Smørgrav 	}
923af12a3e7SDag-Erling Smørgrav 	linenum = 0;
924af12a3e7SDag-Erling Smørgrav 	while (fgets(line, sizeof(line), f)) {
925af12a3e7SDag-Erling Smørgrav 		/* Update line number counter. */
926af12a3e7SDag-Erling Smørgrav 		linenum++;
927af12a3e7SDag-Erling Smørgrav 		if (process_server_config_line(options, line, filename, linenum) != 0)
928af12a3e7SDag-Erling Smørgrav 			bad_options++;
929511b41d2SMark Murray 	}
930511b41d2SMark Murray 	fclose(f);
931ca3176e7SBrian Feldman 	if (bad_options > 0)
932af12a3e7SDag-Erling Smørgrav 		fatal("%s: terminating, %d bad configuration options",
933511b41d2SMark Murray 		    filename, bad_options);
934511b41d2SMark Murray }
935