diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index bbc96811b..e44e5dcd2 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -48,7 +48,6 @@ import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.SerialSingleThreadExecutor; import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xml.Namespace; import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded; import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.pep.PublishOptions; @@ -67,8 +66,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { public static final String LOGPREFIX = "AxolotlService"; - public static final int NUM_KEYS_TO_PUBLISH = 100; - public static final int publishTriesThreshold = 3; + private static final int NUM_KEYS_TO_PUBLISH = 100; + private static final int publishTriesThreshold = 3; private final Account account; private final XmppConnectionService mXmppConnectionService; @@ -1469,7 +1468,9 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } else { Log.d(Config.LOGTAG,account.getJid().asBareJid()+": nothing to flush. Not republishing key"); } - completeSession(session); + if (trustedOrPreviouslyResponded(session)) { + completeSession(session); + } } } @@ -1479,23 +1480,44 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { publishBundlesIfNeeded(false, false); } } - Iterator iterator = postponedSessions.iterator(); + final Iterator iterator = postponedSessions.iterator(); while (iterator.hasNext()) { - completeSession(iterator.next()); + final XmppAxolotlSession session = iterator.next(); + if (trustedOrPreviouslyResponded(session)) { + completeSession(iterator.next()); + } iterator.remove(); } - Iterator postponedHealingAttemptsIterator = postponedHealing.iterator(); + final Iterator postponedHealingAttemptsIterator = postponedHealing.iterator(); while (postponedHealingAttemptsIterator.hasNext()) { notifyRequiresHealing(postponedHealingAttemptsIterator.next()); postponedHealingAttemptsIterator.remove(); } } + + private boolean trustedOrPreviouslyResponded(XmppAxolotlSession session) { + try { + return trustedOrPreviouslyResponded(Jid.of(session.getRemoteAddress().getName())); + } catch (IllegalArgumentException e) { + return false; + } + } + + public boolean trustedOrPreviouslyResponded(Jid jid) { + final Contact contact = account.getRoster().getContact(jid); + if (contact.showInRoster() || contact.isSelf()) { + return true; + } + final Conversation conversation = mXmppConnectionService.find(account, jid); + return conversation != null && conversation.sentMessagesCount() > 0; + } + private void completeSession(XmppAxolotlSession session) { final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage(account.getJid().asBareJid(), getOwnDeviceId()); axolotlMessage.addDevice(session, true); try { - Jid jid = Jid.of(session.getRemoteAddress().getName()); + final Jid jid = Jid.of(session.getRemoteAddress().getName()); MessagePacket packet = mXmppConnectionService.getMessageGenerator().generateKeyTransportMessage(jid, axolotlMessage); mXmppConnectionService.sendMessagePacket(account, packet); } catch (IllegalArgumentException e) { @@ -1505,9 +1527,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { public XmppAxolotlMessage.XmppAxolotlKeyTransportMessage processReceivingKeyTransportMessage(XmppAxolotlMessage message, final boolean postponePreKeyMessageHandling) { - XmppAxolotlMessage.XmppAxolotlKeyTransportMessage keyTransportMessage; - - XmppAxolotlSession session = getReceivingSession(message); + final XmppAxolotlMessage.XmppAxolotlKeyTransportMessage keyTransportMessage; + final XmppAxolotlSession session = getReceivingSession(message); try { keyTransportMessage = message.getParameters(session, getOwnDeviceId()); Integer preKeyId = session.getPreKeyIdAndReset(); @@ -1516,7 +1537,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } } catch (CryptoFailedException e) { Log.d(Config.LOGTAG, "could not decrypt keyTransport message " + e.getMessage()); - keyTransportMessage = null; + return null; } if (session.isFresh() && keyTransportMessage != null) { @@ -1527,7 +1548,6 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } private void putFreshSession(XmppAxolotlSession session) { - Log.d(Config.LOGTAG, "put fresh session"); sessions.put(session); if (Config.X509_VERIFICATION) { if (session.getIdentityKey() != null) { diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 738b8fffa..972ce4195 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -125,8 +125,13 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece plaintextMessage = service.processReceivingPayloadMessage(xmppAxolotlMessage, postpone); } catch (BrokenSessionException e) { if (checkedForDuplicates) { - service.reportBrokenSessionException(e, postpone); - return new Message(conversation, "", Message.ENCRYPTION_AXOLOTL_FAILED, status); + if (service.trustedOrPreviouslyResponded(from.asBareJid())) { + service.reportBrokenSessionException(e, postpone); + return new Message(conversation, "", Message.ENCRYPTION_AXOLOTL_FAILED, status); + } else { + Log.d(Config.LOGTAG, "ignoring broken session exception because contact was not trusted"); + return new Message(conversation, "", Message.ENCRYPTION_AXOLOTL_FAILED, status); + } } else { Log.d(Config.LOGTAG,"ignoring broken session exception because checkForDuplicates failed"); //TODO should be still emit a failed message?