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