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