refactored socks5 connection code. make jingle transport use that new code
This commit is contained in:
parent
ebccb67a72
commit
8ffcc11f27
|
@ -42,7 +42,7 @@ public final class Config {
|
|||
public static final int REFRESH_UI_INTERVAL = 500;
|
||||
|
||||
public static final boolean DISABLE_PROXY_LOOKUP = false; //useful to debug ibb
|
||||
public static final boolean DISABLE_HTTP_UPLOAD = false;
|
||||
public static final boolean DISABLE_HTTP_UPLOAD = true;
|
||||
public static final boolean DISABLE_STRING_PREP = false; // setting to true might increase startup performance
|
||||
public static final boolean EXTENDED_SM_LOGGING = true; // log stanza counts
|
||||
public static final boolean RESET_ATTEMPT_COUNT_ON_NETWORK_CHANGE = true; //setting to true might increase power consumption
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package eu.siacs.conversations.utils;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
|
||||
public class SocksSocketFactory {
|
||||
|
||||
public static void createSocksConnection(Socket socket, String destination, int port) throws IOException {
|
||||
InputStream proxyIs = socket.getInputStream();
|
||||
OutputStream proxyOs = socket.getOutputStream();
|
||||
proxyOs.write(new byte[]{0x05, 0x01, 0x00});
|
||||
byte[] response = new byte[2];
|
||||
proxyIs.read(response);
|
||||
byte[] dest = destination.getBytes();
|
||||
ByteBuffer request = ByteBuffer.allocate(7 + dest.length);
|
||||
request.put(new byte[]{0x05, 0x01, 0x00, 0x03});
|
||||
request.put((byte) dest.length);
|
||||
request.put(dest);
|
||||
request.putShort((short) port);
|
||||
proxyOs.write(request.array());
|
||||
response = new byte[7 + dest.length];
|
||||
proxyIs.read(response);
|
||||
if (response[1] != 0x00) {
|
||||
throw new SocksConnectionException();
|
||||
}
|
||||
}
|
||||
|
||||
public static Socket createSocket(InetSocketAddress address, String destination, int port) throws IOException {
|
||||
Socket socket = new Socket();
|
||||
socket.connect(address, Config.CONNECT_TIMEOUT * 1000);
|
||||
createSocksConnection(socket, destination, port);
|
||||
return socket;
|
||||
}
|
||||
|
||||
public static Socket createSocketOverTor(String destination, int port) throws IOException {
|
||||
return createSocket(new InetSocketAddress(InetAddress.getLocalHost(), 9050), destination, port);
|
||||
}
|
||||
|
||||
static class SocksConnectionException extends IOException {
|
||||
|
||||
}
|
||||
}
|
|
@ -67,6 +67,7 @@ import eu.siacs.conversations.generator.IqGenerator;
|
|||
import eu.siacs.conversations.services.XmppConnectionService;
|
||||
import eu.siacs.conversations.utils.CryptoHelper;
|
||||
import eu.siacs.conversations.utils.DNSHelper;
|
||||
import eu.siacs.conversations.utils.SocksSocketFactory;
|
||||
import eu.siacs.conversations.utils.Xmlns;
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
import eu.siacs.conversations.xml.Tag;
|
||||
|
@ -235,32 +236,14 @@ public class XmppConnection implements Runnable {
|
|||
this.changeStatus(Account.State.CONNECTING);
|
||||
final boolean useTor = mXmppConnectionService.useTorToConnect() || account.isOnion();
|
||||
if (useTor) {
|
||||
InetSocketAddress proxyAddress = new InetSocketAddress(InetAddress.getLocalHost(), 9050);
|
||||
byte[] destination;
|
||||
String destination;
|
||||
if (account.getHostname() == null || account.getHostname().isEmpty()) {
|
||||
destination = account.getServer().toString().getBytes();
|
||||
destination = account.getServer().toString();
|
||||
} else {
|
||||
destination = account.getHostname().getBytes();
|
||||
}
|
||||
Log.d(Config.LOGTAG,"connecting via tor to "+new String(destination));
|
||||
socket = new Socket();
|
||||
socket.connect(proxyAddress, Config.CONNECT_TIMEOUT * 1000);
|
||||
InputStream proxyIs = socket.getInputStream();
|
||||
OutputStream proxyOs = socket.getOutputStream();
|
||||
proxyOs.write(new byte[]{0x05, 0x01, 0x00});
|
||||
byte[] response = new byte[2];
|
||||
proxyIs.read(response);
|
||||
ByteBuffer request = ByteBuffer.allocate(7 + destination.length);
|
||||
request.put(new byte[]{0x05, 0x01, 0x00, 0x03});
|
||||
request.put((byte) destination.length);
|
||||
request.put(destination);
|
||||
request.putShort((short) account.getPort());
|
||||
proxyOs.write(request.array());
|
||||
response = new byte[7 + destination.length];
|
||||
proxyIs.read(response);
|
||||
if (response[1] != 0x00) {
|
||||
throw new UnknownHostException();
|
||||
destination = account.getHostname();
|
||||
}
|
||||
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": connect to "+destination+" via TOR");
|
||||
socket = SocksSocketFactory.createSocketOverTor(destination,account.getPort());
|
||||
} else if (DNSHelper.isIp(account.getServer().toString())) {
|
||||
socket = new Socket();
|
||||
try {
|
||||
|
|
|
@ -21,6 +21,7 @@ import eu.siacs.conversations.Config;
|
|||
import eu.siacs.conversations.entities.DownloadableFile;
|
||||
import eu.siacs.conversations.persistance.FileBackend;
|
||||
import eu.siacs.conversations.utils.CryptoHelper;
|
||||
import eu.siacs.conversations.utils.SocksSocketFactory;
|
||||
|
||||
public class JingleSocks5Transport extends JingleTransport {
|
||||
private JingleCandidate candidate;
|
||||
|
@ -61,36 +62,19 @@ public class JingleSocks5Transport extends JingleTransport {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final boolean useTor = connection.getConnectionManager().getXmppConnectionService().useTorToConnect();
|
||||
final Proxy TOR_PROXY = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(InetAddress.getLocalHost(), 9050));
|
||||
socket = useTor ? new Socket(TOR_PROXY) : new Socket();
|
||||
final boolean useTor = connection.getAccount().isOnion() || connection.getConnectionManager().getXmppConnectionService().useTorToConnect();
|
||||
if (useTor) {
|
||||
socket = SocksSocketFactory.createSocketOverTor(candidate.getHost(),candidate.getPort());
|
||||
} else {
|
||||
socket = new Socket();
|
||||
SocketAddress address = new InetSocketAddress(candidate.getHost(),candidate.getPort());
|
||||
socket.connect(address,Config.SOCKET_TIMEOUT * 1000);
|
||||
}
|
||||
inputStream = socket.getInputStream();
|
||||
outputStream = socket.getOutputStream();
|
||||
byte[] login = { 0x05, 0x01, 0x00 };
|
||||
byte[] expectedReply = { 0x05, 0x00 };
|
||||
byte[] reply = new byte[2];
|
||||
outputStream.write(login);
|
||||
inputStream.read(reply);
|
||||
final String connect = Character.toString('\u0005')
|
||||
+ '\u0001' + '\u0000' + '\u0003' + '\u0028'
|
||||
+ destination + '\u0000' + '\u0000';
|
||||
if (Arrays.equals(reply, expectedReply)) {
|
||||
outputStream.write(connect.getBytes());
|
||||
byte[] result = new byte[2];
|
||||
inputStream.read(result);
|
||||
int status = result[1];
|
||||
if (status == 0) {
|
||||
SocksSocketFactory.createSocksConnection(socket,destination,0);
|
||||
isEstablished = true;
|
||||
callback.established();
|
||||
} else {
|
||||
callback.failed();
|
||||
}
|
||||
} else {
|
||||
socket.close();
|
||||
callback.failed();
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
callback.failed();
|
||||
} catch (IOException e) {
|
||||
|
@ -162,7 +146,7 @@ public class JingleSocks5Transport extends JingleTransport {
|
|||
wakeLock.acquire();
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||||
digest.reset();
|
||||
inputStream.skip(45);
|
||||
//inputStream.skip(45);
|
||||
socket.setSoTimeout(30000);
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
|
|
Loading…
Reference in a new issue