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