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