xref: /freebsd/crypto/openssh/servconf.c (revision 7aee6ffee0748c4c6bd9d11bb2a90c7531244d63)
17aee6ffeSDag-Erling Smørgrav /* $OpenBSD: servconf.c,v 1.195 2009/04/14 21:10:54 jj Exp $ */
2511b41d2SMark Murray /*
3511b41d2SMark Murray  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4511b41d2SMark Murray  *                    All rights reserved
5511b41d2SMark Murray  *
6c2d3a559SKris Kennaway  * As far as I am concerned, the code I have written for this software
7c2d3a559SKris Kennaway  * can be used freely for any purpose.  Any derived versions of this
8c2d3a559SKris Kennaway  * software must be clearly marked as such, and if the derived work is
9c2d3a559SKris Kennaway  * incompatible with the protocol description in the RFC file, it must be
10c2d3a559SKris Kennaway  * called by a name other than "ssh" or "Secure Shell".
11511b41d2SMark Murray  */
12511b41d2SMark Murray 
13511b41d2SMark Murray #include "includes.h"
14333ee039SDag-Erling Smørgrav __RCSID("$FreeBSD$");
15511b41d2SMark Murray 
16333ee039SDag-Erling Smørgrav #include <sys/types.h>
17333ee039SDag-Erling Smørgrav #include <sys/socket.h>
18333ee039SDag-Erling Smørgrav 
19333ee039SDag-Erling Smørgrav #include <netdb.h>
20333ee039SDag-Erling Smørgrav #include <pwd.h>
21333ee039SDag-Erling Smørgrav #include <stdio.h>
22333ee039SDag-Erling Smørgrav #include <stdlib.h>
23333ee039SDag-Erling Smørgrav #include <string.h>
24333ee039SDag-Erling Smørgrav #include <signal.h>
25333ee039SDag-Erling Smørgrav #include <unistd.h>
26333ee039SDag-Erling Smørgrav #include <stdarg.h>
27d4af9e69SDag-Erling Smørgrav #include <errno.h>
28333ee039SDag-Erling Smørgrav 
29d4af9e69SDag-Erling Smørgrav #include "openbsd-compat/sys-queue.h"
30333ee039SDag-Erling Smørgrav #include "xmalloc.h"
31511b41d2SMark Murray #include "ssh.h"
32ca3176e7SBrian Feldman #include "log.h"
33333ee039SDag-Erling Smørgrav #include "buffer.h"
34511b41d2SMark Murray #include "servconf.h"
35e8aafc91SKris Kennaway #include "compat.h"
36ca3176e7SBrian Feldman #include "pathnames.h"
37ca3176e7SBrian Feldman #include "misc.h"
38ca3176e7SBrian Feldman #include "cipher.h"
39333ee039SDag-Erling Smørgrav #include "key.h"
40ca3176e7SBrian Feldman #include "kex.h"
41ca3176e7SBrian Feldman #include "mac.h"
42333ee039SDag-Erling Smørgrav #include "match.h"
43333ee039SDag-Erling Smørgrav #include "channels.h"
44333ee039SDag-Erling Smørgrav #include "groupaccess.h"
45511b41d2SMark Murray 
46cce7d346SDag-Erling Smørgrav static void add_listen_addr(ServerOptions *, char *, int);
47cce7d346SDag-Erling Smørgrav static void add_one_listen_addr(ServerOptions *, char *, int);
48ca3176e7SBrian Feldman 
4980628bacSDag-Erling Smørgrav /* Use of privilege separation or not */
5080628bacSDag-Erling Smørgrav extern int use_privsep;
51333ee039SDag-Erling Smørgrav extern Buffer cfg;
52511b41d2SMark Murray 
53511b41d2SMark Murray /* Initializes the server options to their default values. */
54511b41d2SMark Murray 
55511b41d2SMark Murray void
56511b41d2SMark Murray initialize_server_options(ServerOptions *options)
57511b41d2SMark Murray {
58511b41d2SMark Murray 	memset(options, 0, sizeof(*options));
59989dd127SDag-Erling Smørgrav 
60989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
61cf2b5f3bSDag-Erling Smørgrav 	options->use_pam = -1;
62989dd127SDag-Erling Smørgrav 
63989dd127SDag-Erling Smørgrav 	/* Standard Options */
64511b41d2SMark Murray 	options->num_ports = 0;
65511b41d2SMark Murray 	options->ports_from_cmdline = 0;
66511b41d2SMark Murray 	options->listen_addrs = NULL;
67aa49c926SDag-Erling Smørgrav 	options->address_family = -1;
68ca3176e7SBrian Feldman 	options->num_host_key_files = 0;
69e8aafc91SKris Kennaway 	options->pid_file = NULL;
70511b41d2SMark Murray 	options->server_key_bits = -1;
71511b41d2SMark Murray 	options->login_grace_time = -1;
72511b41d2SMark Murray 	options->key_regeneration_time = -1;
73ca3176e7SBrian Feldman 	options->permit_root_login = PERMIT_NOT_SET;
74511b41d2SMark Murray 	options->ignore_rhosts = -1;
75511b41d2SMark Murray 	options->ignore_user_known_hosts = -1;
76511b41d2SMark Murray 	options->print_motd = -1;
77ca3176e7SBrian Feldman 	options->print_lastlog = -1;
78511b41d2SMark Murray 	options->x11_forwarding = -1;
79511b41d2SMark Murray 	options->x11_display_offset = -1;
80af12a3e7SDag-Erling Smørgrav 	options->x11_use_localhost = -1;
81c2d3a559SKris Kennaway 	options->xauth_location = NULL;
82511b41d2SMark Murray 	options->strict_modes = -1;
831ec0d754SDag-Erling Smørgrav 	options->tcp_keep_alive = -1;
84af12a3e7SDag-Erling Smørgrav 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
85af12a3e7SDag-Erling Smørgrav 	options->log_level = SYSLOG_LEVEL_NOT_SET;
86511b41d2SMark Murray 	options->rhosts_rsa_authentication = -1;
87ca3176e7SBrian Feldman 	options->hostbased_authentication = -1;
88ca3176e7SBrian Feldman 	options->hostbased_uses_name_from_packet_only = -1;
89511b41d2SMark Murray 	options->rsa_authentication = -1;
90ca3176e7SBrian Feldman 	options->pubkey_authentication = -1;
91cb96ab36SAssar Westerlund 	options->kerberos_authentication = -1;
92af12a3e7SDag-Erling Smørgrav 	options->kerberos_or_local_passwd = -1;
93af12a3e7SDag-Erling Smørgrav 	options->kerberos_ticket_cleanup = -1;
941ec0d754SDag-Erling Smørgrav 	options->kerberos_get_afs_token = -1;
95cf2b5f3bSDag-Erling Smørgrav 	options->gss_authentication=-1;
96cf2b5f3bSDag-Erling Smørgrav 	options->gss_cleanup_creds = -1;
97511b41d2SMark Murray 	options->password_authentication = -1;
9809958426SBrian Feldman 	options->kbd_interactive_authentication = -1;
99af12a3e7SDag-Erling Smørgrav 	options->challenge_response_authentication = -1;
100511b41d2SMark Murray 	options->permit_empty_passwd = -1;
101f388f5efSDag-Erling Smørgrav 	options->permit_user_env = -1;
102511b41d2SMark Murray 	options->use_login = -1;
10380628bacSDag-Erling Smørgrav 	options->compression = -1;
10409958426SBrian Feldman 	options->allow_tcp_forwarding = -1;
105d4af9e69SDag-Erling Smørgrav 	options->allow_agent_forwarding = -1;
106511b41d2SMark Murray 	options->num_allow_users = 0;
107511b41d2SMark Murray 	options->num_deny_users = 0;
108511b41d2SMark Murray 	options->num_allow_groups = 0;
109511b41d2SMark Murray 	options->num_deny_groups = 0;
110e8aafc91SKris Kennaway 	options->ciphers = NULL;
111ca3176e7SBrian Feldman 	options->macs = NULL;
112e8aafc91SKris Kennaway 	options->protocol = SSH_PROTO_UNKNOWN;
113e8aafc91SKris Kennaway 	options->gateway_ports = -1;
114c2d3a559SKris Kennaway 	options->num_subsystems = 0;
115c2d3a559SKris Kennaway 	options->max_startups_begin = -1;
116c2d3a559SKris Kennaway 	options->max_startups_rate = -1;
117c2d3a559SKris Kennaway 	options->max_startups = -1;
11821e764dfSDag-Erling Smørgrav 	options->max_authtries = -1;
119d4af9e69SDag-Erling Smørgrav 	options->max_sessions = -1;
120ca3176e7SBrian Feldman 	options->banner = NULL;
121cf2b5f3bSDag-Erling Smørgrav 	options->use_dns = -1;
122ca3176e7SBrian Feldman 	options->client_alive_interval = -1;
123ca3176e7SBrian Feldman 	options->client_alive_count_max = -1;
124af12a3e7SDag-Erling Smørgrav 	options->authorized_keys_file = NULL;
125af12a3e7SDag-Erling Smørgrav 	options->authorized_keys_file2 = NULL;
12621e764dfSDag-Erling Smørgrav 	options->num_accept_env = 0;
127b74df5b2SDag-Erling Smørgrav 	options->permit_tun = -1;
128333ee039SDag-Erling Smørgrav 	options->num_permitted_opens = -1;
129333ee039SDag-Erling Smørgrav 	options->adm_forced_command = NULL;
130d4af9e69SDag-Erling Smørgrav 	options->chroot_directory = NULL;
131cce7d346SDag-Erling Smørgrav 	options->zero_knowledge_password_authentication = -1;
132511b41d2SMark Murray }
133511b41d2SMark Murray 
134511b41d2SMark Murray void
135511b41d2SMark Murray fill_default_server_options(ServerOptions *options)
136511b41d2SMark Murray {
137989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
138cf2b5f3bSDag-Erling Smørgrav 	if (options->use_pam == -1)
139f0477b26SDag-Erling Smørgrav 		options->use_pam = 1;
140989dd127SDag-Erling Smørgrav 
141989dd127SDag-Erling Smørgrav 	/* Standard Options */
142ca3176e7SBrian Feldman 	if (options->protocol == SSH_PROTO_UNKNOWN)
143028c324aSDag-Erling Smørgrav 		options->protocol = SSH_PROTO_2;
144ca3176e7SBrian Feldman 	if (options->num_host_key_files == 0) {
145ca3176e7SBrian Feldman 		/* fill default hostkeys for protocols */
146ca3176e7SBrian Feldman 		if (options->protocol & SSH_PROTO_1)
147af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
148af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_KEY_FILE;
149af12a3e7SDag-Erling Smørgrav 		if (options->protocol & SSH_PROTO_2) {
150af12a3e7SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
151d4af9e69SDag-Erling Smørgrav                             _PATH_HOST_RSA_KEY_FILE;
152d4af9e69SDag-Erling Smørgrav 			options->host_key_files[options->num_host_key_files++] =
153af12a3e7SDag-Erling Smørgrav 			    _PATH_HOST_DSA_KEY_FILE;
154af12a3e7SDag-Erling Smørgrav 		}
155ca3176e7SBrian Feldman 	}
156511b41d2SMark Murray 	if (options->num_ports == 0)
157511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
158511b41d2SMark Murray 	if (options->listen_addrs == NULL)
159ca3176e7SBrian Feldman 		add_listen_addr(options, NULL, 0);
160e8aafc91SKris Kennaway 	if (options->pid_file == NULL)
161ca3176e7SBrian Feldman 		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
162511b41d2SMark Murray 	if (options->server_key_bits == -1)
163d4af9e69SDag-Erling Smørgrav 		options->server_key_bits = 1024;
164511b41d2SMark Murray 	if (options->login_grace_time == -1)
165975616f0SDag-Erling Smørgrav 		options->login_grace_time = 120;
166511b41d2SMark Murray 	if (options->key_regeneration_time == -1)
167511b41d2SMark Murray 		options->key_regeneration_time = 3600;
168ca3176e7SBrian Feldman 	if (options->permit_root_login == PERMIT_NOT_SET)
169975616f0SDag-Erling Smørgrav 		options->permit_root_login = PERMIT_NO;
170511b41d2SMark Murray 	if (options->ignore_rhosts == -1)
171fe5fd017SMark Murray 		options->ignore_rhosts = 1;
172511b41d2SMark Murray 	if (options->ignore_user_known_hosts == -1)
173511b41d2SMark Murray 		options->ignore_user_known_hosts = 0;
174511b41d2SMark Murray 	if (options->print_motd == -1)
175511b41d2SMark Murray 		options->print_motd = 1;
176ca3176e7SBrian Feldman 	if (options->print_lastlog == -1)
177ca3176e7SBrian Feldman 		options->print_lastlog = 1;
178511b41d2SMark Murray 	if (options->x11_forwarding == -1)
179975616f0SDag-Erling Smørgrav 		options->x11_forwarding = 1;
180511b41d2SMark Murray 	if (options->x11_display_offset == -1)
181fe5fd017SMark Murray 		options->x11_display_offset = 10;
182af12a3e7SDag-Erling Smørgrav 	if (options->x11_use_localhost == -1)
183af12a3e7SDag-Erling Smørgrav 		options->x11_use_localhost = 1;
184c2d3a559SKris Kennaway 	if (options->xauth_location == NULL)
185af12a3e7SDag-Erling Smørgrav 		options->xauth_location = _PATH_XAUTH;
186511b41d2SMark Murray 	if (options->strict_modes == -1)
187511b41d2SMark Murray 		options->strict_modes = 1;
1881ec0d754SDag-Erling Smørgrav 	if (options->tcp_keep_alive == -1)
1891ec0d754SDag-Erling Smørgrav 		options->tcp_keep_alive = 1;
190af12a3e7SDag-Erling Smørgrav 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
191511b41d2SMark Murray 		options->log_facility = SYSLOG_FACILITY_AUTH;
192af12a3e7SDag-Erling Smørgrav 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
193511b41d2SMark Murray 		options->log_level = SYSLOG_LEVEL_INFO;
194511b41d2SMark Murray 	if (options->rhosts_rsa_authentication == -1)
195fe5fd017SMark Murray 		options->rhosts_rsa_authentication = 0;
196ca3176e7SBrian Feldman 	if (options->hostbased_authentication == -1)
197ca3176e7SBrian Feldman 		options->hostbased_authentication = 0;
198ca3176e7SBrian Feldman 	if (options->hostbased_uses_name_from_packet_only == -1)
199ca3176e7SBrian Feldman 		options->hostbased_uses_name_from_packet_only = 0;
200511b41d2SMark Murray 	if (options->rsa_authentication == -1)
201511b41d2SMark Murray 		options->rsa_authentication = 1;
202ca3176e7SBrian Feldman 	if (options->pubkey_authentication == -1)
203ca3176e7SBrian Feldman 		options->pubkey_authentication = 1;
204989dd127SDag-Erling Smørgrav 	if (options->kerberos_authentication == -1)
205cf2b5f3bSDag-Erling Smørgrav 		options->kerberos_authentication = 0;
206af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_or_local_passwd == -1)
207af12a3e7SDag-Erling Smørgrav 		options->kerberos_or_local_passwd = 1;
208af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_ticket_cleanup == -1)
209af12a3e7SDag-Erling Smørgrav 		options->kerberos_ticket_cleanup = 1;
2101ec0d754SDag-Erling Smørgrav 	if (options->kerberos_get_afs_token == -1)
2111ec0d754SDag-Erling Smørgrav 		options->kerberos_get_afs_token = 0;
212cf2b5f3bSDag-Erling Smørgrav 	if (options->gss_authentication == -1)
213cf2b5f3bSDag-Erling Smørgrav 		options->gss_authentication = 0;
214cf2b5f3bSDag-Erling Smørgrav 	if (options->gss_cleanup_creds == -1)
215cf2b5f3bSDag-Erling Smørgrav 		options->gss_cleanup_creds = 1;
216511b41d2SMark Murray 	if (options->password_authentication == -1)
217b909c84bSDag-Erling Smørgrav 		options->password_authentication = 0;
21809958426SBrian Feldman 	if (options->kbd_interactive_authentication == -1)
21909958426SBrian Feldman 		options->kbd_interactive_authentication = 0;
220af12a3e7SDag-Erling Smørgrav 	if (options->challenge_response_authentication == -1)
22180241871SDag-Erling Smørgrav 		options->challenge_response_authentication = 1;
222511b41d2SMark Murray 	if (options->permit_empty_passwd == -1)
223fe5fd017SMark Murray 		options->permit_empty_passwd = 0;
224f388f5efSDag-Erling Smørgrav 	if (options->permit_user_env == -1)
225f388f5efSDag-Erling Smørgrav 		options->permit_user_env = 0;
226511b41d2SMark Murray 	if (options->use_login == -1)
227511b41d2SMark Murray 		options->use_login = 0;
22880628bacSDag-Erling Smørgrav 	if (options->compression == -1)
229d4ecd108SDag-Erling Smørgrav 		options->compression = COMP_DELAYED;
23009958426SBrian Feldman 	if (options->allow_tcp_forwarding == -1)
23109958426SBrian Feldman 		options->allow_tcp_forwarding = 1;
232d4af9e69SDag-Erling Smørgrav 	if (options->allow_agent_forwarding == -1)
233d4af9e69SDag-Erling Smørgrav 		options->allow_agent_forwarding = 1;
234e8aafc91SKris Kennaway 	if (options->gateway_ports == -1)
235e8aafc91SKris Kennaway 		options->gateway_ports = 0;
236c2d3a559SKris Kennaway 	if (options->max_startups == -1)
237c2d3a559SKris Kennaway 		options->max_startups = 10;
238c2d3a559SKris Kennaway 	if (options->max_startups_rate == -1)
239c2d3a559SKris Kennaway 		options->max_startups_rate = 100;		/* 100% */
240c2d3a559SKris Kennaway 	if (options->max_startups_begin == -1)
241c2d3a559SKris Kennaway 		options->max_startups_begin = options->max_startups;
24221e764dfSDag-Erling Smørgrav 	if (options->max_authtries == -1)
24321e764dfSDag-Erling Smørgrav 		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
244d4af9e69SDag-Erling Smørgrav 	if (options->max_sessions == -1)
245d4af9e69SDag-Erling Smørgrav 		options->max_sessions = DEFAULT_SESSIONS_MAX;
246cf2b5f3bSDag-Erling Smørgrav 	if (options->use_dns == -1)
247cf2b5f3bSDag-Erling Smørgrav 		options->use_dns = 1;
248ca3176e7SBrian Feldman 	if (options->client_alive_interval == -1)
249ca3176e7SBrian Feldman 		options->client_alive_interval = 0;
250ca3176e7SBrian Feldman 	if (options->client_alive_count_max == -1)
251ca3176e7SBrian Feldman 		options->client_alive_count_max = 3;
252af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file2 == NULL) {
253af12a3e7SDag-Erling Smørgrav 		/* authorized_keys_file2 falls back to authorized_keys_file */
254af12a3e7SDag-Erling Smørgrav 		if (options->authorized_keys_file != NULL)
255af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = options->authorized_keys_file;
256af12a3e7SDag-Erling Smørgrav 		else
257af12a3e7SDag-Erling Smørgrav 			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
258af12a3e7SDag-Erling Smørgrav 	}
259af12a3e7SDag-Erling Smørgrav 	if (options->authorized_keys_file == NULL)
260af12a3e7SDag-Erling Smørgrav 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
261b74df5b2SDag-Erling Smørgrav 	if (options->permit_tun == -1)
262b74df5b2SDag-Erling Smørgrav 		options->permit_tun = SSH_TUNMODE_NO;
263cce7d346SDag-Erling Smørgrav 	if (options->zero_knowledge_password_authentication == -1)
264cce7d346SDag-Erling Smørgrav 		options->zero_knowledge_password_authentication = 0;
26580628bacSDag-Erling Smørgrav 
266989dd127SDag-Erling Smørgrav 	/* Turn privilege separation on by default */
26780628bacSDag-Erling Smørgrav 	if (use_privsep == -1)
268989dd127SDag-Erling Smørgrav 		use_privsep = 1;
269989dd127SDag-Erling Smørgrav 
270f388f5efSDag-Erling Smørgrav #ifndef HAVE_MMAP
271989dd127SDag-Erling Smørgrav 	if (use_privsep && options->compression == 1) {
272989dd127SDag-Erling Smørgrav 		error("This platform does not support both privilege "
273989dd127SDag-Erling Smørgrav 		    "separation and compression");
274989dd127SDag-Erling Smørgrav 		error("Compression disabled");
275989dd127SDag-Erling Smørgrav 		options->compression = 0;
276989dd127SDag-Erling Smørgrav 	}
277989dd127SDag-Erling Smørgrav #endif
278989dd127SDag-Erling Smørgrav 
279511b41d2SMark Murray }
280511b41d2SMark Murray 
281511b41d2SMark Murray /* Keyword tokens. */
282511b41d2SMark Murray typedef enum {
283511b41d2SMark Murray 	sBadOption,		/* == unknown option */
284989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
285cf2b5f3bSDag-Erling Smørgrav 	sUsePAM,
286989dd127SDag-Erling Smørgrav 	/* Standard Options */
287511b41d2SMark Murray 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
288511b41d2SMark Murray 	sPermitRootLogin, sLogFacility, sLogLevel,
289cf2b5f3bSDag-Erling Smørgrav 	sRhostsRSAAuthentication, sRSAAuthentication,
290af12a3e7SDag-Erling Smørgrav 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
2911ec0d754SDag-Erling Smørgrav 	sKerberosGetAFSToken,
292cf2b5f3bSDag-Erling Smørgrav 	sKerberosTgtPassing, sChallengeResponseAuthentication,
293aa49c926SDag-Erling Smørgrav 	sPasswordAuthentication, sKbdInteractiveAuthentication,
294aa49c926SDag-Erling Smørgrav 	sListenAddress, sAddressFamily,
295ca3176e7SBrian Feldman 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
296af12a3e7SDag-Erling Smørgrav 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
2971ec0d754SDag-Erling Smørgrav 	sStrictModes, sEmptyPasswd, sTCPKeepAlive,
298f388f5efSDag-Erling Smørgrav 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
29909958426SBrian Feldman 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
300ca3176e7SBrian Feldman 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
30121e764dfSDag-Erling Smørgrav 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
302d4af9e69SDag-Erling Smørgrav 	sMaxStartups, sMaxAuthTries, sMaxSessions,
303cf2b5f3bSDag-Erling Smørgrav 	sBanner, sUseDNS, sHostbasedAuthentication,
304ca3176e7SBrian Feldman 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
305af12a3e7SDag-Erling Smørgrav 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
306b74df5b2SDag-Erling Smørgrav 	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
307d4af9e69SDag-Erling Smørgrav 	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
308d4af9e69SDag-Erling Smørgrav 	sUsePrivilegeSeparation, sAllowAgentForwarding,
309cce7d346SDag-Erling Smørgrav 	sZeroKnowledgePasswordAuthentication,
310db58a8e4SDag-Erling Smørgrav 	sVersionAddendum,
311cf2b5f3bSDag-Erling Smørgrav 	sDeprecated, sUnsupported
312511b41d2SMark Murray } ServerOpCodes;
313511b41d2SMark Murray 
314333ee039SDag-Erling Smørgrav #define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
315333ee039SDag-Erling Smørgrav #define SSHCFG_MATCH	0x02	/* allowed inside a Match section */
316333ee039SDag-Erling Smørgrav #define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
317333ee039SDag-Erling Smørgrav 
318511b41d2SMark Murray /* Textual representation of the tokens. */
319511b41d2SMark Murray static struct {
320511b41d2SMark Murray 	const char *name;
321511b41d2SMark Murray 	ServerOpCodes opcode;
322333ee039SDag-Erling Smørgrav 	u_int flags;
323511b41d2SMark Murray } keywords[] = {
324989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
325cf2b5f3bSDag-Erling Smørgrav #ifdef USE_PAM
326333ee039SDag-Erling Smørgrav 	{ "usepam", sUsePAM, SSHCFG_GLOBAL },
327cf2b5f3bSDag-Erling Smørgrav #else
328333ee039SDag-Erling Smørgrav 	{ "usepam", sUnsupported, SSHCFG_GLOBAL },
329975616f0SDag-Erling Smørgrav #endif
330333ee039SDag-Erling Smørgrav 	{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
331989dd127SDag-Erling Smørgrav 	/* Standard Options */
332333ee039SDag-Erling Smørgrav 	{ "port", sPort, SSHCFG_GLOBAL },
333333ee039SDag-Erling Smørgrav 	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
334333ee039SDag-Erling Smørgrav 	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },		/* alias */
335333ee039SDag-Erling Smørgrav 	{ "pidfile", sPidFile, SSHCFG_GLOBAL },
336333ee039SDag-Erling Smørgrav 	{ "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
337333ee039SDag-Erling Smørgrav 	{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
338333ee039SDag-Erling Smørgrav 	{ "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
339d4af9e69SDag-Erling Smørgrav 	{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
340333ee039SDag-Erling Smørgrav 	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
341333ee039SDag-Erling Smørgrav 	{ "loglevel", sLogLevel, SSHCFG_GLOBAL },
342333ee039SDag-Erling Smørgrav 	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
343d4af9e69SDag-Erling Smørgrav 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
344d4af9e69SDag-Erling Smørgrav 	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
345333ee039SDag-Erling Smørgrav 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
346d4af9e69SDag-Erling Smørgrav 	{ "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
347d4af9e69SDag-Erling Smørgrav 	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
348333ee039SDag-Erling Smørgrav 	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
349cf2b5f3bSDag-Erling Smørgrav #ifdef KRB5
350d4af9e69SDag-Erling Smørgrav 	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
351333ee039SDag-Erling Smørgrav 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
352333ee039SDag-Erling Smørgrav 	{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
3531ec0d754SDag-Erling Smørgrav #ifdef USE_AFS
354333ee039SDag-Erling Smørgrav 	{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
3551ec0d754SDag-Erling Smørgrav #else
356333ee039SDag-Erling Smørgrav 	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
3571ec0d754SDag-Erling Smørgrav #endif
358cf2b5f3bSDag-Erling Smørgrav #else
359d4af9e69SDag-Erling Smørgrav 	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
360333ee039SDag-Erling Smørgrav 	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
361333ee039SDag-Erling Smørgrav 	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
362333ee039SDag-Erling Smørgrav 	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
363cb96ab36SAssar Westerlund #endif
364333ee039SDag-Erling Smørgrav 	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
365333ee039SDag-Erling Smørgrav 	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
366cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
367d4af9e69SDag-Erling Smørgrav 	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
368333ee039SDag-Erling Smørgrav 	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
369cf2b5f3bSDag-Erling Smørgrav #else
370d4af9e69SDag-Erling Smørgrav 	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
371333ee039SDag-Erling Smørgrav 	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
372511b41d2SMark Murray #endif
373d4af9e69SDag-Erling Smørgrav 	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
374d4af9e69SDag-Erling Smørgrav 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
375333ee039SDag-Erling Smørgrav 	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
376333ee039SDag-Erling Smørgrav 	{ "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
377cce7d346SDag-Erling Smørgrav #ifdef JPAKE
378cce7d346SDag-Erling Smørgrav 	{ "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL },
379cce7d346SDag-Erling Smørgrav #else
380cce7d346SDag-Erling Smørgrav 	{ "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
381cce7d346SDag-Erling Smørgrav #endif
382333ee039SDag-Erling Smørgrav 	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
383333ee039SDag-Erling Smørgrav 	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
384333ee039SDag-Erling Smørgrav 	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
385333ee039SDag-Erling Smørgrav 	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
386333ee039SDag-Erling Smørgrav 	{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
387333ee039SDag-Erling Smørgrav 	{ "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
388333ee039SDag-Erling Smørgrav 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
389333ee039SDag-Erling Smørgrav 	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
390333ee039SDag-Erling Smørgrav 	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
391333ee039SDag-Erling Smørgrav 	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
392333ee039SDag-Erling Smørgrav 	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
393333ee039SDag-Erling Smørgrav 	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
394cce7d346SDag-Erling Smørgrav 	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
395333ee039SDag-Erling Smørgrav 	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
396333ee039SDag-Erling Smørgrav 	{ "uselogin", sUseLogin, SSHCFG_GLOBAL },
397333ee039SDag-Erling Smørgrav 	{ "compression", sCompression, SSHCFG_GLOBAL },
398333ee039SDag-Erling Smørgrav 	{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
399333ee039SDag-Erling Smørgrav 	{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },	/* obsolete alias */
400333ee039SDag-Erling Smørgrav 	{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
401d4af9e69SDag-Erling Smørgrav 	{ "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
402333ee039SDag-Erling Smørgrav 	{ "allowusers", sAllowUsers, SSHCFG_GLOBAL },
403333ee039SDag-Erling Smørgrav 	{ "denyusers", sDenyUsers, SSHCFG_GLOBAL },
404333ee039SDag-Erling Smørgrav 	{ "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
405333ee039SDag-Erling Smørgrav 	{ "denygroups", sDenyGroups, SSHCFG_GLOBAL },
406333ee039SDag-Erling Smørgrav 	{ "ciphers", sCiphers, SSHCFG_GLOBAL },
407333ee039SDag-Erling Smørgrav 	{ "macs", sMacs, SSHCFG_GLOBAL },
408333ee039SDag-Erling Smørgrav 	{ "protocol", sProtocol, SSHCFG_GLOBAL },
409333ee039SDag-Erling Smørgrav 	{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
410333ee039SDag-Erling Smørgrav 	{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
411333ee039SDag-Erling Smørgrav 	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
412d4af9e69SDag-Erling Smørgrav 	{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
413d4af9e69SDag-Erling Smørgrav 	{ "maxsessions", sMaxSessions, SSHCFG_ALL },
414d4af9e69SDag-Erling Smørgrav 	{ "banner", sBanner, SSHCFG_ALL },
415333ee039SDag-Erling Smørgrav 	{ "usedns", sUseDNS, SSHCFG_GLOBAL },
416333ee039SDag-Erling Smørgrav 	{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
417333ee039SDag-Erling Smørgrav 	{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
418333ee039SDag-Erling Smørgrav 	{ "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
419333ee039SDag-Erling Smørgrav 	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
420333ee039SDag-Erling Smørgrav 	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
421333ee039SDag-Erling Smørgrav 	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
422333ee039SDag-Erling Smørgrav 	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
423333ee039SDag-Erling Smørgrav 	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
424333ee039SDag-Erling Smørgrav 	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
425333ee039SDag-Erling Smørgrav 	{ "match", sMatch, SSHCFG_ALL },
426333ee039SDag-Erling Smørgrav 	{ "permitopen", sPermitOpen, SSHCFG_ALL },
427333ee039SDag-Erling Smørgrav 	{ "forcecommand", sForceCommand, SSHCFG_ALL },
428d4af9e69SDag-Erling Smørgrav 	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
429333ee039SDag-Erling Smørgrav 	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
430333ee039SDag-Erling Smørgrav 	{ NULL, sBadOption, 0 }
431511b41d2SMark Murray };
432511b41d2SMark Murray 
433d4af9e69SDag-Erling Smørgrav static struct {
434d4af9e69SDag-Erling Smørgrav 	int val;
435d4af9e69SDag-Erling Smørgrav 	char *text;
436d4af9e69SDag-Erling Smørgrav } tunmode_desc[] = {
437d4af9e69SDag-Erling Smørgrav 	{ SSH_TUNMODE_NO, "no" },
438d4af9e69SDag-Erling Smørgrav 	{ SSH_TUNMODE_POINTOPOINT, "point-to-point" },
439d4af9e69SDag-Erling Smørgrav 	{ SSH_TUNMODE_ETHERNET, "ethernet" },
440d4af9e69SDag-Erling Smørgrav 	{ SSH_TUNMODE_YES, "yes" },
441d4af9e69SDag-Erling Smørgrav 	{ -1, NULL }
442d4af9e69SDag-Erling Smørgrav };
443d4af9e69SDag-Erling Smørgrav 
444511b41d2SMark Murray /*
445ca3176e7SBrian Feldman  * Returns the number of the token pointed to by cp or sBadOption.
446511b41d2SMark Murray  */
447511b41d2SMark Murray 
448511b41d2SMark Murray static ServerOpCodes
449511b41d2SMark Murray parse_token(const char *cp, const char *filename,
450333ee039SDag-Erling Smørgrav 	    int linenum, u_int *flags)
451511b41d2SMark Murray {
452ca3176e7SBrian Feldman 	u_int i;
453511b41d2SMark Murray 
454511b41d2SMark Murray 	for (i = 0; keywords[i].name; i++)
455333ee039SDag-Erling Smørgrav 		if (strcasecmp(cp, keywords[i].name) == 0) {
456333ee039SDag-Erling Smørgrav 			*flags = keywords[i].flags;
457511b41d2SMark Murray 			return keywords[i].opcode;
458333ee039SDag-Erling Smørgrav 		}
459511b41d2SMark Murray 
460ca3176e7SBrian Feldman 	error("%s: line %d: Bad configuration option: %s",
461511b41d2SMark Murray 	    filename, linenum, cp);
462511b41d2SMark Murray 	return sBadOption;
463511b41d2SMark Murray }
464511b41d2SMark Murray 
465af12a3e7SDag-Erling Smørgrav static void
466cce7d346SDag-Erling Smørgrav add_listen_addr(ServerOptions *options, char *addr, int port)
467511b41d2SMark Murray {
468d4ecd108SDag-Erling Smørgrav 	u_int i;
469511b41d2SMark Murray 
470511b41d2SMark Murray 	if (options->num_ports == 0)
471511b41d2SMark Murray 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
472aa49c926SDag-Erling Smørgrav 	if (options->address_family == -1)
473aa49c926SDag-Erling Smørgrav 		options->address_family = AF_UNSPEC;
474ca3176e7SBrian Feldman 	if (port == 0)
475ca3176e7SBrian Feldman 		for (i = 0; i < options->num_ports; i++)
476ca3176e7SBrian Feldman 			add_one_listen_addr(options, addr, options->ports[i]);
477ca3176e7SBrian Feldman 	else
478ca3176e7SBrian Feldman 		add_one_listen_addr(options, addr, port);
479ca3176e7SBrian Feldman }
480ca3176e7SBrian Feldman 
481af12a3e7SDag-Erling Smørgrav static void
482cce7d346SDag-Erling Smørgrav add_one_listen_addr(ServerOptions *options, char *addr, int port)
483ca3176e7SBrian Feldman {
484ca3176e7SBrian Feldman 	struct addrinfo hints, *ai, *aitop;
485ca3176e7SBrian Feldman 	char strport[NI_MAXSERV];
486ca3176e7SBrian Feldman 	int gaierr;
487ca3176e7SBrian Feldman 
488511b41d2SMark Murray 	memset(&hints, 0, sizeof(hints));
489aa49c926SDag-Erling Smørgrav 	hints.ai_family = options->address_family;
490511b41d2SMark Murray 	hints.ai_socktype = SOCK_STREAM;
491511b41d2SMark Murray 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
492cce7d346SDag-Erling Smørgrav 	snprintf(strport, sizeof strport, "%d", port);
493511b41d2SMark Murray 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
494ca3176e7SBrian Feldman 		fatal("bad addr or host: %s (%s)",
495511b41d2SMark Murray 		    addr ? addr : "<NULL>",
496d4af9e69SDag-Erling Smørgrav 		    ssh_gai_strerror(gaierr));
497511b41d2SMark Murray 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
498511b41d2SMark Murray 		;
499511b41d2SMark Murray 	ai->ai_next = options->listen_addrs;
500511b41d2SMark Murray 	options->listen_addrs = aitop;
501511b41d2SMark Murray }
502511b41d2SMark Murray 
503333ee039SDag-Erling Smørgrav /*
504333ee039SDag-Erling Smørgrav  * The strategy for the Match blocks is that the config file is parsed twice.
505333ee039SDag-Erling Smørgrav  *
506333ee039SDag-Erling Smørgrav  * The first time is at startup.  activep is initialized to 1 and the
507333ee039SDag-Erling Smørgrav  * directives in the global context are processed and acted on.  Hitting a
508333ee039SDag-Erling Smørgrav  * Match directive unsets activep and the directives inside the block are
509333ee039SDag-Erling Smørgrav  * checked for syntax only.
510333ee039SDag-Erling Smørgrav  *
511333ee039SDag-Erling Smørgrav  * The second time is after a connection has been established but before
512333ee039SDag-Erling Smørgrav  * authentication.  activep is initialized to 2 and global config directives
513333ee039SDag-Erling Smørgrav  * are ignored since they have already been processed.  If the criteria in a
514333ee039SDag-Erling Smørgrav  * Match block is met, activep is set and the subsequent directives
515333ee039SDag-Erling Smørgrav  * processed and actioned until EOF or another Match block unsets it.  Any
516333ee039SDag-Erling Smørgrav  * options set are copied into the main server config.
517333ee039SDag-Erling Smørgrav  *
518333ee039SDag-Erling Smørgrav  * Potential additions/improvements:
519333ee039SDag-Erling Smørgrav  *  - Add Match support for pre-kex directives, eg Protocol, Ciphers.
520333ee039SDag-Erling Smørgrav  *
521333ee039SDag-Erling Smørgrav  *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
522333ee039SDag-Erling Smørgrav  *	Match Address 192.168.0.*
523333ee039SDag-Erling Smørgrav  *		Tag trusted
524333ee039SDag-Erling Smørgrav  *	Match Group wheel
525333ee039SDag-Erling Smørgrav  *		Tag trusted
526333ee039SDag-Erling Smørgrav  *	Match Tag trusted
527333ee039SDag-Erling Smørgrav  *		AllowTcpForwarding yes
528333ee039SDag-Erling Smørgrav  *		GatewayPorts clientspecified
529333ee039SDag-Erling Smørgrav  *		[...]
530333ee039SDag-Erling Smørgrav  *
531333ee039SDag-Erling Smørgrav  *  - Add a PermittedChannelRequests directive
532333ee039SDag-Erling Smørgrav  *	Match Group shell
533333ee039SDag-Erling Smørgrav  *		PermittedChannelRequests session,forwarded-tcpip
534333ee039SDag-Erling Smørgrav  */
535333ee039SDag-Erling Smørgrav 
536333ee039SDag-Erling Smørgrav static int
537333ee039SDag-Erling Smørgrav match_cfg_line_group(const char *grps, int line, const char *user)
538333ee039SDag-Erling Smørgrav {
539333ee039SDag-Erling Smørgrav 	int result = 0;
540333ee039SDag-Erling Smørgrav 	struct passwd *pw;
541333ee039SDag-Erling Smørgrav 
542333ee039SDag-Erling Smørgrav 	if (user == NULL)
543333ee039SDag-Erling Smørgrav 		goto out;
544333ee039SDag-Erling Smørgrav 
545333ee039SDag-Erling Smørgrav 	if ((pw = getpwnam(user)) == NULL) {
546333ee039SDag-Erling Smørgrav 		debug("Can't match group at line %d because user %.100s does "
547333ee039SDag-Erling Smørgrav 		    "not exist", line, user);
548333ee039SDag-Erling Smørgrav 	} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
549333ee039SDag-Erling Smørgrav 		debug("Can't Match group because user %.100s not in any group "
550333ee039SDag-Erling Smørgrav 		    "at line %d", user, line);
551d4af9e69SDag-Erling Smørgrav 	} else if (ga_match_pattern_list(grps) != 1) {
552d4af9e69SDag-Erling Smørgrav 		debug("user %.100s does not match group list %.100s at line %d",
553d4af9e69SDag-Erling Smørgrav 		    user, grps, line);
554333ee039SDag-Erling Smørgrav 	} else {
555d4af9e69SDag-Erling Smørgrav 		debug("user %.100s matched group list %.100s at line %d", user,
556d4af9e69SDag-Erling Smørgrav 		    grps, line);
557333ee039SDag-Erling Smørgrav 		result = 1;
558333ee039SDag-Erling Smørgrav 	}
559333ee039SDag-Erling Smørgrav out:
560333ee039SDag-Erling Smørgrav 	ga_free();
561333ee039SDag-Erling Smørgrav 	return result;
562333ee039SDag-Erling Smørgrav }
563333ee039SDag-Erling Smørgrav 
564333ee039SDag-Erling Smørgrav static int
565333ee039SDag-Erling Smørgrav match_cfg_line(char **condition, int line, const char *user, const char *host,
566333ee039SDag-Erling Smørgrav     const char *address)
567333ee039SDag-Erling Smørgrav {
568333ee039SDag-Erling Smørgrav 	int result = 1;
569333ee039SDag-Erling Smørgrav 	char *arg, *attrib, *cp = *condition;
570333ee039SDag-Erling Smørgrav 	size_t len;
571333ee039SDag-Erling Smørgrav 
572333ee039SDag-Erling Smørgrav 	if (user == NULL)
573333ee039SDag-Erling Smørgrav 		debug3("checking syntax for 'Match %s'", cp);
574333ee039SDag-Erling Smørgrav 	else
575333ee039SDag-Erling Smørgrav 		debug3("checking match for '%s' user %s host %s addr %s", cp,
576333ee039SDag-Erling Smørgrav 		    user ? user : "(null)", host ? host : "(null)",
577333ee039SDag-Erling Smørgrav 		    address ? address : "(null)");
578333ee039SDag-Erling Smørgrav 
579333ee039SDag-Erling Smørgrav 	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
580333ee039SDag-Erling Smørgrav 		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
581333ee039SDag-Erling Smørgrav 			error("Missing Match criteria for %s", attrib);
582333ee039SDag-Erling Smørgrav 			return -1;
583333ee039SDag-Erling Smørgrav 		}
584333ee039SDag-Erling Smørgrav 		len = strlen(arg);
585333ee039SDag-Erling Smørgrav 		if (strcasecmp(attrib, "user") == 0) {
586333ee039SDag-Erling Smørgrav 			if (!user) {
587333ee039SDag-Erling Smørgrav 				result = 0;
588333ee039SDag-Erling Smørgrav 				continue;
589333ee039SDag-Erling Smørgrav 			}
590333ee039SDag-Erling Smørgrav 			if (match_pattern_list(user, arg, len, 0) != 1)
591333ee039SDag-Erling Smørgrav 				result = 0;
592333ee039SDag-Erling Smørgrav 			else
593333ee039SDag-Erling Smørgrav 				debug("user %.100s matched 'User %.100s' at "
594333ee039SDag-Erling Smørgrav 				    "line %d", user, arg, line);
595333ee039SDag-Erling Smørgrav 		} else if (strcasecmp(attrib, "group") == 0) {
596333ee039SDag-Erling Smørgrav 			switch (match_cfg_line_group(arg, line, user)) {
597333ee039SDag-Erling Smørgrav 			case -1:
598333ee039SDag-Erling Smørgrav 				return -1;
599333ee039SDag-Erling Smørgrav 			case 0:
600333ee039SDag-Erling Smørgrav 				result = 0;
601333ee039SDag-Erling Smørgrav 			}
602333ee039SDag-Erling Smørgrav 		} else if (strcasecmp(attrib, "host") == 0) {
603333ee039SDag-Erling Smørgrav 			if (!host) {
604333ee039SDag-Erling Smørgrav 				result = 0;
605333ee039SDag-Erling Smørgrav 				continue;
606333ee039SDag-Erling Smørgrav 			}
607333ee039SDag-Erling Smørgrav 			if (match_hostname(host, arg, len) != 1)
608333ee039SDag-Erling Smørgrav 				result = 0;
609333ee039SDag-Erling Smørgrav 			else
610333ee039SDag-Erling Smørgrav 				debug("connection from %.100s matched 'Host "
611333ee039SDag-Erling Smørgrav 				    "%.100s' at line %d", host, arg, line);
612333ee039SDag-Erling Smørgrav 		} else if (strcasecmp(attrib, "address") == 0) {
613d4af9e69SDag-Erling Smørgrav 			switch (addr_match_list(address, arg)) {
614d4af9e69SDag-Erling Smørgrav 			case 1:
615333ee039SDag-Erling Smørgrav 				debug("connection from %.100s matched 'Address "
616333ee039SDag-Erling Smørgrav 				    "%.100s' at line %d", address, arg, line);
617d4af9e69SDag-Erling Smørgrav 				break;
618d4af9e69SDag-Erling Smørgrav 			case 0:
619d4af9e69SDag-Erling Smørgrav 			case -1:
620d4af9e69SDag-Erling Smørgrav 				result = 0;
621d4af9e69SDag-Erling Smørgrav 				break;
622d4af9e69SDag-Erling Smørgrav 			case -2:
623d4af9e69SDag-Erling Smørgrav 				return -1;
624d4af9e69SDag-Erling Smørgrav 			}
625333ee039SDag-Erling Smørgrav 		} else {
626333ee039SDag-Erling Smørgrav 			error("Unsupported Match attribute %s", attrib);
627333ee039SDag-Erling Smørgrav 			return -1;
628333ee039SDag-Erling Smørgrav 		}
629333ee039SDag-Erling Smørgrav 	}
630333ee039SDag-Erling Smørgrav 	if (user != NULL)
631333ee039SDag-Erling Smørgrav 		debug3("match %sfound", result ? "" : "not ");
632333ee039SDag-Erling Smørgrav 	*condition = cp;
633333ee039SDag-Erling Smørgrav 	return result;
634333ee039SDag-Erling Smørgrav }
635333ee039SDag-Erling Smørgrav 
636333ee039SDag-Erling Smørgrav #define WHITESPACE " \t\r\n"
637333ee039SDag-Erling Smørgrav 
638af12a3e7SDag-Erling Smørgrav int
639af12a3e7SDag-Erling Smørgrav process_server_config_line(ServerOptions *options, char *line,
640333ee039SDag-Erling Smørgrav     const char *filename, int linenum, int *activep, const char *user,
641333ee039SDag-Erling Smørgrav     const char *host, const char *address)
642511b41d2SMark Murray {
643ca3176e7SBrian Feldman 	char *cp, **charptr, *arg, *p;
644333ee039SDag-Erling Smørgrav 	int cmdline = 0, *intptr, value, n;
645d4af9e69SDag-Erling Smørgrav 	SyslogFacility *log_facility_ptr;
646d4af9e69SDag-Erling Smørgrav 	LogLevel *log_level_ptr;
647511b41d2SMark Murray 	ServerOpCodes opcode;
648cce7d346SDag-Erling Smørgrav 	int port;
649333ee039SDag-Erling Smørgrav 	u_int i, flags = 0;
650333ee039SDag-Erling Smørgrav 	size_t len;
651511b41d2SMark Murray 
652c2d3a559SKris Kennaway 	cp = line;
653333ee039SDag-Erling Smørgrav 	if ((arg = strdelim(&cp)) == NULL)
654333ee039SDag-Erling Smørgrav 		return 0;
655c2d3a559SKris Kennaway 	/* Ignore leading whitespace */
656c2d3a559SKris Kennaway 	if (*arg == '\0')
657c2d3a559SKris Kennaway 		arg = strdelim(&cp);
658ca3176e7SBrian Feldman 	if (!arg || !*arg || *arg == '#')
659af12a3e7SDag-Erling Smørgrav 		return 0;
660ca3176e7SBrian Feldman 	intptr = NULL;
661ca3176e7SBrian Feldman 	charptr = NULL;
662333ee039SDag-Erling Smørgrav 	opcode = parse_token(arg, filename, linenum, &flags);
663333ee039SDag-Erling Smørgrav 
664333ee039SDag-Erling Smørgrav 	if (activep == NULL) { /* We are processing a command line directive */
665333ee039SDag-Erling Smørgrav 		cmdline = 1;
666333ee039SDag-Erling Smørgrav 		activep = &cmdline;
667333ee039SDag-Erling Smørgrav 	}
668333ee039SDag-Erling Smørgrav 	if (*activep && opcode != sMatch)
669333ee039SDag-Erling Smørgrav 		debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
670333ee039SDag-Erling Smørgrav 	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
671333ee039SDag-Erling Smørgrav 		if (user == NULL) {
672333ee039SDag-Erling Smørgrav 			fatal("%s line %d: Directive '%s' is not allowed "
673333ee039SDag-Erling Smørgrav 			    "within a Match block", filename, linenum, arg);
674333ee039SDag-Erling Smørgrav 		} else { /* this is a directive we have already processed */
675333ee039SDag-Erling Smørgrav 			while (arg)
676333ee039SDag-Erling Smørgrav 				arg = strdelim(&cp);
677333ee039SDag-Erling Smørgrav 			return 0;
678333ee039SDag-Erling Smørgrav 		}
679333ee039SDag-Erling Smørgrav 	}
680333ee039SDag-Erling Smørgrav 
681511b41d2SMark Murray 	switch (opcode) {
682989dd127SDag-Erling Smørgrav 	/* Portable-specific options */
683cf2b5f3bSDag-Erling Smørgrav 	case sUsePAM:
684cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->use_pam;
685989dd127SDag-Erling Smørgrav 		goto parse_flag;
686989dd127SDag-Erling Smørgrav 
687989dd127SDag-Erling Smørgrav 	/* Standard Options */
688511b41d2SMark Murray 	case sBadOption:
689af12a3e7SDag-Erling Smørgrav 		return -1;
690511b41d2SMark Murray 	case sPort:
691511b41d2SMark Murray 		/* ignore ports from configfile if cmdline specifies ports */
692511b41d2SMark Murray 		if (options->ports_from_cmdline)
693af12a3e7SDag-Erling Smørgrav 			return 0;
694511b41d2SMark Murray 		if (options->listen_addrs != NULL)
695511b41d2SMark Murray 			fatal("%s line %d: ports must be specified before "
696af12a3e7SDag-Erling Smørgrav 			    "ListenAddress.", filename, linenum);
697511b41d2SMark Murray 		if (options->num_ports >= MAX_PORTS)
698ca3176e7SBrian Feldman 			fatal("%s line %d: too many ports.",
699511b41d2SMark Murray 			    filename, linenum);
700c2d3a559SKris Kennaway 		arg = strdelim(&cp);
701c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
702ca3176e7SBrian Feldman 			fatal("%s line %d: missing port number.",
703511b41d2SMark Murray 			    filename, linenum);
704ca3176e7SBrian Feldman 		options->ports[options->num_ports++] = a2port(arg);
705cce7d346SDag-Erling Smørgrav 		if (options->ports[options->num_ports-1] <= 0)
706ca3176e7SBrian Feldman 			fatal("%s line %d: Badly formatted port number.",
707ca3176e7SBrian Feldman 			    filename, linenum);
708511b41d2SMark Murray 		break;
709511b41d2SMark Murray 
710511b41d2SMark Murray 	case sServerKeyBits:
711511b41d2SMark Murray 		intptr = &options->server_key_bits;
712511b41d2SMark Murray  parse_int:
713c2d3a559SKris Kennaway 		arg = strdelim(&cp);
714ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
715ca3176e7SBrian Feldman 			fatal("%s line %d: missing integer value.",
716511b41d2SMark Murray 			    filename, linenum);
717c2d3a559SKris Kennaway 		value = atoi(arg);
718333ee039SDag-Erling Smørgrav 		if (*activep && *intptr == -1)
719511b41d2SMark Murray 			*intptr = value;
720511b41d2SMark Murray 		break;
721511b41d2SMark Murray 
722511b41d2SMark Murray 	case sLoginGraceTime:
723511b41d2SMark Murray 		intptr = &options->login_grace_time;
724af12a3e7SDag-Erling Smørgrav  parse_time:
725af12a3e7SDag-Erling Smørgrav 		arg = strdelim(&cp);
726af12a3e7SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
727af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: missing time value.",
728af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
729af12a3e7SDag-Erling Smørgrav 		if ((value = convtime(arg)) == -1)
730af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: invalid time value.",
731af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
732af12a3e7SDag-Erling Smørgrav 		if (*intptr == -1)
733af12a3e7SDag-Erling Smørgrav 			*intptr = value;
734af12a3e7SDag-Erling Smørgrav 		break;
735511b41d2SMark Murray 
736511b41d2SMark Murray 	case sKeyRegenerationTime:
737511b41d2SMark Murray 		intptr = &options->key_regeneration_time;
738af12a3e7SDag-Erling Smørgrav 		goto parse_time;
739511b41d2SMark Murray 
740511b41d2SMark Murray 	case sListenAddress:
741c2d3a559SKris Kennaway 		arg = strdelim(&cp);
742aa49c926SDag-Erling Smørgrav 		if (arg == NULL || *arg == '\0')
743aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: missing address",
744511b41d2SMark Murray 			    filename, linenum);
745d4ecd108SDag-Erling Smørgrav 		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
746d4ecd108SDag-Erling Smørgrav 		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
747d4ecd108SDag-Erling Smørgrav 		    && strchr(p+1, ':') != NULL) {
748d4ecd108SDag-Erling Smørgrav 			add_listen_addr(options, arg, 0);
749d4ecd108SDag-Erling Smørgrav 			break;
750d4ecd108SDag-Erling Smørgrav 		}
751aa49c926SDag-Erling Smørgrav 		p = hpdelim(&arg);
752aa49c926SDag-Erling Smørgrav 		if (p == NULL)
753aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: bad address:port usage",
754ca3176e7SBrian Feldman 			    filename, linenum);
755aa49c926SDag-Erling Smørgrav 		p = cleanhostname(p);
756aa49c926SDag-Erling Smørgrav 		if (arg == NULL)
757aa49c926SDag-Erling Smørgrav 			port = 0;
758cce7d346SDag-Erling Smørgrav 		else if ((port = a2port(arg)) <= 0)
759aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: bad port number", filename, linenum);
760ca3176e7SBrian Feldman 
761aa49c926SDag-Erling Smørgrav 		add_listen_addr(options, p, port);
762aa49c926SDag-Erling Smørgrav 
763aa49c926SDag-Erling Smørgrav 		break;
764aa49c926SDag-Erling Smørgrav 
765aa49c926SDag-Erling Smørgrav 	case sAddressFamily:
766aa49c926SDag-Erling Smørgrav 		arg = strdelim(&cp);
767d4ecd108SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
768d4ecd108SDag-Erling Smørgrav 			fatal("%s line %d: missing address family.",
769d4ecd108SDag-Erling Smørgrav 			    filename, linenum);
770aa49c926SDag-Erling Smørgrav 		intptr = &options->address_family;
771aa49c926SDag-Erling Smørgrav 		if (options->listen_addrs != NULL)
772aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: address family must be specified before "
773aa49c926SDag-Erling Smørgrav 			    "ListenAddress.", filename, linenum);
774aa49c926SDag-Erling Smørgrav 		if (strcasecmp(arg, "inet") == 0)
775aa49c926SDag-Erling Smørgrav 			value = AF_INET;
776aa49c926SDag-Erling Smørgrav 		else if (strcasecmp(arg, "inet6") == 0)
777aa49c926SDag-Erling Smørgrav 			value = AF_INET6;
778aa49c926SDag-Erling Smørgrav 		else if (strcasecmp(arg, "any") == 0)
779aa49c926SDag-Erling Smørgrav 			value = AF_UNSPEC;
780ca3176e7SBrian Feldman 		else
781aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: unsupported address family \"%s\".",
782aa49c926SDag-Erling Smørgrav 			    filename, linenum, arg);
783aa49c926SDag-Erling Smørgrav 		if (*intptr == -1)
784aa49c926SDag-Erling Smørgrav 			*intptr = value;
785511b41d2SMark Murray 		break;
786511b41d2SMark Murray 
787511b41d2SMark Murray 	case sHostKeyFile:
788ca3176e7SBrian Feldman 		intptr = &options->num_host_key_files;
789ca3176e7SBrian Feldman 		if (*intptr >= MAX_HOSTKEYS)
790ca3176e7SBrian Feldman 			fatal("%s line %d: too many host keys specified (max %d).",
791ca3176e7SBrian Feldman 			    filename, linenum, MAX_HOSTKEYS);
792ca3176e7SBrian Feldman 		charptr = &options->host_key_files[*intptr];
793c2d3a559SKris Kennaway  parse_filename:
794c2d3a559SKris Kennaway 		arg = strdelim(&cp);
795ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
796ca3176e7SBrian Feldman 			fatal("%s line %d: missing file name.",
797e8aafc91SKris Kennaway 			    filename, linenum);
798333ee039SDag-Erling Smørgrav 		if (*activep && *charptr == NULL) {
799c2d3a559SKris Kennaway 			*charptr = tilde_expand_filename(arg, getuid());
800ca3176e7SBrian Feldman 			/* increase optional counter */
801ca3176e7SBrian Feldman 			if (intptr != NULL)
802ca3176e7SBrian Feldman 				*intptr = *intptr + 1;
803ca3176e7SBrian Feldman 		}
804e8aafc91SKris Kennaway 		break;
805e8aafc91SKris Kennaway 
806e8aafc91SKris Kennaway 	case sPidFile:
807e8aafc91SKris Kennaway 		charptr = &options->pid_file;
808c2d3a559SKris Kennaway 		goto parse_filename;
809511b41d2SMark Murray 
810511b41d2SMark Murray 	case sPermitRootLogin:
811511b41d2SMark Murray 		intptr = &options->permit_root_login;
812c2d3a559SKris Kennaway 		arg = strdelim(&cp);
813ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
814ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/"
815ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
816ca3176e7SBrian Feldman 			    "argument.", filename, linenum);
817ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
818c2d3a559SKris Kennaway 		if (strcmp(arg, "without-password") == 0)
819ca3176e7SBrian Feldman 			value = PERMIT_NO_PASSWD;
820ca3176e7SBrian Feldman 		else if (strcmp(arg, "forced-commands-only") == 0)
821ca3176e7SBrian Feldman 			value = PERMIT_FORCED_ONLY;
822c2d3a559SKris Kennaway 		else if (strcmp(arg, "yes") == 0)
823ca3176e7SBrian Feldman 			value = PERMIT_YES;
824c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
825ca3176e7SBrian Feldman 			value = PERMIT_NO;
826ca3176e7SBrian Feldman 		else
827ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/"
828ca3176e7SBrian Feldman 			    "without-password/forced-commands-only/no "
829ca3176e7SBrian Feldman 			    "argument: %s", filename, linenum, arg);
830d4af9e69SDag-Erling Smørgrav 		if (*activep && *intptr == -1)
831511b41d2SMark Murray 			*intptr = value;
832511b41d2SMark Murray 		break;
833511b41d2SMark Murray 
834511b41d2SMark Murray 	case sIgnoreRhosts:
835511b41d2SMark Murray 		intptr = &options->ignore_rhosts;
836511b41d2SMark Murray  parse_flag:
837c2d3a559SKris Kennaway 		arg = strdelim(&cp);
838ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
839ca3176e7SBrian Feldman 			fatal("%s line %d: missing yes/no argument.",
840511b41d2SMark Murray 			    filename, linenum);
841ca3176e7SBrian Feldman 		value = 0;	/* silence compiler */
842c2d3a559SKris Kennaway 		if (strcmp(arg, "yes") == 0)
843511b41d2SMark Murray 			value = 1;
844c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0)
845511b41d2SMark Murray 			value = 0;
846ca3176e7SBrian Feldman 		else
847ca3176e7SBrian Feldman 			fatal("%s line %d: Bad yes/no argument: %s",
848c2d3a559SKris Kennaway 				filename, linenum, arg);
849333ee039SDag-Erling Smørgrav 		if (*activep && *intptr == -1)
850511b41d2SMark Murray 			*intptr = value;
851511b41d2SMark Murray 		break;
852511b41d2SMark Murray 
853511b41d2SMark Murray 	case sIgnoreUserKnownHosts:
854511b41d2SMark Murray 		intptr = &options->ignore_user_known_hosts;
855962a3f4eSSheldon Hearn 		goto parse_flag;
856511b41d2SMark Murray 
857511b41d2SMark Murray 	case sRhostsRSAAuthentication:
858511b41d2SMark Murray 		intptr = &options->rhosts_rsa_authentication;
859511b41d2SMark Murray 		goto parse_flag;
860511b41d2SMark Murray 
861ca3176e7SBrian Feldman 	case sHostbasedAuthentication:
862ca3176e7SBrian Feldman 		intptr = &options->hostbased_authentication;
863ca3176e7SBrian Feldman 		goto parse_flag;
864ca3176e7SBrian Feldman 
865ca3176e7SBrian Feldman 	case sHostbasedUsesNameFromPacketOnly:
866ca3176e7SBrian Feldman 		intptr = &options->hostbased_uses_name_from_packet_only;
867ca3176e7SBrian Feldman 		goto parse_flag;
868ca3176e7SBrian Feldman 
869511b41d2SMark Murray 	case sRSAAuthentication:
870511b41d2SMark Murray 		intptr = &options->rsa_authentication;
871511b41d2SMark Murray 		goto parse_flag;
872511b41d2SMark Murray 
873ca3176e7SBrian Feldman 	case sPubkeyAuthentication:
874ca3176e7SBrian Feldman 		intptr = &options->pubkey_authentication;
875e8aafc91SKris Kennaway 		goto parse_flag;
876cf2b5f3bSDag-Erling Smørgrav 
877cb96ab36SAssar Westerlund 	case sKerberosAuthentication:
878cb96ab36SAssar Westerlund 		intptr = &options->kerberos_authentication;
879511b41d2SMark Murray 		goto parse_flag;
880511b41d2SMark Murray 
881af12a3e7SDag-Erling Smørgrav 	case sKerberosOrLocalPasswd:
882af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_or_local_passwd;
883511b41d2SMark Murray 		goto parse_flag;
884511b41d2SMark Murray 
885af12a3e7SDag-Erling Smørgrav 	case sKerberosTicketCleanup:
886af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_ticket_cleanup;
887511b41d2SMark Murray 		goto parse_flag;
888cf2b5f3bSDag-Erling Smørgrav 
8891ec0d754SDag-Erling Smørgrav 	case sKerberosGetAFSToken:
8901ec0d754SDag-Erling Smørgrav 		intptr = &options->kerberos_get_afs_token;
8911ec0d754SDag-Erling Smørgrav 		goto parse_flag;
8921ec0d754SDag-Erling Smørgrav 
893cf2b5f3bSDag-Erling Smørgrav 	case sGssAuthentication:
894cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->gss_authentication;
895fe5fd017SMark Murray 		goto parse_flag;
896cf2b5f3bSDag-Erling Smørgrav 
897cf2b5f3bSDag-Erling Smørgrav 	case sGssCleanupCreds:
898cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->gss_cleanup_creds;
899511b41d2SMark Murray 		goto parse_flag;
900511b41d2SMark Murray 
901511b41d2SMark Murray 	case sPasswordAuthentication:
902511b41d2SMark Murray 		intptr = &options->password_authentication;
903511b41d2SMark Murray 		goto parse_flag;
904511b41d2SMark Murray 
905cce7d346SDag-Erling Smørgrav 	case sZeroKnowledgePasswordAuthentication:
906cce7d346SDag-Erling Smørgrav 		intptr = &options->zero_knowledge_password_authentication;
907cce7d346SDag-Erling Smørgrav 		goto parse_flag;
908cce7d346SDag-Erling Smørgrav 
90909958426SBrian Feldman 	case sKbdInteractiveAuthentication:
91009958426SBrian Feldman 		intptr = &options->kbd_interactive_authentication;
91109958426SBrian Feldman 		goto parse_flag;
91209958426SBrian Feldman 
913ca3176e7SBrian Feldman 	case sChallengeResponseAuthentication:
914af12a3e7SDag-Erling Smørgrav 		intptr = &options->challenge_response_authentication;
915511b41d2SMark Murray 		goto parse_flag;
916511b41d2SMark Murray 
917511b41d2SMark Murray 	case sPrintMotd:
918511b41d2SMark Murray 		intptr = &options->print_motd;
919511b41d2SMark Murray 		goto parse_flag;
920511b41d2SMark Murray 
921ca3176e7SBrian Feldman 	case sPrintLastLog:
922ca3176e7SBrian Feldman 		intptr = &options->print_lastlog;
923ca3176e7SBrian Feldman 		goto parse_flag;
924ca3176e7SBrian Feldman 
925511b41d2SMark Murray 	case sX11Forwarding:
926511b41d2SMark Murray 		intptr = &options->x11_forwarding;
927511b41d2SMark Murray 		goto parse_flag;
928511b41d2SMark Murray 
929511b41d2SMark Murray 	case sX11DisplayOffset:
930511b41d2SMark Murray 		intptr = &options->x11_display_offset;
931511b41d2SMark Murray 		goto parse_int;
932511b41d2SMark Murray 
933af12a3e7SDag-Erling Smørgrav 	case sX11UseLocalhost:
934af12a3e7SDag-Erling Smørgrav 		intptr = &options->x11_use_localhost;
935af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
936af12a3e7SDag-Erling Smørgrav 
937c2d3a559SKris Kennaway 	case sXAuthLocation:
938c2d3a559SKris Kennaway 		charptr = &options->xauth_location;
939c2d3a559SKris Kennaway 		goto parse_filename;
940c2d3a559SKris Kennaway 
941511b41d2SMark Murray 	case sStrictModes:
942511b41d2SMark Murray 		intptr = &options->strict_modes;
943511b41d2SMark Murray 		goto parse_flag;
944511b41d2SMark Murray 
9451ec0d754SDag-Erling Smørgrav 	case sTCPKeepAlive:
9461ec0d754SDag-Erling Smørgrav 		intptr = &options->tcp_keep_alive;
947511b41d2SMark Murray 		goto parse_flag;
948511b41d2SMark Murray 
949511b41d2SMark Murray 	case sEmptyPasswd:
950511b41d2SMark Murray 		intptr = &options->permit_empty_passwd;
951511b41d2SMark Murray 		goto parse_flag;
952511b41d2SMark Murray 
953f388f5efSDag-Erling Smørgrav 	case sPermitUserEnvironment:
954f388f5efSDag-Erling Smørgrav 		intptr = &options->permit_user_env;
955f388f5efSDag-Erling Smørgrav 		goto parse_flag;
956f388f5efSDag-Erling Smørgrav 
957511b41d2SMark Murray 	case sUseLogin:
958511b41d2SMark Murray 		intptr = &options->use_login;
959511b41d2SMark Murray 		goto parse_flag;
960511b41d2SMark Murray 
96180628bacSDag-Erling Smørgrav 	case sCompression:
96280628bacSDag-Erling Smørgrav 		intptr = &options->compression;
963d4ecd108SDag-Erling Smørgrav 		arg = strdelim(&cp);
964d4ecd108SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
965d4ecd108SDag-Erling Smørgrav 			fatal("%s line %d: missing yes/no/delayed "
966d4ecd108SDag-Erling Smørgrav 			    "argument.", filename, linenum);
967d4ecd108SDag-Erling Smørgrav 		value = 0;	/* silence compiler */
968d4ecd108SDag-Erling Smørgrav 		if (strcmp(arg, "delayed") == 0)
969d4ecd108SDag-Erling Smørgrav 			value = COMP_DELAYED;
970d4ecd108SDag-Erling Smørgrav 		else if (strcmp(arg, "yes") == 0)
971d4ecd108SDag-Erling Smørgrav 			value = COMP_ZLIB;
972d4ecd108SDag-Erling Smørgrav 		else if (strcmp(arg, "no") == 0)
973d4ecd108SDag-Erling Smørgrav 			value = COMP_NONE;
974d4ecd108SDag-Erling Smørgrav 		else
975d4ecd108SDag-Erling Smørgrav 			fatal("%s line %d: Bad yes/no/delayed "
976d4ecd108SDag-Erling Smørgrav 			    "argument: %s", filename, linenum, arg);
977d4ecd108SDag-Erling Smørgrav 		if (*intptr == -1)
978d4ecd108SDag-Erling Smørgrav 			*intptr = value;
979d4ecd108SDag-Erling Smørgrav 		break;
98080628bacSDag-Erling Smørgrav 
981e8aafc91SKris Kennaway 	case sGatewayPorts:
982e8aafc91SKris Kennaway 		intptr = &options->gateway_ports;
983aa49c926SDag-Erling Smørgrav 		arg = strdelim(&cp);
984aa49c926SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
985aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: missing yes/no/clientspecified "
986aa49c926SDag-Erling Smørgrav 			    "argument.", filename, linenum);
987aa49c926SDag-Erling Smørgrav 		value = 0;	/* silence compiler */
988aa49c926SDag-Erling Smørgrav 		if (strcmp(arg, "clientspecified") == 0)
989aa49c926SDag-Erling Smørgrav 			value = 2;
990aa49c926SDag-Erling Smørgrav 		else if (strcmp(arg, "yes") == 0)
991aa49c926SDag-Erling Smørgrav 			value = 1;
992aa49c926SDag-Erling Smørgrav 		else if (strcmp(arg, "no") == 0)
993aa49c926SDag-Erling Smørgrav 			value = 0;
994aa49c926SDag-Erling Smørgrav 		else
995aa49c926SDag-Erling Smørgrav 			fatal("%s line %d: Bad yes/no/clientspecified "
996aa49c926SDag-Erling Smørgrav 			    "argument: %s", filename, linenum, arg);
997d4af9e69SDag-Erling Smørgrav 		if (*activep && *intptr == -1)
998aa49c926SDag-Erling Smørgrav 			*intptr = value;
999aa49c926SDag-Erling Smørgrav 		break;
1000e8aafc91SKris Kennaway 
1001cf2b5f3bSDag-Erling Smørgrav 	case sUseDNS:
1002cf2b5f3bSDag-Erling Smørgrav 		intptr = &options->use_dns;
1003ca3176e7SBrian Feldman 		goto parse_flag;
1004ca3176e7SBrian Feldman 
1005511b41d2SMark Murray 	case sLogFacility:
1006d4af9e69SDag-Erling Smørgrav 		log_facility_ptr = &options->log_facility;
1007c2d3a559SKris Kennaway 		arg = strdelim(&cp);
1008c2d3a559SKris Kennaway 		value = log_facility_number(arg);
1009af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_FACILITY_NOT_SET)
1010ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log facility '%s'",
1011c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
1012d4af9e69SDag-Erling Smørgrav 		if (*log_facility_ptr == -1)
1013d4af9e69SDag-Erling Smørgrav 			*log_facility_ptr = (SyslogFacility) value;
1014511b41d2SMark Murray 		break;
1015511b41d2SMark Murray 
1016511b41d2SMark Murray 	case sLogLevel:
1017d4af9e69SDag-Erling Smørgrav 		log_level_ptr = &options->log_level;
1018c2d3a559SKris Kennaway 		arg = strdelim(&cp);
1019c2d3a559SKris Kennaway 		value = log_level_number(arg);
1020af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_LEVEL_NOT_SET)
1021ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log level '%s'",
1022c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
1023d4af9e69SDag-Erling Smørgrav 		if (*log_level_ptr == -1)
1024d4af9e69SDag-Erling Smørgrav 			*log_level_ptr = (LogLevel) value;
1025511b41d2SMark Murray 		break;
1026511b41d2SMark Murray 
102709958426SBrian Feldman 	case sAllowTcpForwarding:
102809958426SBrian Feldman 		intptr = &options->allow_tcp_forwarding;
102909958426SBrian Feldman 		goto parse_flag;
103009958426SBrian Feldman 
1031d4af9e69SDag-Erling Smørgrav 	case sAllowAgentForwarding:
1032d4af9e69SDag-Erling Smørgrav 		intptr = &options->allow_agent_forwarding;
1033d4af9e69SDag-Erling Smørgrav 		goto parse_flag;
1034d4af9e69SDag-Erling Smørgrav 
103580628bacSDag-Erling Smørgrav 	case sUsePrivilegeSeparation:
103680628bacSDag-Erling Smørgrav 		intptr = &use_privsep;
103780628bacSDag-Erling Smørgrav 		goto parse_flag;
103880628bacSDag-Erling Smørgrav 
1039511b41d2SMark Murray 	case sAllowUsers:
1040c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
104142f71286SMark Murray 			if (options->num_allow_users >= MAX_ALLOW_USERS)
1042af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow users.",
1043e8aafc91SKris Kennaway 				    filename, linenum);
1044a82e551fSDag-Erling Smørgrav 			options->allow_users[options->num_allow_users++] =
1045a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
1046511b41d2SMark Murray 		}
1047511b41d2SMark Murray 		break;
1048511b41d2SMark Murray 
1049511b41d2SMark Murray 	case sDenyUsers:
1050c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
10512803b77eSBrian Feldman 			if (options->num_deny_users >= MAX_DENY_USERS)
1052af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many deny users.",
1053e8aafc91SKris Kennaway 				    filename, linenum);
1054a82e551fSDag-Erling Smørgrav 			options->deny_users[options->num_deny_users++] =
1055a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
1056511b41d2SMark Murray 		}
1057511b41d2SMark Murray 		break;
1058511b41d2SMark Murray 
1059511b41d2SMark Murray 	case sAllowGroups:
1060c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
106142f71286SMark Murray 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1062af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many allow groups.",
1063e8aafc91SKris Kennaway 				    filename, linenum);
1064a82e551fSDag-Erling Smørgrav 			options->allow_groups[options->num_allow_groups++] =
1065a82e551fSDag-Erling Smørgrav 			    xstrdup(arg);
1066511b41d2SMark Murray 		}
1067511b41d2SMark Murray 		break;
1068511b41d2SMark Murray 
1069511b41d2SMark Murray 	case sDenyGroups:
1070c2d3a559SKris Kennaway 		while ((arg = strdelim(&cp)) && *arg != '\0') {
107142f71286SMark Murray 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
1072af12a3e7SDag-Erling Smørgrav 				fatal("%s line %d: too many deny groups.",
1073e8aafc91SKris Kennaway 				    filename, linenum);
1074c2d3a559SKris Kennaway 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1075511b41d2SMark Murray 		}
1076511b41d2SMark Murray 		break;
1077511b41d2SMark Murray 
1078e8aafc91SKris Kennaway 	case sCiphers:
1079c2d3a559SKris Kennaway 		arg = strdelim(&cp);
1080c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
1081c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
1082c2d3a559SKris Kennaway 		if (!ciphers_valid(arg))
1083e8aafc91SKris Kennaway 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1084c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
1085e8aafc91SKris Kennaway 		if (options->ciphers == NULL)
1086c2d3a559SKris Kennaway 			options->ciphers = xstrdup(arg);
1087e8aafc91SKris Kennaway 		break;
1088e8aafc91SKris Kennaway 
1089ca3176e7SBrian Feldman 	case sMacs:
1090ca3176e7SBrian Feldman 		arg = strdelim(&cp);
1091ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
1092ca3176e7SBrian Feldman 			fatal("%s line %d: Missing argument.", filename, linenum);
1093ca3176e7SBrian Feldman 		if (!mac_valid(arg))
1094ca3176e7SBrian Feldman 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1095ca3176e7SBrian Feldman 			    filename, linenum, arg ? arg : "<NONE>");
1096ca3176e7SBrian Feldman 		if (options->macs == NULL)
1097ca3176e7SBrian Feldman 			options->macs = xstrdup(arg);
1098ca3176e7SBrian Feldman 		break;
1099ca3176e7SBrian Feldman 
1100e8aafc91SKris Kennaway 	case sProtocol:
1101e8aafc91SKris Kennaway 		intptr = &options->protocol;
1102c2d3a559SKris Kennaway 		arg = strdelim(&cp);
1103c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
1104c322fe35SKris Kennaway 			fatal("%s line %d: Missing argument.", filename, linenum);
1105c2d3a559SKris Kennaway 		value = proto_spec(arg);
1106e8aafc91SKris Kennaway 		if (value == SSH_PROTO_UNKNOWN)
1107e8aafc91SKris Kennaway 			fatal("%s line %d: Bad protocol spec '%s'.",
1108c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
1109e8aafc91SKris Kennaway 		if (*intptr == SSH_PROTO_UNKNOWN)
1110e8aafc91SKris Kennaway 			*intptr = value;
1111e8aafc91SKris Kennaway 		break;
1112e8aafc91SKris Kennaway 
1113c2d3a559SKris Kennaway 	case sSubsystem:
1114c2d3a559SKris Kennaway 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1115c2d3a559SKris Kennaway 			fatal("%s line %d: too many subsystems defined.",
1116c2d3a559SKris Kennaway 			    filename, linenum);
1117c2d3a559SKris Kennaway 		}
1118c2d3a559SKris Kennaway 		arg = strdelim(&cp);
1119c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
1120c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem name.",
1121c2d3a559SKris Kennaway 			    filename, linenum);
1122333ee039SDag-Erling Smørgrav 		if (!*activep) {
1123333ee039SDag-Erling Smørgrav 			arg = strdelim(&cp);
1124333ee039SDag-Erling Smørgrav 			break;
1125333ee039SDag-Erling Smørgrav 		}
1126c2d3a559SKris Kennaway 		for (i = 0; i < options->num_subsystems; i++)
1127c2d3a559SKris Kennaway 			if (strcmp(arg, options->subsystem_name[i]) == 0)
1128c2d3a559SKris Kennaway 				fatal("%s line %d: Subsystem '%s' already defined.",
1129c2d3a559SKris Kennaway 				    filename, linenum, arg);
1130c2d3a559SKris Kennaway 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1131c2d3a559SKris Kennaway 		arg = strdelim(&cp);
1132c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
1133c2d3a559SKris Kennaway 			fatal("%s line %d: Missing subsystem command.",
1134c2d3a559SKris Kennaway 			    filename, linenum);
1135c2d3a559SKris Kennaway 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1136333ee039SDag-Erling Smørgrav 
1137333ee039SDag-Erling Smørgrav 		/* Collect arguments (separate to executable) */
1138333ee039SDag-Erling Smørgrav 		p = xstrdup(arg);
1139333ee039SDag-Erling Smørgrav 		len = strlen(p) + 1;
1140333ee039SDag-Erling Smørgrav 		while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1141333ee039SDag-Erling Smørgrav 			len += 1 + strlen(arg);
1142333ee039SDag-Erling Smørgrav 			p = xrealloc(p, 1, len);
1143333ee039SDag-Erling Smørgrav 			strlcat(p, " ", len);
1144333ee039SDag-Erling Smørgrav 			strlcat(p, arg, len);
1145333ee039SDag-Erling Smørgrav 		}
1146333ee039SDag-Erling Smørgrav 		options->subsystem_args[options->num_subsystems] = p;
1147c2d3a559SKris Kennaway 		options->num_subsystems++;
1148c2d3a559SKris Kennaway 		break;
1149c2d3a559SKris Kennaway 
1150c2d3a559SKris Kennaway 	case sMaxStartups:
1151c2d3a559SKris Kennaway 		arg = strdelim(&cp);
1152c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
1153c2d3a559SKris Kennaway 			fatal("%s line %d: Missing MaxStartups spec.",
1154c2d3a559SKris Kennaway 			    filename, linenum);
1155af12a3e7SDag-Erling Smørgrav 		if ((n = sscanf(arg, "%d:%d:%d",
1156c2d3a559SKris Kennaway 		    &options->max_startups_begin,
1157c2d3a559SKris Kennaway 		    &options->max_startups_rate,
1158af12a3e7SDag-Erling Smørgrav 		    &options->max_startups)) == 3) {
1159c2d3a559SKris Kennaway 			if (options->max_startups_begin >
1160c2d3a559SKris Kennaway 			    options->max_startups ||
1161c2d3a559SKris Kennaway 			    options->max_startups_rate > 100 ||
1162c2d3a559SKris Kennaway 			    options->max_startups_rate < 1)
1163c2d3a559SKris Kennaway 				fatal("%s line %d: Illegal MaxStartups spec.",
1164c2d3a559SKris Kennaway 				    filename, linenum);
1165af12a3e7SDag-Erling Smørgrav 		} else if (n != 1)
1166af12a3e7SDag-Erling Smørgrav 			fatal("%s line %d: Illegal MaxStartups spec.",
1167af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
1168af12a3e7SDag-Erling Smørgrav 		else
1169af12a3e7SDag-Erling Smørgrav 			options->max_startups = options->max_startups_begin;
1170933ca70fSBrian Feldman 		break;
1171933ca70fSBrian Feldman 
117221e764dfSDag-Erling Smørgrav 	case sMaxAuthTries:
117321e764dfSDag-Erling Smørgrav 		intptr = &options->max_authtries;
117421e764dfSDag-Erling Smørgrav 		goto parse_int;
117521e764dfSDag-Erling Smørgrav 
1176d4af9e69SDag-Erling Smørgrav 	case sMaxSessions:
1177d4af9e69SDag-Erling Smørgrav 		intptr = &options->max_sessions;
1178d4af9e69SDag-Erling Smørgrav 		goto parse_int;
1179d4af9e69SDag-Erling Smørgrav 
1180ca3176e7SBrian Feldman 	case sBanner:
1181ca3176e7SBrian Feldman 		charptr = &options->banner;
1182ca3176e7SBrian Feldman 		goto parse_filename;
1183d4af9e69SDag-Erling Smørgrav 
1184af12a3e7SDag-Erling Smørgrav 	/*
1185af12a3e7SDag-Erling Smørgrav 	 * These options can contain %X options expanded at
1186af12a3e7SDag-Erling Smørgrav 	 * connect time, so that you can specify paths like:
1187af12a3e7SDag-Erling Smørgrav 	 *
1188af12a3e7SDag-Erling Smørgrav 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
1189af12a3e7SDag-Erling Smørgrav 	 */
1190af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile:
1191af12a3e7SDag-Erling Smørgrav 	case sAuthorizedKeysFile2:
1192af12a3e7SDag-Erling Smørgrav 		charptr = (opcode == sAuthorizedKeysFile) ?
1193af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file :
1194af12a3e7SDag-Erling Smørgrav 		    &options->authorized_keys_file2;
1195af12a3e7SDag-Erling Smørgrav 		goto parse_filename;
1196af12a3e7SDag-Erling Smørgrav 
1197ca3176e7SBrian Feldman 	case sClientAliveInterval:
1198ca3176e7SBrian Feldman 		intptr = &options->client_alive_interval;
1199af12a3e7SDag-Erling Smørgrav 		goto parse_time;
1200af12a3e7SDag-Erling Smørgrav 
1201ca3176e7SBrian Feldman 	case sClientAliveCountMax:
1202ca3176e7SBrian Feldman 		intptr = &options->client_alive_count_max;
1203ca3176e7SBrian Feldman 		goto parse_int;
1204af12a3e7SDag-Erling Smørgrav 
120521e764dfSDag-Erling Smørgrav 	case sAcceptEnv:
120621e764dfSDag-Erling Smørgrav 		while ((arg = strdelim(&cp)) && *arg != '\0') {
120721e764dfSDag-Erling Smørgrav 			if (strchr(arg, '=') != NULL)
120821e764dfSDag-Erling Smørgrav 				fatal("%s line %d: Invalid environment name.",
120921e764dfSDag-Erling Smørgrav 				    filename, linenum);
121021e764dfSDag-Erling Smørgrav 			if (options->num_accept_env >= MAX_ACCEPT_ENV)
121121e764dfSDag-Erling Smørgrav 				fatal("%s line %d: too many allow env.",
121221e764dfSDag-Erling Smørgrav 				    filename, linenum);
1213333ee039SDag-Erling Smørgrav 			if (!*activep)
1214333ee039SDag-Erling Smørgrav 				break;
121521e764dfSDag-Erling Smørgrav 			options->accept_env[options->num_accept_env++] =
121621e764dfSDag-Erling Smørgrav 			    xstrdup(arg);
121721e764dfSDag-Erling Smørgrav 		}
121821e764dfSDag-Erling Smørgrav 		break;
121921e764dfSDag-Erling Smørgrav 
1220b74df5b2SDag-Erling Smørgrav 	case sPermitTunnel:
1221b74df5b2SDag-Erling Smørgrav 		intptr = &options->permit_tun;
1222b74df5b2SDag-Erling Smørgrav 		arg = strdelim(&cp);
1223b74df5b2SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
1224b74df5b2SDag-Erling Smørgrav 			fatal("%s line %d: Missing yes/point-to-point/"
1225b74df5b2SDag-Erling Smørgrav 			    "ethernet/no argument.", filename, linenum);
1226d4af9e69SDag-Erling Smørgrav 		value = -1;
1227d4af9e69SDag-Erling Smørgrav 		for (i = 0; tunmode_desc[i].val != -1; i++)
1228d4af9e69SDag-Erling Smørgrav 			if (strcmp(tunmode_desc[i].text, arg) == 0) {
1229d4af9e69SDag-Erling Smørgrav 				value = tunmode_desc[i].val;
1230d4af9e69SDag-Erling Smørgrav 				break;
1231d4af9e69SDag-Erling Smørgrav 			}
1232d4af9e69SDag-Erling Smørgrav 		if (value == -1)
1233b74df5b2SDag-Erling Smørgrav 			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1234b74df5b2SDag-Erling Smørgrav 			    "no argument: %s", filename, linenum, arg);
1235b74df5b2SDag-Erling Smørgrav 		if (*intptr == -1)
1236b74df5b2SDag-Erling Smørgrav 			*intptr = value;
1237b74df5b2SDag-Erling Smørgrav 		break;
1238b74df5b2SDag-Erling Smørgrav 
1239333ee039SDag-Erling Smørgrav 	case sMatch:
1240333ee039SDag-Erling Smørgrav 		if (cmdline)
1241333ee039SDag-Erling Smørgrav 			fatal("Match directive not supported as a command-line "
1242333ee039SDag-Erling Smørgrav 			   "option");
1243333ee039SDag-Erling Smørgrav 		value = match_cfg_line(&cp, linenum, user, host, address);
1244333ee039SDag-Erling Smørgrav 		if (value < 0)
1245333ee039SDag-Erling Smørgrav 			fatal("%s line %d: Bad Match condition", filename,
1246333ee039SDag-Erling Smørgrav 			    linenum);
1247333ee039SDag-Erling Smørgrav 		*activep = value;
1248333ee039SDag-Erling Smørgrav 		break;
1249333ee039SDag-Erling Smørgrav 
1250333ee039SDag-Erling Smørgrav 	case sPermitOpen:
1251333ee039SDag-Erling Smørgrav 		arg = strdelim(&cp);
1252333ee039SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
1253333ee039SDag-Erling Smørgrav 			fatal("%s line %d: missing PermitOpen specification",
1254333ee039SDag-Erling Smørgrav 			    filename, linenum);
1255d4af9e69SDag-Erling Smørgrav 		n = options->num_permitted_opens;	/* modified later */
1256333ee039SDag-Erling Smørgrav 		if (strcmp(arg, "any") == 0) {
1257d4af9e69SDag-Erling Smørgrav 			if (*activep && n == -1) {
1258333ee039SDag-Erling Smørgrav 				channel_clear_adm_permitted_opens();
1259333ee039SDag-Erling Smørgrav 				options->num_permitted_opens = 0;
1260333ee039SDag-Erling Smørgrav 			}
1261333ee039SDag-Erling Smørgrav 			break;
1262333ee039SDag-Erling Smørgrav 		}
1263d4af9e69SDag-Erling Smørgrav 		if (*activep && n == -1)
1264d4af9e69SDag-Erling Smørgrav 			channel_clear_adm_permitted_opens();
1265333ee039SDag-Erling Smørgrav 		for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1266333ee039SDag-Erling Smørgrav 			p = hpdelim(&arg);
1267333ee039SDag-Erling Smørgrav 			if (p == NULL)
1268333ee039SDag-Erling Smørgrav 				fatal("%s line %d: missing host in PermitOpen",
1269333ee039SDag-Erling Smørgrav 				    filename, linenum);
1270333ee039SDag-Erling Smørgrav 			p = cleanhostname(p);
1271cce7d346SDag-Erling Smørgrav 			if (arg == NULL || (port = a2port(arg)) <= 0)
1272333ee039SDag-Erling Smørgrav 				fatal("%s line %d: bad port number in "
1273333ee039SDag-Erling Smørgrav 				    "PermitOpen", filename, linenum);
1274d4af9e69SDag-Erling Smørgrav 			if (*activep && n == -1)
1275333ee039SDag-Erling Smørgrav 				options->num_permitted_opens =
1276333ee039SDag-Erling Smørgrav 				    channel_add_adm_permitted_opens(p, port);
1277333ee039SDag-Erling Smørgrav 		}
1278333ee039SDag-Erling Smørgrav 		break;
1279333ee039SDag-Erling Smørgrav 
1280333ee039SDag-Erling Smørgrav 	case sForceCommand:
1281333ee039SDag-Erling Smørgrav 		if (cp == NULL)
1282333ee039SDag-Erling Smørgrav 			fatal("%.200s line %d: Missing argument.", filename,
1283333ee039SDag-Erling Smørgrav 			    linenum);
1284333ee039SDag-Erling Smørgrav 		len = strspn(cp, WHITESPACE);
1285333ee039SDag-Erling Smørgrav 		if (*activep && options->adm_forced_command == NULL)
1286333ee039SDag-Erling Smørgrav 			options->adm_forced_command = xstrdup(cp + len);
1287333ee039SDag-Erling Smørgrav 		return 0;
1288333ee039SDag-Erling Smørgrav 
1289d4af9e69SDag-Erling Smørgrav 	case sChrootDirectory:
1290d4af9e69SDag-Erling Smørgrav 		charptr = &options->chroot_directory;
1291d4af9e69SDag-Erling Smørgrav 
1292d4af9e69SDag-Erling Smørgrav 		arg = strdelim(&cp);
1293d4af9e69SDag-Erling Smørgrav 		if (!arg || *arg == '\0')
1294d4af9e69SDag-Erling Smørgrav 			fatal("%s line %d: missing file name.",
1295d4af9e69SDag-Erling Smørgrav 			    filename, linenum);
1296d4af9e69SDag-Erling Smørgrav 		if (*activep && *charptr == NULL)
1297d4af9e69SDag-Erling Smørgrav 			*charptr = xstrdup(arg);
1298d4af9e69SDag-Erling Smørgrav 		break;
1299d4af9e69SDag-Erling Smørgrav 
1300db58a8e4SDag-Erling Smørgrav 	case sVersionAddendum:
1301db58a8e4SDag-Erling Smørgrav                 ssh_version_set_addendum(strtok(cp, "\n"));
1302db58a8e4SDag-Erling Smørgrav                 do {
1303db58a8e4SDag-Erling Smørgrav                         arg = strdelim(&cp);
1304db58a8e4SDag-Erling Smørgrav                 } while (arg != NULL && *arg != '\0');
1305db58a8e4SDag-Erling Smørgrav 		break;
1306db58a8e4SDag-Erling Smørgrav 
1307af12a3e7SDag-Erling Smørgrav 	case sDeprecated:
1308cf2b5f3bSDag-Erling Smørgrav 		logit("%s line %d: Deprecated option %s",
1309cf2b5f3bSDag-Erling Smørgrav 		    filename, linenum, arg);
1310cf2b5f3bSDag-Erling Smørgrav 		while (arg)
1311cf2b5f3bSDag-Erling Smørgrav 		    arg = strdelim(&cp);
1312cf2b5f3bSDag-Erling Smørgrav 		break;
1313cf2b5f3bSDag-Erling Smørgrav 
1314cf2b5f3bSDag-Erling Smørgrav 	case sUnsupported:
1315cf2b5f3bSDag-Erling Smørgrav 		logit("%s line %d: Unsupported option %s",
1316af12a3e7SDag-Erling Smørgrav 		    filename, linenum, arg);
1317af12a3e7SDag-Erling Smørgrav 		while (arg)
1318af12a3e7SDag-Erling Smørgrav 		    arg = strdelim(&cp);
1319af12a3e7SDag-Erling Smørgrav 		break;
1320af12a3e7SDag-Erling Smørgrav 
132142f71286SMark Murray 	default:
1322af12a3e7SDag-Erling Smørgrav 		fatal("%s line %d: Missing handler for opcode %s (%d)",
1323c2d3a559SKris Kennaway 		    filename, linenum, arg, opcode);
1324511b41d2SMark Murray 	}
1325ca3176e7SBrian Feldman 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1326ca3176e7SBrian Feldman 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
1327c2d3a559SKris Kennaway 		    filename, linenum, arg);
1328af12a3e7SDag-Erling Smørgrav 	return 0;
1329af12a3e7SDag-Erling Smørgrav }
1330af12a3e7SDag-Erling Smørgrav 
1331af12a3e7SDag-Erling Smørgrav /* Reads the server configuration file. */
1332af12a3e7SDag-Erling Smørgrav 
1333af12a3e7SDag-Erling Smørgrav void
133421e764dfSDag-Erling Smørgrav load_server_config(const char *filename, Buffer *conf)
1335af12a3e7SDag-Erling Smørgrav {
133621e764dfSDag-Erling Smørgrav 	char line[1024], *cp;
1337a82e551fSDag-Erling Smørgrav 	FILE *f;
1338af12a3e7SDag-Erling Smørgrav 
133921e764dfSDag-Erling Smørgrav 	debug2("%s: filename %s", __func__, filename);
134021e764dfSDag-Erling Smørgrav 	if ((f = fopen(filename, "r")) == NULL) {
1341af12a3e7SDag-Erling Smørgrav 		perror(filename);
1342af12a3e7SDag-Erling Smørgrav 		exit(1);
1343af12a3e7SDag-Erling Smørgrav 	}
134421e764dfSDag-Erling Smørgrav 	buffer_clear(conf);
1345af12a3e7SDag-Erling Smørgrav 	while (fgets(line, sizeof(line), f)) {
134621e764dfSDag-Erling Smørgrav 		/*
134721e764dfSDag-Erling Smørgrav 		 * Trim out comments and strip whitespace
134821e764dfSDag-Erling Smørgrav 		 * NB - preserve newlines, they are needed to reproduce
134921e764dfSDag-Erling Smørgrav 		 * line numbers later for error messages
135021e764dfSDag-Erling Smørgrav 		 */
135121e764dfSDag-Erling Smørgrav 		if ((cp = strchr(line, '#')) != NULL)
135221e764dfSDag-Erling Smørgrav 			memcpy(cp, "\n", 2);
135321e764dfSDag-Erling Smørgrav 		cp = line + strspn(line, " \t\r");
135421e764dfSDag-Erling Smørgrav 
135521e764dfSDag-Erling Smørgrav 		buffer_append(conf, cp, strlen(cp));
135621e764dfSDag-Erling Smørgrav 	}
135721e764dfSDag-Erling Smørgrav 	buffer_append(conf, "\0", 1);
135821e764dfSDag-Erling Smørgrav 	fclose(f);
135921e764dfSDag-Erling Smørgrav 	debug2("%s: done config len = %d", __func__, buffer_len(conf));
136021e764dfSDag-Erling Smørgrav }
136121e764dfSDag-Erling Smørgrav 
136221e764dfSDag-Erling Smørgrav void
1363333ee039SDag-Erling Smørgrav parse_server_match_config(ServerOptions *options, const char *user,
1364333ee039SDag-Erling Smørgrav     const char *host, const char *address)
136521e764dfSDag-Erling Smørgrav {
1366333ee039SDag-Erling Smørgrav 	ServerOptions mo;
1367333ee039SDag-Erling Smørgrav 
1368333ee039SDag-Erling Smørgrav 	initialize_server_options(&mo);
1369333ee039SDag-Erling Smørgrav 	parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1370d4af9e69SDag-Erling Smørgrav 	copy_set_server_options(options, &mo, 0);
1371333ee039SDag-Erling Smørgrav }
1372333ee039SDag-Erling Smørgrav 
1373d4af9e69SDag-Erling Smørgrav /* Helper macros */
1374d4af9e69SDag-Erling Smørgrav #define M_CP_INTOPT(n) do {\
1375d4af9e69SDag-Erling Smørgrav 	if (src->n != -1) \
1376d4af9e69SDag-Erling Smørgrav 		dst->n = src->n; \
1377d4af9e69SDag-Erling Smørgrav } while (0)
1378d4af9e69SDag-Erling Smørgrav #define M_CP_STROPT(n) do {\
1379d4af9e69SDag-Erling Smørgrav 	if (src->n != NULL) { \
1380d4af9e69SDag-Erling Smørgrav 		if (dst->n != NULL) \
1381d4af9e69SDag-Erling Smørgrav 			xfree(dst->n); \
1382d4af9e69SDag-Erling Smørgrav 		dst->n = src->n; \
1383d4af9e69SDag-Erling Smørgrav 	} \
1384d4af9e69SDag-Erling Smørgrav } while(0)
1385d4af9e69SDag-Erling Smørgrav 
1386d4af9e69SDag-Erling Smørgrav /*
1387d4af9e69SDag-Erling Smørgrav  * Copy any supported values that are set.
1388d4af9e69SDag-Erling Smørgrav  *
13897aee6ffeSDag-Erling Smørgrav  * If the preauth flag is set, we do not bother copying the string or
1390d4af9e69SDag-Erling Smørgrav  * array values that are not used pre-authentication, because any that we
1391d4af9e69SDag-Erling Smørgrav  * do use must be explictly sent in mm_getpwnamallow().
1392d4af9e69SDag-Erling Smørgrav  */
1393333ee039SDag-Erling Smørgrav void
1394d4af9e69SDag-Erling Smørgrav copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1395333ee039SDag-Erling Smørgrav {
1396d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(password_authentication);
1397d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(gss_authentication);
1398d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(rsa_authentication);
1399d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(pubkey_authentication);
1400d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(kerberos_authentication);
1401d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(hostbased_authentication);
1402d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(kbd_interactive_authentication);
1403cce7d346SDag-Erling Smørgrav 	M_CP_INTOPT(zero_knowledge_password_authentication);
1404d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(permit_root_login);
1405cce7d346SDag-Erling Smørgrav 	M_CP_INTOPT(permit_empty_passwd);
1406d4af9e69SDag-Erling Smørgrav 
1407d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(allow_tcp_forwarding);
1408d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(allow_agent_forwarding);
1409d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(gateway_ports);
1410d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(x11_display_offset);
1411d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(x11_forwarding);
1412d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(x11_use_localhost);
1413d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(max_sessions);
1414d4af9e69SDag-Erling Smørgrav 	M_CP_INTOPT(max_authtries);
1415d4af9e69SDag-Erling Smørgrav 
1416d4af9e69SDag-Erling Smørgrav 	M_CP_STROPT(banner);
1417d4af9e69SDag-Erling Smørgrav 	if (preauth)
1418d4af9e69SDag-Erling Smørgrav 		return;
1419d4af9e69SDag-Erling Smørgrav 	M_CP_STROPT(adm_forced_command);
1420d4af9e69SDag-Erling Smørgrav 	M_CP_STROPT(chroot_directory);
1421333ee039SDag-Erling Smørgrav }
1422d4af9e69SDag-Erling Smørgrav 
1423d4af9e69SDag-Erling Smørgrav #undef M_CP_INTOPT
1424d4af9e69SDag-Erling Smørgrav #undef M_CP_STROPT
1425333ee039SDag-Erling Smørgrav 
1426333ee039SDag-Erling Smørgrav void
1427333ee039SDag-Erling Smørgrav parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1428333ee039SDag-Erling Smørgrav     const char *user, const char *host, const char *address)
1429333ee039SDag-Erling Smørgrav {
1430333ee039SDag-Erling Smørgrav 	int active, linenum, bad_options = 0;
143121e764dfSDag-Erling Smørgrav 	char *cp, *obuf, *cbuf;
143221e764dfSDag-Erling Smørgrav 
143321e764dfSDag-Erling Smørgrav 	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
143421e764dfSDag-Erling Smørgrav 
143521e764dfSDag-Erling Smørgrav 	obuf = cbuf = xstrdup(buffer_ptr(conf));
1436333ee039SDag-Erling Smørgrav 	active = user ? 0 : 1;
143721e764dfSDag-Erling Smørgrav 	linenum = 1;
143821e764dfSDag-Erling Smørgrav 	while ((cp = strsep(&cbuf, "\n")) != NULL) {
143921e764dfSDag-Erling Smørgrav 		if (process_server_config_line(options, cp, filename,
1440333ee039SDag-Erling Smørgrav 		    linenum++, &active, user, host, address) != 0)
1441af12a3e7SDag-Erling Smørgrav 			bad_options++;
1442511b41d2SMark Murray 	}
144321e764dfSDag-Erling Smørgrav 	xfree(obuf);
1444ca3176e7SBrian Feldman 	if (bad_options > 0)
1445af12a3e7SDag-Erling Smørgrav 		fatal("%s: terminating, %d bad configuration options",
1446511b41d2SMark Murray 		    filename, bad_options);
1447511b41d2SMark Murray }
1448d4af9e69SDag-Erling Smørgrav 
1449d4af9e69SDag-Erling Smørgrav static const char *
1450d4af9e69SDag-Erling Smørgrav fmt_intarg(ServerOpCodes code, int val)
1451d4af9e69SDag-Erling Smørgrav {
1452d4af9e69SDag-Erling Smørgrav 	if (code == sAddressFamily) {
1453d4af9e69SDag-Erling Smørgrav 		switch (val) {
1454d4af9e69SDag-Erling Smørgrav 		case AF_INET:
1455d4af9e69SDag-Erling Smørgrav 			return "inet";
1456d4af9e69SDag-Erling Smørgrav 		case AF_INET6:
1457d4af9e69SDag-Erling Smørgrav 			return "inet6";
1458d4af9e69SDag-Erling Smørgrav 		case AF_UNSPEC:
1459d4af9e69SDag-Erling Smørgrav 			return "any";
1460d4af9e69SDag-Erling Smørgrav 		default:
1461d4af9e69SDag-Erling Smørgrav 			return "UNKNOWN";
1462d4af9e69SDag-Erling Smørgrav 		}
1463d4af9e69SDag-Erling Smørgrav 	}
1464d4af9e69SDag-Erling Smørgrav 	if (code == sPermitRootLogin) {
1465d4af9e69SDag-Erling Smørgrav 		switch (val) {
1466d4af9e69SDag-Erling Smørgrav 		case PERMIT_NO_PASSWD:
1467cce7d346SDag-Erling Smørgrav 			return "without-password";
1468d4af9e69SDag-Erling Smørgrav 		case PERMIT_FORCED_ONLY:
1469d4af9e69SDag-Erling Smørgrav 			return "forced-commands-only";
1470d4af9e69SDag-Erling Smørgrav 		case PERMIT_YES:
1471d4af9e69SDag-Erling Smørgrav 			return "yes";
1472d4af9e69SDag-Erling Smørgrav 		}
1473d4af9e69SDag-Erling Smørgrav 	}
1474d4af9e69SDag-Erling Smørgrav 	if (code == sProtocol) {
1475d4af9e69SDag-Erling Smørgrav 		switch (val) {
1476d4af9e69SDag-Erling Smørgrav 		case SSH_PROTO_1:
1477d4af9e69SDag-Erling Smørgrav 			return "1";
1478d4af9e69SDag-Erling Smørgrav 		case SSH_PROTO_2:
1479d4af9e69SDag-Erling Smørgrav 			return "2";
1480d4af9e69SDag-Erling Smørgrav 		case (SSH_PROTO_1|SSH_PROTO_2):
1481d4af9e69SDag-Erling Smørgrav 			return "2,1";
1482d4af9e69SDag-Erling Smørgrav 		default:
1483d4af9e69SDag-Erling Smørgrav 			return "UNKNOWN";
1484d4af9e69SDag-Erling Smørgrav 		}
1485d4af9e69SDag-Erling Smørgrav 	}
1486d4af9e69SDag-Erling Smørgrav 	if (code == sGatewayPorts && val == 2)
1487d4af9e69SDag-Erling Smørgrav 		return "clientspecified";
1488d4af9e69SDag-Erling Smørgrav 	if (code == sCompression && val == COMP_DELAYED)
1489d4af9e69SDag-Erling Smørgrav 		return "delayed";
1490d4af9e69SDag-Erling Smørgrav 	switch (val) {
1491d4af9e69SDag-Erling Smørgrav 	case -1:
1492d4af9e69SDag-Erling Smørgrav 		return "unset";
1493d4af9e69SDag-Erling Smørgrav 	case 0:
1494d4af9e69SDag-Erling Smørgrav 		return "no";
1495d4af9e69SDag-Erling Smørgrav 	case 1:
1496d4af9e69SDag-Erling Smørgrav 		return "yes";
1497d4af9e69SDag-Erling Smørgrav 	}
1498d4af9e69SDag-Erling Smørgrav 	return "UNKNOWN";
1499d4af9e69SDag-Erling Smørgrav }
1500d4af9e69SDag-Erling Smørgrav 
1501d4af9e69SDag-Erling Smørgrav static const char *
1502d4af9e69SDag-Erling Smørgrav lookup_opcode_name(ServerOpCodes code)
1503d4af9e69SDag-Erling Smørgrav {
1504d4af9e69SDag-Erling Smørgrav 	u_int i;
1505d4af9e69SDag-Erling Smørgrav 
1506d4af9e69SDag-Erling Smørgrav 	for (i = 0; keywords[i].name != NULL; i++)
1507d4af9e69SDag-Erling Smørgrav 		if (keywords[i].opcode == code)
1508d4af9e69SDag-Erling Smørgrav 			return(keywords[i].name);
1509d4af9e69SDag-Erling Smørgrav 	return "UNKNOWN";
1510d4af9e69SDag-Erling Smørgrav }
1511d4af9e69SDag-Erling Smørgrav 
1512d4af9e69SDag-Erling Smørgrav static void
1513d4af9e69SDag-Erling Smørgrav dump_cfg_int(ServerOpCodes code, int val)
1514d4af9e69SDag-Erling Smørgrav {
1515d4af9e69SDag-Erling Smørgrav 	printf("%s %d\n", lookup_opcode_name(code), val);
1516d4af9e69SDag-Erling Smørgrav }
1517d4af9e69SDag-Erling Smørgrav 
1518d4af9e69SDag-Erling Smørgrav static void
1519d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(ServerOpCodes code, int val)
1520d4af9e69SDag-Erling Smørgrav {
1521d4af9e69SDag-Erling Smørgrav 	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
1522d4af9e69SDag-Erling Smørgrav }
1523d4af9e69SDag-Erling Smørgrav 
1524d4af9e69SDag-Erling Smørgrav static void
1525d4af9e69SDag-Erling Smørgrav dump_cfg_string(ServerOpCodes code, const char *val)
1526d4af9e69SDag-Erling Smørgrav {
1527d4af9e69SDag-Erling Smørgrav 	if (val == NULL)
1528d4af9e69SDag-Erling Smørgrav 		return;
1529d4af9e69SDag-Erling Smørgrav 	printf("%s %s\n", lookup_opcode_name(code), val);
1530d4af9e69SDag-Erling Smørgrav }
1531d4af9e69SDag-Erling Smørgrav 
1532d4af9e69SDag-Erling Smørgrav static void
1533d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
1534d4af9e69SDag-Erling Smørgrav {
1535d4af9e69SDag-Erling Smørgrav 	u_int i;
1536d4af9e69SDag-Erling Smørgrav 
1537d4af9e69SDag-Erling Smørgrav 	for (i = 0; i < count; i++)
1538d4af9e69SDag-Erling Smørgrav 		printf("%s %s\n", lookup_opcode_name(code),  vals[i]);
1539d4af9e69SDag-Erling Smørgrav }
1540d4af9e69SDag-Erling Smørgrav 
1541d4af9e69SDag-Erling Smørgrav void
1542d4af9e69SDag-Erling Smørgrav dump_config(ServerOptions *o)
1543d4af9e69SDag-Erling Smørgrav {
1544d4af9e69SDag-Erling Smørgrav 	u_int i;
1545d4af9e69SDag-Erling Smørgrav 	int ret;
1546d4af9e69SDag-Erling Smørgrav 	struct addrinfo *ai;
1547d4af9e69SDag-Erling Smørgrav 	char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
1548d4af9e69SDag-Erling Smørgrav 
1549d4af9e69SDag-Erling Smørgrav 	/* these are usually at the top of the config */
1550d4af9e69SDag-Erling Smørgrav 	for (i = 0; i < o->num_ports; i++)
1551d4af9e69SDag-Erling Smørgrav 		printf("port %d\n", o->ports[i]);
1552d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sProtocol, o->protocol);
1553d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sAddressFamily, o->address_family);
1554d4af9e69SDag-Erling Smørgrav 
1555d4af9e69SDag-Erling Smørgrav 	/* ListenAddress must be after Port */
1556d4af9e69SDag-Erling Smørgrav 	for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
1557d4af9e69SDag-Erling Smørgrav 		if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
1558d4af9e69SDag-Erling Smørgrav 		    sizeof(addr), port, sizeof(port),
1559d4af9e69SDag-Erling Smørgrav 		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1560d4af9e69SDag-Erling Smørgrav 			error("getnameinfo failed: %.100s",
1561d4af9e69SDag-Erling Smørgrav 			    (ret != EAI_SYSTEM) ? gai_strerror(ret) :
1562d4af9e69SDag-Erling Smørgrav 			    strerror(errno));
1563d4af9e69SDag-Erling Smørgrav 		} else {
1564d4af9e69SDag-Erling Smørgrav 			if (ai->ai_family == AF_INET6)
1565d4af9e69SDag-Erling Smørgrav 				printf("listenaddress [%s]:%s\n", addr, port);
1566d4af9e69SDag-Erling Smørgrav 			else
1567d4af9e69SDag-Erling Smørgrav 				printf("listenaddress %s:%s\n", addr, port);
1568d4af9e69SDag-Erling Smørgrav 		}
1569d4af9e69SDag-Erling Smørgrav 	}
1570d4af9e69SDag-Erling Smørgrav 
1571d4af9e69SDag-Erling Smørgrav 	/* integer arguments */
1572cce7d346SDag-Erling Smørgrav #ifdef USE_PAM
1573cce7d346SDag-Erling Smørgrav 	dump_cfg_int(sUsePAM, o->use_pam);
1574cce7d346SDag-Erling Smørgrav #endif
1575d4af9e69SDag-Erling Smørgrav 	dump_cfg_int(sServerKeyBits, o->server_key_bits);
1576d4af9e69SDag-Erling Smørgrav 	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
1577d4af9e69SDag-Erling Smørgrav 	dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
1578d4af9e69SDag-Erling Smørgrav 	dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
1579d4af9e69SDag-Erling Smørgrav 	dump_cfg_int(sMaxAuthTries, o->max_authtries);
1580cce7d346SDag-Erling Smørgrav 	dump_cfg_int(sMaxSessions, o->max_sessions);
1581d4af9e69SDag-Erling Smørgrav 	dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
1582d4af9e69SDag-Erling Smørgrav 	dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
1583d4af9e69SDag-Erling Smørgrav 
1584d4af9e69SDag-Erling Smørgrav 	/* formatted integer arguments */
1585d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
1586d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
1587d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
1588d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
1589d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
1590d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
1591d4af9e69SDag-Erling Smørgrav 	    o->hostbased_uses_name_from_packet_only);
1592d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
1593d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
1594cce7d346SDag-Erling Smørgrav #ifdef KRB5
1595d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
1596d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
1597d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
1598cce7d346SDag-Erling Smørgrav # ifdef USE_AFS
1599d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
1600cce7d346SDag-Erling Smørgrav # endif
1601cce7d346SDag-Erling Smørgrav #endif
1602cce7d346SDag-Erling Smørgrav #ifdef GSSAPI
1603d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
1604d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
1605cce7d346SDag-Erling Smørgrav #endif
1606cce7d346SDag-Erling Smørgrav #ifdef JPAKE
1607cce7d346SDag-Erling Smørgrav 	dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
1608cce7d346SDag-Erling Smørgrav 	    o->zero_knowledge_password_authentication);
1609cce7d346SDag-Erling Smørgrav #endif
1610d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
1611d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sKbdInteractiveAuthentication,
1612d4af9e69SDag-Erling Smørgrav 	    o->kbd_interactive_authentication);
1613d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sChallengeResponseAuthentication,
1614d4af9e69SDag-Erling Smørgrav 	    o->challenge_response_authentication);
1615d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sPrintMotd, o->print_motd);
1616d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
1617d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
1618d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
1619d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sStrictModes, o->strict_modes);
1620d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
1621d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
1622d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
1623d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sUseLogin, o->use_login);
1624d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sCompression, o->compression);
1625d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
1626d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sUseDNS, o->use_dns);
1627d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
1628d4af9e69SDag-Erling Smørgrav 	dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
1629d4af9e69SDag-Erling Smørgrav 
1630d4af9e69SDag-Erling Smørgrav 	/* string arguments */
1631d4af9e69SDag-Erling Smørgrav 	dump_cfg_string(sPidFile, o->pid_file);
1632d4af9e69SDag-Erling Smørgrav 	dump_cfg_string(sXAuthLocation, o->xauth_location);
1633d4af9e69SDag-Erling Smørgrav 	dump_cfg_string(sCiphers, o->ciphers);
1634d4af9e69SDag-Erling Smørgrav 	dump_cfg_string(sMacs, o->macs);
1635d4af9e69SDag-Erling Smørgrav 	dump_cfg_string(sBanner, o->banner);
1636d4af9e69SDag-Erling Smørgrav 	dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
1637d4af9e69SDag-Erling Smørgrav 	dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
1638d4af9e69SDag-Erling Smørgrav 	dump_cfg_string(sForceCommand, o->adm_forced_command);
1639d4af9e69SDag-Erling Smørgrav 
1640d4af9e69SDag-Erling Smørgrav 	/* string arguments requiring a lookup */
1641d4af9e69SDag-Erling Smørgrav 	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1642d4af9e69SDag-Erling Smørgrav 	dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
1643d4af9e69SDag-Erling Smørgrav 
1644d4af9e69SDag-Erling Smørgrav 	/* string array arguments */
1645d4af9e69SDag-Erling Smørgrav 	dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
1646d4af9e69SDag-Erling Smørgrav 	     o->host_key_files);
1647d4af9e69SDag-Erling Smørgrav 	dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
1648d4af9e69SDag-Erling Smørgrav 	dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
1649d4af9e69SDag-Erling Smørgrav 	dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
1650d4af9e69SDag-Erling Smørgrav 	dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
1651d4af9e69SDag-Erling Smørgrav 	dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
1652d4af9e69SDag-Erling Smørgrav 
1653d4af9e69SDag-Erling Smørgrav 	/* other arguments */
1654d4af9e69SDag-Erling Smørgrav 	for (i = 0; i < o->num_subsystems; i++)
1655d4af9e69SDag-Erling Smørgrav 		printf("subsystem %s %s\n", o->subsystem_name[i],
1656d4af9e69SDag-Erling Smørgrav 		    o->subsystem_args[i]);
1657d4af9e69SDag-Erling Smørgrav 
1658d4af9e69SDag-Erling Smørgrav 	printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
1659d4af9e69SDag-Erling Smørgrav 	    o->max_startups_rate, o->max_startups);
1660d4af9e69SDag-Erling Smørgrav 
1661d4af9e69SDag-Erling Smørgrav 	for (i = 0; tunmode_desc[i].val != -1; i++)
1662d4af9e69SDag-Erling Smørgrav 		if (tunmode_desc[i].val == o->permit_tun) {
1663d4af9e69SDag-Erling Smørgrav 			s = tunmode_desc[i].text;
1664d4af9e69SDag-Erling Smørgrav 			break;
1665d4af9e69SDag-Erling Smørgrav 		}
1666d4af9e69SDag-Erling Smørgrav 	dump_cfg_string(sPermitTunnel, s);
1667d4af9e69SDag-Erling Smørgrav 
1668d4af9e69SDag-Erling Smørgrav 	channel_print_adm_permitted_opens();
1669d4af9e69SDag-Erling Smørgrav }
1670