xref: /openbsd-src/usr.bin/ssh/servconf.c (revision 78fec973f57e9fc9edd564490c79661460ad807b)
1 
2 /* $OpenBSD: servconf.c,v 1.385 2022/06/03 04:30:47 djm Exp $ */
3 /*
4  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5  *                    All rights reserved
6  *
7  * As far as I am concerned, the code I have written for this software
8  * can be used freely for any purpose.  Any derived versions of this
9  * software must be clearly marked as such, and if the derived work is
10  * incompatible with the protocol description in the RFC file, it must be
11  * called by a name other than "ssh" or "Secure Shell".
12  */
13 
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <sys/queue.h>
17 #include <sys/sysctl.h>
18 #include <sys/stat.h>
19 
20 #include <netinet/in.h>
21 #include <netinet/ip.h>
22 #include <net/route.h>
23 
24 #include <ctype.h>
25 #include <glob.h>
26 #include <netdb.h>
27 #include <pwd.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <signal.h>
32 #include <unistd.h>
33 #include <limits.h>
34 #include <stdarg.h>
35 #include <errno.h>
36 #include <util.h>
37 
38 #include "xmalloc.h"
39 #include "ssh.h"
40 #include "log.h"
41 #include "sshbuf.h"
42 #include "misc.h"
43 #include "servconf.h"
44 #include "compat.h"
45 #include "pathnames.h"
46 #include "cipher.h"
47 #include "sshkey.h"
48 #include "kex.h"
49 #include "mac.h"
50 #include "match.h"
51 #include "channels.h"
52 #include "groupaccess.h"
53 #include "canohost.h"
54 #include "packet.h"
55 #include "ssherr.h"
56 #include "hostfile.h"
57 #include "auth.h"
58 #include "myproposal.h"
59 #include "digest.h"
60 
61 static void add_listen_addr(ServerOptions *, const char *,
62     const char *, int);
63 static void add_one_listen_addr(ServerOptions *, const char *,
64     const char *, int);
65 static void parse_server_config_depth(ServerOptions *options,
66     const char *filename, struct sshbuf *conf, struct include_list *includes,
67     struct connection_info *connectinfo, int flags, int *activep, int depth);
68 
69 /* Use of privilege separation or not */
70 extern int use_privsep;
71 extern struct sshbuf *cfg;
72 
73 /* Initializes the server options to their default values. */
74 
75 void
76 initialize_server_options(ServerOptions *options)
77 {
78 	memset(options, 0, sizeof(*options));
79 	options->num_ports = 0;
80 	options->ports_from_cmdline = 0;
81 	options->queued_listen_addrs = NULL;
82 	options->num_queued_listens = 0;
83 	options->listen_addrs = NULL;
84 	options->num_listen_addrs = 0;
85 	options->address_family = -1;
86 	options->routing_domain = NULL;
87 	options->num_host_key_files = 0;
88 	options->num_host_cert_files = 0;
89 	options->host_key_agent = NULL;
90 	options->pid_file = NULL;
91 	options->login_grace_time = -1;
92 	options->permit_root_login = PERMIT_NOT_SET;
93 	options->ignore_rhosts = -1;
94 	options->ignore_user_known_hosts = -1;
95 	options->print_motd = -1;
96 	options->print_lastlog = -1;
97 	options->x11_forwarding = -1;
98 	options->x11_display_offset = -1;
99 	options->x11_use_localhost = -1;
100 	options->permit_tty = -1;
101 	options->permit_user_rc = -1;
102 	options->xauth_location = NULL;
103 	options->strict_modes = -1;
104 	options->tcp_keep_alive = -1;
105 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
106 	options->log_level = SYSLOG_LEVEL_NOT_SET;
107 	options->num_log_verbose = 0;
108 	options->log_verbose = NULL;
109 	options->hostbased_authentication = -1;
110 	options->hostbased_uses_name_from_packet_only = -1;
111 	options->hostbased_accepted_algos = NULL;
112 	options->hostkeyalgorithms = NULL;
113 	options->pubkey_authentication = -1;
114 	options->pubkey_auth_options = -1;
115 	options->pubkey_accepted_algos = NULL;
116 	options->kerberos_authentication = -1;
117 	options->kerberos_or_local_passwd = -1;
118 	options->kerberos_ticket_cleanup = -1;
119 	options->kerberos_get_afs_token = -1;
120 	options->gss_authentication=-1;
121 	options->gss_cleanup_creds = -1;
122 	options->gss_strict_acceptor = -1;
123 	options->password_authentication = -1;
124 	options->kbd_interactive_authentication = -1;
125 	options->permit_empty_passwd = -1;
126 	options->permit_user_env = -1;
127 	options->permit_user_env_allowlist = NULL;
128 	options->compression = -1;
129 	options->rekey_limit = -1;
130 	options->rekey_interval = -1;
131 	options->allow_tcp_forwarding = -1;
132 	options->allow_streamlocal_forwarding = -1;
133 	options->allow_agent_forwarding = -1;
134 	options->num_allow_users = 0;
135 	options->num_deny_users = 0;
136 	options->num_allow_groups = 0;
137 	options->num_deny_groups = 0;
138 	options->ciphers = NULL;
139 	options->macs = NULL;
140 	options->kex_algorithms = NULL;
141 	options->ca_sign_algorithms = NULL;
142 	options->fwd_opts.gateway_ports = -1;
143 	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
144 	options->fwd_opts.streamlocal_bind_unlink = -1;
145 	options->num_subsystems = 0;
146 	options->max_startups_begin = -1;
147 	options->max_startups_rate = -1;
148 	options->max_startups = -1;
149 	options->per_source_max_startups = -1;
150 	options->per_source_masklen_ipv4 = -1;
151 	options->per_source_masklen_ipv6 = -1;
152 	options->max_authtries = -1;
153 	options->max_sessions = -1;
154 	options->banner = NULL;
155 	options->use_dns = -1;
156 	options->client_alive_interval = -1;
157 	options->client_alive_count_max = -1;
158 	options->num_authkeys_files = 0;
159 	options->num_accept_env = 0;
160 	options->num_setenv = 0;
161 	options->permit_tun = -1;
162 	options->permitted_opens = NULL;
163 	options->permitted_listens = NULL;
164 	options->adm_forced_command = NULL;
165 	options->chroot_directory = NULL;
166 	options->authorized_keys_command = NULL;
167 	options->authorized_keys_command_user = NULL;
168 	options->revoked_keys_file = NULL;
169 	options->sk_provider = NULL;
170 	options->trusted_user_ca_keys = NULL;
171 	options->authorized_principals_file = NULL;
172 	options->authorized_principals_command = NULL;
173 	options->authorized_principals_command_user = NULL;
174 	options->ip_qos_interactive = -1;
175 	options->ip_qos_bulk = -1;
176 	options->version_addendum = NULL;
177 	options->fingerprint_hash = -1;
178 	options->disable_forwarding = -1;
179 	options->expose_userauth_info = -1;
180 }
181 
182 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
183 static int
184 option_clear_or_none(const char *o)
185 {
186 	return o == NULL || strcasecmp(o, "none") == 0;
187 }
188 
189 static void
190 assemble_algorithms(ServerOptions *o)
191 {
192 	char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
193 	char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
194 	int r;
195 
196 	all_cipher = cipher_alg_list(',', 0);
197 	all_mac = mac_alg_list(',');
198 	all_kex = kex_alg_list(',');
199 	all_key = sshkey_alg_list(0, 0, 1, ',');
200 	all_sig = sshkey_alg_list(0, 1, 1, ',');
201 	/* remove unsupported algos from default lists */
202 	def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher);
203 	def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac);
204 	def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex);
205 	def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
206 	def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
207 #define ASSEMBLE(what, defaults, all) \
208 	do { \
209 		if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
210 			fatal_fr(r, "%s", #what); \
211 	} while (0)
212 	ASSEMBLE(ciphers, def_cipher, all_cipher);
213 	ASSEMBLE(macs, def_mac, all_mac);
214 	ASSEMBLE(kex_algorithms, def_kex, all_kex);
215 	ASSEMBLE(hostkeyalgorithms, def_key, all_key);
216 	ASSEMBLE(hostbased_accepted_algos, def_key, all_key);
217 	ASSEMBLE(pubkey_accepted_algos, def_key, all_key);
218 	ASSEMBLE(ca_sign_algorithms, def_sig, all_sig);
219 #undef ASSEMBLE
220 	free(all_cipher);
221 	free(all_mac);
222 	free(all_kex);
223 	free(all_key);
224 	free(all_sig);
225 	free(def_cipher);
226 	free(def_mac);
227 	free(def_kex);
228 	free(def_key);
229 	free(def_sig);
230 }
231 
232 void
233 servconf_add_hostkey(const char *file, const int line,
234     ServerOptions *options, const char *path, int userprovided)
235 {
236 	char *apath = derelativise_path(path);
237 
238 	opt_array_append2(file, line, "HostKey",
239 	    &options->host_key_files, &options->host_key_file_userprovided,
240 	    &options->num_host_key_files, apath, userprovided);
241 	free(apath);
242 }
243 
244 void
245 servconf_add_hostcert(const char *file, const int line,
246     ServerOptions *options, const char *path)
247 {
248 	char *apath = derelativise_path(path);
249 
250 	opt_array_append(file, line, "HostCertificate",
251 	    &options->host_cert_files, &options->num_host_cert_files, apath);
252 	free(apath);
253 }
254 
255 void
256 fill_default_server_options(ServerOptions *options)
257 {
258 	u_int i;
259 
260 	if (options->num_host_key_files == 0) {
261 		/* fill default hostkeys */
262 		servconf_add_hostkey("[default]", 0, options,
263 		    _PATH_HOST_RSA_KEY_FILE, 0);
264 		servconf_add_hostkey("[default]", 0, options,
265 		    _PATH_HOST_ECDSA_KEY_FILE, 0);
266 		servconf_add_hostkey("[default]", 0, options,
267 		    _PATH_HOST_ED25519_KEY_FILE, 0);
268 #ifdef WITH_XMSS
269 		servconf_add_hostkey("[default]", 0, options,
270 		    _PATH_HOST_XMSS_KEY_FILE, 0);
271 #endif /* WITH_XMSS */
272 	}
273 	/* No certificates by default */
274 	if (options->num_ports == 0)
275 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
276 	if (options->address_family == -1)
277 		options->address_family = AF_UNSPEC;
278 	if (options->listen_addrs == NULL)
279 		add_listen_addr(options, NULL, NULL, 0);
280 	if (options->pid_file == NULL)
281 		options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
282 	if (options->moduli_file == NULL)
283 		options->moduli_file = xstrdup(_PATH_DH_MODULI);
284 	if (options->login_grace_time == -1)
285 		options->login_grace_time = 120;
286 	if (options->permit_root_login == PERMIT_NOT_SET)
287 		options->permit_root_login = PERMIT_NO_PASSWD;
288 	if (options->ignore_rhosts == -1)
289 		options->ignore_rhosts = 1;
290 	if (options->ignore_user_known_hosts == -1)
291 		options->ignore_user_known_hosts = 0;
292 	if (options->print_motd == -1)
293 		options->print_motd = 1;
294 	if (options->print_lastlog == -1)
295 		options->print_lastlog = 1;
296 	if (options->x11_forwarding == -1)
297 		options->x11_forwarding = 0;
298 	if (options->x11_display_offset == -1)
299 		options->x11_display_offset = 10;
300 	if (options->x11_use_localhost == -1)
301 		options->x11_use_localhost = 1;
302 	if (options->xauth_location == NULL)
303 		options->xauth_location = xstrdup(_PATH_XAUTH);
304 	if (options->permit_tty == -1)
305 		options->permit_tty = 1;
306 	if (options->permit_user_rc == -1)
307 		options->permit_user_rc = 1;
308 	if (options->strict_modes == -1)
309 		options->strict_modes = 1;
310 	if (options->tcp_keep_alive == -1)
311 		options->tcp_keep_alive = 1;
312 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
313 		options->log_facility = SYSLOG_FACILITY_AUTH;
314 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
315 		options->log_level = SYSLOG_LEVEL_INFO;
316 	if (options->hostbased_authentication == -1)
317 		options->hostbased_authentication = 0;
318 	if (options->hostbased_uses_name_from_packet_only == -1)
319 		options->hostbased_uses_name_from_packet_only = 0;
320 	if (options->pubkey_authentication == -1)
321 		options->pubkey_authentication = 1;
322 	if (options->pubkey_auth_options == -1)
323 		options->pubkey_auth_options = 0;
324 	if (options->kerberos_authentication == -1)
325 		options->kerberos_authentication = 0;
326 	if (options->kerberos_or_local_passwd == -1)
327 		options->kerberos_or_local_passwd = 1;
328 	if (options->kerberos_ticket_cleanup == -1)
329 		options->kerberos_ticket_cleanup = 1;
330 	if (options->kerberos_get_afs_token == -1)
331 		options->kerberos_get_afs_token = 0;
332 	if (options->gss_authentication == -1)
333 		options->gss_authentication = 0;
334 	if (options->gss_cleanup_creds == -1)
335 		options->gss_cleanup_creds = 1;
336 	if (options->gss_strict_acceptor == -1)
337 		options->gss_strict_acceptor = 1;
338 	if (options->password_authentication == -1)
339 		options->password_authentication = 1;
340 	if (options->kbd_interactive_authentication == -1)
341 		options->kbd_interactive_authentication = 1;
342 	if (options->permit_empty_passwd == -1)
343 		options->permit_empty_passwd = 0;
344 	if (options->permit_user_env == -1) {
345 		options->permit_user_env = 0;
346 		options->permit_user_env_allowlist = NULL;
347 	}
348 	if (options->compression == -1)
349 #ifdef WITH_ZLIB
350 		options->compression = COMP_DELAYED;
351 #else
352 		options->compression = COMP_NONE;
353 #endif
354 
355 	if (options->rekey_limit == -1)
356 		options->rekey_limit = 0;
357 	if (options->rekey_interval == -1)
358 		options->rekey_interval = 0;
359 	if (options->allow_tcp_forwarding == -1)
360 		options->allow_tcp_forwarding = FORWARD_ALLOW;
361 	if (options->allow_streamlocal_forwarding == -1)
362 		options->allow_streamlocal_forwarding = FORWARD_ALLOW;
363 	if (options->allow_agent_forwarding == -1)
364 		options->allow_agent_forwarding = 1;
365 	if (options->fwd_opts.gateway_ports == -1)
366 		options->fwd_opts.gateway_ports = 0;
367 	if (options->max_startups == -1)
368 		options->max_startups = 100;
369 	if (options->max_startups_rate == -1)
370 		options->max_startups_rate = 30;		/* 30% */
371 	if (options->max_startups_begin == -1)
372 		options->max_startups_begin = 10;
373 	if (options->per_source_max_startups == -1)
374 		options->per_source_max_startups = INT_MAX;
375 	if (options->per_source_masklen_ipv4 == -1)
376 		options->per_source_masklen_ipv4 = 32;
377 	if (options->per_source_masklen_ipv6 == -1)
378 		options->per_source_masklen_ipv6 = 128;
379 	if (options->max_authtries == -1)
380 		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
381 	if (options->max_sessions == -1)
382 		options->max_sessions = DEFAULT_SESSIONS_MAX;
383 	if (options->use_dns == -1)
384 		options->use_dns = 0;
385 	if (options->client_alive_interval == -1)
386 		options->client_alive_interval = 0;
387 	if (options->client_alive_count_max == -1)
388 		options->client_alive_count_max = 3;
389 	if (options->num_authkeys_files == 0) {
390 		opt_array_append("[default]", 0, "AuthorizedKeysFiles",
391 		    &options->authorized_keys_files,
392 		    &options->num_authkeys_files,
393 		    _PATH_SSH_USER_PERMITTED_KEYS);
394 		opt_array_append("[default]", 0, "AuthorizedKeysFiles",
395 		    &options->authorized_keys_files,
396 		    &options->num_authkeys_files,
397 		    _PATH_SSH_USER_PERMITTED_KEYS2);
398 	}
399 	if (options->permit_tun == -1)
400 		options->permit_tun = SSH_TUNMODE_NO;
401 	if (options->ip_qos_interactive == -1)
402 		options->ip_qos_interactive = IPTOS_DSCP_AF21;
403 	if (options->ip_qos_bulk == -1)
404 		options->ip_qos_bulk = IPTOS_DSCP_CS1;
405 	if (options->version_addendum == NULL)
406 		options->version_addendum = xstrdup("");
407 	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
408 		options->fwd_opts.streamlocal_bind_mask = 0177;
409 	if (options->fwd_opts.streamlocal_bind_unlink == -1)
410 		options->fwd_opts.streamlocal_bind_unlink = 0;
411 	if (options->fingerprint_hash == -1)
412 		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
413 	if (options->disable_forwarding == -1)
414 		options->disable_forwarding = 0;
415 	if (options->expose_userauth_info == -1)
416 		options->expose_userauth_info = 0;
417 	if (options->sk_provider == NULL)
418 		options->sk_provider = xstrdup("internal");
419 
420 	assemble_algorithms(options);
421 
422 	/* Turn privilege separation and sandboxing on by default */
423 	if (use_privsep == -1)
424 		use_privsep = PRIVSEP_ON;
425 
426 #define CLEAR_ON_NONE(v) \
427 	do { \
428 		if (option_clear_or_none(v)) { \
429 			free(v); \
430 			v = NULL; \
431 		} \
432 	} while(0)
433 	CLEAR_ON_NONE(options->pid_file);
434 	CLEAR_ON_NONE(options->xauth_location);
435 	CLEAR_ON_NONE(options->banner);
436 	CLEAR_ON_NONE(options->trusted_user_ca_keys);
437 	CLEAR_ON_NONE(options->revoked_keys_file);
438 	CLEAR_ON_NONE(options->sk_provider);
439 	CLEAR_ON_NONE(options->authorized_principals_file);
440 	CLEAR_ON_NONE(options->adm_forced_command);
441 	CLEAR_ON_NONE(options->chroot_directory);
442 	CLEAR_ON_NONE(options->routing_domain);
443 	CLEAR_ON_NONE(options->host_key_agent);
444 	for (i = 0; i < options->num_host_key_files; i++)
445 		CLEAR_ON_NONE(options->host_key_files[i]);
446 	for (i = 0; i < options->num_host_cert_files; i++)
447 		CLEAR_ON_NONE(options->host_cert_files[i]);
448 #undef CLEAR_ON_NONE
449 
450 	/* Similar handling for AuthenticationMethods=any */
451 	if (options->num_auth_methods == 1 &&
452 	    strcmp(options->auth_methods[0], "any") == 0) {
453 		free(options->auth_methods[0]);
454 		options->auth_methods[0] = NULL;
455 		options->num_auth_methods = 0;
456 	}
457 }
458 
459 /* Keyword tokens. */
460 typedef enum {
461 	sBadOption,		/* == unknown option */
462 	sPort, sHostKeyFile, sLoginGraceTime,
463 	sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
464 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
465 	sKerberosGetAFSToken, sPasswordAuthentication,
466 	sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
467 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
468 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
469 	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
470 	sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
471 	sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
472 	sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, sModuliFile,
473 	sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedAlgorithms,
474 	sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
475 	sBanner, sUseDNS, sHostbasedAuthentication,
476 	sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms,
477 	sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
478 	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
479 	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
480 	sAcceptEnv, sSetEnv, sPermitTunnel,
481 	sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
482 	sUsePrivilegeSeparation, sAllowAgentForwarding,
483 	sHostCertificate, sInclude,
484 	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
485 	sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
486 	sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
487 	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
488 	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
489 	sStreamLocalBindMask, sStreamLocalBindUnlink,
490 	sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
491 	sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
492 	sDeprecated, sIgnore, sUnsupported
493 } ServerOpCodes;
494 
495 #define SSHCFG_GLOBAL		0x01	/* allowed in main section of config */
496 #define SSHCFG_MATCH		0x02	/* allowed inside a Match section */
497 #define SSHCFG_ALL		(SSHCFG_GLOBAL|SSHCFG_MATCH)
498 #define SSHCFG_NEVERMATCH	0x04  /* Match never matches; internal only */
499 #define SSHCFG_MATCH_ONLY	0x08  /* Match only in conditional blocks; internal only */
500 
501 /* Textual representation of the tokens. */
502 static struct {
503 	const char *name;
504 	ServerOpCodes opcode;
505 	u_int flags;
506 } keywords[] = {
507 	{ "port", sPort, SSHCFG_GLOBAL },
508 	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
509 	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },		/* alias */
510 	{ "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
511 	{ "pidfile", sPidFile, SSHCFG_GLOBAL },
512 	{ "modulifile", sModuliFile, SSHCFG_GLOBAL },
513 	{ "serverkeybits", sDeprecated, SSHCFG_GLOBAL },
514 	{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
515 	{ "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
516 	{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
517 	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
518 	{ "loglevel", sLogLevel, SSHCFG_ALL },
519 	{ "logverbose", sLogVerbose, SSHCFG_ALL },
520 	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
521 	{ "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
522 	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
523 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
524 	{ "hostbasedacceptedalgorithms", sHostbasedAcceptedAlgorithms, SSHCFG_ALL },
525 	{ "hostbasedacceptedkeytypes", sHostbasedAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
526 	{ "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
527 	{ "rsaauthentication", sDeprecated, SSHCFG_ALL },
528 	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
529 	{ "pubkeyacceptedalgorithms", sPubkeyAcceptedAlgorithms, SSHCFG_ALL },
530 	{ "pubkeyacceptedkeytypes", sPubkeyAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
531 	{ "pubkeyauthoptions", sPubkeyAuthOptions, SSHCFG_ALL },
532 	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
533 #ifdef KRB5
534 	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
535 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
536 	{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
537 	{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
538 #else
539 	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
540 	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
541 	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
542 	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
543 #endif
544 	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
545 	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
546 #ifdef GSSAPI
547 	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
548 	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
549 	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
550 #else
551 	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
552 	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
553 	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
554 #endif
555 	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
556 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
557 	{ "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
558 	{ "skeyauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
559 	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
560 	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
561 	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
562 	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
563 	{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
564 	{ "ignorerhosts", sIgnoreRhosts, SSHCFG_ALL },
565 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
566 	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
567 	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
568 	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
569 	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
570 	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
571 	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
572 	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
573 	{ "uselogin", sDeprecated, SSHCFG_GLOBAL },
574 	{ "compression", sCompression, SSHCFG_GLOBAL },
575 	{ "rekeylimit", sRekeyLimit, SSHCFG_ALL },
576 	{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
577 	{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },	/* obsolete alias */
578 	{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
579 	{ "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
580 	{ "allowusers", sAllowUsers, SSHCFG_ALL },
581 	{ "denyusers", sDenyUsers, SSHCFG_ALL },
582 	{ "allowgroups", sAllowGroups, SSHCFG_ALL },
583 	{ "denygroups", sDenyGroups, SSHCFG_ALL },
584 	{ "ciphers", sCiphers, SSHCFG_GLOBAL },
585 	{ "macs", sMacs, SSHCFG_GLOBAL },
586 	{ "protocol", sIgnore, SSHCFG_GLOBAL },
587 	{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
588 	{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
589 	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
590 	{ "persourcemaxstartups", sPerSourceMaxStartups, SSHCFG_GLOBAL },
591 	{ "persourcenetblocksize", sPerSourceNetBlockSize, SSHCFG_GLOBAL },
592 	{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
593 	{ "maxsessions", sMaxSessions, SSHCFG_ALL },
594 	{ "banner", sBanner, SSHCFG_ALL },
595 	{ "usedns", sUseDNS, SSHCFG_GLOBAL },
596 	{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
597 	{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
598 	{ "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
599 	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
600 	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
601 	{ "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
602 	{ "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
603 	{ "acceptenv", sAcceptEnv, SSHCFG_ALL },
604 	{ "setenv", sSetEnv, SSHCFG_ALL },
605 	{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
606 	{ "permittty", sPermitTTY, SSHCFG_ALL },
607 	{ "permituserrc", sPermitUserRC, SSHCFG_ALL },
608 	{ "match", sMatch, SSHCFG_ALL },
609 	{ "permitopen", sPermitOpen, SSHCFG_ALL },
610 	{ "permitlisten", sPermitListen, SSHCFG_ALL },
611 	{ "forcecommand", sForceCommand, SSHCFG_ALL },
612 	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
613 	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
614 	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
615 	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
616 	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
617 	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
618 	{ "include", sInclude, SSHCFG_ALL },
619 	{ "ipqos", sIPQoS, SSHCFG_ALL },
620 	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
621 	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
622 	{ "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
623 	{ "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
624 	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
625 	{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
626 	{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
627 	{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
628 	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
629 	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
630 	{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
631 	{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
632 	{ "rdomain", sRDomain, SSHCFG_ALL },
633 	{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
634 	{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
635 	{ NULL, sBadOption, 0 }
636 };
637 
638 static struct {
639 	int val;
640 	char *text;
641 } tunmode_desc[] = {
642 	{ SSH_TUNMODE_NO, "no" },
643 	{ SSH_TUNMODE_POINTOPOINT, "point-to-point" },
644 	{ SSH_TUNMODE_ETHERNET, "ethernet" },
645 	{ SSH_TUNMODE_YES, "yes" },
646 	{ -1, NULL }
647 };
648 
649 /* Returns an opcode name from its number */
650 
651 static const char *
652 lookup_opcode_name(ServerOpCodes code)
653 {
654 	u_int i;
655 
656 	for (i = 0; keywords[i].name != NULL; i++)
657 		if (keywords[i].opcode == code)
658 			return(keywords[i].name);
659 	return "UNKNOWN";
660 }
661 
662 
663 /*
664  * Returns the number of the token pointed to by cp or sBadOption.
665  */
666 
667 static ServerOpCodes
668 parse_token(const char *cp, const char *filename,
669 	    int linenum, u_int *flags)
670 {
671 	u_int i;
672 
673 	for (i = 0; keywords[i].name; i++)
674 		if (strcasecmp(cp, keywords[i].name) == 0) {
675 			*flags = keywords[i].flags;
676 			return keywords[i].opcode;
677 		}
678 
679 	error("%s: line %d: Bad configuration option: %s",
680 	    filename, linenum, cp);
681 	return sBadOption;
682 }
683 
684 char *
685 derelativise_path(const char *path)
686 {
687 	char *expanded, *ret, cwd[PATH_MAX];
688 
689 	if (strcasecmp(path, "none") == 0)
690 		return xstrdup("none");
691 	expanded = tilde_expand_filename(path, getuid());
692 	if (path_absolute(expanded))
693 		return expanded;
694 	if (getcwd(cwd, sizeof(cwd)) == NULL)
695 		fatal_f("getcwd: %s", strerror(errno));
696 	xasprintf(&ret, "%s/%s", cwd, expanded);
697 	free(expanded);
698 	return ret;
699 }
700 
701 static void
702 add_listen_addr(ServerOptions *options, const char *addr,
703     const char *rdomain, int port)
704 {
705 	u_int i;
706 
707 	if (port > 0)
708 		add_one_listen_addr(options, addr, rdomain, port);
709 	else {
710 		for (i = 0; i < options->num_ports; i++) {
711 			add_one_listen_addr(options, addr, rdomain,
712 			    options->ports[i]);
713 		}
714 	}
715 }
716 
717 static void
718 add_one_listen_addr(ServerOptions *options, const char *addr,
719     const char *rdomain, int port)
720 {
721 	struct addrinfo hints, *ai, *aitop;
722 	char strport[NI_MAXSERV];
723 	int gaierr;
724 	u_int i;
725 
726 	/* Find listen_addrs entry for this rdomain */
727 	for (i = 0; i < options->num_listen_addrs; i++) {
728 		if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
729 			break;
730 		if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
731 			continue;
732 		if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
733 			break;
734 	}
735 	if (i >= options->num_listen_addrs) {
736 		/* No entry for this rdomain; allocate one */
737 		if (i >= INT_MAX)
738 			fatal_f("too many listen addresses");
739 		options->listen_addrs = xrecallocarray(options->listen_addrs,
740 		    options->num_listen_addrs, options->num_listen_addrs + 1,
741 		    sizeof(*options->listen_addrs));
742 		i = options->num_listen_addrs++;
743 		if (rdomain != NULL)
744 			options->listen_addrs[i].rdomain = xstrdup(rdomain);
745 	}
746 	/* options->listen_addrs[i] points to the addresses for this rdomain */
747 
748 	memset(&hints, 0, sizeof(hints));
749 	hints.ai_family = options->address_family;
750 	hints.ai_socktype = SOCK_STREAM;
751 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
752 	snprintf(strport, sizeof strport, "%d", port);
753 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
754 		fatal("bad addr or host: %s (%s)",
755 		    addr ? addr : "<NULL>",
756 		    ssh_gai_strerror(gaierr));
757 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
758 		;
759 	ai->ai_next = options->listen_addrs[i].addrs;
760 	options->listen_addrs[i].addrs = aitop;
761 }
762 
763 /* Returns nonzero if the routing domain name is valid */
764 static int
765 valid_rdomain(const char *name)
766 {
767 	const char *errstr;
768 	long long num;
769 	struct rt_tableinfo info;
770 	int mib[6];
771 	size_t miblen = sizeof(mib);
772 
773 	if (name == NULL)
774 		return 1;
775 
776 	num = strtonum(name, 0, 255, &errstr);
777 	if (errstr != NULL)
778 		return 0;
779 
780 	/* Check whether the table actually exists */
781 	memset(mib, 0, sizeof(mib));
782 	mib[0] = CTL_NET;
783 	mib[1] = PF_ROUTE;
784 	mib[4] = NET_RT_TABLE;
785 	mib[5] = (int)num;
786 	if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
787 		return 0;
788 
789 	return 1;
790 }
791 
792 /*
793  * Queue a ListenAddress to be processed once we have all of the Ports
794  * and AddressFamily options.
795  */
796 static void
797 queue_listen_addr(ServerOptions *options, const char *addr,
798     const char *rdomain, int port)
799 {
800 	struct queued_listenaddr *qla;
801 
802 	options->queued_listen_addrs = xrecallocarray(
803 	    options->queued_listen_addrs,
804 	    options->num_queued_listens, options->num_queued_listens + 1,
805 	    sizeof(*options->queued_listen_addrs));
806 	qla = &options->queued_listen_addrs[options->num_queued_listens++];
807 	qla->addr = xstrdup(addr);
808 	qla->port = port;
809 	qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
810 }
811 
812 /*
813  * Process queued (text) ListenAddress entries.
814  */
815 static void
816 process_queued_listen_addrs(ServerOptions *options)
817 {
818 	u_int i;
819 	struct queued_listenaddr *qla;
820 
821 	if (options->num_ports == 0)
822 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
823 	if (options->address_family == -1)
824 		options->address_family = AF_UNSPEC;
825 
826 	for (i = 0; i < options->num_queued_listens; i++) {
827 		qla = &options->queued_listen_addrs[i];
828 		add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
829 		free(qla->addr);
830 		free(qla->rdomain);
831 	}
832 	free(options->queued_listen_addrs);
833 	options->queued_listen_addrs = NULL;
834 	options->num_queued_listens = 0;
835 }
836 
837 /*
838  * Inform channels layer of permitopen options for a single forwarding
839  * direction (local/remote).
840  */
841 static void
842 process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
843     char **opens, u_int num_opens)
844 {
845 	u_int i;
846 	int port;
847 	char *host, *arg, *oarg;
848 	int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
849 	const char *what = lookup_opcode_name(opcode);
850 
851 	channel_clear_permission(ssh, FORWARD_ADM, where);
852 	if (num_opens == 0)
853 		return; /* permit any */
854 
855 	/* handle keywords: "any" / "none" */
856 	if (num_opens == 1 && strcmp(opens[0], "any") == 0)
857 		return;
858 	if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
859 		channel_disable_admin(ssh, where);
860 		return;
861 	}
862 	/* Otherwise treat it as a list of permitted host:port */
863 	for (i = 0; i < num_opens; i++) {
864 		oarg = arg = xstrdup(opens[i]);
865 		host = hpdelim(&arg);
866 		if (host == NULL)
867 			fatal_f("missing host in %s", what);
868 		host = cleanhostname(host);
869 		if (arg == NULL || ((port = permitopen_port(arg)) < 0))
870 			fatal_f("bad port number in %s", what);
871 		/* Send it to channels layer */
872 		channel_add_permission(ssh, FORWARD_ADM,
873 		    where, host, port);
874 		free(oarg);
875 	}
876 }
877 
878 /*
879  * Inform channels layer of permitopen options from configuration.
880  */
881 void
882 process_permitopen(struct ssh *ssh, ServerOptions *options)
883 {
884 	process_permitopen_list(ssh, sPermitOpen,
885 	    options->permitted_opens, options->num_permitted_opens);
886 	process_permitopen_list(ssh, sPermitListen,
887 	    options->permitted_listens,
888 	    options->num_permitted_listens);
889 }
890 
891 struct connection_info *
892 get_connection_info(struct ssh *ssh, int populate, int use_dns)
893 {
894 	static struct connection_info ci;
895 
896 	if (ssh == NULL || !populate)
897 		return &ci;
898 	ci.host = auth_get_canonical_hostname(ssh, use_dns);
899 	ci.address = ssh_remote_ipaddr(ssh);
900 	ci.laddress = ssh_local_ipaddr(ssh);
901 	ci.lport = ssh_local_port(ssh);
902 	ci.rdomain = ssh_packet_rdomain_in(ssh);
903 	return &ci;
904 }
905 
906 /*
907  * The strategy for the Match blocks is that the config file is parsed twice.
908  *
909  * The first time is at startup.  activep is initialized to 1 and the
910  * directives in the global context are processed and acted on.  Hitting a
911  * Match directive unsets activep and the directives inside the block are
912  * checked for syntax only.
913  *
914  * The second time is after a connection has been established but before
915  * authentication.  activep is initialized to 2 and global config directives
916  * are ignored since they have already been processed.  If the criteria in a
917  * Match block is met, activep is set and the subsequent directives
918  * processed and actioned until EOF or another Match block unsets it.  Any
919  * options set are copied into the main server config.
920  *
921  * Potential additions/improvements:
922  *  - Add Match support for pre-kex directives, eg. Ciphers.
923  *
924  *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
925  *	Match Address 192.168.0.*
926  *		Tag trusted
927  *	Match Group wheel
928  *		Tag trusted
929  *	Match Tag trusted
930  *		AllowTcpForwarding yes
931  *		GatewayPorts clientspecified
932  *		[...]
933  *
934  *  - Add a PermittedChannelRequests directive
935  *	Match Group shell
936  *		PermittedChannelRequests session,forwarded-tcpip
937  */
938 
939 static int
940 match_cfg_line_group(const char *grps, int line, const char *user)
941 {
942 	int result = 0;
943 	struct passwd *pw;
944 
945 	if (user == NULL)
946 		goto out;
947 
948 	if ((pw = getpwnam(user)) == NULL) {
949 		debug("Can't match group at line %d because user %.100s does "
950 		    "not exist", line, user);
951 	} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
952 		debug("Can't Match group because user %.100s not in any group "
953 		    "at line %d", user, line);
954 	} else if (ga_match_pattern_list(grps) != 1) {
955 		debug("user %.100s does not match group list %.100s at line %d",
956 		    user, grps, line);
957 	} else {
958 		debug("user %.100s matched group list %.100s at line %d", user,
959 		    grps, line);
960 		result = 1;
961 	}
962 out:
963 	ga_free();
964 	return result;
965 }
966 
967 static void
968 match_test_missing_fatal(const char *criteria, const char *attrib)
969 {
970 	fatal("'Match %s' in configuration but '%s' not in connection "
971 	    "test specification.", criteria, attrib);
972 }
973 
974 /*
975  * All of the attributes on a single Match line are ANDed together, so we need
976  * to check every attribute and set the result to zero if any attribute does
977  * not match.
978  */
979 static int
980 match_cfg_line(char **condition, int line, struct connection_info *ci)
981 {
982 	int result = 1, attributes = 0, port;
983 	char *arg, *attrib, *cp = *condition;
984 
985 	if (ci == NULL)
986 		debug3("checking syntax for 'Match %s'", cp);
987 	else
988 		debug3("checking match for '%s' user %s host %s addr %s "
989 		    "laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
990 		    ci->host ? ci->host : "(null)",
991 		    ci->address ? ci->address : "(null)",
992 		    ci->laddress ? ci->laddress : "(null)", ci->lport);
993 
994 	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
995 		/* Terminate on comment */
996 		if (*attrib == '#') {
997 			cp = NULL; /* mark all arguments consumed */
998 			break;
999 		}
1000 		arg = NULL;
1001 		attributes++;
1002 		/* Criterion "all" has no argument and must appear alone */
1003 		if (strcasecmp(attrib, "all") == 0) {
1004 			if (attributes > 1 || ((arg = strdelim(&cp)) != NULL &&
1005 			    *arg != '\0' && *arg != '#')) {
1006 				error("'all' cannot be combined with other "
1007 				    "Match attributes");
1008 				return -1;
1009 			}
1010 			if (arg != NULL && *arg == '#')
1011 				cp = NULL; /* mark all arguments consumed */
1012 			*condition = cp;
1013 			return 1;
1014 		}
1015 		/* All other criteria require an argument */
1016 		if ((arg = strdelim(&cp)) == NULL ||
1017 		    *arg == '\0' || *arg == '#') {
1018 			error("Missing Match criteria for %s", attrib);
1019 			return -1;
1020 		}
1021 		if (strcasecmp(attrib, "user") == 0) {
1022 			if (ci == NULL || (ci->test && ci->user == NULL)) {
1023 				result = 0;
1024 				continue;
1025 			}
1026 			if (ci->user == NULL)
1027 				match_test_missing_fatal("User", "user");
1028 			if (match_usergroup_pattern_list(ci->user, arg) != 1)
1029 				result = 0;
1030 			else
1031 				debug("user %.100s matched 'User %.100s' at "
1032 				    "line %d", ci->user, arg, line);
1033 		} else if (strcasecmp(attrib, "group") == 0) {
1034 			if (ci == NULL || (ci->test && ci->user == NULL)) {
1035 				result = 0;
1036 				continue;
1037 			}
1038 			if (ci->user == NULL)
1039 				match_test_missing_fatal("Group", "user");
1040 			switch (match_cfg_line_group(arg, line, ci->user)) {
1041 			case -1:
1042 				return -1;
1043 			case 0:
1044 				result = 0;
1045 			}
1046 		} else if (strcasecmp(attrib, "host") == 0) {
1047 			if (ci == NULL || (ci->test && ci->host == NULL)) {
1048 				result = 0;
1049 				continue;
1050 			}
1051 			if (ci->host == NULL)
1052 				match_test_missing_fatal("Host", "host");
1053 			if (match_hostname(ci->host, arg) != 1)
1054 				result = 0;
1055 			else
1056 				debug("connection from %.100s matched 'Host "
1057 				    "%.100s' at line %d", ci->host, arg, line);
1058 		} else if (strcasecmp(attrib, "address") == 0) {
1059 			if (ci == NULL || (ci->test && ci->address == NULL)) {
1060 				if (addr_match_list(NULL, arg) != 0)
1061 					fatal("Invalid Match address argument "
1062 					    "'%s' at line %d", arg, line);
1063 				result = 0;
1064 				continue;
1065 			}
1066 			if (ci->address == NULL)
1067 				match_test_missing_fatal("Address", "addr");
1068 			switch (addr_match_list(ci->address, arg)) {
1069 			case 1:
1070 				debug("connection from %.100s matched 'Address "
1071 				    "%.100s' at line %d", ci->address, arg, line);
1072 				break;
1073 			case 0:
1074 			case -1:
1075 				result = 0;
1076 				break;
1077 			case -2:
1078 				return -1;
1079 			}
1080 		} else if (strcasecmp(attrib, "localaddress") == 0){
1081 			if (ci == NULL || (ci->test && ci->laddress == NULL)) {
1082 				if (addr_match_list(NULL, arg) != 0)
1083 					fatal("Invalid Match localaddress "
1084 					    "argument '%s' at line %d", arg,
1085 					    line);
1086 				result = 0;
1087 				continue;
1088 			}
1089 			if (ci->laddress == NULL)
1090 				match_test_missing_fatal("LocalAddress",
1091 				    "laddr");
1092 			switch (addr_match_list(ci->laddress, arg)) {
1093 			case 1:
1094 				debug("connection from %.100s matched "
1095 				    "'LocalAddress %.100s' at line %d",
1096 				    ci->laddress, arg, line);
1097 				break;
1098 			case 0:
1099 			case -1:
1100 				result = 0;
1101 				break;
1102 			case -2:
1103 				return -1;
1104 			}
1105 		} else if (strcasecmp(attrib, "localport") == 0) {
1106 			if ((port = a2port(arg)) == -1) {
1107 				error("Invalid LocalPort '%s' on Match line",
1108 				    arg);
1109 				return -1;
1110 			}
1111 			if (ci == NULL || (ci->test && ci->lport == -1)) {
1112 				result = 0;
1113 				continue;
1114 			}
1115 			if (ci->lport == 0)
1116 				match_test_missing_fatal("LocalPort", "lport");
1117 			/* TODO support port lists */
1118 			if (port == ci->lport)
1119 				debug("connection from %.100s matched "
1120 				    "'LocalPort %d' at line %d",
1121 				    ci->laddress, port, line);
1122 			else
1123 				result = 0;
1124 		} else if (strcasecmp(attrib, "rdomain") == 0) {
1125 			if (ci == NULL || (ci->test && ci->rdomain == NULL)) {
1126 				result = 0;
1127 				continue;
1128 			}
1129 			if (ci->rdomain == NULL)
1130 				match_test_missing_fatal("RDomain", "rdomain");
1131 			if (match_pattern_list(ci->rdomain, arg, 0) != 1)
1132 				result = 0;
1133 			else
1134 				debug("user %.100s matched 'RDomain %.100s' at "
1135 				    "line %d", ci->rdomain, arg, line);
1136 		} else {
1137 			error("Unsupported Match attribute %s", attrib);
1138 			return -1;
1139 		}
1140 	}
1141 	if (attributes == 0) {
1142 		error("One or more attributes required for Match");
1143 		return -1;
1144 	}
1145 	if (ci != NULL)
1146 		debug3("match %sfound", result ? "" : "not ");
1147 	*condition = cp;
1148 	return result;
1149 }
1150 
1151 #define WHITESPACE " \t\r\n"
1152 
1153 /* Multistate option parsing */
1154 struct multistate {
1155 	char *key;
1156 	int value;
1157 };
1158 static const struct multistate multistate_flag[] = {
1159 	{ "yes",			1 },
1160 	{ "no",				0 },
1161 	{ NULL, -1 }
1162 };
1163 static const struct multistate multistate_ignore_rhosts[] = {
1164 	{ "yes",			IGNORE_RHOSTS_YES },
1165 	{ "no",				IGNORE_RHOSTS_NO },
1166 	{ "shosts-only",		IGNORE_RHOSTS_SHOSTS },
1167 	{ NULL, -1 }
1168 };
1169 static const struct multistate multistate_addressfamily[] = {
1170 	{ "inet",			AF_INET },
1171 	{ "inet6",			AF_INET6 },
1172 	{ "any",			AF_UNSPEC },
1173 	{ NULL, -1 }
1174 };
1175 static const struct multistate multistate_permitrootlogin[] = {
1176 	{ "without-password",		PERMIT_NO_PASSWD },
1177 	{ "prohibit-password",		PERMIT_NO_PASSWD },
1178 	{ "forced-commands-only",	PERMIT_FORCED_ONLY },
1179 	{ "yes",			PERMIT_YES },
1180 	{ "no",				PERMIT_NO },
1181 	{ NULL, -1 }
1182 };
1183 static const struct multistate multistate_compression[] = {
1184 #ifdef WITH_ZLIB
1185 	{ "yes",			COMP_DELAYED },
1186 	{ "delayed",			COMP_DELAYED },
1187 #endif
1188 	{ "no",				COMP_NONE },
1189 	{ NULL, -1 }
1190 };
1191 static const struct multistate multistate_gatewayports[] = {
1192 	{ "clientspecified",		2 },
1193 	{ "yes",			1 },
1194 	{ "no",				0 },
1195 	{ NULL, -1 }
1196 };
1197 static const struct multistate multistate_tcpfwd[] = {
1198 	{ "yes",			FORWARD_ALLOW },
1199 	{ "all",			FORWARD_ALLOW },
1200 	{ "no",				FORWARD_DENY },
1201 	{ "remote",			FORWARD_REMOTE },
1202 	{ "local",			FORWARD_LOCAL },
1203 	{ NULL, -1 }
1204 };
1205 
1206 static int
1207 process_server_config_line_depth(ServerOptions *options, char *line,
1208     const char *filename, int linenum, int *activep,
1209     struct connection_info *connectinfo, int *inc_flags, int depth,
1210     struct include_list *includes)
1211 {
1212 	char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword;
1213 	int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found;
1214 	SyslogFacility *log_facility_ptr;
1215 	LogLevel *log_level_ptr;
1216 	ServerOpCodes opcode;
1217 	u_int i, *uintptr, uvalue, flags = 0;
1218 	size_t len;
1219 	long long val64;
1220 	const struct multistate *multistate_ptr;
1221 	const char *errstr;
1222 	struct include_item *item;
1223 	glob_t gbuf;
1224 	char **oav = NULL, **av;
1225 	int oac = 0, ac;
1226 	int ret = -1;
1227 
1228 	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1229 	if ((len = strlen(line)) == 0)
1230 		return 0;
1231 	for (len--; len > 0; len--) {
1232 		if (strchr(WHITESPACE "\f", line[len]) == NULL)
1233 			break;
1234 		line[len] = '\0';
1235 	}
1236 
1237 	str = line;
1238 	if ((keyword = strdelim(&str)) == NULL)
1239 		return 0;
1240 	/* Ignore leading whitespace */
1241 	if (*keyword == '\0')
1242 		keyword = strdelim(&str);
1243 	if (!keyword || !*keyword || *keyword == '#')
1244 		return 0;
1245 	if (str == NULL || *str == '\0') {
1246 		error("%s line %d: no argument after keyword \"%s\"",
1247 		    filename, linenum, keyword);
1248 		return -1;
1249 	}
1250 	intptr = NULL;
1251 	charptr = NULL;
1252 	opcode = parse_token(keyword, filename, linenum, &flags);
1253 
1254 	if (argv_split(str, &oac, &oav, 1) != 0) {
1255 		error("%s line %d: invalid quotes", filename, linenum);
1256 		return -1;
1257 	}
1258 	ac = oac;
1259 	av = oav;
1260 
1261 	if (activep == NULL) { /* We are processing a command line directive */
1262 		cmdline = 1;
1263 		activep = &cmdline;
1264 	}
1265 	if (*activep && opcode != sMatch && opcode != sInclude)
1266 		debug3("%s:%d setting %s %s", filename, linenum, keyword, str);
1267 	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1268 		if (connectinfo == NULL) {
1269 			fatal("%s line %d: Directive '%s' is not allowed "
1270 			    "within a Match block", filename, linenum, keyword);
1271 		} else { /* this is a directive we have already processed */
1272 			ret = 0;
1273 			goto out;
1274 		}
1275 	}
1276 
1277 	switch (opcode) {
1278 	case sBadOption:
1279 		goto out;
1280 	case sPort:
1281 		/* ignore ports from configfile if cmdline specifies ports */
1282 		if (options->ports_from_cmdline) {
1283 			argv_consume(&ac);
1284 			break;
1285 		}
1286 		if (options->num_ports >= MAX_PORTS)
1287 			fatal("%s line %d: too many ports.",
1288 			    filename, linenum);
1289 		arg = argv_next(&ac, &av);
1290 		if (!arg || *arg == '\0')
1291 			fatal("%s line %d: missing port number.",
1292 			    filename, linenum);
1293 		options->ports[options->num_ports++] = a2port(arg);
1294 		if (options->ports[options->num_ports-1] <= 0)
1295 			fatal("%s line %d: Badly formatted port number.",
1296 			    filename, linenum);
1297 		break;
1298 
1299 	case sLoginGraceTime:
1300 		intptr = &options->login_grace_time;
1301  parse_time:
1302 		arg = argv_next(&ac, &av);
1303 		if (!arg || *arg == '\0')
1304 			fatal("%s line %d: missing time value.",
1305 			    filename, linenum);
1306 		if ((value = convtime(arg)) == -1)
1307 			fatal("%s line %d: invalid time value.",
1308 			    filename, linenum);
1309 		if (*activep && *intptr == -1)
1310 			*intptr = value;
1311 		break;
1312 
1313 	case sListenAddress:
1314 		arg = argv_next(&ac, &av);
1315 		if (arg == NULL || *arg == '\0')
1316 			fatal("%s line %d: missing address",
1317 			    filename, linenum);
1318 		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
1319 		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1320 		    && strchr(p+1, ':') != NULL) {
1321 			port = 0;
1322 			p = arg;
1323 		} else {
1324 			arg2 = NULL;
1325 			p = hpdelim(&arg);
1326 			if (p == NULL)
1327 				fatal("%s line %d: bad address:port usage",
1328 				    filename, linenum);
1329 			p = cleanhostname(p);
1330 			if (arg == NULL)
1331 				port = 0;
1332 			else if ((port = a2port(arg)) <= 0)
1333 				fatal("%s line %d: bad port number",
1334 				    filename, linenum);
1335 		}
1336 		/* Optional routing table */
1337 		arg2 = NULL;
1338 		if ((arg = argv_next(&ac, &av)) != NULL) {
1339 			if (strcmp(arg, "rdomain") != 0 ||
1340 			    (arg2 = argv_next(&ac, &av)) == NULL)
1341 				fatal("%s line %d: bad ListenAddress syntax",
1342 				    filename, linenum);
1343 			if (!valid_rdomain(arg2))
1344 				fatal("%s line %d: bad routing domain",
1345 				    filename, linenum);
1346 		}
1347 		queue_listen_addr(options, p, arg2, port);
1348 
1349 		break;
1350 
1351 	case sAddressFamily:
1352 		intptr = &options->address_family;
1353 		multistate_ptr = multistate_addressfamily;
1354  parse_multistate:
1355 		arg = argv_next(&ac, &av);
1356 		if (!arg || *arg == '\0')
1357 			fatal("%s line %d: missing argument.",
1358 			    filename, linenum);
1359 		value = -1;
1360 		for (i = 0; multistate_ptr[i].key != NULL; i++) {
1361 			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1362 				value = multistate_ptr[i].value;
1363 				break;
1364 			}
1365 		}
1366 		if (value == -1)
1367 			fatal("%s line %d: unsupported option \"%s\".",
1368 			    filename, linenum, arg);
1369 		if (*activep && *intptr == -1)
1370 			*intptr = value;
1371 		break;
1372 
1373 	case sHostKeyFile:
1374 		arg = argv_next(&ac, &av);
1375 		if (!arg || *arg == '\0')
1376 			fatal("%s line %d: missing file name.",
1377 			    filename, linenum);
1378 		if (*activep) {
1379 			servconf_add_hostkey(filename, linenum,
1380 			    options, arg, 1);
1381 		}
1382 		break;
1383 
1384 	case sHostKeyAgent:
1385 		charptr = &options->host_key_agent;
1386 		arg = argv_next(&ac, &av);
1387 		if (!arg || *arg == '\0')
1388 			fatal("%s line %d: missing socket name.",
1389 			    filename, linenum);
1390 		if (*activep && *charptr == NULL)
1391 			*charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
1392 			    xstrdup(arg) : derelativise_path(arg);
1393 		break;
1394 
1395 	case sHostCertificate:
1396 		arg = argv_next(&ac, &av);
1397 		if (!arg || *arg == '\0')
1398 			fatal("%s line %d: missing file name.",
1399 			    filename, linenum);
1400 		if (*activep)
1401 			servconf_add_hostcert(filename, linenum, options, arg);
1402 		break;
1403 
1404 	case sPidFile:
1405 		charptr = &options->pid_file;
1406  parse_filename:
1407 		arg = argv_next(&ac, &av);
1408 		if (!arg || *arg == '\0')
1409 			fatal("%s line %d: missing file name.",
1410 			    filename, linenum);
1411 		if (*activep && *charptr == NULL) {
1412 			*charptr = derelativise_path(arg);
1413 			/* increase optional counter */
1414 			if (intptr != NULL)
1415 				*intptr = *intptr + 1;
1416 		}
1417 		break;
1418 
1419 	case sModuliFile:
1420 		charptr = &options->moduli_file;
1421 		goto parse_filename;
1422 
1423 	case sPermitRootLogin:
1424 		intptr = &options->permit_root_login;
1425 		multistate_ptr = multistate_permitrootlogin;
1426 		goto parse_multistate;
1427 
1428 	case sIgnoreRhosts:
1429 		intptr = &options->ignore_rhosts;
1430 		multistate_ptr = multistate_ignore_rhosts;
1431 		goto parse_multistate;
1432 
1433 	case sIgnoreUserKnownHosts:
1434 		intptr = &options->ignore_user_known_hosts;
1435  parse_flag:
1436 		multistate_ptr = multistate_flag;
1437 		goto parse_multistate;
1438 
1439 	case sHostbasedAuthentication:
1440 		intptr = &options->hostbased_authentication;
1441 		goto parse_flag;
1442 
1443 	case sHostbasedUsesNameFromPacketOnly:
1444 		intptr = &options->hostbased_uses_name_from_packet_only;
1445 		goto parse_flag;
1446 
1447 	case sHostbasedAcceptedAlgorithms:
1448 		charptr = &options->hostbased_accepted_algos;
1449  parse_pubkey_algos:
1450 		arg = argv_next(&ac, &av);
1451 		if (!arg || *arg == '\0')
1452 			fatal("%s line %d: Missing argument.",
1453 			    filename, linenum);
1454 		if (*arg != '-' &&
1455 		    !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
1456 		    arg + 1 : arg, 1))
1457 			fatal("%s line %d: Bad key types '%s'.",
1458 			    filename, linenum, arg ? arg : "<NONE>");
1459 		if (*activep && *charptr == NULL)
1460 			*charptr = xstrdup(arg);
1461 		break;
1462 
1463 	case sHostKeyAlgorithms:
1464 		charptr = &options->hostkeyalgorithms;
1465 		goto parse_pubkey_algos;
1466 
1467 	case sCASignatureAlgorithms:
1468 		charptr = &options->ca_sign_algorithms;
1469 		goto parse_pubkey_algos;
1470 
1471 	case sPubkeyAuthentication:
1472 		intptr = &options->pubkey_authentication;
1473 		goto parse_flag;
1474 
1475 	case sPubkeyAcceptedAlgorithms:
1476 		charptr = &options->pubkey_accepted_algos;
1477 		goto parse_pubkey_algos;
1478 
1479 	case sPubkeyAuthOptions:
1480 		intptr = &options->pubkey_auth_options;
1481 		value = 0;
1482 		while ((arg = argv_next(&ac, &av)) != NULL) {
1483 			if (strcasecmp(arg, "none") == 0)
1484 				continue;
1485 			if (strcasecmp(arg, "touch-required") == 0)
1486 				value |= PUBKEYAUTH_TOUCH_REQUIRED;
1487 			else if (strcasecmp(arg, "verify-required") == 0)
1488 				value |= PUBKEYAUTH_VERIFY_REQUIRED;
1489 			else {
1490 				error("%s line %d: unsupported %s option %s",
1491 				    filename, linenum, keyword, arg);
1492 				goto out;
1493 			}
1494 		}
1495 		if (*activep && *intptr == -1)
1496 			*intptr = value;
1497 		break;
1498 
1499 	case sKerberosAuthentication:
1500 		intptr = &options->kerberos_authentication;
1501 		goto parse_flag;
1502 
1503 	case sKerberosOrLocalPasswd:
1504 		intptr = &options->kerberos_or_local_passwd;
1505 		goto parse_flag;
1506 
1507 	case sKerberosTicketCleanup:
1508 		intptr = &options->kerberos_ticket_cleanup;
1509 		goto parse_flag;
1510 
1511 	case sKerberosGetAFSToken:
1512 		intptr = &options->kerberos_get_afs_token;
1513 		goto parse_flag;
1514 
1515 	case sGssAuthentication:
1516 		intptr = &options->gss_authentication;
1517 		goto parse_flag;
1518 
1519 	case sGssCleanupCreds:
1520 		intptr = &options->gss_cleanup_creds;
1521 		goto parse_flag;
1522 
1523 	case sGssStrictAcceptor:
1524 		intptr = &options->gss_strict_acceptor;
1525 		goto parse_flag;
1526 
1527 	case sPasswordAuthentication:
1528 		intptr = &options->password_authentication;
1529 		goto parse_flag;
1530 
1531 	case sKbdInteractiveAuthentication:
1532 		intptr = &options->kbd_interactive_authentication;
1533 		goto parse_flag;
1534 
1535 	case sPrintMotd:
1536 		intptr = &options->print_motd;
1537 		goto parse_flag;
1538 
1539 	case sPrintLastLog:
1540 		intptr = &options->print_lastlog;
1541 		goto parse_flag;
1542 
1543 	case sX11Forwarding:
1544 		intptr = &options->x11_forwarding;
1545 		goto parse_flag;
1546 
1547 	case sX11DisplayOffset:
1548 		intptr = &options->x11_display_offset;
1549  parse_int:
1550 		arg = argv_next(&ac, &av);
1551 		if ((errstr = atoi_err(arg, &value)) != NULL)
1552 			fatal("%s line %d: %s integer value %s.",
1553 			    filename, linenum, keyword, errstr);
1554 		if (*activep && *intptr == -1)
1555 			*intptr = value;
1556 		break;
1557 
1558 	case sX11UseLocalhost:
1559 		intptr = &options->x11_use_localhost;
1560 		goto parse_flag;
1561 
1562 	case sXAuthLocation:
1563 		charptr = &options->xauth_location;
1564 		goto parse_filename;
1565 
1566 	case sPermitTTY:
1567 		intptr = &options->permit_tty;
1568 		goto parse_flag;
1569 
1570 	case sPermitUserRC:
1571 		intptr = &options->permit_user_rc;
1572 		goto parse_flag;
1573 
1574 	case sStrictModes:
1575 		intptr = &options->strict_modes;
1576 		goto parse_flag;
1577 
1578 	case sTCPKeepAlive:
1579 		intptr = &options->tcp_keep_alive;
1580 		goto parse_flag;
1581 
1582 	case sEmptyPasswd:
1583 		intptr = &options->permit_empty_passwd;
1584 		goto parse_flag;
1585 
1586 	case sPermitUserEnvironment:
1587 		intptr = &options->permit_user_env;
1588 		charptr = &options->permit_user_env_allowlist;
1589 		arg = argv_next(&ac, &av);
1590 		if (!arg || *arg == '\0')
1591 			fatal("%s line %d: %s missing argument.",
1592 			    filename, linenum, keyword);
1593 		value = 0;
1594 		p = NULL;
1595 		if (strcmp(arg, "yes") == 0)
1596 			value = 1;
1597 		else if (strcmp(arg, "no") == 0)
1598 			value = 0;
1599 		else {
1600 			/* Pattern-list specified */
1601 			value = 1;
1602 			p = xstrdup(arg);
1603 		}
1604 		if (*activep && *intptr == -1) {
1605 			*intptr = value;
1606 			*charptr = p;
1607 			p = NULL;
1608 		}
1609 		free(p);
1610 		break;
1611 
1612 	case sCompression:
1613 		intptr = &options->compression;
1614 		multistate_ptr = multistate_compression;
1615 		goto parse_multistate;
1616 
1617 	case sRekeyLimit:
1618 		arg = argv_next(&ac, &av);
1619 		if (!arg || *arg == '\0')
1620 			fatal("%s line %d: %s missing argument.",
1621 			    filename, linenum, keyword);
1622 		if (strcmp(arg, "default") == 0) {
1623 			val64 = 0;
1624 		} else {
1625 			if (scan_scaled(arg, &val64) == -1)
1626 				fatal("%.200s line %d: Bad %s number '%s': %s",
1627 				    filename, linenum, keyword,
1628 				    arg, strerror(errno));
1629 			if (val64 != 0 && val64 < 16)
1630 				fatal("%.200s line %d: %s too small",
1631 				    filename, linenum, keyword);
1632 		}
1633 		if (*activep && options->rekey_limit == -1)
1634 			options->rekey_limit = val64;
1635 		if (ac != 0) { /* optional rekey interval present */
1636 			if (strcmp(av[0], "none") == 0) {
1637 				(void)argv_next(&ac, &av);	/* discard */
1638 				break;
1639 			}
1640 			intptr = &options->rekey_interval;
1641 			goto parse_time;
1642 		}
1643 		break;
1644 
1645 	case sGatewayPorts:
1646 		intptr = &options->fwd_opts.gateway_ports;
1647 		multistate_ptr = multistate_gatewayports;
1648 		goto parse_multistate;
1649 
1650 	case sUseDNS:
1651 		intptr = &options->use_dns;
1652 		goto parse_flag;
1653 
1654 	case sLogFacility:
1655 		log_facility_ptr = &options->log_facility;
1656 		arg = argv_next(&ac, &av);
1657 		value = log_facility_number(arg);
1658 		if (value == SYSLOG_FACILITY_NOT_SET)
1659 			fatal("%.200s line %d: unsupported log facility '%s'",
1660 			    filename, linenum, arg ? arg : "<NONE>");
1661 		if (*log_facility_ptr == -1)
1662 			*log_facility_ptr = (SyslogFacility) value;
1663 		break;
1664 
1665 	case sLogLevel:
1666 		log_level_ptr = &options->log_level;
1667 		arg = argv_next(&ac, &av);
1668 		value = log_level_number(arg);
1669 		if (value == SYSLOG_LEVEL_NOT_SET)
1670 			fatal("%.200s line %d: unsupported log level '%s'",
1671 			    filename, linenum, arg ? arg : "<NONE>");
1672 		if (*activep && *log_level_ptr == -1)
1673 			*log_level_ptr = (LogLevel) value;
1674 		break;
1675 
1676 	case sLogVerbose:
1677 		found = options->num_log_verbose == 0;
1678 		i = 0;
1679 		while ((arg = argv_next(&ac, &av)) != NULL) {
1680 			if (*arg == '\0') {
1681 				error("%s line %d: keyword %s empty argument",
1682 				    filename, linenum, keyword);
1683 				goto out;
1684 			}
1685 			/* Allow "none" only in first position */
1686 			if (strcasecmp(arg, "none") == 0) {
1687 				if (i > 0 || ac > 0) {
1688 					error("%s line %d: keyword %s \"none\" "
1689 					    "argument must appear alone.",
1690 					    filename, linenum, keyword);
1691 					goto out;
1692 				}
1693 			}
1694 			i++;
1695 			if (!found || !*activep)
1696 				continue;
1697 			opt_array_append(filename, linenum, keyword,
1698 			    &options->log_verbose, &options->num_log_verbose,
1699 			    arg);
1700 		}
1701 		break;
1702 
1703 	case sAllowTcpForwarding:
1704 		intptr = &options->allow_tcp_forwarding;
1705 		multistate_ptr = multistate_tcpfwd;
1706 		goto parse_multistate;
1707 
1708 	case sAllowStreamLocalForwarding:
1709 		intptr = &options->allow_streamlocal_forwarding;
1710 		multistate_ptr = multistate_tcpfwd;
1711 		goto parse_multistate;
1712 
1713 	case sAllowAgentForwarding:
1714 		intptr = &options->allow_agent_forwarding;
1715 		goto parse_flag;
1716 
1717 	case sDisableForwarding:
1718 		intptr = &options->disable_forwarding;
1719 		goto parse_flag;
1720 
1721 	case sAllowUsers:
1722 		chararrayptr = &options->allow_users;
1723 		uintptr = &options->num_allow_users;
1724  parse_allowdenyusers:
1725 		while ((arg = argv_next(&ac, &av)) != NULL) {
1726 			if (*arg == '\0' ||
1727 			    match_user(NULL, NULL, NULL, arg) == -1)
1728 				fatal("%s line %d: invalid %s pattern: \"%s\"",
1729 				    filename, linenum, keyword, arg);
1730 			if (!*activep)
1731 				continue;
1732 			opt_array_append(filename, linenum, keyword,
1733 			    chararrayptr, uintptr, arg);
1734 		}
1735 		break;
1736 
1737 	case sDenyUsers:
1738 		chararrayptr = &options->deny_users;
1739 		uintptr = &options->num_deny_users;
1740 		goto parse_allowdenyusers;
1741 
1742 	case sAllowGroups:
1743 		chararrayptr = &options->allow_groups;
1744 		uintptr = &options->num_allow_groups;
1745  parse_allowdenygroups:
1746 		while ((arg = argv_next(&ac, &av)) != NULL) {
1747 			if (*arg == '\0')
1748 				fatal("%s line %d: empty %s pattern",
1749 				    filename, linenum, keyword);
1750 			if (!*activep)
1751 				continue;
1752 			opt_array_append(filename, linenum, keyword,
1753 			    chararrayptr, uintptr, arg);
1754 		}
1755 		break;
1756 
1757 	case sDenyGroups:
1758 		chararrayptr = &options->deny_groups;
1759 		uintptr = &options->num_deny_groups;
1760 		goto parse_allowdenygroups;
1761 
1762 	case sCiphers:
1763 		arg = argv_next(&ac, &av);
1764 		if (!arg || *arg == '\0')
1765 			fatal("%s line %d: %s missing argument.",
1766 			    filename, linenum, keyword);
1767 		if (*arg != '-' &&
1768 		    !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1769 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1770 			    filename, linenum, arg ? arg : "<NONE>");
1771 		if (options->ciphers == NULL)
1772 			options->ciphers = xstrdup(arg);
1773 		break;
1774 
1775 	case sMacs:
1776 		arg = argv_next(&ac, &av);
1777 		if (!arg || *arg == '\0')
1778 			fatal("%s line %d: %s missing argument.",
1779 			    filename, linenum, keyword);
1780 		if (*arg != '-' &&
1781 		    !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1782 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1783 			    filename, linenum, arg ? arg : "<NONE>");
1784 		if (options->macs == NULL)
1785 			options->macs = xstrdup(arg);
1786 		break;
1787 
1788 	case sKexAlgorithms:
1789 		arg = argv_next(&ac, &av);
1790 		if (!arg || *arg == '\0')
1791 			fatal("%s line %d: %s missing argument.",
1792 			    filename, linenum, keyword);
1793 		if (*arg != '-' &&
1794 		    !kex_names_valid(*arg == '+' || *arg == '^' ?
1795 		    arg + 1 : arg))
1796 			fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1797 			    filename, linenum, arg ? arg : "<NONE>");
1798 		if (options->kex_algorithms == NULL)
1799 			options->kex_algorithms = xstrdup(arg);
1800 		break;
1801 
1802 	case sSubsystem:
1803 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1804 			fatal("%s line %d: too many subsystems defined.",
1805 			    filename, linenum);
1806 		}
1807 		arg = argv_next(&ac, &av);
1808 		if (!arg || *arg == '\0')
1809 			fatal("%s line %d: %s missing argument.",
1810 			    filename, linenum, keyword);
1811 		if (!*activep) {
1812 			arg = argv_next(&ac, &av);
1813 			break;
1814 		}
1815 		for (i = 0; i < options->num_subsystems; i++)
1816 			if (strcmp(arg, options->subsystem_name[i]) == 0)
1817 				fatal("%s line %d: Subsystem '%s' "
1818 				    "already defined.", filename, linenum, arg);
1819 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1820 		arg = argv_next(&ac, &av);
1821 		if (!arg || *arg == '\0')
1822 			fatal("%s line %d: Missing subsystem command.",
1823 			    filename, linenum);
1824 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1825 
1826 		/* Collect arguments (separate to executable) */
1827 		p = xstrdup(arg);
1828 		len = strlen(p) + 1;
1829 		while ((arg = argv_next(&ac, &av)) != NULL) {
1830 			len += 1 + strlen(arg);
1831 			p = xreallocarray(p, 1, len);
1832 			strlcat(p, " ", len);
1833 			strlcat(p, arg, len);
1834 		}
1835 		options->subsystem_args[options->num_subsystems] = p;
1836 		options->num_subsystems++;
1837 		break;
1838 
1839 	case sMaxStartups:
1840 		arg = argv_next(&ac, &av);
1841 		if (!arg || *arg == '\0')
1842 			fatal("%s line %d: %s missing argument.",
1843 			    filename, linenum, keyword);
1844 		if ((n = sscanf(arg, "%d:%d:%d",
1845 		    &options->max_startups_begin,
1846 		    &options->max_startups_rate,
1847 		    &options->max_startups)) == 3) {
1848 			if (options->max_startups_begin >
1849 			    options->max_startups ||
1850 			    options->max_startups_rate > 100 ||
1851 			    options->max_startups_rate < 1)
1852 				fatal("%s line %d: Invalid %s spec.",
1853 				    filename, linenum, keyword);
1854 		} else if (n != 1)
1855 			fatal("%s line %d: Invalid %s spec.",
1856 			    filename, linenum, keyword);
1857 		else
1858 			options->max_startups = options->max_startups_begin;
1859 		break;
1860 
1861 	case sPerSourceNetBlockSize:
1862 		arg = argv_next(&ac, &av);
1863 		if (!arg || *arg == '\0')
1864 			fatal("%s line %d: %s missing argument.",
1865 			    filename, linenum, keyword);
1866 		switch (n = sscanf(arg, "%d:%d", &value, &value2)) {
1867 		case 2:
1868 			if (value2 < 0 || value2 > 128)
1869 				n = -1;
1870 			/* FALLTHROUGH */
1871 		case 1:
1872 			if (value < 0 || value > 32)
1873 				n = -1;
1874 		}
1875 		if (n != 1 && n != 2)
1876 			fatal("%s line %d: Invalid %s spec.",
1877 			    filename, linenum, keyword);
1878 		if (*activep) {
1879 			options->per_source_masklen_ipv4 = value;
1880 			options->per_source_masklen_ipv6 = value2;
1881 		}
1882 		break;
1883 
1884 	case sPerSourceMaxStartups:
1885 		arg = argv_next(&ac, &av);
1886 		if (!arg || *arg == '\0')
1887 			fatal("%s line %d: %s missing argument.",
1888 			    filename, linenum, keyword);
1889 		if (strcmp(arg, "none") == 0) { /* no limit */
1890 			value = INT_MAX;
1891 		} else {
1892 			if ((errstr = atoi_err(arg, &value)) != NULL)
1893 				fatal("%s line %d: %s integer value %s.",
1894 				    filename, linenum, keyword, errstr);
1895 		}
1896 		if (*activep)
1897 			options->per_source_max_startups = value;
1898 		break;
1899 
1900 	case sMaxAuthTries:
1901 		intptr = &options->max_authtries;
1902 		goto parse_int;
1903 
1904 	case sMaxSessions:
1905 		intptr = &options->max_sessions;
1906 		goto parse_int;
1907 
1908 	case sBanner:
1909 		charptr = &options->banner;
1910 		goto parse_filename;
1911 
1912 	/*
1913 	 * These options can contain %X options expanded at
1914 	 * connect time, so that you can specify paths like:
1915 	 *
1916 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
1917 	 */
1918 	case sAuthorizedKeysFile:
1919 		uvalue = options->num_authkeys_files;
1920 		while ((arg = argv_next(&ac, &av)) != NULL) {
1921 			if (*arg == '\0') {
1922 				error("%s line %d: keyword %s empty argument",
1923 				    filename, linenum, keyword);
1924 				goto out;
1925 			}
1926 			arg2 = tilde_expand_filename(arg, getuid());
1927 			if (*activep && uvalue == 0) {
1928 				opt_array_append(filename, linenum, keyword,
1929 				    &options->authorized_keys_files,
1930 				    &options->num_authkeys_files, arg2);
1931 			}
1932 			free(arg2);
1933 		}
1934 		break;
1935 
1936 	case sAuthorizedPrincipalsFile:
1937 		charptr = &options->authorized_principals_file;
1938 		arg = argv_next(&ac, &av);
1939 		if (!arg || *arg == '\0')
1940 			fatal("%s line %d: %s missing argument.",
1941 			    filename, linenum, keyword);
1942 		if (*activep && *charptr == NULL) {
1943 			*charptr = tilde_expand_filename(arg, getuid());
1944 			/* increase optional counter */
1945 			if (intptr != NULL)
1946 				*intptr = *intptr + 1;
1947 		}
1948 		break;
1949 
1950 	case sClientAliveInterval:
1951 		intptr = &options->client_alive_interval;
1952 		goto parse_time;
1953 
1954 	case sClientAliveCountMax:
1955 		intptr = &options->client_alive_count_max;
1956 		goto parse_int;
1957 
1958 	case sAcceptEnv:
1959 		while ((arg = argv_next(&ac, &av)) != NULL) {
1960 			if (*arg == '\0' || strchr(arg, '=') != NULL)
1961 				fatal("%s line %d: Invalid environment name.",
1962 				    filename, linenum);
1963 			if (!*activep)
1964 				continue;
1965 			opt_array_append(filename, linenum, keyword,
1966 			    &options->accept_env, &options->num_accept_env,
1967 			    arg);
1968 		}
1969 		break;
1970 
1971 	case sSetEnv:
1972 		uvalue = options->num_setenv;
1973 		while ((arg = argv_next(&ac, &av)) != NULL) {
1974 			if (*arg == '\0' || strchr(arg, '=') == NULL)
1975 				fatal("%s line %d: Invalid environment.",
1976 				    filename, linenum);
1977 			if (!*activep || uvalue != 0)
1978 				continue;
1979 			if (lookup_setenv_in_list(arg, options->setenv,
1980 			    options->num_setenv) != NULL) {
1981 				debug2("%s line %d: ignoring duplicate env "
1982 				    "name \"%.64s\"", filename, linenum, arg);
1983 				continue;
1984 			}
1985 			opt_array_append(filename, linenum, keyword,
1986 			    &options->setenv, &options->num_setenv, arg);
1987 		}
1988 		break;
1989 
1990 	case sPermitTunnel:
1991 		intptr = &options->permit_tun;
1992 		arg = argv_next(&ac, &av);
1993 		if (!arg || *arg == '\0')
1994 			fatal("%s line %d: %s missing argument.",
1995 			    filename, linenum, keyword);
1996 		value = -1;
1997 		for (i = 0; tunmode_desc[i].val != -1; i++)
1998 			if (strcmp(tunmode_desc[i].text, arg) == 0) {
1999 				value = tunmode_desc[i].val;
2000 				break;
2001 			}
2002 		if (value == -1)
2003 			fatal("%s line %d: bad %s argument %s",
2004 			    filename, linenum, keyword, arg);
2005 		if (*activep && *intptr == -1)
2006 			*intptr = value;
2007 		break;
2008 
2009 	case sInclude:
2010 		if (cmdline) {
2011 			fatal("Include directive not supported as a "
2012 			    "command-line option");
2013 		}
2014 		value = 0;
2015 		while ((arg2 = argv_next(&ac, &av)) != NULL) {
2016 			if (*arg2 == '\0') {
2017 				error("%s line %d: keyword %s empty argument",
2018 				    filename, linenum, keyword);
2019 				goto out;
2020 			}
2021 			value++;
2022 			found = 0;
2023 			if (*arg2 != '/' && *arg2 != '~') {
2024 				xasprintf(&arg, "%s/%s", SSHDIR, arg2);
2025 			} else
2026 				arg = xstrdup(arg2);
2027 
2028 			/*
2029 			 * Don't let included files clobber the containing
2030 			 * file's Match state.
2031 			 */
2032 			oactive = *activep;
2033 
2034 			/* consult cache of include files */
2035 			TAILQ_FOREACH(item, includes, entry) {
2036 				if (strcmp(item->selector, arg) != 0)
2037 					continue;
2038 				if (item->filename != NULL) {
2039 					parse_server_config_depth(options,
2040 					    item->filename, item->contents,
2041 					    includes, connectinfo,
2042 					    (*inc_flags & SSHCFG_MATCH_ONLY
2043 					        ? SSHCFG_MATCH_ONLY : (oactive
2044 					            ? 0 : SSHCFG_NEVERMATCH)),
2045 					    activep, depth + 1);
2046 				}
2047 				found = 1;
2048 				*activep = oactive;
2049 			}
2050 			if (found != 0) {
2051 				free(arg);
2052 				continue;
2053 			}
2054 
2055 			/* requested glob was not in cache */
2056 			debug2("%s line %d: new include %s",
2057 			    filename, linenum, arg);
2058 			if ((r = glob(arg, 0, NULL, &gbuf)) != 0) {
2059 				if (r != GLOB_NOMATCH) {
2060 					fatal("%s line %d: include \"%s\" glob "
2061 					    "failed", filename, linenum, arg);
2062 				}
2063 				/*
2064 				 * If no entry matched then record a
2065 				 * placeholder to skip later glob calls.
2066 				 */
2067 				debug2("%s line %d: no match for %s",
2068 				    filename, linenum, arg);
2069 				item = xcalloc(1, sizeof(*item));
2070 				item->selector = strdup(arg);
2071 				TAILQ_INSERT_TAIL(includes,
2072 				    item, entry);
2073 			}
2074 			if (gbuf.gl_pathc > INT_MAX)
2075 				fatal_f("too many glob results");
2076 			for (n = 0; n < (int)gbuf.gl_pathc; n++) {
2077 				debug2("%s line %d: including %s",
2078 				    filename, linenum, gbuf.gl_pathv[n]);
2079 				item = xcalloc(1, sizeof(*item));
2080 				item->selector = strdup(arg);
2081 				item->filename = strdup(gbuf.gl_pathv[n]);
2082 				if ((item->contents = sshbuf_new()) == NULL)
2083 					fatal_f("sshbuf_new failed");
2084 				load_server_config(item->filename,
2085 				    item->contents);
2086 				parse_server_config_depth(options,
2087 				    item->filename, item->contents,
2088 				    includes, connectinfo,
2089 				    (*inc_flags & SSHCFG_MATCH_ONLY
2090 				        ? SSHCFG_MATCH_ONLY : (oactive
2091 				            ? 0 : SSHCFG_NEVERMATCH)),
2092 				    activep, depth + 1);
2093 				*activep = oactive;
2094 				TAILQ_INSERT_TAIL(includes, item, entry);
2095 			}
2096 			globfree(&gbuf);
2097 			free(arg);
2098 		}
2099 		if (value == 0) {
2100 			fatal("%s line %d: %s missing filename argument",
2101 			    filename, linenum, keyword);
2102 		}
2103 		break;
2104 
2105 	case sMatch:
2106 		if (cmdline)
2107 			fatal("Match directive not supported as a command-line "
2108 			    "option");
2109 		value = match_cfg_line(&str, linenum,
2110 		    (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
2111 		if (value < 0)
2112 			fatal("%s line %d: Bad Match condition", filename,
2113 			    linenum);
2114 		*activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
2115 		/*
2116 		 * The MATCH_ONLY flag is applicable only until the first
2117 		 * match block.
2118 		 */
2119 		*inc_flags &= ~SSHCFG_MATCH_ONLY;
2120 		/*
2121 		 * If match_cfg_line() didn't consume all its arguments then
2122 		 * arrange for the extra arguments check below to fail.
2123 		 */
2124 		if (str == NULL || *str == '\0')
2125 			argv_consume(&ac);
2126 		break;
2127 
2128 	case sPermitListen:
2129 	case sPermitOpen:
2130 		if (opcode == sPermitListen) {
2131 			uintptr = &options->num_permitted_listens;
2132 			chararrayptr = &options->permitted_listens;
2133 		} else {
2134 			uintptr = &options->num_permitted_opens;
2135 			chararrayptr = &options->permitted_opens;
2136 		}
2137 		arg = argv_next(&ac, &av);
2138 		if (!arg || *arg == '\0')
2139 			fatal("%s line %d: %s missing argument.",
2140 			    filename, linenum, keyword);
2141 		uvalue = *uintptr;	/* modified later */
2142 		if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
2143 			if (*activep && uvalue == 0) {
2144 				*uintptr = 1;
2145 				*chararrayptr = xcalloc(1,
2146 				    sizeof(**chararrayptr));
2147 				(*chararrayptr)[0] = xstrdup(arg);
2148 			}
2149 			break;
2150 		}
2151 		for (; arg != NULL && *arg != '\0'; arg = argv_next(&ac, &av)) {
2152 			if (opcode == sPermitListen &&
2153 			    strchr(arg, ':') == NULL) {
2154 				/*
2155 				 * Allow bare port number for PermitListen
2156 				 * to indicate a wildcard listen host.
2157 				 */
2158 				xasprintf(&arg2, "*:%s", arg);
2159 			} else {
2160 				arg2 = xstrdup(arg);
2161 				p = hpdelim(&arg);
2162 				if (p == NULL) {
2163 					fatal("%s line %d: %s missing host",
2164 					    filename, linenum, keyword);
2165 				}
2166 				p = cleanhostname(p);
2167 			}
2168 			if (arg == NULL ||
2169 			    ((port = permitopen_port(arg)) < 0)) {
2170 				fatal("%s line %d: %s bad port number",
2171 				    filename, linenum, keyword);
2172 			}
2173 			if (*activep && uvalue == 0) {
2174 				opt_array_append(filename, linenum, keyword,
2175 				    chararrayptr, uintptr, arg2);
2176 			}
2177 			free(arg2);
2178 		}
2179 		break;
2180 
2181 	case sForceCommand:
2182 		if (str == NULL || *str == '\0')
2183 			fatal("%s line %d: %s missing argument.",
2184 			    filename, linenum, keyword);
2185 		len = strspn(str, WHITESPACE);
2186 		if (*activep && options->adm_forced_command == NULL)
2187 			options->adm_forced_command = xstrdup(str + len);
2188 		argv_consume(&ac);
2189 		break;
2190 
2191 	case sChrootDirectory:
2192 		charptr = &options->chroot_directory;
2193 
2194 		arg = argv_next(&ac, &av);
2195 		if (!arg || *arg == '\0')
2196 			fatal("%s line %d: %s missing argument.",
2197 			    filename, linenum, keyword);
2198 		if (*activep && *charptr == NULL)
2199 			*charptr = xstrdup(arg);
2200 		break;
2201 
2202 	case sTrustedUserCAKeys:
2203 		charptr = &options->trusted_user_ca_keys;
2204 		goto parse_filename;
2205 
2206 	case sRevokedKeys:
2207 		charptr = &options->revoked_keys_file;
2208 		goto parse_filename;
2209 
2210 	case sSecurityKeyProvider:
2211 		charptr = &options->sk_provider;
2212 		arg = argv_next(&ac, &av);
2213 		if (!arg || *arg == '\0')
2214 			fatal("%s line %d: %s missing argument.",
2215 			    filename, linenum, keyword);
2216 		if (*activep && *charptr == NULL) {
2217 			*charptr = strcasecmp(arg, "internal") == 0 ?
2218 			    xstrdup(arg) : derelativise_path(arg);
2219 			/* increase optional counter */
2220 			if (intptr != NULL)
2221 				*intptr = *intptr + 1;
2222 		}
2223 		break;
2224 
2225 	case sIPQoS:
2226 		arg = argv_next(&ac, &av);
2227 		if (!arg || *arg == '\0')
2228 			fatal("%s line %d: %s missing argument.",
2229 			    filename, linenum, keyword);
2230 		if ((value = parse_ipqos(arg)) == -1)
2231 			fatal("%s line %d: Bad %s value: %s",
2232 			    filename, linenum, keyword, arg);
2233 		arg = argv_next(&ac, &av);
2234 		if (arg == NULL)
2235 			value2 = value;
2236 		else if ((value2 = parse_ipqos(arg)) == -1)
2237 			fatal("%s line %d: Bad %s value: %s",
2238 			    filename, linenum, keyword, arg);
2239 		if (*activep) {
2240 			options->ip_qos_interactive = value;
2241 			options->ip_qos_bulk = value2;
2242 		}
2243 		break;
2244 
2245 	case sVersionAddendum:
2246 		if (str == NULL || *str == '\0')
2247 			fatal("%s line %d: %s missing argument.",
2248 			    filename, linenum, keyword);
2249 		len = strspn(str, WHITESPACE);
2250 		if (strchr(str + len, '\r') != NULL) {
2251 			fatal("%.200s line %d: Invalid %s argument",
2252 			    filename, linenum, keyword);
2253 		}
2254 		if ((arg = strchr(line, '#')) != NULL) {
2255 			*arg = '\0';
2256 			rtrim(line);
2257 		}
2258 		if (*activep && options->version_addendum == NULL) {
2259 			if (strcasecmp(str + len, "none") == 0)
2260 				options->version_addendum = xstrdup("");
2261 			else
2262 				options->version_addendum = xstrdup(str + len);
2263 		}
2264 		argv_consume(&ac);
2265 		break;
2266 
2267 	case sAuthorizedKeysCommand:
2268 		charptr = &options->authorized_keys_command;
2269  parse_command:
2270 		len = strspn(str, WHITESPACE);
2271 		if (str[len] != '/' && strcasecmp(str + len, "none") != 0) {
2272 			fatal("%.200s line %d: %s must be an absolute path",
2273 			    filename, linenum, keyword);
2274 		}
2275 		if (*activep && options->authorized_keys_command == NULL)
2276 			*charptr = xstrdup(str + len);
2277 		argv_consume(&ac);
2278 		break;
2279 
2280 	case sAuthorizedKeysCommandUser:
2281 		charptr = &options->authorized_keys_command_user;
2282  parse_localuser:
2283 		arg = argv_next(&ac, &av);
2284 		if (!arg || *arg == '\0') {
2285 			fatal("%s line %d: missing %s argument.",
2286 			    filename, linenum, keyword);
2287 		}
2288 		if (*activep && *charptr == NULL)
2289 			*charptr = xstrdup(arg);
2290 		break;
2291 
2292 	case sAuthorizedPrincipalsCommand:
2293 		charptr = &options->authorized_principals_command;
2294 		goto parse_command;
2295 
2296 	case sAuthorizedPrincipalsCommandUser:
2297 		charptr = &options->authorized_principals_command_user;
2298 		goto parse_localuser;
2299 
2300 	case sAuthenticationMethods:
2301 		found = options->num_auth_methods == 0;
2302 		value = 0; /* seen "any" pseudo-method */
2303 		value2 = 0; /* successfully parsed any method */
2304 		while ((arg = argv_next(&ac, &av)) != NULL) {
2305 			if (strcmp(arg, "any") == 0) {
2306 				if (options->num_auth_methods > 0) {
2307 					fatal("%s line %d: \"any\" must "
2308 					    "appear alone in %s",
2309 					    filename, linenum, keyword);
2310 				}
2311 				value = 1;
2312 			} else if (value) {
2313 				fatal("%s line %d: \"any\" must appear "
2314 				    "alone in %s", filename, linenum, keyword);
2315 			} else if (auth2_methods_valid(arg, 0) != 0) {
2316 				fatal("%s line %d: invalid %s method list.",
2317 				    filename, linenum, keyword);
2318 			}
2319 			value2 = 1;
2320 			if (!found || !*activep)
2321 				continue;
2322 			opt_array_append(filename, linenum, keyword,
2323 			    &options->auth_methods,
2324 			    &options->num_auth_methods, arg);
2325 		}
2326 		if (value2 == 0) {
2327 			fatal("%s line %d: no %s specified",
2328 			    filename, linenum, keyword);
2329 		}
2330 		break;
2331 
2332 	case sStreamLocalBindMask:
2333 		arg = argv_next(&ac, &av);
2334 		if (!arg || *arg == '\0')
2335 			fatal("%s line %d: %s missing argument.",
2336 			    filename, linenum, keyword);
2337 		/* Parse mode in octal format */
2338 		value = strtol(arg, &p, 8);
2339 		if (arg == p || value < 0 || value > 0777)
2340 			fatal("%s line %d: Invalid %s.",
2341 			    filename, linenum, keyword);
2342 		if (*activep)
2343 			options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
2344 		break;
2345 
2346 	case sStreamLocalBindUnlink:
2347 		intptr = &options->fwd_opts.streamlocal_bind_unlink;
2348 		goto parse_flag;
2349 
2350 	case sFingerprintHash:
2351 		arg = argv_next(&ac, &av);
2352 		if (!arg || *arg == '\0')
2353 			fatal("%s line %d: %s missing argument.",
2354 			    filename, linenum, keyword);
2355 		if ((value = ssh_digest_alg_by_name(arg)) == -1)
2356 			fatal("%.200s line %d: Invalid %s algorithm \"%s\".",
2357 			    filename, linenum, keyword, arg);
2358 		if (*activep)
2359 			options->fingerprint_hash = value;
2360 		break;
2361 
2362 	case sExposeAuthInfo:
2363 		intptr = &options->expose_userauth_info;
2364 		goto parse_flag;
2365 
2366 	case sRDomain:
2367 		charptr = &options->routing_domain;
2368 		arg = argv_next(&ac, &av);
2369 		if (!arg || *arg == '\0')
2370 			fatal("%s line %d: %s missing argument.",
2371 			    filename, linenum, keyword);
2372 		if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
2373 		    !valid_rdomain(arg))
2374 			fatal("%s line %d: invalid routing domain",
2375 			    filename, linenum);
2376 		if (*activep && *charptr == NULL)
2377 			*charptr = xstrdup(arg);
2378 		break;
2379 
2380 	case sDeprecated:
2381 	case sIgnore:
2382 	case sUnsupported:
2383 		do_log2(opcode == sIgnore ?
2384 		    SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
2385 		    "%s line %d: %s option %s", filename, linenum,
2386 		    opcode == sUnsupported ? "Unsupported" : "Deprecated",
2387 		    keyword);
2388 		argv_consume(&ac);
2389 		break;
2390 
2391 	default:
2392 		fatal("%s line %d: Missing handler for opcode %s (%d)",
2393 		    filename, linenum, keyword, opcode);
2394 	}
2395 	/* Check that there is no garbage at end of line. */
2396 	if (ac > 0) {
2397 		error("%.200s line %d: keyword %s extra arguments "
2398 		    "at end of line", filename, linenum, keyword);
2399 		goto out;
2400 	}
2401 
2402 	/* success */
2403 	ret = 0;
2404  out:
2405 	argv_free(oav, oac);
2406 	return ret;
2407 }
2408 
2409 int
2410 process_server_config_line(ServerOptions *options, char *line,
2411     const char *filename, int linenum, int *activep,
2412     struct connection_info *connectinfo, struct include_list *includes)
2413 {
2414 	int inc_flags = 0;
2415 
2416 	return process_server_config_line_depth(options, line, filename,
2417 	    linenum, activep, connectinfo, &inc_flags, 0, includes);
2418 }
2419 
2420 
2421 /* Reads the server configuration file. */
2422 
2423 void
2424 load_server_config(const char *filename, struct sshbuf *conf)
2425 {
2426 	struct stat st;
2427 	char *line = NULL, *cp;
2428 	size_t linesize = 0;
2429 	FILE *f;
2430 	int r, lineno = 0;
2431 
2432 	debug2_f("filename %s", filename);
2433 	if ((f = fopen(filename, "r")) == NULL) {
2434 		perror(filename);
2435 		exit(1);
2436 	}
2437 	sshbuf_reset(conf);
2438 	/* grow buffer, so realloc is avoided for large config files */
2439 	if (fstat(fileno(f), &st) == 0 && st.st_size > 0 &&
2440 	    (r = sshbuf_allocate(conf, st.st_size)) != 0)
2441 		fatal_fr(r, "allocate");
2442 	while (getline(&line, &linesize, f) != -1) {
2443 		lineno++;
2444 		/*
2445 		 * Strip whitespace
2446 		 * NB - preserve newlines, they are needed to reproduce
2447 		 * line numbers later for error messages
2448 		 */
2449 		cp = line + strspn(line, " \t\r");
2450 		if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
2451 			fatal_fr(r, "sshbuf_put");
2452 	}
2453 	free(line);
2454 	if ((r = sshbuf_put_u8(conf, 0)) != 0)
2455 		fatal_fr(r, "sshbuf_put_u8");
2456 	fclose(f);
2457 	debug2_f("done config len = %zu", sshbuf_len(conf));
2458 }
2459 
2460 void
2461 parse_server_match_config(ServerOptions *options,
2462    struct include_list *includes, struct connection_info *connectinfo)
2463 {
2464 	ServerOptions mo;
2465 
2466 	initialize_server_options(&mo);
2467 	parse_server_config(&mo, "reprocess config", cfg, includes,
2468 	    connectinfo, 0);
2469 	copy_set_server_options(options, &mo, 0);
2470 }
2471 
2472 int parse_server_match_testspec(struct connection_info *ci, char *spec)
2473 {
2474 	char *p;
2475 
2476 	while ((p = strsep(&spec, ",")) && *p != '\0') {
2477 		if (strncmp(p, "addr=", 5) == 0) {
2478 			ci->address = xstrdup(p + 5);
2479 		} else if (strncmp(p, "host=", 5) == 0) {
2480 			ci->host = xstrdup(p + 5);
2481 		} else if (strncmp(p, "user=", 5) == 0) {
2482 			ci->user = xstrdup(p + 5);
2483 		} else if (strncmp(p, "laddr=", 6) == 0) {
2484 			ci->laddress = xstrdup(p + 6);
2485 		} else if (strncmp(p, "rdomain=", 8) == 0) {
2486 			ci->rdomain = xstrdup(p + 8);
2487 		} else if (strncmp(p, "lport=", 6) == 0) {
2488 			ci->lport = a2port(p + 6);
2489 			if (ci->lport == -1) {
2490 				fprintf(stderr, "Invalid port '%s' in test mode"
2491 				    " specification %s\n", p+6, p);
2492 				return -1;
2493 			}
2494 		} else {
2495 			fprintf(stderr, "Invalid test mode specification %s\n",
2496 			    p);
2497 			return -1;
2498 		}
2499 	}
2500 	return 0;
2501 }
2502 
2503 /*
2504  * Copy any supported values that are set.
2505  *
2506  * If the preauth flag is set, we do not bother copying the string or
2507  * array values that are not used pre-authentication, because any that we
2508  * do use must be explicitly sent in mm_getpwnamallow().
2509  */
2510 void
2511 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2512 {
2513 #define M_CP_INTOPT(n) do {\
2514 	if (src->n != -1) \
2515 		dst->n = src->n; \
2516 } while (0)
2517 
2518 	M_CP_INTOPT(password_authentication);
2519 	M_CP_INTOPT(gss_authentication);
2520 	M_CP_INTOPT(pubkey_authentication);
2521 	M_CP_INTOPT(pubkey_auth_options);
2522 	M_CP_INTOPT(kerberos_authentication);
2523 	M_CP_INTOPT(hostbased_authentication);
2524 	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
2525 	M_CP_INTOPT(kbd_interactive_authentication);
2526 	M_CP_INTOPT(permit_root_login);
2527 	M_CP_INTOPT(permit_empty_passwd);
2528 	M_CP_INTOPT(ignore_rhosts);
2529 
2530 	M_CP_INTOPT(allow_tcp_forwarding);
2531 	M_CP_INTOPT(allow_streamlocal_forwarding);
2532 	M_CP_INTOPT(allow_agent_forwarding);
2533 	M_CP_INTOPT(disable_forwarding);
2534 	M_CP_INTOPT(expose_userauth_info);
2535 	M_CP_INTOPT(permit_tun);
2536 	M_CP_INTOPT(fwd_opts.gateway_ports);
2537 	M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
2538 	M_CP_INTOPT(x11_display_offset);
2539 	M_CP_INTOPT(x11_forwarding);
2540 	M_CP_INTOPT(x11_use_localhost);
2541 	M_CP_INTOPT(permit_tty);
2542 	M_CP_INTOPT(permit_user_rc);
2543 	M_CP_INTOPT(max_sessions);
2544 	M_CP_INTOPT(max_authtries);
2545 	M_CP_INTOPT(client_alive_count_max);
2546 	M_CP_INTOPT(client_alive_interval);
2547 	M_CP_INTOPT(ip_qos_interactive);
2548 	M_CP_INTOPT(ip_qos_bulk);
2549 	M_CP_INTOPT(rekey_limit);
2550 	M_CP_INTOPT(rekey_interval);
2551 	M_CP_INTOPT(log_level);
2552 
2553 	/*
2554 	 * The bind_mask is a mode_t that may be unsigned, so we can't use
2555 	 * M_CP_INTOPT - it does a signed comparison that causes compiler
2556 	 * warnings.
2557 	 */
2558 	if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
2559 		dst->fwd_opts.streamlocal_bind_mask =
2560 		    src->fwd_opts.streamlocal_bind_mask;
2561 	}
2562 
2563 	/* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
2564 #define M_CP_STROPT(n) do {\
2565 	if (src->n != NULL && dst->n != src->n) { \
2566 		free(dst->n); \
2567 		dst->n = src->n; \
2568 	} \
2569 } while(0)
2570 #define M_CP_STRARRAYOPT(s, num_s) do {\
2571 	u_int i; \
2572 	if (src->num_s != 0) { \
2573 		for (i = 0; i < dst->num_s; i++) \
2574 			free(dst->s[i]); \
2575 		free(dst->s); \
2576 		dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2577 		for (i = 0; i < src->num_s; i++) \
2578 			dst->s[i] = xstrdup(src->s[i]); \
2579 		dst->num_s = src->num_s; \
2580 	} \
2581 } while(0)
2582 
2583 	/* See comment in servconf.h */
2584 	COPY_MATCH_STRING_OPTS();
2585 
2586 	/* Arguments that accept '+...' need to be expanded */
2587 	assemble_algorithms(dst);
2588 
2589 	/*
2590 	 * The only things that should be below this point are string options
2591 	 * which are only used after authentication.
2592 	 */
2593 	if (preauth)
2594 		return;
2595 
2596 	/* These options may be "none" to clear a global setting */
2597 	M_CP_STROPT(adm_forced_command);
2598 	if (option_clear_or_none(dst->adm_forced_command)) {
2599 		free(dst->adm_forced_command);
2600 		dst->adm_forced_command = NULL;
2601 	}
2602 	M_CP_STROPT(chroot_directory);
2603 	if (option_clear_or_none(dst->chroot_directory)) {
2604 		free(dst->chroot_directory);
2605 		dst->chroot_directory = NULL;
2606 	}
2607 }
2608 
2609 #undef M_CP_INTOPT
2610 #undef M_CP_STROPT
2611 #undef M_CP_STRARRAYOPT
2612 
2613 #define SERVCONF_MAX_DEPTH	16
2614 static void
2615 parse_server_config_depth(ServerOptions *options, const char *filename,
2616     struct sshbuf *conf, struct include_list *includes,
2617     struct connection_info *connectinfo, int flags, int *activep, int depth)
2618 {
2619 	int linenum, bad_options = 0;
2620 	char *cp, *obuf, *cbuf;
2621 
2622 	if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
2623 		fatal("Too many recursive configuration includes");
2624 
2625 	debug2_f("config %s len %zu%s", filename, sshbuf_len(conf),
2626 	    (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : ""));
2627 
2628 	if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
2629 		fatal_f("sshbuf_dup_string failed");
2630 	linenum = 1;
2631 	while ((cp = strsep(&cbuf, "\n")) != NULL) {
2632 		if (process_server_config_line_depth(options, cp,
2633 		    filename, linenum++, activep, connectinfo, &flags,
2634 		    depth, includes) != 0)
2635 			bad_options++;
2636 	}
2637 	free(obuf);
2638 	if (bad_options > 0)
2639 		fatal("%s: terminating, %d bad configuration options",
2640 		    filename, bad_options);
2641 }
2642 
2643 void
2644 parse_server_config(ServerOptions *options, const char *filename,
2645     struct sshbuf *conf, struct include_list *includes,
2646     struct connection_info *connectinfo, int reexec)
2647 {
2648 	int active = connectinfo ? 0 : 1;
2649 	parse_server_config_depth(options, filename, conf, includes,
2650 	    connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0);
2651 	if (!reexec)
2652 		process_queued_listen_addrs(options);
2653 }
2654 
2655 static const char *
2656 fmt_multistate_int(int val, const struct multistate *m)
2657 {
2658 	u_int i;
2659 
2660 	for (i = 0; m[i].key != NULL; i++) {
2661 		if (m[i].value == val)
2662 			return m[i].key;
2663 	}
2664 	return "UNKNOWN";
2665 }
2666 
2667 static const char *
2668 fmt_intarg(ServerOpCodes code, int val)
2669 {
2670 	if (val == -1)
2671 		return "unset";
2672 	switch (code) {
2673 	case sAddressFamily:
2674 		return fmt_multistate_int(val, multistate_addressfamily);
2675 	case sPermitRootLogin:
2676 		return fmt_multistate_int(val, multistate_permitrootlogin);
2677 	case sGatewayPorts:
2678 		return fmt_multistate_int(val, multistate_gatewayports);
2679 	case sCompression:
2680 		return fmt_multistate_int(val, multistate_compression);
2681 	case sAllowTcpForwarding:
2682 		return fmt_multistate_int(val, multistate_tcpfwd);
2683 	case sAllowStreamLocalForwarding:
2684 		return fmt_multistate_int(val, multistate_tcpfwd);
2685 	case sIgnoreRhosts:
2686 		return fmt_multistate_int(val, multistate_ignore_rhosts);
2687 	case sFingerprintHash:
2688 		return ssh_digest_alg_name(val);
2689 	default:
2690 		switch (val) {
2691 		case 0:
2692 			return "no";
2693 		case 1:
2694 			return "yes";
2695 		default:
2696 			return "UNKNOWN";
2697 		}
2698 	}
2699 }
2700 
2701 static void
2702 dump_cfg_int(ServerOpCodes code, int val)
2703 {
2704 	printf("%s %d\n", lookup_opcode_name(code), val);
2705 }
2706 
2707 static void
2708 dump_cfg_oct(ServerOpCodes code, int val)
2709 {
2710 	printf("%s 0%o\n", lookup_opcode_name(code), val);
2711 }
2712 
2713 static void
2714 dump_cfg_fmtint(ServerOpCodes code, int val)
2715 {
2716 	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2717 }
2718 
2719 static void
2720 dump_cfg_string(ServerOpCodes code, const char *val)
2721 {
2722 	printf("%s %s\n", lookup_opcode_name(code),
2723 	    val == NULL ? "none" : val);
2724 }
2725 
2726 static void
2727 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
2728 {
2729 	u_int i;
2730 
2731 	for (i = 0; i < count; i++)
2732 		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2733 }
2734 
2735 static void
2736 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
2737 {
2738 	u_int i;
2739 
2740 	if (count <= 0 && code != sAuthenticationMethods)
2741 		return;
2742 	printf("%s", lookup_opcode_name(code));
2743 	for (i = 0; i < count; i++)
2744 		printf(" %s",  vals[i]);
2745 	if (code == sAuthenticationMethods && count == 0)
2746 		printf(" any");
2747 	printf("\n");
2748 }
2749 
2750 static char *
2751 format_listen_addrs(struct listenaddr *la)
2752 {
2753 	int r;
2754 	struct addrinfo *ai;
2755 	char addr[NI_MAXHOST], port[NI_MAXSERV];
2756 	char *laddr1 = xstrdup(""), *laddr2 = NULL;
2757 
2758 	/*
2759 	 * ListenAddress must be after Port.  add_one_listen_addr pushes
2760 	 * addresses onto a stack, so to maintain ordering we need to
2761 	 * print these in reverse order.
2762 	 */
2763 	for (ai = la->addrs; ai; ai = ai->ai_next) {
2764 		if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2765 		    sizeof(addr), port, sizeof(port),
2766 		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2767 			error("getnameinfo: %.100s", ssh_gai_strerror(r));
2768 			continue;
2769 		}
2770 		laddr2 = laddr1;
2771 		if (ai->ai_family == AF_INET6) {
2772 			xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
2773 			    addr, port,
2774 			    la->rdomain == NULL ? "" : " rdomain ",
2775 			    la->rdomain == NULL ? "" : la->rdomain,
2776 			    laddr2);
2777 		} else {
2778 			xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
2779 			    addr, port,
2780 			    la->rdomain == NULL ? "" : " rdomain ",
2781 			    la->rdomain == NULL ? "" : la->rdomain,
2782 			    laddr2);
2783 		}
2784 		free(laddr2);
2785 	}
2786 	return laddr1;
2787 }
2788 
2789 void
2790 dump_config(ServerOptions *o)
2791 {
2792 	char *s;
2793 	u_int i;
2794 
2795 	/* these are usually at the top of the config */
2796 	for (i = 0; i < o->num_ports; i++)
2797 		printf("port %d\n", o->ports[i]);
2798 	dump_cfg_fmtint(sAddressFamily, o->address_family);
2799 
2800 	for (i = 0; i < o->num_listen_addrs; i++) {
2801 		s = format_listen_addrs(&o->listen_addrs[i]);
2802 		printf("%s", s);
2803 		free(s);
2804 	}
2805 
2806 	/* integer arguments */
2807 	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
2808 	dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
2809 	dump_cfg_int(sMaxAuthTries, o->max_authtries);
2810 	dump_cfg_int(sMaxSessions, o->max_sessions);
2811 	dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
2812 	dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
2813 	dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
2814 
2815 	/* formatted integer arguments */
2816 	dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
2817 	dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
2818 	dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
2819 	dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
2820 	dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
2821 	    o->hostbased_uses_name_from_packet_only);
2822 	dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
2823 #ifdef KRB5
2824 	dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
2825 	dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
2826 	dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
2827 	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
2828 #endif
2829 #ifdef GSSAPI
2830 	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
2831 	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
2832 #endif
2833 	dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
2834 	dump_cfg_fmtint(sKbdInteractiveAuthentication,
2835 	    o->kbd_interactive_authentication);
2836 	dump_cfg_fmtint(sPrintMotd, o->print_motd);
2837 	dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
2838 	dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
2839 	dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
2840 	dump_cfg_fmtint(sPermitTTY, o->permit_tty);
2841 	dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
2842 	dump_cfg_fmtint(sStrictModes, o->strict_modes);
2843 	dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
2844 	dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
2845 	dump_cfg_fmtint(sCompression, o->compression);
2846 	dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
2847 	dump_cfg_fmtint(sUseDNS, o->use_dns);
2848 	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
2849 	dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
2850 	dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
2851 	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2852 	dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2853 	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2854 	dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
2855 
2856 	/* string arguments */
2857 	dump_cfg_string(sPidFile, o->pid_file);
2858 	dump_cfg_string(sModuliFile, o->moduli_file);
2859 	dump_cfg_string(sXAuthLocation, o->xauth_location);
2860 	dump_cfg_string(sCiphers, o->ciphers);
2861 	dump_cfg_string(sMacs, o->macs);
2862 	dump_cfg_string(sBanner, o->banner);
2863 	dump_cfg_string(sForceCommand, o->adm_forced_command);
2864 	dump_cfg_string(sChrootDirectory, o->chroot_directory);
2865 	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
2866 	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
2867 	dump_cfg_string(sSecurityKeyProvider, o->sk_provider);
2868 	dump_cfg_string(sAuthorizedPrincipalsFile,
2869 	    o->authorized_principals_file);
2870 	dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
2871 	    ? "none" : o->version_addendum);
2872 	dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
2873 	dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
2874 	dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
2875 	dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
2876 	dump_cfg_string(sHostKeyAgent, o->host_key_agent);
2877 	dump_cfg_string(sKexAlgorithms, o->kex_algorithms);
2878 	dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms);
2879 	dump_cfg_string(sHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
2880 	dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
2881 	dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
2882 	dump_cfg_string(sRDomain, o->routing_domain);
2883 
2884 	/* string arguments requiring a lookup */
2885 	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
2886 	dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
2887 
2888 	/* string array arguments */
2889 	dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
2890 	    o->authorized_keys_files);
2891 	dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
2892 	    o->host_key_files);
2893 	dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
2894 	    o->host_cert_files);
2895 	dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
2896 	dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
2897 	dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
2898 	dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
2899 	dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
2900 	dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv);
2901 	dump_cfg_strarray_oneline(sAuthenticationMethods,
2902 	    o->num_auth_methods, o->auth_methods);
2903 	dump_cfg_strarray_oneline(sLogVerbose,
2904 	    o->num_log_verbose, o->log_verbose);
2905 
2906 	/* other arguments */
2907 	for (i = 0; i < o->num_subsystems; i++)
2908 		printf("subsystem %s %s\n", o->subsystem_name[i],
2909 		    o->subsystem_args[i]);
2910 
2911 	printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
2912 	    o->max_startups_rate, o->max_startups);
2913 	printf("persourcemaxstartups ");
2914 	if (o->per_source_max_startups == INT_MAX)
2915 		printf("none\n");
2916 	else
2917 		printf("%d\n", o->per_source_max_startups);
2918 	printf("persourcenetblocksize %d:%d\n", o->per_source_masklen_ipv4,
2919 	    o->per_source_masklen_ipv6);
2920 
2921 	s = NULL;
2922 	for (i = 0; tunmode_desc[i].val != -1; i++) {
2923 		if (tunmode_desc[i].val == o->permit_tun) {
2924 			s = tunmode_desc[i].text;
2925 			break;
2926 		}
2927 	}
2928 	dump_cfg_string(sPermitTunnel, s);
2929 
2930 	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2931 	printf("%s\n", iptos2str(o->ip_qos_bulk));
2932 
2933 	printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
2934 	    o->rekey_interval);
2935 
2936 	printf("permitopen");
2937 	if (o->num_permitted_opens == 0)
2938 		printf(" any");
2939 	else {
2940 		for (i = 0; i < o->num_permitted_opens; i++)
2941 			printf(" %s", o->permitted_opens[i]);
2942 	}
2943 	printf("\n");
2944 	printf("permitlisten");
2945 	if (o->num_permitted_listens == 0)
2946 		printf(" any");
2947 	else {
2948 		for (i = 0; i < o->num_permitted_listens; i++)
2949 			printf(" %s", o->permitted_listens[i]);
2950 	}
2951 	printf("\n");
2952 
2953 	if (o->permit_user_env_allowlist == NULL) {
2954 		dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
2955 	} else {
2956 		printf("permituserenvironment %s\n",
2957 		    o->permit_user_env_allowlist);
2958 	}
2959 
2960 	printf("pubkeyauthoptions");
2961 	if (o->pubkey_auth_options == 0)
2962 		printf(" none");
2963 	if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED)
2964 		printf(" touch-required");
2965 	if (o->pubkey_auth_options & PUBKEYAUTH_VERIFY_REQUIRED)
2966 		printf(" verify-required");
2967 	printf("\n");
2968 }
2969