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