X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fstorage.cpp;h=98ae96806807734f4b2481fcbd21ff79db0fa84e;hp=3c16dd3fc9637900c181053ed0e8005ea6776796;hb=c1cf157116de7fc3da96203aa6f03c38c7ebb650;hpb=077d44f36d2f5c730283ef6be839aea7dd073d56 diff --git a/src/core/storage.cpp b/src/core/storage.cpp index 3c16dd3f..98ae9680 100644 --- a/src/core/storage.cpp +++ b/src/core/storage.cpp @@ -1,11 +1,11 @@ /*************************************************************************** - * Copyright (C) 2005-07 by The Quassel Team * + * Copyright (C) 2005-2018 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * + * (at your option) version 3. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * @@ -15,103 +15,90 @@ * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "storage.h" +#include -// OBSOLETE -// This is kept here for importing the old file-based backlog. +#include -/* This is a sample! - -void Storage::importOldBacklog() { - qDebug() << "Deleting backlog database..."; - logDb.exec(QString("DELETE FROM 'Backlog$%1$' WHERE SenderId != '$VERSION$'").arg(user)); - logDb.exec(QString("DELETE FROM 'Senders$%1$'").arg(user)); - logDb.exec(QString("DELETE FROM 'Buffers$%1$'").arg(user)); - nextMsgId = 1; nextBufferId = 1; nextSenderId = 1; - qDebug() << "Importing old backlog files..."; - initBackLogOld(); - if(!backLogEnabledOld) return; - logDb.exec("VACUUM"); - qDebug() << "Backlog successfully imported, you have to restart Quassel now!"; - exit(0); +Storage::Storage(QObject* parent) + : QObject(parent) +{} +QString Storage::hashPassword(const QString& password) +{ + return hashPasswordSha2_512(password); } -*/ - -// file name scheme: quassel-backlog-2006-29-10.bin -void Storage::initBackLogOld(UserId uid) { - backLogDir = QDir(Global::quasselDir + "/backlog"); - if(!backLogDir.exists()) { - qWarning(QString("Creating backlog directory \"%1\"...").arg(backLogDir.absolutePath()).toAscii()); - if(!backLogDir.mkpath(backLogDir.absolutePath())) { - qWarning(QString("Could not create backlog directory! Disabling logging...").toAscii()); - backLogEnabledOld = false; - return; + +bool Storage::checkHashedPassword(const UserId user, const QString& password, const QString& hashedPassword, const Storage::HashVersion version) +{ + bool passwordCorrect = false; + + switch (version) { + case Storage::HashVersion::Sha1: + passwordCorrect = checkHashedPasswordSha1(password, hashedPassword); + break; + + case Storage::HashVersion::Sha2_512: + passwordCorrect = checkHashedPasswordSha2_512(password, hashedPassword); + break; + + default: + qWarning() << "Password hash version" << QString(version) << "is not supported, please reset password"; } - } - backLogDir.refresh(); - //if(!backLogDir.isReadable()) { - // qWarning(QString("Cannot read directory \"%1\". Disabling logging...").arg(backLogDir.absolutePath()).toAscii()); - // backLogEnabled = false; - // return; - //} - QStringList networks = backLogDir.entryList(QDir::Dirs|QDir::NoDotAndDotDot|QDir::Readable, QDir::Name); - foreach(QString net, networks) { - QDir dir(backLogDir.absolutePath() + "/" + net); - if(!dir.exists()) { - qWarning(QString("Could not change to directory \"%1\"!").arg(dir.absolutePath()).toAscii()); - continue; + + if (passwordCorrect && version < Storage::HashVersion::Latest) { + updateUser(user, password); } - QStringList logs = dir.entryList(QStringList("quassel-backlog-*.bin"), QDir::Files|QDir::Readable, QDir::Name); - foreach(QString name, logs) { - QFile f(dir.absolutePath() + "/" + name); - if(!f.open(QIODevice::ReadOnly)) { - qWarning(QString("Could not open \"%1\" for reading!").arg(f.fileName()).toAscii()); - continue; - } - QDataStream in(&f); - in.setVersion(QDataStream::Qt_4_2); - QByteArray verstring; quint8 vernum; in >> verstring >> vernum; - if(verstring != BACKLOG_STRING) { - qWarning(QString("\"%1\" is not a Quassel backlog file!").arg(f.fileName()).toAscii()); - f.close(); continue; - } - if(vernum != BACKLOG_FORMAT) { - qWarning(QString("\"%1\": Version mismatch!").arg(f.fileName()).toAscii()); - f.close(); continue; - } - qDebug() << "Reading backlog from" << f.fileName(); - logFileDates[net] = QDate::fromString(f.fileName(), - QString("'%1/quassel-backlog-'yyyy-MM-dd'.bin'").arg(dir.absolutePath())); - if(!logFileDates[net].isValid()) { - qWarning(QString("\"%1\" has an invalid file name!").arg(f.fileName()).toAscii()); - } - while(!in.atEnd()) { - quint8 t, f; - quint32 ts; - QByteArray s, m, targ; - in >> ts >> t >> f >> targ >> s >> m; - QString target = QString::fromUtf8(targ); - QString sender = QString::fromUtf8(s); - QString text = QString::fromUtf8(m); - BufferId id; - if((f & Message::PrivMsg) && !(f & Message::Self)) { - id = getBufferId(uid, net, sender); - } else { - id = getBufferId(uid, net, target); - } - Message msg(QDateTime::fromTime_t(ts), id, (Message::Type)t, text, sender, f); - //backLog[net].append(m); - logMessage(msg); - } - f.close(); + + return passwordCorrect; +} + +QString Storage::hashPasswordSha1(const QString& password) +{ + return QString(QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Sha1).toHex()); +} + +bool Storage::checkHashedPasswordSha1(const QString& password, const QString& hashedPassword) +{ + return hashPasswordSha1(password) == hashedPassword; +} + +QString Storage::hashPasswordSha2_512(const QString& password) +{ + // Generate a salt of 512 bits (64 bytes) using the Mersenne Twister + std::random_device seed; + std::mt19937 generator(seed()); + std::uniform_int_distribution distribution(0, 255); + QByteArray saltBytes; + saltBytes.resize(64); + for (int i = 0; i < 64; i++) { + saltBytes[i] = (unsigned char)distribution(generator); } - } - backLogEnabledOld = true; + QString salt(saltBytes.toHex()); + + // Append the salt to the password, hash the result, and append the salt value + return sha2_512(password + salt) + ":" + salt; } +bool Storage::checkHashedPasswordSha2_512(const QString& password, const QString& hashedPassword) +{ + QRegExp colonSplitter("\\:"); + QStringList hashedPasswordAndSalt = hashedPassword.split(colonSplitter); + if (hashedPasswordAndSalt.size() == 2) { + return sha2_512(password + hashedPasswordAndSalt[1]) == hashedPasswordAndSalt[0]; + } + else { + qWarning() << "Password hash and salt were not in the correct format"; + return false; + } +} + +QString Storage::sha2_512(const QString& input) +{ + return QString(QCryptographicHash::hash(input.toUtf8(), QCryptographicHash::Sha512).toHex()); +}