Search in sources :

Example 1 with Socks5BytestreamSession

use of org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession in project ecf by eclipse.

the class Socks5BytestreamManager method establishSession.

/**
 * Establishes a SOCKS5 Bytestream with the given user using the given session ID and returns
 * the Socket to send/receive data to/from the user.
 *
 * @param targetJID the JID of the user a SOCKS5 Bytestream should be established
 * @param sessionID the session ID for the SOCKS5 Bytestream request
 * @return the Socket to send/receive data to/from the user
 * @throws XMPPException if the user doesn't support or accept SOCKS5 Bytestreams, if no Socks5
 *         Proxy could be found, if the user couldn't connect to any of the SOCKS5 Proxies
 * @throws IOException if the bytestream could not be established
 * @throws InterruptedException if the current thread was interrupted while waiting
 */
public Socks5BytestreamSession establishSession(String targetJID, String sessionID) throws XMPPException, IOException, InterruptedException {
    XMPPException discoveryException = null;
    // check if target supports SOCKS5 Bytestream
    if (!supportsSocks5(targetJID)) {
        throw new XMPPException(targetJID + " doesn't support SOCKS5 Bytestream");
    }
    List<String> proxies = new ArrayList<String>();
    // determine SOCKS5 proxies from XMPP-server
    try {
        proxies.addAll(determineProxies());
    } catch (XMPPException e) {
        // don't abort here, just remember the exception thrown by determineProxies()
        // determineStreamHostInfos() will at least add the local Socks5 proxy (if enabled)
        discoveryException = e;
    }
    // determine address and port of each proxy
    List<StreamHost> streamHosts = determineStreamHostInfos(proxies);
    if (streamHosts.isEmpty()) {
        throw discoveryException != null ? discoveryException : new XMPPException("no SOCKS5 proxies available");
    }
    // compute digest
    String digest = Socks5Utils.createDigest(sessionID, this.connection.getUser(), targetJID);
    // prioritize last working SOCKS5 proxy if exists
    if (this.proxyPrioritizationEnabled && this.lastWorkingProxy != null) {
        StreamHost selectedStreamHost = null;
        for (StreamHost streamHost : streamHosts) {
            if (streamHost.getJID().equals(this.lastWorkingProxy)) {
                selectedStreamHost = streamHost;
                break;
            }
        }
        if (selectedStreamHost != null) {
            streamHosts.remove(selectedStreamHost);
            streamHosts.add(0, selectedStreamHost);
        }
    }
    Socks5Proxy socks5Proxy = Socks5Proxy.getSocks5Proxy();
    try {
        // add transfer digest to local proxy to make transfer valid
        socks5Proxy.addTransfer(digest);
        // create initiation packet
        Bytestream initiation = createBytestreamInitiation(sessionID, targetJID, streamHosts);
        // send initiation packet
        Packet response = SyncPacketSend.getReply(this.connection, initiation, getTargetResponseTimeout());
        // extract used stream host from response
        StreamHostUsed streamHostUsed = ((Bytestream) response).getUsedHost();
        StreamHost usedStreamHost = initiation.getStreamHost(streamHostUsed.getJID());
        if (usedStreamHost == null) {
            throw new XMPPException("Remote user responded with unknown host");
        }
        // build SOCKS5 client
        Socks5Client socks5Client = new Socks5ClientForInitiator(usedStreamHost, digest, this.connection, sessionID, targetJID);
        // establish connection to proxy
        Socket socket = socks5Client.getSocket(getProxyConnectionTimeout());
        // remember last working SOCKS5 proxy to prioritize it for next request
        this.lastWorkingProxy = usedStreamHost.getJID();
        // negotiation successful, return the output stream
        return new Socks5BytestreamSession(socket, usedStreamHost.getJID().equals(this.connection.getUser()));
    } catch (TimeoutException e) {
        throw new IOException("Timeout while connecting to SOCKS5 proxy");
    } finally {
        // remove transfer digest if output stream is returned or an exception
        // occurred
        socks5Proxy.removeTransfer(digest);
    }
}
Also used : StreamHostUsed(org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHostUsed) Packet(org.jivesoftware.smack.packet.Packet) ArrayList(java.util.ArrayList) IOException(java.io.IOException) Bytestream(org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream) XMPPException(org.jivesoftware.smack.XMPPException) StreamHost(org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost) Socket(java.net.Socket) TimeoutException(java.util.concurrent.TimeoutException)

Example 2 with Socks5BytestreamSession

use of org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession in project ecf by eclipse.

the class Socks5TransferNegotiator method negotiateIncomingStream.

@Override
InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPException, InterruptedException {
    // build SOCKS5 Bytestream request
    Socks5BytestreamRequest request = new ByteStreamRequest(this.manager, (Bytestream) streamInitiation);
    // always accept the request
    Socks5BytestreamSession session = request.accept();
    // test input stream
    try {
        PushbackInputStream stream = new PushbackInputStream(session.getInputStream());
        int firstByte = stream.read();
        stream.unread(firstByte);
        return stream;
    } catch (IOException e) {
        throw new XMPPException("Error establishing input stream", e);
    }
}
Also used : Socks5BytestreamRequest(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest) PushbackInputStream(java.io.PushbackInputStream) IOException(java.io.IOException) XMPPException(org.jivesoftware.smack.XMPPException) Socks5BytestreamSession(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession)

Example 3 with Socks5BytestreamSession

use of org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession in project Smack by igniterealtime.

the class Socks5ByteStreamTest method testBiDirectionalSocks5BytestreamWithRemoteSocks5Proxy.

/**
 * Socks5 bytestream should be successfully established using a Socks5 proxy provided by the
 * XMPP server. The established connection should transfer data bidirectional if the Socks5
 * proxy supports it.
 * <p>
 * Support for bidirectional Socks5 bytestream:
 * <ul>
 * <li>Openfire (3.6.4 and below) - no</li>
 * <li>ejabberd (2.0.5 and higher) - yes</li>
 * </ul>
 * <p>
 * This test will fail if the XMPP server doesn't provide any Socks5 proxies or the Socks5 proxy
 * only allows Socks5 bytestreams in the context of a file transfer (like Openfire in default
 * configuration, see xmpp.proxy.transfer.required flag).
 *
 * @throws Exception if no Socks5 proxies found or proxy is unwilling to activate Socks5
 *         bytestream
 */
public void testBiDirectionalSocks5BytestreamWithRemoteSocks5Proxy() throws Exception {
    XMPPConnection initiatorConnection = getConnection(0);
    // disable local socks5 proxy
    SmackConfiguration.setLocalSocks5ProxyEnabled(false);
    Socks5Proxy.getSocks5Proxy().stop();
    assertFalse(Socks5Proxy.getSocks5Proxy().isRunning());
    XMPPConnection targetConnection = getConnection(1);
    // test data
    final byte[] data = new byte[] { 1, 2, 3 };
    final SynchronousQueue<byte[]> queue = new SynchronousQueue<byte[]>();
    Socks5BytestreamManager targetByteStreamManager = Socks5BytestreamManager.getBytestreamManager(targetConnection);
    Socks5BytestreamListener incomingByteStreamListener = new Socks5BytestreamListener() {

        public void incomingBytestreamRequest(Socks5BytestreamRequest request) {
            try {
                Socks5BytestreamSession session = request.accept();
                OutputStream outputStream = session.getOutputStream();
                outputStream.write(data);
                outputStream.flush();
                InputStream inputStream = session.getInputStream();
                byte[] receivedData = new byte[3];
                inputStream.read(receivedData);
                queue.put(receivedData);
                session.close();
            } catch (Exception e) {
                fail(e.getMessage());
            }
        }
    };
    targetByteStreamManager.addIncomingBytestreamListener(incomingByteStreamListener);
    Socks5BytestreamManager initiatorByteStreamManager = Socks5BytestreamManager.getBytestreamManager(initiatorConnection);
    Socks5BytestreamSession session = initiatorByteStreamManager.establishSession(targetConnection.getUser());
    assertTrue(session.isMediated());
    // verify stream
    final byte[] receivedData = new byte[3];
    final InputStream inputStream = session.getInputStream();
    FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() {

        public Integer call() throws Exception {
            return inputStream.read(receivedData);
        }
    });
    Thread executor = new Thread(futureTask);
    executor.start();
    try {
        futureTask.get(2000, TimeUnit.MILLISECONDS);
    } catch (TimeoutException e) {
        // reset default configuration
        SmackConfiguration.setLocalSocks5ProxyEnabled(true);
        Socks5Proxy.getSocks5Proxy().start();
        fail("Couldn't send data from target to inititator");
    }
    assertEquals("sent data not equal to received data", data, receivedData);
    OutputStream outputStream = session.getOutputStream();
    outputStream.write(data);
    outputStream.flush();
    outputStream.close();
    assertEquals("received data not equal to sent data", data, queue.take());
    session.close();
    // reset default configuration
    SmackConfiguration.setLocalSocks5ProxyEnabled(true);
    Socks5Proxy.getSocks5Proxy().start();
}
Also used : Socks5BytestreamManager(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager) Socks5BytestreamRequest(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) XMPPConnection(org.jivesoftware.smack.XMPPConnection) TimeoutException(java.util.concurrent.TimeoutException) XMPPException(org.jivesoftware.smack.XMPPException) Socks5BytestreamSession(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession) Socks5BytestreamListener(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamListener) FutureTask(java.util.concurrent.FutureTask) SynchronousQueue(java.util.concurrent.SynchronousQueue) TimeoutException(java.util.concurrent.TimeoutException)

Example 4 with Socks5BytestreamSession

use of org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession in project Smack by igniterealtime.

the class Socks5ByteStreamTest method testSocks5BytestreamWithRemoteSocks5Proxy.

/**
 * Socks5 bytestream should be successfully established using a Socks5 proxy provided by the
 * XMPP server.
 * <p>
 * This test will fail if the XMPP server doesn't provide any Socks5 proxies or the Socks5 proxy
 * only allows Socks5 bytestreams in the context of a file transfer (like Openfire in default
 * configuration, see xmpp.proxy.transfer.required flag).
 *
 * @throws Exception if no Socks5 proxies found or proxy is unwilling to activate Socks5
 *         bytestream
 */
public void testSocks5BytestreamWithRemoteSocks5Proxy() throws Exception {
    // disable local socks5 proxy
    SmackConfiguration.setLocalSocks5ProxyEnabled(false);
    Socks5Proxy.getSocks5Proxy().stop();
    assertFalse(Socks5Proxy.getSocks5Proxy().isRunning());
    XMPPConnection initiatorConnection = getConnection(0);
    XMPPConnection targetConnection = getConnection(1);
    // test data
    final byte[] data = new byte[] { 1, 2, 3 };
    final SynchronousQueue<byte[]> queue = new SynchronousQueue<byte[]>();
    Socks5BytestreamManager targetByteStreamManager = Socks5BytestreamManager.getBytestreamManager(targetConnection);
    Socks5BytestreamListener incomingByteStreamListener = new Socks5BytestreamListener() {

        public void incomingBytestreamRequest(Socks5BytestreamRequest request) {
            InputStream inputStream;
            try {
                Socks5BytestreamSession session = request.accept();
                inputStream = session.getInputStream();
                byte[] receivedData = new byte[3];
                inputStream.read(receivedData);
                queue.put(receivedData);
            } catch (Exception e) {
                fail(e.getMessage());
            }
        }
    };
    targetByteStreamManager.addIncomingBytestreamListener(incomingByteStreamListener);
    Socks5BytestreamManager initiatorByteStreamManager = Socks5BytestreamManager.getBytestreamManager(initiatorConnection);
    Socks5BytestreamSession session = initiatorByteStreamManager.establishSession(targetConnection.getUser());
    OutputStream outputStream = session.getOutputStream();
    assertTrue(session.isMediated());
    // verify stream
    outputStream.write(data);
    outputStream.flush();
    outputStream.close();
    assertEquals("received data not equal to sent data", data, queue.take());
    // reset default configuration
    SmackConfiguration.setLocalSocks5ProxyEnabled(true);
    Socks5Proxy.getSocks5Proxy().start();
}
Also used : Socks5BytestreamManager(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager) Socks5BytestreamListener(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamListener) Socks5BytestreamRequest(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest) InputStream(java.io.InputStream) SynchronousQueue(java.util.concurrent.SynchronousQueue) OutputStream(java.io.OutputStream) XMPPConnection(org.jivesoftware.smack.XMPPConnection) TimeoutException(java.util.concurrent.TimeoutException) XMPPException(org.jivesoftware.smack.XMPPException) Socks5BytestreamSession(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession)

Example 5 with Socks5BytestreamSession

use of org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession in project Smack by igniterealtime.

the class Socks5ByteStreamTest method testSocks5BytestreamWithLocalSocks5Proxy.

/**
 * Socks5 bytestream should be successfully established using the local Socks5 proxy.
 *
 * @throws Exception should not happen
 */
public void testSocks5BytestreamWithLocalSocks5Proxy() throws Exception {
    // setup port for local socks5 proxy
    SmackConfiguration.setLocalSocks5ProxyEnabled(true);
    SmackConfiguration.setLocalSocks5ProxyPort(7778);
    Socks5Proxy socks5Proxy = Socks5Proxy.getSocks5Proxy();
    socks5Proxy.start();
    assertTrue(socks5Proxy.isRunning());
    XMPPConnection initiatorConnection = getConnection(0);
    XMPPConnection targetConnection = getConnection(1);
    // test data
    final byte[] data = new byte[] { 1, 2, 3 };
    final SynchronousQueue<byte[]> queue = new SynchronousQueue<byte[]>();
    Socks5BytestreamManager targetByteStreamManager = Socks5BytestreamManager.getBytestreamManager(targetConnection);
    Socks5BytestreamListener incomingByteStreamListener = new Socks5BytestreamListener() {

        public void incomingBytestreamRequest(Socks5BytestreamRequest request) {
            InputStream inputStream;
            try {
                Socks5BytestreamSession session = request.accept();
                inputStream = session.getInputStream();
                byte[] receivedData = new byte[3];
                inputStream.read(receivedData);
                queue.put(receivedData);
            } catch (Exception e) {
                fail(e.getMessage());
            }
        }
    };
    targetByteStreamManager.addIncomingBytestreamListener(incomingByteStreamListener);
    Socks5BytestreamManager initiatorByteStreamManager = Socks5BytestreamManager.getBytestreamManager(initiatorConnection);
    Socks5BytestreamSession session = initiatorByteStreamManager.establishSession(targetConnection.getUser());
    OutputStream outputStream = session.getOutputStream();
    assertTrue(session.isDirect());
    // verify stream
    outputStream.write(data);
    outputStream.flush();
    outputStream.close();
    assertEquals("received data not equal to sent data", data, queue.take());
    // reset default configuration
    SmackConfiguration.setLocalSocks5ProxyPort(7777);
}
Also used : Socks5BytestreamManager(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager) Socks5BytestreamListener(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamListener) Socks5BytestreamRequest(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest) Socks5Proxy(org.jivesoftware.smackx.bytestreams.socks5.Socks5Proxy) InputStream(java.io.InputStream) SynchronousQueue(java.util.concurrent.SynchronousQueue) OutputStream(java.io.OutputStream) XMPPConnection(org.jivesoftware.smack.XMPPConnection) TimeoutException(java.util.concurrent.TimeoutException) XMPPException(org.jivesoftware.smack.XMPPException) Socks5BytestreamSession(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession)

Aggregations

TimeoutException (java.util.concurrent.TimeoutException)8 XMPPException (org.jivesoftware.smack.XMPPException)8 IOException (java.io.IOException)7 Socks5BytestreamSession (org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession)7 Socks5BytestreamRequest (org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest)5 Bytestream (org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream)5 Socket (java.net.Socket)4 XMPPConnection (org.jivesoftware.smack.XMPPConnection)4 StreamHost (org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost)4 InputStream (java.io.InputStream)3 OutputStream (java.io.OutputStream)3 SynchronousQueue (java.util.concurrent.SynchronousQueue)3 SmackException (org.jivesoftware.smack.SmackException)3 Socks5BytestreamListener (org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamListener)3 Socks5BytestreamManager (org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager)3 PushbackInputStream (java.io.PushbackInputStream)2 ArrayList (java.util.ArrayList)2 XMPPErrorException (org.jivesoftware.smack.XMPPException.XMPPErrorException)2 StreamHostUsed (org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHostUsed)2 HashMap (java.util.HashMap)1