19 #include "validatorpwquality_p.h"
20 #include <pwquality.h>
21 #include <QLoggingCategory>
26 ValidatorRule(*new ValidatorPwQualityPrivate(field, threshold, options, userName, oldPassword, messages))
42 pwquality_settings_t *pwq = pwquality_default_settings();
45 bool optionsSet =
false;
48 const QVariantMap map = options.
toMap();
50 auto i = map.constBegin();
51 while (i != map.constEnd()) {
56 qCWarning(C_VALIDATOR,
"ValidatorPwQuality: Failed to set pwquality option %s: %s", qUtf8Printable(opt), pwquality_strerror(buf,
sizeof(buf), orv,
nullptr));
65 if (C_VALIDATOR().isWarningEnabled()) {
67 const int rcrv = pwquality_read_config(pwq, configFile.
toUtf8().
constData(), &auxerror);
70 qCWarning(C_VALIDATOR,
"ValidatorPwQuality: Failed to read configuration file %s: %s", qUtf8Printable(configFile), pwquality_strerror(buf,
sizeof(buf), rcrv, auxerror));
81 if (C_VALIDATOR().isWarningEnabled()) {
83 const int rcrv = pwquality_read_config(pwq,
nullptr, &auxerror);
86 qCWarning(C_VALIDATOR,
"ValidatorPwQuality: Failed to read default configuration file: %s", pwquality_strerror(buf,
sizeof(buf), rcrv, auxerror));
89 pwquality_read_config(pwq,
nullptr,
nullptr);
100 rv = pwquality_check(pwq, pw, opw, u,
nullptr);
102 pwquality_free_settings(pwq);
105 rv = PWQ_ERROR_MEM_ALLOC;
108 rv = PWQ_ERROR_EMPTY_PASSWORD;
119 switch (returnValue) {
120 case PWQ_ERROR_MEM_ALLOC:
121 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check failed because of a memory allocation error.");
123 case PWQ_ERROR_SAME_PASSWORD:
124 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password is the same as the old one.");
126 case PWQ_ERROR_PALINDROME:
127 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password is a palindrome.");
129 case PWQ_ERROR_CASE_CHANGES_ONLY:
130 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password differs with case changes only.");
132 case PWQ_ERROR_TOO_SIMILAR:
133 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password is too similar to the old one.");
135 case PWQ_ERROR_USER_CHECK:
136 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password contains the user name in some form.");
138 case PWQ_ERROR_GECOS_CHECK:
139 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password contains words from the real name of the user in some form.");
141 case PWQ_ERROR_BAD_WORDS:
142 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password contains forbidden words in some form.");
144 case PWQ_ERROR_MIN_DIGITS:
145 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password contains too few digits.");
147 case PWQ_ERROR_MIN_UPPERS:
148 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password contains too few uppercase letters.");
150 case PWQ_ERROR_MIN_LOWERS:
151 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password contains too few lowercase letters.");
153 case PWQ_ERROR_MIN_OTHERS:
154 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password contains too few non-alphanumeric characters.");
156 case PWQ_ERROR_MIN_LENGTH:
157 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password is too short.");
159 case PWQ_ERROR_ROTATED:
160 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password is just the rotated old one.");
162 case PWQ_ERROR_MIN_CLASSES:
163 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password does not contain enough different character types.");
165 case PWQ_ERROR_MAX_CONSECUTIVE:
166 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password contains too many same characters consecutively.");
168 case PWQ_ERROR_MAX_CLASS_REPEAT:
169 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password contains too many characters of the same type consecutively.");
171 case PWQ_ERROR_MAX_SEQUENCE:
172 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password contains too long a monotonous string.");
174 case PWQ_ERROR_EMPTY_PASSWORD:
175 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"No password supplied.");
178 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check failed because we cannot obtain random numbers from the RNG device.");
180 case PWQ_ERROR_CRACKLIB_CHECK:
181 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password fails the dictionary check.");
183 case PWQ_ERROR_UNKNOWN_SETTING:
184 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check failed because of an unknown setting.");
186 case PWQ_ERROR_INTEGER:
187 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check failed because of a bad integer value in the settings.");
189 case PWQ_ERROR_NON_INT_SETTING:
190 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check failed because of a settings entry is not of integer type.");
192 case PWQ_ERROR_NON_STR_SETTING:
193 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check failed because of a settings entry is not of string type.");
195 case PWQ_ERROR_CFGFILE_OPEN:
196 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check failed because opening the configuration file failed.");
198 case PWQ_ERROR_CFGFILE_MALFORMED:
199 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check failed because the configuration file is malformed.");
201 case PWQ_ERROR_FATAL_FAILURE:
202 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check failed because of a fatal failure.");
206 if (returnValue < 0) {
207 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check failed because of an unknown error.");
209 if (returnValue < threshold) {
217 switch (returnValue) {
218 case PWQ_ERROR_MEM_ALLOC:
219 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check for the “%1“ field failed because of a memory allocation error.").
arg(
label);
221 case PWQ_ERROR_SAME_PASSWORD:
222 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field is the same as the old one.").
arg(
label);
224 case PWQ_ERROR_PALINDROME:
225 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field is a palindrome.").
arg(
label);
227 case PWQ_ERROR_CASE_CHANGES_ONLY:
228 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field differs with case changes only.").
arg(
label);
230 case PWQ_ERROR_TOO_SIMILAR:
231 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field is too similar to the old one.").
arg(
label);
233 case PWQ_ERROR_USER_CHECK:
234 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field contains the user name in some form.").
arg(
label);
236 case PWQ_ERROR_GECOS_CHECK:
237 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field contains words from the real name of the user name in some form.").
arg(
label);
239 case PWQ_ERROR_BAD_WORDS:
240 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field contains forbidden words in some form.").
arg(
label);
242 case PWQ_ERROR_MIN_DIGITS:
243 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field contains too few digits.").
arg(
label);
245 case PWQ_ERROR_MIN_UPPERS:
246 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field contains too few uppercase letters.").
arg(
label);
248 case PWQ_ERROR_MIN_LOWERS:
249 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field contains too few lowercase letters.").
arg(
label);
251 case PWQ_ERROR_MIN_OTHERS:
252 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field contains too few non-alphanumeric characters.").
arg(
label);
254 case PWQ_ERROR_MIN_LENGTH:
255 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field is too short.").
arg(
label);
257 case PWQ_ERROR_ROTATED:
258 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field is just the rotated old one.").
arg(
label);
260 case PWQ_ERROR_MIN_CLASSES:
261 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field does not contain enough character types.").
arg(
label);
263 case PWQ_ERROR_MAX_CONSECUTIVE:
264 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field contains too many same characters consecutively.").
arg(
label);
266 case PWQ_ERROR_MAX_CLASS_REPEAT:
267 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field contains too many characters of the same type consecutively.").
arg(
label);
269 case PWQ_ERROR_MAX_SEQUENCE:
270 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field contains contains too long a monotonous string.").
arg(
label);
272 case PWQ_ERROR_EMPTY_PASSWORD:
273 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"No password supplied in the “%1” field.").
arg(
label);
276 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check for the “%1“ field failed because we cannot obtain random numbers from the RNG device.").
arg(
label);
278 case PWQ_ERROR_CRACKLIB_CHECK:
279 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password in the “%1” field fails the dictionary check.").
arg(
label);
281 case PWQ_ERROR_UNKNOWN_SETTING:
282 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check for the “%1“ field failed because of an unknown setting.").
arg(
label);
284 case PWQ_ERROR_INTEGER:
285 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check for the “%1“ field failed because of a bad integer value in the settings.").
arg(
label);
287 case PWQ_ERROR_NON_INT_SETTING:
288 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check for the “%1“ field failed because of a settings entry is not of integer type.").
arg(
label);
290 case PWQ_ERROR_NON_STR_SETTING:
291 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check for the “%1“ field failed because of a settings entry is not of string type.").
arg(
label);
293 case PWQ_ERROR_CFGFILE_OPEN:
294 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check for the “%1“ field failed because opening the configuration file failed.").
arg(
label);
296 case PWQ_ERROR_CFGFILE_MALFORMED:
297 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check for the “%1“ field failed because the configuration file is malformed.").
arg(
label);
299 case PWQ_ERROR_FATAL_FAILURE:
300 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check for the “%1“ field failed because of a fatal failure.").
arg(
label);
304 if (returnValue < 0) {
305 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"Password quality check for the “%1” field failed because of an unknown error.").
arg(
label);
307 if (returnValue < threshold) {
328 if (d->options.isValid()) {
332 const QString optString = d->options.toString();
333 if (c->
stash().contains(optString)) {
334 opts = c->
stash(optString);
341 if (!d->userName.isEmpty()) {
342 un = params.
value(d->userName);
344 un = c->
stash(d->userName).toString();
348 if (!d->oldPassword.isEmpty()) {
349 opw = params.
value(d->oldPassword);
351 opw = c->
stash(d->oldPassword).toString();
354 int rv =
validate(v, opts, opw, un);
355 if (rv < d->threshold) {
357 if (C_VALIDATOR().isDebugEnabled()) {
360 qCDebug(C_VALIDATOR,
"ValidatorPwQuality: Validation failed for field %s at %s::%s: %s", qPrintable(
field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), pwquality_strerror(buf,
sizeof(buf), rv,
nullptr));
362 qCDebug(C_VALIDATOR,
"ValidatorPwQuality: Validation failed for field %s at %s::%s because the quality score %i is below the threshold of %i.", qPrintable(
field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), rv, d->threshold);
366 qCDebug(C_VALIDATOR,
"ValidatorPwQuality: \"%s\" got a quality score of %i", qPrintable(v), rv);
379 const int returnValue = errorData.
toInt();
void stash(const QVariantHash &unite)
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Validates an input field with libpwquality to check password quality.
ValidatorPwQuality(const QString &field, int threshold=30, const QVariant &options=QVariant(), const QString &userName=QString(), const QString &oldPassword=QString(), const ValidatorMessages &messages=ValidatorMessages())
Constructs a new ValidatorPwQuality with the given parameters.
static QString errorString(Context *c, int returnValue, const QString &label=QString(), int threshold=0)
Returns a human readable string for the return value of ValidatorPwQuality::validate()
QString genericValidationError(Context *c, const QVariant &errorData) const override
Returns a generic error message if validation failed.
~ValidatorPwQuality() override
Deconstructs the ValidatorPwQuality.
Base class for all validator rules.
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
QString field() const
Returns the name of the field to validate.
QString value(const ParamsMultiMap ¶ms) const
Returns the value of the field from the input params.
QString validationError(Context *c, const QVariant &errorData=QVariant()) const
Returns a descriptive error message if validation failed.
static int validate(const QString &value, const QVariant &options=QVariant(), const QString &oldPassword=QString(), const QString &user=QString())
Returns the password quality score for value.
The Cutelyst namespace holds all public Cutelyst API.
const char * constData() const const
bool isEmpty() const const
const T value(const Key &key, const T &defaultValue) const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
bool isEmpty() const const
QString number(int n, int base)
QByteArray toUtf8() const const
bool isValid() const const
int toInt(bool *ok) const const
QMap< QString, QVariant > toMap() const const
QString toString() const const
QVariant::Type type() const const
Stores custom error messages and the input field label.
Contains the result of a single input parameter validation.