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