Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli/Create.cpp')
-rw-r--r--src/cli/Create.cpp89
1 files changed, 73 insertions, 16 deletions
diff --git a/src/cli/Create.cpp b/src/cli/Create.cpp
index fbdebaf47..f72c2b7a5 100644
--- a/src/cli/Create.cpp
+++ b/src/cli/Create.cpp
@@ -30,12 +30,31 @@
#include "keys/CompositeKey.h"
#include "keys/Key.h"
+const QCommandLineOption Create::DecryptionTimeOption =
+ QCommandLineOption(QStringList() << "t"
+ << "decryption-time",
+ QObject::tr("Target decryption time in MS for the database."),
+ QObject::tr("time"));
+
+const QCommandLineOption Create::SetKeyFileOption =
+ QCommandLineOption(QStringList() << "k"
+ << "set-key-file",
+ QObject::tr("Set the key file for the database."),
+ QObject::tr("path"));
+
+const QCommandLineOption Create::SetPasswordOption =
+ QCommandLineOption(QStringList() << "p"
+ << "set-password",
+ QObject::tr("Set a password for the database."));
+
Create::Create()
{
- name = QString("create");
+ name = QString("db-create");
description = QObject::tr("Create a new database.");
positionalArguments.append({QString("database"), QObject::tr("Path of the database."), QString("")});
- options.append(Command::KeyFileOption);
+ options.append(Create::SetKeyFileOption);
+ options.append(Create::SetPasswordOption);
+ options.append(Create::DecryptionTimeOption);
}
/**
@@ -53,14 +72,14 @@ Create::Create()
*/
int Create::execute(const QStringList& arguments)
{
- QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
- QTextStream err(Utils::STDERR, QIODevice::WriteOnly);
-
QSharedPointer<QCommandLineParser> parser = getCommandLineParser(arguments);
if (parser.isNull()) {
return EXIT_FAILURE;
}
+ auto& out = parser->isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT;
+ auto& err = Utils::STDERR;
+
const QStringList args = parser->positionalArguments();
const QString& databaseFilename = args.at(0);
@@ -69,23 +88,45 @@ int Create::execute(const QStringList& arguments)
return EXIT_FAILURE;
}
+ // Validate the decryption time before asking for a password.
+ QString decryptionTimeValue = parser->value(Create::DecryptionTimeOption);
+ int decryptionTime = 0;
+ if (decryptionTimeValue.length() != 0) {
+ decryptionTime = decryptionTimeValue.toInt();
+ if (decryptionTime <= 0) {
+ err << QObject::tr("Invalid decryption time %1.").arg(decryptionTimeValue) << endl;
+ return EXIT_FAILURE;
+ }
+ if (decryptionTime < Kdf::MIN_ENCRYPTION_TIME || decryptionTime > Kdf::MAX_ENCRYPTION_TIME) {
+ err << QObject::tr("Target decryption time must be between %1 and %2.")
+ .arg(QString::number(Kdf::MIN_ENCRYPTION_TIME), QString::number(Kdf::MAX_ENCRYPTION_TIME))
+ << endl;
+ return EXIT_FAILURE;
+ }
+ }
+
auto key = QSharedPointer<CompositeKey>::create();
- auto password = Utils::getPasswordFromStdin();
- if (!password.isNull()) {
- key->addKey(password);
+ if (parser->isSet(Create::SetPasswordOption)) {
+ auto passwordKey = Utils::getConfirmedPassword();
+ if (passwordKey.isNull()) {
+ err << QObject::tr("Failed to set database password.") << endl;
+ return EXIT_FAILURE;
+ }
+ key->addKey(passwordKey);
}
- QSharedPointer<FileKey> fileKey;
- if (parser->isSet(Command::KeyFileOption)) {
- if (!loadFileKey(parser->value(Command::KeyFileOption), fileKey)) {
+ if (parser->isSet(Create::SetKeyFileOption)) {
+ QSharedPointer<FileKey> fileKey;
+
+ if (!loadFileKey(parser->value(Create::SetKeyFileOption), fileKey)) {
err << QObject::tr("Loading the key file failed") << endl;
return EXIT_FAILURE;
}
- }
- if (!fileKey.isNull()) {
- key->addKey(fileKey);
+ if (!fileKey.isNull()) {
+ key->addKey(fileKey);
+ }
}
if (key->isEmpty()) {
@@ -96,6 +137,23 @@ int Create::execute(const QStringList& arguments)
QSharedPointer<Database> db(new Database);
db->setKey(key);
+ if (decryptionTime != 0) {
+ auto kdf = db->kdf();
+ Q_ASSERT(kdf);
+
+ out << QObject::tr("Benchmarking key derivation function for %1ms delay.").arg(decryptionTimeValue) << endl;
+ int rounds = kdf->benchmark(decryptionTime);
+ out << QObject::tr("Setting %1 rounds for key derivation function.").arg(QString::number(rounds)) << endl;
+ kdf->setRounds(rounds);
+
+ bool ok = db->changeKdf(kdf);
+
+ if (!ok) {
+ err << QObject::tr("error while setting database key derivation settings.") << endl;
+ return EXIT_FAILURE;
+ }
+ }
+
QString errorMessage;
if (!db->saveAs(databaseFilename, &errorMessage, true, false)) {
err << QObject::tr("Failed to save the database: %1.").arg(errorMessage) << endl;
@@ -120,8 +178,7 @@ int Create::execute(const QStringList& arguments)
*/
bool Create::loadFileKey(const QString& path, QSharedPointer<FileKey>& fileKey)
{
- QTextStream err(Utils::STDERR, QIODevice::WriteOnly);
-
+ auto& err = Utils::STDERR;
QString error;
fileKey = QSharedPointer<FileKey>(new FileKey());