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