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);
}
}
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;
}
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;
}
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());
}
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());
}
Aggregations