From 2dda6231f62360218d4708ea4dadc6e0c588f0fb Mon Sep 17 00:00:00 2001 From: Ned Wright Date: Thu, 28 Nov 2024 10:53:40 +0000 Subject: [PATCH] sync code --- .../waap_clib/ParserKnownBenignSkipper.cc | 139 +++++++++++++ .../waap/waap_clib/ParserKnownBenignSkipper.h | 52 +++++ .../waap/waap_clib/ParserScreenedJson.cc | 187 ++++++++++++++++++ .../waap/waap_clib/ParserScreenedJson.h | 52 +++++ 4 files changed, 430 insertions(+) create mode 100644 components/security_apps/waap/waap_clib/ParserKnownBenignSkipper.cc create mode 100644 components/security_apps/waap/waap_clib/ParserKnownBenignSkipper.h create mode 100644 components/security_apps/waap/waap_clib/ParserScreenedJson.cc create mode 100644 components/security_apps/waap/waap_clib/ParserScreenedJson.h diff --git a/components/security_apps/waap/waap_clib/ParserKnownBenignSkipper.cc b/components/security_apps/waap/waap_clib/ParserKnownBenignSkipper.cc new file mode 100644 index 0000000..8509537 --- /dev/null +++ b/components/security_apps/waap/waap_clib/ParserKnownBenignSkipper.cc @@ -0,0 +1,139 @@ +// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ParserKnownBenignSkipper.h" +#include "Waf2Util.h" +#include "debug.h" +#include +USE_DEBUG_FLAG(D_WAAP_PARSER_KNOWN_SOURCE_SKIPPER); +USE_DEBUG_FLAG(D_WAAP); + +const std::string ParserKnownBenignSkipper::m_parserName = "ParserKnownBenignSkipper"; +const char* DATA_SENSOR_TAIL = "\"}"; + +ParserKnownBenignSkipper::ParserKnownBenignSkipper( + IParserStreamReceiver &receiver, + size_t parser_depth, + Waap::Util::KnownSourceType source_type +) : + m_receiver(receiver), + m_state(s_start), + m_parser_depth(parser_depth), + m_source_type(source_type) +{} + +ParserKnownBenignSkipper::~ParserKnownBenignSkipper() +{} + +size_t +ParserKnownBenignSkipper::push(const char *buf, size_t len) +{ + dbgTrace(D_WAAP_PARSER_KNOWN_SOURCE_SKIPPER) + << "buf='" + << std::string(buf, std::min((size_t)200, len)) + << (len > 200 ? "..." : "") + << "' len=" + << len + << " depth=" + << depth(); + + const char *c; + + if (m_state == s_error) { + return 0; + } + if (len == 0) + { + dbgTrace(D_WAAP_PARSER_KNOWN_SOURCE_SKIPPER) + << "ParserKnownBenignSkipper::push(): end of stream. m_state=" + << m_state; + + if (m_state == s_end) { + m_receiver.onKvDone(); + } else { + m_state = s_error; + } + return 0; + } + + size_t tail_lookup_offset = 0; + + switch (m_state) { + case s_start: + m_state = s_body; + CP_FALL_THROUGH; + case s_body: + { + if (m_source_type == Waap::Util::SOURCE_TYPE_SENSOR_DATA) { + tail_lookup_offset = + (len > MAX_DATA_SENSOR_TAIL_LOOKUP) ? len - MAX_DATA_SENSOR_TAIL_LOOKUP : 0; + c = strstr(buf + tail_lookup_offset, DATA_SENSOR_TAIL); + if (c) { + dbgTrace(D_WAAP_PARSER_KNOWN_SOURCE_SKIPPER) + << "ParserKnownBenignSkipper::push(): found end of sensor data"; + m_state = s_end; + CP_FALL_THROUGH; + } else { + break; + } + } else { + dbgTrace(D_WAAP_PARSER_KNOWN_SOURCE_SKIPPER) + << "ParserKnownBenignSkipper::push(): unknown source type"; + m_state = s_error; + break; + } + } + case s_end: + dbgTrace(D_WAAP_PARSER_KNOWN_SOURCE_SKIPPER) << "state = end"; + if (m_receiver.onKey("SENSOR_DATA", 11) != 0) { + dbgTrace(D_WAAP_PARSER_KNOWN_SOURCE_SKIPPER) << "state moving to error onKey"; + m_state = s_error; + return 0; + } + if (m_receiver.onValue("", 0) != 0) { + dbgTrace(D_WAAP_PARSER_KNOWN_SOURCE_SKIPPER) << "state moving to error onValue"; + m_state = s_error; + return 0; + } + break; + case s_error: + dbgTrace(D_WAAP_PARSER_KNOWN_SOURCE_SKIPPER) << "state = error"; + break; + default: + dbgTrace(D_WAAP_PARSER_KNOWN_SOURCE_SKIPPER) + << "ParserKnownBenignSkipper::push(): unknown state: " + << m_state; + m_state = s_error; + return 0; + } + dbgTrace(D_WAAP_PARSER_KNOWN_SOURCE_SKIPPER) + << "ParserKnownBenignSkipper::push(): final state: " + << m_state; + return len; +} + + +void ParserKnownBenignSkipper::finish() +{ + push(NULL, 0); +} + +const std::string& ParserKnownBenignSkipper::name() const +{ + return m_parserName; +} + +bool ParserKnownBenignSkipper::error() const +{ + return m_state == s_error; +} diff --git a/components/security_apps/waap/waap_clib/ParserKnownBenignSkipper.h b/components/security_apps/waap/waap_clib/ParserKnownBenignSkipper.h new file mode 100644 index 0000000..67ca4f0 --- /dev/null +++ b/components/security_apps/waap/waap_clib/ParserKnownBenignSkipper.h @@ -0,0 +1,52 @@ +// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __PARSER_BENIGN_SKIPPER_H__ +#define __PARSER_BENIGN_SKIPPER_H__ + +#include "ParserBase.h" +#include "Waf2Util.h" +#include +#include "Waf2Util.h" + +#define MAX_DATA_SENSOR_TAIL_LOOKUP 5 + +class ParserKnownBenignSkipper : public ParserBase { +public: + ParserKnownBenignSkipper( + IParserStreamReceiver &receiver, + size_t parser_depth, + Waap::Util::KnownSourceType source_type=Waap::Util::SOURCE_TYPE_UNKNOWN); + virtual ~ParserKnownBenignSkipper(); + virtual size_t push(const char *buf, size_t len); + virtual void finish(); + virtual const std::string &name() const; + virtual bool error() const; + virtual size_t depth() { return 1; } + +private: + enum state { + s_start, + s_body, + s_end, + s_error + }; + + IParserStreamReceiver &m_receiver; + enum state m_state; + static const std::string m_parserName; + size_t m_parser_depth; + Waap::Util::KnownSourceType m_source_type; +}; + +#endif // __PARSER_BENIGN_SKIPPER_H__ diff --git a/components/security_apps/waap/waap_clib/ParserScreenedJson.cc b/components/security_apps/waap/waap_clib/ParserScreenedJson.cc new file mode 100644 index 0000000..eea08eb --- /dev/null +++ b/components/security_apps/waap/waap_clib/ParserScreenedJson.cc @@ -0,0 +1,187 @@ +#include "ParserScreenedJson.h" +#include "debug.h" + +USE_DEBUG_FLAG(D_WAAP_PARSER_SCREENED_JSON); + +const std::string ParserScreenedJson::m_parserName = "ParserScreenedJson"; + +ParserScreenedJson::ParserScreenedJson(IParserStreamReceiver &receiver, size_t parser_depth) : + m_receiver(receiver), + m_state(s_start), + m_unscreenedLen(0), + m_leftoverLen(0), + m_parser_depth(parser_depth) +{ + dbgTrace(D_WAAP_PARSER_SCREENED_JSON) + << "parser_depth=" + << parser_depth; + + memset(m_unscreened, 0, sizeof(m_unscreened)); +} + +ParserScreenedJson::~ParserScreenedJson() +{} + +size_t +ParserScreenedJson::push(const char *buf, size_t len) +{ + size_t i = 0; + char c; + + dbgTrace(D_WAAP_PARSER_SCREENED_JSON) << "ParserScreenedJson::push(): starting (len=" << len << ")"; + + if (len == 0) { + dbgTrace(D_WAAP_PARSER_SCREENED_JSON) << "ParserScreenedJson::push(): end of data signal! m_state=" << m_state; + // flush unescaped data collected (if any) + if (m_leftoverLen > 0) { + // No need any processing for leftover data - last char must be doublequote, else - error + m_state = s_error; + dbgTrace(D_WAAP_PARSER_SCREENED_JSON) + << "ParserScreenedJson::push(): end of data and leftover detected m_state=" + << m_state; + return i; + } + dbgTrace(D_WAAP_PARSER_SCREENED_JSON) + << "ParserScreenedJson::push(): s_value, pushing m_unscreened = " + << m_unscreened + << ", m_leftoverLen = " + << m_leftoverLen + << ", m_unscreenedLen = " + << m_unscreenedLen; + + if (m_receiver.onKey("json_unscreened", 15) != 0) { + m_state = s_error; + return i; + } + + if (m_receiver.onValue(m_unscreened, m_unscreenedLen) != 0) { + m_state = s_error; + return i; + } + + if (m_receiver.onKvDone() != 0) + { + m_state = s_error; + return i; + } + return 0; + } + + while (i < len) + { + c = buf[i]; + + dbgTrace(D_WAAP_PARSER_SCREENED_JSON) + << "ParserScreenedJson::push(): state=" + << m_state + << "; c='" + << c + << "'" + << "; i=" + << i + << ", m_leftoverLen = " + << m_leftoverLen + << ", m_unscreenedLen = " + << m_unscreenedLen + << ", m_unscreened = " + << m_unscreened; + + switch (m_state) + { + case s_start: + { + dbgTrace(D_WAAP_PARSER_SCREENED_JSON) + << "ParserScreenedJson::push(): s_start"; + m_state = s_value; + + // fallthrough not required, removing 1st doublequote, it denoted by regex // + //CP_FALL_THROUGH; + break; + } + case s_value: + { + if (c == '\\') { + if (m_leftoverLen > 0) { + m_unscreened[m_unscreenedLen] = '\\'; + m_leftoverLen = 0; + m_unscreenedLen++; + } else { + m_leftoverLen++; + } + } else if (c =='\"') { + if (m_leftoverLen > 0) { + m_unscreened[m_unscreenedLen] = '\"'; + m_unscreenedLen++; + if (m_leftoverLen > 0) { + m_leftoverLen = 0; + } + } + } else { + if (m_leftoverLen > 0) { + m_unscreened[m_unscreenedLen] = '\\'; + m_unscreenedLen++; + m_leftoverLen = 0; + } + m_unscreened[m_unscreenedLen] = c; + m_unscreenedLen++; + } + if (m_unscreenedLen >= MAX_UNSCREENED_JSON_SIZE) { + if (m_receiver.onKey("json_unscreened", 15) != 0) { + m_state = s_error; + return i; + } + dbgTrace(D_WAAP_PARSER_SCREENED_JSON) + << "ParserScreenedJson::push(): s_value, pushing m_unscreened = " + << m_unscreened + << ", m_leftoverLen = " + << m_leftoverLen + << ", m_unscreenedLen = " + << m_unscreenedLen; + if (m_receiver.onValue(m_unscreened, m_unscreenedLen) != 0) { + m_state = s_error; + return i; + } + m_unscreenedLen = 0; + } + break; + } + case s_error: + { + dbgTrace(D_WAAP_PARSER_SCREENED_JSON) + << "ParserScreenedJson::push(): s_error"; + return 0; + } + default: + { + dbgTrace(D_WAAP_PARSER_SCREENED_JSON) + << "ParserScreenedJson::push(): JSON parser unrecoverable error"; + m_state = s_error; + return 0; + } + } + ++i; + } + + dbgTrace(D_WAAP_PARSER_SCREENED_JSON) + << "ParserScreenedJson::push(): finished: len=" + << len; + return len; +} + +void +ParserScreenedJson::finish() +{ + push(NULL, 0); +} + +const std::string & +ParserScreenedJson::name() const +{ + return m_parserName; +} + +bool +ParserScreenedJson::error() const +{ + return m_state == s_error; +} diff --git a/components/security_apps/waap/waap_clib/ParserScreenedJson.h b/components/security_apps/waap/waap_clib/ParserScreenedJson.h new file mode 100644 index 0000000..76ea271 --- /dev/null +++ b/components/security_apps/waap/waap_clib/ParserScreenedJson.h @@ -0,0 +1,52 @@ +// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __PARSER_SCREENED_JSON_H_ +#define __PARSER_SCREENED_JSON_H_ + +#include "ParserBase.h" +#include + +#define MAX_UNSCREENED_JSON_SIZE 4095 + +class ParserScreenedJson : public ParserBase { +public: + ParserScreenedJson(IParserStreamReceiver &receiver, size_t parser_depth); + virtual ~ParserScreenedJson(); + size_t push(const char *data, size_t data_len); + void finish(); + virtual const std::string &name() const; + bool error() const; + // LCOV_EXCL_START Reason: The function not in use, compliance with the interface + virtual size_t depth() { return 1; } + // LCOV_EXCL_STOP + +private: + enum state + { + s_start, + s_value, + s_error + }; + + IParserStreamReceiver &m_receiver; + enum state m_state; + size_t m_unscreenedLen; + char m_unscreened[MAX_UNSCREENED_JSON_SIZE]; + size_t m_leftoverLen; + static const std::string m_parserName; + size_t m_parser_depth; +}; + +#endif +