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