mirror of
https://github.com/monero-project/monero-gui.git
synced 2024-12-23 12:09:57 +00:00
Merge pull request #292
9be29eb
zxcvbn: build tweaks to work on other platforms (moneromooo.monero)03c15af
Don't claim a password is "medium" too easily (moneromooo.monero)fbe19d2
Use zxcvbn for password strength estimation (moneromooo.monero)b882de8
add zxcvbn to the qmake build system (moneromooo.monero)aae35df
zxcvbn-c: new module for password strength estimation (moneromooo.monero)
This commit is contained in:
commit
d1b240fca7
21 changed files with 284648 additions and 39 deletions
4
build.sh
4
build.sh
|
@ -17,6 +17,9 @@ if [ ! -d $MONERO_DIR ]; then
|
|||
$SHELL get_libwallet_api.sh $BUILD_TYPE
|
||||
fi
|
||||
|
||||
# build zxcvbn
|
||||
make -C src/zxcvbn-c
|
||||
|
||||
if [ ! -d build ]; then mkdir build; fi
|
||||
|
||||
if [ "$BUILD_TYPE" == "Release" ]; then
|
||||
|
@ -27,7 +30,6 @@ else
|
|||
BIN_PATH=debug/bin
|
||||
fi
|
||||
|
||||
|
||||
# Platform indepenent settings
|
||||
platform=$(get_platform)
|
||||
if [ "$platform" == "linux32" ] || [ "$platform" == "linux64" ]; then
|
||||
|
|
|
@ -72,7 +72,7 @@ Item {
|
|||
width: row.x
|
||||
|
||||
color: {
|
||||
if(item.fillLevel < 3) return "#FF6C3C"
|
||||
if(item.fillLevel < 5) return "#FF6C3C"
|
||||
if(item.fillLevel < 13) return "#FFE00A"
|
||||
return "#36B25C"
|
||||
}
|
||||
|
|
|
@ -34,7 +34,8 @@ HEADERS += \
|
|||
src/QR-Code-generator/QrSegment.hpp \
|
||||
src/daemon/DaemonManager.h \
|
||||
src/model/AddressBookModel.h \
|
||||
src/libwalletqt/AddressBook.h
|
||||
src/libwalletqt/AddressBook.h \
|
||||
src/zxcvbn-c/zxcvbn.h
|
||||
|
||||
|
||||
SOURCES += main.cpp \
|
||||
|
@ -56,7 +57,8 @@ SOURCES += main.cpp \
|
|||
src/QR-Code-generator/QrSegment.cpp \
|
||||
src/daemon/DaemonManager.cpp \
|
||||
src/model/AddressBookModel.cpp \
|
||||
src/libwalletqt/AddressBook.cpp
|
||||
src/libwalletqt/AddressBook.cpp \
|
||||
src/zxcvbn-c/zxcvbn.c
|
||||
|
||||
lupdate_only {
|
||||
SOURCES = *.qml \
|
||||
|
@ -236,7 +238,6 @@ QMAKE_EXTRA_COMPILERS += langrel
|
|||
|
||||
PRE_TARGETDEPS += langupd compiler_langrel_make_all
|
||||
|
||||
|
||||
RESOURCES += qml.qrc
|
||||
|
||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "WalletManager.h"
|
||||
#include "Wallet.h"
|
||||
#include "wallet/wallet2_api.h"
|
||||
#include "zxcvbn-c/zxcvbn.h"
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
|
@ -241,6 +242,21 @@ QUrl WalletManager::localPathToUrl(const QString &path) const
|
|||
return QUrl::fromLocalFile(path);
|
||||
}
|
||||
|
||||
double WalletManager::getPasswordStrength(const QString &password) const
|
||||
{
|
||||
static const char *local_dict[] = {
|
||||
"monero", "fluffypony", NULL
|
||||
};
|
||||
|
||||
if (!ZxcvbnInit("zxcvbn.dict")) {
|
||||
fprintf(stderr, "Failed to open zxcvbn.dict\n");
|
||||
return 0.0;
|
||||
}
|
||||
double e = ZxcvbnMatch(password.toStdString().c_str(), local_dict, NULL);
|
||||
ZxcvbnUnInit();
|
||||
return e;
|
||||
}
|
||||
|
||||
WalletManager::WalletManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
m_pimpl = Monero::WalletManagerFactory::getWalletManager();
|
||||
|
|
|
@ -114,6 +114,8 @@ public:
|
|||
Q_INVOKABLE qint64 addi(qint64 x, qint64 y) const { return x + y; }
|
||||
Q_INVOKABLE qint64 subi(qint64 x, qint64 y) const { return x - y; }
|
||||
|
||||
Q_INVOKABLE double getPasswordStrength(const QString &password) const;
|
||||
|
||||
signals:
|
||||
|
||||
void walletOpened(Wallet * wallet);
|
||||
|
|
28
src/zxcvbn-c/.gitignore
vendored
Normal file
28
src/zxcvbn-c/.gitignore
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
*.gch
|
||||
*.pch
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
test.cpp
|
||||
zxcvbn.cpp
|
||||
zxcvbn.dict
|
||||
test-*file
|
||||
test-*line
|
||||
test-*lib
|
||||
dictgen
|
||||
dict-*.h
|
86
src/zxcvbn-c/README.md
Normal file
86
src/zxcvbn-c/README.md
Normal file
|
@ -0,0 +1,86 @@
|
|||
# zxcvbn-c
|
||||
This is a C/C++ implementation of the zxcvbn password strength estimation.
|
||||
|
||||
The code is intended to be included as part of the source of a C/C++ program. Like the
|
||||
original this code is for character sets which use single byte characters primarily in the
|
||||
code range 0x20 to 0x7E.
|
||||
|
||||
The original coffee script version is available at
|
||||
https://github.com/lowe/zxcvbn
|
||||
|
||||
An article on the reasons for zxcvbn is at
|
||||
https://tech.dropox.com/2012/04/zxcvbn-realistic-password-strength-estimation
|
||||
|
||||
##Building
|
||||
|
||||
The makefile will build several test programs to test the code. It shows the steps needed
|
||||
to use the code in C and C++ programs, using the dictionary data read from file or included
|
||||
within the program executable.
|
||||
The makefile has only been tried on Linux using GCC version 4.8.4, but should be faily
|
||||
portable to other systems.
|
||||
|
||||
When dictionary data is included in your program's executable, the files `zxcvbn.c` ,
|
||||
`zxcvbn.h` , `dict-src.h` are used in your program.
|
||||
|
||||
When dictionary data is read from file, the files `zxcvbn.c` , `zxcvbn.h` , `dict-crc.h`
|
||||
and `zxcvbn.dict` are used in your program, compiled with `#define USE_DICT_FILE`. The CRC
|
||||
of the dictionary data file is written to `dict-crc.h` so your executable can detect
|
||||
corruption of the data.
|
||||
|
||||
Rename `zxcvbn.c` to `zxcvbn.cpp` (or whatever your compiler uses) to compile as C++.
|
||||
|
||||
The `dict*.h` and `zxcvbn.dict` files are generated by the dictgen program compiled from
|
||||
dict-generate.cpp (see makefile for details).
|
||||
|
||||
##Using
|
||||
|
||||
Initially call `ZxcvbnInit()` with the pathname of the `zxcvbn.dict` file. This can be
|
||||
omitted when dictionary data is included in the executable.
|
||||
|
||||
Call `ZxcvbnMatch()` with the password and optional user dictionary to get the entropy
|
||||
estimation and optional information on the password parts (which will need freeing with
|
||||
`ZxcvbnFreeInfo()` after use). Do this for each password to be tested, or as each character
|
||||
of it is entered into your program. The optional user dictionary can change between each
|
||||
call.
|
||||
|
||||
Finally call `ZxcvbnUninit()` to free the dictionary data from read from file. This can be
|
||||
omitted when dictionary data is included in the executable.
|
||||
|
||||
Review the test program in `test.c` for an example.
|
||||
|
||||
|
||||
## Differences from the original version.
|
||||
|
||||
The entropy calculated will sometimes differ from the original because of
|
||||
|
||||
* The UK keyboard layout is also included, so there are additional spacial sequences, e.g.
|
||||
**;'#** is a spacial sequence.
|
||||
* The different character classes in a password are taken into account when calculating the
|
||||
strength of brute-force matches.
|
||||
* Dijktra's path searching algorithm is used to combine parts of the entered password. This
|
||||
can result in the found parts of the password being combined differently than the
|
||||
original coffee script. E.g. the password **passwordassword**
|
||||
is combined by the original coffee script as **p** (3.5 bits) + **asswordassword** (12.6
|
||||
bits) + multiple part allowance (1.0bit) to give total entropy of 17.1 bits. This
|
||||
implementation combines it as **password** (1.0 bit) + **assword** (11.6 bits) + multiple
|
||||
part allowance (1.0bit) to give 13.6 bits.
|
||||
* For multi part passwords the original coffee script version multiplies the number of
|
||||
guesses needed by the factorial of the number of parts. This is not possible in this
|
||||
version as Dijktra's algorithm is used. Instead one bit entropy is added for the part at the
|
||||
end of the password, 1.7 bits for each part in the middle of a password and nothing
|
||||
for the part at the beginning. This gives similar results compared to the coffee script
|
||||
version when there are 4 or less parts, but will differ significantly when there are many
|
||||
parts (which is likely to be a rare occurrence).
|
||||
|
||||
|
||||
##References
|
||||
|
||||
The original coffee-script version is available at
|
||||
https://github.com/lowe/zxcvbn
|
||||
|
||||
The dictionary words are taken from the original coffee script version.
|
||||
|
||||
Dictionary trie encoding (used for by the word lookup code) based on idea from the Caroline
|
||||
Word Graph from
|
||||
http://www.pathcom.com/~vadco/cwg.html
|
||||
|
1762
src/zxcvbn-c/dict-generate.cpp
Normal file
1762
src/zxcvbn-c/dict-generate.cpp
Normal file
File diff suppressed because it is too large
Load diff
104
src/zxcvbn-c/makefile
Normal file
104
src/zxcvbn-c/makefile
Normal file
|
@ -0,0 +1,104 @@
|
|||
CFLAGS ?= -O2 -Wall -Wextra -Wdeclaration-after-statement
|
||||
CXXFLAGS ?= -O2 -Wall -Wextra
|
||||
|
||||
# default programs
|
||||
CC ?= gcc
|
||||
AR ?= ar
|
||||
CXX ?= g++
|
||||
|
||||
# need zxcvbn.h prior to package installation
|
||||
CPPFLAGS += -I.
|
||||
|
||||
# library metadata
|
||||
TARGET_LIB = libzxcvbn.so.0.0.0
|
||||
SONAME = libzxcvbn.so.0
|
||||
|
||||
WORDS = words-eng_wiki.txt words-female.txt words-male.txt words-passwd.txt words-surname.txt words-tv_film.txt
|
||||
|
||||
#all: test-file test-inline test-c++inline test-c++file test-shlib test-statlib
|
||||
all: test-statlib
|
||||
|
||||
test-shlib: test.c $(TARGET_LIB)
|
||||
if [ ! -e libzxcvbn.so ]; then ln -s $(TARGET_LIB) libzxcvbn.so; fi
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -L. $(LDFLAGS) libzxcvbn.so -lm
|
||||
|
||||
$(TARGET_LIB): zxcvbn-inline-pic.o
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) \
|
||||
-o $@ $^ -fPIC -shared -Wl,-soname,$(SONAME) $(LDFLAGS) -lm
|
||||
if [ ! -e $(SONAME) ]; then ln -s $(TARGET_LIB) $(SONAME); fi
|
||||
|
||||
test-statlib: test.c libzxcvbn.a
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lm
|
||||
|
||||
libzxcvbn.a: zxcvbn-inline.o
|
||||
$(AR) cvq $@ $^
|
||||
|
||||
test-file: test.c zxcvbn-file.o
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) \
|
||||
-DUSE_DICT_FILE -o test-file test.c zxcvbn-file.o $(LDFLAGS) -lm
|
||||
|
||||
zxcvbn-file.o: zxcvbn.c dict-crc.h zxcvbn.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) \
|
||||
-DUSE_DICT_FILE -c -o zxcvbn-file.o zxcvbn.c
|
||||
|
||||
test-inline: test.c zxcvbn-inline.o
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) \
|
||||
-o test-inline test.c zxcvbn-inline.o $(LDFLAGS) -lm
|
||||
|
||||
zxcvbn-inline-pic.o: zxcvbn.c dict-src.h zxcvbn.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -c -o $@ $<
|
||||
|
||||
zxcvbn-inline.o: zxcvbn.c dict-src.h zxcvbn.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o zxcvbn-inline.o zxcvbn.c
|
||||
|
||||
dict-src.h: dictgen $(WORDS)
|
||||
./dictgen -o dict-src.h $(WORDS)
|
||||
|
||||
dict-crc.h: dictgen $(WORDS)
|
||||
./dictgen -b -o zxcvbn.dict -h dict-crc.h $(WORDS)
|
||||
|
||||
dictgen: dict-generate.cpp makefile
|
||||
$(CXX) $(CPPFLAGS) -std=c++11 $(CXXFLAGS) \
|
||||
-o dictgen dict-generate.cpp $(LDFLAGS)
|
||||
|
||||
test-c++inline: test.c zxcvbn-c++inline.o
|
||||
if [ ! -e test.cpp ]; then ln -s test.c test.cpp; fi
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) \
|
||||
-o test-c++inline test.cpp zxcvbn-c++inline.o $(LDFLAGS) -lm
|
||||
|
||||
zxcvbn-c++inline.o: zxcvbn.c dict-src.h zxcvbn.h
|
||||
if [ ! -e zxcvbn.cpp ]; then ln -s zxcvbn.c zxcvbn.cpp; fi
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) \
|
||||
-c -o zxcvbn-c++inline.o zxcvbn.cpp
|
||||
|
||||
test-c++file: test.c zxcvbn-c++file.o
|
||||
if [ ! -e test.cpp ]; then ln -s test.c test.cpp; fi
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) \
|
||||
-DUSE_DICT_FILE -o test-c++file test.cpp zxcvbn-c++file.o $(LDFLAGS) -lm
|
||||
|
||||
zxcvbn-c++file.o: zxcvbn.c dict-crc.h zxcvbn.h
|
||||
if [ ! -e zxcvbn.cpp ]; then ln -s zxcvbn.c zxcvbn.cpp; fi
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) \
|
||||
-DUSE_DICT_FILE -c -o zxcvbn-c++file.o zxcvbn.cpp
|
||||
|
||||
test: test-file test-inline test-c++inline test-c++file test-shlib test-statlib testcases.txt
|
||||
@echo Testing C build, dictionary from file
|
||||
./test-file -t testcases.txt
|
||||
@echo Testing C build, dictionary in executable
|
||||
./test-inline -t testcases.txt
|
||||
@echo Testing C shlib, dictionary in shlib
|
||||
LD_LIBRARY_PATH=. ./test-shlib -t testcases.txt
|
||||
@echo Testing C static lib, dictionary in lib
|
||||
./test-statlib -t testcases.txt
|
||||
@echo Testing C++ build, dictionary from file
|
||||
./test-c++file -t testcases.txt
|
||||
@echo Testing C++ build, dictionary in executable
|
||||
./test-c++inline -t testcases.txt
|
||||
@echo Finished
|
||||
|
||||
clean:
|
||||
rm -f test-file zxcvbn-file.o test-c++file zxcvbn-c++file.o
|
||||
rm -f test-inline zxcvbn-inline.o zxcvbn-inline-pic.o test-c++inline zxcvbn-c++inline.o
|
||||
rm -f dict-*.h zxcvbn.dict zxcvbn.cpp test.cpp
|
||||
rm -f dictgen
|
||||
rm -f ${TARGET_LIB} ${SONAME} libzxcvbn.so test-shlib libzxcvbn.a test-statlib
|
281
src/zxcvbn-c/test.c
Normal file
281
src/zxcvbn-c/test.c
Normal file
|
@ -0,0 +1,281 @@
|
|||
/**********************************************************************************
|
||||
* Program to test the C implementation of the zxcvbn password strength estimator.
|
||||
* Copyright (c) 2015, Tony Evans
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
**********************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <zxcvbn.h>
|
||||
|
||||
const char *UsrDict[] =
|
||||
{
|
||||
"Onename.Twoname@example.com", "Onename", "Twoname", "example.com", "example",
|
||||
0
|
||||
};
|
||||
|
||||
static void CalcPass(const char *Pwd, int Quiet)
|
||||
{
|
||||
double e;
|
||||
if (!Quiet)
|
||||
{
|
||||
/* Output the details of how the entropy figure was calculated */
|
||||
int Len, ChkLen;
|
||||
struct timeval t1, t2;
|
||||
ZxcMatch_t *Info, *p;
|
||||
double m = 0.0;
|
||||
|
||||
gettimeofday(&t1, 0);
|
||||
e = ZxcvbnMatch(Pwd, UsrDict, &Info);
|
||||
gettimeofday(&t2, 0);
|
||||
for(p = Info; p; p = p->Next)
|
||||
m += p->Entrpy;
|
||||
|
||||
Len = strlen(Pwd);
|
||||
m = e - m;
|
||||
printf("Pass %s \tLength %d\tEntropy bits=%.3f log10=%.3f\tMulti-word extra bits=%.1f\n", Pwd, Len, e, e * 0.301029996, m);
|
||||
p = Info;
|
||||
ChkLen = 0;
|
||||
while(p)
|
||||
{
|
||||
int n;
|
||||
switch((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);
|
||||
t2.tv_sec -= t1.tv_sec;
|
||||
t2.tv_usec -= t1.tv_usec;
|
||||
t2.tv_usec += t2.tv_sec * 1000000;
|
||||
printf(" Calculation Time %.2fms\n", t2.tv_usec/1000.0);
|
||||
if (ChkLen != Len)
|
||||
printf("*** Password length (%d) != sum of length of parts (%d) ***\n", Len, ChkLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Only get the final entropy figure */
|
||||
e = ZxcvbnMatch(Pwd, UsrDict, 0);
|
||||
printf("Pass %s \tEntropy %.3f\n", Pwd, e);
|
||||
}
|
||||
}
|
||||
|
||||
int DoChecks(char *file)
|
||||
{
|
||||
char Line[500];
|
||||
int y = 0;
|
||||
int w = 0;
|
||||
int r = 0;
|
||||
FILE *f = fopen(file, "r");
|
||||
if (f == NULL)
|
||||
{
|
||||
printf("Failed to open %s\n", file);
|
||||
return 1;
|
||||
}
|
||||
memset(Line, 0, sizeof Line);
|
||||
while(fgets(Line, sizeof Line - 4, f))
|
||||
{
|
||||
/* Line is password + whitespace + expected entropy */
|
||||
char *Pwd, *s, *t;
|
||||
double Ent, e, x;
|
||||
unsigned int i;
|
||||
++y;
|
||||
for(i = 0; i < sizeof Line - 5; ++i)
|
||||
{
|
||||
if (!Line[i] || (Line[i] == '\n'))
|
||||
break;
|
||||
}
|
||||
/* Skip blank lines or those starting with # */
|
||||
if ((i < 3) || (Line[0] == '#'))
|
||||
continue;
|
||||
memset(Line + i, 0, 4);
|
||||
Pwd = Line;
|
||||
/* Skip leading whitespace */
|
||||
while(*Pwd && (*Pwd <= ' '))
|
||||
++Pwd;
|
||||
|
||||
/* Make password null termnated */
|
||||
s = Pwd;
|
||||
t = strchr(s, '\t');
|
||||
if (t == NULL)
|
||||
t = strstr(s, " ");
|
||||
if (t == NULL)
|
||||
{
|
||||
printf("Bad test condition on line %d\n", y);
|
||||
r = 1;
|
||||
break;
|
||||
}
|
||||
*t++ = 0;
|
||||
|
||||
/* Skip whitespace before entropy value */
|
||||
while(*t && (*t <= ' '))
|
||||
++t;
|
||||
if (!*t)
|
||||
{
|
||||
printf("Bad test condition on line %d\n", y);
|
||||
r = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
Ent = atof(t);
|
||||
if ((Ent < 0.0) || (Ent > 1000.0))
|
||||
{
|
||||
printf("Bad entropy value on line %d\n", y);
|
||||
r = 1;
|
||||
break;
|
||||
}
|
||||
e = ZxcvbnMatch(Pwd, UsrDict, 0);
|
||||
x = e / Ent;
|
||||
/* More than 1% difference is a fail. */
|
||||
if ((x > 1.01) || (x < 1.0/1.01))
|
||||
{
|
||||
printf("Line %2d Calculated entropy %5.2f, expected %5.2f <%s>\n", y, e, Ent, Pwd);
|
||||
r = 1;
|
||||
break;
|
||||
}
|
||||
++w;
|
||||
}
|
||||
fclose(f);
|
||||
if (!r)
|
||||
printf("Tested %d words\n", w);
|
||||
return r;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, Quiet, Checks, White;
|
||||
Quiet = 0;
|
||||
Checks = 0;
|
||||
White = 0;
|
||||
if (!ZxcvbnInit("zxcvbn.dict"))
|
||||
{
|
||||
printf("Failed to open dictionary file\n");
|
||||
return 1;
|
||||
}
|
||||
if ((argc > 1) && (argv[1][0] == '-'))
|
||||
{
|
||||
if (!strcmp(argv[1], "-qs") || !strcmp(argv[1], "-sq"))
|
||||
Quiet = White = 1;
|
||||
if (!strcmp(argv[1], "-t"))
|
||||
Checks = 1;
|
||||
if (!strcmp(argv[1], "-q"))
|
||||
Quiet = 1;
|
||||
if (!strcmp(argv[1], "-s"))
|
||||
White = 1;
|
||||
if ((Checks + Quiet + White) == 0)
|
||||
{
|
||||
char *s = strrchr(argv[0], '/');
|
||||
if (s == NULL)
|
||||
s = argv[0];
|
||||
else
|
||||
++s;
|
||||
printf( "Usage: %s [ -q | -qs ] [ pwd1 pwd2 ... ]\n"
|
||||
" Output entropy of given passwords. If no passwords on command line read\n"
|
||||
" them from stdin.\n"
|
||||
" -q option stops password analysis details from being output.\n"
|
||||
" -s Ignore anything from space on a line when reading from stdin.\n"
|
||||
" %s -t file\n"
|
||||
" Read the file and check for correct results.\n", s, s);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (Checks)
|
||||
{
|
||||
for(i = 2; i < argc; ++i)
|
||||
{
|
||||
Checks = DoChecks(argv[i]);
|
||||
if (Checks)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
i = 1+Quiet;
|
||||
if (i >= argc)
|
||||
{
|
||||
/* 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 < (int)(sizeof Line - 1); ++i)
|
||||
{
|
||||
if (Line[i] < ' ')
|
||||
{
|
||||
Line[i] = 0;
|
||||
break;
|
||||
}
|
||||
if (White && (Line[i] == ' '))
|
||||
{
|
||||
Line[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Line[0])
|
||||
CalcPass(Line, Quiet);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do the test passwords on the command line */
|
||||
for(; i < argc; ++i)
|
||||
{
|
||||
CalcPass(argv[i], Quiet);
|
||||
}
|
||||
}
|
||||
ZxcvbnUnInit();
|
||||
return 0;
|
||||
}
|
62
src/zxcvbn-c/testcases.txt
Normal file
62
src/zxcvbn-c/testcases.txt
Normal file
|
@ -0,0 +1,62 @@
|
|||
zxcvbn 5.83
|
||||
qwER43@! 26.44
|
||||
Tr0ub4dour&3 30.87
|
||||
archi 13.61
|
||||
|
||||
D0g.................. 19.02
|
||||
abcdefghijk987654321 8.53
|
||||
neverforget13/3/1997 34.86
|
||||
1qaz2wsx3edc 9.98
|
||||
barbarbara 12.43
|
||||
abarbarbara 16.18
|
||||
|
||||
temppass22 17.20
|
||||
briansmith 5.32
|
||||
htimsnairb 6.07
|
||||
briansmith4mayor 21.63
|
||||
password1 4.0
|
||||
viking 7.93
|
||||
thx1138 7.70
|
||||
ScoRpi0ns 19.54
|
||||
do you know 25.51
|
||||
|
||||
ryanhunter2000 20.8
|
||||
rianhunter2000 28.25
|
||||
|
||||
asdfghju7654rewq 29.57
|
||||
AOEUIDHG&*()LS_ 33.33
|
||||
|
||||
12345678 1.59
|
||||
defghi6789 13.61
|
||||
02468 3.32
|
||||
adgjmpsvy 4.17
|
||||
|
||||
rosebud 8.09
|
||||
Rosebud 9.09
|
||||
ROSEBUD 9.09
|
||||
rosebuD 9.09
|
||||
R0$38uD 12.09
|
||||
ros3bud99 14.41
|
||||
r0s3bud99 14.41
|
||||
R0$38uD99 17.41
|
||||
|
||||
verlineVANDERMARK 27.24
|
||||
|
||||
eheuczkqyq 41.24
|
||||
rWibMFACxAUGZmxhVncy 111.0
|
||||
|
||||
illness 11.26
|
||||
1llness 12.26
|
||||
i1lness 12.84
|
||||
11lness 22.44
|
||||
ssenl1i 12.84
|
||||
Ba9ZyWABu99[BK#6MBgbH88Tofv)vs$w 171.63
|
||||
correcthorsebatterystaple 47.98
|
||||
elpatsyrettabesrohtcerroc 48.98
|
||||
coRrecth0rseba++ery9.23.2007staple$ 71.95
|
||||
|
||||
pass.word.pass.word.pass.word. 60.41
|
||||
passpasswordword 17.28
|
||||
quvpzquvpz 24.50
|
||||
|
||||
magicfavoriteunclepromisedpublicbotherislandjimseriouslycellleadknowingbrokenadvicesomehowpaidblairlosingpushhelpedkillingusuallyearlierbosslaurabeginninglikedinnocentdocruleselizabethsabrinasummerexcoplearnedthirtyrisklettingphillipspeakingofficerridiculoussupportafternoonericwithsobutallwellareheohaboutrightyou're 545.9
|
100000
src/zxcvbn-c/words-eng_wiki.txt
Normal file
100000
src/zxcvbn-c/words-eng_wiki.txt
Normal file
File diff suppressed because it is too large
Load diff
4275
src/zxcvbn-c/words-female.txt
Normal file
4275
src/zxcvbn-c/words-female.txt
Normal file
File diff suppressed because it is too large
Load diff
1219
src/zxcvbn-c/words-male.txt
Normal file
1219
src/zxcvbn-c/words-male.txt
Normal file
File diff suppressed because it is too large
Load diff
47023
src/zxcvbn-c/words-passwd.txt
Normal file
47023
src/zxcvbn-c/words-passwd.txt
Normal file
File diff suppressed because it is too large
Load diff
88799
src/zxcvbn-c/words-surname.txt
Normal file
88799
src/zxcvbn-c/words-surname.txt
Normal file
File diff suppressed because it is too large
Load diff
39070
src/zxcvbn-c/words-tv_film.txt
Normal file
39070
src/zxcvbn-c/words-tv_film.txt
Normal file
File diff suppressed because it is too large
Load diff
1765
src/zxcvbn-c/zxcvbn.c
Normal file
1765
src/zxcvbn-c/zxcvbn.c
Normal file
File diff suppressed because it is too large
Load diff
139
src/zxcvbn-c/zxcvbn.h
Normal file
139
src/zxcvbn-c/zxcvbn.h
Normal file
|
@ -0,0 +1,139 @@
|
|||
#ifndef ZXCVBN_H_F98183CE2A01_INCLUDED
|
||||
#define ZXCVBN_H_F98183CE2A01_INCLUDED
|
||||
/**********************************************************************************
|
||||
* C implementation of the zxcvbn password strength estimation method.
|
||||
* Copyright (c) 2015, Tony Evans
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
**********************************************************************************/
|
||||
|
||||
/* If this is defined, the dictiononary data is read from file. When undefined */
|
||||
/* dictionary data is included in the source code. */
|
||||
/*#define USE_DICT_FILE */
|
||||
|
||||
/* If this is defined, C++ builds which read dictionary data from file will use */
|
||||
/* stdio FILE streams (and fopen,fread,fclose). When undefined, C++ builds will */
|
||||
/* use std::ifstream to read dictionary data. Ignored for C builds (stdio FILE */
|
||||
/* streams are always used). */
|
||||
/*#define USE_FILE_IO */
|
||||
|
||||
#ifndef __cplusplus
|
||||
/* C build. Use the standard malloc/free for heap memory */
|
||||
#include <stdlib.h>
|
||||
#define MallocFn(T,N) ((T *)malloc((N) * sizeof(T)))
|
||||
#define FreeFn(P) free(P)
|
||||
|
||||
#else
|
||||
|
||||
/* C++ build. Use the new/delete operators for heap memory */
|
||||
#define MallocFn(T,N) (new T[N])
|
||||
#define FreeFn(P) (delete [] P)
|
||||
|
||||
#endif
|
||||
|
||||
/* Enum for the types of match returned in the Info arg to ZxcvbnMatch */
|
||||
typedef enum
|
||||
{
|
||||
NON_MATCH, /* 0 */
|
||||
BRUTE_MATCH, /* 1 */
|
||||
DICTIONARY_MATCH, /* 2 */
|
||||
DICT_LEET_MATCH, /* 3 */
|
||||
USER_MATCH, /* 4 */
|
||||
USER_LEET_MATCH, /* 5 */
|
||||
REPEATS_MATCH, /* 6 */
|
||||
SEQUENCE_MATCH, /* 7 */
|
||||
SPATIAL_MATCH, /* 8 */
|
||||
DATE_MATCH, /* 9 */
|
||||
YEAR_MATCH, /* 10 */
|
||||
MULTIPLE_MATCH = 32 /* Added to above to indicate matching part has been repeated */
|
||||
} ZxcTypeMatch_t;
|
||||
|
||||
/* Linked list of information returned in the Info arg to ZxcvbnMatch */
|
||||
struct ZxcMatch
|
||||
{
|
||||
int Begin; /* Char position of begining of match */
|
||||
int Length; /* Number of chars in the match */
|
||||
double Entrpy; /* The entropy of the match */
|
||||
double MltEnpy; /* Entropy with additional allowance for multipart password */
|
||||
ZxcTypeMatch_t Type; /* Type of match (Spatial/Dictionary/Order/Repeat) */
|
||||
struct ZxcMatch *Next;
|
||||
};
|
||||
typedef struct ZxcMatch ZxcMatch_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef USE_DICT_FILE
|
||||
|
||||
/**********************************************************************************
|
||||
* Read the dictionnary data from the given file. Returns 1 if OK, 0 if error.
|
||||
* Called once at program startup.
|
||||
*/
|
||||
int ZxcvbnInit(const char *);
|
||||
|
||||
/**********************************************************************************
|
||||
* Free the dictionnary data after use. Called once at program shutdown.
|
||||
*/
|
||||
void ZxcvbnUnInit();
|
||||
|
||||
#else
|
||||
|
||||
/* As the dictionary data is included in the source, define these functions to do nothing. */
|
||||
#define ZxcvbnInit(s) 1
|
||||
#define ZxcvbnUnInit() do {} while(0)
|
||||
|
||||
#endif
|
||||
|
||||
/**********************************************************************************
|
||||
* The main password matching function. May be called multiple times.
|
||||
* The parameters are:
|
||||
* Passwd The password to be tested. Null terminated string.
|
||||
* UserDict User supplied dictionary words to be considered particulary bad. Passed
|
||||
* as a pointer to array of string pointers, with null last entry (like
|
||||
* the argv parameter to main()). May be null or point to empty array when
|
||||
* there are no user dictionary words.
|
||||
* Info The address of a pointer variable to receive information on the parts
|
||||
* of the password. This parameter can be null if no information is wanted.
|
||||
* The data should be freed by calling ZxcvbnFreeInfo().
|
||||
*
|
||||
* Returns the entropy of the password (in bits).
|
||||
*/
|
||||
double ZxcvbnMatch(const char *Passwd, const char *UserDict[], ZxcMatch_t **Info);
|
||||
|
||||
/**********************************************************************************
|
||||
* Free the data returned in the Info parameter to ZxcvbnMatch().
|
||||
*/
|
||||
void ZxcvbnFreeInfo(ZxcMatch_t *Info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -26,6 +26,7 @@
|
|||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import moneroComponents.WalletManager 1.0
|
||||
import QtQuick 2.2
|
||||
import "../components"
|
||||
import "utils.js" as Utils
|
||||
|
@ -75,8 +76,14 @@ Item {
|
|||
|
||||
wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password
|
||||
|
||||
// scorePassword returns value from 1..100
|
||||
var strength = Utils.scorePassword(passwordItem.password)
|
||||
// scorePassword returns value from 0 to... lots
|
||||
var strength = walletManager.getPasswordStrength(passwordItem.password);
|
||||
// consider anything below 10 bits as dire
|
||||
strength -= 10
|
||||
if (strength < 0)
|
||||
strength = 0
|
||||
// use a slight parabola to discourage short passwords
|
||||
strength = strength ^ 1.2 / 3
|
||||
// privacyLevel component uses 1..13 scale
|
||||
privacyLevel.fillLevel = Utils.mapScope(1, 100, 1, 13, strength)
|
||||
|
||||
|
|
|
@ -1,37 +1,5 @@
|
|||
|
||||
.pragma library
|
||||
|
||||
// grabbed from SO answer page: http://stackoverflow.com/questions/948172/password-strength-meter
|
||||
|
||||
function scorePassword(pass) {
|
||||
var score = 0;
|
||||
if (!pass)
|
||||
return score;
|
||||
|
||||
// award every unique letter until 5 repetitions
|
||||
var letters = {};
|
||||
for (var i=0; i<pass.length; i++) {
|
||||
letters[pass[i]] = (letters[pass[i]] || 0) + 1;
|
||||
score += 5.0 / letters[pass[i]];
|
||||
}
|
||||
|
||||
// bonus points for mixing it up
|
||||
var variations = {
|
||||
digits: /\d/.test(pass),
|
||||
lower: /[a-z]/.test(pass),
|
||||
upper: /[A-Z]/.test(pass),
|
||||
nonWords: /\W/.test(pass),
|
||||
}
|
||||
|
||||
var variationCount = 0;
|
||||
for (var check in variations) {
|
||||
variationCount += (variations[check] === true) ? 1 : 0;
|
||||
}
|
||||
score += (variationCount - 1) * 10;
|
||||
|
||||
return parseInt(score);
|
||||
}
|
||||
|
||||
function mapScope (inputScopeFrom, inputScopeTo, outputScopeFrom, outputScopeTo, value) {
|
||||
var x = (value - inputScopeFrom) / (inputScopeTo - inputScopeFrom);
|
||||
var result = outputScopeFrom + ((outputScopeTo - outputScopeFrom) * x);
|
||||
|
|
Loading…
Reference in a new issue