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