mirror of
https://github.com/monero-project/monero-gui.git
synced 2025-03-25 16:49:11 +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
|
$SHELL get_libwallet_api.sh $BUILD_TYPE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# build zxcvbn
|
||||||
|
make -C src/zxcvbn-c
|
||||||
|
|
||||||
if [ ! -d build ]; then mkdir build; fi
|
if [ ! -d build ]; then mkdir build; fi
|
||||||
|
|
||||||
if [ "$BUILD_TYPE" == "Release" ]; then
|
if [ "$BUILD_TYPE" == "Release" ]; then
|
||||||
|
@ -27,7 +30,6 @@ else
|
||||||
BIN_PATH=debug/bin
|
BIN_PATH=debug/bin
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Platform indepenent settings
|
# Platform indepenent settings
|
||||||
platform=$(get_platform)
|
platform=$(get_platform)
|
||||||
if [ "$platform" == "linux32" ] || [ "$platform" == "linux64" ]; then
|
if [ "$platform" == "linux32" ] || [ "$platform" == "linux64" ]; then
|
||||||
|
|
|
@ -72,7 +72,7 @@ Item {
|
||||||
width: row.x
|
width: row.x
|
||||||
|
|
||||||
color: {
|
color: {
|
||||||
if(item.fillLevel < 3) return "#FF6C3C"
|
if(item.fillLevel < 5) return "#FF6C3C"
|
||||||
if(item.fillLevel < 13) return "#FFE00A"
|
if(item.fillLevel < 13) return "#FFE00A"
|
||||||
return "#36B25C"
|
return "#36B25C"
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,8 @@ HEADERS += \
|
||||||
src/QR-Code-generator/QrSegment.hpp \
|
src/QR-Code-generator/QrSegment.hpp \
|
||||||
src/daemon/DaemonManager.h \
|
src/daemon/DaemonManager.h \
|
||||||
src/model/AddressBookModel.h \
|
src/model/AddressBookModel.h \
|
||||||
src/libwalletqt/AddressBook.h
|
src/libwalletqt/AddressBook.h \
|
||||||
|
src/zxcvbn-c/zxcvbn.h
|
||||||
|
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
|
@ -56,7 +57,8 @@ SOURCES += main.cpp \
|
||||||
src/QR-Code-generator/QrSegment.cpp \
|
src/QR-Code-generator/QrSegment.cpp \
|
||||||
src/daemon/DaemonManager.cpp \
|
src/daemon/DaemonManager.cpp \
|
||||||
src/model/AddressBookModel.cpp \
|
src/model/AddressBookModel.cpp \
|
||||||
src/libwalletqt/AddressBook.cpp
|
src/libwalletqt/AddressBook.cpp \
|
||||||
|
src/zxcvbn-c/zxcvbn.c
|
||||||
|
|
||||||
lupdate_only {
|
lupdate_only {
|
||||||
SOURCES = *.qml \
|
SOURCES = *.qml \
|
||||||
|
@ -236,7 +238,6 @@ QMAKE_EXTRA_COMPILERS += langrel
|
||||||
|
|
||||||
PRE_TARGETDEPS += langupd compiler_langrel_make_all
|
PRE_TARGETDEPS += langupd compiler_langrel_make_all
|
||||||
|
|
||||||
|
|
||||||
RESOURCES += qml.qrc
|
RESOURCES += qml.qrc
|
||||||
|
|
||||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "WalletManager.h"
|
#include "WalletManager.h"
|
||||||
#include "Wallet.h"
|
#include "Wallet.h"
|
||||||
#include "wallet/wallet2_api.h"
|
#include "wallet/wallet2_api.h"
|
||||||
|
#include "zxcvbn-c/zxcvbn.h"
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
@ -241,6 +242,21 @@ QUrl WalletManager::localPathToUrl(const QString &path) const
|
||||||
return QUrl::fromLocalFile(path);
|
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)
|
WalletManager::WalletManager(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
m_pimpl = Monero::WalletManagerFactory::getWalletManager();
|
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 addi(qint64 x, qint64 y) const { return x + y; }
|
||||||
Q_INVOKABLE qint64 subi(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:
|
signals:
|
||||||
|
|
||||||
void walletOpened(Wallet * wallet);
|
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
|
// 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.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import moneroComponents.WalletManager 1.0
|
||||||
import QtQuick 2.2
|
import QtQuick 2.2
|
||||||
import "../components"
|
import "../components"
|
||||||
import "utils.js" as Utils
|
import "utils.js" as Utils
|
||||||
|
@ -75,8 +76,14 @@ Item {
|
||||||
|
|
||||||
wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password
|
wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password
|
||||||
|
|
||||||
// scorePassword returns value from 1..100
|
// scorePassword returns value from 0 to... lots
|
||||||
var strength = Utils.scorePassword(passwordItem.password)
|
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 component uses 1..13 scale
|
||||||
privacyLevel.fillLevel = Utils.mapScope(1, 100, 1, 13, strength)
|
privacyLevel.fillLevel = Utils.mapScope(1, 100, 1, 13, strength)
|
||||||
|
|
||||||
|
|
|
@ -1,37 +1,5 @@
|
||||||
|
|
||||||
.pragma library
|
.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) {
|
function mapScope (inputScopeFrom, inputScopeTo, outputScopeFrom, outputScopeTo, value) {
|
||||||
var x = (value - inputScopeFrom) / (inputScopeTo - inputScopeFrom);
|
var x = (value - inputScopeFrom) / (inputScopeTo - inputScopeFrom);
|
||||||
var result = outputScopeFrom + ((outputScopeTo - outputScopeFrom) * x);
|
var result = outputScopeFrom + ((outputScopeTo - outputScopeFrom) * x);
|
||||||
|
|
Loading…
Reference in a new issue