6#include "validatorpwquality_p.h"
10#include <QLoggingCategory>
40 if (!
value.isEmpty()) {
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()) {
58 "ValidatorPwQuality: Failed to set pwquality option %s: %s",
60 pwquality_strerror(buf,
sizeof(buf), orv,
nullptr));
69 if (C_VALIDATOR().isWarningEnabled()) {
71 const int rcrv = pwquality_read_config(
77 "ValidatorPwQuality: Failed to read configuration file %s: %s",
78 qUtf8Printable(configFile),
79 pwquality_strerror(buf,
sizeof(buf), rcrv, auxerror));
90 if (C_VALIDATOR().isWarningEnabled()) {
92 const int rcrv = pwquality_read_config(pwq,
nullptr, &auxerror);
97 "ValidatorPwQuality: Failed to read default configuration file: %s",
98 pwquality_strerror(buf,
sizeof(buf), rcrv, auxerror));
101 pwquality_read_config(pwq,
nullptr,
nullptr);
112 rv = pwquality_check(pwq, pw, opw, u,
nullptr);
114 pwquality_free_settings(pwq);
117 rv = PWQ_ERROR_MEM_ALLOC;
120 rv = PWQ_ERROR_EMPTY_PASSWORD;
133 if (
label.isEmpty()) {
134 switch (returnValue) {
135 case PWQ_ERROR_MEM_ALLOC:
137 c->
translate(
"Cutelyst::ValidatorPwQuality",
138 "Password quality check failed because of a memory allocation error.");
140 case PWQ_ERROR_SAME_PASSWORD:
141 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
142 "The password is the same as the old one.");
144 case PWQ_ERROR_PALINDROME:
145 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password is a palindrome.");
147 case PWQ_ERROR_CASE_CHANGES_ONLY:
148 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
149 "The password differs with case changes only.");
151 case PWQ_ERROR_TOO_SIMILAR:
152 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
153 "The password is too similar to the old one.");
155 case PWQ_ERROR_USER_CHECK:
156 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
157 "The password contains the user name in some form.");
159 case PWQ_ERROR_GECOS_CHECK:
161 "Cutelyst::ValidatorPwQuality",
162 "The password contains words from the real name of the user in some form.");
164 case PWQ_ERROR_BAD_WORDS:
165 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
166 "The password contains forbidden words in some form.");
168 case PWQ_ERROR_MIN_DIGITS:
169 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
170 "The password contains too few digits.");
172 case PWQ_ERROR_MIN_UPPERS:
173 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
174 "The password contains too few uppercase letters.");
176 case PWQ_ERROR_MIN_LOWERS:
177 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
178 "The password contains too few lowercase letters.");
180 case PWQ_ERROR_MIN_OTHERS:
181 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
182 "The password contains too few non-alphanumeric characters.");
184 case PWQ_ERROR_MIN_LENGTH:
185 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"The password is too short.");
187 case PWQ_ERROR_ROTATED:
188 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
189 "The password is just the rotated old one.");
191 case PWQ_ERROR_MIN_CLASSES:
192 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
193 "The password does not contain enough different character types.");
195 case PWQ_ERROR_MAX_CONSECUTIVE:
196 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
197 "The password contains too many same characters consecutively.");
199 case PWQ_ERROR_MAX_CLASS_REPEAT:
201 "Cutelyst::ValidatorPwQuality",
202 "The password contains too many characters of the same type consecutively.");
204 case PWQ_ERROR_MAX_SEQUENCE:
205 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
206 "The password contains too long a monotonous string.");
208 case PWQ_ERROR_EMPTY_PASSWORD:
209 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
"No password supplied.");
212 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
213 "Password quality check failed because we cannot obtain random "
214 "numbers from the RNG device.");
216 case PWQ_ERROR_CRACKLIB_CHECK:
217 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
218 "The password fails the dictionary check.");
220 case PWQ_ERROR_UNKNOWN_SETTING:
221 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
222 "Password quality check failed because of an unknown setting.");
224 case PWQ_ERROR_INTEGER:
226 "Cutelyst::ValidatorPwQuality",
227 "Password quality check failed because of a bad integer value in the settings.");
229 case PWQ_ERROR_NON_INT_SETTING:
230 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
231 "Password quality check failed because of a settings entry is not "
234 case PWQ_ERROR_NON_STR_SETTING:
236 "Cutelyst::ValidatorPwQuality",
237 "Password quality check failed because of a settings entry is not of string type.");
239 case PWQ_ERROR_CFGFILE_OPEN:
241 "Cutelyst::ValidatorPwQuality",
242 "Password quality check failed because opening the configuration file failed.");
244 case PWQ_ERROR_CFGFILE_MALFORMED:
246 "Cutelyst::ValidatorPwQuality",
247 "Password quality check failed because the configuration file is malformed.");
249 case PWQ_ERROR_FATAL_FAILURE:
250 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
251 "Password quality check failed because of a fatal failure.");
255 if (returnValue < 0) {
256 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
257 "Password quality check failed because of an unknown error.");
259 if (returnValue < threshold) {
261 "Cutelyst::ValidatorPwQuality",
262 "The password quality score of %1 is below the threshold of %2.")
269 switch (returnValue) {
270 case PWQ_ERROR_MEM_ALLOC:
271 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
272 "Password quality check for the “%1“ field failed because of a "
273 "memory allocation error.")
276 case PWQ_ERROR_SAME_PASSWORD:
277 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
278 "The password in the “%1” field is the same as the old one.")
281 case PWQ_ERROR_PALINDROME:
282 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
283 "The password in the “%1” field is a palindrome.")
286 case PWQ_ERROR_CASE_CHANGES_ONLY:
287 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
288 "The password in the “%1” field differs with case changes only.")
291 case PWQ_ERROR_TOO_SIMILAR:
292 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
293 "The password in the “%1” field is too similar to the old one.")
296 case PWQ_ERROR_USER_CHECK:
298 c->
translate(
"Cutelyst::ValidatorPwQuality",
299 "The password in the “%1” field contains the user name in some form.")
302 case PWQ_ERROR_GECOS_CHECK:
303 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
304 "The password in the “%1” field contains words from the real name "
305 "of the user name in some form.")
308 case PWQ_ERROR_BAD_WORDS:
310 "Cutelyst::ValidatorPwQuality",
311 "The password in the “%1” field contains forbidden words in some form.")
314 case PWQ_ERROR_MIN_DIGITS:
315 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
316 "The password in the “%1” field contains too few digits.")
319 case PWQ_ERROR_MIN_UPPERS:
321 c->
translate(
"Cutelyst::ValidatorPwQuality",
322 "The password in the “%1” field contains too few uppercase letters.")
325 case PWQ_ERROR_MIN_LOWERS:
327 c->
translate(
"Cutelyst::ValidatorPwQuality",
328 "The password in the “%1” field contains too few lowercase letters.")
331 case PWQ_ERROR_MIN_OTHERS:
334 "Cutelyst::ValidatorPwQuality",
335 "The password in the “%1” field contains too few non-alphanumeric characters.")
338 case PWQ_ERROR_MIN_LENGTH:
339 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
340 "The password in the “%1” field is too short.")
343 case PWQ_ERROR_ROTATED:
344 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
345 "The password in the “%1” field is just the rotated old one.")
348 case PWQ_ERROR_MIN_CLASSES:
350 "Cutelyst::ValidatorPwQuality",
351 "The password in the “%1” field does not contain enough character types.")
354 case PWQ_ERROR_MAX_CONSECUTIVE:
355 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
356 "The password in the “%1” field contains too many same characters "
360 case PWQ_ERROR_MAX_CLASS_REPEAT:
361 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
362 "The password in the “%1” field contains too many characters of "
363 "the same type consecutively.")
366 case PWQ_ERROR_MAX_SEQUENCE:
367 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
368 "The password in the “%1” field contains contains too long a "
369 "monotonous string.")
372 case PWQ_ERROR_EMPTY_PASSWORD:
373 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
374 "No password supplied in the “%1” field.")
378 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
379 "Password quality check for the “%1“ field failed because we "
380 "cannot obtain random numbers from the RNG device.")
383 case PWQ_ERROR_CRACKLIB_CHECK:
384 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
385 "The password in the “%1” field fails the dictionary check.")
388 case PWQ_ERROR_UNKNOWN_SETTING:
389 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
390 "Password quality check for the “%1“ field failed because of an "
394 case PWQ_ERROR_INTEGER:
395 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
396 "Password quality check for the “%1“ field failed because of a "
397 "bad integer value in the settings.")
400 case PWQ_ERROR_NON_INT_SETTING:
401 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
402 "Password quality check for the “%1“ field failed because of a "
403 "settings entry is not of integer type.")
406 case PWQ_ERROR_NON_STR_SETTING:
407 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
408 "Password quality check for the “%1“ field failed because of a "
409 "settings entry is not of string type.")
412 case PWQ_ERROR_CFGFILE_OPEN:
413 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
414 "Password quality check for the “%1“ field failed because opening "
415 "the configuration file failed.")
418 case PWQ_ERROR_CFGFILE_MALFORMED:
419 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
420 "Password quality check for the “%1“ field failed because the "
421 "configuration file is malformed.")
424 case PWQ_ERROR_FATAL_FAILURE:
427 "Cutelyst::ValidatorPwQuality",
428 "Password quality check for the “%1“ field failed because of a fatal failure.")
433 if (returnValue < 0) {
434 error = c->
translate(
"Cutelyst::ValidatorPwQuality",
435 "Password quality check for the “%1” field failed because of "
439 if (returnValue < threshold) {
441 c->
translate(
"Cutelyst::ValidatorPwQuality",
442 "The quality score of %1 for the password in the “%2” field "
443 "is below the threshold of %3.")
463 if (d->options.isValid()) {
467 const QString optString = d->options.toString();
468 if (c->
stash().contains(optString)) {
469 opts = c->
stash(optString);
476 if (!d->userName.isEmpty()) {
477 un = params.value(d->userName);
479 un = c->
stash(d->userName).toString();
483 if (!d->oldPassword.isEmpty()) {
484 opw = params.value(d->oldPassword);
486 opw = c->
stash(d->oldPassword).toString();
489 int rv =
validate(v, opts, opw, un);
490 if (rv < d->threshold) {
492 if (C_VALIDATOR().isDebugEnabled()) {
496 "ValidatorPwQuality: Validation failed for field %s at %s::%s: %s",
498 qPrintable(c->controllerName()),
499 qPrintable(c->actionName()),
500 pwquality_strerror(buf,
sizeof(buf), rv,
nullptr));
503 "ValidatorPwQuality: Validation failed for field %s at %s::%s because "
504 "the quality score %i is below the threshold of %i.",
506 qPrintable(c->controllerName()),
507 qPrintable(c->actionName()),
514 "ValidatorPwQuality: \"%s\" got a quality score of %i",
529 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
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.
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.
ValidatorRule(const QString &field, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new ValidatorRule with the given parameters.
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.
QMultiMap< QString, QString > ParamsMultiMap
const char * constData() const const
bool isEmpty() 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
Stores custom error messages and the input field label.
Contains the result of a single input parameter validation.