18 #include "credentialpassword_p.h"
19 #include "authenticationrealm.h"
21 #include <QLoggingCategory>
22 #include <QMessageAuthenticationCode>
28 Q_LOGGING_CATEGORY(C_CREDENTIALPASSWORD,
"cutelyst.plugin.credentialpassword", QtWarningMsg)
31 , d_ptr(new CredentialPasswordPrivate)
36 CredentialPassword::~CredentialPassword()
47 if (d->checkPassword(_user, authinfo)) {
50 qCDebug(C_CREDENTIALPASSWORD) <<
"Password didn't match";
53 qCDebug(C_CREDENTIALPASSWORD) <<
"Unable to locate a user matching user info provided in realm";
61 return d->passwordField;
67 d->passwordField = fieldName;
73 return d->passwordType;
79 d->passwordType = type;
85 return d->passwordPreSalt;
97 return d->passwordPostSalt;
110 for(
int i = 0; i < a.
size() && i < b.
size(); i++) {
116 #define HASH_SECTIONS 4
117 #define HASH_ALGORITHM_INDEX 0
118 #define HASH_ITERATION_INDEX 1
119 #define HASH_SALT_INDEX 2
120 #define HASH_PBKDF2_INDEX 3
124 if (params.
size() < HASH_SECTIONS) {
128 int method = CredentialPasswordPrivate::cryptoStrToEnum(params.
at(HASH_ALGORITHM_INDEX));
139 params.
at(HASH_SALT_INDEX),
140 params.
at(HASH_ITERATION_INDEX).toInt(),
150 QFile random(QStringLiteral(
"/dev/urandom"));
152 salt = random.
read(saltByteSize).toBase64();
160 const QByteArray methodStr = CredentialPasswordPrivate::cryptoEnumToStr(method);
184 if (rounds <= 0 || keyLength <= 0) {
185 qCCritical(C_CREDENTIALPASSWORD,
"PBKDF2 ERROR: Invalid parameters.");
189 if (salt.
size() == 0 || salt.
size() > std::numeric_limits<int>::max() - 4) {
194 int saltSize = salt.
size();
196 asalt.
resize(saltSize + 4);
202 for (
int count = 1, remainingBytes = keyLength; remainingBytes > 0; ++count) {
203 asalt[saltSize + 0] =
static_cast<char>((count >> 24) & 0xff);
204 asalt[saltSize + 1] =
static_cast<char>((count >> 16) & 0xff);
205 asalt[saltSize + 2] =
static_cast<char>((count >> 8) & 0xff);
206 asalt[saltSize + 3] =
static_cast<char>(count & 0xff);
210 obuf = d1 = code.
result();
212 for (
int i = 1; i < rounds; ++i) {
216 auto it = obuf.
begin();
218 while (d1It != d1.
cend()) {
226 remainingBytes -= obuf.
size();
229 key = key.
mid(0, keyLength);
243 if (Q_LIKELY(passwordType == CredentialPassword::Hashed)) {
244 if (!passwordPreSalt.isEmpty()) {
248 if (!passwordPostSalt.isEmpty()) {
249 password.
append(password);
253 }
else if (passwordType == CredentialPassword::Clear) {
254 return storedPassword == password;
255 }
else if (passwordType == CredentialPassword::None) {
256 qCDebug(C_CREDENTIALPASSWORD) <<
"CredentialPassword is set to ignore password check";
267 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
269 hashmethod = QByteArrayLiteral(
"Md4");
271 hashmethod = QByteArrayLiteral(
"Md5");
275 hashmethod = QByteArrayLiteral(
"Sha1");
277 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
279 hashmethod = QByteArrayLiteral(
"Sha224");
281 hashmethod = QByteArrayLiteral(
"Sha256");
283 hashmethod = QByteArrayLiteral(
"Sha384");
285 hashmethod = QByteArrayLiteral(
"Sha512");
287 hashmethod = QByteArrayLiteral(
"Sha3_224");
289 hashmethod = QByteArrayLiteral(
"Sha3_256");
291 hashmethod = QByteArrayLiteral(
"Sha3_384");
293 hashmethod = QByteArrayLiteral(
"Sha3_512");
300 int CredentialPasswordPrivate::cryptoStrToEnum(
const QByteArray &hashMethod)
305 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
306 if (hashmethod ==
"Md4") {
308 }
else if (hashmethod ==
"Md5") {
312 if (hashmethod ==
"Sha1") {
315 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
316 if (hashmethod ==
"Sha224") {
318 }
else if (hashmethod ==
"Sha256") {
320 }
else if (hashmethod ==
"Sha384") {
322 }
else if (hashmethod ==
"Sha512") {
324 }
else if (hashmethod ==
"Sha3_224") {
326 }
else if (hashmethod ==
"Sha3_256") {
328 }
else if (hashmethod ==
"Sha3_384") {
330 }
else if (hashmethod ==
"Sha3_512") {
338 #include "moc_credentialpassword.cpp"
virtual AuthenticationUser findUser(Context *c, const ParamsMultiMap &userinfo)
Tries to find the user with authinfo returning a non null AuthenticationUser on success.
bool isNull() const
Returns true if the object is null.
void setPasswordType(PasswordType type)
Sets the type of password this class will be dealing with.
QString passwordField() const
Returns the field to look for when authenticating the user.
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.
static QByteArray pbkdf2(QCryptographicHash::Algorithm method, const QByteArray &password, const QByteArray &salt, int rounds, int keyLength)
Generates a pbkdf2 string for the given password.
static bool validatePassword(const QByteArray &password, const QByteArray &correctHash)
Validates the given password against the correct hash.
QString passwordPreSalt() const
Returns the salt string to be prepended to the password.
PasswordType passwordType() const
Returns the type of password this class will be dealing with.
QString passwordPostSalt() const
Returns the salt string to be appended to the password.
static QByteArray createPassword(const QByteArray &password, QCryptographicHash::Algorithm method, int iterations, int saltByteSize, int hashByteSize)
Creates a password hash string.
void setPasswordField(const QString &fieldName)
Sets the field to look for when authenticating the user.
static QByteArray hmac(QCryptographicHash::Algorithm method, const QByteArray &key, const QByteArray &message)
Generates the Hash-based message authentication code.
void setPasswordPreSalt(const QString &passwordPreSalt)
Sets the salt string to be prepended to the password.
The Cutelyst namespace holds all public Cutelyst API.
QByteArray & append(char ch)
QByteArray::iterator begin()
QByteArray::const_iterator cbegin() const const
QByteArray::const_iterator cend() const const
QByteArray fromBase64(const QByteArray &base64, QByteArray::Base64Options options)
QByteArray mid(int pos, int len) const const
QByteArray number(int n, int base)
QList< QByteArray > split(char sep) const const
QByteArray toBase64(QByteArray::Base64Options options) const const
virtual bool open(QIODevice::OpenMode mode) override
qint64 read(char *data, qint64 maxSize)
const T & at(int i) const const
const T value(const Key &key, const T &defaultValue) const const
void addData(const char *data, int length)
QByteArray hash(const QByteArray &message, const QByteArray &key, QCryptographicHash::Algorithm method)
QByteArray result() const const
QString & append(QChar ch)
QString & prepend(QChar ch)
QByteArray toUtf8() const const
QByteArray toRfc4122() const const
QString toString() const const