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