From e124f17c64eb4af2d3c0bb836d75202e2703a58c Mon Sep 17 00:00:00 2001 From: seregaxvm Date: Mon, 11 Jun 2018 05:37:09 +0300 Subject: [PATCH] Add advanced password generator features (#1841) * Split between simple and advanced features * Finetune password character groups * Support for hex passwords --- src/autotype/AutoType.cpp | 7 +- src/browser/BrowserSettings.cpp | 98 ++++ src/browser/BrowserSettings.h | 16 + src/cli/Generate.cpp | 46 +- src/core/PasswordGenerator.cpp | 139 ++++- src/core/PasswordGenerator.h | 31 +- src/gui/DatabaseWidget.cpp | 1 - src/gui/EditWidgetIcons.cpp | 1 - src/gui/PasswordGeneratorWidget.cpp | 190 ++++++- src/gui/PasswordGeneratorWidget.h | 3 + src/gui/PasswordGeneratorWidget.ui | 785 ++++++++++++++++++++++------ 11 files changed, 1100 insertions(+), 217 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 89c24e55e..aaa742a09 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -756,9 +756,10 @@ bool AutoType::verifyAutoTypeSyntax(const QString& sequence) } } else if (AutoType::checkHighRepetition(sequence)) { QMessageBox::StandardButton reply; - reply = - QMessageBox::question(nullptr, tr("Auto-Type"), tr("This Auto-Type command contains arguments which are " - "repeated very often. Do you really want to proceed?")); + reply = QMessageBox::question(nullptr, + tr("Auto-Type"), + tr("This Auto-Type command contains arguments which are " + "repeated very often. Do you really want to proceed?")); if (reply == QMessageBox::No) { return false; diff --git a/src/browser/BrowserSettings.cpp b/src/browser/BrowserSettings.cpp index 4a75797fd..76163b9d9 100644 --- a/src/browser/BrowserSettings.cpp +++ b/src/browser/BrowserSettings.cpp @@ -261,6 +261,66 @@ void BrowserSettings::setPasswordUseSpecial(bool useSpecial) config()->set("generator/SpecialChars", useSpecial); } +bool BrowserSettings::passwordUseBraces() +{ + return config()->get("generator/Braces", PasswordGenerator::DefaultBraces).toBool(); +} + +void BrowserSettings::setPasswordUseBraces(bool useBraces) +{ + config()->set("generator/Braces", useBraces); +} + +bool BrowserSettings::passwordUsePunctuation() +{ + return config()->get("generator/Punctuation", PasswordGenerator::DefaultQuotes).toBool(); +} + +void BrowserSettings::setPasswordUsePunctuation(bool usePunctuation) +{ + config()->set("generator/Punctuation", usePunctuation); +} + +bool BrowserSettings::passwordUseQuotes() +{ + return config()->get("generator/Quotes", PasswordGenerator::DefaultQuotes).toBool(); +} + +void BrowserSettings::setPasswordUseQuotes(bool useQuotes) +{ + config()->set("generator/Quotes", useQuotes); +} + +bool BrowserSettings::passwordUseDashes() +{ + return config()->get("generator/Dashes", PasswordGenerator::DefaultDashes).toBool(); +} + +void BrowserSettings::setPasswordUseDashes(bool useDashes) +{ + config()->set("generator/Dashes", useDashes); +} + +bool BrowserSettings::passwordUseMath() +{ + return config()->get("generator/Math", PasswordGenerator::DefaultMath).toBool(); +} + +void BrowserSettings::setPasswordUseMath(bool useMath) +{ + config()->set("generator/Math", useMath); +} + +bool BrowserSettings::passwordUseLogograms() +{ + return config()->get("generator/Logograms", PasswordGenerator::DefaultLogograms).toBool(); +} + +void BrowserSettings::setPasswordUseLogograms(bool useLogograms) +{ + config()->set("generator/Logograms", useLogograms); +} + bool BrowserSettings::passwordUseEASCII() { return config()->get("generator/EASCII", PasswordGenerator::DefaultEASCII).toBool(); @@ -271,6 +331,26 @@ void BrowserSettings::setPasswordUseEASCII(bool useEASCII) config()->set("generator/EASCII", useEASCII); } +bool BrowserSettings::advancedMode() +{ + return config()->get("generator/AdvancedMode", PasswordGenerator::DefaultAdvancedMode).toBool(); +} + +void BrowserSettings::setAdvancedMode(bool advancedMode) +{ + config()->set("generator/AdvancedMode", advancedMode); +} + +QString BrowserSettings::passwordExcludedChars() +{ + return config()->get("generator/ExcludedChars", PasswordGenerator::DefaultExcludedChars).toString(); +} + +void BrowserSettings::setPasswordExcludedChars(QString chars) +{ + config()->set("generator/ExcludedChars", chars); +} + int BrowserSettings::passPhraseWordCount() { return config()->get("generator/WordCount", PassphraseGenerator::DefaultWordCount).toInt(); @@ -347,6 +427,24 @@ PasswordGenerator::CharClasses BrowserSettings::passwordCharClasses() if (passwordUseSpecial()) { classes |= PasswordGenerator::SpecialCharacters; } + if (passwordUseBraces()) { + classes |= PasswordGenerator::Braces; + } + if (passwordUsePunctuation()) { + classes |= PasswordGenerator::Punctuation; + } + if (passwordUseQuotes()) { + classes |= PasswordGenerator::Quotes; + } + if (passwordUseDashes()) { + classes |= PasswordGenerator::Dashes; + } + if (passwordUseMath()) { + classes |= PasswordGenerator::Math; + } + if (passwordUseLogograms()) { + classes |= PasswordGenerator::Logograms; + } if (passwordUseEASCII()) { classes |= PasswordGenerator::EASCII; } diff --git a/src/browser/BrowserSettings.h b/src/browser/BrowserSettings.h index b02fd4759..3c79dbed2 100644 --- a/src/browser/BrowserSettings.h +++ b/src/browser/BrowserSettings.h @@ -76,8 +76,24 @@ public: static void setPasswordUseUppercase(bool useUppercase); static bool passwordUseSpecial(); static void setPasswordUseSpecial(bool useSpecial); + static bool passwordUseBraces(); + static void setPasswordUseBraces(bool useBraces); + static bool passwordUsePunctuation(); + static void setPasswordUsePunctuation(bool usePunctuation); + static bool passwordUseQuotes(); + static void setPasswordUseQuotes(bool useQuotes); + static bool passwordUseDashes(); + static void setPasswordUseDashes(bool useDashes); + static bool passwordUseMath(); + static void setPasswordUseMath(bool useMath); + static bool passwordUseLogograms(); + static void setPasswordUseLogograms(bool useLogograms); static bool passwordUseEASCII(); static void setPasswordUseEASCII(bool useEASCII); + static bool advancedMode(); + static void setAdvancedMode(bool advancedMode); + static QString passwordExcludedChars(); + static void setPasswordExcludedChars(QString chars); static int passPhraseWordCount(); static void setPassPhraseWordCount(int wordCount); static QString passPhraseWordSeparator(); diff --git a/src/cli/Generate.cpp b/src/cli/Generate.cpp index 45b67259c..6a5be3f07 100644 --- a/src/cli/Generate.cpp +++ b/src/cli/Generate.cpp @@ -44,19 +44,41 @@ int Generate::execute(const QStringList& arguments) parser.setApplicationDescription(this->description); QCommandLineOption len(QStringList() << "L" << "length", - QObject::tr("Length of the generated password."), + QObject::tr("Length of the generated password"), QObject::tr("length")); parser.addOption(len); - QCommandLineOption lower(QStringList() << "l", QObject::tr("Use lowercase characters in the generated password.")); + QCommandLineOption lower(QStringList() << "l" + << "lower", + QObject::tr("Use lowercase characters")); parser.addOption(lower); - QCommandLineOption upper(QStringList() << "u", QObject::tr("Use uppercase characters in the generated password.")); + QCommandLineOption upper(QStringList() << "u" + << "upper", + QObject::tr("Use uppercase characters")); parser.addOption(upper); - QCommandLineOption numeric(QStringList() << "n", QObject::tr("Use numbers in the generated password.")); + QCommandLineOption numeric(QStringList() << "n" + << "numeric", + QObject::tr("Use numbers.")); parser.addOption(numeric); - QCommandLineOption special(QStringList() << "s", QObject::tr("Use special characters in the generated password.")); + QCommandLineOption special(QStringList() << "s" + << "special", + QObject::tr("Use special characters")); parser.addOption(special); - QCommandLineOption extended(QStringList() << "e", QObject::tr("Use extended ASCII in the generated password.")); + QCommandLineOption extended(QStringList() << "e" + << "extended", + QObject::tr("Use extended ASCII")); parser.addOption(extended); + QCommandLineOption exclude(QStringList() << "x" + << "exclude", + QObject::tr("Exclude character set"), + QObject::tr("chars")); + parser.addOption(exclude); + QCommandLineOption exclude_similar(QStringList() << "exclude-similar", + QObject::tr("Exclude similar looking characters")); + parser.addOption(exclude_similar); + QCommandLineOption every_group(QStringList() << "every-group", + QObject::tr("Include characters from every selected group")); + parser.addOption(every_group); + parser.process(arguments); const QStringList args = parser.positionalArguments(); @@ -92,8 +114,18 @@ int Generate::execute(const QStringList& arguments) classes |= PasswordGenerator::EASCII; } + PasswordGenerator::GeneratorFlags flags = 0x0; + + if (parser.isSet(exclude_similar)) { + flags |= PasswordGenerator::ExcludeLookAlike; + } + if (parser.isSet(every_group)) { + flags |= PasswordGenerator::CharFromEveryGroup; + } + passwordGenerator.setCharClasses(classes); - passwordGenerator.setFlags(PasswordGenerator::DefaultFlags); + passwordGenerator.setFlags(flags); + passwordGenerator.setExcludedChars(parser.value(exclude)); if (!passwordGenerator.isValid()) { outputTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli generate"); diff --git a/src/core/PasswordGenerator.cpp b/src/core/PasswordGenerator.cpp index 00984d313..01b715072 100644 --- a/src/core/PasswordGenerator.cpp +++ b/src/core/PasswordGenerator.cpp @@ -21,10 +21,13 @@ #include "crypto/Random.h" #include +const char* PasswordGenerator::DefaultExcludedChars = ""; + PasswordGenerator::PasswordGenerator() : m_length(0) , m_classes(0) , m_flags(0) + , m_excluded(PasswordGenerator::DefaultExcludedChars) { } @@ -56,6 +59,11 @@ void PasswordGenerator::setFlags(const GeneratorFlags& flags) m_flags = flags; } +void PasswordGenerator::setExcludedChars(const QString& chars) +{ + m_excluded = chars; +} + QString PasswordGenerator::generatePassword() const { Q_ASSERT(isValid()); @@ -130,6 +138,10 @@ bool PasswordGenerator::isValid() const return false; } + if (passwordGroups().size() == 0) { + return false; + } + return true; } @@ -140,7 +152,8 @@ QVector PasswordGenerator::passwordGroups() const if (m_classes & LowerLetters) { PasswordGroup group; - for (int i = 97; i < (97 + 26); i++) { + for (int i = 97; i <= (97 + 25); i++) { + if ((m_flags & ExcludeLookAlike) && (i == 108)) { // "l" continue; } @@ -153,7 +166,8 @@ QVector PasswordGenerator::passwordGroups() const if (m_classes & UpperLetters) { PasswordGroup group; - for (int i = 65; i < (65 + 26); i++) { + for (int i = 65; i <= (65 + 25); i++) { + if ((m_flags & ExcludeLookAlike) && (i == 73 || i == 79)) { // "I" and "O" continue; } @@ -176,28 +190,79 @@ QVector PasswordGenerator::passwordGroups() const passwordGroups.append(group); } - if (m_classes & SpecialCharacters) { + if (m_classes & Braces) { PasswordGroup group; - for (int i = 33; i <= 47; i++) { - group.append(i); + // ()[]{} + group.append(40); + group.append(41); + group.append(91); + group.append(93); + group.append(123); + group.append(125); + + passwordGroups.append(group); + } + if (m_classes & Punctuation) { + PasswordGroup group; + + // .,:; + group.append(44); + group.append(46); + group.append(58); + group.append(59); + + passwordGroups.append(group); + } + if (m_classes & Quotes) { + PasswordGroup group; + + // "' + group.append(34); + group.append(39); + + passwordGroups.append(group); + } + if (m_classes & Dashes) { + PasswordGroup group; + + // -/\_| + group.append(45); + group.append(47); + group.append(92); + group.append(95); + if (!(m_flags & ExcludeLookAlike)) { + group.append(124); // "|" } - for (int i = 58; i <= 64; i++) { - group.append(i); - } - - for (int i = 91; i <= 96; i++) { - group.append(i); - } - - for (int i = 123; i <= 126; i++) { - if ((m_flags & ExcludeLookAlike) && (i == 124)) { // "|" - continue; - } - + passwordGroups.append(group); + } + if (m_classes & Math) { + PasswordGroup group; + + // !*+-<=>? + group.append(33); + group.append(42); + group.append(43); + group.append(60); + group.append(61); + group.append(62); + group.append(63); + + passwordGroups.append(group); + } + if (m_classes & Logograms) { + PasswordGroup group; + + // #$%& + for (int i = 35; i <= 38; i++) { group.append(i); } + // @^`~ + group.append(64); + group.append(94); + group.append(96); + group.append(126); passwordGroups.append(group); } @@ -220,6 +285,27 @@ QVector PasswordGenerator::passwordGroups() const passwordGroups.append(group); } + // Loop over character groups and remove excluded characters from them; + // remove empty groups + int i = 0; + while (i != passwordGroups.size()) { + PasswordGroup group = passwordGroups[i]; + + for (QChar ch : m_excluded) { + int j = group.indexOf(ch); + while (j != -1) { + group.remove(j); + j = group.indexOf(ch); + } + } + if (group.size() > 0) { + passwordGroups.replace(i, group); + i++; + } else { + passwordGroups.remove(i); + } + } + return passwordGroups; } @@ -236,7 +322,22 @@ int PasswordGenerator::numCharClasses() const if (m_classes & Numbers) { numClasses++; } - if (m_classes & SpecialCharacters) { + if (m_classes & Braces) { + numClasses++; + } + if (m_classes & Punctuation) { + numClasses++; + } + if (m_classes & Quotes) { + numClasses++; + } + if (m_classes & Dashes) { + numClasses++; + } + if (m_classes & Math) { + numClasses++; + } + if (m_classes & Logograms) { numClasses++; } if (m_classes & EASCII) { diff --git a/src/core/PasswordGenerator.h b/src/core/PasswordGenerator.h index d6866b5ef..1d6ac73f6 100644 --- a/src/core/PasswordGenerator.h +++ b/src/core/PasswordGenerator.h @@ -30,19 +30,26 @@ class PasswordGenerator public: enum CharClass { - LowerLetters = 0x1, - UpperLetters = 0x2, - Numbers = 0x4, - SpecialCharacters = 0x8, - EASCII = 0x10, + LowerLetters = (1 << 0), + UpperLetters = (1 << 1), + Numbers = (1 << 2), + Braces = (1 << 3), + Punctuation = (1 << 4), + Quotes = (1 << 5), + Dashes = (1 << 6), + Math = (1 << 7), + Logograms = (1 << 8), + SpecialCharacters = Braces | Punctuation | Quotes | Dashes | Math | Logograms, + EASCII = (1 << 9), DefaultCharset = LowerLetters | UpperLetters | Numbers }; Q_DECLARE_FLAGS(CharClasses, CharClass) enum GeneratorFlag { - ExcludeLookAlike = 0x1, - CharFromEveryGroup = 0x2, + ExcludeLookAlike = (1 << 0), + CharFromEveryGroup = (1 << 1), + AdvancedMode = (1 << 2), DefaultFlags = ExcludeLookAlike | CharFromEveryGroup }; Q_DECLARE_FLAGS(GeneratorFlags, GeneratorFlag) @@ -54,6 +61,7 @@ public: void setLength(int length); void setCharClasses(const CharClasses& classes); void setFlags(const GeneratorFlags& flags); + void setExcludedChars(const QString& chars); bool isValid() const; @@ -61,10 +69,18 @@ public: int getbits() const; static const int DefaultLength = 16; + static const char* DefaultExcludedChars; static constexpr bool DefaultLower = (DefaultCharset & LowerLetters) != 0; static constexpr bool DefaultUpper = (DefaultCharset & UpperLetters) != 0; static constexpr bool DefaultNumbers = (DefaultCharset & Numbers) != 0; static constexpr bool DefaultSpecial = (DefaultCharset & SpecialCharacters) != 0; + static constexpr bool DefaultAdvancedMode = (DefaultFlags & AdvancedMode) != 0; + static constexpr bool DefaultBraces = (DefaultCharset & Braces) != 0; + static constexpr bool DefaultPunctuation = (DefaultCharset & Punctuation) != 0; + static constexpr bool DefaultQuotes = (DefaultCharset & Quotes) != 0; + static constexpr bool DefaultDashes = (DefaultCharset & Dashes) != 0; + static constexpr bool DefaultMath = (DefaultCharset & Math) != 0; + static constexpr bool DefaultLogograms = (DefaultCharset & Logograms) != 0; static constexpr bool DefaultEASCII = (DefaultCharset & EASCII) != 0; static constexpr bool DefaultLookAlike = (DefaultFlags & ExcludeLookAlike) != 0; static constexpr bool DefaultFromEveryGroup = (DefaultFlags & CharFromEveryGroup) != 0; @@ -76,6 +92,7 @@ private: int m_length; CharClasses m_classes; GeneratorFlags m_flags; + QString m_excluded; Q_DISABLE_COPY(PasswordGenerator) }; diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 7ee317ad0..f1eb1793b 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/src/gui/EditWidgetIcons.cpp b/src/gui/EditWidgetIcons.cpp index 4292234e1..2228501bd 100644 --- a/src/gui/EditWidgetIcons.cpp +++ b/src/gui/EditWidgetIcons.cpp @@ -19,7 +19,6 @@ #include "EditWidgetIcons.h" #include "ui_EditWidgetIcons.h" -#include #include #include diff --git a/src/gui/PasswordGeneratorWidget.cpp b/src/gui/PasswordGeneratorWidget.cpp index 3d8ebf7be..fed34754b 100644 --- a/src/gui/PasswordGeneratorWidget.cpp +++ b/src/gui/PasswordGeneratorWidget.cpp @@ -42,6 +42,10 @@ PasswordGeneratorWidget::PasswordGeneratorWidget(QWidget* parent) connect(m_ui->editNewPassword, SIGNAL(textChanged(QString)), SLOT(updateButtonsEnabled(QString))); connect(m_ui->editNewPassword, SIGNAL(textChanged(QString)), SLOT(updatePasswordStrength(QString))); connect(m_ui->togglePasswordButton, SIGNAL(toggled(bool)), SLOT(togglePasswordShown(bool))); + connect(m_ui->buttonSimpleMode, SIGNAL(clicked()), SLOT(selectSimpleMode())); + connect(m_ui->buttonAdvancedMode, SIGNAL(clicked()), SLOT(selectAdvancedMode())); + connect(m_ui->buttonAddHex, SIGNAL(clicked()), SLOT(excludeHexChars())); + connect(m_ui->editExcludedChars, SIGNAL(textChanged(QString)), SLOT(updateGenerator())); connect(m_ui->buttonApply, SIGNAL(clicked()), SLOT(applyPassword())); connect(m_ui->buttonCopy, SIGNAL(clicked()), SLOT(copyPassword())); connect(m_ui->buttonGenerate, SIGNAL(clicked()), SLOT(regeneratePassword())); @@ -94,11 +98,34 @@ void PasswordGeneratorWidget::loadSettings() { // Password config m_ui->checkBoxLower->setChecked(config()->get("generator/LowerCase", PasswordGenerator::DefaultLower).toBool()); + m_ui->checkBoxLowerAdv->setChecked(config()->get("generator/LowerCase", PasswordGenerator::DefaultLower).toBool()); m_ui->checkBoxUpper->setChecked(config()->get("generator/UpperCase", PasswordGenerator::DefaultUpper).toBool()); + m_ui->checkBoxUpperAdv->setChecked(config()->get("generator/UpperCase", PasswordGenerator::DefaultUpper).toBool()); m_ui->checkBoxNumbers->setChecked(config()->get("generator/Numbers", PasswordGenerator::DefaultNumbers).toBool()); - m_ui->checkBoxSpecialChars->setChecked( - config()->get("generator/SpecialChars", PasswordGenerator::DefaultSpecial).toBool()); + m_ui->checkBoxNumbersAdv->setChecked( + config()->get("generator/Numbers", PasswordGenerator::DefaultNumbers).toBool()); + m_ui->advancedBar->setVisible( + config()->get("generator/AdvancedMode", PasswordGenerator::DefaultAdvancedMode).toBool()); + m_ui->excludedChars->setVisible( + config()->get("generator/AdvancedMode", PasswordGenerator::DefaultAdvancedMode).toBool()); + m_ui->checkBoxExcludeAlike->setVisible( + config()->get("generator/AdvancedMode", PasswordGenerator::DefaultAdvancedMode).toBool()); + m_ui->checkBoxEnsureEvery->setVisible( + config()->get("generator/AdvancedMode", PasswordGenerator::DefaultAdvancedMode).toBool()); + m_ui->editExcludedChars->setText( + config()->get("generator/ExcludedChars", PasswordGenerator::DefaultExcludedChars).toString()); + m_ui->simpleBar->setVisible( + !(config()->get("generator/AdvancedMode", PasswordGenerator::DefaultAdvancedMode).toBool())); + m_ui->checkBoxBraces->setChecked(config()->get("generator/Braces", PasswordGenerator::DefaultBraces).toBool()); + m_ui->checkBoxQuotes->setChecked(config()->get("generator/Quotes", PasswordGenerator::DefaultQuotes).toBool()); + m_ui->checkBoxPunctuation->setChecked( + config()->get("generator/Punctuation", PasswordGenerator::DefaultPunctuation).toBool()); + m_ui->checkBoxDashes->setChecked(config()->get("generator/Dashes", PasswordGenerator::DefaultDashes).toBool()); + m_ui->checkBoxMath->setChecked(config()->get("generator/Math", PasswordGenerator::DefaultMath).toBool()); + m_ui->checkBoxLogograms->setChecked( + config()->get("generator/Logograms", PasswordGenerator::DefaultLogograms).toBool()); m_ui->checkBoxExtASCII->setChecked(config()->get("generator/EASCII", PasswordGenerator::DefaultEASCII).toBool()); + m_ui->checkBoxExtASCIIAdv->setChecked(config()->get("generator/EASCII", PasswordGenerator::DefaultEASCII).toBool()); m_ui->checkBoxExcludeAlike->setChecked( config()->get("generator/ExcludeAlike", PasswordGenerator::DefaultLookAlike).toBool()); m_ui->checkBoxEnsureEvery->setChecked( @@ -120,11 +147,25 @@ void PasswordGeneratorWidget::loadSettings() void PasswordGeneratorWidget::saveSettings() { // Password config - config()->set("generator/LowerCase", m_ui->checkBoxLower->isChecked()); - config()->set("generator/UpperCase", m_ui->checkBoxUpper->isChecked()); - config()->set("generator/Numbers", m_ui->checkBoxNumbers->isChecked()); + if (m_ui->simpleBar->isVisible()) { + config()->set("generator/LowerCase", m_ui->checkBoxLower->isChecked()); + config()->set("generator/UpperCase", m_ui->checkBoxUpper->isChecked()); + config()->set("generator/Numbers", m_ui->checkBoxNumbers->isChecked()); + config()->set("generator/EASCII", m_ui->checkBoxExtASCII->isChecked()); + } else { + config()->set("generator/LowerCase", m_ui->checkBoxLowerAdv->isChecked()); + config()->set("generator/UpperCase", m_ui->checkBoxUpperAdv->isChecked()); + config()->set("generator/Numbers", m_ui->checkBoxNumbersAdv->isChecked()); + config()->set("generator/EASCII", m_ui->checkBoxExtASCIIAdv->isChecked()); + } config()->set("generator/SpecialChars", m_ui->checkBoxSpecialChars->isChecked()); - config()->set("generator/EASCII", m_ui->checkBoxExtASCII->isChecked()); + config()->set("generator/Braces", m_ui->checkBoxBraces->isChecked()); + config()->set("generator/Punctuation", m_ui->checkBoxPunctuation->isChecked()); + config()->set("generator/Quotes", m_ui->checkBoxQuotes->isChecked()); + config()->set("generator/Dashes", m_ui->checkBoxDashes->isChecked()); + config()->set("generator/Math", m_ui->checkBoxMath->isChecked()); + config()->set("generator/Logograms", m_ui->checkBoxLogograms->isChecked()); + config()->set("generator/ExcludedChars", m_ui->editExcludedChars->text()); config()->set("generator/ExcludeAlike", m_ui->checkBoxExcludeAlike->isChecked()); config()->set("generator/EnsureEvery", m_ui->checkBoxEnsureEvery->isChecked()); config()->set("generator/Length", m_ui->spinBoxLength->value()); @@ -276,6 +317,48 @@ void PasswordGeneratorWidget::togglePasswordShown(bool showing) m_ui->togglePasswordButton->blockSignals(blockSignals); } +void PasswordGeneratorWidget::selectSimpleMode() +{ + m_ui->advancedBar->hide(); + m_ui->excludedChars->hide(); + m_ui->checkBoxExcludeAlike->hide(); + m_ui->checkBoxEnsureEvery->hide(); + m_ui->checkBoxUpper->setChecked(m_ui->checkBoxUpperAdv->isChecked()); + m_ui->checkBoxLower->setChecked(m_ui->checkBoxLowerAdv->isChecked()); + m_ui->checkBoxNumbers->setChecked(m_ui->checkBoxNumbersAdv->isChecked()); + m_ui->checkBoxSpecialChars->setChecked(m_ui->checkBoxBraces->isChecked() | m_ui->checkBoxPunctuation->isChecked() + | m_ui->checkBoxQuotes->isChecked() + | m_ui->checkBoxMath->isChecked() + | m_ui->checkBoxDashes->isChecked() + | m_ui->checkBoxLogograms->isChecked()); + m_ui->checkBoxExtASCII->setChecked(m_ui->checkBoxExtASCIIAdv->isChecked()); + m_ui->simpleBar->show(); +} + +void PasswordGeneratorWidget::selectAdvancedMode() +{ + m_ui->simpleBar->hide(); + m_ui->checkBoxUpperAdv->setChecked(m_ui->checkBoxUpper->isChecked()); + m_ui->checkBoxLowerAdv->setChecked(m_ui->checkBoxLower->isChecked()); + m_ui->checkBoxNumbersAdv->setChecked(m_ui->checkBoxNumbers->isChecked()); + m_ui->checkBoxBraces->setChecked(m_ui->checkBoxSpecialChars->isChecked()); + m_ui->checkBoxPunctuation->setChecked(m_ui->checkBoxSpecialChars->isChecked()); + m_ui->checkBoxQuotes->setChecked(m_ui->checkBoxSpecialChars->isChecked()); + m_ui->checkBoxMath->setChecked(m_ui->checkBoxSpecialChars->isChecked()); + m_ui->checkBoxDashes->setChecked(m_ui->checkBoxSpecialChars->isChecked()); + m_ui->checkBoxLogograms->setChecked(m_ui->checkBoxSpecialChars->isChecked()); + m_ui->checkBoxExtASCIIAdv->setChecked(m_ui->checkBoxExtASCII->isChecked()); + m_ui->advancedBar->show(); + m_ui->excludedChars->show(); + m_ui->checkBoxExcludeAlike->show(); + m_ui->checkBoxEnsureEvery->show(); +} + +void PasswordGeneratorWidget::excludeHexChars() +{ + m_ui->editExcludedChars->setText("GHIJKLMNOPQRSTUVWXYZghijklmnopqrstuvwxyz"); +} + void PasswordGeneratorWidget::colorStrengthIndicator(double entropy) { // Take the existing stylesheet and convert the text and background color to arguments @@ -306,24 +389,69 @@ PasswordGenerator::CharClasses PasswordGeneratorWidget::charClasses() { PasswordGenerator::CharClasses classes; - if (m_ui->checkBoxLower->isChecked()) { - classes |= PasswordGenerator::LowerLetters; - } + if (m_ui->simpleBar->isVisible()) { - if (m_ui->checkBoxUpper->isChecked()) { - classes |= PasswordGenerator::UpperLetters; - } + if (m_ui->checkBoxLower->isChecked()) { + classes |= PasswordGenerator::LowerLetters; + } - if (m_ui->checkBoxNumbers->isChecked()) { - classes |= PasswordGenerator::Numbers; - } + if (m_ui->checkBoxUpper->isChecked()) { + classes |= PasswordGenerator::UpperLetters; + } - if (m_ui->checkBoxSpecialChars->isChecked()) { - classes |= PasswordGenerator::SpecialCharacters; - } + if (m_ui->checkBoxNumbers->isChecked()) { + classes |= PasswordGenerator::Numbers; + } - if (m_ui->checkBoxExtASCII->isChecked()) { - classes |= PasswordGenerator::EASCII; + if (m_ui->checkBoxSpecialChars->isChecked()) { + classes |= PasswordGenerator::SpecialCharacters; + } + + if (m_ui->checkBoxExtASCII->isChecked()) { + classes |= PasswordGenerator::EASCII; + } + + } else { + + if (m_ui->checkBoxLowerAdv->isChecked()) { + classes |= PasswordGenerator::LowerLetters; + } + + if (m_ui->checkBoxUpperAdv->isChecked()) { + classes |= PasswordGenerator::UpperLetters; + } + + if (m_ui->checkBoxNumbersAdv->isChecked()) { + classes |= PasswordGenerator::Numbers; + } + + if (m_ui->checkBoxBraces->isChecked()) { + classes |= PasswordGenerator::Braces; + } + + if (m_ui->checkBoxPunctuation->isChecked()) { + classes |= PasswordGenerator::Punctuation; + } + + if (m_ui->checkBoxQuotes->isChecked()) { + classes |= PasswordGenerator::Quotes; + } + + if (m_ui->checkBoxDashes->isChecked()) { + classes |= PasswordGenerator::Dashes; + } + + if (m_ui->checkBoxMath->isChecked()) { + classes |= PasswordGenerator::Math; + } + + if (m_ui->checkBoxLogograms->isChecked()) { + classes |= PasswordGenerator::Logograms; + } + + if (m_ui->checkBoxExtASCIIAdv->isChecked()) { + classes |= PasswordGenerator::EASCII; + } } return classes; @@ -361,7 +489,22 @@ void PasswordGeneratorWidget::updateGenerator() if (classes.testFlag(PasswordGenerator::Numbers)) { minLength++; } - if (classes.testFlag(PasswordGenerator::SpecialCharacters)) { + if (classes.testFlag(PasswordGenerator::Braces)) { + minLength++; + } + if (classes.testFlag(PasswordGenerator::Punctuation)) { + minLength++; + } + if (classes.testFlag(PasswordGenerator::Quotes)) { + minLength++; + } + if (classes.testFlag(PasswordGenerator::Dashes)) { + minLength++; + } + if (classes.testFlag(PasswordGenerator::Math)) { + minLength++; + } + if (classes.testFlag(PasswordGenerator::Logograms)) { minLength++; } if (classes.testFlag(PasswordGenerator::EASCII)) { @@ -382,6 +525,11 @@ void PasswordGeneratorWidget::updateGenerator() m_passwordGenerator->setLength(m_ui->spinBoxLength->value()); m_passwordGenerator->setCharClasses(classes); + if (m_ui->simpleBar->isVisible()) { + m_passwordGenerator->setExcludedChars(""); + } else { + m_passwordGenerator->setExcludedChars(m_ui->editExcludedChars->text()); + } m_passwordGenerator->setFlags(flags); if (m_passwordGenerator->isValid()) { diff --git a/src/gui/PasswordGeneratorWidget.h b/src/gui/PasswordGeneratorWidget.h index 84d5484b9..5b65d7d22 100644 --- a/src/gui/PasswordGeneratorWidget.h +++ b/src/gui/PasswordGeneratorWidget.h @@ -65,6 +65,9 @@ private slots: void updateButtonsEnabled(const QString& password); void updatePasswordStrength(const QString& password); void togglePasswordShown(bool hidden); + void selectSimpleMode(); + void selectAdvancedMode(); + void excludeHexChars(); void passwordSliderMoved(); void passwordSpinBoxChanged(); diff --git a/src/gui/PasswordGeneratorWidget.ui b/src/gui/PasswordGeneratorWidget.ui index 03f70806f..e196ff89f 100644 --- a/src/gui/PasswordGeneratorWidget.ui +++ b/src/gui/PasswordGeneratorWidget.ui @@ -6,8 +6,8 @@ 0 0 - 547 - 352 + 571 + 394 @@ -19,7 +19,7 @@ - + QLayout::SetMinimumSize @@ -175,12 +175,6 @@ QProgressBar::chunk { - - - 0 - 0 - - QTabWidget::North @@ -204,155 +198,598 @@ QProgressBar::chunk { - - - - - - 0 - 25 - - - - Qt::StrongFocus - - - Upper Case Letters - - - A-Z - - - true - - - optionButtons - - - - - - - - 0 - 25 - - - - Qt::StrongFocus - - - Lower Case Letters - - - a-z - - - true - - - optionButtons - - - - - - - - 0 - 25 - - - - Qt::StrongFocus - - - Numbers - - - 0-9 - - - true - - - optionButtons - - - - - - - - 0 - 25 - - - - Qt::StrongFocus - - - Special Characters - - - /*_& ... - - - true - - - optionButtons - - - - - - - - 0 - 25 - - - - - 16777215 - 16777215 - - - - Qt::StrongFocus - - - Extended ASCII - - - Extended ASCII - - - true - - - optionButtons - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + 25 + + + + Qt::StrongFocus + + + Upper Case Letters + + + A-Z + + + true + + + optionButtons + + + + + + + + 0 + 25 + + + + Qt::StrongFocus + + + Lower Case Letters + + + a-z + + + true + + + optionButtons + + + + + + + + 0 + 25 + + + + Qt::StrongFocus + + + Numbers + + + 0-9 + + + true + + + optionButtons + + + + + + + true + + + + 0 + 25 + + + + Qt::StrongFocus + + + Special Characters + + + /*_& ... + + + true + + + optionButtons + + + + + + + + 0 + 25 + + + + + 16777215 + 16777215 + + + + Qt::StrongFocus + + + Extended ASCII + + + ExtendedASCII + + + true + + + optionButtons + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 25 + + + + Switch to advanced mode + + + Advanced + + + optionButtons + + + + + + + + + + + + true + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 40 + 25 + + + + Qt::StrongFocus + + + Upper Case Letters A to F + + + A-Z + + + true + + + optionButtons + + + + + + + + 40 + 25 + + + + Qt::StrongFocus + + + Lower Case Letters A to F + + + a-z + + + true + + + optionButtons + + + + + + + + + + + + 40 + 25 + + + + Qt::StrongFocus + + + Numbers + + + 0-9 + + + true + + + optionButtons + + + + + + + + 40 + 25 + + + + Qt::StrongFocus + + + Braces + + + {[( + + + true + + + optionButtons + + + + + + + + + + + + 35 + 25 + + + + Qt::StrongFocus + + + Punctuation + + + .,:; + + + true + + + optionButtons + + + + + + + + 35 + 25 + + + + Qt::StrongFocus + + + Quotes + + + " ' + + + true + + + optionButtons + + + + + + + + + + + + 60 + 25 + + + + Qt::StrongFocus + + + Math + + + <*+!?= + + + true + + + optionButtons + + + + + + + + 60 + 25 + + + + Qt::StrongFocus + + + Dashes + + + \_|-/ + + + true + + + optionButtons + + + + + + + + + + + + 105 + 25 + + + + Qt::StrongFocus + + + Logograms + + + #$%&&@^`~ + + + true + + + optionButtons + + + + + + + + 105 + 25 + + + + Qt::StrongFocus + + + Extended ASCII + + + ExtendedASCII + + + true + + + optionButtons + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 25 + + + + Switch to simple mode + + + Simple + + + optionButtons + + + + + + + + + + + + true + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 25 + + + + Character set to exclude from generated password + + + true + + + + + + + Do not include: + + + + + + + + 0 + 25 + + + + Add non-hex letters to "do not include" list + + + Hex + + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + Excluded characters: "0", "1", "l", "I", "O", "|", "﹒" + Exclude look-alike characters @@ -534,6 +971,19 @@ QProgressBar::chunk { + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -585,9 +1035,6 @@ QProgressBar::chunk { - - - @@ -607,7 +1054,29 @@ QProgressBar::chunk { checkBoxLower checkBoxNumbers checkBoxSpecialChars + checkBoxExtASCII + buttonAdvancedMode + checkBoxUpperAdv + checkBoxNumbersAdv + checkBoxPunctuation + checkBoxMath + checkBoxLogograms + checkBoxBraces + checkBoxQuotes + checkBoxDashes + checkBoxExtASCIIAdv + editExcludedChars + buttonSimpleMode checkBoxExcludeAlike + checkBoxEnsureEvery + tabWidget + comboBoxWordList + sliderWordCount + spinBoxWordCount + editWordSeparator + buttonGenerate + buttonCopy + buttonApply