From 471e684151c90e35335a21e36d779cbdb3f8d61f Mon Sep 17 00:00:00 2001 From: louib Date: Mon, 4 Dec 2017 09:46:23 -0500 Subject: [PATCH 1/2] Rename EntropyMeter -> Estimate (#1250) * EntropyMeter -> Estimate * Cleaning estimate * Documentation * clang-formatting /cli --- src/cli/CMakeLists.txt | 4 +- src/cli/Clip.cpp | 4 +- src/cli/Command.cpp | 6 +- src/cli/EntropyMeter.cpp | 141 -------------------- src/cli/Estimate.cpp | 175 +++++++++++++++++++++++++ src/cli/{EntropyMeter.h => Estimate.h} | 12 +- src/cli/Extract.cpp | 1 - src/cli/List.cpp | 3 +- src/cli/Locate.cpp | 1 - src/cli/Merge.cpp | 12 +- src/cli/Utils.cpp | 1 - src/cli/keepassxc-cli.1 | 10 +- 12 files changed, 201 insertions(+), 169 deletions(-) delete mode 100644 src/cli/EntropyMeter.cpp create mode 100644 src/cli/Estimate.cpp rename src/cli/{EntropyMeter.h => Estimate.h} (81%) diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index e9f50d1a8..4c8620d55 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -22,8 +22,8 @@ set(cli_SOURCES Command.h Edit.cpp Edit.h - EntropyMeter.cpp - EntropyMeter.h + Estimate.cpp + Estimate.h Extract.cpp Extract.h List.cpp diff --git a/src/cli/Clip.cpp b/src/cli/Clip.cpp index d50b32f0c..dd51d7f0b 100644 --- a/src/cli/Clip.cpp +++ b/src/cli/Clip.cpp @@ -55,9 +55,7 @@ int Clip::execute(QStringList arguments) parser.addOption(keyFile); parser.addPositionalArgument("entry", QObject::tr("Path of the entry to clip.")); parser.addPositionalArgument( - "timeout", - QObject::tr("Timeout in seconds before clearing the clipboard."), - QString("[timeout]")); + "timeout", QObject::tr("Timeout in seconds before clearing the clipboard."), QString("[timeout]")); parser.process(arguments); const QStringList args = parser.positionalArguments(); diff --git a/src/cli/Command.cpp b/src/cli/Command.cpp index c7eff6b08..6ec07b7af 100644 --- a/src/cli/Command.cpp +++ b/src/cli/Command.cpp @@ -23,9 +23,9 @@ #include "Command.h" #include "Add.h" -#include "Edit.h" #include "Clip.h" -#include "EntropyMeter.h" +#include "Edit.h" +#include "Estimate.h" #include "Extract.h" #include "List.h" #include "Locate.h" @@ -62,7 +62,7 @@ void populateCommands() commands.insert(QString("add"), new Add()); commands.insert(QString("clip"), new Clip()); commands.insert(QString("edit"), new Edit()); - commands.insert(QString("entropy-meter"), new EntropyMeter()); + commands.insert(QString("estimate"), new Estimate()); commands.insert(QString("extract"), new Extract()); commands.insert(QString("locate"), new Locate()); commands.insert(QString("ls"), new List()); diff --git a/src/cli/EntropyMeter.cpp b/src/cli/EntropyMeter.cpp deleted file mode 100644 index 1632fe234..000000000 --- a/src/cli/EntropyMeter.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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 "EntropyMeter.h" - -#include -#include -#include -#include - -/* For pre-compiled headers under windows */ -#ifdef _WIN32 -#ifndef __MINGW32__ -#include "stdafx.h" -#endif -#endif - -EntropyMeter::EntropyMeter() -{ - this->name = QString("entropy-meter"); - this->description = QObject::tr("Calculate password entropy."); -} - -EntropyMeter::~EntropyMeter() -{ -} - -static void calculate(const char *pwd, int advanced) -{ - double e; - int len = strlen(pwd); - if (advanced == 0){ - e = ZxcvbnMatch(pwd, 0, 0); - printf("Pass '%s' \tLength %d\tEntropy %.3f\tLog10 %.3f\n", pwd, len, e, e * 0.301029996); - } else { - int ChkLen; - ZxcMatch_t *info, *p; - double m = 0.0; - e = ZxcvbnMatch(pwd, 0, &info); - for(p = info; p; p = p->Next) { - m += p->Entrpy; - } - m = e - m; - printf("Pass '%s' \tLength %d\tEntropy %.3f\tLog10 %.3f\n Multi-word extra bits %.1f\n", pwd, len, e, e * 0.301029996, m); - p = info; - ChkLen = 0; - while(p) { - int n; - switch(static_cast(p->Type)) - { - case BRUTE_MATCH: printf(" Type: Bruteforce "); break; - case DICTIONARY_MATCH: printf(" Type: Dictionary "); break; - case DICT_LEET_MATCH: printf(" Type: Dict+Leet "); break; - case USER_MATCH: printf(" Type: User Words "); break; - case USER_LEET_MATCH: printf(" Type: User+Leet "); break; - case REPEATS_MATCH: printf(" Type: Repeated "); break; - case SEQUENCE_MATCH: printf(" Type: Sequence "); break; - case SPATIAL_MATCH: printf(" Type: Spatial "); break; - case DATE_MATCH: printf(" Type: Date "); break; - case BRUTE_MATCH+MULTIPLE_MATCH: printf(" Type: Bruteforce(Rep)"); break; - case DICTIONARY_MATCH+MULTIPLE_MATCH: printf(" Type: Dictionary(Rep)"); break; - case DICT_LEET_MATCH+MULTIPLE_MATCH: printf(" Type: Dict+Leet(Rep) "); break; - case USER_MATCH+MULTIPLE_MATCH: printf(" Type: User Words(Rep)"); break; - case USER_LEET_MATCH+MULTIPLE_MATCH: printf(" Type: User+Leet(Rep) "); break; - case REPEATS_MATCH+MULTIPLE_MATCH: printf(" Type: Repeated(Rep) "); break; - case SEQUENCE_MATCH+MULTIPLE_MATCH: printf(" Type: Sequence(Rep) "); break; - case SPATIAL_MATCH+MULTIPLE_MATCH: printf(" Type: Spatial(Rep) "); break; - case DATE_MATCH+MULTIPLE_MATCH: printf(" Type: Date(Rep) "); break; - - default: printf(" Type: Unknown%d ", p->Type); break; - } - ChkLen += p->Length; - printf(" Length %d Entropy %6.3f (%.2f) ", p->Length, p->Entrpy, p->Entrpy * 0.301029996); - for(n = 0; n < p->Length; ++n, ++pwd) { - printf("%c", *pwd); - } - printf("\n"); - p = p->Next; - } - ZxcvbnFreeInfo(info); - if (ChkLen != len) - printf("*** Password length (%d) != sum of length of parts (%d) ***\n", len, ChkLen); - } -} - -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 = 0; - if (arguments.size() > 1 && arguments.at(1) == "-a") - { - advanced = 1; - arguments.removeAt(1); - } - i = 1; - if (i >= arguments.size()) - { - /* No test passwords on command line, so get them from stdin */ - char line[500]; - while(fgets(line, sizeof line, stdin)) - { - /* Drop the trailing newline character */ - for(i = 0; i < static_cast(sizeof line - 1); ++i) - { - if (line[i] < ' ') - { - line[i] = 0; - break; - } - } - if (line[0]) { - calculate(line,advanced); - printf("> "); - } - } - } - else - { - /* Do the test passwords on the command line */ - for(; i < arguments.size(); ++i) - { - calculate(arguments.at(i).toLatin1(), advanced); - } - } - return 0; -} diff --git a/src/cli/Estimate.cpp b/src/cli/Estimate.cpp new file mode 100644 index 000000000..fbab96962 --- /dev/null +++ b/src/cli/Estimate.cpp @@ -0,0 +1,175 @@ +/* + * 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 "Estimate.h" + +#include +#include + +#include +#include +#include +#include + +/* For pre-compiled headers under windows */ +#ifdef _WIN32 +#ifndef __MINGW32__ +#include "stdafx.h" +#endif +#endif + +Estimate::Estimate() +{ + this->name = QString("estimate"); + this->description = QObject::tr("Estimate the entropy of a password."); +} + +Estimate::~Estimate() +{ +} + +static void calculate(const char* pwd, bool advanced) +{ + double e; + int len = strlen(pwd); + if (!advanced) { + e = ZxcvbnMatch(pwd, 0, 0); + printf("Pass '%s' \tLength %d\tEntropy %.3f\tLog10 %.3f\n", pwd, len, e, e * 0.301029996); + } else { + int ChkLen; + ZxcMatch_t *info, *p; + double m = 0.0; + e = ZxcvbnMatch(pwd, 0, &info); + for (p = info; p; p = p->Next) { + m += p->Entrpy; + } + m = e - m; + printf("Pass '%s' \tLength %d\tEntropy %.3f\tLog10 %.3f\n Multi-word extra bits %.1f\n", + pwd, + len, + e, + e * 0.301029996, + m); + p = info; + ChkLen = 0; + while (p) { + int n; + switch (static_cast(p->Type)) { + case BRUTE_MATCH: + printf(" Type: Bruteforce "); + break; + case DICTIONARY_MATCH: + printf(" Type: Dictionary "); + break; + case DICT_LEET_MATCH: + printf(" Type: Dict+Leet "); + break; + case USER_MATCH: + printf(" Type: User Words "); + break; + case USER_LEET_MATCH: + printf(" Type: User+Leet "); + break; + case REPEATS_MATCH: + printf(" Type: Repeated "); + break; + case SEQUENCE_MATCH: + printf(" Type: Sequence "); + break; + case SPATIAL_MATCH: + printf(" Type: Spatial "); + break; + case DATE_MATCH: + printf(" Type: Date "); + break; + case BRUTE_MATCH + MULTIPLE_MATCH: + printf(" Type: Bruteforce(Rep)"); + break; + case DICTIONARY_MATCH + MULTIPLE_MATCH: + printf(" Type: Dictionary(Rep)"); + break; + case DICT_LEET_MATCH + MULTIPLE_MATCH: + printf(" Type: Dict+Leet(Rep) "); + break; + case USER_MATCH + MULTIPLE_MATCH: + printf(" Type: User Words(Rep)"); + break; + case USER_LEET_MATCH + MULTIPLE_MATCH: + printf(" Type: User+Leet(Rep) "); + break; + case REPEATS_MATCH + MULTIPLE_MATCH: + printf(" Type: Repeated(Rep) "); + break; + case SEQUENCE_MATCH + MULTIPLE_MATCH: + printf(" Type: Sequence(Rep) "); + break; + case SPATIAL_MATCH + MULTIPLE_MATCH: + printf(" Type: Spatial(Rep) "); + break; + case DATE_MATCH + MULTIPLE_MATCH: + printf(" Type: Date(Rep) "); + break; + + default: + printf(" Type: Unknown%d ", p->Type); + break; + } + ChkLen += p->Length; + printf(" Length %d Entropy %6.3f (%.2f) ", p->Length, p->Entrpy, p->Entrpy * 0.301029996); + for (n = 0; n < p->Length; ++n, ++pwd) { + printf("%c", *pwd); + } + printf("\n"); + p = p->Next; + } + ZxcvbnFreeInfo(info); + if (ChkLen != len) { + printf("*** Password length (%d) != sum of length of parts (%d) ***\n", len, ChkLen); + } + } +} + +int Estimate::execute(QStringList arguments) +{ + QTextStream inputTextStream(stdin, QIODevice::ReadOnly); + QTextStream outputTextStream(stdout, QIODevice::WriteOnly); + + QCommandLineParser parser; + parser.setApplicationDescription(this->description); + parser.addPositionalArgument("password", QObject::tr("Password for which to estimate the entropy."), "[password]"); + QCommandLineOption advancedOption(QStringList() << "a" + << "advanced", + QObject::tr("Perform advanced analysis on the password.")); + parser.addOption(advancedOption); + parser.process(arguments); + + const QStringList args = parser.positionalArguments(); + if (args.size() > 1) { + outputTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli estimate"); + return EXIT_FAILURE; + } + + QString password; + if (args.size() == 1) { + password = args.at(0); + } else { + password = inputTextStream.readLine(); + } + + calculate(password.toLatin1(), parser.isSet(advancedOption)); + return EXIT_SUCCESS; +} diff --git a/src/cli/EntropyMeter.h b/src/cli/Estimate.h similarity index 81% rename from src/cli/EntropyMeter.h rename to src/cli/Estimate.h index 614e2de35..2cbe49104 100644 --- a/src/cli/EntropyMeter.h +++ b/src/cli/Estimate.h @@ -15,17 +15,17 @@ * along with this program. If not, see . */ -#ifndef KEEPASSXC_ENTROPYMETER_H -#define KEEPASSXC_ENTROPYMETER_H +#ifndef KEEPASSXC_ESTIMATE_H +#define KEEPASSXC_ESTIMATE_H #include "Command.h" -class EntropyMeter : public Command +class Estimate : public Command { public: - EntropyMeter(); - ~EntropyMeter(); + Estimate(); + ~Estimate(); int execute(QStringList arguments); }; -#endif // KEEPASSXC_ENTROPYMETER_H +#endif // KEEPASSXC_ESTIMATE_H diff --git a/src/cli/Extract.cpp b/src/cli/Extract.cpp index 2d519f9a1..73879f67d 100644 --- a/src/cli/Extract.cpp +++ b/src/cli/Extract.cpp @@ -85,7 +85,6 @@ int Extract::execute(QStringList arguments) compositeKey.addKey(fileKey); } - QString databaseFilename = args.at(0); QFile dbFile(databaseFilename); if (!dbFile.exists()) { diff --git a/src/cli/List.cpp b/src/cli/List.cpp index 63e48ee22..73830cab8 100644 --- a/src/cli/List.cpp +++ b/src/cli/List.cpp @@ -44,8 +44,7 @@ int List::execute(QStringList arguments) 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]")); + parser.addPositionalArgument("group", QObject::tr("Path of the group to list. Default is /"), QString("[group]")); QCommandLineOption keyFile(QStringList() << "k" << "key-file", QObject::tr("Key file of the database."), diff --git a/src/cli/Locate.cpp b/src/cli/Locate.cpp index bb9831be1..83a3c5ce0 100644 --- a/src/cli/Locate.cpp +++ b/src/cli/Locate.cpp @@ -83,5 +83,4 @@ int Locate::locateEntry(Database* database, QString searchTerm) outputTextStream << result << endl; } return EXIT_SUCCESS; - } diff --git a/src/cli/Merge.cpp b/src/cli/Merge.cpp index a713cbb33..5df6b0188 100644 --- a/src/cli/Merge.cpp +++ b/src/cli/Merge.cpp @@ -43,10 +43,9 @@ int Merge::execute(QStringList arguments) parser.addPositionalArgument("database1", QObject::tr("Path of the database to merge into.")); parser.addPositionalArgument("database2", QObject::tr("Path of the database to merge from.")); - QCommandLineOption samePasswordOption( - QStringList() << "s" - << "same-credentials", - QObject::tr("Use the same credentials for both database files.")); + QCommandLineOption samePasswordOption(QStringList() << "s" + << "same-credentials", + QObject::tr("Use the same credentials for both database files.")); QCommandLineOption keyFile(QStringList() << "k" << "key-file", @@ -55,8 +54,8 @@ int Merge::execute(QStringList arguments) parser.addOption(keyFile); QCommandLineOption keyFileFrom(QStringList() << "f" << "key-file-from", - QObject::tr("Key file of the database to merge from."), - QObject::tr("path")); + QObject::tr("Key file of the database to merge from."), + QObject::tr("path")); parser.addOption(keyFileFrom); parser.addOption(samePasswordOption); @@ -68,7 +67,6 @@ int Merge::execute(QStringList arguments) return EXIT_FAILURE; } - Database* db1 = Database::unlockFromStdin(args.at(0), parser.value(keyFile)); if (db1 == nullptr) { return EXIT_FAILURE; diff --git a/src/cli/Utils.cpp b/src/cli/Utils.cpp index b9866a1a2..f42095cbb 100644 --- a/src/cli/Utils.cpp +++ b/src/cli/Utils.cpp @@ -27,7 +27,6 @@ #include #include - void Utils::setStdinEcho(bool enable = true) { #ifdef Q_OS_WIN diff --git a/src/cli/keepassxc-cli.1 b/src/cli/keepassxc-cli.1 index 940b3d4cf..37127abc7 100644 --- a/src/cli/keepassxc-cli.1 +++ b/src/cli/keepassxc-cli.1 @@ -22,8 +22,8 @@ Copies the password of a database entry to the clipboard. If multiple entries wi .IP "edit [options] " Edits a database entry. A password can be generated (\fI-g\fP option), or a prompt can be displayed to input the password (\fI-p\fP option). -.IP "entropy-meter [-a pwd1 pwd2 ...]" -Calculates the entropy of a single, or multiple passwords specified using the \fI-a\fP option. If no passwords are specified, the program will run in interactive mode and prompt the user to enter a password. +.IP "estimate [options] [password]" +Estimates the entropy of a password. The password to estimate can be provided as a positional argument, or using the standard input. .IP "extract [options] " Extracts and prints the contents of a database to standard output in XML format. @@ -90,6 +90,12 @@ Specify the length of the password to generate. Specify the title of the entry. +.SS "Estimate options" + +.IP "-a, --advanced" +Perform advanced analysis on the password. + + .SH REPORTING BUGS Bugs and feature requests can be reported on GitHub at https://github.com/keepassxreboot/keepassxc/issues. From afe2967473dd6b6e23b81b2dbbab7d5402f71a1b Mon Sep 17 00:00:00 2001 From: Jean-Louis Dupond Date: Sat, 28 Oct 2017 20:10:59 +0200 Subject: [PATCH 2/2] Add WMClass to the desktop file to have proper linking to the desktop file --- share/linux/org.keepassxc.KeePassXC.desktop | 1 + 1 file changed, 1 insertion(+) diff --git a/share/linux/org.keepassxc.KeePassXC.desktop b/share/linux/org.keepassxc.KeePassXC.desktop index d3b007bdc..8a0169800 100644 --- a/share/linux/org.keepassxc.KeePassXC.desktop +++ b/share/linux/org.keepassxc.KeePassXC.desktop @@ -9,6 +9,7 @@ Comment=Community-driven port of the Windows application “KeePass Password Saf Exec=keepassxc %f TryExec=keepassxc Icon=keepassxc +StartupWMClass=keepassxc Terminal=false Type=Application Version=1.0