]> andersk Git - openssh.git/blobdiff - readconf.c
- djm@cvs.openbsd.org 2006/03/25 01:13:23
[openssh.git] / readconf.c
index acdf128f63c63f88eecbd0e6a61a87a540785df6..e2e10d9d6fbedd14ca87bbba7ba0841fe0d3eb82 100644 (file)
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.106 2003/04/09 12:00:37 djm Exp $");
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
 
 #include "ssh.h"
 #include "xmalloc.h"
 
 #include "ssh.h"
 #include "xmalloc.h"
@@ -57,7 +61,6 @@ RCSID("$OpenBSD: readconf.c,v 1.106 2003/04/09 12:00:37 djm Exp $");
    Host fascist.blob.com
      Port 23123
      User tylonen
    Host fascist.blob.com
      Port 23123
      User tylonen
-     RhostsAuthentication no
      PasswordAuthentication no
 
    Host puukko.hut.fi
      PasswordAuthentication no
 
    Host puukko.hut.fi
@@ -71,16 +74,19 @@ RCSID("$OpenBSD: readconf.c,v 1.106 2003/04/09 12:00:37 djm Exp $");
      Cipher none
      PasswordAuthentication no
 
      Cipher none
      PasswordAuthentication no
 
+   Host vpn.fake.com
+     Tunnel yes
+     TunnelDevice 3
+
    # Defaults for various options
    Host *
      ForwardAgent no
      ForwardX11 no
    # Defaults for various options
    Host *
      ForwardAgent no
      ForwardX11 no
-     RhostsAuthentication yes
      PasswordAuthentication yes
      RSAAuthentication yes
      RhostsRSAAuthentication yes
      StrictHostKeyChecking yes
      PasswordAuthentication yes
      RSAAuthentication yes
      RhostsRSAAuthentication yes
      StrictHostKeyChecking yes
-     KeepAlives no
+     TcpKeepAlive no
      IdentityFile ~/.ssh/identity
      Port 22
      EscapeChar ~
      IdentityFile ~/.ssh/identity
      Port 22
      EscapeChar ~
@@ -91,31 +97,26 @@ RCSID("$OpenBSD: readconf.c,v 1.106 2003/04/09 12:00:37 djm Exp $");
 
 typedef enum {
        oBadOption,
 
 typedef enum {
        oBadOption,
-       oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
+       oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
        oPasswordAuthentication, oRSAAuthentication,
        oChallengeResponseAuthentication, oXAuthLocation,
        oPasswordAuthentication, oRSAAuthentication,
        oChallengeResponseAuthentication, oXAuthLocation,
-#if defined(KRB4) || defined(KRB5)
-       oKerberosAuthentication,
-#endif
-#if defined(AFS) || defined(KRB5)
-       oKerberosTgtPassing,
-#endif
-#ifdef AFS
-       oAFSTokenPassing,
-#endif
        oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
        oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
        oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
        oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
        oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
        oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
        oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
        oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
-       oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
+       oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
        oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
        oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
        oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
        oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
        oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
        oClearAllForwardings, oNoHostAuthenticationForLocalhost,
        oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
        oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
        oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
        oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
        oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
        oClearAllForwardings, oNoHostAuthenticationForLocalhost,
-       oEnableSSHKeysign, oRekeyLimit,
-       oDeprecated
+       oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
+       oAddressFamily, oGssAuthentication, oGssDelegateCreds,
+       oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
+       oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
+       oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
+       oDeprecated, oUnsupported
 } OpCodes;
 
 /* Textual representations of the tokens. */
 } OpCodes;
 
 /* Textual representations of the tokens. */
@@ -126,10 +127,11 @@ static struct {
 } keywords[] = {
        { "forwardagent", oForwardAgent },
        { "forwardx11", oForwardX11 },
 } keywords[] = {
        { "forwardagent", oForwardAgent },
        { "forwardx11", oForwardX11 },
+       { "forwardx11trusted", oForwardX11Trusted },
        { "xauthlocation", oXAuthLocation },
        { "gatewayports", oGatewayPorts },
        { "useprivilegedport", oUsePrivilegedPort },
        { "xauthlocation", oXAuthLocation },
        { "gatewayports", oGatewayPorts },
        { "useprivilegedport", oUsePrivilegedPort },
-       { "rhostsauthentication", oRhostsAuthentication },
+       { "rhostsauthentication", oDeprecated },
        { "passwordauthentication", oPasswordAuthentication },
        { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
        { "kbdinteractivedevices", oKbdInteractiveDevices },
        { "passwordauthentication", oPasswordAuthentication },
        { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
        { "kbdinteractivedevices", oKbdInteractiveDevices },
@@ -141,19 +143,21 @@ static struct {
        { "challengeresponseauthentication", oChallengeResponseAuthentication },
        { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
        { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
        { "challengeresponseauthentication", oChallengeResponseAuthentication },
        { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
        { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
-#if defined(KRB4) || defined(KRB5)
-       { "kerberosauthentication", oKerberosAuthentication },
-#endif
-#if defined(AFS) || defined(KRB5)
-       { "kerberostgtpassing", oKerberosTgtPassing },
-#endif
-#ifdef AFS
-       { "afstokenpassing", oAFSTokenPassing },
+       { "kerberosauthentication", oUnsupported },
+       { "kerberostgtpassing", oUnsupported },
+       { "afstokenpassing", oUnsupported },
+#if defined(GSSAPI)
+       { "gssapiauthentication", oGssAuthentication },
+       { "gssapidelegatecredentials", oGssDelegateCreds },
+#else
+       { "gssapiauthentication", oUnsupported },
+       { "gssapidelegatecredentials", oUnsupported },
 #endif
        { "fallbacktorsh", oDeprecated },
        { "usersh", oDeprecated },
        { "identityfile", oIdentityFile },
        { "identityfile2", oIdentityFile },                     /* alias */
 #endif
        { "fallbacktorsh", oDeprecated },
        { "usersh", oDeprecated },
        { "identityfile", oIdentityFile },
        { "identityfile2", oIdentityFile },                     /* alias */
+       { "identitiesonly", oIdentitiesOnly },
        { "hostname", oHostName },
        { "hostkeyalias", oHostKeyAlias },
        { "proxycommand", oProxyCommand },
        { "hostname", oHostName },
        { "hostkeyalias", oHostKeyAlias },
        { "proxycommand", oProxyCommand },
@@ -177,18 +181,36 @@ static struct {
        { "stricthostkeychecking", oStrictHostKeyChecking },
        { "compression", oCompression },
        { "compressionlevel", oCompressionLevel },
        { "stricthostkeychecking", oStrictHostKeyChecking },
        { "compression", oCompression },
        { "compressionlevel", oCompressionLevel },
-       { "keepalive", oKeepAlives },
+       { "tcpkeepalive", oTCPKeepAlive },
+       { "keepalive", oTCPKeepAlive },                         /* obsolete */
        { "numberofpasswordprompts", oNumberOfPasswordPrompts },
        { "loglevel", oLogLevel },
        { "dynamicforward", oDynamicForward },
        { "preferredauthentications", oPreferredAuthentications },
        { "hostkeyalgorithms", oHostKeyAlgorithms },
        { "bindaddress", oBindAddress },
        { "numberofpasswordprompts", oNumberOfPasswordPrompts },
        { "loglevel", oLogLevel },
        { "dynamicforward", oDynamicForward },
        { "preferredauthentications", oPreferredAuthentications },
        { "hostkeyalgorithms", oHostKeyAlgorithms },
        { "bindaddress", oBindAddress },
+#ifdef SMARTCARD
        { "smartcarddevice", oSmartcardDevice },
        { "smartcarddevice", oSmartcardDevice },
+#else
+       { "smartcarddevice", oUnsupported },
+#endif
        { "clearallforwardings", oClearAllForwardings },
        { "enablesshkeysign", oEnableSSHKeysign },
        { "clearallforwardings", oClearAllForwardings },
        { "enablesshkeysign", oEnableSSHKeysign },
+       { "verifyhostkeydns", oVerifyHostKeyDNS },
        { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
        { "rekeylimit", oRekeyLimit },
        { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
        { "rekeylimit", oRekeyLimit },
+       { "connecttimeout", oConnectTimeout },
+       { "addressfamily", oAddressFamily },
+       { "serveraliveinterval", oServerAliveInterval },
+       { "serveralivecountmax", oServerAliveCountMax },
+       { "sendenv", oSendEnv },
+       { "controlpath", oControlPath },
+       { "controlmaster", oControlMaster },
+       { "hashknownhosts", oHashKnownHosts },
+       { "tunnel", oTunnel },
+       { "tunneldevice", oTunnelDevice },
+       { "localcommand", oLocalCommand },
+       { "permitlocalcommand", oPermitLocalCommand },
        { NULL, oBadOption }
 };
 
        { NULL, oBadOption }
 };
 
@@ -198,21 +220,23 @@ static struct {
  */
 
 void
  */
 
 void
-add_local_forward(Options *options, u_short port, const char *host,
-                 u_short host_port)
+add_local_forward(Options *options, const Forward *newfwd)
 {
        Forward *fwd;
 #ifndef NO_IPPORT_RESERVED_CONCEPT
        extern uid_t original_real_uid;
 {
        Forward *fwd;
 #ifndef NO_IPPORT_RESERVED_CONCEPT
        extern uid_t original_real_uid;
-       if (port < IPPORT_RESERVED && original_real_uid != 0)
+       if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
                fatal("Privileged ports can only be forwarded by root.");
 #endif
        if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
                fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
        fwd = &options->local_forwards[options->num_local_forwards++];
                fatal("Privileged ports can only be forwarded by root.");
 #endif
        if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
                fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
        fwd = &options->local_forwards[options->num_local_forwards++];
-       fwd->port = port;
-       fwd->host = xstrdup(host);
-       fwd->host_port = host_port;
+
+       fwd->listen_host = (newfwd->listen_host == NULL) ?
+           NULL : xstrdup(newfwd->listen_host);
+       fwd->listen_port = newfwd->listen_port;
+       fwd->connect_host = xstrdup(newfwd->connect_host);
+       fwd->connect_port = newfwd->connect_port;
 }
 
 /*
 }
 
 /*
@@ -221,17 +245,19 @@ add_local_forward(Options *options, u_short port, const char *host,
  */
 
 void
  */
 
 void
-add_remote_forward(Options *options, u_short port, const char *host,
-                  u_short host_port)
+add_remote_forward(Options *options, const Forward *newfwd)
 {
        Forward *fwd;
        if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
                fatal("Too many remote forwards (max %d).",
                    SSH_MAX_FORWARDS_PER_DIRECTION);
        fwd = &options->remote_forwards[options->num_remote_forwards++];
 {
        Forward *fwd;
        if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
                fatal("Too many remote forwards (max %d).",
                    SSH_MAX_FORWARDS_PER_DIRECTION);
        fwd = &options->remote_forwards[options->num_remote_forwards++];
-       fwd->port = port;
-       fwd->host = xstrdup(host);
-       fwd->host_port = host_port;
+
+       fwd->listen_host = (newfwd->listen_host == NULL) ?
+           NULL : xstrdup(newfwd->listen_host);
+       fwd->listen_port = newfwd->listen_port;
+       fwd->connect_host = xstrdup(newfwd->connect_host);
+       fwd->connect_port = newfwd->connect_port;
 }
 
 static void
 }
 
 static void
@@ -239,12 +265,19 @@ clear_forwardings(Options *options)
 {
        int i;
 
 {
        int i;
 
-       for (i = 0; i < options->num_local_forwards; i++)
-               xfree(options->local_forwards[i].host);
+       for (i = 0; i < options->num_local_forwards; i++) {
+               if (options->local_forwards[i].listen_host != NULL)
+                       xfree(options->local_forwards[i].listen_host);
+               xfree(options->local_forwards[i].connect_host);
+       }
        options->num_local_forwards = 0;
        options->num_local_forwards = 0;
-       for (i = 0; i < options->num_remote_forwards; i++)
-               xfree(options->remote_forwards[i].host);
+       for (i = 0; i < options->num_remote_forwards; i++) {
+               if (options->remote_forwards[i].listen_host != NULL)
+                       xfree(options->remote_forwards[i].listen_host);
+               xfree(options->remote_forwards[i].connect_host);
+       }
        options->num_remote_forwards = 0;
        options->num_remote_forwards = 0;
+       options->tun_open = SSH_TUNMODE_NO;
 }
 
 /*
 }
 
 /*
@@ -276,14 +309,14 @@ process_config_line(Options *options, const char *host,
                    char *line, const char *filename, int linenum,
                    int *activep)
 {
                    char *line, const char *filename, int linenum,
                    int *activep)
 {
-       char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
-       int opcode, *intptr, value;
+       char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
+       int opcode, *intptr, value, value2, scale;
+       long long orig, val64;
        size_t len;
        size_t len;
-       u_short fwd_port, fwd_host_port;
-       char sfwd_host_port[6];
+       Forward fwd;
 
        /* Strip trailing whitespace */
 
        /* Strip trailing whitespace */
-       for(len = strlen(line) - 1; len > 0; len--) {
+       for (len = strlen(line) - 1; len > 0; len--) {
                if (strchr(WHITESPACE, line[len]) == NULL)
                        break;
                line[len] = '\0';
                if (strchr(WHITESPACE, line[len]) == NULL)
                        break;
                line[len] = '\0';
@@ -291,7 +324,8 @@ process_config_line(Options *options, const char *host,
 
        s = line;
        /* Get the keyword. (Each line is supposed to begin with a keyword). */
 
        s = line;
        /* Get the keyword. (Each line is supposed to begin with a keyword). */
-       keyword = strdelim(&s);
+       if ((keyword = strdelim(&s)) == NULL)
+               return 0;
        /* Ignore leading whitespace. */
        if (*keyword == '\0')
                keyword = strdelim(&s);
        /* Ignore leading whitespace. */
        if (*keyword == '\0')
                keyword = strdelim(&s);
@@ -305,6 +339,20 @@ process_config_line(Options *options, const char *host,
                /* don't panic, but count bad options */
                return -1;
                /* NOTREACHED */
                /* don't panic, but count bad options */
                return -1;
                /* NOTREACHED */
+       case oConnectTimeout:
+               intptr = &options->connection_timeout;
+parse_time:
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing time value.",
+                           filename, linenum);
+               if ((value = convtime(arg)) == -1)
+                       fatal("%s line %d: invalid time value.",
+                           filename, linenum);
+               if (*intptr == -1)
+                       *intptr = value;
+               break;
+
        case oForwardAgent:
                intptr = &options->forward_agent;
 parse_flag:
        case oForwardAgent:
                intptr = &options->forward_agent;
 parse_flag:
@@ -326,6 +374,10 @@ parse_flag:
                intptr = &options->forward_x11;
                goto parse_flag;
 
                intptr = &options->forward_x11;
                goto parse_flag;
 
+       case oForwardX11Trusted:
+               intptr = &options->forward_x11_trusted;
+               goto parse_flag;
+
        case oGatewayPorts:
                intptr = &options->gateway_ports;
                goto parse_flag;
        case oGatewayPorts:
                intptr = &options->gateway_ports;
                goto parse_flag;
@@ -334,10 +386,6 @@ parse_flag:
                intptr = &options->use_privileged_port;
                goto parse_flag;
 
                intptr = &options->use_privileged_port;
                goto parse_flag;
 
-       case oRhostsAuthentication:
-               intptr = &options->rhosts_authentication;
-               goto parse_flag;
-
        case oPasswordAuthentication:
                intptr = &options->password_authentication;
                goto parse_flag;
        case oPasswordAuthentication:
                intptr = &options->password_authentication;
                goto parse_flag;
@@ -369,21 +417,15 @@ parse_flag:
        case oChallengeResponseAuthentication:
                intptr = &options->challenge_response_authentication;
                goto parse_flag;
        case oChallengeResponseAuthentication:
                intptr = &options->challenge_response_authentication;
                goto parse_flag;
-#if defined(KRB4) || defined(KRB5)
-       case oKerberosAuthentication:
-               intptr = &options->kerberos_authentication;
-               goto parse_flag;
-#endif
-#if defined(AFS) || defined(KRB5)
-       case oKerberosTgtPassing:
-               intptr = &options->kerberos_tgt_passing;
+
+       case oGssAuthentication:
+               intptr = &options->gss_authentication;
                goto parse_flag;
                goto parse_flag;
-#endif
-#ifdef AFS
-       case oAFSTokenPassing:
-               intptr = &options->afs_token_passing;
+
+       case oGssDelegateCreds:
+               intptr = &options->gss_deleg_creds;
                goto parse_flag;
                goto parse_flag;
-#endif
+
        case oBatchMode:
                intptr = &options->batch_mode;
                goto parse_flag;
        case oBatchMode:
                intptr = &options->batch_mode;
                goto parse_flag;
@@ -392,8 +434,13 @@ parse_flag:
                intptr = &options->check_host_ip;
                goto parse_flag;
 
                intptr = &options->check_host_ip;
                goto parse_flag;
 
+       case oVerifyHostKeyDNS:
+               intptr = &options->verify_host_key_dns;
+               goto parse_yesnoask;
+
        case oStrictHostKeyChecking:
                intptr = &options->strict_host_key_checking;
        case oStrictHostKeyChecking:
                intptr = &options->strict_host_key_checking;
+parse_yesnoask:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing yes/no/ask argument.",
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing yes/no/ask argument.",
@@ -415,8 +462,8 @@ parse_flag:
                intptr = &options->compression;
                goto parse_flag;
 
                intptr = &options->compression;
                goto parse_flag;
 
-       case oKeepAlives:
-               intptr = &options->keepalives;
+       case oTCPKeepAlive:
+               intptr = &options->tcp_keep_alive;
                goto parse_flag;
 
        case oNoHostAuthenticationForLocalhost:
                goto parse_flag;
 
        case oNoHostAuthenticationForLocalhost:
@@ -438,22 +485,36 @@ parse_flag:
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (arg[0] < '0' || arg[0] > '9')
                        fatal("%.200s line %d: Bad number.", filename, linenum);
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (arg[0] < '0' || arg[0] > '9')
                        fatal("%.200s line %d: Bad number.", filename, linenum);
-               value = strtol(arg, &endofnumber, 10);
+               orig = val64 = strtoll(arg, &endofnumber, 10);
                if (arg == endofnumber)
                        fatal("%.200s line %d: Bad number.", filename, linenum);
                switch (toupper(*endofnumber)) {
                if (arg == endofnumber)
                        fatal("%.200s line %d: Bad number.", filename, linenum);
                switch (toupper(*endofnumber)) {
+               case '\0':
+                       scale = 1;
+                       break;
                case 'K':
                case 'K':
-                       value *= 1<<10;
+                       scale = 1<<10;
                        break;
                case 'M':
                        break;
                case 'M':
-                       value *= 1<<20;
+                       scale = 1<<20;
                        break;
                case 'G':
                        break;
                case 'G':
-                       value *= 1<<30;
+                       scale = 1<<30;
                        break;
                        break;
+               default:
+                       fatal("%.200s line %d: Invalid RekeyLimit suffix",
+                           filename, linenum);
                }
                }
+               val64 *= scale;
+               /* detect integer wrap and too-large limits */
+               if ((val64 / scale) != orig || val64 > INT_MAX)
+                       fatal("%.200s line %d: RekeyLimit too large",
+                           filename, linenum);
+               if (val64 < 16)
+                       fatal("%.200s line %d: RekeyLimit too small",
+                           filename, linenum);
                if (*activep && *intptr == -1)
                if (*activep && *intptr == -1)
-                       *intptr = value;
+                       *intptr = (int)val64;
                break;
 
        case oIdentityFile:
                break;
 
        case oIdentityFile:
@@ -523,6 +584,9 @@ parse_string:
 
        case oProxyCommand:
                charptr = &options->proxy_command;
 
        case oProxyCommand:
                charptr = &options->proxy_command;
+parse_command:
+               if (s == NULL)
+                       fatal("%.200s line %d: Missing argument.", filename, linenum);
                len = strspn(s, WHITESPACE "=");
                if (*activep && *charptr == NULL)
                        *charptr = xstrdup(s + len);
                len = strspn(s, WHITESPACE "=");
                if (*activep && *charptr == NULL)
                        *charptr = xstrdup(s + len);
@@ -622,30 +686,26 @@ parse_int:
        case oLocalForward:
        case oRemoteForward:
                arg = strdelim(&s);
        case oLocalForward:
        case oRemoteForward:
                arg = strdelim(&s);
-               if (!arg || *arg == '\0')
+               if (arg == NULL || *arg == '\0')
                        fatal("%.200s line %d: Missing port argument.",
                            filename, linenum);
                        fatal("%.200s line %d: Missing port argument.",
                            filename, linenum);
-               if ((fwd_port = a2port(arg)) == 0)
-                       fatal("%.200s line %d: Bad listen port.",
-                           filename, linenum);
-               arg = strdelim(&s);
-               if (!arg || *arg == '\0')
-                       fatal("%.200s line %d: Missing second argument.",
+               arg2 = strdelim(&s);
+               if (arg2 == NULL || *arg2 == '\0')
+                       fatal("%.200s line %d: Missing target argument.",
                            filename, linenum);
                            filename, linenum);
-               if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
-                   sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
+
+               /* construct a string for parse_forward */
+               snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
+
+               if (parse_forward(&fwd, fwdarg) == 0)
                        fatal("%.200s line %d: Bad forwarding specification.",
                            filename, linenum);
                        fatal("%.200s line %d: Bad forwarding specification.",
                            filename, linenum);
-               if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
-                       fatal("%.200s line %d: Bad forwarding port.",
-                           filename, linenum);
+
                if (*activep) {
                        if (opcode == oLocalForward)
                if (*activep) {
                        if (opcode == oLocalForward)
-                               add_local_forward(options, fwd_port, buf,
-                                   fwd_host_port);
+                               add_local_forward(options, &fwd);
                        else if (opcode == oRemoteForward)
                        else if (opcode == oRemoteForward)
-                               add_remote_forward(options, fwd_port, buf,
-                                   fwd_host_port);
+                               add_remote_forward(options, &fwd);
                }
                break;
 
                }
                break;
 
@@ -654,12 +714,25 @@ parse_int:
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing port argument.",
                            filename, linenum);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing port argument.",
                            filename, linenum);
-               fwd_port = a2port(arg);
-               if (fwd_port == 0)
+               memset(&fwd, '\0', sizeof(fwd));
+               fwd.connect_host = "socks";
+               fwd.listen_host = hpdelim(&arg);
+               if (fwd.listen_host == NULL ||
+                   strlen(fwd.listen_host) >= NI_MAXHOST)
+                       fatal("%.200s line %d: Bad forwarding specification.",
+                           filename, linenum);
+               if (arg) {
+                       fwd.listen_port = a2port(arg);
+                       fwd.listen_host = cleanhostname(fwd.listen_host);
+               } else {
+                       fwd.listen_port = a2port(fwd.listen_host);
+                       fwd.listen_host = NULL;
+               }
+               if (fwd.listen_port == 0)
                        fatal("%.200s line %d: Badly formatted port number.",
                            filename, linenum);
                if (*activep)
                        fatal("%.200s line %d: Badly formatted port number.",
                            filename, linenum);
                if (*activep)
-                       add_local_forward(options, fwd_port, "socks4", 0);
+                       add_local_forward(options, &fwd);
                break;
 
        case oClearAllForwardings:
                break;
 
        case oClearAllForwardings:
@@ -699,15 +772,140 @@ parse_int:
                        *intptr = value;
                break;
 
                        *intptr = value;
                break;
 
+       case oAddressFamily:
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing address family.",
+                           filename, linenum);
+               intptr = &options->address_family;
+               if (strcasecmp(arg, "inet") == 0)
+                       value = AF_INET;
+               else if (strcasecmp(arg, "inet6") == 0)
+                       value = AF_INET6;
+               else if (strcasecmp(arg, "any") == 0)
+                       value = AF_UNSPEC;
+               else
+                       fatal("Unsupported AddressFamily \"%s\"", arg);
+               if (*activep && *intptr == -1)
+                       *intptr = value;
+               break;
+
        case oEnableSSHKeysign:
                intptr = &options->enable_ssh_keysign;
                goto parse_flag;
 
        case oEnableSSHKeysign:
                intptr = &options->enable_ssh_keysign;
                goto parse_flag;
 
+       case oIdentitiesOnly:
+               intptr = &options->identities_only;
+               goto parse_flag;
+
+       case oServerAliveInterval:
+               intptr = &options->server_alive_interval;
+               goto parse_time;
+
+       case oServerAliveCountMax:
+               intptr = &options->server_alive_count_max;
+               goto parse_int;
+
+       case oSendEnv:
+               while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
+                       if (strchr(arg, '=') != NULL)
+                               fatal("%s line %d: Invalid environment name.",
+                                   filename, linenum);
+                       if (!*activep)
+                               continue;
+                       if (options->num_send_env >= MAX_SEND_ENV)
+                               fatal("%s line %d: too many send env.",
+                                   filename, linenum);
+                       options->send_env[options->num_send_env++] =
+                           xstrdup(arg);
+               }
+               break;
+
+       case oControlPath:
+               charptr = &options->control_path;
+               goto parse_string;
+
+       case oControlMaster:
+               intptr = &options->control_master;
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%.200s line %d: Missing ControlMaster argument.",
+                           filename, linenum);
+               value = 0;      /* To avoid compiler warning... */
+               if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
+                       value = SSHCTL_MASTER_YES;
+               else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
+                       value = SSHCTL_MASTER_NO;
+               else if (strcmp(arg, "auto") == 0)
+                       value = SSHCTL_MASTER_AUTO;
+               else if (strcmp(arg, "ask") == 0)
+                       value = SSHCTL_MASTER_ASK;
+               else if (strcmp(arg, "autoask") == 0)
+                       value = SSHCTL_MASTER_AUTO_ASK;
+               else
+                       fatal("%.200s line %d: Bad ControlMaster argument.",
+                           filename, linenum);
+               if (*activep && *intptr == -1)
+                       *intptr = value;
+               break;
+
+       case oHashKnownHosts:
+               intptr = &options->hash_known_hosts;
+               goto parse_flag;
+
+       case oTunnel:
+               intptr = &options->tun_open;
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: Missing yes/point-to-point/"
+                           "ethernet/no argument.", filename, linenum);
+               value = 0;      /* silence compiler */
+               if (strcasecmp(arg, "ethernet") == 0)
+                       value = SSH_TUNMODE_ETHERNET;
+               else if (strcasecmp(arg, "point-to-point") == 0)
+                       value = SSH_TUNMODE_POINTOPOINT;
+               else if (strcasecmp(arg, "yes") == 0)
+                       value = SSH_TUNMODE_DEFAULT;
+               else if (strcasecmp(arg, "no") == 0)
+                       value = SSH_TUNMODE_NO;
+               else
+                       fatal("%s line %d: Bad yes/point-to-point/ethernet/"
+                           "no argument: %s", filename, linenum, arg);
+               if (*activep)
+                       *intptr = value;
+               break;
+
+       case oTunnelDevice:
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%.200s line %d: Missing argument.", filename, linenum);
+               value = a2tun(arg, &value2);
+               if (value == SSH_TUNID_ERR)
+                       fatal("%.200s line %d: Bad tun device.", filename, linenum);
+               if (*activep) {
+                       options->tun_local = value;
+                       options->tun_remote = value2;
+               }
+               break;
+
+       case oLocalCommand:
+               charptr = &options->local_command;
+               goto parse_command;
+
+       case oPermitLocalCommand:
+               intptr = &options->permit_local_command;
+               goto parse_flag;
+
        case oDeprecated:
                debug("%s line %d: Deprecated option \"%s\"",
                    filename, linenum, keyword);
                return 0;
 
        case oDeprecated:
                debug("%s line %d: Deprecated option \"%s\"",
                    filename, linenum, keyword);
                return 0;
 
+       case oUnsupported:
+               error("%s line %d: Unsupported option \"%s\"",
+                   filename, linenum, keyword);
+               return 0;
+
        default:
                fatal("process_config_line: Unimplemented opcode %d", opcode);
        }
        default:
                fatal("process_config_line: Unimplemented opcode %d", opcode);
        }
@@ -715,7 +913,7 @@ parse_int:
        /* Check that there is no garbage at end of line. */
        if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
                fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
        /* Check that there is no garbage at end of line. */
        if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
                fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
-                    filename, linenum, arg);
+                   filename, linenum, arg);
        }
        return 0;
 }
        }
        return 0;
 }
@@ -728,7 +926,8 @@ parse_int:
  */
 
 int
  */
 
 int
-read_config_file(const char *filename, const char *host, Options *options)
+read_config_file(const char *filename, const char *host, Options *options,
+    int checkperm)
 {
        FILE *f;
        char line[1024];
 {
        FILE *f;
        char line[1024];
@@ -736,10 +935,19 @@ read_config_file(const char *filename, const char *host, Options *options)
        int bad_options = 0;
 
        /* Open the file. */
        int bad_options = 0;
 
        /* Open the file. */
-       f = fopen(filename, "r");
-       if (!f)
+       if ((f = fopen(filename, "r")) == NULL)
                return 0;
 
                return 0;
 
+       if (checkperm) {
+               struct stat sb;
+
+               if (fstat(fileno(f), &sb) == -1)
+                       fatal("fstat %s: %s", filename, strerror(errno));
+               if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
+                   (sb.st_mode & 022) != 0))
+                       fatal("Bad owner or permissions on %s", filename);
+       }
+
        debug("Reading configuration data %.200s", filename);
 
        /*
        debug("Reading configuration data %.200s", filename);
 
        /*
@@ -774,22 +982,15 @@ initialize_options(Options * options)
        memset(options, 'X', sizeof(*options));
        options->forward_agent = -1;
        options->forward_x11 = -1;
        memset(options, 'X', sizeof(*options));
        options->forward_agent = -1;
        options->forward_x11 = -1;
+       options->forward_x11_trusted = -1;
        options->xauth_location = NULL;
        options->gateway_ports = -1;
        options->use_privileged_port = -1;
        options->xauth_location = NULL;
        options->gateway_ports = -1;
        options->use_privileged_port = -1;
-       options->rhosts_authentication = -1;
        options->rsa_authentication = -1;
        options->pubkey_authentication = -1;
        options->challenge_response_authentication = -1;
        options->rsa_authentication = -1;
        options->pubkey_authentication = -1;
        options->challenge_response_authentication = -1;
-#if defined(KRB4) || defined(KRB5)
-       options->kerberos_authentication = -1;
-#endif
-#if defined(AFS) || defined(KRB5)
-       options->kerberos_tgt_passing = -1;
-#endif
-#ifdef AFS
-       options->afs_token_passing = -1;
-#endif
+       options->gss_authentication = -1;
+       options->gss_deleg_creds = -1;
        options->password_authentication = -1;
        options->kbd_interactive_authentication = -1;
        options->kbd_interactive_devices = NULL;
        options->password_authentication = -1;
        options->kbd_interactive_authentication = -1;
        options->kbd_interactive_devices = NULL;
@@ -799,10 +1000,12 @@ initialize_options(Options * options)
        options->check_host_ip = -1;
        options->strict_host_key_checking = -1;
        options->compression = -1;
        options->check_host_ip = -1;
        options->strict_host_key_checking = -1;
        options->compression = -1;
-       options->keepalives = -1;
+       options->tcp_keep_alive = -1;
        options->compression_level = -1;
        options->port = -1;
        options->compression_level = -1;
        options->port = -1;
+       options->address_family = -1;
        options->connection_attempts = -1;
        options->connection_attempts = -1;
+       options->connection_timeout = -1;
        options->number_of_password_prompts = -1;
        options->cipher = -1;
        options->ciphers = NULL;
        options->number_of_password_prompts = -1;
        options->cipher = -1;
        options->ciphers = NULL;
@@ -828,7 +1031,20 @@ initialize_options(Options * options)
        options->smartcard_device = NULL;
        options->enable_ssh_keysign = - 1;
        options->no_host_authentication_for_localhost = - 1;
        options->smartcard_device = NULL;
        options->enable_ssh_keysign = - 1;
        options->no_host_authentication_for_localhost = - 1;
+       options->identities_only = - 1;
        options->rekey_limit = - 1;
        options->rekey_limit = - 1;
+       options->verify_host_key_dns = -1;
+       options->server_alive_interval = -1;
+       options->server_alive_count_max = -1;
+       options->num_send_env = 0;
+       options->control_path = NULL;
+       options->control_master = -1;
+       options->hash_known_hosts = -1;
+       options->tun_open = -1;
+       options->tun_local = -1;
+       options->tun_remote = -1;
+       options->local_command = NULL;
+       options->permit_local_command = -1;
 }
 
 /*
 }
 
 /*
@@ -845,32 +1061,24 @@ fill_default_options(Options * options)
                options->forward_agent = 0;
        if (options->forward_x11 == -1)
                options->forward_x11 = 0;
                options->forward_agent = 0;
        if (options->forward_x11 == -1)
                options->forward_x11 = 0;
+       if (options->forward_x11_trusted == -1)
+               options->forward_x11_trusted = 0;
        if (options->xauth_location == NULL)
                options->xauth_location = _PATH_XAUTH;
        if (options->gateway_ports == -1)
                options->gateway_ports = 0;
        if (options->use_privileged_port == -1)
                options->use_privileged_port = 0;
        if (options->xauth_location == NULL)
                options->xauth_location = _PATH_XAUTH;
        if (options->gateway_ports == -1)
                options->gateway_ports = 0;
        if (options->use_privileged_port == -1)
                options->use_privileged_port = 0;
-       if (options->rhosts_authentication == -1)
-               options->rhosts_authentication = 0;
        if (options->rsa_authentication == -1)
                options->rsa_authentication = 1;
        if (options->pubkey_authentication == -1)
                options->pubkey_authentication = 1;
        if (options->challenge_response_authentication == -1)
                options->challenge_response_authentication = 1;
        if (options->rsa_authentication == -1)
                options->rsa_authentication = 1;
        if (options->pubkey_authentication == -1)
                options->pubkey_authentication = 1;
        if (options->challenge_response_authentication == -1)
                options->challenge_response_authentication = 1;
-#if defined(KRB4) || defined(KRB5)
-       if (options->kerberos_authentication == -1)
-               options->kerberos_authentication = 1;
-#endif
-#if defined(AFS) || defined(KRB5)
-       if (options->kerberos_tgt_passing == -1)
-               options->kerberos_tgt_passing = 1;
-#endif
-#ifdef AFS
-       if (options->afs_token_passing == -1)
-               options->afs_token_passing = 1;
-#endif
+       if (options->gss_authentication == -1)
+               options->gss_authentication = 0;
+       if (options->gss_deleg_creds == -1)
+               options->gss_deleg_creds = 0;
        if (options->password_authentication == -1)
                options->password_authentication = 1;
        if (options->kbd_interactive_authentication == -1)
        if (options->password_authentication == -1)
                options->password_authentication = 1;
        if (options->kbd_interactive_authentication == -1)
@@ -887,12 +1095,14 @@ fill_default_options(Options * options)
                options->strict_host_key_checking = 2;  /* 2 is default */
        if (options->compression == -1)
                options->compression = 0;
                options->strict_host_key_checking = 2;  /* 2 is default */
        if (options->compression == -1)
                options->compression = 0;
-       if (options->keepalives == -1)
-               options->keepalives = 1;
+       if (options->tcp_keep_alive == -1)
+               options->tcp_keep_alive = 1;
        if (options->compression_level == -1)
                options->compression_level = 6;
        if (options->port == -1)
                options->port = 0;      /* Filled in ssh_connect. */
        if (options->compression_level == -1)
                options->compression_level = 6;
        if (options->port == -1)
                options->port = 0;      /* Filled in ssh_connect. */
+       if (options->address_family == -1)
+               options->address_family = AF_UNSPEC;
        if (options->connection_attempts == -1)
                options->connection_attempts = 1;
        if (options->number_of_password_prompts == -1)
        if (options->connection_attempts == -1)
                options->connection_attempts = 1;
        if (options->number_of_password_prompts == -1)
@@ -943,13 +1153,99 @@ fill_default_options(Options * options)
                clear_forwardings(options);
        if (options->no_host_authentication_for_localhost == - 1)
                options->no_host_authentication_for_localhost = 0;
                clear_forwardings(options);
        if (options->no_host_authentication_for_localhost == - 1)
                options->no_host_authentication_for_localhost = 0;
+       if (options->identities_only == -1)
+               options->identities_only = 0;
        if (options->enable_ssh_keysign == -1)
                options->enable_ssh_keysign = 0;
        if (options->rekey_limit == -1)
                options->rekey_limit = 0;
        if (options->enable_ssh_keysign == -1)
                options->enable_ssh_keysign = 0;
        if (options->rekey_limit == -1)
                options->rekey_limit = 0;
+       if (options->verify_host_key_dns == -1)
+               options->verify_host_key_dns = 0;
+       if (options->server_alive_interval == -1)
+               options->server_alive_interval = 0;
+       if (options->server_alive_count_max == -1)
+               options->server_alive_count_max = 3;
+       if (options->control_master == -1)
+               options->control_master = 0;
+       if (options->hash_known_hosts == -1)
+               options->hash_known_hosts = 0;
+       if (options->tun_open == -1)
+               options->tun_open = SSH_TUNMODE_NO;
+       if (options->tun_local == -1)
+               options->tun_local = SSH_TUNID_ANY;
+       if (options->tun_remote == -1)
+               options->tun_remote = SSH_TUNID_ANY;
+       if (options->permit_local_command == -1)
+               options->permit_local_command = 0;
+       /* options->local_command should not be set by default */
        /* options->proxy_command should not be set by default */
        /* options->user will be set in the main program if appropriate */
        /* options->hostname will be set in the main program if appropriate */
        /* options->host_key_alias should not be set by default */
        /* options->preferred_authentications will be set in ssh */
 }
        /* options->proxy_command should not be set by default */
        /* options->user will be set in the main program if appropriate */
        /* options->hostname will be set in the main program if appropriate */
        /* options->host_key_alias should not be set by default */
        /* options->preferred_authentications will be set in ssh */
 }
+
+/*
+ * parse_forward
+ * parses a string containing a port forwarding specification of the form:
+ *     [listenhost:]listenport:connecthost:connectport
+ * returns number of arguments parsed or zero on error
+ */
+int
+parse_forward(Forward *fwd, const char *fwdspec)
+{
+       int i;
+       char *p, *cp, *fwdarg[4];
+
+       memset(fwd, '\0', sizeof(*fwd));
+
+       cp = p = xstrdup(fwdspec);
+
+       /* skip leading spaces */
+       while (*cp && isspace(*cp))
+               cp++;
+
+       for (i = 0; i < 4; ++i)
+               if ((fwdarg[i] = hpdelim(&cp)) == NULL)
+                       break;
+
+       /* Check for trailing garbage in 4-arg case*/
+       if (cp != NULL)
+               i = 0;  /* failure */
+
+       switch (i) {
+       case 3:
+               fwd->listen_host = NULL;
+               fwd->listen_port = a2port(fwdarg[0]);
+               fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
+               fwd->connect_port = a2port(fwdarg[2]);
+               break;
+
+       case 4:
+               fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
+               fwd->listen_port = a2port(fwdarg[1]);
+               fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
+               fwd->connect_port = a2port(fwdarg[3]);
+               break;
+       default:
+               i = 0; /* failure */
+       }
+
+       xfree(p);
+
+       if (fwd->listen_port == 0 && fwd->connect_port == 0)
+               goto fail_free;
+
+       if (fwd->connect_host != NULL &&
+           strlen(fwd->connect_host) >= NI_MAXHOST)
+               goto fail_free;
+
+       return (i);
+
+ fail_free:
+       if (fwd->connect_host != NULL)
+               xfree(fwd->connect_host);
+       if (fwd->listen_host != NULL)
+               xfree(fwd->listen_host);
+       return (0);
+}
This page took 0.069205 seconds and 4 git commands to generate.