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