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