forked from teamnwah/openmw-tes3coop
[General] Add integrity checks to PacketPreInit
This commit is contained in:
parent
d999cc0d55
commit
45c7c3a0b6
2 changed files with 75 additions and 22 deletions
|
@ -1,5 +1,5 @@
|
|||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
#include "PacketPreInit.hpp"
|
||||
|
||||
mwmp::PacketPreInit::PacketPreInit(RakNet::RakPeerInterface *peer) : BasePacket(peer)
|
||||
|
@ -11,30 +11,80 @@ void mwmp::PacketPreInit::Packet(RakNet::BitStream *bs, bool send)
|
|||
{
|
||||
BasePacket::Packet(bs, send);
|
||||
|
||||
size_t size = checksums->size();
|
||||
RW(size, send);
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
const RakNet::BitSize_t packetSize = bs->GetNumberOfBytesUsed();
|
||||
uint32_t expectedPacketSize = BasePacket::headerSize() + sizeof(uint32_t);
|
||||
if (!send && expectedPacketSize > packetSize)
|
||||
{
|
||||
LOG_MESSAGE(Log::LOG_ERROR, "Wrong packet size %d when expected %d", packetSize, expectedPacketSize);
|
||||
packetValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t numberOfChecksums = checksums->size();
|
||||
RW(numberOfChecksums, send);
|
||||
|
||||
if (numberOfChecksums > maxPlugins)
|
||||
{
|
||||
LOG_MESSAGE(Log::LOG_ERROR, "Wrong number of checksums %d when maximum is %d", numberOfChecksums, maxPlugins);
|
||||
packetValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
struct NAS
|
||||
{
|
||||
uint32_t hashN;
|
||||
uint32_t strSize;
|
||||
};
|
||||
|
||||
std::vector<NAS> NumberOfHashesAndStrSizes(numberOfChecksums);
|
||||
|
||||
PluginContainer::const_iterator checksumIt = checksums->begin();
|
||||
|
||||
for (auto &&nas : NumberOfHashesAndStrSizes)
|
||||
{
|
||||
PluginPair ppair;
|
||||
if (send)
|
||||
ppair = (*checksums)[i];
|
||||
|
||||
RW(ppair.first, send);
|
||||
|
||||
size_t hashSize = ppair.second.size();
|
||||
RW(hashSize, send);
|
||||
for (size_t j = 0; j < hashSize; j++)
|
||||
{
|
||||
unsigned hash;
|
||||
if (send)
|
||||
hash = ppair.second[j];
|
||||
RW(hash, send);
|
||||
if (!send)
|
||||
ppair.second.push_back(hash);
|
||||
nas.strSize = checksumIt->first.size();
|
||||
nas.hashN = checksumIt++->second.size();
|
||||
}
|
||||
if (!send)
|
||||
checksums->push_back(ppair);
|
||||
RW(nas, send);
|
||||
|
||||
expectedPacketSize += nas.strSize + nas.hashN;
|
||||
|
||||
if (nas.strSize > pluginNameMaxLength)
|
||||
LOG_MESSAGE(Log::LOG_ERROR, "Wrong string length %d when maximum length is %d",
|
||||
nas.strSize,
|
||||
pluginNameMaxLength);
|
||||
else if (nas.hashN > maxHashes)
|
||||
LOG_MESSAGE(Log::LOG_ERROR, "Wrong number of hashes %d when maximum is %d", nas.hashN, maxHashes);
|
||||
else
|
||||
continue;
|
||||
packetValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!send && expectedPacketSize == packetSize) // server accepted plugin list via sending "empty" packet
|
||||
return;
|
||||
|
||||
if (!send && expectedPacketSize > packetSize)
|
||||
{
|
||||
LOG_MESSAGE(Log::LOG_ERROR, "Wrong packet size %d when expected %d", packetSize, expectedPacketSize);
|
||||
packetValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
checksums->resize(numberOfChecksums);
|
||||
|
||||
auto numberOfHashesIt = NumberOfHashesAndStrSizes.cbegin();
|
||||
|
||||
for (auto &&checksum : *checksums)
|
||||
{
|
||||
RW(checksum.first, send, false, numberOfHashesIt->strSize);
|
||||
|
||||
checksum.second.resize(numberOfHashesIt->hashN);
|
||||
for (auto &&hash : checksum.second)
|
||||
RW(hash, send);
|
||||
++numberOfHashesIt;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace mwmp
|
|||
class PacketPreInit : public BasePacket
|
||||
{
|
||||
public:
|
||||
typedef std::vector<unsigned> HashList;
|
||||
typedef std::vector<uint32_t> HashList;
|
||||
typedef std::pair<std::string, HashList> PluginPair;
|
||||
typedef std::vector<PluginPair> PluginContainer;
|
||||
|
||||
|
@ -20,6 +20,9 @@ namespace mwmp
|
|||
void setChecksums(PluginContainer *checksums);
|
||||
private:
|
||||
PluginContainer *checksums;
|
||||
const static uint32_t maxPlugins = 256;
|
||||
const static uint32_t pluginNameMaxLength = 256;
|
||||
const static uint32_t maxHashes = 16;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue