use of org.jxmpp.jid.Jid 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.jxmpp.jid.Jid 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.jxmpp.jid.Jid in project Smack by igniterealtime.
the class Socks5BytestreamManager method determineStreamHostInfos.
/**
* Returns a list of stream hosts containing the IP address an the port for the given list of
* SOCKS5 proxy JIDs. The order of the returned list is the same as the given list of JIDs
* excluding all SOCKS5 proxies who's network settings could not be determined. If a local
* SOCKS5 proxy is running it will be the first item in the list returned.
*
* @param proxies a list of SOCKS5 proxy JIDs
* @return a list of stream hosts containing the IP address an the port
*/
private List<StreamHost> determineStreamHostInfos(List<Jid> proxies) {
XMPPConnection connection = connection();
List<StreamHost> streamHosts = new ArrayList<StreamHost>();
// add local proxy on first position if exists
List<StreamHost> localProxies = getLocalStreamHost();
if (localProxies != null) {
streamHosts.addAll(localProxies);
}
// query SOCKS5 proxies for network settings
for (Jid proxy : proxies) {
Bytestream streamHostRequest = createStreamHostRequest(proxy);
try {
Bytestream response = (Bytestream) connection.createStanzaCollectorAndSend(streamHostRequest).nextResultOrThrow();
streamHosts.addAll(response.getStreamHosts());
} catch (Exception e) {
// blacklist errornous proxies
this.proxyBlacklist.add(proxy);
}
}
return streamHosts;
}
use of org.jxmpp.jid.Jid in project Smack by igniterealtime.
the class BlockContactsIQTest method checkBlockContactIQStanza.
@Test
public void checkBlockContactIQStanza() throws Exception {
List<Jid> jids = new ArrayList<>();
jids.add(JidCreate.from("romeo@montague.net"));
jids.add(JidCreate.from("pepe@montague.net"));
BlockContactsIQ blockContactIQ = new BlockContactsIQ(jids);
blockContactIQ.setStanzaId("block1");
Assert.assertEquals(blockContactIQExample, blockContactIQ.toXML().toString());
}
use of org.jxmpp.jid.Jid in project Smack by igniterealtime.
the class IoTControlIntegrationTest method controlTest.
/**
* Connection one provides a thing, which is controlled by connection two.
*
* @throws Exception
* @throws TimeoutException
*/
@SmackIntegrationTest
public // @SmackSerialIntegrationTest
void controlTest() throws TimeoutException, Exception {
final String key = StringUtils.randomString(12);
final String sn = StringUtils.randomString(12);
final SimpleResultSyncPoint syncPoint = new SimpleResultSyncPoint();
Thing controlThing = Thing.builder().setKey(key).setSerialNumber(sn).setControlRequestHandler(new ThingControlRequest() {
@Override
public void processRequest(Jid from, Collection<SetData> setData) throws XMPPErrorException {
if (!from.equals(conTwo.getUser())) {
return;
}
for (final SetData data : setData) {
if (!data.getName().equals(testRunId))
continue;
if (!(data instanceof SetBoolData))
continue;
SetBoolData boolData = (SetBoolData) data;
if (boolData.getBooleanValue()) {
syncPoint.signal();
break;
}
}
}
}).build();
IoTControlManagerOne.installThing(controlThing);
try {
RosterIntegrationTest.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, timeout);
SetData data = new SetBoolData(testRunId, true);
IoTSetResponse response = IoTControlManagerTwo.setUsingIq(conOne.getUser(), data);
assertNotNull(response);
} finally {
IoTControlManagerOne.uninstallThing(controlThing);
RosterIntegrationTest.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo);
}
syncPoint.waitForResult(timeout);
}
Aggregations