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