[users] Consume error information from libpwquality
Previously, the auxerror information was never stored, and the messages were all un-numbered or un-explained. Now, consume that information and store it when check() is called, ready to be used when (possibly much later, or after a translation change) explanation() is called.
This commit is contained in:
parent
43565027f5
commit
b4c3236e4a
@ -112,24 +112,73 @@ public:
|
|||||||
/// Sets an option via the configuration string @p v, <key>=<value> style.
|
/// Sets an option via the configuration string @p v, <key>=<value> style.
|
||||||
int set( const QString& v ) { return pwquality_set_option( m_settings, v.toUtf8().constData() ); }
|
int set( const QString& v ) { return pwquality_set_option( m_settings, v.toUtf8().constData() ); }
|
||||||
|
|
||||||
/// Checks the given password @p pwd against the current configuration
|
/** @brief Checks the given password @p pwd against the current configuration
|
||||||
|
*
|
||||||
|
* Resets m_errorString and m_errorCount and then sets them appropriately
|
||||||
|
* so that explanation() can be called afterwards. Sets m_rv as well.
|
||||||
|
*/
|
||||||
|
|
||||||
int check( const QString& pwd )
|
int check( const QString& pwd )
|
||||||
{
|
{
|
||||||
void* auxerror = nullptr;
|
void* auxerror = nullptr;
|
||||||
int r = pwquality_check( m_settings, pwd.toUtf8().constData(), nullptr, nullptr, &auxerror );
|
m_rv = pwquality_check( m_settings, pwd.toUtf8().constData(), nullptr, nullptr, &auxerror );
|
||||||
m_rv = r;
|
|
||||||
return r;
|
// Positive return values could be ignored; some negative ones
|
||||||
|
// place extra information in auxerror, which is a void* and
|
||||||
|
// which needs interpretation to long- or string-values.
|
||||||
|
m_errorCount = 0;
|
||||||
|
m_errorString = QString();
|
||||||
|
|
||||||
|
switch ( m_rv )
|
||||||
|
{
|
||||||
|
case PWQ_ERROR_CRACKLIB_CHECK:
|
||||||
|
if ( auxerror )
|
||||||
|
{
|
||||||
|
/* Here the string comes from cracklib, don't free? */
|
||||||
|
m_errorString = mungeString( auxerror );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PWQ_ERROR_MEM_ALLOC:
|
||||||
|
case PWQ_ERROR_UNKNOWN_SETTING:
|
||||||
|
case PWQ_ERROR_INTEGER:
|
||||||
|
case PWQ_ERROR_NON_INT_SETTING:
|
||||||
|
case PWQ_ERROR_NON_STR_SETTING:
|
||||||
|
if ( auxerror )
|
||||||
|
{
|
||||||
|
m_errorString = mungeString( auxerror );
|
||||||
|
free( auxerror );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PWQ_ERROR_MIN_DIGITS:
|
||||||
|
case PWQ_ERROR_MIN_UPPERS:
|
||||||
|
case PWQ_ERROR_MIN_LOWERS:
|
||||||
|
case PWQ_ERROR_MIN_OTHERS:
|
||||||
|
case PWQ_ERROR_MIN_LENGTH:
|
||||||
|
case PWQ_ERROR_MIN_CLASSES:
|
||||||
|
case PWQ_ERROR_MAX_CONSECUTIVE:
|
||||||
|
case PWQ_ERROR_MAX_CLASS_REPEAT:
|
||||||
|
case PWQ_ERROR_MAX_SEQUENCE:
|
||||||
|
if ( auxerror )
|
||||||
|
{
|
||||||
|
m_errorCount = mungeLong( auxerror );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is roughly the same as the function pwquality_strerror,
|
return m_rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @brief Explain the results of the last call to check()
|
||||||
|
*
|
||||||
|
* This is roughly the same as the function pwquality_strerror,
|
||||||
* only with QStrings instead, and using the Qt translation scheme.
|
* only with QStrings instead, and using the Qt translation scheme.
|
||||||
* It is used under the terms of the GNU GPL v3 or later, as
|
* It is used under the terms of the GNU GPL v3 or later, as
|
||||||
* allowed by the libpwquality license (LICENSES/GPLv2+-libpwquality)
|
* allowed by the libpwquality license (LICENSES/GPLv2+-libpwquality)
|
||||||
*/
|
*/
|
||||||
QString explanation()
|
QString explanation()
|
||||||
{
|
{
|
||||||
void* auxerror = nullptr;
|
|
||||||
|
|
||||||
if ( m_rv >= arbitrary_minimum_strength )
|
if ( m_rv >= arbitrary_minimum_strength )
|
||||||
{
|
{
|
||||||
return QString();
|
return QString();
|
||||||
@ -142,12 +191,10 @@ public:
|
|||||||
switch ( m_rv )
|
switch ( m_rv )
|
||||||
{
|
{
|
||||||
case PWQ_ERROR_MEM_ALLOC:
|
case PWQ_ERROR_MEM_ALLOC:
|
||||||
if ( auxerror )
|
if ( !m_errorString.isEmpty() )
|
||||||
{
|
{
|
||||||
QString s = QCoreApplication::translate( "PWQ", "Memory allocation error when setting '%1'" )
|
return QCoreApplication::translate( "PWQ", "Memory allocation error when setting '%1'" )
|
||||||
.arg( mungeString( auxerror ) );
|
.arg( m_errorString );
|
||||||
free( auxerror );
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "Memory allocation error" );
|
return QCoreApplication::translate( "PWQ", "Memory allocation error" );
|
||||||
case PWQ_ERROR_SAME_PASSWORD:
|
case PWQ_ERROR_SAME_PASSWORD:
|
||||||
@ -166,79 +213,75 @@ public:
|
|||||||
case PWQ_ERROR_BAD_WORDS:
|
case PWQ_ERROR_BAD_WORDS:
|
||||||
return QCoreApplication::translate( "PWQ", "The password contains forbidden words in some form" );
|
return QCoreApplication::translate( "PWQ", "The password contains forbidden words in some form" );
|
||||||
case PWQ_ERROR_MIN_DIGITS:
|
case PWQ_ERROR_MIN_DIGITS:
|
||||||
if ( auxerror )
|
if ( m_errorCount )
|
||||||
{
|
{
|
||||||
return QCoreApplication::translate(
|
return QCoreApplication::translate(
|
||||||
"PWQ", "The password contains fewer than %n digits", nullptr, mungeLong( auxerror ) );
|
"PWQ", "The password contains fewer than %n digits", nullptr, m_errorCount );
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "The password contains too few digits" );
|
return QCoreApplication::translate( "PWQ", "The password contains too few digits" );
|
||||||
case PWQ_ERROR_MIN_UPPERS:
|
case PWQ_ERROR_MIN_UPPERS:
|
||||||
if ( auxerror )
|
if ( m_errorCount )
|
||||||
{
|
{
|
||||||
return QCoreApplication::translate(
|
return QCoreApplication::translate(
|
||||||
"PWQ", "The password contains fewer than %n uppercase letters", nullptr, mungeLong( auxerror ) );
|
"PWQ", "The password contains fewer than %n uppercase letters", nullptr, m_errorCount );
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "The password contains too few uppercase letters" );
|
return QCoreApplication::translate( "PWQ", "The password contains too few uppercase letters" );
|
||||||
case PWQ_ERROR_MIN_LOWERS:
|
case PWQ_ERROR_MIN_LOWERS:
|
||||||
if ( auxerror )
|
if ( m_errorCount )
|
||||||
{
|
{
|
||||||
return QCoreApplication::translate(
|
return QCoreApplication::translate(
|
||||||
"PWQ", "The password contains fewer than %n lowercase letters", nullptr, mungeLong( auxerror ) );
|
"PWQ", "The password contains fewer than %n lowercase letters", nullptr, m_errorCount );
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "The password contains too few lowercase letters" );
|
return QCoreApplication::translate( "PWQ", "The password contains too few lowercase letters" );
|
||||||
case PWQ_ERROR_MIN_OTHERS:
|
case PWQ_ERROR_MIN_OTHERS:
|
||||||
if ( auxerror )
|
if ( m_errorCount )
|
||||||
{
|
{
|
||||||
return QCoreApplication::translate( "PWQ",
|
return QCoreApplication::translate(
|
||||||
"The password contains fewer than %n non-alphanumeric characters",
|
"PWQ", "The password contains fewer than %n non-alphanumeric characters", nullptr, m_errorCount );
|
||||||
nullptr,
|
|
||||||
mungeLong( auxerror ) );
|
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "The password contains too few non-alphanumeric characters" );
|
return QCoreApplication::translate( "PWQ", "The password contains too few non-alphanumeric characters" );
|
||||||
case PWQ_ERROR_MIN_LENGTH:
|
case PWQ_ERROR_MIN_LENGTH:
|
||||||
if ( auxerror )
|
if ( m_errorCount )
|
||||||
{
|
{
|
||||||
return QCoreApplication::translate(
|
return QCoreApplication::translate(
|
||||||
"PWQ", "The password is shorter than %n characters", nullptr, mungeLong( auxerror ) );
|
"PWQ", "The password is shorter than %n characters", nullptr, m_errorCount );
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "The password is too short" );
|
return QCoreApplication::translate( "PWQ", "The password is too short" );
|
||||||
case PWQ_ERROR_ROTATED:
|
case PWQ_ERROR_ROTATED:
|
||||||
return QCoreApplication::translate( "PWQ", "The password is a rotated version of the previous one" );
|
return QCoreApplication::translate( "PWQ", "The password is a rotated version of the previous one" );
|
||||||
case PWQ_ERROR_MIN_CLASSES:
|
case PWQ_ERROR_MIN_CLASSES:
|
||||||
if ( auxerror )
|
if ( m_errorCount )
|
||||||
{
|
{
|
||||||
return QCoreApplication::translate(
|
return QCoreApplication::translate(
|
||||||
"PWQ", "The password contains fewer than %n character classes", nullptr, mungeLong( auxerror ) );
|
"PWQ", "The password contains fewer than %n character classes", nullptr, m_errorCount );
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "The password does not contain enough character classes" );
|
return QCoreApplication::translate( "PWQ", "The password does not contain enough character classes" );
|
||||||
case PWQ_ERROR_MAX_CONSECUTIVE:
|
case PWQ_ERROR_MAX_CONSECUTIVE:
|
||||||
if ( auxerror )
|
if ( m_errorCount )
|
||||||
{
|
{
|
||||||
return QCoreApplication::translate( "PWQ",
|
return QCoreApplication::translate(
|
||||||
"The password contains more than %n same characters consecutively",
|
"PWQ", "The password contains more than %n same characters consecutively", nullptr, m_errorCount );
|
||||||
nullptr,
|
|
||||||
mungeLong( auxerror ) );
|
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "The password contains too many same characters consecutively" );
|
return QCoreApplication::translate( "PWQ", "The password contains too many same characters consecutively" );
|
||||||
case PWQ_ERROR_MAX_CLASS_REPEAT:
|
case PWQ_ERROR_MAX_CLASS_REPEAT:
|
||||||
if ( auxerror )
|
if ( m_errorCount )
|
||||||
{
|
{
|
||||||
return QCoreApplication::translate(
|
return QCoreApplication::translate(
|
||||||
"PWQ",
|
"PWQ",
|
||||||
"The password contains more than %n characters of the same class consecutively",
|
"The password contains more than %n characters of the same class consecutively",
|
||||||
nullptr,
|
nullptr,
|
||||||
mungeLong( auxerror ) );
|
m_errorCount );
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate(
|
return QCoreApplication::translate(
|
||||||
"PWQ", "The password contains too many characters of the same class consecutively" );
|
"PWQ", "The password contains too many characters of the same class consecutively" );
|
||||||
case PWQ_ERROR_MAX_SEQUENCE:
|
case PWQ_ERROR_MAX_SEQUENCE:
|
||||||
if ( auxerror )
|
if ( m_errorCount )
|
||||||
{
|
{
|
||||||
return QCoreApplication::translate(
|
return QCoreApplication::translate(
|
||||||
"PWQ",
|
"PWQ",
|
||||||
"The password contains monotonic sequence longer than %n characters",
|
"The password contains monotonic sequence longer than %n characters",
|
||||||
nullptr,
|
nullptr,
|
||||||
mungeLong( auxerror ) );
|
m_errorCount );
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ",
|
return QCoreApplication::translate( "PWQ",
|
||||||
"The password contains too long of a monotonic character sequence" );
|
"The password contains too long of a monotonic character sequence" );
|
||||||
@ -250,46 +293,34 @@ public:
|
|||||||
return QCoreApplication::translate( "PWQ",
|
return QCoreApplication::translate( "PWQ",
|
||||||
"Password generation failed - required entropy too low for settings" );
|
"Password generation failed - required entropy too low for settings" );
|
||||||
case PWQ_ERROR_CRACKLIB_CHECK:
|
case PWQ_ERROR_CRACKLIB_CHECK:
|
||||||
if ( auxerror )
|
if ( !m_errorString.isEmpty() )
|
||||||
{
|
{
|
||||||
/* Here the string comes from cracklib, don't free? */
|
|
||||||
return QCoreApplication::translate( "PWQ", "The password fails the dictionary check - %1" )
|
return QCoreApplication::translate( "PWQ", "The password fails the dictionary check - %1" )
|
||||||
.arg( mungeString( auxerror ) );
|
.arg( m_errorString );
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "The password fails the dictionary check" );
|
return QCoreApplication::translate( "PWQ", "The password fails the dictionary check" );
|
||||||
case PWQ_ERROR_UNKNOWN_SETTING:
|
case PWQ_ERROR_UNKNOWN_SETTING:
|
||||||
if ( auxerror )
|
if ( !m_errorString.isEmpty() )
|
||||||
{
|
{
|
||||||
QString s = QCoreApplication::translate( "PWQ", "Unknown setting - %1" ).arg( mungeString( auxerror ) );
|
return QCoreApplication::translate( "PWQ", "Unknown setting - %1" ).arg( m_errorString );
|
||||||
free( auxerror );
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "Unknown setting" );
|
return QCoreApplication::translate( "PWQ", "Unknown setting" );
|
||||||
case PWQ_ERROR_INTEGER:
|
case PWQ_ERROR_INTEGER:
|
||||||
if ( auxerror )
|
if ( !m_errorString.isEmpty() )
|
||||||
{
|
{
|
||||||
QString s = QCoreApplication::translate( "PWQ", "Bad integer value of setting - %1" )
|
return QCoreApplication::translate( "PWQ", "Bad integer value of setting - %1" ).arg( m_errorString );
|
||||||
.arg( mungeString( auxerror ) );
|
|
||||||
free( auxerror );
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "Bad integer value" );
|
return QCoreApplication::translate( "PWQ", "Bad integer value" );
|
||||||
case PWQ_ERROR_NON_INT_SETTING:
|
case PWQ_ERROR_NON_INT_SETTING:
|
||||||
if ( auxerror )
|
if ( !m_errorString.isEmpty() )
|
||||||
{
|
{
|
||||||
QString s = QCoreApplication::translate( "PWQ", "Setting %1 is not of integer type" )
|
return QCoreApplication::translate( "PWQ", "Setting %1 is not of integer type" ).arg( m_errorString );
|
||||||
.arg( mungeString( auxerror ) );
|
|
||||||
free( auxerror );
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "Setting is not of integer type" );
|
return QCoreApplication::translate( "PWQ", "Setting is not of integer type" );
|
||||||
case PWQ_ERROR_NON_STR_SETTING:
|
case PWQ_ERROR_NON_STR_SETTING:
|
||||||
if ( auxerror )
|
if ( !m_errorString.isEmpty() )
|
||||||
{
|
{
|
||||||
QString s = QCoreApplication::translate( "PWQ", "Setting %1 is not of string type" )
|
return QCoreApplication::translate( "PWQ", "Setting %1 is not of string type" ).arg( m_errorString );
|
||||||
.arg( mungeString( auxerror ) );
|
|
||||||
free( auxerror );
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
return QCoreApplication::translate( "PWQ", "Setting is not of string type" );
|
return QCoreApplication::translate( "PWQ", "Setting is not of string type" );
|
||||||
case PWQ_ERROR_CFGFILE_OPEN:
|
case PWQ_ERROR_CFGFILE_OPEN:
|
||||||
@ -304,8 +335,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pwquality_settings_t* m_settings;
|
QString m_errorString; ///< Textual error from last call to check()
|
||||||
int m_rv;
|
int m_errorCount = 0; ///< Count (used in %n) error from last call to check()
|
||||||
|
int m_rv = 0; ///< Return value from libpwquality
|
||||||
|
|
||||||
|
pwquality_settings_t* m_settings = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_CHECK_FUNC( libpwquality )
|
DEFINE_CHECK_FUNC( libpwquality )
|
||||||
|
Loading…
Reference in New Issue
Block a user