diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index 0ed5d991..e090ad1d 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -14,14 +14,16 @@ # along with this program. If not, see . set(cli_SOURCES + EntropyMeter.cpp + EntropyMeter.h + Extract.cpp + Extract.h List.cpp List.h Merge.cpp Merge.h - EntropyMeter.cpp - EntropyMeter.h - Extract.cpp - Extract.h) + Show.cpp + Show.h) add_library(cli STATIC ${cli_SOURCES}) target_link_libraries(cli Qt5::Core Qt5::Widgets) diff --git a/src/cli/Extract.cpp b/src/cli/Extract.cpp index 5bfb1185..81a9ddf0 100644 --- a/src/cli/Extract.cpp +++ b/src/cli/Extract.cpp @@ -38,7 +38,7 @@ int Extract::execute(int argc, char **argv) QCommandLineParser parser; parser.setApplicationDescription(QCoreApplication::translate("main", "Extract and print the content of a database.")); - parser.addPositionalArgument("database", QCoreApplication::translate("main", "path of the database to extract.")); + parser.addPositionalArgument("database", QCoreApplication::translate("main", "Path of the database to extract.")); parser.process(app); const QStringList args = parser.positionalArguments(); diff --git a/src/cli/List.cpp b/src/cli/List.cpp index 1702a469..cfeba3ce 100644 --- a/src/cli/List.cpp +++ b/src/cli/List.cpp @@ -65,7 +65,7 @@ int List::execute(int argc, char **argv) QCommandLineParser parser; parser.setApplicationDescription(QCoreApplication::translate("main", "List database entries.")); - parser.addPositionalArgument("database", QCoreApplication::translate("main", "path of the database.")); + parser.addPositionalArgument("database", QCoreApplication::translate("main", "Path of the database.")); parser.process(app); const QStringList args = parser.positionalArguments(); diff --git a/src/cli/Merge.cpp b/src/cli/Merge.cpp index 0f4a9011..404892f7 100644 --- a/src/cli/Merge.cpp +++ b/src/cli/Merge.cpp @@ -39,11 +39,11 @@ int Merge::execute(int argc, char** argv) QCommandLineParser parser; parser.setApplicationDescription(QCoreApplication::translate("main", "Merge two databases.")); - parser.addPositionalArgument("database1", QCoreApplication::translate("main", "path of the database to merge into.")); - parser.addPositionalArgument("database2", QCoreApplication::translate("main", "path of the database to merge from.")); + parser.addPositionalArgument("database1", QCoreApplication::translate("main", "Path of the database to merge into.")); + parser.addPositionalArgument("database2", QCoreApplication::translate("main", "Path of the database to merge from.")); QCommandLineOption samePasswordOption(QStringList() << "s" << "same-password", - QCoreApplication::translate("main", "use the same password for both database files.")); + QCoreApplication::translate("main", "Use the same password for both database files.")); parser.addOption(samePasswordOption); parser.process(app); diff --git a/src/cli/Show.cpp b/src/cli/Show.cpp new file mode 100644 index 00000000..c4a3b1ac --- /dev/null +++ b/src/cli/Show.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2017 KeePassXC Team + * + * 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 . + */ + +#include +#include + +#include "Show.h" + +#include +#include +#include +#include +#include + +#include "core/Database.h" +#include "core/Entry.h" +#include "core/Group.h" +#include "format/KeePass2Reader.h" +#include "keys/CompositeKey.h" + +int Show::execute(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + QTextStream out(stdout); + + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::translate("main", + "Show a password.")); + parser.addPositionalArgument("database", QCoreApplication::translate("main", "Path of the database.")); + parser.addPositionalArgument("uuid", QCoreApplication::translate("main", "Uuid of the entry to show")); + parser.process(app); + + const QStringList args = parser.positionalArguments(); + if (args.size() != 2) { + parser.showHelp(); + return EXIT_FAILURE; + } + + out << "Insert the database password\n> "; + out.flush(); + + static QTextStream inputTextStream(stdin, QIODevice::ReadOnly); + QString line = inputTextStream.readLine(); + CompositeKey key = CompositeKey::readFromLine(line); + + QString databaseFilename = args.at(0); + QFile dbFile(databaseFilename); + if (!dbFile.exists()) { + qCritical("File %s does not exist.", qPrintable(databaseFilename)); + return EXIT_FAILURE; + } + if (!dbFile.open(QIODevice::ReadOnly)) { + qCritical("Unable to open file %s.", qPrintable(databaseFilename)); + return EXIT_FAILURE; + } + + KeePass2Reader reader; + Database* db = reader.readDatabase(&dbFile, key); + + if (reader.hasError()) { + qCritical("Error while parsing the database:\n%s\n", qPrintable(reader.errorString())); + return EXIT_FAILURE; + } + + Uuid uuid = Uuid::fromHex(args.at(1)); + Entry* entry = db->resolveEntry(uuid); + out << entry->password() << "\n"; + return EXIT_SUCCESS; +} diff --git a/src/cli/Show.h b/src/cli/Show.h new file mode 100644 index 00000000..aa06b5c9 --- /dev/null +++ b/src/cli/Show.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 KeePassXC Team + * + * 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 . + */ + +#ifndef KEEPASSXC_SHOW_H +#define KEEPASSXC_SHOW_H + +class Show +{ +public: + static int execute(int argc, char** argv); +}; + +#endif // KEEPASSXC_SHOW_H diff --git a/src/cli/keepassxc-cli.cpp b/src/cli/keepassxc-cli.cpp index 85b679bd..1802870e 100644 --- a/src/cli/keepassxc-cli.cpp +++ b/src/cli/keepassxc-cli.cpp @@ -21,10 +21,12 @@ #include #include +#include +#include #include #include -#include -#include +#include + #include "config-keepassx.h" #include "core/Tools.h" #include "crypto/Crypto.h" @@ -51,6 +53,7 @@ int main(int argc, char **argv) description = description.append(QString("\n entropy-meter\tCalculate password entropy.")); description = description.append(QString("\n list\t\tList database entries.")); description = description.append(QString("\n merge\t\tMerge two databases.")); + description = description.append(QString("\n show\t\tShow a password.")); parser.setApplicationDescription(QCoreApplication::translate("main", qPrintable(description))); parser.addPositionalArgument("command", QCoreApplication::translate("main", "Name of the command to execute.")); @@ -73,6 +76,16 @@ int main(int argc, char **argv) ++argv; --argc; + if (commandName == "entropy-meter") { + argv[0] = const_cast("keepassxc-cli entropy-meter"); + return EntropyMeter::execute(argc, argv); + } + + if (commandName == "extract") { + argv[0] = const_cast("keepassxc-cli extract"); + return Extract::execute(argc, argv); + } + if (commandName == "list") { argv[0] = const_cast("keepassxc-cli list"); return List::execute(argc, argv); @@ -83,14 +96,9 @@ int main(int argc, char **argv) return Merge::execute(argc, argv); } - if (commandName == "extract") { - argv[0] = const_cast("keepassxc-cli extract"); - return Extract::execute(argc, argv); - } - - if (commandName == "entropy-meter") { - argv[0] = const_cast("keepassxc-cli entropy-meter"); - return EntropyMeter::execute(argc, argv); + if (commandName == "show") { + argv[0] = const_cast("keepassxc-cli show"); + return Show::execute(argc, argv); } qCritical("Invalid command %s.", qPrintable(commandName));