mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-08-01 19:16:16 -04:00
Add some password-related feature (#92)
* Add Standalone Password Generator. Closes #18 * Add an entropy meter for passwords. Closes #84 * Don't require password repeat when it is visible. Fixes #27
This commit is contained in:
parent
19a960856c
commit
b2f3cc6903
28 changed files with 28401 additions and 195 deletions
|
@ -174,13 +174,17 @@ endif()
|
|||
|
||||
qt5_wrap_ui(keepassx_SOURCES ${keepassx_FORMS})
|
||||
|
||||
add_library(zxcvbn STATIC zxcvbn/zxcvbn.cpp)
|
||||
target_link_libraries(zxcvbn)
|
||||
|
||||
add_library(keepassx_core STATIC ${keepassx_SOURCES})
|
||||
set_target_properties(keepassx_core PROPERTIES COMPILE_DEFINITIONS KEEPASSX_BUILDING_CORE)
|
||||
target_link_libraries(keepassx_core Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Network)
|
||||
target_link_libraries(keepassx_core zxcvbn Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Network)
|
||||
|
||||
add_executable(${PROGNAME} WIN32 MACOSX_BUNDLE ${keepassx_SOURCES_MAINEXE})
|
||||
target_link_libraries(${PROGNAME}
|
||||
keepassx_core
|
||||
zxcvbn
|
||||
${MHD_LIBRARIES}
|
||||
Qt5::Core
|
||||
Qt5::Concurrent
|
||||
|
|
|
@ -102,6 +102,7 @@ void Config::init(const QString& fileName)
|
|||
m_defaults.insert("security/lockdatabaseidle", false);
|
||||
m_defaults.insert("security/lockdatabaseidlesec", 10);
|
||||
m_defaults.insert("security/lockdatabaseminimize", false);
|
||||
m_defaults.insert("security/passwordsrepeat", false);
|
||||
m_defaults.insert("security/passwordscleartext", false);
|
||||
m_defaults.insert("security/autotypeask", true);
|
||||
m_defaults.insert("GUI/Language", "system");
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "PasswordGenerator.h"
|
||||
|
||||
#include "crypto/Random.h"
|
||||
#include "zxcvbn/zxcvbn.h"
|
||||
|
||||
PasswordGenerator::PasswordGenerator()
|
||||
: m_length(0)
|
||||
|
@ -26,6 +27,11 @@ PasswordGenerator::PasswordGenerator()
|
|||
{
|
||||
}
|
||||
|
||||
double PasswordGenerator::calculateEntropy(QString password)
|
||||
{
|
||||
return ZxcvbnMatch(password.toLatin1(), 0, 0);
|
||||
}
|
||||
|
||||
void PasswordGenerator::setLength(int length)
|
||||
{
|
||||
m_length = length;
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
public:
|
||||
PasswordGenerator();
|
||||
|
||||
double calculateEntropy(QString password);
|
||||
void setLength(int length);
|
||||
void setCharClasses(const CharClasses& classes);
|
||||
void setFlags(const GeneratorFlags& flags);
|
||||
|
|
|
@ -69,24 +69,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="PasswordEdit" name="editPassword">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonTogglePassword">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
|
@ -111,6 +93,24 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="PasswordEdit" name="editPassword">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonTogglePassword">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "http/HttpSettings.h"
|
||||
#include "http/OptionDialog.h"
|
||||
#include "gui/SettingsWidget.h"
|
||||
#include "gui/PasswordGeneratorWidget.h"
|
||||
|
||||
class HttpPlugin: public ISettingsPage
|
||||
{
|
||||
|
@ -168,6 +169,7 @@ MainWindow::MainWindow()
|
|||
m_ui->actionGroupDelete->setIcon(filePath()->icon("actions", "group-delete", false));
|
||||
|
||||
m_ui->actionSettings->setIcon(filePath()->icon("actions", "configure"));
|
||||
m_ui->actionPasswordGenerator->setIcon(filePath()->icon("actions", "password-generator", false));
|
||||
|
||||
m_ui->actionAbout->setIcon(filePath()->icon("actions", "help-about"));
|
||||
|
||||
|
@ -261,6 +263,8 @@ MainWindow::MainWindow()
|
|||
SLOT(deleteGroup()));
|
||||
|
||||
connect(m_ui->actionSettings, SIGNAL(triggered()), SLOT(switchToSettings()));
|
||||
connect(m_ui->actionPasswordGenerator, SIGNAL(toggled(bool)), SLOT(switchToPasswordGen(bool)));
|
||||
connect(m_ui->passwordGeneratorWidget, SIGNAL(dialogTerminated()), SLOT(closePasswordGen()));
|
||||
|
||||
connect(m_ui->actionAbout, SIGNAL(triggered()), SLOT(showAboutDialog()));
|
||||
|
||||
|
@ -340,8 +344,9 @@ void MainWindow::minimizeWindow()
|
|||
|
||||
void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
||||
{
|
||||
bool inDatabaseTabWidget = (m_ui->stackedWidget->currentIndex() == 0);
|
||||
bool inWelcomeWidget = (m_ui->stackedWidget->currentIndex() == 2);
|
||||
int currentIndex = m_ui->stackedWidget->currentIndex();
|
||||
bool inDatabaseTabWidget = (currentIndex == 0);
|
||||
bool inWelcomeWidget = (currentIndex == 2);
|
||||
|
||||
if (inDatabaseTabWidget && m_ui->tabWidget->currentIndex() != -1) {
|
||||
DatabaseWidget* dbWidget = m_ui->tabWidget->currentDatabaseWidget();
|
||||
|
@ -453,6 +458,12 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
|||
m_ui->actionRepairDatabase->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
|
||||
|
||||
m_ui->actionLockDatabases->setEnabled(m_ui->tabWidget->hasLockableDatabases());
|
||||
|
||||
if ((3 == currentIndex) != m_ui->actionPasswordGenerator->isChecked()) {
|
||||
bool blocked = m_ui->actionPasswordGenerator->blockSignals(true);
|
||||
m_ui->actionPasswordGenerator->toggle();
|
||||
m_ui->actionPasswordGenerator->blockSignals(blocked);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateWindowTitle()
|
||||
|
@ -501,6 +512,24 @@ void MainWindow::switchToSettings()
|
|||
m_ui->stackedWidget->setCurrentIndex(1);
|
||||
}
|
||||
|
||||
void MainWindow::switchToPasswordGen(bool enabled)
|
||||
{
|
||||
if (enabled == true) {
|
||||
m_ui->passwordGeneratorWidget->loadSettings();
|
||||
m_ui->passwordGeneratorWidget->regeneratePassword();
|
||||
m_ui->passwordGeneratorWidget->setStandaloneMode(true);
|
||||
m_ui->stackedWidget->setCurrentIndex(3);
|
||||
} else {
|
||||
m_ui->passwordGeneratorWidget->saveSettings();
|
||||
switchToDatabases();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::closePasswordGen()
|
||||
{
|
||||
switchToPasswordGen(false);
|
||||
}
|
||||
|
||||
void MainWindow::databaseStatusChanged(DatabaseWidget *)
|
||||
{
|
||||
updateTrayIcon();
|
||||
|
|
|
@ -54,6 +54,8 @@ private Q_SLOTS:
|
|||
void showAboutDialog();
|
||||
void switchToDatabases();
|
||||
void switchToSettings();
|
||||
void switchToPasswordGen(bool enabled);
|
||||
void closePasswordGen();
|
||||
void databaseStatusChanged(DatabaseWidget *dbWidget);
|
||||
void databaseTabChanged(int tabIndex);
|
||||
void openRecentDatabase(QAction* action);
|
||||
|
|
|
@ -87,6 +87,13 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="pagePasswordGenerator">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="PasswordGeneratorWidget" name="passwordGeneratorWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -171,6 +178,7 @@
|
|||
<string>Tools</string>
|
||||
</property>
|
||||
<addaction name="actionLockDatabases"/>
|
||||
<addaction name="actionPasswordGenerator"/>
|
||||
<addaction name="actionSettings"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
|
@ -205,6 +213,7 @@
|
|||
<addaction name="actionEntryCopyUsername"/>
|
||||
<addaction name="actionEntryCopyPassword"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionPasswordGenerator"/>
|
||||
<addaction name="actionLockDatabases"/>
|
||||
<addaction name="separator"/>
|
||||
</widget>
|
||||
|
@ -372,6 +381,14 @@
|
|||
<string>&Settings</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPasswordGenerator">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Password Generator</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEntryAutoType">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
|
@ -453,6 +470,12 @@
|
|||
<header>gui/WelcomeWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>PasswordGeneratorWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/PasswordGeneratorWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
|
||||
#include "PasswordEdit.h"
|
||||
|
||||
#include "core/Config.h"
|
||||
|
||||
#include <QFontDatabase>
|
||||
|
||||
const QColor PasswordEdit::CorrectSoFarColor = QColor(255, 205, 15);
|
||||
const QColor PasswordEdit::ErrorColor = QColor(255, 125, 125);
|
||||
|
||||
|
@ -24,6 +28,13 @@ PasswordEdit::PasswordEdit(QWidget* parent)
|
|||
: QLineEdit(parent)
|
||||
, m_basePasswordEdit(nullptr)
|
||||
{
|
||||
setEchoMode(QLineEdit::Password);
|
||||
updateStylesheet();
|
||||
|
||||
// set font to system monospace font and increase letter spacing
|
||||
QFont passwordFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
|
||||
passwordFont.setLetterSpacing(QFont::PercentageSpacing, 110);
|
||||
setFont(passwordFont);
|
||||
}
|
||||
|
||||
void PasswordEdit::enableVerifyMode(PasswordEdit* basePasswordEdit)
|
||||
|
@ -31,6 +42,8 @@ void PasswordEdit::enableVerifyMode(PasswordEdit* basePasswordEdit)
|
|||
m_basePasswordEdit = basePasswordEdit;
|
||||
|
||||
updateStylesheet();
|
||||
|
||||
connect(m_basePasswordEdit, SIGNAL(textChanged(QString)), SLOT(autocompletePassword(QString)));
|
||||
connect(m_basePasswordEdit, SIGNAL(textChanged(QString)), SLOT(updateStylesheet()));
|
||||
connect(this, SIGNAL(textChanged(QString)), SLOT(updateStylesheet()));
|
||||
|
||||
|
@ -40,6 +53,21 @@ void PasswordEdit::enableVerifyMode(PasswordEdit* basePasswordEdit)
|
|||
void PasswordEdit::setShowPassword(bool show)
|
||||
{
|
||||
setEchoMode(show ? QLineEdit::Normal : QLineEdit::Password);
|
||||
// if I have a parent, I'm the child
|
||||
if (m_basePasswordEdit){
|
||||
if (config()->get("security/passwordsrepeat").toBool()) {
|
||||
setEnabled(!show);
|
||||
setReadOnly(show);
|
||||
setText(m_basePasswordEdit->text());
|
||||
}
|
||||
else {
|
||||
// This fix a bug when the QLineEdit is disabled while switching config
|
||||
if (isEnabled() == false) {
|
||||
setEnabled(true);
|
||||
setReadOnly(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
updateStylesheet();
|
||||
Q_EMIT showPasswordChanged(show);
|
||||
}
|
||||
|
@ -53,15 +81,6 @@ void PasswordEdit::updateStylesheet()
|
|||
{
|
||||
QString stylesheet("QLineEdit { ");
|
||||
|
||||
if (echoMode() == QLineEdit::Normal) {
|
||||
#ifdef Q_OS_MAC
|
||||
// Qt on Mac OS doesn't seem to know the generic monospace family (tested with 4.8.6)
|
||||
stylesheet.append("font-family: monospace,Menlo,Monaco; ");
|
||||
#else
|
||||
stylesheet.append("font-family: monospace,Courier New; ");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (m_basePasswordEdit && !passwordsEqual()) {
|
||||
stylesheet.append("background: %1; ");
|
||||
|
||||
|
@ -76,3 +95,10 @@ void PasswordEdit::updateStylesheet()
|
|||
stylesheet.append("}");
|
||||
setStyleSheet(stylesheet);
|
||||
}
|
||||
|
||||
void PasswordEdit::autocompletePassword(QString password)
|
||||
{
|
||||
if (config()->get("security/passwordsrepeat").toBool() && echoMode() == QLineEdit::Normal) {
|
||||
setText(password);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ Q_SIGNALS:
|
|||
|
||||
private Q_SLOTS:
|
||||
void updateStylesheet();
|
||||
void autocompletePassword(QString password);
|
||||
|
||||
private:
|
||||
bool passwordsEqual() const;
|
||||
|
|
|
@ -34,18 +34,23 @@ PasswordGeneratorWidget::PasswordGeneratorWidget(QWidget* parent)
|
|||
|
||||
m_ui->togglePasswordButton->setIcon(filePath()->onOffIcon("actions", "password-show"));
|
||||
|
||||
connect(m_ui->editNewPassword->lineEdit(), SIGNAL(textChanged(QString)), SLOT(updateApplyEnabled(QString)));
|
||||
connect(m_ui->togglePasswordButton, SIGNAL(toggled(bool)), m_ui->editNewPassword, SLOT(setEcho(bool)));
|
||||
connect(m_ui->buttonApply, SIGNAL(clicked()), SLOT(emitNewPassword()));
|
||||
connect(m_ui->buttonApply, SIGNAL(clicked()), SLOT(saveSettings()));
|
||||
connect(m_ui->editNewPassword, SIGNAL(textChanged(QString)), SLOT(updateApplyEnabled(QString)));
|
||||
connect(m_ui->editNewPassword, SIGNAL(textChanged(QString)), SLOT(updatePasswordStrength(QString)));
|
||||
connect(m_ui->togglePasswordButton, SIGNAL(toggled(bool)), SLOT(togglePasswordShown(bool)));
|
||||
connect(m_ui->buttonApply, SIGNAL(clicked()), SLOT(applyPassword()));
|
||||
connect(m_ui->buttonGenerate, SIGNAL(clicked()), SLOT(generatePassword()));
|
||||
|
||||
connect(m_ui->sliderLength, SIGNAL(valueChanged(int)), SLOT(sliderMoved()));
|
||||
connect(m_ui->spinBoxLength, SIGNAL(valueChanged(int)), SLOT(spinBoxChanged()));
|
||||
|
||||
connect(m_ui->optionButtons, SIGNAL(buttonClicked(int)), SLOT(updateGenerator()));
|
||||
|
||||
m_ui->editNewPassword->setGenerator(m_generator.data());
|
||||
|
||||
// set font size of password quality and entropy labels dynamically to 80% of the default font size
|
||||
QFont defaultFont;
|
||||
defaultFont.setPointSize(static_cast<int>(defaultFont.pointSize() * 0.8f));
|
||||
m_ui->entropyLabel->setFont(defaultFont);
|
||||
m_ui->strengthLabel->setFont(defaultFont);
|
||||
|
||||
loadSettings();
|
||||
reset();
|
||||
}
|
||||
|
@ -82,17 +87,28 @@ void PasswordGeneratorWidget::saveSettings()
|
|||
|
||||
void PasswordGeneratorWidget::reset()
|
||||
{
|
||||
m_ui->editNewPassword->lineEdit()->setText("");
|
||||
m_ui->togglePasswordButton->setChecked(config()->get("security/passwordscleartext").toBool());
|
||||
|
||||
m_ui->editNewPassword->setText("");
|
||||
setStandaloneMode(false);
|
||||
togglePasswordShown(config()->get("security/passwordscleartext").toBool());
|
||||
updateGenerator();
|
||||
}
|
||||
|
||||
void PasswordGeneratorWidget::setStandaloneMode(bool standalone)
|
||||
{
|
||||
if (standalone) {
|
||||
m_ui->buttonApply->setText(tr("Close"));
|
||||
togglePasswordShown(true);
|
||||
} else {
|
||||
m_ui->buttonApply->setText(tr("Apply"));
|
||||
}
|
||||
}
|
||||
|
||||
void PasswordGeneratorWidget::regeneratePassword()
|
||||
{
|
||||
if (m_generator->isValid()) {
|
||||
QString password = m_generator->generatePassword();
|
||||
m_ui->editNewPassword->setEditText(password);
|
||||
m_ui->editNewPassword->setText(password);
|
||||
updatePasswordStrength(password);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,9 +117,30 @@ void PasswordGeneratorWidget::updateApplyEnabled(const QString& password)
|
|||
m_ui->buttonApply->setEnabled(!password.isEmpty());
|
||||
}
|
||||
|
||||
void PasswordGeneratorWidget::emitNewPassword()
|
||||
void PasswordGeneratorWidget::updatePasswordStrength(const QString& password)
|
||||
{
|
||||
Q_EMIT newPassword(m_ui->editNewPassword->lineEdit()->text());
|
||||
double entropy = m_generator->calculateEntropy(password);
|
||||
m_ui->entropyLabel->setText(tr("Entropy: %1 bit").arg(QString::number(entropy, 'f', 2)));
|
||||
|
||||
if (entropy > m_ui->entropyProgressBar->maximum()) {
|
||||
entropy = m_ui->entropyProgressBar->maximum();
|
||||
}
|
||||
m_ui->entropyProgressBar->setValue(entropy);
|
||||
|
||||
colorStrengthIndicator(entropy);
|
||||
}
|
||||
|
||||
void PasswordGeneratorWidget::generatePassword()
|
||||
{
|
||||
QString password = m_generator->generatePassword();
|
||||
m_ui->editNewPassword->setText(password);
|
||||
}
|
||||
|
||||
void PasswordGeneratorWidget::applyPassword()
|
||||
{
|
||||
saveSettings();
|
||||
Q_EMIT appliedPassword(m_ui->editNewPassword->text());
|
||||
Q_EMIT dialogTerminated();
|
||||
}
|
||||
|
||||
void PasswordGeneratorWidget::sliderMoved()
|
||||
|
@ -133,6 +170,41 @@ void PasswordGeneratorWidget::spinBoxChanged()
|
|||
updateGenerator();
|
||||
}
|
||||
|
||||
void PasswordGeneratorWidget::togglePasswordShown(bool showing)
|
||||
{
|
||||
m_ui->editNewPassword->setShowPassword(showing);
|
||||
bool blockSignals = m_ui->togglePasswordButton->blockSignals(true);
|
||||
m_ui->togglePasswordButton->setChecked(showing);
|
||||
m_ui->togglePasswordButton->blockSignals(blockSignals);
|
||||
}
|
||||
|
||||
void PasswordGeneratorWidget::colorStrengthIndicator(double entropy)
|
||||
{
|
||||
// Take the existing stylesheet and convert the text and background color to arguments
|
||||
QString style = m_ui->entropyProgressBar->styleSheet();
|
||||
QRegularExpression re("(QProgressBar::chunk\\s*\\{.*?background-color:)[^;]+;",
|
||||
QRegularExpression::CaseInsensitiveOption |
|
||||
QRegularExpression::DotMatchesEverythingOption);
|
||||
style.replace(re, "\\1 %1;");
|
||||
|
||||
// Set the color and background based on entropy
|
||||
// colors are taking from the KDE breeze palette
|
||||
// <https://community.kde.org/KDE_Visual_Design_Group/HIG/Color>
|
||||
if (entropy < 35) {
|
||||
m_ui->entropyProgressBar->setStyleSheet(style.arg("#c0392b"));
|
||||
m_ui->strengthLabel->setText(tr("Password Quality: %1").arg(tr("Poor")));
|
||||
} else if (entropy >= 35 && entropy < 55) {
|
||||
m_ui->entropyProgressBar->setStyleSheet(style.arg("#f39c1f"));
|
||||
m_ui->strengthLabel->setText(tr("Password Quality: %1").arg(tr("Weak")));
|
||||
} else if (entropy >= 55 && entropy < 100) {
|
||||
m_ui->entropyProgressBar->setStyleSheet(style.arg("#11d116"));
|
||||
m_ui->strengthLabel->setText(tr("Password Quality: %1").arg(tr("Good")));
|
||||
} else {
|
||||
m_ui->entropyProgressBar->setStyleSheet(style.arg("#27ae60"));
|
||||
m_ui->strengthLabel->setText(tr("Password Quality: %1").arg(tr("Excellent")));
|
||||
}
|
||||
}
|
||||
|
||||
PasswordGenerator::CharClasses PasswordGeneratorWidget::charClasses()
|
||||
{
|
||||
PasswordGenerator::CharClasses classes;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <QWidget>
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
|
||||
#include "core/PasswordGenerator.h"
|
||||
|
||||
|
@ -37,19 +38,25 @@ public:
|
|||
explicit PasswordGeneratorWidget(QWidget* parent = nullptr);
|
||||
~PasswordGeneratorWidget();
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
void reset();
|
||||
void setStandaloneMode(bool standalone);
|
||||
void regeneratePassword();
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
void newPassword(const QString& password);
|
||||
void appliedPassword(const QString& password);
|
||||
void dialogTerminated();
|
||||
|
||||
private Q_SLOTS:
|
||||
void applyPassword();
|
||||
void generatePassword();
|
||||
void updateApplyEnabled(const QString& password);
|
||||
void updatePasswordStrength(const QString& password);
|
||||
void togglePasswordShown(bool hidden);
|
||||
|
||||
void emitNewPassword();
|
||||
void saveSettings();
|
||||
void sliderMoved();
|
||||
void spinBoxChanged();
|
||||
void colorStrengthIndicator(double entropy);
|
||||
|
||||
void updateGenerator();
|
||||
|
||||
|
|
|
@ -6,60 +6,197 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>434</width>
|
||||
<height>250</height>
|
||||
<width>500</width>
|
||||
<height>278</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<layout class="QGridLayout" name="passwordFieldLayout">
|
||||
<property name="bottomMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="1">
|
||||
<widget class="QProgressBar" name="entropyProgressBar">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QProgressBar {
|
||||
border: none;
|
||||
height: 2px;
|
||||
font-size: 1px;
|
||||
background-color: transparent;
|
||||
padding: 0 1px;
|
||||
}
|
||||
QProgressBar::chunk {
|
||||
background-color: #c0392b;
|
||||
border-radius: 2px;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>200</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="textDirection">
|
||||
<enum>QProgressBar::TopToBottom</enum>
|
||||
</property>
|
||||
<property name="format">
|
||||
<string>%p%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelNewPassword">
|
||||
<property name="text">
|
||||
<string>Password:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editNewPassword</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetNoConstraint</enum>
|
||||
</property>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="passwordStrengthTextLayout">
|
||||
<item>
|
||||
<widget class="PasswordComboBox" name="editNewPassword">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
<widget class="QLabel" name="strengthLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>strength</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="togglePasswordButton">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="entropyLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>entropy</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelLength">
|
||||
<property name="text">
|
||||
<string>Length:</string>
|
||||
<item row="0" column="1">
|
||||
<widget class="PasswordEdit" name="editNewPassword">
|
||||
<property name="maxLength">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelLength">
|
||||
<property name="text">
|
||||
<string>&Length:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxLength</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<layout class="QHBoxLayout" name="passwordLengthSliderLayout">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSlider" name="sliderLength">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>64</number>
|
||||
<number>128</number>
|
||||
</property>
|
||||
<property name="sliderPosition">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
|
@ -72,7 +209,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item alignment="Qt::AlignRight">
|
||||
<widget class="QSpinBox" name="spinBoxLength">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
|
@ -80,30 +217,139 @@
|
|||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="togglePasswordButton">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Character Types</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<layout class="QHBoxLayout" name="optionsLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Character Types</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkBoxUpper">
|
||||
<property name="toolTip">
|
||||
<string>Upper Case Letters</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="alphabetLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkBoxUpper">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>26</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Upper Case Letters</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">A-Z</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">optionButtons</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkBoxLower">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>26</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Lower Case Letters</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">a-z</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">optionButtons</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkBoxNumbers">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Numbers</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">0-9</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">optionButtons</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkBoxSpecialChars">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Special Characters</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">/*_& ...</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">optionButtons</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxExcludeAlike">
|
||||
<property name="text">
|
||||
<string notr="true">A-Z</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
<string>Exclude look-alike characters</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">optionButtons</string>
|
||||
|
@ -111,115 +357,38 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkBoxLower">
|
||||
<property name="toolTip">
|
||||
<string>Lower Case Letters</string>
|
||||
</property>
|
||||
<widget class="QCheckBox" name="checkBoxEnsureEvery">
|
||||
<property name="text">
|
||||
<string notr="true">a-z</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
<string>Pick characters from every group</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">optionButtons</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkBoxNumbers">
|
||||
<property name="toolTip">
|
||||
<string>Numbers</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">0-9</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">optionButtons</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkBoxSpecialChars">
|
||||
<property name="toolTip">
|
||||
<string>Special Characters</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">/*_& ...</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">optionButtons</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxExcludeAlike">
|
||||
<property name="text">
|
||||
<string>Exclude look-alike characters</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">optionButtons</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxEnsureEvery">
|
||||
<property name="text">
|
||||
<string>Ensure that the password contains characters from every group</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">optionButtons</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonApply">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Accept</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QVBoxLayout" name="globalButtonsLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonGenerate">
|
||||
<property name="text">
|
||||
<string>Generate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonApply">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Accept</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
@ -227,9 +396,9 @@
|
|||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>PasswordComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header location="global">gui/PasswordComboBox.h</header>
|
||||
<class>PasswordEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>gui/PasswordEdit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
|
@ -243,6 +412,7 @@
|
|||
<tabstop>checkBoxSpecialChars</tabstop>
|
||||
<tabstop>checkBoxExcludeAlike</tabstop>
|
||||
<tabstop>checkBoxEnsureEvery</tabstop>
|
||||
<tabstop>buttonGenerate</tabstop>
|
||||
<tabstop>buttonApply</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
|
|
|
@ -137,6 +137,7 @@ void SettingsWidget::loadSettings()
|
|||
m_secUi->lockDatabaseMinimizeCheckBox->setChecked(config()->get("security/lockdatabaseminimize").toBool());
|
||||
|
||||
m_secUi->passwordCleartextCheckBox->setChecked(config()->get("security/passwordscleartext").toBool());
|
||||
m_secUi->passwordRepeatCheckBox->setChecked(config()->get("security/passwordsrepeat").toBool());
|
||||
|
||||
m_secUi->autoTypeAskCheckBox->setChecked(config()->get("security/autotypeask").toBool());
|
||||
|
||||
|
@ -181,6 +182,7 @@ void SettingsWidget::saveSettings()
|
|||
config()->set("security/lockdatabaseminimize", m_secUi->lockDatabaseMinimizeCheckBox->isChecked());
|
||||
|
||||
config()->set("security/passwordscleartext", m_secUi->passwordCleartextCheckBox->isChecked());
|
||||
config()->set("security/passwordsrepeat", m_secUi->passwordRepeatCheckBox->isChecked());
|
||||
|
||||
config()->set("security/autotypeask", m_secUi->autoTypeAskCheckBox->isChecked());
|
||||
|
||||
|
|
|
@ -72,6 +72,13 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="passwordRepeatCheckBox">
|
||||
<property name="text">
|
||||
<string>Don't require password repeat when it is visible</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="autoTypeAskCheckBox">
|
||||
<property name="text">
|
||||
<string>Always ask before performing auto-type</string>
|
||||
|
|
|
@ -93,7 +93,7 @@ void EditEntryWidget::setupMain()
|
|||
connect(m_mainUi->tooglePasswordGeneratorButton, SIGNAL(toggled(bool)), SLOT(togglePasswordGeneratorButton(bool)));
|
||||
connect(m_mainUi->expireCheck, SIGNAL(toggled(bool)), m_mainUi->expireDatePicker, SLOT(setEnabled(bool)));
|
||||
m_mainUi->passwordRepeatEdit->enableVerifyMode(m_mainUi->passwordEdit);
|
||||
connect(m_mainUi->passwordGenerator, SIGNAL(newPassword(QString)), SLOT(setGeneratedPassword(QString)));
|
||||
connect(m_mainUi->passwordGenerator, SIGNAL(appliedPassword(QString)), SLOT(setGeneratedPassword(QString)));
|
||||
|
||||
m_mainUi->expirePresets->setMenu(createPresetsMenu());
|
||||
connect(m_mainUi->expirePresets->menu(), SIGNAL(triggered(QAction*)), this, SLOT(useExpiryPreset(QAction*)));
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>372</width>
|
||||
<height>301</height>
|
||||
<height>364</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
|
@ -78,7 +78,7 @@
|
|||
<item>
|
||||
<widget class="QToolButton" name="tooglePasswordGeneratorButton">
|
||||
<property name="text">
|
||||
<string>Gen.</string>
|
||||
<string>Generate</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
|
24872
src/zxcvbn/dict-src.h
Normal file
24872
src/zxcvbn/dict-src.h
Normal file
File diff suppressed because it is too large
Load diff
1772
src/zxcvbn/zxcvbn.cpp
Normal file
1772
src/zxcvbn/zxcvbn.cpp
Normal file
File diff suppressed because it is too large
Load diff
139
src/zxcvbn/zxcvbn.h
Normal file
139
src/zxcvbn/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
|
Loading…
Add table
Add a link
Reference in a new issue