mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Upgrade database version after a modification
This commit is contained in:
@@ -2,6 +2,7 @@ KeePassDX(3.2.0)
|
||||
* Manage data merge #840 #977
|
||||
* Inherit color from template #1213
|
||||
* Add path in quick search
|
||||
* Small fixes
|
||||
|
||||
KeePassDX(3.1.0)
|
||||
* Add breadcrumb
|
||||
|
||||
@@ -34,6 +34,7 @@ open class SaveDatabaseRunnable(protected var context: Context,
|
||||
override fun onStartRun() {}
|
||||
|
||||
override fun onActionRun() {
|
||||
database.checkVersion()
|
||||
if (saveDatabase && result.isSuccess) {
|
||||
try {
|
||||
database.saveData(context.contentResolver)
|
||||
|
||||
@@ -269,6 +269,12 @@ class Database {
|
||||
val version: String
|
||||
get() = mDatabaseKDB?.version ?: mDatabaseKDBX?.version ?: "-"
|
||||
|
||||
fun checkVersion() {
|
||||
mDatabaseKDBX?.getMinKdbxVersion()?.let {
|
||||
mDatabaseKDBX?.kdbxVersion = it
|
||||
}
|
||||
}
|
||||
|
||||
val type: Class<*>?
|
||||
get() = mDatabaseKDB?.javaClass ?: mDatabaseKDBX?.javaClass
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.database.action.node.NodeHandler
|
||||
import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm
|
||||
import com.kunzisoft.keepass.database.crypto.VariantDictionary
|
||||
import com.kunzisoft.keepass.database.crypto.kdf.AesKdf
|
||||
import com.kunzisoft.keepass.database.crypto.kdf.KdfEngine
|
||||
import com.kunzisoft.keepass.database.crypto.kdf.KdfFactory
|
||||
import com.kunzisoft.keepass.database.crypto.kdf.KdfParameters
|
||||
@@ -42,6 +43,7 @@ import com.kunzisoft.keepass.database.element.icon.IconImageCustom
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImageStandard
|
||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||
import com.kunzisoft.keepass.database.element.node.NodeIdUUID
|
||||
import com.kunzisoft.keepass.database.element.node.NodeKDBXInterface
|
||||
import com.kunzisoft.keepass.database.element.node.NodeVersioned
|
||||
import com.kunzisoft.keepass.database.element.security.MemoryProtectionConfig
|
||||
import com.kunzisoft.keepass.database.element.template.Template
|
||||
@@ -187,6 +189,67 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
|
||||
return "V2 - KDBX$kdbxStringVersion"
|
||||
}
|
||||
|
||||
private open class NodeOperationHandler<T: NodeKDBXInterface> : NodeHandler<T>() {
|
||||
var containsCustomData = false
|
||||
override fun operate(node: T): Boolean {
|
||||
if (node.customData.isNotEmpty()) {
|
||||
containsCustomData = true
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private inner class EntryOperationHandler: NodeOperationHandler<EntryKDBX>() {
|
||||
var passwordQualityEstimationDisabled = false
|
||||
override fun operate(node: EntryKDBX): Boolean {
|
||||
if (!node.qualityCheck) {
|
||||
passwordQualityEstimationDisabled = true
|
||||
}
|
||||
return super.operate(node)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class GroupOperationHandler: NodeOperationHandler<GroupKDBX>() {
|
||||
var containsTags = false
|
||||
override fun operate(node: GroupKDBX): Boolean {
|
||||
if (!node.tags.isEmpty())
|
||||
containsTags = true
|
||||
return super.operate(node)
|
||||
}
|
||||
}
|
||||
|
||||
fun getMinKdbxVersion(): UnsignedInt {
|
||||
val entryHandler = EntryOperationHandler()
|
||||
val groupHandler = GroupOperationHandler()
|
||||
rootGroup?.doForEachChildAndForIt(entryHandler, groupHandler)
|
||||
|
||||
// https://keepass.info/help/kb/kdbx_4.1.html
|
||||
val containsGroupWithTag = groupHandler.containsTags
|
||||
val containsEntryWithPasswordQualityEstimationDisabled = entryHandler.passwordQualityEstimationDisabled
|
||||
val containsCustomIconWithNameOrLastModificationTime = iconsManager.containsCustomIconWithNameOrLastModificationTime()
|
||||
val containsHeaderCustomDataWithLastModificationTime = customData.containsItemWithLastModificationTime()
|
||||
|
||||
// https://keepass.info/help/kb/kdbx_4.html
|
||||
// If AES is not use, it's at least 4.0
|
||||
val kdfIsNotAes = kdfParameters?.uuid != AesKdf.CIPHER_UUID
|
||||
val containsHeaderCustomData = customData.isNotEmpty()
|
||||
val containsNodeCustomData = entryHandler.containsCustomData || groupHandler.containsCustomData
|
||||
|
||||
// Check each condition to determine version
|
||||
return if (containsGroupWithTag
|
||||
|| containsEntryWithPasswordQualityEstimationDisabled
|
||||
|| containsCustomIconWithNameOrLastModificationTime
|
||||
|| containsHeaderCustomDataWithLastModificationTime) {
|
||||
FILE_VERSION_41
|
||||
} else if (kdfIsNotAes
|
||||
|| containsHeaderCustomData
|
||||
|| containsNodeCustomData) {
|
||||
FILE_VERSION_40
|
||||
} else {
|
||||
FILE_VERSION_31
|
||||
}
|
||||
}
|
||||
|
||||
val availableCompressionAlgorithms: List<CompressionAlgorithm> = listOf(
|
||||
CompressionAlgorithm.None,
|
||||
CompressionAlgorithm.GZip
|
||||
|
||||
@@ -87,71 +87,10 @@ class DatabaseHeaderKDBX(private val databaseV4: DatabaseKDBX) : DatabaseHeader(
|
||||
inner class HeaderAndHash(var header: ByteArray, var hash: ByteArray)
|
||||
|
||||
init {
|
||||
this.version = getMinKdbxVersion(databaseV4) // Only for writing
|
||||
this.version = databaseV4.getMinKdbxVersion()
|
||||
this.masterSeed = ByteArray(32)
|
||||
}
|
||||
|
||||
private open class NodeOperationHandler<T: NodeKDBXInterface> : NodeHandler<T>() {
|
||||
var containsCustomData = false
|
||||
override fun operate(node: T): Boolean {
|
||||
if (node.customData.isNotEmpty()) {
|
||||
containsCustomData = true
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private inner class EntryOperationHandler: NodeOperationHandler<EntryKDBX>() {
|
||||
var passwordQualityEstimationDisabled = false
|
||||
override fun operate(node: EntryKDBX): Boolean {
|
||||
if (!node.qualityCheck) {
|
||||
passwordQualityEstimationDisabled = true
|
||||
}
|
||||
return super.operate(node)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class GroupOperationHandler: NodeOperationHandler<GroupKDBX>() {
|
||||
var containsTags = false
|
||||
override fun operate(node: GroupKDBX): Boolean {
|
||||
if (!node.tags.isEmpty())
|
||||
containsTags = true
|
||||
return super.operate(node)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMinKdbxVersion(databaseKDBX: DatabaseKDBX): UnsignedInt {
|
||||
val entryHandler = EntryOperationHandler()
|
||||
val groupHandler = GroupOperationHandler()
|
||||
databaseKDBX.rootGroup?.doForEachChildAndForIt(entryHandler, groupHandler)
|
||||
|
||||
// https://keepass.info/help/kb/kdbx_4.1.html
|
||||
val containsGroupWithTag = groupHandler.containsTags
|
||||
val containsEntryWithPasswordQualityEstimationDisabled = entryHandler.passwordQualityEstimationDisabled
|
||||
val containsCustomIconWithNameOrLastModificationTime = databaseKDBX.iconsManager.containsCustomIconWithNameOrLastModificationTime()
|
||||
val containsHeaderCustomDataWithLastModificationTime = databaseKDBX.customData.containsItemWithLastModificationTime()
|
||||
|
||||
// https://keepass.info/help/kb/kdbx_4.html
|
||||
// If AES is not use, it's at least 4.0
|
||||
val kdfIsNotAes = databaseKDBX.kdfParameters?.uuid != AesKdf.CIPHER_UUID
|
||||
val containsHeaderCustomData = databaseKDBX.customData.isNotEmpty()
|
||||
val containsNodeCustomData = entryHandler.containsCustomData || groupHandler.containsCustomData
|
||||
|
||||
// Check each condition to determine version
|
||||
return if (containsGroupWithTag
|
||||
|| containsEntryWithPasswordQualityEstimationDisabled
|
||||
|| containsCustomIconWithNameOrLastModificationTime
|
||||
|| containsHeaderCustomDataWithLastModificationTime) {
|
||||
FILE_VERSION_41
|
||||
} else if (kdfIsNotAes
|
||||
|| containsHeaderCustomData
|
||||
|| containsNodeCustomData) {
|
||||
FILE_VERSION_40
|
||||
} else {
|
||||
FILE_VERSION_31
|
||||
}
|
||||
}
|
||||
|
||||
/** Assumes the input stream is at the beginning of the .kdbx file
|
||||
* @param inputStream
|
||||
* @throws IOException
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
* Manage data merge #840 #977
|
||||
* Inherit color from template #1213
|
||||
* Add path in quick search
|
||||
* Small fixes
|
||||
@@ -1,3 +1,4 @@
|
||||
* Gestion de la fusion des données #840 #977
|
||||
* Héritage de la couleur du gabarit #1213
|
||||
* Ajout du chemin dans la recherche rapide
|
||||
* Petis correctifs
|
||||
Reference in New Issue
Block a user