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