Example #1
0
  void SocksConnection::HandleRequest() 
  {
    if(_socket->bytesAvailable() < _addr_len) {
      return;
    }

    QByteArray socks_addr = _socket->read(_addr_len);
    QString host;
    quint16 port;
    if(!ParseSocksAddress(socks_addr, host, port)) {
      EstablishFail(SocksReply_AddressTypeNotSupported);
      return;
    }

    qDebug() << "SOCKS Host Parsed:" << host << port;

    switch(_command) {
      case SocksCommand_Connect:
        StartConnect(host, port);
        break;
      case SocksCommand_UdpAssociate:
        StartUdpAssociate(host, port);
        break;
      default:
        qDebug() << "FAIL: Command not supported";
        EstablishFail(SocksReply_CommandNotSupported);
        return;
    }

    if(_socket->bytesAvailable()) {
      ReadFromSocket();
    }
  }
Example #2
0
  void SocksConnection::ProcessRequest() {
    if(_addr_buf.count() < 3) {
      qDebug() << "Address string is too short";
      return EstablishFail(SocksReply_AddressTypeNotSupported);
    }

    int bytes_read;
    SocksHostAddress dest_addr;

    SocksAddressType code = ParseSocksAddressBytes(_addr_type, _addr_buf, dest_addr, bytes_read);

    if(!(code == SocksAddress_IPv4 || code == SocksAddress_DomainName)) {
      qDebug() << "SOCKS FAIL!";
      return EstablishFail(SocksReply_AddressTypeNotSupported);
    }

    qDebug() << "SOCKS Parsed Host" << dest_addr.ToString();

    switch(_command) {
      case SocksCommand_Connect:
        StartConnect(dest_addr);
        return;

      case SocksCommand_UdpAssociate:
        StartUdpAssociate(dest_addr);
        return;

      default:
        qDebug() << "FAIL: Command not supported";
        return EstablishFail(SocksReply_CommandNotSupported);
    } 
  }
Example #3
0
  void SocksConnection::StartUdpAssociate(const QString &, quint16)
  {
    _udp_socket = QSharedPointer<QUdpSocket>(new QUdpSocket());
    if(!_udp_socket->bind(_socket->localAddress(), 0)) {
      EstablishFail(SocksReply_GeneralServerFailure);
      return;
    }
    
    connect(_udp_socket.data(), SIGNAL(readyRead()), this, SLOT(UdpReadFromSocket()));
    connect(_udp_socket.data(), SIGNAL(disconnected()), this, SLOT(Close()));
    connect(_udp_socket.data(), SIGNAL(error(QAbstractSocket::SocketError)), 
             SLOT(UdpHandleError(QAbstractSocket::SocketError)));

    QByteArray verif_bytes = _verif_key->GetByteArray();
    _conn_id = Hash().ComputeHash(verif_bytes);

    emit ProxyConnected();
    _state = ConnState_Connected;

    TunnelPacket packet = TunnelPacket::BuildUdpStart(GetConnectionId(),
        verif_bytes);
    SendUpstreamPacket(packet.GetPacket());

    qDebug() << "SOCKS UDP Addr" << _udp_socket->localAddress() << _udp_socket->localPort();
    WriteSocksReply(SocksReply_Succeeded, _udp_socket->localAddress(),
        _udp_socket->localPort());
  }
Example #4
0
  void SocksConnection::HandleRequestHeader()
  {
    int header_len = 5;
    if(_socket->bytesAvailable() < header_len) {
      return;
    }

    QByteArray request_buf = _socket->read(3);
    char addr[2];
    Q_ASSERT(2 == _socket->peek(addr, 2));

    // Request header -- 4 bytes fixed:
    //  byte[0] = version
    //  byte[1] = command (connect, bind, or UDP associate)
    //  byte[2] = reserved
    //  byte[3] = address type
    //  byte[4] = first byte of address

    if(((uchar)request_buf[0] != (uchar)SocksVersion_5) || request_buf[2]) {
      Close();
      return;
    }
    
    _command = request_buf[1];
    _addr_len = 1;

    switch(addr[0]) {
      case SocksAddress_IPv4:
        qDebug() << "IS IPv4 address";
        _addr_len += 4;
        break;
      case SocksAddress_DomainName:
        qDebug() << "IS DomainName address";
        _addr_len += addr[1] + 1;
        break;
      case SocksAddress_IPv6:
        _addr_len += 16;
        break;
      default: 
        qDebug() << "Received an invalid SocksAddress type";
        EstablishFail(SocksReply_AddressTypeNotSupported);
        return;
    }

    // Add two bytes for the port number
    _addr_len += 2; 

    _state = ConnState_WaitingForRequest;

    if(_socket->bytesAvailable() >= _addr_len) {
      ReadFromSocket();
    }
  }
Example #5
0
  void SocksConnection::StartUdpAssociate(const SocksHostAddress &peer_host)
  {
    if(!peer_host.IsHostName() 
        && peer_host.GetPort() 
        && peer_host.GetAddress() != QHostAddress::Any 
        && peer_host.GetAddress() != QHostAddress::AnyIPv6) {
      _udp_peer = peer_host.GetAddress();
      _udp_peer_port = peer_host.GetPort();
    }

    _udp_socket = QSharedPointer<QUdpSocket>(new QUdpSocket());
    // Bind to some accessible port on the same address as the
    // SOCKS TCP server 
    _udp_socket->bind(_socket->localAddress(), 0);
    
    if(_udp_socket->state() != QAbstractSocket::BoundState) {
      return EstablishFail(SocksReply_GeneralServerFailure);
    }
    
    // Connect to methods here
    connect(_udp_socket.data(), SIGNAL(readyRead()), this, SLOT(UdpReadFromSocket()));
    connect(_udp_socket.data(), SIGNAL(disconnected()), this, SLOT(Close()));
    connect(_udp_socket.data(), SIGNAL(error(QAbstractSocket::SocketError)), 
             SLOT(UdpHandleError(QAbstractSocket::SocketError)));

    QByteArray verif_bytes = _verif_key->GetByteArray();
    QByteArray packet = UdpStartPacket(verif_bytes).ToByteArray();

    // Start the connection
    _conn_id = _hash_algo->ComputeHash(verif_bytes);
    emit ProxyConnected();
    _state = ConnState_Connected;

    SendUpstreamPacket(packet); 

    qDebug() << "SOCKS UDP Addr" << _udp_socket->localAddress() << _udp_socket->localPort();
    SocksConnection::WriteSocksReply(SocksReply_Succeeded, _udp_socket->localAddress(), _udp_socket->localPort());
  }