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