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