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)
23 CredentialPassword::~CredentialPassword()
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();
234 if (Q_LIKELY(passwordType == CredentialPassword::Hashed)) {
235 if (!passwordPreSalt.isEmpty()) {
239 if (!passwordPostSalt.isEmpty()) {
240 password.
append(password);
244 }
else if (passwordType == CredentialPassword::Clear) {
245 return storedPassword == password;
246 }
else if (passwordType == CredentialPassword::None) {
247 qCDebug(C_CREDENTIALPASSWORD) <<
"CredentialPassword is set to ignore password check";
258 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 260 hashmethod = QByteArrayLiteral(
"Md4");
262 hashmethod = QByteArrayLiteral(
"Md5");
266 hashmethod = QByteArrayLiteral(
"Sha1");
268 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 270 hashmethod = QByteArrayLiteral(
"Sha224");
272 hashmethod = QByteArrayLiteral(
"Sha256");
274 hashmethod = QByteArrayLiteral(
"Sha384");
276 hashmethod = QByteArrayLiteral(
"Sha512");
278 hashmethod = QByteArrayLiteral(
"Sha3_224");
280 hashmethod = QByteArrayLiteral(
"Sha3_256");
282 hashmethod = QByteArrayLiteral(
"Sha3_384");
284 hashmethod = QByteArrayLiteral(
"Sha3_512");
291 int CredentialPasswordPrivate::cryptoStrToEnum(
const QByteArray &hashMethod)
296 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 297 if (hashmethod ==
"Md4") {
299 }
else if (hashmethod ==
"Md5") {
303 if (hashmethod ==
"Sha1") {
306 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 307 if (hashmethod ==
"Sha224") {
309 }
else if (hashmethod ==
"Sha256") {
311 }
else if (hashmethod ==
"Sha384") {
313 }
else if (hashmethod ==
"Sha512") {
315 }
else if (hashmethod ==
"Sha3_224") {
317 }
else if (hashmethod ==
"Sha3_256") {
319 }
else if (hashmethod ==
"Sha3_384") {
321 }
else if (hashmethod ==
"Sha3_512") {
329 #include "moc_credentialpassword.cpp" const_iterator cbegin() const const
QString passwordPostSalt() const
Returns the salt string to be appended to the password.
QString & append(QChar ch)
QList< QByteArray > split(char sep) const const
virtual AuthenticationUser findUser(Context *c, const ParamsMultiMap &userinfo)
Tries to find the user with authinfo returning a non null AuthenticationUser on success.
const_iterator cend() const const
void reserve(qsizetype size)
void setPasswordPreSalt(const QString &passwordPreSalt)
Sets the salt string to be prepended to the password.
QString & prepend(QChar ch)
bool isNull() const
Returns true if the object is null.
const_reference at(qsizetype i) const const
static QByteArray hmac(QCryptographicHash::Algorithm method, const QByteArray &key, const QByteArray &message)
Generates the Hash-based message authentication code.
qsizetype length() const const
qsizetype size() const const
QByteArray read(qint64 maxSize)
void setPasswordType(PasswordType type)
Sets the type of password this class will be dealing with.
static QByteArray createPassword(const QByteArray &password, QCryptographicHash::Algorithm method, int iterations, int saltByteSize, int hashByteSize)
Creates a password hash string.
QByteArray result() const const
QByteArray number(double n, char format, int precision)
QString passwordField() const
Returns the field to look for when authenticating the user.
QString passwordPreSalt() const
Returns the salt string to be prepended to the password.
void truncate(qsizetype pos)
The Cutelyst namespace holds all public Cutelyst API.
QByteArray & append(QByteArrayView data)
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)
void setPasswordField(const QString &fieldName)
Sets the field to look for when authenticating the user.
bool open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags)
PasswordType passwordType() const
Returns the type of password this class will be dealing with.
static QByteArray pbkdf2(QCryptographicHash::Algorithm method, const QByteArray &password, const QByteArray &salt, int rounds, int keyLength)
Generates a pbkdf2 string for the given password.
QByteArray toBase64(Base64Options options) const const
void setPasswordPostSalt(const QString &passwordPostSalt)
Sets the salt string to be appended to the password.
AuthenticationUser authenticate(Context *c, AuthenticationRealm *realm, const ParamsMultiMap &authinfo) final
Tries to authenticate the authinfo using the give realm.
qsizetype size() const const
QString toString() const const
QByteArray toRfc4122() const const
static bool validatePassword(const QByteArray &password, const QByteArray &correctHash)
Validates the given password against the correct hash.
T value(const Key &key, const T &defaultValue) const const
QByteArray toUtf8() const const