Database is 0 Byte if Yubikey save is canceled #1680
This commit is contained in:
J-Jamet
2024-05-13 11:38:16 +02:00
parent e1ad1e31f8
commit 9e714c4192
2 changed files with 63 additions and 18 deletions

View File

@@ -27,6 +27,7 @@ import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import android.widget.Toast
import androidx.annotation.StringRes
import androidx.media.app.NotificationCompat
import com.kunzisoft.keepass.R
@@ -36,10 +37,24 @@ import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.database.ContextualDatabase
import com.kunzisoft.keepass.database.MainCredential
import com.kunzisoft.keepass.database.ProgressMessage
import com.kunzisoft.keepass.database.action.*
import com.kunzisoft.keepass.database.action.CreateDatabaseRunnable
import com.kunzisoft.keepass.database.action.LoadDatabaseRunnable
import com.kunzisoft.keepass.database.action.MergeDatabaseRunnable
import com.kunzisoft.keepass.database.action.ReloadDatabaseRunnable
import com.kunzisoft.keepass.database.action.RemoveUnlinkedDataDatabaseRunnable
import com.kunzisoft.keepass.database.action.SaveDatabaseRunnable
import com.kunzisoft.keepass.database.action.UpdateCompressionBinariesDatabaseRunnable
import com.kunzisoft.keepass.database.action.history.DeleteEntryHistoryDatabaseRunnable
import com.kunzisoft.keepass.database.action.history.RestoreEntryHistoryDatabaseRunnable
import com.kunzisoft.keepass.database.action.node.*
import com.kunzisoft.keepass.database.action.node.ActionNodesValues
import com.kunzisoft.keepass.database.action.node.AddEntryRunnable
import com.kunzisoft.keepass.database.action.node.AddGroupRunnable
import com.kunzisoft.keepass.database.action.node.AfterActionNodesFinish
import com.kunzisoft.keepass.database.action.node.CopyNodesRunnable
import com.kunzisoft.keepass.database.action.node.DeleteNodesRunnable
import com.kunzisoft.keepass.database.action.node.MoveNodesRunnable
import com.kunzisoft.keepass.database.action.node.UpdateEntryRunnable
import com.kunzisoft.keepass.database.action.node.UpdateGroupRunnable
import com.kunzisoft.keepass.database.element.Entry
import com.kunzisoft.keepass.database.element.Group
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
@@ -62,9 +77,17 @@ import com.kunzisoft.keepass.utils.getParcelableExtraCompat
import com.kunzisoft.keepass.utils.getParcelableList
import com.kunzisoft.keepass.utils.putParcelableList
import com.kunzisoft.keepass.viewmodels.FileDatabaseInfo
import kotlinx.coroutines.*
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import kotlinx.coroutines.channels.Channel
import java.util.*
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import java.util.UUID
open class DatabaseTaskNotificationService : LockNotificationService(), ProgressTaskUpdater {
@@ -250,6 +273,13 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
val responseChannel = mResponseChallengeChannel
if (responseChannel == null || responseChannel.isEmpty) {
if (response.isEmpty()) {
Toast.makeText(
this@DatabaseTaskNotificationService,
getString(
R.string.error_action_empty_response_from_challenge),
Toast.LENGTH_LONG
).show()
mResponseChallengeChannel?.send(response)
cancelChallengeResponse(R.string.error_no_response_from_challenge)
} else {
mResponseChallengeChannel?.send(response)
@@ -831,6 +861,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
if (intent.hasExtra(MAIN_CREDENTIAL_KEY)) {
databaseToMergeMainCredential = intent.getParcelableExtraCompat(MAIN_CREDENTIAL_KEY)
}
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
return MergeDatabaseRunnable(
this,
databaseToMergeUri,
@@ -839,7 +870,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
retrieveResponseFromChallenge(hardwareKey, seed)
},
database,
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
!database.isReadOnly && saveDatabase,
{ hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
},
@@ -932,12 +963,13 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
val parentId: NodeId<*>? = intent.getParcelableExtraCompat(PARENT_ID_KEY)
val newGroup: Group? = intent.getParcelableExtraCompat(GROUP_KEY)
if (parentId == null || newGroup == null) return null
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
database.getGroupById(parentId)?.let { parent ->
AddGroupRunnable(this,
database,
newGroup,
parent,
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
!database.isReadOnly && saveDatabase,
AfterActionNodesRunnable()
) { hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
@@ -959,12 +991,13 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
val groupId: NodeId<*>? = intent.getParcelableExtraCompat(GROUP_ID_KEY)
val newGroup: Group? = intent.getParcelableExtraCompat(GROUP_KEY)
if (groupId == null || newGroup == null) return null
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
database.getGroupById(groupId)?.let { oldGroup ->
UpdateGroupRunnable(this,
database,
oldGroup,
newGroup,
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
!database.isReadOnly && saveDatabase,
AfterActionNodesRunnable()
) { hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
@@ -986,12 +1019,13 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
val parentId: NodeId<*>? = intent.getParcelableExtraCompat(PARENT_ID_KEY)
val newEntry: Entry? = intent.getParcelableExtraCompat(ENTRY_KEY)
if (parentId == null || newEntry == null) return null
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
database.getGroupById(parentId)?.let { parent ->
AddEntryRunnable(this,
database,
newEntry,
parent,
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
!database.isReadOnly && saveDatabase,
AfterActionNodesRunnable()
) { hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
@@ -1013,12 +1047,13 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
val entryId: NodeId<UUID>? = intent.getParcelableExtraCompat(ENTRY_ID_KEY)
val newEntry: Entry? = intent.getParcelableExtraCompat(ENTRY_KEY)
if (entryId == null || newEntry == null) return null
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
database.getEntryById(entryId)?.let { oldEntry ->
UpdateEntryRunnable(this,
database,
oldEntry,
newEntry,
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
!database.isReadOnly && saveDatabase,
AfterActionNodesRunnable()
) { hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
@@ -1039,12 +1074,13 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val parentId: NodeId<*> = intent.getParcelableExtraCompat(PARENT_ID_KEY) ?: return null
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
database.getGroupById(parentId)?.let { newParent ->
CopyNodesRunnable(this,
database,
getListNodesFromBundle(database, intent.extras!!),
newParent,
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
!database.isReadOnly && saveDatabase,
AfterActionNodesRunnable()
) { hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
@@ -1065,12 +1101,13 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val parentId: NodeId<*> = intent.getParcelableExtraCompat(PARENT_ID_KEY) ?: return null
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
database.getGroupById(parentId)?.let { newParent ->
MoveNodesRunnable(this,
database,
getListNodesFromBundle(database, intent.extras!!),
newParent,
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
!database.isReadOnly && saveDatabase,
AfterActionNodesRunnable()
) { hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
@@ -1089,11 +1126,12 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
&& intent.hasExtra(ENTRIES_ID_KEY)
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
DeleteNodesRunnable(this,
database,
getListNodesFromBundle(database, intent.extras!!),
resources.getString(R.string.recycle_bin),
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
!database.isReadOnly && saveDatabase,
AfterActionNodesRunnable()
) { hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
@@ -1112,12 +1150,13 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val entryId: NodeId<UUID> = intent.getParcelableExtraCompat(ENTRY_ID_KEY) ?: return null
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
database.getEntryById(entryId)?.let { mainEntry ->
RestoreEntryHistoryDatabaseRunnable(this,
database,
mainEntry,
intent.getIntExtra(ENTRY_HISTORY_POSITION_KEY, -1),
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
!database.isReadOnly && saveDatabase
) { hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
}
@@ -1136,12 +1175,13 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val entryId: NodeId<UUID> = intent.getParcelableExtraCompat(ENTRY_ID_KEY) ?: return null
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
database.getEntryById(entryId)?.let { mainEntry ->
DeleteEntryHistoryDatabaseRunnable(this,
database,
mainEntry,
intent.getIntExtra(ENTRY_HISTORY_POSITION_KEY, -1),
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
!database.isReadOnly && saveDatabase
) { hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
}
@@ -1162,11 +1202,12 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
val oldElement: CompressionAlgorithm? = intent.getParcelableExtraCompat(OLD_ELEMENT_KEY)
val newElement: CompressionAlgorithm? = intent.getParcelableExtraCompat(NEW_ELEMENT_KEY)
if (oldElement == null || newElement == null) return null
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
return UpdateCompressionBinariesDatabaseRunnable(this,
database,
oldElement,
newElement,
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
!database.isReadOnly && saveDatabase
) { hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
}.apply {
@@ -1184,9 +1225,10 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
database: ContextualDatabase,
): ActionRunnable? {
return if (intent.hasExtra(SAVE_DATABASE_KEY)) {
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
return RemoveUnlinkedDataDatabaseRunnable(this,
database,
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
!database.isReadOnly && saveDatabase
) { hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
}.apply {
@@ -1204,9 +1246,10 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
database: ContextualDatabase,
): ActionRunnable? {
return if (intent.hasExtra(SAVE_DATABASE_KEY)) {
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
return SaveDatabaseRunnable(this,
database,
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
!database.isReadOnly && saveDatabase,
null,
{ hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)
@@ -1229,13 +1272,14 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
database: ContextualDatabase
): ActionRunnable? {
return if (intent.hasExtra(SAVE_DATABASE_KEY)) {
val saveDatabase = intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
var databaseCopyUri: Uri? = null
if (intent.hasExtra(DATABASE_URI_KEY)) {
databaseCopyUri = intent.getParcelableExtraCompat(DATABASE_URI_KEY)
}
SaveDatabaseRunnable(this,
database,
!database.isReadOnly && intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
!database.isReadOnly && saveDatabase,
null,
{ hardwareKey, seed ->
retrieveResponseFromChallenge(hardwareKey, seed)

View File

@@ -204,6 +204,7 @@
<string name="error_challenge_already_requested">"Challenge already requested"</string>
<string name="error_response_already_provided">Response already provided.</string>
<string name="error_no_response_from_challenge">Unable to get the response from the challenge.</string>
<string name="error_action_empty_response_from_challenge">WARNING : Action performed with an empty challenge response.</string>
<string name="error_cancel_by_user">Cancelled by user.</string>
<string name="error_driver_required">Driver for %1$s is required.</string>
<string name="error_unable_merge_database_kdb">Unable to merge from a database V1.</string>