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