5 #include "authenticationrealm.h" 6 #include "credentialpassword_p.h" 10 #include <QLoggingCategory> 11 #include <QMessageAuthenticationCode> 17 Q_LOGGING_CATEGORY(C_CREDENTIALPASSWORD,
"cutelyst.plugin.credentialpassword", QtWarningMsg)
21 , d_ptr(new CredentialPasswordPrivate)
38 bool validPassword =
false;
39 if (d->passwordType == PasswordType::SelfCheck) {
44 validPassword = d->checkPassword(_user, authinfo);
50 qCDebug(C_CREDENTIALPASSWORD) <<
"Password didn't match";
53 qCDebug(C_CREDENTIALPASSWORD)
54 <<
"Unable to locate a user matching user info provided in realm";
62 return d->passwordField;
68 d->passwordField = fieldName;
74 return d->passwordType;
80 d->passwordType = type;
86 return d->passwordPreSalt;
92 d->passwordPreSalt = passwordPreSalt;
98 return d->passwordPostSalt;
104 d->passwordPostSalt = passwordPostSalt;
111 for (
int i = 0; i < a.
size() && i < b.
size(); i++) {
118 #define HASH_SECTIONS 4 119 #define HASH_ALGORITHM_INDEX 0 120 #define HASH_ITERATION_INDEX 1 121 #define HASH_SALT_INDEX 2 122 #define HASH_PBKDF2_INDEX 3 128 if (params.
size() < HASH_SECTIONS) {
132 int method = CredentialPasswordPrivate::cryptoStrToEnum(params.
at(HASH_ALGORITHM_INDEX));
138 return slowEquals(pbkdf2Hash,
139 pbkdf2(static_cast<QCryptographicHash::Algorithm>(method),
141 params.
at(HASH_SALT_INDEX),
142 params.
at(HASH_ITERATION_INDEX).toInt(),
154 QFile random(u
"/dev/urandom"_s);
164 const QByteArray methodStr = CredentialPasswordPrivate::cryptoEnumToStr(method);
166 pbkdf2(method, password, salt, iterations, hashByteSize).
toBase64();
186 if (rounds <= 0 || keyLength <= 0) {
187 qCCritical(C_CREDENTIALPASSWORD,
"PBKDF2 ERROR: Invalid parameters.");
191 if (salt.
size() == 0 || salt.
size() > std::numeric_limits<int>::max() - 4) {
196 int saltSize = salt.
size();
198 asalt.
resize(saltSize + 4);
205 for (
int count = 1, remainingBytes = keyLength; remainingBytes > 0; ++count) {
206 asalt[saltSize + 0] =
static_cast<char>((count >> 24) & 0xff);
207 asalt[saltSize + 1] =
static_cast<char>((count >> 16) & 0xff);
208 asalt[saltSize + 2] =
static_cast<char>((count >> 8) & 0xff);
209 asalt[saltSize + 3] =
static_cast<char>(count & 0xff);
213 obuf = d1 = code.
result();
215 for (
int i = 1; i < rounds; ++i) {
219 auto it = obuf.
begin();
221 while (d1It != d1.
cend()) {
229 remainingBytes -= obuf.
size();
246 const QString password = passwordPreSalt + authinfo.
value(passwordField) + passwordPostSalt;
252 return storedPassword == password;
254 qCDebug(C_CREDENTIALPASSWORD) <<
"CredentialPassword is set to ignore password check";
257 qCWarning(C_CREDENTIALPASSWORD) <<
"checkPassword called with SelfCheck type; " 258 "password validation should be delegated to the store";
268 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 270 hashmethod = QByteArrayLiteral(
"Md4");
272 hashmethod = QByteArrayLiteral(
"Md5");
276 hashmethod = QByteArrayLiteral(
"Sha1");
278 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 280 hashmethod = QByteArrayLiteral(
"Sha224");
282 hashmethod = QByteArrayLiteral(
"Sha256");
284 hashmethod = QByteArrayLiteral(
"Sha384");
286 hashmethod = QByteArrayLiteral(
"Sha512");
288 hashmethod = QByteArrayLiteral(
"Sha3_224");
290 hashmethod = QByteArrayLiteral(
"Sha3_256");
292 hashmethod = QByteArrayLiteral(
"Sha3_384");
294 hashmethod = QByteArrayLiteral(
"Sha3_512");
301 int CredentialPasswordPrivate::cryptoStrToEnum(
const QByteArray &hashMethod)
306 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 307 if (hashmethod ==
"Md4") {
309 }
else if (hashmethod ==
"Md5") {
313 if (hashmethod ==
"Sha1") {
316 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 317 if (hashmethod ==
"Sha224") {
319 }
else if (hashmethod ==
"Sha256") {
321 }
else if (hashmethod ==
"Sha384") {
323 }
else if (hashmethod ==
"Sha512") {
325 }
else if (hashmethod ==
"Sha3_224") {
327 }
else if (hashmethod ==
"Sha3_256") {
329 }
else if (hashmethod ==
"Sha3_384") {
331 }
else if (hashmethod ==
"Sha3_512") {
339 #include "moc_credentialpassword.cpp" const_iterator cbegin() const const
QString passwordPostSalt() const
QList< QByteArray > split(char sep) const const
virtual AuthenticationUser findUser(Context *c, const ParamsMultiMap &userinfo)
const_iterator cend() const const
bool checkPassword(Context *c, AuthenticationRealm *realm, const QString &password, const QString &passwordField=QStringLiteral("password"))
void reserve(qsizetype size)
void setPasswordPreSalt(const QString &passwordPreSalt)
const_reference at(qsizetype i) const const
static QByteArray hmac(QCryptographicHash::Algorithm method, const QByteArray &key, const QByteArray &message)
Use password based authentication to authenticate a user.
qsizetype length() const const
Abstract class to validate authentication credentials like user name and password.
qsizetype size() const const
Combines user store and credential validation into a named realm.
QByteArray read(qint64 maxSize)
void setPasswordType(PasswordType type)
static QByteArray createPassword(const QByteArray &password, QCryptographicHash::Algorithm method, int iterations, int saltByteSize, int hashByteSize)
QByteArray result() const const
QByteArray number(double n, char format, int precision)
QString passwordField() const
QString passwordPreSalt() const
void truncate(qsizetype pos)
The Cutelyst namespace holds all public Cutelyst API.
QByteArray & append(QByteArrayView data)
Container for user data retrieved from an AuthenticationStore.
void resize(qsizetype newSize, char c)
QByteArray hash(QByteArrayView message, QByteArrayView key, QCryptographicHash::Algorithm method)
bool addData(QIODevice *device)
QByteArray fromBase64(const QByteArray &base64, Base64Options options)
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
void setPasswordField(const QString &fieldName)
bool open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags)
PasswordType passwordType() const
static QByteArray pbkdf2(QCryptographicHash::Algorithm method, const QByteArray &password, const QByteArray &salt, int rounds, int keyLength)
QByteArray toBase64(Base64Options options) const const
void setPasswordPostSalt(const QString &passwordPostSalt)
AuthenticationUser authenticate(Context *c, AuthenticationRealm *realm, const ParamsMultiMap &authinfo) final
qsizetype size() const const
QString toString() const const
QByteArray toRfc4122() const const
virtual ~CredentialPassword() override
static bool validatePassword(const QByteArray &password, const QByteArray &correctHash)
T value(const Key &key, const T &defaultValue) const const
QByteArray toUtf8() const const