6 #include "validatorpwquality_p.h" 10 #include <QLoggingCategory> 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;
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();
Validates an input field with libpwquality to check password quality.
QString validationError(Context *c, const QVariant &errorData=QVariant()) const
Returns a descriptive error message if validation failed.
Stores custom error messages and the input field label.
bool isEmpty() const const
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.
QString number(double n, char format, int precision)
int toInt(bool *ok) const const
void stash(const QVariantHash &unite)
~ValidatorPwQuality() override
Deconstructs the ValidatorPwQuality.
bool isEmpty() const 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.
const char * constData() const const
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
The Cutelyst namespace holds all public Cutelyst API.
QString genericValidationError(Context *c, const QVariant &errorData) const override
Returns a generic error message if validation failed.
Base class for all validator rules.
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
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 value(const ParamsMultiMap ¶ms) const
Returns the value of the field from the input params.
QMap< QString, QVariant > toMap() const const
QString field() const
Returns the name of the field to validate.
bool isValid() const const
Contains the result of a single input parameter validation.
QString arg(Args &&... args) const const
QString toString() const const
T value(const Key &key, const T &defaultValue) const const
QByteArray toUtf8() const const