Protocol: call the encryptor once before sending data
This commit is contained in:
parent
8a08b3d3b7
commit
e735faf755
@ -238,6 +238,7 @@ void cClientHandle::ProcessProtocolOut()
|
|||||||
// to prevent it being reset between the null check and the Send:
|
// to prevent it being reset between the null check and the Send:
|
||||||
if (auto Link = m_Link; Link != nullptr)
|
if (auto Link = m_Link; Link != nullptr)
|
||||||
{
|
{
|
||||||
|
m_Protocol->DataPrepared(OutgoingData);
|
||||||
Link->Send(OutgoingData.data(), OutgoingData.size());
|
Link->Send(OutgoingData.data(), OutgoingData.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -346,10 +346,15 @@ public:
|
|||||||
Game = 3,
|
Game = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Called to process them, when client sends some data.
|
/** Called by cClientHandle to process data, when the client sends some.
|
||||||
The protocol uses the provided buffers for storage and processing, and must have exclusive access to them. */
|
The protocol uses the provided buffers for storage and processing, and must have exclusive access to them. */
|
||||||
virtual void DataReceived(cByteBuffer & a_Buffer, ContiguousByteBuffer && a_Data) = 0;
|
virtual void DataReceived(cByteBuffer & a_Buffer, ContiguousByteBuffer && a_Data) = 0;
|
||||||
|
|
||||||
|
/** Called by cClientHandle to finalise a buffer of prepared data before they are sent to the client.
|
||||||
|
Descendants may for example, encrypt the data if needed.
|
||||||
|
The protocol modifies the provided buffer in-place. */
|
||||||
|
virtual void DataPrepared(ContiguousByteBuffer & a_Data) = 0;
|
||||||
|
|
||||||
// Sending stuff to clients (alphabetically sorted):
|
// Sending stuff to clients (alphabetically sorted):
|
||||||
virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity & a_Vehicle) = 0;
|
virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity & a_Vehicle) = 0;
|
||||||
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) = 0;
|
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) = 0;
|
||||||
@ -466,9 +471,6 @@ protected:
|
|||||||
/** Returns the current protocol's version, for handling status requests. */
|
/** Returns the current protocol's version, for handling status requests. */
|
||||||
virtual Version GetProtocolVersion() const = 0;
|
virtual Version GetProtocolVersion() const = 0;
|
||||||
|
|
||||||
/** A generic data-sending routine, all outgoing packet data needs to be routed through this so that descendants may override it. */
|
|
||||||
virtual void SendData(ContiguousByteBufferView a_Data) = 0;
|
|
||||||
|
|
||||||
/** Sends a single packet contained within the cPacketizer class.
|
/** Sends a single packet contained within the cPacketizer class.
|
||||||
The cPacketizer's destructor calls this to send the contained packet; protocol may transform the data (compression in 1.8 etc). */
|
The cPacketizer's destructor calls this to send the contained packet; protocol may transform the data (compression in 1.8 etc). */
|
||||||
virtual void SendPacket(cPacketizer & a_Packet) = 0;
|
virtual void SendPacket(cPacketizer & a_Packet) = 0;
|
||||||
|
@ -188,6 +188,18 @@ void cProtocol_1_8_0::DataReceived(cByteBuffer & a_Buffer, ContiguousByteBuffer
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol_1_8_0::DataPrepared(ContiguousByteBuffer & a_Data)
|
||||||
|
{
|
||||||
|
if (m_IsEncrypted)
|
||||||
|
{
|
||||||
|
m_Encryptor.ProcessData(a_Data.data(), a_Data.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cProtocol_1_8_0::SendAttachEntity(const cEntity & a_Entity, const cEntity & a_Vehicle)
|
void cProtocol_1_8_0::SendAttachEntity(const cEntity & a_Entity, const cEntity & a_Vehicle)
|
||||||
{
|
{
|
||||||
ASSERT(m_State == 3); // In game mode?
|
ASSERT(m_State == 3); // In game mode?
|
||||||
@ -370,7 +382,7 @@ void cProtocol_1_8_0::SendChunkData(const ContiguousByteBufferView a_ChunkData)
|
|||||||
ASSERT(m_State == 3); // In game mode?
|
ASSERT(m_State == 3); // In game mode?
|
||||||
|
|
||||||
cCSLock Lock(m_CSPacket);
|
cCSLock Lock(m_CSPacket);
|
||||||
SendData(a_ChunkData);
|
m_Client->SendData(a_ChunkData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3003,31 +3015,6 @@ void cProtocol_1_8_0::SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_Ob
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cProtocol_1_8_0::SendData(ContiguousByteBufferView a_Data)
|
|
||||||
{
|
|
||||||
if (m_IsEncrypted)
|
|
||||||
{
|
|
||||||
std::byte Encrypted[8 KiB]; // Larger buffer, we may be sending lots of data (chunks)
|
|
||||||
|
|
||||||
while (a_Data.size() > 0)
|
|
||||||
{
|
|
||||||
const auto NumBytes = (a_Data.size() > sizeof(Encrypted)) ? sizeof(Encrypted) : a_Data.size();
|
|
||||||
m_Encryptor.ProcessData(Encrypted, a_Data.data(), NumBytes);
|
|
||||||
m_Client->SendData({ Encrypted, NumBytes });
|
|
||||||
|
|
||||||
a_Data = a_Data.substr(NumBytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_Client->SendData(a_Data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cProtocol_1_8_0::SendPacket(cPacketizer & a_Pkt)
|
void cProtocol_1_8_0::SendPacket(cPacketizer & a_Pkt)
|
||||||
{
|
{
|
||||||
ASSERT(m_OutPacketBuffer.GetReadableSpace() == m_OutPacketBuffer.GetUsedSpace());
|
ASSERT(m_OutPacketBuffer.GetReadableSpace() == m_OutPacketBuffer.GetUsedSpace());
|
||||||
@ -3045,7 +3032,7 @@ void cProtocol_1_8_0::SendPacket(cPacketizer & a_Pkt)
|
|||||||
cProtocol_1_8_0::CompressPacket(m_Compressor, CompressedPacket);
|
cProtocol_1_8_0::CompressPacket(m_Compressor, CompressedPacket);
|
||||||
|
|
||||||
// Send the packet's payload compressed:
|
// Send the packet's payload compressed:
|
||||||
SendData(CompressedPacket);
|
m_Client->SendData(CompressedPacket);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3054,10 +3041,10 @@ void cProtocol_1_8_0::SendPacket(cPacketizer & a_Pkt)
|
|||||||
ContiguousByteBuffer LengthData;
|
ContiguousByteBuffer LengthData;
|
||||||
m_OutPacketLenBuffer.ReadAll(LengthData);
|
m_OutPacketLenBuffer.ReadAll(LengthData);
|
||||||
m_OutPacketLenBuffer.CommitRead();
|
m_OutPacketLenBuffer.CommitRead();
|
||||||
SendData(LengthData);
|
m_Client->SendData(LengthData);
|
||||||
|
|
||||||
// Send the packet's payload directly:
|
// Send the packet's payload directly:
|
||||||
SendData(PacketData);
|
m_Client->SendData(PacketData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log the comm into logfile:
|
// Log the comm into logfile:
|
||||||
|
@ -36,11 +36,10 @@ public:
|
|||||||
|
|
||||||
cProtocol_1_8_0(cClientHandle * a_Client, const AString & a_ServerAddress, State a_State);
|
cProtocol_1_8_0(cClientHandle * a_Client, const AString & a_ServerAddress, State a_State);
|
||||||
|
|
||||||
/** Called to process them, when client sends some data.
|
|
||||||
The protocol uses the provided buffers for storage and processing, and must have exclusive access to them. */
|
|
||||||
virtual void DataReceived(cByteBuffer & a_Buffer, ContiguousByteBuffer && a_Data) override;
|
virtual void DataReceived(cByteBuffer & a_Buffer, ContiguousByteBuffer && a_Data) override;
|
||||||
|
virtual void DataPrepared(ContiguousByteBuffer & a_Data) override;
|
||||||
|
|
||||||
/** Sending stuff to clients (alphabetically sorted): */
|
// Sending stuff to clients (alphabetically sorted):
|
||||||
virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity & a_Vehicle) override;
|
virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity & a_Vehicle) override;
|
||||||
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override;
|
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override;
|
||||||
virtual void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
|
virtual void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
|
||||||
@ -216,9 +215,6 @@ protected:
|
|||||||
/** Sends the entity type and entity-dependent data required for the entity to initially spawn. */
|
/** Sends the entity type and entity-dependent data required for the entity to initially spawn. */
|
||||||
virtual void SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData);
|
virtual void SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData);
|
||||||
|
|
||||||
/** Sends the data to the client, encrypting them if needed. */
|
|
||||||
virtual void SendData(ContiguousByteBufferView a_Size) override;
|
|
||||||
|
|
||||||
/** Sends the packet to the client. Called by the cPacketizer's destructor. */
|
/** Sends the packet to the client. Called by the cPacketizer's destructor. */
|
||||||
virtual void SendPacket(cPacketizer & a_Packet) override;
|
virtual void SendPacket(cPacketizer & a_Packet) override;
|
||||||
|
|
||||||
|
@ -43,8 +43,8 @@ void cAesCfb128Encryptor::Init(const Byte a_Key[16], const Byte a_IV[16])
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cAesCfb128Encryptor::ProcessData(std::byte * const a_EncryptedOut, const std::byte * const a_PlainIn, size_t a_Length)
|
void cAesCfb128Encryptor::ProcessData(std::byte * const a_PlainIn, const size_t a_Length)
|
||||||
{
|
{
|
||||||
ASSERT(IsValid()); // Must Init() first
|
ASSERT(IsValid()); // Must Init() first
|
||||||
mbedtls_aes_crypt_cfb8(&m_Aes, MBEDTLS_AES_ENCRYPT, a_Length, m_IV, reinterpret_cast<const unsigned char *>(a_PlainIn), reinterpret_cast<unsigned char *>(a_EncryptedOut));
|
mbedtls_aes_crypt_cfb8(&m_Aes, MBEDTLS_AES_ENCRYPT, a_Length, m_IV, reinterpret_cast<const unsigned char *>(a_PlainIn), reinterpret_cast<unsigned char *>(a_PlainIn));
|
||||||
}
|
}
|
||||||
|
@ -26,13 +26,14 @@ public:
|
|||||||
/** Initializes the decryptor with the specified Key / IV */
|
/** Initializes the decryptor with the specified Key / IV */
|
||||||
void Init(const Byte a_Key[16], const Byte a_IV[16]);
|
void Init(const Byte a_Key[16], const Byte a_IV[16]);
|
||||||
|
|
||||||
/** Encrypts a_Length bytes of the plain data; produces a_Length output bytes */
|
/** Encrypts a_Length bytes of the plain data in-place; produces a_Length output bytes */
|
||||||
void ProcessData(std::byte * a_EncryptedOut, const std::byte * a_PlainIn, size_t a_Length);
|
void ProcessData(std::byte * a_PlainIn, size_t a_Length);
|
||||||
|
|
||||||
/** Returns true if the object has been initialized with the Key / IV */
|
/** Returns true if the object has been initialized with the Key / IV */
|
||||||
bool IsValid(void) const { return m_IsValid; }
|
bool IsValid(void) const { return m_IsValid; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
mbedtls_aes_context m_Aes;
|
mbedtls_aes_context m_Aes;
|
||||||
|
|
||||||
/** The InitialVector, used by the CFB mode encryption */
|
/** The InitialVector, used by the CFB mode encryption */
|
||||||
@ -41,8 +42,3 @@ protected:
|
|||||||
/** Indicates whether the object has been initialized with the Key / IV */
|
/** Indicates whether the object has been initialized with the Key / IV */
|
||||||
bool m_IsValid;
|
bool m_IsValid;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user