do socks5 connect manually
This commit is contained in:
parent
f0b1761ec3
commit
ebccb67a72
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue