mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-05-03 23:15:44 +01:00
Skip sends to users with prekey failures.
This commit is contained in:
committed by
Cody Henthorne
parent
6b91e525db
commit
3e21fb77c7
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.signalservice.api
|
||||
|
||||
import org.signal.libsignal.protocol.InvalidKeyException
|
||||
import org.signal.libsignal.protocol.SignalProtocolAddress
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Wraps an [InvalidKeyException] in an [IOException] with a nicer message.
|
||||
*/
|
||||
class InvalidPreKeyException(
|
||||
address: SignalProtocolAddress,
|
||||
invalidKeyException: InvalidKeyException
|
||||
) : IOException("Invalid prekey for $address", invalidKeyException)
|
||||
@@ -1849,24 +1849,28 @@ public class SignalServiceMessageSender {
|
||||
results.add(futureResult.get());
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof UntrustedIdentityException) {
|
||||
Log.w(TAG, e);
|
||||
Log.w(TAG, "[" + timestamp + "] Hit identity mismatch: " + recipient.getIdentifier(), e);
|
||||
results.add(SendMessageResult.identityFailure(recipient, ((UntrustedIdentityException) e.getCause()).getIdentityKey()));
|
||||
} else if (e.getCause() instanceof UnregisteredUserException) {
|
||||
Log.w(TAG, "[" + timestamp + "] Found unregistered user.");
|
||||
Log.w(TAG, "[" + timestamp + "] Hit unregistered user: " + recipient.getIdentifier());
|
||||
results.add(SendMessageResult.unregisteredFailure(recipient));
|
||||
} else if (e.getCause() instanceof PushNetworkException) {
|
||||
Log.w(TAG, e);
|
||||
Log.w(TAG, "[" + timestamp + "] Hit network failure: " + recipient.getIdentifier(), e);
|
||||
results.add(SendMessageResult.networkFailure(recipient));
|
||||
} else if (e.getCause() instanceof ServerRejectedException) {
|
||||
Log.w(TAG, e);
|
||||
Log.w(TAG, "[" + timestamp + "] Hit server rejection: " + recipient.getIdentifier(), e);
|
||||
throw ((ServerRejectedException) e.getCause());
|
||||
} else if (e.getCause() instanceof ProofRequiredException) {
|
||||
Log.w(TAG, e);
|
||||
Log.w(TAG, "[" + timestamp + "] Hit proof required: " + recipient.getIdentifier(), e);
|
||||
results.add(SendMessageResult.proofRequiredFailure(recipient, (ProofRequiredException) e.getCause()));
|
||||
} else if (e.getCause() instanceof RateLimitException) {
|
||||
Log.w(TAG, e);
|
||||
Log.w(TAG, "[" + timestamp + "] Hit rate limit: " + recipient.getIdentifier(), e);
|
||||
results.add(SendMessageResult.rateLimitFailure(recipient, (RateLimitException) e.getCause()));
|
||||
} else if (e.getCause() instanceof InvalidPreKeyException) {
|
||||
Log.w(TAG, "[" + timestamp + "] Hit invalid prekey: " + recipient.getIdentifier(), e);
|
||||
results.add(SendMessageResult.invalidPreKeyFailure(recipient));
|
||||
} else {
|
||||
Log.w(TAG, "[" + timestamp + "] Hit unknown exception: " + recipient.getIdentifier(), e);
|
||||
throw new IOException(e);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
@@ -2317,10 +2321,10 @@ public class SignalServiceMessageSender {
|
||||
|
||||
// Visible for testing only
|
||||
public OutgoingPushMessage getEncryptedMessage(SignalServiceAddress recipient,
|
||||
Optional<UnidentifiedAccess> unidentifiedAccess,
|
||||
int deviceId,
|
||||
EnvelopeContent plaintext,
|
||||
boolean story)
|
||||
Optional<UnidentifiedAccess> unidentifiedAccess,
|
||||
int deviceId,
|
||||
EnvelopeContent plaintext,
|
||||
boolean story)
|
||||
throws IOException, InvalidKeyException, UntrustedIdentityException
|
||||
{
|
||||
SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(recipient.getIdentifier(), deviceId);
|
||||
@@ -2331,6 +2335,8 @@ public class SignalServiceMessageSender {
|
||||
List<PreKeyBundle> preKeys = getPreKeys(recipient, unidentifiedAccess, deviceId, story);
|
||||
|
||||
for (PreKeyBundle preKey : preKeys) {
|
||||
Log.d(TAG, "Initializing prekey session for " + signalProtocolAddress);
|
||||
|
||||
try {
|
||||
SignalProtocolAddress preKeyAddress = new SignalProtocolAddress(recipient.getIdentifier(), preKey.getDeviceId());
|
||||
SignalSessionBuilder sessionBuilder = new SignalSessionBuilder(sessionLock, new SessionBuilder(aciStore, preKeyAddress));
|
||||
@@ -2344,7 +2350,7 @@ public class SignalServiceMessageSender {
|
||||
eventListener.get().onSecurityEvent(recipient);
|
||||
}
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new IOException(e);
|
||||
throw new InvalidPreKeyException(signalProtocolAddress, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,29 +19,34 @@ public class SendMessageResult {
|
||||
private final IdentityFailure identityFailure;
|
||||
private final ProofRequiredException proofRequiredFailure;
|
||||
private final RateLimitException rateLimitFailure;
|
||||
private final boolean invalidPreKeyFailure;
|
||||
|
||||
public static SendMessageResult success(SignalServiceAddress address, List<Integer> devices, boolean unidentified, boolean needsSync, long duration, Optional<Content> content) {
|
||||
return new SendMessageResult(address, new Success(unidentified, needsSync, duration, content, devices), false, false, null, null, null);
|
||||
return new SendMessageResult(address, new Success(unidentified, needsSync, duration, content, devices), false, false, null, null, null, false);
|
||||
}
|
||||
|
||||
public static SendMessageResult networkFailure(SignalServiceAddress address) {
|
||||
return new SendMessageResult(address, null, true, false, null, null, null);
|
||||
return new SendMessageResult(address, null, true, false, null, null, null, false);
|
||||
}
|
||||
|
||||
public static SendMessageResult unregisteredFailure(SignalServiceAddress address) {
|
||||
return new SendMessageResult(address, null, false, true, null, null, null);
|
||||
return new SendMessageResult(address, null, false, true, null, null, null, false);
|
||||
}
|
||||
|
||||
public static SendMessageResult identityFailure(SignalServiceAddress address, IdentityKey identityKey) {
|
||||
return new SendMessageResult(address, null, false, false, new IdentityFailure(identityKey), null, null);
|
||||
return new SendMessageResult(address, null, false, false, new IdentityFailure(identityKey), null, null, false);
|
||||
}
|
||||
|
||||
public static SendMessageResult proofRequiredFailure(SignalServiceAddress address, ProofRequiredException proofRequiredException) {
|
||||
return new SendMessageResult(address, null, false, false, null, proofRequiredException, null);
|
||||
return new SendMessageResult(address, null, false, false, null, proofRequiredException, null, false);
|
||||
}
|
||||
|
||||
public static SendMessageResult rateLimitFailure(SignalServiceAddress address, RateLimitException rateLimitException) {
|
||||
return new SendMessageResult(address, null, false, false, null, null, rateLimitException);
|
||||
return new SendMessageResult(address, null, false, false, null, null, rateLimitException, false);
|
||||
}
|
||||
|
||||
public static SendMessageResult invalidPreKeyFailure(SignalServiceAddress address) {
|
||||
return new SendMessageResult(address, null, false, false, null, null, null, true);
|
||||
}
|
||||
|
||||
public SignalServiceAddress getAddress() {
|
||||
@@ -76,13 +81,18 @@ public class SendMessageResult {
|
||||
return rateLimitFailure;
|
||||
}
|
||||
|
||||
public boolean isInvalidPreKeyFailure() {
|
||||
return invalidPreKeyFailure;
|
||||
}
|
||||
|
||||
private SendMessageResult(SignalServiceAddress address,
|
||||
Success success,
|
||||
boolean networkFailure,
|
||||
boolean unregisteredFailure,
|
||||
IdentityFailure identityFailure,
|
||||
ProofRequiredException proofRequiredFailure,
|
||||
RateLimitException rateLimitFailure)
|
||||
RateLimitException rateLimitFailure,
|
||||
boolean invalidPreKeyFailure)
|
||||
{
|
||||
this.address = address;
|
||||
this.success = success;
|
||||
@@ -91,6 +101,7 @@ public class SendMessageResult {
|
||||
this.identityFailure = identityFailure;
|
||||
this.proofRequiredFailure = proofRequiredFailure;
|
||||
this.rateLimitFailure = rateLimitFailure;
|
||||
this.invalidPreKeyFailure = invalidPreKeyFailure;
|
||||
}
|
||||
|
||||
public static class Success {
|
||||
|
||||
Reference in New Issue
Block a user