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