Do not allow remote backups while unregistered.

This commit is contained in:
Greyson Parrelli
2026-09-09 16:37:44 -04:00
committed by Cody Henthorne
parent bd3c4af8e4
commit c4f9b0e416
6 changed files with 32 additions and 2 deletions
@@ -163,7 +163,7 @@ object ArchiveUploadProgress {
AppDependencies.jobManager.cancelAllInQueue(ArchiveCommitAttachmentDeletesJob.ARCHIVE_ATTACHMENT_QUEUE)
AppDependencies.jobManager.cancelAllInQueues(UploadAttachmentToArchiveJob.QUEUES)
AppDependencies.jobManager.cancelAllInQueue(ArchiveThumbnailUploadJob.KEY)
AppDependencies.jobManager.cancelAllInQueues(ArchiveThumbnailUploadJob.QUEUES)
}
@WorkerThread
@@ -238,6 +238,16 @@ object BackupRepository {
SignalStore.backup.backupSecretRestoreRequired = false
}
@JvmStatic
fun haltBackupWritesForDeregistration() {
Log.w(TAG, "Deregistered. Canceling backup upload jobs and clearing cached archive credentials.", true)
ArchiveUploadProgress.cancel()
SignalStore.backup.messageCredentials.clearAll()
SignalStore.backup.mediaCredentials.clearAll()
}
fun resetInitializedStateAndAuthCredentials() {
SignalStore.backup.messageBackupInitialized = false
SignalStore.backup.mediaBackupInitialized = false
@@ -56,6 +56,7 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.storage.StorageSyncHelper
import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.RemoteConfig
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.api.messages.AttachmentTransferProgress
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment
import org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException
@@ -88,8 +89,17 @@ class BackupMessagesJob private constructor(
const val KEY = "BackupMessagesJob"
private fun isRegistered(): Boolean {
return SignalStore.account.isRegistered && !TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application)
}
private fun isBackupAllowed(): Boolean {
return when {
!isRegistered() -> {
Log.w(TAG, "Backup not allowed: not registered.", true)
false
}
SignalStore.registration.restoreDecisionState.isDecisionPending -> {
Log.i(TAG, "Backup not allowed: a restore decision is pending.", true)
false
@@ -217,6 +227,12 @@ class BackupMessagesJob private constructor(
// We're building a new file, so whatever the previous attempt left behind is dead, including any SVRB state we may advance past below.
clearPendingBackupFile()
if (!isRegistered()) {
Log.w(TAG, "Deregistered before storing to SVRB. Aborting.", true)
backupErrorHandled = true
return Result.failure()
}
val auth = when (val result = AppDependencies.archiveService.getSvrBAuth()) {
is Either.Right -> result.value
is Either.Left -> when (val error = result.value) {
@@ -18,6 +18,7 @@ import org.signal.libsignal.protocol.IdentityKey
import org.signal.libsignal.protocol.IdentityKeyPair
import org.signal.libsignal.protocol.ecc.ECPrivateKey
import org.signal.libsignal.protocol.util.Medium
import org.thoughtcrime.securesms.backup.v2.BackupRepository
import org.thoughtcrime.securesms.crypto.MasterCipher
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil
import org.thoughtcrime.securesms.crypto.storage.PreKeyMetadataStore
@@ -499,6 +500,7 @@ class AccountValues internal constructor(store: KeyValueStore, context: Context)
if (previous && !registered) {
clearLocalCredentials()
BackupRepository.haltBackupWritesForDeregistration()
}
if ((previous && !registered) || isAciChanged) {
@@ -24,6 +24,7 @@ import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.backup.proto.SharedPreference;
import org.thoughtcrime.securesms.backup.v2.BackupRepository;
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
@@ -385,6 +386,7 @@ public class TextSecurePreferences {
if (value) {
notifyUnregisteredReceived(context);
clearLocalCredentials(context);
BackupRepository.haltBackupWritesForDeregistration();
}
}
}
@@ -160,7 +160,7 @@ class ArchiveUploadProgressTest {
verify { BackupMessagesJob.cancel() }
verify { AppDependencies.jobManager.cancelAllInQueue(ArchiveCommitAttachmentDeletesJob.ARCHIVE_ATTACHMENT_QUEUE) }
verify { AppDependencies.jobManager.cancelAllInQueues(UploadAttachmentToArchiveJob.QUEUES) }
verify { AppDependencies.jobManager.cancelAllInQueue(ArchiveThumbnailUploadJob.KEY) }
verify { AppDependencies.jobManager.cancelAllInQueues(ArchiveThumbnailUploadJob.QUEUES) }
}
@Test