Commit 53330090 authored by cockatrice's avatar cockatrice
Browse files

added sha512 password hashing, protocol version 13, server version bump

parent 8344920f
...@@ -59,7 +59,7 @@ private: ...@@ -59,7 +59,7 @@ private:
static void initializeHashAuto(); static void initializeHashAuto();
bool receiverMayDelete; bool receiverMayDelete;
public: public:
static const int protocolVersion = 12; static const int protocolVersion = 13;
static void initializeHash(); static void initializeHash();
virtual int getItemId() const = 0; virtual int getItemId() const = 0;
bool getReceiverMayDelete() const { return receiverMayDelete; } bool getReceiverMayDelete() const { return receiverMayDelete; }
......
...@@ -8,6 +8,7 @@ DEPENDPATH += . src ../common ...@@ -8,6 +8,7 @@ DEPENDPATH += . src ../common
INCLUDEPATH += . src ../common INCLUDEPATH += . src ../common
MOC_DIR = build MOC_DIR = build
OBJECTS_DIR = build OBJECTS_DIR = build
LIBS += -lgcrypt
CONFIG += qt debug CONFIG += qt debug
QT += network sql QT += network sql
...@@ -18,6 +19,7 @@ HEADERS += src/main.h \ ...@@ -18,6 +19,7 @@ HEADERS += src/main.h \
src/serversocketinterface.h \ src/serversocketinterface.h \
src/server_logger.h \ src/server_logger.h \
src/serversocketthread.h \ src/serversocketthread.h \
src/passwordhasher.h \
../common/color.h \ ../common/color.h \
../common/serializable_item.h \ ../common/serializable_item.h \
../common/decklist.h \ ../common/decklist.h \
...@@ -42,6 +44,7 @@ SOURCES += src/main.cpp \ ...@@ -42,6 +44,7 @@ SOURCES += src/main.cpp \
src/serversocketinterface.cpp \ src/serversocketinterface.cpp \
src/server_logger.cpp \ src/server_logger.cpp \
src/serversocketthread.cpp \ src/serversocketthread.cpp \
src/passwordhasher.cpp \
../common/serializable_item.cpp \ ../common/serializable_item.cpp \
../common/decklist.cpp \ ../common/decklist.cpp \
../common/protocol.cpp \ ../common/protocol.cpp \
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include <iostream> #include <iostream>
#include <QMetaType> #include <QMetaType>
#include <QSettings> #include <QSettings>
#include <QDateTime>
#include "passwordhasher.h"
#include "servatrice.h" #include "servatrice.h"
#include "server_logger.h" #include "server_logger.h"
#include "rng_sfmt.h" #include "rng_sfmt.h"
...@@ -68,6 +70,17 @@ void testRNG() ...@@ -68,6 +70,17 @@ void testRNG()
std::cerr << std::endl << std::endl; std::cerr << std::endl << std::endl;
} }
void testHash()
{
const int n = 5000;
std::cerr << "Benchmarking password hash function (n =" << n << ")..." << std::endl;
QDateTime startTime = QDateTime::currentDateTime();
for (int i = 0; i < n; ++i)
PasswordHasher::computeHash("aaaaaa", "aaaaaaaaaaaaaaaa");
QDateTime endTime = QDateTime::currentDateTime();
std::cerr << startTime.secsTo(endTime) << "secs" << std::endl;
}
void myMessageOutput(QtMsgType /*type*/, const char *msg) void myMessageOutput(QtMsgType /*type*/, const char *msg)
{ {
logger->logMessage(msg); logger->logMessage(msg);
...@@ -93,6 +106,7 @@ int main(int argc, char *argv[]) ...@@ -93,6 +106,7 @@ int main(int argc, char *argv[])
QStringList args = app.arguments(); QStringList args = app.arguments();
bool testRandom = args.contains("--test-random"); bool testRandom = args.contains("--test-random");
bool testHashFunction = args.contains("--test-hash");
qRegisterMetaType<QList<int> >("QList<int>"); qRegisterMetaType<QList<int> >("QList<int>");
...@@ -128,6 +142,8 @@ int main(int argc, char *argv[]) ...@@ -128,6 +142,8 @@ int main(int argc, char *argv[])
if (testRandom) if (testRandom)
testRNG(); testRNG();
if (testHashFunction)
testHash();
Servatrice *server = new Servatrice(settings); Servatrice *server = new Servatrice(settings);
QObject::connect(server, SIGNAL(destroyed()), &app, SLOT(quit()), Qt::QueuedConnection); QObject::connect(server, SIGNAL(destroyed()), &app, SLOT(quit()), Qt::QueuedConnection);
......
#include "passwordhasher.h"
#include <stdio.h>
#include <string.h>
#include <gcrypt.h>
QString PasswordHasher::computeHash(const QString &password, const QString &salt)
{
const int algo = GCRY_MD_SHA512;
const int rounds = 1000;
QByteArray passwordBuffer = (salt + password).toAscii();
int hashLen = gcry_md_get_algo_dlen(algo);
char hash[hashLen], tmp[hashLen];
gcry_md_hash_buffer(algo, hash, passwordBuffer.data(), passwordBuffer.size());
for (int i = 1; i < rounds; ++i) {
memcpy(tmp, hash, hashLen);
gcry_md_hash_buffer(algo, hash, tmp, hashLen);
}
return salt + QString(QByteArray(hash, hashLen).toBase64());
}
#ifndef PASSWORDHASHER_H
#define PASSWORDHASHER_H
#include <QObject>
class PasswordHasher {
public:
static QString computeHash(const QString &password, const QString &salt);
};
#endif
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "protocol.h" #include "protocol.h"
#include "server_logger.h" #include "server_logger.h"
#include "main.h" #include "main.h"
#include "passwordhasher.h"
void Servatrice_TcpServer::incomingConnection(int socketDescriptor) void Servatrice_TcpServer::incomingConnection(int socketDescriptor)
{ {
...@@ -185,7 +186,7 @@ AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handl ...@@ -185,7 +186,7 @@ AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handl
checkSql(); checkSql();
QSqlQuery query; QSqlQuery query;
query.prepare("select a.password, time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))) < 0, b.minutes <=> 0 from " + dbPrefix + "_users a left join " + dbPrefix + "_bans b on b.id_user = a.id and b.time_from = (select max(c.time_from) from " + dbPrefix + "_bans c where c.id_user = a.id) where a.name = :name and a.active = 1"); query.prepare("select a.password_sha512, time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))) < 0, b.minutes <=> 0 from " + dbPrefix + "_users a left join " + dbPrefix + "_bans b on b.id_user = a.id and b.time_from = (select max(c.time_from) from " + dbPrefix + "_bans c where c.id_user = a.id) where a.name = :name and a.active = 1");
query.bindValue(":name", user); query.bindValue(":name", user);
if (!execSqlQuery(query)) { if (!execSqlQuery(query)) {
qDebug("Login denied: SQL error"); qDebug("Login denied: SQL error");
...@@ -197,7 +198,7 @@ AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handl ...@@ -197,7 +198,7 @@ AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handl
qDebug("Login denied: banned"); qDebug("Login denied: banned");
return PasswordWrong; return PasswordWrong;
} }
if (query.value(0).toString() == password) { if (query.value(0).toString() == PasswordHasher::computeHash(password, query.value(0).toString().left(16))) {
qDebug("Login accepted: password right"); qDebug("Login accepted: password right");
return PasswordRight; return PasswordRight;
} else { } else {
...@@ -423,4 +424,4 @@ void Servatrice::shutdownTimeout() ...@@ -423,4 +424,4 @@ void Servatrice::shutdownTimeout()
deleteLater(); deleteLater();
} }
const QString Servatrice::versionString = "Servatrice 0.20110803"; const QString Servatrice::versionString = "Servatrice 0.20110921";
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment