[BACK]Return to channels.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/channels.c between version 1.192 and 1.193

version 1.192, 2003/07/02 12:56:34 version 1.193, 2003/07/02 14:51:16
Line 54 
Line 54 
 #include "key.h"  #include "key.h"
 #include "authfd.h"  #include "authfd.h"
 #include "pathnames.h"  #include "pathnames.h"
   #include "bufaux.h"
   
   
 /* -- channel core */  /* -- channel core */
   
 /*  /*
Line 940 
Line 940 
         return 1;          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 */  /* dynamic port forwarding */
 static void  static void
 channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)  channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
Line 952 
Line 1063 
         debug2("channel %d: pre_dynamic: have %d", c->self, have);          debug2("channel %d: pre_dynamic: have %d", c->self, have);
         /* buffer_dump(&c->input); */          /* buffer_dump(&c->input); */
         /* check if the fixed size part of the packet is in buffer. */          /* check if the fixed size part of the packet is in buffer. */
         if (have < 4) {          if (have < 3) {
                 /* need more */                  /* need more */
                 FD_SET(c->sock, readset);                  FD_SET(c->sock, readset);
                 return;                  return;
Line 962 
Line 1073 
         switch (p[0]) {          switch (p[0]) {
         case 0x04:          case 0x04:
                 ret = channel_decode_socks4(c, readset, writeset);                  ret = channel_decode_socks4(c, readset, writeset);
                   break;
           case 0x05:
                   ret = channel_decode_socks5(c, readset, writeset);
                 break;                  break;
         default:          default:
                 ret = -1;                  ret = -1;

Legend:
Removed from v.1.192  
changed lines
  Added in v.1.193