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