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