aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Gultsch <daniel@gultsch.de>2015-11-29 15:44:45 +0100
committerDaniel Gultsch <daniel@gultsch.de>2015-12-01 12:00:50 +0100
commitebccb67a7208042ca8362ae326b6b75369d61d12 (patch)
treecd069ecb7f9220edf1cc88af5ba6ea70fccac32c
parentf0b1761ec3826b72fe3b20032b532dc5b1adfc1c (diff)
do socks5 connect manually
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Account.java20
-rw-r--r--src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java52
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java48
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) {