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