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