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