Renew session if message decryption fails with ProtocolInvalidMessageException

This commit is contained in:
AsamK 2021-05-05 20:20:02 +02:00
parent b7f05a1c80
commit 1bd60eea81
3 changed files with 57 additions and 1 deletions

View file

@ -187,3 +187,32 @@ class RetrieveProfileAction implements HandleAction {
return recipientId.hashCode(); return recipientId.hashCode();
} }
} }
class RenewSessionAction implements HandleAction {
private final RecipientId recipientId;
public RenewSessionAction(final RecipientId recipientId) {
this.recipientId = recipientId;
}
@Override
public void execute(Manager m) throws Throwable {
m.renewSession(recipientId);
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final RenewSessionAction that = (RenewSessionAction) o;
return recipientId.equals(that.recipientId);
}
@Override
public int hashCode() {
return recipientId.hashCode();
}
}

View file

@ -1088,6 +1088,11 @@ public class Manager implements Closeable {
} }
} }
SendMessageResult renewSession(RecipientId recipientId) throws IOException {
account.getSessionStore().archiveSessions(recipientId);
return sendNullMessage(recipientId);
}
public String getContactName(String number) throws InvalidNumberException { public String getContactName(String number) throws InvalidNumberException {
var contact = account.getContactStore().getContact(canonicalizeAndResolveRecipient(number)); var contact = account.getContactStore().getContact(canonicalizeAndResolveRecipient(number));
return contact == null || contact.getName() == null ? "" : contact.getName(); return contact == null || contact.getName() == null ? "" : contact.getName();
@ -1468,6 +1473,23 @@ public class Manager implements Closeable {
} }
} }
private SendMessageResult sendNullMessage(RecipientId recipientId) throws IOException {
var messageSender = createMessageSender();
final var address = resolveSignalServiceAddress(recipientId);
try {
try {
return messageSender.sendNullMessage(address, unidentifiedAccessHelper.getAccessFor(recipientId));
} catch (UnregisteredUserException e) {
final var newRecipientId = refreshRegisteredUser(recipientId);
final var newAddress = resolveSignalServiceAddress(newRecipientId);
return messageSender.sendNullMessage(newAddress, unidentifiedAccessHelper.getAccessFor(newRecipientId));
}
} catch (UntrustedIdentityException e) {
return SendMessageResult.identityFailure(address, e.getIdentityKey());
}
}
private SignalServiceContent decryptMessage(SignalServiceEnvelope envelope) throws InvalidMetadataMessageException, ProtocolInvalidMessageException, ProtocolDuplicateMessageException, ProtocolLegacyMessageException, ProtocolInvalidKeyIdException, InvalidMetadataVersionException, ProtocolInvalidVersionException, ProtocolNoSessionException, ProtocolInvalidKeyException, SelfSendException, UnsupportedDataMessageException, org.whispersystems.libsignal.UntrustedIdentityException { private SignalServiceContent decryptMessage(SignalServiceEnvelope envelope) throws InvalidMetadataMessageException, ProtocolInvalidMessageException, ProtocolDuplicateMessageException, ProtocolLegacyMessageException, ProtocolInvalidKeyIdException, InvalidMetadataVersionException, ProtocolInvalidVersionException, ProtocolNoSessionException, ProtocolInvalidKeyException, SelfSendException, UnsupportedDataMessageException, org.whispersystems.libsignal.UntrustedIdentityException {
var cipher = new SignalServiceCipher(account.getSelfAddress(), var cipher = new SignalServiceCipher(account.getSelfAddress(),
account.getSignalProtocolStore(), account.getSignalProtocolStore(),
@ -1812,6 +1834,11 @@ public class Manager implements Closeable {
exception = e; exception = e;
} }
var actions = handleMessage(envelope, content, ignoreAttachments); var actions = handleMessage(envelope, content, ignoreAttachments);
if (exception instanceof ProtocolInvalidMessageException) {
final var sender = resolveRecipient(((ProtocolInvalidMessageException) exception).getSender());
logger.debug("Received invalid message, queuing renew session action.");
actions.add(new RenewSessionAction(sender));
}
if (hasCaughtUpWithOldMessages) { if (hasCaughtUpWithOldMessages) {
for (var action : actions) { for (var action : actions) {
try { try {

View file

@ -84,7 +84,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler {
} }
} }
if (content == null) { if (content == null) {
writer.println("Failed to decrypt message."); writer.println("No message content");
} else { } else {
writer.println("Sender: {} (device: {})", writer.println("Sender: {} (device: {})",
formatContact(content.getSender()), formatContact(content.getSender()),