xref: /freebsd/crypto/openssh/servconf.c (revision 1edb7116)
1 /* $OpenBSD: servconf.c,v 1.403 2023/10/11 22:42:26 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_ALL },
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 void
974 process_channel_timeouts(struct ssh *ssh, ServerOptions *options)
975 {
976 	int secs;
977 	u_int i;
978 	char *type;
979 
980 	debug3_f("setting %u timeouts", options->num_channel_timeouts);
981 	channel_clear_timeouts(ssh);
982 	for (i = 0; i < options->num_channel_timeouts; i++) {
983 		if (parse_pattern_interval(options->channel_timeouts[i],
984 		    &type, &secs) != 0) {
985 			fatal_f("internal error: bad timeout %s",
986 			    options->channel_timeouts[i]);
987 		}
988 		channel_add_timeout(ssh, type, secs);
989 		free(type);
990 	}
991 }
992 
993 struct connection_info *
994 get_connection_info(struct ssh *ssh, int populate, int use_dns)
995 {
996 	static struct connection_info ci;
997 
998 	if (ssh == NULL || !populate)
999 		return &ci;
1000 	ci.host = auth_get_canonical_hostname(ssh, use_dns);
1001 	ci.address = ssh_remote_ipaddr(ssh);
1002 	ci.laddress = ssh_local_ipaddr(ssh);
1003 	ci.lport = ssh_local_port(ssh);
1004 	ci.rdomain = ssh_packet_rdomain_in(ssh);
1005 	return &ci;
1006 }
1007 
1008 /*
1009  * The strategy for the Match blocks is that the config file is parsed twice.
1010  *
1011  * The first time is at startup.  activep is initialized to 1 and the
1012  * directives in the global context are processed and acted on.  Hitting a
1013  * Match directive unsets activep and the directives inside the block are
1014  * checked for syntax only.
1015  *
1016  * The second time is after a connection has been established but before
1017  * authentication.  activep is initialized to 2 and global config directives
1018  * are ignored since they have already been processed.  If the criteria in a
1019  * Match block is met, activep is set and the subsequent directives
1020  * processed and actioned until EOF or another Match block unsets it.  Any
1021  * options set are copied into the main server config.
1022  *
1023  * Potential additions/improvements:
1024  *  - Add Match support for pre-kex directives, eg. Ciphers.
1025  *
1026  *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
1027  *	Match Address 192.168.0.*
1028  *		Tag trusted
1029  *	Match Group wheel
1030  *		Tag trusted
1031  *	Match Tag trusted
1032  *		AllowTcpForwarding yes
1033  *		GatewayPorts clientspecified
1034  *		[...]
1035  *
1036  *  - Add a PermittedChannelRequests directive
1037  *	Match Group shell
1038  *		PermittedChannelRequests session,forwarded-tcpip
1039  */
1040 
1041 static int
1042 match_cfg_line_group(const char *grps, int line, const char *user)
1043 {
1044 	int result = 0;
1045 	struct passwd *pw;
1046 
1047 	if (user == NULL)
1048 		goto out;
1049 
1050 	if ((pw = getpwnam(user)) == NULL) {
1051 		debug("Can't match group at line %d because user %.100s does "
1052 		    "not exist", line, user);
1053 	} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
1054 		debug("Can't Match group because user %.100s not in any group "
1055 		    "at line %d", user, line);
1056 	} else if (ga_match_pattern_list(grps) != 1) {
1057 		debug("user %.100s does not match group list %.100s at line %d",
1058 		    user, grps, line);
1059 	} else {
1060 		debug("user %.100s matched group list %.100s at line %d", user,
1061 		    grps, line);
1062 		result = 1;
1063 	}
1064 out:
1065 	ga_free();
1066 	return result;
1067 }
1068 
1069 static void
1070 match_test_missing_fatal(const char *criteria, const char *attrib)
1071 {
1072 	fatal("'Match %s' in configuration but '%s' not in connection "
1073 	    "test specification.", criteria, attrib);
1074 }
1075 
1076 /*
1077  * All of the attributes on a single Match line are ANDed together, so we need
1078  * to check every attribute and set the result to zero if any attribute does
1079  * not match.
1080  */
1081 static int
1082 match_cfg_line(char **condition, int line, struct connection_info *ci)
1083 {
1084 	int result = 1, attributes = 0, port;
1085 	char *arg, *attrib, *cp = *condition;
1086 
1087 	if (ci == NULL)
1088 		debug3("checking syntax for 'Match %s'", cp);
1089 	else
1090 		debug3("checking match for '%s' user %s host %s addr %s "
1091 		    "laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
1092 		    ci->host ? ci->host : "(null)",
1093 		    ci->address ? ci->address : "(null)",
1094 		    ci->laddress ? ci->laddress : "(null)", ci->lport);
1095 
1096 	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
1097 		/* Terminate on comment */
1098 		if (*attrib == '#') {
1099 			cp = NULL; /* mark all arguments consumed */
1100 			break;
1101 		}
1102 		arg = NULL;
1103 		attributes++;
1104 		/* Criterion "all" has no argument and must appear alone */
1105 		if (strcasecmp(attrib, "all") == 0) {
1106 			if (attributes > 1 || ((arg = strdelim(&cp)) != NULL &&
1107 			    *arg != '\0' && *arg != '#')) {
1108 				error("'all' cannot be combined with other "
1109 				    "Match attributes");
1110 				return -1;
1111 			}
1112 			if (arg != NULL && *arg == '#')
1113 				cp = NULL; /* mark all arguments consumed */
1114 			*condition = cp;
1115 			return 1;
1116 		}
1117 		/* All other criteria require an argument */
1118 		if ((arg = strdelim(&cp)) == NULL ||
1119 		    *arg == '\0' || *arg == '#') {
1120 			error("Missing Match criteria for %s", attrib);
1121 			return -1;
1122 		}
1123 		if (strcasecmp(attrib, "user") == 0) {
1124 			if (ci == NULL || (ci->test && ci->user == NULL)) {
1125 				result = 0;
1126 				continue;
1127 			}
1128 			if (ci->user == NULL)
1129 				match_test_missing_fatal("User", "user");
1130 			if (match_usergroup_pattern_list(ci->user, arg) != 1)
1131 				result = 0;
1132 			else
1133 				debug("user %.100s matched 'User %.100s' at "
1134 				    "line %d", ci->user, arg, line);
1135 		} else if (strcasecmp(attrib, "group") == 0) {
1136 			if (ci == NULL || (ci->test && ci->user == NULL)) {
1137 				result = 0;
1138 				continue;
1139 			}
1140 			if (ci->user == NULL)
1141 				match_test_missing_fatal("Group", "user");
1142 			switch (match_cfg_line_group(arg, line, ci->user)) {
1143 			case -1:
1144 				return -1;
1145 			case 0:
1146 				result = 0;
1147 			}
1148 		} else if (strcasecmp(attrib, "host") == 0) {
1149 			if (ci == NULL || (ci->test && ci->host == NULL)) {
1150 				result = 0;
1151 				continue;
1152 			}
1153 			if (ci->host == NULL)
1154 				match_test_missing_fatal("Host", "host");
1155 			if (match_hostname(ci->host, arg) != 1)
1156 				result = 0;
1157 			else
1158 				debug("connection from %.100s matched 'Host "
1159 				    "%.100s' at line %d", ci->host, arg, line);
1160 		} else if (strcasecmp(attrib, "address") == 0) {
1161 			if (ci == NULL || (ci->test && ci->address == NULL)) {
1162 				if (addr_match_list(NULL, arg) != 0)
1163 					fatal("Invalid Match address argument "
1164 					    "'%s' at line %d", arg, line);
1165 				result = 0;
1166 				continue;
1167 			}
1168 			if (ci->address == NULL)
1169 				match_test_missing_fatal("Address", "addr");
1170 			switch (addr_match_list(ci->address, arg)) {
1171 			case 1:
1172 				debug("connection from %.100s matched 'Address "
1173 				    "%.100s' at line %d", ci->address, arg, line);
1174 				break;
1175 			case 0:
1176 			case -1:
1177 				result = 0;
1178 				break;
1179 			case -2:
1180 				return -1;
1181 			}
1182 		} else if (strcasecmp(attrib, "localaddress") == 0){
1183 			if (ci == NULL || (ci->test && ci->laddress == NULL)) {
1184 				if (addr_match_list(NULL, arg) != 0)
1185 					fatal("Invalid Match localaddress "
1186 					    "argument '%s' at line %d", arg,
1187 					    line);
1188 				result = 0;
1189 				continue;
1190 			}
1191 			if (ci->laddress == NULL)
1192 				match_test_missing_fatal("LocalAddress",
1193 				    "laddr");
1194 			switch (addr_match_list(ci->laddress, arg)) {
1195 			case 1:
1196 				debug("connection from %.100s matched "
1197 				    "'LocalAddress %.100s' at line %d",
1198 				    ci->laddress, arg, line);
1199 				break;
1200 			case 0:
1201 			case -1:
1202 				result = 0;
1203 				break;
1204 			case -2:
1205 				return -1;
1206 			}
1207 		} else if (strcasecmp(attrib, "localport") == 0) {
1208 			if ((port = a2port(arg)) == -1) {
1209 				error("Invalid LocalPort '%s' on Match line",
1210 				    arg);
1211 				return -1;
1212 			}
1213 			if (ci == NULL || (ci->test && ci->lport == -1)) {
1214 				result = 0;
1215 				continue;
1216 			}
1217 			if (ci->lport == 0)
1218 				match_test_missing_fatal("LocalPort", "lport");
1219 			/* TODO support port lists */
1220 			if (port == ci->lport)
1221 				debug("connection from %.100s matched "
1222 				    "'LocalPort %d' at line %d",
1223 				    ci->laddress, port, line);
1224 			else
1225 				result = 0;
1226 		} else if (strcasecmp(attrib, "rdomain") == 0) {
1227 			if (ci == NULL || (ci->test && ci->rdomain == NULL)) {
1228 				result = 0;
1229 				continue;
1230 			}
1231 			if (ci->rdomain == NULL)
1232 				match_test_missing_fatal("RDomain", "rdomain");
1233 			if (match_pattern_list(ci->rdomain, arg, 0) != 1)
1234 				result = 0;
1235 			else
1236 				debug("user %.100s matched 'RDomain %.100s' at "
1237 				    "line %d", ci->rdomain, arg, line);
1238 		} else {
1239 			error("Unsupported Match attribute %s", attrib);
1240 			return -1;
1241 		}
1242 	}
1243 	if (attributes == 0) {
1244 		error("One or more attributes required for Match");
1245 		return -1;
1246 	}
1247 	if (ci != NULL)
1248 		debug3("match %sfound", result ? "" : "not ");
1249 	*condition = cp;
1250 	return result;
1251 }
1252 
1253 #define WHITESPACE " \t\r\n"
1254 
1255 /* Multistate option parsing */
1256 struct multistate {
1257 	char *key;
1258 	int value;
1259 };
1260 static const struct multistate multistate_flag[] = {
1261 	{ "yes",			1 },
1262 	{ "no",				0 },
1263 	{ NULL, -1 }
1264 };
1265 static const struct multistate multistate_ignore_rhosts[] = {
1266 	{ "yes",			IGNORE_RHOSTS_YES },
1267 	{ "no",				IGNORE_RHOSTS_NO },
1268 	{ "shosts-only",		IGNORE_RHOSTS_SHOSTS },
1269 	{ NULL, -1 }
1270 };
1271 static const struct multistate multistate_addressfamily[] = {
1272 	{ "inet",			AF_INET },
1273 	{ "inet6",			AF_INET6 },
1274 	{ "any",			AF_UNSPEC },
1275 	{ NULL, -1 }
1276 };
1277 static const struct multistate multistate_permitrootlogin[] = {
1278 	{ "without-password",		PERMIT_NO_PASSWD },
1279 	{ "prohibit-password",		PERMIT_NO_PASSWD },
1280 	{ "forced-commands-only",	PERMIT_FORCED_ONLY },
1281 	{ "yes",			PERMIT_YES },
1282 	{ "no",				PERMIT_NO },
1283 	{ NULL, -1 }
1284 };
1285 static const struct multistate multistate_compression[] = {
1286 #ifdef WITH_ZLIB
1287 	{ "yes",			COMP_DELAYED },
1288 	{ "delayed",			COMP_DELAYED },
1289 #endif
1290 	{ "no",				COMP_NONE },
1291 	{ NULL, -1 }
1292 };
1293 static const struct multistate multistate_gatewayports[] = {
1294 	{ "clientspecified",		2 },
1295 	{ "yes",			1 },
1296 	{ "no",				0 },
1297 	{ NULL, -1 }
1298 };
1299 static const struct multistate multistate_tcpfwd[] = {
1300 	{ "yes",			FORWARD_ALLOW },
1301 	{ "all",			FORWARD_ALLOW },
1302 	{ "no",				FORWARD_DENY },
1303 	{ "remote",			FORWARD_REMOTE },
1304 	{ "local",			FORWARD_LOCAL },
1305 	{ NULL, -1 }
1306 };
1307 
1308 static int
1309 process_server_config_line_depth(ServerOptions *options, char *line,
1310     const char *filename, int linenum, int *activep,
1311     struct connection_info *connectinfo, int *inc_flags, int depth,
1312     struct include_list *includes)
1313 {
1314 	char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword;
1315 	int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found;
1316 	int ca_only = 0;
1317 	SyslogFacility *log_facility_ptr;
1318 	LogLevel *log_level_ptr;
1319 	ServerOpCodes opcode;
1320 	u_int i, *uintptr, uvalue, flags = 0;
1321 	size_t len;
1322 	long long val64;
1323 	const struct multistate *multistate_ptr;
1324 	const char *errstr;
1325 	struct include_item *item;
1326 	glob_t gbuf;
1327 	char **oav = NULL, **av;
1328 	int oac = 0, ac;
1329 	int ret = -1;
1330 
1331 	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1332 	if ((len = strlen(line)) == 0)
1333 		return 0;
1334 	for (len--; len > 0; len--) {
1335 		if (strchr(WHITESPACE "\f", line[len]) == NULL)
1336 			break;
1337 		line[len] = '\0';
1338 	}
1339 
1340 	str = line;
1341 	if ((keyword = strdelim(&str)) == NULL)
1342 		return 0;
1343 	/* Ignore leading whitespace */
1344 	if (*keyword == '\0')
1345 		keyword = strdelim(&str);
1346 	if (!keyword || !*keyword || *keyword == '#')
1347 		return 0;
1348 	if (str == NULL || *str == '\0') {
1349 		error("%s line %d: no argument after keyword \"%s\"",
1350 		    filename, linenum, keyword);
1351 		return -1;
1352 	}
1353 	intptr = NULL;
1354 	charptr = NULL;
1355 	opcode = parse_token(keyword, filename, linenum, &flags);
1356 
1357 	if (argv_split(str, &oac, &oav, 1) != 0) {
1358 		error("%s line %d: invalid quotes", filename, linenum);
1359 		return -1;
1360 	}
1361 	ac = oac;
1362 	av = oav;
1363 
1364 	if (activep == NULL) { /* We are processing a command line directive */
1365 		cmdline = 1;
1366 		activep = &cmdline;
1367 	}
1368 	if (*activep && opcode != sMatch && opcode != sInclude)
1369 		debug3("%s:%d setting %s %s", filename, linenum, keyword, str);
1370 	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1371 		if (connectinfo == NULL) {
1372 			fatal("%s line %d: Directive '%s' is not allowed "
1373 			    "within a Match block", filename, linenum, keyword);
1374 		} else { /* this is a directive we have already processed */
1375 			ret = 0;
1376 			goto out;
1377 		}
1378 	}
1379 
1380 	switch (opcode) {
1381 	/* Portable-specific options */
1382 	case sUsePAM:
1383 		intptr = &options->use_pam;
1384 		goto parse_flag;
1385 
1386 	/* Standard Options */
1387 	case sBadOption:
1388 		goto out;
1389 	case sPort:
1390 		/* ignore ports from configfile if cmdline specifies ports */
1391 		if (options->ports_from_cmdline) {
1392 			argv_consume(&ac);
1393 			break;
1394 		}
1395 		if (options->num_ports >= MAX_PORTS)
1396 			fatal("%s line %d: too many ports.",
1397 			    filename, linenum);
1398 		arg = argv_next(&ac, &av);
1399 		if (!arg || *arg == '\0')
1400 			fatal("%s line %d: missing port number.",
1401 			    filename, linenum);
1402 		options->ports[options->num_ports++] = a2port(arg);
1403 		if (options->ports[options->num_ports-1] <= 0)
1404 			fatal("%s line %d: Badly formatted port number.",
1405 			    filename, linenum);
1406 		break;
1407 
1408 	case sLoginGraceTime:
1409 		intptr = &options->login_grace_time;
1410  parse_time:
1411 		arg = argv_next(&ac, &av);
1412 		if (!arg || *arg == '\0')
1413 			fatal("%s line %d: missing time value.",
1414 			    filename, linenum);
1415 		if ((value = convtime(arg)) == -1)
1416 			fatal("%s line %d: invalid time value.",
1417 			    filename, linenum);
1418 		if (*activep && *intptr == -1)
1419 			*intptr = value;
1420 		break;
1421 
1422 	case sListenAddress:
1423 		arg = argv_next(&ac, &av);
1424 		if (arg == NULL || *arg == '\0')
1425 			fatal("%s line %d: missing address",
1426 			    filename, linenum);
1427 		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
1428 		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1429 		    && strchr(p+1, ':') != NULL) {
1430 			port = 0;
1431 			p = arg;
1432 		} else {
1433 			arg2 = NULL;
1434 			p = hpdelim(&arg);
1435 			if (p == NULL)
1436 				fatal("%s line %d: bad address:port usage",
1437 				    filename, linenum);
1438 			p = cleanhostname(p);
1439 			if (arg == NULL)
1440 				port = 0;
1441 			else if ((port = a2port(arg)) <= 0)
1442 				fatal("%s line %d: bad port number",
1443 				    filename, linenum);
1444 		}
1445 		/* Optional routing table */
1446 		arg2 = NULL;
1447 		if ((arg = argv_next(&ac, &av)) != NULL) {
1448 			if (strcmp(arg, "rdomain") != 0 ||
1449 			    (arg2 = argv_next(&ac, &av)) == NULL)
1450 				fatal("%s line %d: bad ListenAddress syntax",
1451 				    filename, linenum);
1452 			if (!valid_rdomain(arg2))
1453 				fatal("%s line %d: bad routing domain",
1454 				    filename, linenum);
1455 		}
1456 		queue_listen_addr(options, p, arg2, port);
1457 
1458 		break;
1459 
1460 	case sAddressFamily:
1461 		intptr = &options->address_family;
1462 		multistate_ptr = multistate_addressfamily;
1463  parse_multistate:
1464 		arg = argv_next(&ac, &av);
1465 		if (!arg || *arg == '\0')
1466 			fatal("%s line %d: missing argument.",
1467 			    filename, linenum);
1468 		value = -1;
1469 		for (i = 0; multistate_ptr[i].key != NULL; i++) {
1470 			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1471 				value = multistate_ptr[i].value;
1472 				break;
1473 			}
1474 		}
1475 		if (value == -1)
1476 			fatal("%s line %d: unsupported option \"%s\".",
1477 			    filename, linenum, arg);
1478 		if (*activep && *intptr == -1)
1479 			*intptr = value;
1480 		break;
1481 
1482 	case sHostKeyFile:
1483 		arg = argv_next(&ac, &av);
1484 		if (!arg || *arg == '\0')
1485 			fatal("%s line %d: missing file name.",
1486 			    filename, linenum);
1487 		if (*activep) {
1488 			servconf_add_hostkey(filename, linenum,
1489 			    options, arg, 1);
1490 		}
1491 		break;
1492 
1493 	case sHostKeyAgent:
1494 		charptr = &options->host_key_agent;
1495 		arg = argv_next(&ac, &av);
1496 		if (!arg || *arg == '\0')
1497 			fatal("%s line %d: missing socket name.",
1498 			    filename, linenum);
1499 		if (*activep && *charptr == NULL)
1500 			*charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
1501 			    xstrdup(arg) : derelativise_path(arg);
1502 		break;
1503 
1504 	case sHostCertificate:
1505 		arg = argv_next(&ac, &av);
1506 		if (!arg || *arg == '\0')
1507 			fatal("%s line %d: missing file name.",
1508 			    filename, linenum);
1509 		if (*activep)
1510 			servconf_add_hostcert(filename, linenum, options, arg);
1511 		break;
1512 
1513 	case sPidFile:
1514 		charptr = &options->pid_file;
1515  parse_filename:
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 && *charptr == NULL) {
1521 			*charptr = derelativise_path(arg);
1522 			/* increase optional counter */
1523 			if (intptr != NULL)
1524 				*intptr = *intptr + 1;
1525 		}
1526 		break;
1527 
1528 	case sModuliFile:
1529 		charptr = &options->moduli_file;
1530 		goto parse_filename;
1531 
1532 	case sPermitRootLogin:
1533 		intptr = &options->permit_root_login;
1534 		multistate_ptr = multistate_permitrootlogin;
1535 		goto parse_multistate;
1536 
1537 	case sIgnoreRhosts:
1538 		intptr = &options->ignore_rhosts;
1539 		multistate_ptr = multistate_ignore_rhosts;
1540 		goto parse_multistate;
1541 
1542 	case sIgnoreUserKnownHosts:
1543 		intptr = &options->ignore_user_known_hosts;
1544  parse_flag:
1545 		multistate_ptr = multistate_flag;
1546 		goto parse_multistate;
1547 
1548 	case sHostbasedAuthentication:
1549 		intptr = &options->hostbased_authentication;
1550 		goto parse_flag;
1551 
1552 	case sHostbasedUsesNameFromPacketOnly:
1553 		intptr = &options->hostbased_uses_name_from_packet_only;
1554 		goto parse_flag;
1555 
1556 	case sHostbasedAcceptedAlgorithms:
1557 		charptr = &options->hostbased_accepted_algos;
1558 		ca_only = 0;
1559  parse_pubkey_algos:
1560 		arg = argv_next(&ac, &av);
1561 		if (!arg || *arg == '\0')
1562 			fatal("%s line %d: Missing argument.",
1563 			    filename, linenum);
1564 		if (*arg != '-' &&
1565 		    !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
1566 		    arg + 1 : arg, 1, ca_only))
1567 			fatal("%s line %d: Bad key types '%s'.",
1568 			    filename, linenum, arg ? arg : "<NONE>");
1569 		if (*activep && *charptr == NULL)
1570 			*charptr = xstrdup(arg);
1571 		break;
1572 
1573 	case sHostKeyAlgorithms:
1574 		charptr = &options->hostkeyalgorithms;
1575 		ca_only = 0;
1576 		goto parse_pubkey_algos;
1577 
1578 	case sCASignatureAlgorithms:
1579 		charptr = &options->ca_sign_algorithms;
1580 		ca_only = 1;
1581 		goto parse_pubkey_algos;
1582 
1583 	case sPubkeyAuthentication:
1584 		intptr = &options->pubkey_authentication;
1585 		ca_only = 0;
1586 		goto parse_flag;
1587 
1588 	case sPubkeyAcceptedAlgorithms:
1589 		charptr = &options->pubkey_accepted_algos;
1590 		ca_only = 0;
1591 		goto parse_pubkey_algos;
1592 
1593 	case sPubkeyAuthOptions:
1594 		intptr = &options->pubkey_auth_options;
1595 		value = 0;
1596 		while ((arg = argv_next(&ac, &av)) != NULL) {
1597 			if (strcasecmp(arg, "none") == 0)
1598 				continue;
1599 			if (strcasecmp(arg, "touch-required") == 0)
1600 				value |= PUBKEYAUTH_TOUCH_REQUIRED;
1601 			else if (strcasecmp(arg, "verify-required") == 0)
1602 				value |= PUBKEYAUTH_VERIFY_REQUIRED;
1603 			else {
1604 				error("%s line %d: unsupported %s option %s",
1605 				    filename, linenum, keyword, arg);
1606 				goto out;
1607 			}
1608 		}
1609 		if (*activep && *intptr == -1)
1610 			*intptr = value;
1611 		break;
1612 
1613 	case sKerberosAuthentication:
1614 		intptr = &options->kerberos_authentication;
1615 		goto parse_flag;
1616 
1617 	case sKerberosOrLocalPasswd:
1618 		intptr = &options->kerberos_or_local_passwd;
1619 		goto parse_flag;
1620 
1621 	case sKerberosTicketCleanup:
1622 		intptr = &options->kerberos_ticket_cleanup;
1623 		goto parse_flag;
1624 
1625 	case sKerberosGetAFSToken:
1626 		intptr = &options->kerberos_get_afs_token;
1627 		goto parse_flag;
1628 
1629 	case sGssAuthentication:
1630 		intptr = &options->gss_authentication;
1631 		goto parse_flag;
1632 
1633 	case sGssCleanupCreds:
1634 		intptr = &options->gss_cleanup_creds;
1635 		goto parse_flag;
1636 
1637 	case sGssStrictAcceptor:
1638 		intptr = &options->gss_strict_acceptor;
1639 		goto parse_flag;
1640 
1641 	case sPasswordAuthentication:
1642 		intptr = &options->password_authentication;
1643 		goto parse_flag;
1644 
1645 	case sKbdInteractiveAuthentication:
1646 		intptr = &options->kbd_interactive_authentication;
1647 		goto parse_flag;
1648 
1649 	case sPrintMotd:
1650 		intptr = &options->print_motd;
1651 		goto parse_flag;
1652 
1653 	case sPrintLastLog:
1654 		intptr = &options->print_lastlog;
1655 		goto parse_flag;
1656 
1657 	case sX11Forwarding:
1658 		intptr = &options->x11_forwarding;
1659 		goto parse_flag;
1660 
1661 	case sX11DisplayOffset:
1662 		intptr = &options->x11_display_offset;
1663  parse_int:
1664 		arg = argv_next(&ac, &av);
1665 		if ((errstr = atoi_err(arg, &value)) != NULL)
1666 			fatal("%s line %d: %s integer value %s.",
1667 			    filename, linenum, keyword, errstr);
1668 		if (*activep && *intptr == -1)
1669 			*intptr = value;
1670 		break;
1671 
1672 	case sX11UseLocalhost:
1673 		intptr = &options->x11_use_localhost;
1674 		goto parse_flag;
1675 
1676 	case sXAuthLocation:
1677 		charptr = &options->xauth_location;
1678 		goto parse_filename;
1679 
1680 	case sPermitTTY:
1681 		intptr = &options->permit_tty;
1682 		goto parse_flag;
1683 
1684 	case sPermitUserRC:
1685 		intptr = &options->permit_user_rc;
1686 		goto parse_flag;
1687 
1688 	case sStrictModes:
1689 		intptr = &options->strict_modes;
1690 		goto parse_flag;
1691 
1692 	case sTCPKeepAlive:
1693 		intptr = &options->tcp_keep_alive;
1694 		goto parse_flag;
1695 
1696 	case sEmptyPasswd:
1697 		intptr = &options->permit_empty_passwd;
1698 		goto parse_flag;
1699 
1700 	case sPermitUserEnvironment:
1701 		intptr = &options->permit_user_env;
1702 		charptr = &options->permit_user_env_allowlist;
1703 		arg = argv_next(&ac, &av);
1704 		if (!arg || *arg == '\0')
1705 			fatal("%s line %d: %s missing argument.",
1706 			    filename, linenum, keyword);
1707 		value = 0;
1708 		p = NULL;
1709 		if (strcmp(arg, "yes") == 0)
1710 			value = 1;
1711 		else if (strcmp(arg, "no") == 0)
1712 			value = 0;
1713 		else {
1714 			/* Pattern-list specified */
1715 			value = 1;
1716 			p = xstrdup(arg);
1717 		}
1718 		if (*activep && *intptr == -1) {
1719 			*intptr = value;
1720 			*charptr = p;
1721 			p = NULL;
1722 		}
1723 		free(p);
1724 		break;
1725 
1726 	case sCompression:
1727 		intptr = &options->compression;
1728 		multistate_ptr = multistate_compression;
1729 		goto parse_multistate;
1730 
1731 	case sRekeyLimit:
1732 		arg = argv_next(&ac, &av);
1733 		if (!arg || *arg == '\0')
1734 			fatal("%s line %d: %s missing argument.",
1735 			    filename, linenum, keyword);
1736 		if (strcmp(arg, "default") == 0) {
1737 			val64 = 0;
1738 		} else {
1739 			if (scan_scaled(arg, &val64) == -1)
1740 				fatal("%.200s line %d: Bad %s number '%s': %s",
1741 				    filename, linenum, keyword,
1742 				    arg, strerror(errno));
1743 			if (val64 != 0 && val64 < 16)
1744 				fatal("%.200s line %d: %s too small",
1745 				    filename, linenum, keyword);
1746 		}
1747 		if (*activep && options->rekey_limit == -1)
1748 			options->rekey_limit = val64;
1749 		if (ac != 0) { /* optional rekey interval present */
1750 			if (strcmp(av[0], "none") == 0) {
1751 				(void)argv_next(&ac, &av);	/* discard */
1752 				break;
1753 			}
1754 			intptr = &options->rekey_interval;
1755 			goto parse_time;
1756 		}
1757 		break;
1758 
1759 	case sGatewayPorts:
1760 		intptr = &options->fwd_opts.gateway_ports;
1761 		multistate_ptr = multistate_gatewayports;
1762 		goto parse_multistate;
1763 
1764 	case sUseDNS:
1765 		intptr = &options->use_dns;
1766 		goto parse_flag;
1767 
1768 	case sLogFacility:
1769 		log_facility_ptr = &options->log_facility;
1770 		arg = argv_next(&ac, &av);
1771 		value = log_facility_number(arg);
1772 		if (value == SYSLOG_FACILITY_NOT_SET)
1773 			fatal("%.200s line %d: unsupported log facility '%s'",
1774 			    filename, linenum, arg ? arg : "<NONE>");
1775 		if (*log_facility_ptr == -1)
1776 			*log_facility_ptr = (SyslogFacility) value;
1777 		break;
1778 
1779 	case sLogLevel:
1780 		log_level_ptr = &options->log_level;
1781 		arg = argv_next(&ac, &av);
1782 		value = log_level_number(arg);
1783 		if (value == SYSLOG_LEVEL_NOT_SET)
1784 			fatal("%.200s line %d: unsupported log level '%s'",
1785 			    filename, linenum, arg ? arg : "<NONE>");
1786 		if (*activep && *log_level_ptr == -1)
1787 			*log_level_ptr = (LogLevel) value;
1788 		break;
1789 
1790 	case sLogVerbose:
1791 		found = options->num_log_verbose == 0;
1792 		i = 0;
1793 		while ((arg = argv_next(&ac, &av)) != NULL) {
1794 			if (*arg == '\0') {
1795 				error("%s line %d: keyword %s empty argument",
1796 				    filename, linenum, keyword);
1797 				goto out;
1798 			}
1799 			/* Allow "none" only in first position */
1800 			if (strcasecmp(arg, "none") == 0) {
1801 				if (i > 0 || ac > 0) {
1802 					error("%s line %d: keyword %s \"none\" "
1803 					    "argument must appear alone.",
1804 					    filename, linenum, keyword);
1805 					goto out;
1806 				}
1807 			}
1808 			i++;
1809 			if (!found || !*activep)
1810 				continue;
1811 			opt_array_append(filename, linenum, keyword,
1812 			    &options->log_verbose, &options->num_log_verbose,
1813 			    arg);
1814 		}
1815 		break;
1816 
1817 	case sAllowTcpForwarding:
1818 		intptr = &options->allow_tcp_forwarding;
1819 		multistate_ptr = multistate_tcpfwd;
1820 		goto parse_multistate;
1821 
1822 	case sAllowStreamLocalForwarding:
1823 		intptr = &options->allow_streamlocal_forwarding;
1824 		multistate_ptr = multistate_tcpfwd;
1825 		goto parse_multistate;
1826 
1827 	case sAllowAgentForwarding:
1828 		intptr = &options->allow_agent_forwarding;
1829 		goto parse_flag;
1830 
1831 	case sDisableForwarding:
1832 		intptr = &options->disable_forwarding;
1833 		goto parse_flag;
1834 
1835 	case sAllowUsers:
1836 		chararrayptr = &options->allow_users;
1837 		uintptr = &options->num_allow_users;
1838  parse_allowdenyusers:
1839 		while ((arg = argv_next(&ac, &av)) != NULL) {
1840 			if (*arg == '\0' ||
1841 			    match_user(NULL, NULL, NULL, arg) == -1)
1842 				fatal("%s line %d: invalid %s pattern: \"%s\"",
1843 				    filename, linenum, keyword, arg);
1844 			if (!*activep)
1845 				continue;
1846 			opt_array_append(filename, linenum, keyword,
1847 			    chararrayptr, uintptr, arg);
1848 		}
1849 		break;
1850 
1851 	case sDenyUsers:
1852 		chararrayptr = &options->deny_users;
1853 		uintptr = &options->num_deny_users;
1854 		goto parse_allowdenyusers;
1855 
1856 	case sAllowGroups:
1857 		chararrayptr = &options->allow_groups;
1858 		uintptr = &options->num_allow_groups;
1859  parse_allowdenygroups:
1860 		while ((arg = argv_next(&ac, &av)) != NULL) {
1861 			if (*arg == '\0')
1862 				fatal("%s line %d: empty %s pattern",
1863 				    filename, linenum, keyword);
1864 			if (!*activep)
1865 				continue;
1866 			opt_array_append(filename, linenum, keyword,
1867 			    chararrayptr, uintptr, arg);
1868 		}
1869 		break;
1870 
1871 	case sDenyGroups:
1872 		chararrayptr = &options->deny_groups;
1873 		uintptr = &options->num_deny_groups;
1874 		goto parse_allowdenygroups;
1875 
1876 	case sCiphers:
1877 		arg = argv_next(&ac, &av);
1878 		if (!arg || *arg == '\0')
1879 			fatal("%s line %d: %s missing argument.",
1880 			    filename, linenum, keyword);
1881 		if (*arg != '-' &&
1882 		    !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1883 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1884 			    filename, linenum, arg ? arg : "<NONE>");
1885 		if (options->ciphers == NULL)
1886 			options->ciphers = xstrdup(arg);
1887 		break;
1888 
1889 	case sMacs:
1890 		arg = argv_next(&ac, &av);
1891 		if (!arg || *arg == '\0')
1892 			fatal("%s line %d: %s missing argument.",
1893 			    filename, linenum, keyword);
1894 		if (*arg != '-' &&
1895 		    !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1896 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1897 			    filename, linenum, arg ? arg : "<NONE>");
1898 		if (options->macs == NULL)
1899 			options->macs = xstrdup(arg);
1900 		break;
1901 
1902 	case sKexAlgorithms:
1903 		arg = argv_next(&ac, &av);
1904 		if (!arg || *arg == '\0')
1905 			fatal("%s line %d: %s missing argument.",
1906 			    filename, linenum, keyword);
1907 		if (*arg != '-' &&
1908 		    !kex_names_valid(*arg == '+' || *arg == '^' ?
1909 		    arg + 1 : arg))
1910 			fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1911 			    filename, linenum, arg ? arg : "<NONE>");
1912 		if (options->kex_algorithms == NULL)
1913 			options->kex_algorithms = xstrdup(arg);
1914 		break;
1915 
1916 	case sSubsystem:
1917 		arg = argv_next(&ac, &av);
1918 		if (!arg || *arg == '\0')
1919 			fatal("%s line %d: %s missing argument.",
1920 			    filename, linenum, keyword);
1921 		if (!*activep) {
1922 			argv_consume(&ac);
1923 			break;
1924 		}
1925 		found = 0;
1926 		for (i = 0; i < options->num_subsystems; i++) {
1927 			if (strcmp(arg, options->subsystem_name[i]) == 0) {
1928 				found = 1;
1929 				break;
1930 			}
1931 		}
1932 		if (found) {
1933 			debug("%s line %d: Subsystem '%s' already defined.",
1934 			    filename, linenum, arg);
1935 			argv_consume(&ac);
1936 			break;
1937 		}
1938 		options->subsystem_name = xrecallocarray(
1939 		    options->subsystem_name, options->num_subsystems,
1940 		    options->num_subsystems + 1,
1941 		    sizeof(*options->subsystem_name));
1942 		options->subsystem_command = xrecallocarray(
1943 		    options->subsystem_command, options->num_subsystems,
1944 		    options->num_subsystems + 1,
1945 		    sizeof(*options->subsystem_command));
1946 		options->subsystem_args = xrecallocarray(
1947 		    options->subsystem_args, options->num_subsystems,
1948 		    options->num_subsystems + 1,
1949 		    sizeof(*options->subsystem_args));
1950 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1951 		arg = argv_next(&ac, &av);
1952 		if (!arg || *arg == '\0') {
1953 			fatal("%s line %d: Missing subsystem command.",
1954 			    filename, linenum);
1955 		}
1956 		options->subsystem_command[options->num_subsystems] =
1957 		    xstrdup(arg);
1958 		/* Collect arguments (separate to executable) */
1959 		arg = argv_assemble(1, &arg); /* quote command correctly */
1960 		arg2 = argv_assemble(ac, av); /* rest of command */
1961 		xasprintf(&options->subsystem_args[options->num_subsystems],
1962 		    "%s %s", arg, arg2);
1963 		free(arg2);
1964 		argv_consume(&ac);
1965 		options->num_subsystems++;
1966 		break;
1967 
1968 	case sMaxStartups:
1969 		arg = argv_next(&ac, &av);
1970 		if (!arg || *arg == '\0')
1971 			fatal("%s line %d: %s missing argument.",
1972 			    filename, linenum, keyword);
1973 		if ((n = sscanf(arg, "%d:%d:%d",
1974 		    &options->max_startups_begin,
1975 		    &options->max_startups_rate,
1976 		    &options->max_startups)) == 3) {
1977 			if (options->max_startups_begin >
1978 			    options->max_startups ||
1979 			    options->max_startups_rate > 100 ||
1980 			    options->max_startups_rate < 1)
1981 				fatal("%s line %d: Invalid %s spec.",
1982 				    filename, linenum, keyword);
1983 		} else if (n != 1)
1984 			fatal("%s line %d: Invalid %s spec.",
1985 			    filename, linenum, keyword);
1986 		else
1987 			options->max_startups = options->max_startups_begin;
1988 		if (options->max_startups <= 0 ||
1989 		    options->max_startups_begin <= 0)
1990 			fatal("%s line %d: Invalid %s spec.",
1991 			    filename, linenum, keyword);
1992 		break;
1993 
1994 	case sPerSourceNetBlockSize:
1995 		arg = argv_next(&ac, &av);
1996 		if (!arg || *arg == '\0')
1997 			fatal("%s line %d: %s missing argument.",
1998 			    filename, linenum, keyword);
1999 		switch (n = sscanf(arg, "%d:%d", &value, &value2)) {
2000 		case 2:
2001 			if (value2 < 0 || value2 > 128)
2002 				n = -1;
2003 			/* FALLTHROUGH */
2004 		case 1:
2005 			if (value < 0 || value > 32)
2006 				n = -1;
2007 		}
2008 		if (n != 1 && n != 2)
2009 			fatal("%s line %d: Invalid %s spec.",
2010 			    filename, linenum, keyword);
2011 		if (*activep) {
2012 			options->per_source_masklen_ipv4 = value;
2013 			options->per_source_masklen_ipv6 = value2;
2014 		}
2015 		break;
2016 
2017 	case sPerSourceMaxStartups:
2018 		arg = argv_next(&ac, &av);
2019 		if (!arg || *arg == '\0')
2020 			fatal("%s line %d: %s missing argument.",
2021 			    filename, linenum, keyword);
2022 		if (strcmp(arg, "none") == 0) { /* no limit */
2023 			value = INT_MAX;
2024 		} else {
2025 			if ((errstr = atoi_err(arg, &value)) != NULL)
2026 				fatal("%s line %d: %s integer value %s.",
2027 				    filename, linenum, keyword, errstr);
2028 		}
2029 		if (*activep && options->per_source_max_startups == -1)
2030 			options->per_source_max_startups = value;
2031 		break;
2032 
2033 	case sMaxAuthTries:
2034 		intptr = &options->max_authtries;
2035 		goto parse_int;
2036 
2037 	case sMaxSessions:
2038 		intptr = &options->max_sessions;
2039 		goto parse_int;
2040 
2041 	case sBanner:
2042 		charptr = &options->banner;
2043 		goto parse_filename;
2044 
2045 	/*
2046 	 * These options can contain %X options expanded at
2047 	 * connect time, so that you can specify paths like:
2048 	 *
2049 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
2050 	 */
2051 	case sAuthorizedKeysFile:
2052 		uvalue = options->num_authkeys_files;
2053 		while ((arg = argv_next(&ac, &av)) != NULL) {
2054 			if (*arg == '\0') {
2055 				error("%s line %d: keyword %s empty argument",
2056 				    filename, linenum, keyword);
2057 				goto out;
2058 			}
2059 			arg2 = tilde_expand_filename(arg, getuid());
2060 			if (*activep && uvalue == 0) {
2061 				opt_array_append(filename, linenum, keyword,
2062 				    &options->authorized_keys_files,
2063 				    &options->num_authkeys_files, arg2);
2064 			}
2065 			free(arg2);
2066 		}
2067 		break;
2068 
2069 	case sAuthorizedPrincipalsFile:
2070 		charptr = &options->authorized_principals_file;
2071 		arg = argv_next(&ac, &av);
2072 		if (!arg || *arg == '\0')
2073 			fatal("%s line %d: %s missing argument.",
2074 			    filename, linenum, keyword);
2075 		if (*activep && *charptr == NULL) {
2076 			*charptr = tilde_expand_filename(arg, getuid());
2077 			/* increase optional counter */
2078 			if (intptr != NULL)
2079 				*intptr = *intptr + 1;
2080 		}
2081 		break;
2082 
2083 	case sClientAliveInterval:
2084 		intptr = &options->client_alive_interval;
2085 		goto parse_time;
2086 
2087 	case sClientAliveCountMax:
2088 		intptr = &options->client_alive_count_max;
2089 		goto parse_int;
2090 
2091 	case sAcceptEnv:
2092 		while ((arg = argv_next(&ac, &av)) != NULL) {
2093 			if (*arg == '\0' || strchr(arg, '=') != NULL)
2094 				fatal("%s line %d: Invalid environment name.",
2095 				    filename, linenum);
2096 			if (!*activep)
2097 				continue;
2098 			opt_array_append(filename, linenum, keyword,
2099 			    &options->accept_env, &options->num_accept_env,
2100 			    arg);
2101 		}
2102 		break;
2103 
2104 	case sSetEnv:
2105 		uvalue = options->num_setenv;
2106 		while ((arg = argv_next(&ac, &av)) != NULL) {
2107 			if (*arg == '\0' || strchr(arg, '=') == NULL)
2108 				fatal("%s line %d: Invalid environment.",
2109 				    filename, linenum);
2110 			if (!*activep || uvalue != 0)
2111 				continue;
2112 			if (lookup_setenv_in_list(arg, options->setenv,
2113 			    options->num_setenv) != NULL) {
2114 				debug2("%s line %d: ignoring duplicate env "
2115 				    "name \"%.64s\"", filename, linenum, arg);
2116 				continue;
2117 			}
2118 			opt_array_append(filename, linenum, keyword,
2119 			    &options->setenv, &options->num_setenv, arg);
2120 		}
2121 		break;
2122 
2123 	case sPermitTunnel:
2124 		intptr = &options->permit_tun;
2125 		arg = argv_next(&ac, &av);
2126 		if (!arg || *arg == '\0')
2127 			fatal("%s line %d: %s missing argument.",
2128 			    filename, linenum, keyword);
2129 		value = -1;
2130 		for (i = 0; tunmode_desc[i].val != -1; i++)
2131 			if (strcmp(tunmode_desc[i].text, arg) == 0) {
2132 				value = tunmode_desc[i].val;
2133 				break;
2134 			}
2135 		if (value == -1)
2136 			fatal("%s line %d: bad %s argument %s",
2137 			    filename, linenum, keyword, arg);
2138 		if (*activep && *intptr == -1)
2139 			*intptr = value;
2140 		break;
2141 
2142 	case sInclude:
2143 		if (cmdline) {
2144 			fatal("Include directive not supported as a "
2145 			    "command-line option");
2146 		}
2147 		value = 0;
2148 		while ((arg2 = argv_next(&ac, &av)) != NULL) {
2149 			if (*arg2 == '\0') {
2150 				error("%s line %d: keyword %s empty argument",
2151 				    filename, linenum, keyword);
2152 				goto out;
2153 			}
2154 			value++;
2155 			found = 0;
2156 			if (*arg2 != '/' && *arg2 != '~') {
2157 				xasprintf(&arg, "%s/%s", SSHDIR, arg2);
2158 			} else
2159 				arg = xstrdup(arg2);
2160 
2161 			/*
2162 			 * Don't let included files clobber the containing
2163 			 * file's Match state.
2164 			 */
2165 			oactive = *activep;
2166 
2167 			/* consult cache of include files */
2168 			TAILQ_FOREACH(item, includes, entry) {
2169 				if (strcmp(item->selector, arg) != 0)
2170 					continue;
2171 				if (item->filename != NULL) {
2172 					parse_server_config_depth(options,
2173 					    item->filename, item->contents,
2174 					    includes, connectinfo,
2175 					    (*inc_flags & SSHCFG_MATCH_ONLY
2176 					        ? SSHCFG_MATCH_ONLY : (oactive
2177 					            ? 0 : SSHCFG_NEVERMATCH)),
2178 					    activep, depth + 1);
2179 				}
2180 				found = 1;
2181 				*activep = oactive;
2182 			}
2183 			if (found != 0) {
2184 				free(arg);
2185 				continue;
2186 			}
2187 
2188 			/* requested glob was not in cache */
2189 			debug2("%s line %d: new include %s",
2190 			    filename, linenum, arg);
2191 			if ((r = glob(arg, 0, NULL, &gbuf)) != 0) {
2192 				if (r != GLOB_NOMATCH) {
2193 					fatal("%s line %d: include \"%s\" glob "
2194 					    "failed", filename, linenum, arg);
2195 				}
2196 				/*
2197 				 * If no entry matched then record a
2198 				 * placeholder to skip later glob calls.
2199 				 */
2200 				debug2("%s line %d: no match for %s",
2201 				    filename, linenum, arg);
2202 				item = xcalloc(1, sizeof(*item));
2203 				item->selector = strdup(arg);
2204 				TAILQ_INSERT_TAIL(includes,
2205 				    item, entry);
2206 			}
2207 			if (gbuf.gl_pathc > INT_MAX)
2208 				fatal_f("too many glob results");
2209 			for (n = 0; n < (int)gbuf.gl_pathc; n++) {
2210 				debug2("%s line %d: including %s",
2211 				    filename, linenum, gbuf.gl_pathv[n]);
2212 				item = xcalloc(1, sizeof(*item));
2213 				item->selector = strdup(arg);
2214 				item->filename = strdup(gbuf.gl_pathv[n]);
2215 				if ((item->contents = sshbuf_new()) == NULL)
2216 					fatal_f("sshbuf_new failed");
2217 				load_server_config(item->filename,
2218 				    item->contents);
2219 				parse_server_config_depth(options,
2220 				    item->filename, item->contents,
2221 				    includes, connectinfo,
2222 				    (*inc_flags & SSHCFG_MATCH_ONLY
2223 				        ? SSHCFG_MATCH_ONLY : (oactive
2224 				            ? 0 : SSHCFG_NEVERMATCH)),
2225 				    activep, depth + 1);
2226 				*activep = oactive;
2227 				TAILQ_INSERT_TAIL(includes, item, entry);
2228 			}
2229 			globfree(&gbuf);
2230 			free(arg);
2231 		}
2232 		if (value == 0) {
2233 			fatal("%s line %d: %s missing filename argument",
2234 			    filename, linenum, keyword);
2235 		}
2236 		break;
2237 
2238 	case sMatch:
2239 		if (cmdline)
2240 			fatal("Match directive not supported as a command-line "
2241 			    "option");
2242 		value = match_cfg_line(&str, linenum,
2243 		    (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
2244 		if (value < 0)
2245 			fatal("%s line %d: Bad Match condition", filename,
2246 			    linenum);
2247 		*activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
2248 		/*
2249 		 * The MATCH_ONLY flag is applicable only until the first
2250 		 * match block.
2251 		 */
2252 		*inc_flags &= ~SSHCFG_MATCH_ONLY;
2253 		/*
2254 		 * If match_cfg_line() didn't consume all its arguments then
2255 		 * arrange for the extra arguments check below to fail.
2256 		 */
2257 		if (str == NULL || *str == '\0')
2258 			argv_consume(&ac);
2259 		break;
2260 
2261 	case sPermitListen:
2262 	case sPermitOpen:
2263 		if (opcode == sPermitListen) {
2264 			uintptr = &options->num_permitted_listens;
2265 			chararrayptr = &options->permitted_listens;
2266 		} else {
2267 			uintptr = &options->num_permitted_opens;
2268 			chararrayptr = &options->permitted_opens;
2269 		}
2270 		arg = argv_next(&ac, &av);
2271 		if (!arg || *arg == '\0')
2272 			fatal("%s line %d: %s missing argument.",
2273 			    filename, linenum, keyword);
2274 		uvalue = *uintptr;	/* modified later */
2275 		if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
2276 			if (*activep && uvalue == 0) {
2277 				*uintptr = 1;
2278 				*chararrayptr = xcalloc(1,
2279 				    sizeof(**chararrayptr));
2280 				(*chararrayptr)[0] = xstrdup(arg);
2281 			}
2282 			break;
2283 		}
2284 		for (; arg != NULL && *arg != '\0'; arg = argv_next(&ac, &av)) {
2285 			if (opcode == sPermitListen &&
2286 			    strchr(arg, ':') == NULL) {
2287 				/*
2288 				 * Allow bare port number for PermitListen
2289 				 * to indicate a wildcard listen host.
2290 				 */
2291 				xasprintf(&arg2, "*:%s", arg);
2292 			} else {
2293 				arg2 = xstrdup(arg);
2294 				p = hpdelim(&arg);
2295 				if (p == NULL) {
2296 					fatal("%s line %d: %s missing host",
2297 					    filename, linenum, keyword);
2298 				}
2299 				p = cleanhostname(p);
2300 			}
2301 			if (arg == NULL ||
2302 			    ((port = permitopen_port(arg)) < 0)) {
2303 				fatal("%s line %d: %s bad port number",
2304 				    filename, linenum, keyword);
2305 			}
2306 			if (*activep && uvalue == 0) {
2307 				opt_array_append(filename, linenum, keyword,
2308 				    chararrayptr, uintptr, arg2);
2309 			}
2310 			free(arg2);
2311 		}
2312 		break;
2313 
2314 	case sForceCommand:
2315 		if (str == NULL || *str == '\0')
2316 			fatal("%s line %d: %s missing argument.",
2317 			    filename, linenum, keyword);
2318 		len = strspn(str, WHITESPACE);
2319 		if (*activep && options->adm_forced_command == NULL)
2320 			options->adm_forced_command = xstrdup(str + len);
2321 		argv_consume(&ac);
2322 		break;
2323 
2324 	case sChrootDirectory:
2325 		charptr = &options->chroot_directory;
2326 
2327 		arg = argv_next(&ac, &av);
2328 		if (!arg || *arg == '\0')
2329 			fatal("%s line %d: %s missing argument.",
2330 			    filename, linenum, keyword);
2331 		if (*activep && *charptr == NULL)
2332 			*charptr = xstrdup(arg);
2333 		break;
2334 
2335 	case sTrustedUserCAKeys:
2336 		charptr = &options->trusted_user_ca_keys;
2337 		goto parse_filename;
2338 
2339 	case sRevokedKeys:
2340 		charptr = &options->revoked_keys_file;
2341 		goto parse_filename;
2342 
2343 	case sSecurityKeyProvider:
2344 		charptr = &options->sk_provider;
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 = strcasecmp(arg, "internal") == 0 ?
2351 			    xstrdup(arg) : derelativise_path(arg);
2352 			/* increase optional counter */
2353 			if (intptr != NULL)
2354 				*intptr = *intptr + 1;
2355 		}
2356 		break;
2357 
2358 	case sIPQoS:
2359 		arg = argv_next(&ac, &av);
2360 		if (!arg || *arg == '\0')
2361 			fatal("%s line %d: %s missing argument.",
2362 			    filename, linenum, keyword);
2363 		if ((value = parse_ipqos(arg)) == -1)
2364 			fatal("%s line %d: Bad %s value: %s",
2365 			    filename, linenum, keyword, arg);
2366 		arg = argv_next(&ac, &av);
2367 		if (arg == NULL)
2368 			value2 = value;
2369 		else if ((value2 = parse_ipqos(arg)) == -1)
2370 			fatal("%s line %d: Bad %s value: %s",
2371 			    filename, linenum, keyword, arg);
2372 		if (*activep) {
2373 			options->ip_qos_interactive = value;
2374 			options->ip_qos_bulk = value2;
2375 		}
2376 		break;
2377 
2378 	case sVersionAddendum:
2379 		if (str == NULL || *str == '\0')
2380 			fatal("%s line %d: %s missing argument.",
2381 			    filename, linenum, keyword);
2382 		len = strspn(str, WHITESPACE);
2383 		if (strchr(str + len, '\r') != NULL) {
2384 			fatal("%.200s line %d: Invalid %s argument",
2385 			    filename, linenum, keyword);
2386 		}
2387 		if ((arg = strchr(line, '#')) != NULL) {
2388 			*arg = '\0';
2389 			rtrim(line);
2390 		}
2391 		if (*activep && options->version_addendum == NULL) {
2392 			if (strcasecmp(str + len, "none") == 0)
2393 				options->version_addendum = xstrdup("");
2394 			else
2395 				options->version_addendum = xstrdup(str + len);
2396 		}
2397 		argv_consume(&ac);
2398 		break;
2399 
2400 	case sAuthorizedKeysCommand:
2401 		charptr = &options->authorized_keys_command;
2402  parse_command:
2403 		len = strspn(str, WHITESPACE);
2404 		if (str[len] != '/' && strcasecmp(str + len, "none") != 0) {
2405 			fatal("%.200s line %d: %s must be an absolute path",
2406 			    filename, linenum, keyword);
2407 		}
2408 		if (*activep && *charptr == NULL)
2409 			*charptr = xstrdup(str + len);
2410 		argv_consume(&ac);
2411 		break;
2412 
2413 	case sAuthorizedKeysCommandUser:
2414 		charptr = &options->authorized_keys_command_user;
2415  parse_localuser:
2416 		arg = argv_next(&ac, &av);
2417 		if (!arg || *arg == '\0') {
2418 			fatal("%s line %d: missing %s argument.",
2419 			    filename, linenum, keyword);
2420 		}
2421 		if (*activep && *charptr == NULL)
2422 			*charptr = xstrdup(arg);
2423 		break;
2424 
2425 	case sAuthorizedPrincipalsCommand:
2426 		charptr = &options->authorized_principals_command;
2427 		goto parse_command;
2428 
2429 	case sAuthorizedPrincipalsCommandUser:
2430 		charptr = &options->authorized_principals_command_user;
2431 		goto parse_localuser;
2432 
2433 	case sAuthenticationMethods:
2434 		found = options->num_auth_methods == 0;
2435 		value = 0; /* seen "any" pseudo-method */
2436 		value2 = 0; /* successfully parsed any method */
2437 		while ((arg = argv_next(&ac, &av)) != NULL) {
2438 			if (strcmp(arg, "any") == 0) {
2439 				if (options->num_auth_methods > 0) {
2440 					fatal("%s line %d: \"any\" must "
2441 					    "appear alone in %s",
2442 					    filename, linenum, keyword);
2443 				}
2444 				value = 1;
2445 			} else if (value) {
2446 				fatal("%s line %d: \"any\" must appear "
2447 				    "alone in %s", filename, linenum, keyword);
2448 			} else if (auth2_methods_valid(arg, 0) != 0) {
2449 				fatal("%s line %d: invalid %s method list.",
2450 				    filename, linenum, keyword);
2451 			}
2452 			value2 = 1;
2453 			if (!found || !*activep)
2454 				continue;
2455 			opt_array_append(filename, linenum, keyword,
2456 			    &options->auth_methods,
2457 			    &options->num_auth_methods, arg);
2458 		}
2459 		if (value2 == 0) {
2460 			fatal("%s line %d: no %s specified",
2461 			    filename, linenum, keyword);
2462 		}
2463 		break;
2464 
2465 	case sStreamLocalBindMask:
2466 		arg = argv_next(&ac, &av);
2467 		if (!arg || *arg == '\0')
2468 			fatal("%s line %d: %s missing argument.",
2469 			    filename, linenum, keyword);
2470 		/* Parse mode in octal format */
2471 		value = strtol(arg, &p, 8);
2472 		if (arg == p || value < 0 || value > 0777)
2473 			fatal("%s line %d: Invalid %s.",
2474 			    filename, linenum, keyword);
2475 		if (*activep)
2476 			options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
2477 		break;
2478 
2479 	case sStreamLocalBindUnlink:
2480 		intptr = &options->fwd_opts.streamlocal_bind_unlink;
2481 		goto parse_flag;
2482 
2483 	case sFingerprintHash:
2484 		arg = argv_next(&ac, &av);
2485 		if (!arg || *arg == '\0')
2486 			fatal("%s line %d: %s missing argument.",
2487 			    filename, linenum, keyword);
2488 		if ((value = ssh_digest_alg_by_name(arg)) == -1)
2489 			fatal("%.200s line %d: Invalid %s algorithm \"%s\".",
2490 			    filename, linenum, keyword, arg);
2491 		if (*activep)
2492 			options->fingerprint_hash = value;
2493 		break;
2494 
2495 	case sExposeAuthInfo:
2496 		intptr = &options->expose_userauth_info;
2497 		goto parse_flag;
2498 
2499 	case sRDomain:
2500 #if !defined(__OpenBSD__) && !defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
2501 		fatal("%s line %d: setting RDomain not supported on this "
2502 		    "platform.", filename, linenum);
2503 #endif
2504 		charptr = &options->routing_domain;
2505 		arg = argv_next(&ac, &av);
2506 		if (!arg || *arg == '\0')
2507 			fatal("%s line %d: %s missing argument.",
2508 			    filename, linenum, keyword);
2509 		if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
2510 		    !valid_rdomain(arg))
2511 			fatal("%s line %d: invalid routing domain",
2512 			    filename, linenum);
2513 		if (*activep && *charptr == NULL)
2514 			*charptr = xstrdup(arg);
2515 		break;
2516 
2517 	case sRequiredRSASize:
2518 		intptr = &options->required_rsa_size;
2519 		goto parse_int;
2520 
2521 	case sChannelTimeout:
2522 		uvalue = options->num_channel_timeouts;
2523 		i = 0;
2524 		while ((arg = argv_next(&ac, &av)) != NULL) {
2525 			/* Allow "none" only in first position */
2526 			if (strcasecmp(arg, "none") == 0) {
2527 				if (i > 0 || ac > 0) {
2528 					error("%s line %d: keyword %s \"none\" "
2529 					    "argument must appear alone.",
2530 					    filename, linenum, keyword);
2531 					goto out;
2532 				}
2533 			} else if (parse_pattern_interval(arg,
2534 			    NULL, NULL) != 0) {
2535 				fatal("%s line %d: invalid channel timeout %s",
2536 				    filename, linenum, arg);
2537 			}
2538 			if (!*activep || uvalue != 0)
2539 				continue;
2540 			opt_array_append(filename, linenum, keyword,
2541 			    &options->channel_timeouts,
2542 			    &options->num_channel_timeouts, arg);
2543 		}
2544 		break;
2545 
2546 	case sUnusedConnectionTimeout:
2547 		intptr = &options->unused_connection_timeout;
2548 		/* peek at first arg for "none" so we can reuse parse_time */
2549 		if (av[0] != NULL && strcasecmp(av[0], "none") == 0) {
2550 			(void)argv_next(&ac, &av); /* consume arg */
2551 			if (*activep)
2552 				*intptr = 0;
2553 			break;
2554 		}
2555 		goto parse_time;
2556 
2557 	case sUseBlacklist:
2558 		intptr = &options->use_blacklist;
2559 		goto parse_flag;
2560 
2561 	case sDeprecated:
2562 	case sIgnore:
2563 	case sUnsupported:
2564 		do_log2(opcode == sIgnore ?
2565 		    SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
2566 		    "%s line %d: %s option %s", filename, linenum,
2567 		    opcode == sUnsupported ? "Unsupported" : "Deprecated",
2568 		    keyword);
2569 		argv_consume(&ac);
2570 		break;
2571 
2572 	default:
2573 		fatal("%s line %d: Missing handler for opcode %s (%d)",
2574 		    filename, linenum, keyword, opcode);
2575 	}
2576 	/* Check that there is no garbage at end of line. */
2577 	if (ac > 0) {
2578 		error("%.200s line %d: keyword %s extra arguments "
2579 		    "at end of line", filename, linenum, keyword);
2580 		goto out;
2581 	}
2582 
2583 	/* success */
2584 	ret = 0;
2585  out:
2586 	argv_free(oav, oac);
2587 	return ret;
2588 }
2589 
2590 int
2591 process_server_config_line(ServerOptions *options, char *line,
2592     const char *filename, int linenum, int *activep,
2593     struct connection_info *connectinfo, struct include_list *includes)
2594 {
2595 	int inc_flags = 0;
2596 
2597 	return process_server_config_line_depth(options, line, filename,
2598 	    linenum, activep, connectinfo, &inc_flags, 0, includes);
2599 }
2600 
2601 
2602 /* Reads the server configuration file. */
2603 
2604 void
2605 load_server_config(const char *filename, struct sshbuf *conf)
2606 {
2607 	struct stat st;
2608 	char *line = NULL, *cp;
2609 	size_t linesize = 0;
2610 	FILE *f;
2611 	int r;
2612 
2613 	debug2_f("filename %s", filename);
2614 	if ((f = fopen(filename, "r")) == NULL) {
2615 		perror(filename);
2616 		exit(1);
2617 	}
2618 	sshbuf_reset(conf);
2619 	/* grow buffer, so realloc is avoided for large config files */
2620 	if (fstat(fileno(f), &st) == 0 && st.st_size > 0 &&
2621 	    (r = sshbuf_allocate(conf, st.st_size)) != 0)
2622 		fatal_fr(r, "allocate");
2623 	while (getline(&line, &linesize, f) != -1) {
2624 		/*
2625 		 * Strip whitespace
2626 		 * NB - preserve newlines, they are needed to reproduce
2627 		 * line numbers later for error messages
2628 		 */
2629 		cp = line + strspn(line, " \t\r");
2630 		if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
2631 			fatal_fr(r, "sshbuf_put");
2632 	}
2633 	free(line);
2634 	if ((r = sshbuf_put_u8(conf, 0)) != 0)
2635 		fatal_fr(r, "sshbuf_put_u8");
2636 	fclose(f);
2637 	debug2_f("done config len = %zu", sshbuf_len(conf));
2638 }
2639 
2640 void
2641 parse_server_match_config(ServerOptions *options,
2642    struct include_list *includes, struct connection_info *connectinfo)
2643 {
2644 	ServerOptions mo;
2645 
2646 	initialize_server_options(&mo);
2647 	parse_server_config(&mo, "reprocess config", cfg, includes,
2648 	    connectinfo, 0);
2649 	copy_set_server_options(options, &mo, 0);
2650 }
2651 
2652 int parse_server_match_testspec(struct connection_info *ci, char *spec)
2653 {
2654 	char *p;
2655 
2656 	while ((p = strsep(&spec, ",")) && *p != '\0') {
2657 		if (strncmp(p, "addr=", 5) == 0) {
2658 			ci->address = xstrdup(p + 5);
2659 		} else if (strncmp(p, "host=", 5) == 0) {
2660 			ci->host = xstrdup(p + 5);
2661 		} else if (strncmp(p, "user=", 5) == 0) {
2662 			ci->user = xstrdup(p + 5);
2663 		} else if (strncmp(p, "laddr=", 6) == 0) {
2664 			ci->laddress = xstrdup(p + 6);
2665 		} else if (strncmp(p, "rdomain=", 8) == 0) {
2666 			ci->rdomain = xstrdup(p + 8);
2667 		} else if (strncmp(p, "lport=", 6) == 0) {
2668 			ci->lport = a2port(p + 6);
2669 			if (ci->lport == -1) {
2670 				fprintf(stderr, "Invalid port '%s' in test mode"
2671 				    " specification %s\n", p+6, p);
2672 				return -1;
2673 			}
2674 		} else {
2675 			fprintf(stderr, "Invalid test mode specification %s\n",
2676 			    p);
2677 			return -1;
2678 		}
2679 	}
2680 	return 0;
2681 }
2682 
2683 void
2684 servconf_merge_subsystems(ServerOptions *dst, ServerOptions *src)
2685 {
2686 	u_int i, j, found;
2687 
2688 	for (i = 0; i < src->num_subsystems; i++) {
2689 		found = 0;
2690 		for (j = 0; j < dst->num_subsystems; j++) {
2691 			if (strcmp(src->subsystem_name[i],
2692 			    dst->subsystem_name[j]) == 0) {
2693 				found = 1;
2694 				break;
2695 			}
2696 		}
2697 		if (found) {
2698 			debug_f("override \"%s\"", dst->subsystem_name[j]);
2699 			free(dst->subsystem_command[j]);
2700 			free(dst->subsystem_args[j]);
2701 			dst->subsystem_command[j] =
2702 			    xstrdup(src->subsystem_command[i]);
2703 			dst->subsystem_args[j] =
2704 			    xstrdup(src->subsystem_args[i]);
2705 			continue;
2706 		}
2707 		debug_f("add \"%s\"", src->subsystem_name[i]);
2708 		dst->subsystem_name = xrecallocarray(
2709 		    dst->subsystem_name, dst->num_subsystems,
2710 		    dst->num_subsystems + 1, sizeof(*dst->subsystem_name));
2711 		dst->subsystem_command = xrecallocarray(
2712 		    dst->subsystem_command, dst->num_subsystems,
2713 		    dst->num_subsystems + 1, sizeof(*dst->subsystem_command));
2714 		dst->subsystem_args = xrecallocarray(
2715 		    dst->subsystem_args, dst->num_subsystems,
2716 		    dst->num_subsystems + 1, sizeof(*dst->subsystem_args));
2717 		j = dst->num_subsystems++;
2718 		dst->subsystem_name[j] = xstrdup(src->subsystem_name[i]);
2719 		dst->subsystem_command[j] = xstrdup(src->subsystem_command[i]);
2720 		dst->subsystem_args[j] = xstrdup(src->subsystem_args[i]);
2721 	}
2722 }
2723 
2724 /*
2725  * Copy any supported values that are set.
2726  *
2727  * If the preauth flag is set, we do not bother copying the string or
2728  * array values that are not used pre-authentication, because any that we
2729  * do use must be explicitly sent in mm_getpwnamallow().
2730  */
2731 void
2732 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2733 {
2734 #define M_CP_INTOPT(n) do {\
2735 	if (src->n != -1) \
2736 		dst->n = src->n; \
2737 } while (0)
2738 
2739 	M_CP_INTOPT(password_authentication);
2740 	M_CP_INTOPT(gss_authentication);
2741 	M_CP_INTOPT(pubkey_authentication);
2742 	M_CP_INTOPT(pubkey_auth_options);
2743 	M_CP_INTOPT(kerberos_authentication);
2744 	M_CP_INTOPT(hostbased_authentication);
2745 	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
2746 	M_CP_INTOPT(kbd_interactive_authentication);
2747 	M_CP_INTOPT(permit_root_login);
2748 	M_CP_INTOPT(permit_empty_passwd);
2749 	M_CP_INTOPT(ignore_rhosts);
2750 
2751 	M_CP_INTOPT(allow_tcp_forwarding);
2752 	M_CP_INTOPT(allow_streamlocal_forwarding);
2753 	M_CP_INTOPT(allow_agent_forwarding);
2754 	M_CP_INTOPT(disable_forwarding);
2755 	M_CP_INTOPT(expose_userauth_info);
2756 	M_CP_INTOPT(permit_tun);
2757 	M_CP_INTOPT(fwd_opts.gateway_ports);
2758 	M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
2759 	M_CP_INTOPT(x11_display_offset);
2760 	M_CP_INTOPT(x11_forwarding);
2761 	M_CP_INTOPT(x11_use_localhost);
2762 	M_CP_INTOPT(permit_tty);
2763 	M_CP_INTOPT(permit_user_rc);
2764 	M_CP_INTOPT(max_sessions);
2765 	M_CP_INTOPT(max_authtries);
2766 	M_CP_INTOPT(client_alive_count_max);
2767 	M_CP_INTOPT(client_alive_interval);
2768 	M_CP_INTOPT(ip_qos_interactive);
2769 	M_CP_INTOPT(ip_qos_bulk);
2770 	M_CP_INTOPT(rekey_limit);
2771 	M_CP_INTOPT(rekey_interval);
2772 	M_CP_INTOPT(log_level);
2773 	M_CP_INTOPT(required_rsa_size);
2774 	M_CP_INTOPT(unused_connection_timeout);
2775 
2776 	/*
2777 	 * The bind_mask is a mode_t that may be unsigned, so we can't use
2778 	 * M_CP_INTOPT - it does a signed comparison that causes compiler
2779 	 * warnings.
2780 	 */
2781 	if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
2782 		dst->fwd_opts.streamlocal_bind_mask =
2783 		    src->fwd_opts.streamlocal_bind_mask;
2784 	}
2785 
2786 	/* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
2787 #define M_CP_STROPT(n) do {\
2788 	if (src->n != NULL && dst->n != src->n) { \
2789 		free(dst->n); \
2790 		dst->n = src->n; \
2791 	} \
2792 } while(0)
2793 #define M_CP_STRARRAYOPT(s, num_s) do {\
2794 	u_int i; \
2795 	if (src->num_s != 0) { \
2796 		for (i = 0; i < dst->num_s; i++) \
2797 			free(dst->s[i]); \
2798 		free(dst->s); \
2799 		dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2800 		for (i = 0; i < src->num_s; i++) \
2801 			dst->s[i] = xstrdup(src->s[i]); \
2802 		dst->num_s = src->num_s; \
2803 	} \
2804 } while(0)
2805 
2806 	/* See comment in servconf.h */
2807 	COPY_MATCH_STRING_OPTS();
2808 
2809 	/* Arguments that accept '+...' need to be expanded */
2810 	assemble_algorithms(dst);
2811 
2812 	/*
2813 	 * The only things that should be below this point are string options
2814 	 * which are only used after authentication.
2815 	 */
2816 	if (preauth)
2817 		return;
2818 
2819 	/* These options may be "none" to clear a global setting */
2820 	M_CP_STROPT(adm_forced_command);
2821 	if (option_clear_or_none(dst->adm_forced_command)) {
2822 		free(dst->adm_forced_command);
2823 		dst->adm_forced_command = NULL;
2824 	}
2825 	M_CP_STROPT(chroot_directory);
2826 	if (option_clear_or_none(dst->chroot_directory)) {
2827 		free(dst->chroot_directory);
2828 		dst->chroot_directory = NULL;
2829 	}
2830 
2831 	/* Subsystems require merging. */
2832 	servconf_merge_subsystems(dst, src);
2833 }
2834 
2835 #undef M_CP_INTOPT
2836 #undef M_CP_STROPT
2837 #undef M_CP_STRARRAYOPT
2838 
2839 #define SERVCONF_MAX_DEPTH	16
2840 static void
2841 parse_server_config_depth(ServerOptions *options, const char *filename,
2842     struct sshbuf *conf, struct include_list *includes,
2843     struct connection_info *connectinfo, int flags, int *activep, int depth)
2844 {
2845 	int linenum, bad_options = 0;
2846 	char *cp, *obuf, *cbuf;
2847 
2848 	if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
2849 		fatal("Too many recursive configuration includes");
2850 
2851 	debug2_f("config %s len %zu%s", filename, sshbuf_len(conf),
2852 	    (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : ""));
2853 
2854 	if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
2855 		fatal_f("sshbuf_dup_string failed");
2856 	linenum = 1;
2857 	while ((cp = strsep(&cbuf, "\n")) != NULL) {
2858 		if (process_server_config_line_depth(options, cp,
2859 		    filename, linenum++, activep, connectinfo, &flags,
2860 		    depth, includes) != 0)
2861 			bad_options++;
2862 	}
2863 	free(obuf);
2864 	if (bad_options > 0)
2865 		fatal("%s: terminating, %d bad configuration options",
2866 		    filename, bad_options);
2867 }
2868 
2869 void
2870 parse_server_config(ServerOptions *options, const char *filename,
2871     struct sshbuf *conf, struct include_list *includes,
2872     struct connection_info *connectinfo, int reexec)
2873 {
2874 	int active = connectinfo ? 0 : 1;
2875 	parse_server_config_depth(options, filename, conf, includes,
2876 	    connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0);
2877 	if (!reexec)
2878 		process_queued_listen_addrs(options);
2879 }
2880 
2881 static const char *
2882 fmt_multistate_int(int val, const struct multistate *m)
2883 {
2884 	u_int i;
2885 
2886 	for (i = 0; m[i].key != NULL; i++) {
2887 		if (m[i].value == val)
2888 			return m[i].key;
2889 	}
2890 	return "UNKNOWN";
2891 }
2892 
2893 static const char *
2894 fmt_intarg(ServerOpCodes code, int val)
2895 {
2896 	if (val == -1)
2897 		return "unset";
2898 	switch (code) {
2899 	case sAddressFamily:
2900 		return fmt_multistate_int(val, multistate_addressfamily);
2901 	case sPermitRootLogin:
2902 		return fmt_multistate_int(val, multistate_permitrootlogin);
2903 	case sGatewayPorts:
2904 		return fmt_multistate_int(val, multistate_gatewayports);
2905 	case sCompression:
2906 		return fmt_multistate_int(val, multistate_compression);
2907 	case sAllowTcpForwarding:
2908 		return fmt_multistate_int(val, multistate_tcpfwd);
2909 	case sAllowStreamLocalForwarding:
2910 		return fmt_multistate_int(val, multistate_tcpfwd);
2911 	case sIgnoreRhosts:
2912 		return fmt_multistate_int(val, multistate_ignore_rhosts);
2913 	case sFingerprintHash:
2914 		return ssh_digest_alg_name(val);
2915 	default:
2916 		switch (val) {
2917 		case 0:
2918 			return "no";
2919 		case 1:
2920 			return "yes";
2921 		default:
2922 			return "UNKNOWN";
2923 		}
2924 	}
2925 }
2926 
2927 static void
2928 dump_cfg_int(ServerOpCodes code, int val)
2929 {
2930 	if (code == sUnusedConnectionTimeout && val == 0) {
2931 		printf("%s none\n", lookup_opcode_name(code));
2932 		return;
2933 	}
2934 	printf("%s %d\n", lookup_opcode_name(code), val);
2935 }
2936 
2937 static void
2938 dump_cfg_oct(ServerOpCodes code, int val)
2939 {
2940 	printf("%s 0%o\n", lookup_opcode_name(code), val);
2941 }
2942 
2943 static void
2944 dump_cfg_fmtint(ServerOpCodes code, int val)
2945 {
2946 	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2947 }
2948 
2949 static void
2950 dump_cfg_string(ServerOpCodes code, const char *val)
2951 {
2952 	printf("%s %s\n", lookup_opcode_name(code),
2953 	    val == NULL ? "none" : val);
2954 }
2955 
2956 static void
2957 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
2958 {
2959 	u_int i;
2960 
2961 	for (i = 0; i < count; i++)
2962 		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2963 }
2964 
2965 static void
2966 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
2967 {
2968 	u_int i;
2969 
2970 	switch (code) {
2971 	case sAuthenticationMethods:
2972 	case sChannelTimeout:
2973 		break;
2974 	default:
2975 		if (count <= 0)
2976 			return;
2977 		break;
2978 	}
2979 
2980 	printf("%s", lookup_opcode_name(code));
2981 	for (i = 0; i < count; i++)
2982 		printf(" %s",  vals[i]);
2983 	if (code == sAuthenticationMethods && count == 0)
2984 		printf(" any");
2985 	else if (code == sChannelTimeout && count == 0)
2986 		printf(" none");
2987 	printf("\n");
2988 }
2989 
2990 static char *
2991 format_listen_addrs(struct listenaddr *la)
2992 {
2993 	int r;
2994 	struct addrinfo *ai;
2995 	char addr[NI_MAXHOST], port[NI_MAXSERV];
2996 	char *laddr1 = xstrdup(""), *laddr2 = NULL;
2997 
2998 	/*
2999 	 * ListenAddress must be after Port.  add_one_listen_addr pushes
3000 	 * addresses onto a stack, so to maintain ordering we need to
3001 	 * print these in reverse order.
3002 	 */
3003 	for (ai = la->addrs; ai; ai = ai->ai_next) {
3004 		if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
3005 		    sizeof(addr), port, sizeof(port),
3006 		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
3007 			error("getnameinfo: %.100s", ssh_gai_strerror(r));
3008 			continue;
3009 		}
3010 		laddr2 = laddr1;
3011 		if (ai->ai_family == AF_INET6) {
3012 			xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
3013 			    addr, port,
3014 			    la->rdomain == NULL ? "" : " rdomain ",
3015 			    la->rdomain == NULL ? "" : la->rdomain,
3016 			    laddr2);
3017 		} else {
3018 			xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
3019 			    addr, port,
3020 			    la->rdomain == NULL ? "" : " rdomain ",
3021 			    la->rdomain == NULL ? "" : la->rdomain,
3022 			    laddr2);
3023 		}
3024 		free(laddr2);
3025 	}
3026 	return laddr1;
3027 }
3028 
3029 void
3030 dump_config(ServerOptions *o)
3031 {
3032 	char *s;
3033 	u_int i;
3034 
3035 	/* these are usually at the top of the config */
3036 	for (i = 0; i < o->num_ports; i++)
3037 		printf("port %d\n", o->ports[i]);
3038 	dump_cfg_fmtint(sAddressFamily, o->address_family);
3039 
3040 	for (i = 0; i < o->num_listen_addrs; i++) {
3041 		s = format_listen_addrs(&o->listen_addrs[i]);
3042 		printf("%s", s);
3043 		free(s);
3044 	}
3045 
3046 	/* integer arguments */
3047 #ifdef USE_PAM
3048 	dump_cfg_fmtint(sUsePAM, o->use_pam);
3049 #endif
3050 	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
3051 	dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
3052 	dump_cfg_int(sMaxAuthTries, o->max_authtries);
3053 	dump_cfg_int(sMaxSessions, o->max_sessions);
3054 	dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
3055 	dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
3056 	dump_cfg_int(sRequiredRSASize, o->required_rsa_size);
3057 	dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
3058 	dump_cfg_int(sUnusedConnectionTimeout, o->unused_connection_timeout);
3059 
3060 	/* formatted integer arguments */
3061 	dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
3062 	dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
3063 	dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
3064 	dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
3065 	dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
3066 	    o->hostbased_uses_name_from_packet_only);
3067 	dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
3068 #ifdef KRB5
3069 	dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
3070 	dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
3071 	dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
3072 # ifdef USE_AFS
3073 	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
3074 # endif
3075 #endif
3076 #ifdef GSSAPI
3077 	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
3078 	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
3079 #endif
3080 	dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
3081 	dump_cfg_fmtint(sKbdInteractiveAuthentication,
3082 	    o->kbd_interactive_authentication);
3083 	dump_cfg_fmtint(sPrintMotd, o->print_motd);
3084 #ifndef DISABLE_LASTLOG
3085 	dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
3086 #endif
3087 	dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
3088 	dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
3089 	dump_cfg_fmtint(sPermitTTY, o->permit_tty);
3090 	dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
3091 	dump_cfg_fmtint(sStrictModes, o->strict_modes);
3092 	dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
3093 	dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
3094 	dump_cfg_fmtint(sCompression, o->compression);
3095 	dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
3096 	dump_cfg_fmtint(sUseDNS, o->use_dns);
3097 	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
3098 	dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
3099 	dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
3100 	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
3101 	dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
3102 	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
3103 	dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
3104 	dump_cfg_fmtint(sUseBlacklist, o->use_blacklist);
3105 
3106 	/* string arguments */
3107 	dump_cfg_string(sPidFile, o->pid_file);
3108 	dump_cfg_string(sModuliFile, o->moduli_file);
3109 	dump_cfg_string(sXAuthLocation, o->xauth_location);
3110 	dump_cfg_string(sCiphers, o->ciphers);
3111 	dump_cfg_string(sMacs, o->macs);
3112 	dump_cfg_string(sBanner, o->banner);
3113 	dump_cfg_string(sForceCommand, o->adm_forced_command);
3114 	dump_cfg_string(sChrootDirectory, o->chroot_directory);
3115 	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
3116 	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
3117 	dump_cfg_string(sSecurityKeyProvider, o->sk_provider);
3118 	dump_cfg_string(sAuthorizedPrincipalsFile,
3119 	    o->authorized_principals_file);
3120 	dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
3121 	    ? "none" : o->version_addendum);
3122 	dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
3123 	dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
3124 	dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
3125 	dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
3126 	dump_cfg_string(sHostKeyAgent, o->host_key_agent);
3127 	dump_cfg_string(sKexAlgorithms, o->kex_algorithms);
3128 	dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms);
3129 	dump_cfg_string(sHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
3130 	dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
3131 	dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
3132 #if defined(__OpenBSD__) || defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
3133 	dump_cfg_string(sRDomain, o->routing_domain);
3134 #endif
3135 
3136 	/* string arguments requiring a lookup */
3137 	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
3138 	dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
3139 
3140 	/* string array arguments */
3141 	dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
3142 	    o->authorized_keys_files);
3143 	dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
3144 	    o->host_key_files);
3145 	dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
3146 	    o->host_cert_files);
3147 	dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
3148 	dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
3149 	dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
3150 	dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
3151 	dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
3152 	dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv);
3153 	dump_cfg_strarray_oneline(sAuthenticationMethods,
3154 	    o->num_auth_methods, o->auth_methods);
3155 	dump_cfg_strarray_oneline(sLogVerbose,
3156 	    o->num_log_verbose, o->log_verbose);
3157 	dump_cfg_strarray_oneline(sChannelTimeout,
3158 	    o->num_channel_timeouts, o->channel_timeouts);
3159 
3160 	/* other arguments */
3161 	for (i = 0; i < o->num_subsystems; i++)
3162 		printf("subsystem %s %s\n", o->subsystem_name[i],
3163 		    o->subsystem_args[i]);
3164 
3165 	printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
3166 	    o->max_startups_rate, o->max_startups);
3167 	printf("persourcemaxstartups ");
3168 	if (o->per_source_max_startups == INT_MAX)
3169 		printf("none\n");
3170 	else
3171 		printf("%d\n", o->per_source_max_startups);
3172 	printf("persourcenetblocksize %d:%d\n", o->per_source_masklen_ipv4,
3173 	    o->per_source_masklen_ipv6);
3174 
3175 	s = NULL;
3176 	for (i = 0; tunmode_desc[i].val != -1; i++) {
3177 		if (tunmode_desc[i].val == o->permit_tun) {
3178 			s = tunmode_desc[i].text;
3179 			break;
3180 		}
3181 	}
3182 	dump_cfg_string(sPermitTunnel, s);
3183 
3184 	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
3185 	printf("%s\n", iptos2str(o->ip_qos_bulk));
3186 
3187 	printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
3188 	    o->rekey_interval);
3189 
3190 	printf("permitopen");
3191 	if (o->num_permitted_opens == 0)
3192 		printf(" any");
3193 	else {
3194 		for (i = 0; i < o->num_permitted_opens; i++)
3195 			printf(" %s", o->permitted_opens[i]);
3196 	}
3197 	printf("\n");
3198 	printf("permitlisten");
3199 	if (o->num_permitted_listens == 0)
3200 		printf(" any");
3201 	else {
3202 		for (i = 0; i < o->num_permitted_listens; i++)
3203 			printf(" %s", o->permitted_listens[i]);
3204 	}
3205 	printf("\n");
3206 
3207 	if (o->permit_user_env_allowlist == NULL) {
3208 		dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
3209 	} else {
3210 		printf("permituserenvironment %s\n",
3211 		    o->permit_user_env_allowlist);
3212 	}
3213 
3214 	printf("pubkeyauthoptions");
3215 	if (o->pubkey_auth_options == 0)
3216 		printf(" none");
3217 	if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED)
3218 		printf(" touch-required");
3219 	if (o->pubkey_auth_options & PUBKEYAUTH_VERIFY_REQUIRED)
3220 		printf(" verify-required");
3221 	printf("\n");
3222 }
3223