Improve OPVault handling and replace test opvault

* Fix various bugs in opvault parsing to include: TOTP parsing, date handling, naming convention, attachments, and multiple url's.

* Remove category groups that don't have any entries.

* Simplify tests by focusing on the resulting database instead of the parsing mechanics.

* Remove proprietary "freddy" opvault in favor of self-made "keepassxc" opvault.

* Fix #4069, select opvault file on macOS
This commit is contained in:
Jonathan White
2020-04-19 11:50:48 -04:00
parent 560209550c
commit 612f8d2e5b
38 changed files with 176 additions and 937 deletions

View File

@@ -66,6 +66,8 @@ Database* OpVaultReader::readDatabase(QDir& opdataDir, const QString& password)
return nullptr;
}
auto vaultName = opdataDir.dirName();
auto key = QSharedPointer<CompositeKey>::create();
key->addKey(QSharedPointer<PasswordKey>::create(password));
@@ -73,12 +75,12 @@ Database* OpVaultReader::readDatabase(QDir& opdataDir, const QString& password)
db->setKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2));
db->setCipher(KeePass2::CIPHER_AES256);
db->setKey(key, true, false);
db->metadata()->setName(opdataDir.dirName());
db->metadata()->setName(vaultName);
auto rootGroup = db->rootGroup();
rootGroup->setTimeInfo({});
rootGroup->setUpdateTimeinfo(false);
rootGroup->setName("OPVault Root Group");
rootGroup->setName(vaultName.remove(".opvault"));
rootGroup->setUuid(QUuid::createUuid());
populateCategoryGroups(rootGroup);
@@ -110,7 +112,6 @@ Database* OpVaultReader::readDatabase(QDir& opdataDir, const QString& password)
for (QChar ch : bandChars) {
QFile bandFile(defaultDir.filePath(bandPattern.arg(ch)));
if (!bandFile.exists()) {
qWarning() << "Skipping missing file \"" << bandFile.fileName() << "\"";
continue;
}
// https://support.1password.com/opvault-design/#band-files
@@ -137,13 +138,20 @@ Database* OpVaultReader::readDatabase(QDir& opdataDir, const QString& password)
continue;
}
// https://support.1password.com/opvault-design/#items
Entry* entry = processBandEntry(bandEnt, defaultDir, rootGroup);
auto entry = processBandEntry(bandEnt, defaultDir, rootGroup);
if (!entry) {
qWarning() << "Unable to process Band Entry " << uuid;
}
}
}
// Remove empty categories (groups)
for (auto group : rootGroup->children()) {
if (group->isEmpty()) {
delete group;
}
}
zeroKeys();
return db.take();
}