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