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