Home | History | Annotate | Line # | Download | only in dist
readconf.c revision 1.11
      1  1.11  christos /*	$NetBSD: readconf.c,v 1.11 2013/11/08 19:18:25 christos Exp $	*/
      2  1.11  christos /* $OpenBSD: readconf.c,v 1.204 2013/06/10 19:19:44 dtucker Exp $ */
      3   1.1  christos /*
      4   1.1  christos  * Author: Tatu Ylonen <ylo (at) cs.hut.fi>
      5   1.1  christos  * Copyright (c) 1995 Tatu Ylonen <ylo (at) cs.hut.fi>, Espoo, Finland
      6   1.1  christos  *                    All rights reserved
      7   1.1  christos  * Functions for reading the configuration files.
      8   1.1  christos  *
      9   1.1  christos  * As far as I am concerned, the code I have written for this software
     10   1.1  christos  * can be used freely for any purpose.  Any derived versions of this
     11   1.1  christos  * software must be clearly marked as such, and if the derived work is
     12   1.1  christos  * incompatible with the protocol description in the RFC file, it must be
     13   1.1  christos  * called by a name other than "ssh" or "Secure Shell".
     14   1.1  christos  */
     15   1.1  christos 
     16   1.2  christos #include "includes.h"
     17  1.11  christos __RCSID("$NetBSD: readconf.c,v 1.11 2013/11/08 19:18:25 christos Exp $");
     18   1.1  christos #include <sys/types.h>
     19   1.1  christos #include <sys/stat.h>
     20   1.1  christos #include <sys/socket.h>
     21   1.1  christos 
     22   1.1  christos #include <netinet/in.h>
     23   1.5  christos #include <netinet/in_systm.h>
     24   1.5  christos #include <netinet/ip.h>
     25   1.1  christos 
     26   1.1  christos #include <ctype.h>
     27   1.1  christos #include <errno.h>
     28   1.1  christos #include <netdb.h>
     29   1.1  christos #include <signal.h>
     30   1.1  christos #include <stdio.h>
     31   1.1  christos #include <string.h>
     32   1.1  christos #include <unistd.h>
     33   1.2  christos #include <limits.h>
     34  1.11  christos #include <util.h>
     35   1.1  christos 
     36   1.1  christos #include "xmalloc.h"
     37   1.1  christos #include "ssh.h"
     38   1.1  christos #include "compat.h"
     39   1.1  christos #include "cipher.h"
     40   1.1  christos #include "pathnames.h"
     41   1.1  christos #include "log.h"
     42   1.1  christos #include "key.h"
     43   1.1  christos #include "readconf.h"
     44   1.1  christos #include "match.h"
     45   1.1  christos #include "misc.h"
     46   1.1  christos #include "buffer.h"
     47   1.1  christos #include "kex.h"
     48   1.1  christos #include "mac.h"
     49  1.11  christos #include "fmt_scaled.h"
     50   1.1  christos 
     51   1.1  christos /* Format of the configuration file:
     52   1.1  christos 
     53   1.1  christos    # Configuration data is parsed as follows:
     54   1.1  christos    #  1. command line options
     55   1.1  christos    #  2. user-specific file
     56   1.1  christos    #  3. system-wide file
     57   1.1  christos    # Any configuration value is only changed the first time it is set.
     58   1.1  christos    # Thus, host-specific definitions should be at the beginning of the
     59   1.1  christos    # configuration file, and defaults at the end.
     60   1.1  christos 
     61   1.1  christos    # Host-specific declarations.  These may override anything above.  A single
     62   1.1  christos    # host may match multiple declarations; these are processed in the order
     63   1.1  christos    # that they are given in.
     64   1.1  christos 
     65   1.1  christos    Host *.ngs.fi ngs.fi
     66   1.1  christos      User foo
     67   1.1  christos 
     68   1.1  christos    Host fake.com
     69   1.1  christos      HostName another.host.name.real.org
     70   1.1  christos      User blaah
     71   1.1  christos      Port 34289
     72   1.1  christos      ForwardX11 no
     73   1.1  christos      ForwardAgent no
     74   1.1  christos 
     75   1.1  christos    Host books.com
     76   1.1  christos      RemoteForward 9999 shadows.cs.hut.fi:9999
     77   1.1  christos      Cipher 3des
     78   1.1  christos 
     79   1.1  christos    Host fascist.blob.com
     80   1.1  christos      Port 23123
     81   1.1  christos      User tylonen
     82   1.1  christos      PasswordAuthentication no
     83   1.1  christos 
     84   1.1  christos    Host puukko.hut.fi
     85   1.1  christos      User t35124p
     86   1.1  christos      ProxyCommand ssh-proxy %h %p
     87   1.1  christos 
     88   1.1  christos    Host *.fr
     89   1.1  christos      PublicKeyAuthentication no
     90   1.1  christos 
     91   1.1  christos    Host *.su
     92   1.1  christos      Cipher none
     93   1.1  christos      PasswordAuthentication no
     94   1.1  christos 
     95   1.1  christos    Host vpn.fake.com
     96   1.1  christos      Tunnel yes
     97   1.1  christos      TunnelDevice 3
     98   1.1  christos 
     99   1.1  christos    # Defaults for various options
    100   1.1  christos    Host *
    101   1.1  christos      ForwardAgent no
    102   1.1  christos      ForwardX11 no
    103   1.1  christos      PasswordAuthentication yes
    104   1.1  christos      RSAAuthentication yes
    105   1.1  christos      RhostsRSAAuthentication yes
    106   1.1  christos      StrictHostKeyChecking yes
    107   1.1  christos      TcpKeepAlive no
    108   1.1  christos      IdentityFile ~/.ssh/identity
    109   1.1  christos      Port 22
    110   1.1  christos      EscapeChar ~
    111   1.1  christos 
    112   1.1  christos */
    113   1.1  christos 
    114   1.1  christos /* Keyword tokens. */
    115   1.1  christos 
    116   1.1  christos typedef enum {
    117   1.1  christos 	oBadOption,
    118   1.4      adam 	oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
    119   1.4      adam 	oGatewayPorts, oExitOnForwardFailure,
    120   1.1  christos 	oPasswordAuthentication, oRSAAuthentication,
    121   1.1  christos 	oChallengeResponseAuthentication, oXAuthLocation,
    122   1.2  christos #if defined(KRB4) || defined(KRB5)
    123   1.2  christos 	oKerberosAuthentication,
    124   1.2  christos #endif
    125   1.2  christos #if defined(AFS) || defined(KRB5)
    126   1.2  christos 	oKerberosTgtPassing,
    127   1.2  christos #endif
    128   1.2  christos #ifdef AFS
    129   1.2  christos 	oAFSTokenPassing,
    130   1.2  christos #endif
    131   1.1  christos 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
    132   1.1  christos 	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
    133   1.1  christos 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
    134   1.1  christos 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
    135   1.1  christos 	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
    136   1.1  christos 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
    137   1.1  christos 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
    138   1.1  christos 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
    139   1.1  christos 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
    140   1.4      adam 	oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
    141   1.1  christos 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
    142   1.1  christos 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
    143   1.1  christos 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
    144   1.1  christos 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
    145   1.4      adam 	oSendEnv, oControlPath, oControlMaster, oControlPersist,
    146   1.4      adam 	oHashKnownHosts,
    147   1.1  christos 	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
    148   1.3  christos 	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
    149  1.11  christos 	oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown,
    150  1.11  christos 	oIgnoredUnknownOption,
    151   1.2  christos 	oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
    152   1.2  christos 	oHPNBufferSize,
    153   1.7       tls 	oSendVersionFirst,
    154   1.1  christos 	oDeprecated, oUnsupported
    155   1.1  christos } OpCodes;
    156   1.1  christos 
    157   1.1  christos /* Textual representations of the tokens. */
    158   1.1  christos 
    159   1.1  christos static struct {
    160   1.1  christos 	const char *name;
    161   1.1  christos 	OpCodes opcode;
    162   1.1  christos } keywords[] = {
    163   1.1  christos 	{ "forwardagent", oForwardAgent },
    164   1.1  christos 	{ "forwardx11", oForwardX11 },
    165   1.1  christos 	{ "forwardx11trusted", oForwardX11Trusted },
    166   1.4      adam 	{ "forwardx11timeout", oForwardX11Timeout },
    167   1.1  christos 	{ "exitonforwardfailure", oExitOnForwardFailure },
    168   1.1  christos 	{ "xauthlocation", oXAuthLocation },
    169   1.1  christos 	{ "gatewayports", oGatewayPorts },
    170   1.1  christos 	{ "useprivilegedport", oUsePrivilegedPort },
    171   1.1  christos 	{ "rhostsauthentication", oDeprecated },
    172   1.1  christos 	{ "passwordauthentication", oPasswordAuthentication },
    173   1.1  christos 	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
    174   1.1  christos 	{ "kbdinteractivedevices", oKbdInteractiveDevices },
    175   1.1  christos 	{ "rsaauthentication", oRSAAuthentication },
    176   1.1  christos 	{ "pubkeyauthentication", oPubkeyAuthentication },
    177   1.1  christos 	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
    178   1.1  christos 	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
    179   1.1  christos 	{ "hostbasedauthentication", oHostbasedAuthentication },
    180   1.1  christos 	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
    181   1.1  christos 	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
    182   1.1  christos 	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
    183   1.2  christos #if defined(KRB4) || defined(KRB5)
    184   1.2  christos 	{ "kerberosauthentication", oKerberosAuthentication },
    185   1.2  christos #endif
    186   1.2  christos #if defined(AFS) || defined(KRB5)
    187   1.2  christos 	{ "kerberostgtpassing", oKerberosTgtPassing },
    188   1.2  christos 	{ "kerberos5tgtpassing", oKerberosTgtPassing },		/* alias */
    189   1.2  christos 	{ "kerberos4tgtpassing", oKerberosTgtPassing },		/* alias */
    190   1.2  christos #endif
    191   1.2  christos #ifdef AFS
    192   1.2  christos 	{ "afstokenpassing", oAFSTokenPassing },
    193   1.2  christos #endif
    194   1.1  christos #if defined(GSSAPI)
    195   1.1  christos 	{ "gssapiauthentication", oGssAuthentication },
    196   1.1  christos 	{ "gssapidelegatecredentials", oGssDelegateCreds },
    197   1.1  christos #else
    198   1.1  christos 	{ "gssapiauthentication", oUnsupported },
    199   1.1  christos 	{ "gssapidelegatecredentials", oUnsupported },
    200   1.1  christos #endif
    201   1.1  christos 	{ "fallbacktorsh", oDeprecated },
    202   1.1  christos 	{ "usersh", oDeprecated },
    203   1.1  christos 	{ "identityfile", oIdentityFile },
    204   1.1  christos 	{ "identityfile2", oIdentityFile },			/* obsolete */
    205   1.1  christos 	{ "identitiesonly", oIdentitiesOnly },
    206   1.1  christos 	{ "hostname", oHostName },
    207   1.1  christos 	{ "hostkeyalias", oHostKeyAlias },
    208   1.1  christos 	{ "proxycommand", oProxyCommand },
    209   1.1  christos 	{ "port", oPort },
    210   1.1  christos 	{ "cipher", oCipher },
    211   1.1  christos 	{ "ciphers", oCiphers },
    212   1.1  christos 	{ "macs", oMacs },
    213   1.1  christos 	{ "protocol", oProtocol },
    214   1.1  christos 	{ "remoteforward", oRemoteForward },
    215   1.1  christos 	{ "localforward", oLocalForward },
    216   1.1  christos 	{ "user", oUser },
    217   1.1  christos 	{ "host", oHost },
    218   1.1  christos 	{ "escapechar", oEscapeChar },
    219   1.1  christos 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
    220   1.6  christos 	{ "globalknownhostsfile2", oDeprecated },
    221   1.1  christos 	{ "userknownhostsfile", oUserKnownHostsFile },
    222   1.6  christos 	{ "userknownhostsfile2", oDeprecated },
    223   1.1  christos 	{ "connectionattempts", oConnectionAttempts },
    224   1.1  christos 	{ "batchmode", oBatchMode },
    225   1.1  christos 	{ "checkhostip", oCheckHostIP },
    226   1.1  christos 	{ "stricthostkeychecking", oStrictHostKeyChecking },
    227   1.1  christos 	{ "compression", oCompression },
    228   1.1  christos 	{ "compressionlevel", oCompressionLevel },
    229   1.1  christos 	{ "tcpkeepalive", oTCPKeepAlive },
    230   1.1  christos 	{ "keepalive", oTCPKeepAlive },				/* obsolete */
    231   1.1  christos 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
    232   1.1  christos 	{ "loglevel", oLogLevel },
    233   1.1  christos 	{ "dynamicforward", oDynamicForward },
    234   1.1  christos 	{ "preferredauthentications", oPreferredAuthentications },
    235   1.1  christos 	{ "hostkeyalgorithms", oHostKeyAlgorithms },
    236   1.1  christos 	{ "bindaddress", oBindAddress },
    237   1.4      adam #ifdef ENABLE_PKCS11
    238   1.4      adam 	{ "smartcarddevice", oPKCS11Provider },
    239   1.4      adam 	{ "pkcs11provider", oPKCS11Provider },
    240   1.1  christos #else
    241   1.1  christos 	{ "smartcarddevice", oUnsupported },
    242   1.4      adam 	{ "pkcs11provider", oUnsupported },
    243   1.1  christos #endif
    244   1.1  christos 	{ "clearallforwardings", oClearAllForwardings },
    245   1.1  christos 	{ "enablesshkeysign", oEnableSSHKeysign },
    246   1.1  christos 	{ "verifyhostkeydns", oVerifyHostKeyDNS },
    247   1.1  christos 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
    248   1.1  christos 	{ "rekeylimit", oRekeyLimit },
    249   1.1  christos 	{ "connecttimeout", oConnectTimeout },
    250   1.1  christos 	{ "addressfamily", oAddressFamily },
    251   1.1  christos 	{ "serveraliveinterval", oServerAliveInterval },
    252   1.1  christos 	{ "serveralivecountmax", oServerAliveCountMax },
    253   1.1  christos 	{ "sendenv", oSendEnv },
    254   1.1  christos 	{ "controlpath", oControlPath },
    255   1.1  christos 	{ "controlmaster", oControlMaster },
    256   1.4      adam 	{ "controlpersist", oControlPersist },
    257   1.1  christos 	{ "hashknownhosts", oHashKnownHosts },
    258   1.1  christos 	{ "tunnel", oTunnel },
    259   1.1  christos 	{ "tunneldevice", oTunnelDevice },
    260   1.1  christos 	{ "localcommand", oLocalCommand },
    261   1.1  christos 	{ "permitlocalcommand", oPermitLocalCommand },
    262   1.1  christos 	{ "visualhostkey", oVisualHostKey },
    263   1.3  christos 	{ "useroaming", oUseRoaming },
    264   1.1  christos #ifdef JPAKE
    265   1.1  christos 	{ "zeroknowledgepasswordauthentication",
    266   1.1  christos 	    oZeroKnowledgePasswordAuthentication },
    267   1.1  christos #else
    268   1.1  christos 	{ "zeroknowledgepasswordauthentication", oUnsupported },
    269   1.1  christos #endif
    270   1.5  christos 	{ "kexalgorithms", oKexAlgorithms },
    271   1.5  christos 	{ "ipqos", oIPQoS },
    272   1.6  christos 	{ "requesttty", oRequestTTY },
    273  1.11  christos 	{ "ignoreunknown", oIgnoreUnknown },
    274   1.2  christos 	{ "noneenabled", oNoneEnabled },
    275   1.2  christos 	{ "tcprcvbufpoll", oTcpRcvBufPoll },
    276   1.2  christos 	{ "tcprcvbuf", oTcpRcvBuf },
    277   1.2  christos 	{ "noneswitch", oNoneSwitch },
    278   1.2  christos 	{ "hpndisabled", oHPNDisabled },
    279   1.2  christos 	{ "hpnbuffersize", oHPNBufferSize },
    280   1.7       tls 	{ "sendversionfirst", oSendVersionFirst },
    281   1.1  christos 	{ NULL, oBadOption }
    282   1.1  christos };
    283   1.1  christos 
    284   1.1  christos /*
    285   1.1  christos  * Adds a local TCP/IP port forward to options.  Never returns if there is an
    286   1.1  christos  * error.
    287   1.1  christos  */
    288   1.1  christos 
    289   1.1  christos void
    290   1.1  christos add_local_forward(Options *options, const Forward *newfwd)
    291   1.1  christos {
    292   1.1  christos 	Forward *fwd;
    293   1.1  christos 	extern uid_t original_real_uid;
    294   1.4      adam 
    295   1.1  christos 	if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
    296   1.1  christos 		fatal("Privileged ports can only be forwarded by root.");
    297   1.4      adam 	options->local_forwards = xrealloc(options->local_forwards,
    298   1.4      adam 	    options->num_local_forwards + 1,
    299   1.4      adam 	    sizeof(*options->local_forwards));
    300   1.1  christos 	fwd = &options->local_forwards[options->num_local_forwards++];
    301   1.1  christos 
    302   1.1  christos 	fwd->listen_host = newfwd->listen_host;
    303   1.1  christos 	fwd->listen_port = newfwd->listen_port;
    304   1.1  christos 	fwd->connect_host = newfwd->connect_host;
    305   1.1  christos 	fwd->connect_port = newfwd->connect_port;
    306   1.1  christos }
    307   1.1  christos 
    308   1.1  christos /*
    309   1.1  christos  * Adds a remote TCP/IP port forward to options.  Never returns if there is
    310   1.1  christos  * an error.
    311   1.1  christos  */
    312   1.1  christos 
    313   1.1  christos void
    314   1.1  christos add_remote_forward(Options *options, const Forward *newfwd)
    315   1.1  christos {
    316   1.1  christos 	Forward *fwd;
    317   1.4      adam 
    318   1.4      adam 	options->remote_forwards = xrealloc(options->remote_forwards,
    319   1.4      adam 	    options->num_remote_forwards + 1,
    320   1.4      adam 	    sizeof(*options->remote_forwards));
    321   1.1  christos 	fwd = &options->remote_forwards[options->num_remote_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  christos 	fwd->connect_host = newfwd->connect_host;
    326   1.1  christos 	fwd->connect_port = newfwd->connect_port;
    327   1.8  christos 	fwd->handle = newfwd->handle;
    328   1.4      adam 	fwd->allocated_port = 0;
    329   1.1  christos }
    330   1.1  christos 
    331   1.1  christos static void
    332   1.1  christos clear_forwardings(Options *options)
    333   1.1  christos {
    334   1.1  christos 	int i;
    335   1.1  christos 
    336   1.1  christos 	for (i = 0; i < options->num_local_forwards; i++) {
    337  1.11  christos 		free(options->local_forwards[i].listen_host);
    338  1.11  christos 		free(options->local_forwards[i].connect_host);
    339   1.1  christos 	}
    340   1.4      adam 	if (options->num_local_forwards > 0) {
    341  1.11  christos 		free(options->local_forwards);
    342   1.4      adam 		options->local_forwards = NULL;
    343   1.4      adam 	}
    344   1.1  christos 	options->num_local_forwards = 0;
    345   1.1  christos 	for (i = 0; i < options->num_remote_forwards; i++) {
    346  1.11  christos 		free(options->remote_forwards[i].listen_host);
    347  1.11  christos 		free(options->remote_forwards[i].connect_host);
    348   1.1  christos 	}
    349   1.4      adam 	if (options->num_remote_forwards > 0) {
    350  1.11  christos 		free(options->remote_forwards);
    351   1.4      adam 		options->remote_forwards = NULL;
    352   1.4      adam 	}
    353   1.1  christos 	options->num_remote_forwards = 0;
    354   1.1  christos 	options->tun_open = SSH_TUNMODE_NO;
    355   1.1  christos }
    356   1.1  christos 
    357   1.9   mlelstv void
    358   1.9   mlelstv add_identity_file(Options *options, const char *dir, const char *filename,
    359   1.9   mlelstv     int userprovided)
    360   1.9   mlelstv {
    361   1.9   mlelstv 	char *path;
    362   1.9   mlelstv 
    363   1.9   mlelstv 	if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
    364   1.9   mlelstv 		fatal("Too many identity files specified (max %d)",
    365   1.9   mlelstv 		    SSH_MAX_IDENTITY_FILES);
    366   1.9   mlelstv 
    367   1.9   mlelstv 	if (dir == NULL) /* no dir, filename is absolute */
    368   1.9   mlelstv 		path = xstrdup(filename);
    369   1.9   mlelstv 	else
    370   1.9   mlelstv 		(void)xasprintf(&path, "%.100s%.100s", dir, filename);
    371   1.9   mlelstv 
    372   1.9   mlelstv 	options->identity_file_userprovided[options->num_identity_files] =
    373   1.9   mlelstv 	    userprovided;
    374   1.9   mlelstv 	options->identity_files[options->num_identity_files++] = path;
    375   1.9   mlelstv }
    376   1.9   mlelstv 
    377   1.1  christos /*
    378   1.1  christos  * Returns the number of the token pointed to by cp or oBadOption.
    379   1.1  christos  */
    380   1.1  christos 
    381   1.1  christos static OpCodes
    382  1.11  christos parse_token(const char *cp, const char *filename, int linenum,
    383  1.11  christos     const char *ignored_unknown)
    384   1.1  christos {
    385  1.11  christos 	int i;
    386   1.1  christos 
    387   1.1  christos 	for (i = 0; keywords[i].name; i++)
    388  1.11  christos 		if (strcmp(cp, keywords[i].name) == 0)
    389   1.1  christos 			return keywords[i].opcode;
    390  1.11  christos 	if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
    391  1.11  christos 	    strlen(ignored_unknown), 1) == 1)
    392  1.11  christos 		return oIgnoredUnknownOption;
    393   1.1  christos 	error("%s: line %d: Bad configuration option: %s",
    394   1.1  christos 	    filename, linenum, cp);
    395   1.1  christos 	return oBadOption;
    396   1.1  christos }
    397   1.1  christos 
    398   1.1  christos /*
    399   1.1  christos  * Processes a single option line as used in the configuration files. This
    400   1.1  christos  * only sets those values that have not already been set.
    401   1.1  christos  */
    402   1.1  christos #define WHITESPACE " \t\r\n"
    403   1.1  christos 
    404   1.1  christos int
    405   1.1  christos process_config_line(Options *options, const char *host,
    406   1.1  christos 		    char *line, const char *filename, int linenum,
    407   1.9   mlelstv 		    int *activep, int userconfig)
    408   1.1  christos {
    409   1.6  christos 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
    410   1.6  christos 	char **cpptr, fwdarg[256];
    411  1.11  christos 	u_int i, *uintptr, max_entries = 0;
    412  1.11  christos 	int negated, opcode, *intptr, value, value2;
    413   1.1  christos 	LogLevel *log_level_ptr;
    414  1.11  christos 	long long val64;
    415   1.1  christos 	size_t len;
    416   1.1  christos 	Forward fwd;
    417   1.1  christos 
    418   1.1  christos 	/* Strip trailing whitespace */
    419   1.1  christos 	for (len = strlen(line) - 1; len > 0; len--) {
    420   1.1  christos 		if (strchr(WHITESPACE, line[len]) == NULL)
    421   1.1  christos 			break;
    422   1.1  christos 		line[len] = '\0';
    423   1.1  christos 	}
    424   1.1  christos 
    425   1.1  christos 	s = line;
    426   1.1  christos 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
    427   1.1  christos 	if ((keyword = strdelim(&s)) == NULL)
    428   1.1  christos 		return 0;
    429   1.1  christos 	/* Ignore leading whitespace. */
    430   1.1  christos 	if (*keyword == '\0')
    431   1.1  christos 		keyword = strdelim(&s);
    432   1.1  christos 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
    433   1.1  christos 		return 0;
    434  1.11  christos 	/* Match lowercase keyword */
    435  1.11  christos 	for (i = 0; i < strlen(keyword); i++)
    436  1.11  christos 		keyword[i] = tolower((unsigned char)keyword[i]);
    437   1.1  christos 
    438  1.11  christos 	opcode = parse_token(keyword, filename, linenum,
    439  1.11  christos 	    options->ignored_unknown);
    440   1.1  christos 
    441   1.1  christos 	switch (opcode) {
    442   1.1  christos 	case oBadOption:
    443   1.1  christos 		/* don't panic, but count bad options */
    444   1.1  christos 		return -1;
    445   1.1  christos 		/* NOTREACHED */
    446  1.11  christos 	case oIgnoredUnknownOption:
    447  1.11  christos 		debug("%s line %d: Ignored unknown option \"%s\"",
    448  1.11  christos 		    filename, linenum, keyword);
    449  1.11  christos 		return 0;
    450   1.1  christos 	case oConnectTimeout:
    451   1.1  christos 		intptr = &options->connection_timeout;
    452   1.1  christos parse_time:
    453   1.1  christos 		arg = strdelim(&s);
    454   1.1  christos 		if (!arg || *arg == '\0')
    455   1.1  christos 			fatal("%s line %d: missing time value.",
    456   1.1  christos 			    filename, linenum);
    457   1.1  christos 		if ((value = convtime(arg)) == -1)
    458   1.1  christos 			fatal("%s line %d: invalid time value.",
    459   1.1  christos 			    filename, linenum);
    460   1.1  christos 		if (*activep && *intptr == -1)
    461   1.1  christos 			*intptr = value;
    462   1.1  christos 		break;
    463   1.1  christos 
    464   1.1  christos 	case oForwardAgent:
    465   1.1  christos 		intptr = &options->forward_agent;
    466   1.1  christos parse_flag:
    467   1.1  christos 		arg = strdelim(&s);
    468   1.1  christos 		if (!arg || *arg == '\0')
    469   1.1  christos 			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
    470   1.1  christos 		value = 0;	/* To avoid compiler warning... */
    471   1.1  christos 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
    472   1.1  christos 			value = 1;
    473   1.1  christos 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
    474   1.1  christos 			value = 0;
    475   1.1  christos 		else
    476   1.1  christos 			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
    477   1.1  christos 		if (*activep && *intptr == -1)
    478   1.1  christos 			*intptr = value;
    479   1.1  christos 		break;
    480   1.1  christos 
    481   1.1  christos 	case oForwardX11:
    482   1.1  christos 		intptr = &options->forward_x11;
    483   1.1  christos 		goto parse_flag;
    484   1.1  christos 
    485   1.1  christos 	case oForwardX11Trusted:
    486   1.1  christos 		intptr = &options->forward_x11_trusted;
    487   1.1  christos 		goto parse_flag;
    488   1.4      adam 
    489   1.4      adam 	case oForwardX11Timeout:
    490   1.4      adam 		intptr = &options->forward_x11_timeout;
    491   1.4      adam 		goto parse_time;
    492   1.1  christos 
    493   1.1  christos 	case oGatewayPorts:
    494   1.1  christos 		intptr = &options->gateway_ports;
    495   1.1  christos 		goto parse_flag;
    496   1.1  christos 
    497   1.1  christos 	case oExitOnForwardFailure:
    498   1.1  christos 		intptr = &options->exit_on_forward_failure;
    499   1.1  christos 		goto parse_flag;
    500   1.1  christos 
    501   1.1  christos 	case oUsePrivilegedPort:
    502   1.1  christos 		intptr = &options->use_privileged_port;
    503   1.1  christos 		goto parse_flag;
    504   1.1  christos 
    505   1.1  christos 	case oPasswordAuthentication:
    506   1.1  christos 		intptr = &options->password_authentication;
    507   1.1  christos 		goto parse_flag;
    508   1.1  christos 
    509   1.1  christos 	case oZeroKnowledgePasswordAuthentication:
    510   1.1  christos 		intptr = &options->zero_knowledge_password_authentication;
    511   1.1  christos 		goto parse_flag;
    512   1.1  christos 
    513   1.1  christos 	case oKbdInteractiveAuthentication:
    514   1.1  christos 		intptr = &options->kbd_interactive_authentication;
    515   1.1  christos 		goto parse_flag;
    516   1.1  christos 
    517   1.1  christos 	case oKbdInteractiveDevices:
    518   1.1  christos 		charptr = &options->kbd_interactive_devices;
    519   1.1  christos 		goto parse_string;
    520   1.1  christos 
    521   1.1  christos 	case oPubkeyAuthentication:
    522   1.1  christos 		intptr = &options->pubkey_authentication;
    523   1.1  christos 		goto parse_flag;
    524   1.1  christos 
    525   1.1  christos 	case oRSAAuthentication:
    526   1.1  christos 		intptr = &options->rsa_authentication;
    527   1.1  christos 		goto parse_flag;
    528   1.1  christos 
    529   1.1  christos 	case oRhostsRSAAuthentication:
    530   1.1  christos 		intptr = &options->rhosts_rsa_authentication;
    531   1.1  christos 		goto parse_flag;
    532   1.1  christos 
    533   1.1  christos 	case oHostbasedAuthentication:
    534   1.1  christos 		intptr = &options->hostbased_authentication;
    535   1.1  christos 		goto parse_flag;
    536   1.1  christos 
    537   1.1  christos 	case oChallengeResponseAuthentication:
    538   1.1  christos 		intptr = &options->challenge_response_authentication;
    539   1.1  christos 		goto parse_flag;
    540   1.1  christos 
    541   1.2  christos #if defined(KRB4) || defined(KRB5)
    542   1.2  christos 	case oKerberosAuthentication:
    543   1.2  christos 		intptr = &options->kerberos_authentication;
    544   1.2  christos 		goto parse_flag;
    545   1.2  christos #endif
    546   1.2  christos #if defined(AFS) || defined(KRB5)
    547   1.2  christos 	case oKerberosTgtPassing:
    548   1.2  christos 		intptr = &options->kerberos_tgt_passing;
    549   1.2  christos 		goto parse_flag;
    550   1.2  christos #endif
    551   1.2  christos 
    552   1.1  christos 	case oGssAuthentication:
    553   1.1  christos 		intptr = &options->gss_authentication;
    554   1.1  christos 		goto parse_flag;
    555   1.1  christos 
    556   1.2  christos #ifdef AFS
    557   1.2  christos 	case oAFSTokenPassing:
    558   1.2  christos 		intptr = &options->afs_token_passing;
    559   1.2  christos  		goto parse_flag;
    560   1.2  christos #endif
    561   1.2  christos 
    562   1.1  christos 	case oGssDelegateCreds:
    563   1.1  christos 		intptr = &options->gss_deleg_creds;
    564   1.1  christos 		goto parse_flag;
    565   1.1  christos 
    566   1.1  christos 	case oBatchMode:
    567   1.1  christos 		intptr = &options->batch_mode;
    568   1.1  christos 		goto parse_flag;
    569   1.1  christos 
    570   1.1  christos 	case oCheckHostIP:
    571   1.1  christos 		intptr = &options->check_host_ip;
    572   1.1  christos 		goto parse_flag;
    573   1.1  christos 
    574   1.2  christos 	case oNoneEnabled:
    575   1.2  christos 		intptr = &options->none_enabled;
    576   1.2  christos 		goto parse_flag;
    577   1.2  christos 
    578   1.2  christos 	/* we check to see if the command comes from the */
    579   1.2  christos 	/* command line or not. If it does then enable it */
    580   1.2  christos 	/* otherwise fail. NONE should never be a default configuration */
    581   1.2  christos 	case oNoneSwitch:
    582   1.2  christos 		if(strcmp(filename,"command-line")==0)
    583   1.2  christos 		{
    584   1.2  christos 		    intptr = &options->none_switch;
    585   1.2  christos 		    goto parse_flag;
    586   1.2  christos 		} else {
    587   1.2  christos 		    error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
    588   1.2  christos 		    error("Continuing...");
    589   1.2  christos 		    debug("NoneSwitch directive found in %.200s.", filename);
    590   1.2  christos 		    return 0;
    591   1.2  christos 	        }
    592   1.2  christos 
    593   1.2  christos 	case oHPNDisabled:
    594   1.2  christos 		intptr = &options->hpn_disabled;
    595   1.2  christos 		goto parse_flag;
    596   1.2  christos 
    597   1.2  christos 	case oHPNBufferSize:
    598   1.2  christos 		intptr = &options->hpn_buffer_size;
    599   1.2  christos 		goto parse_int;
    600   1.2  christos 
    601   1.2  christos 	case oTcpRcvBufPoll:
    602   1.2  christos 		intptr = &options->tcp_rcv_buf_poll;
    603   1.2  christos 		goto parse_flag;
    604   1.2  christos 
    605   1.1  christos 	case oVerifyHostKeyDNS:
    606   1.1  christos 		intptr = &options->verify_host_key_dns;
    607   1.1  christos 		goto parse_yesnoask;
    608   1.1  christos 
    609   1.1  christos 	case oStrictHostKeyChecking:
    610   1.1  christos 		intptr = &options->strict_host_key_checking;
    611   1.1  christos parse_yesnoask:
    612   1.1  christos 		arg = strdelim(&s);
    613   1.1  christos 		if (!arg || *arg == '\0')
    614   1.1  christos 			fatal("%.200s line %d: Missing yes/no/ask argument.",
    615   1.1  christos 			    filename, linenum);
    616   1.1  christos 		value = 0;	/* To avoid compiler warning... */
    617   1.1  christos 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
    618   1.1  christos 			value = 1;
    619   1.1  christos 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
    620   1.1  christos 			value = 0;
    621   1.1  christos 		else if (strcmp(arg, "ask") == 0)
    622   1.1  christos 			value = 2;
    623   1.1  christos 		else
    624   1.1  christos 			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
    625   1.1  christos 		if (*activep && *intptr == -1)
    626   1.1  christos 			*intptr = value;
    627   1.1  christos 		break;
    628   1.1  christos 
    629   1.1  christos 	case oCompression:
    630   1.1  christos 		intptr = &options->compression;
    631   1.1  christos 		goto parse_flag;
    632   1.1  christos 
    633   1.1  christos 	case oTCPKeepAlive:
    634   1.1  christos 		intptr = &options->tcp_keep_alive;
    635   1.1  christos 		goto parse_flag;
    636   1.1  christos 
    637   1.1  christos 	case oNoHostAuthenticationForLocalhost:
    638   1.1  christos 		intptr = &options->no_host_authentication_for_localhost;
    639   1.1  christos 		goto parse_flag;
    640   1.1  christos 
    641   1.1  christos 	case oNumberOfPasswordPrompts:
    642   1.1  christos 		intptr = &options->number_of_password_prompts;
    643   1.1  christos 		goto parse_int;
    644   1.1  christos 
    645   1.1  christos 	case oCompressionLevel:
    646   1.1  christos 		intptr = &options->compression_level;
    647   1.1  christos 		goto parse_int;
    648   1.1  christos 
    649   1.1  christos 	case oRekeyLimit:
    650   1.1  christos 		arg = strdelim(&s);
    651   1.1  christos 		if (!arg || *arg == '\0')
    652  1.11  christos 			fatal("%.200s line %d: Missing argument.", filename,
    653  1.11  christos 			    linenum);
    654  1.11  christos 		if (strcmp(arg, "default") == 0) {
    655  1.11  christos 			val64 = 0;
    656  1.11  christos 		} else {
    657  1.11  christos 			if (scan_scaled(arg, &val64) == -1)
    658  1.11  christos 				fatal("%.200s line %d: Bad number '%s': %s",
    659  1.11  christos 				    filename, linenum, arg, strerror(errno));
    660  1.11  christos 			/* check for too-large or too-small limits */
    661  1.11  christos 			if (val64 > UINT_MAX)
    662  1.11  christos 				fatal("%.200s line %d: RekeyLimit too large",
    663  1.11  christos 				    filename, linenum);
    664  1.11  christos 			if (val64 != 0 && val64 < 16)
    665  1.11  christos 				fatal("%.200s line %d: RekeyLimit too small",
    666  1.11  christos 				    filename, linenum);
    667   1.1  christos 		}
    668   1.1  christos 		if (*activep && options->rekey_limit == -1)
    669   1.1  christos 			options->rekey_limit = (u_int32_t)val64;
    670  1.11  christos 		if (s != NULL) { /* optional rekey interval present */
    671  1.11  christos 			if (strcmp(s, "none") == 0) {
    672  1.11  christos 				(void)strdelim(&s);	/* discard */
    673  1.11  christos 				break;
    674  1.11  christos 			}
    675  1.11  christos 			intptr = &options->rekey_interval;
    676  1.11  christos 			goto parse_time;
    677  1.11  christos 		}
    678   1.1  christos 		break;
    679   1.1  christos 
    680   1.1  christos 	case oIdentityFile:
    681   1.1  christos 		arg = strdelim(&s);
    682   1.1  christos 		if (!arg || *arg == '\0')
    683   1.1  christos 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    684   1.1  christos 		if (*activep) {
    685   1.1  christos 			intptr = &options->num_identity_files;
    686   1.1  christos 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
    687   1.1  christos 				fatal("%.200s line %d: Too many identity files specified (max %d).",
    688   1.1  christos 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
    689   1.9   mlelstv 			add_identity_file(options, NULL, arg, userconfig);
    690   1.1  christos 		}
    691   1.1  christos 		break;
    692   1.1  christos 
    693   1.1  christos 	case oXAuthLocation:
    694   1.1  christos 		charptr=&options->xauth_location;
    695   1.1  christos 		goto parse_string;
    696   1.1  christos 
    697   1.1  christos 	case oUser:
    698   1.1  christos 		charptr = &options->user;
    699   1.1  christos parse_string:
    700   1.1  christos 		arg = strdelim(&s);
    701   1.1  christos 		if (!arg || *arg == '\0')
    702   1.6  christos 			fatal("%.200s line %d: Missing argument.",
    703   1.6  christos 			    filename, linenum);
    704   1.1  christos 		if (*activep && *charptr == NULL)
    705   1.1  christos 			*charptr = xstrdup(arg);
    706   1.1  christos 		break;
    707   1.1  christos 
    708   1.1  christos 	case oGlobalKnownHostsFile:
    709   1.6  christos 		cpptr = (char **)&options->system_hostfiles;
    710   1.6  christos 		uintptr = &options->num_system_hostfiles;
    711   1.6  christos 		max_entries = SSH_MAX_HOSTS_FILES;
    712   1.6  christos parse_char_array:
    713   1.6  christos 		if (*activep && *uintptr == 0) {
    714   1.6  christos 			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
    715   1.6  christos 				if ((*uintptr) >= max_entries)
    716   1.6  christos 					fatal("%s line %d: "
    717   1.6  christos 					    "too many authorized keys files.",
    718   1.6  christos 					    filename, linenum);
    719   1.6  christos 				cpptr[(*uintptr)++] = xstrdup(arg);
    720   1.6  christos 			}
    721   1.6  christos 		}
    722   1.6  christos 		return 0;
    723   1.1  christos 
    724   1.1  christos 	case oUserKnownHostsFile:
    725   1.6  christos 		cpptr = (char **)&options->user_hostfiles;
    726   1.6  christos 		uintptr = &options->num_user_hostfiles;
    727   1.6  christos 		max_entries = SSH_MAX_HOSTS_FILES;
    728   1.6  christos 		goto parse_char_array;
    729   1.1  christos 
    730   1.1  christos 	case oHostName:
    731   1.1  christos 		charptr = &options->hostname;
    732   1.1  christos 		goto parse_string;
    733   1.1  christos 
    734   1.1  christos 	case oHostKeyAlias:
    735   1.1  christos 		charptr = &options->host_key_alias;
    736   1.1  christos 		goto parse_string;
    737   1.1  christos 
    738   1.1  christos 	case oPreferredAuthentications:
    739   1.1  christos 		charptr = &options->preferred_authentications;
    740   1.1  christos 		goto parse_string;
    741   1.1  christos 
    742   1.1  christos 	case oBindAddress:
    743   1.1  christos 		charptr = &options->bind_address;
    744   1.1  christos 		goto parse_string;
    745   1.1  christos 
    746   1.4      adam 	case oPKCS11Provider:
    747   1.4      adam 		charptr = &options->pkcs11_provider;
    748   1.1  christos 		goto parse_string;
    749   1.1  christos 
    750   1.1  christos 	case oProxyCommand:
    751   1.1  christos 		charptr = &options->proxy_command;
    752   1.1  christos parse_command:
    753   1.1  christos 		if (s == NULL)
    754   1.1  christos 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    755   1.1  christos 		len = strspn(s, WHITESPACE "=");
    756   1.1  christos 		if (*activep && *charptr == NULL)
    757   1.1  christos 			*charptr = xstrdup(s + len);
    758   1.1  christos 		return 0;
    759   1.1  christos 
    760   1.1  christos 	case oPort:
    761   1.1  christos 		intptr = &options->port;
    762   1.1  christos parse_int:
    763   1.1  christos 		arg = strdelim(&s);
    764   1.1  christos 		if (!arg || *arg == '\0')
    765   1.1  christos 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    766   1.1  christos 		if (arg[0] < '0' || arg[0] > '9')
    767   1.1  christos 			fatal("%.200s line %d: Bad number.", filename, linenum);
    768   1.1  christos 
    769   1.1  christos 		/* Octal, decimal, or hex format? */
    770   1.1  christos 		value = strtol(arg, &endofnumber, 0);
    771   1.1  christos 		if (arg == endofnumber)
    772   1.1  christos 			fatal("%.200s line %d: Bad number.", filename, linenum);
    773   1.1  christos 		if (*activep && *intptr == -1)
    774   1.1  christos 			*intptr = value;
    775   1.1  christos 		break;
    776   1.1  christos 
    777   1.1  christos 	case oConnectionAttempts:
    778   1.1  christos 		intptr = &options->connection_attempts;
    779   1.1  christos 		goto parse_int;
    780   1.1  christos 
    781   1.2  christos 	case oTcpRcvBuf:
    782   1.2  christos 		intptr = &options->tcp_rcv_buf;
    783   1.2  christos 		goto parse_int;
    784   1.2  christos 
    785   1.1  christos 	case oCipher:
    786   1.1  christos 		intptr = &options->cipher;
    787   1.1  christos 		arg = strdelim(&s);
    788   1.1  christos 		if (!arg || *arg == '\0')
    789   1.1  christos 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    790   1.1  christos 		value = cipher_number(arg);
    791   1.1  christos 		if (value == -1)
    792   1.1  christos 			fatal("%.200s line %d: Bad cipher '%s'.",
    793   1.1  christos 			    filename, linenum, arg ? arg : "<NONE>");
    794   1.1  christos 		if (*activep && *intptr == -1)
    795   1.1  christos 			*intptr = value;
    796   1.1  christos 		break;
    797   1.1  christos 
    798   1.1  christos 	case oCiphers:
    799   1.1  christos 		arg = strdelim(&s);
    800   1.1  christos 		if (!arg || *arg == '\0')
    801   1.1  christos 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    802   1.1  christos 		if (!ciphers_valid(arg))
    803   1.1  christos 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
    804   1.1  christos 			    filename, linenum, arg ? arg : "<NONE>");
    805   1.1  christos 		if (*activep && options->ciphers == NULL)
    806   1.1  christos 			options->ciphers = xstrdup(arg);
    807   1.1  christos 		break;
    808   1.1  christos 
    809   1.1  christos 	case oMacs:
    810   1.1  christos 		arg = strdelim(&s);
    811   1.1  christos 		if (!arg || *arg == '\0')
    812   1.1  christos 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    813   1.1  christos 		if (!mac_valid(arg))
    814   1.1  christos 			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
    815   1.1  christos 			    filename, linenum, arg ? arg : "<NONE>");
    816   1.1  christos 		if (*activep && options->macs == NULL)
    817   1.1  christos 			options->macs = xstrdup(arg);
    818   1.1  christos 		break;
    819   1.1  christos 
    820   1.5  christos 	case oKexAlgorithms:
    821   1.5  christos 		arg = strdelim(&s);
    822   1.5  christos 		if (!arg || *arg == '\0')
    823   1.5  christos 			fatal("%.200s line %d: Missing argument.",
    824   1.5  christos 			    filename, linenum);
    825   1.5  christos 		if (!kex_names_valid(arg))
    826   1.5  christos 			fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
    827   1.5  christos 			    filename, linenum, arg ? arg : "<NONE>");
    828   1.5  christos 		if (*activep && options->kex_algorithms == NULL)
    829   1.5  christos 			options->kex_algorithms = xstrdup(arg);
    830   1.5  christos 		break;
    831   1.5  christos 
    832   1.1  christos 	case oHostKeyAlgorithms:
    833   1.1  christos 		arg = strdelim(&s);
    834   1.1  christos 		if (!arg || *arg == '\0')
    835   1.1  christos 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    836   1.1  christos 		if (!key_names_valid2(arg))
    837   1.1  christos 			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
    838   1.1  christos 			    filename, linenum, arg ? arg : "<NONE>");
    839   1.1  christos 		if (*activep && options->hostkeyalgorithms == NULL)
    840   1.1  christos 			options->hostkeyalgorithms = xstrdup(arg);
    841   1.1  christos 		break;
    842   1.1  christos 
    843   1.1  christos 	case oProtocol:
    844   1.1  christos 		intptr = &options->protocol;
    845   1.1  christos 		arg = strdelim(&s);
    846   1.1  christos 		if (!arg || *arg == '\0')
    847   1.1  christos 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    848   1.1  christos 		value = proto_spec(arg);
    849   1.1  christos 		if (value == SSH_PROTO_UNKNOWN)
    850   1.1  christos 			fatal("%.200s line %d: Bad protocol spec '%s'.",
    851   1.1  christos 			    filename, linenum, arg ? arg : "<NONE>");
    852   1.1  christos 		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
    853   1.1  christos 			*intptr = value;
    854   1.1  christos 		break;
    855   1.1  christos 
    856   1.1  christos 	case oLogLevel:
    857   1.1  christos 		log_level_ptr = &options->log_level;
    858   1.1  christos 		arg = strdelim(&s);
    859   1.1  christos 		value = log_level_number(arg);
    860   1.1  christos 		if (value == SYSLOG_LEVEL_NOT_SET)
    861   1.1  christos 			fatal("%.200s line %d: unsupported log level '%s'",
    862   1.1  christos 			    filename, linenum, arg ? arg : "<NONE>");
    863   1.1  christos 		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
    864   1.1  christos 			*log_level_ptr = (LogLevel) value;
    865   1.1  christos 		break;
    866   1.1  christos 
    867   1.1  christos 	case oLocalForward:
    868   1.1  christos 	case oRemoteForward:
    869   1.1  christos 	case oDynamicForward:
    870   1.1  christos 		arg = strdelim(&s);
    871   1.1  christos 		if (arg == NULL || *arg == '\0')
    872   1.1  christos 			fatal("%.200s line %d: Missing port argument.",
    873   1.1  christos 			    filename, linenum);
    874   1.1  christos 
    875   1.1  christos 		if (opcode == oLocalForward ||
    876   1.1  christos 		    opcode == oRemoteForward) {
    877   1.1  christos 			arg2 = strdelim(&s);
    878   1.1  christos 			if (arg2 == NULL || *arg2 == '\0')
    879   1.1  christos 				fatal("%.200s line %d: Missing target argument.",
    880   1.1  christos 				    filename, linenum);
    881   1.1  christos 
    882   1.1  christos 			/* construct a string for parse_forward */
    883   1.1  christos 			snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
    884   1.1  christos 		} else if (opcode == oDynamicForward) {
    885   1.1  christos 			strlcpy(fwdarg, arg, sizeof(fwdarg));
    886   1.1  christos 		}
    887   1.1  christos 
    888   1.1  christos 		if (parse_forward(&fwd, fwdarg,
    889   1.1  christos 		    opcode == oDynamicForward ? 1 : 0,
    890   1.1  christos 		    opcode == oRemoteForward ? 1 : 0) == 0)
    891   1.1  christos 			fatal("%.200s line %d: Bad forwarding specification.",
    892   1.1  christos 			    filename, linenum);
    893   1.1  christos 
    894   1.1  christos 		if (*activep) {
    895   1.1  christos 			if (opcode == oLocalForward ||
    896   1.1  christos 			    opcode == oDynamicForward)
    897   1.1  christos 				add_local_forward(options, &fwd);
    898   1.1  christos 			else if (opcode == oRemoteForward)
    899   1.1  christos 				add_remote_forward(options, &fwd);
    900   1.1  christos 		}
    901   1.1  christos 		break;
    902   1.1  christos 
    903   1.1  christos 	case oClearAllForwardings:
    904   1.1  christos 		intptr = &options->clear_forwardings;
    905   1.1  christos 		goto parse_flag;
    906   1.1  christos 
    907   1.1  christos 	case oHost:
    908   1.1  christos 		*activep = 0;
    909   1.6  christos 		arg2 = NULL;
    910   1.6  christos 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
    911   1.6  christos 			negated = *arg == '!';
    912   1.6  christos 			if (negated)
    913   1.6  christos 				arg++;
    914   1.1  christos 			if (match_pattern(host, arg)) {
    915   1.6  christos 				if (negated) {
    916   1.6  christos 					debug("%.200s line %d: Skipping Host "
    917   1.6  christos 					    "block because of negated match "
    918   1.6  christos 					    "for %.100s", filename, linenum,
    919   1.6  christos 					    arg);
    920   1.6  christos 					*activep = 0;
    921   1.6  christos 					break;
    922   1.6  christos 				}
    923   1.6  christos 				if (!*activep)
    924   1.6  christos 					arg2 = arg; /* logged below */
    925   1.1  christos 				*activep = 1;
    926   1.1  christos 			}
    927   1.6  christos 		}
    928   1.6  christos 		if (*activep)
    929   1.6  christos 			debug("%.200s line %d: Applying options for %.100s",
    930   1.6  christos 			    filename, linenum, arg2);
    931   1.1  christos 		/* Avoid garbage check below, as strdelim is done. */
    932   1.1  christos 		return 0;
    933   1.1  christos 
    934   1.1  christos 	case oEscapeChar:
    935   1.1  christos 		intptr = &options->escape_char;
    936   1.1  christos 		arg = strdelim(&s);
    937   1.1  christos 		if (!arg || *arg == '\0')
    938   1.1  christos 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    939   1.2  christos 		value = 0;	/* To avoid compiler warning... */
    940   1.1  christos 		if (arg[0] == '^' && arg[2] == 0 &&
    941   1.1  christos 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
    942   1.1  christos 			value = (u_char) arg[1] & 31;
    943   1.1  christos 		else if (strlen(arg) == 1)
    944   1.1  christos 			value = (u_char) arg[0];
    945   1.1  christos 		else if (strcmp(arg, "none") == 0)
    946   1.1  christos 			value = SSH_ESCAPECHAR_NONE;
    947   1.1  christos 		else {
    948   1.1  christos 			fatal("%.200s line %d: Bad escape character.",
    949   1.1  christos 			    filename, linenum);
    950   1.1  christos 			/* NOTREACHED */
    951   1.1  christos 			value = 0;	/* Avoid compiler warning. */
    952   1.1  christos 		}
    953   1.1  christos 		if (*activep && *intptr == -1)
    954   1.1  christos 			*intptr = value;
    955   1.1  christos 		break;
    956   1.1  christos 
    957   1.1  christos 	case oAddressFamily:
    958   1.1  christos 		arg = strdelim(&s);
    959   1.1  christos 		if (!arg || *arg == '\0')
    960   1.1  christos 			fatal("%s line %d: missing address family.",
    961   1.1  christos 			    filename, linenum);
    962   1.1  christos 		intptr = &options->address_family;
    963   1.2  christos 		value = 0;	/* To avoid compiler warning... */
    964   1.1  christos 		if (strcasecmp(arg, "inet") == 0)
    965   1.1  christos 			value = AF_INET;
    966   1.1  christos 		else if (strcasecmp(arg, "inet6") == 0)
    967   1.1  christos 			value = AF_INET6;
    968   1.1  christos 		else if (strcasecmp(arg, "any") == 0)
    969   1.1  christos 			value = AF_UNSPEC;
    970   1.1  christos 		else
    971   1.1  christos 			fatal("Unsupported AddressFamily \"%s\"", arg);
    972   1.1  christos 		if (*activep && *intptr == -1)
    973   1.1  christos 			*intptr = value;
    974   1.1  christos 		break;
    975   1.1  christos 
    976   1.1  christos 	case oEnableSSHKeysign:
    977   1.1  christos 		intptr = &options->enable_ssh_keysign;
    978   1.1  christos 		goto parse_flag;
    979   1.1  christos 
    980   1.1  christos 	case oIdentitiesOnly:
    981   1.1  christos 		intptr = &options->identities_only;
    982   1.1  christos 		goto parse_flag;
    983   1.1  christos 
    984   1.1  christos 	case oServerAliveInterval:
    985   1.1  christos 		intptr = &options->server_alive_interval;
    986   1.1  christos 		goto parse_time;
    987   1.1  christos 
    988   1.1  christos 	case oServerAliveCountMax:
    989   1.1  christos 		intptr = &options->server_alive_count_max;
    990   1.1  christos 		goto parse_int;
    991   1.1  christos 
    992   1.1  christos 	case oSendEnv:
    993   1.1  christos 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
    994   1.1  christos 			if (strchr(arg, '=') != NULL)
    995   1.1  christos 				fatal("%s line %d: Invalid environment name.",
    996   1.1  christos 				    filename, linenum);
    997   1.1  christos 			if (!*activep)
    998   1.1  christos 				continue;
    999   1.1  christos 			if (options->num_send_env >= MAX_SEND_ENV)
   1000   1.1  christos 				fatal("%s line %d: too many send env.",
   1001   1.1  christos 				    filename, linenum);
   1002   1.1  christos 			options->send_env[options->num_send_env++] =
   1003   1.1  christos 			    xstrdup(arg);
   1004   1.1  christos 		}
   1005   1.1  christos 		break;
   1006   1.1  christos 
   1007   1.1  christos 	case oControlPath:
   1008   1.1  christos 		charptr = &options->control_path;
   1009   1.1  christos 		goto parse_string;
   1010   1.1  christos 
   1011   1.1  christos 	case oControlMaster:
   1012   1.1  christos 		intptr = &options->control_master;
   1013   1.1  christos 		arg = strdelim(&s);
   1014   1.1  christos 		if (!arg || *arg == '\0')
   1015   1.1  christos 			fatal("%.200s line %d: Missing ControlMaster argument.",
   1016   1.1  christos 			    filename, linenum);
   1017   1.1  christos 		value = 0;	/* To avoid compiler warning... */
   1018   1.1  christos 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
   1019   1.1  christos 			value = SSHCTL_MASTER_YES;
   1020   1.1  christos 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
   1021   1.1  christos 			value = SSHCTL_MASTER_NO;
   1022   1.1  christos 		else if (strcmp(arg, "auto") == 0)
   1023   1.1  christos 			value = SSHCTL_MASTER_AUTO;
   1024   1.1  christos 		else if (strcmp(arg, "ask") == 0)
   1025   1.1  christos 			value = SSHCTL_MASTER_ASK;
   1026   1.1  christos 		else if (strcmp(arg, "autoask") == 0)
   1027   1.1  christos 			value = SSHCTL_MASTER_AUTO_ASK;
   1028   1.1  christos 		else
   1029   1.1  christos 			fatal("%.200s line %d: Bad ControlMaster argument.",
   1030   1.1  christos 			    filename, linenum);
   1031   1.1  christos 		if (*activep && *intptr == -1)
   1032   1.1  christos 			*intptr = value;
   1033   1.1  christos 		break;
   1034   1.1  christos 
   1035   1.4      adam 	case oControlPersist:
   1036   1.4      adam 		/* no/false/yes/true, or a time spec */
   1037   1.4      adam 		intptr = &options->control_persist;
   1038   1.4      adam 		arg = strdelim(&s);
   1039   1.4      adam 		if (!arg || *arg == '\0')
   1040   1.4      adam 			fatal("%.200s line %d: Missing ControlPersist"
   1041   1.4      adam 			    " argument.", filename, linenum);
   1042   1.4      adam 		value = 0;
   1043   1.4      adam 		value2 = 0;	/* timeout */
   1044   1.4      adam 		if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
   1045   1.4      adam 			value = 0;
   1046   1.4      adam 		else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
   1047   1.4      adam 			value = 1;
   1048   1.4      adam 		else if ((value2 = convtime(arg)) >= 0)
   1049   1.4      adam 			value = 1;
   1050   1.4      adam 		else
   1051   1.4      adam 			fatal("%.200s line %d: Bad ControlPersist argument.",
   1052   1.4      adam 			    filename, linenum);
   1053   1.4      adam 		if (*activep && *intptr == -1) {
   1054   1.4      adam 			*intptr = value;
   1055   1.4      adam 			options->control_persist_timeout = value2;
   1056   1.4      adam 		}
   1057   1.4      adam 		break;
   1058   1.4      adam 
   1059   1.1  christos 	case oHashKnownHosts:
   1060   1.1  christos 		intptr = &options->hash_known_hosts;
   1061   1.1  christos 		goto parse_flag;
   1062   1.1  christos 
   1063   1.1  christos 	case oTunnel:
   1064   1.1  christos 		intptr = &options->tun_open;
   1065   1.1  christos 		arg = strdelim(&s);
   1066   1.1  christos 		if (!arg || *arg == '\0')
   1067   1.1  christos 			fatal("%s line %d: Missing yes/point-to-point/"
   1068   1.1  christos 			    "ethernet/no argument.", filename, linenum);
   1069   1.1  christos 		value = 0;	/* silence compiler */
   1070   1.1  christos 		if (strcasecmp(arg, "ethernet") == 0)
   1071   1.1  christos 			value = SSH_TUNMODE_ETHERNET;
   1072   1.1  christos 		else if (strcasecmp(arg, "point-to-point") == 0)
   1073   1.1  christos 			value = SSH_TUNMODE_POINTOPOINT;
   1074   1.1  christos 		else if (strcasecmp(arg, "yes") == 0)
   1075   1.1  christos 			value = SSH_TUNMODE_DEFAULT;
   1076   1.1  christos 		else if (strcasecmp(arg, "no") == 0)
   1077   1.1  christos 			value = SSH_TUNMODE_NO;
   1078   1.1  christos 		else
   1079   1.1  christos 			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
   1080   1.1  christos 			    "no argument: %s", filename, linenum, arg);
   1081   1.1  christos 		if (*activep)
   1082   1.1  christos 			*intptr = value;
   1083   1.1  christos 		break;
   1084   1.1  christos 
   1085   1.1  christos 	case oTunnelDevice:
   1086   1.1  christos 		arg = strdelim(&s);
   1087   1.1  christos 		if (!arg || *arg == '\0')
   1088   1.1  christos 			fatal("%.200s line %d: Missing argument.", filename, linenum);
   1089   1.1  christos 		value = a2tun(arg, &value2);
   1090   1.1  christos 		if (value == SSH_TUNID_ERR)
   1091   1.1  christos 			fatal("%.200s line %d: Bad tun device.", filename, linenum);
   1092   1.1  christos 		if (*activep) {
   1093   1.1  christos 			options->tun_local = value;
   1094   1.1  christos 			options->tun_remote = value2;
   1095   1.1  christos 		}
   1096   1.1  christos 		break;
   1097   1.1  christos 
   1098   1.1  christos 	case oLocalCommand:
   1099   1.1  christos 		charptr = &options->local_command;
   1100   1.1  christos 		goto parse_command;
   1101   1.1  christos 
   1102   1.1  christos 	case oPermitLocalCommand:
   1103   1.1  christos 		intptr = &options->permit_local_command;
   1104   1.1  christos 		goto parse_flag;
   1105   1.1  christos 
   1106   1.1  christos 	case oVisualHostKey:
   1107   1.1  christos 		intptr = &options->visual_host_key;
   1108   1.1  christos 		goto parse_flag;
   1109   1.1  christos 
   1110   1.5  christos 	case oIPQoS:
   1111   1.5  christos 		arg = strdelim(&s);
   1112   1.5  christos 		if ((value = parse_ipqos(arg)) == -1)
   1113   1.5  christos 			fatal("%s line %d: Bad IPQoS value: %s",
   1114   1.5  christos 			    filename, linenum, arg);
   1115   1.5  christos 		arg = strdelim(&s);
   1116   1.5  christos 		if (arg == NULL)
   1117   1.5  christos 			value2 = value;
   1118   1.5  christos 		else if ((value2 = parse_ipqos(arg)) == -1)
   1119   1.5  christos 			fatal("%s line %d: Bad IPQoS value: %s",
   1120   1.5  christos 			    filename, linenum, arg);
   1121   1.5  christos 		if (*activep) {
   1122   1.5  christos 			options->ip_qos_interactive = value;
   1123   1.5  christos 			options->ip_qos_bulk = value2;
   1124   1.5  christos 		}
   1125   1.5  christos 		break;
   1126   1.5  christos 
   1127   1.3  christos 	case oUseRoaming:
   1128   1.3  christos 		intptr = &options->use_roaming;
   1129   1.3  christos 		goto parse_flag;
   1130   1.3  christos 
   1131   1.6  christos 	case oRequestTTY:
   1132   1.6  christos 		arg = strdelim(&s);
   1133   1.6  christos 		if (!arg || *arg == '\0')
   1134   1.6  christos 			fatal("%s line %d: missing argument.",
   1135   1.6  christos 			    filename, linenum);
   1136   1.6  christos 		intptr = &options->request_tty;
   1137   1.6  christos 		if (strcasecmp(arg, "yes") == 0)
   1138   1.6  christos 			value = REQUEST_TTY_YES;
   1139   1.6  christos 		else if (strcasecmp(arg, "no") == 0)
   1140   1.6  christos 			value = REQUEST_TTY_NO;
   1141   1.6  christos 		else if (strcasecmp(arg, "force") == 0)
   1142   1.6  christos 			value = REQUEST_TTY_FORCE;
   1143   1.6  christos 		else if (strcasecmp(arg, "auto") == 0)
   1144   1.6  christos 			value = REQUEST_TTY_AUTO;
   1145   1.6  christos 		else
   1146   1.6  christos 			fatal("Unsupported RequestTTY \"%s\"", arg);
   1147   1.6  christos 		if (*activep && *intptr == -1)
   1148   1.6  christos 			*intptr = value;
   1149   1.6  christos 		break;
   1150   1.6  christos 
   1151   1.7       tls 	case oSendVersionFirst:
   1152   1.7       tls 		intptr = &options->send_version_first;
   1153   1.7       tls 		goto parse_flag;
   1154   1.7       tls 
   1155  1.11  christos 	case oIgnoreUnknown:
   1156  1.11  christos 		charptr = &options->ignored_unknown;
   1157  1.11  christos 		goto parse_string;
   1158  1.11  christos 
   1159   1.1  christos 	case oDeprecated:
   1160   1.1  christos 		debug("%s line %d: Deprecated option \"%s\"",
   1161   1.1  christos 		    filename, linenum, keyword);
   1162   1.1  christos 		return 0;
   1163   1.1  christos 
   1164   1.1  christos 	case oUnsupported:
   1165   1.1  christos 		error("%s line %d: Unsupported option \"%s\"",
   1166   1.1  christos 		    filename, linenum, keyword);
   1167   1.1  christos 		return 0;
   1168   1.1  christos 
   1169   1.1  christos 	default:
   1170   1.1  christos 		fatal("process_config_line: Unimplemented opcode %d", opcode);
   1171   1.1  christos 	}
   1172   1.1  christos 
   1173   1.1  christos 	/* Check that there is no garbage at end of line. */
   1174   1.1  christos 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
   1175   1.1  christos 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
   1176   1.1  christos 		    filename, linenum, arg);
   1177   1.1  christos 	}
   1178   1.1  christos 	return 0;
   1179   1.1  christos }
   1180   1.1  christos 
   1181   1.1  christos 
   1182   1.1  christos /*
   1183   1.1  christos  * Reads the config file and modifies the options accordingly.  Options
   1184   1.1  christos  * should already be initialized before this call.  This never returns if
   1185   1.1  christos  * there is an error.  If the file does not exist, this returns 0.
   1186   1.1  christos  */
   1187   1.1  christos 
   1188   1.1  christos int
   1189   1.1  christos read_config_file(const char *filename, const char *host, Options *options,
   1190   1.9   mlelstv     int flags)
   1191   1.1  christos {
   1192   1.1  christos 	FILE *f;
   1193   1.1  christos 	char line[1024];
   1194   1.1  christos 	int active, linenum;
   1195   1.1  christos 	int bad_options = 0;
   1196   1.1  christos 
   1197   1.1  christos 	if ((f = fopen(filename, "r")) == NULL)
   1198   1.1  christos 		return 0;
   1199   1.1  christos 
   1200   1.9   mlelstv 	if (flags & SSHCONF_CHECKPERM) {
   1201   1.1  christos 		struct stat sb;
   1202   1.1  christos 
   1203   1.1  christos 		if (fstat(fileno(f), &sb) == -1)
   1204   1.1  christos 			fatal("fstat %s: %s", filename, strerror(errno));
   1205   1.1  christos 		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
   1206   1.1  christos 		    (sb.st_mode & 022) != 0))
   1207   1.1  christos 			fatal("Bad owner or permissions on %s", filename);
   1208   1.1  christos 	}
   1209   1.1  christos 
   1210   1.1  christos 	debug("Reading configuration data %.200s", filename);
   1211   1.1  christos 
   1212   1.1  christos 	/*
   1213   1.1  christos 	 * Mark that we are now processing the options.  This flag is turned
   1214   1.1  christos 	 * on/off by Host specifications.
   1215   1.1  christos 	 */
   1216   1.1  christos 	active = 1;
   1217   1.1  christos 	linenum = 0;
   1218   1.1  christos 	while (fgets(line, sizeof(line), f)) {
   1219   1.1  christos 		/* Update line number counter. */
   1220   1.1  christos 		linenum++;
   1221   1.9   mlelstv 		if (process_config_line(options, host, line, filename, linenum,
   1222   1.9   mlelstv 		    &active, flags & SSHCONF_USERCONF) != 0)
   1223   1.1  christos 			bad_options++;
   1224   1.1  christos 	}
   1225   1.1  christos 	fclose(f);
   1226   1.1  christos 	if (bad_options > 0)
   1227   1.1  christos 		fatal("%s: terminating, %d bad configuration options",
   1228   1.1  christos 		    filename, bad_options);
   1229   1.1  christos 	return 1;
   1230   1.1  christos }
   1231   1.1  christos 
   1232   1.1  christos /*
   1233   1.1  christos  * Initializes options to special values that indicate that they have not yet
   1234   1.1  christos  * been set.  Read_config_file will only set options with this value. Options
   1235   1.1  christos  * are processed in the following order: command line, user config file,
   1236   1.1  christos  * system config file.  Last, fill_default_options is called.
   1237   1.1  christos  */
   1238   1.1  christos 
   1239   1.1  christos void
   1240   1.1  christos initialize_options(Options * options)
   1241   1.1  christos {
   1242   1.1  christos 	memset(options, 'X', sizeof(*options));
   1243   1.1  christos 	options->forward_agent = -1;
   1244   1.1  christos 	options->forward_x11 = -1;
   1245   1.1  christos 	options->forward_x11_trusted = -1;
   1246   1.4      adam 	options->forward_x11_timeout = -1;
   1247   1.1  christos 	options->exit_on_forward_failure = -1;
   1248   1.1  christos 	options->xauth_location = NULL;
   1249   1.1  christos 	options->gateway_ports = -1;
   1250   1.1  christos 	options->use_privileged_port = -1;
   1251   1.1  christos 	options->rsa_authentication = -1;
   1252   1.1  christos 	options->pubkey_authentication = -1;
   1253   1.1  christos 	options->challenge_response_authentication = -1;
   1254   1.2  christos #if defined(KRB4) || defined(KRB5)
   1255   1.2  christos 	options->kerberos_authentication = -1;
   1256   1.2  christos #endif
   1257   1.2  christos #if defined(AFS) || defined(KRB5)
   1258   1.2  christos 	options->kerberos_tgt_passing = -1;
   1259   1.2  christos #endif
   1260   1.2  christos #ifdef AFS
   1261   1.2  christos 	options->afs_token_passing = -1;
   1262   1.2  christos #endif
   1263   1.1  christos 	options->gss_authentication = -1;
   1264   1.1  christos 	options->gss_deleg_creds = -1;
   1265   1.1  christos 	options->password_authentication = -1;
   1266   1.1  christos 	options->kbd_interactive_authentication = -1;
   1267   1.1  christos 	options->kbd_interactive_devices = NULL;
   1268   1.1  christos 	options->rhosts_rsa_authentication = -1;
   1269   1.1  christos 	options->hostbased_authentication = -1;
   1270   1.1  christos 	options->batch_mode = -1;
   1271   1.1  christos 	options->check_host_ip = -1;
   1272   1.1  christos 	options->strict_host_key_checking = -1;
   1273   1.1  christos 	options->compression = -1;
   1274   1.1  christos 	options->tcp_keep_alive = -1;
   1275   1.1  christos 	options->compression_level = -1;
   1276   1.1  christos 	options->port = -1;
   1277   1.1  christos 	options->address_family = -1;
   1278   1.1  christos 	options->connection_attempts = -1;
   1279   1.1  christos 	options->connection_timeout = -1;
   1280   1.1  christos 	options->number_of_password_prompts = -1;
   1281   1.1  christos 	options->cipher = -1;
   1282   1.1  christos 	options->ciphers = NULL;
   1283   1.1  christos 	options->macs = NULL;
   1284   1.5  christos 	options->kex_algorithms = NULL;
   1285   1.1  christos 	options->hostkeyalgorithms = NULL;
   1286   1.1  christos 	options->protocol = SSH_PROTO_UNKNOWN;
   1287   1.1  christos 	options->num_identity_files = 0;
   1288   1.1  christos 	options->hostname = NULL;
   1289   1.1  christos 	options->host_key_alias = NULL;
   1290   1.1  christos 	options->proxy_command = NULL;
   1291   1.1  christos 	options->user = NULL;
   1292   1.1  christos 	options->escape_char = -1;
   1293   1.6  christos 	options->num_system_hostfiles = 0;
   1294   1.6  christos 	options->num_user_hostfiles = 0;
   1295   1.4      adam 	options->local_forwards = NULL;
   1296   1.1  christos 	options->num_local_forwards = 0;
   1297   1.4      adam 	options->remote_forwards = NULL;
   1298   1.1  christos 	options->num_remote_forwards = 0;
   1299   1.1  christos 	options->clear_forwardings = -1;
   1300   1.1  christos 	options->log_level = SYSLOG_LEVEL_NOT_SET;
   1301   1.1  christos 	options->preferred_authentications = NULL;
   1302   1.1  christos 	options->bind_address = NULL;
   1303   1.4      adam 	options->pkcs11_provider = NULL;
   1304   1.1  christos 	options->enable_ssh_keysign = - 1;
   1305   1.1  christos 	options->no_host_authentication_for_localhost = - 1;
   1306   1.1  christos 	options->identities_only = - 1;
   1307   1.1  christos 	options->rekey_limit = - 1;
   1308  1.11  christos 	options->rekey_interval = -1;
   1309   1.1  christos 	options->verify_host_key_dns = -1;
   1310   1.1  christos 	options->server_alive_interval = -1;
   1311   1.1  christos 	options->server_alive_count_max = -1;
   1312   1.1  christos 	options->num_send_env = 0;
   1313   1.1  christos 	options->control_path = NULL;
   1314   1.1  christos 	options->control_master = -1;
   1315   1.4      adam 	options->control_persist = -1;
   1316   1.4      adam 	options->control_persist_timeout = 0;
   1317   1.1  christos 	options->hash_known_hosts = -1;
   1318   1.1  christos 	options->tun_open = -1;
   1319   1.1  christos 	options->tun_local = -1;
   1320   1.1  christos 	options->tun_remote = -1;
   1321   1.1  christos 	options->local_command = NULL;
   1322   1.1  christos 	options->permit_local_command = -1;
   1323   1.3  christos 	options->use_roaming = -1;
   1324   1.1  christos 	options->visual_host_key = -1;
   1325   1.1  christos 	options->zero_knowledge_password_authentication = -1;
   1326   1.5  christos 	options->ip_qos_interactive = -1;
   1327   1.5  christos 	options->ip_qos_bulk = -1;
   1328   1.6  christos 	options->request_tty = -1;
   1329  1.11  christos 	options->ignored_unknown = NULL;
   1330   1.2  christos 	options->none_switch = -1;
   1331   1.2  christos 	options->none_enabled = -1;
   1332   1.2  christos 	options->hpn_disabled = -1;
   1333   1.2  christos 	options->hpn_buffer_size = -1;
   1334   1.2  christos 	options->tcp_rcv_buf_poll = -1;
   1335   1.2  christos 	options->tcp_rcv_buf = -1;
   1336   1.7       tls 	options->send_version_first = -1;
   1337   1.1  christos }
   1338   1.1  christos 
   1339   1.1  christos /*
   1340   1.1  christos  * Called after processing other sources of option data, this fills those
   1341   1.1  christos  * options for which no value has been specified with their default values.
   1342   1.1  christos  */
   1343   1.1  christos 
   1344   1.1  christos void
   1345   1.1  christos fill_default_options(Options * options)
   1346   1.1  christos {
   1347   1.1  christos 	if (options->forward_agent == -1)
   1348   1.1  christos 		options->forward_agent = 0;
   1349   1.1  christos 	if (options->forward_x11 == -1)
   1350   1.1  christos 		options->forward_x11 = 0;
   1351   1.1  christos 	if (options->forward_x11_trusted == -1)
   1352   1.1  christos 		options->forward_x11_trusted = 0;
   1353   1.4      adam 	if (options->forward_x11_timeout == -1)
   1354   1.4      adam 		options->forward_x11_timeout = 1200;
   1355   1.1  christos 	if (options->exit_on_forward_failure == -1)
   1356   1.1  christos 		options->exit_on_forward_failure = 0;
   1357   1.1  christos 	if (options->xauth_location == NULL)
   1358   1.5  christos 		options->xauth_location = __UNCONST(_PATH_XAUTH);
   1359   1.1  christos 	if (options->gateway_ports == -1)
   1360   1.1  christos 		options->gateway_ports = 0;
   1361   1.1  christos 	if (options->use_privileged_port == -1)
   1362   1.1  christos 		options->use_privileged_port = 0;
   1363   1.1  christos 	if (options->rsa_authentication == -1)
   1364   1.1  christos 		options->rsa_authentication = 1;
   1365   1.1  christos 	if (options->pubkey_authentication == -1)
   1366   1.1  christos 		options->pubkey_authentication = 1;
   1367   1.1  christos 	if (options->challenge_response_authentication == -1)
   1368   1.1  christos 		options->challenge_response_authentication = 1;
   1369   1.2  christos #if defined(KRB4) || defined(KRB5)
   1370   1.2  christos 	if (options->kerberos_authentication == -1)
   1371   1.2  christos 		options->kerberos_authentication = 1;
   1372   1.2  christos #endif
   1373   1.2  christos #if defined(AFS) || defined(KRB5)
   1374   1.2  christos 	if (options->kerberos_tgt_passing == -1)
   1375   1.2  christos 		options->kerberos_tgt_passing = 1;
   1376   1.2  christos #endif
   1377   1.2  christos #ifdef AFS
   1378   1.2  christos 	if (options->afs_token_passing == -1)
   1379   1.2  christos 		options->afs_token_passing = 1;
   1380   1.2  christos #endif
   1381   1.1  christos 	if (options->gss_authentication == -1)
   1382   1.1  christos 		options->gss_authentication = 0;
   1383   1.1  christos 	if (options->gss_deleg_creds == -1)
   1384   1.1  christos 		options->gss_deleg_creds = 0;
   1385   1.1  christos 	if (options->password_authentication == -1)
   1386   1.1  christos 		options->password_authentication = 1;
   1387   1.1  christos 	if (options->kbd_interactive_authentication == -1)
   1388   1.1  christos 		options->kbd_interactive_authentication = 1;
   1389   1.1  christos 	if (options->rhosts_rsa_authentication == -1)
   1390   1.1  christos 		options->rhosts_rsa_authentication = 0;
   1391   1.1  christos 	if (options->hostbased_authentication == -1)
   1392   1.1  christos 		options->hostbased_authentication = 0;
   1393   1.1  christos 	if (options->batch_mode == -1)
   1394   1.1  christos 		options->batch_mode = 0;
   1395   1.1  christos 	if (options->check_host_ip == -1)
   1396   1.1  christos 		options->check_host_ip = 1;
   1397   1.1  christos 	if (options->strict_host_key_checking == -1)
   1398   1.1  christos 		options->strict_host_key_checking = 2;	/* 2 is default */
   1399   1.1  christos 	if (options->compression == -1)
   1400   1.1  christos 		options->compression = 0;
   1401   1.1  christos 	if (options->tcp_keep_alive == -1)
   1402   1.1  christos 		options->tcp_keep_alive = 1;
   1403   1.1  christos 	if (options->compression_level == -1)
   1404   1.1  christos 		options->compression_level = 6;
   1405   1.1  christos 	if (options->port == -1)
   1406   1.1  christos 		options->port = 0;	/* Filled in ssh_connect. */
   1407   1.1  christos 	if (options->address_family == -1)
   1408   1.1  christos 		options->address_family = AF_UNSPEC;
   1409   1.1  christos 	if (options->connection_attempts == -1)
   1410   1.1  christos 		options->connection_attempts = 1;
   1411   1.1  christos 	if (options->number_of_password_prompts == -1)
   1412   1.1  christos 		options->number_of_password_prompts = 3;
   1413   1.1  christos 	/* Selected in ssh_login(). */
   1414   1.1  christos 	if (options->cipher == -1)
   1415   1.1  christos 		options->cipher = SSH_CIPHER_NOT_SET;
   1416   1.1  christos 	/* options->ciphers, default set in myproposals.h */
   1417   1.1  christos 	/* options->macs, default set in myproposals.h */
   1418   1.5  christos 	/* options->kex_algorithms, default set in myproposals.h */
   1419   1.1  christos 	/* options->hostkeyalgorithms, default set in myproposals.h */
   1420   1.1  christos 	if (options->protocol == SSH_PROTO_UNKNOWN)
   1421   1.4      adam 		options->protocol = SSH_PROTO_2;
   1422   1.1  christos 	if (options->num_identity_files == 0) {
   1423   1.1  christos 		if (options->protocol & SSH_PROTO_1) {
   1424  1.10   mlelstv 			add_identity_file(options, "~/",
   1425  1.10   mlelstv 			    _PATH_SSH_CLIENT_IDENTITY, 0);
   1426   1.1  christos 		}
   1427   1.1  christos 		if (options->protocol & SSH_PROTO_2) {
   1428  1.10   mlelstv 			add_identity_file(options, "~/",
   1429  1.10   mlelstv 			    _PATH_SSH_CLIENT_ID_RSA, 0);
   1430  1.10   mlelstv 			add_identity_file(options, "~/",
   1431  1.10   mlelstv 			    _PATH_SSH_CLIENT_ID_DSA, 0);
   1432  1.10   mlelstv 			add_identity_file(options, "~/",
   1433  1.10   mlelstv 			    _PATH_SSH_CLIENT_ID_ECDSA, 0);
   1434   1.1  christos 		}
   1435   1.1  christos 	}
   1436   1.1  christos 	if (options->escape_char == -1)
   1437   1.1  christos 		options->escape_char = '~';
   1438   1.6  christos 	if (options->num_system_hostfiles == 0) {
   1439   1.6  christos 		options->system_hostfiles[options->num_system_hostfiles++] =
   1440   1.6  christos 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
   1441   1.6  christos 		options->system_hostfiles[options->num_system_hostfiles++] =
   1442   1.6  christos 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
   1443   1.6  christos 	}
   1444   1.6  christos 	if (options->num_user_hostfiles == 0) {
   1445   1.6  christos 		options->user_hostfiles[options->num_user_hostfiles++] =
   1446   1.6  christos 		    xstrdup(_PATH_SSH_USER_HOSTFILE);
   1447   1.6  christos 		options->user_hostfiles[options->num_user_hostfiles++] =
   1448   1.6  christos 		    xstrdup(_PATH_SSH_USER_HOSTFILE2);
   1449   1.6  christos 	}
   1450   1.1  christos 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
   1451   1.1  christos 		options->log_level = SYSLOG_LEVEL_INFO;
   1452   1.1  christos 	if (options->clear_forwardings == 1)
   1453   1.1  christos 		clear_forwardings(options);
   1454   1.1  christos 	if (options->no_host_authentication_for_localhost == - 1)
   1455   1.1  christos 		options->no_host_authentication_for_localhost = 0;
   1456   1.1  christos 	if (options->identities_only == -1)
   1457   1.1  christos 		options->identities_only = 0;
   1458   1.1  christos 	if (options->enable_ssh_keysign == -1)
   1459   1.1  christos 		options->enable_ssh_keysign = 0;
   1460   1.1  christos 	if (options->rekey_limit == -1)
   1461   1.1  christos 		options->rekey_limit = 0;
   1462  1.11  christos 	if (options->rekey_interval == -1)
   1463  1.11  christos 		options->rekey_interval = 0;
   1464   1.1  christos 	if (options->verify_host_key_dns == -1)
   1465   1.1  christos 		options->verify_host_key_dns = 0;
   1466   1.1  christos 	if (options->server_alive_interval == -1)
   1467   1.1  christos 		options->server_alive_interval = 0;
   1468   1.1  christos 	if (options->server_alive_count_max == -1)
   1469   1.1  christos 		options->server_alive_count_max = 3;
   1470   1.2  christos 	if (options->none_switch == -1)
   1471   1.2  christos 	        options->none_switch = 0;
   1472   1.2  christos 	if (options->hpn_disabled == -1)
   1473   1.2  christos 	        options->hpn_disabled = 0;
   1474   1.2  christos 	if (options->hpn_buffer_size > -1)
   1475   1.2  christos 	{
   1476   1.2  christos 	  /* if a user tries to set the size to 0 set it to 1KB */
   1477   1.2  christos 		if (options->hpn_buffer_size == 0)
   1478   1.2  christos 		options->hpn_buffer_size = 1024;
   1479   1.2  christos 		/*limit the buffer to 64MB*/
   1480   1.2  christos 		if (options->hpn_buffer_size > 65536)
   1481   1.2  christos 		{
   1482   1.2  christos 			options->hpn_buffer_size = 65536*1024;
   1483   1.2  christos 			debug("User requested buffer larger than 64MB. Request reverted to 64MB");
   1484   1.2  christos 		}
   1485   1.2  christos 		debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
   1486   1.2  christos 	}
   1487   1.2  christos 	if (options->tcp_rcv_buf == 0)
   1488   1.2  christos 		options->tcp_rcv_buf = 1;
   1489   1.2  christos 	if (options->tcp_rcv_buf > -1)
   1490   1.2  christos 		options->tcp_rcv_buf *=1024;
   1491   1.2  christos 	if (options->tcp_rcv_buf_poll == -1)
   1492   1.2  christos 		options->tcp_rcv_buf_poll = 1;
   1493   1.1  christos 	if (options->control_master == -1)
   1494   1.1  christos 		options->control_master = 0;
   1495   1.4      adam 	if (options->control_persist == -1) {
   1496   1.4      adam 		options->control_persist = 0;
   1497   1.4      adam 		options->control_persist_timeout = 0;
   1498   1.4      adam 	}
   1499   1.1  christos 	if (options->hash_known_hosts == -1)
   1500   1.1  christos 		options->hash_known_hosts = 0;
   1501   1.1  christos 	if (options->tun_open == -1)
   1502   1.1  christos 		options->tun_open = SSH_TUNMODE_NO;
   1503   1.1  christos 	if (options->tun_local == -1)
   1504   1.1  christos 		options->tun_local = SSH_TUNID_ANY;
   1505   1.1  christos 	if (options->tun_remote == -1)
   1506   1.1  christos 		options->tun_remote = SSH_TUNID_ANY;
   1507   1.1  christos 	if (options->permit_local_command == -1)
   1508   1.1  christos 		options->permit_local_command = 0;
   1509   1.3  christos 	if (options->use_roaming == -1)
   1510   1.3  christos 		options->use_roaming = 1;
   1511   1.1  christos 	if (options->visual_host_key == -1)
   1512   1.1  christos 		options->visual_host_key = 0;
   1513   1.1  christos 	if (options->zero_knowledge_password_authentication == -1)
   1514   1.1  christos 		options->zero_knowledge_password_authentication = 0;
   1515   1.5  christos 	if (options->ip_qos_interactive == -1)
   1516   1.5  christos 		options->ip_qos_interactive = IPTOS_LOWDELAY;
   1517   1.5  christos 	if (options->ip_qos_bulk == -1)
   1518   1.5  christos 		options->ip_qos_bulk = IPTOS_THROUGHPUT;
   1519   1.6  christos 	if (options->request_tty == -1)
   1520   1.6  christos 		options->request_tty = REQUEST_TTY_AUTO;
   1521   1.7       tls 	if (options->send_version_first == -1)
   1522   1.7       tls 		options->send_version_first = 1;
   1523   1.1  christos 	/* options->local_command should not be set by default */
   1524   1.1  christos 	/* options->proxy_command should not be set by default */
   1525   1.1  christos 	/* options->user will be set in the main program if appropriate */
   1526   1.1  christos 	/* options->hostname will be set in the main program if appropriate */
   1527   1.1  christos 	/* options->host_key_alias should not be set by default */
   1528   1.1  christos 	/* options->preferred_authentications will be set in ssh */
   1529   1.1  christos }
   1530   1.1  christos 
   1531   1.1  christos /*
   1532   1.1  christos  * parse_forward
   1533   1.1  christos  * parses a string containing a port forwarding specification of the form:
   1534   1.1  christos  *   dynamicfwd == 0
   1535   1.1  christos  *	[listenhost:]listenport:connecthost:connectport
   1536   1.1  christos  *   dynamicfwd == 1
   1537   1.1  christos  *	[listenhost:]listenport
   1538   1.1  christos  * returns number of arguments parsed or zero on error
   1539   1.1  christos  */
   1540   1.1  christos int
   1541   1.1  christos parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
   1542   1.1  christos {
   1543   1.1  christos 	int i;
   1544   1.1  christos 	char *p, *cp, *fwdarg[4];
   1545   1.1  christos 
   1546   1.1  christos 	memset(fwd, '\0', sizeof(*fwd));
   1547   1.1  christos 
   1548   1.1  christos 	cp = p = xstrdup(fwdspec);
   1549   1.1  christos 
   1550   1.1  christos 	/* skip leading spaces */
   1551   1.2  christos 	while (isspace((unsigned char)*cp))
   1552   1.1  christos 		cp++;
   1553   1.1  christos 
   1554   1.1  christos 	for (i = 0; i < 4; ++i)
   1555   1.1  christos 		if ((fwdarg[i] = hpdelim(&cp)) == NULL)
   1556   1.1  christos 			break;
   1557   1.1  christos 
   1558   1.1  christos 	/* Check for trailing garbage */
   1559   1.1  christos 	if (cp != NULL)
   1560   1.1  christos 		i = 0;	/* failure */
   1561   1.1  christos 
   1562   1.1  christos 	switch (i) {
   1563   1.1  christos 	case 1:
   1564   1.1  christos 		fwd->listen_host = NULL;
   1565   1.1  christos 		fwd->listen_port = a2port(fwdarg[0]);
   1566   1.1  christos 		fwd->connect_host = xstrdup("socks");
   1567   1.1  christos 		break;
   1568   1.1  christos 
   1569   1.1  christos 	case 2:
   1570   1.1  christos 		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
   1571   1.1  christos 		fwd->listen_port = a2port(fwdarg[1]);
   1572   1.1  christos 		fwd->connect_host = xstrdup("socks");
   1573   1.1  christos 		break;
   1574   1.1  christos 
   1575   1.1  christos 	case 3:
   1576   1.1  christos 		fwd->listen_host = NULL;
   1577   1.1  christos 		fwd->listen_port = a2port(fwdarg[0]);
   1578   1.1  christos 		fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
   1579   1.1  christos 		fwd->connect_port = a2port(fwdarg[2]);
   1580   1.1  christos 		break;
   1581   1.1  christos 
   1582   1.1  christos 	case 4:
   1583   1.1  christos 		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
   1584   1.1  christos 		fwd->listen_port = a2port(fwdarg[1]);
   1585   1.1  christos 		fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
   1586   1.1  christos 		fwd->connect_port = a2port(fwdarg[3]);
   1587   1.1  christos 		break;
   1588   1.1  christos 	default:
   1589   1.1  christos 		i = 0; /* failure */
   1590   1.1  christos 	}
   1591   1.1  christos 
   1592  1.11  christos 	free(p);
   1593   1.1  christos 
   1594   1.1  christos 	if (dynamicfwd) {
   1595   1.1  christos 		if (!(i == 1 || i == 2))
   1596   1.1  christos 			goto fail_free;
   1597   1.1  christos 	} else {
   1598   1.1  christos 		if (!(i == 3 || i == 4))
   1599   1.1  christos 			goto fail_free;
   1600   1.1  christos 		if (fwd->connect_port <= 0)
   1601   1.1  christos 			goto fail_free;
   1602   1.1  christos 	}
   1603   1.1  christos 
   1604   1.1  christos 	if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
   1605   1.1  christos 		goto fail_free;
   1606   1.1  christos 
   1607   1.1  christos 	if (fwd->connect_host != NULL &&
   1608   1.1  christos 	    strlen(fwd->connect_host) >= NI_MAXHOST)
   1609   1.1  christos 		goto fail_free;
   1610   1.1  christos 	if (fwd->listen_host != NULL &&
   1611   1.1  christos 	    strlen(fwd->listen_host) >= NI_MAXHOST)
   1612   1.1  christos 		goto fail_free;
   1613   1.1  christos 
   1614   1.1  christos 
   1615   1.1  christos 	return (i);
   1616   1.1  christos 
   1617   1.1  christos  fail_free:
   1618  1.11  christos 	free(fwd->connect_host);
   1619  1.11  christos 	fwd->connect_host = NULL;
   1620  1.11  christos 	free(fwd->listen_host);
   1621  1.11  christos 	fwd->listen_host = NULL;
   1622   1.1  christos 	return (0);
   1623   1.1  christos }
   1624