Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature : --key-file option for CLI #816

Merged
merged 5 commits into from
Jul 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 8 additions & 21 deletions src/cli/Clip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,13 @@

#include "Clip.h"

#include <QApplication>
#include <QCommandLineParser>
#include <QStringList>
#include <QTextStream>

#include "cli/Utils.h"
#include "core/Database.h"
#include "core/Entry.h"
#include "core/Group.h"
#include "gui/UnlockDatabaseDialog.h"

Clip::Clip()
{
Expand All @@ -43,24 +40,19 @@ Clip::~Clip()
{
}

int Clip::execute(int argc, char** argv)
int Clip::execute(QStringList arguments)
{
QStringList arguments;
// Skipping the first argument (keepassxc).
for (int i = 1; i < argc; ++i) {
arguments << QString(argv[i]);
}

QTextStream out(stdout);
QApplication app(argc, argv);

QCommandLineParser parser;
parser.setApplicationDescription(this->description);
parser.addPositionalArgument("database", QObject::tr("Path of the database."));
QCommandLineOption guiPrompt(QStringList() << "g"
<< "gui-prompt",
QObject::tr("Use a GUI prompt unlocking the database."));
parser.addOption(guiPrompt);
QCommandLineOption keyFile(QStringList() << "k"
<< "key-file",
QObject::tr("Key file of the database."),
QObject::tr("path"));
parser.addOption(keyFile);
parser.addPositionalArgument("entry", QObject::tr("Path of the entry to clip."));
parser.addPositionalArgument(
"timeout",
Expand All @@ -74,16 +66,11 @@ int Clip::execute(int argc, char** argv)
return EXIT_FAILURE;
}

Database* db = nullptr;
if (parser.isSet("gui-prompt")) {
db = UnlockDatabaseDialog::openDatabasePrompt(args.at(0));
} else {
db = Database::unlockFromStdin(args.at(0));
}

Database* db = Database::unlockFromStdin(args.at(0), parser.value(keyFile));
if (!db) {
return EXIT_FAILURE;
}

return this->clipEntry(db, args.at(1), args.value(2));
}

Expand Down
2 changes: 1 addition & 1 deletion src/cli/Clip.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Clip : public Command
public:
Clip();
~Clip();
int execute(int argc, char** argv);
int execute(QStringList arguments);
int clipEntry(Database* database, QString entryPath, QString timeout);
};

Expand Down
2 changes: 1 addition & 1 deletion src/cli/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Command::~Command()
{
}

int Command::execute(int, char**)
int Command::execute(QStringList)
{
return EXIT_FAILURE;
}
Expand Down
2 changes: 1 addition & 1 deletion src/cli/Command.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Command
{
public:
virtual ~Command();
virtual int execute(int argc, char** argv);
virtual int execute(QStringList arguments);
QString name;
QString description;
QString getDescriptionLine();
Expand Down
15 changes: 8 additions & 7 deletions src/cli/EntropyMeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,18 @@ static void calculate(const char *pwd, int advanced)
}
}

int EntropyMeter::execute(int argc, char **argv)
int EntropyMeter::execute(QStringList arguments)
{
printf("KeePassXC Entropy Meter, based on zxcvbn-c.\nEnter your password below or pass it as argv\n");
printf(" Usage: entropy-meter [-a] [pwd1 pwd2 ...]\n> ");
int i, advanced;
if ((argc > 1) && (argv[1][0] == '-') && (!strcmp(argv[1], "-a")))
int i, advanced = 0;
if (arguments.size() > 1 && arguments.at(1) == "-a")
{
advanced = 1;
arguments.removeAt(1);
}
i = 2;
if (i >= argc)
i = 1;
if (i >= arguments.size())
{
/* No test passwords on command line, so get them from stdin */
char line[500];
Expand All @@ -131,9 +132,9 @@ int EntropyMeter::execute(int argc, char **argv)
else
{
/* Do the test passwords on the command line */
for(; i < argc; ++i)
for(; i < arguments.size(); ++i)
{
calculate(argv[i],advanced);
calculate(arguments.at(i).toLatin1(), advanced);
}
}
return 0;
Expand Down
2 changes: 1 addition & 1 deletion src/cli/EntropyMeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class EntropyMeter : public Command
public:
EntropyMeter();
~EntropyMeter();
int execute(int argc, char** argv);
int execute(QStringList arguments);
};

#endif // KEEPASSXC_ENTROPYMETER_H
20 changes: 8 additions & 12 deletions src/cli/Extract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,14 @@
#include "Extract.h"

#include <QCommandLineParser>
#include <QCoreApplication>
#include <QFile>
#include <QStringList>
#include <QTextStream>

#include "cli/Utils.h"
#include "core/Database.h"
#include "format/KeePass2Reader.h"
#include "keys/CompositeKey.h"
#include "keys/PasswordKey.h"

Extract::Extract()
{
Expand All @@ -41,15 +40,8 @@ Extract::~Extract()
{
}

int Extract::execute(int argc, char** argv)
int Extract::execute(QStringList arguments)
{
QStringList arguments;
// Skipping the first argument (keepassxc).
for (int i = 1; i < argc; ++i) {
arguments << QString(argv[i]);
}

QCoreApplication app(argc, argv);
QTextStream out(stdout);

QCommandLineParser parser;
Expand All @@ -66,8 +58,12 @@ int Extract::execute(int argc, char** argv)
out << "Insert the database password\n> ";
out.flush();

CompositeKey compositeKey;

QString line = Utils::getPassword();
CompositeKey key = CompositeKey::readFromLine(line);
PasswordKey passwordKey;
passwordKey.setPassword(line);
compositeKey.addKey(passwordKey);

QString databaseFilename = args.at(0);
QFile dbFile(databaseFilename);
Expand All @@ -82,7 +78,7 @@ int Extract::execute(int argc, char** argv)

KeePass2Reader reader;
reader.setSaveXml(true);
Database* db = reader.readDatabase(&dbFile, key);
Database* db = reader.readDatabase(&dbFile, compositeKey);
delete db;

QByteArray xmlData = reader.xmlData();
Expand Down
2 changes: 1 addition & 1 deletion src/cli/Extract.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Extract : public Command
public:
Extract();
~Extract();
int execute(int argc, char** argv);
int execute(QStringList arguments);
};

#endif // KEEPASSXC_EXTRACT_H
32 changes: 7 additions & 25 deletions src/cli/List.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,12 @@

#include "List.h"

#include <QApplication>
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QStringList>
#include <QTextStream>

#include "core/Database.h"
#include "core/Entry.h"
#include "core/Group.h"
#include "gui/UnlockDatabaseDialog.h"

List::List()
{
Expand All @@ -41,43 +37,29 @@ List::~List()
{
}

int List::execute(int argc, char** argv)
int List::execute(QStringList arguments)
{
QStringList arguments;
// Skipping the first argument (keepassxc).
for (int i = 1; i < argc; ++i) {
arguments << QString(argv[i]);
}

QTextStream out(stdout);

QCommandLineParser parser;
parser.setApplicationDescription(this->description);
parser.addPositionalArgument("database", QObject::tr("Path of the database."));
parser.addPositionalArgument(
"group", QObject::tr("Path of the group to list. Default is /"), QString("[group]"));
QCommandLineOption guiPrompt(QStringList() << "g"
<< "gui-prompt",
QObject::tr("Use a GUI prompt unlocking the database."));
parser.addOption(guiPrompt);
QCommandLineOption keyFile(QStringList() << "k"
<< "key-file",
QObject::tr("Key file of the database."),
QObject::tr("path"));
parser.addOption(keyFile);
parser.process(arguments);

const QStringList args = parser.positionalArguments();
if (args.size() != 1 && args.size() != 2) {
QCoreApplication app(argc, argv);
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli ls");
return EXIT_FAILURE;
}

Database* db = nullptr;
if (parser.isSet("gui-prompt")) {
QApplication app(argc, argv);
db = UnlockDatabaseDialog::openDatabasePrompt(args.at(0));
} else {
QCoreApplication app(argc, argv);
db = Database::unlockFromStdin(args.at(0));
}

Database* db = Database::unlockFromStdin(args.at(0), parser.value(keyFile));
if (db == nullptr) {
return EXIT_FAILURE;
}
Expand Down
2 changes: 1 addition & 1 deletion src/cli/List.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class List : public Command
public:
List();
~List();
int execute(int argc, char** argv);
int execute(QStringList arguments);
int listGroup(Database* database, QString groupPath = QString(""));
};

Expand Down
61 changes: 23 additions & 38 deletions src/cli/Merge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,10 @@

#include "Merge.h"

#include <QApplication>
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QStringList>
#include <QTextStream>

#include "core/Database.h"
#include "gui/UnlockDatabaseDialog.h"

Merge::Merge()
{
Expand All @@ -38,14 +34,8 @@ Merge::~Merge()
{
}

int Merge::execute(int argc, char** argv)
int Merge::execute(QStringList arguments)
{
QStringList arguments;
// Skipping the first argument (keepassxc).
for (int i = 1; i < argc; ++i) {
arguments << QString(argv[i]);
}

QTextStream out(stdout);

QCommandLineParser parser;
Expand All @@ -55,52 +45,47 @@ int Merge::execute(int argc, char** argv)

QCommandLineOption samePasswordOption(
QStringList() << "s"
<< "same-password",
QObject::tr("Use the same password for both database files."));

QCommandLineOption guiPrompt(QStringList() << "g"
<< "gui-prompt",
QObject::tr("Use a GUI prompt unlocking the database."));
parser.addOption(guiPrompt);
<< "same-credentials",
QObject::tr("Use the same credentials for both database files."));

QCommandLineOption keyFile(QStringList() << "k"
<< "key-file",
QObject::tr("Key file of the database."),
QObject::tr("path"));
parser.addOption(keyFile);
QCommandLineOption keyFileFrom(QStringList() << "f"
<< "key-file-from",
QObject::tr("Key file of the database to merge from."),
QObject::tr("path"));
parser.addOption(keyFileFrom);

parser.addOption(samePasswordOption);
parser.process(arguments);

const QStringList args = parser.positionalArguments();
if (args.size() != 2) {
QCoreApplication app(argc, argv);
out << parser.helpText().replace("keepassxc-cli", "keepassxc-cli merge");
return EXIT_FAILURE;
}

Database* db1;
Database* db2;

if (parser.isSet("gui-prompt")) {
QApplication app(argc, argv);
db1 = UnlockDatabaseDialog::openDatabasePrompt(args.at(0));
if (!parser.isSet("same-password")) {
db2 = UnlockDatabaseDialog::openDatabasePrompt(args.at(1));
} else {
db2 = Database::openDatabaseFile(args.at(1), *(db1->key().clone()));
}
} else {
QCoreApplication app(argc, argv);
db1 = Database::unlockFromStdin(args.at(0));
if (!parser.isSet("same-password")) {
db2 = Database::unlockFromStdin(args.at(1));
} else {
db2 = Database::openDatabaseFile(args.at(1), *(db1->key().clone()));
}
}
Database* db1 = Database::unlockFromStdin(args.at(0), parser.value(keyFile));
if (db1 == nullptr) {
return EXIT_FAILURE;
}

Database* db2;
if (!parser.isSet("same-credentials")) {
db2 = Database::unlockFromStdin(args.at(1), parser.value(keyFileFrom));
} else {
db2 = Database::openDatabaseFile(args.at(1), *(db1->key().clone()));
}
if (db2 == nullptr) {
return EXIT_FAILURE;
}

db1->merge(db2);

QString errorMessage = db1->saveToFile(args.at(0));
if (!errorMessage.isEmpty()) {
qCritical("Unable to save database to file : %s", qPrintable(errorMessage));
Expand Down
2 changes: 1 addition & 1 deletion src/cli/Merge.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Merge : public Command
public:
Merge();
~Merge();
int execute(int argc, char** argv);
int execute(QStringList arguments);
};

#endif // KEEPASSXC_MERGE_H
Loading