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