summaryrefslogtreecommitdiffstats
path: root/signet
diff options
context:
space:
mode:
authorBen Boeckel <MathStuf@gmail.com>2008-11-01 17:01:26 +0000
committerBen Boeckel <MathStuf@gmail.com>2008-11-01 17:01:26 +0000
commite41f087652cf102c04df1a78ac7a2c72724e740c (patch)
tree8913943b66f388bdd132e998bb3174175184898f /signet
parenta286bb188d7654d644e2f26b71e8ddeaf4490a9d (diff)
downloadsigen-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
Diffstat (limited to 'signet')
-rw-r--r--signet/ConnectionHandler.cpp21
-rw-r--r--signet/ConnectionHandler.h8
-rw-r--r--signet/Room.cpp2
-rw-r--r--signet/Server.cpp25
-rw-r--r--signet/Server.h9
-rw-r--r--signet/protocol/ChallengeMediator.cpp4
-rw-r--r--signet/protocol/ChallengeMediator.h2
-rw-r--r--signet/protocol/PacketMaker.cpp85
-rw-r--r--signet/protocol/PacketMaker.h4
9 files changed, 127 insertions, 33 deletions
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);