diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java b/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java index 4714b568..5069749c 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java @@ -109,8 +109,8 @@ public final class IncomingMessageHandler { SignalServiceContent content = null; if (!envelope.isReceipt()) { account.getIdentityKeyStore().setRetryingDecryption(true); - final var destination = getDestination(envelope).serviceId(); try { + final var destination = getDestination(envelope).serviceId(); final var cipherResult = dependencies.getCipher(destination == null || destination.equals(account.getAci()) ? ServiceIdType.ACI : ServiceIdType.PNI) .decrypt(envelope.getProto(), envelope.getServerDeliveredTimestamp()); @@ -140,6 +140,9 @@ public final class IncomingMessageHandler { final Manager.ReceiveMessageHandler handler ) { final var actions = new ArrayList(); + if (envelope.isPreKeySignalMessage()) { + actions.add(RefreshPreKeysAction.create()); + } SignalServiceContent content = null; Exception exception = null; if (envelope.getSourceServiceId() != null) { @@ -148,8 +151,19 @@ public final class IncomingMessageHandler { account.getRecipientResolver().resolveRecipient(envelope.getSourceServiceId()); } if (!envelope.isReceipt()) { - final var destination = getDestination(envelope).serviceId(); try { + final var destination = getDestination(envelope).serviceId(); + + if (destination == account.getPni() && envelope.getSourceServiceId() == null) { + throw new InvalidMessageException( + "Got a sealed sender message to our PNI? Invalid message, ignoring."); + } + + if (envelope.getSourceServiceId() instanceof ServiceId.PNI + && envelope.getProto().type != Envelope.Type.SERVER_DELIVERY_RECEIPT) { + throw new InvalidMessageException("Got a message from a PNI that was not a SERVER_DELIVERY_RECEIPT."); + } + final var cipherResult = dependencies.getCipher(destination == null || destination.equals(account.getAci()) ? ServiceIdType.ACI : ServiceIdType.PNI) .decrypt(envelope.getProto(), envelope.getServerDeliveredTimestamp()); @@ -174,7 +188,13 @@ public final class IncomingMessageHandler { logger.debug("Received invalid message from blocked contact, ignoring."); } else { var serviceId = ServiceId.parseOrNull(e.getSender()); - if (serviceId != null) { + ServiceId destination; + try { + destination = getDestination(envelope).serviceId(); + } catch (InvalidMessageException ex) { + destination = null; + } + if (serviceId != null && destination != null) { final var isSelf = sender.equals(account.getSelfRecipientId()) && e.getSenderDevice() == account.getDeviceId(); logger.debug("Received invalid message, queuing renew session action."); @@ -312,7 +332,12 @@ public final class IncomingMessageHandler { final var sender = senderDeviceAddress.recipientId(); final var senderServiceId = senderDeviceAddress.serviceId(); final var senderDeviceId = senderDeviceAddress.deviceId(); - final var destination = getDestination(envelope); + final DeviceAddress destination; + try { + destination = getDestination(envelope); + } catch (InvalidMessageException e) { + throw new AssertionError(e); + } if (account.getPni().equals(destination.serviceId)) { account.getRecipientStore().markNeedsPniSignature(destination.recipientId, true); @@ -1066,10 +1091,13 @@ public final class IncomingMessageHandler { } } - private DeviceAddress getDestination(SignalServiceEnvelope envelope) { + private DeviceAddress getDestination(SignalServiceEnvelope envelope) throws InvalidMessageException { final var destination = envelope.getDestinationServiceId(); if (destination == null || destination.isUnknown()) { - return new DeviceAddress(account.getSelfRecipientId(), account.getAci(), account.getDeviceId()); + throw new InvalidMessageException("Missing destination"); + } + if (!account.getAci().equals(destination) && !account.getPni().equals(destination)) { + throw new InvalidMessageException("Message not intended for this account"); } return new DeviceAddress(account.getRecipientResolver().resolveRecipient(destination), destination,