[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/sourcecodes2/keepassxc/develop/src/core/PasswordHealth.cpp [Back]  [Original]

/*
 *  Copyright (C) 2019 KeePassXC Team 
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 or (at your option)
 *  version 3 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see .
 */

#include 
#include 

#include "Database.h"
#include "Entry.h"
#include "Group.h"
#include "PasswordHealth.h"
#include "zxcvbn.h"

// Define the static member variable with the custom field name
const QString PasswordHealth::OPTION_KNOWN_BAD = QStringLiteral("KnownBad");

PasswordHealth::PasswordHealth(double entropy)
    : m_score(entropy)
    , m_entropy(entropy)
{
    switch (quality()) {
    case Quality::Bad:
    case Quality::Poor:
        m_scoreReasons hierarchy().join('/'), entry->title());
        }
    }
}

/**
 * Call operator of the Health Checker class.
 *
 * Returns the health of the password in `entry`, considering
 * password entropy, re-use, expiration, etc.
 */
QSharedPointer HealthChecker::evaluate(const Entry* entry) const
{
    // Pointer sanity check
    if (!entry) {
        return {};
    }

    // First analyse the password itself
    const auto pwd = entry->password();
    auto health = QSharedPointer(new PasswordHealth(pwd));

    // Second, if the password is in the database more than once,
    // reduce the score accordingly
    const auto& used = m_reuse[pwd];
    const auto count = used.size();
    if (count > 1) {
        constexpr auto penalty = 15;
        health->adjustScore(-penalty * (count - 1));
        health->addScoreReason(QApplication::tr("Password is used %1 times").arg(QString::number(count)));
        // Add the first 20 uses of the password to prevent the details display from growing too large
        for (int i = 0; i < used.size(); ++i) {
            health->addScoreDetails(used[i]);
            if (i == 19) {
                health->addScoreDetails("");
                break;
            }
        }

        // Don't allow re-used passwords to be considered "good"
        // no matter how great their entropy is.
        if (health->score() > 64) {
            health->setScore(64);
        }
    }

    // Third, if the password has already expired, reduce score to 0;
    // or, if the password is going to expire in the next 30 days,
    // reduce score by 2 points per day.
    if (entry->isExpired()) {
        health->setScore(0);
        health->addScoreReason(QApplication::tr("Password has expired"));
        health->addScoreDetails(QApplication::tr("Password expiry was %1")
                                    .arg(entry->timeInfo().expiryTime().toString(Qt::DefaultLocaleShortDate)));
    } else if (entry->timeInfo().expires()) {
        const auto days = QDateTime::currentDateTime().daysTo(entry->timeInfo().expiryTime());
        if (days  60) {
                health->setScore(60);
            }
            // clang-format off
            health->adjustScore((30 - days) * -2);
            health->addScoreReason(days timeInfo().expiryTime().toString(Qt::DefaultLocaleShortDate)));
            //clang-format on
        }
    }

    // Return the result
    return health;
}

Web Proxy Viewer  |  New URL  |  Original Page