* Mark the database as clean after fully completing the file save operation INSTEAD of when merely writing the database to a file.
* Stop the modified timer when marking the database as clean, this prevents latent erroneous modified signals from being emitted.
* Do not restart the modified timer after a new change is detected while it is still running.
The transformed secrets were stored in normal QByteArrays,
which are at risk of being swapped out. We now use secure
PasswordKey objects instead. There are still a few areas
where QByteArrays are used for storing secrets, but since
they are all temporary, they are less critical. It may be
worth hunting those down as well, though.
When we lock a database, we reset the database pointer to
free its resources. Since various other widgets besides the
DatabaseWidget hold references to the shared pointer object,
however, it cannot be guaranteed that the actual database
object will be freed right away. This patch adds a releaseData()
method which is called upon database lock to ensure all
residual data is cleared without having to rely on the actual
database object being cleaned up.
* Fix#3506
* Fix#2389
* Fix#2536
* Fix#2230
Every database that has been opened now watch's it's own file. This allows the database class to manage file changes and detect fail conditions during saving. Additionally, all stakeholders of the database can listen for the database file changed notification and respond accordingly.
Performed significant cleanup of the autoreload code within DatabaseWidget. Fixed several issues with handling changes due to merging, not merging, and other scenarios while reloading.
Prevent database saves to the same file if there are changes on disk that have not been merged with the open database.
The CLI now contains an "import" command that creates a new database from the specified XML export. The new database is in kdbx 4 format, and does not currently accept a keyfile in database creation.
This change is required to create new databases from XML backups.
Fixes#2458
* Fixes#3126
* Limit autocompletion to the top ten used usernames
- Load common usernames when database is opened
- Transition from QLineEdit to QComboBox for usernames
- Dropdown menu of the combobox lets user choose a common username
- Common usernames are autocompleted via inline completion
- Common usernames are sorted by frequency (first) and name (second)
* Mark database dirty if saving fails
* Restore database file from backup if unsafe save fails between deleting database file and copying temporary file into place
* Improve error message display for opening and saving database files
* Do not automatically retry saving after failure. This prevents deletion of the backup database file and improves user awareness of issues.
* Fix#2877 - password is unchecked by default
* Smarter activation of key components based on contents of text entry fields
* Prevent multiple copies of the same database from opening when the canonicalFileName != fileName
The database master key settings widget does not actually
need to (re-)transform the master key, it only needs to update
the Key object on the database. Transformation can be deferred
until the Database is persisted to disk. This avoids delays
and unnecessary user interaction with challenge-response
dongles by eliminating redundant key transformations.
Previously, extracting the XML from a database was done with the
`saveXml` attribute in the `KeePass2Reader` class.
This had several unfortunate consequences:
* The `KdbxReader` class had to import the `KdbxXmlWriter` class
in order to perform the export (bad separation of concerns);
* The CLI database unlocking logic had to be duplicated only
for the `Extract` command;
* The `xmlData` had to be stored in the `KeePass2Reader` as
a temporary result.
* Lots of `setSaveXml` functions were implemented only
to trickle down this functionality.
Also, the naming of the `saveXml` variable was not really
helpful to understand it's role.
Overall, this change will make it easier to maintain and expand
the CLI database unlocking logic (for example, adding a `--no-password`
option as requested in https://github.com/keepassxreboot/keepassxc/issues/1873)
It also opens to door to other types of extraction/exporting (for
example exporting to CSV, as requested in
https://github.com/keepassxreboot/keepassxc/issues/2572)
The Database, DatabaseWidget, and DatabaseTabWidget classes share many responsibilities in inconsistent ways resulting in impenetrable and unmaintainable code and a diverse set of bugs and architecture restrictions. This patch reworks the architecture, responsibilities of, and dependencies between these classes.
The core changes are:
* Move loading and saving logic from widgets into the Database class
* Get rid of the DatabaseManagerStruct and move all the information contained in it into the Database
* Let database objects keep track of modifications and dirty/clean state instead of handing this to external widgets
* Move GUI interactions for loading and saving from the DatabaseTabWidget into the DatabaseWidget (resolves#2494 as a side-effect)
* Heavily clean up DatabaseTabWidget and degrade it to a slightly glorified QTabWidget
* Use QSharedPointers for all Database objects
* Remove the modifiedImmediate signal and replace it with a markAsModified() method
* Implement proper tabName() method instead of reading back titles from GUI widgets (resolves#1389 and its duplicates #2146#855)
* Fix unwanted AES-KDF downgrade if database uses Argon2 and has CustomData
* Improve code
This patch is also the first major step towards solving issues #476 and #2322.
This patch aims at reducing the number of copies for obejcts that could
be referenced rather than copied, because they're not modified during
the computation.
The CLI module was lacking unit test coverage and showed some severe
coding style violations, which this patch addresses.
In addition, all uses of qCritical() with untranslatble raw char*
sequences were removed in favor of proper locale strings. These are
written to STDERR through QTextStreams and support output
redirection for testing purposes. With this change, error messages don't
depend on the global Qt logging settings and targets anymore and go
directly to the terminal or into a file if needed.
This patch also fixes a bug discovered during unit test development,
where the extract command would just dump the raw XML contents without
decrypting embedded Salsa20-protected values first, making the XML
export mostly useless, since passwords are scrambled.
Lastly, all CLI commands received a dedicated -h/--help option.
* Add source folder keeshare for sharing with corresponding define WITH_XC_KEESHARE
* Move common crypto parts to src/crypto/ssh
* Extended OpenSSHKey
* Move filewatching to own file (currently in two related classes DelayedFileWatcher and BulkFileWatcher)
* Small improvements for style and code in several classes
* Sharing is secured using RSA-Keys which are generated on demand
* Publisher signs the container using their private key
* Client can verify the signed container and choose to decline an import,
import only once or trust the publisher and automatically import all
data of this source henceforth
* Integration of settings into Group-Settings, Database-Settings and Application-Settings
* Introduced dependency QuaZip as dependency to allow combined export of
key container and the (custom format) certificate
* Create history-based merging that keeps older data in history instead of discarding or deleting it
* Extract merge logic into the Merger class
* Allows special merge behavior
* Improve handling of deletion and changes on groups
* Enable basic change tracking while merging
* Prevent unintended timestamp changes while merging
* Handle differences in timestamp precision
* Introduce comparison operators to allow for more sophisticated comparisons (ignore special properties, ...)
* Introduce Clock class to handle datetime across the app
Merge Strategies:
* Default (use inherited/fallback method)
* Duplicate (duplicate conflicting nodes, apply all deletions)
* KeepLocal (use local values, but apply all deletions)
* KeepRemote (use remote values, but apply all deletions)
* KeepNewer (merge history only)
* Synchronize (merge history, newest value stays on top, apply all deletions)
This patch implements a new database wizard to guide users through the process
of setting up a new database and choosing sane encryption settings.
It also reimplements the master key settings to be more
user-friendly. Users can now add, change, or remove individual composite
key components instead of having to set all components at once. This
avoids confusion about a password being reset if the user only wants to
add a key file.
With these changes comes a major refactor of how database composite keys and key
components are handled. Copying of keys is prohibited and each key
exists only once in memory and is referenced via shared pointers. GUI
components for changing individual keys are encapsulated into separate
classes to be more reusable. The password edit and generator widgets
have also been refactored to be more reusable.
* User is prompted to disable safe saves after three failed attempts
* Completely retooled basic settings to group settings logically
* Added setting for "atomic saves"
* Adds KDBX4 reader/writer interfaces
* Adds KDBX4 XML reader/write interfaces
* Implements test cases for KDBX4
* Fully compatible with KeePass2
* Corrects minor issues with Argon2 KDF
* Save the master seed upon first challenge so it can be used as a
challenge at a later point.
* When verifyKey() is called, verify that the challenge is successful.
* Uncheck YubiKey box to not leak information about how the database is
protected.
Signed-off-by: Kyle Manna <kyle@kylemanna.com>
* Tweak the logic so it more closely resembles other code (i.e.
trasnformKey()). Matches existing style better.
* Save the challengeResponseKey in the database structure so that
it can be referred to later (i.e. database unlocking).
Signed-off-by: Kyle Manna <kyle@kylemanna.com>
* If a removed Yubikey is to blame, re-inserting the Yubikey won't
resolve the issue. Hot plug isn't supported at this point.
* The caller should detect the error and cancel the database write.
Signed-off-by: Kyle Manna <kyle@kylemanna.com>
* Pass the master seed from the database to CompositeKey::challenge()
function which will in turn issue challenges to all selected
drivers.
Signed-off-by: Kyle Manna <kyle@kylemanna.com>