xref: /freebsd/crypto/openssh/readconf.c (revision 949eda893bfe47e0bd09b43681f4463f0e695450)
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 	    newfwd->listen_path == NULL)
324 		fatal("Privileged ports can only be forwarded by root.");
325 #endif
326 	options->local_forwards = xreallocarray(options->local_forwards,
327 	    options->num_local_forwards + 1,
328 	    sizeof(*options->local_forwards));
329 	fwd = &options->local_forwards[options->num_local_forwards++];
330 
331 	fwd->listen_host = newfwd->listen_host;
332 	fwd->listen_port = newfwd->listen_port;
333 	fwd->listen_path = newfwd->listen_path;
334 	fwd->connect_host = newfwd->connect_host;
335 	fwd->connect_port = newfwd->connect_port;
336 	fwd->connect_path = newfwd->connect_path;
337 }
338 
339 /*
340  * Adds a remote TCP/IP port forward to options.  Never returns if there is
341  * an error.
342  */
343 
344 void
345 add_remote_forward(Options *options, const struct Forward *newfwd)
346 {
347 	struct Forward *fwd;
348 
349 	options->remote_forwards = xreallocarray(options->remote_forwards,
350 	    options->num_remote_forwards + 1,
351 	    sizeof(*options->remote_forwards));
352 	fwd = &options->remote_forwards[options->num_remote_forwards++];
353 
354 	fwd->listen_host = newfwd->listen_host;
355 	fwd->listen_port = newfwd->listen_port;
356 	fwd->listen_path = newfwd->listen_path;
357 	fwd->connect_host = newfwd->connect_host;
358 	fwd->connect_port = newfwd->connect_port;
359 	fwd->connect_path = newfwd->connect_path;
360 	fwd->handle = newfwd->handle;
361 	fwd->allocated_port = 0;
362 }
363 
364 static void
365 clear_forwardings(Options *options)
366 {
367 	int i;
368 
369 	for (i = 0; i < options->num_local_forwards; i++) {
370 		free(options->local_forwards[i].listen_host);
371 		free(options->local_forwards[i].listen_path);
372 		free(options->local_forwards[i].connect_host);
373 		free(options->local_forwards[i].connect_path);
374 	}
375 	if (options->num_local_forwards > 0) {
376 		free(options->local_forwards);
377 		options->local_forwards = NULL;
378 	}
379 	options->num_local_forwards = 0;
380 	for (i = 0; i < options->num_remote_forwards; i++) {
381 		free(options->remote_forwards[i].listen_host);
382 		free(options->remote_forwards[i].listen_path);
383 		free(options->remote_forwards[i].connect_host);
384 		free(options->remote_forwards[i].connect_path);
385 	}
386 	if (options->num_remote_forwards > 0) {
387 		free(options->remote_forwards);
388 		options->remote_forwards = NULL;
389 	}
390 	options->num_remote_forwards = 0;
391 	options->tun_open = SSH_TUNMODE_NO;
392 }
393 
394 void
395 add_certificate_file(Options *options, const char *path, int userprovided)
396 {
397 	int i;
398 
399 	if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
400 		fatal("Too many certificate files specified (max %d)",
401 		    SSH_MAX_CERTIFICATE_FILES);
402 
403 	/* Avoid registering duplicates */
404 	for (i = 0; i < options->num_certificate_files; i++) {
405 		if (options->certificate_file_userprovided[i] == userprovided &&
406 		    strcmp(options->certificate_files[i], path) == 0) {
407 			debug2("%s: ignoring duplicate key %s", __func__, path);
408 			return;
409 		}
410 	}
411 
412 	options->certificate_file_userprovided[options->num_certificate_files] =
413 	    userprovided;
414 	options->certificate_files[options->num_certificate_files++] =
415 	    xstrdup(path);
416 }
417 
418 void
419 add_identity_file(Options *options, const char *dir, const char *filename,
420     int userprovided)
421 {
422 	char *path;
423 	int i;
424 
425 	if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
426 		fatal("Too many identity files specified (max %d)",
427 		    SSH_MAX_IDENTITY_FILES);
428 
429 	if (dir == NULL) /* no dir, filename is absolute */
430 		path = xstrdup(filename);
431 	else
432 		(void)xasprintf(&path, "%.100s%.100s", dir, filename);
433 
434 	/* Avoid registering duplicates */
435 	for (i = 0; i < options->num_identity_files; i++) {
436 		if (options->identity_file_userprovided[i] == userprovided &&
437 		    strcmp(options->identity_files[i], path) == 0) {
438 			debug2("%s: ignoring duplicate key %s", __func__, path);
439 			free(path);
440 			return;
441 		}
442 	}
443 
444 	options->identity_file_userprovided[options->num_identity_files] =
445 	    userprovided;
446 	options->identity_files[options->num_identity_files++] = path;
447 }
448 
449 int
450 default_ssh_port(void)
451 {
452 	static int port;
453 	struct servent *sp;
454 
455 	if (port == 0) {
456 		sp = getservbyname(SSH_SERVICE_NAME, "tcp");
457 		port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
458 	}
459 	return port;
460 }
461 
462 /*
463  * Execute a command in a shell.
464  * Return its exit status or -1 on abnormal exit.
465  */
466 static int
467 execute_in_shell(const char *cmd)
468 {
469 	char *shell;
470 	pid_t pid;
471 	int devnull, status;
472 	extern uid_t original_real_uid;
473 
474 	if ((shell = getenv("SHELL")) == NULL)
475 		shell = _PATH_BSHELL;
476 
477 	/* Need this to redirect subprocess stdin/out */
478 	if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
479 		fatal("open(/dev/null): %s", strerror(errno));
480 
481 	debug("Executing command: '%.500s'", cmd);
482 
483 	/* Fork and execute the command. */
484 	if ((pid = fork()) == 0) {
485 		char *argv[4];
486 
487 		/* Child.  Permanently give up superuser privileges. */
488 		permanently_drop_suid(original_real_uid);
489 
490 		/* Redirect child stdin and stdout. Leave stderr */
491 		if (dup2(devnull, STDIN_FILENO) == -1)
492 			fatal("dup2: %s", strerror(errno));
493 		if (dup2(devnull, STDOUT_FILENO) == -1)
494 			fatal("dup2: %s", strerror(errno));
495 		if (devnull > STDERR_FILENO)
496 			close(devnull);
497 		closefrom(STDERR_FILENO + 1);
498 
499 		argv[0] = shell;
500 		argv[1] = "-c";
501 		argv[2] = xstrdup(cmd);
502 		argv[3] = NULL;
503 
504 		execv(argv[0], argv);
505 		error("Unable to execute '%.100s': %s", cmd, strerror(errno));
506 		/* Die with signal to make this error apparent to parent. */
507 		signal(SIGTERM, SIG_DFL);
508 		kill(getpid(), SIGTERM);
509 		_exit(1);
510 	}
511 	/* Parent. */
512 	if (pid < 0)
513 		fatal("%s: fork: %.100s", __func__, strerror(errno));
514 
515 	close(devnull);
516 
517 	while (waitpid(pid, &status, 0) == -1) {
518 		if (errno != EINTR && errno != EAGAIN)
519 			fatal("%s: waitpid: %s", __func__, strerror(errno));
520 	}
521 	if (!WIFEXITED(status)) {
522 		error("command '%.100s' exited abnormally", cmd);
523 		return -1;
524 	}
525 	debug3("command returned status %d", WEXITSTATUS(status));
526 	return WEXITSTATUS(status);
527 }
528 
529 /*
530  * Parse and execute a Match directive.
531  */
532 static int
533 match_cfg_line(Options *options, char **condition, struct passwd *pw,
534     const char *host_arg, const char *original_host, int post_canon,
535     const char *filename, int linenum)
536 {
537 	char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
538 	const char *ruser;
539 	int r, port, this_result, result = 1, attributes = 0, negate;
540 	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
541 
542 	/*
543 	 * Configuration is likely to be incomplete at this point so we
544 	 * must be prepared to use default values.
545 	 */
546 	port = options->port <= 0 ? default_ssh_port() : options->port;
547 	ruser = options->user == NULL ? pw->pw_name : options->user;
548 	if (post_canon) {
549 		host = xstrdup(options->hostname);
550 	} else if (options->hostname != NULL) {
551 		/* NB. Please keep in sync with ssh.c:main() */
552 		host = percent_expand(options->hostname,
553 		    "h", host_arg, (char *)NULL);
554 	} else {
555 		host = xstrdup(host_arg);
556 	}
557 
558 	debug2("checking match for '%s' host %s originally %s",
559 	    cp, host, original_host);
560 	while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
561 		criteria = NULL;
562 		this_result = 1;
563 		if ((negate = attrib[0] == '!'))
564 			attrib++;
565 		/* criteria "all" and "canonical" have no argument */
566 		if (strcasecmp(attrib, "all") == 0) {
567 			if (attributes > 1 ||
568 			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
569 				error("%.200s line %d: '%s' cannot be combined "
570 				    "with other Match attributes",
571 				    filename, linenum, oattrib);
572 				result = -1;
573 				goto out;
574 			}
575 			if (result)
576 				result = negate ? 0 : 1;
577 			goto out;
578 		}
579 		attributes++;
580 		if (strcasecmp(attrib, "canonical") == 0) {
581 			r = !!post_canon;  /* force bitmask member to boolean */
582 			if (r == (negate ? 1 : 0))
583 				this_result = result = 0;
584 			debug3("%.200s line %d: %smatched '%s'",
585 			    filename, linenum,
586 			    this_result ? "" : "not ", oattrib);
587 			continue;
588 		}
589 		/* All other criteria require an argument */
590 		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
591 			error("Missing Match criteria for %s", attrib);
592 			result = -1;
593 			goto out;
594 		}
595 		if (strcasecmp(attrib, "host") == 0) {
596 			criteria = xstrdup(host);
597 			r = match_hostname(host, arg) == 1;
598 			if (r == (negate ? 1 : 0))
599 				this_result = result = 0;
600 		} else if (strcasecmp(attrib, "originalhost") == 0) {
601 			criteria = xstrdup(original_host);
602 			r = match_hostname(original_host, arg) == 1;
603 			if (r == (negate ? 1 : 0))
604 				this_result = result = 0;
605 		} else if (strcasecmp(attrib, "user") == 0) {
606 			criteria = xstrdup(ruser);
607 			r = match_pattern_list(ruser, arg, 0) == 1;
608 			if (r == (negate ? 1 : 0))
609 				this_result = result = 0;
610 		} else if (strcasecmp(attrib, "localuser") == 0) {
611 			criteria = xstrdup(pw->pw_name);
612 			r = match_pattern_list(pw->pw_name, arg, 0) == 1;
613 			if (r == (negate ? 1 : 0))
614 				this_result = result = 0;
615 		} else if (strcasecmp(attrib, "exec") == 0) {
616 			if (gethostname(thishost, sizeof(thishost)) == -1)
617 				fatal("gethostname: %s", strerror(errno));
618 			strlcpy(shorthost, thishost, sizeof(shorthost));
619 			shorthost[strcspn(thishost, ".")] = '\0';
620 			snprintf(portstr, sizeof(portstr), "%d", port);
621 
622 			cmd = percent_expand(arg,
623 			    "L", shorthost,
624 			    "d", pw->pw_dir,
625 			    "h", host,
626 			    "l", thishost,
627 			    "n", original_host,
628 			    "p", portstr,
629 			    "r", ruser,
630 			    "u", pw->pw_name,
631 			    (char *)NULL);
632 			if (result != 1) {
633 				/* skip execution if prior predicate failed */
634 				debug3("%.200s line %d: skipped exec "
635 				    "\"%.100s\"", filename, linenum, cmd);
636 				free(cmd);
637 				continue;
638 			}
639 			r = execute_in_shell(cmd);
640 			if (r == -1) {
641 				fatal("%.200s line %d: match exec "
642 				    "'%.100s' error", filename,
643 				    linenum, cmd);
644 			}
645 			criteria = xstrdup(cmd);
646 			free(cmd);
647 			/* Force exit status to boolean */
648 			r = r == 0;
649 			if (r == (negate ? 1 : 0))
650 				this_result = result = 0;
651 		} else {
652 			error("Unsupported Match attribute %s", attrib);
653 			result = -1;
654 			goto out;
655 		}
656 		debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
657 		    filename, linenum, this_result ? "": "not ",
658 		    oattrib, criteria);
659 		free(criteria);
660 	}
661 	if (attributes == 0) {
662 		error("One or more attributes required for Match");
663 		result = -1;
664 		goto out;
665 	}
666  out:
667 	if (result != -1)
668 		debug2("match %sfound", result ? "" : "not ");
669 	*condition = cp;
670 	free(host);
671 	return result;
672 }
673 
674 /* Check and prepare a domain name: removes trailing '.' and lowercases */
675 static void
676 valid_domain(char *name, const char *filename, int linenum)
677 {
678 	size_t i, l = strlen(name);
679 	u_char c, last = '\0';
680 
681 	if (l == 0)
682 		fatal("%s line %d: empty hostname suffix", filename, linenum);
683 	if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
684 		fatal("%s line %d: hostname suffix \"%.100s\" "
685 		    "starts with invalid character", filename, linenum, name);
686 	for (i = 0; i < l; i++) {
687 		c = tolower((u_char)name[i]);
688 		name[i] = (char)c;
689 		if (last == '.' && c == '.')
690 			fatal("%s line %d: hostname suffix \"%.100s\" contains "
691 			    "consecutive separators", filename, linenum, name);
692 		if (c != '.' && c != '-' && !isalnum(c) &&
693 		    c != '_') /* technically invalid, but common */
694 			fatal("%s line %d: hostname suffix \"%.100s\" contains "
695 			    "invalid characters", filename, linenum, name);
696 		last = c;
697 	}
698 	if (name[l - 1] == '.')
699 		name[l - 1] = '\0';
700 }
701 
702 /*
703  * Returns the number of the token pointed to by cp or oBadOption.
704  */
705 static OpCodes
706 parse_token(const char *cp, const char *filename, int linenum,
707     const char *ignored_unknown)
708 {
709 	int i;
710 
711 	for (i = 0; keywords[i].name; i++)
712 		if (strcmp(cp, keywords[i].name) == 0)
713 			return keywords[i].opcode;
714 	if (ignored_unknown != NULL &&
715 	    match_pattern_list(cp, ignored_unknown, 1) == 1)
716 		return oIgnoredUnknownOption;
717 	error("%s: line %d: Bad configuration option: %s",
718 	    filename, linenum, cp);
719 	return oBadOption;
720 }
721 
722 /* Multistate option parsing */
723 struct multistate {
724 	char *key;
725 	int value;
726 };
727 static const struct multistate multistate_flag[] = {
728 	{ "true",			1 },
729 	{ "false",			0 },
730 	{ "yes",			1 },
731 	{ "no",				0 },
732 	{ NULL, -1 }
733 };
734 static const struct multistate multistate_yesnoask[] = {
735 	{ "true",			1 },
736 	{ "false",			0 },
737 	{ "yes",			1 },
738 	{ "no",				0 },
739 	{ "ask",			2 },
740 	{ NULL, -1 }
741 };
742 static const struct multistate multistate_yesnoaskconfirm[] = {
743 	{ "true",			1 },
744 	{ "false",			0 },
745 	{ "yes",			1 },
746 	{ "no",				0 },
747 	{ "ask",			2 },
748 	{ "confirm",			3 },
749 	{ NULL, -1 }
750 };
751 static const struct multistate multistate_addressfamily[] = {
752 	{ "inet",			AF_INET },
753 	{ "inet6",			AF_INET6 },
754 	{ "any",			AF_UNSPEC },
755 	{ NULL, -1 }
756 };
757 static const struct multistate multistate_controlmaster[] = {
758 	{ "true",			SSHCTL_MASTER_YES },
759 	{ "yes",			SSHCTL_MASTER_YES },
760 	{ "false",			SSHCTL_MASTER_NO },
761 	{ "no",				SSHCTL_MASTER_NO },
762 	{ "auto",			SSHCTL_MASTER_AUTO },
763 	{ "ask",			SSHCTL_MASTER_ASK },
764 	{ "autoask",			SSHCTL_MASTER_AUTO_ASK },
765 	{ NULL, -1 }
766 };
767 static const struct multistate multistate_tunnel[] = {
768 	{ "ethernet",			SSH_TUNMODE_ETHERNET },
769 	{ "point-to-point",		SSH_TUNMODE_POINTOPOINT },
770 	{ "true",			SSH_TUNMODE_DEFAULT },
771 	{ "yes",			SSH_TUNMODE_DEFAULT },
772 	{ "false",			SSH_TUNMODE_NO },
773 	{ "no",				SSH_TUNMODE_NO },
774 	{ NULL, -1 }
775 };
776 static const struct multistate multistate_requesttty[] = {
777 	{ "true",			REQUEST_TTY_YES },
778 	{ "yes",			REQUEST_TTY_YES },
779 	{ "false",			REQUEST_TTY_NO },
780 	{ "no",				REQUEST_TTY_NO },
781 	{ "force",			REQUEST_TTY_FORCE },
782 	{ "auto",			REQUEST_TTY_AUTO },
783 	{ NULL, -1 }
784 };
785 static const struct multistate multistate_canonicalizehostname[] = {
786 	{ "true",			SSH_CANONICALISE_YES },
787 	{ "false",			SSH_CANONICALISE_NO },
788 	{ "yes",			SSH_CANONICALISE_YES },
789 	{ "no",				SSH_CANONICALISE_NO },
790 	{ "always",			SSH_CANONICALISE_ALWAYS },
791 	{ NULL, -1 }
792 };
793 
794 /*
795  * Processes a single option line as used in the configuration files. This
796  * only sets those values that have not already been set.
797  */
798 #define WHITESPACE " \t\r\n"
799 int
800 process_config_line(Options *options, struct passwd *pw, const char *host,
801     const char *original_host, char *line, const char *filename,
802     int linenum, int *activep, int flags)
803 {
804 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
805 	char **cpptr, fwdarg[256];
806 	u_int i, *uintptr, max_entries = 0;
807 	int negated, opcode, *intptr, value, value2, cmdline = 0;
808 	LogLevel *log_level_ptr;
809 	long long val64;
810 	size_t len;
811 	struct Forward fwd;
812 	const struct multistate *multistate_ptr;
813 	struct allowed_cname *cname;
814 
815 	if (activep == NULL) { /* We are processing a command line directive */
816 		cmdline = 1;
817 		activep = &cmdline;
818 	}
819 
820 	/* Strip trailing whitespace */
821 	if ((len = strlen(line)) == 0)
822 		return 0;
823 	for (len--; len > 0; len--) {
824 		if (strchr(WHITESPACE, line[len]) == NULL)
825 			break;
826 		line[len] = '\0';
827 	}
828 
829 	s = line;
830 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
831 	if ((keyword = strdelim(&s)) == NULL)
832 		return 0;
833 	/* Ignore leading whitespace. */
834 	if (*keyword == '\0')
835 		keyword = strdelim(&s);
836 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
837 		return 0;
838 	/* Match lowercase keyword */
839 	lowercase(keyword);
840 
841 	opcode = parse_token(keyword, filename, linenum,
842 	    options->ignored_unknown);
843 
844 	switch (opcode) {
845 	case oBadOption:
846 		/* don't panic, but count bad options */
847 		return -1;
848 		/* NOTREACHED */
849 	case oIgnoredUnknownOption:
850 		debug("%s line %d: Ignored unknown option \"%s\"",
851 		    filename, linenum, keyword);
852 		return 0;
853 	case oConnectTimeout:
854 		intptr = &options->connection_timeout;
855 parse_time:
856 		arg = strdelim(&s);
857 		if (!arg || *arg == '\0')
858 			fatal("%s line %d: missing time value.",
859 			    filename, linenum);
860 		if (strcmp(arg, "none") == 0)
861 			value = -1;
862 		else if ((value = convtime(arg)) == -1)
863 			fatal("%s line %d: invalid time value.",
864 			    filename, linenum);
865 		if (*activep && *intptr == -1)
866 			*intptr = value;
867 		break;
868 
869 	case oForwardAgent:
870 		intptr = &options->forward_agent;
871  parse_flag:
872 		multistate_ptr = multistate_flag;
873  parse_multistate:
874 		arg = strdelim(&s);
875 		if (!arg || *arg == '\0')
876 			fatal("%s line %d: missing argument.",
877 			    filename, linenum);
878 		value = -1;
879 		for (i = 0; multistate_ptr[i].key != NULL; i++) {
880 			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
881 				value = multistate_ptr[i].value;
882 				break;
883 			}
884 		}
885 		if (value == -1)
886 			fatal("%s line %d: unsupported option \"%s\".",
887 			    filename, linenum, arg);
888 		if (*activep && *intptr == -1)
889 			*intptr = value;
890 		break;
891 
892 	case oForwardX11:
893 		intptr = &options->forward_x11;
894 		goto parse_flag;
895 
896 	case oForwardX11Trusted:
897 		intptr = &options->forward_x11_trusted;
898 		goto parse_flag;
899 
900 	case oForwardX11Timeout:
901 		intptr = &options->forward_x11_timeout;
902 		goto parse_time;
903 
904 	case oGatewayPorts:
905 		intptr = &options->fwd_opts.gateway_ports;
906 		goto parse_flag;
907 
908 	case oExitOnForwardFailure:
909 		intptr = &options->exit_on_forward_failure;
910 		goto parse_flag;
911 
912 	case oUsePrivilegedPort:
913 		intptr = &options->use_privileged_port;
914 		goto parse_flag;
915 
916 	case oPasswordAuthentication:
917 		intptr = &options->password_authentication;
918 		goto parse_flag;
919 
920 	case oKbdInteractiveAuthentication:
921 		intptr = &options->kbd_interactive_authentication;
922 		goto parse_flag;
923 
924 	case oKbdInteractiveDevices:
925 		charptr = &options->kbd_interactive_devices;
926 		goto parse_string;
927 
928 	case oPubkeyAuthentication:
929 		intptr = &options->pubkey_authentication;
930 		goto parse_flag;
931 
932 	case oRSAAuthentication:
933 		intptr = &options->rsa_authentication;
934 		goto parse_flag;
935 
936 	case oRhostsRSAAuthentication:
937 		intptr = &options->rhosts_rsa_authentication;
938 		goto parse_flag;
939 
940 	case oHostbasedAuthentication:
941 		intptr = &options->hostbased_authentication;
942 		goto parse_flag;
943 
944 	case oChallengeResponseAuthentication:
945 		intptr = &options->challenge_response_authentication;
946 		goto parse_flag;
947 
948 	case oGssAuthentication:
949 		intptr = &options->gss_authentication;
950 		goto parse_flag;
951 
952 	case oGssDelegateCreds:
953 		intptr = &options->gss_deleg_creds;
954 		goto parse_flag;
955 
956 	case oBatchMode:
957 		intptr = &options->batch_mode;
958 		goto parse_flag;
959 
960 	case oCheckHostIP:
961 		intptr = &options->check_host_ip;
962 		goto parse_flag;
963 
964 	case oVerifyHostKeyDNS:
965 		intptr = &options->verify_host_key_dns;
966 		multistate_ptr = multistate_yesnoask;
967 		goto parse_multistate;
968 
969 	case oStrictHostKeyChecking:
970 		intptr = &options->strict_host_key_checking;
971 		multistate_ptr = multistate_yesnoask;
972 		goto parse_multistate;
973 
974 	case oCompression:
975 		intptr = &options->compression;
976 		goto parse_flag;
977 
978 	case oTCPKeepAlive:
979 		intptr = &options->tcp_keep_alive;
980 		goto parse_flag;
981 
982 	case oNoHostAuthenticationForLocalhost:
983 		intptr = &options->no_host_authentication_for_localhost;
984 		goto parse_flag;
985 
986 	case oNumberOfPasswordPrompts:
987 		intptr = &options->number_of_password_prompts;
988 		goto parse_int;
989 
990 	case oCompressionLevel:
991 		intptr = &options->compression_level;
992 		goto parse_int;
993 
994 	case oRekeyLimit:
995 		arg = strdelim(&s);
996 		if (!arg || *arg == '\0')
997 			fatal("%.200s line %d: Missing argument.", filename,
998 			    linenum);
999 		if (strcmp(arg, "default") == 0) {
1000 			val64 = 0;
1001 		} else {
1002 			if (scan_scaled(arg, &val64) == -1)
1003 				fatal("%.200s line %d: Bad number '%s': %s",
1004 				    filename, linenum, arg, strerror(errno));
1005 			if (val64 != 0 && val64 < 16)
1006 				fatal("%.200s line %d: RekeyLimit too small",
1007 				    filename, linenum);
1008 		}
1009 		if (*activep && options->rekey_limit == -1)
1010 			options->rekey_limit = val64;
1011 		if (s != NULL) { /* optional rekey interval present */
1012 			if (strcmp(s, "none") == 0) {
1013 				(void)strdelim(&s);	/* discard */
1014 				break;
1015 			}
1016 			intptr = &options->rekey_interval;
1017 			goto parse_time;
1018 		}
1019 		break;
1020 
1021 	case oIdentityFile:
1022 		arg = strdelim(&s);
1023 		if (!arg || *arg == '\0')
1024 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1025 		if (*activep) {
1026 			intptr = &options->num_identity_files;
1027 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
1028 				fatal("%.200s line %d: Too many identity files specified (max %d).",
1029 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
1030 			add_identity_file(options, NULL,
1031 			    arg, flags & SSHCONF_USERCONF);
1032 		}
1033 		break;
1034 
1035 	case oCertificateFile:
1036 		arg = strdelim(&s);
1037 		if (!arg || *arg == '\0')
1038 			fatal("%.200s line %d: Missing argument.",
1039 			    filename, linenum);
1040 		if (*activep) {
1041 			intptr = &options->num_certificate_files;
1042 			if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1043 				fatal("%.200s line %d: Too many certificate "
1044 				    "files specified (max %d).",
1045 				    filename, linenum,
1046 				    SSH_MAX_CERTIFICATE_FILES);
1047 			}
1048 			add_certificate_file(options, arg,
1049 			    flags & SSHCONF_USERCONF);
1050 		}
1051 		break;
1052 
1053 	case oXAuthLocation:
1054 		charptr=&options->xauth_location;
1055 		goto parse_string;
1056 
1057 	case oUser:
1058 		charptr = &options->user;
1059 parse_string:
1060 		arg = strdelim(&s);
1061 		if (!arg || *arg == '\0')
1062 			fatal("%.200s line %d: Missing argument.",
1063 			    filename, linenum);
1064 		if (*activep && *charptr == NULL)
1065 			*charptr = xstrdup(arg);
1066 		break;
1067 
1068 	case oGlobalKnownHostsFile:
1069 		cpptr = (char **)&options->system_hostfiles;
1070 		uintptr = &options->num_system_hostfiles;
1071 		max_entries = SSH_MAX_HOSTS_FILES;
1072 parse_char_array:
1073 		if (*activep && *uintptr == 0) {
1074 			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1075 				if ((*uintptr) >= max_entries)
1076 					fatal("%s line %d: "
1077 					    "too many authorized keys files.",
1078 					    filename, linenum);
1079 				cpptr[(*uintptr)++] = xstrdup(arg);
1080 			}
1081 		}
1082 		return 0;
1083 
1084 	case oUserKnownHostsFile:
1085 		cpptr = (char **)&options->user_hostfiles;
1086 		uintptr = &options->num_user_hostfiles;
1087 		max_entries = SSH_MAX_HOSTS_FILES;
1088 		goto parse_char_array;
1089 
1090 	case oHostName:
1091 		charptr = &options->hostname;
1092 		goto parse_string;
1093 
1094 	case oHostKeyAlias:
1095 		charptr = &options->host_key_alias;
1096 		goto parse_string;
1097 
1098 	case oPreferredAuthentications:
1099 		charptr = &options->preferred_authentications;
1100 		goto parse_string;
1101 
1102 	case oBindAddress:
1103 		charptr = &options->bind_address;
1104 		goto parse_string;
1105 
1106 	case oPKCS11Provider:
1107 		charptr = &options->pkcs11_provider;
1108 		goto parse_string;
1109 
1110 	case oProxyCommand:
1111 		charptr = &options->proxy_command;
1112 parse_command:
1113 		if (s == NULL)
1114 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1115 		len = strspn(s, WHITESPACE "=");
1116 		if (*activep && *charptr == NULL)
1117 			*charptr = xstrdup(s + len);
1118 		return 0;
1119 
1120 	case oPort:
1121 		intptr = &options->port;
1122 parse_int:
1123 		arg = strdelim(&s);
1124 		if (!arg || *arg == '\0')
1125 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1126 		if (arg[0] < '0' || arg[0] > '9')
1127 			fatal("%.200s line %d: Bad number.", filename, linenum);
1128 
1129 		/* Octal, decimal, or hex format? */
1130 		value = strtol(arg, &endofnumber, 0);
1131 		if (arg == endofnumber)
1132 			fatal("%.200s line %d: Bad number.", filename, linenum);
1133 		if (*activep && *intptr == -1)
1134 			*intptr = value;
1135 		break;
1136 
1137 	case oConnectionAttempts:
1138 		intptr = &options->connection_attempts;
1139 		goto parse_int;
1140 
1141 	case oCipher:
1142 		intptr = &options->cipher;
1143 		arg = strdelim(&s);
1144 		if (!arg || *arg == '\0')
1145 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1146 		value = cipher_number(arg);
1147 		if (value == -1)
1148 			fatal("%.200s line %d: Bad cipher '%s'.",
1149 			    filename, linenum, arg ? arg : "<NONE>");
1150 		if (*activep && *intptr == -1)
1151 			*intptr = value;
1152 		break;
1153 
1154 	case oCiphers:
1155 		arg = strdelim(&s);
1156 		if (!arg || *arg == '\0')
1157 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1158 		if (!ciphers_valid(*arg == '+' ? arg + 1 : arg))
1159 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1160 			    filename, linenum, arg ? arg : "<NONE>");
1161 		if (*activep && options->ciphers == NULL)
1162 			options->ciphers = xstrdup(arg);
1163 		break;
1164 
1165 	case oMacs:
1166 		arg = strdelim(&s);
1167 		if (!arg || *arg == '\0')
1168 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1169 		if (!mac_valid(*arg == '+' ? arg + 1 : arg))
1170 			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1171 			    filename, linenum, arg ? arg : "<NONE>");
1172 		if (*activep && options->macs == NULL)
1173 			options->macs = xstrdup(arg);
1174 		break;
1175 
1176 	case oKexAlgorithms:
1177 		arg = strdelim(&s);
1178 		if (!arg || *arg == '\0')
1179 			fatal("%.200s line %d: Missing argument.",
1180 			    filename, linenum);
1181 		if (!kex_names_valid(*arg == '+' ? arg + 1 : arg))
1182 			fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1183 			    filename, linenum, arg ? arg : "<NONE>");
1184 		if (*activep && options->kex_algorithms == NULL)
1185 			options->kex_algorithms = xstrdup(arg);
1186 		break;
1187 
1188 	case oHostKeyAlgorithms:
1189 		charptr = &options->hostkeyalgorithms;
1190 parse_keytypes:
1191 		arg = strdelim(&s);
1192 		if (!arg || *arg == '\0')
1193 			fatal("%.200s line %d: Missing argument.",
1194 			    filename, linenum);
1195 		if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1196 			fatal("%s line %d: Bad key types '%s'.",
1197 				filename, linenum, arg ? arg : "<NONE>");
1198 		if (*activep && *charptr == NULL)
1199 			*charptr = xstrdup(arg);
1200 		break;
1201 
1202 	case oProtocol:
1203 		intptr = &options->protocol;
1204 		arg = strdelim(&s);
1205 		if (!arg || *arg == '\0')
1206 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1207 		value = proto_spec(arg);
1208 		if (value == SSH_PROTO_UNKNOWN)
1209 			fatal("%.200s line %d: Bad protocol spec '%s'.",
1210 			    filename, linenum, arg ? arg : "<NONE>");
1211 		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1212 			*intptr = value;
1213 		break;
1214 
1215 	case oLogLevel:
1216 		log_level_ptr = &options->log_level;
1217 		arg = strdelim(&s);
1218 		value = log_level_number(arg);
1219 		if (value == SYSLOG_LEVEL_NOT_SET)
1220 			fatal("%.200s line %d: unsupported log level '%s'",
1221 			    filename, linenum, arg ? arg : "<NONE>");
1222 		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1223 			*log_level_ptr = (LogLevel) value;
1224 		break;
1225 
1226 	case oLocalForward:
1227 	case oRemoteForward:
1228 	case oDynamicForward:
1229 		arg = strdelim(&s);
1230 		if (arg == NULL || *arg == '\0')
1231 			fatal("%.200s line %d: Missing port argument.",
1232 			    filename, linenum);
1233 
1234 		if (opcode == oLocalForward ||
1235 		    opcode == oRemoteForward) {
1236 			arg2 = strdelim(&s);
1237 			if (arg2 == NULL || *arg2 == '\0')
1238 				fatal("%.200s line %d: Missing target argument.",
1239 				    filename, linenum);
1240 
1241 			/* construct a string for parse_forward */
1242 			snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1243 		} else if (opcode == oDynamicForward) {
1244 			strlcpy(fwdarg, arg, sizeof(fwdarg));
1245 		}
1246 
1247 		if (parse_forward(&fwd, fwdarg,
1248 		    opcode == oDynamicForward ? 1 : 0,
1249 		    opcode == oRemoteForward ? 1 : 0) == 0)
1250 			fatal("%.200s line %d: Bad forwarding specification.",
1251 			    filename, linenum);
1252 
1253 		if (*activep) {
1254 			if (opcode == oLocalForward ||
1255 			    opcode == oDynamicForward)
1256 				add_local_forward(options, &fwd);
1257 			else if (opcode == oRemoteForward)
1258 				add_remote_forward(options, &fwd);
1259 		}
1260 		break;
1261 
1262 	case oClearAllForwardings:
1263 		intptr = &options->clear_forwardings;
1264 		goto parse_flag;
1265 
1266 	case oHost:
1267 		if (cmdline)
1268 			fatal("Host directive not supported as a command-line "
1269 			    "option");
1270 		*activep = 0;
1271 		arg2 = NULL;
1272 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1273 			negated = *arg == '!';
1274 			if (negated)
1275 				arg++;
1276 			if (match_pattern(host, arg)) {
1277 				if (negated) {
1278 					debug("%.200s line %d: Skipping Host "
1279 					    "block because of negated match "
1280 					    "for %.100s", filename, linenum,
1281 					    arg);
1282 					*activep = 0;
1283 					break;
1284 				}
1285 				if (!*activep)
1286 					arg2 = arg; /* logged below */
1287 				*activep = 1;
1288 			}
1289 		}
1290 		if (*activep)
1291 			debug("%.200s line %d: Applying options for %.100s",
1292 			    filename, linenum, arg2);
1293 		/* Avoid garbage check below, as strdelim is done. */
1294 		return 0;
1295 
1296 	case oMatch:
1297 		if (cmdline)
1298 			fatal("Host directive not supported as a command-line "
1299 			    "option");
1300 		value = match_cfg_line(options, &s, pw, host, original_host,
1301 		    flags & SSHCONF_POSTCANON, filename, linenum);
1302 		if (value < 0)
1303 			fatal("%.200s line %d: Bad Match condition", filename,
1304 			    linenum);
1305 		*activep = value;
1306 		break;
1307 
1308 	case oEscapeChar:
1309 		intptr = &options->escape_char;
1310 		arg = strdelim(&s);
1311 		if (!arg || *arg == '\0')
1312 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1313 		if (strcmp(arg, "none") == 0)
1314 			value = SSH_ESCAPECHAR_NONE;
1315 		else if (arg[1] == '\0')
1316 			value = (u_char) arg[0];
1317 		else if (arg[0] == '^' && arg[2] == 0 &&
1318 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1319 			value = (u_char) arg[1] & 31;
1320 		else {
1321 			fatal("%.200s line %d: Bad escape character.",
1322 			    filename, linenum);
1323 			/* NOTREACHED */
1324 			value = 0;	/* Avoid compiler warning. */
1325 		}
1326 		if (*activep && *intptr == -1)
1327 			*intptr = value;
1328 		break;
1329 
1330 	case oAddressFamily:
1331 		intptr = &options->address_family;
1332 		multistate_ptr = multistate_addressfamily;
1333 		goto parse_multistate;
1334 
1335 	case oEnableSSHKeysign:
1336 		intptr = &options->enable_ssh_keysign;
1337 		goto parse_flag;
1338 
1339 	case oIdentitiesOnly:
1340 		intptr = &options->identities_only;
1341 		goto parse_flag;
1342 
1343 	case oServerAliveInterval:
1344 		intptr = &options->server_alive_interval;
1345 		goto parse_time;
1346 
1347 	case oServerAliveCountMax:
1348 		intptr = &options->server_alive_count_max;
1349 		goto parse_int;
1350 
1351 	case oSendEnv:
1352 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1353 			if (strchr(arg, '=') != NULL)
1354 				fatal("%s line %d: Invalid environment name.",
1355 				    filename, linenum);
1356 			if (!*activep)
1357 				continue;
1358 			if (options->num_send_env >= MAX_SEND_ENV)
1359 				fatal("%s line %d: too many send env.",
1360 				    filename, linenum);
1361 			options->send_env[options->num_send_env++] =
1362 			    xstrdup(arg);
1363 		}
1364 		break;
1365 
1366 	case oControlPath:
1367 		charptr = &options->control_path;
1368 		goto parse_string;
1369 
1370 	case oControlMaster:
1371 		intptr = &options->control_master;
1372 		multistate_ptr = multistate_controlmaster;
1373 		goto parse_multistate;
1374 
1375 	case oControlPersist:
1376 		/* no/false/yes/true, or a time spec */
1377 		intptr = &options->control_persist;
1378 		arg = strdelim(&s);
1379 		if (!arg || *arg == '\0')
1380 			fatal("%.200s line %d: Missing ControlPersist"
1381 			    " argument.", filename, linenum);
1382 		value = 0;
1383 		value2 = 0;	/* timeout */
1384 		if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1385 			value = 0;
1386 		else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1387 			value = 1;
1388 		else if ((value2 = convtime(arg)) >= 0)
1389 			value = 1;
1390 		else
1391 			fatal("%.200s line %d: Bad ControlPersist argument.",
1392 			    filename, linenum);
1393 		if (*activep && *intptr == -1) {
1394 			*intptr = value;
1395 			options->control_persist_timeout = value2;
1396 		}
1397 		break;
1398 
1399 	case oHashKnownHosts:
1400 		intptr = &options->hash_known_hosts;
1401 		goto parse_flag;
1402 
1403 	case oTunnel:
1404 		intptr = &options->tun_open;
1405 		multistate_ptr = multistate_tunnel;
1406 		goto parse_multistate;
1407 
1408 	case oTunnelDevice:
1409 		arg = strdelim(&s);
1410 		if (!arg || *arg == '\0')
1411 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1412 		value = a2tun(arg, &value2);
1413 		if (value == SSH_TUNID_ERR)
1414 			fatal("%.200s line %d: Bad tun device.", filename, linenum);
1415 		if (*activep) {
1416 			options->tun_local = value;
1417 			options->tun_remote = value2;
1418 		}
1419 		break;
1420 
1421 	case oLocalCommand:
1422 		charptr = &options->local_command;
1423 		goto parse_command;
1424 
1425 	case oPermitLocalCommand:
1426 		intptr = &options->permit_local_command;
1427 		goto parse_flag;
1428 
1429 	case oVisualHostKey:
1430 		intptr = &options->visual_host_key;
1431 		goto parse_flag;
1432 
1433 	case oIPQoS:
1434 		arg = strdelim(&s);
1435 		if ((value = parse_ipqos(arg)) == -1)
1436 			fatal("%s line %d: Bad IPQoS value: %s",
1437 			    filename, linenum, arg);
1438 		arg = strdelim(&s);
1439 		if (arg == NULL)
1440 			value2 = value;
1441 		else if ((value2 = parse_ipqos(arg)) == -1)
1442 			fatal("%s line %d: Bad IPQoS value: %s",
1443 			    filename, linenum, arg);
1444 		if (*activep) {
1445 			options->ip_qos_interactive = value;
1446 			options->ip_qos_bulk = value2;
1447 		}
1448 		break;
1449 
1450 	case oRequestTTY:
1451 		intptr = &options->request_tty;
1452 		multistate_ptr = multistate_requesttty;
1453 		goto parse_multistate;
1454 
1455 	case oVersionAddendum:
1456 		if (s == NULL)
1457 			fatal("%.200s line %d: Missing argument.", filename,
1458 			    linenum);
1459 		len = strspn(s, WHITESPACE);
1460 		if (*activep && options->version_addendum == NULL) {
1461 			if (strcasecmp(s + len, "none") == 0)
1462 				options->version_addendum = xstrdup("");
1463 			else if (strchr(s + len, '\r') != NULL)
1464 				fatal("%.200s line %d: Invalid argument",
1465 				    filename, linenum);
1466 			else
1467 				options->version_addendum = xstrdup(s + len);
1468 		}
1469 		return 0;
1470 
1471 	case oIgnoreUnknown:
1472 		charptr = &options->ignored_unknown;
1473 		goto parse_string;
1474 
1475 	case oProxyUseFdpass:
1476 		intptr = &options->proxy_use_fdpass;
1477 		goto parse_flag;
1478 
1479 	case oCanonicalDomains:
1480 		value = options->num_canonical_domains != 0;
1481 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1482 			valid_domain(arg, filename, linenum);
1483 			if (!*activep || value)
1484 				continue;
1485 			if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1486 				fatal("%s line %d: too many hostname suffixes.",
1487 				    filename, linenum);
1488 			options->canonical_domains[
1489 			    options->num_canonical_domains++] = xstrdup(arg);
1490 		}
1491 		break;
1492 
1493 	case oCanonicalizePermittedCNAMEs:
1494 		value = options->num_permitted_cnames != 0;
1495 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1496 			/* Either '*' for everything or 'list:list' */
1497 			if (strcmp(arg, "*") == 0)
1498 				arg2 = arg;
1499 			else {
1500 				lowercase(arg);
1501 				if ((arg2 = strchr(arg, ':')) == NULL ||
1502 				    arg2[1] == '\0') {
1503 					fatal("%s line %d: "
1504 					    "Invalid permitted CNAME \"%s\"",
1505 					    filename, linenum, arg);
1506 				}
1507 				*arg2 = '\0';
1508 				arg2++;
1509 			}
1510 			if (!*activep || value)
1511 				continue;
1512 			if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1513 				fatal("%s line %d: too many permitted CNAMEs.",
1514 				    filename, linenum);
1515 			cname = options->permitted_cnames +
1516 			    options->num_permitted_cnames++;
1517 			cname->source_list = xstrdup(arg);
1518 			cname->target_list = xstrdup(arg2);
1519 		}
1520 		break;
1521 
1522 	case oCanonicalizeHostname:
1523 		intptr = &options->canonicalize_hostname;
1524 		multistate_ptr = multistate_canonicalizehostname;
1525 		goto parse_multistate;
1526 
1527 	case oCanonicalizeMaxDots:
1528 		intptr = &options->canonicalize_max_dots;
1529 		goto parse_int;
1530 
1531 	case oCanonicalizeFallbackLocal:
1532 		intptr = &options->canonicalize_fallback_local;
1533 		goto parse_flag;
1534 
1535 	case oStreamLocalBindMask:
1536 		arg = strdelim(&s);
1537 		if (!arg || *arg == '\0')
1538 			fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1539 		/* Parse mode in octal format */
1540 		value = strtol(arg, &endofnumber, 8);
1541 		if (arg == endofnumber || value < 0 || value > 0777)
1542 			fatal("%.200s line %d: Bad mask.", filename, linenum);
1543 		options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1544 		break;
1545 
1546 	case oStreamLocalBindUnlink:
1547 		intptr = &options->fwd_opts.streamlocal_bind_unlink;
1548 		goto parse_flag;
1549 
1550 	case oRevokedHostKeys:
1551 		charptr = &options->revoked_host_keys;
1552 		goto parse_string;
1553 
1554 	case oFingerprintHash:
1555 		intptr = &options->fingerprint_hash;
1556 		arg = strdelim(&s);
1557 		if (!arg || *arg == '\0')
1558 			fatal("%.200s line %d: Missing argument.",
1559 			    filename, linenum);
1560 		if ((value = ssh_digest_alg_by_name(arg)) == -1)
1561 			fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1562 			    filename, linenum, arg);
1563 		if (*activep && *intptr == -1)
1564 			*intptr = value;
1565 		break;
1566 
1567 	case oUpdateHostkeys:
1568 		intptr = &options->update_hostkeys;
1569 		multistate_ptr = multistate_yesnoask;
1570 		goto parse_multistate;
1571 
1572 	case oHostbasedKeyTypes:
1573 		charptr = &options->hostbased_key_types;
1574 		goto parse_keytypes;
1575 
1576 	case oPubkeyAcceptedKeyTypes:
1577 		charptr = &options->pubkey_key_types;
1578 		goto parse_keytypes;
1579 
1580 	case oAddKeysToAgent:
1581 		intptr = &options->add_keys_to_agent;
1582 		multistate_ptr = multistate_yesnoaskconfirm;
1583 		goto parse_multistate;
1584 
1585 	case oDeprecated:
1586 		debug("%s line %d: Deprecated option \"%s\"",
1587 		    filename, linenum, keyword);
1588 		return 0;
1589 
1590 	case oUnsupported:
1591 		error("%s line %d: Unsupported option \"%s\"",
1592 		    filename, linenum, keyword);
1593 		return 0;
1594 
1595 	default:
1596 		fatal("%s: Unimplemented opcode %d", __func__, opcode);
1597 	}
1598 
1599 	/* Check that there is no garbage at end of line. */
1600 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1601 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1602 		    filename, linenum, arg);
1603 	}
1604 	return 0;
1605 }
1606 
1607 
1608 /*
1609  * Reads the config file and modifies the options accordingly.  Options
1610  * should already be initialized before this call.  This never returns if
1611  * there is an error.  If the file does not exist, this returns 0.
1612  */
1613 
1614 int
1615 read_config_file(const char *filename, struct passwd *pw, const char *host,
1616     const char *original_host, Options *options, int flags)
1617 {
1618 	FILE *f;
1619 	char line[1024];
1620 	int active, linenum;
1621 	int bad_options = 0;
1622 
1623 	if ((f = fopen(filename, "r")) == NULL)
1624 		return 0;
1625 
1626 	if (flags & SSHCONF_CHECKPERM) {
1627 		struct stat sb;
1628 
1629 		if (fstat(fileno(f), &sb) == -1)
1630 			fatal("fstat %s: %s", filename, strerror(errno));
1631 		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1632 		    (sb.st_mode & 022) != 0))
1633 			fatal("Bad owner or permissions on %s", filename);
1634 	}
1635 
1636 	debug("Reading configuration data %.200s", filename);
1637 
1638 	/*
1639 	 * Mark that we are now processing the options.  This flag is turned
1640 	 * on/off by Host specifications.
1641 	 */
1642 	active = 1;
1643 	linenum = 0;
1644 	while (fgets(line, sizeof(line), f)) {
1645 		/* Update line number counter. */
1646 		linenum++;
1647 		if (process_config_line(options, pw, host, original_host,
1648 		    line, filename, linenum, &active, flags) != 0)
1649 			bad_options++;
1650 	}
1651 	fclose(f);
1652 	if (bad_options > 0)
1653 		fatal("%s: terminating, %d bad configuration options",
1654 		    filename, bad_options);
1655 	return 1;
1656 }
1657 
1658 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1659 int
1660 option_clear_or_none(const char *o)
1661 {
1662 	return o == NULL || strcasecmp(o, "none") == 0;
1663 }
1664 
1665 /*
1666  * Initializes options to special values that indicate that they have not yet
1667  * been set.  Read_config_file will only set options with this value. Options
1668  * are processed in the following order: command line, user config file,
1669  * system config file.  Last, fill_default_options is called.
1670  */
1671 
1672 void
1673 initialize_options(Options * options)
1674 {
1675 	memset(options, 'X', sizeof(*options));
1676 	options->version_addendum = NULL;
1677 	options->forward_agent = -1;
1678 	options->forward_x11 = -1;
1679 	options->forward_x11_trusted = -1;
1680 	options->forward_x11_timeout = -1;
1681 	options->exit_on_forward_failure = -1;
1682 	options->xauth_location = NULL;
1683 	options->fwd_opts.gateway_ports = -1;
1684 	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1685 	options->fwd_opts.streamlocal_bind_unlink = -1;
1686 	options->use_privileged_port = -1;
1687 	options->rsa_authentication = -1;
1688 	options->pubkey_authentication = -1;
1689 	options->challenge_response_authentication = -1;
1690 	options->gss_authentication = -1;
1691 	options->gss_deleg_creds = -1;
1692 	options->password_authentication = -1;
1693 	options->kbd_interactive_authentication = -1;
1694 	options->kbd_interactive_devices = NULL;
1695 	options->rhosts_rsa_authentication = -1;
1696 	options->hostbased_authentication = -1;
1697 	options->batch_mode = -1;
1698 	options->check_host_ip = -1;
1699 	options->strict_host_key_checking = -1;
1700 	options->compression = -1;
1701 	options->tcp_keep_alive = -1;
1702 	options->compression_level = -1;
1703 	options->port = -1;
1704 	options->address_family = -1;
1705 	options->connection_attempts = -1;
1706 	options->connection_timeout = -1;
1707 	options->number_of_password_prompts = -1;
1708 	options->cipher = -1;
1709 	options->ciphers = NULL;
1710 	options->macs = NULL;
1711 	options->kex_algorithms = NULL;
1712 	options->hostkeyalgorithms = NULL;
1713 	options->protocol = SSH_PROTO_UNKNOWN;
1714 	options->num_identity_files = 0;
1715 	options->num_certificate_files = 0;
1716 	options->hostname = NULL;
1717 	options->host_key_alias = NULL;
1718 	options->proxy_command = NULL;
1719 	options->user = NULL;
1720 	options->escape_char = -1;
1721 	options->num_system_hostfiles = 0;
1722 	options->num_user_hostfiles = 0;
1723 	options->local_forwards = NULL;
1724 	options->num_local_forwards = 0;
1725 	options->remote_forwards = NULL;
1726 	options->num_remote_forwards = 0;
1727 	options->clear_forwardings = -1;
1728 	options->log_level = SYSLOG_LEVEL_NOT_SET;
1729 	options->preferred_authentications = NULL;
1730 	options->bind_address = NULL;
1731 	options->pkcs11_provider = NULL;
1732 	options->enable_ssh_keysign = - 1;
1733 	options->no_host_authentication_for_localhost = - 1;
1734 	options->identities_only = - 1;
1735 	options->rekey_limit = - 1;
1736 	options->rekey_interval = -1;
1737 	options->verify_host_key_dns = -1;
1738 	options->server_alive_interval = -1;
1739 	options->server_alive_count_max = -1;
1740 	options->num_send_env = 0;
1741 	options->control_path = NULL;
1742 	options->control_master = -1;
1743 	options->control_persist = -1;
1744 	options->control_persist_timeout = 0;
1745 	options->hash_known_hosts = -1;
1746 	options->tun_open = -1;
1747 	options->tun_local = -1;
1748 	options->tun_remote = -1;
1749 	options->local_command = NULL;
1750 	options->permit_local_command = -1;
1751 	options->add_keys_to_agent = -1;
1752 	options->visual_host_key = -1;
1753 	options->ip_qos_interactive = -1;
1754 	options->ip_qos_bulk = -1;
1755 	options->request_tty = -1;
1756 	options->proxy_use_fdpass = -1;
1757 	options->ignored_unknown = NULL;
1758 	options->num_canonical_domains = 0;
1759 	options->num_permitted_cnames = 0;
1760 	options->canonicalize_max_dots = -1;
1761 	options->canonicalize_fallback_local = -1;
1762 	options->canonicalize_hostname = -1;
1763 	options->revoked_host_keys = NULL;
1764 	options->fingerprint_hash = -1;
1765 	options->update_hostkeys = -1;
1766 	options->hostbased_key_types = NULL;
1767 	options->pubkey_key_types = NULL;
1768 }
1769 
1770 /*
1771  * A petite version of fill_default_options() that just fills the options
1772  * needed for hostname canonicalization to proceed.
1773  */
1774 void
1775 fill_default_options_for_canonicalization(Options *options)
1776 {
1777 	if (options->canonicalize_max_dots == -1)
1778 		options->canonicalize_max_dots = 1;
1779 	if (options->canonicalize_fallback_local == -1)
1780 		options->canonicalize_fallback_local = 1;
1781 	if (options->canonicalize_hostname == -1)
1782 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
1783 }
1784 
1785 /*
1786  * Called after processing other sources of option data, this fills those
1787  * options for which no value has been specified with their default values.
1788  */
1789 void
1790 fill_default_options(Options * options)
1791 {
1792 	if (options->forward_agent == -1)
1793 		options->forward_agent = 0;
1794 	if (options->forward_x11 == -1)
1795 		options->forward_x11 = 0;
1796 	if (options->forward_x11_trusted == -1)
1797 		options->forward_x11_trusted = 0;
1798 	if (options->forward_x11_timeout == -1)
1799 		options->forward_x11_timeout = 1200;
1800 	if (options->exit_on_forward_failure == -1)
1801 		options->exit_on_forward_failure = 0;
1802 	if (options->xauth_location == NULL)
1803 		options->xauth_location = _PATH_XAUTH;
1804 	if (options->fwd_opts.gateway_ports == -1)
1805 		options->fwd_opts.gateway_ports = 0;
1806 	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1807 		options->fwd_opts.streamlocal_bind_mask = 0177;
1808 	if (options->fwd_opts.streamlocal_bind_unlink == -1)
1809 		options->fwd_opts.streamlocal_bind_unlink = 0;
1810 	if (options->use_privileged_port == -1)
1811 		options->use_privileged_port = 0;
1812 	if (options->rsa_authentication == -1)
1813 		options->rsa_authentication = 1;
1814 	if (options->pubkey_authentication == -1)
1815 		options->pubkey_authentication = 1;
1816 	if (options->challenge_response_authentication == -1)
1817 		options->challenge_response_authentication = 1;
1818 	if (options->gss_authentication == -1)
1819 		options->gss_authentication = 0;
1820 	if (options->gss_deleg_creds == -1)
1821 		options->gss_deleg_creds = 0;
1822 	if (options->password_authentication == -1)
1823 		options->password_authentication = 1;
1824 	if (options->kbd_interactive_authentication == -1)
1825 		options->kbd_interactive_authentication = 1;
1826 	if (options->rhosts_rsa_authentication == -1)
1827 		options->rhosts_rsa_authentication = 0;
1828 	if (options->hostbased_authentication == -1)
1829 		options->hostbased_authentication = 0;
1830 	if (options->batch_mode == -1)
1831 		options->batch_mode = 0;
1832 	if (options->check_host_ip == -1)
1833 		options->check_host_ip = 0;
1834 	if (options->strict_host_key_checking == -1)
1835 		options->strict_host_key_checking = 2;	/* 2 is default */
1836 	if (options->compression == -1)
1837 		options->compression = 0;
1838 	if (options->tcp_keep_alive == -1)
1839 		options->tcp_keep_alive = 1;
1840 	if (options->compression_level == -1)
1841 		options->compression_level = 6;
1842 	if (options->port == -1)
1843 		options->port = 0;	/* Filled in ssh_connect. */
1844 	if (options->address_family == -1)
1845 		options->address_family = AF_UNSPEC;
1846 	if (options->connection_attempts == -1)
1847 		options->connection_attempts = 1;
1848 	if (options->number_of_password_prompts == -1)
1849 		options->number_of_password_prompts = 3;
1850 	/* Selected in ssh_login(). */
1851 	if (options->cipher == -1)
1852 		options->cipher = SSH_CIPHER_NOT_SET;
1853 	/* options->hostkeyalgorithms, default set in myproposals.h */
1854 	if (options->protocol == SSH_PROTO_UNKNOWN)
1855 		options->protocol = SSH_PROTO_2;
1856 	if (options->add_keys_to_agent == -1)
1857 		options->add_keys_to_agent = 0;
1858 	if (options->num_identity_files == 0) {
1859 		if (options->protocol & SSH_PROTO_1) {
1860 			add_identity_file(options, "~/",
1861 			    _PATH_SSH_CLIENT_IDENTITY, 0);
1862 		}
1863 		if (options->protocol & SSH_PROTO_2) {
1864 			add_identity_file(options, "~/",
1865 			    _PATH_SSH_CLIENT_ID_RSA, 0);
1866 			add_identity_file(options, "~/",
1867 			    _PATH_SSH_CLIENT_ID_DSA, 0);
1868 #ifdef OPENSSL_HAS_ECC
1869 			add_identity_file(options, "~/",
1870 			    _PATH_SSH_CLIENT_ID_ECDSA, 0);
1871 #endif
1872 			add_identity_file(options, "~/",
1873 			    _PATH_SSH_CLIENT_ID_ED25519, 0);
1874 		}
1875 	}
1876 	if (options->escape_char == -1)
1877 		options->escape_char = '~';
1878 	if (options->num_system_hostfiles == 0) {
1879 		options->system_hostfiles[options->num_system_hostfiles++] =
1880 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1881 		options->system_hostfiles[options->num_system_hostfiles++] =
1882 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1883 	}
1884 	if (options->num_user_hostfiles == 0) {
1885 		options->user_hostfiles[options->num_user_hostfiles++] =
1886 		    xstrdup(_PATH_SSH_USER_HOSTFILE);
1887 		options->user_hostfiles[options->num_user_hostfiles++] =
1888 		    xstrdup(_PATH_SSH_USER_HOSTFILE2);
1889 	}
1890 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1891 		options->log_level = SYSLOG_LEVEL_INFO;
1892 	if (options->clear_forwardings == 1)
1893 		clear_forwardings(options);
1894 	if (options->no_host_authentication_for_localhost == - 1)
1895 		options->no_host_authentication_for_localhost = 0;
1896 	if (options->identities_only == -1)
1897 		options->identities_only = 0;
1898 	if (options->enable_ssh_keysign == -1)
1899 		options->enable_ssh_keysign = 0;
1900 	if (options->rekey_limit == -1)
1901 		options->rekey_limit = 0;
1902 	if (options->rekey_interval == -1)
1903 		options->rekey_interval = 0;
1904 #if HAVE_LDNS
1905 	if (options->verify_host_key_dns == -1)
1906 		/* automatically trust a verified SSHFP record */
1907 		options->verify_host_key_dns = 1;
1908 #else
1909 	if (options->verify_host_key_dns == -1)
1910 		options->verify_host_key_dns = 0;
1911 #endif
1912 	if (options->server_alive_interval == -1)
1913 		options->server_alive_interval = 0;
1914 	if (options->server_alive_count_max == -1)
1915 		options->server_alive_count_max = 3;
1916 	if (options->control_master == -1)
1917 		options->control_master = 0;
1918 	if (options->control_persist == -1) {
1919 		options->control_persist = 0;
1920 		options->control_persist_timeout = 0;
1921 	}
1922 	if (options->hash_known_hosts == -1)
1923 		options->hash_known_hosts = 0;
1924 	if (options->tun_open == -1)
1925 		options->tun_open = SSH_TUNMODE_NO;
1926 	if (options->tun_local == -1)
1927 		options->tun_local = SSH_TUNID_ANY;
1928 	if (options->tun_remote == -1)
1929 		options->tun_remote = SSH_TUNID_ANY;
1930 	if (options->permit_local_command == -1)
1931 		options->permit_local_command = 0;
1932 	if (options->visual_host_key == -1)
1933 		options->visual_host_key = 0;
1934 	if (options->ip_qos_interactive == -1)
1935 		options->ip_qos_interactive = IPTOS_LOWDELAY;
1936 	if (options->ip_qos_bulk == -1)
1937 		options->ip_qos_bulk = IPTOS_THROUGHPUT;
1938 	if (options->request_tty == -1)
1939 		options->request_tty = REQUEST_TTY_AUTO;
1940 	if (options->proxy_use_fdpass == -1)
1941 		options->proxy_use_fdpass = 0;
1942 	if (options->canonicalize_max_dots == -1)
1943 		options->canonicalize_max_dots = 1;
1944 	if (options->canonicalize_fallback_local == -1)
1945 		options->canonicalize_fallback_local = 1;
1946 	if (options->canonicalize_hostname == -1)
1947 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
1948 	if (options->fingerprint_hash == -1)
1949 		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
1950 	if (options->update_hostkeys == -1)
1951 		options->update_hostkeys = 0;
1952 	if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
1953 	    kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
1954 	    kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
1955 	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
1956 	    &options->hostbased_key_types) != 0 ||
1957 	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
1958 	    &options->pubkey_key_types) != 0)
1959 		fatal("%s: kex_assemble_names failed", __func__);
1960 
1961 #define CLEAR_ON_NONE(v) \
1962 	do { \
1963 		if (option_clear_or_none(v)) { \
1964 			free(v); \
1965 			v = NULL; \
1966 		} \
1967 	} while(0)
1968 	CLEAR_ON_NONE(options->local_command);
1969 	CLEAR_ON_NONE(options->proxy_command);
1970 	CLEAR_ON_NONE(options->control_path);
1971 	CLEAR_ON_NONE(options->revoked_host_keys);
1972 	/* options->user will be set in the main program if appropriate */
1973 	/* options->hostname will be set in the main program if appropriate */
1974 	/* options->host_key_alias should not be set by default */
1975 	/* options->preferred_authentications will be set in ssh */
1976 	if (options->version_addendum == NULL)
1977 		options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
1978 }
1979 
1980 struct fwdarg {
1981 	char *arg;
1982 	int ispath;
1983 };
1984 
1985 /*
1986  * parse_fwd_field
1987  * parses the next field in a port forwarding specification.
1988  * sets fwd to the parsed field and advances p past the colon
1989  * or sets it to NULL at end of string.
1990  * returns 0 on success, else non-zero.
1991  */
1992 static int
1993 parse_fwd_field(char **p, struct fwdarg *fwd)
1994 {
1995 	char *ep, *cp = *p;
1996 	int ispath = 0;
1997 
1998 	if (*cp == '\0') {
1999 		*p = NULL;
2000 		return -1;	/* end of string */
2001 	}
2002 
2003 	/*
2004 	 * A field escaped with square brackets is used literally.
2005 	 * XXX - allow ']' to be escaped via backslash?
2006 	 */
2007 	if (*cp == '[') {
2008 		/* find matching ']' */
2009 		for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2010 			if (*ep == '/')
2011 				ispath = 1;
2012 		}
2013 		/* no matching ']' or not at end of field. */
2014 		if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2015 			return -1;
2016 		/* NUL terminate the field and advance p past the colon */
2017 		*ep++ = '\0';
2018 		if (*ep != '\0')
2019 			*ep++ = '\0';
2020 		fwd->arg = cp + 1;
2021 		fwd->ispath = ispath;
2022 		*p = ep;
2023 		return 0;
2024 	}
2025 
2026 	for (cp = *p; *cp != '\0'; cp++) {
2027 		switch (*cp) {
2028 		case '\\':
2029 			memmove(cp, cp + 1, strlen(cp + 1) + 1);
2030 			if (*cp == '\0')
2031 				return -1;
2032 			break;
2033 		case '/':
2034 			ispath = 1;
2035 			break;
2036 		case ':':
2037 			*cp++ = '\0';
2038 			goto done;
2039 		}
2040 	}
2041 done:
2042 	fwd->arg = *p;
2043 	fwd->ispath = ispath;
2044 	*p = cp;
2045 	return 0;
2046 }
2047 
2048 /*
2049  * parse_forward
2050  * parses a string containing a port forwarding specification of the form:
2051  *   dynamicfwd == 0
2052  *	[listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2053  *	listenpath:connectpath
2054  *   dynamicfwd == 1
2055  *	[listenhost:]listenport
2056  * returns number of arguments parsed or zero on error
2057  */
2058 int
2059 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2060 {
2061 	struct fwdarg fwdargs[4];
2062 	char *p, *cp;
2063 	int i;
2064 
2065 	memset(fwd, 0, sizeof(*fwd));
2066 	memset(fwdargs, 0, sizeof(fwdargs));
2067 
2068 	cp = p = xstrdup(fwdspec);
2069 
2070 	/* skip leading spaces */
2071 	while (isspace((u_char)*cp))
2072 		cp++;
2073 
2074 	for (i = 0; i < 4; ++i) {
2075 		if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2076 			break;
2077 	}
2078 
2079 	/* Check for trailing garbage */
2080 	if (cp != NULL && *cp != '\0') {
2081 		i = 0;	/* failure */
2082 	}
2083 
2084 	switch (i) {
2085 	case 1:
2086 		if (fwdargs[0].ispath) {
2087 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2088 			fwd->listen_port = PORT_STREAMLOCAL;
2089 		} else {
2090 			fwd->listen_host = NULL;
2091 			fwd->listen_port = a2port(fwdargs[0].arg);
2092 		}
2093 		fwd->connect_host = xstrdup("socks");
2094 		break;
2095 
2096 	case 2:
2097 		if (fwdargs[0].ispath && fwdargs[1].ispath) {
2098 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2099 			fwd->listen_port = PORT_STREAMLOCAL;
2100 			fwd->connect_path = xstrdup(fwdargs[1].arg);
2101 			fwd->connect_port = PORT_STREAMLOCAL;
2102 		} else if (fwdargs[1].ispath) {
2103 			fwd->listen_host = NULL;
2104 			fwd->listen_port = a2port(fwdargs[0].arg);
2105 			fwd->connect_path = xstrdup(fwdargs[1].arg);
2106 			fwd->connect_port = PORT_STREAMLOCAL;
2107 		} else {
2108 			fwd->listen_host = xstrdup(fwdargs[0].arg);
2109 			fwd->listen_port = a2port(fwdargs[1].arg);
2110 			fwd->connect_host = xstrdup("socks");
2111 		}
2112 		break;
2113 
2114 	case 3:
2115 		if (fwdargs[0].ispath) {
2116 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2117 			fwd->listen_port = PORT_STREAMLOCAL;
2118 			fwd->connect_host = xstrdup(fwdargs[1].arg);
2119 			fwd->connect_port = a2port(fwdargs[2].arg);
2120 		} else if (fwdargs[2].ispath) {
2121 			fwd->listen_host = xstrdup(fwdargs[0].arg);
2122 			fwd->listen_port = a2port(fwdargs[1].arg);
2123 			fwd->connect_path = xstrdup(fwdargs[2].arg);
2124 			fwd->connect_port = PORT_STREAMLOCAL;
2125 		} else {
2126 			fwd->listen_host = NULL;
2127 			fwd->listen_port = a2port(fwdargs[0].arg);
2128 			fwd->connect_host = xstrdup(fwdargs[1].arg);
2129 			fwd->connect_port = a2port(fwdargs[2].arg);
2130 		}
2131 		break;
2132 
2133 	case 4:
2134 		fwd->listen_host = xstrdup(fwdargs[0].arg);
2135 		fwd->listen_port = a2port(fwdargs[1].arg);
2136 		fwd->connect_host = xstrdup(fwdargs[2].arg);
2137 		fwd->connect_port = a2port(fwdargs[3].arg);
2138 		break;
2139 	default:
2140 		i = 0; /* failure */
2141 	}
2142 
2143 	free(p);
2144 
2145 	if (dynamicfwd) {
2146 		if (!(i == 1 || i == 2))
2147 			goto fail_free;
2148 	} else {
2149 		if (!(i == 3 || i == 4)) {
2150 			if (fwd->connect_path == NULL &&
2151 			    fwd->listen_path == NULL)
2152 				goto fail_free;
2153 		}
2154 		if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2155 			goto fail_free;
2156 	}
2157 
2158 	if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2159 	    (!remotefwd && fwd->listen_port == 0))
2160 		goto fail_free;
2161 	if (fwd->connect_host != NULL &&
2162 	    strlen(fwd->connect_host) >= NI_MAXHOST)
2163 		goto fail_free;
2164 	/* XXX - if connecting to a remote socket, max sun len may not match this host */
2165 	if (fwd->connect_path != NULL &&
2166 	    strlen(fwd->connect_path) >= PATH_MAX_SUN)
2167 		goto fail_free;
2168 	if (fwd->listen_host != NULL &&
2169 	    strlen(fwd->listen_host) >= NI_MAXHOST)
2170 		goto fail_free;
2171 	if (fwd->listen_path != NULL &&
2172 	    strlen(fwd->listen_path) >= PATH_MAX_SUN)
2173 		goto fail_free;
2174 
2175 	return (i);
2176 
2177  fail_free:
2178 	free(fwd->connect_host);
2179 	fwd->connect_host = NULL;
2180 	free(fwd->connect_path);
2181 	fwd->connect_path = NULL;
2182 	free(fwd->listen_host);
2183 	fwd->listen_host = NULL;
2184 	free(fwd->listen_path);
2185 	fwd->listen_path = NULL;
2186 	return (0);
2187 }
2188 
2189 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2190 static const char *
2191 fmt_multistate_int(int val, const struct multistate *m)
2192 {
2193 	u_int i;
2194 
2195 	for (i = 0; m[i].key != NULL; i++) {
2196 		if (m[i].value == val)
2197 			return m[i].key;
2198 	}
2199 	return "UNKNOWN";
2200 }
2201 
2202 static const char *
2203 fmt_intarg(OpCodes code, int val)
2204 {
2205 	if (val == -1)
2206 		return "unset";
2207 	switch (code) {
2208 	case oAddressFamily:
2209 		return fmt_multistate_int(val, multistate_addressfamily);
2210 	case oVerifyHostKeyDNS:
2211 	case oStrictHostKeyChecking:
2212 	case oUpdateHostkeys:
2213 		return fmt_multistate_int(val, multistate_yesnoask);
2214 	case oControlMaster:
2215 		return fmt_multistate_int(val, multistate_controlmaster);
2216 	case oTunnel:
2217 		return fmt_multistate_int(val, multistate_tunnel);
2218 	case oRequestTTY:
2219 		return fmt_multistate_int(val, multistate_requesttty);
2220 	case oCanonicalizeHostname:
2221 		return fmt_multistate_int(val, multistate_canonicalizehostname);
2222 	case oFingerprintHash:
2223 		return ssh_digest_alg_name(val);
2224 	case oProtocol:
2225 		switch (val) {
2226 		case SSH_PROTO_1:
2227 			return "1";
2228 		case SSH_PROTO_2:
2229 			return "2";
2230 		case (SSH_PROTO_1|SSH_PROTO_2):
2231 			return "2,1";
2232 		default:
2233 			return "UNKNOWN";
2234 		}
2235 	default:
2236 		switch (val) {
2237 		case 0:
2238 			return "no";
2239 		case 1:
2240 			return "yes";
2241 		default:
2242 			return "UNKNOWN";
2243 		}
2244 	}
2245 }
2246 
2247 static const char *
2248 lookup_opcode_name(OpCodes code)
2249 {
2250 	u_int i;
2251 
2252 	for (i = 0; keywords[i].name != NULL; i++)
2253 		if (keywords[i].opcode == code)
2254 			return(keywords[i].name);
2255 	return "UNKNOWN";
2256 }
2257 
2258 static void
2259 dump_cfg_int(OpCodes code, int val)
2260 {
2261 	printf("%s %d\n", lookup_opcode_name(code), val);
2262 }
2263 
2264 static void
2265 dump_cfg_fmtint(OpCodes code, int val)
2266 {
2267 	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2268 }
2269 
2270 static void
2271 dump_cfg_string(OpCodes code, const char *val)
2272 {
2273 	if (val == NULL)
2274 		return;
2275 	printf("%s %s\n", lookup_opcode_name(code), val);
2276 }
2277 
2278 static void
2279 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2280 {
2281 	u_int i;
2282 
2283 	for (i = 0; i < count; i++)
2284 		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2285 }
2286 
2287 static void
2288 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2289 {
2290 	u_int i;
2291 
2292 	printf("%s", lookup_opcode_name(code));
2293 	for (i = 0; i < count; i++)
2294 		printf(" %s",  vals[i]);
2295 	printf("\n");
2296 }
2297 
2298 static void
2299 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2300 {
2301 	const struct Forward *fwd;
2302 	u_int i;
2303 
2304 	/* oDynamicForward */
2305 	for (i = 0; i < count; i++) {
2306 		fwd = &fwds[i];
2307 		if (code == oDynamicForward &&
2308 		    strcmp(fwd->connect_host, "socks") != 0)
2309 			continue;
2310 		if (code == oLocalForward &&
2311 		    strcmp(fwd->connect_host, "socks") == 0)
2312 			continue;
2313 		printf("%s", lookup_opcode_name(code));
2314 		if (fwd->listen_port == PORT_STREAMLOCAL)
2315 			printf(" %s", fwd->listen_path);
2316 		else if (fwd->listen_host == NULL)
2317 			printf(" %d", fwd->listen_port);
2318 		else {
2319 			printf(" [%s]:%d",
2320 			    fwd->listen_host, fwd->listen_port);
2321 		}
2322 		if (code != oDynamicForward) {
2323 			if (fwd->connect_port == PORT_STREAMLOCAL)
2324 				printf(" %s", fwd->connect_path);
2325 			else if (fwd->connect_host == NULL)
2326 				printf(" %d", fwd->connect_port);
2327 			else {
2328 				printf(" [%s]:%d",
2329 				    fwd->connect_host, fwd->connect_port);
2330 			}
2331 		}
2332 		printf("\n");
2333 	}
2334 }
2335 
2336 void
2337 dump_client_config(Options *o, const char *host)
2338 {
2339 	int i;
2340 	char vbuf[5];
2341 
2342 	/* This is normally prepared in ssh_kex2 */
2343 	if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2344 		fatal("%s: kex_assemble_names failed", __func__);
2345 
2346 	/* Most interesting options first: user, host, port */
2347 	dump_cfg_string(oUser, o->user);
2348 	dump_cfg_string(oHostName, host);
2349 	dump_cfg_int(oPort, o->port);
2350 
2351 	/* Flag options */
2352 	dump_cfg_fmtint(oAddressFamily, o->address_family);
2353 	dump_cfg_fmtint(oBatchMode, o->batch_mode);
2354 	dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2355 	dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2356 	dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2357 	dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2358 	dump_cfg_fmtint(oCompression, o->compression);
2359 	dump_cfg_fmtint(oControlMaster, o->control_master);
2360 	dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2361 	dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2362 	dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2363 	dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2364 	dump_cfg_fmtint(oForwardX11, o->forward_x11);
2365 	dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2366 	dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2367 #ifdef GSSAPI
2368 	dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2369 	dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2370 #endif /* GSSAPI */
2371 	dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2372 	dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2373 	dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2374 	dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2375 	dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2376 	dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2377 	dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2378 	dump_cfg_fmtint(oProtocol, o->protocol);
2379 	dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2380 	dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2381 	dump_cfg_fmtint(oRequestTTY, o->request_tty);
2382 	dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2383 	dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
2384 	dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2385 	dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2386 	dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2387 	dump_cfg_fmtint(oTunnel, o->tun_open);
2388 	dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2389 	dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2390 	dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2391 	dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2392 
2393 	/* Integer options */
2394 	dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2395 	dump_cfg_int(oCompressionLevel, o->compression_level);
2396 	dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2397 	dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2398 	dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2399 	dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2400 	dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2401 
2402 	/* String options */
2403 	dump_cfg_string(oBindAddress, o->bind_address);
2404 	dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2405 	dump_cfg_string(oControlPath, o->control_path);
2406 	dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2407 	dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2408 	dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2409 	dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2410 	dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2411 	dump_cfg_string(oLocalCommand, o->local_command);
2412 	dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2413 	dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2414 	dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2415 	dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2416 	dump_cfg_string(oProxyCommand, o->proxy_command);
2417 	dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2418 	dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2419 	dump_cfg_string(oXAuthLocation, o->xauth_location);
2420 
2421 	/* Forwards */
2422 	dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2423 	dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2424 	dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2425 
2426 	/* String array options */
2427 	dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2428 	dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2429 	dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2430 	dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2431 	dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2432 
2433 	/* Special cases */
2434 
2435 	/* oConnectTimeout */
2436 	if (o->connection_timeout == -1)
2437 		printf("connecttimeout none\n");
2438 	else
2439 		dump_cfg_int(oConnectTimeout, o->connection_timeout);
2440 
2441 	/* oTunnelDevice */
2442 	printf("tunneldevice");
2443 	if (o->tun_local == SSH_TUNID_ANY)
2444 		printf(" any");
2445 	else
2446 		printf(" %d", o->tun_local);
2447 	if (o->tun_remote == SSH_TUNID_ANY)
2448 		printf(":any");
2449 	else
2450 		printf(":%d", o->tun_remote);
2451 	printf("\n");
2452 
2453 	/* oCanonicalizePermittedCNAMEs */
2454 	if ( o->num_permitted_cnames > 0) {
2455 		printf("canonicalizePermittedcnames");
2456 		for (i = 0; i < o->num_permitted_cnames; i++) {
2457 			printf(" %s:%s", o->permitted_cnames[i].source_list,
2458 			    o->permitted_cnames[i].target_list);
2459 		}
2460 		printf("\n");
2461 	}
2462 
2463 	/* oCipher */
2464 	if (o->cipher != SSH_CIPHER_NOT_SET)
2465 		printf("Cipher %s\n", cipher_name(o->cipher));
2466 
2467 	/* oControlPersist */
2468 	if (o->control_persist == 0 || o->control_persist_timeout == 0)
2469 		dump_cfg_fmtint(oControlPersist, o->control_persist);
2470 	else
2471 		dump_cfg_int(oControlPersist, o->control_persist_timeout);
2472 
2473 	/* oEscapeChar */
2474 	if (o->escape_char == SSH_ESCAPECHAR_NONE)
2475 		printf("escapechar none\n");
2476 	else {
2477 		vis(vbuf, o->escape_char, VIS_WHITE, 0);
2478 		printf("escapechar %s\n", vbuf);
2479 	}
2480 
2481 	/* oIPQoS */
2482 	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2483 	printf("%s\n", iptos2str(o->ip_qos_bulk));
2484 
2485 	/* oRekeyLimit */
2486 	printf("rekeylimit %llu %d\n",
2487 	    (unsigned long long)o->rekey_limit, o->rekey_interval);
2488 
2489 	/* oStreamLocalBindMask */
2490 	printf("streamlocalbindmask 0%o\n",
2491 	    o->fwd_opts.streamlocal_bind_mask);
2492 }
2493