]> andersk Git - openssh.git/commitdiff
- markus@cvs.openbsd.org 2003/07/02 14:51:16
authordtucker <dtucker>
Thu, 3 Jul 2003 03:55:19 +0000 (03:55 +0000)
committerdtucker <dtucker>
Thu, 3 Jul 2003 03:55:19 +0000 (03:55 +0000)
     [channels.c ssh.1 ssh_config.5]
     (re)add socks5 suppport to -D; ok djm@
     now ssh(1) can act both as a socks 4 and socks 5 server and
     dynamically forward ports.

ChangeLog
channels.c
ssh.1
ssh_config.5

index 06c3b620fd33c034a87697793b5177b625282d02..c2c151039995ee1c3573c24028451b617b864a07 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
    - markus@cvs.openbsd.org 2003/07/02 12:56:34
      [channels.c]
      deny dynamic forwarding with -R for v1, too; ok djm@
+   - markus@cvs.openbsd.org 2003/07/02 14:51:16
+     [channels.c ssh.1 ssh_config.5]
+     (re)add socks5 suppport to -D; ok djm@
+     now ssh(1) can act both as a socks 4 and socks 5 server and
+     dynamically forward ports.
 
 20030630
  - (djm) Search for support functions necessary to build our 
index ce07db5c0225c13c6b8df0990be81a9000f82ca9..e5b2b8c515580a92c9b832cca66850430a3761ae 100644 (file)
@@ -39,7 +39,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.192 2003/07/02 12:56:34 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.193 2003/07/02 14:51:16 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -54,7 +54,7 @@ RCSID("$OpenBSD: channels.c,v 1.192 2003/07/02 12:56:34 markus Exp $");
 #include "key.h"
 #include "authfd.h"
 #include "pathnames.h"
-
+#include "bufaux.h"
 
 /* -- channel core */
 
@@ -941,6 +941,117 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
        return 1;
 }
 
+/* try to decode a socks5 header */
+#define SSH_SOCKS5_AUTHDONE    0x1000
+#define SSH_SOCKS5_NOAUTH      0x00
+#define SSH_SOCKS5_IPV4                0x01
+#define SSH_SOCKS5_DOMAIN      0x03
+#define SSH_SOCKS5_IPV6                0x04
+#define SSH_SOCKS5_CONNECT     0x01
+#define SSH_SOCKS5_SUCCESS     0x00
+
+static int
+channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
+{
+       struct {
+               u_int8_t version;
+               u_int8_t command;
+               u_int8_t reserved;
+               u_int8_t atyp;
+       } s5_req, s5_rsp;
+       u_int16_t dest_port;
+       u_char *p, dest_addr[255+1];
+       int i, have, found, nmethods, addrlen, af;
+
+       debug2("channel %d: decode socks5", c->self);
+       p = buffer_ptr(&c->input);
+       if (p[0] != 0x05)
+               return -1;
+       have = buffer_len(&c->input);
+       if (!(c->flags & SSH_SOCKS5_AUTHDONE)) {
+               /* format: ver | nmethods | methods */
+               if (have < 2) 
+                       return 0;
+               nmethods = p[1];
+               if (have < nmethods + 2)
+                       return 0;
+               /* look for method: "NO AUTHENTICATION REQUIRED" */
+               for (found = 0, i = 2 ; i < nmethods + 2; i++) {
+                       if (p[i] == SSH_SOCKS5_NOAUTH ) {
+                               found = 1;
+                               break;
+                       }
+               }
+               if (!found) {
+                       debug("channel %d: method SSH_SOCKS5_NOAUTH not found",
+                           c->self);
+                       return -1;
+               }
+               buffer_consume(&c->input, nmethods + 2);
+               buffer_put_char(&c->output, 0x05);              /* version */
+               buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH); /* method */
+               FD_SET(c->sock, writeset);
+               c->flags |= SSH_SOCKS5_AUTHDONE;
+               debug2("channel %d: socks5 auth done", c->self);
+               return 0;                               /* need more */
+       }
+       debug2("channel %d: socks5 post auth", c->self);
+       if (have < sizeof(s5_req)+1)
+               return 0;                       /* need more */
+       memcpy((char *)&s5_req, p, sizeof(s5_req));
+       if (s5_req.version != 0x05 ||
+           s5_req.command != SSH_SOCKS5_CONNECT ||
+           s5_req.reserved != 0x00) {
+               debug("channel %d: only socks5 connect supported", c->self);
+               return -1;
+       }
+       switch(s5_req.atyp){
+       case SSH_SOCKS5_IPV4:
+               addrlen = 4;
+               af = AF_INET;
+               break;
+       case SSH_SOCKS5_DOMAIN:
+               addrlen = p[sizeof(s5_req)];
+               af = -1;
+               break;
+       case SSH_SOCKS5_IPV6:
+               addrlen = 16;
+               af = AF_INET6;
+               break;
+       default:
+               debug("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);
+               return -1;
+       }
+       if (have < 4 + addrlen + 2)
+               return 0;
+       buffer_consume(&c->input, sizeof(s5_req));
+       if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
+               buffer_consume(&c->input, 1);    /* host string length */
+       buffer_get(&c->input, (char *)&dest_addr, addrlen);
+       buffer_get(&c->input, (char *)&dest_port, 2);
+       dest_addr[addrlen] = '\0';
+       if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
+               strlcpy(c->path, dest_addr, sizeof(c->path));
+       else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL)
+               return -1;
+       c->host_port = ntohs(dest_port);
+       
+       debug("channel %d: dynamic request: socks5 host %s port %u command %u",
+           c->self, c->path, c->host_port, s5_req.command);
+
+       s5_rsp.version = 0x05;
+       s5_rsp.command = SSH_SOCKS5_SUCCESS;
+       s5_rsp.reserved = 0;                    /* ignored */
+       s5_rsp.atyp = SSH_SOCKS5_IPV4;
+       ((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY;
+       dest_port = 0;                          /* ignored */
+
+       buffer_append(&c->output, (char *)&s5_rsp, sizeof(s5_rsp));
+       buffer_append(&c->output, (char *)&dest_addr, sizeof(struct in_addr));
+       buffer_append(&c->output, (char *)&dest_port, sizeof(dest_port));
+       return 1;
+}
+
 /* dynamic port forwarding */
 static void
 channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
@@ -953,7 +1064,7 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
        debug2("channel %d: pre_dynamic: have %d", c->self, have);
        /* buffer_dump(&c->input); */
        /* check if the fixed size part of the packet is in buffer. */
-       if (have < 4) {
+       if (have < 3) {
                /* need more */
                FD_SET(c->sock, readset);
                return;
@@ -964,6 +1075,9 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
        case 0x04:
                ret = channel_decode_socks4(c, readset, writeset);
                break;
+       case 0x05:
+               ret = channel_decode_socks5(c, readset, writeset);
+               break;
        default:
                ret = -1;
                break;
diff --git a/ssh.1 b/ssh.1
index defc0e6409e5b56e191c3f4f961ea2969dd61b21..8a7d2f428548c5400269a005f504de2ca8ec2c54 100644 (file)
--- a/ssh.1
+++ b/ssh.1
@@ -34,7 +34,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh.1,v 1.173 2003/06/10 09:12:11 jmc Exp $
+.\" $OpenBSD: ssh.1,v 1.174 2003/07/02 14:51:16 markus Exp $
 .Dd September 25, 1999
 .Dt SSH 1
 .Os
@@ -649,9 +649,9 @@ on the local side, and whenever a connection is made to this port, the
 connection is forwarded over the secure channel, and the application
 protocol is then used to determine where to connect to from the
 remote machine.
-Currently the SOCKS4 protocol is supported, and
+Currently the SOCKS4 and SOCKS5 protocols are supported, and
 .Nm
-will act as a SOCKS4 server.
+will act as a SOCKS server.
 Only root can forward privileged ports.
 Dynamic port forwardings can also be specified in the configuration file.
 .It Fl 1
index 56df3acec7cc72703964514f86527fe076de8d42..79d05f018ae4d6499fd2bc4d6c0c01eba8974797 100644 (file)
@@ -34,7 +34,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh_config.5,v 1.14 2003/06/23 09:02:44 markus Exp $
+.\" $OpenBSD: ssh_config.5,v 1.15 2003/07/02 14:51:16 markus Exp $
 .Dd September 25, 1999
 .Dt SSH_CONFIG 5
 .Os
@@ -246,9 +246,9 @@ over the secure channel, and the application
 protocol is then used to determine where to connect to from the
 remote machine.
 The argument must be a port number.
-Currently the SOCKS4 protocol is supported, and
+Currently the SOCKS4 and SOCKS5 protocols are supported, and
 .Nm ssh
-will act as a SOCKS4 server.
+will act as a SOCKS server.
 Multiple forwardings may be specified, and
 additional forwardings can be given on the command line.
 Only the superuser can forward privileged ports.
This page took 0.054098 seconds and 5 git commands to generate.