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