Bump libsignal to v0.96.2

Co-authored-by: Cody Henthorne <cody@signal.org>
This commit is contained in:
andrew-signal
2026-06-23 11:45:52 -04:00
committed by jeffrey-signal
parent 7fdaf6f706
commit 9dac02fa1c
30 changed files with 200 additions and 141 deletions
@@ -4,6 +4,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.thoughtcrime.securesms.crypto.SealedSenderAccessUtil;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.RecipientTable.RegisteredState;
@@ -144,6 +145,8 @@ public class AutomaticSessionResetJob extends BaseJob {
messageSender.sendNullMessage(address, SealedSenderAccessUtil.getSealedSenderAccessFor(recipient));
} catch (UntrustedIdentityException e) {
Log.w(TAG, "Unable to send null message.");
} catch (NoSessionException e) {
Log.w(TAG, "Unable to send null message; no session to send over.", e);
}
}
@@ -4,8 +4,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.thoughtcrime.securesms.database.GroupTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.model.RecipientRecord;
@@ -169,7 +169,7 @@ public class GroupCallUpdateSendJob extends BaseJob {
}
private @NonNull List<Recipient> deliver(@NonNull GroupId groupId, @NonNull List<Recipient> destinations)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
SignalServiceDataMessage.Builder dataMessageBuilder = SignalServiceDataMessage.newBuilder()
.withTimestamp(System.currentTimeMillis())
@@ -5,6 +5,7 @@ import androidx.annotation.WorkerThread
import okio.utf8Size
import org.signal.core.util.UuidUtil.parseOrThrow
import org.signal.core.util.logging.Log
import org.signal.libsignal.protocol.NoSessionException
import org.thoughtcrime.securesms.crypto.SealedSenderAccessUtil
import org.thoughtcrime.securesms.database.NoSuchMessageException
import org.thoughtcrime.securesms.database.RecipientTable.SealedSenderAccessMode
@@ -163,7 +164,17 @@ class IndividualSendJob private constructor(parameters: Parameters, private val
val profileKey = recipient.profileKey
val accessMode = recipient.sealedSenderAccessMode
val unidentified = deliver(message, originalEditedMessage)
val unidentified = try {
deliver(message, originalEditedMessage)
} catch (e: NoSessionException) {
warn(TAG, message.sentTimeMillis.toString(), "Failed to send message, likely due to a missing or corrupt session. Archiving sessions and retrying.", e)
val recipientId = message.threadRecipient.id
AppDependencies.protocolStore.aci().sessions().archiveSessions(recipientId)
AppDependencies.protocolStore.pni().sessions().archiveSessions(recipientId)
throw RetryLaterException()
}
SignalDatabase.messages.markAsSent(messageId)
markAttachmentsUploaded(messageId, message)
@@ -5,6 +5,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.signal.network.exceptions.PushNetworkException;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.JsonJobData;
@@ -13,12 +15,10 @@ import org.thoughtcrime.securesms.jobmanager.impl.SealedSenderConstraint;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.net.NotPushRegisteredException;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.multidevice.ConfigurationMessage;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.signal.network.exceptions.PushNetworkException;
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
import java.io.IOException;
@@ -88,7 +88,7 @@ public class MultiDeviceConfigurationUpdateJob extends BaseJob {
}
@Override
public void onRun() throws IOException, UntrustedIdentityException {
public void onRun() throws IOException, UntrustedIdentityException, NoSessionException {
if (!Recipient.self().isRegistered()) {
throw new NotPushRegisteredException();
}
@@ -14,6 +14,9 @@ import org.signal.core.ui.permissions.Permissions;
import org.signal.core.util.AppForegroundObserver;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.IdentityKey;
import org.signal.libsignal.protocol.NoSessionException;
import org.signal.network.exceptions.PushNetworkException;
import org.signal.network.service.CdnService;
import org.signal.network.exceptions.PushNetworkException;
import org.signal.network.service.CdnService;
import org.thoughtcrime.securesms.database.RecipientTable;
@@ -118,7 +121,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
@Override
public void onRun()
throws IOException, UntrustedIdentityException, NetworkException
throws IOException, UntrustedIdentityException, NetworkException, NoSessionException
{
if (!Recipient.self().isRegistered()) {
throw new NotPushRegisteredException();
@@ -139,7 +142,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
}
private void generateSingleContactUpdate(@NonNull RecipientId recipientId)
throws IOException, UntrustedIdentityException, NetworkException
throws IOException, UntrustedIdentityException, NetworkException, NoSessionException
{
WriteDetails writeDetails = createTempFile();
@@ -190,7 +193,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
}
private void generateFullContactUpdate()
throws IOException, UntrustedIdentityException, NetworkException
throws IOException, UntrustedIdentityException, NetworkException, NoSessionException
{
boolean isAppVisible = AppForegroundObserver.isForegrounded();
long timeSinceLastSync = System.currentTimeMillis() - TextSecurePreferences.getLastFullContactSyncTime(context);
@@ -277,7 +280,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
}
private void sendUpdate(SignalServiceMessageSender messageSender, InputStream stream, long length, boolean complete)
throws UntrustedIdentityException, NetworkException
throws UntrustedIdentityException, NetworkException, NoSessionException
{
if (length > 0) {
try {
@@ -5,6 +5,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.signal.network.exceptions.PushNetworkException;
import org.thoughtcrime.securesms.database.RecipientTable.RegisteredState;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.model.RecipientRecord;
@@ -17,12 +19,10 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.net.NotPushRegisteredException;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.multidevice.MessageRequestResponseMessage;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.signal.network.exceptions.PushNetworkException;
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
import java.io.IOException;
@@ -97,7 +97,7 @@ public class MultiDeviceMessageRequestResponseJob extends BaseJob {
}
@Override
public void onRun() throws IOException, UntrustedIdentityException {
public void onRun() throws IOException, UntrustedIdentityException, NoSessionException {
if (!Recipient.self().isRegistered()) {
throw new NotPushRegisteredException();
}
@@ -5,9 +5,9 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.signal.libsignal.protocol.NoSessionException;
import org.signal.network.exceptions.PushNetworkException;
import org.signal.network.service.CdnService;
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
@@ -18,15 +18,14 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream;
import org.whispersystems.signalservice.api.messages.multidevice.ContactsMessage;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsOutputStream;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.signal.network.exceptions.PushNetworkException;
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream;
import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec;
import java.io.ByteArrayInputStream;
@@ -66,7 +65,7 @@ public class MultiDeviceProfileKeyUpdateJob extends BaseJob {
}
@Override
public void onRun() throws IOException, UntrustedIdentityException {
public void onRun() throws IOException, UntrustedIdentityException, NoSessionException {
if (!Recipient.self().isRegistered()) {
throw new NotPushRegisteredException();
}
@@ -3,12 +3,14 @@ package org.thoughtcrime.securesms.jobs;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.signal.core.models.ServiceId;
import org.signal.core.util.JsonUtils;
import org.signal.core.util.ListUtil;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.signal.network.exceptions.PushNetworkException;
import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
import org.thoughtcrime.securesms.database.RecipientTable.RegisteredState;
import org.thoughtcrime.securesms.database.SignalDatabase;
@@ -23,13 +25,10 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.net.NotPushRegisteredException;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.signal.core.util.JsonUtils;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.multidevice.ReadMessage;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.signal.core.models.ServiceId;
import org.signal.network.exceptions.PushNetworkException;
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
import java.io.IOException;
@@ -37,6 +36,8 @@ import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class MultiDeviceReadUpdateJob extends BaseJob {
@@ -106,7 +107,7 @@ public class MultiDeviceReadUpdateJob extends BaseJob {
}
@Override
public void onRun() throws IOException, UntrustedIdentityException {
public void onRun() throws IOException, UntrustedIdentityException, NoSessionException {
if (!Recipient.self().isRegistered()) {
throw new NotPushRegisteredException();
}
@@ -8,6 +8,8 @@ import org.signal.core.util.Base64;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.IdentityKey;
import org.signal.libsignal.protocol.InvalidKeyException;
import org.signal.libsignal.protocol.NoSessionException;
import org.signal.network.exceptions.PushNetworkException;
import org.thoughtcrime.securesms.database.IdentityTable.VerifiedStatus;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
import org.thoughtcrime.securesms.jobmanager.Job;
@@ -19,13 +21,11 @@ import org.thoughtcrime.securesms.net.NotPushRegisteredException;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.signal.network.exceptions.PushNetworkException;
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
import java.io.IOException;
@@ -90,7 +90,7 @@ public class MultiDeviceVerifiedUpdateJob extends BaseJob {
}
@Override
public void onRun() throws IOException, UntrustedIdentityException {
public void onRun() throws IOException, UntrustedIdentityException, NoSessionException {
if (!Recipient.self().isRegistered()) {
throw new NotPushRegisteredException();
}
@@ -5,7 +5,10 @@ import androidx.annotation.Nullable;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.signal.core.util.JsonUtils;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.signal.network.exceptions.PushNetworkException;
import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
import org.thoughtcrime.securesms.database.RecipientTable.RegisteredState;
import org.thoughtcrime.securesms.database.SignalDatabase;
@@ -19,13 +22,10 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.net.NotPushRegisteredException;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.signal.core.util.JsonUtils;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.whispersystems.signalservice.api.messages.multidevice.ViewOnceOpenMessage;
import org.signal.network.exceptions.PushNetworkException;
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
import java.io.IOException;
@@ -76,7 +76,7 @@ public class MultiDeviceViewOnceOpenJob extends BaseJob {
}
@Override
public void onRun() throws IOException, UntrustedIdentityException {
public void onRun() throws IOException, UntrustedIdentityException, NoSessionException {
if (!Recipient.self().isRegistered()) {
throw new NotPushRegisteredException();
}
@@ -3,12 +3,13 @@ package org.thoughtcrime.securesms.jobs;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.signal.core.util.JsonUtils;
import org.signal.core.util.ListUtil;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.signal.network.exceptions.PushNetworkException;
import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
import org.thoughtcrime.securesms.database.RecipientTable.RegisteredState;
import org.thoughtcrime.securesms.database.SignalDatabase;
@@ -23,13 +24,10 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.net.NotPushRegisteredException;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.signal.core.util.JsonUtils;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.whispersystems.signalservice.api.messages.multidevice.ViewedMessage;
import org.signal.network.exceptions.PushNetworkException;
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
import java.io.IOException;
@@ -37,6 +35,8 @@ import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class MultiDeviceViewedUpdateJob extends BaseJob {
@@ -106,7 +106,7 @@ public class MultiDeviceViewedUpdateJob extends BaseJob {
}
@Override
public void onRun() throws IOException, UntrustedIdentityException {
public void onRun() throws IOException, UntrustedIdentityException, NoSessionException {
if (!Recipient.self().isRegistered()) {
throw new NotPushRegisteredException();
}
@@ -5,6 +5,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.thoughtcrime.securesms.database.GroupTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.model.RecipientRecord;
@@ -188,7 +189,7 @@ public class ProfileKeySendJob extends BaseJob {
}
private List<Recipient> deliver(@NonNull List<Recipient> destinations) throws IOException, UntrustedIdentityException {
private List<Recipient> deliver(@NonNull List<Recipient> destinations) throws IOException, UntrustedIdentityException, NoSessionException {
SignalServiceDataMessage.Builder dataMessage = SignalServiceDataMessage.newBuilder()
.asProfileKeyUpdate(true)
.withTimestamp(System.currentTimeMillis())
@@ -6,8 +6,9 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import org.signal.core.util.Util;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.database.GroupReceiptTable;
@@ -33,7 +34,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.stories.Stories;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
import org.signal.core.util.Util;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.SendMessageResult;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
@@ -189,7 +189,7 @@ public final class PushDistributionListSendJob extends PushSendJob {
PushGroupSendJob.processGroupMessageResults(context, messageId, -1, null, message, results, targets, skipped, existingNetworkFailures, existingIdentityMismatches);
} catch (UntrustedIdentityException | UndeliverableMessageException e) {
} catch (UntrustedIdentityException | UndeliverableMessageException | NoSessionException e) {
warn(TAG, String.valueOf(message.getSentTimeMillis()), e);
database.markAsSentFailed(messageId);
notifyMediaMessageDeliveryFailed(context, messageId);
@@ -202,7 +202,7 @@ public final class PushDistributionListSendJob extends PushSendJob {
}
private List<SendMessageResult> deliver(@NonNull OutgoingMessage message, @NonNull List<Recipient> destinations)
throws IOException, UntrustedIdentityException, UndeliverableMessageException
throws IOException, UntrustedIdentityException, UndeliverableMessageException, NoSessionException
{
try {
List<Attachment> attachments = message.getAttachments().stream().filter(attachment -> !attachment.isSticker()).collect(Collectors.toList());
@@ -6,10 +6,11 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import java.util.stream.Collectors;
import org.signal.core.util.ByteUnit;
import org.signal.core.util.SetUtil;
import org.signal.core.util.Util;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.database.GroupReceiptTable;
import org.thoughtcrime.securesms.database.GroupReceiptTable.GroupReceiptInfo;
@@ -44,12 +45,10 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
import org.signal.core.util.ByteUnit;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.util.MessageUtil;
import org.thoughtcrime.securesms.util.RecipientAccessList;
import org.thoughtcrime.securesms.util.SignalLocalMetrics;
import org.signal.core.util.Util;
import org.whispersystems.signalservice.api.crypto.ContentHint;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.SendMessageResult;
@@ -74,9 +73,9 @@ import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import kotlin.Pair;
import okio.ByteString;
import okio.Utf8;
@@ -250,7 +249,7 @@ public final class PushGroupSendJob extends PushSendJob {
ConversationShortcutRankingUpdateJob.enqueueForOutgoingIfNecessary(groupRecipient);
Log.i(TAG, JobLogger.format(this, "Finished send."));
} catch (UntrustedIdentityException | UndeliverableMessageException e) {
} catch (UntrustedIdentityException | UndeliverableMessageException | NoSessionException e) {
warn(TAG, String.valueOf(message.getSentTimeMillis()), e);
database.markAsSentFailed(messageId);
notifyMediaMessageDeliveryFailed(context, messageId);
@@ -271,7 +270,7 @@ public final class PushGroupSendJob extends PushSendJob {
}
private List<SendMessageResult> deliver(OutgoingMessage message, @Nullable MessageRecord originalEditedMessage, @NonNull Recipient groupRecipient, @NonNull List<Recipient> destinations)
throws IOException, UntrustedIdentityException, UndeliverableMessageException
throws IOException, UntrustedIdentityException, UndeliverableMessageException, NoSessionException
{
if (Utf8.size(message.getBody()) > MessageUtil.MAX_INLINE_BODY_SIZE_BYTES) {
throw new UndeliverableMessageException("The total body size was greater than our limit of " + MessageUtil.MAX_INLINE_BODY_SIZE_BYTES + " bytes.");
@@ -10,6 +10,7 @@ import org.signal.core.models.ServiceId;
import org.signal.core.models.ServiceId.ACI;
import org.signal.core.util.Base64;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
import org.thoughtcrime.securesms.database.RecipientTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
@@ -178,7 +179,7 @@ public final class PushGroupSilentUpdateSendJob extends BaseJob {
}
private @NonNull List<Recipient> deliver(@NonNull List<Recipient> destinations, @NonNull GroupId.V2 groupId)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
SignalServiceGroupV2 group = SignalServiceGroupV2.fromProtobuf(groupContextV2);
SignalServiceDataMessage groupDataMessage = SignalServiceDataMessage.newBuilder()
@@ -7,6 +7,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.thoughtcrime.securesms.database.GroupTable;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.ReactionTable;
@@ -229,7 +230,7 @@ public class ReactionSendJob extends BaseJob {
}
private @NonNull List<Recipient> deliver(@NonNull RecipientRecord conversationRecipient, @NonNull List<Recipient> destinations, @NonNull Recipient targetAuthor, long targetSentTimestamp)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
SignalServiceDataMessage.Builder dataMessageBuilder = SignalServiceDataMessage.newBuilder()
.withTimestamp(System.currentTimeMillis())
@@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.jobs
import org.signal.core.util.logging.Log
import org.signal.libsignal.protocol.NoSessionException
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.recipients.RecipientId
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException
@@ -23,15 +24,15 @@ object ReceiptSender {
fun sendWithSessionRepair(recipientId: RecipientId, operation: ReceiptSendOperation): SendMessageResult? {
return try {
operation.send()
} catch (e: IllegalStateException) {
Log.w(TAG, "Failed to send receipt, likely due to a missing or corrupt session. Archiving sessions and retrying.", e)
} catch (e: NoSessionException) {
Log.w(TAG, "Failed to send receipt due to a missing session. Archiving sessions and retrying.", e)
AppDependencies.protocolStore.aci().sessions().archiveSessions(recipientId)
AppDependencies.protocolStore.pni().sessions().archiveSessions(recipientId)
try {
operation.send()
} catch (retryError: IllegalStateException) {
} catch (retryError: NoSessionException) {
Log.w(TAG, "Failed to send receipt even after archiving sessions. Dropping.", retryError)
null
}
@@ -39,7 +40,7 @@ object ReceiptSender {
}
fun interface ReceiptSendOperation {
@Throws(IOException::class, UntrustedIdentityException::class)
@Throws(IOException::class, UntrustedIdentityException::class, NoSessionException::class)
fun send(): SendMessageResult
}
}
@@ -7,6 +7,7 @@ import androidx.annotation.WorkerThread;
import org.signal.core.util.SetUtil;
import org.signal.core.util.Util;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.thoughtcrime.securesms.database.GroupTable;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
@@ -228,7 +229,7 @@ public class RemoteDeleteSendJob extends BaseJob {
long targetSentTimestamp,
boolean isForStory,
@Nullable DistributionListId distributionListId)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
SignalServiceDataMessage.Builder dataMessageBuilder = SignalServiceDataMessage.newBuilder()
.withTimestamp(System.currentTimeMillis())
@@ -5,6 +5,7 @@ import androidx.annotation.Nullable;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.signal.libsignal.protocol.SignalProtocolAddress;
import org.signal.libsignal.protocol.message.SenderKeyDistributionMessage;
import org.thoughtcrime.securesms.crypto.SealedSenderAccessUtil;
@@ -187,8 +188,8 @@ public class ResendMessageJob extends BaseJob {
try {
result = messageSender.resendContent(address, access, sentTimestamp, contentToSend, contentHint, Optional.ofNullable(groupId).map(GroupId::getDecodedId), urgent);
} catch (IllegalStateException e) {
Log.w(TAG, "Failed to resend content. Archiving session and trying again.", e);
} catch (NoSessionException e) {
Log.w(TAG, "Failed to resend content due to a missing session. Archiving session and trying again.", e);
AppDependencies.getProtocolStore().aci().sessions().archiveSessions(recipientId, SignalServiceAddress.DEFAULT_DEVICE_ID);
AppDependencies.getProtocolStore().aci().sessions().archiveSiblingSessions(recipient.getServiceId().toProtocolAddress(SignalServiceAddress.DEFAULT_DEVICE_ID));
AppDependencies.getProtocolStore().pni().sessions().archiveSessions(recipientId, SignalServiceAddress.DEFAULT_DEVICE_ID);
@@ -6,6 +6,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import org.signal.core.models.ServiceId;
import org.signal.core.util.Util;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.metadata.certificate.SenderCertificate;
import org.signal.libsignal.protocol.InvalidKeyException;
@@ -14,6 +16,7 @@ import org.signal.libsignal.protocol.NoSessionException;
import org.signal.libsignal.zkgroup.groups.GroupSecretParams;
import org.signal.libsignal.zkgroup.groupsend.GroupSendEndorsement;
import org.signal.libsignal.zkgroup.groupsend.GroupSendFullToken;
import org.signal.network.util.Preconditions;
import org.thoughtcrime.securesms.crypto.SealedSenderAccessUtil;
import org.thoughtcrime.securesms.crypto.SenderKeyUtil;
import org.thoughtcrime.securesms.database.MessageSendLogTables;
@@ -34,7 +37,6 @@ import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.util.RecipientAccessList;
import org.thoughtcrime.securesms.util.RemoteConfig;
import org.thoughtcrime.securesms.util.SignalLocalMetrics;
import org.signal.core.util.Util;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.SignalServiceMessageSender.LegacyGroupEvents;
import org.whispersystems.signalservice.api.SignalServiceMessageSender.SenderKeyGroupEvents;
@@ -51,10 +53,8 @@ import org.whispersystems.signalservice.api.messages.SignalServiceStoryMessageRe
import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage;
import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage;
import org.whispersystems.signalservice.api.push.DistributionId;
import org.signal.core.models.ServiceId;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.NotFoundException;
import org.signal.network.util.Preconditions;
import org.whispersystems.signalservice.internal.push.exceptions.InvalidUnidentifiedAccessHeaderException;
import org.whispersystems.signalservice.internal.push.http.CancelationSignal;
import org.whispersystems.signalservice.internal.push.http.PartialSendBatchCompleteListener;
@@ -108,7 +108,7 @@ public final class GroupSendUtil {
boolean isForStory,
@Nullable SignalServiceEditMessage editMessage,
@Nullable CancelationSignal cancelationSignal)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
Preconditions.checkArgument(groupId == null || distributionListId == null, "Cannot supply both a groupId and a distributionListId!");
@@ -135,7 +135,7 @@ public final class GroupSendUtil {
@NonNull SignalServiceDataMessage message,
boolean urgent,
CancelationSignal cancelationSignal)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
return sendMessage(context, groupId, getDistributionId(groupId), null, allTargets, isRecipientUpdate, false, DataSendOperation.unresendable(message, contentHint, urgent), cancelationSignal);
}
@@ -152,7 +152,7 @@ public final class GroupSendUtil {
@NonNull List<Recipient> allTargets,
@NonNull SignalServiceTypingMessage message,
@Nullable CancelationSignal cancelationSignal)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
return sendMessage(context, groupId, getDistributionId(groupId), null, allTargets, false, false, new TypingSendOperation(message), cancelationSignal);
}
@@ -168,7 +168,7 @@ public final class GroupSendUtil {
@NonNull GroupId.V2 groupId,
@NonNull List<Recipient> allTargets,
@NonNull SignalServiceCallMessage message)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
return sendMessage(context, groupId, getDistributionId(groupId), null, allTargets, false, false, new CallSendOperation(message), null);
}
@@ -187,7 +187,7 @@ public final class GroupSendUtil {
long sentTimestamp,
@NonNull SignalServiceStoryMessage message,
@NonNull Set<SignalServiceStoryMessageRecipient> manifest)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
return sendMessage(
context,
@@ -214,7 +214,7 @@ public final class GroupSendUtil {
@NonNull MessageId messageId,
long sentTimestamp,
@NonNull SignalServiceStoryMessage message)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
return sendMessage(
context,
@@ -253,7 +253,7 @@ public final class GroupSendUtil {
boolean isStorySend,
@NonNull SendOperation sendOperation,
@Nullable CancelationSignal cancelationSignal)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
Log.i(TAG, "Starting group send. GroupId: " + (groupId != null ? groupId.toString() : "none") + ", DistributionId: " + (distributionId != null ? distributionId.toString() : "none") + " RelatedMessageId: " + (relatedMessageId != null ? relatedMessageId.toString() : "none") + ", Targets: " + allTargets.size() + ", RecipientUpdate: " + isRecipientUpdate + ", Operation: " + sendOperation.getClass().getSimpleName());
@@ -577,7 +577,7 @@ public final class GroupSendUtil {
boolean isRecipientUpdate,
@Nullable PartialSendCompleteListener partialListener,
@Nullable CancelationSignal cancelationSignal)
throws IOException, UntrustedIdentityException;
throws IOException, UntrustedIdentityException, NoSessionException;
@NonNull ContentHint getContentHint();
long getSentTimestamp();
@@ -639,7 +639,7 @@ public final class GroupSendUtil {
boolean isRecipientUpdate,
@Nullable PartialSendCompleteListener partialListener,
@Nullable CancelationSignal cancelationSignal)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
// PniSignatures are only needed for 1:1 messages, but some message jobs use the GroupSendUtil methods to send 1:1
if (targets.size() == 1 && relatedMessageId == null) {
@@ -877,7 +877,7 @@ public final class GroupSendUtil {
boolean isRecipientUpdate,
@Nullable PartialSendCompleteListener partialListener,
@Nullable CancelationSignal cancelationSignal)
throws IOException, UntrustedIdentityException
throws IOException, UntrustedIdentityException, NoSessionException
{
// We only allow legacy sends if you're sending to an empty group and just need to send a sync message.
if (targets.isEmpty()) {
@@ -13,16 +13,19 @@ import androidx.annotation.Nullable;
import org.greenrobot.eventbus.EventBus;
import org.signal.core.models.ServiceId.ACI;
import org.signal.core.util.AppForegroundObserver;
import org.signal.core.util.Util;
import org.signal.core.util.concurrent.KeyedSerialMonoLifoExecutor;
import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.NoSessionException;
import org.signal.libsignal.zkgroup.GenericServerPublicParams;
import org.signal.libsignal.zkgroup.InvalidInputException;
import org.signal.libsignal.zkgroup.VerificationFailedException;
import org.signal.libsignal.zkgroup.calllinks.CallLinkAuthCredentialPresentation;
import org.signal.libsignal.zkgroup.calllinks.CallLinkSecretParams;
import org.signal.libsignal.zkgroup.groups.GroupIdentifier;
import org.signal.network.NetworkResult;
import org.signal.ringrtc.CallException;
import org.signal.ringrtc.CallId;
import org.signal.ringrtc.CallLinkRootKey;
@@ -68,7 +71,6 @@ import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId;
import org.thoughtcrime.securesms.service.webrtc.links.SignalCallLinkManager;
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcEphemeralState;
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
import org.signal.core.util.AppForegroundObserver;
import org.thoughtcrime.securesms.util.RecipientAccessList;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.rx.RxStore;
@@ -76,7 +78,6 @@ import org.thoughtcrime.securesms.webrtc.CallNotificationBuilder;
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
import org.webrtc.PeerConnection;
import org.signal.network.NetworkResult;
import org.whispersystems.signalservice.api.NetworkResultUtil;
import org.whispersystems.signalservice.api.crypto.SealedSenderAccess;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
@@ -902,6 +903,10 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
} catch (IOException e) {
Log.i(TAG, "onSendCallMessage onFailure: ", e);
process((s, p) -> p.handleGroupMessageSentError(s, Collections.singletonList(recipient.getId()), NETWORK_FAILURE));
} catch (NoSessionException e) {
Log.w(TAG, "onSendCallMessage onFailure: missing or corrupt session. Archiving sessions so the next send rebuilds.", e);
archiveSessions(recipient.getId());
process((s, p) -> p.handleGroupMessageSentError(s, Collections.singletonList(recipient.getId()), NETWORK_FAILURE));
}
});
}
@@ -947,7 +952,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
RetrieveProfileJob.enqueue(identifyFailureRecipientIds, true);
}
} catch (UntrustedIdentityException | IOException | InvalidInputException e) {
} catch (UntrustedIdentityException | IOException | InvalidInputException | NoSessionException e) {
Log.w(TAG, "onSendCallMessageToGroup failed", e);
}
});
@@ -1323,10 +1328,23 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
remotePeer.getCallId(),
e instanceof UnregisteredUserException ? NO_SUCH_USER : NETWORK_FAILURE,
Optional.empty()));
} catch (NoSessionException e) {
Log.w(TAG, "sendCallMessage: missing or corrupt session. Archiving sessions so the next send rebuilds.", e);
archiveSessions(recipient.getId());
processSendMessageFailureWithChangeDetection(remotePeer,
(s, p) -> p.handleMessageSentError(s,
remotePeer.getCallId(),
NETWORK_FAILURE,
Optional.empty()));
}
});
}
private void archiveSessions(@NonNull RecipientId recipientId) {
AppDependencies.getProtocolStore().aci().sessions().archiveSessions(recipientId);
AppDependencies.getProtocolStore().pni().sessions().archiveSessions(recipientId);
}
public void sendAcceptedCallEventSyncMessage(@NonNull RemotePeer remotePeer, boolean isOutgoing, boolean isVideoCall) {
SignalDatabase
.calls()
@@ -1337,7 +1355,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
try {
SyncMessage.CallEvent callEvent = CallEventSyncMessageUtil.createAcceptedSyncMessage(remotePeer, System.currentTimeMillis(), isOutgoing, isVideoCall);
AppDependencies.getSignalServiceMessageSender().sendSyncMessage(SignalServiceSyncMessage.forCallEvent(callEvent));
} catch (IOException | UntrustedIdentityException e) {
} catch (IOException | UntrustedIdentityException | NoSessionException e) {
Log.w(TAG, "Unable to send call event sync message for " + remotePeer.getCallId().longValue(), e);
}
});
@@ -1354,7 +1372,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
try {
SyncMessage.CallEvent callEvent = CallEventSyncMessageUtil.createNotAcceptedSyncMessage(remotePeer, System.currentTimeMillis(), isOutgoing, isVideoCall);
AppDependencies.getSignalServiceMessageSender().sendSyncMessage(SignalServiceSyncMessage.forCallEvent(callEvent));
} catch (IOException | UntrustedIdentityException e) {
} catch (IOException | UntrustedIdentityException | NoSessionException e) {
Log.w(TAG, "Unable to send call event sync message for " + remotePeer.getCallId().longValue(), e);
}
});
@@ -1367,7 +1385,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
try {
SyncMessage.CallEvent callEvent = CallEventSyncMessageUtil.createNotAcceptedSyncMessage(remotePeer, System.currentTimeMillis(), isOutgoing, true);
AppDependencies.getSignalServiceMessageSender().sendSyncMessage(SignalServiceSyncMessage.forCallEvent(callEvent));
} catch (IOException | UntrustedIdentityException e) {
} catch (IOException | UntrustedIdentityException | NoSessionException e) {
Log.w(TAG, "Unable to send call event sync message for " + remotePeer.getCallId().longValue(), e);
}
});