Stop caching SVRB auth credentials
This commit is contained in:
parent
8f0c315ad7
commit
65f577efed
@ -107,39 +107,22 @@ extension BackupImportSource {
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> MessageBackupKey {
|
||||
switch self {
|
||||
case let .remote(key, noneSource):
|
||||
case let .remote(key, nonceSource):
|
||||
let forwardSecrecyToken: BackupForwardSecrecyToken?
|
||||
switch noneSource {
|
||||
switch nonceSource {
|
||||
case let .provisioningMessage(token):
|
||||
forwardSecrecyToken = token
|
||||
case let .svrB(metadataHeader, chatAuth):
|
||||
do {
|
||||
forwardSecrecyToken = try await self.fetchForwardSecrecyTokenFromSvr(
|
||||
key: key,
|
||||
metadataHeader: metadataHeader,
|
||||
chatAuth: chatAuth,
|
||||
forceRefreshSVRBAuthCredential: false,
|
||||
backupRequestManager: backupRequestManager,
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
nonceStore: nonceStore,
|
||||
logger: logger,
|
||||
)
|
||||
} catch SignalError.webSocketError {
|
||||
// This may represent an "expired auth" error from the SVRB
|
||||
// servers. Try again, force-refreshing credentials.
|
||||
forwardSecrecyToken = try await self.fetchForwardSecrecyTokenFromSvr(
|
||||
key: key,
|
||||
metadataHeader: metadataHeader,
|
||||
chatAuth: chatAuth,
|
||||
forceRefreshSVRBAuthCredential: true,
|
||||
backupRequestManager: backupRequestManager,
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
nonceStore: nonceStore,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
forwardSecrecyToken = try await self.fetchForwardSecrecyTokenFromSvr(
|
||||
key: key,
|
||||
metadataHeader: metadataHeader,
|
||||
chatAuth: chatAuth,
|
||||
backupRequestManager: backupRequestManager,
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
nonceStore: nonceStore,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
|
||||
return try MessageBackupKey(
|
||||
@ -161,29 +144,17 @@ extension BackupImportSource {
|
||||
key: MessageRootBackupKey,
|
||||
metadataHeader: BackupNonce.MetadataHeader,
|
||||
chatAuth: ChatServiceAuth,
|
||||
forceRefreshSVRBAuthCredential: Bool,
|
||||
backupRequestManager: BackupRequestManager,
|
||||
db: any DB,
|
||||
libsignalNet: LibSignalClient.Net,
|
||||
nonceStore: BackupNonceMetadataStore,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupForwardSecrecyToken {
|
||||
let svrBAuth: LibSignalClient.Auth
|
||||
do {
|
||||
svrBAuth = try await backupRequestManager.fetchSVRBAuthCredential(
|
||||
key: key,
|
||||
chatServiceAuth: chatAuth,
|
||||
forceRefresh: forceRefreshSVRBAuthCredential,
|
||||
logger: logger,
|
||||
)
|
||||
} catch let error as CancellationError {
|
||||
throw error
|
||||
} catch let error where error.isNetworkFailureOrTimeout {
|
||||
throw error
|
||||
} catch let error {
|
||||
owsFailDebug("Permanently failed to fetch svrB auth! \(error)")
|
||||
throw SVRBError.unrecoverable
|
||||
}
|
||||
let svrBAuth = try await backupRequestManager.fetchSVRBAuthCredential(
|
||||
key: key,
|
||||
chatServiceAuth: chatAuth,
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
let svrB = libsignalNet.svrB(auth: svrBAuth)
|
||||
|
||||
@ -212,7 +183,6 @@ extension BackupImportSource {
|
||||
key: key,
|
||||
metadataHeader: metadataHeader,
|
||||
chatAuth: chatAuth,
|
||||
forceRefreshSVRBAuthCredential: false,
|
||||
backupRequestManager: backupRequestManager,
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
@ -273,29 +243,14 @@ extension BackupExportPurpose {
|
||||
) async throws -> EncryptionMetadata {
|
||||
switch self {
|
||||
case let .remoteExport(key, chatAuth):
|
||||
do {
|
||||
return try await storeEncryptionMetadataToSVRB(
|
||||
key: key,
|
||||
chatAuth: chatAuth,
|
||||
forceRefreshSVRBAuthCredential: false,
|
||||
backupRequestManager: backupRequestManager,
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
nonceStore: nonceStore,
|
||||
)
|
||||
} catch SignalError.webSocketError {
|
||||
// This may represent an "expired auth" error from the SVRB
|
||||
// servers. Try again, force-refreshing credentials.
|
||||
return try await storeEncryptionMetadataToSVRB(
|
||||
key: key,
|
||||
chatAuth: chatAuth,
|
||||
forceRefreshSVRBAuthCredential: true,
|
||||
backupRequestManager: backupRequestManager,
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
nonceStore: nonceStore,
|
||||
)
|
||||
}
|
||||
return try await storeEncryptionMetadataToSVRB(
|
||||
key: key,
|
||||
chatAuth: chatAuth,
|
||||
backupRequestManager: backupRequestManager,
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
nonceStore: nonceStore,
|
||||
)
|
||||
case let .linkNsync(ephemeralKey, aci):
|
||||
let backupId = ephemeralKey.deriveBackupId(aci: aci)
|
||||
let encryptionKey = try MessageBackupKey(
|
||||
@ -315,28 +270,16 @@ extension BackupExportPurpose {
|
||||
private func storeEncryptionMetadataToSVRB(
|
||||
key: MessageRootBackupKey,
|
||||
chatAuth: ChatServiceAuth,
|
||||
forceRefreshSVRBAuthCredential: Bool,
|
||||
backupRequestManager: BackupRequestManager,
|
||||
db: any DB,
|
||||
libsignalNet: LibSignalClient.Net,
|
||||
nonceStore: BackupNonceMetadataStore,
|
||||
) async throws -> EncryptionMetadata {
|
||||
let svrBAuth: LibSignalClient.Auth
|
||||
do {
|
||||
svrBAuth = try await backupRequestManager.fetchSVRBAuthCredential(
|
||||
key: key,
|
||||
chatServiceAuth: chatAuth,
|
||||
forceRefresh: forceRefreshSVRBAuthCredential,
|
||||
logger: logger,
|
||||
)
|
||||
} catch let error as CancellationError {
|
||||
throw error
|
||||
} catch let error where error.isNetworkFailureOrTimeout {
|
||||
throw error
|
||||
} catch let error {
|
||||
owsFailDebug("Permanently failed to fetch svrB auth. \(error)")
|
||||
throw SVRBError.unrecoverable
|
||||
}
|
||||
let svrBAuth = try await backupRequestManager.fetchSVRBAuthCredential(
|
||||
key: key,
|
||||
chatServiceAuth: chatAuth,
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
let svrB = libsignalNet.svrB(auth: svrBAuth)
|
||||
|
||||
@ -374,7 +317,6 @@ extension BackupExportPurpose {
|
||||
return try await storeEncryptionMetadataToSVRB(
|
||||
key: key,
|
||||
chatAuth: chatAuth,
|
||||
forceRefreshSVRBAuthCredential: false,
|
||||
backupRequestManager: backupRequestManager,
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
@ -387,7 +329,6 @@ extension BackupExportPurpose {
|
||||
return try await storeEncryptionMetadataToSVRB(
|
||||
key: key,
|
||||
chatAuth: chatAuth,
|
||||
forceRefreshSVRBAuthCredential: false,
|
||||
backupRequestManager: backupRequestManager,
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
|
||||
@ -154,7 +154,6 @@ public protocol BackupRequestManager {
|
||||
func fetchSVRBAuthCredential(
|
||||
key: MessageRootBackupKey,
|
||||
chatServiceAuth auth: ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth
|
||||
}
|
||||
@ -485,13 +484,11 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
public func fetchSVRBAuthCredential(
|
||||
key: MessageRootBackupKey,
|
||||
chatServiceAuth auth: ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth {
|
||||
return try await backupAuthCredentialManager.fetchSVRBAuthCredential(
|
||||
key: key,
|
||||
chatServiceAuth: auth,
|
||||
forceRefresh: forceRefresh,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
@ -679,7 +676,6 @@ public class BackupRequestManagerMock: BackupRequestManager {
|
||||
public func fetchSVRBAuthCredential(
|
||||
key: SignalServiceKit.MessageRootBackupKey,
|
||||
chatServiceAuth auth: SignalServiceKit.ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth {
|
||||
return LibSignalClient.Auth(username: "", password: "")
|
||||
|
||||
@ -329,6 +329,7 @@ public class GRDBSchemaMigrator {
|
||||
case dropAttachmentContentTypeAUTrigger
|
||||
case addOrphanedAttachmentTimestamp
|
||||
case migrateSecureValueRecovery
|
||||
case wipeCachedSVRBAuthCredentials
|
||||
|
||||
// NOTE: Every time we add a migration id, consider
|
||||
// incrementing grdbSchemaVersionLatest.
|
||||
@ -5169,6 +5170,14 @@ public class GRDBSchemaMigrator {
|
||||
return .success(())
|
||||
}
|
||||
|
||||
migrator.registerMigration(.wipeCachedSVRBAuthCredentials) { tx in
|
||||
try tx.database.execute(sql: """
|
||||
DELETE FROM keyvalue
|
||||
WHERE collection = 'SVR🐝AuthCredential'
|
||||
""")
|
||||
return .success(())
|
||||
}
|
||||
|
||||
// MARK: - Schema Migration Insertion Point
|
||||
}
|
||||
|
||||
|
||||
@ -11,14 +11,12 @@ public class AuthCredentialStore {
|
||||
private let groupAuthCredentialStore: KeyValueStore
|
||||
private let backupMessagesAuthCredentialStore: KeyValueStore
|
||||
private let backupMediaAuthCredentialStore: KeyValueStore
|
||||
private let svrBAuthCredentialStore: KeyValueStore
|
||||
|
||||
public init() {
|
||||
self.callLinkAuthCredentialStore = KeyValueStore(collection: "CallLinkAuthCredential")
|
||||
self.groupAuthCredentialStore = KeyValueStore(collection: "GroupsV2Impl.authCredentialStoreStore")
|
||||
self.backupMessagesAuthCredentialStore = KeyValueStore(collection: "BackupAuthCredential")
|
||||
self.backupMediaAuthCredentialStore = KeyValueStore(collection: "MediaAuthCredential")
|
||||
self.svrBAuthCredentialStore = KeyValueStore(collection: "SVR🐝AuthCredential")
|
||||
}
|
||||
|
||||
private static func callLinkAuthCredentialKey(for redemptionTime: UInt64) -> String {
|
||||
@ -136,49 +134,6 @@ public class AuthCredentialStore {
|
||||
)
|
||||
}
|
||||
|
||||
static let svrBAuthCredentialExpirationTime: TimeInterval = .day - .hour
|
||||
static let svrBAuthCredentialExpiryDateKey = "svr🐝AuthCredentialTimestampKey"
|
||||
static let svrBAuthCredentialUsernameKey = "svr🐝AuthCredentialUsernameKey"
|
||||
static let svrBAuthCredentialPasswordKey = "svr🐝AuthCredentialPasswordKey"
|
||||
|
||||
func svrBAuthCredential(
|
||||
now: Date,
|
||||
tx: DBReadTransaction,
|
||||
) -> LibSignalClient.Auth? {
|
||||
guard
|
||||
let username = svrBAuthCredentialStore.getString(Self.svrBAuthCredentialUsernameKey, transaction: tx),
|
||||
let password = svrBAuthCredentialStore.getString(Self.svrBAuthCredentialPasswordKey, transaction: tx),
|
||||
let expiryDate = svrBAuthCredentialStore.getDate(Self.svrBAuthCredentialExpiryDateKey, transaction: tx)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
guard expiryDate > now else {
|
||||
return nil
|
||||
}
|
||||
return Auth(
|
||||
username: username,
|
||||
password: password,
|
||||
)
|
||||
}
|
||||
|
||||
func setSVRBAuthCredential(
|
||||
_ credential: LibSignalClient.Auth?,
|
||||
now: Date,
|
||||
tx: DBWriteTransaction,
|
||||
) {
|
||||
guard let credential else {
|
||||
svrBAuthCredentialStore.removeAll(transaction: tx)
|
||||
return
|
||||
}
|
||||
svrBAuthCredentialStore.setString(credential.username, key: Self.svrBAuthCredentialUsernameKey, transaction: tx)
|
||||
svrBAuthCredentialStore.setString(credential.password, key: Self.svrBAuthCredentialPasswordKey, transaction: tx)
|
||||
svrBAuthCredentialStore.setDate(
|
||||
now.addingTimeInterval(Self.svrBAuthCredentialExpirationTime),
|
||||
key: Self.svrBAuthCredentialExpiryDateKey,
|
||||
transaction: tx,
|
||||
)
|
||||
}
|
||||
|
||||
func removeAllBackupAuthCredentials(ofType credentialType: BackupAuthCredentialType, tx: DBWriteTransaction) {
|
||||
let store: KeyValueStore = switch credentialType {
|
||||
case .media: backupMediaAuthCredentialStore
|
||||
@ -186,13 +141,6 @@ public class AuthCredentialStore {
|
||||
}
|
||||
|
||||
store.removeAll(transaction: tx)
|
||||
|
||||
switch credentialType {
|
||||
case .media:
|
||||
break
|
||||
case .messages:
|
||||
svrBAuthCredentialStore.removeAll(transaction: tx)
|
||||
}
|
||||
}
|
||||
|
||||
public func removeAllBackupAuthCredentials(tx: DBWriteTransaction) {
|
||||
|
||||
@ -52,7 +52,6 @@ public protocol BackupAuthCredentialManager {
|
||||
func fetchSVRBAuthCredential(
|
||||
key: MessageRootBackupKey,
|
||||
chatServiceAuth: ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth
|
||||
}
|
||||
@ -189,14 +188,12 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
func fetchSVRBAuthCredential(
|
||||
key: MessageRootBackupKey,
|
||||
chatServiceAuth auth: ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth {
|
||||
try await serialTaskQueue.run {
|
||||
try await _fetchSVRBAuthCredential(
|
||||
key: key,
|
||||
chatServiceAuth: auth,
|
||||
forceRefresh: forceRefresh,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
@ -205,20 +202,8 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
private func _fetchSVRBAuthCredential(
|
||||
key: MessageRootBackupKey,
|
||||
chatServiceAuth auth: ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth {
|
||||
let now = dateProvider()
|
||||
|
||||
if
|
||||
!forceRefresh,
|
||||
let cachedCredential = db.read(block: { tx in
|
||||
authCredentialStore.svrBAuthCredential(now: now, tx: tx)
|
||||
})
|
||||
{
|
||||
return cachedCredential
|
||||
}
|
||||
|
||||
let backupServiceAuth = try await _fetchBackupServiceAuth(
|
||||
key: key,
|
||||
localAci: key.aci,
|
||||
@ -238,10 +223,6 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
password: receivedSVRBAuthCredential.password,
|
||||
)
|
||||
|
||||
await db.awaitableWrite { tx in
|
||||
authCredentialStore.setSVRBAuthCredential(svrBAuth, now: now, tx: tx)
|
||||
}
|
||||
|
||||
return svrBAuth
|
||||
}
|
||||
|
||||
|
||||
@ -198,7 +198,6 @@ class _AttachmentUploadManager_BackupRequestManagerMock: BackupRequestManager {
|
||||
func fetchSVRBAuthCredential(
|
||||
key: SignalServiceKit.MessageRootBackupKey,
|
||||
chatServiceAuth auth: SignalServiceKit.ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth {
|
||||
return LibSignalClient.Auth(username: "", password: "")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user