aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/pixart/messenger/xmpp
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2019-09-06 22:07:20 +0200
committerChristian Schneppe <christian@pix-art.de>2019-09-06 22:07:20 +0200
commit75548eafa43786dfbe90571e8a6dfeaa6b7cdddd (patch)
treea5441db32367fde55427b539a9a7cd707d2f94b8 /src/main/java/de/pixart/messenger/xmpp
parentc7629a60933ac61d6c38c1adb4a97c7d336514c4 (diff)
make Tor connections work with direct TLS
Diffstat (limited to 'src/main/java/de/pixart/messenger/xmpp')
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/XmppConnection.java108
1 files changed, 48 insertions, 60 deletions
diff --git a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java
index 01c19322b..54f72754c 100644
--- a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java
+++ b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java
@@ -293,8 +293,17 @@ public class XmppConnection implements Runnable {
destination = account.getHostname();
this.verifiedHostname = destination;
}
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": connect to " + destination + " via Tor");
- localSocket = SocksSocketFactory.createSocketOverTor(destination, account.getPort());
+ final int port = account.getPort();
+ final boolean directTls = Resolver.useDirectTls(port);
+
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": connect to " + destination + " via Tor. directTls=" + directTls);
+ localSocket = SocksSocketFactory.createSocketOverTor(destination, port);
+
+ if (directTls) {
+ localSocket = upgradeSocketToTls(localSocket);
+ features.encryptionEnabled = true;
+ }
+
try {
startXmpp(localSocket);
} catch (InterruptedException e) {
@@ -354,29 +363,13 @@ public class XmppConnection implements Runnable {
+ result.getHostname().toString() + ":" + result.getPort() + " tls: " + features.encryptionEnabled);
}
- if (!features.encryptionEnabled) {
- localSocket = new Socket();
- localSocket.connect(addr, Config.SOCKET_TIMEOUT * 1000);
- } else {
- final TlsFactoryVerifier tlsFactoryVerifier = getTlsFactoryVerifier();
- localSocket = tlsFactoryVerifier.factory.createSocket();
-
- if (localSocket == null) {
- throw new IOException("could not initialize ssl socket");
- }
-
- SSLSocketHelper.setSecurity((SSLSocket) localSocket);
- SSLSocketHelper.setHostname((SSLSocket) localSocket, account.getServer());
- SSLSocketHelper.setApplicationProtocol((SSLSocket) localSocket, "xmpp-client");
+ localSocket = new Socket();
+ localSocket.connect(addr, Config.SOCKET_TIMEOUT * 1000);
- localSocket.connect(addr, Config.SOCKET_TIMEOUT * 1000);
-
- if (!tlsFactoryVerifier.verifier.verify(account.getServer(), verifiedHostname, ((SSLSocket) localSocket).getSession())) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": TLS certificate verification failed");
- FileBackend.close(localSocket);
- throw new StateChangingException(Account.State.TLS_ERROR);
- }
+ if (features.encryptionEnabled) {
+ localSocket = upgradeSocketToTls(localSocket);
}
+
localSocket.setSoTimeout(Config.SOCKET_TIMEOUT * 1000);
if (startXmpp(localSocket)) {
localSocket.setSoTimeout(0); //reset to 0; once the connection is established we don’t want this
@@ -410,6 +403,8 @@ public class XmppConnection implements Runnable {
this.changeStatus(e.state);
} catch (final UnknownHostException e) {
this.changeStatus(Account.State.SERVER_NOT_FOUND);
+ } catch (final SocksSocketFactory.HostNotFoundException e) {
+ this.changeStatus(Account.State.SERVER_NOT_FOUND);
} catch (final ConnectException e) {
this.changeStatus(Account.State.SERVER_NOT_FOUND);
} catch (final SocksSocketFactory.SocksProxyNotFoundException e) {
@@ -834,48 +829,41 @@ public class XmppConnection implements Runnable {
private void switchOverToTls() throws XmlPullParserException, IOException {
tagReader.readTag();
- try {
- final TlsFactoryVerifier tlsFactoryVerifier = getTlsFactoryVerifier();
- final InetAddress address = socket == null ? null : socket.getInetAddress();
-
- if (address == null) {
- throw new IOException("could not setup ssl");
- }
-
- final SSLSocket sslSocket = (SSLSocket) tlsFactoryVerifier.factory.createSocket(socket, address.getHostAddress(), socket.getPort(), true);
-
- if (sslSocket == null) {
- throw new IOException("could not initialize ssl socket");
- }
-
- SSLSocketHelper.setSecurity(sslSocket);
- SSLSocketHelper.setHostname(sslSocket, account.getServer());
- SSLSocketHelper.setApplicationProtocol(sslSocket, "xmpp-client");
+ final Socket socket = this.socket;
+ final SSLSocket sslSocket = upgradeSocketToTls(socket);
+ tagReader.setInputStream(sslSocket.getInputStream());
+ tagWriter.setOutputStream(sslSocket.getOutputStream());
+ sendStartStream();
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": TLS connection established");
+ features.encryptionEnabled = true;
+ final Tag tag = tagReader.readTag();
+ if (tag != null && tag.isStart("stream")) {
+ SSLSocketHelper.log(account, sslSocket);
+ processStream();
+ } else {
+ throw new StateChangingException(Account.State.STREAM_OPENING_ERROR);
+ }
+ sslSocket.close();
+ }
- if (!tlsFactoryVerifier.verifier.verify(account.getServer(), this.verifiedHostname, sslSocket.getSession())) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": TLS certificate verification failed");
- throw new StateChangingException(Account.State.TLS_ERROR);
- }
- tagReader.setInputStream(sslSocket.getInputStream());
- tagWriter.setOutputStream(sslSocket.getOutputStream());
- sendStartStream();
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": TLS connection established");
- features.encryptionEnabled = true;
- final Tag tag = tagReader.readTag();
- if (tag != null && tag.isStart("stream")) {
- SSLSocketHelper.log(account, sslSocket);
- processStream();
- } else {
- throw new StateChangingException(Account.State.STREAM_OPENING_ERROR);
- }
- sslSocket.close();
- } catch (final NoSuchAlgorithmException e1) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": TLS certificate verification failed");
+ private SSLSocket upgradeSocketToTls(final Socket socket) throws IOException {
+ final TlsFactoryVerifier tlsFactoryVerifier;
+ try {
+ tlsFactoryVerifier = getTlsFactoryVerifier();
+ } catch (final NoSuchAlgorithmException | KeyManagementException e) {
throw new StateChangingException(Account.State.TLS_ERROR);
- } catch (final KeyManagementException e1) {
+ }
+ final InetAddress address = socket.getInetAddress();
+ final SSLSocket sslSocket = (SSLSocket) tlsFactoryVerifier.factory.createSocket(socket, address.getHostAddress(), socket.getPort(), true);
+ SSLSocketHelper.setSecurity(sslSocket);
+ SSLSocketHelper.setHostname(sslSocket, account.getServer());
+ SSLSocketHelper.setApplicationProtocol(sslSocket, "xmpp-client");
+ if (!tlsFactoryVerifier.verifier.verify(account.getServer(), this.verifiedHostname, sslSocket.getSession())) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": TLS certificate verification failed");
+ FileBackend.close(sslSocket);
throw new StateChangingException(Account.State.TLS_ERROR);
}
+ return sslSocket;
}
private void processStreamFeatures(final Tag currentTag) throws XmlPullParserException, IOException {