Rename EntropyMeter -> Estimate (#1250)

* EntropyMeter -> Estimate
* Cleaning estimate
* Documentation
* clang-formatting /cli
This commit is contained in:
louib 2017-12-04 09:46:23 -05:00 committed by GitHub
parent 18c4df98ff
commit 471e684151
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 201 additions and 169 deletions

View File

@ -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

View File

@ -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();

View File

@ -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());

View File

@ -1,141 +0,0 @@
/*
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* 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 "EntropyMeter.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zxcvbn.h>
/* 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<int>(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<int>(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;
}

175
src/cli/Estimate.cpp Normal file
View File

@ -0,0 +1,175 @@
/*
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* 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 "Estimate.h"
#include <QCommandLineParser>
#include <QTextStream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zxcvbn.h>
/* 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<int>(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;
}

View File

@ -15,17 +15,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -85,7 +85,6 @@ int Extract::execute(QStringList arguments)
compositeKey.addKey(fileKey);
}
QString databaseFilename = args.at(0);
QFile dbFile(databaseFilename);
if (!dbFile.exists()) {

View File

@ -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."),

View File

@ -83,5 +83,4 @@ int Locate::locateEntry(Database* database, QString searchTerm)
outputTextStream << result << endl;
}
return EXIT_SUCCESS;
}

View File

@ -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;

View File

@ -27,7 +27,6 @@
#include <QProcess>
#include <QTextStream>
void Utils::setStdinEcho(bool enable = true)
{
#ifdef Q_OS_WIN

View File

@ -22,8 +22,8 @@ Copies the password of a database entry to the clipboard. If multiple entries wi
.IP "edit [options] <database> <entry>"
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] <database>"
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.