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