From 459d7ed574c91fc15d38c65102919f9de20b4c51 Mon Sep 17 00:00:00 2001 From: lotodore Date: Fri, 14 Aug 2009 21:18:28 +0000 Subject: [PATCH] Adding ASN.1 protocol to chat cleaner server. --- chatcleaner.pro | 3 + src/chatcleaner/cleanerserver.cpp | 117 ++++++++++++++++++- src/chatcleaner/cleanerserver.h | 7 +- src/net/chatcleanermanager.h | 3 - src/net/common/chatcleanermanager.cpp | 14 ++- src/net/common/internalchatcleanerpacket.cpp | 1 + src/net/internalchatcleanerpacket.h | 5 +- 7 files changed, 136 insertions(+), 14 deletions(-) diff --git a/chatcleaner.pro b/chatcleaner.pro index 14a000a5..b3bdb06e 100644 --- a/chatcleaner.pro +++ b/chatcleaner.pro @@ -44,3 +44,6 @@ HEADERS += cleanerserver.h \ capsfloodcheck.h \ letterrepeatingcheck.h \ urlcheck.h +LIBPATH += lib +LIBS += -lpokerth_lib \ + -lpokerth_protocol diff --git a/src/chatcleaner/cleanerserver.cpp b/src/chatcleaner/cleanerserver.cpp index 8f8a26be..962ff9e4 100644 --- a/src/chatcleaner/cleanerserver.cpp +++ b/src/chatcleaner/cleanerserver.cpp @@ -2,11 +2,15 @@ #include #include -#include +#include +#include +#include #include "messagefilter.h" #include "cleanerconfig.h" +using namespace std; + CleanerServer::CleanerServer(): config(0), blockConnection(false) { config = new CleanerConfig; @@ -46,7 +50,41 @@ void CleanerServer::newCon() void CleanerServer::onRead() { - char buf[1024]; + qint64 bytesRead = tcpSocket->read((char *)m_recvBuf + m_recvBufUsed, sizeof(m_recvBuf) - m_recvBufUsed); + bool error = bytesRead < 1; + if (!error) + { + m_recvBufUsed += bytesRead; + + asn_dec_rval_t retVal; + do + { + // Try to decode the packets. + InternalChatCleanerPacket recvMsg; + retVal = ber_decode(0, &asn_DEF_ChatCleanerMessage, (void **)recvMsg.GetMsgPtr(), m_recvBuf, m_recvBufUsed); + if(retVal.code == RC_OK) + { + if (retVal.consumed < m_recvBufUsed) + { + m_recvBufUsed -= retVal.consumed; + memmove(m_recvBuf, m_recvBuf + retVal.consumed, m_recvBufUsed); + } + else + m_recvBufUsed = 0; + + // Handle the packets. + error = handleMessage(recvMsg); + } + } while (!error && retVal.code == RC_OK); + } + + if (error) + { + qDebug() << "Error handling packets from client."; + tcpSocket->close(); + } + +/* char buf[1024]; tcpSocket->readLine(buf, sizeof(buf)); QString message = QString::fromUtf8("%1").arg(buf); @@ -56,7 +94,69 @@ void CleanerServer::onRead() // TESTING DEFAULT VALUES QString checkMessage = myMessageFilter->check(playerId, nick, message); - tcpSocket->write(checkMessage.toAscii().data(), checkMessage.length()); + tcpSocket->write(checkMessage.toAscii().data(), checkMessage.length());*/ +} + +bool CleanerServer::handleMessage(InternalChatCleanerPacket &msg) { + bool error = true; + if (msg.GetMsg()->present == ChatCleanerMessage_PR_cleanerInitMessage) + { + CleanerInitMessage_t *netInit = &msg.GetMsg()->choice.cleanerInitMessage; + if (netInit->requestedVersion == CLEANER_PROTOCOL_VERSION) + { + string tmpClientSecret((const char *)netInit->clientSecret.buf, netInit->clientSecret.size); + if (clientSecret == QString::fromStdString(tmpClientSecret)) + { + error = false; + + InternalChatCleanerPacket tmpAck; + tmpAck.GetMsg()->present = ChatCleanerMessage_PR_cleanerInitAckMessage; + CleanerInitAckMessage_t *netAck = &tmpAck.GetMsg()->choice.cleanerInitAckMessage; + netAck->serverVersion = CLEANER_PROTOCOL_VERSION; + string tmpServerSecret(serverSecret.toStdString()); + OCTET_STRING_fromBuf(&netAck->serverSecret, + tmpServerSecret.c_str(), + tmpServerSecret.length()); + sendMessageToClient(tmpAck); + } + else + qDebug() << "Invalid client secret."; + } + else + qDebug() << "Invalid client version: " << netInit->requestedVersion; + } + else if (msg.GetMsg()->present == ChatCleanerMessage_PR_cleanerChatRequestMessage) + { + error = false; + CleanerChatRequestMessage_t *netRequest = &msg.GetMsg()->choice.cleanerChatRequestMessage; + unsigned playerId = netRequest->playerId; + QString nick(QString::fromUtf8( + string((const char *)netRequest->playerName.buf, netRequest->playerName.size).c_str())); + QString message(QString::fromUtf8( + string((const char *)netRequest->chatMessage.buf, netRequest->chatMessage.size).c_str())); + QString checkMessage = myMessageFilter->check(playerId, nick, message); + + if (!checkMessage.isEmpty()) + { + InternalChatCleanerPacket tmpReply; + tmpReply.GetMsg()->present = ChatCleanerMessage_PR_cleanerChatReplyMessage; + CleanerChatReplyMessage_t *netReply = &tmpReply.GetMsg()->choice.cleanerChatReplyMessage; + netReply->requestId = netRequest->requestId; + netReply->cleanerActionType = cleanerActionType_cleanerActionNone; + /* cleanerActionType_cleanerActionNone + cleanerActionType_cleanerActionWarning + cleanerActionType_cleanerActionKick + cleanerActionType_cleanerActionBan */ + string tmpCheck(checkMessage.toUtf8()); + netReply->cleanerText = + OCTET_STRING_new_fromBuf( + &asn_DEF_OCTET_STRING, + (const char *)tmpCheck.c_str(), + tmpCheck.length()); + sendMessageToClient(tmpReply); + } + } + return error; } void CleanerServer::socketStateChanged(QAbstractSocket::SocketState state) { @@ -70,3 +170,14 @@ void CleanerServer::refreshConfig() { config->fillBuffer(); myMessageFilter->refreshConfig(); } + +void CleanerServer::sendMessageToClient(InternalChatCleanerPacket &msg) +{ + unsigned char buf[MAX_CLEANER_PACKET_SIZE]; + asn_enc_rval_t e = der_encode_to_buffer(&asn_DEF_ChatCleanerMessage, msg.GetMsg(), buf, MAX_CLEANER_PACKET_SIZE); + + if (e.encoded == -1) + qDebug() << "Failed to encode chat cleaner packet: " << msg.GetMsg()->present; + else + tcpSocket->write((const char *)buf, e.encoded); +} diff --git a/src/chatcleaner/cleanerserver.h b/src/chatcleaner/cleanerserver.h index 8e70035b..b5071109 100644 --- a/src/chatcleaner/cleanerserver.h +++ b/src/chatcleaner/cleanerserver.h @@ -3,8 +3,7 @@ #include #include -#include -#include +#include class MessageFilter; class CleanerConfig; @@ -19,8 +18,10 @@ public: private slots: void newCon(); void onRead(); + bool handleMessage(InternalChatCleanerPacket &msg); void socketStateChanged(QAbstractSocket::SocketState); void refreshConfig(); + void sendMessageToClient(InternalChatCleanerPacket &msg); private: QTcpServer *tcpServer; @@ -30,6 +31,8 @@ private: CleanerConfig *config; bool blockConnection; + QString clientSecret; + QString serverSecret; unsigned char m_recvBuf[2*MAX_CLEANER_PACKET_SIZE]; unsigned m_recvBufUsed; diff --git a/src/net/chatcleanermanager.h b/src/net/chatcleanermanager.h index 7fe59ff6..42668c0a 100644 --- a/src/net/chatcleanermanager.h +++ b/src/net/chatcleanermanager.h @@ -25,9 +25,6 @@ #include #include -#define CLEANER_PROTOCOL_VERSION 1 -#define MAX_CLEANER_PACKET_SIZE 384 - class InternalChatCleanerPacket; class EncodedPacket; diff --git a/src/net/common/chatcleanermanager.cpp b/src/net/common/chatcleanermanager.cpp index 1ebc4e8a..dcc39186 100644 --- a/src/net/common/chatcleanermanager.cpp +++ b/src/net/common/chatcleanermanager.cpp @@ -193,6 +193,11 @@ ChatCleanerManager::HandleRead(const boost::system::error_code &ec, size_t bytes boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } + else + { + m_socket->close(); + m_connected = false; + } } else if (ec != boost::asio::error::operation_aborted) { @@ -205,7 +210,7 @@ ChatCleanerManager::HandleRead(const boost::system::error_code &ec, size_t bytes bool ChatCleanerManager::HandleMessage(InternalChatCleanerPacket &msg) { - bool error = false; + bool error = true; if (msg.GetMsg()->present == ChatCleanerMessage_PR_cleanerInitAckMessage) { CleanerInitAckMessage_t *netAck = &msg.GetMsg()->choice.cleanerInitAckMessage; @@ -213,14 +218,13 @@ ChatCleanerManager::HandleMessage(InternalChatCleanerPacket &msg) { string tmpSecret((const char *)netAck->serverSecret.buf, netAck->serverSecret.size); if (m_serverSecret == tmpSecret) + { m_connected = true; + error = false; + } } if (!m_connected) - { LOG_ERROR("Chat cleaner handshake failed."); - m_socket->close(); - error = true; - } } return error; } diff --git a/src/net/common/internalchatcleanerpacket.cpp b/src/net/common/internalchatcleanerpacket.cpp index 0726b13d..85c980c1 100644 --- a/src/net/common/internalchatcleanerpacket.cpp +++ b/src/net/common/internalchatcleanerpacket.cpp @@ -18,6 +18,7 @@ ***************************************************************************/ #include +#include #include using namespace std; diff --git a/src/net/internalchatcleanerpacket.h b/src/net/internalchatcleanerpacket.h index f585f18c..5b7b7e81 100644 --- a/src/net/internalchatcleanerpacket.h +++ b/src/net/internalchatcleanerpacket.h @@ -21,7 +21,10 @@ #ifndef _INTERNALCHATCLEANERPACKET_H_ #define _INTERNALCHATCLEANERPACKET_H_ -#include +#define CLEANER_PROTOCOL_VERSION 1 +#define MAX_CLEANER_PACKET_SIZE 384 + +typedef struct ChatCleanerMessage ChatCleanerMessage_t; class InternalChatCleanerPacket {