Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Работа через socks5 (https://forum.antichat.xyz/showthread.php?t=128571)

Ant1b10t1k 06.07.2009 18:41

Работа через socks5
 
Хочу написать паблик чекер акк. mail.ru через sock5.
Нашел удобный класс для работы с проксями. После того как я подключился к smtp.mail.ru через проксю, я должен от него получить данные, а потом отправить. Загвоздка в том что я получаю данные и сразу же хост мне lost connection. Все уже пересмотрел ошибок вроде нет. Посмотрите вы пожалуйста. С прокси все нормально. Без проксей все получается, думаю что ошибка в классе а найти не могу помогите.

Код:

#include <winsock2.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <iostream>
  using namespace std;

  #pragma comment(lib, "Ws2_32.lib")

class CTSocket
{
    public:
      virtual BOOL CreateSocket();
      virtual BOOL Connect(unsigned long ip, unsigned short port);
      virtual BOOL Connect(LPCSTR name, unsigned short port);
      virtual int Send(const char* str, int len);
      virtual int Recv(char* buf, int max);
      virtual void Close();
      virtual unsigned long GetHost(); // Узнать свой адрес. Это тоже может понадобиться.

    private:
      SOCKET sock;
  };

  BOOL CTSocket::CreateSocket()
  {
          return (sock = socket(AF_INET, SOCK_STREAM, 0)) != NULL;
  }

  BOOL CTSocket::Connect(unsigned long ip, unsigned short port)
  {
          SOCKADDR_IN addr;
          memset(&addr, 0, sizeof(addr));
          addr.sin_family = AF_INET;
          addr.sin_addr.S_un.S_addr = ip;
          addr.sin_port = port;
          return connect(sock, (SOCKADDR*)&addr, sizeof(addr)) == 0;
  }

  BOOL CTSocket::Connect(LPCSTR name, unsigned short port)
  {
          HOSTENT* p = gethostbyname(name);
          if (p == NULL) return FALSE;
          return Connect(p->h_addr_list[0], port);
  }

  int CTSocket::Send(const char* str, int len)
  {
          return send(sock, str, len, 0);
  }

  int CTSocket::Recv(char* buf, int max)
  {
          return recv(sock, buf, max, 0);
  }

  void CTSocket::Close()
  {
          closesocket(sock);
  }

  unsigned long CTSocket::GetHost()
  {
          SOCKADDR_IN addr;
          int cbName = sizeof(addr);
          if (getsockname(sock, (SOCKADDR*)&addr, &cbName) == 0)
          {
                  return addr.sin_addr.S_un.S_addr;
          } else return 0;
  }


  class CSocksSocket : public CTSocket
  {
    public:
      virtual BOOL CreateSocket();
      virtual BOOL Connect(unsigned long ip, unsigned short port);
      virtual BOOL Connect(LPCSTR name, unsigned short port);
      virtual int Send(const char* str, int len);
      virtual int Recv(char* buf, int max);
      virtual void Close();
      virtual unsigned long GetHost();

    CTSocket* pSocket;
    unsigned long socks_ip;
    unsigned short socks_port;

    private:
      char buffer[512];    // Такого размера точно хватит
      unsigned long l_ip;  // Адрес, возвращаемый функцией GetHost()
  };

  // Реализация
  BOOL CSocksSocket::CreateSocket()
  {
    if (!pSocket->CreateSocket()) return FALSE;
        if (!pSocket->Connect(socks_ip, socks_port)) return FALSE;
    buffer[0] = 5;  // Ver
    buffer[1] = 1;  // 1 method
    buffer[2] = 0;  // no auth
    pSocket->Send(buffer, 3);
    int n = pSocket->Recv(buffer, 2);
    if (n != 2) return FALSE;
    if (buffer[1] != 0) return FALSE;  // method 0 not supported
    return TRUE;
  }

  BOOL CSocksSocket::Connect(unsigned long ip, unsigned short port)
  {
    buffer[0] = 5;  // Ver
    buffer[1] = 1;  // CONNECT
    buffer[2] = 0;  // Reserved
    buffer[3] = 1;  // IPv4
    *((unsigned long*)(buffer + 4)) = ip;
    *((unsigned short*)(buffer + 8)) = port;
    pSocket->Send(buffer, 10);
    int n = pSocket->Recv(buffer, 10);
    if (n != 10) return FALSE;
    if (buffer[1] != 0) return FALSE; // Can't connect
    if (buffer[3] != 1) return FALSE; // Будем требовать, чтобы нам сказали IP, а не что-нибудь другое.
    l_ip = *((unsigned long*)(buffer + 4));
    return TRUE;
  }

  BOOL CSocksSocket::Connect(LPCSTR name, unsigned short port)
  {
    buffer[0] = 5;
    buffer[1] = 1;
    buffer[2] = 0;
    buffer[3] = 3;  // Domain name
    int m = strlen(name);
    buffer[4] = m;  // Length byte
    memcpy(buffer+5, name, m); // Копируем строку без завершающего нуля
    *((unsigned short*)(buffer + 5 + m)) = port;
    pSocket->Send(buffer, m + 7);
    int n = pSocket->Recv(buffer, 10);
    if (n != 10) return FALSE;
    if (buffer[1] != 0) return FALSE;
    if (buffer[3] != 1) return FALSE; // Будем требовать, чтобы нам сказали IP, а не что-нибудь другое.
    l_ip = *((unsigned long*)(buffer + 4));
    return TRUE;
  }

  int CSocksSocket::Send(const char* str, int len)
  {
    return pSocket->Send(str, len);
  }

  int CSocksSocket::Recv(char* buf, int max)
  {
    return pSocket->Recv(buf, max);
  }

  void CSocksSocket::Close()
  {
    pSocket->Close();
  }

  unsigned long CSocksSocket::GetHost()
  {
    return l_ip;
  }

  // Ну, а теперь тестовая прога
void main()
{
    WSADATA wsadata;
    CTSocket tsock;
    CSocksSocket ssock;
        ssock.pSocket = &tsock;

    WSAStartup(MAKEWORD(2,2), &wsadata); 

    ssock.socks_ip = inet_addr("10.10.7.150"); // Впишите сюда нужный адрес
    ssock.socks_port = htons(1080); // Впишите сюда порт
   
    if (!ssock.CreateSocket()) return;        // Can't connect to socks
                                        // or auth required
    if (!ssock.Connect("smtp.mail.ru", htons(2525))) return; // www.mail.ru
                                                          // is inaccessible
   
    char buf[79];
    ssock.Recv(buf, 79);

    LPSTR q = "EHLO mail.ru";
    ssock.Send(q, strlen(q));

    ssock.Close();
    WSACleanup();
}

Что получаю от сервака. Отловив сниффером

Код:

220 mail.ru ESMTP Mon, 06 Jul 2009 15:39:05 +0400
421 mx39.mail.ru lost input connection
EHLO mail.ru



Время: 11:34