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