xref: /freebsd/crypto/openssh/servconf.c (revision af12a3e74a283727a2aa141f2b4c68ff10fe8dc6)
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"
13af12a3e7SDag-Erling Smørgrav RCSID("$OpenBSD: servconf.c,v 1.101 2002/02/04 12:15:25 markus Exp $");
14c2d3a559SKris Kennaway RCSID("$FreeBSD$");
15511b41d2SMark Murray 
16af12a3e7SDag-Erling Smørgrav #if defined(KRB4) || defined(KRB5)
17ca3176e7SBrian Feldman #include <krb.h>
18ca3176e7SBrian Feldman #endif
19ca3176e7SBrian Feldman #ifdef AFS
20ca3176e7SBrian Feldman #include <kafs.h>
21ca3176e7SBrian Feldman #endif
22ca3176e7SBrian Feldman 
23511b41d2SMark Murray #include "ssh.h"
24ca3176e7SBrian Feldman #include "log.h"
25511b41d2SMark Murray #include "servconf.h"
26511b41d2SMark Murray #include "xmalloc.h"
27e8aafc91SKris Kennaway #include "compat.h"
28ca3176e7SBrian Feldman #include "pathnames.h"
29ca3176e7SBrian Feldman #include "tildexpand.h"
30ca3176e7SBrian Feldman #include "misc.h"
31ca3176e7SBrian Feldman #include "cipher.h"
32ca3176e7SBrian Feldman #include "kex.h"
33ca3176e7SBrian Feldman #include "mac.h"
34511b41d2SMark Murray 
35af12a3e7SDag-Erling Smørgrav static void add_listen_addr(ServerOptions *, char *, u_short);
36af12a3e7SDag-Erling Smørgrav static void add_one_listen_addr(ServerOptions *, char *, u_short);
37ca3176e7SBrian Feldman 
38ca3176e7SBrian Feldman /* AF_UNSPEC or AF_INET or AF_INET6 */
39ca3176e7SBrian Feldman extern int IPv4or6;
40511b41d2SMark Murray 
41511b41d2SMark Murray /* Initializes the server options to their default values. */
42511b41d2SMark Murray 
43511b41d2SMark Murray void
44511b41d2SMark Murray initialize_server_options(ServerOptions *options)
45511b41d2SMark Murray {
46511b41d2SMark Murray 	memset(options, 0, sizeof(*options));
47511b41d2SMark Murray 	options->num_ports = 0;
48511b41d2SMark Murray 	options->ports_from_cmdline = 0;
49511b41d2SMark Murray 	options->listen_addrs = NULL;
50ca3176e7SBrian Feldman 	options->num_host_key_files = 0;
51e8aafc91SKris Kennaway 	options->pid_file = NULL;
52511b41d2SMark Murray 	options->server_key_bits = -1;
53511b41d2SMark Murray 	options->login_grace_time = -1;
54511b41d2SMark Murray 	options->key_regeneration_time = -1;
55ca3176e7SBrian Feldman 	options->permit_root_login = PERMIT_NOT_SET;
56511b41d2SMark Murray 	options->ignore_rhosts = -1;
57511b41d2SMark Murray 	options->ignore_user_known_hosts = -1;
58511b41d2SMark Murray 	options->print_motd = -1;
59ca3176e7SBrian Feldman 	options->print_lastlog = -1;
60511b41d2SMark Murray 	options->x11_forwarding = -1;
61511b41d2SMark Murray 	options->x11_display_offset = -1;
62af12a3e7SDag-Erling Smørgrav 	options->x11_use_localhost = -1;
63c2d3a559SKris Kennaway 	options->xauth_location = NULL;
64511b41d2SMark Murray 	options->strict_modes = -1;
65511b41d2SMark Murray 	options->keepalives = -1;
66af12a3e7SDag-Erling Smørgrav 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
67af12a3e7SDag-Erling Smørgrav 	options->log_level = SYSLOG_LEVEL_NOT_SET;
68511b41d2SMark Murray 	options->rhosts_authentication = -1;
69511b41d2SMark Murray 	options->rhosts_rsa_authentication = -1;
70ca3176e7SBrian Feldman 	options->hostbased_authentication = -1;
71ca3176e7SBrian Feldman 	options->hostbased_uses_name_from_packet_only = -1;
72511b41d2SMark Murray 	options->rsa_authentication = -1;
73ca3176e7SBrian Feldman 	options->pubkey_authentication = -1;
74cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
75cb96ab36SAssar Westerlund 	options->kerberos_authentication = -1;
76af12a3e7SDag-Erling Smørgrav 	options->kerberos_or_local_passwd = -1;
77af12a3e7SDag-Erling Smørgrav 	options->kerberos_ticket_cleanup = -1;
78cb96ab36SAssar Westerlund #endif
79af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
80af12a3e7SDag-Erling Smørgrav 	options->kerberos_tgt_passing = -1;
81511b41d2SMark Murray #endif
82511b41d2SMark Murray #ifdef AFS
83511b41d2SMark Murray 	options->afs_token_passing = -1;
84511b41d2SMark Murray #endif
85511b41d2SMark Murray 	options->password_authentication = -1;
8609958426SBrian Feldman 	options->kbd_interactive_authentication = -1;
87af12a3e7SDag-Erling Smørgrav 	options->challenge_response_authentication = -1;
88511b41d2SMark Murray 	options->permit_empty_passwd = -1;
89511b41d2SMark Murray 	options->use_login = -1;
9009958426SBrian Feldman 	options->allow_tcp_forwarding = -1;
91511b41d2SMark Murray 	options->num_allow_users = 0;
92511b41d2SMark Murray 	options->num_deny_users = 0;
93511b41d2SMark Murray 	options->num_allow_groups = 0;
94511b41d2SMark Murray 	options->num_deny_groups = 0;
95e8aafc91SKris Kennaway 	options->ciphers = NULL;
96ca3176e7SBrian Feldman 	options->macs = NULL;
97e8aafc91SKris Kennaway 	options->protocol = SSH_PROTO_UNKNOWN;
98e8aafc91SKris Kennaway 	options->gateway_ports = -1;
9942f71286SMark Murray 	options->connections_period = 0;
100c2d3a559SKris Kennaway 	options->num_subsystems = 0;
101c2d3a559SKris Kennaway 	options->max_startups_begin = -1;
102c2d3a559SKris Kennaway 	options->max_startups_rate = -1;
103c2d3a559SKris Kennaway 	options->max_startups = -1;
104ca3176e7SBrian Feldman 	options->banner = NULL;
105af12a3e7SDag-Erling Smørgrav 	options->verify_reverse_mapping = -1;
106ca3176e7SBrian Feldman 	options->client_alive_interval = -1;
107ca3176e7SBrian Feldman 	options->client_alive_count_max = -1;
108af12a3e7SDag-Erling Smørgrav 	options->authorized_keys_file = NULL;
109af12a3e7SDag-Erling Smørgrav 	options->authorized_keys_file2 = NULL;
110511b41d2SMark Murray }
111511b41d2SMark Murray 
112511b41d2SMark Murray void
113511b41d2SMark Murray fill_default_server_options(ServerOptions *options)
114511b41d2SMark Murray {
115ca3176e7SBrian Feldman 	if (options->protocol == SSH_PROTO_UNKNOWN)
116ca3176e7SBrian Feldman 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
117ca3176e7SBrian Feldman 	if (options->num_host_key_files == 0) {
118ca3176e7SBrian Feldman 		/* fill default hostkeys for protocols */
119ca3176e7SBrian Feldman 		if (options->protocol & SSH_PROTO_1)
120af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
121af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_KEY_FILE;
122af12a3e7SDag-Erling Smørgrav 		if (options->protocol & SSH_PROTO_2) {
123af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
124af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_RSA_KEY_FILE;
125af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
126af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_DSA_KEY_FILE;
127af12a3e7SDag-Erling Smørgrav 		}
128ca3176e7SBrian Feldman 	}
129511b41d2SMark Murray 	if (options->num_ports == 0)
130511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
131511b41d2SMark Murray 	if (options->listen_addrs == NULL)
132ca3176e7SBrian Feldman 		add_listen_addr(options, NULL, 0);
133e8aafc91SKris Kennaway 	if (options->pid_file == NULL)
134ca3176e7SBrian Feldman 		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
135511b41d2SMark Murray 	if (options->server_key_bits == -1)
136511b41d2SMark Murray 		options->server_key_bits = 768;
137511b41d2SMark Murray 	if (options->login_grace_time == -1)
138b87db7ceSKris Kennaway 		options->login_grace_time = 120;
139511b41d2SMark Murray 	if (options->key_regeneration_time == -1)
140511b41d2SMark Murray 		options->key_regeneration_time = 3600;
141ca3176e7SBrian Feldman 	if (options->permit_root_login == PERMIT_NOT_SET)
142ca3176e7SBrian Feldman 		options->permit_root_login = PERMIT_NO;
143511b41d2SMark Murray 	if (options->ignore_rhosts == -1)
144fe5fd017SMark Murray 		options->ignore_rhosts = 1;
145511b41d2SMark Murray 	if (options->ignore_user_known_hosts == -1)
146511b41d2SMark Murray 		options->ignore_user_known_hosts = 0;
147511b41d2SMark Murray 	if (options->check_mail == -1)
148365c420eSPeter Wemm 		options->check_mail = 1;
149511b41d2SMark Murray 	if (options->print_motd == -1)
150511b41d2SMark Murray 		options->print_motd = 1;
151ca3176e7SBrian Feldman 	if (options->print_lastlog == -1)
152ca3176e7SBrian Feldman 		options->print_lastlog = 1;
153511b41d2SMark Murray 	if (options->x11_forwarding == -1)
1541610cd7fSKris Kennaway 		options->x11_forwarding = 1;
155511b41d2SMark Murray 	if (options->x11_display_offset == -1)
156fe5fd017SMark Murray 		options->x11_display_offset = 10;
157af12a3e7SDag-Erling Smørgrav 	if (options->x11_use_localhost == -1)
158af12a3e7SDag-Erling Smørgrav 		options->x11_use_localhost = 1;
159c2d3a559SKris Kennaway 	if (options->xauth_location == NULL)
160af12a3e7SDag-Erling Smørgrav 		options->xauth_location = _PATH_XAUTH;
161511b41d2SMark Murray 	if (options->strict_modes == -1)
162511b41d2SMark Murray 		options->strict_modes = 1;
163511b41d2SMark Murray 	if (options->keepalives == -1)
164511b41d2SMark Murray 		options->keepalives = 1;
165af12a3e7SDag-Erling Smørgrav 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
166511b41d2SMark Murray 		options->log_facility = SYSLOG_FACILITY_AUTH;
167af12a3e7SDag-Erling Smørgrav 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
168511b41d2SMark Murray 		options->log_level = SYSLOG_LEVEL_INFO;
169511b41d2SMark Murray 	if (options->rhosts_authentication == -1)
170511b41d2SMark Murray 		options->rhosts_authentication = 0;
171511b41d2SMark Murray 	if (options->rhosts_rsa_authentication == -1)
172fe5fd017SMark Murray 		options->rhosts_rsa_authentication = 0;
173ca3176e7SBrian Feldman 	if (options->hostbased_authentication == -1)
174ca3176e7SBrian Feldman 		options->hostbased_authentication = 0;
175ca3176e7SBrian Feldman 	if (options->hostbased_uses_name_from_packet_only == -1)
176ca3176e7SBrian Feldman 		options->hostbased_uses_name_from_packet_only = 0;
177511b41d2SMark Murray 	if (options->rsa_authentication == -1)
178511b41d2SMark Murray 		options->rsa_authentication = 1;
179ca3176e7SBrian Feldman 	if (options->pubkey_authentication == -1)
180ca3176e7SBrian Feldman 		options->pubkey_authentication = 1;
181af12a3e7SDag-Erling Smørgrav #if defined(KRB4) || defined(KRB5)
182cb96ab36SAssar Westerlund 	if (options->kerberos_authentication == -1)
183cb96ab36SAssar Westerlund 		options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
184af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_or_local_passwd == -1)
185af12a3e7SDag-Erling Smørgrav 		options->kerberos_or_local_passwd = 1;
186af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_ticket_cleanup == -1)
187af12a3e7SDag-Erling Smørgrav 		options->kerberos_ticket_cleanup = 1;
188cb96ab36SAssar Westerlund #endif
189af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
190af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_tgt_passing == -1)
191af12a3e7SDag-Erling Smørgrav 		options->kerberos_tgt_passing = 0;
192af12a3e7SDag-Erling Smørgrav #endif
193511b41d2SMark Murray #ifdef AFS
194511b41d2SMark Murray 	if (options->afs_token_passing == -1)
195511b41d2SMark Murray 		options->afs_token_passing = k_hasafs();
196af12a3e7SDag-Erling Smørgrav #endif
197511b41d2SMark Murray 	if (options->password_authentication == -1)
198511b41d2SMark Murray 		options->password_authentication = 1;
19909958426SBrian Feldman 	if (options->kbd_interactive_authentication == -1)
20009958426SBrian Feldman 		options->kbd_interactive_authentication = 0;
201af12a3e7SDag-Erling Smørgrav 	if (options->challenge_response_authentication == -1)
202af12a3e7SDag-Erling Smørgrav 		options->challenge_response_authentication = 1;
203511b41d2SMark Murray 	if (options->permit_empty_passwd == -1)
204fe5fd017SMark Murray 		options->permit_empty_passwd = 0;
205511b41d2SMark Murray 	if (options->use_login == -1)
206511b41d2SMark Murray 		options->use_login = 0;
20709958426SBrian Feldman 	if (options->allow_tcp_forwarding == -1)
20809958426SBrian Feldman 		options->allow_tcp_forwarding = 1;
209e8aafc91SKris Kennaway 	if (options->gateway_ports == -1)
210e8aafc91SKris Kennaway 		options->gateway_ports = 0;
211c2d3a559SKris Kennaway 	if (options->max_startups == -1)
212c2d3a559SKris Kennaway 		options->max_startups = 10;
213c2d3a559SKris Kennaway 	if (options->max_startups_rate == -1)
214c2d3a559SKris Kennaway 		options->max_startups_rate = 100;		/* 100% */
215c2d3a559SKris Kennaway 	if (options->max_startups_begin == -1)
216c2d3a559SKris Kennaway 		options->max_startups_begin = options->max_startups;
217af12a3e7SDag-Erling Smørgrav 	if (options->verify_reverse_mapping == -1)
218af12a3e7SDag-Erling Smørgrav 		options->verify_reverse_mapping = 0;
219ca3176e7SBrian Feldman 	if (options->client_alive_interval == -1)
220ca3176e7SBrian Feldman 		options->client_alive_interval = 0;
221ca3176e7SBrian Feldman 	if (options->client_alive_count_max == -1)
222ca3176e7SBrian Feldman 		options->client_alive_count_max = 3;
223af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file2 == NULL) {
224af12a3e7SDag-Erling Smørgrav 		/* authorized_keys_file2 falls back to authorized_keys_file */
225af12a3e7SDag-Erling Smørgrav 		if (options->authorized_keys_file != NULL)
226af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = options->authorized_keys_file;
227af12a3e7SDag-Erling Smørgrav 		else
228af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
229af12a3e7SDag-Erling Smørgrav 	}
230af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file == NULL)
231af12a3e7SDag-Erling Smørgrav 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
232511b41d2SMark Murray }
233511b41d2SMark Murray 
234511b41d2SMark Murray /* Keyword tokens. */
235511b41d2SMark Murray typedef enum {
236511b41d2SMark Murray 	sBadOption,		/* == unknown option */
237511b41d2SMark Murray 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
238511b41d2SMark Murray 	sPermitRootLogin, sLogFacility, sLogLevel,
239511b41d2SMark Murray 	sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
240cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
241af12a3e7SDag-Erling Smørgrav 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
242cb96ab36SAssar Westerlund #endif
243af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
244af12a3e7SDag-Erling Smørgrav 	sKerberosTgtPassing,
245511b41d2SMark Murray #endif
246511b41d2SMark Murray #ifdef AFS
247af12a3e7SDag-Erling Smørgrav 	sAFSTokenPassing,
248511b41d2SMark Murray #endif
249ca3176e7SBrian Feldman 	sChallengeResponseAuthentication,
25009958426SBrian Feldman 	sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
251ca3176e7SBrian Feldman 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
252af12a3e7SDag-Erling Smørgrav 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
253af12a3e7SDag-Erling Smørgrav 	sStrictModes, sEmptyPasswd, sKeepAlives,
25409958426SBrian Feldman 	sUseLogin, sAllowTcpForwarding,
25509958426SBrian Feldman 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
256ca3176e7SBrian Feldman 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
257ca3176e7SBrian Feldman 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
258af12a3e7SDag-Erling Smørgrav 	sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
259ca3176e7SBrian Feldman 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
260af12a3e7SDag-Erling Smørgrav 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
261af12a3e7SDag-Erling Smørgrav 	sCheckMail, sVersionAddendum,
262af12a3e7SDag-Erling Smørgrav 	sDeprecated
263511b41d2SMark Murray } ServerOpCodes;
264511b41d2SMark Murray 
265511b41d2SMark Murray /* Textual representation of the tokens. */
266511b41d2SMark Murray static struct {
267511b41d2SMark Murray 	const char *name;
268511b41d2SMark Murray 	ServerOpCodes opcode;
269511b41d2SMark Murray } keywords[] = {
270511b41d2SMark Murray 	{ "port", sPort },
271511b41d2SMark Murray 	{ "hostkey", sHostKeyFile },
272ca3176e7SBrian Feldman 	{ "hostdsakey", sHostKeyFile },					/* alias */
273e8aafc91SKris Kennaway 	{ "pidfile", sPidFile },
274511b41d2SMark Murray 	{ "serverkeybits", sServerKeyBits },
275511b41d2SMark Murray 	{ "logingracetime", sLoginGraceTime },
276511b41d2SMark Murray 	{ "keyregenerationinterval", sKeyRegenerationTime },
277511b41d2SMark Murray 	{ "permitrootlogin", sPermitRootLogin },
278511b41d2SMark Murray 	{ "syslogfacility", sLogFacility },
279511b41d2SMark Murray 	{ "loglevel", sLogLevel },
280511b41d2SMark Murray 	{ "rhostsauthentication", sRhostsAuthentication },
281511b41d2SMark Murray 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
282ca3176e7SBrian Feldman 	{ "hostbasedauthentication", sHostbasedAuthentication },
283ca3176e7SBrian Feldman 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
284af12a3e7SDag-Erling Smørgrav 	{ "rsaauthentication", sRSAAuthentication },
285ca3176e7SBrian Feldman 	{ "pubkeyauthentication", sPubkeyAuthentication },
286ca3176e7SBrian Feldman 	{ "dsaauthentication", sPubkeyAuthentication },			/* alias */
287cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
288cb96ab36SAssar Westerlund 	{ "kerberosauthentication", sKerberosAuthentication },
289af12a3e7SDag-Erling Smørgrav 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
290af12a3e7SDag-Erling Smørgrav 	{ "kerberosticketcleanup", sKerberosTicketCleanup },
291cb96ab36SAssar Westerlund #endif
292af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
293af12a3e7SDag-Erling Smørgrav 	{ "kerberostgtpassing", sKerberosTgtPassing },
294511b41d2SMark Murray #endif
295511b41d2SMark Murray #ifdef AFS
296511b41d2SMark Murray 	{ "afstokenpassing", sAFSTokenPassing },
297511b41d2SMark Murray #endif
298511b41d2SMark Murray 	{ "passwordauthentication", sPasswordAuthentication },
29909958426SBrian Feldman 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
300ca3176e7SBrian Feldman 	{ "challengeresponseauthentication", sChallengeResponseAuthentication },
301ca3176e7SBrian Feldman 	{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
302511b41d2SMark Murray 	{ "listenaddress", sListenAddress },
303511b41d2SMark Murray 	{ "printmotd", sPrintMotd },
304ca3176e7SBrian Feldman 	{ "printlastlog", sPrintLastLog },
305511b41d2SMark Murray 	{ "ignorerhosts", sIgnoreRhosts },
306511b41d2SMark Murray 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
307511b41d2SMark Murray 	{ "x11forwarding", sX11Forwarding },
308511b41d2SMark Murray 	{ "x11displayoffset", sX11DisplayOffset },
309af12a3e7SDag-Erling Smørgrav 	{ "x11uselocalhost", sX11UseLocalhost },
310c2d3a559SKris Kennaway 	{ "xauthlocation", sXAuthLocation },
311511b41d2SMark Murray 	{ "strictmodes", sStrictModes },
312511b41d2SMark Murray 	{ "permitemptypasswords", sEmptyPasswd },
313511b41d2SMark Murray 	{ "uselogin", sUseLogin },
314511b41d2SMark Murray 	{ "keepalive", sKeepAlives },
31509958426SBrian Feldman 	{ "allowtcpforwarding", sAllowTcpForwarding },
316511b41d2SMark Murray 	{ "allowusers", sAllowUsers },
317511b41d2SMark Murray 	{ "denyusers", sDenyUsers },
318511b41d2SMark Murray 	{ "allowgroups", sAllowGroups },
319511b41d2SMark Murray 	{ "denygroups", sDenyGroups },
320e8aafc91SKris Kennaway 	{ "ciphers", sCiphers },
321ca3176e7SBrian Feldman 	{ "macs", sMacs },
322e8aafc91SKris Kennaway 	{ "protocol", sProtocol },
323e8aafc91SKris Kennaway 	{ "gatewayports", sGatewayPorts },
324c2d3a559SKris Kennaway 	{ "subsystem", sSubsystem },
325c2d3a559SKris Kennaway 	{ "maxstartups", sMaxStartups },
326ca3176e7SBrian Feldman 	{ "banner", sBanner },
327af12a3e7SDag-Erling Smørgrav 	{ "verifyreversemapping", sVerifyReverseMapping },
328af12a3e7SDag-Erling Smørgrav 	{ "reversemappingcheck", sVerifyReverseMapping },
329ca3176e7SBrian Feldman 	{ "clientaliveinterval", sClientAliveInterval },
330ca3176e7SBrian Feldman 	{ "clientalivecountmax", sClientAliveCountMax },
331af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile", sAuthorizedKeysFile },
332af12a3e7SDag-Erling Smørgrav 	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
333af12a3e7SDag-Erling Smørgrav 	{ "checkmail", sCheckMail },
334af12a3e7SDag-Erling Smørgrav 	{ "versionaddendum", sVersionAddendum },
335af12a3e7SDag-Erling Smørgrav 	{ NULL, sBadOption }
336511b41d2SMark Murray };
337511b41d2SMark Murray 
338511b41d2SMark Murray /*
339ca3176e7SBrian Feldman  * Returns the number of the token pointed to by cp or sBadOption.
340511b41d2SMark Murray  */
341511b41d2SMark Murray 
342511b41d2SMark Murray static ServerOpCodes
343511b41d2SMark Murray parse_token(const char *cp, const char *filename,
344511b41d2SMark Murray 	    int linenum)
345511b41d2SMark Murray {
346ca3176e7SBrian Feldman 	u_int i;
347511b41d2SMark Murray 
348511b41d2SMark Murray 	for (i = 0; keywords[i].name; i++)
349511b41d2SMark Murray 		if (strcasecmp(cp, keywords[i].name) == 0)
350511b41d2SMark Murray 			return keywords[i].opcode;
351511b41d2SMark Murray 
352ca3176e7SBrian Feldman 	error("%s: line %d: Bad configuration option: %s",
353511b41d2SMark Murray 	    filename, linenum, cp);
354511b41d2SMark Murray 	return sBadOption;
355511b41d2SMark Murray }
356511b41d2SMark Murray 
357af12a3e7SDag-Erling Smørgrav static void
358ca3176e7SBrian Feldman add_listen_addr(ServerOptions *options, char *addr, u_short port)
359511b41d2SMark Murray {
360511b41d2SMark Murray 	int i;
361511b41d2SMark Murray 
362511b41d2SMark Murray 	if (options->num_ports == 0)
363511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
364ca3176e7SBrian Feldman 	if (port == 0)
365ca3176e7SBrian Feldman 		for (i = 0; i < options->num_ports; i++)
366ca3176e7SBrian Feldman 			add_one_listen_addr(options, addr, options->ports[i]);
367ca3176e7SBrian Feldman 	else
368ca3176e7SBrian Feldman 		add_one_listen_addr(options, addr, port);
369ca3176e7SBrian Feldman }
370ca3176e7SBrian Feldman 
371af12a3e7SDag-Erling Smørgrav static void
372ca3176e7SBrian Feldman add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
373ca3176e7SBrian Feldman {
374ca3176e7SBrian Feldman 	struct addrinfo hints, *ai, *aitop;
375ca3176e7SBrian Feldman 	char strport[NI_MAXSERV];
376ca3176e7SBrian Feldman 	int gaierr;
377ca3176e7SBrian Feldman 
378511b41d2SMark Murray 	memset(&hints, 0, sizeof(hints));
379511b41d2SMark Murray 	hints.ai_family = IPv4or6;
380511b41d2SMark Murray 	hints.ai_socktype = SOCK_STREAM;
381511b41d2SMark Murray 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
382ca3176e7SBrian Feldman 	snprintf(strport, sizeof strport, "%d", port);
383511b41d2SMark Murray 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
384ca3176e7SBrian Feldman 		fatal("bad addr or host: %s (%s)",
385511b41d2SMark Murray 		    addr ? addr : "<NULL>",
386511b41d2SMark Murray 		    gai_strerror(gaierr));
387511b41d2SMark Murray 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
388511b41d2SMark Murray 		;
389511b41d2SMark Murray 	ai->ai_next = options->listen_addrs;
390511b41d2SMark Murray 	options->listen_addrs = aitop;
391511b41d2SMark Murray }
392511b41d2SMark Murray 
393af12a3e7SDag-Erling Smørgrav int
394af12a3e7SDag-Erling Smørgrav process_server_config_line(ServerOptions *options, char *line,
395af12a3e7SDag-Erling Smørgrav     const char *filename, int linenum)
396511b41d2SMark Murray {
397ca3176e7SBrian Feldman 	char *cp, **charptr, *arg, *p;
398af12a3e7SDag-Erling Smørgrav 	int *intptr, value;
399511b41d2SMark Murray 	ServerOpCodes opcode;
400af12a3e7SDag-Erling Smørgrav 	int i, n;
401511b41d2SMark Murray 
402c2d3a559SKris Kennaway 	cp = line;
403c2d3a559SKris Kennaway 	arg = strdelim(&cp);
404c2d3a559SKris Kennaway 	/* Ignore leading whitespace */
405c2d3a559SKris Kennaway 	if (*arg == '\0')
406c2d3a559SKris Kennaway 		arg = strdelim(&cp);
407ca3176e7SBrian Feldman 	if (!arg || !*arg || *arg == '#')
408af12a3e7SDag-Erling Smørgrav 		return 0;
409ca3176e7SBrian Feldman 	intptr = NULL;
410ca3176e7SBrian Feldman 	charptr = NULL;
411c2d3a559SKris Kennaway 	opcode = parse_token(arg, filename, linenum);
412511b41d2SMark Murray 	switch (opcode) {
413511b41d2SMark Murray 	case sBadOption:
414af12a3e7SDag-Erling Smørgrav 		return -1;
415511b41d2SMark Murray 	case sPort:
416511b41d2SMark Murray 		/* ignore ports from configfile if cmdline specifies ports */
417511b41d2SMark Murray 		if (options->ports_from_cmdline)
418af12a3e7SDag-Erling Smørgrav 			return 0;
419511b41d2SMark Murray 		if (options->listen_addrs != NULL)
420511b41d2SMark Murray 			fatal("%s line %d: ports must be specified before "
421af12a3e7SDag-Erling Smørgrav 			    "ListenAddress.", filename, linenum);
422511b41d2SMark Murray 		if (options->num_ports >= MAX_PORTS)
423ca3176e7SBrian Feldman 			fatal("%s line %d: too many ports.",
424511b41d2SMark Murray 			    filename, linenum);
425c2d3a559SKris Kennaway 		arg = strdelim(&cp);
426c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
427ca3176e7SBrian Feldman 			fatal("%s line %d: missing port number.",
428511b41d2SMark Murray 			    filename, linenum);
429ca3176e7SBrian Feldman 		options->ports[options->num_ports++] = a2port(arg);
430ca3176e7SBrian Feldman 		if (options->ports[options->num_ports-1] == 0)
431ca3176e7SBrian Feldman 			fatal("%s line %d: Badly formatted port number.",
432ca3176e7SBrian Feldman 			    filename, linenum);
433511b41d2SMark Murray 		break;
434511b41d2SMark Murray 
435511b41d2SMark Murray 	case sServerKeyBits:
436511b41d2SMark Murray 		intptr = &options->server_key_bits;
437511b41d2SMark Murray parse_int:
438c2d3a559SKris Kennaway 		arg = strdelim(&cp);
439ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
440ca3176e7SBrian Feldman 			fatal("%s line %d: missing integer value.",
441511b41d2SMark Murray 			    filename, linenum);
442c2d3a559SKris Kennaway 		value = atoi(arg);
443511b41d2SMark Murray 		if (*intptr == -1)
444511b41d2SMark Murray 			*intptr = value;
445511b41d2SMark Murray 		break;
446511b41d2SMark Murray 
447511b41d2SMark Murray 	case sLoginGraceTime:
448511b41d2SMark Murray 		intptr = &options->login_grace_time;
449af12a3e7SDag-Erling Smørgrav parse_time:
450af12a3e7SDag-Erling Smørgrav 		arg = strdelim(&cp);
451af12a3e7SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
452af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: missing time value.",
453af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
454af12a3e7SDag-Erling Smørgrav 		if ((value = convtime(arg)) == -1)
455af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: invalid time value.",
456af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
457af12a3e7SDag-Erling Smørgrav 		if (*intptr == -1)
458af12a3e7SDag-Erling Smørgrav 			*intptr = value;
459af12a3e7SDag-Erling Smørgrav 		break;
460511b41d2SMark Murray 
461511b41d2SMark Murray 	case sKeyRegenerationTime:
462511b41d2SMark Murray 		intptr = &options->key_regeneration_time;
463af12a3e7SDag-Erling Smørgrav 		goto parse_time;
464511b41d2SMark Murray 
465511b41d2SMark Murray 	case sListenAddress:
466c2d3a559SKris Kennaway 		arg = strdelim(&cp);
467ca3176e7SBrian Feldman 		if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
468ca3176e7SBrian Feldman 			fatal("%s line %d: missing inet addr.",
469511b41d2SMark Murray 			    filename, linenum);
470ca3176e7SBrian Feldman 		if (*arg == '[') {
471ca3176e7SBrian Feldman 			if ((p = strchr(arg, ']')) == NULL)
472ca3176e7SBrian Feldman 				fatal("%s line %d: bad ipv6 inet addr usage.",
473ca3176e7SBrian Feldman 				    filename, linenum);
474ca3176e7SBrian Feldman 			arg++;
475ca3176e7SBrian Feldman 			memmove(p, p+1, strlen(p+1)+1);
476ca3176e7SBrian Feldman 		} else if (((p = strchr(arg, ':')) == NULL) ||
477ca3176e7SBrian Feldman 			    (strchr(p+1, ':') != NULL)) {
478ca3176e7SBrian Feldman 			add_listen_addr(options, arg, 0);
479ca3176e7SBrian Feldman 			break;
480ca3176e7SBrian Feldman 		}
481ca3176e7SBrian Feldman 		if (*p == ':') {
482ca3176e7SBrian Feldman 			u_short port;
483ca3176e7SBrian Feldman 
484ca3176e7SBrian Feldman 			p++;
485ca3176e7SBrian Feldman 			if (*p == '\0')
486ca3176e7SBrian Feldman 				fatal("%s line %d: bad inet addr:port usage.",
487ca3176e7SBrian Feldman 				    filename, linenum);
488ca3176e7SBrian Feldman 			else {
489ca3176e7SBrian Feldman 				*(p-1) = '\0';
490ca3176e7SBrian Feldman 				if ((port = a2port(p)) == 0)
491ca3176e7SBrian Feldman 					fatal("%s line %d: bad port number.",
492ca3176e7SBrian Feldman 					    filename, linenum);
493ca3176e7SBrian Feldman 				add_listen_addr(options, arg, port);
494ca3176e7SBrian Feldman 			}
495ca3176e7SBrian Feldman 		} else if (*p == '\0')
496ca3176e7SBrian Feldman 			add_listen_addr(options, arg, 0);
497ca3176e7SBrian Feldman 		else
498ca3176e7SBrian Feldman 			fatal("%s line %d: bad inet addr usage.",
499ca3176e7SBrian Feldman 			    filename, linenum);
500511b41d2SMark Murray 		break;
501511b41d2SMark Murray 
502511b41d2SMark Murray 	case sHostKeyFile:
503ca3176e7SBrian Feldman 		intptr = &options->num_host_key_files;
504ca3176e7SBrian Feldman 		if (*intptr >= MAX_HOSTKEYS)
505ca3176e7SBrian Feldman 			fatal("%s line %d: too many host keys specified (max %d).",
506ca3176e7SBrian Feldman 			    filename, linenum, MAX_HOSTKEYS);
507ca3176e7SBrian Feldman 		charptr = &options->host_key_files[*intptr];
508c2d3a559SKris Kennaway parse_filename:
509c2d3a559SKris Kennaway 		arg = strdelim(&cp);
510ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
511ca3176e7SBrian Feldman 			fatal("%s line %d: missing file name.",
512e8aafc91SKris Kennaway 			    filename, linenum);
513ca3176e7SBrian Feldman 		if (*charptr == NULL) {
514c2d3a559SKris Kennaway 			*charptr = tilde_expand_filename(arg, getuid());
515ca3176e7SBrian Feldman 			/* increase optional counter */
516ca3176e7SBrian Feldman 			if (intptr != NULL)
517ca3176e7SBrian Feldman 				*intptr = *intptr + 1;
518ca3176e7SBrian Feldman 		}
519e8aafc91SKris Kennaway 		break;
520e8aafc91SKris Kennaway 
521e8aafc91SKris Kennaway 	case sPidFile:
522e8aafc91SKris Kennaway 		charptr = &options->pid_file;
523c2d3a559SKris Kennaway 		goto parse_filename;
524511b41d2SMark Murray 
525511b41d2SMark Murray 	case sPermitRootLogin:
526511b41d2SMark Murray 		intptr = &options->permit_root_login;
527c2d3a559SKris Kennaway 		arg = strdelim(&cp);
528ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
529ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/"
530ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
531ca3176e7SBrian Feldman 			    "argument.", filename, linenum);
532ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
533c2d3a559SKris Kennaway 		if (strcmp(arg, "without-password") == 0)
534ca3176e7SBrian Feldman 			value = PERMIT_NO_PASSWD;
535ca3176e7SBrian Feldman 		else if (strcmp(arg, "forced-commands-only") == 0)
536ca3176e7SBrian Feldman 			value = PERMIT_FORCED_ONLY;
537c2d3a559SKris Kennaway 		else if (strcmp(arg, "yes") == 0)
538ca3176e7SBrian Feldman 			value = PERMIT_YES;
539c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
540ca3176e7SBrian Feldman 			value = PERMIT_NO;
541ca3176e7SBrian Feldman 		else
542ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/"
543ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
544ca3176e7SBrian Feldman 			    "argument: %s", filename, linenum, arg);
545511b41d2SMark Murray 		if (*intptr == -1)
546511b41d2SMark Murray 			*intptr = value;
547511b41d2SMark Murray 		break;
548511b41d2SMark Murray 
549511b41d2SMark Murray 	case sIgnoreRhosts:
550511b41d2SMark Murray 		intptr = &options->ignore_rhosts;
551511b41d2SMark Murray parse_flag:
552c2d3a559SKris Kennaway 		arg = strdelim(&cp);
553ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
554ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/no argument.",
555511b41d2SMark Murray 			    filename, linenum);
556ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
557c2d3a559SKris Kennaway 		if (strcmp(arg, "yes") == 0)
558511b41d2SMark Murray 			value = 1;
559c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
560511b41d2SMark Murray 			value = 0;
561ca3176e7SBrian Feldman 		else
562ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/no argument: %s",
563c2d3a559SKris Kennaway 				filename, linenum, arg);
564511b41d2SMark Murray 		if (*intptr == -1)
565511b41d2SMark Murray 			*intptr = value;
566511b41d2SMark Murray 		break;
567511b41d2SMark Murray 
568511b41d2SMark Murray 	case sIgnoreUserKnownHosts:
569511b41d2SMark Murray 		intptr = &options->ignore_user_known_hosts;
570962a3f4eSSheldon Hearn 		goto parse_flag;
571511b41d2SMark Murray 
572511b41d2SMark Murray 	case sRhostsAuthentication:
573511b41d2SMark Murray 		intptr = &options->rhosts_authentication;
574511b41d2SMark Murray 		goto parse_flag;
575511b41d2SMark Murray 
576511b41d2SMark Murray 	case sRhostsRSAAuthentication:
577511b41d2SMark Murray 		intptr = &options->rhosts_rsa_authentication;
578511b41d2SMark Murray 		goto parse_flag;
579511b41d2SMark Murray 
580ca3176e7SBrian Feldman 	case sHostbasedAuthentication:
581ca3176e7SBrian Feldman 		intptr = &options->hostbased_authentication;
582ca3176e7SBrian Feldman 		goto parse_flag;
583ca3176e7SBrian Feldman 
584ca3176e7SBrian Feldman 	case sHostbasedUsesNameFromPacketOnly:
585ca3176e7SBrian Feldman 		intptr = &options->hostbased_uses_name_from_packet_only;
586ca3176e7SBrian Feldman 		goto parse_flag;
587ca3176e7SBrian Feldman 
588511b41d2SMark Murray 	case sRSAAuthentication:
589511b41d2SMark Murray 		intptr = &options->rsa_authentication;
590511b41d2SMark Murray 		goto parse_flag;
591511b41d2SMark Murray 
592ca3176e7SBrian Feldman 	case sPubkeyAuthentication:
593ca3176e7SBrian Feldman 		intptr = &options->pubkey_authentication;
594e8aafc91SKris Kennaway 		goto parse_flag;
595cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
596cb96ab36SAssar Westerlund 	case sKerberosAuthentication:
597cb96ab36SAssar Westerlund 		intptr = &options->kerberos_authentication;
598511b41d2SMark Murray 		goto parse_flag;
599511b41d2SMark Murray 
600af12a3e7SDag-Erling Smørgrav 	case sKerberosOrLocalPasswd:
601af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_or_local_passwd;
602511b41d2SMark Murray 		goto parse_flag;
603511b41d2SMark Murray 
604af12a3e7SDag-Erling Smørgrav 	case sKerberosTicketCleanup:
605af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_ticket_cleanup;
606511b41d2SMark Murray 		goto parse_flag;
607511b41d2SMark Murray #endif
608af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
609af12a3e7SDag-Erling Smørgrav 	case sKerberosTgtPassing:
610af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_tgt_passing;
611fe5fd017SMark Murray 		goto parse_flag;
612af12a3e7SDag-Erling Smørgrav #endif
613511b41d2SMark Murray #ifdef AFS
614511b41d2SMark Murray 	case sAFSTokenPassing:
615511b41d2SMark Murray 		intptr = &options->afs_token_passing;
616511b41d2SMark Murray 		goto parse_flag;
617511b41d2SMark Murray #endif
618511b41d2SMark Murray 
619511b41d2SMark Murray 	case sPasswordAuthentication:
620511b41d2SMark Murray 		intptr = &options->password_authentication;
621511b41d2SMark Murray 		goto parse_flag;
622511b41d2SMark Murray 
62309958426SBrian Feldman 	case sKbdInteractiveAuthentication:
62409958426SBrian Feldman 		intptr = &options->kbd_interactive_authentication;
62509958426SBrian Feldman 		goto parse_flag;
62609958426SBrian Feldman 
627ca3176e7SBrian Feldman 	case sChallengeResponseAuthentication:
628af12a3e7SDag-Erling Smørgrav 		intptr = &options->challenge_response_authentication;
629511b41d2SMark Murray 		goto parse_flag;
630511b41d2SMark Murray 
631511b41d2SMark Murray 	case sPrintMotd:
632511b41d2SMark Murray 		intptr = &options->print_motd;
633511b41d2SMark Murray 		goto parse_flag;
634511b41d2SMark Murray 
635ca3176e7SBrian Feldman 	case sPrintLastLog:
636ca3176e7SBrian Feldman 		intptr = &options->print_lastlog;
637ca3176e7SBrian Feldman 		goto parse_flag;
638ca3176e7SBrian Feldman 
639511b41d2SMark Murray 	case sX11Forwarding:
640511b41d2SMark Murray 		intptr = &options->x11_forwarding;
641511b41d2SMark Murray 		goto parse_flag;
642511b41d2SMark Murray 
643511b41d2SMark Murray 	case sX11DisplayOffset:
644511b41d2SMark Murray 		intptr = &options->x11_display_offset;
645511b41d2SMark Murray 		goto parse_int;
646511b41d2SMark Murray 
647af12a3e7SDag-Erling Smørgrav 	case sX11UseLocalhost:
648af12a3e7SDag-Erling Smørgrav 		intptr = &options->x11_use_localhost;
649af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
650af12a3e7SDag-Erling Smørgrav 
651c2d3a559SKris Kennaway 	case sXAuthLocation:
652c2d3a559SKris Kennaway 		charptr = &options->xauth_location;
653c2d3a559SKris Kennaway 		goto parse_filename;
654c2d3a559SKris Kennaway 
655511b41d2SMark Murray 	case sStrictModes:
656511b41d2SMark Murray 		intptr = &options->strict_modes;
657511b41d2SMark Murray 		goto parse_flag;
658511b41d2SMark Murray 
659511b41d2SMark Murray 	case sKeepAlives:
660511b41d2SMark Murray 		intptr = &options->keepalives;
661511b41d2SMark Murray 		goto parse_flag;
662511b41d2SMark Murray 
663511b41d2SMark Murray 	case sEmptyPasswd:
664511b41d2SMark Murray 		intptr = &options->permit_empty_passwd;
665511b41d2SMark Murray 		goto parse_flag;
666511b41d2SMark Murray 
667511b41d2SMark Murray 	case sUseLogin:
668511b41d2SMark Murray 		intptr = &options->use_login;
669511b41d2SMark Murray 		goto parse_flag;
670511b41d2SMark Murray 
671e8aafc91SKris Kennaway 	case sGatewayPorts:
672e8aafc91SKris Kennaway 		intptr = &options->gateway_ports;
673e8aafc91SKris Kennaway 		goto parse_flag;
674e8aafc91SKris Kennaway 
675af12a3e7SDag-Erling Smørgrav 	case sVerifyReverseMapping:
676af12a3e7SDag-Erling Smørgrav 		intptr = &options->verify_reverse_mapping;
677ca3176e7SBrian Feldman 		goto parse_flag;
678ca3176e7SBrian Feldman 
679511b41d2SMark Murray 	case sLogFacility:
680511b41d2SMark Murray 		intptr = (int *) &options->log_facility;
681c2d3a559SKris Kennaway 		arg = strdelim(&cp);
682c2d3a559SKris Kennaway 		value = log_facility_number(arg);
683af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_FACILITY_NOT_SET)
684ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log facility '%s'",
685c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
686511b41d2SMark Murray 		if (*intptr == -1)
687511b41d2SMark Murray 			*intptr = (SyslogFacility) value;
688511b41d2SMark Murray 		break;
689511b41d2SMark Murray 
690511b41d2SMark Murray 	case sLogLevel:
691511b41d2SMark Murray 		intptr = (int *) &options->log_level;
692c2d3a559SKris Kennaway 		arg = strdelim(&cp);
693c2d3a559SKris Kennaway 		value = log_level_number(arg);
694af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_LEVEL_NOT_SET)
695ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log level '%s'",
696c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
697511b41d2SMark Murray 		if (*intptr == -1)
698511b41d2SMark Murray 			*intptr = (LogLevel) value;
699511b41d2SMark Murray 		break;
700511b41d2SMark Murray 
70109958426SBrian Feldman 	case sAllowTcpForwarding:
70209958426SBrian Feldman 		intptr = &options->allow_tcp_forwarding;
70309958426SBrian Feldman 		goto parse_flag;
70409958426SBrian Feldman 
705511b41d2SMark Murray 	case sAllowUsers:
706c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
70742f71286SMark Murray 			if (options->num_allow_users >= MAX_ALLOW_USERS)
708af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow users.",
709e8aafc91SKris Kennaway 				    filename, linenum);
710c2d3a559SKris Kennaway 			options->allow_users[options->num_allow_users++] = xstrdup(arg);
711511b41d2SMark Murray 		}
712511b41d2SMark Murray 		break;
713511b41d2SMark Murray 
714511b41d2SMark Murray 	case sDenyUsers:
715c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
7162803b77eSBrian Feldman 			if (options->num_deny_users >= MAX_DENY_USERS)
717af12a3e7SDag-Erling Smørgrav 				fatal( "%s line %d: too many deny users.",
718e8aafc91SKris Kennaway 				    filename, linenum);
719c2d3a559SKris Kennaway 			options->deny_users[options->num_deny_users++] = xstrdup(arg);
720511b41d2SMark Murray 		}
721511b41d2SMark Murray 		break;
722511b41d2SMark Murray 
723511b41d2SMark Murray 	case sAllowGroups:
724c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
72542f71286SMark Murray 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
726af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow groups.",
727e8aafc91SKris Kennaway 				    filename, linenum);
728c2d3a559SKris Kennaway 			options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
729511b41d2SMark Murray 		}
730511b41d2SMark Murray 		break;
731511b41d2SMark Murray 
732511b41d2SMark Murray 	case sDenyGroups:
733c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
73442f71286SMark Murray 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
735af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many deny groups.",
736e8aafc91SKris Kennaway 				    filename, linenum);
737c2d3a559SKris Kennaway 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
738511b41d2SMark Murray 		}
739511b41d2SMark Murray 		break;
740511b41d2SMark Murray 
741e8aafc91SKris Kennaway 	case sCiphers:
742c2d3a559SKris Kennaway 		arg = strdelim(&cp);
743c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
744c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
745c2d3a559SKris Kennaway 		if (!ciphers_valid(arg))
746e8aafc91SKris Kennaway 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
747c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
748e8aafc91SKris Kennaway 		if (options->ciphers == NULL)
749c2d3a559SKris Kennaway 			options->ciphers = xstrdup(arg);
750e8aafc91SKris Kennaway 		break;
751e8aafc91SKris Kennaway 
752ca3176e7SBrian Feldman 	case sMacs:
753ca3176e7SBrian Feldman 		arg = strdelim(&cp);
754ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
755ca3176e7SBrian Feldman 			fatal("%s line %d: Missing argument.", filename, linenum);
756ca3176e7SBrian Feldman 		if (!mac_valid(arg))
757ca3176e7SBrian Feldman 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
758ca3176e7SBrian Feldman 			    filename, linenum, arg ? arg : "<NONE>");
759ca3176e7SBrian Feldman 		if (options->macs == NULL)
760ca3176e7SBrian Feldman 			options->macs = xstrdup(arg);
761ca3176e7SBrian Feldman 		break;
762ca3176e7SBrian Feldman 
763e8aafc91SKris Kennaway 	case sProtocol:
764e8aafc91SKris Kennaway 		intptr = &options->protocol;
765c2d3a559SKris Kennaway 		arg = strdelim(&cp);
766c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
767c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
768c2d3a559SKris Kennaway 		value = proto_spec(arg);
769e8aafc91SKris Kennaway 		if (value == SSH_PROTO_UNKNOWN)
770e8aafc91SKris Kennaway 			fatal("%s line %d: Bad protocol spec '%s'.",
771c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
772e8aafc91SKris Kennaway 		if (*intptr == SSH_PROTO_UNKNOWN)
773e8aafc91SKris Kennaway 			*intptr = value;
774e8aafc91SKris Kennaway 		break;
775e8aafc91SKris Kennaway 
776c2d3a559SKris Kennaway 	case sSubsystem:
777c2d3a559SKris Kennaway 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
778c2d3a559SKris Kennaway 			fatal("%s line %d: too many subsystems defined.",
779c2d3a559SKris Kennaway 			    filename, linenum);
780c2d3a559SKris Kennaway 		}
781c2d3a559SKris Kennaway 		arg = strdelim(&cp);
782c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
783c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem name.",
784c2d3a559SKris Kennaway 			    filename, linenum);
785c2d3a559SKris Kennaway 		for (i = 0; i < options->num_subsystems; i++)
786c2d3a559SKris Kennaway 			if (strcmp(arg, options->subsystem_name[i]) == 0)
787c2d3a559SKris Kennaway 				fatal("%s line %d: Subsystem '%s' already defined.",
788c2d3a559SKris Kennaway 				    filename, linenum, arg);
789c2d3a559SKris Kennaway 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
790c2d3a559SKris Kennaway 		arg = strdelim(&cp);
791c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
792c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem command.",
793c2d3a559SKris Kennaway 			    filename, linenum);
794c2d3a559SKris Kennaway 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
795c2d3a559SKris Kennaway 		options->num_subsystems++;
796c2d3a559SKris Kennaway 		break;
797c2d3a559SKris Kennaway 
798c2d3a559SKris Kennaway 	case sMaxStartups:
799c2d3a559SKris Kennaway 		arg = strdelim(&cp);
800c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
801c2d3a559SKris Kennaway 			fatal("%s line %d: Missing MaxStartups spec.",
802c2d3a559SKris Kennaway 			    filename, linenum);
803af12a3e7SDag-Erling Smørgrav 		if ((n = sscanf(arg, "%d:%d:%d",
804c2d3a559SKris Kennaway 		    &options->max_startups_begin,
805c2d3a559SKris Kennaway 		    &options->max_startups_rate,
806af12a3e7SDag-Erling Smørgrav 		    &options->max_startups)) == 3) {
807c2d3a559SKris Kennaway 			if (options->max_startups_begin >
808c2d3a559SKris Kennaway 			    options->max_startups ||
809c2d3a559SKris Kennaway 			    options->max_startups_rate > 100 ||
810c2d3a559SKris Kennaway 			    options->max_startups_rate < 1)
811c2d3a559SKris Kennaway 				fatal("%s line %d: Illegal MaxStartups spec.",
812c2d3a559SKris Kennaway 				    filename, linenum);
813af12a3e7SDag-Erling Smørgrav 		} else if (n != 1)
814af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: Illegal MaxStartups spec.",
815af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
816af12a3e7SDag-Erling Smørgrav 		else
817af12a3e7SDag-Erling Smørgrav 			options->max_startups = options->max_startups_begin;
818933ca70fSBrian Feldman 		break;
819933ca70fSBrian Feldman 
820ca3176e7SBrian Feldman 	case sBanner:
821ca3176e7SBrian Feldman 		charptr = &options->banner;
822ca3176e7SBrian Feldman 		goto parse_filename;
823af12a3e7SDag-Erling Smørgrav 	/*
824af12a3e7SDag-Erling Smørgrav 	 * These options can contain %X options expanded at
825af12a3e7SDag-Erling Smørgrav 	 * connect time, so that you can specify paths like:
826af12a3e7SDag-Erling Smørgrav 	 *
827af12a3e7SDag-Erling Smørgrav 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
828af12a3e7SDag-Erling Smørgrav 	 */
829af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile:
830af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile2:
831af12a3e7SDag-Erling Smørgrav 		charptr = (opcode == sAuthorizedKeysFile ) ?
832af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file :
833af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file2;
834af12a3e7SDag-Erling Smørgrav 		goto parse_filename;
835af12a3e7SDag-Erling Smørgrav 
836ca3176e7SBrian Feldman 	case sClientAliveInterval:
837ca3176e7SBrian Feldman 		intptr = &options->client_alive_interval;
838af12a3e7SDag-Erling Smørgrav 		goto parse_time;
839af12a3e7SDag-Erling Smørgrav 
840ca3176e7SBrian Feldman 	case sClientAliveCountMax:
841ca3176e7SBrian Feldman 		intptr = &options->client_alive_count_max;
842ca3176e7SBrian Feldman 		goto parse_int;
843af12a3e7SDag-Erling Smørgrav 
844af12a3e7SDag-Erling Smørgrav 	case sDeprecated:
845af12a3e7SDag-Erling Smørgrav 		log("%s line %d: Deprecated option %s",
846af12a3e7SDag-Erling Smørgrav 		    filename, linenum, arg);
847af12a3e7SDag-Erling Smørgrav 		while (arg)
848af12a3e7SDag-Erling Smørgrav 		    arg = strdelim(&cp);
849af12a3e7SDag-Erling Smørgrav 		break;
850af12a3e7SDag-Erling Smørgrav 
851af12a3e7SDag-Erling Smørgrav 	case sCheckMail:
852af12a3e7SDag-Erling Smørgrav 		intptr = &options->check_mail;
853af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
854af12a3e7SDag-Erling Smørgrav 
855af12a3e7SDag-Erling Smørgrav 	case sVersionAddendum:
856af12a3e7SDag-Erling Smørgrav 		ssh_version_set_addendum(strtok(cp, "\n"));
857af12a3e7SDag-Erling Smørgrav 		do {
858af12a3e7SDag-Erling Smørgrav 			arg = strdelim(&cp);
859af12a3e7SDag-Erling Smørgrav 		} while (arg != NULL && *arg != '\0');
860af12a3e7SDag-Erling Smørgrav 		break;
861af12a3e7SDag-Erling Smørgrav 
86242f71286SMark Murray 	default:
863af12a3e7SDag-Erling Smørgrav 		fatal("%s line %d: Missing handler for opcode %s (%d)",
864c2d3a559SKris Kennaway 		    filename, linenum, arg, opcode);
865511b41d2SMark Murray 	}
866ca3176e7SBrian Feldman 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
867ca3176e7SBrian Feldman 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
868c2d3a559SKris Kennaway 		    filename, linenum, arg);
869af12a3e7SDag-Erling Smørgrav 	return 0;
870af12a3e7SDag-Erling Smørgrav }
871af12a3e7SDag-Erling Smørgrav 
872af12a3e7SDag-Erling Smørgrav /* Reads the server configuration file. */
873af12a3e7SDag-Erling Smørgrav 
874af12a3e7SDag-Erling Smørgrav void
875af12a3e7SDag-Erling Smørgrav read_server_config(ServerOptions *options, const char *filename)
876af12a3e7SDag-Erling Smørgrav {
877af12a3e7SDag-Erling Smørgrav 	FILE *f;
878af12a3e7SDag-Erling Smørgrav 	char line[1024];
879af12a3e7SDag-Erling Smørgrav 	int linenum;
880af12a3e7SDag-Erling Smørgrav 	int bad_options = 0;
881af12a3e7SDag-Erling Smørgrav 
882af12a3e7SDag-Erling Smørgrav 	f = fopen(filename, "r");
883af12a3e7SDag-Erling Smørgrav 	if (!f) {
884af12a3e7SDag-Erling Smørgrav 		perror(filename);
885af12a3e7SDag-Erling Smørgrav 		exit(1);
886af12a3e7SDag-Erling Smørgrav 	}
887af12a3e7SDag-Erling Smørgrav 	linenum = 0;
888af12a3e7SDag-Erling Smørgrav 	while (fgets(line, sizeof(line), f)) {
889af12a3e7SDag-Erling Smørgrav 		/* Update line number counter. */
890af12a3e7SDag-Erling Smørgrav 		linenum++;
891af12a3e7SDag-Erling Smørgrav 		if (process_server_config_line(options, line, filename, linenum) != 0)
892af12a3e7SDag-Erling Smørgrav 			bad_options++;
893511b41d2SMark Murray 	}
894511b41d2SMark Murray 	fclose(f);
895ca3176e7SBrian Feldman 	if (bad_options > 0)
896af12a3e7SDag-Erling Smørgrav 		fatal("%s: terminating, %d bad configuration options",
897511b41d2SMark Murray 		    filename, bad_options);
898511b41d2SMark Murray }
899