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 int REFRESH_UI_INTERVAL = 500;
|
||||||
|
|
||||||
public static final boolean DISABLE_PROXY_LOOKUP = false; //useful to debug ibb
|
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 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 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
|
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.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
import eu.siacs.conversations.utils.CryptoHelper;
|
||||||
import eu.siacs.conversations.utils.DNSHelper;
|
import eu.siacs.conversations.utils.DNSHelper;
|
||||||
|
import eu.siacs.conversations.utils.SocksSocketFactory;
|
||||||
import eu.siacs.conversations.utils.Xmlns;
|
import eu.siacs.conversations.utils.Xmlns;
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
import eu.siacs.conversations.xml.Tag;
|
import eu.siacs.conversations.xml.Tag;
|
||||||
|
@ -235,32 +236,14 @@ public class XmppConnection implements Runnable {
|
||||||
this.changeStatus(Account.State.CONNECTING);
|
this.changeStatus(Account.State.CONNECTING);
|
||||||
final boolean useTor = mXmppConnectionService.useTorToConnect() || account.isOnion();
|
final boolean useTor = mXmppConnectionService.useTorToConnect() || account.isOnion();
|
||||||
if (useTor) {
|
if (useTor) {
|
||||||
InetSocketAddress proxyAddress = new InetSocketAddress(InetAddress.getLocalHost(), 9050);
|
String destination;
|
||||||
byte[] destination;
|
|
||||||
if (account.getHostname() == null || account.getHostname().isEmpty()) {
|
if (account.getHostname() == null || account.getHostname().isEmpty()) {
|
||||||
destination = account.getServer().toString().getBytes();
|
destination = account.getServer().toString();
|
||||||
} else {
|
} else {
|
||||||
destination = account.getHostname().getBytes();
|
destination = account.getHostname();
|
||||||
}
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
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())) {
|
} else if (DNSHelper.isIp(account.getServer().toString())) {
|
||||||
socket = new Socket();
|
socket = new Socket();
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.entities.DownloadableFile;
|
import eu.siacs.conversations.entities.DownloadableFile;
|
||||||
import eu.siacs.conversations.persistance.FileBackend;
|
import eu.siacs.conversations.persistance.FileBackend;
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
import eu.siacs.conversations.utils.CryptoHelper;
|
||||||
|
import eu.siacs.conversations.utils.SocksSocketFactory;
|
||||||
|
|
||||||
public class JingleSocks5Transport extends JingleTransport {
|
public class JingleSocks5Transport extends JingleTransport {
|
||||||
private JingleCandidate candidate;
|
private JingleCandidate candidate;
|
||||||
|
@ -61,36 +62,19 @@ public class JingleSocks5Transport extends JingleTransport {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
final boolean useTor = connection.getConnectionManager().getXmppConnectionService().useTorToConnect();
|
final boolean useTor = connection.getAccount().isOnion() || connection.getConnectionManager().getXmppConnectionService().useTorToConnect();
|
||||||
final Proxy TOR_PROXY = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(InetAddress.getLocalHost(), 9050));
|
if (useTor) {
|
||||||
socket = useTor ? new Socket(TOR_PROXY) : new Socket();
|
socket = SocksSocketFactory.createSocketOverTor(candidate.getHost(),candidate.getPort());
|
||||||
|
} else {
|
||||||
|
socket = new Socket();
|
||||||
SocketAddress address = new InetSocketAddress(candidate.getHost(),candidate.getPort());
|
SocketAddress address = new InetSocketAddress(candidate.getHost(),candidate.getPort());
|
||||||
socket.connect(address,Config.SOCKET_TIMEOUT * 1000);
|
socket.connect(address,Config.SOCKET_TIMEOUT * 1000);
|
||||||
|
}
|
||||||
inputStream = socket.getInputStream();
|
inputStream = socket.getInputStream();
|
||||||
outputStream = socket.getOutputStream();
|
outputStream = socket.getOutputStream();
|
||||||
byte[] login = { 0x05, 0x01, 0x00 };
|
SocksSocketFactory.createSocksConnection(socket,destination,0);
|
||||||
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) {
|
|
||||||
isEstablished = true;
|
isEstablished = true;
|
||||||
callback.established();
|
callback.established();
|
||||||
} else {
|
|
||||||
callback.failed();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
socket.close();
|
|
||||||
callback.failed();
|
|
||||||
}
|
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
callback.failed();
|
callback.failed();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -162,7 +146,7 @@ public class JingleSocks5Transport extends JingleTransport {
|
||||||
wakeLock.acquire();
|
wakeLock.acquire();
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||||||
digest.reset();
|
digest.reset();
|
||||||
inputStream.skip(45);
|
//inputStream.skip(45);
|
||||||
socket.setSoTimeout(30000);
|
socket.setSoTimeout(30000);
|
||||||
file.getParentFile().mkdirs();
|
file.getParentFile().mkdirs();
|
||||||
file.createNewFile();
|
file.createNewFile();
|
||||||
|
|
Loading…
Reference in a new issue