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