diff options
author | Daniel Gultsch <daniel@gultsch.de> | 2015-11-29 15:44:45 +0100 |
---|---|---|
committer | Daniel Gultsch <daniel@gultsch.de> | 2015-12-01 12:00:50 +0100 |
commit | ebccb67a7208042ca8362ae326b6b75369d61d12 (patch) | |
tree | cd069ecb7f9220edf1cc88af5ba6ea70fccac32c | |
parent | f0b1761ec3826b72fe3b20032b532dc5b1adfc1c (diff) |
do socks5 connect manually
3 files changed, 69 insertions, 51 deletions
diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index 3aa1675f..062c0d25 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -2,8 +2,6 @@ package eu.siacs.conversations.entities; import android.content.ContentValues; import android.database.Cursor; -import android.os.Bundle; -import android.os.Parcelable; import android.os.SystemClock; import eu.siacs.conversations.crypto.PgpDecryptionService; @@ -15,7 +13,6 @@ import org.json.JSONObject; import java.security.PublicKey; import java.security.interfaces.DSAPublicKey; -import java.util.ArrayList; import java.util.Collection; import java.util.List; 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 { DISABLED, OFFLINE, @@ -268,6 +252,10 @@ public class Account extends AbstractEntity { return this.hostname == null ? "" : this.hostname; } + public boolean isOnion() { + return getServer().toString().toLowerCase().endsWith(".onion"); + } + public void setPort(int port) { this.port = port; } diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index bbdc7524..961d2cd6 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -129,6 +129,31 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate mAccountJid.requestFocus(); 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 (Config.DOMAIN_LOCK != null) { 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 passwordConfirm = mPasswordConfirm.getText().toString(); - final String hostname = mHostname.getText().toString(); - final String port = mPort.getText().toString(); if (registerNewAccount) { if (!password.equals(passwordConfirm)) { mPasswordConfirm.setError(getString(R.string.passwords_do_not_match)); @@ -151,29 +174,12 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } if (mAccount != null) { mAccount.setJid(jid); + mAccount.setPort(numericPort); + mAccount.setHostname(hostname); mAccountJid.setError(null); mPasswordConfirm.setError(null); mAccount.setPassword(password); 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); } else { if (xmppConnectionService.findAccountByJid(jid) != null) { @@ -182,11 +188,15 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate return; } mAccount = new Account(jid.toBareJid(), password); + mAccount.setPort(numericPort); + mAccount.setHostname(hostname); mAccount.setOption(Account.OPTION_USETLS, true); mAccount.setOption(Account.OPTION_USECOMPRESSION, true); mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount); xmppConnectionService.createAccount(mAccount); } + mHostname.setError(null); + mPort.setError(null); if (!mAccount.isOptionSet(Account.OPTION_DISABLED) && !registerNewAccount && !mInitMode) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index dec3cad6..f5f3860c 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -13,7 +13,6 @@ import android.util.Log; import android.util.Pair; import android.util.SparseArray; -import org.apache.http.conn.ssl.StrictHostnameVerifier; import org.json.JSONException; import org.json.JSONObject; import org.xmlpull.v1.XmlPullParserException; @@ -27,10 +26,10 @@ import java.net.ConnectException; import java.net.IDN; import java.net.InetAddress; import java.net.InetSocketAddress; -import java.net.Proxy; import java.net.Socket; import java.net.UnknownHostException; import java.net.URL; +import java.nio.ByteBuffer; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.Principal; @@ -234,23 +233,44 @@ public class XmppConnection implements Runnable { tagReader = new XmlReader(wakeLock); tagWriter = new TagWriter(); this.changeStatus(Account.State.CONNECTING); - final boolean useTor = mXmppConnectionService.useTorToConnect(); - final Proxy TOR_PROXY = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(InetAddress.getLocalHost(), 9050)); - if (DNSHelper.isIp(account.getServer().toString())) { - socket = useTor ? new Socket(TOR_PROXY) : new Socket(); + final boolean useTor = mXmppConnectionService.useTorToConnect() || account.isOnion(); + if (useTor) { + InetSocketAddress proxyAddress = new InetSocketAddress(InetAddress.getLocalHost(), 9050); + 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 { socket.connect(new InetSocketAddress(account.getServer().toString(), 5222), Config.SOCKET_TIMEOUT * 1000); } catch (IOException e) { throw new UnknownHostException(); } } else { - final ArrayList<Parcelable> values; - if (useTor) { - values = account.getHostnamePortBundles(); - } else { - final Bundle result = DNSHelper.getSRVRecord(account.getServer(),mXmppConnectionService); - values = result.getParcelableArrayList("values"); - } + final Bundle result = DNSHelper.getSRVRecord(account.getServer(),mXmppConnectionService); + final ArrayList<Parcelable>values = result.getParcelableArrayList("values"); int i = 0; boolean socketError = true; while (socketError && values.size() > i) { @@ -277,7 +297,7 @@ public class XmppConnection implements Runnable { + ": using values from dns " + srvRecordServer + ":" + srvRecordPort); } - socket = useTor ? new Socket(TOR_PROXY) : new Socket(); + socket = new Socket(); socket.connect(addr, Config.SOCKET_TIMEOUT * 1000); socketError = false; } catch (final Throwable e) { |