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