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