SOCKS5 works (no external proxy)

This commit is contained in:
vanitasvitae 2017-08-03 23:01:55 +02:00
parent ff2f66fa67
commit 23eb34932f
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
9 changed files with 166 additions and 89 deletions

View File

@ -161,13 +161,18 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
public IQ handleSessionAccept(JingleElement request, XMPPConnection connection) {
LOGGER.log(Level.INFO, "RECEIVED SESSION ACCEPT!");
for (JingleContentElement contentElement : request.getContents()) {
if (contentElement.getName().equals(getName())) {
JingleContent content = fromElement(contentElement);
getTransport().setPeersProposal(content.getTransport());
break;
JingleContentElement contentElement = null;
for (JingleContentElement c : request.getContents()) {
if (c.getName().equals(getName())) {
contentElement = c;
}
}
if (contentElement == null) {
throw new AssertionError("Session Accept did not contain this content.");
}
getTransport().handleSessionAccept(contentElement.getTransport(), connection);
onAccept(connection);
return IQ.createResultIQ(request);
}
@ -313,9 +318,12 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
}
public void onAccept(final XMPPConnection connection) {
transport.prepare(connection);
if (security != null) {
security.prepare(connection, getParent().getPeer());
}
//Establish transport
Async.go(new Runnable() {
@Override

View File

@ -17,10 +17,8 @@
package org.jivesoftware.smackx.jingle.components;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -66,9 +64,6 @@ public class JingleSession {
private SessionState sessionState;
private final Map<JingleContent, PendingJingleAction> pendingJingleActions =
Collections.synchronizedMap(new HashMap<JingleContent, PendingJingleAction>());
public JingleSession(JingleManager manager, FullJid initiator, FullJid responder, Role role, String sessionId) {
this.jingleManager = manager;
this.initiator = initiator;
@ -88,7 +83,7 @@ public class JingleSession {
List<JingleContentElement> initiateContents = initiate.getContents();
for (JingleContentElement content : initiateContents) {
session.addContent(content);
session.addContent(content, manager);
}
session.sessionState = SessionState.pending;
@ -481,7 +476,7 @@ public class JingleSession {
content.setParent(this);
}
public void addContent(JingleContentElement content)
public void addContent(JingleContentElement content, JingleManager manager)
throws UnsupportedSecurityException, UnsupportedTransportException, UnsupportedDescriptionException {
addContent(JingleContent.fromElement(content));
}

View File

@ -100,6 +100,8 @@ public abstract class JingleTransport<D extends JingleContentTransportElement> e
}
}
public abstract void prepare(XMPPConnection connection);
public List<JingleTransportCandidate<?>> getOurCandidates() {
return ourCandidates;
}
@ -116,8 +118,6 @@ public abstract class JingleTransport<D extends JingleContentTransportElement> e
public abstract void establishOutgoingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback, JingleSession session)
throws SmackException.NotConnectedException, InterruptedException;
public abstract void setPeersProposal(JingleTransport<?> peersProposal);
public abstract IQ handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping);
public void setParent(JingleContent parent) {
@ -133,4 +133,6 @@ public abstract class JingleTransport<D extends JingleContentTransportElement> e
public BytestreamSession getBytestreamSession() {
return bytestreamSession;
}
public abstract void handleSessionAccept(JingleContentTransportElement transportElement, XMPPConnection connection);
}

View File

@ -33,6 +33,7 @@ import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.components.JingleSession;
import org.jivesoftware.smackx.jingle.components.JingleTransport;
import org.jivesoftware.smackx.jingle.components.JingleTransportCandidate;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportInfoElement;
import org.jivesoftware.smackx.jingle.element.JingleElement;
import org.jivesoftware.smackx.jingle.transport.jingle_ibb.element.JingleIBBTransportElement;
@ -76,6 +77,12 @@ public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElemen
return NAMESPACE;
}
@Override
public void handleSessionAccept(JingleContentTransportElement transportElement, XMPPConnection connection) {
JingleIBBTransportElement element = (JingleIBBTransportElement) transportElement;
blockSize = (blockSize < element.getBlockSize() ? blockSize : element.getBlockSize());
}
@Override
public void establishIncomingBytestreamSession(final XMPPConnection connection, final JingleTransportCallback callback, final JingleSession session) {
final InBandBytestreamManager inBandBytestreamManager = InBandBytestreamManager.getByteStreamManager(connection);
@ -120,15 +127,13 @@ public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElemen
}
@Override
public void setPeersProposal(JingleTransport<?> peersProposal) {
JingleIBBTransport transport = (JingleIBBTransport) peersProposal;
//Respect peers wish for smaller block size.
blockSize = (blockSize < transport.blockSize ? blockSize : transport.blockSize);
public void addOurCandidate(JingleTransportCandidate<?> candidate) {
// Sorry, we don't want any candidates.
}
@Override
public void addOurCandidate(JingleTransportCandidate<?> candidate) {
// Sorry, we don't want any candidates.
public void prepare(XMPPConnection connection) {
// Nuffin taddooh.
}
@Override

View File

@ -35,10 +35,11 @@ import org.jivesoftware.smackx.bytestreams.socks5.Socks5Utils;
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
import org.jivesoftware.smackx.jingle.JingleManager;
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.components.JingleContent;
import org.jivesoftware.smackx.jingle.components.JingleSession;
import org.jivesoftware.smackx.jingle.components.JingleTransport;
import org.jivesoftware.smackx.jingle.components.JingleTransportCandidate;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportCandidateElement;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportInfoElement;
import org.jivesoftware.smackx.jingle.element.JingleElement;
import org.jivesoftware.smackx.jingle.exception.FailedTransportException;
@ -62,8 +63,11 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
private final String sid;
private String dstAddr;
private Bytestream.Mode mode;
private String ourDstAddr;
private String theirDstAddr;
private Bytestream.Mode ourMode;
private Bytestream.Mode theirMode;
// PEERS candidate of OUR choice.
private JingleS5BTransportCandidate ourSelectedCandidate;
@ -71,59 +75,106 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
private JingleTransportCallback callback;
/**
* Create fresh JingleS5BTransport.
* @param initiator initiator.
* @param responder responder.
*/
public JingleS5BTransport(FullJid initiator, FullJid responder, String sid, List<JingleTransportCandidate<?>> ourCandidates, List<JingleTransportCandidate<?>> theirCandidates) {
this(sid, Socks5Utils.createDigest(sid, initiator, responder), Bytestream.Mode.tcp, ourCandidates, theirCandidates);
@Override
public void handleSessionAccept(JingleContentTransportElement transportElement, XMPPConnection connection) {
JingleS5BTransportElement transport = (JingleS5BTransportElement) transportElement;
theirDstAddr = transport.getDestinationAddress();
theirMode = transport.getMode();
for (JingleContentTransportCandidateElement c : transport.getCandidates()) {
JingleS5BTransportCandidateElement candidate = (JingleS5BTransportCandidateElement) c;
addTheirCandidate(new JingleS5BTransportCandidate(candidate));
}
}
/**
* Create a JingleS5BTransport as response to another JingleS5BTransport proposal.
* @param content content which this transport will be child of.
* @param other other JingleS5BTransport proposal.
* @param candidates list of available JingleS5BTransportCandidates.
*/
public JingleS5BTransport(JingleContent content, JingleS5BTransport other, List<JingleTransportCandidate<?>> candidates) {
this(other.getSid(),
Socks5Utils.createDigest(other.getSid(), content.getParent().getInitiator(), content.getParent().getResponder()),
other.mode, candidates, other.getOurCandidates());
setPeersProposal(other);
}
/**
* Create a new JingleS5BTransport.
* Create transport as initiator.
* @param initiator
* @param responder
* @param sid
* @param dstAddr
* @param mode
* @param candidates
* @param ourCandidates
*/
public JingleS5BTransport(String sid, String dstAddr, Bytestream.Mode mode, List<JingleTransportCandidate<?>> candidates, List<JingleTransportCandidate<?>> theirCandidates) {
public JingleS5BTransport(FullJid initiator, FullJid responder, String sid, Bytestream.Mode mode, List<JingleTransportCandidate<?>> ourCandidates) {
this.sid = sid;
this.dstAddr = dstAddr;
this.mode = mode;
this.ourMode = mode;
this.ourDstAddr = Socks5Utils.createDigest(sid, initiator, responder);
Socks5Proxy.getSocks5Proxy().addTransfer(ourDstAddr);
for (JingleTransportCandidate<?> c : (candidates != null ?
candidates : Collections.<JingleS5BTransportCandidate>emptySet())) {
for (JingleTransportCandidate<?> c : ourCandidates) {
addOurCandidate(c);
}
}
/**
* Create simple transport as responder.
* @param initiator
* @param responder
* @param ourCandidates
* @param other
*/
public JingleS5BTransport(FullJid initiator, FullJid responder, List<JingleTransportCandidate<?>> ourCandidates, JingleS5BTransport other) {
this.sid = other.sid;
this.ourMode = other.theirMode;
this.ourDstAddr = Socks5Utils.createDigest(other.sid, initiator, responder);
Socks5Proxy.getSocks5Proxy().addTransfer(ourDstAddr);
this.theirMode = other.theirMode;
this.theirDstAddr = other.theirDstAddr;
for (JingleTransportCandidate<?> c : ourCandidates) {
addOurCandidate(c);
}
for (JingleTransportCandidate<?> c : (theirCandidates != null ?
theirCandidates : Collections.<JingleS5BTransportCandidate>emptySet())) {
for (JingleTransportCandidate<?> c : other.getTheirCandidates()) {
addTheirCandidate(c);
}
}
/**
* Create custom transport as responder.
* @param sid
* @param ourMode
* @param theirMode
* @param ourDstAddr
* @param theirDstAddr
* @param ourCandidates
* @param theirCandidates
*/
public JingleS5BTransport(String sid, Bytestream.Mode ourMode, Bytestream.Mode theirMode, String ourDstAddr, String theirDstAddr, List<JingleTransportCandidate<?>> ourCandidates, List<JingleTransportCandidate<?>> theirCandidates) {
this.sid = sid;
this.ourMode = ourMode;
this.theirMode = theirMode;
this.ourDstAddr = ourDstAddr;
Socks5Proxy.getSocks5Proxy().addTransfer(ourDstAddr);
this.theirDstAddr = theirDstAddr;
for (JingleTransportCandidate<?> c : (ourCandidates != null ? ourCandidates :
Collections.<JingleS5BTransportCandidate>emptySet())) {
addOurCandidate(c);
}
for (JingleTransportCandidate<?> c : (theirCandidates != null ? theirCandidates :
Collections.<JingleS5BTransportCandidate>emptySet())) {
addTheirCandidate(c);
}
}
/**
* Copy constructor.
* @param transport which will be copied.
* @param original
*/
public JingleS5BTransport(JingleS5BTransport transport) {
this(transport.sid, transport.dstAddr, transport.mode, null, null);
for (JingleTransportCandidate<?> c : transport.getOurCandidates()) {
this.addOurCandidate(new JingleS5BTransportCandidate((JingleS5BTransportCandidate) c));
public JingleS5BTransport(JingleS5BTransport original) {
this.sid = original.sid;
this.ourDstAddr = original.ourDstAddr;
this.theirDstAddr = original.theirDstAddr;
this.ourMode = original.ourMode;
this.theirMode = original.theirMode;
for (JingleTransportCandidate<?> c : original.getOurCandidates()) {
addOurCandidate(new JingleS5BTransportCandidate((JingleS5BTransportCandidate) c));
}
for (JingleTransportCandidate<?> c : original.getTheirCandidates()) {
addTheirCandidate(new JingleS5BTransportCandidate((JingleS5BTransportCandidate) c));
}
}
@ -131,8 +182,8 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
public JingleS5BTransportElement getElement() {
JingleS5BTransportElement.Builder builder = JingleS5BTransportElement.getBuilder()
.setStreamId(sid)
.setDestinationAddress(dstAddr)
.setMode(mode);
.setDestinationAddress(ourDstAddr)
.setMode(ourMode);
for (JingleTransportCandidate<?> candidate : getOurCandidates()) {
builder.addTransportCandidate((JingleS5BTransportCandidateElement) candidate.getElement());
@ -145,12 +196,16 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
return sid;
}
public String getDstAddr() {
return dstAddr;
public String getOurDstAddr() {
return ourDstAddr;
}
public Bytestream.Mode getMode() {
return mode;
public String getTheirDstAddr() {
return theirDstAddr;
}
public Bytestream.Mode getOurMode() {
return ourMode;
}
@Override
@ -165,6 +220,26 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
establishBytestreamSession(connection);
}
@Override
public void prepare(XMPPConnection connection) {
JingleSession session = getParent().getParent();
if (getOurDstAddr() == null) {
ourDstAddr = Socks5Utils.createDigest(session.getSessionId(), session.getInitiator(), session.getResponder());
Socks5Proxy.getSocks5Proxy().addTransfer(ourDstAddr);
}
if (ourMode == null) {
ourMode = Bytestream.Mode.tcp;
}
if (getOurCandidates().size() == 0) {
List<JingleTransportCandidate<?>> candidates = JingleS5BTransportManager.getInstanceFor(connection).collectCandidates();
for (JingleTransportCandidate<?> c : candidates) {
addOurCandidate(c);
}
}
}
@Override
public void establishOutgoingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback, JingleSession session)
throws SmackException.NotConnectedException, InterruptedException {
@ -172,18 +247,9 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
establishBytestreamSession(connection);
}
@Override
public void setPeersProposal(JingleTransport<?> peersProposal) {
JingleS5BTransport transport = (JingleS5BTransport) peersProposal;
getTheirCandidates().clear();
for (JingleTransportCandidate<?> c : transport.getOurCandidates()) {
addTheirCandidate(c);
}
}
void establishBytestreamSession(XMPPConnection connection)
throws SmackException.NotConnectedException, InterruptedException {
Socks5Proxy.getSocks5Proxy().addTransfer(dstAddr);
Socks5Proxy.getSocks5Proxy().addTransfer(ourDstAddr);
JingleS5BTransportManager transportManager = JingleS5BTransportManager.getInstanceFor(connection);
this.ourSelectedCandidate = connectToCandidates(MAX_TIMEOUT);

View File

@ -39,7 +39,7 @@ public class JingleS5BTransportAdapter implements JingleTransportAdapter<JingleS
candidates.add(JingleS5BTransportCandidate.fromElement((JingleS5BTransportCandidateElement) e));
}
return new JingleS5BTransport(s5b.getSid(), s5b.getDestinationAddress(), s5b.getMode(), null, candidates);
return new JingleS5BTransport(s5b.getSid(), null, s5b.getMode(), null, s5b.getDestinationAddress(), null, candidates);
}
@Override

View File

@ -44,6 +44,10 @@ public class JingleS5BTransportCandidate extends JingleTransportCandidate<Jingle
private Socket socket;
public JingleS5BTransportCandidate(JingleS5BTransportCandidateElement element) {
this(element.getCandidateId(), new Bytestream.StreamHost(element.getJid(), element.getHost(), element.getPort()), element.getPriority(), element.getType());
}
public JingleS5BTransportCandidate(String candidateId,
Bytestream.StreamHost streamHost,
int priority,
@ -91,14 +95,14 @@ public class JingleS5BTransportCandidate extends JingleTransportCandidate<Jingle
Socks5Client client;
if (peersProposal) {
LOGGER.log(Level.INFO, "Connect to foreign candidate " + getCandidateId() + " using " + transport.getDstAddr());
client = new Socks5Client(getStreamHost(), transport.getDstAddr());
LOGGER.log(Level.INFO, "Connect to foreign candidate " + getCandidateId() + " using " + transport.getTheirDstAddr());
client = new Socks5Client(getStreamHost(), transport.getTheirDstAddr());
}
else {
LOGGER.log(Level.INFO, "Connect to our candidate " + getCandidateId() + " using " + ((JingleS5BTransport) getParent()).getDstAddr());
LOGGER.log(Level.INFO, "Connect to our candidate " + getCandidateId() + " using " + transport.getOurDstAddr());
JingleContent content = transport.getParent();
JingleSession session = content.getParent();
client = new Socks5ClientForInitiator(getStreamHost(), transport.getDstAddr(), session.getJingleManager().getConnection(), transport.getSid(), session.getPeer());
client = new Socks5ClientForInitiator(getStreamHost(), transport.getOurDstAddr(), session.getJingleManager().getConnection(), transport.getSid(), session.getPeer());
}
this.socket = client.getSocket(timeout);

View File

@ -64,7 +64,7 @@ public final class JingleS5BTransportManager extends Manager implements JingleTr
private List<Bytestream.StreamHost> localStreamHosts = null;
private List<Bytestream.StreamHost> availableStreamHosts = null;
private static boolean useLocalCandidates = true;
private static boolean useLocalCandidates = false;
private static boolean useExternalCandidates = true;
static {
@ -99,16 +99,13 @@ public final class JingleS5BTransportManager extends Manager implements JingleTr
public JingleTransport<?> createTransport(JingleContent content) {
JingleSession session = content.getParent();
List<JingleTransportCandidate<?>> candidates = collectCandidates();
return new JingleS5BTransport(session.getInitiator(), session.getResponder(), StringUtils.randomString(24), candidates, null);
return new JingleS5BTransport(session.getInitiator(), session.getResponder(), StringUtils.randomString(24), Bytestream.Mode.tcp, candidates);
}
@Override
public JingleTransport<?> createTransport(JingleContent content, JingleTransport<?> peersTransport) {
JingleS5BTransport transport = (JingleS5BTransport) peersTransport;
List<JingleTransportCandidate<?>> candidates = collectCandidates();
JingleS5BTransport mTransport = new JingleS5BTransport(content, transport, candidates);
mTransport.setPeersProposal(transport);
return mTransport;
JingleSession session = content.getParent();
return new JingleS5BTransport(session.getInitiator(), session.getResponder(), collectCandidates(), (JingleS5BTransport) peersTransport);
}
@Override
@ -116,7 +113,7 @@ public final class JingleS5BTransportManager extends Manager implements JingleTr
return 10000;
}
private List<JingleTransportCandidate<?>> collectCandidates() {
public List<JingleTransportCandidate<?>> collectCandidates() {
List<JingleTransportCandidate<?>> candidates = new ArrayList<>();
//Local host

View File

@ -93,8 +93,8 @@ public class JingleTransportTest extends AbstractSmackIntegrationTest {
JingleS5BTransport rTransport = (JingleS5BTransport) JingleS5BTransportManager.getInstanceFor(receiver).createTransport(rContent, sTransport);
sContent.setTransport(sTransport);
rContent.setTransport(rTransport);
sTransport.setPeersProposal(new JingleS5BTransport(rTransport));
rTransport.setPeersProposal(new JingleS5BTransport(sTransport));
sTransport.handleSessionAccept(rTransport.getElement(), sender);
rTransport.handleSessionAccept(sTransport.getElement(), receiver);
basicTransportTest(sSession, rSession, sTransport, rTransport);
}