xref: /freebsd/crypto/openssh/servconf.c (revision db58a8e40ce0ed8b27d51fd274ab609b18d74273)
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 $");
14511b41d2SMark Murray 
151d9e2b0aSDag-Erling Smørgrav #if defined(KRB4)
16ca3176e7SBrian Feldman #include <krb.h>
17ca3176e7SBrian Feldman #endif
181d9e2b0aSDag-Erling Smørgrav #if defined(KRB5)
19989dd127SDag-Erling Smørgrav #ifdef HEIMDAL
20989dd127SDag-Erling Smørgrav #include <krb.h>
21989dd127SDag-Erling Smørgrav #else
22989dd127SDag-Erling Smørgrav /* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V
23989dd127SDag-Erling Smørgrav  * keytab */
24989dd127SDag-Erling Smørgrav #define KEYFILE "/etc/krb5.keytab"
25989dd127SDag-Erling Smørgrav #endif
261d9e2b0aSDag-Erling Smørgrav #endif
27ca3176e7SBrian Feldman #ifdef AFS
28ca3176e7SBrian Feldman #include <kafs.h>
29ca3176e7SBrian Feldman #endif
30ca3176e7SBrian Feldman 
31511b41d2SMark Murray #include "ssh.h"
32ca3176e7SBrian Feldman #include "log.h"
33511b41d2SMark Murray #include "servconf.h"
34511b41d2SMark Murray #include "xmalloc.h"
35e8aafc91SKris Kennaway #include "compat.h"
36ca3176e7SBrian Feldman #include "pathnames.h"
37ca3176e7SBrian Feldman #include "tildexpand.h"
38ca3176e7SBrian Feldman #include "misc.h"
39ca3176e7SBrian Feldman #include "cipher.h"
40ca3176e7SBrian Feldman #include "kex.h"
41ca3176e7SBrian Feldman #include "mac.h"
42511b41d2SMark Murray 
43af12a3e7SDag-Erling Smørgrav static void add_listen_addr(ServerOptions *, char *, u_short);
44af12a3e7SDag-Erling Smørgrav static void add_one_listen_addr(ServerOptions *, char *, u_short);
45ca3176e7SBrian Feldman 
46ca3176e7SBrian Feldman /* AF_UNSPEC or AF_INET or AF_INET6 */
47ca3176e7SBrian Feldman extern int IPv4or6;
4880628bacSDag-Erling Smørgrav /* Use of privilege separation or not */
4980628bacSDag-Erling Smørgrav extern int use_privsep;
50511b41d2SMark Murray 
51511b41d2SMark Murray /* Initializes the server options to their default values. */
52511b41d2SMark Murray 
53511b41d2SMark Murray void
54511b41d2SMark Murray initialize_server_options(ServerOptions *options)
55511b41d2SMark Murray {
56511b41d2SMark Murray 	memset(options, 0, sizeof(*options));
57989dd127SDag-Erling Smørgrav 
58989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
59989dd127SDag-Erling Smørgrav 	options->pam_authentication_via_kbd_int = -1;
60989dd127SDag-Erling Smørgrav 
61989dd127SDag-Erling Smørgrav 	/* Standard Options */
62511b41d2SMark Murray 	options->num_ports = 0;
63511b41d2SMark Murray 	options->ports_from_cmdline = 0;
64511b41d2SMark Murray 	options->listen_addrs = NULL;
65ca3176e7SBrian Feldman 	options->num_host_key_files = 0;
66e8aafc91SKris Kennaway 	options->pid_file = NULL;
67511b41d2SMark Murray 	options->server_key_bits = -1;
68511b41d2SMark Murray 	options->login_grace_time = -1;
69511b41d2SMark Murray 	options->key_regeneration_time = -1;
70ca3176e7SBrian Feldman 	options->permit_root_login = PERMIT_NOT_SET;
71511b41d2SMark Murray 	options->ignore_rhosts = -1;
72511b41d2SMark Murray 	options->ignore_user_known_hosts = -1;
73511b41d2SMark Murray 	options->print_motd = -1;
74ca3176e7SBrian Feldman 	options->print_lastlog = -1;
75511b41d2SMark Murray 	options->x11_forwarding = -1;
76511b41d2SMark Murray 	options->x11_display_offset = -1;
77af12a3e7SDag-Erling Smørgrav 	options->x11_use_localhost = -1;
78c2d3a559SKris Kennaway 	options->xauth_location = NULL;
79511b41d2SMark Murray 	options->strict_modes = -1;
80511b41d2SMark Murray 	options->keepalives = -1;
81af12a3e7SDag-Erling Smørgrav 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
82af12a3e7SDag-Erling Smørgrav 	options->log_level = SYSLOG_LEVEL_NOT_SET;
83511b41d2SMark Murray 	options->rhosts_authentication = -1;
84511b41d2SMark Murray 	options->rhosts_rsa_authentication = -1;
85ca3176e7SBrian Feldman 	options->hostbased_authentication = -1;
86ca3176e7SBrian Feldman 	options->hostbased_uses_name_from_packet_only = -1;
87511b41d2SMark Murray 	options->rsa_authentication = -1;
88ca3176e7SBrian Feldman 	options->pubkey_authentication = -1;
89cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
90cb96ab36SAssar Westerlund 	options->kerberos_authentication = -1;
91af12a3e7SDag-Erling Smørgrav 	options->kerberos_or_local_passwd = -1;
92af12a3e7SDag-Erling Smørgrav 	options->kerberos_ticket_cleanup = -1;
93cb96ab36SAssar Westerlund #endif
94af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
95af12a3e7SDag-Erling Smørgrav 	options->kerberos_tgt_passing = -1;
96511b41d2SMark Murray #endif
97511b41d2SMark Murray #ifdef AFS
98511b41d2SMark Murray 	options->afs_token_passing = -1;
99511b41d2SMark Murray #endif
100511b41d2SMark Murray 	options->password_authentication = -1;
10109958426SBrian Feldman 	options->kbd_interactive_authentication = -1;
102af12a3e7SDag-Erling Smørgrav 	options->challenge_response_authentication = -1;
103511b41d2SMark Murray 	options->permit_empty_passwd = -1;
104511b41d2SMark Murray 	options->use_login = -1;
10580628bacSDag-Erling Smørgrav 	options->compression = -1;
10609958426SBrian Feldman 	options->allow_tcp_forwarding = -1;
107511b41d2SMark Murray 	options->num_allow_users = 0;
108511b41d2SMark Murray 	options->num_deny_users = 0;
109511b41d2SMark Murray 	options->num_allow_groups = 0;
110511b41d2SMark Murray 	options->num_deny_groups = 0;
111e8aafc91SKris Kennaway 	options->ciphers = NULL;
112ca3176e7SBrian Feldman 	options->macs = NULL;
113e8aafc91SKris Kennaway 	options->protocol = SSH_PROTO_UNKNOWN;
114e8aafc91SKris Kennaway 	options->gateway_ports = -1;
115c2d3a559SKris Kennaway 	options->num_subsystems = 0;
116c2d3a559SKris Kennaway 	options->max_startups_begin = -1;
117c2d3a559SKris Kennaway 	options->max_startups_rate = -1;
118c2d3a559SKris Kennaway 	options->max_startups = -1;
119ca3176e7SBrian Feldman 	options->banner = NULL;
120af12a3e7SDag-Erling Smørgrav 	options->verify_reverse_mapping = -1;
121ca3176e7SBrian Feldman 	options->client_alive_interval = -1;
122ca3176e7SBrian Feldman 	options->client_alive_count_max = -1;
123af12a3e7SDag-Erling Smørgrav 	options->authorized_keys_file = NULL;
124af12a3e7SDag-Erling Smørgrav 	options->authorized_keys_file2 = NULL;
12580628bacSDag-Erling Smørgrav 
12680628bacSDag-Erling Smørgrav 	/* Needs to be accessable in many places */
12780628bacSDag-Erling Smørgrav 	use_privsep = -1;
128511b41d2SMark Murray }
129511b41d2SMark Murray 
130511b41d2SMark Murray void
131511b41d2SMark Murray fill_default_server_options(ServerOptions *options)
132511b41d2SMark Murray {
133989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
134989dd127SDag-Erling Smørgrav 	if (options->pam_authentication_via_kbd_int == -1)
135989dd127SDag-Erling Smørgrav 		options->pam_authentication_via_kbd_int = 0;
136989dd127SDag-Erling Smørgrav 
137989dd127SDag-Erling Smørgrav 	/* Standard Options */
138ca3176e7SBrian Feldman 	if (options->protocol == SSH_PROTO_UNKNOWN)
139ca3176e7SBrian Feldman 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
140ca3176e7SBrian Feldman 	if (options->num_host_key_files == 0) {
141ca3176e7SBrian Feldman 		/* fill default hostkeys for protocols */
142ca3176e7SBrian Feldman 		if (options->protocol & SSH_PROTO_1)
143af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
144af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_KEY_FILE;
145af12a3e7SDag-Erling Smørgrav 		if (options->protocol & SSH_PROTO_2) {
146af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
147989dd127SDag-Erling Smørgrav 			    _PATH_HOST_RSA_KEY_FILE;
148989dd127SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
149af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_DSA_KEY_FILE;
150af12a3e7SDag-Erling Smørgrav 		}
151ca3176e7SBrian Feldman 	}
152511b41d2SMark Murray 	if (options->num_ports == 0)
153511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
154511b41d2SMark Murray 	if (options->listen_addrs == NULL)
155ca3176e7SBrian Feldman 		add_listen_addr(options, NULL, 0);
156e8aafc91SKris Kennaway 	if (options->pid_file == NULL)
157ca3176e7SBrian Feldman 		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
158511b41d2SMark Murray 	if (options->server_key_bits == -1)
159511b41d2SMark Murray 		options->server_key_bits = 768;
160511b41d2SMark Murray 	if (options->login_grace_time == -1)
161989dd127SDag-Erling Smørgrav 		options->login_grace_time = 600;
162511b41d2SMark Murray 	if (options->key_regeneration_time == -1)
163511b41d2SMark Murray 		options->key_regeneration_time = 3600;
164ca3176e7SBrian Feldman 	if (options->permit_root_login == PERMIT_NOT_SET)
165989dd127SDag-Erling Smørgrav 		options->permit_root_login = PERMIT_YES;
166511b41d2SMark Murray 	if (options->ignore_rhosts == -1)
167fe5fd017SMark Murray 		options->ignore_rhosts = 1;
168511b41d2SMark Murray 	if (options->ignore_user_known_hosts == -1)
169511b41d2SMark Murray 		options->ignore_user_known_hosts = 0;
170511b41d2SMark Murray 	if (options->print_motd == -1)
171511b41d2SMark Murray 		options->print_motd = 1;
172ca3176e7SBrian Feldman 	if (options->print_lastlog == -1)
173ca3176e7SBrian Feldman 		options->print_lastlog = 1;
174511b41d2SMark Murray 	if (options->x11_forwarding == -1)
175989dd127SDag-Erling Smørgrav 		options->x11_forwarding = 0;
176511b41d2SMark Murray 	if (options->x11_display_offset == -1)
177fe5fd017SMark Murray 		options->x11_display_offset = 10;
178af12a3e7SDag-Erling Smørgrav 	if (options->x11_use_localhost == -1)
179af12a3e7SDag-Erling Smørgrav 		options->x11_use_localhost = 1;
180c2d3a559SKris Kennaway 	if (options->xauth_location == NULL)
181af12a3e7SDag-Erling Smørgrav 		options->xauth_location = _PATH_XAUTH;
182511b41d2SMark Murray 	if (options->strict_modes == -1)
183511b41d2SMark Murray 		options->strict_modes = 1;
184511b41d2SMark Murray 	if (options->keepalives == -1)
185511b41d2SMark Murray 		options->keepalives = 1;
186af12a3e7SDag-Erling Smørgrav 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
187511b41d2SMark Murray 		options->log_facility = SYSLOG_FACILITY_AUTH;
188af12a3e7SDag-Erling Smørgrav 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
189511b41d2SMark Murray 		options->log_level = SYSLOG_LEVEL_INFO;
190511b41d2SMark Murray 	if (options->rhosts_authentication == -1)
191511b41d2SMark Murray 		options->rhosts_authentication = 0;
192511b41d2SMark Murray 	if (options->rhosts_rsa_authentication == -1)
193fe5fd017SMark Murray 		options->rhosts_rsa_authentication = 0;
194ca3176e7SBrian Feldman 	if (options->hostbased_authentication == -1)
195ca3176e7SBrian Feldman 		options->hostbased_authentication = 0;
196ca3176e7SBrian Feldman 	if (options->hostbased_uses_name_from_packet_only == -1)
197ca3176e7SBrian Feldman 		options->hostbased_uses_name_from_packet_only = 0;
198511b41d2SMark Murray 	if (options->rsa_authentication == -1)
199511b41d2SMark Murray 		options->rsa_authentication = 1;
200ca3176e7SBrian Feldman 	if (options->pubkey_authentication == -1)
201ca3176e7SBrian Feldman 		options->pubkey_authentication = 1;
2021d9e2b0aSDag-Erling Smørgrav #if defined(KRB4) || defined(KRB5)
203989dd127SDag-Erling Smørgrav 	if (options->kerberos_authentication == -1)
204989dd127SDag-Erling Smørgrav 		options->kerberos_authentication = 0;
205af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_or_local_passwd == -1)
206af12a3e7SDag-Erling Smørgrav 		options->kerberos_or_local_passwd = 1;
207af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_ticket_cleanup == -1)
208af12a3e7SDag-Erling Smørgrav 		options->kerberos_ticket_cleanup = 1;
209cb96ab36SAssar Westerlund #endif
210af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
211af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_tgt_passing == -1)
212af12a3e7SDag-Erling Smørgrav 		options->kerberos_tgt_passing = 0;
213af12a3e7SDag-Erling Smørgrav #endif
214511b41d2SMark Murray #ifdef AFS
215511b41d2SMark Murray 	if (options->afs_token_passing == -1)
21680628bacSDag-Erling Smørgrav 		options->afs_token_passing = 0;
217af12a3e7SDag-Erling Smørgrav #endif
218511b41d2SMark Murray 	if (options->password_authentication == -1)
219511b41d2SMark Murray 		options->password_authentication = 1;
22009958426SBrian Feldman 	if (options->kbd_interactive_authentication == -1)
22109958426SBrian Feldman 		options->kbd_interactive_authentication = 0;
222af12a3e7SDag-Erling Smørgrav 	if (options->challenge_response_authentication == -1)
22380241871SDag-Erling Smørgrav 		options->challenge_response_authentication = 1;
224511b41d2SMark Murray 	if (options->permit_empty_passwd == -1)
225fe5fd017SMark Murray 		options->permit_empty_passwd = 0;
226511b41d2SMark Murray 	if (options->use_login == -1)
227511b41d2SMark Murray 		options->use_login = 0;
22880628bacSDag-Erling Smørgrav 	if (options->compression == -1)
22980628bacSDag-Erling Smørgrav 		options->compression = 1;
23009958426SBrian Feldman 	if (options->allow_tcp_forwarding == -1)
23109958426SBrian Feldman 		options->allow_tcp_forwarding = 1;
232e8aafc91SKris Kennaway 	if (options->gateway_ports == -1)
233e8aafc91SKris Kennaway 		options->gateway_ports = 0;
234c2d3a559SKris Kennaway 	if (options->max_startups == -1)
235c2d3a559SKris Kennaway 		options->max_startups = 10;
236c2d3a559SKris Kennaway 	if (options->max_startups_rate == -1)
237c2d3a559SKris Kennaway 		options->max_startups_rate = 100;		/* 100% */
238c2d3a559SKris Kennaway 	if (options->max_startups_begin == -1)
239c2d3a559SKris Kennaway 		options->max_startups_begin = options->max_startups;
240af12a3e7SDag-Erling Smørgrav 	if (options->verify_reverse_mapping == -1)
241af12a3e7SDag-Erling Smørgrav 		options->verify_reverse_mapping = 0;
242ca3176e7SBrian Feldman 	if (options->client_alive_interval == -1)
243ca3176e7SBrian Feldman 		options->client_alive_interval = 0;
244ca3176e7SBrian Feldman 	if (options->client_alive_count_max == -1)
245ca3176e7SBrian Feldman 		options->client_alive_count_max = 3;
246af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file2 == NULL) {
247af12a3e7SDag-Erling Smørgrav 		/* authorized_keys_file2 falls back to authorized_keys_file */
248af12a3e7SDag-Erling Smørgrav 		if (options->authorized_keys_file != NULL)
249af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = options->authorized_keys_file;
250af12a3e7SDag-Erling Smørgrav 		else
251af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
252af12a3e7SDag-Erling Smørgrav 	}
253af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file == NULL)
254af12a3e7SDag-Erling Smørgrav 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
25580628bacSDag-Erling Smørgrav 
256989dd127SDag-Erling Smørgrav 	/* Turn privilege separation on by default */
25780628bacSDag-Erling Smørgrav 	if (use_privsep == -1)
258989dd127SDag-Erling Smørgrav 		use_privsep = 1;
259989dd127SDag-Erling Smørgrav 
260989dd127SDag-Erling Smørgrav #if !defined(HAVE_MMAP) || !defined(MAP_ANON)
261989dd127SDag-Erling Smørgrav 	if (use_privsep && options->compression == 1) {
262989dd127SDag-Erling Smørgrav 		error("This platform does not support both privilege "
263989dd127SDag-Erling Smørgrav 		    "separation and compression");
264989dd127SDag-Erling Smørgrav 		error("Compression disabled");
265989dd127SDag-Erling Smørgrav 		options->compression = 0;
266989dd127SDag-Erling Smørgrav 	}
267989dd127SDag-Erling Smørgrav #endif
268989dd127SDag-Erling Smørgrav 
269511b41d2SMark Murray }
270511b41d2SMark Murray 
271511b41d2SMark Murray /* Keyword tokens. */
272511b41d2SMark Murray typedef enum {
273511b41d2SMark Murray 	sBadOption,		/* == unknown option */
274989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
275989dd127SDag-Erling Smørgrav 	sPAMAuthenticationViaKbdInt,
276989dd127SDag-Erling Smørgrav 	/* Standard Options */
277511b41d2SMark Murray 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
278511b41d2SMark Murray 	sPermitRootLogin, sLogFacility, sLogLevel,
279511b41d2SMark Murray 	sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
280cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
281af12a3e7SDag-Erling Smørgrav 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
282cb96ab36SAssar Westerlund #endif
283af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
284af12a3e7SDag-Erling Smørgrav 	sKerberosTgtPassing,
285511b41d2SMark Murray #endif
286511b41d2SMark Murray #ifdef AFS
287af12a3e7SDag-Erling Smørgrav 	sAFSTokenPassing,
288511b41d2SMark Murray #endif
289ca3176e7SBrian Feldman 	sChallengeResponseAuthentication,
29009958426SBrian Feldman 	sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
291ca3176e7SBrian Feldman 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
292af12a3e7SDag-Erling Smørgrav 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
293af12a3e7SDag-Erling Smørgrav 	sStrictModes, sEmptyPasswd, sKeepAlives,
29480628bacSDag-Erling Smørgrav 	sUseLogin, sAllowTcpForwarding, sCompression,
29509958426SBrian Feldman 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
296ca3176e7SBrian Feldman 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
297ca3176e7SBrian Feldman 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
298af12a3e7SDag-Erling Smørgrav 	sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
299ca3176e7SBrian Feldman 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
300af12a3e7SDag-Erling Smørgrav 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
30180628bacSDag-Erling Smørgrav 	sUsePrivilegeSeparation,
302db58a8e4SDag-Erling Smørgrav 	sVersionAddendum,
303af12a3e7SDag-Erling Smørgrav 	sDeprecated
304511b41d2SMark Murray } ServerOpCodes;
305511b41d2SMark Murray 
306511b41d2SMark Murray /* Textual representation of the tokens. */
307511b41d2SMark Murray static struct {
308511b41d2SMark Murray 	const char *name;
309511b41d2SMark Murray 	ServerOpCodes opcode;
310511b41d2SMark Murray } keywords[] = {
311989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
312989dd127SDag-Erling Smørgrav 	{ "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt },
313989dd127SDag-Erling Smørgrav 	/* Standard Options */
314511b41d2SMark Murray 	{ "port", sPort },
315511b41d2SMark Murray 	{ "hostkey", sHostKeyFile },
316ca3176e7SBrian Feldman 	{ "hostdsakey", sHostKeyFile },					/* alias */
317e8aafc91SKris Kennaway 	{ "pidfile", sPidFile },
318511b41d2SMark Murray 	{ "serverkeybits", sServerKeyBits },
319511b41d2SMark Murray 	{ "logingracetime", sLoginGraceTime },
320511b41d2SMark Murray 	{ "keyregenerationinterval", sKeyRegenerationTime },
321511b41d2SMark Murray 	{ "permitrootlogin", sPermitRootLogin },
322511b41d2SMark Murray 	{ "syslogfacility", sLogFacility },
323511b41d2SMark Murray 	{ "loglevel", sLogLevel },
324511b41d2SMark Murray 	{ "rhostsauthentication", sRhostsAuthentication },
325511b41d2SMark Murray 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
326ca3176e7SBrian Feldman 	{ "hostbasedauthentication", sHostbasedAuthentication },
327ca3176e7SBrian Feldman 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
328af12a3e7SDag-Erling Smørgrav 	{ "rsaauthentication", sRSAAuthentication },
329ca3176e7SBrian Feldman 	{ "pubkeyauthentication", sPubkeyAuthentication },
330ca3176e7SBrian Feldman 	{ "dsaauthentication", sPubkeyAuthentication },			/* alias */
331cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
332cb96ab36SAssar Westerlund 	{ "kerberosauthentication", sKerberosAuthentication },
333af12a3e7SDag-Erling Smørgrav 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
334af12a3e7SDag-Erling Smørgrav 	{ "kerberosticketcleanup", sKerberosTicketCleanup },
335cb96ab36SAssar Westerlund #endif
336af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
337af12a3e7SDag-Erling Smørgrav 	{ "kerberostgtpassing", sKerberosTgtPassing },
338511b41d2SMark Murray #endif
339511b41d2SMark Murray #ifdef AFS
340511b41d2SMark Murray 	{ "afstokenpassing", sAFSTokenPassing },
341511b41d2SMark Murray #endif
342511b41d2SMark Murray 	{ "passwordauthentication", sPasswordAuthentication },
34309958426SBrian Feldman 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
344ca3176e7SBrian Feldman 	{ "challengeresponseauthentication", sChallengeResponseAuthentication },
345ca3176e7SBrian Feldman 	{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
346989dd127SDag-Erling Smørgrav 	{ "checkmail", sDeprecated },
347511b41d2SMark Murray 	{ "listenaddress", sListenAddress },
348511b41d2SMark Murray 	{ "printmotd", sPrintMotd },
349ca3176e7SBrian Feldman 	{ "printlastlog", sPrintLastLog },
350511b41d2SMark Murray 	{ "ignorerhosts", sIgnoreRhosts },
351511b41d2SMark Murray 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
352511b41d2SMark Murray 	{ "x11forwarding", sX11Forwarding },
353511b41d2SMark Murray 	{ "x11displayoffset", sX11DisplayOffset },
354af12a3e7SDag-Erling Smørgrav 	{ "x11uselocalhost", sX11UseLocalhost },
355c2d3a559SKris Kennaway 	{ "xauthlocation", sXAuthLocation },
356511b41d2SMark Murray 	{ "strictmodes", sStrictModes },
357511b41d2SMark Murray 	{ "permitemptypasswords", sEmptyPasswd },
358511b41d2SMark Murray 	{ "uselogin", sUseLogin },
35980628bacSDag-Erling Smørgrav 	{ "compression", sCompression },
360511b41d2SMark Murray 	{ "keepalive", sKeepAlives },
36109958426SBrian Feldman 	{ "allowtcpforwarding", sAllowTcpForwarding },
362511b41d2SMark Murray 	{ "allowusers", sAllowUsers },
363511b41d2SMark Murray 	{ "denyusers", sDenyUsers },
364511b41d2SMark Murray 	{ "allowgroups", sAllowGroups },
365511b41d2SMark Murray 	{ "denygroups", sDenyGroups },
366e8aafc91SKris Kennaway 	{ "ciphers", sCiphers },
367ca3176e7SBrian Feldman 	{ "macs", sMacs },
368e8aafc91SKris Kennaway 	{ "protocol", sProtocol },
369e8aafc91SKris Kennaway 	{ "gatewayports", sGatewayPorts },
370c2d3a559SKris Kennaway 	{ "subsystem", sSubsystem },
371c2d3a559SKris Kennaway 	{ "maxstartups", sMaxStartups },
372ca3176e7SBrian Feldman 	{ "banner", sBanner },
373af12a3e7SDag-Erling Smørgrav 	{ "verifyreversemapping", sVerifyReverseMapping },
374af12a3e7SDag-Erling Smørgrav 	{ "reversemappingcheck", sVerifyReverseMapping },
375ca3176e7SBrian Feldman 	{ "clientaliveinterval", sClientAliveInterval },
376ca3176e7SBrian Feldman 	{ "clientalivecountmax", sClientAliveCountMax },
377af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile", sAuthorizedKeysFile },
378af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
37980628bacSDag-Erling Smørgrav 	{ "useprivilegeseparation", sUsePrivilegeSeparation},
380db58a8e4SDag-Erling Smørgrav 	{ "versionaddendum", sVersionAddendum },
381af12a3e7SDag-Erling Smørgrav 	{ NULL, sBadOption }
382511b41d2SMark Murray };
383511b41d2SMark Murray 
384511b41d2SMark Murray /*
385ca3176e7SBrian Feldman  * Returns the number of the token pointed to by cp or sBadOption.
386511b41d2SMark Murray  */
387511b41d2SMark Murray 
388511b41d2SMark Murray static ServerOpCodes
389511b41d2SMark Murray parse_token(const char *cp, const char *filename,
390511b41d2SMark Murray 	    int linenum)
391511b41d2SMark Murray {
392ca3176e7SBrian Feldman 	u_int i;
393511b41d2SMark Murray 
394511b41d2SMark Murray 	for (i = 0; keywords[i].name; i++)
395511b41d2SMark Murray 		if (strcasecmp(cp, keywords[i].name) == 0)
396511b41d2SMark Murray 			return keywords[i].opcode;
397511b41d2SMark Murray 
398ca3176e7SBrian Feldman 	error("%s: line %d: Bad configuration option: %s",
399511b41d2SMark Murray 	    filename, linenum, cp);
400511b41d2SMark Murray 	return sBadOption;
401511b41d2SMark Murray }
402511b41d2SMark Murray 
403af12a3e7SDag-Erling Smørgrav static void
404ca3176e7SBrian Feldman add_listen_addr(ServerOptions *options, char *addr, u_short port)
405511b41d2SMark Murray {
406511b41d2SMark Murray 	int i;
407511b41d2SMark Murray 
408511b41d2SMark Murray 	if (options->num_ports == 0)
409511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
410ca3176e7SBrian Feldman 	if (port == 0)
411ca3176e7SBrian Feldman 		for (i = 0; i < options->num_ports; i++)
412ca3176e7SBrian Feldman 			add_one_listen_addr(options, addr, options->ports[i]);
413ca3176e7SBrian Feldman 	else
414ca3176e7SBrian Feldman 		add_one_listen_addr(options, addr, port);
415ca3176e7SBrian Feldman }
416ca3176e7SBrian Feldman 
417af12a3e7SDag-Erling Smørgrav static void
418ca3176e7SBrian Feldman add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
419ca3176e7SBrian Feldman {
420ca3176e7SBrian Feldman 	struct addrinfo hints, *ai, *aitop;
421ca3176e7SBrian Feldman 	char strport[NI_MAXSERV];
422ca3176e7SBrian Feldman 	int gaierr;
423ca3176e7SBrian Feldman 
424511b41d2SMark Murray 	memset(&hints, 0, sizeof(hints));
425511b41d2SMark Murray 	hints.ai_family = IPv4or6;
426511b41d2SMark Murray 	hints.ai_socktype = SOCK_STREAM;
427511b41d2SMark Murray 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
428ca3176e7SBrian Feldman 	snprintf(strport, sizeof strport, "%d", port);
429511b41d2SMark Murray 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
430ca3176e7SBrian Feldman 		fatal("bad addr or host: %s (%s)",
431511b41d2SMark Murray 		    addr ? addr : "<NULL>",
432511b41d2SMark Murray 		    gai_strerror(gaierr));
433511b41d2SMark Murray 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
434511b41d2SMark Murray 		;
435511b41d2SMark Murray 	ai->ai_next = options->listen_addrs;
436511b41d2SMark Murray 	options->listen_addrs = aitop;
437511b41d2SMark Murray }
438511b41d2SMark Murray 
439af12a3e7SDag-Erling Smørgrav int
440af12a3e7SDag-Erling Smørgrav process_server_config_line(ServerOptions *options, char *line,
441af12a3e7SDag-Erling Smørgrav     const char *filename, int linenum)
442511b41d2SMark Murray {
443ca3176e7SBrian Feldman 	char *cp, **charptr, *arg, *p;
444af12a3e7SDag-Erling Smørgrav 	int *intptr, value;
445511b41d2SMark Murray 	ServerOpCodes opcode;
446af12a3e7SDag-Erling Smørgrav 	int i, n;
447511b41d2SMark Murray 
448c2d3a559SKris Kennaway 	cp = line;
449c2d3a559SKris Kennaway 	arg = strdelim(&cp);
450c2d3a559SKris Kennaway 	/* Ignore leading whitespace */
451c2d3a559SKris Kennaway 	if (*arg == '\0')
452c2d3a559SKris Kennaway 		arg = strdelim(&cp);
453ca3176e7SBrian Feldman 	if (!arg || !*arg || *arg == '#')
454af12a3e7SDag-Erling Smørgrav 		return 0;
455ca3176e7SBrian Feldman 	intptr = NULL;
456ca3176e7SBrian Feldman 	charptr = NULL;
457c2d3a559SKris Kennaway 	opcode = parse_token(arg, filename, linenum);
458511b41d2SMark Murray 	switch (opcode) {
459989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
460989dd127SDag-Erling Smørgrav 	case sPAMAuthenticationViaKbdInt:
461989dd127SDag-Erling Smørgrav 		intptr = &options->pam_authentication_via_kbd_int;
462989dd127SDag-Erling Smørgrav 		goto parse_flag;
463989dd127SDag-Erling Smørgrav 
464989dd127SDag-Erling Smørgrav 	/* Standard Options */
465511b41d2SMark Murray 	case sBadOption:
466af12a3e7SDag-Erling Smørgrav 		return -1;
467511b41d2SMark Murray 	case sPort:
468511b41d2SMark Murray 		/* ignore ports from configfile if cmdline specifies ports */
469511b41d2SMark Murray 		if (options->ports_from_cmdline)
470af12a3e7SDag-Erling Smørgrav 			return 0;
471511b41d2SMark Murray 		if (options->listen_addrs != NULL)
472511b41d2SMark Murray 			fatal("%s line %d: ports must be specified before "
473af12a3e7SDag-Erling Smørgrav 			    "ListenAddress.", filename, linenum);
474511b41d2SMark Murray 		if (options->num_ports >= MAX_PORTS)
475ca3176e7SBrian Feldman 			fatal("%s line %d: too many ports.",
476511b41d2SMark Murray 			    filename, linenum);
477c2d3a559SKris Kennaway 		arg = strdelim(&cp);
478c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
479ca3176e7SBrian Feldman 			fatal("%s line %d: missing port number.",
480511b41d2SMark Murray 			    filename, linenum);
481ca3176e7SBrian Feldman 		options->ports[options->num_ports++] = a2port(arg);
482ca3176e7SBrian Feldman 		if (options->ports[options->num_ports-1] == 0)
483ca3176e7SBrian Feldman 			fatal("%s line %d: Badly formatted port number.",
484ca3176e7SBrian Feldman 			    filename, linenum);
485511b41d2SMark Murray 		break;
486511b41d2SMark Murray 
487511b41d2SMark Murray 	case sServerKeyBits:
488511b41d2SMark Murray 		intptr = &options->server_key_bits;
489511b41d2SMark Murray parse_int:
490c2d3a559SKris Kennaway 		arg = strdelim(&cp);
491ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
492ca3176e7SBrian Feldman 			fatal("%s line %d: missing integer value.",
493511b41d2SMark Murray 			    filename, linenum);
494c2d3a559SKris Kennaway 		value = atoi(arg);
495511b41d2SMark Murray 		if (*intptr == -1)
496511b41d2SMark Murray 			*intptr = value;
497511b41d2SMark Murray 		break;
498511b41d2SMark Murray 
499511b41d2SMark Murray 	case sLoginGraceTime:
500511b41d2SMark Murray 		intptr = &options->login_grace_time;
501af12a3e7SDag-Erling Smørgrav parse_time:
502af12a3e7SDag-Erling Smørgrav 		arg = strdelim(&cp);
503af12a3e7SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
504af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: missing time value.",
505af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
506af12a3e7SDag-Erling Smørgrav 		if ((value = convtime(arg)) == -1)
507af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: invalid time value.",
508af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
509af12a3e7SDag-Erling Smørgrav 		if (*intptr == -1)
510af12a3e7SDag-Erling Smørgrav 			*intptr = value;
511af12a3e7SDag-Erling Smørgrav 		break;
512511b41d2SMark Murray 
513511b41d2SMark Murray 	case sKeyRegenerationTime:
514511b41d2SMark Murray 		intptr = &options->key_regeneration_time;
515af12a3e7SDag-Erling Smørgrav 		goto parse_time;
516511b41d2SMark Murray 
517511b41d2SMark Murray 	case sListenAddress:
518c2d3a559SKris Kennaway 		arg = strdelim(&cp);
519ca3176e7SBrian Feldman 		if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
520ca3176e7SBrian Feldman 			fatal("%s line %d: missing inet addr.",
521511b41d2SMark Murray 			    filename, linenum);
522ca3176e7SBrian Feldman 		if (*arg == '[') {
523ca3176e7SBrian Feldman 			if ((p = strchr(arg, ']')) == NULL)
524ca3176e7SBrian Feldman 				fatal("%s line %d: bad ipv6 inet addr usage.",
525ca3176e7SBrian Feldman 				    filename, linenum);
526ca3176e7SBrian Feldman 			arg++;
527ca3176e7SBrian Feldman 			memmove(p, p+1, strlen(p+1)+1);
528ca3176e7SBrian Feldman 		} else if (((p = strchr(arg, ':')) == NULL) ||
529ca3176e7SBrian Feldman 			    (strchr(p+1, ':') != NULL)) {
530ca3176e7SBrian Feldman 			add_listen_addr(options, arg, 0);
531ca3176e7SBrian Feldman 			break;
532ca3176e7SBrian Feldman 		}
533ca3176e7SBrian Feldman 		if (*p == ':') {
534ca3176e7SBrian Feldman 			u_short port;
535ca3176e7SBrian Feldman 
536ca3176e7SBrian Feldman 			p++;
537ca3176e7SBrian Feldman 			if (*p == '\0')
538ca3176e7SBrian Feldman 				fatal("%s line %d: bad inet addr:port usage.",
539ca3176e7SBrian Feldman 				    filename, linenum);
540ca3176e7SBrian Feldman 			else {
541ca3176e7SBrian Feldman 				*(p-1) = '\0';
542ca3176e7SBrian Feldman 				if ((port = a2port(p)) == 0)
543ca3176e7SBrian Feldman 					fatal("%s line %d: bad port number.",
544ca3176e7SBrian Feldman 					    filename, linenum);
545ca3176e7SBrian Feldman 				add_listen_addr(options, arg, port);
546ca3176e7SBrian Feldman 			}
547ca3176e7SBrian Feldman 		} else if (*p == '\0')
548ca3176e7SBrian Feldman 			add_listen_addr(options, arg, 0);
549ca3176e7SBrian Feldman 		else
550ca3176e7SBrian Feldman 			fatal("%s line %d: bad inet addr usage.",
551ca3176e7SBrian Feldman 			    filename, linenum);
552511b41d2SMark Murray 		break;
553511b41d2SMark Murray 
554511b41d2SMark Murray 	case sHostKeyFile:
555ca3176e7SBrian Feldman 		intptr = &options->num_host_key_files;
556ca3176e7SBrian Feldman 		if (*intptr >= MAX_HOSTKEYS)
557ca3176e7SBrian Feldman 			fatal("%s line %d: too many host keys specified (max %d).",
558ca3176e7SBrian Feldman 			    filename, linenum, MAX_HOSTKEYS);
559ca3176e7SBrian Feldman 		charptr = &options->host_key_files[*intptr];
560c2d3a559SKris Kennaway parse_filename:
561c2d3a559SKris Kennaway 		arg = strdelim(&cp);
562ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
563ca3176e7SBrian Feldman 			fatal("%s line %d: missing file name.",
564e8aafc91SKris Kennaway 			    filename, linenum);
565ca3176e7SBrian Feldman 		if (*charptr == NULL) {
566c2d3a559SKris Kennaway 			*charptr = tilde_expand_filename(arg, getuid());
567ca3176e7SBrian Feldman 			/* increase optional counter */
568ca3176e7SBrian Feldman 			if (intptr != NULL)
569ca3176e7SBrian Feldman 				*intptr = *intptr + 1;
570ca3176e7SBrian Feldman 		}
571e8aafc91SKris Kennaway 		break;
572e8aafc91SKris Kennaway 
573e8aafc91SKris Kennaway 	case sPidFile:
574e8aafc91SKris Kennaway 		charptr = &options->pid_file;
575c2d3a559SKris Kennaway 		goto parse_filename;
576511b41d2SMark Murray 
577511b41d2SMark Murray 	case sPermitRootLogin:
578511b41d2SMark Murray 		intptr = &options->permit_root_login;
579c2d3a559SKris Kennaway 		arg = strdelim(&cp);
580ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
581ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/"
582ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
583ca3176e7SBrian Feldman 			    "argument.", filename, linenum);
584ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
585c2d3a559SKris Kennaway 		if (strcmp(arg, "without-password") == 0)
586ca3176e7SBrian Feldman 			value = PERMIT_NO_PASSWD;
587ca3176e7SBrian Feldman 		else if (strcmp(arg, "forced-commands-only") == 0)
588ca3176e7SBrian Feldman 			value = PERMIT_FORCED_ONLY;
589c2d3a559SKris Kennaway 		else if (strcmp(arg, "yes") == 0)
590ca3176e7SBrian Feldman 			value = PERMIT_YES;
591c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
592ca3176e7SBrian Feldman 			value = PERMIT_NO;
593ca3176e7SBrian Feldman 		else
594ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/"
595ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
596ca3176e7SBrian Feldman 			    "argument: %s", filename, linenum, arg);
597511b41d2SMark Murray 		if (*intptr == -1)
598511b41d2SMark Murray 			*intptr = value;
599511b41d2SMark Murray 		break;
600511b41d2SMark Murray 
601511b41d2SMark Murray 	case sIgnoreRhosts:
602511b41d2SMark Murray 		intptr = &options->ignore_rhosts;
603511b41d2SMark Murray parse_flag:
604c2d3a559SKris Kennaway 		arg = strdelim(&cp);
605ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
606ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/no argument.",
607511b41d2SMark Murray 			    filename, linenum);
608ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
609c2d3a559SKris Kennaway 		if (strcmp(arg, "yes") == 0)
610511b41d2SMark Murray 			value = 1;
611c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
612511b41d2SMark Murray 			value = 0;
613ca3176e7SBrian Feldman 		else
614ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/no argument: %s",
615c2d3a559SKris Kennaway 				filename, linenum, arg);
616511b41d2SMark Murray 		if (*intptr == -1)
617511b41d2SMark Murray 			*intptr = value;
618511b41d2SMark Murray 		break;
619511b41d2SMark Murray 
620511b41d2SMark Murray 	case sIgnoreUserKnownHosts:
621511b41d2SMark Murray 		intptr = &options->ignore_user_known_hosts;
622962a3f4eSSheldon Hearn 		goto parse_flag;
623511b41d2SMark Murray 
624511b41d2SMark Murray 	case sRhostsAuthentication:
625511b41d2SMark Murray 		intptr = &options->rhosts_authentication;
626511b41d2SMark Murray 		goto parse_flag;
627511b41d2SMark Murray 
628511b41d2SMark Murray 	case sRhostsRSAAuthentication:
629511b41d2SMark Murray 		intptr = &options->rhosts_rsa_authentication;
630511b41d2SMark Murray 		goto parse_flag;
631511b41d2SMark Murray 
632ca3176e7SBrian Feldman 	case sHostbasedAuthentication:
633ca3176e7SBrian Feldman 		intptr = &options->hostbased_authentication;
634ca3176e7SBrian Feldman 		goto parse_flag;
635ca3176e7SBrian Feldman 
636ca3176e7SBrian Feldman 	case sHostbasedUsesNameFromPacketOnly:
637ca3176e7SBrian Feldman 		intptr = &options->hostbased_uses_name_from_packet_only;
638ca3176e7SBrian Feldman 		goto parse_flag;
639ca3176e7SBrian Feldman 
640511b41d2SMark Murray 	case sRSAAuthentication:
641511b41d2SMark Murray 		intptr = &options->rsa_authentication;
642511b41d2SMark Murray 		goto parse_flag;
643511b41d2SMark Murray 
644ca3176e7SBrian Feldman 	case sPubkeyAuthentication:
645ca3176e7SBrian Feldman 		intptr = &options->pubkey_authentication;
646e8aafc91SKris Kennaway 		goto parse_flag;
647cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
648cb96ab36SAssar Westerlund 	case sKerberosAuthentication:
649cb96ab36SAssar Westerlund 		intptr = &options->kerberos_authentication;
650511b41d2SMark Murray 		goto parse_flag;
651511b41d2SMark Murray 
652af12a3e7SDag-Erling Smørgrav 	case sKerberosOrLocalPasswd:
653af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_or_local_passwd;
654511b41d2SMark Murray 		goto parse_flag;
655511b41d2SMark Murray 
656af12a3e7SDag-Erling Smørgrav 	case sKerberosTicketCleanup:
657af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_ticket_cleanup;
658511b41d2SMark Murray 		goto parse_flag;
659511b41d2SMark Murray #endif
660af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
661af12a3e7SDag-Erling Smørgrav 	case sKerberosTgtPassing:
662af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_tgt_passing;
663fe5fd017SMark Murray 		goto parse_flag;
664af12a3e7SDag-Erling Smørgrav #endif
665511b41d2SMark Murray #ifdef AFS
666511b41d2SMark Murray 	case sAFSTokenPassing:
667511b41d2SMark Murray 		intptr = &options->afs_token_passing;
668511b41d2SMark Murray 		goto parse_flag;
669511b41d2SMark Murray #endif
670511b41d2SMark Murray 
671511b41d2SMark Murray 	case sPasswordAuthentication:
672511b41d2SMark Murray 		intptr = &options->password_authentication;
673511b41d2SMark Murray 		goto parse_flag;
674511b41d2SMark Murray 
67509958426SBrian Feldman 	case sKbdInteractiveAuthentication:
67609958426SBrian Feldman 		intptr = &options->kbd_interactive_authentication;
67709958426SBrian Feldman 		goto parse_flag;
67809958426SBrian Feldman 
679ca3176e7SBrian Feldman 	case sChallengeResponseAuthentication:
680af12a3e7SDag-Erling Smørgrav 		intptr = &options->challenge_response_authentication;
681511b41d2SMark Murray 		goto parse_flag;
682511b41d2SMark Murray 
683511b41d2SMark Murray 	case sPrintMotd:
684511b41d2SMark Murray 		intptr = &options->print_motd;
685511b41d2SMark Murray 		goto parse_flag;
686511b41d2SMark Murray 
687ca3176e7SBrian Feldman 	case sPrintLastLog:
688ca3176e7SBrian Feldman 		intptr = &options->print_lastlog;
689ca3176e7SBrian Feldman 		goto parse_flag;
690ca3176e7SBrian Feldman 
691511b41d2SMark Murray 	case sX11Forwarding:
692511b41d2SMark Murray 		intptr = &options->x11_forwarding;
693511b41d2SMark Murray 		goto parse_flag;
694511b41d2SMark Murray 
695511b41d2SMark Murray 	case sX11DisplayOffset:
696511b41d2SMark Murray 		intptr = &options->x11_display_offset;
697511b41d2SMark Murray 		goto parse_int;
698511b41d2SMark Murray 
699af12a3e7SDag-Erling Smørgrav 	case sX11UseLocalhost:
700af12a3e7SDag-Erling Smørgrav 		intptr = &options->x11_use_localhost;
701af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
702af12a3e7SDag-Erling Smørgrav 
703c2d3a559SKris Kennaway 	case sXAuthLocation:
704c2d3a559SKris Kennaway 		charptr = &options->xauth_location;
705c2d3a559SKris Kennaway 		goto parse_filename;
706c2d3a559SKris Kennaway 
707511b41d2SMark Murray 	case sStrictModes:
708511b41d2SMark Murray 		intptr = &options->strict_modes;
709511b41d2SMark Murray 		goto parse_flag;
710511b41d2SMark Murray 
711511b41d2SMark Murray 	case sKeepAlives:
712511b41d2SMark Murray 		intptr = &options->keepalives;
713511b41d2SMark Murray 		goto parse_flag;
714511b41d2SMark Murray 
715511b41d2SMark Murray 	case sEmptyPasswd:
716511b41d2SMark Murray 		intptr = &options->permit_empty_passwd;
717511b41d2SMark Murray 		goto parse_flag;
718511b41d2SMark Murray 
719511b41d2SMark Murray 	case sUseLogin:
720511b41d2SMark Murray 		intptr = &options->use_login;
721511b41d2SMark Murray 		goto parse_flag;
722511b41d2SMark Murray 
72380628bacSDag-Erling Smørgrav 	case sCompression:
72480628bacSDag-Erling Smørgrav 		intptr = &options->compression;
72580628bacSDag-Erling Smørgrav 		goto parse_flag;
72680628bacSDag-Erling Smørgrav 
727e8aafc91SKris Kennaway 	case sGatewayPorts:
728e8aafc91SKris Kennaway 		intptr = &options->gateway_ports;
729e8aafc91SKris Kennaway 		goto parse_flag;
730e8aafc91SKris Kennaway 
731af12a3e7SDag-Erling Smørgrav 	case sVerifyReverseMapping:
732af12a3e7SDag-Erling Smørgrav 		intptr = &options->verify_reverse_mapping;
733ca3176e7SBrian Feldman 		goto parse_flag;
734ca3176e7SBrian Feldman 
735511b41d2SMark Murray 	case sLogFacility:
736511b41d2SMark Murray 		intptr = (int *) &options->log_facility;
737c2d3a559SKris Kennaway 		arg = strdelim(&cp);
738c2d3a559SKris Kennaway 		value = log_facility_number(arg);
739af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_FACILITY_NOT_SET)
740ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log facility '%s'",
741c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
742511b41d2SMark Murray 		if (*intptr == -1)
743511b41d2SMark Murray 			*intptr = (SyslogFacility) value;
744511b41d2SMark Murray 		break;
745511b41d2SMark Murray 
746511b41d2SMark Murray 	case sLogLevel:
747511b41d2SMark Murray 		intptr = (int *) &options->log_level;
748c2d3a559SKris Kennaway 		arg = strdelim(&cp);
749c2d3a559SKris Kennaway 		value = log_level_number(arg);
750af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_LEVEL_NOT_SET)
751ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log level '%s'",
752c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
753511b41d2SMark Murray 		if (*intptr == -1)
754511b41d2SMark Murray 			*intptr = (LogLevel) value;
755511b41d2SMark Murray 		break;
756511b41d2SMark Murray 
75709958426SBrian Feldman 	case sAllowTcpForwarding:
75809958426SBrian Feldman 		intptr = &options->allow_tcp_forwarding;
75909958426SBrian Feldman 		goto parse_flag;
76009958426SBrian Feldman 
76180628bacSDag-Erling Smørgrav 	case sUsePrivilegeSeparation:
76280628bacSDag-Erling Smørgrav 		intptr = &use_privsep;
76380628bacSDag-Erling Smørgrav 		goto parse_flag;
76480628bacSDag-Erling Smørgrav 
765511b41d2SMark Murray 	case sAllowUsers:
766c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
76742f71286SMark Murray 			if (options->num_allow_users >= MAX_ALLOW_USERS)
768af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow users.",
769e8aafc91SKris Kennaway 				    filename, linenum);
770c2d3a559SKris Kennaway 			options->allow_users[options->num_allow_users++] = xstrdup(arg);
771511b41d2SMark Murray 		}
772511b41d2SMark Murray 		break;
773511b41d2SMark Murray 
774511b41d2SMark Murray 	case sDenyUsers:
775c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
7762803b77eSBrian Feldman 			if (options->num_deny_users >= MAX_DENY_USERS)
777af12a3e7SDag-Erling Smørgrav 				fatal( "%s line %d: too many deny users.",
778e8aafc91SKris Kennaway 				    filename, linenum);
779c2d3a559SKris Kennaway 			options->deny_users[options->num_deny_users++] = xstrdup(arg);
780511b41d2SMark Murray 		}
781511b41d2SMark Murray 		break;
782511b41d2SMark Murray 
783511b41d2SMark Murray 	case sAllowGroups:
784c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
78542f71286SMark Murray 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
786af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow groups.",
787e8aafc91SKris Kennaway 				    filename, linenum);
788c2d3a559SKris Kennaway 			options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
789511b41d2SMark Murray 		}
790511b41d2SMark Murray 		break;
791511b41d2SMark Murray 
792511b41d2SMark Murray 	case sDenyGroups:
793c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
79442f71286SMark Murray 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
795af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many deny groups.",
796e8aafc91SKris Kennaway 				    filename, linenum);
797c2d3a559SKris Kennaway 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
798511b41d2SMark Murray 		}
799511b41d2SMark Murray 		break;
800511b41d2SMark Murray 
801e8aafc91SKris Kennaway 	case sCiphers:
802c2d3a559SKris Kennaway 		arg = strdelim(&cp);
803c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
804c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
805c2d3a559SKris Kennaway 		if (!ciphers_valid(arg))
806e8aafc91SKris Kennaway 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
807c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
808e8aafc91SKris Kennaway 		if (options->ciphers == NULL)
809c2d3a559SKris Kennaway 			options->ciphers = xstrdup(arg);
810e8aafc91SKris Kennaway 		break;
811e8aafc91SKris Kennaway 
812ca3176e7SBrian Feldman 	case sMacs:
813ca3176e7SBrian Feldman 		arg = strdelim(&cp);
814ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
815ca3176e7SBrian Feldman 			fatal("%s line %d: Missing argument.", filename, linenum);
816ca3176e7SBrian Feldman 		if (!mac_valid(arg))
817ca3176e7SBrian Feldman 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
818ca3176e7SBrian Feldman 			    filename, linenum, arg ? arg : "<NONE>");
819ca3176e7SBrian Feldman 		if (options->macs == NULL)
820ca3176e7SBrian Feldman 			options->macs = xstrdup(arg);
821ca3176e7SBrian Feldman 		break;
822ca3176e7SBrian Feldman 
823e8aafc91SKris Kennaway 	case sProtocol:
824e8aafc91SKris Kennaway 		intptr = &options->protocol;
825c2d3a559SKris Kennaway 		arg = strdelim(&cp);
826c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
827c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
828c2d3a559SKris Kennaway 		value = proto_spec(arg);
829e8aafc91SKris Kennaway 		if (value == SSH_PROTO_UNKNOWN)
830e8aafc91SKris Kennaway 			fatal("%s line %d: Bad protocol spec '%s'.",
831c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
832e8aafc91SKris Kennaway 		if (*intptr == SSH_PROTO_UNKNOWN)
833e8aafc91SKris Kennaway 			*intptr = value;
834e8aafc91SKris Kennaway 		break;
835e8aafc91SKris Kennaway 
836c2d3a559SKris Kennaway 	case sSubsystem:
837c2d3a559SKris Kennaway 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
838c2d3a559SKris Kennaway 			fatal("%s line %d: too many subsystems defined.",
839c2d3a559SKris Kennaway 			    filename, linenum);
840c2d3a559SKris Kennaway 		}
841c2d3a559SKris Kennaway 		arg = strdelim(&cp);
842c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
843c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem name.",
844c2d3a559SKris Kennaway 			    filename, linenum);
845c2d3a559SKris Kennaway 		for (i = 0; i < options->num_subsystems; i++)
846c2d3a559SKris Kennaway 			if (strcmp(arg, options->subsystem_name[i]) == 0)
847c2d3a559SKris Kennaway 				fatal("%s line %d: Subsystem '%s' already defined.",
848c2d3a559SKris Kennaway 				    filename, linenum, arg);
849c2d3a559SKris Kennaway 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
850c2d3a559SKris Kennaway 		arg = strdelim(&cp);
851c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
852c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem command.",
853c2d3a559SKris Kennaway 			    filename, linenum);
854c2d3a559SKris Kennaway 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
855c2d3a559SKris Kennaway 		options->num_subsystems++;
856c2d3a559SKris Kennaway 		break;
857c2d3a559SKris Kennaway 
858c2d3a559SKris Kennaway 	case sMaxStartups:
859c2d3a559SKris Kennaway 		arg = strdelim(&cp);
860c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
861c2d3a559SKris Kennaway 			fatal("%s line %d: Missing MaxStartups spec.",
862c2d3a559SKris Kennaway 			    filename, linenum);
863af12a3e7SDag-Erling Smørgrav 		if ((n = sscanf(arg, "%d:%d:%d",
864c2d3a559SKris Kennaway 		    &options->max_startups_begin,
865c2d3a559SKris Kennaway 		    &options->max_startups_rate,
866af12a3e7SDag-Erling Smørgrav 		    &options->max_startups)) == 3) {
867c2d3a559SKris Kennaway 			if (options->max_startups_begin >
868c2d3a559SKris Kennaway 			    options->max_startups ||
869c2d3a559SKris Kennaway 			    options->max_startups_rate > 100 ||
870c2d3a559SKris Kennaway 			    options->max_startups_rate < 1)
871c2d3a559SKris Kennaway 				fatal("%s line %d: Illegal MaxStartups spec.",
872c2d3a559SKris Kennaway 				    filename, linenum);
873af12a3e7SDag-Erling Smørgrav 		} else if (n != 1)
874af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: Illegal MaxStartups spec.",
875af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
876af12a3e7SDag-Erling Smørgrav 		else
877af12a3e7SDag-Erling Smørgrav 			options->max_startups = options->max_startups_begin;
878933ca70fSBrian Feldman 		break;
879933ca70fSBrian Feldman 
880ca3176e7SBrian Feldman 	case sBanner:
881ca3176e7SBrian Feldman 		charptr = &options->banner;
882ca3176e7SBrian Feldman 		goto parse_filename;
883af12a3e7SDag-Erling Smørgrav 	/*
884af12a3e7SDag-Erling Smørgrav 	 * These options can contain %X options expanded at
885af12a3e7SDag-Erling Smørgrav 	 * connect time, so that you can specify paths like:
886af12a3e7SDag-Erling Smørgrav 	 *
887af12a3e7SDag-Erling Smørgrav 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
888af12a3e7SDag-Erling Smørgrav 	 */
889af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile:
890af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile2:
891af12a3e7SDag-Erling Smørgrav 		charptr = (opcode == sAuthorizedKeysFile ) ?
892af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file :
893af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file2;
894af12a3e7SDag-Erling Smørgrav 		goto parse_filename;
895af12a3e7SDag-Erling Smørgrav 
896ca3176e7SBrian Feldman 	case sClientAliveInterval:
897ca3176e7SBrian Feldman 		intptr = &options->client_alive_interval;
898af12a3e7SDag-Erling Smørgrav 		goto parse_time;
899af12a3e7SDag-Erling Smørgrav 
900ca3176e7SBrian Feldman 	case sClientAliveCountMax:
901ca3176e7SBrian Feldman 		intptr = &options->client_alive_count_max;
902ca3176e7SBrian Feldman 		goto parse_int;
903af12a3e7SDag-Erling Smørgrav 
904db58a8e4SDag-Erling Smørgrav 	case sVersionAddendum:
905db58a8e4SDag-Erling Smørgrav                 ssh_version_set_addendum(strtok(cp, "\n"));
906db58a8e4SDag-Erling Smørgrav                 do {
907db58a8e4SDag-Erling Smørgrav                         arg = strdelim(&cp);
908db58a8e4SDag-Erling Smørgrav                 } while (arg != NULL && *arg != '\0');
909db58a8e4SDag-Erling Smørgrav 		break;
910db58a8e4SDag-Erling Smørgrav 
911af12a3e7SDag-Erling Smørgrav 	case sDeprecated:
912af12a3e7SDag-Erling Smørgrav 		log("%s line %d: Deprecated option %s",
913af12a3e7SDag-Erling Smørgrav 		    filename, linenum, arg);
914af12a3e7SDag-Erling Smørgrav 		while (arg)
915af12a3e7SDag-Erling Smørgrav 		    arg = strdelim(&cp);
916af12a3e7SDag-Erling Smørgrav 		break;
917af12a3e7SDag-Erling Smørgrav 
91842f71286SMark Murray 	default:
919af12a3e7SDag-Erling Smørgrav 		fatal("%s line %d: Missing handler for opcode %s (%d)",
920c2d3a559SKris Kennaway 		    filename, linenum, arg, opcode);
921511b41d2SMark Murray 	}
922ca3176e7SBrian Feldman 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
923ca3176e7SBrian Feldman 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
924c2d3a559SKris Kennaway 		    filename, linenum, arg);
925af12a3e7SDag-Erling Smørgrav 	return 0;
926af12a3e7SDag-Erling Smørgrav }
927af12a3e7SDag-Erling Smørgrav 
928af12a3e7SDag-Erling Smørgrav /* Reads the server configuration file. */
929af12a3e7SDag-Erling Smørgrav 
930af12a3e7SDag-Erling Smørgrav void
931af12a3e7SDag-Erling Smørgrav read_server_config(ServerOptions *options, const char *filename)
932af12a3e7SDag-Erling Smørgrav {
933af12a3e7SDag-Erling Smørgrav 	FILE *f;
934af12a3e7SDag-Erling Smørgrav 	char line[1024];
935af12a3e7SDag-Erling Smørgrav 	int linenum;
936af12a3e7SDag-Erling Smørgrav 	int bad_options = 0;
937af12a3e7SDag-Erling Smørgrav 
938af12a3e7SDag-Erling Smørgrav 	f = fopen(filename, "r");
939af12a3e7SDag-Erling Smørgrav 	if (!f) {
940af12a3e7SDag-Erling Smørgrav 		perror(filename);
941af12a3e7SDag-Erling Smørgrav 		exit(1);
942af12a3e7SDag-Erling Smørgrav 	}
943af12a3e7SDag-Erling Smørgrav 	linenum = 0;
944af12a3e7SDag-Erling Smørgrav 	while (fgets(line, sizeof(line), f)) {
945af12a3e7SDag-Erling Smørgrav 		/* Update line number counter. */
946af12a3e7SDag-Erling Smørgrav 		linenum++;
947af12a3e7SDag-Erling Smørgrav 		if (process_server_config_line(options, line, filename, linenum) != 0)
948af12a3e7SDag-Erling Smørgrav 			bad_options++;
949511b41d2SMark Murray 	}
950511b41d2SMark Murray 	fclose(f);
951ca3176e7SBrian Feldman 	if (bad_options > 0)
952af12a3e7SDag-Erling Smørgrav 		fatal("%s: terminating, %d bad configuration options",
953511b41d2SMark Murray 		    filename, bad_options);
954511b41d2SMark Murray }
955