diff options
Diffstat (limited to 'src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java')
-rw-r--r-- | src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 37b2da68..ab647a15 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.xmpp; +import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; @@ -13,6 +14,7 @@ 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; @@ -20,6 +22,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.math.BigInteger; import java.net.ConnectException; import java.net.IDN; @@ -34,11 +37,16 @@ import java.security.Principal; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.TreeSet; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.KeyManager; @@ -48,6 +56,9 @@ import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.X509KeyManager; import javax.net.ssl.X509TrustManager; +import de.thedevstack.android.logcat.Logging; +import de.thedevstack.conversationsplus.dto.SrvRecord; + import de.duenndns.ssl.MemorizingTrustManager; import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.XmppDomainVerifier; @@ -88,7 +99,7 @@ import eu.siacs.conversations.xmpp.stanzas.streammgmt.RequestPacket; import eu.siacs.conversations.xmpp.stanzas.streammgmt.ResumePacket; public class XmppConnection implements Runnable { - + private static final int DEFAULT_PORT = 5222; private static final int PACKET_IQ = 0; private static final int PACKET_MESSAGE = 1; private static final int PACKET_PRESENCE = 2; @@ -220,7 +231,7 @@ public class XmppConnection implements Runnable { } protected void connect() { - Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": connecting"); + Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": connecting"); features.encryptionEnabled = false; lastConnect = SystemClock.elapsedRealtime(); lastPingSent = SystemClock.elapsedRealtime(); @@ -265,7 +276,7 @@ public class XmppConnection implements Runnable { } else if (DNSHelper.isIp(account.getServer().toString())) { socket = new Socket(); try { - socket.connect(new InetSocketAddress(account.getServer().toString(), 5222), Config.SOCKET_TIMEOUT * 1000); + socket.connect(new InetSocketAddress(account.getServer().toString(), DEFAULT_PORT), Config.SOCKET_TIMEOUT * 1000); } catch (IOException e) { throw new UnknownHostException(); } @@ -347,7 +358,7 @@ public class XmppConnection implements Runnable { } catch (final SocksSocketFactory.SocksProxyNotFoundException e) { this.changeStatus(Account.State.TOR_NOT_AVAILABLE); } catch (final IOException | XmlPullParserException | NoSuchAlgorithmException e) { - Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage()); + Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage()); this.changeStatus(Account.State.OFFLINE); this.attempt--; //don't count attempt when reconnecting instantly anyway } finally { @@ -659,7 +670,7 @@ public class XmppConnection implements Runnable { callback = packetCallbackDuple.second; packetCallbacks.remove(packet.getId()); } else { - Log.e(Config.LOGTAG, account.getJid().toBareJid().toString() + ": ignoring spoofed iq packet"); + Logging.e(Config.LOGTAG, account.getJid().toBareJid().toString() + ": ignoring spoofed iq packet"); } } } else if (packet.getType() == IqPacket.TYPE.GET || packet.getType() == IqPacket.TYPE.SET) { @@ -766,16 +777,16 @@ public class XmppConnection implements Runnable { try { if (keys.has(Account.PINNED_MECHANISM_KEY) && keys.getInt(Account.PINNED_MECHANISM_KEY) > saslMechanism.getPriority()) { - Log.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() + + Logging.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() + " has lower priority (" + String.valueOf(saslMechanism.getPriority()) + ") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) + "). Possible downgrade attack?"); throw new SecurityException(); } } catch (final JSONException e) { - Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism"); + Logging.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism"); } - Log.d(Config.LOGTAG, account.getJid().toString() + ": Authenticating with " + saslMechanism.getMechanism()); + Logging.d(Config.LOGTAG, account.getJid().toString() + ": Authenticating with " + saslMechanism.getMechanism()); auth.setAttribute("mechanism", saslMechanism.getMechanism()); if (!saslMechanism.getClientFirstMessage().isEmpty()) { auth.setContent(saslMechanism.getClientFirstMessage()); @@ -786,7 +797,7 @@ public class XmppConnection implements Runnable { } } else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:" + smVersion) && streamId != null) { if (Config.EXTENDED_SM_LOGGING) { - Log.d(Config.LOGTAG,account.getJid().toBareJid()+": resuming after stanza #"+stanzasReceived); + Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": resuming after stanza #"+stanzasReceived); } final ResumePacket resume = new ResumePacket(this.streamId, stanzasReceived, smVersion); this.tagWriter.writeStanzaAsync(resume); @@ -858,7 +869,7 @@ public class XmppConnection implements Runnable { URL uri = new URL(urlString); captcha = BitmapFactory.decodeStream(uri.openConnection().getInputStream()); } catch (IOException e) { - Log.e(Config.LOGTAG, e.toString()); + Logging.e(Config.LOGTAG, e.toString()); } } @@ -927,11 +938,11 @@ public class XmppConnection implements Runnable { sendPostBindInitialization(); } } else { - Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure"); + Logging.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure"); disconnect(true); } } else { - Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure"); + Logging.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure"); disconnect(true); } } @@ -991,7 +1002,7 @@ public class XmppConnection implements Runnable { if (packet.getType() == IqPacket.TYPE.RESULT) { sendPostBindInitialization(); } else if (packet.getType() != IqPacket.TYPE.TIMEOUT) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not init sessions"); + Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not init sessions"); disconnect(true); } } @@ -1080,13 +1091,13 @@ public class XmppConnection implements Runnable { enableAdvancedStreamFeatures(); } } else { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not query disco info for " + jid.toString()); + Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not query disco info for " + jid.toString()); } if (packet.getType() != IqPacket.TYPE.TIMEOUT) { mPendingServiceDiscoveries--; if (mPendingServiceDiscoveries == 0) { - Log.d(Config.LOGTAG,account.getJid().toBareJid()+": done with service discovery"); - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": online with resource " + account.getResource()); + Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": done with service discovery"); + Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": online with resource " + account.getResource()); changeStatus(Account.State.ONLINE); if (bindListener != null) { bindListener.onBind(account); @@ -1146,11 +1157,11 @@ public class XmppConnection implements Runnable { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { if (!packet.hasChild("error")) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": successfully enabled carbons"); features.carbonsEnabled = true; } else { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": error enableing carbons " + packet.toString()); } } @@ -1163,11 +1174,11 @@ public class XmppConnection implements Runnable { if (streamError != null && streamError.hasChild("conflict")) { final String resource = account.getResource().split("\\.")[0]; account.setResource(resource + "." + nextRandomId()); - Log.d(Config.LOGTAG, + Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": switching resource due to conflict (" + account.getResource() + ")"); } else if (streamError != null) { - Log.d(Config.LOGTAG,account.getJid().toBareJid()+": stream error "+streamError.toString()); + Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": stream error "+streamError.toString()); } } @@ -1281,12 +1292,12 @@ public class XmppConnection implements Runnable { } public void disconnect(final boolean force) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": disconnecting force="+Boolean.valueOf(force)); + Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": disconnecting force="+Boolean.valueOf(force)); if (force) { try { socket.close(); } catch(Exception e) { - Log.d(Config.LOGTAG,account.getJid().toBareJid().toString()+": exception during force close ("+e.getMessage()+")"); + Logging.d(Config.LOGTAG,account.getJid().toBareJid().toString()+": exception during force close ("+e.getMessage()+")"); } return; } else { @@ -1379,7 +1390,12 @@ public class XmppConnection implements Runnable { } public long getLastSessionEstablished() { - final long diff = SystemClock.elapsedRealtime() - this.lastSessionStarted; + final long diff; + if (this.lastSessionStarted == 0) { + diff = SystemClock.elapsedRealtime() - this.lastConnect; + } else { + diff = SystemClock.elapsedRealtime() - this.lastSessionStarted; + } return System.currentTimeMillis() - diff; } |