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