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