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