From e4d6af37a979831b37cc7f72de4ae6966eb69964 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 18 Jan 2017 14:11:25 +0200 Subject: [PATCH] Masking: Distinguish between EOF and 8 byte integer When processing the response to a COM_QUERY, the rows will be terminated by an EOF packet. However, as the type byte of an EOF packet is 0xFE and the identifying byte of an 8 byte length encoded integer is also 0xFE it is not possible to distinguish the two except by also looking at packet length. --- .../filter/masking/maskingfiltersession.cc | 34 ++++++++------- .../filter/masking/maskingfiltersession.hh | 2 +- server/modules/filter/masking/mysql.hh | 41 ++++++++++++++----- 3 files changed, 48 insertions(+), 29 deletions(-) diff --git a/server/modules/filter/masking/maskingfiltersession.cc b/server/modules/filter/masking/maskingfiltersession.cc index 58d64ad5d..8f9ad1682 100644 --- a/server/modules/filter/masking/maskingfiltersession.cc +++ b/server/modules/filter/masking/maskingfiltersession.cc @@ -216,28 +216,26 @@ void warn_of_type_mismatch(const MaskingRules::Rule& rule) void MaskingFilterSession::handle_row(GWBUF* pPacket) { - ComResponse response(pPacket); + ComPacket response(pPacket); - switch (response.type()) + if ((response.payload_len() == ComEOF::PAYLOAD_LEN) && + (ComResponse(response).type() == ComPacket::EOF_PACKET)) { - case ComPacket::EOF_PACKET: // EOF after last row. + ComEOF eof(response); + + if (eof.status() & SERVER_MORE_RESULTS_EXIST) { - ComEOF eof(response); - - if (eof.status() & SERVER_MORE_RESULTS_EXIST) - { - m_res.reset_multi(); - m_state = EXPECTING_RESPONSE; - } - else - { - m_state = EXPECTING_NOTHING; - } + m_res.reset_multi(); + m_state = EXPECTING_RESPONSE; } - break; - - default: + else + { + m_state = EXPECTING_NOTHING; + } + } + else + { if (m_res.some_rule_matches()) { if (response.payload_len() >= ComPacket::MAX_PAYLOAD_LEN) @@ -267,7 +265,7 @@ void MaskingFilterSession::handle_large_payload() } } -void MaskingFilterSession::mask_values(ComResponse& response) +void MaskingFilterSession::mask_values(ComPacket& response) { switch (m_res.command()) { diff --git a/server/modules/filter/masking/maskingfiltersession.hh b/server/modules/filter/masking/maskingfiltersession.hh index 45c7804d5..9a1644117 100644 --- a/server/modules/filter/masking/maskingfiltersession.hh +++ b/server/modules/filter/masking/maskingfiltersession.hh @@ -59,7 +59,7 @@ private: void handle_eof(GWBUF* pPacket); void handle_large_payload(); - void mask_values(ComResponse& response); + void mask_values(ComPacket& response); private: typedef std::tr1::shared_ptr SMaskingRules; diff --git a/server/modules/filter/masking/mysql.hh b/server/modules/filter/masking/mysql.hh index 678f5e8ca..34fb8337e 100644 --- a/server/modules/filter/masking/mysql.hh +++ b/server/modules/filter/masking/mysql.hh @@ -493,16 +493,6 @@ public: MAX_PAYLOAD_LEN = 0xffffff }; - uint32_t payload_len() const - { - return m_payload_len; - } - uint8_t packet_no() const - { - return m_packet_no; - } - -protected: ComPacket(GWBUF* pPacket) : m_pPacket(pPacket) , m_pData(GWBUF_DATA(pPacket)) @@ -521,6 +511,22 @@ protected: m_pData += MYSQL_HEADER_LEN; } + uint32_t payload_len() const + { + return m_payload_len; + } + + uint32_t packet_len() const + { + return MYSQL_HEADER_LEN + m_payload_len; + } + + uint8_t packet_no() const + { + return m_packet_no; + } + +protected: GWBUF* m_pPacket; uint8_t* m_pData; @@ -542,13 +548,22 @@ public: : ComPacket(pPacket) , m_type(*m_pData) { + ss_dassert(packet_len() >= MYSQL_HEADER_LEN + 1); ++m_pData; } + ComResponse(const ComPacket& packet) + : ComPacket(packet) + , m_type(*m_pData) + { + ss_dassert(packet_len() >= MYSQL_HEADER_LEN + 1); + ++m_pData; + } ComResponse(const ComResponse& packet) : ComPacket(packet) , m_type(packet.m_type) { + ss_dassert(packet_len() >= MYSQL_HEADER_LEN + 1); ++m_pData; } @@ -579,6 +594,12 @@ protected: class ComEOF : public ComResponse { public: + enum + { + PAYLOAD_LEN = 5, + PACKET_LEN = MYSQL_HEADER_LEN + PAYLOAD_LEN + }; + ComEOF(GWBUF* pPacket) : ComResponse(pPacket) {