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