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