/**
   * Initiator and target should successfully connect to the local SOCKS5 proxy.
   *
   * @throws Exception should not happen
   */
  @Test
  public void shouldSuccessfullyConnectThroughLocalSocks5Proxy() throws Exception {

    // start a local SOCKS5 proxy
    Socks5Proxy.setLocalSocks5ProxyPort(proxyPort);
    Socks5Proxy socks5Proxy = Socks5Proxy.getSocks5Proxy();
    socks5Proxy.start();

    // test data
    final byte[] data = new byte[] {1, 2, 3};

    // create digest
    final String digest = Socks5Utils.createDigest(sessionID, initiatorJID, targetJID);

    // allow connection of target with this digest
    socks5Proxy.addTransfer(digest);

    // build stream host information
    final StreamHost streamHost =
        new StreamHost(connection.getUser(), socks5Proxy.getLocalAddresses().get(0));
    streamHost.setPort(socks5Proxy.getPort());

    // target connects to local SOCKS5 proxy
    Thread targetThread =
        new Thread() {

          @Override
          public void run() {
            try {
              Socks5Client targetClient = new Socks5Client(streamHost, digest);
              Socket socket = targetClient.getSocket(10000);
              socket.getOutputStream().write(data);
            } catch (Exception e) {
              fail(e.getMessage());
            }
          }
        };
    targetThread.start();

    Thread.sleep(200);

    // initiator connects
    Socks5ClientForInitiator socks5Client =
        new Socks5ClientForInitiator(streamHost, digest, connection, sessionID, targetJID);

    Socket socket = socks5Client.getSocket(10000);

    // verify test data
    InputStream in = socket.getInputStream();
    for (int i = 0; i < data.length; i++) {
      assertEquals(data[i], in.read());
    }

    targetThread.join();

    protocol.verifyAll(); // assert no XMPP messages were sent

    socks5Proxy.removeTransfer(digest);
    socks5Proxy.stop();
  }
  /**
   * If the target is not connected to the local SOCKS5 proxy an exception should be thrown.
   *
   * @throws Exception should not happen
   */
  @Test
  public void shouldFailIfTargetIsNotConnectedToLocalSocks5Proxy() throws Exception {

    // start a local SOCKS5 proxy
    Socks5Proxy.setLocalSocks5ProxyPort(proxyPort);
    Socks5Proxy socks5Proxy = Socks5Proxy.getSocks5Proxy();
    socks5Proxy.start();

    // build stream host information for local SOCKS5 proxy
    StreamHost streamHost =
        new StreamHost(connection.getUser(), socks5Proxy.getLocalAddresses().get(0));
    streamHost.setPort(socks5Proxy.getPort());

    // create digest to get the socket opened by target
    String digest = Socks5Utils.createDigest(sessionID, initiatorJID, targetJID);

    Socks5ClientForInitiator socks5Client =
        new Socks5ClientForInitiator(streamHost, digest, connection, sessionID, targetJID);

    try {
      socks5Client.getSocket(10000);

      fail("exception should be thrown");
    } catch (SmackException e) {
      assertTrue(e.getMessage().contains("target is not connected to SOCKS5 proxy"));
      protocol.verifyAll(); // assert no XMPP messages were sent
    }

    socks5Proxy.stop();
  }
Example #3
0
  private IByteStreamConnection connectInternal(String connectionID, JID peer) throws IOException {

    IByteStreamConnection connection = null;

    final String connectionIDToken = toConnectionIDToken(connectionID, OUT, peer);

    synchronized (currentOutgoingConnectionEstablishments) {
      if (!currentOutgoingConnectionEstablishments.contains(connectionIDToken)) {
        connection = getCurrentConnection(connectionID, peer);

        if (connection == null) currentOutgoingConnectionEstablishments.add(connectionIDToken);
      }

      if (connection != null) return connection;
    }

    connectLock.lock();

    try {

      connection = getCurrentConnection(connectionID, peer);

      if (connection != null) return connection;

      JID connectionJID = currentLocalJID;

      if (connectionJID == null) throw new IOException("not connected to a XMPP server");

      ArrayList<ITransport> transportModesToUse = new ArrayList<ITransport>(availableTransports);

      LOG.debug(
          "currently used IP addresses for Socks5Proxy: "
              + Arrays.toString(Socks5Proxy.getSocks5Proxy().getLocalAddresses().toArray()));

      for (ITransport transport : transportModesToUse) {
        LOG.info(
            "establishing connection to "
                + peer.getBase()
                + " from "
                + connectionJID
                + " using "
                + transport);
        try {
          connection = transport.connect(connectionID, peer);
          break;
        } catch (IOException e) {
          LOG.error(peer + " failed to connect using " + transport + ": " + e.getMessage(), e);
        } catch (InterruptedException e) {
          IOException io = new InterruptedIOException("connecting cancelled: " + e.getMessage());
          io.initCause(e);
          throw io;
        } catch (Exception e) {
          LOG.error(
              peer
                  + " failed to connect using "
                  + transport
                  + " because of an unknown error: "
                  + e.getMessage(),
              e);
        }
      }

      if (connection != null) {
        byteStreamConnectionListener.connectionChanged(connectionID, peer, connection, false);

        return connection;
      }

      throw new IOException("could not connect to: " + peer);
    } finally {
      synchronized (currentOutgoingConnectionEstablishments) {
        currentOutgoingConnectionEstablishments.remove(connectionIDToken);
      }
      connectLock.unlock();
    }
  }
 /** Reset default port for local SOCKS5 proxy. */
 @After
 public void cleanup() {
   Socks5Proxy.setLocalSocks5ProxyPort(7777);
 }