Search in sources :

Example 21 with XMPPErrorException

use of org.jivesoftware.smack.XMPPException.XMPPErrorException in project Smack by igniterealtime.

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 IOException if the bytestream could not be established
     * @throws InterruptedException if the current thread was interrupted while waiting
     * @throws NoResponseException 
     * @throws SmackException if the target does not support SOCKS5.
     * @throws XMPPException 
     */
@Override
public Socks5BytestreamSession establishSession(Jid targetJID, String sessionID) throws IOException, InterruptedException, NoResponseException, SmackException, XMPPException {
    XMPPConnection connection = connection();
    XMPPErrorException discoveryException = null;
    // check if target supports SOCKS5 Bytestream
    if (!supportsSocks5(targetJID)) {
        throw new FeatureNotSupportedException("SOCKS5 Bytestream", targetJID);
    }
    List<Jid> proxies = new ArrayList<>();
    // determine SOCKS5 proxies from XMPP-server
    try {
        proxies.addAll(determineProxies());
    } catch (XMPPErrorException 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()) {
        if (discoveryException != null) {
            throw discoveryException;
        } else {
            throw new SmackException("no SOCKS5 proxies available");
        }
    }
    // compute digest
    String digest = Socks5Utils.createDigest(sessionID, 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
        Stanza response = connection.createStanzaCollectorAndSend(initiation).nextResultOrThrow(getTargetResponseTimeout());
        // extract used stream host from response
        StreamHostUsed streamHostUsed = ((Bytestream) response).getUsedHost();
        StreamHost usedStreamHost = initiation.getStreamHost(streamHostUsed.getJID());
        if (usedStreamHost == null) {
            throw new SmackException("Remote user responded with unknown host");
        }
        // build SOCKS5 client
        Socks5Client socks5Client = new Socks5ClientForInitiator(usedStreamHost, digest, 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(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) XMPPErrorException(org.jivesoftware.smack.XMPPException.XMPPErrorException) Jid(org.jxmpp.jid.Jid) SmackException(org.jivesoftware.smack.SmackException) Stanza(org.jivesoftware.smack.packet.Stanza) FeatureNotSupportedException(org.jivesoftware.smack.SmackException.FeatureNotSupportedException) ArrayList(java.util.ArrayList) XMPPConnection(org.jivesoftware.smack.XMPPConnection) IOException(java.io.IOException) Bytestream(org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream) StreamHost(org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost) Socket(java.net.Socket) TimeoutException(java.util.concurrent.TimeoutException)

Example 22 with XMPPErrorException

use of org.jivesoftware.smack.XMPPException.XMPPErrorException in project Smack by igniterealtime.

the class Socks5BytestreamManager method determineProxies.

/**
     * Returns a list of JIDs of SOCKS5 proxies by querying the XMPP server. The SOCKS5 proxies are
     * in the same order as returned by the XMPP server.
     * 
     * @return list of JIDs of SOCKS5 proxies
     * @throws XMPPErrorException if there was an error querying the XMPP server for SOCKS5 proxies
     * @throws NoResponseException if there was no response from the server.
     * @throws NotConnectedException 
     * @throws InterruptedException 
     */
private List<Jid> determineProxies() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
    XMPPConnection connection = connection();
    ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection);
    List<Jid> proxies = new ArrayList<>();
    // get all items from XMPP server
    DiscoverItems discoverItems = serviceDiscoveryManager.discoverItems(connection.getXMPPServiceDomain());
    // query all items if they are SOCKS5 proxies
    for (Item item : discoverItems.getItems()) {
        // skip blacklisted servers
        if (this.proxyBlacklist.contains(item.getEntityID())) {
            continue;
        }
        DiscoverInfo proxyInfo;
        try {
            proxyInfo = serviceDiscoveryManager.discoverInfo(item.getEntityID());
        } catch (NoResponseException | XMPPErrorException e) {
            // blacklist errornous server
            proxyBlacklist.add(item.getEntityID());
            continue;
        }
        if (proxyInfo.hasIdentity("proxy", "bytestreams")) {
            proxies.add(item.getEntityID());
        } else {
            /*
                 * server is not a SOCKS5 proxy, blacklist server to skip next time a Socks5
                 * bytestream should be established
                 */
            this.proxyBlacklist.add(item.getEntityID());
        }
    }
    return proxies;
}
Also used : Item(org.jivesoftware.smackx.disco.packet.DiscoverItems.Item) DiscoverInfo(org.jivesoftware.smackx.disco.packet.DiscoverInfo) XMPPErrorException(org.jivesoftware.smack.XMPPException.XMPPErrorException) Jid(org.jxmpp.jid.Jid) ArrayList(java.util.ArrayList) DiscoverItems(org.jivesoftware.smackx.disco.packet.DiscoverItems) XMPPConnection(org.jivesoftware.smack.XMPPConnection) NoResponseException(org.jivesoftware.smack.SmackException.NoResponseException) ServiceDiscoveryManager(org.jivesoftware.smackx.disco.ServiceDiscoveryManager)

Example 23 with XMPPErrorException

use of org.jivesoftware.smack.XMPPException.XMPPErrorException in project Smack by igniterealtime.

the class AdHocCommandManager method newInstanceOfCmd.

/**
     * Creates a new instance of a command to be used by a new execution request
     * 
     * @param commandNode the command node that identifies it.
     * @param sessionID the session id of this execution.
     * @return the command instance to execute.
     * @throws XMPPErrorException if there is problem creating the new instance.
     */
@SuppressWarnings("deprecation")
private LocalCommand newInstanceOfCmd(String commandNode, String sessionID) throws XMPPErrorException {
    AdHocCommandInfo commandInfo = commands.get(commandNode);
    LocalCommand command;
    try {
        command = commandInfo.getCommandInstance();
        command.setSessionID(sessionID);
        command.setName(commandInfo.getName());
        command.setNode(commandInfo.getNode());
    } catch (InstantiationException e) {
        throw new XMPPErrorException(XMPPError.getBuilder(XMPPError.Condition.internal_server_error));
    } catch (IllegalAccessException e) {
        throw new XMPPErrorException(XMPPError.getBuilder(XMPPError.Condition.internal_server_error));
    }
    return command;
}
Also used : XMPPErrorException(org.jivesoftware.smack.XMPPException.XMPPErrorException)

Example 24 with XMPPErrorException

use of org.jivesoftware.smack.XMPPException.XMPPErrorException in project Smack by igniterealtime.

the class Socks5ByteStreamRequestTest method shouldBlacklistInvalidProxyAfter2Failures.

/**
     * Target should not try to connect to SOCKS5 proxies that already failed twice.
     * 
     * @throws Exception should not happen
     */
@Test
public void shouldBlacklistInvalidProxyAfter2Failures() throws Exception {
    // build SOCKS5 Bytestream initialization request
    Bytestream bytestreamInitialization = Socks5PacketUtils.createBytestreamInitiation(initiatorJID, targetJID, sessionID);
    bytestreamInitialization.addStreamHost(JidCreate.from("invalid." + proxyJID), "127.0.0.2", 7778);
    // get SOCKS5 Bytestream manager for connection
    Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection);
    // try to connect several times
    for (int i = 0; i < 2; i++) {
        try {
            // build SOCKS5 Bytestream request with the bytestream initialization
            Socks5BytestreamRequest byteStreamRequest = new Socks5BytestreamRequest(byteStreamManager, bytestreamInitialization);
            // set timeouts
            byteStreamRequest.setTotalConnectTimeout(600);
            byteStreamRequest.setMinimumConnectTimeout(300);
            // accept the stream (this is the call that is tested here)
            byteStreamRequest.accept();
            fail("exception should be thrown");
        } catch (XMPPErrorException e) {
            assertTrue(e.getXMPPError().getDescriptiveText("en").contains("Could not establish socket with any provided host"));
        }
        // verify targets response
        assertEquals(1, protocol.getRequests().size());
        Stanza targetResponse = protocol.getRequests().remove(0);
        assertTrue(IQ.class.isInstance(targetResponse));
        assertEquals(initiatorJID, targetResponse.getTo());
        assertEquals(IQ.Type.error, ((IQ) targetResponse).getType());
        assertEquals(XMPPError.Condition.item_not_found, ((IQ) targetResponse).getError().getCondition());
    }
    // create test data for stream
    byte[] data = new byte[] { 1, 2, 3 };
    Socks5TestProxy socks5Proxy = Socks5TestProxy.getProxy(7779);
    assertTrue(socks5Proxy.isRunning());
    // add a valid SOCKS5 proxy
    bytestreamInitialization.addStreamHost(proxyJID, proxyAddress, 7779);
    // build SOCKS5 Bytestream request with the bytestream initialization
    Socks5BytestreamRequest byteStreamRequest = new Socks5BytestreamRequest(byteStreamManager, bytestreamInitialization);
    // set timeouts
    byteStreamRequest.setTotalConnectTimeout(600);
    byteStreamRequest.setMinimumConnectTimeout(300);
    // accept the stream (this is the call that is tested here)
    InputStream inputStream = byteStreamRequest.accept().getInputStream();
    // create digest to get the socket opened by target
    String digest = Socks5Utils.createDigest(sessionID, initiatorJID, targetJID);
    // test stream by sending some data
    OutputStream outputStream = socks5Proxy.getSocket(digest).getOutputStream();
    outputStream.write(data);
    // verify that data is transferred correctly
    byte[] result = new byte[3];
    inputStream.read(result);
    assertArrayEquals(data, result);
    // verify targets response
    assertEquals(1, protocol.getRequests().size());
    Stanza targetResponse = protocol.getRequests().remove(0);
    assertEquals(Bytestream.class, targetResponse.getClass());
    assertEquals(initiatorJID, targetResponse.getTo());
    assertEquals(IQ.Type.result, ((Bytestream) targetResponse).getType());
    assertEquals(proxyJID, ((Bytestream) targetResponse).getUsedHost().getJID());
}
Also used : Bytestream(org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream) XMPPErrorException(org.jivesoftware.smack.XMPPException.XMPPErrorException) InputStream(java.io.InputStream) Stanza(org.jivesoftware.smack.packet.Stanza) OutputStream(java.io.OutputStream) IQ(org.jivesoftware.smack.packet.IQ) Test(org.junit.Test)

Example 25 with XMPPErrorException

use of org.jivesoftware.smack.XMPPException.XMPPErrorException in project Smack by igniterealtime.

the class SmackIntegrationTestFrameworkUnitTest method logsNonFatalExceptionTest.

@Test
public void logsNonFatalExceptionTest() throws KeyManagementException, NoSuchAlgorithmException, SmackException, IOException, XMPPException, InterruptedException {
    DummySmackIntegrationTestFramework sinttest = getFrameworkForUnitTest(ThrowsNonFatalExceptionDummyTest.class);
    TestRunResult testRunResult = sinttest.run();
    List<FailedTest> failedTests = testRunResult.getFailedTests();
    assertEquals(1, failedTests.size());
    FailedTest failedTest = failedTests.get(0);
    assertTrue(failedTest.failureReason instanceof XMPPErrorException);
    XMPPErrorException ex = (XMPPErrorException) failedTest.failureReason;
    assertEquals(XMPPError.Condition.bad_request, ex.getXMPPError().getCondition());
    assertEquals(ThrowsNonFatalExceptionDummyTest.DESCRIPTIVE_TEXT, ex.getXMPPError().getDescriptiveText());
}
Also used : XMPPErrorException(org.jivesoftware.smack.XMPPException.XMPPErrorException) TestRunResult(org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.TestRunResult) DummySmackIntegrationTestFramework(org.igniterealtime.smack.inttest.DummySmackIntegrationTestFramework) FailedTest(org.igniterealtime.smack.inttest.FailedTest) FailedTest(org.igniterealtime.smack.inttest.FailedTest) AbstractSmackIntegrationTest(org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest) SmackIntegrationTestUnitTestUtil.getFrameworkForUnitTest(org.igniterealtime.smack.inttest.SmackIntegrationTestUnitTestUtil.getFrameworkForUnitTest) Test(org.junit.Test) SmackIntegrationTest(org.igniterealtime.smack.inttest.SmackIntegrationTest)

Aggregations

XMPPErrorException (org.jivesoftware.smack.XMPPException.XMPPErrorException)27 NoResponseException (org.jivesoftware.smack.SmackException.NoResponseException)10 IQ (org.jivesoftware.smack.packet.IQ)9 Test (org.junit.Test)9 IOException (java.io.IOException)7 SmackException (org.jivesoftware.smack.SmackException)7 NotConnectedException (org.jivesoftware.smack.SmackException.NotConnectedException)7 Stanza (org.jivesoftware.smack.packet.Stanza)6 Bytestream (org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream)6 XMPPError (org.jivesoftware.smack.packet.XMPPError)5 DiscoverInfo (org.jivesoftware.smackx.disco.packet.DiscoverInfo)5 InputStream (java.io.InputStream)4 XMPPException (org.jivesoftware.smack.XMPPException)4 XMPPConnection (org.jivesoftware.smack.XMPPConnection)3 DiscoverItems (org.jivesoftware.smackx.disco.packet.DiscoverItems)3 FileNotFoundException (java.io.FileNotFoundException)2 ArrayList (java.util.ArrayList)2 TimeoutException (java.util.concurrent.TimeoutException)2 AbstractSmackIntegrationTest (org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest)2 SmackIntegrationTest (org.igniterealtime.smack.inttest.SmackIntegrationTest)2