Browse Source

Screen incoming GameMessages because we cannot trust the server (because the server trusts other clients too much)

Adam Johnson 13 years ago
parent
commit
656b86a685
  1. 2
      Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.h
  2. 4
      Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgrSend.cpp
  3. 6
      Sources/Plasma/PubUtilLib/plNetClient/plNetClientMsgHandler.cpp
  4. 54
      Sources/Plasma/PubUtilLib/plNetClient/plNetClientMsgScreener.cpp
  5. 4
      Sources/Plasma/PubUtilLib/plNetClient/plNetClientMsgScreener.h

2
Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.h

@ -34,6 +34,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plNetVoiceList.h"
#include "plNetClientMsgHandler.h"
#include "plNetClientStats.h" // STATS Counters
#include "plNetClientMsgScreener.h"
#include "pnNetCommon/plNetApp.h"
@ -162,6 +163,7 @@ private:
plNetTalkList fTalkList; // other players I'm talking to
plNetClientMsgHandler fMsgHandler;
plNetClientMsgScreener fScreener;
// recorder support
plNetClientRecorder* fMsgRecorder;

4
Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgrSend.cpp

@ -28,7 +28,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plNetClientMgr.h"
#include "plCreatableIndex.h"
#include "plNetObjectDebugger.h"
#include "plNetClientMsgScreener.h"
#include "pnNetCommon/plSynchedObject.h"
#include "pnNetCommon/plSDLTypes.h"
@ -220,8 +219,7 @@ int plNetClientMgr::ISendGameMessage(plMessage* msg)
if (GetFlagsBit(kDisabled))
return hsOK;
static plNetClientMsgScreener screener; // make static so that there's only 1 log per session
if (!screener.AllowMessage(msg))
if (!fScreener.AllowOutgoingMessage(msg))
{
if (GetFlagsBit(kScreenMessages))
return hsOK; // filter out illegal messages

6
Sources/Plasma/PubUtilLib/plNetClient/plNetClientMsgHandler.cpp

@ -351,6 +351,12 @@ MSG_HANDLER_DEFN(plNetClientMsgHandler,plNetMsgGameMessage)
nc->DebugMsg("Converting game msg future timeStamp, curT=%f, futT=%f", secs, timeStamp);
}
// Do some basic security checks on the incoming message because
// we cannot nesecarily trust the server because the server trusts
// the remote client WAY too much.
if (!IGetNetClientMgr()->fScreener.AllowIncomingMessage(gameMsg))
return hsOK;
plgDispatch::Dispatch()->MsgSend(gameMsg);
// Debug

54
Sources/Plasma/PubUtilLib/plNetClient/plNetClientMsgScreener.cpp

@ -23,9 +23,11 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
Mead, WA 99021
*==LICENSE==*/
#include "plCreatableIndex.h"
#include "plNetClientMsgScreener.h"
#include "plNetLinkingMgr.h"
#include "pfMessage/pfKIMsg.h"
#include "pnNetCommon/plNetApp.h"
#include "pnMessage/plMessage.h"
@ -86,7 +88,7 @@ bool plNetClientMsgScreener::IIsSenderCCR(const plNetGameMember* gm) const
//
// return true if msg is allowed/accepted as a net msg
//
bool plNetClientMsgScreener::AllowMessage(const plMessage* msg) const
bool plNetClientMsgScreener::AllowOutgoingMessage(const plMessage* msg) const
{
if (!msg)
return false;
@ -96,14 +98,60 @@ bool plNetClientMsgScreener::AllowMessage(const plMessage* msg) const
return true;
if (ans==kNo)
{
// WarningMsg("Quick-reject net propagated msg %s", msg->ClassName());
WarningMsg("Rejected: (Outgoing) %s [Illegal Message]", msg->ClassName());
return false;
}
if (!IValidateMessage(msg))
{
// WarningMsg("Validation failed. Blocking net propagated msg %s", msg->ClassName());
WarningMsg("Rejected: (Outgoing) %s [Validation Failed]", msg->ClassName());
return false;
}
return true;
}
//
// Return false for obvious hacked network messages
// This is all because we cannot trust Cyan's servers
//
bool plNetClientMsgScreener::AllowIncomingMessage(const plMessage* msg) const
{
if (!msg)
return false;
bool result = IScreenIncoming(msg);
if (!result)
WarningMsg("Rejected: (Incoming) %s", msg->ClassName());
return result;
}
bool plNetClientMsgScreener::IScreenIncoming(const plMessage* msg) const
{
// Why would you EVER send a RefMsg accross the network???
if (plFactory::DerivesFrom(CLASS_INDEX_SCOPED(plRefMsg), msg->ClassIndex()))
return false;
// Blacklist some obvious hacks here...
switch (msg->ClassIndex())
{
case CLASS_INDEX_SCOPED(plAudioSysMsg):
// This message has a flawed read/write
return false;
case CLASS_INDEX_SCOPED(plConsoleMsg):
// Python remote code execution vunerability
return false;
case CLASS_INDEX_SCOPED(pfKIMsg):
{
// Only accept Chat Messages!
const pfKIMsg* ki = pfKIMsg::ConvertNoRef(msg);
if (ki->GetCommand() != pfKIMsg::kHACKChatMsg)
return false;
return true;
}
default:
// Default allow everything else, otherweise we
// might break something that we really shouldn't...
return true;
}
}

4
Sources/Plasma/PubUtilLib/plNetClient/plNetClientMsgScreener.h

@ -41,11 +41,13 @@ protected:
bool IIsLocalArmatureModKey(plKey key, const plNetGameMember* gm) const;
bool IIsSenderCCR(const plNetGameMember* gm=nil) const;
bool IAmClient() const { return true; }
bool IScreenIncoming(const plMessage* msg) const;
public:
plNetClientMsgScreener();
bool AllowMessage(const plMessage* msg) const;
bool AllowOutgoingMessage(const plMessage* msg) const;
bool AllowIncomingMessage(const plMessage* msg) const;
};

Loading…
Cancel
Save