-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
373 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
/* | ||
* Copyright (C) 2022 KeePassXC Team <[email protected]> | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 2 or (at your option) | ||
* version 3 of the License. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include "DatabaseEdit.h" | ||
|
||
#include "Utils.h" | ||
#include "cli/Create.h" | ||
#include "keys/ChallengeResponseKey.h" | ||
#include "keys/FileKey.h" | ||
#include "keys/PasswordKey.h" | ||
|
||
#include <QCommandLineParser> | ||
#include <QFileInfo> | ||
|
||
const QCommandLineOption DatabaseEdit::UnsetPasswordOption = | ||
QCommandLineOption(QStringList() << "unset-password", QObject::tr("Unset the password for the database.")); | ||
const QCommandLineOption DatabaseEdit::UnsetKeyFileOption = | ||
QCommandLineOption(QStringList() << "unset-key-file", QObject::tr("Unset the key file for the database.")); | ||
|
||
DatabaseEdit::DatabaseEdit() | ||
{ | ||
name = QString("db-edit"); | ||
description = QObject::tr("Edit a database."); | ||
options.append(Create::SetKeyFileOption); | ||
options.append(Create::SetPasswordOption); | ||
options.append(DatabaseEdit::UnsetKeyFileOption); | ||
options.append(DatabaseEdit::UnsetPasswordOption); | ||
} | ||
|
||
int DatabaseEdit::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<QCommandLineParser> parser) | ||
{ | ||
auto& out = Utils::STDOUT; | ||
auto& err = Utils::STDERR; | ||
|
||
const QStringList args = parser->positionalArguments(); | ||
bool databaseWasChanged = false; | ||
|
||
if (parser->isSet(Create::SetPasswordOption) && parser->isSet(DatabaseEdit::UnsetPasswordOption)) { | ||
err << QObject::tr("Cannot use %1 and %2 at the same time.") | ||
.arg(Create::SetPasswordOption.names().at(0)) | ||
.arg(DatabaseEdit::UnsetPasswordOption.names().at(0)) | ||
<< endl; | ||
return EXIT_FAILURE; | ||
} | ||
|
||
if (parser->isSet(Create::SetKeyFileOption) && parser->isSet(DatabaseEdit::UnsetKeyFileOption)) { | ||
err << QObject::tr("Cannot use %1 and %2 at the same time.") | ||
.arg(Create::SetKeyFileOption.names().at(0)) | ||
.arg(DatabaseEdit::UnsetKeyFileOption.names().at(0)) | ||
<< endl; | ||
return EXIT_FAILURE; | ||
} | ||
|
||
bool hasKeyChange = | ||
(parser->isSet(Create::SetPasswordOption) || parser->isSet(Create::SetKeyFileOption) | ||
|| parser->isSet(DatabaseEdit::UnsetPasswordOption) || parser->isSet(DatabaseEdit::UnsetKeyFileOption)); | ||
|
||
if (hasKeyChange) { | ||
auto newDatabaseKey = getNewDatabaseKey(database, | ||
parser->isSet(Create::SetPasswordOption), | ||
parser->isSet(DatabaseEdit::UnsetPasswordOption), | ||
parser->value(Create::SetKeyFileOption), | ||
parser->isSet(DatabaseEdit::UnsetKeyFileOption)); | ||
if (newDatabaseKey.isNull()) { | ||
err << QObject::tr("Could not change the database key.") << endl; | ||
return EXIT_FAILURE; | ||
} | ||
database->setKey(newDatabaseKey); | ||
databaseWasChanged = true; | ||
} | ||
|
||
if (!databaseWasChanged) { | ||
out << QObject::tr("Database was not modified.") << endl; | ||
return EXIT_SUCCESS; | ||
} | ||
|
||
QString errorMessage; | ||
if (!database->save(Database::Atomic, {}, &errorMessage)) { | ||
err << QObject::tr("Writing the database failed: %1").arg(errorMessage) << endl; | ||
return EXIT_FAILURE; | ||
} | ||
|
||
out << QObject::tr("Successfully edited the database.") << endl; | ||
return EXIT_SUCCESS; | ||
} | ||
|
||
QSharedPointer<CompositeKey> DatabaseEdit::getNewDatabaseKey(QSharedPointer<Database> database, | ||
bool updatePassword, | ||
bool removePassword, | ||
QString newFileKeyPath, | ||
bool removeKeyFile) | ||
{ | ||
auto& err = Utils::STDERR; | ||
auto newDatabaseKey = QSharedPointer<CompositeKey>::create(); | ||
|
||
for (const auto& key : database->key()->keys()) { | ||
if (key->uuid() == PasswordKey::UUID) { | ||
if (removePassword) { | ||
continue; | ||
} | ||
|
||
if (!updatePassword) { | ||
newDatabaseKey->addKey(key); | ||
continue; | ||
} | ||
|
||
continue; | ||
} | ||
|
||
if (key->uuid() == FileKey::UUID) { | ||
if (removeKeyFile) { | ||
continue; | ||
} | ||
|
||
if (newFileKeyPath.isEmpty()) { | ||
newDatabaseKey->addKey(key); | ||
continue; | ||
} | ||
|
||
continue; | ||
} | ||
|
||
// Not sure that we should ever get here. | ||
newDatabaseKey->addKey(key); | ||
} | ||
|
||
for (const auto& key : database->key()->challengeResponseKeys()) { | ||
if (key->uuid() == ChallengeResponseKey::UUID) { | ||
newDatabaseKey->addKey(key); | ||
} | ||
} | ||
|
||
if (updatePassword) { | ||
auto passwordKey = Utils::getConfirmedPassword(); | ||
if (passwordKey.isNull()) { | ||
err << QObject::tr("Failed to set database password.") << endl; | ||
return {}; | ||
} | ||
newDatabaseKey->addKey(passwordKey); | ||
} | ||
|
||
if (!newFileKeyPath.isEmpty()) { | ||
auto newFileKey = QSharedPointer<FileKey>::create(); | ||
QString errorMessage; | ||
if (!newFileKey->load(newFileKeyPath, &errorMessage)) { | ||
err << QObject::tr("Loading the new key file failed: %1").arg(errorMessage) << endl; | ||
return {}; | ||
} | ||
newDatabaseKey->addKey(newFileKey); | ||
} | ||
|
||
if (newDatabaseKey->keys().isEmpty()) { | ||
err << QObject::tr("Cannot remove all the keys from a database.") << endl; | ||
return {}; | ||
} | ||
|
||
return newDatabaseKey; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright (C) 2022 KeePassXC Team <[email protected]> | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 2 or (at your option) | ||
* version 3 of the License. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef KEEPASSXC_DATABASEEDIT_H | ||
#define KEEPASSXC_DATABASEEDIT_H | ||
|
||
#include "DatabaseCommand.h" | ||
|
||
class DatabaseEdit : public DatabaseCommand | ||
{ | ||
public: | ||
DatabaseEdit(); | ||
|
||
int executeWithDatabase(QSharedPointer<Database> db, QSharedPointer<QCommandLineParser> parser) override; | ||
|
||
static const QCommandLineOption UnsetKeyFileOption; | ||
static const QCommandLineOption UnsetPasswordOption; | ||
|
||
private: | ||
QSharedPointer<CompositeKey> getNewDatabaseKey(QSharedPointer<Database> database, | ||
bool updatePassword, | ||
bool removePassword, | ||
QString newFileKeyPath, | ||
bool removeKeyFile); | ||
}; | ||
|
||
#endif // KEEPASSXC_DATABASEEDIT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.