32 const QVariant &options,
33 const QString &oldPassword,
38 if (!
value.isEmpty()) {
40 pwquality_settings_t *pwq = pwquality_default_settings();
43 bool optionsSet =
false;
44 if (options.isValid()) {
45 if (options.typeId() == QMetaType::QVariantMap) {
46 const QVariantMap map = options.toMap();
47 for (
const auto &[key, mapValue] : map.asKeyValueRange()) {
48 const QString opt = key + u
'=' + mapValue.toString();
49 const int orv = pwquality_set_option(pwq, opt.toUtf8().constData());
51 QList<char> buf(ValidatorPwQualityPrivate::errStrBufSize);
52 qCWarning(C_VALIDATOR).noquote().nospace()
53 <<
"ValidatorPwQuality: Failed to set pwquality option " << opt
54 <<
": " << pwquality_strerror(buf.data(), buf.size(), orv,
nullptr);
58 }
else if (options.typeId() == QMetaType::QString) {
59 const QString configFile = options.toString();
60 if (!configFile.isEmpty()) {
61 if (C_VALIDATOR().isWarningEnabled()) {
62 void *auxerror =
nullptr;
63 const int rcrv = pwquality_read_config(
64 pwq, configFile.toUtf8().constData(), &auxerror);
66 QList<char> buf(ValidatorPwQualityPrivate::errStrBufSize);
67 qCWarning(C_VALIDATOR).noquote().nospace()
68 <<
"ValidatorPwQuality: Failed to read configuration file "
70 << pwquality_strerror(buf.data(), buf.size(), rcrv, auxerror);
73 pwquality_read_config(pwq, configFile.toUtf8().constData(),
nullptr);
81 if (C_VALIDATOR().isWarningEnabled()) {
82 void *auxerror =
nullptr;
83 const int rcrv = pwquality_read_config(pwq,
nullptr, &auxerror);
85 QList<char> buf(ValidatorPwQualityPrivate::errStrBufSize);
86 qCWarning(C_VALIDATOR).noquote()
87 <<
"VaidatorPwQuality: Failed to read default configuration file:"
88 << pwquality_strerror(buf.data(), buf.size(), rcrv, auxerror);
91 pwquality_read_config(pwq,
nullptr,
nullptr);
95 const QByteArray pwba =
value.toUtf8();
96 const char *pw = pwba.constData();
97 const QByteArray opwba = oldPassword.toUtf8();
98 const char *opw = opwba.isEmpty() ? nullptr : opwba.constData();
99 const QByteArray uba = user.toUtf8();
100 const char *u = uba.isEmpty() ? nullptr : uba.constData();
102 rv = pwquality_check(pwq, pw, opw, u,
nullptr);
104 pwquality_free_settings(pwq);
107 rv = PWQ_ERROR_MEM_ALLOC;
110 rv = PWQ_ERROR_EMPTY_PASSWORD;
118 const QString &
label,
121 if (
label.isEmpty()) {
122 switch (returnValue) {
123 case PWQ_ERROR_MEM_ALLOC:
125 return c->
qtTrId(
"cutelyst-valpwq-err-memalloc");
126 case PWQ_ERROR_SAME_PASSWORD:
128 return c->
qtTrId(
"cutelyst-valpwq-err-samepass");
129 case PWQ_ERROR_PALINDROME:
131 return c->
qtTrId(
"cutelyst-valpwq-err-palindrome");
132 case PWQ_ERROR_CASE_CHANGES_ONLY:
134 return c->
qtTrId(
"cutelyst-valpwq-err-casechangesonly");
135 case PWQ_ERROR_TOO_SIMILAR:
137 return c->
qtTrId(
"cutelyst-valpwq-err-toosimilar");
138 case PWQ_ERROR_USER_CHECK:
140 return c->
qtTrId(
"cutelyst-valpwq-err-usercheck");
141 case PWQ_ERROR_GECOS_CHECK:
143 return c->
qtTrId(
"cutelyst-valpwq-err-gecoscheck");
144 case PWQ_ERROR_BAD_WORDS:
146 return c->
qtTrId(
"cutelyst-valpwq-err-badwords");
147 case PWQ_ERROR_MIN_DIGITS:
149 return c->
qtTrId(
"cutelyst-valpwq-err-mindigits");
150 case PWQ_ERROR_MIN_UPPERS:
152 return c->
qtTrId(
"cutelyst-valpwq-err-minuppers");
153 case PWQ_ERROR_MIN_LOWERS:
155 return c->
qtTrId(
"cutelyst-valpwq-err-minlowers");
156 case PWQ_ERROR_MIN_OTHERS:
158 return c->
qtTrId(
"cutelyst-valpwq-err-minothers");
159 case PWQ_ERROR_MIN_LENGTH:
161 return c->
qtTrId(
"cutelyst-valpwq-err-minlength");
162 case PWQ_ERROR_ROTATED:
164 return c->
qtTrId(
"cutelyst-valpwq-err-rotated");
165 case PWQ_ERROR_MIN_CLASSES:
167 return c->
qtTrId(
"cutelyst-valpwq-err-minclasses");
168 case PWQ_ERROR_MAX_CONSECUTIVE:
170 return c->
qtTrId(
"cutelyst-valpwq-err-maxconsecutive");
171 case PWQ_ERROR_MAX_CLASS_REPEAT:
173 return c->
qtTrId(
"cutelyst-valpwq-err-maxclassrepeat");
174 case PWQ_ERROR_MAX_SEQUENCE:
176 return c->
qtTrId(
"cutelyst-valpwq-err-maxsequence");
177 case PWQ_ERROR_EMPTY_PASSWORD:
179 return c->
qtTrId(
"cutelyst-valpwq-err-emptypw");
183 return c->
qtTrId(
"cutelyst-valpwq-err-rng");
184 case PWQ_ERROR_CRACKLIB_CHECK:
186 return c->
qtTrId(
"cutelyst-valpwq-err-cracklibcheck");
187 case PWQ_ERROR_UNKNOWN_SETTING:
189 return c->
qtTrId(
"cutelyst-valpwq-err-unknownsetting");
190 case PWQ_ERROR_INTEGER:
192 return c->
qtTrId(
"cutelyst-valpwq-err-integer");
193 case PWQ_ERROR_NON_INT_SETTING:
196 return c->
qtTrId(
"cutelyst-valpwq-err-nonintsetting");
197 case PWQ_ERROR_NON_STR_SETTING:
199 return c->
qtTrId(
"cutelyst-valpwq-err-nonstrsetting");
200 case PWQ_ERROR_CFGFILE_OPEN:
202 return c->
qtTrId(
"cutelyst-valpwq-err-cfgfileopen");
203 case PWQ_ERROR_CFGFILE_MALFORMED:
205 return c->
qtTrId(
"cutelyst-valpwq-err-cfgfilemalformed");
206 case PWQ_ERROR_FATAL_FAILURE:
208 return c->
qtTrId(
"cutelyst-valpwq-err-fatalfailure");
211 if (returnValue < 0) {
213 return c->
qtTrId(
"cutelyst-valpwq-err-unknown");
215 if (returnValue < threshold) {
217 return c->
qtTrId(
"cutelyst-valpwq-err-belowthreshold")
218 .arg(QString::number(returnValue), QString::number(threshold));
226 switch (returnValue) {
227 case PWQ_ERROR_MEM_ALLOC:
230 return c->
qtTrId(
"cutelyst-valpwq-err-memalloc-label").arg(
label);
231 case PWQ_ERROR_SAME_PASSWORD:
233 return c->
qtTrId(
"cutelyst-valpwq-err-samepass-label").arg(
label);
234 case PWQ_ERROR_PALINDROME:
236 return c->
qtTrId(
"cutelyst-valpwq-err-palindrome-label").arg(
label);
237 case PWQ_ERROR_CASE_CHANGES_ONLY:
239 return c->
qtTrId(
"cutelyst-valpwq-err-casechangesonly-label").arg(
label);
240 case PWQ_ERROR_TOO_SIMILAR:
242 return c->
qtTrId(
"cutelyst-valpwq-err-toosimilar-label").arg(
label);
243 case PWQ_ERROR_USER_CHECK:
245 return c->
qtTrId(
"cutelyst-valpwq-err-usercheck-label").arg(
label);
246 case PWQ_ERROR_GECOS_CHECK:
249 return c->
qtTrId(
"cutelyst-valpwq-err-gecoscheck-label").arg(
label);
250 case PWQ_ERROR_BAD_WORDS:
252 return c->
qtTrId(
"cutelyst-valpwq-err-badwords-label").arg(
label);
253 case PWQ_ERROR_MIN_DIGITS:
255 return c->
qtTrId(
"cutelyst-valpwq-err-mindigits-label").arg(
label);
256 case PWQ_ERROR_MIN_UPPERS:
258 return c->
qtTrId(
"cutelyst-valpwq-err-minuppers-label").arg(
label);
259 case PWQ_ERROR_MIN_LOWERS:
261 return c->
qtTrId(
"cutelyst-valpwq-err-minlowers-label").arg(
label);
262 case PWQ_ERROR_MIN_OTHERS:
265 return c->
qtTrId(
"cutelyst-valpwq-err-minothers-label").arg(
label);
266 case PWQ_ERROR_MIN_LENGTH:
268 return c->
qtTrId(
"cutelyst-valpwq-err-minlength-label").arg(
label);
269 case PWQ_ERROR_ROTATED:
271 return c->
qtTrId(
"cutelyst-valpwq-err-rotated-label").arg(
label);
272 case PWQ_ERROR_MIN_CLASSES:
274 return c->
qtTrId(
"cutelyst-valpwq-err-minclasses-label").arg(
label);
275 case PWQ_ERROR_MAX_CONSECUTIVE:
278 return c->
qtTrId(
"cutelyst-valpwq-err-maxconsecutive-label").arg(
label);
279 case PWQ_ERROR_MAX_CLASS_REPEAT:
282 return c->
qtTrId(
"cutelyst-valpwq-err-maxclassrepeat-label").arg(
label);
283 case PWQ_ERROR_MAX_SEQUENCE:
286 return c->
qtTrId(
"cutelyst-valpwq-err-maxsequence-label").arg(
label);
287 case PWQ_ERROR_EMPTY_PASSWORD:
289 return c->
qtTrId(
"cutelyst-valpwq-err-emptypw-label").arg(
label);
293 return c->
qtTrId(
"cutelyst-valpwq-err-rng-label").arg(
label);
294 case PWQ_ERROR_CRACKLIB_CHECK:
296 return c->
qtTrId(
"cutelyst-valpwq-err-cracklibcheck-label").arg(
label);
297 case PWQ_ERROR_UNKNOWN_SETTING:
300 return c->
qtTrId(
"cutelyst-valpwq-err-unknownsetting-label").arg(
label);
301 case PWQ_ERROR_INTEGER:
304 return c->
qtTrId(
"cutelyst-valpwq-err-integer-label").arg(
label);
305 case PWQ_ERROR_NON_INT_SETTING:
308 return c->
qtTrId(
"cutelyst-valpwq-err-nonintsetting-label").arg(
label);
309 case PWQ_ERROR_NON_STR_SETTING:
312 return c->
qtTrId(
"cutelyst-valpwq-err-nonstrsetting-label").arg(
label);
313 case PWQ_ERROR_CFGFILE_OPEN:
316 return c->
qtTrId(
"cutelyst-valpwq-err-cfgfileopen-label").arg(
label);
317 case PWQ_ERROR_CFGFILE_MALFORMED:
320 return c->
qtTrId(
"cutelyst-valpwq-err-cfgfilemalformed-label").arg(
label);
321 case PWQ_ERROR_FATAL_FAILURE:
323 return c->
qtTrId(
"cutelyst-valpwq-err-fatalfailure-label").arg(
label);
326 if (returnValue < 0) {
329 return c->
qtTrId(
"cutelyst-valpwq-err-unknown-label").arg(
label);
331 if (returnValue < threshold) {
334 return c->
qtTrId(
"cutelyst-valpwq-err-belowthreshold-label")
335 .arg(QString::number(returnValue), QString::number(threshold));
349 const QString v =
value(params);
354 if (d->options.isValid()) {
355 if (d->options.typeId() == QMetaType::QVariantMap) {
357 }
else if (d->options.typeId() == QMetaType::QString) {
358 const QString optString = d->options.toString();
359 if (c->
stash().contains(optString)) {
360 opts = c->
stash(optString);
367 if (!d->userName.isEmpty()) {
368 un = params.value(d->userName);
370 un = c->
stash(d->userName).toString();
374 if (!d->oldPassword.isEmpty()) {
375 opw = params.value(d->oldPassword);
377 opw = c->
stash(d->oldPassword).toString();
380 int rv =
validate(v, opts, opw, un);
381 if (rv < d->threshold) {
383 if (C_VALIDATOR().isDebugEnabled()) {
385 QList<char> buf(ValidatorPwQualityPrivate::errStrBufSize);
386 qCDebug(C_VALIDATOR).noquote()
388 << pwquality_strerror(buf.data(), buf.size(), rv,
nullptr);
390 qCDebug(C_VALIDATOR).noquote() <<
debugString(c) <<
"The quality score" << rv
391 <<
"is below the threshold of" << d->threshold;
395 qCDebug(C_VALIDATOR).noquote()
396 <<
"ValidatorPwQuality: \"" << v <<
"\" got a quality score of" << rv;
void stash(const QVariantHash &unite)
QString qtTrId(const char *id, int n=-1) const
ValidatorPwQuality(const QString &field, int threshold=ValidatorPwQuality::defaultThreshold, const QVariant &options=QVariant(), const QString &userName={}, const QString &oldPassword={}, const ValidatorMessages &messages=ValidatorMessages())