2014-02-17 23:58:40 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* Copyright the original author or authors
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
package org.jivesoftware.smackx.bytestreams.socks5;
|
|
|
|
|
2020-04-06 13:25:07 +02:00
|
|
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
2019-05-08 11:05:47 +02:00
|
|
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
2020-04-06 13:25:07 +02:00
|
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.io.OutputStream;
|
|
|
|
import java.net.ServerSocket;
|
|
|
|
import java.net.Socket;
|
|
|
|
|
2014-03-10 09:45:50 +01:00
|
|
|
import org.jivesoftware.smack.XMPPConnection;
|
2014-02-17 23:58:40 +01:00
|
|
|
import org.jivesoftware.smack.packet.IQ;
|
2015-02-05 11:17:27 +01:00
|
|
|
import org.jivesoftware.smack.packet.Stanza;
|
2018-04-07 21:25:40 +02:00
|
|
|
import org.jivesoftware.smack.packet.StanzaError;
|
2020-04-11 21:59:21 +02:00
|
|
|
import org.jivesoftware.smack.test.util.NetworkUtil;
|
2017-06-14 17:12:43 +02:00
|
|
|
|
2014-02-17 23:58:40 +01:00
|
|
|
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
|
2017-06-14 17:12:43 +02:00
|
|
|
|
2014-02-17 23:58:40 +01:00
|
|
|
import org.jivesoftware.util.ConnectionUtils;
|
|
|
|
import org.jivesoftware.util.Protocol;
|
2020-04-06 13:25:07 +02:00
|
|
|
import org.junit.jupiter.api.Test;
|
2015-02-14 17:15:02 +01:00
|
|
|
import org.jxmpp.jid.DomainBareJid;
|
2015-05-27 19:29:51 +02:00
|
|
|
import org.jxmpp.jid.EntityFullJid;
|
2015-02-14 17:15:02 +01:00
|
|
|
import org.jxmpp.jid.JidTestUtil;
|
|
|
|
import org.jxmpp.jid.impl.JidCreate;
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests for the Socks5BytestreamRequest class.
|
2018-05-09 23:06:12 +02:00
|
|
|
*
|
2014-02-17 23:58:40 +01:00
|
|
|
* @author Henning Staib
|
|
|
|
*/
|
|
|
|
public class Socks5ByteStreamRequestTest {
|
|
|
|
|
|
|
|
// settings
|
2017-12-13 23:10:11 +01:00
|
|
|
private static final EntityFullJid initiatorJID = JidTestUtil.DUMMY_AT_EXAMPLE_ORG_SLASH_DUMMYRESOURCE;
|
|
|
|
private static final EntityFullJid targetJID = JidTestUtil.FULL_JID_1_RESOURCE_1;
|
|
|
|
private static final DomainBareJid proxyJID = JidTestUtil.MUC_EXAMPLE_ORG;
|
|
|
|
private static final String proxyAddress = "127.0.0.1";
|
|
|
|
private static final String sessionID = "session_id";
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Accepting a SOCKS5 Bytestream request should fail if the request doesn't contain any Socks5
|
|
|
|
* proxies.
|
2018-05-09 23:06:12 +02:00
|
|
|
*
|
2014-02-17 23:58:40 +01:00
|
|
|
* @throws Exception should not happen
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void shouldFailIfRequestHasNoStreamHosts() throws Exception {
|
2019-06-02 10:38:19 +02:00
|
|
|
final Protocol protocol = new Protocol();
|
|
|
|
final XMPPConnection connection = ConnectionUtils.createMockedConnection(protocol, targetJID);
|
|
|
|
|
2019-05-08 11:05:47 +02:00
|
|
|
assertThrows(Socks5Exception.NoSocks5StreamHostsProvided.class, () -> {
|
2014-02-17 23:58:40 +01:00
|
|
|
// build SOCKS5 Bytestream initialization request with no SOCKS5 proxies
|
|
|
|
Bytestream bytestreamInitialization = Socks5PacketUtils.createBytestreamInitiation(
|
|
|
|
initiatorJID, targetJID, sessionID);
|
|
|
|
|
|
|
|
// get SOCKS5 Bytestream manager for connection
|
|
|
|
Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection);
|
|
|
|
|
|
|
|
// build SOCKS5 Bytestream request with the bytestream initialization
|
|
|
|
Socks5BytestreamRequest byteStreamRequest = new Socks5BytestreamRequest(
|
|
|
|
byteStreamManager, bytestreamInitialization);
|
|
|
|
|
|
|
|
// accept the stream (this is the call that is tested here)
|
|
|
|
byteStreamRequest.accept();
|
2019-05-08 11:05:47 +02:00
|
|
|
});
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
// verify targets response
|
|
|
|
assertEquals(1, protocol.getRequests().size());
|
2015-02-05 11:17:27 +01:00
|
|
|
Stanza targetResponse = protocol.getRequests().remove(0);
|
2014-02-17 23:58:40 +01:00
|
|
|
assertTrue(IQ.class.isInstance(targetResponse));
|
|
|
|
assertEquals(initiatorJID, targetResponse.getTo());
|
2014-06-06 02:20:45 +02:00
|
|
|
assertEquals(IQ.Type.error, ((IQ) targetResponse).getType());
|
2018-04-07 21:25:40 +02:00
|
|
|
assertEquals(StanzaError.Condition.item_not_found,
|
2017-12-13 23:10:11 +01:00
|
|
|
targetResponse.getError().getCondition());
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Accepting a SOCKS5 Bytestream request should fail if target is not able to connect to any of
|
|
|
|
* the provided SOCKS5 proxies.
|
2018-05-09 23:06:12 +02:00
|
|
|
*
|
2019-08-30 12:08:30 +02:00
|
|
|
* @throws Exception if an exception occurs.
|
2014-02-17 23:58:40 +01:00
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void shouldFailIfRequestHasInvalidStreamHosts() throws Exception {
|
2019-06-02 10:38:19 +02:00
|
|
|
final Protocol protocol = new Protocol();
|
|
|
|
final XMPPConnection connection = ConnectionUtils.createMockedConnection(protocol, targetJID);
|
|
|
|
|
2019-05-08 11:05:47 +02:00
|
|
|
assertThrows(Socks5Exception.CouldNotConnectToAnyProvidedSocks5Host.class, () -> {
|
2014-02-17 23:58:40 +01:00
|
|
|
// build SOCKS5 Bytestream initialization request
|
|
|
|
Bytestream bytestreamInitialization = Socks5PacketUtils.createBytestreamInitiation(
|
|
|
|
initiatorJID, targetJID, sessionID);
|
|
|
|
// add proxy that is not running
|
|
|
|
bytestreamInitialization.addStreamHost(proxyJID, proxyAddress, 7778);
|
|
|
|
|
|
|
|
// get SOCKS5 Bytestream manager for connection
|
|
|
|
Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection);
|
|
|
|
|
|
|
|
// build SOCKS5 Bytestream request with the bytestream initialization
|
|
|
|
Socks5BytestreamRequest byteStreamRequest = new Socks5BytestreamRequest(
|
|
|
|
byteStreamManager, bytestreamInitialization);
|
|
|
|
|
|
|
|
// accept the stream (this is the call that is tested here)
|
|
|
|
byteStreamRequest.accept();
|
2019-05-08 11:05:47 +02:00
|
|
|
});
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
// verify targets response
|
|
|
|
assertEquals(1, protocol.getRequests().size());
|
2015-02-05 11:17:27 +01:00
|
|
|
Stanza targetResponse = protocol.getRequests().remove(0);
|
2014-02-17 23:58:40 +01:00
|
|
|
assertTrue(IQ.class.isInstance(targetResponse));
|
|
|
|
assertEquals(initiatorJID, targetResponse.getTo());
|
2014-06-06 02:20:45 +02:00
|
|
|
assertEquals(IQ.Type.error, ((IQ) targetResponse).getType());
|
2018-04-07 21:25:40 +02:00
|
|
|
assertEquals(StanzaError.Condition.item_not_found,
|
2017-12-13 23:10:11 +01:00
|
|
|
targetResponse.getError().getCondition());
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Target should not try to connect to SOCKS5 proxies that already failed twice.
|
2018-05-09 23:06:12 +02:00
|
|
|
*
|
2014-02-17 23:58:40 +01:00
|
|
|
* @throws Exception should not happen
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void shouldBlacklistInvalidProxyAfter2Failures() throws Exception {
|
2019-06-02 10:38:19 +02:00
|
|
|
final Protocol protocol = new Protocol();
|
|
|
|
final XMPPConnection connection = ConnectionUtils.createMockedConnection(protocol, targetJID);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
// build SOCKS5 Bytestream initialization request
|
|
|
|
Bytestream bytestreamInitialization = Socks5PacketUtils.createBytestreamInitiation(
|
|
|
|
initiatorJID, targetJID, sessionID);
|
2019-06-02 10:38:19 +02:00
|
|
|
// Add an unreachable stream host.
|
2015-02-14 17:15:02 +01:00
|
|
|
bytestreamInitialization.addStreamHost(JidCreate.from("invalid." + proxyJID), "127.0.0.2", 7778);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
// get SOCKS5 Bytestream manager for connection
|
|
|
|
Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection);
|
|
|
|
|
|
|
|
// try to connect several times
|
|
|
|
for (int i = 0; i < 2; i++) {
|
2019-05-08 11:05:47 +02:00
|
|
|
assertThrows(Socks5Exception.CouldNotConnectToAnyProvidedSocks5Host.class, () -> {
|
2014-02-17 23:58:40 +01:00
|
|
|
// 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();
|
2019-05-08 11:05:47 +02:00
|
|
|
});
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
// verify targets response
|
|
|
|
assertEquals(1, protocol.getRequests().size());
|
2015-02-05 11:17:27 +01:00
|
|
|
Stanza targetResponse = protocol.getRequests().remove(0);
|
2014-02-17 23:58:40 +01:00
|
|
|
assertTrue(IQ.class.isInstance(targetResponse));
|
|
|
|
assertEquals(initiatorJID, targetResponse.getTo());
|
2014-06-06 02:20:45 +02:00
|
|
|
assertEquals(IQ.Type.error, ((IQ) targetResponse).getType());
|
2018-04-07 21:25:40 +02:00
|
|
|
assertEquals(StanzaError.Condition.item_not_found,
|
2017-12-13 23:10:11 +01:00
|
|
|
targetResponse.getError().getCondition());
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// create test data for stream
|
|
|
|
byte[] data = new byte[] { 1, 2, 3 };
|
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
try (Socks5TestProxy socks5Proxy = new Socks5TestProxy()) {
|
|
|
|
assertTrue(socks5Proxy.isRunning());
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// add a valid SOCKS5 proxy
|
|
|
|
bytestreamInitialization.addStreamHost(proxyJID, proxyAddress, socks5Proxy.getPort());
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// build SOCKS5 Bytestream request with the bytestream initialization
|
|
|
|
Socks5BytestreamRequest byteStreamRequest = new Socks5BytestreamRequest(byteStreamManager,
|
|
|
|
bytestreamInitialization);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// set timeouts
|
|
|
|
byteStreamRequest.setTotalConnectTimeout(600);
|
|
|
|
byteStreamRequest.setMinimumConnectTimeout(300);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// accept the stream (this is the call that is tested here)
|
|
|
|
InputStream inputStream = byteStreamRequest.accept().getInputStream();
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// create digest to get the socket opened by target
|
|
|
|
String digest = Socks5Utils.createDigest(sessionID, initiatorJID, targetJID);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// test stream by sending some data
|
|
|
|
OutputStream outputStream = socks5Proxy.getSocket(digest).getOutputStream();
|
|
|
|
outputStream.write(data);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// verify that data is transferred correctly
|
|
|
|
byte[] result = new byte[3];
|
|
|
|
inputStream.read(result);
|
|
|
|
assertArrayEquals(data, result);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// 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());
|
|
|
|
}
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Target should not not blacklist any SOCKS5 proxies regardless of failing connections.
|
2018-05-09 23:06:12 +02:00
|
|
|
*
|
2014-02-17 23:58:40 +01:00
|
|
|
* @throws Exception should not happen
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void shouldNotBlacklistInvalidProxy() throws Exception {
|
2019-06-02 10:38:19 +02:00
|
|
|
final Protocol protocol = new Protocol();
|
|
|
|
final XMPPConnection connection = ConnectionUtils.createMockedConnection(protocol, targetJID);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
// build SOCKS5 Bytestream initialization request
|
|
|
|
Bytestream bytestreamInitialization = Socks5PacketUtils.createBytestreamInitiation(
|
|
|
|
initiatorJID, targetJID, sessionID);
|
2015-02-14 17:15:02 +01:00
|
|
|
bytestreamInitialization.addStreamHost(JidCreate.from("invalid." + proxyJID), "127.0.0.2", 7778);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
// get SOCKS5 Bytestream manager for connection
|
|
|
|
Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection);
|
|
|
|
|
|
|
|
// try to connect several times
|
|
|
|
for (int i = 0; i < 10; i++) {
|
2019-05-08 11:05:47 +02:00
|
|
|
assertThrows(Socks5Exception.CouldNotConnectToAnyProvidedSocks5Host.class, () -> {
|
2014-02-17 23:58:40 +01:00
|
|
|
// build SOCKS5 Bytestream request with the bytestream initialization
|
|
|
|
Socks5BytestreamRequest byteStreamRequest = new Socks5BytestreamRequest(
|
|
|
|
byteStreamManager, bytestreamInitialization);
|
|
|
|
|
|
|
|
// set timeouts
|
|
|
|
byteStreamRequest.setTotalConnectTimeout(600);
|
|
|
|
byteStreamRequest.setMinimumConnectTimeout(300);
|
2019-06-02 10:38:19 +02:00
|
|
|
byteStreamRequest.setConnectFailureThreshold(0);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
// accept the stream (this is the call that is tested here)
|
|
|
|
byteStreamRequest.accept();
|
2019-05-08 11:05:47 +02:00
|
|
|
});
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
// verify targets response
|
|
|
|
assertEquals(1, protocol.getRequests().size());
|
2015-02-05 11:17:27 +01:00
|
|
|
Stanza targetResponse = protocol.getRequests().remove(0);
|
2014-02-17 23:58:40 +01:00
|
|
|
assertTrue(IQ.class.isInstance(targetResponse));
|
|
|
|
assertEquals(initiatorJID, targetResponse.getTo());
|
2014-06-06 02:20:45 +02:00
|
|
|
assertEquals(IQ.Type.error, ((IQ) targetResponse).getType());
|
2018-04-07 21:25:40 +02:00
|
|
|
assertEquals(StanzaError.Condition.item_not_found,
|
2017-12-13 23:10:11 +01:00
|
|
|
targetResponse.getError().getCondition());
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If the SOCKS5 Bytestream request contains multiple SOCKS5 proxies and the first one doesn't
|
|
|
|
* respond, the connection attempt to this proxy should not consume the whole timeout for
|
|
|
|
* connecting to the proxies.
|
2018-05-09 23:06:12 +02:00
|
|
|
*
|
2014-02-17 23:58:40 +01:00
|
|
|
* @throws Exception should not happen
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void shouldNotTimeoutIfFirstSocks5ProxyDoesNotRespond() throws Exception {
|
2019-06-02 10:38:19 +02:00
|
|
|
final Protocol protocol = new Protocol();
|
|
|
|
final XMPPConnection connection = ConnectionUtils.createMockedConnection(protocol, targetJID);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
// start a local SOCKS5 proxy
|
2019-06-02 10:38:19 +02:00
|
|
|
try (Socks5TestProxy socks5Proxy = new Socks5TestProxy()) {
|
|
|
|
// create a fake SOCKS5 proxy that doesn't respond to a request
|
|
|
|
ServerSocket unresponsiveSocks5Socket = NetworkUtil.getSocketOnLoopback();
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
try {
|
|
|
|
// build SOCKS5 Bytestream initialization request
|
|
|
|
Bytestream bytestreamInitialization = Socks5PacketUtils.createBytestreamInitiation(
|
|
|
|
initiatorJID, targetJID, sessionID);
|
|
|
|
bytestreamInitialization.addStreamHost(proxyJID, proxyAddress, unresponsiveSocks5Socket.getLocalPort());
|
|
|
|
bytestreamInitialization.addStreamHost(proxyJID, proxyAddress, socks5Proxy.getPort());
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// create test data for stream
|
|
|
|
byte[] data = new byte[] { 1, 2, 3 };
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// get SOCKS5 Bytestream manager for connection
|
|
|
|
Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// build SOCKS5 Bytestream request with the bytestream initialization
|
|
|
|
Socks5BytestreamRequest byteStreamRequest = new Socks5BytestreamRequest(byteStreamManager,
|
|
|
|
bytestreamInitialization);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// set timeouts
|
|
|
|
byteStreamRequest.setTotalConnectTimeout(2000);
|
|
|
|
byteStreamRequest.setMinimumConnectTimeout(1000);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// accept the stream (this is the call that is tested here)
|
|
|
|
InputStream inputStream = byteStreamRequest.accept().getInputStream();
|
|
|
|
|
|
|
|
// assert that client tries to connect to dumb SOCKS5 proxy
|
|
|
|
Socket socket = unresponsiveSocks5Socket.accept();
|
|
|
|
assertNotNull(socket);
|
|
|
|
|
|
|
|
// 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());
|
|
|
|
} finally {
|
|
|
|
unresponsiveSocks5Socket.close();
|
|
|
|
}
|
|
|
|
}
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Accepting the SOCKS5 Bytestream request should be successfully.
|
2018-05-09 23:06:12 +02:00
|
|
|
*
|
2014-02-17 23:58:40 +01:00
|
|
|
* @throws Exception should not happen
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void shouldAcceptSocks5BytestreamRequestAndReceiveData() throws Exception {
|
2019-06-02 10:38:19 +02:00
|
|
|
final Protocol protocol = new Protocol();
|
|
|
|
final XMPPConnection connection = ConnectionUtils.createMockedConnection(protocol, targetJID);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
// start a local SOCKS5 proxy
|
2019-06-02 10:38:19 +02:00
|
|
|
try (Socks5TestProxy socks5Proxy = new Socks5TestProxy()) {
|
|
|
|
// build SOCKS5 Bytestream initialization request
|
|
|
|
Bytestream bytestreamInitialization = Socks5PacketUtils.createBytestreamInitiation(
|
|
|
|
initiatorJID, targetJID, sessionID);
|
|
|
|
bytestreamInitialization.addStreamHost(proxyJID, proxyAddress, socks5Proxy.getPort());
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// create test data for stream
|
|
|
|
byte[] data = new byte[] { 1, 2, 3 };
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// get SOCKS5 Bytestream manager for connection
|
|
|
|
Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// build SOCKS5 Bytestream request with the bytestream initialization
|
|
|
|
Socks5BytestreamRequest byteStreamRequest = new Socks5BytestreamRequest(byteStreamManager,
|
|
|
|
bytestreamInitialization);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// accept the stream (this is the call that is tested here)
|
|
|
|
InputStream inputStream = byteStreamRequest.accept().getInputStream();
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// create digest to get the socket opened by target
|
|
|
|
String digest = Socks5Utils.createDigest(sessionID, initiatorJID, targetJID);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// test stream by sending some data
|
|
|
|
OutputStream outputStream = socks5Proxy.getSocket(digest).getOutputStream();
|
|
|
|
outputStream.write(data);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// verify that data is transferred correctly
|
|
|
|
byte[] result = new byte[3];
|
|
|
|
inputStream.read(result);
|
|
|
|
assertArrayEquals(data, result);
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2019-06-02 10:38:19 +02:00
|
|
|
// 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());
|
|
|
|
}
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
|
|
|
}
|