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