5 #include "authenticationrealm.h" 6 #include "credentialpassword_p.h" 9 #include <QLoggingCategory> 10 #include <QMessageAuthenticationCode> 15 Q_LOGGING_CATEGORY(C_CREDENTIALPASSWORD,
"cutelyst.plugin.credentialpassword", QtWarningMsg)
19 , d_ptr(new CredentialPasswordPrivate)
36 if (d->checkPassword(_user, authinfo)) {
39 qCDebug(C_CREDENTIALPASSWORD) <<
"Password didn't match";
42 qCDebug(C_CREDENTIALPASSWORD)
43 <<
"Unable to locate a user matching user info provided in realm";
51 return d->passwordField;
57 d->passwordField = fieldName;
63 return d->passwordType;
69 d->passwordType = type;
75 return d->passwordPreSalt;
87 return d->passwordPostSalt;
100 for (
int i = 0; i < a.
size() && i < b.
size(); i++) {
106 #define HASH_SECTIONS 4 107 #define HASH_ALGORITHM_INDEX 0 108 #define HASH_ITERATION_INDEX 1 109 #define HASH_SALT_INDEX 2 110 #define HASH_PBKDF2_INDEX 3 114 if (params.
size() < HASH_SECTIONS) {
118 int method = CredentialPasswordPrivate::cryptoStrToEnum(params.
at(HASH_ALGORITHM_INDEX));
124 return slowEquals(pbkdf2Hash,
125 pbkdf2(static_cast<QCryptographicHash::Algorithm>(method),
127 params.
at(HASH_SALT_INDEX),
128 params.
at(HASH_ITERATION_INDEX).toInt(),
140 QFile random(QStringLiteral(
"/dev/urandom"));
150 const QByteArray methodStr = CredentialPasswordPrivate::cryptoEnumToStr(method);
152 pbkdf2(method, password, salt, iterations, hashByteSize).
toBase64();
172 if (rounds <= 0 || keyLength <= 0) {
173 qCCritical(C_CREDENTIALPASSWORD,
"PBKDF2 ERROR: Invalid parameters.");
177 if (salt.
size() == 0 || salt.
size() > std::numeric_limits<int>::max() - 4) {
182 int saltSize = salt.
size();
184 asalt.
resize(saltSize + 4);
190 for (
int count = 1, remainingBytes = keyLength; remainingBytes > 0; ++count) {
191 asalt[saltSize + 0] =
static_cast<char>((count >> 24) & 0xff);
192 asalt[saltSize + 1] =
static_cast<char>((count >> 16) & 0xff);
193 asalt[saltSize + 2] =
static_cast<char>((count >> 8) & 0xff);
194 asalt[saltSize + 3] =
static_cast<char>(count & 0xff);
198 obuf = d1 = code.
result();
200 for (
int i = 1; i < rounds; ++i) {
204 auto it = obuf.
begin();
206 while (d1It != d1.
cend()) {
214 remainingBytes -= obuf.
size();
231 const QString password = passwordPreSalt + authinfo.
value(passwordField) + passwordPostSalt;
237 return storedPassword == password;
239 qCDebug(C_CREDENTIALPASSWORD) <<
"CredentialPassword is set to ignore password check";
250 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 252 hashmethod = QByteArrayLiteral(
"Md4");
254 hashmethod = QByteArrayLiteral(
"Md5");
258 hashmethod = QByteArrayLiteral(
"Sha1");
260 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 262 hashmethod = QByteArrayLiteral(
"Sha224");
264 hashmethod = QByteArrayLiteral(
"Sha256");
266 hashmethod = QByteArrayLiteral(
"Sha384");
268 hashmethod = QByteArrayLiteral(
"Sha512");
270 hashmethod = QByteArrayLiteral(
"Sha3_224");
272 hashmethod = QByteArrayLiteral(
"Sha3_256");
274 hashmethod = QByteArrayLiteral(
"Sha3_384");
276 hashmethod = QByteArrayLiteral(
"Sha3_512");
283 int CredentialPasswordPrivate::cryptoStrToEnum(
const QByteArray &hashMethod)
288 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 289 if (hashmethod ==
"Md4") {
291 }
else if (hashmethod ==
"Md5") {
295 if (hashmethod ==
"Sha1") {
298 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 299 if (hashmethod ==
"Sha224") {
301 }
else if (hashmethod ==
"Sha256") {
303 }
else if (hashmethod ==
"Sha384") {
305 }
else if (hashmethod ==
"Sha512") {
307 }
else if (hashmethod ==
"Sha3_224") {
309 }
else if (hashmethod ==
"Sha3_256") {
311 }
else if (hashmethod ==
"Sha3_384") {
313 }
else if (hashmethod ==
"Sha3_512") {
321 #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
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