xref: /openbsd-src/usr.bin/ssh/readconf.c (revision 6c6408334dbede3a2c0dcd9ff9c489157df0c856)
1 /* $OpenBSD: readconf.c,v 1.283 2018/02/23 15:58:37 markus Exp $ */
2 /*
3  * Author: Tatu Ylonen <ylo@cs.hut.fi>
4  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5  *                    All rights reserved
6  * Functions for reading the configuration files.
7  *
8  * As far as I am concerned, the code I have written for this software
9  * can be used freely for any purpose.  Any derived versions of this
10  * software must be clearly marked as such, and if the derived work is
11  * incompatible with the protocol description in the RFC file, it must be
12  * called by a name other than "ssh" or "Secure Shell".
13  */
14 
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <sys/socket.h>
18 #include <sys/wait.h>
19 #include <sys/un.h>
20 
21 #include <netinet/in.h>
22 #include <netinet/ip.h>
23 
24 #include <ctype.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <glob.h>
28 #include <netdb.h>
29 #include <paths.h>
30 #include <pwd.h>
31 #include <signal.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <limits.h>
36 #include <util.h>
37 #include <vis.h>
38 
39 #include "xmalloc.h"
40 #include "ssh.h"
41 #include "compat.h"
42 #include "cipher.h"
43 #include "pathnames.h"
44 #include "log.h"
45 #include "sshkey.h"
46 #include "misc.h"
47 #include "readconf.h"
48 #include "match.h"
49 #include "kex.h"
50 #include "mac.h"
51 #include "uidswap.h"
52 #include "myproposal.h"
53 #include "digest.h"
54 
55 /* Format of the configuration file:
56 
57    # Configuration data is parsed as follows:
58    #  1. command line options
59    #  2. user-specific file
60    #  3. system-wide file
61    # Any configuration value is only changed the first time it is set.
62    # Thus, host-specific definitions should be at the beginning of the
63    # configuration file, and defaults at the end.
64 
65    # Host-specific declarations.  These may override anything above.  A single
66    # host may match multiple declarations; these are processed in the order
67    # that they are given in.
68 
69    Host *.ngs.fi ngs.fi
70      User foo
71 
72    Host fake.com
73      HostName another.host.name.real.org
74      User blaah
75      Port 34289
76      ForwardX11 no
77      ForwardAgent no
78 
79    Host books.com
80      RemoteForward 9999 shadows.cs.hut.fi:9999
81      Ciphers 3des-cbc
82 
83    Host fascist.blob.com
84      Port 23123
85      User tylonen
86      PasswordAuthentication no
87 
88    Host puukko.hut.fi
89      User t35124p
90      ProxyCommand ssh-proxy %h %p
91 
92    Host *.fr
93      PublicKeyAuthentication no
94 
95    Host *.su
96      Ciphers aes128-ctr
97      PasswordAuthentication no
98 
99    Host vpn.fake.com
100      Tunnel yes
101      TunnelDevice 3
102 
103    # Defaults for various options
104    Host *
105      ForwardAgent no
106      ForwardX11 no
107      PasswordAuthentication yes
108      RSAAuthentication yes
109      RhostsRSAAuthentication yes
110      StrictHostKeyChecking yes
111      TcpKeepAlive no
112      IdentityFile ~/.ssh/identity
113      Port 22
114      EscapeChar ~
115 
116 */
117 
118 static int read_config_file_depth(const char *filename, struct passwd *pw,
119     const char *host, const char *original_host, Options *options,
120     int flags, int *activep, int depth);
121 static int process_config_line_depth(Options *options, struct passwd *pw,
122     const char *host, const char *original_host, char *line,
123     const char *filename, int linenum, int *activep, int flags, int depth);
124 
125 /* Keyword tokens. */
126 
127 typedef enum {
128 	oBadOption,
129 	oHost, oMatch, oInclude,
130 	oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
131 	oGatewayPorts, oExitOnForwardFailure,
132 	oPasswordAuthentication, oRSAAuthentication,
133 	oChallengeResponseAuthentication, oXAuthLocation,
134 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
135 	oCertificateFile, oAddKeysToAgent, oIdentityAgent,
136 	oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
137 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
138 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
139 	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
140 	oUsePrivilegedPort, oLogFacility, oLogLevel, oCiphers, oMacs,
141 	oPubkeyAuthentication,
142 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
143 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
144 	oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider,
145 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
146 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
147 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
148 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
149 	oSendEnv, oControlPath, oControlMaster, oControlPersist,
150 	oHashKnownHosts,
151 	oTunnel, oTunnelDevice,
152 	oLocalCommand, oPermitLocalCommand, oRemoteCommand,
153 	oVisualHostKey,
154 	oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
155 	oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
156 	oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
157 	oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
158 	oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
159 	oPubkeyAcceptedKeyTypes, oProxyJump,
160 	oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
161 } OpCodes;
162 
163 /* Textual representations of the tokens. */
164 
165 static struct {
166 	const char *name;
167 	OpCodes opcode;
168 } keywords[] = {
169 	/* Deprecated options */
170 	{ "protocol", oIgnore }, /* NB. silently ignored */
171 	{ "cipher", oDeprecated },
172 	{ "fallbacktorsh", oDeprecated },
173 	{ "globalknownhostsfile2", oDeprecated },
174 	{ "rhostsauthentication", oDeprecated },
175 	{ "userknownhostsfile2", oDeprecated },
176 	{ "useroaming", oDeprecated },
177 	{ "usersh", oDeprecated },
178 
179 	/* Unsupported options */
180 	{ "afstokenpassing", oUnsupported },
181 	{ "kerberosauthentication", oUnsupported },
182 	{ "kerberostgtpassing", oUnsupported },
183 
184 	/* Sometimes-unsupported options */
185 #if defined(GSSAPI)
186 	{ "gssapiauthentication", oGssAuthentication },
187 	{ "gssapidelegatecredentials", oGssDelegateCreds },
188 # else
189 	{ "gssapiauthentication", oUnsupported },
190 	{ "gssapidelegatecredentials", oUnsupported },
191 #endif
192 #ifdef ENABLE_PKCS11
193 	{ "smartcarddevice", oPKCS11Provider },
194 	{ "pkcs11provider", oPKCS11Provider },
195 # else
196 	{ "smartcarddevice", oUnsupported },
197 	{ "pkcs11provider", oUnsupported },
198 #endif
199 	{ "rsaauthentication", oUnsupported },
200 	{ "rhostsrsaauthentication", oUnsupported },
201 	{ "compressionlevel", oUnsupported },
202 
203 	{ "forwardagent", oForwardAgent },
204 	{ "forwardx11", oForwardX11 },
205 	{ "forwardx11trusted", oForwardX11Trusted },
206 	{ "forwardx11timeout", oForwardX11Timeout },
207 	{ "exitonforwardfailure", oExitOnForwardFailure },
208 	{ "xauthlocation", oXAuthLocation },
209 	{ "gatewayports", oGatewayPorts },
210 	{ "useprivilegedport", oUsePrivilegedPort },
211 	{ "passwordauthentication", oPasswordAuthentication },
212 	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
213 	{ "kbdinteractivedevices", oKbdInteractiveDevices },
214 	{ "pubkeyauthentication", oPubkeyAuthentication },
215 	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
216 	{ "hostbasedauthentication", oHostbasedAuthentication },
217 	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
218 	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
219 	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
220 	{ "identityfile", oIdentityFile },
221 	{ "identityfile2", oIdentityFile },			/* obsolete */
222 	{ "identitiesonly", oIdentitiesOnly },
223 	{ "certificatefile", oCertificateFile },
224 	{ "addkeystoagent", oAddKeysToAgent },
225 	{ "identityagent", oIdentityAgent },
226 	{ "hostname", oHostName },
227 	{ "hostkeyalias", oHostKeyAlias },
228 	{ "proxycommand", oProxyCommand },
229 	{ "port", oPort },
230 	{ "ciphers", oCiphers },
231 	{ "macs", oMacs },
232 	{ "remoteforward", oRemoteForward },
233 	{ "localforward", oLocalForward },
234 	{ "user", oUser },
235 	{ "host", oHost },
236 	{ "match", oMatch },
237 	{ "escapechar", oEscapeChar },
238 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
239 	{ "userknownhostsfile", oUserKnownHostsFile },
240 	{ "connectionattempts", oConnectionAttempts },
241 	{ "batchmode", oBatchMode },
242 	{ "checkhostip", oCheckHostIP },
243 	{ "stricthostkeychecking", oStrictHostKeyChecking },
244 	{ "compression", oCompression },
245 	{ "tcpkeepalive", oTCPKeepAlive },
246 	{ "keepalive", oTCPKeepAlive },				/* obsolete */
247 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
248 	{ "syslogfacility", oLogFacility },
249 	{ "loglevel", oLogLevel },
250 	{ "dynamicforward", oDynamicForward },
251 	{ "preferredauthentications", oPreferredAuthentications },
252 	{ "hostkeyalgorithms", oHostKeyAlgorithms },
253 	{ "bindaddress", oBindAddress },
254 	{ "bindinterface", oBindInterface },
255 	{ "clearallforwardings", oClearAllForwardings },
256 	{ "enablesshkeysign", oEnableSSHKeysign },
257 	{ "verifyhostkeydns", oVerifyHostKeyDNS },
258 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
259 	{ "rekeylimit", oRekeyLimit },
260 	{ "connecttimeout", oConnectTimeout },
261 	{ "addressfamily", oAddressFamily },
262 	{ "serveraliveinterval", oServerAliveInterval },
263 	{ "serveralivecountmax", oServerAliveCountMax },
264 	{ "sendenv", oSendEnv },
265 	{ "controlpath", oControlPath },
266 	{ "controlmaster", oControlMaster },
267 	{ "controlpersist", oControlPersist },
268 	{ "hashknownhosts", oHashKnownHosts },
269 	{ "include", oInclude },
270 	{ "tunnel", oTunnel },
271 	{ "tunneldevice", oTunnelDevice },
272 	{ "localcommand", oLocalCommand },
273 	{ "permitlocalcommand", oPermitLocalCommand },
274 	{ "remotecommand", oRemoteCommand },
275 	{ "visualhostkey", oVisualHostKey },
276 	{ "kexalgorithms", oKexAlgorithms },
277 	{ "ipqos", oIPQoS },
278 	{ "requesttty", oRequestTTY },
279 	{ "proxyusefdpass", oProxyUseFdpass },
280 	{ "canonicaldomains", oCanonicalDomains },
281 	{ "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
282 	{ "canonicalizehostname", oCanonicalizeHostname },
283 	{ "canonicalizemaxdots", oCanonicalizeMaxDots },
284 	{ "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
285 	{ "streamlocalbindmask", oStreamLocalBindMask },
286 	{ "streamlocalbindunlink", oStreamLocalBindUnlink },
287 	{ "revokedhostkeys", oRevokedHostKeys },
288 	{ "fingerprinthash", oFingerprintHash },
289 	{ "updatehostkeys", oUpdateHostkeys },
290 	{ "hostbasedkeytypes", oHostbasedKeyTypes },
291 	{ "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
292 	{ "ignoreunknown", oIgnoreUnknown },
293 	{ "proxyjump", oProxyJump },
294 
295 	{ NULL, oBadOption }
296 };
297 
298 /*
299  * Adds a local TCP/IP port forward to options.  Never returns if there is an
300  * error.
301  */
302 
303 void
304 add_local_forward(Options *options, const struct Forward *newfwd)
305 {
306 	struct Forward *fwd;
307 	extern uid_t original_real_uid;
308 	int i;
309 
310 	if (!bind_permitted(newfwd->listen_port, original_real_uid) &&
311 	    newfwd->listen_path == NULL)
312 		fatal("Privileged ports can only be forwarded by root.");
313 	/* Don't add duplicates */
314 	for (i = 0; i < options->num_local_forwards; i++) {
315 		if (forward_equals(newfwd, options->local_forwards + i))
316 			return;
317 	}
318 	options->local_forwards = xreallocarray(options->local_forwards,
319 	    options->num_local_forwards + 1,
320 	    sizeof(*options->local_forwards));
321 	fwd = &options->local_forwards[options->num_local_forwards++];
322 
323 	fwd->listen_host = newfwd->listen_host;
324 	fwd->listen_port = newfwd->listen_port;
325 	fwd->listen_path = newfwd->listen_path;
326 	fwd->connect_host = newfwd->connect_host;
327 	fwd->connect_port = newfwd->connect_port;
328 	fwd->connect_path = newfwd->connect_path;
329 }
330 
331 /*
332  * Adds a remote TCP/IP port forward to options.  Never returns if there is
333  * an error.
334  */
335 
336 void
337 add_remote_forward(Options *options, const struct Forward *newfwd)
338 {
339 	struct Forward *fwd;
340 	int i;
341 
342 	/* Don't add duplicates */
343 	for (i = 0; i < options->num_remote_forwards; i++) {
344 		if (forward_equals(newfwd, options->remote_forwards + i))
345 			return;
346 	}
347 	options->remote_forwards = xreallocarray(options->remote_forwards,
348 	    options->num_remote_forwards + 1,
349 	    sizeof(*options->remote_forwards));
350 	fwd = &options->remote_forwards[options->num_remote_forwards++];
351 
352 	fwd->listen_host = newfwd->listen_host;
353 	fwd->listen_port = newfwd->listen_port;
354 	fwd->listen_path = newfwd->listen_path;
355 	fwd->connect_host = newfwd->connect_host;
356 	fwd->connect_port = newfwd->connect_port;
357 	fwd->connect_path = newfwd->connect_path;
358 	fwd->handle = newfwd->handle;
359 	fwd->allocated_port = 0;
360 }
361 
362 static void
363 clear_forwardings(Options *options)
364 {
365 	int i;
366 
367 	for (i = 0; i < options->num_local_forwards; i++) {
368 		free(options->local_forwards[i].listen_host);
369 		free(options->local_forwards[i].listen_path);
370 		free(options->local_forwards[i].connect_host);
371 		free(options->local_forwards[i].connect_path);
372 	}
373 	if (options->num_local_forwards > 0) {
374 		free(options->local_forwards);
375 		options->local_forwards = NULL;
376 	}
377 	options->num_local_forwards = 0;
378 	for (i = 0; i < options->num_remote_forwards; i++) {
379 		free(options->remote_forwards[i].listen_host);
380 		free(options->remote_forwards[i].listen_path);
381 		free(options->remote_forwards[i].connect_host);
382 		free(options->remote_forwards[i].connect_path);
383 	}
384 	if (options->num_remote_forwards > 0) {
385 		free(options->remote_forwards);
386 		options->remote_forwards = NULL;
387 	}
388 	options->num_remote_forwards = 0;
389 	options->tun_open = SSH_TUNMODE_NO;
390 }
391 
392 void
393 add_certificate_file(Options *options, const char *path, int userprovided)
394 {
395 	int i;
396 
397 	if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
398 		fatal("Too many certificate files specified (max %d)",
399 		    SSH_MAX_CERTIFICATE_FILES);
400 
401 	/* Avoid registering duplicates */
402 	for (i = 0; i < options->num_certificate_files; i++) {
403 		if (options->certificate_file_userprovided[i] == userprovided &&
404 		    strcmp(options->certificate_files[i], path) == 0) {
405 			debug2("%s: ignoring duplicate key %s", __func__, path);
406 			return;
407 		}
408 	}
409 
410 	options->certificate_file_userprovided[options->num_certificate_files] =
411 	    userprovided;
412 	options->certificate_files[options->num_certificate_files++] =
413 	    xstrdup(path);
414 }
415 
416 void
417 add_identity_file(Options *options, const char *dir, const char *filename,
418     int userprovided)
419 {
420 	char *path;
421 	int i;
422 
423 	if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
424 		fatal("Too many identity files specified (max %d)",
425 		    SSH_MAX_IDENTITY_FILES);
426 
427 	if (dir == NULL) /* no dir, filename is absolute */
428 		path = xstrdup(filename);
429 	else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
430 		fatal("Identity file path %s too long", path);
431 
432 	/* Avoid registering duplicates */
433 	for (i = 0; i < options->num_identity_files; i++) {
434 		if (options->identity_file_userprovided[i] == userprovided &&
435 		    strcmp(options->identity_files[i], path) == 0) {
436 			debug2("%s: ignoring duplicate key %s", __func__, path);
437 			free(path);
438 			return;
439 		}
440 	}
441 
442 	options->identity_file_userprovided[options->num_identity_files] =
443 	    userprovided;
444 	options->identity_files[options->num_identity_files++] = path;
445 }
446 
447 int
448 default_ssh_port(void)
449 {
450 	static int port;
451 	struct servent *sp;
452 
453 	if (port == 0) {
454 		sp = getservbyname(SSH_SERVICE_NAME, "tcp");
455 		port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
456 	}
457 	return port;
458 }
459 
460 /*
461  * Execute a command in a shell.
462  * Return its exit status or -1 on abnormal exit.
463  */
464 static int
465 execute_in_shell(const char *cmd)
466 {
467 	char *shell;
468 	pid_t pid;
469 	int devnull, status;
470 	extern uid_t original_real_uid;
471 
472 	if ((shell = getenv("SHELL")) == NULL)
473 		shell = _PATH_BSHELL;
474 
475 	/* Need this to redirect subprocess stdin/out */
476 	if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
477 		fatal("open(/dev/null): %s", strerror(errno));
478 
479 	debug("Executing command: '%.500s'", cmd);
480 
481 	/* Fork and execute the command. */
482 	if ((pid = fork()) == 0) {
483 		char *argv[4];
484 
485 		/* Child.  Permanently give up superuser privileges. */
486 		permanently_drop_suid(original_real_uid);
487 
488 		/* Redirect child stdin and stdout. Leave stderr */
489 		if (dup2(devnull, STDIN_FILENO) == -1)
490 			fatal("dup2: %s", strerror(errno));
491 		if (dup2(devnull, STDOUT_FILENO) == -1)
492 			fatal("dup2: %s", strerror(errno));
493 		if (devnull > STDERR_FILENO)
494 			close(devnull);
495 		closefrom(STDERR_FILENO + 1);
496 
497 		argv[0] = shell;
498 		argv[1] = "-c";
499 		argv[2] = xstrdup(cmd);
500 		argv[3] = NULL;
501 
502 		execv(argv[0], argv);
503 		error("Unable to execute '%.100s': %s", cmd, strerror(errno));
504 		/* Die with signal to make this error apparent to parent. */
505 		signal(SIGTERM, SIG_DFL);
506 		kill(getpid(), SIGTERM);
507 		_exit(1);
508 	}
509 	/* Parent. */
510 	if (pid < 0)
511 		fatal("%s: fork: %.100s", __func__, strerror(errno));
512 
513 	close(devnull);
514 
515 	while (waitpid(pid, &status, 0) == -1) {
516 		if (errno != EINTR && errno != EAGAIN)
517 			fatal("%s: waitpid: %s", __func__, strerror(errno));
518 	}
519 	if (!WIFEXITED(status)) {
520 		error("command '%.100s' exited abnormally", cmd);
521 		return -1;
522 	}
523 	debug3("command returned status %d", WEXITSTATUS(status));
524 	return WEXITSTATUS(status);
525 }
526 
527 /*
528  * Parse and execute a Match directive.
529  */
530 static int
531 match_cfg_line(Options *options, char **condition, struct passwd *pw,
532     const char *host_arg, const char *original_host, int post_canon,
533     const char *filename, int linenum)
534 {
535 	char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
536 	const char *ruser;
537 	int r, port, this_result, result = 1, attributes = 0, negate;
538 	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
539 
540 	/*
541 	 * Configuration is likely to be incomplete at this point so we
542 	 * must be prepared to use default values.
543 	 */
544 	port = options->port <= 0 ? default_ssh_port() : options->port;
545 	ruser = options->user == NULL ? pw->pw_name : options->user;
546 	if (post_canon) {
547 		host = xstrdup(options->hostname);
548 	} else if (options->hostname != NULL) {
549 		/* NB. Please keep in sync with ssh.c:main() */
550 		host = percent_expand(options->hostname,
551 		    "h", host_arg, (char *)NULL);
552 	} else {
553 		host = xstrdup(host_arg);
554 	}
555 
556 	debug2("checking match for '%s' host %s originally %s",
557 	    cp, host, original_host);
558 	while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
559 		criteria = NULL;
560 		this_result = 1;
561 		if ((negate = attrib[0] == '!'))
562 			attrib++;
563 		/* criteria "all" and "canonical" have no argument */
564 		if (strcasecmp(attrib, "all") == 0) {
565 			if (attributes > 1 ||
566 			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
567 				error("%.200s line %d: '%s' cannot be combined "
568 				    "with other Match attributes",
569 				    filename, linenum, oattrib);
570 				result = -1;
571 				goto out;
572 			}
573 			if (result)
574 				result = negate ? 0 : 1;
575 			goto out;
576 		}
577 		attributes++;
578 		if (strcasecmp(attrib, "canonical") == 0) {
579 			r = !!post_canon;  /* force bitmask member to boolean */
580 			if (r == (negate ? 1 : 0))
581 				this_result = result = 0;
582 			debug3("%.200s line %d: %smatched '%s'",
583 			    filename, linenum,
584 			    this_result ? "" : "not ", oattrib);
585 			continue;
586 		}
587 		/* All other criteria require an argument */
588 		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
589 			error("Missing Match criteria for %s", attrib);
590 			result = -1;
591 			goto out;
592 		}
593 		if (strcasecmp(attrib, "host") == 0) {
594 			criteria = xstrdup(host);
595 			r = match_hostname(host, arg) == 1;
596 			if (r == (negate ? 1 : 0))
597 				this_result = result = 0;
598 		} else if (strcasecmp(attrib, "originalhost") == 0) {
599 			criteria = xstrdup(original_host);
600 			r = match_hostname(original_host, arg) == 1;
601 			if (r == (negate ? 1 : 0))
602 				this_result = result = 0;
603 		} else if (strcasecmp(attrib, "user") == 0) {
604 			criteria = xstrdup(ruser);
605 			r = match_pattern_list(ruser, arg, 0) == 1;
606 			if (r == (negate ? 1 : 0))
607 				this_result = result = 0;
608 		} else if (strcasecmp(attrib, "localuser") == 0) {
609 			criteria = xstrdup(pw->pw_name);
610 			r = match_pattern_list(pw->pw_name, arg, 0) == 1;
611 			if (r == (negate ? 1 : 0))
612 				this_result = result = 0;
613 		} else if (strcasecmp(attrib, "exec") == 0) {
614 			if (gethostname(thishost, sizeof(thishost)) == -1)
615 				fatal("gethostname: %s", strerror(errno));
616 			strlcpy(shorthost, thishost, sizeof(shorthost));
617 			shorthost[strcspn(thishost, ".")] = '\0';
618 			snprintf(portstr, sizeof(portstr), "%d", port);
619 
620 			cmd = percent_expand(arg,
621 			    "L", shorthost,
622 			    "d", pw->pw_dir,
623 			    "h", host,
624 			    "l", thishost,
625 			    "n", original_host,
626 			    "p", portstr,
627 			    "r", ruser,
628 			    "u", pw->pw_name,
629 			    (char *)NULL);
630 			if (result != 1) {
631 				/* skip execution if prior predicate failed */
632 				debug3("%.200s line %d: skipped exec "
633 				    "\"%.100s\"", filename, linenum, cmd);
634 				free(cmd);
635 				continue;
636 			}
637 			r = execute_in_shell(cmd);
638 			if (r == -1) {
639 				fatal("%.200s line %d: match exec "
640 				    "'%.100s' error", filename,
641 				    linenum, cmd);
642 			}
643 			criteria = xstrdup(cmd);
644 			free(cmd);
645 			/* Force exit status to boolean */
646 			r = r == 0;
647 			if (r == (negate ? 1 : 0))
648 				this_result = result = 0;
649 		} else {
650 			error("Unsupported Match attribute %s", attrib);
651 			result = -1;
652 			goto out;
653 		}
654 		debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
655 		    filename, linenum, this_result ? "": "not ",
656 		    oattrib, criteria);
657 		free(criteria);
658 	}
659 	if (attributes == 0) {
660 		error("One or more attributes required for Match");
661 		result = -1;
662 		goto out;
663 	}
664  out:
665 	if (result != -1)
666 		debug2("match %sfound", result ? "" : "not ");
667 	*condition = cp;
668 	free(host);
669 	return result;
670 }
671 
672 /*
673  * Returns the number of the token pointed to by cp or oBadOption.
674  */
675 static OpCodes
676 parse_token(const char *cp, const char *filename, int linenum,
677     const char *ignored_unknown)
678 {
679 	int i;
680 
681 	for (i = 0; keywords[i].name; i++)
682 		if (strcmp(cp, keywords[i].name) == 0)
683 			return keywords[i].opcode;
684 	if (ignored_unknown != NULL &&
685 	    match_pattern_list(cp, ignored_unknown, 1) == 1)
686 		return oIgnoredUnknownOption;
687 	error("%s: line %d: Bad configuration option: %s",
688 	    filename, linenum, cp);
689 	return oBadOption;
690 }
691 
692 /* Multistate option parsing */
693 struct multistate {
694 	char *key;
695 	int value;
696 };
697 static const struct multistate multistate_flag[] = {
698 	{ "true",			1 },
699 	{ "false",			0 },
700 	{ "yes",			1 },
701 	{ "no",				0 },
702 	{ NULL, -1 }
703 };
704 static const struct multistate multistate_yesnoask[] = {
705 	{ "true",			1 },
706 	{ "false",			0 },
707 	{ "yes",			1 },
708 	{ "no",				0 },
709 	{ "ask",			2 },
710 	{ NULL, -1 }
711 };
712 static const struct multistate multistate_strict_hostkey[] = {
713 	{ "true",			SSH_STRICT_HOSTKEY_YES },
714 	{ "false",			SSH_STRICT_HOSTKEY_OFF },
715 	{ "yes",			SSH_STRICT_HOSTKEY_YES },
716 	{ "no",				SSH_STRICT_HOSTKEY_OFF },
717 	{ "ask",			SSH_STRICT_HOSTKEY_ASK },
718 	{ "off",			SSH_STRICT_HOSTKEY_OFF },
719 	{ "accept-new",			SSH_STRICT_HOSTKEY_NEW },
720 	{ NULL, -1 }
721 };
722 static const struct multistate multistate_yesnoaskconfirm[] = {
723 	{ "true",			1 },
724 	{ "false",			0 },
725 	{ "yes",			1 },
726 	{ "no",				0 },
727 	{ "ask",			2 },
728 	{ "confirm",			3 },
729 	{ NULL, -1 }
730 };
731 static const struct multistate multistate_addressfamily[] = {
732 	{ "inet",			AF_INET },
733 	{ "inet6",			AF_INET6 },
734 	{ "any",			AF_UNSPEC },
735 	{ NULL, -1 }
736 };
737 static const struct multistate multistate_controlmaster[] = {
738 	{ "true",			SSHCTL_MASTER_YES },
739 	{ "yes",			SSHCTL_MASTER_YES },
740 	{ "false",			SSHCTL_MASTER_NO },
741 	{ "no",				SSHCTL_MASTER_NO },
742 	{ "auto",			SSHCTL_MASTER_AUTO },
743 	{ "ask",			SSHCTL_MASTER_ASK },
744 	{ "autoask",			SSHCTL_MASTER_AUTO_ASK },
745 	{ NULL, -1 }
746 };
747 static const struct multistate multistate_tunnel[] = {
748 	{ "ethernet",			SSH_TUNMODE_ETHERNET },
749 	{ "point-to-point",		SSH_TUNMODE_POINTOPOINT },
750 	{ "true",			SSH_TUNMODE_DEFAULT },
751 	{ "yes",			SSH_TUNMODE_DEFAULT },
752 	{ "false",			SSH_TUNMODE_NO },
753 	{ "no",				SSH_TUNMODE_NO },
754 	{ NULL, -1 }
755 };
756 static const struct multistate multistate_requesttty[] = {
757 	{ "true",			REQUEST_TTY_YES },
758 	{ "yes",			REQUEST_TTY_YES },
759 	{ "false",			REQUEST_TTY_NO },
760 	{ "no",				REQUEST_TTY_NO },
761 	{ "force",			REQUEST_TTY_FORCE },
762 	{ "auto",			REQUEST_TTY_AUTO },
763 	{ NULL, -1 }
764 };
765 static const struct multistate multistate_canonicalizehostname[] = {
766 	{ "true",			SSH_CANONICALISE_YES },
767 	{ "false",			SSH_CANONICALISE_NO },
768 	{ "yes",			SSH_CANONICALISE_YES },
769 	{ "no",				SSH_CANONICALISE_NO },
770 	{ "always",			SSH_CANONICALISE_ALWAYS },
771 	{ NULL, -1 }
772 };
773 
774 /*
775  * Processes a single option line as used in the configuration files. This
776  * only sets those values that have not already been set.
777  */
778 int
779 process_config_line(Options *options, struct passwd *pw, const char *host,
780     const char *original_host, char *line, const char *filename,
781     int linenum, int *activep, int flags)
782 {
783 	return process_config_line_depth(options, pw, host, original_host,
784 	    line, filename, linenum, activep, flags, 0);
785 }
786 
787 #define WHITESPACE " \t\r\n"
788 static int
789 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
790     const char *original_host, char *line, const char *filename,
791     int linenum, int *activep, int flags, int depth)
792 {
793 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
794 	char **cpptr, fwdarg[256];
795 	u_int i, *uintptr, max_entries = 0;
796 	int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
797 	int remotefwd, dynamicfwd;
798 	LogLevel *log_level_ptr;
799 	SyslogFacility *log_facility_ptr;
800 	long long val64;
801 	size_t len;
802 	struct Forward fwd;
803 	const struct multistate *multistate_ptr;
804 	struct allowed_cname *cname;
805 	glob_t gl;
806 	const char *errstr;
807 
808 	if (activep == NULL) { /* We are processing a command line directive */
809 		cmdline = 1;
810 		activep = &cmdline;
811 	}
812 
813 	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
814 	if ((len = strlen(line)) == 0)
815 		return 0;
816 	for (len--; len > 0; len--) {
817 		if (strchr(WHITESPACE "\f", line[len]) == NULL)
818 			break;
819 		line[len] = '\0';
820 	}
821 
822 	s = line;
823 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
824 	if ((keyword = strdelim(&s)) == NULL)
825 		return 0;
826 	/* Ignore leading whitespace. */
827 	if (*keyword == '\0')
828 		keyword = strdelim(&s);
829 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
830 		return 0;
831 	/* Match lowercase keyword */
832 	lowercase(keyword);
833 
834 	opcode = parse_token(keyword, filename, linenum,
835 	    options->ignored_unknown);
836 
837 	switch (opcode) {
838 	case oBadOption:
839 		/* don't panic, but count bad options */
840 		return -1;
841 	case oIgnore:
842 		return 0;
843 	case oIgnoredUnknownOption:
844 		debug("%s line %d: Ignored unknown option \"%s\"",
845 		    filename, linenum, keyword);
846 		return 0;
847 	case oConnectTimeout:
848 		intptr = &options->connection_timeout;
849 parse_time:
850 		arg = strdelim(&s);
851 		if (!arg || *arg == '\0')
852 			fatal("%s line %d: missing time value.",
853 			    filename, linenum);
854 		if (strcmp(arg, "none") == 0)
855 			value = -1;
856 		else if ((value = convtime(arg)) == -1)
857 			fatal("%s line %d: invalid time value.",
858 			    filename, linenum);
859 		if (*activep && *intptr == -1)
860 			*intptr = value;
861 		break;
862 
863 	case oForwardAgent:
864 		intptr = &options->forward_agent;
865  parse_flag:
866 		multistate_ptr = multistate_flag;
867  parse_multistate:
868 		arg = strdelim(&s);
869 		if (!arg || *arg == '\0')
870 			fatal("%s line %d: missing argument.",
871 			    filename, linenum);
872 		value = -1;
873 		for (i = 0; multistate_ptr[i].key != NULL; i++) {
874 			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
875 				value = multistate_ptr[i].value;
876 				break;
877 			}
878 		}
879 		if (value == -1)
880 			fatal("%s line %d: unsupported option \"%s\".",
881 			    filename, linenum, arg);
882 		if (*activep && *intptr == -1)
883 			*intptr = value;
884 		break;
885 
886 	case oForwardX11:
887 		intptr = &options->forward_x11;
888 		goto parse_flag;
889 
890 	case oForwardX11Trusted:
891 		intptr = &options->forward_x11_trusted;
892 		goto parse_flag;
893 
894 	case oForwardX11Timeout:
895 		intptr = &options->forward_x11_timeout;
896 		goto parse_time;
897 
898 	case oGatewayPorts:
899 		intptr = &options->fwd_opts.gateway_ports;
900 		goto parse_flag;
901 
902 	case oExitOnForwardFailure:
903 		intptr = &options->exit_on_forward_failure;
904 		goto parse_flag;
905 
906 	case oUsePrivilegedPort:
907 		intptr = &options->use_privileged_port;
908 		goto parse_flag;
909 
910 	case oPasswordAuthentication:
911 		intptr = &options->password_authentication;
912 		goto parse_flag;
913 
914 	case oKbdInteractiveAuthentication:
915 		intptr = &options->kbd_interactive_authentication;
916 		goto parse_flag;
917 
918 	case oKbdInteractiveDevices:
919 		charptr = &options->kbd_interactive_devices;
920 		goto parse_string;
921 
922 	case oPubkeyAuthentication:
923 		intptr = &options->pubkey_authentication;
924 		goto parse_flag;
925 
926 	case oHostbasedAuthentication:
927 		intptr = &options->hostbased_authentication;
928 		goto parse_flag;
929 
930 	case oChallengeResponseAuthentication:
931 		intptr = &options->challenge_response_authentication;
932 		goto parse_flag;
933 
934 	case oGssAuthentication:
935 		intptr = &options->gss_authentication;
936 		goto parse_flag;
937 
938 	case oGssDelegateCreds:
939 		intptr = &options->gss_deleg_creds;
940 		goto parse_flag;
941 
942 	case oBatchMode:
943 		intptr = &options->batch_mode;
944 		goto parse_flag;
945 
946 	case oCheckHostIP:
947 		intptr = &options->check_host_ip;
948 		goto parse_flag;
949 
950 	case oVerifyHostKeyDNS:
951 		intptr = &options->verify_host_key_dns;
952 		multistate_ptr = multistate_yesnoask;
953 		goto parse_multistate;
954 
955 	case oStrictHostKeyChecking:
956 		intptr = &options->strict_host_key_checking;
957 		multistate_ptr = multistate_strict_hostkey;
958 		goto parse_multistate;
959 
960 	case oCompression:
961 		intptr = &options->compression;
962 		goto parse_flag;
963 
964 	case oTCPKeepAlive:
965 		intptr = &options->tcp_keep_alive;
966 		goto parse_flag;
967 
968 	case oNoHostAuthenticationForLocalhost:
969 		intptr = &options->no_host_authentication_for_localhost;
970 		goto parse_flag;
971 
972 	case oNumberOfPasswordPrompts:
973 		intptr = &options->number_of_password_prompts;
974 		goto parse_int;
975 
976 	case oRekeyLimit:
977 		arg = strdelim(&s);
978 		if (!arg || *arg == '\0')
979 			fatal("%.200s line %d: Missing argument.", filename,
980 			    linenum);
981 		if (strcmp(arg, "default") == 0) {
982 			val64 = 0;
983 		} else {
984 			if (scan_scaled(arg, &val64) == -1)
985 				fatal("%.200s line %d: Bad number '%s': %s",
986 				    filename, linenum, arg, strerror(errno));
987 			if (val64 != 0 && val64 < 16)
988 				fatal("%.200s line %d: RekeyLimit too small",
989 				    filename, linenum);
990 		}
991 		if (*activep && options->rekey_limit == -1)
992 			options->rekey_limit = val64;
993 		if (s != NULL) { /* optional rekey interval present */
994 			if (strcmp(s, "none") == 0) {
995 				(void)strdelim(&s);	/* discard */
996 				break;
997 			}
998 			intptr = &options->rekey_interval;
999 			goto parse_time;
1000 		}
1001 		break;
1002 
1003 	case oIdentityFile:
1004 		arg = strdelim(&s);
1005 		if (!arg || *arg == '\0')
1006 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1007 		if (*activep) {
1008 			intptr = &options->num_identity_files;
1009 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
1010 				fatal("%.200s line %d: Too many identity files specified (max %d).",
1011 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
1012 			add_identity_file(options, NULL,
1013 			    arg, flags & SSHCONF_USERCONF);
1014 		}
1015 		break;
1016 
1017 	case oCertificateFile:
1018 		arg = strdelim(&s);
1019 		if (!arg || *arg == '\0')
1020 			fatal("%.200s line %d: Missing argument.",
1021 			    filename, linenum);
1022 		if (*activep) {
1023 			intptr = &options->num_certificate_files;
1024 			if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1025 				fatal("%.200s line %d: Too many certificate "
1026 				    "files specified (max %d).",
1027 				    filename, linenum,
1028 				    SSH_MAX_CERTIFICATE_FILES);
1029 			}
1030 			add_certificate_file(options, arg,
1031 			    flags & SSHCONF_USERCONF);
1032 		}
1033 		break;
1034 
1035 	case oXAuthLocation:
1036 		charptr=&options->xauth_location;
1037 		goto parse_string;
1038 
1039 	case oUser:
1040 		charptr = &options->user;
1041 parse_string:
1042 		arg = strdelim(&s);
1043 		if (!arg || *arg == '\0')
1044 			fatal("%.200s line %d: Missing argument.",
1045 			    filename, linenum);
1046 		if (*activep && *charptr == NULL)
1047 			*charptr = xstrdup(arg);
1048 		break;
1049 
1050 	case oGlobalKnownHostsFile:
1051 		cpptr = (char **)&options->system_hostfiles;
1052 		uintptr = &options->num_system_hostfiles;
1053 		max_entries = SSH_MAX_HOSTS_FILES;
1054 parse_char_array:
1055 		if (*activep && *uintptr == 0) {
1056 			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1057 				if ((*uintptr) >= max_entries)
1058 					fatal("%s line %d: "
1059 					    "too many authorized keys files.",
1060 					    filename, linenum);
1061 				cpptr[(*uintptr)++] = xstrdup(arg);
1062 			}
1063 		}
1064 		return 0;
1065 
1066 	case oUserKnownHostsFile:
1067 		cpptr = (char **)&options->user_hostfiles;
1068 		uintptr = &options->num_user_hostfiles;
1069 		max_entries = SSH_MAX_HOSTS_FILES;
1070 		goto parse_char_array;
1071 
1072 	case oHostName:
1073 		charptr = &options->hostname;
1074 		goto parse_string;
1075 
1076 	case oHostKeyAlias:
1077 		charptr = &options->host_key_alias;
1078 		goto parse_string;
1079 
1080 	case oPreferredAuthentications:
1081 		charptr = &options->preferred_authentications;
1082 		goto parse_string;
1083 
1084 	case oBindAddress:
1085 		charptr = &options->bind_address;
1086 		goto parse_string;
1087 
1088 	case oBindInterface:
1089 		charptr = &options->bind_interface;
1090 		goto parse_string;
1091 
1092 	case oPKCS11Provider:
1093 		charptr = &options->pkcs11_provider;
1094 		goto parse_string;
1095 
1096 	case oProxyCommand:
1097 		charptr = &options->proxy_command;
1098 		/* Ignore ProxyCommand if ProxyJump already specified */
1099 		if (options->jump_host != NULL)
1100 			charptr = &options->jump_host; /* Skip below */
1101 parse_command:
1102 		if (s == NULL)
1103 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1104 		len = strspn(s, WHITESPACE "=");
1105 		if (*activep && *charptr == NULL)
1106 			*charptr = xstrdup(s + len);
1107 		return 0;
1108 
1109 	case oProxyJump:
1110 		if (s == NULL) {
1111 			fatal("%.200s line %d: Missing argument.",
1112 			    filename, linenum);
1113 		}
1114 		len = strspn(s, WHITESPACE "=");
1115 		if (parse_jump(s + len, options, *activep) == -1) {
1116 			fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1117 			    filename, linenum, s + len);
1118 		}
1119 		return 0;
1120 
1121 	case oPort:
1122 		intptr = &options->port;
1123 parse_int:
1124 		arg = strdelim(&s);
1125 		if ((errstr = atoi_err(arg, &value)) != NULL)
1126 			fatal("%s line %d: integer value %s.",
1127 			    filename, linenum, errstr);
1128 		if (*activep && *intptr == -1)
1129 			*intptr = value;
1130 		break;
1131 
1132 	case oConnectionAttempts:
1133 		intptr = &options->connection_attempts;
1134 		goto parse_int;
1135 
1136 	case oCiphers:
1137 		arg = strdelim(&s);
1138 		if (!arg || *arg == '\0')
1139 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1140 		if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
1141 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1142 			    filename, linenum, arg ? arg : "<NONE>");
1143 		if (*activep && options->ciphers == NULL)
1144 			options->ciphers = xstrdup(arg);
1145 		break;
1146 
1147 	case oMacs:
1148 		arg = strdelim(&s);
1149 		if (!arg || *arg == '\0')
1150 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1151 		if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
1152 			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1153 			    filename, linenum, arg ? arg : "<NONE>");
1154 		if (*activep && options->macs == NULL)
1155 			options->macs = xstrdup(arg);
1156 		break;
1157 
1158 	case oKexAlgorithms:
1159 		arg = strdelim(&s);
1160 		if (!arg || *arg == '\0')
1161 			fatal("%.200s line %d: Missing argument.",
1162 			    filename, linenum);
1163 		if (*arg != '-' &&
1164 		    !kex_names_valid(*arg == '+' ? arg + 1 : arg))
1165 			fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1166 			    filename, linenum, arg ? arg : "<NONE>");
1167 		if (*activep && options->kex_algorithms == NULL)
1168 			options->kex_algorithms = xstrdup(arg);
1169 		break;
1170 
1171 	case oHostKeyAlgorithms:
1172 		charptr = &options->hostkeyalgorithms;
1173 parse_keytypes:
1174 		arg = strdelim(&s);
1175 		if (!arg || *arg == '\0')
1176 			fatal("%.200s line %d: Missing argument.",
1177 			    filename, linenum);
1178 		if (*arg != '-' &&
1179 		    !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1180 			fatal("%s line %d: Bad key types '%s'.",
1181 				filename, linenum, arg ? arg : "<NONE>");
1182 		if (*activep && *charptr == NULL)
1183 			*charptr = xstrdup(arg);
1184 		break;
1185 
1186 	case oLogLevel:
1187 		log_level_ptr = &options->log_level;
1188 		arg = strdelim(&s);
1189 		value = log_level_number(arg);
1190 		if (value == SYSLOG_LEVEL_NOT_SET)
1191 			fatal("%.200s line %d: unsupported log level '%s'",
1192 			    filename, linenum, arg ? arg : "<NONE>");
1193 		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1194 			*log_level_ptr = (LogLevel) value;
1195 		break;
1196 
1197 	case oLogFacility:
1198 		log_facility_ptr = &options->log_facility;
1199 		arg = strdelim(&s);
1200 		value = log_facility_number(arg);
1201 		if (value == SYSLOG_FACILITY_NOT_SET)
1202 			fatal("%.200s line %d: unsupported log facility '%s'",
1203 			    filename, linenum, arg ? arg : "<NONE>");
1204 		if (*log_facility_ptr == -1)
1205 			*log_facility_ptr = (SyslogFacility) value;
1206 		break;
1207 
1208 	case oLocalForward:
1209 	case oRemoteForward:
1210 	case oDynamicForward:
1211 		arg = strdelim(&s);
1212 		if (arg == NULL || *arg == '\0')
1213 			fatal("%.200s line %d: Missing port argument.",
1214 			    filename, linenum);
1215 
1216 		remotefwd = (opcode == oRemoteForward);
1217 		dynamicfwd = (opcode == oDynamicForward);
1218 
1219 		if (!dynamicfwd) {
1220 			arg2 = strdelim(&s);
1221 			if (arg2 == NULL || *arg2 == '\0') {
1222 				if (remotefwd)
1223 					dynamicfwd = 1;
1224 				else
1225 					fatal("%.200s line %d: Missing target "
1226 					    "argument.", filename, linenum);
1227 			} else {
1228 				/* construct a string for parse_forward */
1229 				snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
1230 				    arg2);
1231 			}
1232 		}
1233 		if (dynamicfwd)
1234 			strlcpy(fwdarg, arg, sizeof(fwdarg));
1235 
1236 		if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
1237 			fatal("%.200s line %d: Bad forwarding specification.",
1238 			    filename, linenum);
1239 
1240 		if (*activep) {
1241 			if (remotefwd) {
1242 				add_remote_forward(options, &fwd);
1243 			} else {
1244 				add_local_forward(options, &fwd);
1245 			}
1246 		}
1247 		break;
1248 
1249 	case oClearAllForwardings:
1250 		intptr = &options->clear_forwardings;
1251 		goto parse_flag;
1252 
1253 	case oHost:
1254 		if (cmdline)
1255 			fatal("Host directive not supported as a command-line "
1256 			    "option");
1257 		*activep = 0;
1258 		arg2 = NULL;
1259 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1260 			if ((flags & SSHCONF_NEVERMATCH) != 0)
1261 				break;
1262 			negated = *arg == '!';
1263 			if (negated)
1264 				arg++;
1265 			if (match_pattern(host, arg)) {
1266 				if (negated) {
1267 					debug("%.200s line %d: Skipping Host "
1268 					    "block because of negated match "
1269 					    "for %.100s", filename, linenum,
1270 					    arg);
1271 					*activep = 0;
1272 					break;
1273 				}
1274 				if (!*activep)
1275 					arg2 = arg; /* logged below */
1276 				*activep = 1;
1277 			}
1278 		}
1279 		if (*activep)
1280 			debug("%.200s line %d: Applying options for %.100s",
1281 			    filename, linenum, arg2);
1282 		/* Avoid garbage check below, as strdelim is done. */
1283 		return 0;
1284 
1285 	case oMatch:
1286 		if (cmdline)
1287 			fatal("Host directive not supported as a command-line "
1288 			    "option");
1289 		value = match_cfg_line(options, &s, pw, host, original_host,
1290 		    flags & SSHCONF_POSTCANON, filename, linenum);
1291 		if (value < 0)
1292 			fatal("%.200s line %d: Bad Match condition", filename,
1293 			    linenum);
1294 		*activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1295 		break;
1296 
1297 	case oEscapeChar:
1298 		intptr = &options->escape_char;
1299 		arg = strdelim(&s);
1300 		if (!arg || *arg == '\0')
1301 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1302 		if (strcmp(arg, "none") == 0)
1303 			value = SSH_ESCAPECHAR_NONE;
1304 		else if (arg[1] == '\0')
1305 			value = (u_char) arg[0];
1306 		else if (arg[0] == '^' && arg[2] == 0 &&
1307 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1308 			value = (u_char) arg[1] & 31;
1309 		else {
1310 			fatal("%.200s line %d: Bad escape character.",
1311 			    filename, linenum);
1312 			/* NOTREACHED */
1313 			value = 0;	/* Avoid compiler warning. */
1314 		}
1315 		if (*activep && *intptr == -1)
1316 			*intptr = value;
1317 		break;
1318 
1319 	case oAddressFamily:
1320 		intptr = &options->address_family;
1321 		multistate_ptr = multistate_addressfamily;
1322 		goto parse_multistate;
1323 
1324 	case oEnableSSHKeysign:
1325 		intptr = &options->enable_ssh_keysign;
1326 		goto parse_flag;
1327 
1328 	case oIdentitiesOnly:
1329 		intptr = &options->identities_only;
1330 		goto parse_flag;
1331 
1332 	case oServerAliveInterval:
1333 		intptr = &options->server_alive_interval;
1334 		goto parse_time;
1335 
1336 	case oServerAliveCountMax:
1337 		intptr = &options->server_alive_count_max;
1338 		goto parse_int;
1339 
1340 	case oSendEnv:
1341 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1342 			if (strchr(arg, '=') != NULL)
1343 				fatal("%s line %d: Invalid environment name.",
1344 				    filename, linenum);
1345 			if (!*activep)
1346 				continue;
1347 			if (options->num_send_env >= MAX_SEND_ENV)
1348 				fatal("%s line %d: too many send env.",
1349 				    filename, linenum);
1350 			options->send_env[options->num_send_env++] =
1351 			    xstrdup(arg);
1352 		}
1353 		break;
1354 
1355 	case oControlPath:
1356 		charptr = &options->control_path;
1357 		goto parse_string;
1358 
1359 	case oControlMaster:
1360 		intptr = &options->control_master;
1361 		multistate_ptr = multistate_controlmaster;
1362 		goto parse_multistate;
1363 
1364 	case oControlPersist:
1365 		/* no/false/yes/true, or a time spec */
1366 		intptr = &options->control_persist;
1367 		arg = strdelim(&s);
1368 		if (!arg || *arg == '\0')
1369 			fatal("%.200s line %d: Missing ControlPersist"
1370 			    " argument.", filename, linenum);
1371 		value = 0;
1372 		value2 = 0;	/* timeout */
1373 		if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1374 			value = 0;
1375 		else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1376 			value = 1;
1377 		else if ((value2 = convtime(arg)) >= 0)
1378 			value = 1;
1379 		else
1380 			fatal("%.200s line %d: Bad ControlPersist argument.",
1381 			    filename, linenum);
1382 		if (*activep && *intptr == -1) {
1383 			*intptr = value;
1384 			options->control_persist_timeout = value2;
1385 		}
1386 		break;
1387 
1388 	case oHashKnownHosts:
1389 		intptr = &options->hash_known_hosts;
1390 		goto parse_flag;
1391 
1392 	case oTunnel:
1393 		intptr = &options->tun_open;
1394 		multistate_ptr = multistate_tunnel;
1395 		goto parse_multistate;
1396 
1397 	case oTunnelDevice:
1398 		arg = strdelim(&s);
1399 		if (!arg || *arg == '\0')
1400 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1401 		value = a2tun(arg, &value2);
1402 		if (value == SSH_TUNID_ERR)
1403 			fatal("%.200s line %d: Bad tun device.", filename, linenum);
1404 		if (*activep) {
1405 			options->tun_local = value;
1406 			options->tun_remote = value2;
1407 		}
1408 		break;
1409 
1410 	case oLocalCommand:
1411 		charptr = &options->local_command;
1412 		goto parse_command;
1413 
1414 	case oPermitLocalCommand:
1415 		intptr = &options->permit_local_command;
1416 		goto parse_flag;
1417 
1418 	case oRemoteCommand:
1419 		charptr = &options->remote_command;
1420 		goto parse_command;
1421 
1422 	case oVisualHostKey:
1423 		intptr = &options->visual_host_key;
1424 		goto parse_flag;
1425 
1426 	case oInclude:
1427 		if (cmdline)
1428 			fatal("Include directive not supported as a "
1429 			    "command-line option");
1430 		value = 0;
1431 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1432 			/*
1433 			 * Ensure all paths are anchored. User configuration
1434 			 * files may begin with '~/' but system configurations
1435 			 * must not. If the path is relative, then treat it
1436 			 * as living in ~/.ssh for user configurations or
1437 			 * /etc/ssh for system ones.
1438 			 */
1439 			if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1440 				fatal("%.200s line %d: bad include path %s.",
1441 				    filename, linenum, arg);
1442 			if (*arg != '/' && *arg != '~') {
1443 				xasprintf(&arg2, "%s/%s",
1444 				    (flags & SSHCONF_USERCONF) ?
1445 				    "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1446 			} else
1447 				arg2 = xstrdup(arg);
1448 			memset(&gl, 0, sizeof(gl));
1449 			r = glob(arg2, GLOB_TILDE, NULL, &gl);
1450 			if (r == GLOB_NOMATCH) {
1451 				debug("%.200s line %d: include %s matched no "
1452 				    "files",filename, linenum, arg2);
1453 				free(arg2);
1454 				continue;
1455 			} else if (r != 0 || gl.gl_pathc < 0)
1456 				fatal("%.200s line %d: glob failed for %s.",
1457 				    filename, linenum, arg2);
1458 			free(arg2);
1459 			oactive = *activep;
1460 			for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1461 				debug3("%.200s line %d: Including file %s "
1462 				    "depth %d%s", filename, linenum,
1463 				    gl.gl_pathv[i], depth,
1464 				    oactive ? "" : " (parse only)");
1465 				r = read_config_file_depth(gl.gl_pathv[i],
1466 				    pw, host, original_host, options,
1467 				    flags | SSHCONF_CHECKPERM |
1468 				    (oactive ? 0 : SSHCONF_NEVERMATCH),
1469 				    activep, depth + 1);
1470 				if (r != 1 && errno != ENOENT) {
1471 					fatal("Can't open user config file "
1472 					    "%.100s: %.100s", gl.gl_pathv[i],
1473 					    strerror(errno));
1474 				}
1475 				/*
1476 				 * don't let Match in includes clobber the
1477 				 * containing file's Match state.
1478 				 */
1479 				*activep = oactive;
1480 				if (r != 1)
1481 					value = -1;
1482 			}
1483 			globfree(&gl);
1484 		}
1485 		if (value != 0)
1486 			return value;
1487 		break;
1488 
1489 	case oIPQoS:
1490 		arg = strdelim(&s);
1491 		if ((value = parse_ipqos(arg)) == -1)
1492 			fatal("%s line %d: Bad IPQoS value: %s",
1493 			    filename, linenum, arg);
1494 		arg = strdelim(&s);
1495 		if (arg == NULL)
1496 			value2 = value;
1497 		else if ((value2 = parse_ipqos(arg)) == -1)
1498 			fatal("%s line %d: Bad IPQoS value: %s",
1499 			    filename, linenum, arg);
1500 		if (*activep) {
1501 			options->ip_qos_interactive = value;
1502 			options->ip_qos_bulk = value2;
1503 		}
1504 		break;
1505 
1506 	case oRequestTTY:
1507 		intptr = &options->request_tty;
1508 		multistate_ptr = multistate_requesttty;
1509 		goto parse_multistate;
1510 
1511 	case oIgnoreUnknown:
1512 		charptr = &options->ignored_unknown;
1513 		goto parse_string;
1514 
1515 	case oProxyUseFdpass:
1516 		intptr = &options->proxy_use_fdpass;
1517 		goto parse_flag;
1518 
1519 	case oCanonicalDomains:
1520 		value = options->num_canonical_domains != 0;
1521 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1522 			if (!valid_domain(arg, 1, &errstr)) {
1523 				fatal("%s line %d: %s", filename, linenum,
1524 				    errstr);
1525 			}
1526 			if (!*activep || value)
1527 				continue;
1528 			if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1529 				fatal("%s line %d: too many hostname suffixes.",
1530 				    filename, linenum);
1531 			options->canonical_domains[
1532 			    options->num_canonical_domains++] = xstrdup(arg);
1533 		}
1534 		break;
1535 
1536 	case oCanonicalizePermittedCNAMEs:
1537 		value = options->num_permitted_cnames != 0;
1538 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1539 			/* Either '*' for everything or 'list:list' */
1540 			if (strcmp(arg, "*") == 0)
1541 				arg2 = arg;
1542 			else {
1543 				lowercase(arg);
1544 				if ((arg2 = strchr(arg, ':')) == NULL ||
1545 				    arg2[1] == '\0') {
1546 					fatal("%s line %d: "
1547 					    "Invalid permitted CNAME \"%s\"",
1548 					    filename, linenum, arg);
1549 				}
1550 				*arg2 = '\0';
1551 				arg2++;
1552 			}
1553 			if (!*activep || value)
1554 				continue;
1555 			if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1556 				fatal("%s line %d: too many permitted CNAMEs.",
1557 				    filename, linenum);
1558 			cname = options->permitted_cnames +
1559 			    options->num_permitted_cnames++;
1560 			cname->source_list = xstrdup(arg);
1561 			cname->target_list = xstrdup(arg2);
1562 		}
1563 		break;
1564 
1565 	case oCanonicalizeHostname:
1566 		intptr = &options->canonicalize_hostname;
1567 		multistate_ptr = multistate_canonicalizehostname;
1568 		goto parse_multistate;
1569 
1570 	case oCanonicalizeMaxDots:
1571 		intptr = &options->canonicalize_max_dots;
1572 		goto parse_int;
1573 
1574 	case oCanonicalizeFallbackLocal:
1575 		intptr = &options->canonicalize_fallback_local;
1576 		goto parse_flag;
1577 
1578 	case oStreamLocalBindMask:
1579 		arg = strdelim(&s);
1580 		if (!arg || *arg == '\0')
1581 			fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1582 		/* Parse mode in octal format */
1583 		value = strtol(arg, &endofnumber, 8);
1584 		if (arg == endofnumber || value < 0 || value > 0777)
1585 			fatal("%.200s line %d: Bad mask.", filename, linenum);
1586 		options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1587 		break;
1588 
1589 	case oStreamLocalBindUnlink:
1590 		intptr = &options->fwd_opts.streamlocal_bind_unlink;
1591 		goto parse_flag;
1592 
1593 	case oRevokedHostKeys:
1594 		charptr = &options->revoked_host_keys;
1595 		goto parse_string;
1596 
1597 	case oFingerprintHash:
1598 		intptr = &options->fingerprint_hash;
1599 		arg = strdelim(&s);
1600 		if (!arg || *arg == '\0')
1601 			fatal("%.200s line %d: Missing argument.",
1602 			    filename, linenum);
1603 		if ((value = ssh_digest_alg_by_name(arg)) == -1)
1604 			fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1605 			    filename, linenum, arg);
1606 		if (*activep && *intptr == -1)
1607 			*intptr = value;
1608 		break;
1609 
1610 	case oUpdateHostkeys:
1611 		intptr = &options->update_hostkeys;
1612 		multistate_ptr = multistate_yesnoask;
1613 		goto parse_multistate;
1614 
1615 	case oHostbasedKeyTypes:
1616 		charptr = &options->hostbased_key_types;
1617 		goto parse_keytypes;
1618 
1619 	case oPubkeyAcceptedKeyTypes:
1620 		charptr = &options->pubkey_key_types;
1621 		goto parse_keytypes;
1622 
1623 	case oAddKeysToAgent:
1624 		intptr = &options->add_keys_to_agent;
1625 		multistate_ptr = multistate_yesnoaskconfirm;
1626 		goto parse_multistate;
1627 
1628 	case oIdentityAgent:
1629 		charptr = &options->identity_agent;
1630 		goto parse_string;
1631 
1632 	case oDeprecated:
1633 		debug("%s line %d: Deprecated option \"%s\"",
1634 		    filename, linenum, keyword);
1635 		return 0;
1636 
1637 	case oUnsupported:
1638 		error("%s line %d: Unsupported option \"%s\"",
1639 		    filename, linenum, keyword);
1640 		return 0;
1641 
1642 	default:
1643 		fatal("%s: Unimplemented opcode %d", __func__, opcode);
1644 	}
1645 
1646 	/* Check that there is no garbage at end of line. */
1647 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1648 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1649 		    filename, linenum, arg);
1650 	}
1651 	return 0;
1652 }
1653 
1654 /*
1655  * Reads the config file and modifies the options accordingly.  Options
1656  * should already be initialized before this call.  This never returns if
1657  * there is an error.  If the file does not exist, this returns 0.
1658  */
1659 int
1660 read_config_file(const char *filename, struct passwd *pw, const char *host,
1661     const char *original_host, Options *options, int flags)
1662 {
1663 	int active = 1;
1664 
1665 	return read_config_file_depth(filename, pw, host, original_host,
1666 	    options, flags, &active, 0);
1667 }
1668 
1669 #define READCONF_MAX_DEPTH	16
1670 static int
1671 read_config_file_depth(const char *filename, struct passwd *pw,
1672     const char *host, const char *original_host, Options *options,
1673     int flags, int *activep, int depth)
1674 {
1675 	FILE *f;
1676 	char line[4096];
1677 	int linenum;
1678 	int bad_options = 0;
1679 
1680 	if (depth < 0 || depth > READCONF_MAX_DEPTH)
1681 		fatal("Too many recursive configuration includes");
1682 
1683 	if ((f = fopen(filename, "r")) == NULL)
1684 		return 0;
1685 
1686 	if (flags & SSHCONF_CHECKPERM) {
1687 		struct stat sb;
1688 
1689 		if (fstat(fileno(f), &sb) == -1)
1690 			fatal("fstat %s: %s", filename, strerror(errno));
1691 		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1692 		    (sb.st_mode & 022) != 0))
1693 			fatal("Bad owner or permissions on %s", filename);
1694 	}
1695 
1696 	debug("Reading configuration data %.200s", filename);
1697 
1698 	/*
1699 	 * Mark that we are now processing the options.  This flag is turned
1700 	 * on/off by Host specifications.
1701 	 */
1702 	linenum = 0;
1703 	while (fgets(line, sizeof(line), f)) {
1704 		/* Update line number counter. */
1705 		linenum++;
1706 		if (strlen(line) == sizeof(line) - 1)
1707 			fatal("%s line %d too long", filename, linenum);
1708 		if (process_config_line_depth(options, pw, host, original_host,
1709 		    line, filename, linenum, activep, flags, depth) != 0)
1710 			bad_options++;
1711 	}
1712 	fclose(f);
1713 	if (bad_options > 0)
1714 		fatal("%s: terminating, %d bad configuration options",
1715 		    filename, bad_options);
1716 	return 1;
1717 }
1718 
1719 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1720 int
1721 option_clear_or_none(const char *o)
1722 {
1723 	return o == NULL || strcasecmp(o, "none") == 0;
1724 }
1725 
1726 /*
1727  * Initializes options to special values that indicate that they have not yet
1728  * been set.  Read_config_file will only set options with this value. Options
1729  * are processed in the following order: command line, user config file,
1730  * system config file.  Last, fill_default_options is called.
1731  */
1732 
1733 void
1734 initialize_options(Options * options)
1735 {
1736 	memset(options, 'X', sizeof(*options));
1737 	options->forward_agent = -1;
1738 	options->forward_x11 = -1;
1739 	options->forward_x11_trusted = -1;
1740 	options->forward_x11_timeout = -1;
1741 	options->stdio_forward_host = NULL;
1742 	options->stdio_forward_port = 0;
1743 	options->clear_forwardings = -1;
1744 	options->exit_on_forward_failure = -1;
1745 	options->xauth_location = NULL;
1746 	options->fwd_opts.gateway_ports = -1;
1747 	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1748 	options->fwd_opts.streamlocal_bind_unlink = -1;
1749 	options->use_privileged_port = -1;
1750 	options->pubkey_authentication = -1;
1751 	options->challenge_response_authentication = -1;
1752 	options->gss_authentication = -1;
1753 	options->gss_deleg_creds = -1;
1754 	options->password_authentication = -1;
1755 	options->kbd_interactive_authentication = -1;
1756 	options->kbd_interactive_devices = NULL;
1757 	options->hostbased_authentication = -1;
1758 	options->batch_mode = -1;
1759 	options->check_host_ip = -1;
1760 	options->strict_host_key_checking = -1;
1761 	options->compression = -1;
1762 	options->tcp_keep_alive = -1;
1763 	options->port = -1;
1764 	options->address_family = -1;
1765 	options->connection_attempts = -1;
1766 	options->connection_timeout = -1;
1767 	options->number_of_password_prompts = -1;
1768 	options->ciphers = NULL;
1769 	options->macs = NULL;
1770 	options->kex_algorithms = NULL;
1771 	options->hostkeyalgorithms = NULL;
1772 	options->num_identity_files = 0;
1773 	options->num_certificate_files = 0;
1774 	options->hostname = NULL;
1775 	options->host_key_alias = NULL;
1776 	options->proxy_command = NULL;
1777 	options->jump_user = NULL;
1778 	options->jump_host = NULL;
1779 	options->jump_port = -1;
1780 	options->jump_extra = NULL;
1781 	options->user = NULL;
1782 	options->escape_char = -1;
1783 	options->num_system_hostfiles = 0;
1784 	options->num_user_hostfiles = 0;
1785 	options->local_forwards = NULL;
1786 	options->num_local_forwards = 0;
1787 	options->remote_forwards = NULL;
1788 	options->num_remote_forwards = 0;
1789 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
1790 	options->log_level = SYSLOG_LEVEL_NOT_SET;
1791 	options->preferred_authentications = NULL;
1792 	options->bind_address = NULL;
1793 	options->bind_interface = NULL;
1794 	options->pkcs11_provider = NULL;
1795 	options->enable_ssh_keysign = - 1;
1796 	options->no_host_authentication_for_localhost = - 1;
1797 	options->identities_only = - 1;
1798 	options->rekey_limit = - 1;
1799 	options->rekey_interval = -1;
1800 	options->verify_host_key_dns = -1;
1801 	options->server_alive_interval = -1;
1802 	options->server_alive_count_max = -1;
1803 	options->num_send_env = 0;
1804 	options->control_path = NULL;
1805 	options->control_master = -1;
1806 	options->control_persist = -1;
1807 	options->control_persist_timeout = 0;
1808 	options->hash_known_hosts = -1;
1809 	options->tun_open = -1;
1810 	options->tun_local = -1;
1811 	options->tun_remote = -1;
1812 	options->local_command = NULL;
1813 	options->permit_local_command = -1;
1814 	options->remote_command = NULL;
1815 	options->add_keys_to_agent = -1;
1816 	options->identity_agent = NULL;
1817 	options->visual_host_key = -1;
1818 	options->ip_qos_interactive = -1;
1819 	options->ip_qos_bulk = -1;
1820 	options->request_tty = -1;
1821 	options->proxy_use_fdpass = -1;
1822 	options->ignored_unknown = NULL;
1823 	options->num_canonical_domains = 0;
1824 	options->num_permitted_cnames = 0;
1825 	options->canonicalize_max_dots = -1;
1826 	options->canonicalize_fallback_local = -1;
1827 	options->canonicalize_hostname = -1;
1828 	options->revoked_host_keys = NULL;
1829 	options->fingerprint_hash = -1;
1830 	options->update_hostkeys = -1;
1831 	options->hostbased_key_types = NULL;
1832 	options->pubkey_key_types = NULL;
1833 }
1834 
1835 /*
1836  * A petite version of fill_default_options() that just fills the options
1837  * needed for hostname canonicalization to proceed.
1838  */
1839 void
1840 fill_default_options_for_canonicalization(Options *options)
1841 {
1842 	if (options->canonicalize_max_dots == -1)
1843 		options->canonicalize_max_dots = 1;
1844 	if (options->canonicalize_fallback_local == -1)
1845 		options->canonicalize_fallback_local = 1;
1846 	if (options->canonicalize_hostname == -1)
1847 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
1848 }
1849 
1850 /*
1851  * Called after processing other sources of option data, this fills those
1852  * options for which no value has been specified with their default values.
1853  */
1854 void
1855 fill_default_options(Options * options)
1856 {
1857 	if (options->forward_agent == -1)
1858 		options->forward_agent = 0;
1859 	if (options->forward_x11 == -1)
1860 		options->forward_x11 = 0;
1861 	if (options->forward_x11_trusted == -1)
1862 		options->forward_x11_trusted = 0;
1863 	if (options->forward_x11_timeout == -1)
1864 		options->forward_x11_timeout = 1200;
1865 	/*
1866 	 * stdio forwarding (-W) changes the default for these but we defer
1867 	 * setting the values so they can be overridden.
1868 	 */
1869 	if (options->exit_on_forward_failure == -1)
1870 		options->exit_on_forward_failure =
1871 		    options->stdio_forward_host != NULL ? 1 : 0;
1872 	if (options->clear_forwardings == -1)
1873 		options->clear_forwardings =
1874 		    options->stdio_forward_host != NULL ? 1 : 0;
1875 	if (options->clear_forwardings == 1)
1876 		clear_forwardings(options);
1877 
1878 	if (options->xauth_location == NULL)
1879 		options->xauth_location = _PATH_XAUTH;
1880 	if (options->fwd_opts.gateway_ports == -1)
1881 		options->fwd_opts.gateway_ports = 0;
1882 	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1883 		options->fwd_opts.streamlocal_bind_mask = 0177;
1884 	if (options->fwd_opts.streamlocal_bind_unlink == -1)
1885 		options->fwd_opts.streamlocal_bind_unlink = 0;
1886 	if (options->use_privileged_port == -1)
1887 		options->use_privileged_port = 0;
1888 	if (options->pubkey_authentication == -1)
1889 		options->pubkey_authentication = 1;
1890 	if (options->challenge_response_authentication == -1)
1891 		options->challenge_response_authentication = 1;
1892 	if (options->gss_authentication == -1)
1893 		options->gss_authentication = 0;
1894 	if (options->gss_deleg_creds == -1)
1895 		options->gss_deleg_creds = 0;
1896 	if (options->password_authentication == -1)
1897 		options->password_authentication = 1;
1898 	if (options->kbd_interactive_authentication == -1)
1899 		options->kbd_interactive_authentication = 1;
1900 	if (options->hostbased_authentication == -1)
1901 		options->hostbased_authentication = 0;
1902 	if (options->batch_mode == -1)
1903 		options->batch_mode = 0;
1904 	if (options->check_host_ip == -1)
1905 		options->check_host_ip = 1;
1906 	if (options->strict_host_key_checking == -1)
1907 		options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
1908 	if (options->compression == -1)
1909 		options->compression = 0;
1910 	if (options->tcp_keep_alive == -1)
1911 		options->tcp_keep_alive = 1;
1912 	if (options->port == -1)
1913 		options->port = 0;	/* Filled in ssh_connect. */
1914 	if (options->address_family == -1)
1915 		options->address_family = AF_UNSPEC;
1916 	if (options->connection_attempts == -1)
1917 		options->connection_attempts = 1;
1918 	if (options->number_of_password_prompts == -1)
1919 		options->number_of_password_prompts = 3;
1920 	/* options->hostkeyalgorithms, default set in myproposals.h */
1921 	if (options->add_keys_to_agent == -1)
1922 		options->add_keys_to_agent = 0;
1923 	if (options->num_identity_files == 0) {
1924 		add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
1925 		add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
1926 		add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
1927 		add_identity_file(options, "~/",
1928 		    _PATH_SSH_CLIENT_ID_ED25519, 0);
1929 		add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
1930 	}
1931 	if (options->escape_char == -1)
1932 		options->escape_char = '~';
1933 	if (options->num_system_hostfiles == 0) {
1934 		options->system_hostfiles[options->num_system_hostfiles++] =
1935 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1936 		options->system_hostfiles[options->num_system_hostfiles++] =
1937 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1938 	}
1939 	if (options->num_user_hostfiles == 0) {
1940 		options->user_hostfiles[options->num_user_hostfiles++] =
1941 		    xstrdup(_PATH_SSH_USER_HOSTFILE);
1942 		options->user_hostfiles[options->num_user_hostfiles++] =
1943 		    xstrdup(_PATH_SSH_USER_HOSTFILE2);
1944 	}
1945 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1946 		options->log_level = SYSLOG_LEVEL_INFO;
1947 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
1948 		options->log_facility = SYSLOG_FACILITY_USER;
1949 	if (options->no_host_authentication_for_localhost == - 1)
1950 		options->no_host_authentication_for_localhost = 0;
1951 	if (options->identities_only == -1)
1952 		options->identities_only = 0;
1953 	if (options->enable_ssh_keysign == -1)
1954 		options->enable_ssh_keysign = 0;
1955 	if (options->rekey_limit == -1)
1956 		options->rekey_limit = 0;
1957 	if (options->rekey_interval == -1)
1958 		options->rekey_interval = 0;
1959 	if (options->verify_host_key_dns == -1)
1960 		options->verify_host_key_dns = 0;
1961 	if (options->server_alive_interval == -1)
1962 		options->server_alive_interval = 0;
1963 	if (options->server_alive_count_max == -1)
1964 		options->server_alive_count_max = 3;
1965 	if (options->control_master == -1)
1966 		options->control_master = 0;
1967 	if (options->control_persist == -1) {
1968 		options->control_persist = 0;
1969 		options->control_persist_timeout = 0;
1970 	}
1971 	if (options->hash_known_hosts == -1)
1972 		options->hash_known_hosts = 0;
1973 	if (options->tun_open == -1)
1974 		options->tun_open = SSH_TUNMODE_NO;
1975 	if (options->tun_local == -1)
1976 		options->tun_local = SSH_TUNID_ANY;
1977 	if (options->tun_remote == -1)
1978 		options->tun_remote = SSH_TUNID_ANY;
1979 	if (options->permit_local_command == -1)
1980 		options->permit_local_command = 0;
1981 	if (options->visual_host_key == -1)
1982 		options->visual_host_key = 0;
1983 	if (options->ip_qos_interactive == -1)
1984 		options->ip_qos_interactive = IPTOS_LOWDELAY;
1985 	if (options->ip_qos_bulk == -1)
1986 		options->ip_qos_bulk = IPTOS_THROUGHPUT;
1987 	if (options->request_tty == -1)
1988 		options->request_tty = REQUEST_TTY_AUTO;
1989 	if (options->proxy_use_fdpass == -1)
1990 		options->proxy_use_fdpass = 0;
1991 	if (options->canonicalize_max_dots == -1)
1992 		options->canonicalize_max_dots = 1;
1993 	if (options->canonicalize_fallback_local == -1)
1994 		options->canonicalize_fallback_local = 1;
1995 	if (options->canonicalize_hostname == -1)
1996 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
1997 	if (options->fingerprint_hash == -1)
1998 		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
1999 	if (options->update_hostkeys == -1)
2000 		options->update_hostkeys = 0;
2001 	if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
2002 	    kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
2003 	    kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
2004 	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
2005 	    &options->hostbased_key_types) != 0 ||
2006 	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
2007 	    &options->pubkey_key_types) != 0)
2008 		fatal("%s: kex_assemble_names failed", __func__);
2009 
2010 #define CLEAR_ON_NONE(v) \
2011 	do { \
2012 		if (option_clear_or_none(v)) { \
2013 			free(v); \
2014 			v = NULL; \
2015 		} \
2016 	} while(0)
2017 	CLEAR_ON_NONE(options->local_command);
2018 	CLEAR_ON_NONE(options->remote_command);
2019 	CLEAR_ON_NONE(options->proxy_command);
2020 	CLEAR_ON_NONE(options->control_path);
2021 	CLEAR_ON_NONE(options->revoked_host_keys);
2022 	/* options->identity_agent distinguishes NULL from 'none' */
2023 	/* options->user will be set in the main program if appropriate */
2024 	/* options->hostname will be set in the main program if appropriate */
2025 	/* options->host_key_alias should not be set by default */
2026 	/* options->preferred_authentications will be set in ssh */
2027 }
2028 
2029 struct fwdarg {
2030 	char *arg;
2031 	int ispath;
2032 };
2033 
2034 /*
2035  * parse_fwd_field
2036  * parses the next field in a port forwarding specification.
2037  * sets fwd to the parsed field and advances p past the colon
2038  * or sets it to NULL at end of string.
2039  * returns 0 on success, else non-zero.
2040  */
2041 static int
2042 parse_fwd_field(char **p, struct fwdarg *fwd)
2043 {
2044 	char *ep, *cp = *p;
2045 	int ispath = 0;
2046 
2047 	if (*cp == '\0') {
2048 		*p = NULL;
2049 		return -1;	/* end of string */
2050 	}
2051 
2052 	/*
2053 	 * A field escaped with square brackets is used literally.
2054 	 * XXX - allow ']' to be escaped via backslash?
2055 	 */
2056 	if (*cp == '[') {
2057 		/* find matching ']' */
2058 		for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2059 			if (*ep == '/')
2060 				ispath = 1;
2061 		}
2062 		/* no matching ']' or not at end of field. */
2063 		if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2064 			return -1;
2065 		/* NUL terminate the field and advance p past the colon */
2066 		*ep++ = '\0';
2067 		if (*ep != '\0')
2068 			*ep++ = '\0';
2069 		fwd->arg = cp + 1;
2070 		fwd->ispath = ispath;
2071 		*p = ep;
2072 		return 0;
2073 	}
2074 
2075 	for (cp = *p; *cp != '\0'; cp++) {
2076 		switch (*cp) {
2077 		case '\\':
2078 			memmove(cp, cp + 1, strlen(cp + 1) + 1);
2079 			if (*cp == '\0')
2080 				return -1;
2081 			break;
2082 		case '/':
2083 			ispath = 1;
2084 			break;
2085 		case ':':
2086 			*cp++ = '\0';
2087 			goto done;
2088 		}
2089 	}
2090 done:
2091 	fwd->arg = *p;
2092 	fwd->ispath = ispath;
2093 	*p = cp;
2094 	return 0;
2095 }
2096 
2097 /*
2098  * parse_forward
2099  * parses a string containing a port forwarding specification of the form:
2100  *   dynamicfwd == 0
2101  *	[listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2102  *	listenpath:connectpath
2103  *   dynamicfwd == 1
2104  *	[listenhost:]listenport
2105  * returns number of arguments parsed or zero on error
2106  */
2107 int
2108 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2109 {
2110 	struct fwdarg fwdargs[4];
2111 	char *p, *cp;
2112 	int i;
2113 
2114 	memset(fwd, 0, sizeof(*fwd));
2115 	memset(fwdargs, 0, sizeof(fwdargs));
2116 
2117 	cp = p = xstrdup(fwdspec);
2118 
2119 	/* skip leading spaces */
2120 	while (isspace((u_char)*cp))
2121 		cp++;
2122 
2123 	for (i = 0; i < 4; ++i) {
2124 		if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2125 			break;
2126 	}
2127 
2128 	/* Check for trailing garbage */
2129 	if (cp != NULL && *cp != '\0') {
2130 		i = 0;	/* failure */
2131 	}
2132 
2133 	switch (i) {
2134 	case 1:
2135 		if (fwdargs[0].ispath) {
2136 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2137 			fwd->listen_port = PORT_STREAMLOCAL;
2138 		} else {
2139 			fwd->listen_host = NULL;
2140 			fwd->listen_port = a2port(fwdargs[0].arg);
2141 		}
2142 		fwd->connect_host = xstrdup("socks");
2143 		break;
2144 
2145 	case 2:
2146 		if (fwdargs[0].ispath && fwdargs[1].ispath) {
2147 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2148 			fwd->listen_port = PORT_STREAMLOCAL;
2149 			fwd->connect_path = xstrdup(fwdargs[1].arg);
2150 			fwd->connect_port = PORT_STREAMLOCAL;
2151 		} else if (fwdargs[1].ispath) {
2152 			fwd->listen_host = NULL;
2153 			fwd->listen_port = a2port(fwdargs[0].arg);
2154 			fwd->connect_path = xstrdup(fwdargs[1].arg);
2155 			fwd->connect_port = PORT_STREAMLOCAL;
2156 		} else {
2157 			fwd->listen_host = xstrdup(fwdargs[0].arg);
2158 			fwd->listen_port = a2port(fwdargs[1].arg);
2159 			fwd->connect_host = xstrdup("socks");
2160 		}
2161 		break;
2162 
2163 	case 3:
2164 		if (fwdargs[0].ispath) {
2165 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2166 			fwd->listen_port = PORT_STREAMLOCAL;
2167 			fwd->connect_host = xstrdup(fwdargs[1].arg);
2168 			fwd->connect_port = a2port(fwdargs[2].arg);
2169 		} else if (fwdargs[2].ispath) {
2170 			fwd->listen_host = xstrdup(fwdargs[0].arg);
2171 			fwd->listen_port = a2port(fwdargs[1].arg);
2172 			fwd->connect_path = xstrdup(fwdargs[2].arg);
2173 			fwd->connect_port = PORT_STREAMLOCAL;
2174 		} else {
2175 			fwd->listen_host = NULL;
2176 			fwd->listen_port = a2port(fwdargs[0].arg);
2177 			fwd->connect_host = xstrdup(fwdargs[1].arg);
2178 			fwd->connect_port = a2port(fwdargs[2].arg);
2179 		}
2180 		break;
2181 
2182 	case 4:
2183 		fwd->listen_host = xstrdup(fwdargs[0].arg);
2184 		fwd->listen_port = a2port(fwdargs[1].arg);
2185 		fwd->connect_host = xstrdup(fwdargs[2].arg);
2186 		fwd->connect_port = a2port(fwdargs[3].arg);
2187 		break;
2188 	default:
2189 		i = 0; /* failure */
2190 	}
2191 
2192 	free(p);
2193 
2194 	if (dynamicfwd) {
2195 		if (!(i == 1 || i == 2))
2196 			goto fail_free;
2197 	} else {
2198 		if (!(i == 3 || i == 4)) {
2199 			if (fwd->connect_path == NULL &&
2200 			    fwd->listen_path == NULL)
2201 				goto fail_free;
2202 		}
2203 		if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2204 			goto fail_free;
2205 	}
2206 
2207 	if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2208 	    (!remotefwd && fwd->listen_port == 0))
2209 		goto fail_free;
2210 	if (fwd->connect_host != NULL &&
2211 	    strlen(fwd->connect_host) >= NI_MAXHOST)
2212 		goto fail_free;
2213 	/* XXX - if connecting to a remote socket, max sun len may not match this host */
2214 	if (fwd->connect_path != NULL &&
2215 	    strlen(fwd->connect_path) >= PATH_MAX_SUN)
2216 		goto fail_free;
2217 	if (fwd->listen_host != NULL &&
2218 	    strlen(fwd->listen_host) >= NI_MAXHOST)
2219 		goto fail_free;
2220 	if (fwd->listen_path != NULL &&
2221 	    strlen(fwd->listen_path) >= PATH_MAX_SUN)
2222 		goto fail_free;
2223 
2224 	return (i);
2225 
2226  fail_free:
2227 	free(fwd->connect_host);
2228 	fwd->connect_host = NULL;
2229 	free(fwd->connect_path);
2230 	fwd->connect_path = NULL;
2231 	free(fwd->listen_host);
2232 	fwd->listen_host = NULL;
2233 	free(fwd->listen_path);
2234 	fwd->listen_path = NULL;
2235 	return (0);
2236 }
2237 
2238 int
2239 parse_jump(const char *s, Options *o, int active)
2240 {
2241 	char *orig, *sdup, *cp;
2242 	char *host = NULL, *user = NULL;
2243 	int ret = -1, port = -1, first;
2244 
2245 	active &= o->proxy_command == NULL && o->jump_host == NULL;
2246 
2247 	orig = sdup = xstrdup(s);
2248 	first = active;
2249 	do {
2250 		if ((cp = strrchr(sdup, ',')) == NULL)
2251 			cp = sdup; /* last */
2252 		else
2253 			*cp++ = '\0';
2254 
2255 		if (first) {
2256 			/* First argument and configuration is active */
2257 			if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||
2258 			    parse_user_host_port(cp, &user, &host, &port) != 0)
2259 				goto out;
2260 		} else {
2261 			/* Subsequent argument or inactive configuration */
2262 			if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||
2263 			    parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2264 				goto out;
2265 		}
2266 		first = 0; /* only check syntax for subsequent hosts */
2267 	} while (cp != sdup);
2268 	/* success */
2269 	if (active) {
2270 		o->jump_user = user;
2271 		o->jump_host = host;
2272 		o->jump_port = port;
2273 		o->proxy_command = xstrdup("none");
2274 		user = host = NULL;
2275 		if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2276 			o->jump_extra = xstrdup(s);
2277 			o->jump_extra[cp - s] = '\0';
2278 		}
2279 	}
2280 	ret = 0;
2281  out:
2282 	free(orig);
2283 	free(user);
2284 	free(host);
2285 	return ret;
2286 }
2287 
2288 int
2289 parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
2290 {
2291 	char *path;
2292 	int r;
2293 
2294 	r = parse_uri("ssh", uri, userp, hostp, portp, &path);
2295 	if (r == 0 && path != NULL)
2296 		r = -1;		/* path not allowed */
2297 	return r;
2298 }
2299 
2300 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2301 static const char *
2302 fmt_multistate_int(int val, const struct multistate *m)
2303 {
2304 	u_int i;
2305 
2306 	for (i = 0; m[i].key != NULL; i++) {
2307 		if (m[i].value == val)
2308 			return m[i].key;
2309 	}
2310 	return "UNKNOWN";
2311 }
2312 
2313 static const char *
2314 fmt_intarg(OpCodes code, int val)
2315 {
2316 	if (val == -1)
2317 		return "unset";
2318 	switch (code) {
2319 	case oAddressFamily:
2320 		return fmt_multistate_int(val, multistate_addressfamily);
2321 	case oVerifyHostKeyDNS:
2322 	case oUpdateHostkeys:
2323 		return fmt_multistate_int(val, multistate_yesnoask);
2324 	case oStrictHostKeyChecking:
2325 		return fmt_multistate_int(val, multistate_strict_hostkey);
2326 	case oControlMaster:
2327 		return fmt_multistate_int(val, multistate_controlmaster);
2328 	case oTunnel:
2329 		return fmt_multistate_int(val, multistate_tunnel);
2330 	case oRequestTTY:
2331 		return fmt_multistate_int(val, multistate_requesttty);
2332 	case oCanonicalizeHostname:
2333 		return fmt_multistate_int(val, multistate_canonicalizehostname);
2334 	case oFingerprintHash:
2335 		return ssh_digest_alg_name(val);
2336 	default:
2337 		switch (val) {
2338 		case 0:
2339 			return "no";
2340 		case 1:
2341 			return "yes";
2342 		default:
2343 			return "UNKNOWN";
2344 		}
2345 	}
2346 }
2347 
2348 static const char *
2349 lookup_opcode_name(OpCodes code)
2350 {
2351 	u_int i;
2352 
2353 	for (i = 0; keywords[i].name != NULL; i++)
2354 		if (keywords[i].opcode == code)
2355 			return(keywords[i].name);
2356 	return "UNKNOWN";
2357 }
2358 
2359 static void
2360 dump_cfg_int(OpCodes code, int val)
2361 {
2362 	printf("%s %d\n", lookup_opcode_name(code), val);
2363 }
2364 
2365 static void
2366 dump_cfg_fmtint(OpCodes code, int val)
2367 {
2368 	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2369 }
2370 
2371 static void
2372 dump_cfg_string(OpCodes code, const char *val)
2373 {
2374 	if (val == NULL)
2375 		return;
2376 	printf("%s %s\n", lookup_opcode_name(code), val);
2377 }
2378 
2379 static void
2380 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2381 {
2382 	u_int i;
2383 
2384 	for (i = 0; i < count; i++)
2385 		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2386 }
2387 
2388 static void
2389 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2390 {
2391 	u_int i;
2392 
2393 	printf("%s", lookup_opcode_name(code));
2394 	for (i = 0; i < count; i++)
2395 		printf(" %s",  vals[i]);
2396 	printf("\n");
2397 }
2398 
2399 static void
2400 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2401 {
2402 	const struct Forward *fwd;
2403 	u_int i;
2404 
2405 	/* oDynamicForward */
2406 	for (i = 0; i < count; i++) {
2407 		fwd = &fwds[i];
2408 		if (code == oDynamicForward && fwd->connect_host != NULL &&
2409 		    strcmp(fwd->connect_host, "socks") != 0)
2410 			continue;
2411 		if (code == oLocalForward && fwd->connect_host != NULL &&
2412 		    strcmp(fwd->connect_host, "socks") == 0)
2413 			continue;
2414 		printf("%s", lookup_opcode_name(code));
2415 		if (fwd->listen_port == PORT_STREAMLOCAL)
2416 			printf(" %s", fwd->listen_path);
2417 		else if (fwd->listen_host == NULL)
2418 			printf(" %d", fwd->listen_port);
2419 		else {
2420 			printf(" [%s]:%d",
2421 			    fwd->listen_host, fwd->listen_port);
2422 		}
2423 		if (code != oDynamicForward) {
2424 			if (fwd->connect_port == PORT_STREAMLOCAL)
2425 				printf(" %s", fwd->connect_path);
2426 			else if (fwd->connect_host == NULL)
2427 				printf(" %d", fwd->connect_port);
2428 			else {
2429 				printf(" [%s]:%d",
2430 				    fwd->connect_host, fwd->connect_port);
2431 			}
2432 		}
2433 		printf("\n");
2434 	}
2435 }
2436 
2437 void
2438 dump_client_config(Options *o, const char *host)
2439 {
2440 	int i;
2441 	char buf[8];
2442 
2443 	/* This is normally prepared in ssh_kex2 */
2444 	if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2445 		fatal("%s: kex_assemble_names failed", __func__);
2446 
2447 	/* Most interesting options first: user, host, port */
2448 	dump_cfg_string(oUser, o->user);
2449 	dump_cfg_string(oHostName, host);
2450 	dump_cfg_int(oPort, o->port);
2451 
2452 	/* Flag options */
2453 	dump_cfg_fmtint(oAddressFamily, o->address_family);
2454 	dump_cfg_fmtint(oBatchMode, o->batch_mode);
2455 	dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2456 	dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2457 	dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2458 	dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2459 	dump_cfg_fmtint(oCompression, o->compression);
2460 	dump_cfg_fmtint(oControlMaster, o->control_master);
2461 	dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2462 	dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2463 	dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2464 	dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2465 	dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2466 	dump_cfg_fmtint(oForwardX11, o->forward_x11);
2467 	dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2468 	dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2469 #ifdef GSSAPI
2470 	dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2471 	dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2472 #endif /* GSSAPI */
2473 	dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2474 	dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2475 	dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2476 	dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2477 	dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2478 	dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2479 	dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2480 	dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2481 	dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2482 	dump_cfg_fmtint(oRequestTTY, o->request_tty);
2483 	dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2484 	dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2485 	dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2486 	dump_cfg_fmtint(oTunnel, o->tun_open);
2487 	dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2488 	dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2489 	dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2490 	dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2491 
2492 	/* Integer options */
2493 	dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2494 	dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2495 	dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2496 	dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2497 	dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2498 	dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2499 
2500 	/* String options */
2501 	dump_cfg_string(oBindAddress, o->bind_address);
2502 	dump_cfg_string(oBindInterface, o->bind_interface);
2503 	dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2504 	dump_cfg_string(oControlPath, o->control_path);
2505 	dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2506 	dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2507 	dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2508 	dump_cfg_string(oIdentityAgent, o->identity_agent);
2509 	dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2510 	dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2511 	dump_cfg_string(oLocalCommand, o->local_command);
2512 	dump_cfg_string(oRemoteCommand, o->remote_command);
2513 	dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2514 	dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2515 #ifdef ENABLE_PKCS11
2516 	dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2517 #endif
2518 	dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2519 	dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2520 	dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2521 	dump_cfg_string(oXAuthLocation, o->xauth_location);
2522 
2523 	/* Forwards */
2524 	dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2525 	dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2526 	dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2527 
2528 	/* String array options */
2529 	dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2530 	dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2531 	dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2532 	dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2533 	dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2534 
2535 	/* Special cases */
2536 
2537 	/* oConnectTimeout */
2538 	if (o->connection_timeout == -1)
2539 		printf("connecttimeout none\n");
2540 	else
2541 		dump_cfg_int(oConnectTimeout, o->connection_timeout);
2542 
2543 	/* oTunnelDevice */
2544 	printf("tunneldevice");
2545 	if (o->tun_local == SSH_TUNID_ANY)
2546 		printf(" any");
2547 	else
2548 		printf(" %d", o->tun_local);
2549 	if (o->tun_remote == SSH_TUNID_ANY)
2550 		printf(":any");
2551 	else
2552 		printf(":%d", o->tun_remote);
2553 	printf("\n");
2554 
2555 	/* oCanonicalizePermittedCNAMEs */
2556 	if ( o->num_permitted_cnames > 0) {
2557 		printf("canonicalizePermittedcnames");
2558 		for (i = 0; i < o->num_permitted_cnames; i++) {
2559 			printf(" %s:%s", o->permitted_cnames[i].source_list,
2560 			    o->permitted_cnames[i].target_list);
2561 		}
2562 		printf("\n");
2563 	}
2564 
2565 	/* oControlPersist */
2566 	if (o->control_persist == 0 || o->control_persist_timeout == 0)
2567 		dump_cfg_fmtint(oControlPersist, o->control_persist);
2568 	else
2569 		dump_cfg_int(oControlPersist, o->control_persist_timeout);
2570 
2571 	/* oEscapeChar */
2572 	if (o->escape_char == SSH_ESCAPECHAR_NONE)
2573 		printf("escapechar none\n");
2574 	else {
2575 		vis(buf, o->escape_char, VIS_WHITE, 0);
2576 		printf("escapechar %s\n", buf);
2577 	}
2578 
2579 	/* oIPQoS */
2580 	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2581 	printf("%s\n", iptos2str(o->ip_qos_bulk));
2582 
2583 	/* oRekeyLimit */
2584 	printf("rekeylimit %llu %d\n",
2585 	    (unsigned long long)o->rekey_limit, o->rekey_interval);
2586 
2587 	/* oStreamLocalBindMask */
2588 	printf("streamlocalbindmask 0%o\n",
2589 	    o->fwd_opts.streamlocal_bind_mask);
2590 
2591 	/* oProxyCommand / oProxyJump */
2592 	if (o->jump_host == NULL)
2593 		dump_cfg_string(oProxyCommand, o->proxy_command);
2594 	else {
2595 		/* Check for numeric addresses */
2596 		i = strchr(o->jump_host, ':') != NULL ||
2597 		    strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2598 		snprintf(buf, sizeof(buf), "%d", o->jump_port);
2599 		printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2600 		    /* optional additional jump spec */
2601 		    o->jump_extra == NULL ? "" : o->jump_extra,
2602 		    o->jump_extra == NULL ? "" : ",",
2603 		    /* optional user */
2604 		    o->jump_user == NULL ? "" : o->jump_user,
2605 		    o->jump_user == NULL ? "" : "@",
2606 		    /* opening [ if hostname is numeric */
2607 		    i ? "[" : "",
2608 		    /* mandatory hostname */
2609 		    o->jump_host,
2610 		    /* closing ] if hostname is numeric */
2611 		    i ? "]" : "",
2612 		    /* optional port number */
2613 		    o->jump_port <= 0 ? "" : ":",
2614 		    o->jump_port <= 0 ? "" : buf);
2615 	}
2616 }
2617