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