コード例 #1
0
 private int extractAddressAndPort(byte[] data, int index, ATYP atyp)
 {
     if (atyp == ATYP.DOMAINNAME)
     {
         /**
          * the address field contains a fully-qualified domain name.  The first
          * octet of the address field contains the number of octets of name that
          * follow, there is no terminating NUL octet.
          **/
         //read as a pascal string
         byte length = data[index];
         //we might wanna add support for punycode here to hanlde characters like едц
         this.domainName = System.Text.Encoding.ASCII.GetString(data, index + 1, length);
         this.port       = Utils.ByteConverter.ToUInt16(data, index + length + 1, false);
         return(length + 3);
     }
     else if (atyp == ATYP.IPv4 || atyp == ATYP.IPv6)
     {
         byte[] ipBytes;
         if (atyp == ATYP.IPv4)
         {
             ipBytes = new byte[4];//the address is a version-4 IP address, with a length of 4 octets
         }
         else
         {
             ipBytes = new byte[16];//the address is a version-6 IP address, with a length of 16 octets.
         }
         Array.Copy(data, index, ipBytes, 0, ipBytes.Length);
         this.ipAddress = new System.Net.IPAddress(ipBytes);
         this.port      = Utils.ByteConverter.ToUInt16(data, index + ipBytes.Length, false);
         return(ipBytes.Length + 2);
     }
     else
     {
         return(0);
     }
 }
コード例 #2
0
        internal SocksPacket(Frame parentFrame, int packetStartIndex, int packetEndIndex, bool clientToServer)
            : base(parentFrame, packetStartIndex, packetEndIndex, "SOCKS")
        {
            this.clientToServer   = clientToServer;
            this.parsedBytesCount = 0;
            this.atyp             = ATYP.None;

            int index = PacketStartIndex;

            if (clientToServer)
            {
                /**
                 * version identifier/method selection message. Example: 050100
                 * +----+----------+----------+
                 * |VER | NMETHODS | METHODS  |
                 * +----+----------+----------+
                 * | 1  |    1     | 1 to 255 |
                 * +----+----------+----------+
                 * o  X'00' NO AUTHENTICATION REQUIRED
                 * o  X'01' GSSAPI
                 * o  X'02' USERNAME/PASSWORD
                 * o  X'03' to X'7F' IANA ASSIGNED
                 * o  X'80' to X'FE' RESERVED FOR PRIVATE METHODS
                 * o  X'FF' NO ACCEPTABLE METHODS
                 *
                 * SOCKS request. Example 0501000314636865636b2e746f7270726f6a6563742e6f726701bb
                 * +----+-----+-------+------+----------+----------+
                 * |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
                 * +----+-----+-------+------+----------+----------+
                 * | 1  |  1  | X'00' |  1   | Variable |    2     |
                 * +----+-----+-------+------+----------+----------+
                 * o  VER    protocol version: X'05'
                 * o  CMD
                 *      o  CONNECT X'01'
                 *      o  BIND X'02'
                 *      o  UDP ASSOCIATE X'03'
                 * o  RSV    RESERVED
                 * o  ATYP   address type of following address
                 *      o  IP V4 address: X'01'
                 *      o  DOMAINNAME: X'03'
                 *      o  IP V6 address: X'04'
                 * o  DST.ADDR       desired destination address
                 * o  DST.PORT desired destination port in network octet order
                 */

                /**
                 * Username/Password subnegotiation
                 *  +----+------+----------+------+----------+
                 *  |VER | ULEN |  UNAME   | PLEN |  PASSWD  |
                 *  +----+------+----------+------+----------+
                 *  | 1  |  1   | 1 to 255 |  1   | 1 to 255 |
                 *  +----+------+----------+------+----------+
                 *  The VER field contains the current version of the subnegotiation, which is X'01'
                 **/


                //allow unix style line feeds (0x0a) from clients
                this.socksVersion = parentFrame.Data[index++];
                byte nMethodsOrCmdOrUlen = parentFrame.Data[index++];
                byte method1OrRsv        = parentFrame.Data[index++];
                if (method1OrRsv != 0 && packetEndIndex - packetStartIndex == nMethodsOrCmdOrUlen + 1)
                {
                    //version identifier/method selection message
                    index = packetEndIndex + 1;//skip the data
                }
                else if (isLikelyInitialUsernamePasswordNegotiation(parentFrame, packetStartIndex, packetEndIndex))
                {
                    //Username/Password subnegotiation
                    byte userLenght = parentFrame.Data[packetStartIndex + 1];
                    this.username = System.Text.Encoding.ASCII.GetString(parentFrame.Data, PacketStartIndex + 2, userLenght);
                    byte passLength = parentFrame.Data[packetStartIndex + userLenght + 2];
                    this.password = System.Text.Encoding.ASCII.GetString(parentFrame.Data, PacketStartIndex + userLenght + 3, passLength);
                    index         = packetEndIndex + 1;
                }
                else if (method1OrRsv == 0)
                {
                    //SOCKS request
                    this.commandOrReply = nMethodsOrCmdOrUlen;
                    byte atyp = parentFrame.Data[index++];
                    if (Enum.IsDefined(typeof(ATYP), atyp))
                    {
                        this.atyp = (ATYP)atyp;
                        index    += this.extractAddressAndPort(parentFrame.Data, index, this.atyp);
                    }
                    else
                    {
                        index = packetStartIndex;
                    }
                }
            }
            else
            {
                if (base.PacketLength == 2 && parentFrame.Data[packetStartIndex] == 1 && parentFrame.Data[packetStartIndex + 1] == 0)
                {
                    //rfc1929 initial negotiation response
                    index = packetStartIndex + 2;
                }
                else
                {
                    /**
                     * METHOD selection message:
                     * +----+--------+
                     * |VER | METHOD |
                     * +----+--------+
                     * | 1  |   1    |
                     * +----+--------+
                     *
                     * SOCKS reply
                     * +----+-----+-------+------+----------+----------+
                     * |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
                     * +----+-----+-------+------+----------+----------+
                     * | 1  |  1  | X'00' |  1   | Variable |    2     |
                     * +----+-----+-------+------+----------+----------+
                     **/
                    this.socksVersion = parentFrame.Data[index++];
                    if (packetEndIndex - packetStartIndex == 1)
                    {
                        //METHOD selection message
                        index++;//just skip past the method selection
                    }
                    else if (base.PacketLength > 6 && parentFrame.Data[packetStartIndex + 2] == 0)
                    {
                        //SOCKS reply
                        this.commandOrReply = parentFrame.Data[packetStartIndex + 1];
                        byte atyp = parentFrame.Data[packetStartIndex + 3];
                        if (Enum.IsDefined(typeof(ATYP), atyp))
                        {
                            this.atyp = (ATYP)atyp;
                            index    += 3;
                            index    += this.extractAddressAndPort(parentFrame.Data, index, this.atyp);
                        }
                        else
                        {
                            index = packetStartIndex;
                        }
                    }
                    else
                    {
                        index = packetStartIndex;//nothing to parse
                    }
                }
            }
            this.parsedBytesCount = index - packetStartIndex;
        }