Exemplo n.º 1
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());
  }
Exemplo n.º 2
0
  void SocksConnection::StartConnect(const QString &host, quint16 port)
  {
    QByteArray verif_bytes = _verif_key->GetByteArray();
    _conn_id = Hash().ComputeHash(verif_bytes);

    emit ProxyConnected();
    _state = ConnState_Connected;

    TunnelPacket packet = TunnelPacket::BuildTcpStart(GetConnectionId(),
        host, port, verif_bytes);
    SendUpstreamPacket(packet.GetPacket());
    WriteSocksReply(SocksReply_Succeeded, _socket->localAddress(),
        _socket->localPort());
  }
Exemplo n.º 3
0
  void SocksConnection::HandleConnected()
  {
    if(_command != SocksCommand_Connect) {
      qWarning() << "SOCKS Got TCP data on a UDP channel";
      Close();
    }

    while(_socket->bytesAvailable()) {
      // This seems rather large...
      QByteArray data = _socket->read(TunnelPacket::MAX_MESSAGE_SIZE);
      qDebug() << "SOCKS Read" << data.count() << "bytes from socket";
      TunnelPacket packet = TunnelPacket::BuildTcpRequest(GetConnectionId(), data);
      SendUpstreamPacket(packet.GetPacket());
    } 
  }
Exemplo n.º 4
0
  void SocksConnection::StartConnect(const SocksHostAddress &dest_host) 
  {
    QByteArray verif_bytes = _verif_key->GetByteArray();
    QByteArray packet = TcpStartPacket(verif_bytes, dest_host).ToByteArray();

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

    SendUpstreamPacket(packet); 
    WriteSocksReply(SocksReply_Succeeded, QHostAddress(), 8888);

    ReadFromSocket();
  }
Exemplo n.º 5
0
  void SocksConnection::UdpProcessDatagram(const QByteArray &datagram) 
  {
    if(datagram.count() < 6) {
      qWarning() << "SOCKS UDP packet too small to include header. Len:" << datagram.count();
      return;
    }

    /* Each UDP packet gets the following header:
     * +----+------+------+----------+----------+----------+
     * |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
     * +----+------+------+----------+----------+----------+
     * | 2  |  1   |  1   | Variable |    2     | Variable |
     * +----+------+------+----------+----------+----------+
     */

    if(datagram[0] || datagram[1]) {
      qWarning() << "SOCKS UDP reserved bytes are non-zero"; 
      return;
    }

    if(datagram[2]) {
      qWarning() << "SOCKS UDP fragmentation unsupported. Dropping fragment packet.";
      return;
    }

    char addr_type = datagram[3];

    QByteArray addr_bytes = datagram.mid(4);

    SocksHostAddress dest_addr;
    int bytes_read;

    SocksAddressType code = ParseSocksAddressBytes(addr_type, addr_bytes, dest_addr, bytes_read);
    if(code == SocksAddress_Illegal || code == SocksAddress_Unsupported) {
      qWarning() << "SOCKS got invalid address type";
      return;
    }

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

    QByteArray payload = datagram.mid(4 + bytes_read);
    SendUpstreamPacket(
        UdpRequestPacket(
          _conn_id, 
          _signing_key->Sign(dest_addr.ToString().toAscii() + payload), 
          dest_addr, 
          payload).ToByteArray()); 
  }
Exemplo n.º 6
0
  void SocksConnection::Close()
  {
    if(!_socket_open) return;
    _socket_open = false;

    if(_conn_id.count()) {
      qDebug() << "MEM Send finish";
      SendUpstreamPacket(FinishPacket(_conn_id).ToByteArray());
    }

    _socket->close();
    _socket->deleteLater();

    qDebug() << "Close()";
    emit Closed();
  }
Exemplo n.º 7
0
  void SocksConnection::HandleConnected()
  {
    if(_command != SocksCommand_Connect) {
      qWarning() << "SOCKS Got TCP data on a UDP channel";
      Close();
    }

    do {
      QByteArray data = _socket->read(BytesPerPacket);
      qDebug() << "SOCKS Read" << data.count() << "bytes from socket";
      TcpRequestPacket reqp(_conn_id, _signing_key->Sign(data), data);

      QByteArray req_bytes = reqp.ToByteArray();
      qDebug() << "SOCKS Sending request packet of bytes" << req_bytes.count();
      SendUpstreamPacket(req_bytes);
    } while(_socket->bytesAvailable());
  }
Exemplo n.º 8
0
  void SocksConnection::UdpProcessDatagram(const QByteArray &datagram) 
  {
    if(datagram.count() < 6) {
      qWarning() << "SOCKS UDP packet too small to include header. Len:" << datagram.count();
      return;
    }

    /* Each UDP packet gets the following header:
     * +----+------+------+----------+----------+----------+
     * |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
     * +----+------+------+----------+----------+----------+
     * | 2  |  1   |  1   | Variable |    2     | Variable |
     * +----+------+------+----------+----------+----------+
     */

    if(datagram[0] || datagram[1]) {
      qWarning() << "SOCKS UDP reserved bytes are non-zero"; 
      return;
    }

    if(datagram[2]) {
      qWarning() << "SOCKS UDP fragmentation unsupported. Dropping fragment packet.";
      return;
    }

    QByteArray addr = QByteArray::fromRawData(datagram.constData() + 3,
        datagram.size() - 3);
    QString host;
    quint16 port;
    int read;

    if(!ParseSocksAddress(addr, host, port, read)) {
      qDebug() << "SOCKS received an invalid address type";
      return;
    }

    QByteArray payload = QByteArray::fromRawData(addr.constData() + read,
        addr.size() - read);
    qDebug() << "SOCKS Host" << host << port << "packet size" << payload.size();

    TunnelPacket packet = TunnelPacket::BuildUdpRequest(GetConnectionId(),
        host, port, payload);
    SendUpstreamPacket(packet.GetPacket());
  }
Exemplo n.º 9
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());
  }