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