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