xref: /openbsd-src/usr.bin/ssh/readconf.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /* $OpenBSD: readconf.c,v 1.260 2016/08/25 23:56:51 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 	case oIgnoredUnknownOption:
847 		debug("%s line %d: Ignored unknown option \"%s\"",
848 		    filename, linenum, keyword);
849 		return 0;
850 	case oConnectTimeout:
851 		intptr = &options->connection_timeout;
852 parse_time:
853 		arg = strdelim(&s);
854 		if (!arg || *arg == '\0')
855 			fatal("%s line %d: missing time value.",
856 			    filename, linenum);
857 		if (strcmp(arg, "none") == 0)
858 			value = -1;
859 		else if ((value = convtime(arg)) == -1)
860 			fatal("%s line %d: invalid time value.",
861 			    filename, linenum);
862 		if (*activep && *intptr == -1)
863 			*intptr = value;
864 		break;
865 
866 	case oForwardAgent:
867 		intptr = &options->forward_agent;
868  parse_flag:
869 		multistate_ptr = multistate_flag;
870  parse_multistate:
871 		arg = strdelim(&s);
872 		if (!arg || *arg == '\0')
873 			fatal("%s line %d: missing argument.",
874 			    filename, linenum);
875 		value = -1;
876 		for (i = 0; multistate_ptr[i].key != NULL; i++) {
877 			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
878 				value = multistate_ptr[i].value;
879 				break;
880 			}
881 		}
882 		if (value == -1)
883 			fatal("%s line %d: unsupported option \"%s\".",
884 			    filename, linenum, arg);
885 		if (*activep && *intptr == -1)
886 			*intptr = value;
887 		break;
888 
889 	case oForwardX11:
890 		intptr = &options->forward_x11;
891 		goto parse_flag;
892 
893 	case oForwardX11Trusted:
894 		intptr = &options->forward_x11_trusted;
895 		goto parse_flag;
896 
897 	case oForwardX11Timeout:
898 		intptr = &options->forward_x11_timeout;
899 		goto parse_time;
900 
901 	case oGatewayPorts:
902 		intptr = &options->fwd_opts.gateway_ports;
903 		goto parse_flag;
904 
905 	case oExitOnForwardFailure:
906 		intptr = &options->exit_on_forward_failure;
907 		goto parse_flag;
908 
909 	case oUsePrivilegedPort:
910 		intptr = &options->use_privileged_port;
911 		goto parse_flag;
912 
913 	case oPasswordAuthentication:
914 		intptr = &options->password_authentication;
915 		goto parse_flag;
916 
917 	case oKbdInteractiveAuthentication:
918 		intptr = &options->kbd_interactive_authentication;
919 		goto parse_flag;
920 
921 	case oKbdInteractiveDevices:
922 		charptr = &options->kbd_interactive_devices;
923 		goto parse_string;
924 
925 	case oPubkeyAuthentication:
926 		intptr = &options->pubkey_authentication;
927 		goto parse_flag;
928 
929 	case oRSAAuthentication:
930 		intptr = &options->rsa_authentication;
931 		goto parse_flag;
932 
933 	case oRhostsRSAAuthentication:
934 		intptr = &options->rhosts_rsa_authentication;
935 		goto parse_flag;
936 
937 	case oHostbasedAuthentication:
938 		intptr = &options->hostbased_authentication;
939 		goto parse_flag;
940 
941 	case oChallengeResponseAuthentication:
942 		intptr = &options->challenge_response_authentication;
943 		goto parse_flag;
944 
945 	case oGssAuthentication:
946 		intptr = &options->gss_authentication;
947 		goto parse_flag;
948 
949 	case oGssDelegateCreds:
950 		intptr = &options->gss_deleg_creds;
951 		goto parse_flag;
952 
953 	case oBatchMode:
954 		intptr = &options->batch_mode;
955 		goto parse_flag;
956 
957 	case oCheckHostIP:
958 		intptr = &options->check_host_ip;
959 		goto parse_flag;
960 
961 	case oVerifyHostKeyDNS:
962 		intptr = &options->verify_host_key_dns;
963 		multistate_ptr = multistate_yesnoask;
964 		goto parse_multistate;
965 
966 	case oStrictHostKeyChecking:
967 		intptr = &options->strict_host_key_checking;
968 		multistate_ptr = multistate_yesnoask;
969 		goto parse_multistate;
970 
971 	case oCompression:
972 		intptr = &options->compression;
973 		goto parse_flag;
974 
975 	case oTCPKeepAlive:
976 		intptr = &options->tcp_keep_alive;
977 		goto parse_flag;
978 
979 	case oNoHostAuthenticationForLocalhost:
980 		intptr = &options->no_host_authentication_for_localhost;
981 		goto parse_flag;
982 
983 	case oNumberOfPasswordPrompts:
984 		intptr = &options->number_of_password_prompts;
985 		goto parse_int;
986 
987 	case oCompressionLevel:
988 		intptr = &options->compression_level;
989 		goto parse_int;
990 
991 	case oRekeyLimit:
992 		arg = strdelim(&s);
993 		if (!arg || *arg == '\0')
994 			fatal("%.200s line %d: Missing argument.", filename,
995 			    linenum);
996 		if (strcmp(arg, "default") == 0) {
997 			val64 = 0;
998 		} else {
999 			if (scan_scaled(arg, &val64) == -1)
1000 				fatal("%.200s line %d: Bad number '%s': %s",
1001 				    filename, linenum, arg, strerror(errno));
1002 			if (val64 != 0 && val64 < 16)
1003 				fatal("%.200s line %d: RekeyLimit too small",
1004 				    filename, linenum);
1005 		}
1006 		if (*activep && options->rekey_limit == -1)
1007 			options->rekey_limit = val64;
1008 		if (s != NULL) { /* optional rekey interval present */
1009 			if (strcmp(s, "none") == 0) {
1010 				(void)strdelim(&s);	/* discard */
1011 				break;
1012 			}
1013 			intptr = &options->rekey_interval;
1014 			goto parse_time;
1015 		}
1016 		break;
1017 
1018 	case oIdentityFile:
1019 		arg = strdelim(&s);
1020 		if (!arg || *arg == '\0')
1021 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1022 		if (*activep) {
1023 			intptr = &options->num_identity_files;
1024 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
1025 				fatal("%.200s line %d: Too many identity files specified (max %d).",
1026 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
1027 			add_identity_file(options, NULL,
1028 			    arg, flags & SSHCONF_USERCONF);
1029 		}
1030 		break;
1031 
1032 	case oCertificateFile:
1033 		arg = strdelim(&s);
1034 		if (!arg || *arg == '\0')
1035 			fatal("%.200s line %d: Missing argument.",
1036 			    filename, linenum);
1037 		if (*activep) {
1038 			intptr = &options->num_certificate_files;
1039 			if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1040 				fatal("%.200s line %d: Too many certificate "
1041 				    "files specified (max %d).",
1042 				    filename, linenum,
1043 				    SSH_MAX_CERTIFICATE_FILES);
1044 			}
1045 			add_certificate_file(options, arg,
1046 			    flags & SSHCONF_USERCONF);
1047 		}
1048 		break;
1049 
1050 	case oXAuthLocation:
1051 		charptr=&options->xauth_location;
1052 		goto parse_string;
1053 
1054 	case oUser:
1055 		charptr = &options->user;
1056 parse_string:
1057 		arg = strdelim(&s);
1058 		if (!arg || *arg == '\0')
1059 			fatal("%.200s line %d: Missing argument.",
1060 			    filename, linenum);
1061 		if (*activep && *charptr == NULL)
1062 			*charptr = xstrdup(arg);
1063 		break;
1064 
1065 	case oGlobalKnownHostsFile:
1066 		cpptr = (char **)&options->system_hostfiles;
1067 		uintptr = &options->num_system_hostfiles;
1068 		max_entries = SSH_MAX_HOSTS_FILES;
1069 parse_char_array:
1070 		if (*activep && *uintptr == 0) {
1071 			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1072 				if ((*uintptr) >= max_entries)
1073 					fatal("%s line %d: "
1074 					    "too many authorized keys files.",
1075 					    filename, linenum);
1076 				cpptr[(*uintptr)++] = xstrdup(arg);
1077 			}
1078 		}
1079 		return 0;
1080 
1081 	case oUserKnownHostsFile:
1082 		cpptr = (char **)&options->user_hostfiles;
1083 		uintptr = &options->num_user_hostfiles;
1084 		max_entries = SSH_MAX_HOSTS_FILES;
1085 		goto parse_char_array;
1086 
1087 	case oHostName:
1088 		charptr = &options->hostname;
1089 		goto parse_string;
1090 
1091 	case oHostKeyAlias:
1092 		charptr = &options->host_key_alias;
1093 		goto parse_string;
1094 
1095 	case oPreferredAuthentications:
1096 		charptr = &options->preferred_authentications;
1097 		goto parse_string;
1098 
1099 	case oBindAddress:
1100 		charptr = &options->bind_address;
1101 		goto parse_string;
1102 
1103 	case oPKCS11Provider:
1104 		charptr = &options->pkcs11_provider;
1105 		goto parse_string;
1106 
1107 	case oProxyCommand:
1108 		charptr = &options->proxy_command;
1109 		/* Ignore ProxyCommand if ProxyJump already specified */
1110 		if (options->jump_host != NULL)
1111 			charptr = &options->jump_host; /* Skip below */
1112 parse_command:
1113 		if (s == NULL)
1114 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1115 		len = strspn(s, WHITESPACE "=");
1116 		if (*activep && *charptr == NULL)
1117 			*charptr = xstrdup(s + len);
1118 		return 0;
1119 
1120 	case oProxyJump:
1121 		if (s == NULL) {
1122 			fatal("%.200s line %d: Missing argument.",
1123 			    filename, linenum);
1124 		}
1125 		len = strspn(s, WHITESPACE "=");
1126 		if (parse_jump(s + len, options, *activep) == -1) {
1127 			fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1128 			    filename, linenum, s + len);
1129 		}
1130 		return 0;
1131 
1132 	case oPort:
1133 		intptr = &options->port;
1134 parse_int:
1135 		arg = strdelim(&s);
1136 		if (!arg || *arg == '\0')
1137 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1138 		if (arg[0] < '0' || arg[0] > '9')
1139 			fatal("%.200s line %d: Bad number.", filename, linenum);
1140 
1141 		/* Octal, decimal, or hex format? */
1142 		value = strtol(arg, &endofnumber, 0);
1143 		if (arg == endofnumber)
1144 			fatal("%.200s line %d: Bad number.", filename, linenum);
1145 		if (*activep && *intptr == -1)
1146 			*intptr = value;
1147 		break;
1148 
1149 	case oConnectionAttempts:
1150 		intptr = &options->connection_attempts;
1151 		goto parse_int;
1152 
1153 	case oCipher:
1154 		intptr = &options->cipher;
1155 		arg = strdelim(&s);
1156 		if (!arg || *arg == '\0')
1157 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1158 		value = cipher_number(arg);
1159 		if (value == -1)
1160 			fatal("%.200s line %d: Bad cipher '%s'.",
1161 			    filename, linenum, arg ? arg : "<NONE>");
1162 		if (*activep && *intptr == -1)
1163 			*intptr = value;
1164 		break;
1165 
1166 	case oCiphers:
1167 		arg = strdelim(&s);
1168 		if (!arg || *arg == '\0')
1169 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1170 		if (!ciphers_valid(*arg == '+' ? arg + 1 : arg))
1171 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1172 			    filename, linenum, arg ? arg : "<NONE>");
1173 		if (*activep && options->ciphers == NULL)
1174 			options->ciphers = xstrdup(arg);
1175 		break;
1176 
1177 	case oMacs:
1178 		arg = strdelim(&s);
1179 		if (!arg || *arg == '\0')
1180 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1181 		if (!mac_valid(*arg == '+' ? arg + 1 : arg))
1182 			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1183 			    filename, linenum, arg ? arg : "<NONE>");
1184 		if (*activep && options->macs == NULL)
1185 			options->macs = xstrdup(arg);
1186 		break;
1187 
1188 	case oKexAlgorithms:
1189 		arg = strdelim(&s);
1190 		if (!arg || *arg == '\0')
1191 			fatal("%.200s line %d: Missing argument.",
1192 			    filename, linenum);
1193 		if (!kex_names_valid(*arg == '+' ? arg + 1 : arg))
1194 			fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1195 			    filename, linenum, arg ? arg : "<NONE>");
1196 		if (*activep && options->kex_algorithms == NULL)
1197 			options->kex_algorithms = xstrdup(arg);
1198 		break;
1199 
1200 	case oHostKeyAlgorithms:
1201 		charptr = &options->hostkeyalgorithms;
1202 parse_keytypes:
1203 		arg = strdelim(&s);
1204 		if (!arg || *arg == '\0')
1205 			fatal("%.200s line %d: Missing argument.",
1206 			    filename, linenum);
1207 		if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1208 			fatal("%s line %d: Bad key types '%s'.",
1209 				filename, linenum, arg ? arg : "<NONE>");
1210 		if (*activep && *charptr == NULL)
1211 			*charptr = xstrdup(arg);
1212 		break;
1213 
1214 	case oProtocol:
1215 		intptr = &options->protocol;
1216 		arg = strdelim(&s);
1217 		if (!arg || *arg == '\0')
1218 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1219 		value = proto_spec(arg);
1220 		if (value == SSH_PROTO_UNKNOWN)
1221 			fatal("%.200s line %d: Bad protocol spec '%s'.",
1222 			    filename, linenum, arg ? arg : "<NONE>");
1223 		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1224 			*intptr = value;
1225 		break;
1226 
1227 	case oLogLevel:
1228 		log_level_ptr = &options->log_level;
1229 		arg = strdelim(&s);
1230 		value = log_level_number(arg);
1231 		if (value == SYSLOG_LEVEL_NOT_SET)
1232 			fatal("%.200s line %d: unsupported log level '%s'",
1233 			    filename, linenum, arg ? arg : "<NONE>");
1234 		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1235 			*log_level_ptr = (LogLevel) value;
1236 		break;
1237 
1238 	case oLocalForward:
1239 	case oRemoteForward:
1240 	case oDynamicForward:
1241 		arg = strdelim(&s);
1242 		if (arg == NULL || *arg == '\0')
1243 			fatal("%.200s line %d: Missing port argument.",
1244 			    filename, linenum);
1245 
1246 		if (opcode == oLocalForward ||
1247 		    opcode == oRemoteForward) {
1248 			arg2 = strdelim(&s);
1249 			if (arg2 == NULL || *arg2 == '\0')
1250 				fatal("%.200s line %d: Missing target argument.",
1251 				    filename, linenum);
1252 
1253 			/* construct a string for parse_forward */
1254 			snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1255 		} else if (opcode == oDynamicForward) {
1256 			strlcpy(fwdarg, arg, sizeof(fwdarg));
1257 		}
1258 
1259 		if (parse_forward(&fwd, fwdarg,
1260 		    opcode == oDynamicForward ? 1 : 0,
1261 		    opcode == oRemoteForward ? 1 : 0) == 0)
1262 			fatal("%.200s line %d: Bad forwarding specification.",
1263 			    filename, linenum);
1264 
1265 		if (*activep) {
1266 			if (opcode == oLocalForward ||
1267 			    opcode == oDynamicForward)
1268 				add_local_forward(options, &fwd);
1269 			else if (opcode == oRemoteForward)
1270 				add_remote_forward(options, &fwd);
1271 		}
1272 		break;
1273 
1274 	case oClearAllForwardings:
1275 		intptr = &options->clear_forwardings;
1276 		goto parse_flag;
1277 
1278 	case oHost:
1279 		if (cmdline)
1280 			fatal("Host directive not supported as a command-line "
1281 			    "option");
1282 		*activep = 0;
1283 		arg2 = NULL;
1284 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1285 			if ((flags & SSHCONF_NEVERMATCH) != 0)
1286 				break;
1287 			negated = *arg == '!';
1288 			if (negated)
1289 				arg++;
1290 			if (match_pattern(host, arg)) {
1291 				if (negated) {
1292 					debug("%.200s line %d: Skipping Host "
1293 					    "block because of negated match "
1294 					    "for %.100s", filename, linenum,
1295 					    arg);
1296 					*activep = 0;
1297 					break;
1298 				}
1299 				if (!*activep)
1300 					arg2 = arg; /* logged below */
1301 				*activep = 1;
1302 			}
1303 		}
1304 		if (*activep)
1305 			debug("%.200s line %d: Applying options for %.100s",
1306 			    filename, linenum, arg2);
1307 		/* Avoid garbage check below, as strdelim is done. */
1308 		return 0;
1309 
1310 	case oMatch:
1311 		if (cmdline)
1312 			fatal("Host directive not supported as a command-line "
1313 			    "option");
1314 		value = match_cfg_line(options, &s, pw, host, original_host,
1315 		    flags & SSHCONF_POSTCANON, filename, linenum);
1316 		if (value < 0)
1317 			fatal("%.200s line %d: Bad Match condition", filename,
1318 			    linenum);
1319 		*activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1320 		break;
1321 
1322 	case oEscapeChar:
1323 		intptr = &options->escape_char;
1324 		arg = strdelim(&s);
1325 		if (!arg || *arg == '\0')
1326 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1327 		if (strcmp(arg, "none") == 0)
1328 			value = SSH_ESCAPECHAR_NONE;
1329 		else if (arg[1] == '\0')
1330 			value = (u_char) arg[0];
1331 		else if (arg[0] == '^' && arg[2] == 0 &&
1332 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1333 			value = (u_char) arg[1] & 31;
1334 		else {
1335 			fatal("%.200s line %d: Bad escape character.",
1336 			    filename, linenum);
1337 			/* NOTREACHED */
1338 			value = 0;	/* Avoid compiler warning. */
1339 		}
1340 		if (*activep && *intptr == -1)
1341 			*intptr = value;
1342 		break;
1343 
1344 	case oAddressFamily:
1345 		intptr = &options->address_family;
1346 		multistate_ptr = multistate_addressfamily;
1347 		goto parse_multistate;
1348 
1349 	case oEnableSSHKeysign:
1350 		intptr = &options->enable_ssh_keysign;
1351 		goto parse_flag;
1352 
1353 	case oIdentitiesOnly:
1354 		intptr = &options->identities_only;
1355 		goto parse_flag;
1356 
1357 	case oServerAliveInterval:
1358 		intptr = &options->server_alive_interval;
1359 		goto parse_time;
1360 
1361 	case oServerAliveCountMax:
1362 		intptr = &options->server_alive_count_max;
1363 		goto parse_int;
1364 
1365 	case oSendEnv:
1366 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1367 			if (strchr(arg, '=') != NULL)
1368 				fatal("%s line %d: Invalid environment name.",
1369 				    filename, linenum);
1370 			if (!*activep)
1371 				continue;
1372 			if (options->num_send_env >= MAX_SEND_ENV)
1373 				fatal("%s line %d: too many send env.",
1374 				    filename, linenum);
1375 			options->send_env[options->num_send_env++] =
1376 			    xstrdup(arg);
1377 		}
1378 		break;
1379 
1380 	case oControlPath:
1381 		charptr = &options->control_path;
1382 		goto parse_string;
1383 
1384 	case oControlMaster:
1385 		intptr = &options->control_master;
1386 		multistate_ptr = multistate_controlmaster;
1387 		goto parse_multistate;
1388 
1389 	case oControlPersist:
1390 		/* no/false/yes/true, or a time spec */
1391 		intptr = &options->control_persist;
1392 		arg = strdelim(&s);
1393 		if (!arg || *arg == '\0')
1394 			fatal("%.200s line %d: Missing ControlPersist"
1395 			    " argument.", filename, linenum);
1396 		value = 0;
1397 		value2 = 0;	/* timeout */
1398 		if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1399 			value = 0;
1400 		else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1401 			value = 1;
1402 		else if ((value2 = convtime(arg)) >= 0)
1403 			value = 1;
1404 		else
1405 			fatal("%.200s line %d: Bad ControlPersist argument.",
1406 			    filename, linenum);
1407 		if (*activep && *intptr == -1) {
1408 			*intptr = value;
1409 			options->control_persist_timeout = value2;
1410 		}
1411 		break;
1412 
1413 	case oHashKnownHosts:
1414 		intptr = &options->hash_known_hosts;
1415 		goto parse_flag;
1416 
1417 	case oTunnel:
1418 		intptr = &options->tun_open;
1419 		multistate_ptr = multistate_tunnel;
1420 		goto parse_multistate;
1421 
1422 	case oTunnelDevice:
1423 		arg = strdelim(&s);
1424 		if (!arg || *arg == '\0')
1425 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1426 		value = a2tun(arg, &value2);
1427 		if (value == SSH_TUNID_ERR)
1428 			fatal("%.200s line %d: Bad tun device.", filename, linenum);
1429 		if (*activep) {
1430 			options->tun_local = value;
1431 			options->tun_remote = value2;
1432 		}
1433 		break;
1434 
1435 	case oLocalCommand:
1436 		charptr = &options->local_command;
1437 		goto parse_command;
1438 
1439 	case oPermitLocalCommand:
1440 		intptr = &options->permit_local_command;
1441 		goto parse_flag;
1442 
1443 	case oVisualHostKey:
1444 		intptr = &options->visual_host_key;
1445 		goto parse_flag;
1446 
1447 	case oInclude:
1448 		if (cmdline)
1449 			fatal("Include directive not supported as a "
1450 			    "command-line option");
1451 		value = 0;
1452 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1453 			/*
1454 			 * Ensure all paths are anchored. User configuration
1455 			 * files may begin with '~/' but system configurations
1456 			 * must not. If the path is relative, then treat it
1457 			 * as living in ~/.ssh for user configurations or
1458 			 * /etc/ssh for system ones.
1459 			 */
1460 			if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1461 				fatal("%.200s line %d: bad include path %s.",
1462 				    filename, linenum, arg);
1463 			if (*arg != '/' && *arg != '~') {
1464 				xasprintf(&arg2, "%s/%s",
1465 				    (flags & SSHCONF_USERCONF) ?
1466 				    "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1467 			} else
1468 				arg2 = xstrdup(arg);
1469 			memset(&gl, 0, sizeof(gl));
1470 			r = glob(arg2, GLOB_TILDE, NULL, &gl);
1471 			if (r == GLOB_NOMATCH) {
1472 				debug("%.200s line %d: include %s matched no "
1473 				    "files",filename, linenum, arg2);
1474 				continue;
1475 			} else if (r != 0 || gl.gl_pathc < 0)
1476 				fatal("%.200s line %d: glob failed for %s.",
1477 				    filename, linenum, arg2);
1478 			free(arg2);
1479 			oactive = *activep;
1480 			for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1481 				debug3("%.200s line %d: Including file %s "
1482 				    "depth %d%s", filename, linenum,
1483 				    gl.gl_pathv[i], depth,
1484 				    oactive ? "" : " (parse only)");
1485 				r = read_config_file_depth(gl.gl_pathv[i],
1486 				    pw, host, original_host, options,
1487 				    flags | SSHCONF_CHECKPERM |
1488 				    (oactive ? 0 : SSHCONF_NEVERMATCH),
1489 				    activep, depth + 1);
1490 				/*
1491 				 * don't let Match in includes clobber the
1492 				 * containing file's Match state.
1493 				 */
1494 				*activep = oactive;
1495 				if (r != 1)
1496 					value = -1;
1497 			}
1498 			globfree(&gl);
1499 		}
1500 		if (value != 0)
1501 			return value;
1502 		break;
1503 
1504 	case oIPQoS:
1505 		arg = strdelim(&s);
1506 		if ((value = parse_ipqos(arg)) == -1)
1507 			fatal("%s line %d: Bad IPQoS value: %s",
1508 			    filename, linenum, arg);
1509 		arg = strdelim(&s);
1510 		if (arg == NULL)
1511 			value2 = value;
1512 		else if ((value2 = parse_ipqos(arg)) == -1)
1513 			fatal("%s line %d: Bad IPQoS value: %s",
1514 			    filename, linenum, arg);
1515 		if (*activep) {
1516 			options->ip_qos_interactive = value;
1517 			options->ip_qos_bulk = value2;
1518 		}
1519 		break;
1520 
1521 	case oRequestTTY:
1522 		intptr = &options->request_tty;
1523 		multistate_ptr = multistate_requesttty;
1524 		goto parse_multistate;
1525 
1526 	case oIgnoreUnknown:
1527 		charptr = &options->ignored_unknown;
1528 		goto parse_string;
1529 
1530 	case oProxyUseFdpass:
1531 		intptr = &options->proxy_use_fdpass;
1532 		goto parse_flag;
1533 
1534 	case oCanonicalDomains:
1535 		value = options->num_canonical_domains != 0;
1536 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1537 			valid_domain(arg, filename, linenum);
1538 			if (!*activep || value)
1539 				continue;
1540 			if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1541 				fatal("%s line %d: too many hostname suffixes.",
1542 				    filename, linenum);
1543 			options->canonical_domains[
1544 			    options->num_canonical_domains++] = xstrdup(arg);
1545 		}
1546 		break;
1547 
1548 	case oCanonicalizePermittedCNAMEs:
1549 		value = options->num_permitted_cnames != 0;
1550 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1551 			/* Either '*' for everything or 'list:list' */
1552 			if (strcmp(arg, "*") == 0)
1553 				arg2 = arg;
1554 			else {
1555 				lowercase(arg);
1556 				if ((arg2 = strchr(arg, ':')) == NULL ||
1557 				    arg2[1] == '\0') {
1558 					fatal("%s line %d: "
1559 					    "Invalid permitted CNAME \"%s\"",
1560 					    filename, linenum, arg);
1561 				}
1562 				*arg2 = '\0';
1563 				arg2++;
1564 			}
1565 			if (!*activep || value)
1566 				continue;
1567 			if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1568 				fatal("%s line %d: too many permitted CNAMEs.",
1569 				    filename, linenum);
1570 			cname = options->permitted_cnames +
1571 			    options->num_permitted_cnames++;
1572 			cname->source_list = xstrdup(arg);
1573 			cname->target_list = xstrdup(arg2);
1574 		}
1575 		break;
1576 
1577 	case oCanonicalizeHostname:
1578 		intptr = &options->canonicalize_hostname;
1579 		multistate_ptr = multistate_canonicalizehostname;
1580 		goto parse_multistate;
1581 
1582 	case oCanonicalizeMaxDots:
1583 		intptr = &options->canonicalize_max_dots;
1584 		goto parse_int;
1585 
1586 	case oCanonicalizeFallbackLocal:
1587 		intptr = &options->canonicalize_fallback_local;
1588 		goto parse_flag;
1589 
1590 	case oStreamLocalBindMask:
1591 		arg = strdelim(&s);
1592 		if (!arg || *arg == '\0')
1593 			fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1594 		/* Parse mode in octal format */
1595 		value = strtol(arg, &endofnumber, 8);
1596 		if (arg == endofnumber || value < 0 || value > 0777)
1597 			fatal("%.200s line %d: Bad mask.", filename, linenum);
1598 		options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1599 		break;
1600 
1601 	case oStreamLocalBindUnlink:
1602 		intptr = &options->fwd_opts.streamlocal_bind_unlink;
1603 		goto parse_flag;
1604 
1605 	case oRevokedHostKeys:
1606 		charptr = &options->revoked_host_keys;
1607 		goto parse_string;
1608 
1609 	case oFingerprintHash:
1610 		intptr = &options->fingerprint_hash;
1611 		arg = strdelim(&s);
1612 		if (!arg || *arg == '\0')
1613 			fatal("%.200s line %d: Missing argument.",
1614 			    filename, linenum);
1615 		if ((value = ssh_digest_alg_by_name(arg)) == -1)
1616 			fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1617 			    filename, linenum, arg);
1618 		if (*activep && *intptr == -1)
1619 			*intptr = value;
1620 		break;
1621 
1622 	case oUpdateHostkeys:
1623 		intptr = &options->update_hostkeys;
1624 		multistate_ptr = multistate_yesnoask;
1625 		goto parse_multistate;
1626 
1627 	case oHostbasedKeyTypes:
1628 		charptr = &options->hostbased_key_types;
1629 		goto parse_keytypes;
1630 
1631 	case oPubkeyAcceptedKeyTypes:
1632 		charptr = &options->pubkey_key_types;
1633 		goto parse_keytypes;
1634 
1635 	case oAddKeysToAgent:
1636 		intptr = &options->add_keys_to_agent;
1637 		multistate_ptr = multistate_yesnoaskconfirm;
1638 		goto parse_multistate;
1639 
1640 	case oIdentityAgent:
1641 		charptr = &options->identity_agent;
1642 		goto parse_string;
1643 
1644 	case oDeprecated:
1645 		debug("%s line %d: Deprecated option \"%s\"",
1646 		    filename, linenum, keyword);
1647 		return 0;
1648 
1649 	case oUnsupported:
1650 		error("%s line %d: Unsupported option \"%s\"",
1651 		    filename, linenum, keyword);
1652 		return 0;
1653 
1654 	default:
1655 		fatal("%s: Unimplemented opcode %d", __func__, opcode);
1656 	}
1657 
1658 	/* Check that there is no garbage at end of line. */
1659 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1660 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1661 		    filename, linenum, arg);
1662 	}
1663 	return 0;
1664 }
1665 
1666 /*
1667  * Reads the config file and modifies the options accordingly.  Options
1668  * should already be initialized before this call.  This never returns if
1669  * there is an error.  If the file does not exist, this returns 0.
1670  */
1671 int
1672 read_config_file(const char *filename, struct passwd *pw, const char *host,
1673     const char *original_host, Options *options, int flags)
1674 {
1675 	int active = 1;
1676 
1677 	return read_config_file_depth(filename, pw, host, original_host,
1678 	    options, flags, &active, 0);
1679 }
1680 
1681 #define READCONF_MAX_DEPTH	16
1682 static int
1683 read_config_file_depth(const char *filename, struct passwd *pw,
1684     const char *host, const char *original_host, Options *options,
1685     int flags, int *activep, int depth)
1686 {
1687 	FILE *f;
1688 	char line[1024];
1689 	int linenum;
1690 	int bad_options = 0;
1691 
1692 	if (depth < 0 || depth > READCONF_MAX_DEPTH)
1693 		fatal("Too many recursive configuration includes");
1694 
1695 	if ((f = fopen(filename, "r")) == NULL)
1696 		return 0;
1697 
1698 	if (flags & SSHCONF_CHECKPERM) {
1699 		struct stat sb;
1700 
1701 		if (fstat(fileno(f), &sb) == -1)
1702 			fatal("fstat %s: %s", filename, strerror(errno));
1703 		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1704 		    (sb.st_mode & 022) != 0))
1705 			fatal("Bad owner or permissions on %s", filename);
1706 	}
1707 
1708 	debug("Reading configuration data %.200s", filename);
1709 
1710 	/*
1711 	 * Mark that we are now processing the options.  This flag is turned
1712 	 * on/off by Host specifications.
1713 	 */
1714 	linenum = 0;
1715 	while (fgets(line, sizeof(line), f)) {
1716 		/* Update line number counter. */
1717 		linenum++;
1718 		if (process_config_line_depth(options, pw, host, original_host,
1719 		    line, filename, linenum, activep, flags, depth) != 0)
1720 			bad_options++;
1721 	}
1722 	fclose(f);
1723 	if (bad_options > 0)
1724 		fatal("%s: terminating, %d bad configuration options",
1725 		    filename, bad_options);
1726 	return 1;
1727 }
1728 
1729 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1730 int
1731 option_clear_or_none(const char *o)
1732 {
1733 	return o == NULL || strcasecmp(o, "none") == 0;
1734 }
1735 
1736 /*
1737  * Initializes options to special values that indicate that they have not yet
1738  * been set.  Read_config_file will only set options with this value. Options
1739  * are processed in the following order: command line, user config file,
1740  * system config file.  Last, fill_default_options is called.
1741  */
1742 
1743 void
1744 initialize_options(Options * options)
1745 {
1746 	memset(options, 'X', sizeof(*options));
1747 	options->forward_agent = -1;
1748 	options->forward_x11 = -1;
1749 	options->forward_x11_trusted = -1;
1750 	options->forward_x11_timeout = -1;
1751 	options->stdio_forward_host = NULL;
1752 	options->stdio_forward_port = 0;
1753 	options->clear_forwardings = -1;
1754 	options->exit_on_forward_failure = -1;
1755 	options->xauth_location = NULL;
1756 	options->fwd_opts.gateway_ports = -1;
1757 	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1758 	options->fwd_opts.streamlocal_bind_unlink = -1;
1759 	options->use_privileged_port = -1;
1760 	options->rsa_authentication = -1;
1761 	options->pubkey_authentication = -1;
1762 	options->challenge_response_authentication = -1;
1763 	options->gss_authentication = -1;
1764 	options->gss_deleg_creds = -1;
1765 	options->password_authentication = -1;
1766 	options->kbd_interactive_authentication = -1;
1767 	options->kbd_interactive_devices = NULL;
1768 	options->rhosts_rsa_authentication = -1;
1769 	options->hostbased_authentication = -1;
1770 	options->batch_mode = -1;
1771 	options->check_host_ip = -1;
1772 	options->strict_host_key_checking = -1;
1773 	options->compression = -1;
1774 	options->tcp_keep_alive = -1;
1775 	options->compression_level = -1;
1776 	options->port = -1;
1777 	options->address_family = -1;
1778 	options->connection_attempts = -1;
1779 	options->connection_timeout = -1;
1780 	options->number_of_password_prompts = -1;
1781 	options->cipher = -1;
1782 	options->ciphers = NULL;
1783 	options->macs = NULL;
1784 	options->kex_algorithms = NULL;
1785 	options->hostkeyalgorithms = NULL;
1786 	options->protocol = SSH_PROTO_UNKNOWN;
1787 	options->num_identity_files = 0;
1788 	options->num_certificate_files = 0;
1789 	options->hostname = NULL;
1790 	options->host_key_alias = NULL;
1791 	options->proxy_command = NULL;
1792 	options->jump_user = NULL;
1793 	options->jump_host = NULL;
1794 	options->jump_port = -1;
1795 	options->jump_extra = NULL;
1796 	options->user = NULL;
1797 	options->escape_char = -1;
1798 	options->num_system_hostfiles = 0;
1799 	options->num_user_hostfiles = 0;
1800 	options->local_forwards = NULL;
1801 	options->num_local_forwards = 0;
1802 	options->remote_forwards = NULL;
1803 	options->num_remote_forwards = 0;
1804 	options->log_level = SYSLOG_LEVEL_NOT_SET;
1805 	options->preferred_authentications = NULL;
1806 	options->bind_address = NULL;
1807 	options->pkcs11_provider = NULL;
1808 	options->enable_ssh_keysign = - 1;
1809 	options->no_host_authentication_for_localhost = - 1;
1810 	options->identities_only = - 1;
1811 	options->rekey_limit = - 1;
1812 	options->rekey_interval = -1;
1813 	options->verify_host_key_dns = -1;
1814 	options->server_alive_interval = -1;
1815 	options->server_alive_count_max = -1;
1816 	options->num_send_env = 0;
1817 	options->control_path = NULL;
1818 	options->control_master = -1;
1819 	options->control_persist = -1;
1820 	options->control_persist_timeout = 0;
1821 	options->hash_known_hosts = -1;
1822 	options->tun_open = -1;
1823 	options->tun_local = -1;
1824 	options->tun_remote = -1;
1825 	options->local_command = NULL;
1826 	options->permit_local_command = -1;
1827 	options->add_keys_to_agent = -1;
1828 	options->identity_agent = NULL;
1829 	options->visual_host_key = -1;
1830 	options->ip_qos_interactive = -1;
1831 	options->ip_qos_bulk = -1;
1832 	options->request_tty = -1;
1833 	options->proxy_use_fdpass = -1;
1834 	options->ignored_unknown = NULL;
1835 	options->num_canonical_domains = 0;
1836 	options->num_permitted_cnames = 0;
1837 	options->canonicalize_max_dots = -1;
1838 	options->canonicalize_fallback_local = -1;
1839 	options->canonicalize_hostname = -1;
1840 	options->revoked_host_keys = NULL;
1841 	options->fingerprint_hash = -1;
1842 	options->update_hostkeys = -1;
1843 	options->hostbased_key_types = NULL;
1844 	options->pubkey_key_types = NULL;
1845 }
1846 
1847 /*
1848  * A petite version of fill_default_options() that just fills the options
1849  * needed for hostname canonicalization to proceed.
1850  */
1851 void
1852 fill_default_options_for_canonicalization(Options *options)
1853 {
1854 	if (options->canonicalize_max_dots == -1)
1855 		options->canonicalize_max_dots = 1;
1856 	if (options->canonicalize_fallback_local == -1)
1857 		options->canonicalize_fallback_local = 1;
1858 	if (options->canonicalize_hostname == -1)
1859 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
1860 }
1861 
1862 /*
1863  * Called after processing other sources of option data, this fills those
1864  * options for which no value has been specified with their default values.
1865  */
1866 void
1867 fill_default_options(Options * options)
1868 {
1869 	if (options->forward_agent == -1)
1870 		options->forward_agent = 0;
1871 	if (options->forward_x11 == -1)
1872 		options->forward_x11 = 0;
1873 	if (options->forward_x11_trusted == -1)
1874 		options->forward_x11_trusted = 0;
1875 	if (options->forward_x11_timeout == -1)
1876 		options->forward_x11_timeout = 1200;
1877 	/*
1878 	 * stdio forwarding (-W) changes the default for these but we defer
1879 	 * setting the values so they can be overridden.
1880 	 */
1881 	if (options->exit_on_forward_failure == -1)
1882 		options->exit_on_forward_failure =
1883 		    options->stdio_forward_host != NULL ? 1 : 0;
1884 	if (options->clear_forwardings == -1)
1885 		options->clear_forwardings =
1886 		    options->stdio_forward_host != NULL ? 1 : 0;
1887 	if (options->clear_forwardings == 1)
1888 		clear_forwardings(options);
1889 
1890 	if (options->xauth_location == NULL)
1891 		options->xauth_location = _PATH_XAUTH;
1892 	if (options->fwd_opts.gateway_ports == -1)
1893 		options->fwd_opts.gateway_ports = 0;
1894 	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1895 		options->fwd_opts.streamlocal_bind_mask = 0177;
1896 	if (options->fwd_opts.streamlocal_bind_unlink == -1)
1897 		options->fwd_opts.streamlocal_bind_unlink = 0;
1898 	if (options->use_privileged_port == -1)
1899 		options->use_privileged_port = 0;
1900 	if (options->rsa_authentication == -1)
1901 		options->rsa_authentication = 1;
1902 	if (options->pubkey_authentication == -1)
1903 		options->pubkey_authentication = 1;
1904 	if (options->challenge_response_authentication == -1)
1905 		options->challenge_response_authentication = 1;
1906 	if (options->gss_authentication == -1)
1907 		options->gss_authentication = 0;
1908 	if (options->gss_deleg_creds == -1)
1909 		options->gss_deleg_creds = 0;
1910 	if (options->password_authentication == -1)
1911 		options->password_authentication = 1;
1912 	if (options->kbd_interactive_authentication == -1)
1913 		options->kbd_interactive_authentication = 1;
1914 	if (options->rhosts_rsa_authentication == -1)
1915 		options->rhosts_rsa_authentication = 0;
1916 	if (options->hostbased_authentication == -1)
1917 		options->hostbased_authentication = 0;
1918 	if (options->batch_mode == -1)
1919 		options->batch_mode = 0;
1920 	if (options->check_host_ip == -1)
1921 		options->check_host_ip = 1;
1922 	if (options->strict_host_key_checking == -1)
1923 		options->strict_host_key_checking = 2;	/* 2 is default */
1924 	if (options->compression == -1)
1925 		options->compression = 0;
1926 	if (options->tcp_keep_alive == -1)
1927 		options->tcp_keep_alive = 1;
1928 	if (options->compression_level == -1)
1929 		options->compression_level = 6;
1930 	if (options->port == -1)
1931 		options->port = 0;	/* Filled in ssh_connect. */
1932 	if (options->address_family == -1)
1933 		options->address_family = AF_UNSPEC;
1934 	if (options->connection_attempts == -1)
1935 		options->connection_attempts = 1;
1936 	if (options->number_of_password_prompts == -1)
1937 		options->number_of_password_prompts = 3;
1938 	/* Selected in ssh_login(). */
1939 	if (options->cipher == -1)
1940 		options->cipher = SSH_CIPHER_NOT_SET;
1941 	/* options->hostkeyalgorithms, default set in myproposals.h */
1942 	if (options->protocol == SSH_PROTO_UNKNOWN)
1943 		options->protocol = SSH_PROTO_2;
1944 	if (options->add_keys_to_agent == -1)
1945 		options->add_keys_to_agent = 0;
1946 	if (options->num_identity_files == 0) {
1947 		if (options->protocol & SSH_PROTO_1) {
1948 			add_identity_file(options, "~/",
1949 			    _PATH_SSH_CLIENT_IDENTITY, 0);
1950 		}
1951 		if (options->protocol & SSH_PROTO_2) {
1952 			add_identity_file(options, "~/",
1953 			    _PATH_SSH_CLIENT_ID_RSA, 0);
1954 			add_identity_file(options, "~/",
1955 			    _PATH_SSH_CLIENT_ID_DSA, 0);
1956 			add_identity_file(options, "~/",
1957 			    _PATH_SSH_CLIENT_ID_ECDSA, 0);
1958 			add_identity_file(options, "~/",
1959 			    _PATH_SSH_CLIENT_ID_ED25519, 0);
1960 		}
1961 	}
1962 	if (options->escape_char == -1)
1963 		options->escape_char = '~';
1964 	if (options->num_system_hostfiles == 0) {
1965 		options->system_hostfiles[options->num_system_hostfiles++] =
1966 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1967 		options->system_hostfiles[options->num_system_hostfiles++] =
1968 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1969 	}
1970 	if (options->num_user_hostfiles == 0) {
1971 		options->user_hostfiles[options->num_user_hostfiles++] =
1972 		    xstrdup(_PATH_SSH_USER_HOSTFILE);
1973 		options->user_hostfiles[options->num_user_hostfiles++] =
1974 		    xstrdup(_PATH_SSH_USER_HOSTFILE2);
1975 	}
1976 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1977 		options->log_level = SYSLOG_LEVEL_INFO;
1978 	if (options->no_host_authentication_for_localhost == - 1)
1979 		options->no_host_authentication_for_localhost = 0;
1980 	if (options->identities_only == -1)
1981 		options->identities_only = 0;
1982 	if (options->enable_ssh_keysign == -1)
1983 		options->enable_ssh_keysign = 0;
1984 	if (options->rekey_limit == -1)
1985 		options->rekey_limit = 0;
1986 	if (options->rekey_interval == -1)
1987 		options->rekey_interval = 0;
1988 	if (options->verify_host_key_dns == -1)
1989 		options->verify_host_key_dns = 0;
1990 	if (options->server_alive_interval == -1)
1991 		options->server_alive_interval = 0;
1992 	if (options->server_alive_count_max == -1)
1993 		options->server_alive_count_max = 3;
1994 	if (options->control_master == -1)
1995 		options->control_master = 0;
1996 	if (options->control_persist == -1) {
1997 		options->control_persist = 0;
1998 		options->control_persist_timeout = 0;
1999 	}
2000 	if (options->hash_known_hosts == -1)
2001 		options->hash_known_hosts = 0;
2002 	if (options->tun_open == -1)
2003 		options->tun_open = SSH_TUNMODE_NO;
2004 	if (options->tun_local == -1)
2005 		options->tun_local = SSH_TUNID_ANY;
2006 	if (options->tun_remote == -1)
2007 		options->tun_remote = SSH_TUNID_ANY;
2008 	if (options->permit_local_command == -1)
2009 		options->permit_local_command = 0;
2010 	if (options->visual_host_key == -1)
2011 		options->visual_host_key = 0;
2012 	if (options->ip_qos_interactive == -1)
2013 		options->ip_qos_interactive = IPTOS_LOWDELAY;
2014 	if (options->ip_qos_bulk == -1)
2015 		options->ip_qos_bulk = IPTOS_THROUGHPUT;
2016 	if (options->request_tty == -1)
2017 		options->request_tty = REQUEST_TTY_AUTO;
2018 	if (options->proxy_use_fdpass == -1)
2019 		options->proxy_use_fdpass = 0;
2020 	if (options->canonicalize_max_dots == -1)
2021 		options->canonicalize_max_dots = 1;
2022 	if (options->canonicalize_fallback_local == -1)
2023 		options->canonicalize_fallback_local = 1;
2024 	if (options->canonicalize_hostname == -1)
2025 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
2026 	if (options->fingerprint_hash == -1)
2027 		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2028 	if (options->update_hostkeys == -1)
2029 		options->update_hostkeys = 0;
2030 	if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
2031 	    kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
2032 	    kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
2033 	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
2034 	    &options->hostbased_key_types) != 0 ||
2035 	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
2036 	    &options->pubkey_key_types) != 0)
2037 		fatal("%s: kex_assemble_names failed", __func__);
2038 
2039 #define CLEAR_ON_NONE(v) \
2040 	do { \
2041 		if (option_clear_or_none(v)) { \
2042 			free(v); \
2043 			v = NULL; \
2044 		} \
2045 	} while(0)
2046 	CLEAR_ON_NONE(options->local_command);
2047 	CLEAR_ON_NONE(options->proxy_command);
2048 	CLEAR_ON_NONE(options->control_path);
2049 	CLEAR_ON_NONE(options->revoked_host_keys);
2050 	/* options->identity_agent distinguishes NULL from 'none' */
2051 	/* options->user will be set in the main program if appropriate */
2052 	/* options->hostname will be set in the main program if appropriate */
2053 	/* options->host_key_alias should not be set by default */
2054 	/* options->preferred_authentications will be set in ssh */
2055 }
2056 
2057 struct fwdarg {
2058 	char *arg;
2059 	int ispath;
2060 };
2061 
2062 /*
2063  * parse_fwd_field
2064  * parses the next field in a port forwarding specification.
2065  * sets fwd to the parsed field and advances p past the colon
2066  * or sets it to NULL at end of string.
2067  * returns 0 on success, else non-zero.
2068  */
2069 static int
2070 parse_fwd_field(char **p, struct fwdarg *fwd)
2071 {
2072 	char *ep, *cp = *p;
2073 	int ispath = 0;
2074 
2075 	if (*cp == '\0') {
2076 		*p = NULL;
2077 		return -1;	/* end of string */
2078 	}
2079 
2080 	/*
2081 	 * A field escaped with square brackets is used literally.
2082 	 * XXX - allow ']' to be escaped via backslash?
2083 	 */
2084 	if (*cp == '[') {
2085 		/* find matching ']' */
2086 		for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2087 			if (*ep == '/')
2088 				ispath = 1;
2089 		}
2090 		/* no matching ']' or not at end of field. */
2091 		if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2092 			return -1;
2093 		/* NUL terminate the field and advance p past the colon */
2094 		*ep++ = '\0';
2095 		if (*ep != '\0')
2096 			*ep++ = '\0';
2097 		fwd->arg = cp + 1;
2098 		fwd->ispath = ispath;
2099 		*p = ep;
2100 		return 0;
2101 	}
2102 
2103 	for (cp = *p; *cp != '\0'; cp++) {
2104 		switch (*cp) {
2105 		case '\\':
2106 			memmove(cp, cp + 1, strlen(cp + 1) + 1);
2107 			if (*cp == '\0')
2108 				return -1;
2109 			break;
2110 		case '/':
2111 			ispath = 1;
2112 			break;
2113 		case ':':
2114 			*cp++ = '\0';
2115 			goto done;
2116 		}
2117 	}
2118 done:
2119 	fwd->arg = *p;
2120 	fwd->ispath = ispath;
2121 	*p = cp;
2122 	return 0;
2123 }
2124 
2125 /*
2126  * parse_forward
2127  * parses a string containing a port forwarding specification of the form:
2128  *   dynamicfwd == 0
2129  *	[listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2130  *	listenpath:connectpath
2131  *   dynamicfwd == 1
2132  *	[listenhost:]listenport
2133  * returns number of arguments parsed or zero on error
2134  */
2135 int
2136 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2137 {
2138 	struct fwdarg fwdargs[4];
2139 	char *p, *cp;
2140 	int i;
2141 
2142 	memset(fwd, 0, sizeof(*fwd));
2143 	memset(fwdargs, 0, sizeof(fwdargs));
2144 
2145 	cp = p = xstrdup(fwdspec);
2146 
2147 	/* skip leading spaces */
2148 	while (isspace((u_char)*cp))
2149 		cp++;
2150 
2151 	for (i = 0; i < 4; ++i) {
2152 		if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2153 			break;
2154 	}
2155 
2156 	/* Check for trailing garbage */
2157 	if (cp != NULL && *cp != '\0') {
2158 		i = 0;	/* failure */
2159 	}
2160 
2161 	switch (i) {
2162 	case 1:
2163 		if (fwdargs[0].ispath) {
2164 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2165 			fwd->listen_port = PORT_STREAMLOCAL;
2166 		} else {
2167 			fwd->listen_host = NULL;
2168 			fwd->listen_port = a2port(fwdargs[0].arg);
2169 		}
2170 		fwd->connect_host = xstrdup("socks");
2171 		break;
2172 
2173 	case 2:
2174 		if (fwdargs[0].ispath && fwdargs[1].ispath) {
2175 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2176 			fwd->listen_port = PORT_STREAMLOCAL;
2177 			fwd->connect_path = xstrdup(fwdargs[1].arg);
2178 			fwd->connect_port = PORT_STREAMLOCAL;
2179 		} else if (fwdargs[1].ispath) {
2180 			fwd->listen_host = NULL;
2181 			fwd->listen_port = a2port(fwdargs[0].arg);
2182 			fwd->connect_path = xstrdup(fwdargs[1].arg);
2183 			fwd->connect_port = PORT_STREAMLOCAL;
2184 		} else {
2185 			fwd->listen_host = xstrdup(fwdargs[0].arg);
2186 			fwd->listen_port = a2port(fwdargs[1].arg);
2187 			fwd->connect_host = xstrdup("socks");
2188 		}
2189 		break;
2190 
2191 	case 3:
2192 		if (fwdargs[0].ispath) {
2193 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2194 			fwd->listen_port = PORT_STREAMLOCAL;
2195 			fwd->connect_host = xstrdup(fwdargs[1].arg);
2196 			fwd->connect_port = a2port(fwdargs[2].arg);
2197 		} else if (fwdargs[2].ispath) {
2198 			fwd->listen_host = xstrdup(fwdargs[0].arg);
2199 			fwd->listen_port = a2port(fwdargs[1].arg);
2200 			fwd->connect_path = xstrdup(fwdargs[2].arg);
2201 			fwd->connect_port = PORT_STREAMLOCAL;
2202 		} else {
2203 			fwd->listen_host = NULL;
2204 			fwd->listen_port = a2port(fwdargs[0].arg);
2205 			fwd->connect_host = xstrdup(fwdargs[1].arg);
2206 			fwd->connect_port = a2port(fwdargs[2].arg);
2207 		}
2208 		break;
2209 
2210 	case 4:
2211 		fwd->listen_host = xstrdup(fwdargs[0].arg);
2212 		fwd->listen_port = a2port(fwdargs[1].arg);
2213 		fwd->connect_host = xstrdup(fwdargs[2].arg);
2214 		fwd->connect_port = a2port(fwdargs[3].arg);
2215 		break;
2216 	default:
2217 		i = 0; /* failure */
2218 	}
2219 
2220 	free(p);
2221 
2222 	if (dynamicfwd) {
2223 		if (!(i == 1 || i == 2))
2224 			goto fail_free;
2225 	} else {
2226 		if (!(i == 3 || i == 4)) {
2227 			if (fwd->connect_path == NULL &&
2228 			    fwd->listen_path == NULL)
2229 				goto fail_free;
2230 		}
2231 		if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2232 			goto fail_free;
2233 	}
2234 
2235 	if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2236 	    (!remotefwd && fwd->listen_port == 0))
2237 		goto fail_free;
2238 	if (fwd->connect_host != NULL &&
2239 	    strlen(fwd->connect_host) >= NI_MAXHOST)
2240 		goto fail_free;
2241 	/* XXX - if connecting to a remote socket, max sun len may not match this host */
2242 	if (fwd->connect_path != NULL &&
2243 	    strlen(fwd->connect_path) >= PATH_MAX_SUN)
2244 		goto fail_free;
2245 	if (fwd->listen_host != NULL &&
2246 	    strlen(fwd->listen_host) >= NI_MAXHOST)
2247 		goto fail_free;
2248 	if (fwd->listen_path != NULL &&
2249 	    strlen(fwd->listen_path) >= PATH_MAX_SUN)
2250 		goto fail_free;
2251 
2252 	return (i);
2253 
2254  fail_free:
2255 	free(fwd->connect_host);
2256 	fwd->connect_host = NULL;
2257 	free(fwd->connect_path);
2258 	fwd->connect_path = NULL;
2259 	free(fwd->listen_host);
2260 	fwd->listen_host = NULL;
2261 	free(fwd->listen_path);
2262 	fwd->listen_path = NULL;
2263 	return (0);
2264 }
2265 
2266 int
2267 parse_jump(const char *s, Options *o, int active)
2268 {
2269 	char *orig, *sdup, *cp;
2270 	char *host = NULL, *user = NULL;
2271 	int ret = -1, port = -1, first;
2272 
2273 	active &= o->proxy_command == NULL && o->jump_host == NULL;
2274 
2275 	orig = sdup = xstrdup(s);
2276 	first = active;
2277 	do {
2278 		if ((cp = strrchr(sdup, ',')) == NULL)
2279 			cp = sdup; /* last */
2280 		else
2281 			*cp++ = '\0';
2282 
2283 		if (first) {
2284 			/* First argument and configuration is active */
2285 			if (parse_user_host_port(cp, &user, &host, &port) != 0)
2286 				goto out;
2287 		} else {
2288 			/* Subsequent argument or inactive configuration */
2289 			if (parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2290 				goto out;
2291 		}
2292 		first = 0; /* only check syntax for subsequent hosts */
2293 	} while (cp != sdup);
2294 	/* success */
2295 	if (active) {
2296 		o->jump_user = user;
2297 		o->jump_host = host;
2298 		o->jump_port = port;
2299 		o->proxy_command = xstrdup("none");
2300 		user = host = NULL;
2301 		if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2302 			o->jump_extra = xstrdup(s);
2303 			o->jump_extra[cp - s] = '\0';
2304 		}
2305 	}
2306 	ret = 0;
2307  out:
2308 	free(orig);
2309 	free(user);
2310 	free(host);
2311 	return ret;
2312 }
2313 
2314 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2315 static const char *
2316 fmt_multistate_int(int val, const struct multistate *m)
2317 {
2318 	u_int i;
2319 
2320 	for (i = 0; m[i].key != NULL; i++) {
2321 		if (m[i].value == val)
2322 			return m[i].key;
2323 	}
2324 	return "UNKNOWN";
2325 }
2326 
2327 static const char *
2328 fmt_intarg(OpCodes code, int val)
2329 {
2330 	if (val == -1)
2331 		return "unset";
2332 	switch (code) {
2333 	case oAddressFamily:
2334 		return fmt_multistate_int(val, multistate_addressfamily);
2335 	case oVerifyHostKeyDNS:
2336 	case oStrictHostKeyChecking:
2337 	case oUpdateHostkeys:
2338 		return fmt_multistate_int(val, multistate_yesnoask);
2339 	case oControlMaster:
2340 		return fmt_multistate_int(val, multistate_controlmaster);
2341 	case oTunnel:
2342 		return fmt_multistate_int(val, multistate_tunnel);
2343 	case oRequestTTY:
2344 		return fmt_multistate_int(val, multistate_requesttty);
2345 	case oCanonicalizeHostname:
2346 		return fmt_multistate_int(val, multistate_canonicalizehostname);
2347 	case oFingerprintHash:
2348 		return ssh_digest_alg_name(val);
2349 	case oProtocol:
2350 		switch (val) {
2351 		case SSH_PROTO_1:
2352 			return "1";
2353 		case SSH_PROTO_2:
2354 			return "2";
2355 		case (SSH_PROTO_1|SSH_PROTO_2):
2356 			return "2,1";
2357 		default:
2358 			return "UNKNOWN";
2359 		}
2360 	default:
2361 		switch (val) {
2362 		case 0:
2363 			return "no";
2364 		case 1:
2365 			return "yes";
2366 		default:
2367 			return "UNKNOWN";
2368 		}
2369 	}
2370 }
2371 
2372 static const char *
2373 lookup_opcode_name(OpCodes code)
2374 {
2375 	u_int i;
2376 
2377 	for (i = 0; keywords[i].name != NULL; i++)
2378 		if (keywords[i].opcode == code)
2379 			return(keywords[i].name);
2380 	return "UNKNOWN";
2381 }
2382 
2383 static void
2384 dump_cfg_int(OpCodes code, int val)
2385 {
2386 	printf("%s %d\n", lookup_opcode_name(code), val);
2387 }
2388 
2389 static void
2390 dump_cfg_fmtint(OpCodes code, int val)
2391 {
2392 	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2393 }
2394 
2395 static void
2396 dump_cfg_string(OpCodes code, const char *val)
2397 {
2398 	if (val == NULL)
2399 		return;
2400 	printf("%s %s\n", lookup_opcode_name(code), val);
2401 }
2402 
2403 static void
2404 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2405 {
2406 	u_int i;
2407 
2408 	for (i = 0; i < count; i++)
2409 		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2410 }
2411 
2412 static void
2413 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2414 {
2415 	u_int i;
2416 
2417 	printf("%s", lookup_opcode_name(code));
2418 	for (i = 0; i < count; i++)
2419 		printf(" %s",  vals[i]);
2420 	printf("\n");
2421 }
2422 
2423 static void
2424 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2425 {
2426 	const struct Forward *fwd;
2427 	u_int i;
2428 
2429 	/* oDynamicForward */
2430 	for (i = 0; i < count; i++) {
2431 		fwd = &fwds[i];
2432 		if (code == oDynamicForward &&
2433 		    strcmp(fwd->connect_host, "socks") != 0)
2434 			continue;
2435 		if (code == oLocalForward &&
2436 		    strcmp(fwd->connect_host, "socks") == 0)
2437 			continue;
2438 		printf("%s", lookup_opcode_name(code));
2439 		if (fwd->listen_port == PORT_STREAMLOCAL)
2440 			printf(" %s", fwd->listen_path);
2441 		else if (fwd->listen_host == NULL)
2442 			printf(" %d", fwd->listen_port);
2443 		else {
2444 			printf(" [%s]:%d",
2445 			    fwd->listen_host, fwd->listen_port);
2446 		}
2447 		if (code != oDynamicForward) {
2448 			if (fwd->connect_port == PORT_STREAMLOCAL)
2449 				printf(" %s", fwd->connect_path);
2450 			else if (fwd->connect_host == NULL)
2451 				printf(" %d", fwd->connect_port);
2452 			else {
2453 				printf(" [%s]:%d",
2454 				    fwd->connect_host, fwd->connect_port);
2455 			}
2456 		}
2457 		printf("\n");
2458 	}
2459 }
2460 
2461 void
2462 dump_client_config(Options *o, const char *host)
2463 {
2464 	int i;
2465 	char buf[8];
2466 
2467 	/* This is normally prepared in ssh_kex2 */
2468 	if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2469 		fatal("%s: kex_assemble_names failed", __func__);
2470 
2471 	/* Most interesting options first: user, host, port */
2472 	dump_cfg_string(oUser, o->user);
2473 	dump_cfg_string(oHostName, host);
2474 	dump_cfg_int(oPort, o->port);
2475 
2476 	/* Flag options */
2477 	dump_cfg_fmtint(oAddressFamily, o->address_family);
2478 	dump_cfg_fmtint(oBatchMode, o->batch_mode);
2479 	dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2480 	dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2481 	dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2482 	dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2483 	dump_cfg_fmtint(oCompression, o->compression);
2484 	dump_cfg_fmtint(oControlMaster, o->control_master);
2485 	dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2486 	dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2487 	dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2488 	dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2489 	dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2490 	dump_cfg_fmtint(oForwardX11, o->forward_x11);
2491 	dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2492 	dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2493 #ifdef GSSAPI
2494 	dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2495 	dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2496 #endif /* GSSAPI */
2497 	dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2498 	dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2499 	dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2500 	dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2501 	dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2502 	dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2503 	dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2504 	dump_cfg_fmtint(oProtocol, o->protocol);
2505 	dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2506 	dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2507 	dump_cfg_fmtint(oRequestTTY, o->request_tty);
2508 	dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2509 	dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
2510 	dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2511 	dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2512 	dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2513 	dump_cfg_fmtint(oTunnel, o->tun_open);
2514 	dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2515 	dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2516 	dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2517 	dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2518 
2519 	/* Integer options */
2520 	dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2521 	dump_cfg_int(oCompressionLevel, o->compression_level);
2522 	dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2523 	dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2524 	dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2525 	dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2526 	dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2527 
2528 	/* String options */
2529 	dump_cfg_string(oBindAddress, o->bind_address);
2530 	dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2531 	dump_cfg_string(oControlPath, o->control_path);
2532 	dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2533 	dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2534 	dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2535 	dump_cfg_string(oIdentityAgent, o->identity_agent);
2536 	dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2537 	dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2538 	dump_cfg_string(oLocalCommand, o->local_command);
2539 	dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2540 	dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2541 	dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2542 	dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2543 	dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2544 	dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2545 	dump_cfg_string(oXAuthLocation, o->xauth_location);
2546 
2547 	/* Forwards */
2548 	dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2549 	dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2550 	dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2551 
2552 	/* String array options */
2553 	dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2554 	dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2555 	dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2556 	dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2557 	dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2558 
2559 	/* Special cases */
2560 
2561 	/* oConnectTimeout */
2562 	if (o->connection_timeout == -1)
2563 		printf("connecttimeout none\n");
2564 	else
2565 		dump_cfg_int(oConnectTimeout, o->connection_timeout);
2566 
2567 	/* oTunnelDevice */
2568 	printf("tunneldevice");
2569 	if (o->tun_local == SSH_TUNID_ANY)
2570 		printf(" any");
2571 	else
2572 		printf(" %d", o->tun_local);
2573 	if (o->tun_remote == SSH_TUNID_ANY)
2574 		printf(":any");
2575 	else
2576 		printf(":%d", o->tun_remote);
2577 	printf("\n");
2578 
2579 	/* oCanonicalizePermittedCNAMEs */
2580 	if ( o->num_permitted_cnames > 0) {
2581 		printf("canonicalizePermittedcnames");
2582 		for (i = 0; i < o->num_permitted_cnames; i++) {
2583 			printf(" %s:%s", o->permitted_cnames[i].source_list,
2584 			    o->permitted_cnames[i].target_list);
2585 		}
2586 		printf("\n");
2587 	}
2588 
2589 	/* oCipher */
2590 	if (o->cipher != SSH_CIPHER_NOT_SET)
2591 		printf("Cipher %s\n", cipher_name(o->cipher));
2592 
2593 	/* oControlPersist */
2594 	if (o->control_persist == 0 || o->control_persist_timeout == 0)
2595 		dump_cfg_fmtint(oControlPersist, o->control_persist);
2596 	else
2597 		dump_cfg_int(oControlPersist, o->control_persist_timeout);
2598 
2599 	/* oEscapeChar */
2600 	if (o->escape_char == SSH_ESCAPECHAR_NONE)
2601 		printf("escapechar none\n");
2602 	else {
2603 		vis(buf, o->escape_char, VIS_WHITE, 0);
2604 		printf("escapechar %s\n", buf);
2605 	}
2606 
2607 	/* oIPQoS */
2608 	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2609 	printf("%s\n", iptos2str(o->ip_qos_bulk));
2610 
2611 	/* oRekeyLimit */
2612 	printf("rekeylimit %llu %d\n",
2613 	    (unsigned long long)o->rekey_limit, o->rekey_interval);
2614 
2615 	/* oStreamLocalBindMask */
2616 	printf("streamlocalbindmask 0%o\n",
2617 	    o->fwd_opts.streamlocal_bind_mask);
2618 
2619 	/* oProxyCommand / oProxyJump */
2620 	if (o->jump_host == NULL)
2621 		dump_cfg_string(oProxyCommand, o->proxy_command);
2622 	else {
2623 		/* Check for numeric addresses */
2624 		i = strchr(o->jump_host, ':') != NULL ||
2625 		    strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2626 		snprintf(buf, sizeof(buf), "%d", o->jump_port);
2627 		printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2628 		    /* optional additional jump spec */
2629 		    o->jump_extra == NULL ? "" : o->jump_extra,
2630 		    o->jump_extra == NULL ? "" : ",",
2631 		    /* optional user */
2632 		    o->jump_user == NULL ? "" : o->jump_user,
2633 		    o->jump_user == NULL ? "" : "@",
2634 		    /* opening [ if hostname is numeric */
2635 		    i ? "[" : "",
2636 		    /* mandatory hostname */
2637 		    o->jump_host,
2638 		    /* closing ] if hostname is numeric */
2639 		    i ? "]" : "",
2640 		    /* optional port number */
2641 		    o->jump_port <= 0 ? "" : ":",
2642 		    o->jump_port <= 0 ? "" : buf);
2643 	}
2644 }
2645