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