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