diff options
author | Ben Boeckel <MathStuf@gmail.com> | 2008-11-01 17:01:26 +0000 |
---|---|---|
committer | Ben Boeckel <MathStuf@gmail.com> | 2008-11-01 17:01:26 +0000 |
commit | e41f087652cf102c04df1a78ac7a2c72724e740c (patch) | |
tree | 8913943b66f388bdd132e998bb3174175184898f | |
parent | a286bb188d7654d644e2f26b71e8ddeaf4490a9d (diff) | |
download | sigen-e41f087652cf102c04df1a78ac7a2c72724e740c.tar.gz sigen-e41f087652cf102c04df1a78ac7a2c72724e740c.tar.xz sigen-e41f087652cf102c04df1a78ac7a2c72724e740c.zip |
[FIX] Challenge login can fail due to unknown user
[FIX] PacketMaker makes Packets (Packets only hold information)
git-svn-id: https://pokegen.svn.sourceforge.net/svnroot/pokegen/trunk@292 6ecfd1a5-f3ed-3746-8530-beee90d26b22
-rw-r--r-- | Changelog | 8 | ||||
-rw-r--r-- | signet/ConnectionHandler.cpp | 21 | ||||
-rw-r--r-- | signet/ConnectionHandler.h | 8 | ||||
-rw-r--r-- | signet/Room.cpp | 2 | ||||
-rw-r--r-- | signet/Server.cpp | 25 | ||||
-rw-r--r-- | signet/Server.h | 9 | ||||
-rw-r--r-- | signet/protocol/ChallengeMediator.cpp | 4 | ||||
-rw-r--r-- | signet/protocol/ChallengeMediator.h | 2 | ||||
-rw-r--r-- | signet/protocol/PacketMaker.cpp | 85 | ||||
-rw-r--r-- | signet/protocol/PacketMaker.h | 4 |
10 files changed, 135 insertions, 33 deletions
@@ -1,4 +1,12 @@ ----------------- +Rev: 292 +Date: 1 November 2008 +User: MathStuf +----------------- +[FIX] Challenge login can fail due to unknown user +[FIX] PacketMaker makes Packets (Packets only hold information) + +----------------- Rev: 291 Date: 31 October 2008 User: MathStuf diff --git a/signet/ConnectionHandler.cpp b/signet/ConnectionHandler.cpp index 98c2420b..7cab06b6 100644 --- a/signet/ConnectionHandler.cpp +++ b/signet/ConnectionHandler.cpp @@ -55,7 +55,7 @@ QByteArray Signet::ConnectionHandler::generateResponse(const QByteArray& key1, c return QByteArray(); } -Signet::ConnectionHandler::ChallengeError Signet::ConnectionHandler::challenge(QTcpSocket* socket, const QByteArray& secret) +Signet::ConnectionHandler::ChallengeError Signet::ConnectionHandler::challenge(QTcpSocket* socket, const QByteArray& secret, const QByteArray& id) { QByteArray clientKey; QByteArray serverKey; @@ -63,9 +63,11 @@ Signet::ConnectionHandler::ChallengeError Signet::ConnectionHandler::challenge(Q QByteArray serverResponse; QByteArray expectedServerResponse; Protocol::ChallengeMediator mediator(socket, Protocol::ChallengeMediator::Client); - mediator.init(); + mediator.init(id); if (!mediator.getServerKey(&serverKey)) return SocketError; + if (mediator.state() == Protocol::ChallengeMediator::Accepted) + return UnknownUser; clientKey = generateChallengeKey(); clientResponse = generateResponse(clientKey, serverKey, secret); expectedServerResponse = generateResponse(serverKey, clientKey, secret); @@ -83,15 +85,20 @@ Signet::ConnectionHandler::ChallengeError Signet::ConnectionHandler::challenge(Q return NoError; } -Signet::ConnectionHandler::ChallengeError Signet::ConnectionHandler::challenged(QTcpSocket* socket) +Signet::ConnectionHandler::ChallengeError Signet::ConnectionHandler::challenged(QTcpSocket* socket, const QByteArray& id) { QByteArray clientKey; QByteArray serverKey; QByteArray clientResponse; QByteArray serverResponse; QByteArray expectedClientResponse; - QByteArray secret = secretForHost(socket->peerAddress()); + QByteArray secret = secretForHost(id); Protocol::ChallengeMediator mediator(socket, Protocol::ChallengeMediator::Server); + if (!secret.size()) + { + mediator.notifyClientFail(); + return ClientFailed; + } serverKey = generateChallengeKey(); mediator.serverKey(serverKey); if (!mediator.getClientResponse(&clientKey, &clientResponse)) @@ -100,7 +107,7 @@ Signet::ConnectionHandler::ChallengeError Signet::ConnectionHandler::challenged( if (clientResponse != expectedClientResponse) { mediator.notifyClientFail(); - return ClientFailed; + return UnknownUser; } serverResponse = generateResponse(serverKey, clientKey, secret); mediator.serverResponse(serverResponse); @@ -111,9 +118,9 @@ Signet::ConnectionHandler::ChallengeError Signet::ConnectionHandler::challenged( return NoError; } -QByteArray Signet::ConnectionHandler::secretForHost(const QHostAddress& address) const +QByteArray Signet::ConnectionHandler::secretForHost(const QByteArray& id) const { - Q_UNUSED(address) + Q_UNUSED(id) return QByteArray(); } diff --git a/signet/ConnectionHandler.h b/signet/ConnectionHandler.h index 9108a9a9..c4556973 100644 --- a/signet/ConnectionHandler.h +++ b/signet/ConnectionHandler.h @@ -41,6 +41,7 @@ class SIGNET_EXPORT ConnectionHandler : public QObject enum ChallengeError { NoError, + UnknownUser, ClientFailed, ServerFailed, SocketError @@ -50,10 +51,8 @@ class SIGNET_EXPORT ConnectionHandler : public QObject static QByteArray generateChallengeKey(); static QByteArray generateResponse(const QByteArray& key1, const QByteArray& key2, const QByteArray& secret); - static ChallengeError challenge(QTcpSocket* socket, const QByteArray& secret); - ChallengeError challenged(QTcpSocket* socket); - - virtual QByteArray secretForHost(const QHostAddress& address) const; + static ChallengeError challenge(QTcpSocket* socket, const QByteArray& secret, const QByteArray& id); + ChallengeError challenged(QTcpSocket* socket, const QByteArray& id); virtual QString type() const = 0; virtual QString name() const = 0; @@ -63,6 +62,7 @@ class SIGNET_EXPORT ConnectionHandler : public QObject signals: void dataReceived(const QByteArray& data); protected: + virtual QByteArray secretForHost(const QByteArray& id) const; protected slots: void sendData(Client* client, const QByteArray& data); private: diff --git a/signet/Room.cpp b/signet/Room.cpp index 461ad437..fad6c332 100644 --- a/signet/Room.cpp +++ b/signet/Room.cpp @@ -60,5 +60,7 @@ bool Signet::Room::joinTable(Client* client, const QString& tableName) if (!m_tables[tableName]->addClient(client)) { // TODO: Let the client know about the error. + return false; } + return true; } diff --git a/signet/Server.cpp b/signet/Server.cpp index 422f2d45..ad6ea20a 100644 --- a/signet/Server.cpp +++ b/signet/Server.cpp @@ -54,33 +54,33 @@ void Signet::Server::closeRoom(const QString& room) } } -void Signet::Server::hostFound() +void Signet::Server::masterFound() { qDebug("Master server found"); } -void Signet::Server::hostConnected() +void Signet::Server::masterConnected() { qDebug("Master server connected"); - ChallengeError error = challenge(m_master, m_key); + ChallengeError error = challenge(m_master, m_key, m_name.toUtf8()); if (error == NoError) qDebug("Master server connected"); else if (error != SocketError) { - qCritical("Challenge negotiation failed: %s", (error == ClientFailed) ? "Client" : "Server"); + qWarning("Challenge negotiation failed: %s", (error == ClientFailed) ? "Client" : ((error == ServerFailed) ? "Server" : "User")); m_master->disconnectFromHost(); } } -void Signet::Server::hostDisconnected() +void Signet::Server::masterDisconnected() { QTimer::singleShot(60000, this, SLOT(connectToMaster())); - qCritical("Master server disconnected; will retry in 60 seconds"); + qWarning("Master server disconnected; will retry in 60 seconds"); } -void Signet::Server::hostError() +void Signet::Server::masterError() { - qCritical("Master server socket error: %s", m_master->errorString().toUtf8().constData()); + qWarning("Master server socket error: %s", m_master->errorString().toUtf8().constData()); } void Signet::Server::joinRoom(Client* client, const QString& roomName) @@ -105,6 +105,7 @@ void Signet::Server::loadConfiguration() if (m_masterPort < 0) qFatal("Invalid port for the master server: %d", m_masterPort); m_key = group.readEntry("Key", QByteArray()); + m_name = group.readEntry("Name", ""); } else qFatal("Configuration does not contain a \"Master Server\" group"); @@ -115,10 +116,10 @@ void Signet::Server::connectToMaster() if (!m_master) { m_master = new QTcpSocket(this); - connect(m_master, SIGNAL(hostFound()), this, SLOT(hostFound())); - connect(m_master, SIGNAL(connected()), this, SLOT(hostConnected())); - connect(m_master, SIGNAL(disconnected()), this, SLOT(hostDisconnected())); - connect(m_master, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(hostError())); + connect(m_master, SIGNAL(hostFound()), this, SLOT(masterFound())); + connect(m_master, SIGNAL(connected()), this, SLOT(masterConnected())); + connect(m_master, SIGNAL(disconnected()), this, SLOT(masterDisconnected())); + connect(m_master, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(masterError())); } // TODO: Proxy support? m_master->connectToHost(m_masterHost, m_masterPort); diff --git a/signet/Server.h b/signet/Server.h index ee90455a..fdcf368e 100644 --- a/signet/Server.h +++ b/signet/Server.h @@ -51,10 +51,10 @@ class SIGNET_EXPORT Server : public ConnectionHandler bool verifyUser(Client* client); protected slots: - void hostFound(); - void hostConnected(); - void hostDisconnected(); - void hostError(); + void masterFound(); + void masterConnected(); + void masterDisconnected(); + void masterError(); void joinRoom(Client* client, const QString& roomName); @@ -67,6 +67,7 @@ class SIGNET_EXPORT Server : public ConnectionHandler QHostAddress m_masterHost; int m_masterPort; QByteArray m_key; + QString m_name; QMap<QString, Room*> m_rooms; }; diff --git a/signet/protocol/ChallengeMediator.cpp b/signet/protocol/ChallengeMediator.cpp index 0cbe95ff..f267d998 100644 --- a/signet/protocol/ChallengeMediator.cpp +++ b/signet/protocol/ChallengeMediator.cpp @@ -32,10 +32,10 @@ Signet::Protocol::ChallengeMediator::ChallengeMediator(QTcpSocket* socket, Side { } -void Signet::Protocol::ChallengeMediator::init() +void Signet::Protocol::ChallengeMediator::init(const QByteArray& id) { Q_ASSERT(m_side == Client); - PacketMaker::challengePacket(m_socket); + PacketMaker::challenge(m_socket, id); } void Signet::Protocol::ChallengeMediator::serverKey(const QByteArray& serverKey) diff --git a/signet/protocol/ChallengeMediator.h b/signet/protocol/ChallengeMediator.h index bc02245d..7287cd96 100644 --- a/signet/protocol/ChallengeMediator.h +++ b/signet/protocol/ChallengeMediator.h @@ -45,7 +45,7 @@ class SIGNET_EXPORT ChallengeMediator ChallengeMediator(QTcpSocket* socket, Side side); - void init(); + void init(const QByteArray& id); void serverKey(const QByteArray& serverKey); bool getServerKey(QByteArray* serverKey); diff --git a/signet/protocol/PacketMaker.cpp b/signet/protocol/PacketMaker.cpp index 3eb3e0b2..f608fa18 100644 --- a/signet/protocol/PacketMaker.cpp +++ b/signet/protocol/PacketMaker.cpp @@ -18,19 +18,102 @@ // Header include #include "PacketMaker.h" +// Qt includes +#include <QtCore/QtEndian> +#include <QtCore/QBuffer> +#include <QtCore/QIODevice> + +bool readIntoBuffer(QIODevice* dest, QIODevice* src, const int size) +{ + char* tbuffer = new char[size]; + int totalRead = 0; + while ((totalRead < size) && src->waitForReadyRead(30000)) + { + int read = src->read(tbuffer + totalRead, 10 - totalRead); + int written = 0; + if (read < 0) + { + delete [] tbuffer; + return false; + } + while (written < read) + { + int writtenThisTime = dest->write(tbuffer + written, read - written); + if (writtenThisTime < 0) + { + delete [] tbuffer; + return false; + } + written += writtenThisTime; + } + totalRead += read; + } + delete [] tbuffer; + return true; +} + void Signet::Protocol::PacketMaker::deny(QIODevice* device) { + Packet packet(Packet::Denial); + packet.dump(device); } void Signet::Protocol::PacketMaker::accept(QIODevice* device) { + Packet packet(Packet::Acceptance); + packet.dump(device); } -void Signet::Protocol::PacketMaker::challengePacket(QIODevice* device) +void Signet::Protocol::PacketMaker::challenge(QIODevice* device, const QByteArray& id) { + Packet packet(Packet::Challenge); + packet.write(id); + packet.dump(device); } Signet::Protocol::Packet Signet::Protocol::PacketMaker::unwrap(QIODevice* device) { + QByteArray temp; + QBuffer buffer(&temp); + union + { + char expectedType_raw[2]; + qint16 expectedType; + }; + union + { + char expectedSize_raw[8]; + qint64 expectedSize; + }; + if (!readIntoBuffer(&buffer, device, 10)) + return Packet(); + buffer.write(expectedType_raw, 2); + expectedType = qFromBigEndian(expectedType); + buffer.write(expectedSize_raw, 8); + expectedSize = qFromBigEndian(expectedSize); Packet packet; + switch (expectedType) + { + case Packet::RawData: + packet = Packet(Packet::RawData); + if (readIntoBuffer(&buffer, device, expectedSize)) + packet.write(buffer.buffer()); + break; + case Packet::Acceptance: + if (!expectedSize) + packet = Packet(Packet::Acceptance); + break; + case Packet::Denial: + if (!expectedSize) + packet = Packet(Packet::Denial); + break; + case Packet::Challenge: + packet = Packet(Packet::Challenge); + if (readIntoBuffer(&buffer, device, expectedSize)) + packet.write(buffer.buffer()); + break; + default: + break; + } + return packet; } diff --git a/signet/protocol/PacketMaker.h b/signet/protocol/PacketMaker.h index 877eef9b..880d0827 100644 --- a/signet/protocol/PacketMaker.h +++ b/signet/protocol/PacketMaker.h @@ -25,7 +25,7 @@ #include "../Global.h" // Forward declarations -#include <QtCore/QIODevice> +class QIODevice; namespace Signet { @@ -37,7 +37,7 @@ class SIGNET_EXPORT PacketMaker static void deny(QIODevice* device); static void accept(QIODevice* device); - static void challengePacket(QIODevice* device); + static void challenge(QIODevice* device, const QByteArray& id); template<typename T> static void wrap(QIODevice* device, const T& data); |