xref: /openbsd-src/usr.bin/ssh/readconf.c (revision 8ead0783a05eee83ab02af2c7b14b10fbcdce47d)
1 /* $OpenBSD: readconf.c,v 1.280 2017/10/21 23:06:24 millert 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, 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 	{ "clearallforwardings", oClearAllForwardings },
255 	{ "enablesshkeysign", oEnableSSHKeysign },
256 	{ "verifyhostkeydns", oVerifyHostKeyDNS },
257 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
258 	{ "rekeylimit", oRekeyLimit },
259 	{ "connecttimeout", oConnectTimeout },
260 	{ "addressfamily", oAddressFamily },
261 	{ "serveraliveinterval", oServerAliveInterval },
262 	{ "serveralivecountmax", oServerAliveCountMax },
263 	{ "sendenv", oSendEnv },
264 	{ "controlpath", oControlPath },
265 	{ "controlmaster", oControlMaster },
266 	{ "controlpersist", oControlPersist },
267 	{ "hashknownhosts", oHashKnownHosts },
268 	{ "include", oInclude },
269 	{ "tunnel", oTunnel },
270 	{ "tunneldevice", oTunnelDevice },
271 	{ "localcommand", oLocalCommand },
272 	{ "permitlocalcommand", oPermitLocalCommand },
273 	{ "remotecommand", oRemoteCommand },
274 	{ "visualhostkey", oVisualHostKey },
275 	{ "kexalgorithms", oKexAlgorithms },
276 	{ "ipqos", oIPQoS },
277 	{ "requesttty", oRequestTTY },
278 	{ "proxyusefdpass", oProxyUseFdpass },
279 	{ "canonicaldomains", oCanonicalDomains },
280 	{ "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
281 	{ "canonicalizehostname", oCanonicalizeHostname },
282 	{ "canonicalizemaxdots", oCanonicalizeMaxDots },
283 	{ "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
284 	{ "streamlocalbindmask", oStreamLocalBindMask },
285 	{ "streamlocalbindunlink", oStreamLocalBindUnlink },
286 	{ "revokedhostkeys", oRevokedHostKeys },
287 	{ "fingerprinthash", oFingerprintHash },
288 	{ "updatehostkeys", oUpdateHostkeys },
289 	{ "hostbasedkeytypes", oHostbasedKeyTypes },
290 	{ "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
291 	{ "ignoreunknown", oIgnoreUnknown },
292 	{ "proxyjump", oProxyJump },
293 
294 	{ NULL, oBadOption }
295 };
296 
297 /*
298  * Adds a local TCP/IP port forward to options.  Never returns if there is an
299  * error.
300  */
301 
302 void
303 add_local_forward(Options *options, const struct Forward *newfwd)
304 {
305 	struct Forward *fwd;
306 	extern uid_t original_real_uid;
307 	int i;
308 
309 	if (!bind_permitted(newfwd->listen_port, original_real_uid) &&
310 	    newfwd->listen_path == NULL)
311 		fatal("Privileged ports can only be forwarded by root.");
312 	/* Don't add duplicates */
313 	for (i = 0; i < options->num_local_forwards; i++) {
314 		if (forward_equals(newfwd, options->local_forwards + i))
315 			return;
316 	}
317 	options->local_forwards = xreallocarray(options->local_forwards,
318 	    options->num_local_forwards + 1,
319 	    sizeof(*options->local_forwards));
320 	fwd = &options->local_forwards[options->num_local_forwards++];
321 
322 	fwd->listen_host = newfwd->listen_host;
323 	fwd->listen_port = newfwd->listen_port;
324 	fwd->listen_path = newfwd->listen_path;
325 	fwd->connect_host = newfwd->connect_host;
326 	fwd->connect_port = newfwd->connect_port;
327 	fwd->connect_path = newfwd->connect_path;
328 }
329 
330 /*
331  * Adds a remote TCP/IP port forward to options.  Never returns if there is
332  * an error.
333  */
334 
335 void
336 add_remote_forward(Options *options, const struct Forward *newfwd)
337 {
338 	struct Forward *fwd;
339 	int i;
340 
341 	/* Don't add duplicates */
342 	for (i = 0; i < options->num_remote_forwards; i++) {
343 		if (forward_equals(newfwd, options->remote_forwards + i))
344 			return;
345 	}
346 	options->remote_forwards = xreallocarray(options->remote_forwards,
347 	    options->num_remote_forwards + 1,
348 	    sizeof(*options->remote_forwards));
349 	fwd = &options->remote_forwards[options->num_remote_forwards++];
350 
351 	fwd->listen_host = newfwd->listen_host;
352 	fwd->listen_port = newfwd->listen_port;
353 	fwd->listen_path = newfwd->listen_path;
354 	fwd->connect_host = newfwd->connect_host;
355 	fwd->connect_port = newfwd->connect_port;
356 	fwd->connect_path = newfwd->connect_path;
357 	fwd->handle = newfwd->handle;
358 	fwd->allocated_port = 0;
359 }
360 
361 static void
362 clear_forwardings(Options *options)
363 {
364 	int i;
365 
366 	for (i = 0; i < options->num_local_forwards; i++) {
367 		free(options->local_forwards[i].listen_host);
368 		free(options->local_forwards[i].listen_path);
369 		free(options->local_forwards[i].connect_host);
370 		free(options->local_forwards[i].connect_path);
371 	}
372 	if (options->num_local_forwards > 0) {
373 		free(options->local_forwards);
374 		options->local_forwards = NULL;
375 	}
376 	options->num_local_forwards = 0;
377 	for (i = 0; i < options->num_remote_forwards; i++) {
378 		free(options->remote_forwards[i].listen_host);
379 		free(options->remote_forwards[i].listen_path);
380 		free(options->remote_forwards[i].connect_host);
381 		free(options->remote_forwards[i].connect_path);
382 	}
383 	if (options->num_remote_forwards > 0) {
384 		free(options->remote_forwards);
385 		options->remote_forwards = NULL;
386 	}
387 	options->num_remote_forwards = 0;
388 	options->tun_open = SSH_TUNMODE_NO;
389 }
390 
391 void
392 add_certificate_file(Options *options, const char *path, int userprovided)
393 {
394 	int i;
395 
396 	if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
397 		fatal("Too many certificate files specified (max %d)",
398 		    SSH_MAX_CERTIFICATE_FILES);
399 
400 	/* Avoid registering duplicates */
401 	for (i = 0; i < options->num_certificate_files; i++) {
402 		if (options->certificate_file_userprovided[i] == userprovided &&
403 		    strcmp(options->certificate_files[i], path) == 0) {
404 			debug2("%s: ignoring duplicate key %s", __func__, path);
405 			return;
406 		}
407 	}
408 
409 	options->certificate_file_userprovided[options->num_certificate_files] =
410 	    userprovided;
411 	options->certificate_files[options->num_certificate_files++] =
412 	    xstrdup(path);
413 }
414 
415 void
416 add_identity_file(Options *options, const char *dir, const char *filename,
417     int userprovided)
418 {
419 	char *path;
420 	int i;
421 
422 	if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
423 		fatal("Too many identity files specified (max %d)",
424 		    SSH_MAX_IDENTITY_FILES);
425 
426 	if (dir == NULL) /* no dir, filename is absolute */
427 		path = xstrdup(filename);
428 	else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
429 		fatal("Identity file path %s too long", path);
430 
431 	/* Avoid registering duplicates */
432 	for (i = 0; i < options->num_identity_files; i++) {
433 		if (options->identity_file_userprovided[i] == userprovided &&
434 		    strcmp(options->identity_files[i], path) == 0) {
435 			debug2("%s: ignoring duplicate key %s", __func__, path);
436 			free(path);
437 			return;
438 		}
439 	}
440 
441 	options->identity_file_userprovided[options->num_identity_files] =
442 	    userprovided;
443 	options->identity_files[options->num_identity_files++] = path;
444 }
445 
446 int
447 default_ssh_port(void)
448 {
449 	static int port;
450 	struct servent *sp;
451 
452 	if (port == 0) {
453 		sp = getservbyname(SSH_SERVICE_NAME, "tcp");
454 		port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
455 	}
456 	return port;
457 }
458 
459 /*
460  * Execute a command in a shell.
461  * Return its exit status or -1 on abnormal exit.
462  */
463 static int
464 execute_in_shell(const char *cmd)
465 {
466 	char *shell;
467 	pid_t pid;
468 	int devnull, status;
469 	extern uid_t original_real_uid;
470 
471 	if ((shell = getenv("SHELL")) == NULL)
472 		shell = _PATH_BSHELL;
473 
474 	/* Need this to redirect subprocess stdin/out */
475 	if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
476 		fatal("open(/dev/null): %s", strerror(errno));
477 
478 	debug("Executing command: '%.500s'", cmd);
479 
480 	/* Fork and execute the command. */
481 	if ((pid = fork()) == 0) {
482 		char *argv[4];
483 
484 		/* Child.  Permanently give up superuser privileges. */
485 		permanently_drop_suid(original_real_uid);
486 
487 		/* Redirect child stdin and stdout. Leave stderr */
488 		if (dup2(devnull, STDIN_FILENO) == -1)
489 			fatal("dup2: %s", strerror(errno));
490 		if (dup2(devnull, STDOUT_FILENO) == -1)
491 			fatal("dup2: %s", strerror(errno));
492 		if (devnull > STDERR_FILENO)
493 			close(devnull);
494 		closefrom(STDERR_FILENO + 1);
495 
496 		argv[0] = shell;
497 		argv[1] = "-c";
498 		argv[2] = xstrdup(cmd);
499 		argv[3] = NULL;
500 
501 		execv(argv[0], argv);
502 		error("Unable to execute '%.100s': %s", cmd, strerror(errno));
503 		/* Die with signal to make this error apparent to parent. */
504 		signal(SIGTERM, SIG_DFL);
505 		kill(getpid(), SIGTERM);
506 		_exit(1);
507 	}
508 	/* Parent. */
509 	if (pid < 0)
510 		fatal("%s: fork: %.100s", __func__, strerror(errno));
511 
512 	close(devnull);
513 
514 	while (waitpid(pid, &status, 0) == -1) {
515 		if (errno != EINTR && errno != EAGAIN)
516 			fatal("%s: waitpid: %s", __func__, strerror(errno));
517 	}
518 	if (!WIFEXITED(status)) {
519 		error("command '%.100s' exited abnormally", cmd);
520 		return -1;
521 	}
522 	debug3("command returned status %d", WEXITSTATUS(status));
523 	return WEXITSTATUS(status);
524 }
525 
526 /*
527  * Parse and execute a Match directive.
528  */
529 static int
530 match_cfg_line(Options *options, char **condition, struct passwd *pw,
531     const char *host_arg, const char *original_host, int post_canon,
532     const char *filename, int linenum)
533 {
534 	char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
535 	const char *ruser;
536 	int r, port, this_result, result = 1, attributes = 0, negate;
537 	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
538 
539 	/*
540 	 * Configuration is likely to be incomplete at this point so we
541 	 * must be prepared to use default values.
542 	 */
543 	port = options->port <= 0 ? default_ssh_port() : options->port;
544 	ruser = options->user == NULL ? pw->pw_name : options->user;
545 	if (post_canon) {
546 		host = xstrdup(options->hostname);
547 	} else if (options->hostname != NULL) {
548 		/* NB. Please keep in sync with ssh.c:main() */
549 		host = percent_expand(options->hostname,
550 		    "h", host_arg, (char *)NULL);
551 	} else {
552 		host = xstrdup(host_arg);
553 	}
554 
555 	debug2("checking match for '%s' host %s originally %s",
556 	    cp, host, original_host);
557 	while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
558 		criteria = NULL;
559 		this_result = 1;
560 		if ((negate = attrib[0] == '!'))
561 			attrib++;
562 		/* criteria "all" and "canonical" have no argument */
563 		if (strcasecmp(attrib, "all") == 0) {
564 			if (attributes > 1 ||
565 			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
566 				error("%.200s line %d: '%s' cannot be combined "
567 				    "with other Match attributes",
568 				    filename, linenum, oattrib);
569 				result = -1;
570 				goto out;
571 			}
572 			if (result)
573 				result = negate ? 0 : 1;
574 			goto out;
575 		}
576 		attributes++;
577 		if (strcasecmp(attrib, "canonical") == 0) {
578 			r = !!post_canon;  /* force bitmask member to boolean */
579 			if (r == (negate ? 1 : 0))
580 				this_result = result = 0;
581 			debug3("%.200s line %d: %smatched '%s'",
582 			    filename, linenum,
583 			    this_result ? "" : "not ", oattrib);
584 			continue;
585 		}
586 		/* All other criteria require an argument */
587 		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
588 			error("Missing Match criteria for %s", attrib);
589 			result = -1;
590 			goto out;
591 		}
592 		if (strcasecmp(attrib, "host") == 0) {
593 			criteria = xstrdup(host);
594 			r = match_hostname(host, arg) == 1;
595 			if (r == (negate ? 1 : 0))
596 				this_result = result = 0;
597 		} else if (strcasecmp(attrib, "originalhost") == 0) {
598 			criteria = xstrdup(original_host);
599 			r = match_hostname(original_host, arg) == 1;
600 			if (r == (negate ? 1 : 0))
601 				this_result = result = 0;
602 		} else if (strcasecmp(attrib, "user") == 0) {
603 			criteria = xstrdup(ruser);
604 			r = match_pattern_list(ruser, arg, 0) == 1;
605 			if (r == (negate ? 1 : 0))
606 				this_result = result = 0;
607 		} else if (strcasecmp(attrib, "localuser") == 0) {
608 			criteria = xstrdup(pw->pw_name);
609 			r = match_pattern_list(pw->pw_name, arg, 0) == 1;
610 			if (r == (negate ? 1 : 0))
611 				this_result = result = 0;
612 		} else if (strcasecmp(attrib, "exec") == 0) {
613 			if (gethostname(thishost, sizeof(thishost)) == -1)
614 				fatal("gethostname: %s", strerror(errno));
615 			strlcpy(shorthost, thishost, sizeof(shorthost));
616 			shorthost[strcspn(thishost, ".")] = '\0';
617 			snprintf(portstr, sizeof(portstr), "%d", port);
618 
619 			cmd = percent_expand(arg,
620 			    "L", shorthost,
621 			    "d", pw->pw_dir,
622 			    "h", host,
623 			    "l", thishost,
624 			    "n", original_host,
625 			    "p", portstr,
626 			    "r", ruser,
627 			    "u", pw->pw_name,
628 			    (char *)NULL);
629 			if (result != 1) {
630 				/* skip execution if prior predicate failed */
631 				debug3("%.200s line %d: skipped exec "
632 				    "\"%.100s\"", filename, linenum, cmd);
633 				free(cmd);
634 				continue;
635 			}
636 			r = execute_in_shell(cmd);
637 			if (r == -1) {
638 				fatal("%.200s line %d: match exec "
639 				    "'%.100s' error", filename,
640 				    linenum, cmd);
641 			}
642 			criteria = xstrdup(cmd);
643 			free(cmd);
644 			/* Force exit status to boolean */
645 			r = r == 0;
646 			if (r == (negate ? 1 : 0))
647 				this_result = result = 0;
648 		} else {
649 			error("Unsupported Match attribute %s", attrib);
650 			result = -1;
651 			goto out;
652 		}
653 		debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
654 		    filename, linenum, this_result ? "": "not ",
655 		    oattrib, criteria);
656 		free(criteria);
657 	}
658 	if (attributes == 0) {
659 		error("One or more attributes required for Match");
660 		result = -1;
661 		goto out;
662 	}
663  out:
664 	if (result != -1)
665 		debug2("match %sfound", result ? "" : "not ");
666 	*condition = cp;
667 	free(host);
668 	return result;
669 }
670 
671 /*
672  * Returns the number of the token pointed to by cp or oBadOption.
673  */
674 static OpCodes
675 parse_token(const char *cp, const char *filename, int linenum,
676     const char *ignored_unknown)
677 {
678 	int i;
679 
680 	for (i = 0; keywords[i].name; i++)
681 		if (strcmp(cp, keywords[i].name) == 0)
682 			return keywords[i].opcode;
683 	if (ignored_unknown != NULL &&
684 	    match_pattern_list(cp, ignored_unknown, 1) == 1)
685 		return oIgnoredUnknownOption;
686 	error("%s: line %d: Bad configuration option: %s",
687 	    filename, linenum, cp);
688 	return oBadOption;
689 }
690 
691 /* Multistate option parsing */
692 struct multistate {
693 	char *key;
694 	int value;
695 };
696 static const struct multistate multistate_flag[] = {
697 	{ "true",			1 },
698 	{ "false",			0 },
699 	{ "yes",			1 },
700 	{ "no",				0 },
701 	{ NULL, -1 }
702 };
703 static const struct multistate multistate_yesnoask[] = {
704 	{ "true",			1 },
705 	{ "false",			0 },
706 	{ "yes",			1 },
707 	{ "no",				0 },
708 	{ "ask",			2 },
709 	{ NULL, -1 }
710 };
711 static const struct multistate multistate_strict_hostkey[] = {
712 	{ "true",			SSH_STRICT_HOSTKEY_YES },
713 	{ "false",			SSH_STRICT_HOSTKEY_OFF },
714 	{ "yes",			SSH_STRICT_HOSTKEY_YES },
715 	{ "no",				SSH_STRICT_HOSTKEY_OFF },
716 	{ "ask",			SSH_STRICT_HOSTKEY_ASK },
717 	{ "off",			SSH_STRICT_HOSTKEY_OFF },
718 	{ "accept-new",			SSH_STRICT_HOSTKEY_NEW },
719 	{ NULL, -1 }
720 };
721 static const struct multistate multistate_yesnoaskconfirm[] = {
722 	{ "true",			1 },
723 	{ "false",			0 },
724 	{ "yes",			1 },
725 	{ "no",				0 },
726 	{ "ask",			2 },
727 	{ "confirm",			3 },
728 	{ NULL, -1 }
729 };
730 static const struct multistate multistate_addressfamily[] = {
731 	{ "inet",			AF_INET },
732 	{ "inet6",			AF_INET6 },
733 	{ "any",			AF_UNSPEC },
734 	{ NULL, -1 }
735 };
736 static const struct multistate multistate_controlmaster[] = {
737 	{ "true",			SSHCTL_MASTER_YES },
738 	{ "yes",			SSHCTL_MASTER_YES },
739 	{ "false",			SSHCTL_MASTER_NO },
740 	{ "no",				SSHCTL_MASTER_NO },
741 	{ "auto",			SSHCTL_MASTER_AUTO },
742 	{ "ask",			SSHCTL_MASTER_ASK },
743 	{ "autoask",			SSHCTL_MASTER_AUTO_ASK },
744 	{ NULL, -1 }
745 };
746 static const struct multistate multistate_tunnel[] = {
747 	{ "ethernet",			SSH_TUNMODE_ETHERNET },
748 	{ "point-to-point",		SSH_TUNMODE_POINTOPOINT },
749 	{ "true",			SSH_TUNMODE_DEFAULT },
750 	{ "yes",			SSH_TUNMODE_DEFAULT },
751 	{ "false",			SSH_TUNMODE_NO },
752 	{ "no",				SSH_TUNMODE_NO },
753 	{ NULL, -1 }
754 };
755 static const struct multistate multistate_requesttty[] = {
756 	{ "true",			REQUEST_TTY_YES },
757 	{ "yes",			REQUEST_TTY_YES },
758 	{ "false",			REQUEST_TTY_NO },
759 	{ "no",				REQUEST_TTY_NO },
760 	{ "force",			REQUEST_TTY_FORCE },
761 	{ "auto",			REQUEST_TTY_AUTO },
762 	{ NULL, -1 }
763 };
764 static const struct multistate multistate_canonicalizehostname[] = {
765 	{ "true",			SSH_CANONICALISE_YES },
766 	{ "false",			SSH_CANONICALISE_NO },
767 	{ "yes",			SSH_CANONICALISE_YES },
768 	{ "no",				SSH_CANONICALISE_NO },
769 	{ "always",			SSH_CANONICALISE_ALWAYS },
770 	{ NULL, -1 }
771 };
772 
773 /*
774  * Processes a single option line as used in the configuration files. This
775  * only sets those values that have not already been set.
776  */
777 int
778 process_config_line(Options *options, struct passwd *pw, const char *host,
779     const char *original_host, char *line, const char *filename,
780     int linenum, int *activep, int flags)
781 {
782 	return process_config_line_depth(options, pw, host, original_host,
783 	    line, filename, linenum, activep, flags, 0);
784 }
785 
786 #define WHITESPACE " \t\r\n"
787 static int
788 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
789     const char *original_host, char *line, const char *filename,
790     int linenum, int *activep, int flags, int depth)
791 {
792 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
793 	char **cpptr, fwdarg[256];
794 	u_int i, *uintptr, max_entries = 0;
795 	int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
796 	int remotefwd, dynamicfwd;
797 	LogLevel *log_level_ptr;
798 	SyslogFacility *log_facility_ptr;
799 	long long val64;
800 	size_t len;
801 	struct Forward fwd;
802 	const struct multistate *multistate_ptr;
803 	struct allowed_cname *cname;
804 	glob_t gl;
805 
806 	if (activep == NULL) { /* We are processing a command line directive */
807 		cmdline = 1;
808 		activep = &cmdline;
809 	}
810 
811 	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
812 	if ((len = strlen(line)) == 0)
813 		return 0;
814 	for (len--; len > 0; len--) {
815 		if (strchr(WHITESPACE "\f", line[len]) == NULL)
816 			break;
817 		line[len] = '\0';
818 	}
819 
820 	s = line;
821 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
822 	if ((keyword = strdelim(&s)) == NULL)
823 		return 0;
824 	/* Ignore leading whitespace. */
825 	if (*keyword == '\0')
826 		keyword = strdelim(&s);
827 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
828 		return 0;
829 	/* Match lowercase keyword */
830 	lowercase(keyword);
831 
832 	opcode = parse_token(keyword, filename, linenum,
833 	    options->ignored_unknown);
834 
835 	switch (opcode) {
836 	case oBadOption:
837 		/* don't panic, but count bad options */
838 		return -1;
839 	case oIgnore:
840 		return 0;
841 	case oIgnoredUnknownOption:
842 		debug("%s line %d: Ignored unknown option \"%s\"",
843 		    filename, linenum, keyword);
844 		return 0;
845 	case oConnectTimeout:
846 		intptr = &options->connection_timeout;
847 parse_time:
848 		arg = strdelim(&s);
849 		if (!arg || *arg == '\0')
850 			fatal("%s line %d: missing time value.",
851 			    filename, linenum);
852 		if (strcmp(arg, "none") == 0)
853 			value = -1;
854 		else if ((value = convtime(arg)) == -1)
855 			fatal("%s line %d: invalid time value.",
856 			    filename, linenum);
857 		if (*activep && *intptr == -1)
858 			*intptr = value;
859 		break;
860 
861 	case oForwardAgent:
862 		intptr = &options->forward_agent;
863  parse_flag:
864 		multistate_ptr = multistate_flag;
865  parse_multistate:
866 		arg = strdelim(&s);
867 		if (!arg || *arg == '\0')
868 			fatal("%s line %d: missing argument.",
869 			    filename, linenum);
870 		value = -1;
871 		for (i = 0; multistate_ptr[i].key != NULL; i++) {
872 			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
873 				value = multistate_ptr[i].value;
874 				break;
875 			}
876 		}
877 		if (value == -1)
878 			fatal("%s line %d: unsupported option \"%s\".",
879 			    filename, linenum, arg);
880 		if (*activep && *intptr == -1)
881 			*intptr = value;
882 		break;
883 
884 	case oForwardX11:
885 		intptr = &options->forward_x11;
886 		goto parse_flag;
887 
888 	case oForwardX11Trusted:
889 		intptr = &options->forward_x11_trusted;
890 		goto parse_flag;
891 
892 	case oForwardX11Timeout:
893 		intptr = &options->forward_x11_timeout;
894 		goto parse_time;
895 
896 	case oGatewayPorts:
897 		intptr = &options->fwd_opts.gateway_ports;
898 		goto parse_flag;
899 
900 	case oExitOnForwardFailure:
901 		intptr = &options->exit_on_forward_failure;
902 		goto parse_flag;
903 
904 	case oUsePrivilegedPort:
905 		intptr = &options->use_privileged_port;
906 		goto parse_flag;
907 
908 	case oPasswordAuthentication:
909 		intptr = &options->password_authentication;
910 		goto parse_flag;
911 
912 	case oKbdInteractiveAuthentication:
913 		intptr = &options->kbd_interactive_authentication;
914 		goto parse_flag;
915 
916 	case oKbdInteractiveDevices:
917 		charptr = &options->kbd_interactive_devices;
918 		goto parse_string;
919 
920 	case oPubkeyAuthentication:
921 		intptr = &options->pubkey_authentication;
922 		goto parse_flag;
923 
924 	case oHostbasedAuthentication:
925 		intptr = &options->hostbased_authentication;
926 		goto parse_flag;
927 
928 	case oChallengeResponseAuthentication:
929 		intptr = &options->challenge_response_authentication;
930 		goto parse_flag;
931 
932 	case oGssAuthentication:
933 		intptr = &options->gss_authentication;
934 		goto parse_flag;
935 
936 	case oGssDelegateCreds:
937 		intptr = &options->gss_deleg_creds;
938 		goto parse_flag;
939 
940 	case oBatchMode:
941 		intptr = &options->batch_mode;
942 		goto parse_flag;
943 
944 	case oCheckHostIP:
945 		intptr = &options->check_host_ip;
946 		goto parse_flag;
947 
948 	case oVerifyHostKeyDNS:
949 		intptr = &options->verify_host_key_dns;
950 		multistate_ptr = multistate_yesnoask;
951 		goto parse_multistate;
952 
953 	case oStrictHostKeyChecking:
954 		intptr = &options->strict_host_key_checking;
955 		multistate_ptr = multistate_strict_hostkey;
956 		goto parse_multistate;
957 
958 	case oCompression:
959 		intptr = &options->compression;
960 		goto parse_flag;
961 
962 	case oTCPKeepAlive:
963 		intptr = &options->tcp_keep_alive;
964 		goto parse_flag;
965 
966 	case oNoHostAuthenticationForLocalhost:
967 		intptr = &options->no_host_authentication_for_localhost;
968 		goto parse_flag;
969 
970 	case oNumberOfPasswordPrompts:
971 		intptr = &options->number_of_password_prompts;
972 		goto parse_int;
973 
974 	case oRekeyLimit:
975 		arg = strdelim(&s);
976 		if (!arg || *arg == '\0')
977 			fatal("%.200s line %d: Missing argument.", filename,
978 			    linenum);
979 		if (strcmp(arg, "default") == 0) {
980 			val64 = 0;
981 		} else {
982 			if (scan_scaled(arg, &val64) == -1)
983 				fatal("%.200s line %d: Bad number '%s': %s",
984 				    filename, linenum, arg, strerror(errno));
985 			if (val64 != 0 && val64 < 16)
986 				fatal("%.200s line %d: RekeyLimit too small",
987 				    filename, linenum);
988 		}
989 		if (*activep && options->rekey_limit == -1)
990 			options->rekey_limit = val64;
991 		if (s != NULL) { /* optional rekey interval present */
992 			if (strcmp(s, "none") == 0) {
993 				(void)strdelim(&s);	/* discard */
994 				break;
995 			}
996 			intptr = &options->rekey_interval;
997 			goto parse_time;
998 		}
999 		break;
1000 
1001 	case oIdentityFile:
1002 		arg = strdelim(&s);
1003 		if (!arg || *arg == '\0')
1004 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1005 		if (*activep) {
1006 			intptr = &options->num_identity_files;
1007 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
1008 				fatal("%.200s line %d: Too many identity files specified (max %d).",
1009 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
1010 			add_identity_file(options, NULL,
1011 			    arg, flags & SSHCONF_USERCONF);
1012 		}
1013 		break;
1014 
1015 	case oCertificateFile:
1016 		arg = strdelim(&s);
1017 		if (!arg || *arg == '\0')
1018 			fatal("%.200s line %d: Missing argument.",
1019 			    filename, linenum);
1020 		if (*activep) {
1021 			intptr = &options->num_certificate_files;
1022 			if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1023 				fatal("%.200s line %d: Too many certificate "
1024 				    "files specified (max %d).",
1025 				    filename, linenum,
1026 				    SSH_MAX_CERTIFICATE_FILES);
1027 			}
1028 			add_certificate_file(options, arg,
1029 			    flags & SSHCONF_USERCONF);
1030 		}
1031 		break;
1032 
1033 	case oXAuthLocation:
1034 		charptr=&options->xauth_location;
1035 		goto parse_string;
1036 
1037 	case oUser:
1038 		charptr = &options->user;
1039 parse_string:
1040 		arg = strdelim(&s);
1041 		if (!arg || *arg == '\0')
1042 			fatal("%.200s line %d: Missing argument.",
1043 			    filename, linenum);
1044 		if (*activep && *charptr == NULL)
1045 			*charptr = xstrdup(arg);
1046 		break;
1047 
1048 	case oGlobalKnownHostsFile:
1049 		cpptr = (char **)&options->system_hostfiles;
1050 		uintptr = &options->num_system_hostfiles;
1051 		max_entries = SSH_MAX_HOSTS_FILES;
1052 parse_char_array:
1053 		if (*activep && *uintptr == 0) {
1054 			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1055 				if ((*uintptr) >= max_entries)
1056 					fatal("%s line %d: "
1057 					    "too many authorized keys files.",
1058 					    filename, linenum);
1059 				cpptr[(*uintptr)++] = xstrdup(arg);
1060 			}
1061 		}
1062 		return 0;
1063 
1064 	case oUserKnownHostsFile:
1065 		cpptr = (char **)&options->user_hostfiles;
1066 		uintptr = &options->num_user_hostfiles;
1067 		max_entries = SSH_MAX_HOSTS_FILES;
1068 		goto parse_char_array;
1069 
1070 	case oHostName:
1071 		charptr = &options->hostname;
1072 		goto parse_string;
1073 
1074 	case oHostKeyAlias:
1075 		charptr = &options->host_key_alias;
1076 		goto parse_string;
1077 
1078 	case oPreferredAuthentications:
1079 		charptr = &options->preferred_authentications;
1080 		goto parse_string;
1081 
1082 	case oBindAddress:
1083 		charptr = &options->bind_address;
1084 		goto parse_string;
1085 
1086 	case oPKCS11Provider:
1087 		charptr = &options->pkcs11_provider;
1088 		goto parse_string;
1089 
1090 	case oProxyCommand:
1091 		charptr = &options->proxy_command;
1092 		/* Ignore ProxyCommand if ProxyJump already specified */
1093 		if (options->jump_host != NULL)
1094 			charptr = &options->jump_host; /* Skip below */
1095 parse_command:
1096 		if (s == NULL)
1097 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1098 		len = strspn(s, WHITESPACE "=");
1099 		if (*activep && *charptr == NULL)
1100 			*charptr = xstrdup(s + len);
1101 		return 0;
1102 
1103 	case oProxyJump:
1104 		if (s == NULL) {
1105 			fatal("%.200s line %d: Missing argument.",
1106 			    filename, linenum);
1107 		}
1108 		len = strspn(s, WHITESPACE "=");
1109 		if (parse_jump(s + len, options, *activep) == -1) {
1110 			fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1111 			    filename, linenum, s + len);
1112 		}
1113 		return 0;
1114 
1115 	case oPort:
1116 		intptr = &options->port;
1117 parse_int:
1118 		arg = strdelim(&s);
1119 		if (!arg || *arg == '\0')
1120 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1121 		if (arg[0] < '0' || arg[0] > '9')
1122 			fatal("%.200s line %d: Bad number.", filename, linenum);
1123 
1124 		/* Octal, decimal, or hex format? */
1125 		value = strtol(arg, &endofnumber, 0);
1126 		if (arg == endofnumber)
1127 			fatal("%.200s line %d: Bad number.", filename, linenum);
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 			const char *errstr;
1523 			if (!valid_domain(arg, 1, &errstr)) {
1524 				fatal("%s line %d: %s", filename, linenum,
1525 				    errstr);
1526 			}
1527 			if (!*activep || value)
1528 				continue;
1529 			if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1530 				fatal("%s line %d: too many hostname suffixes.",
1531 				    filename, linenum);
1532 			options->canonical_domains[
1533 			    options->num_canonical_domains++] = xstrdup(arg);
1534 		}
1535 		break;
1536 
1537 	case oCanonicalizePermittedCNAMEs:
1538 		value = options->num_permitted_cnames != 0;
1539 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1540 			/* Either '*' for everything or 'list:list' */
1541 			if (strcmp(arg, "*") == 0)
1542 				arg2 = arg;
1543 			else {
1544 				lowercase(arg);
1545 				if ((arg2 = strchr(arg, ':')) == NULL ||
1546 				    arg2[1] == '\0') {
1547 					fatal("%s line %d: "
1548 					    "Invalid permitted CNAME \"%s\"",
1549 					    filename, linenum, arg);
1550 				}
1551 				*arg2 = '\0';
1552 				arg2++;
1553 			}
1554 			if (!*activep || value)
1555 				continue;
1556 			if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1557 				fatal("%s line %d: too many permitted CNAMEs.",
1558 				    filename, linenum);
1559 			cname = options->permitted_cnames +
1560 			    options->num_permitted_cnames++;
1561 			cname->source_list = xstrdup(arg);
1562 			cname->target_list = xstrdup(arg2);
1563 		}
1564 		break;
1565 
1566 	case oCanonicalizeHostname:
1567 		intptr = &options->canonicalize_hostname;
1568 		multistate_ptr = multistate_canonicalizehostname;
1569 		goto parse_multistate;
1570 
1571 	case oCanonicalizeMaxDots:
1572 		intptr = &options->canonicalize_max_dots;
1573 		goto parse_int;
1574 
1575 	case oCanonicalizeFallbackLocal:
1576 		intptr = &options->canonicalize_fallback_local;
1577 		goto parse_flag;
1578 
1579 	case oStreamLocalBindMask:
1580 		arg = strdelim(&s);
1581 		if (!arg || *arg == '\0')
1582 			fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1583 		/* Parse mode in octal format */
1584 		value = strtol(arg, &endofnumber, 8);
1585 		if (arg == endofnumber || value < 0 || value > 0777)
1586 			fatal("%.200s line %d: Bad mask.", filename, linenum);
1587 		options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1588 		break;
1589 
1590 	case oStreamLocalBindUnlink:
1591 		intptr = &options->fwd_opts.streamlocal_bind_unlink;
1592 		goto parse_flag;
1593 
1594 	case oRevokedHostKeys:
1595 		charptr = &options->revoked_host_keys;
1596 		goto parse_string;
1597 
1598 	case oFingerprintHash:
1599 		intptr = &options->fingerprint_hash;
1600 		arg = strdelim(&s);
1601 		if (!arg || *arg == '\0')
1602 			fatal("%.200s line %d: Missing argument.",
1603 			    filename, linenum);
1604 		if ((value = ssh_digest_alg_by_name(arg)) == -1)
1605 			fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1606 			    filename, linenum, arg);
1607 		if (*activep && *intptr == -1)
1608 			*intptr = value;
1609 		break;
1610 
1611 	case oUpdateHostkeys:
1612 		intptr = &options->update_hostkeys;
1613 		multistate_ptr = multistate_yesnoask;
1614 		goto parse_multistate;
1615 
1616 	case oHostbasedKeyTypes:
1617 		charptr = &options->hostbased_key_types;
1618 		goto parse_keytypes;
1619 
1620 	case oPubkeyAcceptedKeyTypes:
1621 		charptr = &options->pubkey_key_types;
1622 		goto parse_keytypes;
1623 
1624 	case oAddKeysToAgent:
1625 		intptr = &options->add_keys_to_agent;
1626 		multistate_ptr = multistate_yesnoaskconfirm;
1627 		goto parse_multistate;
1628 
1629 	case oIdentityAgent:
1630 		charptr = &options->identity_agent;
1631 		goto parse_string;
1632 
1633 	case oDeprecated:
1634 		debug("%s line %d: Deprecated option \"%s\"",
1635 		    filename, linenum, keyword);
1636 		return 0;
1637 
1638 	case oUnsupported:
1639 		error("%s line %d: Unsupported option \"%s\"",
1640 		    filename, linenum, keyword);
1641 		return 0;
1642 
1643 	default:
1644 		fatal("%s: Unimplemented opcode %d", __func__, opcode);
1645 	}
1646 
1647 	/* Check that there is no garbage at end of line. */
1648 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1649 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1650 		    filename, linenum, arg);
1651 	}
1652 	return 0;
1653 }
1654 
1655 /*
1656  * Reads the config file and modifies the options accordingly.  Options
1657  * should already be initialized before this call.  This never returns if
1658  * there is an error.  If the file does not exist, this returns 0.
1659  */
1660 int
1661 read_config_file(const char *filename, struct passwd *pw, const char *host,
1662     const char *original_host, Options *options, int flags)
1663 {
1664 	int active = 1;
1665 
1666 	return read_config_file_depth(filename, pw, host, original_host,
1667 	    options, flags, &active, 0);
1668 }
1669 
1670 #define READCONF_MAX_DEPTH	16
1671 static int
1672 read_config_file_depth(const char *filename, struct passwd *pw,
1673     const char *host, const char *original_host, Options *options,
1674     int flags, int *activep, int depth)
1675 {
1676 	FILE *f;
1677 	char line[4096];
1678 	int linenum;
1679 	int bad_options = 0;
1680 
1681 	if (depth < 0 || depth > READCONF_MAX_DEPTH)
1682 		fatal("Too many recursive configuration includes");
1683 
1684 	if ((f = fopen(filename, "r")) == NULL)
1685 		return 0;
1686 
1687 	if (flags & SSHCONF_CHECKPERM) {
1688 		struct stat sb;
1689 
1690 		if (fstat(fileno(f), &sb) == -1)
1691 			fatal("fstat %s: %s", filename, strerror(errno));
1692 		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1693 		    (sb.st_mode & 022) != 0))
1694 			fatal("Bad owner or permissions on %s", filename);
1695 	}
1696 
1697 	debug("Reading configuration data %.200s", filename);
1698 
1699 	/*
1700 	 * Mark that we are now processing the options.  This flag is turned
1701 	 * on/off by Host specifications.
1702 	 */
1703 	linenum = 0;
1704 	while (fgets(line, sizeof(line), f)) {
1705 		/* Update line number counter. */
1706 		linenum++;
1707 		if (strlen(line) == sizeof(line) - 1)
1708 			fatal("%s line %d too long", filename, linenum);
1709 		if (process_config_line_depth(options, pw, host, original_host,
1710 		    line, filename, linenum, activep, flags, depth) != 0)
1711 			bad_options++;
1712 	}
1713 	fclose(f);
1714 	if (bad_options > 0)
1715 		fatal("%s: terminating, %d bad configuration options",
1716 		    filename, bad_options);
1717 	return 1;
1718 }
1719 
1720 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1721 int
1722 option_clear_or_none(const char *o)
1723 {
1724 	return o == NULL || strcasecmp(o, "none") == 0;
1725 }
1726 
1727 /*
1728  * Initializes options to special values that indicate that they have not yet
1729  * been set.  Read_config_file will only set options with this value. Options
1730  * are processed in the following order: command line, user config file,
1731  * system config file.  Last, fill_default_options is called.
1732  */
1733 
1734 void
1735 initialize_options(Options * options)
1736 {
1737 	memset(options, 'X', sizeof(*options));
1738 	options->forward_agent = -1;
1739 	options->forward_x11 = -1;
1740 	options->forward_x11_trusted = -1;
1741 	options->forward_x11_timeout = -1;
1742 	options->stdio_forward_host = NULL;
1743 	options->stdio_forward_port = 0;
1744 	options->clear_forwardings = -1;
1745 	options->exit_on_forward_failure = -1;
1746 	options->xauth_location = NULL;
1747 	options->fwd_opts.gateway_ports = -1;
1748 	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1749 	options->fwd_opts.streamlocal_bind_unlink = -1;
1750 	options->use_privileged_port = -1;
1751 	options->pubkey_authentication = -1;
1752 	options->challenge_response_authentication = -1;
1753 	options->gss_authentication = -1;
1754 	options->gss_deleg_creds = -1;
1755 	options->password_authentication = -1;
1756 	options->kbd_interactive_authentication = -1;
1757 	options->kbd_interactive_devices = NULL;
1758 	options->hostbased_authentication = -1;
1759 	options->batch_mode = -1;
1760 	options->check_host_ip = -1;
1761 	options->strict_host_key_checking = -1;
1762 	options->compression = -1;
1763 	options->tcp_keep_alive = -1;
1764 	options->port = -1;
1765 	options->address_family = -1;
1766 	options->connection_attempts = -1;
1767 	options->connection_timeout = -1;
1768 	options->number_of_password_prompts = -1;
1769 	options->ciphers = NULL;
1770 	options->macs = NULL;
1771 	options->kex_algorithms = NULL;
1772 	options->hostkeyalgorithms = NULL;
1773 	options->num_identity_files = 0;
1774 	options->num_certificate_files = 0;
1775 	options->hostname = NULL;
1776 	options->host_key_alias = NULL;
1777 	options->proxy_command = NULL;
1778 	options->jump_user = NULL;
1779 	options->jump_host = NULL;
1780 	options->jump_port = -1;
1781 	options->jump_extra = NULL;
1782 	options->user = NULL;
1783 	options->escape_char = -1;
1784 	options->num_system_hostfiles = 0;
1785 	options->num_user_hostfiles = 0;
1786 	options->local_forwards = NULL;
1787 	options->num_local_forwards = 0;
1788 	options->remote_forwards = NULL;
1789 	options->num_remote_forwards = 0;
1790 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
1791 	options->log_level = SYSLOG_LEVEL_NOT_SET;
1792 	options->preferred_authentications = NULL;
1793 	options->bind_address = 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 	}
1930 	if (options->escape_char == -1)
1931 		options->escape_char = '~';
1932 	if (options->num_system_hostfiles == 0) {
1933 		options->system_hostfiles[options->num_system_hostfiles++] =
1934 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1935 		options->system_hostfiles[options->num_system_hostfiles++] =
1936 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1937 	}
1938 	if (options->num_user_hostfiles == 0) {
1939 		options->user_hostfiles[options->num_user_hostfiles++] =
1940 		    xstrdup(_PATH_SSH_USER_HOSTFILE);
1941 		options->user_hostfiles[options->num_user_hostfiles++] =
1942 		    xstrdup(_PATH_SSH_USER_HOSTFILE2);
1943 	}
1944 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1945 		options->log_level = SYSLOG_LEVEL_INFO;
1946 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
1947 		options->log_facility = SYSLOG_FACILITY_USER;
1948 	if (options->no_host_authentication_for_localhost == - 1)
1949 		options->no_host_authentication_for_localhost = 0;
1950 	if (options->identities_only == -1)
1951 		options->identities_only = 0;
1952 	if (options->enable_ssh_keysign == -1)
1953 		options->enable_ssh_keysign = 0;
1954 	if (options->rekey_limit == -1)
1955 		options->rekey_limit = 0;
1956 	if (options->rekey_interval == -1)
1957 		options->rekey_interval = 0;
1958 	if (options->verify_host_key_dns == -1)
1959 		options->verify_host_key_dns = 0;
1960 	if (options->server_alive_interval == -1)
1961 		options->server_alive_interval = 0;
1962 	if (options->server_alive_count_max == -1)
1963 		options->server_alive_count_max = 3;
1964 	if (options->control_master == -1)
1965 		options->control_master = 0;
1966 	if (options->control_persist == -1) {
1967 		options->control_persist = 0;
1968 		options->control_persist_timeout = 0;
1969 	}
1970 	if (options->hash_known_hosts == -1)
1971 		options->hash_known_hosts = 0;
1972 	if (options->tun_open == -1)
1973 		options->tun_open = SSH_TUNMODE_NO;
1974 	if (options->tun_local == -1)
1975 		options->tun_local = SSH_TUNID_ANY;
1976 	if (options->tun_remote == -1)
1977 		options->tun_remote = SSH_TUNID_ANY;
1978 	if (options->permit_local_command == -1)
1979 		options->permit_local_command = 0;
1980 	if (options->visual_host_key == -1)
1981 		options->visual_host_key = 0;
1982 	if (options->ip_qos_interactive == -1)
1983 		options->ip_qos_interactive = IPTOS_LOWDELAY;
1984 	if (options->ip_qos_bulk == -1)
1985 		options->ip_qos_bulk = IPTOS_THROUGHPUT;
1986 	if (options->request_tty == -1)
1987 		options->request_tty = REQUEST_TTY_AUTO;
1988 	if (options->proxy_use_fdpass == -1)
1989 		options->proxy_use_fdpass = 0;
1990 	if (options->canonicalize_max_dots == -1)
1991 		options->canonicalize_max_dots = 1;
1992 	if (options->canonicalize_fallback_local == -1)
1993 		options->canonicalize_fallback_local = 1;
1994 	if (options->canonicalize_hostname == -1)
1995 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
1996 	if (options->fingerprint_hash == -1)
1997 		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
1998 	if (options->update_hostkeys == -1)
1999 		options->update_hostkeys = 0;
2000 	if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
2001 	    kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
2002 	    kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
2003 	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
2004 	    &options->hostbased_key_types) != 0 ||
2005 	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
2006 	    &options->pubkey_key_types) != 0)
2007 		fatal("%s: kex_assemble_names failed", __func__);
2008 
2009 #define CLEAR_ON_NONE(v) \
2010 	do { \
2011 		if (option_clear_or_none(v)) { \
2012 			free(v); \
2013 			v = NULL; \
2014 		} \
2015 	} while(0)
2016 	CLEAR_ON_NONE(options->local_command);
2017 	CLEAR_ON_NONE(options->remote_command);
2018 	CLEAR_ON_NONE(options->proxy_command);
2019 	CLEAR_ON_NONE(options->control_path);
2020 	CLEAR_ON_NONE(options->revoked_host_keys);
2021 	/* options->identity_agent distinguishes NULL from 'none' */
2022 	/* options->user will be set in the main program if appropriate */
2023 	/* options->hostname will be set in the main program if appropriate */
2024 	/* options->host_key_alias should not be set by default */
2025 	/* options->preferred_authentications will be set in ssh */
2026 }
2027 
2028 struct fwdarg {
2029 	char *arg;
2030 	int ispath;
2031 };
2032 
2033 /*
2034  * parse_fwd_field
2035  * parses the next field in a port forwarding specification.
2036  * sets fwd to the parsed field and advances p past the colon
2037  * or sets it to NULL at end of string.
2038  * returns 0 on success, else non-zero.
2039  */
2040 static int
2041 parse_fwd_field(char **p, struct fwdarg *fwd)
2042 {
2043 	char *ep, *cp = *p;
2044 	int ispath = 0;
2045 
2046 	if (*cp == '\0') {
2047 		*p = NULL;
2048 		return -1;	/* end of string */
2049 	}
2050 
2051 	/*
2052 	 * A field escaped with square brackets is used literally.
2053 	 * XXX - allow ']' to be escaped via backslash?
2054 	 */
2055 	if (*cp == '[') {
2056 		/* find matching ']' */
2057 		for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2058 			if (*ep == '/')
2059 				ispath = 1;
2060 		}
2061 		/* no matching ']' or not at end of field. */
2062 		if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2063 			return -1;
2064 		/* NUL terminate the field and advance p past the colon */
2065 		*ep++ = '\0';
2066 		if (*ep != '\0')
2067 			*ep++ = '\0';
2068 		fwd->arg = cp + 1;
2069 		fwd->ispath = ispath;
2070 		*p = ep;
2071 		return 0;
2072 	}
2073 
2074 	for (cp = *p; *cp != '\0'; cp++) {
2075 		switch (*cp) {
2076 		case '\\':
2077 			memmove(cp, cp + 1, strlen(cp + 1) + 1);
2078 			if (*cp == '\0')
2079 				return -1;
2080 			break;
2081 		case '/':
2082 			ispath = 1;
2083 			break;
2084 		case ':':
2085 			*cp++ = '\0';
2086 			goto done;
2087 		}
2088 	}
2089 done:
2090 	fwd->arg = *p;
2091 	fwd->ispath = ispath;
2092 	*p = cp;
2093 	return 0;
2094 }
2095 
2096 /*
2097  * parse_forward
2098  * parses a string containing a port forwarding specification of the form:
2099  *   dynamicfwd == 0
2100  *	[listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2101  *	listenpath:connectpath
2102  *   dynamicfwd == 1
2103  *	[listenhost:]listenport
2104  * returns number of arguments parsed or zero on error
2105  */
2106 int
2107 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2108 {
2109 	struct fwdarg fwdargs[4];
2110 	char *p, *cp;
2111 	int i;
2112 
2113 	memset(fwd, 0, sizeof(*fwd));
2114 	memset(fwdargs, 0, sizeof(fwdargs));
2115 
2116 	cp = p = xstrdup(fwdspec);
2117 
2118 	/* skip leading spaces */
2119 	while (isspace((u_char)*cp))
2120 		cp++;
2121 
2122 	for (i = 0; i < 4; ++i) {
2123 		if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2124 			break;
2125 	}
2126 
2127 	/* Check for trailing garbage */
2128 	if (cp != NULL && *cp != '\0') {
2129 		i = 0;	/* failure */
2130 	}
2131 
2132 	switch (i) {
2133 	case 1:
2134 		if (fwdargs[0].ispath) {
2135 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2136 			fwd->listen_port = PORT_STREAMLOCAL;
2137 		} else {
2138 			fwd->listen_host = NULL;
2139 			fwd->listen_port = a2port(fwdargs[0].arg);
2140 		}
2141 		fwd->connect_host = xstrdup("socks");
2142 		break;
2143 
2144 	case 2:
2145 		if (fwdargs[0].ispath && fwdargs[1].ispath) {
2146 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2147 			fwd->listen_port = PORT_STREAMLOCAL;
2148 			fwd->connect_path = xstrdup(fwdargs[1].arg);
2149 			fwd->connect_port = PORT_STREAMLOCAL;
2150 		} else if (fwdargs[1].ispath) {
2151 			fwd->listen_host = NULL;
2152 			fwd->listen_port = a2port(fwdargs[0].arg);
2153 			fwd->connect_path = xstrdup(fwdargs[1].arg);
2154 			fwd->connect_port = PORT_STREAMLOCAL;
2155 		} else {
2156 			fwd->listen_host = xstrdup(fwdargs[0].arg);
2157 			fwd->listen_port = a2port(fwdargs[1].arg);
2158 			fwd->connect_host = xstrdup("socks");
2159 		}
2160 		break;
2161 
2162 	case 3:
2163 		if (fwdargs[0].ispath) {
2164 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2165 			fwd->listen_port = PORT_STREAMLOCAL;
2166 			fwd->connect_host = xstrdup(fwdargs[1].arg);
2167 			fwd->connect_port = a2port(fwdargs[2].arg);
2168 		} else if (fwdargs[2].ispath) {
2169 			fwd->listen_host = xstrdup(fwdargs[0].arg);
2170 			fwd->listen_port = a2port(fwdargs[1].arg);
2171 			fwd->connect_path = xstrdup(fwdargs[2].arg);
2172 			fwd->connect_port = PORT_STREAMLOCAL;
2173 		} else {
2174 			fwd->listen_host = NULL;
2175 			fwd->listen_port = a2port(fwdargs[0].arg);
2176 			fwd->connect_host = xstrdup(fwdargs[1].arg);
2177 			fwd->connect_port = a2port(fwdargs[2].arg);
2178 		}
2179 		break;
2180 
2181 	case 4:
2182 		fwd->listen_host = xstrdup(fwdargs[0].arg);
2183 		fwd->listen_port = a2port(fwdargs[1].arg);
2184 		fwd->connect_host = xstrdup(fwdargs[2].arg);
2185 		fwd->connect_port = a2port(fwdargs[3].arg);
2186 		break;
2187 	default:
2188 		i = 0; /* failure */
2189 	}
2190 
2191 	free(p);
2192 
2193 	if (dynamicfwd) {
2194 		if (!(i == 1 || i == 2))
2195 			goto fail_free;
2196 	} else {
2197 		if (!(i == 3 || i == 4)) {
2198 			if (fwd->connect_path == NULL &&
2199 			    fwd->listen_path == NULL)
2200 				goto fail_free;
2201 		}
2202 		if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2203 			goto fail_free;
2204 	}
2205 
2206 	if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2207 	    (!remotefwd && fwd->listen_port == 0))
2208 		goto fail_free;
2209 	if (fwd->connect_host != NULL &&
2210 	    strlen(fwd->connect_host) >= NI_MAXHOST)
2211 		goto fail_free;
2212 	/* XXX - if connecting to a remote socket, max sun len may not match this host */
2213 	if (fwd->connect_path != NULL &&
2214 	    strlen(fwd->connect_path) >= PATH_MAX_SUN)
2215 		goto fail_free;
2216 	if (fwd->listen_host != NULL &&
2217 	    strlen(fwd->listen_host) >= NI_MAXHOST)
2218 		goto fail_free;
2219 	if (fwd->listen_path != NULL &&
2220 	    strlen(fwd->listen_path) >= PATH_MAX_SUN)
2221 		goto fail_free;
2222 
2223 	return (i);
2224 
2225  fail_free:
2226 	free(fwd->connect_host);
2227 	fwd->connect_host = NULL;
2228 	free(fwd->connect_path);
2229 	fwd->connect_path = NULL;
2230 	free(fwd->listen_host);
2231 	fwd->listen_host = NULL;
2232 	free(fwd->listen_path);
2233 	fwd->listen_path = NULL;
2234 	return (0);
2235 }
2236 
2237 int
2238 parse_jump(const char *s, Options *o, int active)
2239 {
2240 	char *orig, *sdup, *cp;
2241 	char *host = NULL, *user = NULL;
2242 	int ret = -1, port = -1, first;
2243 
2244 	active &= o->proxy_command == NULL && o->jump_host == NULL;
2245 
2246 	orig = sdup = xstrdup(s);
2247 	first = active;
2248 	do {
2249 		if ((cp = strrchr(sdup, ',')) == NULL)
2250 			cp = sdup; /* last */
2251 		else
2252 			*cp++ = '\0';
2253 
2254 		if (first) {
2255 			/* First argument and configuration is active */
2256 			if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||
2257 			    parse_user_host_port(cp, &user, &host, &port) != 0)
2258 				goto out;
2259 		} else {
2260 			/* Subsequent argument or inactive configuration */
2261 			if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||
2262 			    parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2263 				goto out;
2264 		}
2265 		first = 0; /* only check syntax for subsequent hosts */
2266 	} while (cp != sdup);
2267 	/* success */
2268 	if (active) {
2269 		o->jump_user = user;
2270 		o->jump_host = host;
2271 		o->jump_port = port;
2272 		o->proxy_command = xstrdup("none");
2273 		user = host = NULL;
2274 		if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2275 			o->jump_extra = xstrdup(s);
2276 			o->jump_extra[cp - s] = '\0';
2277 		}
2278 	}
2279 	ret = 0;
2280  out:
2281 	free(orig);
2282 	free(user);
2283 	free(host);
2284 	return ret;
2285 }
2286 
2287 int
2288 parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
2289 {
2290 	char *path;
2291 	int r;
2292 
2293 	r = parse_uri("ssh", uri, userp, hostp, portp, &path);
2294 	if (r == 0 && path != NULL)
2295 		r = -1;		/* path not allowed */
2296 	return r;
2297 }
2298 
2299 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2300 static const char *
2301 fmt_multistate_int(int val, const struct multistate *m)
2302 {
2303 	u_int i;
2304 
2305 	for (i = 0; m[i].key != NULL; i++) {
2306 		if (m[i].value == val)
2307 			return m[i].key;
2308 	}
2309 	return "UNKNOWN";
2310 }
2311 
2312 static const char *
2313 fmt_intarg(OpCodes code, int val)
2314 {
2315 	if (val == -1)
2316 		return "unset";
2317 	switch (code) {
2318 	case oAddressFamily:
2319 		return fmt_multistate_int(val, multistate_addressfamily);
2320 	case oVerifyHostKeyDNS:
2321 	case oUpdateHostkeys:
2322 		return fmt_multistate_int(val, multistate_yesnoask);
2323 	case oStrictHostKeyChecking:
2324 		return fmt_multistate_int(val, multistate_strict_hostkey);
2325 	case oControlMaster:
2326 		return fmt_multistate_int(val, multistate_controlmaster);
2327 	case oTunnel:
2328 		return fmt_multistate_int(val, multistate_tunnel);
2329 	case oRequestTTY:
2330 		return fmt_multistate_int(val, multistate_requesttty);
2331 	case oCanonicalizeHostname:
2332 		return fmt_multistate_int(val, multistate_canonicalizehostname);
2333 	case oFingerprintHash:
2334 		return ssh_digest_alg_name(val);
2335 	default:
2336 		switch (val) {
2337 		case 0:
2338 			return "no";
2339 		case 1:
2340 			return "yes";
2341 		default:
2342 			return "UNKNOWN";
2343 		}
2344 	}
2345 }
2346 
2347 static const char *
2348 lookup_opcode_name(OpCodes code)
2349 {
2350 	u_int i;
2351 
2352 	for (i = 0; keywords[i].name != NULL; i++)
2353 		if (keywords[i].opcode == code)
2354 			return(keywords[i].name);
2355 	return "UNKNOWN";
2356 }
2357 
2358 static void
2359 dump_cfg_int(OpCodes code, int val)
2360 {
2361 	printf("%s %d\n", lookup_opcode_name(code), val);
2362 }
2363 
2364 static void
2365 dump_cfg_fmtint(OpCodes code, int val)
2366 {
2367 	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2368 }
2369 
2370 static void
2371 dump_cfg_string(OpCodes code, const char *val)
2372 {
2373 	if (val == NULL)
2374 		return;
2375 	printf("%s %s\n", lookup_opcode_name(code), val);
2376 }
2377 
2378 static void
2379 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2380 {
2381 	u_int i;
2382 
2383 	for (i = 0; i < count; i++)
2384 		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2385 }
2386 
2387 static void
2388 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2389 {
2390 	u_int i;
2391 
2392 	printf("%s", lookup_opcode_name(code));
2393 	for (i = 0; i < count; i++)
2394 		printf(" %s",  vals[i]);
2395 	printf("\n");
2396 }
2397 
2398 static void
2399 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2400 {
2401 	const struct Forward *fwd;
2402 	u_int i;
2403 
2404 	/* oDynamicForward */
2405 	for (i = 0; i < count; i++) {
2406 		fwd = &fwds[i];
2407 		if (code == oDynamicForward && fwd->connect_host != NULL &&
2408 		    strcmp(fwd->connect_host, "socks") != 0)
2409 			continue;
2410 		if (code == oLocalForward && fwd->connect_host != NULL &&
2411 		    strcmp(fwd->connect_host, "socks") == 0)
2412 			continue;
2413 		printf("%s", lookup_opcode_name(code));
2414 		if (fwd->listen_port == PORT_STREAMLOCAL)
2415 			printf(" %s", fwd->listen_path);
2416 		else if (fwd->listen_host == NULL)
2417 			printf(" %d", fwd->listen_port);
2418 		else {
2419 			printf(" [%s]:%d",
2420 			    fwd->listen_host, fwd->listen_port);
2421 		}
2422 		if (code != oDynamicForward) {
2423 			if (fwd->connect_port == PORT_STREAMLOCAL)
2424 				printf(" %s", fwd->connect_path);
2425 			else if (fwd->connect_host == NULL)
2426 				printf(" %d", fwd->connect_port);
2427 			else {
2428 				printf(" [%s]:%d",
2429 				    fwd->connect_host, fwd->connect_port);
2430 			}
2431 		}
2432 		printf("\n");
2433 	}
2434 }
2435 
2436 void
2437 dump_client_config(Options *o, const char *host)
2438 {
2439 	int i;
2440 	char buf[8];
2441 
2442 	/* This is normally prepared in ssh_kex2 */
2443 	if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2444 		fatal("%s: kex_assemble_names failed", __func__);
2445 
2446 	/* Most interesting options first: user, host, port */
2447 	dump_cfg_string(oUser, o->user);
2448 	dump_cfg_string(oHostName, host);
2449 	dump_cfg_int(oPort, o->port);
2450 
2451 	/* Flag options */
2452 	dump_cfg_fmtint(oAddressFamily, o->address_family);
2453 	dump_cfg_fmtint(oBatchMode, o->batch_mode);
2454 	dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2455 	dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2456 	dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2457 	dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2458 	dump_cfg_fmtint(oCompression, o->compression);
2459 	dump_cfg_fmtint(oControlMaster, o->control_master);
2460 	dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2461 	dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2462 	dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2463 	dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2464 	dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2465 	dump_cfg_fmtint(oForwardX11, o->forward_x11);
2466 	dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2467 	dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2468 #ifdef GSSAPI
2469 	dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2470 	dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2471 #endif /* GSSAPI */
2472 	dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2473 	dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2474 	dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2475 	dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2476 	dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2477 	dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2478 	dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2479 	dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2480 	dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2481 	dump_cfg_fmtint(oRequestTTY, o->request_tty);
2482 	dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2483 	dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2484 	dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2485 	dump_cfg_fmtint(oTunnel, o->tun_open);
2486 	dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2487 	dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2488 	dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2489 	dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2490 
2491 	/* Integer options */
2492 	dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2493 	dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2494 	dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2495 	dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2496 	dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2497 	dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2498 
2499 	/* String options */
2500 	dump_cfg_string(oBindAddress, o->bind_address);
2501 	dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2502 	dump_cfg_string(oControlPath, o->control_path);
2503 	dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2504 	dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2505 	dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2506 	dump_cfg_string(oIdentityAgent, o->identity_agent);
2507 	dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2508 	dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2509 	dump_cfg_string(oLocalCommand, o->local_command);
2510 	dump_cfg_string(oRemoteCommand, o->remote_command);
2511 	dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2512 	dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2513 #ifdef ENABLE_PKCS11
2514 	dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2515 #endif
2516 	dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2517 	dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2518 	dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2519 	dump_cfg_string(oXAuthLocation, o->xauth_location);
2520 
2521 	/* Forwards */
2522 	dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2523 	dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2524 	dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2525 
2526 	/* String array options */
2527 	dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2528 	dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2529 	dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2530 	dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2531 	dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2532 
2533 	/* Special cases */
2534 
2535 	/* oConnectTimeout */
2536 	if (o->connection_timeout == -1)
2537 		printf("connecttimeout none\n");
2538 	else
2539 		dump_cfg_int(oConnectTimeout, o->connection_timeout);
2540 
2541 	/* oTunnelDevice */
2542 	printf("tunneldevice");
2543 	if (o->tun_local == SSH_TUNID_ANY)
2544 		printf(" any");
2545 	else
2546 		printf(" %d", o->tun_local);
2547 	if (o->tun_remote == SSH_TUNID_ANY)
2548 		printf(":any");
2549 	else
2550 		printf(":%d", o->tun_remote);
2551 	printf("\n");
2552 
2553 	/* oCanonicalizePermittedCNAMEs */
2554 	if ( o->num_permitted_cnames > 0) {
2555 		printf("canonicalizePermittedcnames");
2556 		for (i = 0; i < o->num_permitted_cnames; i++) {
2557 			printf(" %s:%s", o->permitted_cnames[i].source_list,
2558 			    o->permitted_cnames[i].target_list);
2559 		}
2560 		printf("\n");
2561 	}
2562 
2563 	/* oControlPersist */
2564 	if (o->control_persist == 0 || o->control_persist_timeout == 0)
2565 		dump_cfg_fmtint(oControlPersist, o->control_persist);
2566 	else
2567 		dump_cfg_int(oControlPersist, o->control_persist_timeout);
2568 
2569 	/* oEscapeChar */
2570 	if (o->escape_char == SSH_ESCAPECHAR_NONE)
2571 		printf("escapechar none\n");
2572 	else {
2573 		vis(buf, o->escape_char, VIS_WHITE, 0);
2574 		printf("escapechar %s\n", buf);
2575 	}
2576 
2577 	/* oIPQoS */
2578 	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2579 	printf("%s\n", iptos2str(o->ip_qos_bulk));
2580 
2581 	/* oRekeyLimit */
2582 	printf("rekeylimit %llu %d\n",
2583 	    (unsigned long long)o->rekey_limit, o->rekey_interval);
2584 
2585 	/* oStreamLocalBindMask */
2586 	printf("streamlocalbindmask 0%o\n",
2587 	    o->fwd_opts.streamlocal_bind_mask);
2588 
2589 	/* oProxyCommand / oProxyJump */
2590 	if (o->jump_host == NULL)
2591 		dump_cfg_string(oProxyCommand, o->proxy_command);
2592 	else {
2593 		/* Check for numeric addresses */
2594 		i = strchr(o->jump_host, ':') != NULL ||
2595 		    strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2596 		snprintf(buf, sizeof(buf), "%d", o->jump_port);
2597 		printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2598 		    /* optional additional jump spec */
2599 		    o->jump_extra == NULL ? "" : o->jump_extra,
2600 		    o->jump_extra == NULL ? "" : ",",
2601 		    /* optional user */
2602 		    o->jump_user == NULL ? "" : o->jump_user,
2603 		    o->jump_user == NULL ? "" : "@",
2604 		    /* opening [ if hostname is numeric */
2605 		    i ? "[" : "",
2606 		    /* mandatory hostname */
2607 		    o->jump_host,
2608 		    /* closing ] if hostname is numeric */
2609 		    i ? "]" : "",
2610 		    /* optional port number */
2611 		    o->jump_port <= 0 ? "" : ":",
2612 		    o->jump_port <= 0 ? "" : buf);
2613 	}
2614 }
2615