do socks5 connect manually

This commit is contained in:
Daniel Gultsch 2015-11-29 15:44:45 +01:00
parent f0b1761ec3
commit ebccb67a72
3 changed files with 69 additions and 51 deletions

View file

@ -2,8 +2,6 @@ package eu.siacs.conversations.entities;
import android.content.ContentValues; import android.content.ContentValues;
import android.database.Cursor; import android.database.Cursor;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.SystemClock; import android.os.SystemClock;
import eu.siacs.conversations.crypto.PgpDecryptionService; import eu.siacs.conversations.crypto.PgpDecryptionService;
@ -15,7 +13,6 @@ import org.json.JSONObject;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.interfaces.DSAPublicKey; import java.security.interfaces.DSAPublicKey;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@ -72,19 +69,6 @@ public class Account extends AbstractEntity {
} }
} }
public ArrayList<Parcelable> getHostnamePortBundles() {
ArrayList<Parcelable> values = new ArrayList<>();
Bundle hostPort = new Bundle();
if (hostname != null && !hostname.isEmpty()) {
hostPort.putString("name", hostname);
} else {
hostPort.putString("name", getServer().toString());
}
hostPort.putInt("port", port);
values.add(hostPort);
return values;
}
public enum State { public enum State {
DISABLED, DISABLED,
OFFLINE, OFFLINE,
@ -268,6 +252,10 @@ public class Account extends AbstractEntity {
return this.hostname == null ? "" : this.hostname; return this.hostname == null ? "" : this.hostname;
} }
public boolean isOnion() {
return getServer().toString().toLowerCase().endsWith(".onion");
}
public void setPort(int port) { public void setPort(int port) {
this.port = port; this.port = port;
} }

View file

@ -129,6 +129,31 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
mAccountJid.requestFocus(); mAccountJid.requestFocus();
return; return;
} }
String hostname = null;
int numericPort = 5222;
if (mUseTor) {
hostname = mHostname.getText().toString();
final String port = mPort.getText().toString();
if (hostname.contains(" ")) {
mHostname.setError(getString(R.string.not_valid_hostname));
mHostname.requestFocus();
return;
}
try {
numericPort = Integer.parseInt(port);
if (numericPort < 0 || numericPort > 65535) {
mPort.setError(getString(R.string.not_a_valid_port));
mPort.requestFocus();
return;
}
} catch (NumberFormatException e) {
mPort.setError(getString(R.string.not_a_valid_port));
mPort.requestFocus();
return;
}
}
if (jid.isDomainJid()) { if (jid.isDomainJid()) {
if (Config.DOMAIN_LOCK != null) { if (Config.DOMAIN_LOCK != null) {
mAccountJid.setError(getString(R.string.invalid_username)); mAccountJid.setError(getString(R.string.invalid_username));
@ -140,8 +165,6 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
} }
final String password = mPassword.getText().toString(); final String password = mPassword.getText().toString();
final String passwordConfirm = mPasswordConfirm.getText().toString(); final String passwordConfirm = mPasswordConfirm.getText().toString();
final String hostname = mHostname.getText().toString();
final String port = mPort.getText().toString();
if (registerNewAccount) { if (registerNewAccount) {
if (!password.equals(passwordConfirm)) { if (!password.equals(passwordConfirm)) {
mPasswordConfirm.setError(getString(R.string.passwords_do_not_match)); mPasswordConfirm.setError(getString(R.string.passwords_do_not_match));
@ -151,29 +174,12 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
} }
if (mAccount != null) { if (mAccount != null) {
mAccount.setJid(jid); mAccount.setJid(jid);
mAccount.setPort(numericPort);
mAccount.setHostname(hostname);
mAccountJid.setError(null); mAccountJid.setError(null);
mPasswordConfirm.setError(null); mPasswordConfirm.setError(null);
mAccount.setPassword(password); mAccount.setPassword(password);
mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount); mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
if (hostname.contains(" ")) {
mHostname.setError(getString(R.string.not_valid_hostname));
mHostname.requestFocus();
return;
}
mAccount.setHostname(hostname);
try {
int numericPort = Integer.parseInt(port);
if (numericPort < 0 || numericPort > 65535) {
mPort.setError(getString(R.string.not_a_valid_port));
mPort.requestFocus();
return;
}
mAccount.setPort(numericPort);
} catch (NumberFormatException e) {
mPort.setError(getString(R.string.not_a_valid_port));
mPort.requestFocus();
return;
}
xmppConnectionService.updateAccount(mAccount); xmppConnectionService.updateAccount(mAccount);
} else { } else {
if (xmppConnectionService.findAccountByJid(jid) != null) { if (xmppConnectionService.findAccountByJid(jid) != null) {
@ -182,11 +188,15 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
return; return;
} }
mAccount = new Account(jid.toBareJid(), password); mAccount = new Account(jid.toBareJid(), password);
mAccount.setPort(numericPort);
mAccount.setHostname(hostname);
mAccount.setOption(Account.OPTION_USETLS, true); mAccount.setOption(Account.OPTION_USETLS, true);
mAccount.setOption(Account.OPTION_USECOMPRESSION, true); mAccount.setOption(Account.OPTION_USECOMPRESSION, true);
mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount); mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
xmppConnectionService.createAccount(mAccount); xmppConnectionService.createAccount(mAccount);
} }
mHostname.setError(null);
mPort.setError(null);
if (!mAccount.isOptionSet(Account.OPTION_DISABLED) if (!mAccount.isOptionSet(Account.OPTION_DISABLED)
&& !registerNewAccount && !registerNewAccount
&& !mInitMode) { && !mInitMode) {

View file

@ -13,7 +13,6 @@ import android.util.Log;
import android.util.Pair; import android.util.Pair;
import android.util.SparseArray; import android.util.SparseArray;
import org.apache.http.conn.ssl.StrictHostnameVerifier;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -27,10 +26,10 @@ import java.net.ConnectException;
import java.net.IDN; import java.net.IDN;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket; import java.net.Socket;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.net.URL; import java.net.URL;
import java.nio.ByteBuffer;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.Principal; import java.security.Principal;
@ -234,23 +233,44 @@ public class XmppConnection implements Runnable {
tagReader = new XmlReader(wakeLock); tagReader = new XmlReader(wakeLock);
tagWriter = new TagWriter(); tagWriter = new TagWriter();
this.changeStatus(Account.State.CONNECTING); this.changeStatus(Account.State.CONNECTING);
final boolean useTor = mXmppConnectionService.useTorToConnect(); final boolean useTor = mXmppConnectionService.useTorToConnect() || account.isOnion();
final Proxy TOR_PROXY = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(InetAddress.getLocalHost(), 9050)); if (useTor) {
if (DNSHelper.isIp(account.getServer().toString())) { InetSocketAddress proxyAddress = new InetSocketAddress(InetAddress.getLocalHost(), 9050);
socket = useTor ? new Socket(TOR_PROXY) : new Socket(); byte[] destination;
if (account.getHostname() == null || account.getHostname().isEmpty()) {
destination = account.getServer().toString().getBytes();
} 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();
}
} else if (DNSHelper.isIp(account.getServer().toString())) {
socket = new Socket();
try { try {
socket.connect(new InetSocketAddress(account.getServer().toString(), 5222), Config.SOCKET_TIMEOUT * 1000); socket.connect(new InetSocketAddress(account.getServer().toString(), 5222), Config.SOCKET_TIMEOUT * 1000);
} catch (IOException e) { } catch (IOException e) {
throw new UnknownHostException(); throw new UnknownHostException();
} }
} else {
final ArrayList<Parcelable> values;
if (useTor) {
values = account.getHostnamePortBundles();
} else { } else {
final Bundle result = DNSHelper.getSRVRecord(account.getServer(),mXmppConnectionService); final Bundle result = DNSHelper.getSRVRecord(account.getServer(),mXmppConnectionService);
values = result.getParcelableArrayList("values"); final ArrayList<Parcelable>values = result.getParcelableArrayList("values");
}
int i = 0; int i = 0;
boolean socketError = true; boolean socketError = true;
while (socketError && values.size() > i) { while (socketError && values.size() > i) {
@ -277,7 +297,7 @@ public class XmppConnection implements Runnable {
+ ": using values from dns " + ": using values from dns "
+ srvRecordServer + ":" + srvRecordPort); + srvRecordServer + ":" + srvRecordPort);
} }
socket = useTor ? new Socket(TOR_PROXY) : new Socket(); socket = new Socket();
socket.connect(addr, Config.SOCKET_TIMEOUT * 1000); socket.connect(addr, Config.SOCKET_TIMEOUT * 1000);
socketError = false; socketError = false;
} catch (final Throwable e) { } catch (final Throwable e) {