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