diff --git a/components/attachment-intakers/nginx_attachment/nginx_attachment.cc b/components/attachment-intakers/nginx_attachment/nginx_attachment.cc index 43b8221..8df0049 100755 --- a/components/attachment-intakers/nginx_attachment/nginx_attachment.cc +++ b/components/attachment-intakers/nginx_attachment/nginx_attachment.cc @@ -589,7 +589,7 @@ private: uint32_t handled_session_id = session_verdict.unpack().first; bool is_signal_needed = session_verdict.unpack().second; - if (is_signal_needed || !isDataAvailable(attachment_ipc)) { + if (is_signal_needed) { dbgTrace(D_NGINX_ATTACHMENT) << "Signaling attachment to read verdict"; bool res = false; vector session_id_data( @@ -1486,7 +1486,8 @@ private: i_transaction_table->unsetActiveKey(); } - return make_pair(cur_session_id, is_final_verdict); + bool should_signal = (is_final_verdict || !isDataAvailable(attachment_ipc)); + return make_pair(cur_session_id, should_signal); } bool diff --git a/components/include/env_details.h b/components/include/env_details.h new file mode 100644 index 0000000..aeaa1b3 --- /dev/null +++ b/components/include/env_details.h @@ -0,0 +1,41 @@ +// 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 __ENV_DETAILS_H__ +#define __ENV_DETAILS_H__ + +#include +#include +#include + +#include "i_env_details.h" +#include "singleton.h" +#include "debug.h" + +class EnvDetails : Singleton::Provide::SelfInterface +{ +public: + EnvDetails(); + + virtual EnvType getEnvType() override; + virtual std::string getToken() override; + +private: + std::string retrieveToken(); + std::string readFileContent(const std::string &file_path); + + std::string token; + EnvType env_type; +}; + +#endif // __ENV_DETAILS_H__ diff --git a/components/include/i_local_policy_mgmt_gen.h b/components/include/i_local_policy_mgmt_gen.h index 01c9c97..e9f9b94 100755 --- a/components/include/i_local_policy_mgmt_gen.h +++ b/components/include/i_local_policy_mgmt_gen.h @@ -17,11 +17,8 @@ class I_LocalPolicyMgmtGen { public: - enum class LocalPolicyEnv { LINUX, K8S, COUNT }; - virtual std::string parsePolicy(const std::string &policy_version) = 0; virtual const std::string & getPolicyPath(void) const = 0; - virtual LocalPolicyEnv getEnvType() const = 0; protected: ~I_LocalPolicyMgmtGen() {} diff --git a/components/include/i_pm_scan.h b/components/include/i_pm_scan.h index fdf5ea6..84f55cc 100755 --- a/components/include/i_pm_scan.h +++ b/components/include/i_pm_scan.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "buffer.h" #include "maybe_res.h" @@ -57,7 +58,7 @@ public: using CBFunction = std::function; virtual std::set scanBuf(const Buffer &buf) const = 0; - virtual std::set> scanBufWithOffset(const Buffer &buf) const = 0; + virtual std::set> scanBufWithOffset(const Buffer &buf) const = 0; virtual void scanBufWithOffsetLambda(const Buffer &buf, CBFunction cb) const = 0; protected: diff --git a/components/include/local_policy_mgmt_gen.h b/components/include/local_policy_mgmt_gen.h index b22a6fa..5c13929 100644 --- a/components/include/local_policy_mgmt_gen.h +++ b/components/include/local_policy_mgmt_gen.h @@ -17,23 +17,20 @@ #include "config.h" #include "component.h" #include "i_mainloop.h" -#include "i_environment.h" #include "i_local_policy_mgmt_gen.h" +#include "i_env_details.h" class LocalPolicyMgmtGenerator : public Component, Singleton::Provide, - Singleton::Consume, Singleton::Consume, - Singleton::Consume + Singleton::Consume { public: LocalPolicyMgmtGenerator(); ~LocalPolicyMgmtGenerator(); - void preload() override; - void init() override; private: diff --git a/components/include/pm_hook.h b/components/include/pm_hook.h index 282d96d..f587189 100644 --- a/components/include/pm_hook.h +++ b/components/include/pm_hook.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "i_pm_scan.h" @@ -30,7 +31,7 @@ public: Maybe prepare(const std::set &patterns); std::set scanBuf(const Buffer &buf) const override; - std::set> scanBufWithOffset(const Buffer &buf) const override; + std::set> scanBufWithOffset(const Buffer &buf) const override; void scanBufWithOffsetLambda(const Buffer &buf, I_PMScan::CBFunction cb) const override; // Line may begin with ^ or $ sign to mark LSS is at begin/end of buffer. diff --git a/components/security_apps/orchestration/CMakeLists.txt b/components/security_apps/orchestration/CMakeLists.txt index a0f5954..565ab08 100755 --- a/components/security_apps/orchestration/CMakeLists.txt +++ b/components/security_apps/orchestration/CMakeLists.txt @@ -13,5 +13,6 @@ add_subdirectory(update_communication) add_subdirectory(details_resolver) add_subdirectory(health_check) add_subdirectory(local_policy_mgmt_gen) +add_subdirectory(env_details) add_subdirectory(orchestration_ut) diff --git a/components/security_apps/orchestration/details_resolver/details_resolver_handlers/checkpoint_product_handlers.h b/components/security_apps/orchestration/details_resolver/details_resolver_handlers/checkpoint_product_handlers.h index 84f4d07..f8293a4 100755 --- a/components/security_apps/orchestration/details_resolver/details_resolver_handlers/checkpoint_product_handlers.h +++ b/components/security_apps/orchestration/details_resolver/details_resolver_handlers/checkpoint_product_handlers.h @@ -116,6 +116,47 @@ getMgmtObjName(shared_ptr file_stream) return getMgmtObjAttr(file_stream, "name "); } +Maybe +getGWIPAddress(shared_ptr file_stream) +{ + return getMgmtObjAttr(file_stream, "ipaddr "); +} + +Maybe +getGWHardware(shared_ptr file_stream) +{ + Maybe val = getMgmtObjAttr(file_stream, "appliance_type "); + if(val.ok()) { + if (val == string("software")) return string("Open server"); + if (val == string("Maestro Gateway")) return string("Maestro"); + } + return val; +} + +Maybe +getGWApplicationControlBlade(shared_ptr file_stream) +{ + return getMgmtObjAttr(file_stream, "application_firewall_blade "); +} + +Maybe +getGWURLFilteringBlade(shared_ptr file_stream) +{ + return getMgmtObjAttr(file_stream, "advanced_uf_blade "); +} + +Maybe +getGWIPSecVPNBlade(shared_ptr file_stream) +{ + return getMgmtObjAttr(file_stream, "VPN_1 "); +} + +Maybe +getGWVersion(shared_ptr file_stream) +{ + return getMgmtObjAttr(file_stream, "svn_version_name "); +} + Maybe getSmbObjectName(const string &command_output) { diff --git a/components/security_apps/orchestration/details_resolver/details_resolver_handlers/details_resolver_impl.h b/components/security_apps/orchestration/details_resolver/details_resolver_handlers/details_resolver_impl.h index 915d22b..940b15a 100755 --- a/components/security_apps/orchestration/details_resolver/details_resolver_handlers/details_resolver_impl.h +++ b/components/security_apps/orchestration/details_resolver/details_resolver_handlers/details_resolver_impl.h @@ -87,6 +87,37 @@ FILE_CONTENT_HANDLER( (getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myown.C", getMgmtObjUid ) +FILE_CONTENT_HANDLER( + "IP Address", + (getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myself_objects.C", + getGWIPAddress +) +FILE_CONTENT_HANDLER( + "Hardware", + (getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myself_objects.C", + getGWHardware +) +FILE_CONTENT_HANDLER( + "Application Control", + (getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myself_objects.C", + getGWApplicationControlBlade +) +FILE_CONTENT_HANDLER( + "URL Filtering", + (getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myself_objects.C", + getGWURLFilteringBlade +) +FILE_CONTENT_HANDLER( + "IPSec VPN", + (getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myself_objects.C", + getGWIPSecVPNBlade +) +FILE_CONTENT_HANDLER( + "Version", + (getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myself_objects.C", + getGWVersion +) + #else // !(gaia || smb) FILE_CONTENT_HANDLER("os_release", "/etc/os-release", getOsRelease) #endif // gaia || smb diff --git a/components/security_apps/orchestration/env_details/CMakeLists.txt b/components/security_apps/orchestration/env_details/CMakeLists.txt new file mode 100644 index 0000000..91f3232 --- /dev/null +++ b/components/security_apps/orchestration/env_details/CMakeLists.txt @@ -0,0 +1 @@ +add_library(env_details env_details.cc) diff --git a/components/security_apps/orchestration/env_details/env_details.cc b/components/security_apps/orchestration/env_details/env_details.cc new file mode 100644 index 0000000..10af97b --- /dev/null +++ b/components/security_apps/orchestration/env_details/env_details.cc @@ -0,0 +1,66 @@ +// 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 "env_details.h" + +#include "config.h" +#include "debug.h" + +using namespace std; + +USE_DEBUG_FLAG(D_LOCAL_POLICY); + +static const string k8s_service_account = "/var/run/secrets/kubernetes.io/serviceaccount"; +// LCOV_EXCL_START Reason: can't use on the pipline environment +EnvDetails::EnvDetails() +{ + token = retrieveToken(); + token.empty() ? env_type = EnvType::LINUX : env_type = EnvType::K8S; +} + +EnvType +EnvDetails::getEnvType() +{ + return env_type; +} + +string +EnvDetails::getToken() +{ + return token; +} + +string +EnvDetails::retrieveToken() +{ + return readFileContent(k8s_service_account + "/token"); +} + +string +EnvDetails::readFileContent(const string &file_path) +{ + try { + ifstream file(file_path); + stringstream buffer; + buffer << file.rdbuf(); + return buffer.str(); + } catch (ifstream::failure &f) { + dbgWarning(D_LOCAL_POLICY) + << "Cannot read the file" + << " File: " << file_path + << " Error: " << f.what(); + return ""; + } +} + +// LCOV_EXCL_STOP diff --git a/components/security_apps/orchestration/include/declarative_policy_utils.h b/components/security_apps/orchestration/include/declarative_policy_utils.h index 0f38c4a..1afe87a 100644 --- a/components/security_apps/orchestration/include/declarative_policy_utils.h +++ b/components/security_apps/orchestration/include/declarative_policy_utils.h @@ -22,6 +22,7 @@ #include "i_time_get.h" #include "i_shell_cmd.h" #include "i_encryptor.h" +#include "i_env_details.h" #include "maybe_res.h" #include "event.h" @@ -35,6 +36,7 @@ class DeclarativePolicyUtils : public Singleton::Consume, Singleton::Consume, + Singleton::Consume, Singleton::Consume, Singleton::Consume, Singleton::Consume, diff --git a/components/security_apps/orchestration/include/hybrid_communication.h b/components/security_apps/orchestration/include/hybrid_communication.h index e452354..6e85345 100755 --- a/components/security_apps/orchestration/include/hybrid_communication.h +++ b/components/security_apps/orchestration/include/hybrid_communication.h @@ -40,7 +40,7 @@ class HybridCommunication : public FogAuthenticator, - Singleton::Consume + Singleton::Consume { public: void init() override; diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/CMakeLists.txt b/components/security_apps/orchestration/local_policy_mgmt_gen/CMakeLists.txt index 1ecfeb7..34db07a 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/CMakeLists.txt +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/CMakeLists.txt @@ -1,3 +1,3 @@ include_directories(include) -add_library(local_policy_mgmt_gen appsec_practice_section.cc exceptions_section.cc ingress_data.cc local_policy_mgmt_gen.cc policy_maker_utils.cc rules_config_section.cc settings_section.cc snort_section.cc triggers_section.cc trusted_sources_section.cc) +add_library(local_policy_mgmt_gen appsec_practice_section.cc exceptions_section.cc ingress_data.cc local_policy_mgmt_gen.cc policy_maker_utils.cc rules_config_section.cc settings_section.cc snort_section.cc triggers_section.cc trusted_sources_section.cc k8s_policy_utils.cc namespace_data.cc) diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/appsec_practice_section.cc b/components/security_apps/orchestration/local_policy_mgmt_gen/appsec_practice_section.cc index 3d35fd4..ab8b09f 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/appsec_practice_section.cc +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/appsec_practice_section.cc @@ -17,6 +17,10 @@ using namespace std; USE_DEBUG_FLAG(D_LOCAL_POLICY); // LCOV_EXCL_START Reason: no test exist + +static const set valid_modes = {"prevent-learn", "detect-learn", "prevent", "detect", "inactive"}; +static const set valid_confidences = {"medium", "high", "critical"}; + void AppSecWebBotsURI::load(cereal::JSONInputArchive &archive_in) { @@ -37,6 +41,9 @@ AppSecPracticeAntiBot::load(cereal::JSONInputArchive &archive_in) parseAppsecJSONKey>("injected-URIs", injected_uris, archive_in); parseAppsecJSONKey>("validated-URIs", validated_uris, archive_in); parseAppsecJSONKey("override-mode", override_mode, archive_in, "Inactive"); + if (valid_modes.count(override_mode) == 0) { + dbgWarning(D_LOCAL_POLICY) << "AppSec Web Bots override mode invalid: " << override_mode; + } } void @@ -106,8 +113,17 @@ AppSecPracticeWebAttacks::load(cereal::JSONInputArchive &archive_in) dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec"; parseAppsecJSONKey("protections", protections, archive_in); parseAppsecJSONKey("override-mode", mode, archive_in, "Unset"); + if (valid_modes.count(mode) == 0) { + dbgWarning(D_LOCAL_POLICY) << "AppSec practice override mode invalid: " << mode; + } + if (getMode() == "Prevent") { parseAppsecJSONKey("minimum-confidence", minimum_confidence, archive_in, "critical"); + if (valid_confidences.count(minimum_confidence) == 0) { + dbgWarning(D_LOCAL_POLICY) + << "AppSec practice override minimum confidence invalid: " + << minimum_confidence; + } } else { minimum_confidence = "Transparent"; } @@ -163,6 +179,9 @@ AppSecPracticeSnortSignatures::load(cereal::JSONInputArchive &archive_in) dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Snort Signatures practice"; parseAppsecJSONKey("override-mode", override_mode, archive_in, "Inactive"); parseAppsecJSONKey>("configmap", config_map, archive_in); + if (valid_modes.count(override_mode) == 0) { + dbgWarning(D_LOCAL_POLICY) << "AppSec Snort Signatures override mode invalid: " << override_mode; + } } const string & @@ -180,9 +199,12 @@ AppSecPracticeSnortSignatures::getConfigMap() const void AppSecPracticeOpenSchemaAPI::load(cereal::JSONInputArchive &archive_in) { - dbgTrace(D_LOCAL_POLICY) << "Loading AppSecPracticeOpenSchemaAPI practice"; - parseAppsecJSONKey("override-mode", override_mode, archive_in, "Inactive"); + dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Practice OpenSchemaAPI practice"; parseAppsecJSONKey>("configmap", config_map, archive_in); + parseAppsecJSONKey("override-mode", override_mode, archive_in, "Inactive"); + if (valid_modes.count(override_mode) == 0) { + dbgWarning(D_LOCAL_POLICY) << "AppSec Open Schema API override mode invalid: " << override_mode; + } } const string & @@ -196,7 +218,7 @@ AppSecPracticeOpenSchemaAPI::getConfigMap() const { return config_map; } - +// LCOV_EXCL_STOP void AppSecPracticeSpec::load(cereal::JSONInputArchive &archive_in) { @@ -212,6 +234,13 @@ AppSecPracticeSpec::load(cereal::JSONInputArchive &archive_in) parseAppsecJSONKey("name", practice_name, archive_in); } +void +AppSecPracticeSpec::setName(const string &_name) +{ + practice_name = _name; +} + +// LCOV_EXCL_START Reason: no test exist const AppSecPracticeOpenSchemaAPI & AppSecPracticeSpec::getOpenSchemaValidation() const { @@ -223,6 +252,7 @@ AppSecPracticeSpec::getSnortSignatures() const { return snort_signatures; } +// LCOV_EXCL_STOP const AppSecPracticeWebAttacks & AppSecPracticeSpec::getWebAttacks() const @@ -345,6 +375,9 @@ WebAppSection::save(cereal::JSONOutputArchive &out_ar) const cereal::make_nvp("assetName", asset_name), cereal::make_nvp("ruleId", rule_id), cereal::make_nvp("ruleName", rule_name), + cereal::make_nvp("schemaValidation", false), + cereal::make_nvp("schemaValidation_v2", disabled_str), + cereal::make_nvp("oas", empty_list), cereal::make_nvp("triggers", triggers), cereal::make_nvp("applicationUrls", application_urls), cereal::make_nvp("overrides", overrides), @@ -355,19 +388,7 @@ WebAppSection::save(cereal::JSONOutputArchive &out_ar) const cereal::make_nvp("botProtection_v2", detect_str) ); } - -const string & -WebAppSection::getPracticeId() const -{ - return practice_id; -} - -bool -WebAppSection::operator<(const WebAppSection &other) const -{ - return getPracticeId() < other.getPracticeId(); -} - +// LCOV_EXCL_START Reason: no test exist void WebAPISection::save(cereal::JSONOutputArchive &out_ar) const { @@ -396,12 +417,7 @@ WebAPISection::save(cereal::JSONOutputArchive &out_ar) const cereal::make_nvp("overrides", empty_list) ); } - -const string & -WebAPISection::getPracticeId() const -{ - return practice_id; -} +// LCOV_EXCL_STOP void AppSecRulebase::save(cereal::JSONOutputArchive &out_ar) const @@ -426,6 +442,9 @@ ParsedRule::load(cereal::JSONInputArchive &archive_in) parseAppsecJSONKey>("triggers", log_triggers, archive_in); parseAppsecJSONKey>("practices", practices, archive_in); parseAppsecJSONKey("mode", mode, archive_in); + if (valid_modes.count(mode) == 0) { + dbgWarning(D_LOCAL_POLICY) << "AppSec Parsed Rule mode invalid: " << mode; + } parseAppsecJSONKey("custom-response", custom_response, archive_in); parseAppsecJSONKey("source-identifiers", source_identifiers, archive_in); parseAppsecJSONKey("trusted-sources", trusted_sources, archive_in); @@ -500,11 +519,6 @@ AppsecPolicySpec::load(cereal::JSONInputArchive &archive_in) { dbgTrace(D_LOCAL_POLICY) << "Loading AppSec policy spec"; parseAppsecJSONKey("default", default_rule, archive_in); - auto default_mode_annot = - Singleton::Consume::by()->get("default mode annotation"); - if (default_mode_annot.ok() && !default_mode_annot.unpack().empty() && default_rule.getMode().empty()) { - default_rule.setMode(default_mode_annot.unpack()); - } default_rule.setHost("*"); parseAppsecJSONKey>("specific-rules", specific_rules, archive_in); } @@ -521,6 +535,21 @@ AppsecPolicySpec::getSpecificRules() const return specific_rules; } +bool +AppsecPolicySpec::isAssetHostExist(const std::string &full_url) const +{ + for (const ParsedRule &rule : specific_rules) { + if (rule.getHost() == full_url) return true; + } + return false; +} + +void +AppsecPolicySpec::addSpecificRule(const ParsedRule &_rule) +{ + specific_rules.push_back(_rule); +} + void AppsecLinuxPolicy::serialize(cereal::JSONInputArchive &archive_in) { @@ -580,4 +609,8 @@ AppsecLinuxPolicy::getAppsecSourceIdentifierSpecs() const return sources_identifiers; } -// LCOV_EXCL_STOP +void +AppsecLinuxPolicy::addSpecificRule(const ParsedRule &_rule) +{ + policies.addSpecificRule(_rule); +} diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/exceptions_section.cc b/components/security_apps/orchestration/local_policy_mgmt_gen/exceptions_section.cc index f69e7af..6b6afdb 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/exceptions_section.cc +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/exceptions_section.cc @@ -18,12 +18,18 @@ using namespace std; USE_DEBUG_FLAG(D_LOCAL_POLICY); // LCOV_EXCL_START Reason: no test exist +static const set valid_actions = {"skip", "accept", "drop", "suppressLog"}; + void AppsecExceptionSpec::load(cereal::JSONInputArchive &archive_in) { dbgTrace(D_LOCAL_POLICY) << "Loading AppSec exception spec"; parseAppsecJSONKey("name", name, archive_in); parseAppsecJSONKey("action", action, archive_in); + if (valid_actions.count(action) == 0) { + dbgWarning(D_LOCAL_POLICY) << "AppSec exception action invalid: " << action; + } + parseAppsecJSONKey>("countryCode", country_code, archive_in); parseAppsecJSONKey>("countryName", country_name, archive_in); parseAppsecJSONKey>("hostName", host_name, archive_in); @@ -35,6 +41,12 @@ AppsecExceptionSpec::load(cereal::JSONInputArchive &archive_in) parseAppsecJSONKey>("url", url, archive_in); } +void +AppsecExceptionSpec::setName(const string &_name) +{ + name = _name; +} + const string & AppsecExceptionSpec::getName() const { @@ -209,12 +221,6 @@ InnerException::getBehaviorId() const return behavior.getBehaviorId(); } -bool -InnerException::operator<(const InnerException &other) const -{ - return getBehaviorId() < other.getBehaviorId(); -} - ExceptionsRulebase::ExceptionsRulebase( vector _exceptions) : @@ -251,5 +257,3 @@ ExceptionsWrapper::save(cereal::JSONOutputArchive &out_ar) const cereal::make_nvp("rulebase", exception_rulebase) ); } - -// LCOV_EXCL_STOP diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/include/appsec_practice_section.h b/components/security_apps/orchestration/local_policy_mgmt_gen/include/appsec_practice_section.h index 1f8eabc..d9e7c2b 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/include/appsec_practice_section.h +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/include/appsec_practice_section.h @@ -24,12 +24,11 @@ #include "config.h" #include "debug.h" #include "customized_cereal_map.h" -#include "k8s_policy_common.h" +#include "local_policy_common.h" #include "triggers_section.h" #include "exceptions_section.h" #include "trusted_sources_section.h" -// LCOV_EXCL_START Reason: no test exist class AppSecWebBotsURI { public: @@ -129,6 +128,7 @@ public: const AppSecPracticeWebAttacks & getWebAttacks() const; const AppSecPracticeAntiBot & getAntiBot() const; const std::string & getName() const; + void setName(const std::string &_name); private: AppSecPracticeOpenSchemaAPI openapi_schema_validation; @@ -214,8 +214,6 @@ public: ); void save(cereal::JSONOutputArchive &out_ar) const; - const std::string & getPracticeId() const; - bool operator<(const WebAppSection &other) const; private: std::string application_urls; @@ -271,8 +269,6 @@ public: void save(cereal::JSONOutputArchive &out_ar) const; - const std::string & getPracticeId() const; - private: std::string application_urls; std::string asset_id; @@ -323,8 +319,10 @@ private: class ParsedRule { public: - void load(cereal::JSONInputArchive &archive_in); + ParsedRule() {} + ParsedRule(const std::string &_host) : host(_host) {} + void load(cereal::JSONInputArchive &archive_in); const std::vector & getExceptions() const; const std::vector & getLogTriggers() const; const std::vector & getPractices() const; @@ -354,6 +352,8 @@ public: const ParsedRule & getDefaultRule() const; const std::vector & getSpecificRules() const; + bool isAssetHostExist(const std::string &full_url) const; + void addSpecificRule(const ParsedRule &_rule); private: ParsedRule default_rule; @@ -363,8 +363,25 @@ private: class AppsecLinuxPolicy : Singleton::Consume { public: - void - serialize(cereal::JSONInputArchive &archive_in); + AppsecLinuxPolicy() {} + AppsecLinuxPolicy( + const AppsecPolicySpec &_policies, + const std::vector &_practices, + const std::vector &_log_triggers, + const std::vector &_custom_responses, + const std::vector &_exceptions, + const std::vector &_trusted_sources, + const std::vector &_sources_identifiers) + : + policies(_policies), + practices(_practices), + log_triggers(_log_triggers), + custom_responses(_custom_responses), + exceptions(_exceptions), + trusted_sources(_trusted_sources), + sources_identifiers(_sources_identifiers) {} + + void serialize(cereal::JSONInputArchive &archive_in); const AppsecPolicySpec & getAppsecPolicySpec() const; const std::vector & getAppSecPracticeSpecs() const; @@ -373,6 +390,7 @@ public: const std::vector & getAppsecExceptionSpecs() const; const std::vector & getAppsecTrustedSourceSpecs() const; const std::vector & getAppsecSourceIdentifierSpecs() const; + void addSpecificRule(const ParsedRule &_rule); private: AppsecPolicySpec policies; @@ -384,5 +402,4 @@ private: std::vector sources_identifiers; }; -// LCOV_EXCL_STOP #endif // __APPSEC_PRACTICE_SECTION_H__ diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/include/exceptions_section.h b/components/security_apps/orchestration/local_policy_mgmt_gen/include/exceptions_section.h index dcc4143..329bb4b 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/include/exceptions_section.h +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/include/exceptions_section.h @@ -23,9 +23,8 @@ #include "config.h" #include "debug.h" #include "rest.h" -#include "k8s_policy_common.h" +#include "local_policy_common.h" -// LCOV_EXCL_START Reason: no test exist class AppsecExceptionSpec { public: @@ -42,6 +41,7 @@ public: const std::vector & getSourceIdentifier() const; const std::vector & getSourceIp() const; const std::vector & getUrl() const; + void setName(const std::string &_name); private: std::string name; @@ -111,7 +111,6 @@ public: void save(cereal::JSONOutputArchive &out_ar) const; const std::string getBehaviorId() const; - bool operator<(const InnerException &other) const; private: ExceptionBehavior behavior; @@ -150,5 +149,4 @@ public: private: Exception exception_rulebase; }; -// LCOV_EXCL_STOP #endif // __EXCEPTPIONS_SECTION_H__ diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/include/ingress_data.h b/components/security_apps/orchestration/local_policy_mgmt_gen/include/ingress_data.h index b51a118..16d7e78 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/include/ingress_data.h +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/include/ingress_data.h @@ -22,18 +22,15 @@ #include "rest.h" #include "cereal/archives/json.hpp" #include +#include "customized_cereal_map.h" -#include "k8s_policy_common.h" +#include "local_policy_common.h" -// LCOV_EXCL_START Reason: no test exist class IngressMetadata { public: void load(cereal::JSONInputArchive &archive_in); - const std::string & getName() const; - const std::string & getResourceVersion() const; - const std::string & getNamespace() const; const std::map & getAnnotations() const; private: @@ -46,8 +43,7 @@ private: class IngressRulePath { public: - void - load(cereal::JSONInputArchive &archive_in); + void load(cereal::JSONInputArchive &archive_in); const std::string & getPath() const; @@ -55,13 +51,6 @@ private: std::string path; }; -inline std::ostream & -operator<<(std::ostream &os, const IngressRulePath &obj) -{ - os << obj.getPath(); - return os; -} - class IngressRulePathsWrapper { public: @@ -86,25 +75,10 @@ private: IngressRulePathsWrapper paths_wrapper; }; -inline std::ostream & -operator<<(std::ostream &os, const IngressDefinedRule &obj) -{ - os - << "host: " - << obj.getHost() - << ", paths: [" << std::endl - << makeSeparatedStr(obj.getPathsWrapper().getRulePaths(), ",") - << std::endl << "]"; - return os; -} - class DefaultBackend { public: - void - load(cereal::JSONInputArchive &); - - bool isExists() const; + void load(cereal::JSONInputArchive &); private: bool is_exists = false; @@ -113,12 +87,9 @@ private: class IngressSpec { public: - void - load(cereal::JSONInputArchive &archive_in); + void load(cereal::JSONInputArchive &archive_in); - const std::string & getIngressClassName() const; const std::vector & getRules() const; - bool isDefaultBackendExists() const; private: std::string ingress_class_name; @@ -129,8 +100,7 @@ private: class SingleIngressData { public: - void - load(cereal::JSONInputArchive &archive_in); + void load(cereal::JSONInputArchive &archive_in); const IngressMetadata & getMetadata() const; const IngressSpec & getSpec() const; @@ -146,12 +116,10 @@ class IngressData : public ClientRest public: bool loadJson(const std::string &json); - const std::string & getapiVersion() const; const std::vector & getItems() const; private: std::string apiVersion; std::vector items; }; -// LCOV_EXCL_STOP #endif // __INGRESS_DATA_H__ diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/include/k8s_policy_utils.h b/components/security_apps/orchestration/local_policy_mgmt_gen/include/k8s_policy_utils.h new file mode 100644 index 0000000..a63a7ea --- /dev/null +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/include/k8s_policy_utils.h @@ -0,0 +1,81 @@ +// 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 __K8S_POLICY_UTILS_H__ +#define __K8S_POLICY_UTILS_H__ + +#include +#include +#include +#include + +#include + +#include "maybe_res.h" +#include "i_orchestration_tools.h" +#include "i_shell_cmd.h" +#include "i_messaging.h" +#include "i_env_details.h" +#include "i_agent_details.h" +#include "appsec_practice_section.h" +#include "policy_maker_utils.h" + +enum class AnnotationKeys { PolicyKey, OpenAppsecIo, SyslogAddressKey, SyslogPortKey, ModeKey }; + +class K8sPolicyUtils + : + Singleton::Consume, + Singleton::Consume, + Singleton::Consume, + Singleton::Consume, + Singleton::Consume, + Singleton::Consume +{ +public: + void init(); + + std::map createAppsecPoliciesFromIngresses(); + bool getClusterId() const; + +private: + std::map parseIngressAnnotations( + const std::map &annotations + ) const; + + template + Maybe getObjectFromCluster(const std::string &path) const; + + std::map> extractElementsNames( + const std::vector &specific_rules, + const ParsedRule &default_rule + ) const; + + template + std::vector extractElementsFromCluster( + const std::string &crd_plural, + const std::unordered_set &elements_names + ) const; + + Maybe createAppsecPolicyK8s( + const std::string &policy_name, + const std::string &ingress_mode + ) const; + + I_EnvDetails* env_details = nullptr; + I_Messaging* messaging = nullptr; + EnvType env_type; + Flags conn_flags; + std::string token; +}; + +#endif // __K8S_POLICY_UTILS_H__ diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/include/local_policy_common.h b/components/security_apps/orchestration/local_policy_mgmt_gen/include/local_policy_common.h new file mode 100644 index 0000000..9ee5819 --- /dev/null +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/include/local_policy_common.h @@ -0,0 +1,112 @@ +// 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 __LOCAL_POLICY_COMMON_H__ +#define __LOCAL_POLICY_COMMON_H__ + +#include +#include +#include +#include + +#include "config.h" +#include "debug.h" +#include "rest.h" + +USE_DEBUG_FLAG(D_LOCAL_POLICY); + +enum class PracticeType { WebApplication, WebAPI }; +enum class TriggerType { Log, WebUserResponse }; +enum class MatchType { Condition, Operator }; + +static const std::unordered_map string_to_match_type = { + { "condition", MatchType::Condition }, + { "operator", MatchType::Operator } +}; + +static const std::unordered_map string_to_practice_type = { + { "WebApplication", PracticeType::WebApplication }, + { "WebAPI", PracticeType::WebAPI } +}; + +static const std::unordered_map string_to_trigger_type = { + { "log", TriggerType::Log }, + { "WebUserResponse", TriggerType::WebUserResponse } +}; + +static const std::unordered_map key_to_practices_val = { + { "prevent-learn", "Prevent"}, + { "detect-learn", "Detect"}, + { "prevent", "Prevent"}, + { "detect", "Detect"}, + { "inactive", "Inactive"} +}; + +template +void +parseAppsecJSONKey( + const std::string &key_name, + T &value, + cereal::JSONInputArchive &archive_in, + const T &default_value = T()) +{ + try { + archive_in(cereal::make_nvp(key_name, value)); + } catch (const cereal::Exception &e) { + archive_in.setNextName(nullptr); + value = default_value; + dbgDebug(D_LOCAL_POLICY) + << "Could not parse the required key. Key: " + << key_name + << ", Error: " + << e.what(); + } +} + +template +class AppsecSpecParser : public ClientRest +{ +public: + AppsecSpecParser() = default; + AppsecSpecParser(const T &_spec) : spec(_spec) {} + + bool + loadJson(const std::string &json) + { + std::string modified_json = json; + modified_json.pop_back(); + std::stringstream ss; + ss.str(modified_json); + try { + cereal::JSONInputArchive in_ar(ss); + in_ar(cereal::make_nvp("spec", spec)); + } catch (cereal::Exception &e) { + dbgWarning(D_LOCAL_POLICY) << "Failed to load spec JSON. Error: " << e.what(); + return false; + } + return true; + } + + void + setName(const std::string &_name) + { + spec.setName(_name); + } + + const T & getSpec() const { return spec; } + +private: + T spec; +}; + +#endif // __LOCAL_POLICY_COMMON_H__ diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/include/namespace_data.h b/components/security_apps/orchestration/local_policy_mgmt_gen/include/namespace_data.h new file mode 100644 index 0000000..a895467 --- /dev/null +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/include/namespace_data.h @@ -0,0 +1,35 @@ +// 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 __NAMESPACE_DATA_H__ +#define __NAMESPACE_DATA_H__ + +#include +#include + +#include "cereal/archives/json.hpp" +#include + +#include "rest.h" + +class NamespaceData : public ClientRest +{ +public: + bool loadJson(const std::string &json); + Maybe getNamespaceUidByName(const std::string &name); + +private: + std::map ns_name_to_uid; +}; + +#endif // __NAMESPACE_DATA_H__ diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/include/policy_maker_utils.h b/components/security_apps/orchestration/local_policy_mgmt_gen/include/policy_maker_utils.h index 511587f..9dbc856 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/include/policy_maker_utils.h +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/include/policy_maker_utils.h @@ -29,17 +29,16 @@ #include "maybe_res.h" #include "i_orchestration_tools.h" #include "i_shell_cmd.h" +#include "i_messaging.h" #include "appsec_practice_section.h" #include "ingress_data.h" #include "settings_section.h" #include "triggers_section.h" -#include "k8s_policy_common.h" +#include "local_policy_common.h" #include "exceptions_section.h" #include "rules_config_section.h" #include "trusted_sources_section.h" -USE_DEBUG_FLAG(D_NGINX_POLICY); - enum class AnnotationTypes { PRACTICE, TRIGGER, @@ -50,7 +49,6 @@ enum class AnnotationTypes { COUNT }; -// LCOV_EXCL_START Reason: no test exist class SecurityAppsWrapper { public: @@ -93,11 +91,11 @@ private: SettingsWrapper settings; SecurityAppsWrapper security_apps; }; -// LCOV_EXCL_STOP class PolicyMakerUtils : Singleton::Consume, Singleton::Consume, + Singleton::Consume, Singleton::Consume { public: @@ -113,7 +111,7 @@ public: std::tuple splitHostName(const std::string &host_name); - std::string dumpPolicyToFile(const PolicyWrapper &policy, const std::string &policy_path) const; + std::string dumpPolicyToFile(const PolicyWrapper &policy, const std::string &policy_path); PolicyWrapper combineElementsToPolicy(const std::string &policy_version); diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/include/rules_config_section.h b/components/security_apps/orchestration/local_policy_mgmt_gen/include/rules_config_section.h index cabe95a..16e9507 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/include/rules_config_section.h +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/include/rules_config_section.h @@ -23,9 +23,8 @@ #include "config.h" #include "debug.h" -#include "k8s_policy_common.h" +#include "local_policy_common.h" -// LCOV_EXCL_START Reason: no test exist class AssetUrlParser { public: @@ -41,13 +40,11 @@ public: PracticeSection( const std::string &_id, const std::string &_type, - const std::string &_practice_name); + const std::string &_practice_name + ); void save(cereal::JSONOutputArchive &out_ar) const; - const std::string & getPracticeId() const; - const std::string & getPracticeName() const; - private: std::string id; std::string name; @@ -60,7 +57,6 @@ public: ParametersSection(const std::string &_id, const std::string &_name); void save(cereal::JSONOutputArchive &out_ar) const; - const std::string & getId() const; private: std::string name; @@ -74,13 +70,11 @@ public: RulesTriggerSection( const std::string &_name, const std::string &_id, - const std::string &_type); + const std::string &_type + ); void save(cereal::JSONOutputArchive &out_ar) const; - const std::string & getId() const; - const std::string & getName() const; - private: std::string name; std::string id; @@ -99,20 +93,14 @@ public: const std::string &_uri, std::vector _practices, std::vector _parameters, - std::vector _triggers); + std::vector _triggers + ); void save(cereal::JSONOutputArchive &out_ar) const; - const std::string & getRuleId() const; const std::string & getAssetName() const; - const std::string & getRuleName() const; const std::string & getAssetId() const; - const std::string & getPracticeId() const; - const std::string & getPracticeName() const; const std::string & getContext() const; - const std::vector & getPractice() const; - const std::vector & getParameters() const; - const std::vector & getTriggers() const; private: std::string context; @@ -130,7 +118,8 @@ public: UsersIdentifier( const std::string &_source_identifier, - std::vector _identifier_values); + std::vector _identifier_values + ); void save(cereal::JSONOutputArchive &out_ar) const; @@ -148,8 +137,9 @@ public: UsersIdentifiersRulebase( const std::string &_context, const std::string &_source_identifier, - std::vector _identifier_values, - std::vector _source_identifiers); + const std::vector &_identifier_values, + const std::vector &_source_identifiers + ); void save(cereal::JSONOutputArchive &out_ar) const; @@ -165,7 +155,8 @@ class RulesRulebase public: RulesRulebase( const std::vector &_rules_config, - const std::vector &_users_identifiers); + const std::vector &_users_identifiers + ); void save(cereal::JSONOutputArchive &out_ar) const; @@ -192,5 +183,4 @@ public: private: RulesRulebase rules_config_rulebase; }; -// LCOV_EXCL_STOP #endif // __RULES_CONFIG_SECTION_H__ diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/include/settings_section.h b/components/security_apps/orchestration/local_policy_mgmt_gen/include/settings_section.h index d782118..ebbfaee 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/include/settings_section.h +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/include/settings_section.h @@ -21,7 +21,7 @@ #include "config.h" #include "debug.h" -#include "k8s_policy_common.h" +#include "local_policy_common.h" // LCOV_EXCL_START Reason: no test exist class AgentSettingsSection diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/include/triggers_section.h b/components/security_apps/orchestration/local_policy_mgmt_gen/include/triggers_section.h index 9bbf37c..e7ccea9 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/include/triggers_section.h +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/include/triggers_section.h @@ -21,9 +21,8 @@ #include "config.h" #include "debug.h" -#include "k8s_policy_common.h" +#include "local_policy_common.h" -// LCOV_EXCL_START Reason: no test exist class LogTriggerSection { public: @@ -58,7 +57,6 @@ public: const std::string & getTriggerId() const; const std::string & getTriggerName() const; - bool operator<(const LogTriggerSection &other) const; private: std::string id; @@ -102,9 +100,6 @@ public: void save(cereal::JSONOutputArchive &out_ar) const; const std::string & getTriggerId() const; - const std::string & getTriggerName() const; - - bool operator<(const WebUserResponseTriggerSection &other) const; private: std::string id; @@ -126,6 +121,7 @@ public: const std::string & getMessageTitle() const; const std::string & getMode() const; const std::string & getName() const; + void setName(const std::string &_name); private: int httpResponseCode; @@ -158,9 +154,6 @@ class AppsecTriggerAccessControlLogging public: void load(cereal::JSONInputArchive &archive_in); - bool isAllowEvents() const; - bool isDropEvents() const; - private: bool allow_events = false; bool drop_events = false; @@ -220,7 +213,6 @@ public: void load(cereal::JSONInputArchive &archive_in); const std::string & getAddress() const; - const std::string & getProto() const; int getPort() const; private: @@ -273,8 +265,8 @@ class AppsecTriggerSpec public: void load(cereal::JSONInputArchive &archive_in); - const AppsecTriggerAccessControlLogging & getAppsecTriggerAccessControlLogging() const; const std::string & getName() const; + void setName(const std::string &_name); const AppsecTriggerAdditionalSuspiciousEventsLogging & getAppsecTriggerAdditionalSuspiciousEventsLogging() const; const AppsecTriggerLogging & getAppsecTriggerLogging() const; const AppsecTriggerExtendedLogging & getAppsecTriggerExtendedLogging() const; @@ -300,5 +292,4 @@ public: private: TriggersRulebase triggers_rulebase; }; -// LCOV_EXCL_STOP #endif // __TRIGGERS_SECTION_H__ diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/include/trusted_sources_section.h b/components/security_apps/orchestration/local_policy_mgmt_gen/include/trusted_sources_section.h index 1cb0901..09f1dcc 100755 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/include/trusted_sources_section.h +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/include/trusted_sources_section.h @@ -22,9 +22,8 @@ #include "config.h" #include "debug.h" -#include "k8s_policy_common.h" +#include "local_policy_common.h" -// LCOV_EXCL_START Reason: no test exist class TrustedSourcesSpec { public: @@ -33,6 +32,7 @@ public: int getMinNumOfSources() const; const std::vector & getSourcesIdentifiers() const; const std::string & getName() const; + void setName(const std::string &_name); private: int min_num_of_sources = 0; @@ -77,6 +77,7 @@ public: const std::string & getName() const; const std::vector & getIdentifiers() const; + void setName(const std::string &_name); private: std::string name; @@ -104,5 +105,4 @@ private: int num_of_sources = 0; std::vector sources_identifiers; }; -// LCOV_EXCL_STOP #endif // __TRUSTED_SOURCES_SECTION_H__ diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/ingress_data.cc b/components/security_apps/orchestration/local_policy_mgmt_gen/ingress_data.cc index 0eea593..8be6f1d 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/ingress_data.cc +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/ingress_data.cc @@ -17,7 +17,6 @@ using namespace std; USE_DEBUG_FLAG(D_LOCAL_POLICY); -// LCOV_EXCL_START Reason: no test exist void IngressMetadata::load(cereal::JSONInputArchive &archive_in) { @@ -28,24 +27,6 @@ IngressMetadata::load(cereal::JSONInputArchive &archive_in) parseAppsecJSONKey>("annotations", annotations, archive_in); } -const string & -IngressMetadata::getName() const -{ - return name; -} - -const string & -IngressMetadata::getResourceVersion() const -{ - return resourceVersion; -} - -const string & -IngressMetadata::getNamespace() const -{ - return namespace_name; -} - const map & IngressMetadata::getAnnotations() const { @@ -105,12 +86,6 @@ DefaultBackend::load(cereal::JSONInputArchive &) is_exists = true; } -bool -DefaultBackend::isExists() const -{ - return is_exists; -} - void IngressSpec::load(cereal::JSONInputArchive &archive_in) { @@ -120,22 +95,11 @@ IngressSpec::load(cereal::JSONInputArchive &archive_in) parseAppsecJSONKey("defaultBackend", default_backend, archive_in); } -const string & -IngressSpec::getIngressClassName() const -{ - return ingress_class_name; -} - const vector & IngressSpec::getRules() const { return rules; } -bool -IngressSpec::isDefaultBackendExists() const -{ - return default_backend.isExists(); -} void SingleIngressData::load(cereal::JSONInputArchive &archive_in) @@ -178,15 +142,8 @@ IngressData::loadJson(const string &json) return true; } -const string & -IngressData::getapiVersion() const -{ - return apiVersion; -} - const vector & IngressData::getItems() const { return items; } -// LCOV_EXCL_STOP diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/k8s_policy_utils.cc b/components/security_apps/orchestration/local_policy_mgmt_gen/k8s_policy_utils.cc new file mode 100644 index 0000000..f8860e3 --- /dev/null +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/k8s_policy_utils.cc @@ -0,0 +1,343 @@ +// 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 "k8s_policy_utils.h" +#include "namespace_data.h" + +using namespace std; + +USE_DEBUG_FLAG(D_NGINX_POLICY); + +string +convertAnnotationKeysTostring(const AnnotationKeys &key) +{ + switch (key) { + case AnnotationKeys::PolicyKey: + return "policy"; + case AnnotationKeys::OpenAppsecIo: + return "openappsec.io/"; + case AnnotationKeys::SyslogAddressKey: + return "syslog"; + case AnnotationKeys::ModeKey: + return "mode"; + default: + return "Irrelevant key"; + } +} + +void +K8sPolicyUtils::init() +{ + env_details = Singleton::Consume::by(); + env_type = env_details->getEnvType(); + if (env_type == EnvType::K8S) { + token = env_details->getToken(); + messaging = Singleton::Consume::by(); + conn_flags.setFlag(MessageConnConfig::SECURE_CONN); + conn_flags.setFlag(MessageConnConfig::IGNORE_SSL_VALIDATION); + } +} + +map +K8sPolicyUtils::parseIngressAnnotations(const map &annotations) const +{ + map annotations_values; + for (const pair &annotation : annotations) { + string annotation_key = annotation.first; + string annotation_val = annotation.second; + if (annotation_key.find(convertAnnotationKeysTostring(AnnotationKeys::OpenAppsecIo)) != string::npos) { + if (annotation_key.find(convertAnnotationKeysTostring(AnnotationKeys::PolicyKey)) != string::npos) { + annotations_values[AnnotationKeys::PolicyKey] = annotation_val; + } else if ( + annotation_key.find(convertAnnotationKeysTostring(AnnotationKeys::SyslogAddressKey)) != string::npos + ) { + bool has_port = annotation_val.find(":"); + annotations_values[AnnotationKeys::SyslogAddressKey] = + annotation_val.substr(0, annotation_val.find(":")); + annotations_values[AnnotationKeys::SyslogPortKey] = + has_port ? annotation_val.substr(annotation_val.find(":") + 1) : ""; + } else if (annotation_key.find(convertAnnotationKeysTostring(AnnotationKeys::ModeKey)) != string::npos) { + annotations_values[AnnotationKeys::ModeKey] = annotation_val; + } + } + } + return annotations_values; +} + +template +Maybe +K8sPolicyUtils::getObjectFromCluster(const string &path) const +{ + T object; + bool res = messaging->sendObject( + object, + I_Messaging::Method::GET, + "kubernetes.default.svc", + 443, + conn_flags, + path, + "Authorization: Bearer " + token + "\nConnection: close" + ); + + if (res) return object; + + return genError(string("Was not able to get object form k8s cluser in path: " + path)); +} + +map> +K8sPolicyUtils::extractElementsNames(const vector &specific_rules, const ParsedRule &default_rule) const +{ + map> policy_elements_names; + for (const ParsedRule &specific_rule : specific_rules) { + policy_elements_names[AnnotationTypes::EXCEPTION].insert( + specific_rule.getExceptions().begin(), + specific_rule.getExceptions().end() + ); + policy_elements_names[AnnotationTypes::PRACTICE].insert( + specific_rule.getPractices().begin(), + specific_rule.getPractices().end() + ); + policy_elements_names[AnnotationTypes::TRIGGER].insert( + specific_rule.getLogTriggers().begin(), + specific_rule.getLogTriggers().end() + ); + policy_elements_names[AnnotationTypes::WEB_USER_RES].insert(specific_rule.getCustomResponse()); + policy_elements_names[AnnotationTypes::SOURCE_IDENTIFIERS].insert(specific_rule.getSourceIdentifiers()); + policy_elements_names[AnnotationTypes::TRUSTED_SOURCES].insert(specific_rule.getTrustedSources()); + } + policy_elements_names[AnnotationTypes::EXCEPTION].insert( + default_rule.getExceptions().begin(), + default_rule.getExceptions().end() + ); + policy_elements_names[AnnotationTypes::PRACTICE].insert( + default_rule.getPractices().begin(), + default_rule.getPractices().end() + ); + policy_elements_names[AnnotationTypes::TRIGGER].insert( + default_rule.getLogTriggers().begin(), + default_rule.getLogTriggers().end() + ); + policy_elements_names[AnnotationTypes::WEB_USER_RES].insert(default_rule.getCustomResponse()); + policy_elements_names[AnnotationTypes::SOURCE_IDENTIFIERS].insert(default_rule.getSourceIdentifiers()); + policy_elements_names[AnnotationTypes::TRUSTED_SOURCES].insert(default_rule.getTrustedSources()); + + return policy_elements_names; +} + +template +vector +K8sPolicyUtils::extractElementsFromCluster( + const string &crd_plural, + const unordered_set &elements_names) const +{ + dbgTrace(D_LOCAL_POLICY) << "Retrieve AppSec elements. type: " << crd_plural; + vector elements; + for (const string &element_name : elements_names) { + dbgTrace(D_LOCAL_POLICY) << "AppSec element name: " << element_name; + auto maybe_appsec_element = getObjectFromCluster>( + "/apis/openappsec.io/v1beta1/" + crd_plural + "/" + element_name + ); + + if (!maybe_appsec_element.ok()) { + dbgWarning(D_LOCAL_POLICY) + << "Failed to retrieve AppSec element. type: " + << crd_plural + << ", name: " + << element_name + << ". Error: " + << maybe_appsec_element.getErr(); + continue; + } + + AppsecSpecParser appsec_element = maybe_appsec_element.unpack(); + if (appsec_element.getSpec().getName() == "") { + appsec_element.setName(element_name); + } + elements.push_back(appsec_element.getSpec()); + } + return elements; +} + +Maybe +K8sPolicyUtils::createAppsecPolicyK8s(const string &policy_name, const string &ingress_mode) const +{ + auto maybe_appsec_policy_spec = getObjectFromCluster>( + "/apis/openappsec.io/v1beta1/policies/" + policy_name + ); + if (!maybe_appsec_policy_spec.ok()) { + dbgWarning(D_LOCAL_POLICY) + << "Failed to retrieve AppSec policy. Error: " + << maybe_appsec_policy_spec.getErr(); + return genError("Failed to retrieve AppSec policy. Error: " + maybe_appsec_policy_spec.getErr()); + } + AppsecSpecParser appsec_policy_spec = maybe_appsec_policy_spec.unpack(); + ParsedRule default_rule = appsec_policy_spec.getSpec().getDefaultRule(); + vector specific_rules = appsec_policy_spec.getSpec().getSpecificRules(); + + if (!ingress_mode.empty() && default_rule.getMode().empty()) { + default_rule.setMode(ingress_mode); + } + + map> policy_elements_names = extractElementsNames( + specific_rules, + default_rule + ); + + + vector practices = extractElementsFromCluster( + "practices", + policy_elements_names[AnnotationTypes::PRACTICE] + ); + + vector log_triggers = extractElementsFromCluster( + "logtriggers", + policy_elements_names[AnnotationTypes::TRIGGER] + ); + + vector web_user_responses = extractElementsFromCluster( + "customresponses", + policy_elements_names[AnnotationTypes::WEB_USER_RES] + ); + + vector exceptions = extractElementsFromCluster( + "exceptions", + policy_elements_names[AnnotationTypes::EXCEPTION] + ); + + vector source_identifiers = extractElementsFromCluster( + "sourcesidentifiers", + policy_elements_names[AnnotationTypes::SOURCE_IDENTIFIERS] + ); + + vector trusted_sources = extractElementsFromCluster( + "trustedsources", + policy_elements_names[AnnotationTypes::TRUSTED_SOURCES] + ); + + AppsecLinuxPolicy appsec_policy = AppsecLinuxPolicy( + appsec_policy_spec.getSpec(), + practices, + log_triggers, + web_user_responses, + exceptions, + trusted_sources, + source_identifiers + ); + return appsec_policy; +} + +map +K8sPolicyUtils::createAppsecPoliciesFromIngresses() +{ + dbgFlow(D_LOCAL_POLICY) << "Getting all policy object from Ingresses"; + map policies; + auto maybe_ingress = getObjectFromCluster("/apis/networking.k8s.io/v1/ingresses"); + + if (!maybe_ingress.ok()) { + // TBD: Error handling : INXT-31444 + dbgWarning(D_LOCAL_POLICY) + << "Failed to retrieve K8S Ingress configurations. Error: " + << maybe_ingress.getErr(); + return policies; + } + + IngressData ingress = maybe_ingress.unpack(); + for (const SingleIngressData &item : ingress.getItems()) { + map annotations_values = parseIngressAnnotations( + item.getMetadata().getAnnotations() + ); + + if (annotations_values[AnnotationKeys::PolicyKey].empty()) { + dbgInfo(D_LOCAL_POLICY) << "No policy was found in this ingress"; + continue; + } + + Maybe maybe_appsec_policy = createAppsecPolicyK8s( + annotations_values[AnnotationKeys::PolicyKey], + annotations_values[AnnotationKeys::ModeKey] + ); + if (!maybe_appsec_policy.ok()) { + dbgWarning(D_LOCAL_POLICY) + << "Failed to create appsec policy. Error: " + << maybe_appsec_policy.getErr(); + continue; + } + + AppsecLinuxPolicy appsec_policy = maybe_appsec_policy.unpack(); + for (const IngressDefinedRule &rule : item.getSpec().getRules()) { + string url = rule.getHost(); + for (const IngressRulePath &uri : rule.getPathsWrapper().getRulePaths()) { + if (!appsec_policy.getAppsecPolicySpec().isAssetHostExist(url + uri.getPath())) { + dbgTrace(D_LOCAL_POLICY) + << "Inserting Host data to the specific asset set:" + << "URL: '" + << url + << "' uri: '" + << uri.getPath() + << "'"; + ParsedRule ingress_rule = ParsedRule(url + uri.getPath()); + appsec_policy.addSpecificRule(ingress_rule); + } + } + } + policies[annotations_values[AnnotationKeys::PolicyKey]] = appsec_policy; + } + return policies; +} + +bool +isPlaygroundEnv() +{ + const char *env_string = getenv("PLAYGROUND"); + + if (env_string == nullptr) return false; + string env_value = env_string; + transform(env_value.begin(), env_value.end(), env_value.begin(), ::tolower); + + return env_value == "true"; +} + +bool +K8sPolicyUtils::getClusterId() const +{ + string playground_uid = isPlaygroundEnv() ? "playground-" : ""; + + dbgTrace(D_LOCAL_POLICY) << "Getting cluster UID"; + auto maybe_namespaces_data = getObjectFromCluster("/api/v1/namespaces/"); + + if (!maybe_namespaces_data.ok()) { + dbgWarning(D_LOCAL_POLICY) + << "Failed to retrieve K8S namespace data. Error: " + << maybe_namespaces_data.getErr(); + return false; + } + + NamespaceData namespaces_data = maybe_namespaces_data.unpack(); + + Maybe maybe_ns_uid = namespaces_data.getNamespaceUidByName("kube-system"); + if (!maybe_ns_uid.ok()) { + dbgWarning(D_LOCAL_POLICY) << maybe_ns_uid.getErr(); + return false; + } + string uid = playground_uid + maybe_ns_uid.unpack(); + dbgTrace(D_LOCAL_POLICY) << "Found k8s cluster UID: " << uid; + I_Environment *env = Singleton::Consume::by(); + env->getConfigurationContext().registerValue( + "k8sClusterId", + uid, + EnvKeyAttr::LogSection::SOURCE + ); + I_AgentDetails *i_agent_details = Singleton::Consume::by(); + i_agent_details->setClusterId(uid); + return true; +} diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/local_policy_mgmt_gen.cc b/components/security_apps/orchestration/local_policy_mgmt_gen/local_policy_mgmt_gen.cc index fd1521e..aec2403 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/local_policy_mgmt_gen.cc +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/local_policy_mgmt_gen.cc @@ -32,19 +32,19 @@ #include "config.h" #include "connkey.h" #include "url_parser.h" -#include "i_messaging.h" #include "i_agent_details.h" -#include "i_shell_cmd.h" #include "customized_cereal_map.h" #include "include/appsec_practice_section.h" #include "include/ingress_data.h" #include "include/settings_section.h" #include "include/triggers_section.h" -#include "include/k8s_policy_common.h" +#include "include/local_policy_common.h" #include "include/exceptions_section.h" #include "include/rules_config_section.h" #include "include/trusted_sources_section.h" #include "include/policy_maker_utils.h" +#include "include/k8s_policy_utils.h" +#include "i_env_details.h" using namespace std; @@ -56,105 +56,34 @@ const static string policy_key = "policy"; const static string syslog_key = "syslog"; const static string mode_key = "mode"; const static string local_mgmt_policy_path = "/conf/local_policy.yaml"; -// LCOV_EXCL_START Reason: no test exist - -class NamespaceMetadata -{ -public: - void - load(cereal::JSONInputArchive &archive_in) - { - dbgInfo(D_LOCAL_POLICY) << "NamespaceMetadata load"; - parseAppsecJSONKey("name", name, archive_in); - parseAppsecJSONKey("uid", uid, archive_in); - } - - const string & getName() const { return name; } - const string & getUID() const { return uid; } - -private: - string name; - string uid; -}; - -class SingleNamespaceData -{ -public: - void - load(cereal::JSONInputArchive &archive_in) - { - parseAppsecJSONKey("metadata", metadata, archive_in); - } - - const NamespaceMetadata & getMetadata() const { return metadata; } - -private: - NamespaceMetadata metadata; -}; - -class NamespaceData : public ClientRest -{ -public: - bool - loadJson(const string &json) - { - dbgTrace(D_LOCAL_POLICY) << "Loading namespace data"; - string modified_json = json; - modified_json.pop_back(); - stringstream in; - in.str(modified_json); - try { - cereal::JSONInputArchive in_ar(in); - in_ar( - cereal::make_nvp("items", items) - ); - } catch (cereal::Exception &e) { - dbgError(D_LOCAL_POLICY) << "Failed to load namespace data JSON. Error: " << e.what(); - return false; - } - return true; - } - - const vector & getItems() const { return items; } - -private: - vector items; -}; +// LCOV_EXCL_STOP class LocalPolicyMgmtGenerator::Impl : public Singleton::Provide::From, - public Singleton::Consume, - public Singleton::Consume, - public Singleton::Consume, public Singleton::Consume, - public Singleton::Consume, - public Singleton::Consume + public Singleton::Consume { + public: +// LCOV_EXCL_START Reason: no test exist void init() { - token = retrieveToken(); - if (token.empty()) { - dbgInfo(D_LOCAL_POLICY) << "Initializing Linux Local-Policy generator"; - env_type = LocalPolicyEnv::LINUX; + env_details = Singleton::Consume::by(); + env_type = env_details->getEnvType(); + if (env_type == EnvType::LINUX) { + dbgInfo(D_LOCAL_POLICY) << "Initializing Linux policy generator"; return; } - env_type = LocalPolicyEnv::K8S; dbgInfo(D_LOCAL_POLICY) << "Initializing K8S policy generator"; - conn_flags.setFlag(MessageConnConfig::SECURE_CONN); - conn_flags.setFlag(MessageConnConfig::IGNORE_SSL_VALIDATION); - - messaging = Singleton::Consume::by(); + k8s_policy_utils.init(); Singleton::Consume::by()->addOneTimeRoutine( I_MainLoop::RoutineType::Offline, [this] () { - ScopedContext ctx; - ctx.registerValue("k8s_env", true); - while(!getClusterId()) { + while(!k8s_policy_utils.getClusterId()) { Singleton::Consume::by()->yield(chrono::seconds(1)); } return; @@ -163,47 +92,10 @@ public: ); } - const string & getPolicyPath(void) const override { return local_appsec_policy_path; } - - template - container_it - extractElement(container_it begin, container_it end, const string &element_name) - { - dbgTrace(D_LOCAL_POLICY) << "Tryting to find element: " << element_name; - for (container_it it = begin; it < end; it++) { - if (element_name == it->getName()) { - dbgTrace(D_LOCAL_POLICY) << "Element with name " << element_name << "was found"; - return it; - } - } - dbgTrace(D_LOCAL_POLICY) << "Element with name " << element_name << "was not found"; - return end; - } - - template - Maybe - getObjectFromCluster(const string &path) - { - T object; - bool res = messaging->sendObject( - object, - I_Messaging::Method::GET, - "kubernetes.default.svc", - 443, - conn_flags, - path, - "Authorization: Bearer " + token + "\nConnection: close" - ); - - if (res) return object; - - return genError("Was not able to get object form k8s cluser in path: " + path); - } - string parseLinuxPolicy(const string &policy_version) { - dbgFlow(D_LOCAL_POLICY); + dbgFlow(D_LOCAL_POLICY) << "Starting to parse policy - embedded environment"; string policy_path = getConfigurationFlagWithDefault( getFilesystemPathConfig() + local_mgmt_policy_path, @@ -217,6 +109,7 @@ public: } AppsecLinuxPolicy policy = maybe_policy.unpack(); string policy_name = policy_maker_utils.getPolicyName(policy_path); + dbgTrace(D_LOCAL_POLICY) << "Proccesing policy, name: " << policy_name; ParsedRule default_rule = policy.getAppsecPolicySpec().getDefaultRule(); @@ -237,1118 +130,59 @@ public: ); } - LocalPolicyEnv getEnvType() const { return env_type;} - string parseK8sPolicy(const string &policy_version) { - ScopedContext ctx; - ctx.registerValue("k8s_env", true); + dbgFlow(D_LOCAL_POLICY) << "Starting to parse policy - K8S environment"; - auto maybe_ingress = getObjectFromCluster("/apis/networking.k8s.io/v1/ingresses"); + map appsec_policies = k8s_policy_utils.createAppsecPoliciesFromIngresses(); - if (!maybe_ingress.ok()) { - // TBD: Error handling : INXT-31444 - dbgError(D_LOCAL_POLICY) - << "Failed to retrieve K8S Ingress configurations. Error: " - << maybe_ingress.getErr(); - return ""; - } + for (const auto &appsec_policy : appsec_policies) { + string policy_name = appsec_policy.first; + dbgTrace(D_LOCAL_POLICY) << "Proccesing policy, name: " << policy_name; + AppsecLinuxPolicy policy = appsec_policy.second; - IngressData ingress = maybe_ingress.unpack(); + ParsedRule default_rule = policy.getAppsecPolicySpec().getDefaultRule(); - set generated_apps; - set parsed_web_apps_set; - vector parsed_web_apps; - vector parsed_rules; - vector users_identifiers; - vector parsed_log_triggers; - set parsed_exeptions; - vector parsed_web_user_res; - map practice_map; - map log_triggers_map; - map exception_map; - map web_user_res_map; - map trusted_sources_map; - map> source_identifiers_map; - RulesConfigRulebase cleanup_rule; - string cleanup_rule_mode = "Inactive"; + // add default rule to policy + policy_maker_utils.createPolicyElementsByRule(default_rule, default_rule, policy, policy_name); - dbgTrace(D_LOCAL_POLICY) << "Received Ingress apiVersion: " << ingress.getapiVersion(); - dbgTrace(D_LOCAL_POLICY) << "Ingress items ammount: " << ingress.getItems().size(); - // TBD: break to methods : INXT-31445 - for (const SingleIngressData &item : ingress.getItems()) { - set> specific_assets_from_ingress; - for (const IngressDefinedRule &rule : item.getSpec().getRules()) { - string url = rule.getHost(); - for (const IngressRulePath &uri : rule.getPathsWrapper().getRulePaths()) { - specific_assets_from_ingress.insert({url, uri.getPath()}); - dbgTrace(D_LOCAL_POLICY) - << "Inserting Host data to the specific asset set:" - << "URL: '" - << url - << "' uri: '" - << uri.getPath() - << "'"; - } - } - - string asset; - string annotation_type; - string annotation_name; - string policy_annotation; - string syslog_address; - string syslog_port; - string mode_annotation; - for (const pair &annotation : item.getMetadata().getAnnotations()) { - string annotation_key = annotation.first; - string annotation_val = annotation.second; - if (annotation_key.find(open_appsec_io) != string::npos) { - if (annotation_key.find(policy_key) != string::npos) policy_annotation = annotation_val; - if (annotation_key.find(syslog_key) != string::npos) { - bool has_port = annotation_val.find(":"); - syslog_address = annotation_val.substr(0, annotation_val.find(":")); - syslog_port = has_port ? annotation_val.substr(annotation_val.find(":") + 1) : ""; - } - if (annotation_key.find(mode_key) != string::npos) { - mode_annotation = annotation_val; - ctx.registerValue("default mode annotation", mode_annotation); - } - } - } - if (policy_annotation.empty()) { - dbgInfo(D_LOCAL_POLICY) << "No policy was found in this ingress"; - continue; - } - - dbgTrace(D_LOCAL_POLICY) << "Trying to parse policy for " << policy_annotation; - auto maybe_appsec_policy = getObjectFromCluster>( - "/apis/openappsec.io/v1beta1/policies/" + policy_annotation + vector specific_rules = policy.getAppsecPolicySpec().getSpecificRules(); + policy_maker_utils.createPolicyElements( + specific_rules, + default_rule, + policy, + policy_name ); - - if (!maybe_appsec_policy.ok()) { - dbgError(D_LOCAL_POLICY) - << "Failed to retrieve AppSec policy. Error: " - << maybe_appsec_policy.getErr(); - return ""; - } - - AppsecSpecParser appsec_policy = maybe_appsec_policy.unpack(); - - vector specific_rules = appsec_policy.getSpec().getSpecificRules(); - ParsedRule default_rule = appsec_policy.getSpec().getDefaultRule(); - - for (const ParsedRule &parsed_rule : specific_rules) { - string asset_name = parsed_rule.getHost(); - dbgTrace(D_LOCAL_POLICY) << "Handling specific rule for asset: " << asset_name; - - string practice_annotation_name; - // TBD: support multiple practices - if (parsed_rule.getPractices().size() > 0 && !parsed_rule.getPractices()[0].empty()) { - practice_annotation_name = parsed_rule.getPractices()[0]; - } else if (default_rule.getPractices().size() > 0 && !default_rule.getPractices()[0].empty()) { - practice_annotation_name = default_rule.getPractices()[0]; - } - - string trigger_annotation_name; - // TBD: support multiple triggers - if (parsed_rule.getLogTriggers().size() > 0 && !parsed_rule.getLogTriggers()[0].empty()) { - trigger_annotation_name = parsed_rule.getLogTriggers()[0]; - } else if (default_rule.getLogTriggers().size() > 0 && !default_rule.getLogTriggers()[0].empty()) { - trigger_annotation_name = default_rule.getLogTriggers()[0]; - } - - string exception_annotation_name; - // TBD: support multiple exceptions - if (parsed_rule.getExceptions().size() > 0 && !parsed_rule.getExceptions()[0].empty()) { - exception_annotation_name = parsed_rule.getExceptions()[0]; - } else if (default_rule.getExceptions().size() > 0 && !default_rule.getExceptions()[0].empty()) { - exception_annotation_name = default_rule.getExceptions()[0]; - } - - string web_user_res_annotation_name = - parsed_rule.getCustomResponse().empty() ? - default_rule.getCustomResponse() : - parsed_rule.getCustomResponse(); - - string source_identifiers_annotation_name = - parsed_rule.getSourceIdentifiers().empty() ? - default_rule.getSourceIdentifiers() : - parsed_rule.getSourceIdentifiers(); - - string trusted_sources_annotation_name = - parsed_rule.getTrustedSources ().empty() ? - default_rule.getTrustedSources() : - parsed_rule.getTrustedSources(); - - auto pos = asset_name.find("/"); - string url; - string uri; - if (pos != string::npos) { - url = asset_name.substr(0, asset_name.find("/")); - uri = asset_name.substr(asset_name.find("/")); - } else { - url = asset_name; - uri = ""; - } - if (specific_assets_from_ingress.find({url, uri}) != specific_assets_from_ingress.end()) { - // Erasing the current asset from the specific assets, because it won't have default policy - specific_assets_from_ingress.erase({url, uri}); - } - - vector> web_user_res_vec; - if (!extractExceptions(exception_annotation_name, exception_map, parsed_exeptions)) { - dbgWarning(D_LOCAL_POLICY) - << "Failed extracting exceptions. Exception name: " - << exception_annotation_name; - return ""; - } - - if (!extractTriggers( - trigger_annotation_name, - log_triggers_map, - parsed_log_triggers, - syslog_address, - syslog_port) - ) { - dbgWarning(D_LOCAL_POLICY) - << "Failed extracting triggers. Trigger name: " - << trigger_annotation_name; - return ""; - } - - if (!extractWebUserResponse( - web_user_res_annotation_name, - web_user_res_map, - web_user_res_vec, - parsed_web_user_res) - ) { - dbgWarning(D_LOCAL_POLICY) - << "Failed extracting custom response. Custom response name: " - << web_user_res_annotation_name; - return ""; - } - - AppSecTrustedSources parsed_trusted_sources; - if (!extractTrustedSources( - asset_name, - trusted_sources_annotation_name, - source_identifiers_annotation_name, - trusted_sources_map, - source_identifiers_map, - parsed_trusted_sources) - ) { - dbgWarning(D_LOCAL_POLICY) - << "Failed extracting trused sources. Trusted source name: " - << trusted_sources_annotation_name - << ", Source identifiers annotation name: " - << source_identifiers_annotation_name; - return ""; - } - - if (!practice_annotation_name.empty() && practice_map.count(practice_annotation_name) == 0) { - auto maybe_appsec_practice = getObjectFromCluster>( - "/apis/openappsec.io/v1beta1/practices/" + practice_annotation_name - ); - - if (!maybe_appsec_practice.ok()) { - dbgError(D_LOCAL_POLICY) - << "Failed to retrieve AppSec practice for asset " - << asset_name - << ". Error: " - << maybe_appsec_practice.getErr(); - return ""; - } - - AppsecSpecParser appsec_practice = maybe_appsec_practice.unpack(); - practice_map.emplace(practice_annotation_name, appsec_practice.getSpec()); - } - - string log_trigger_id; - LogTriggerSection log_trigger_annotation; - if (log_triggers_map.count(trigger_annotation_name) > 0) { - log_trigger_id = log_triggers_map.at(trigger_annotation_name).getTriggerId(); - log_trigger_annotation = log_triggers_map.at(trigger_annotation_name); - } - string exception_id; - if (exception_map.count(exception_annotation_name) > 0) { - exception_id = exception_map.at(exception_annotation_name).getBehaviorId(); - } - RulesConfigRulebase rules_config = createMultiRulesSections( - url, - uri, - practice_annotation_name, - "WebApplication", - trigger_annotation_name, - log_trigger_id, - "log", - web_user_res_vec, - asset_name, - exception_annotation_name, - exception_id - ); - string port = "80"; - string full_url = asset_name == "Any" ? "" : url + "/" + uri + ":" + port; - string asset_id = rules_config.getAssetId(); - string practice_id = rules_config.getPracticeId(); - - if (!generated_apps.count(full_url)) { - WebAppSection web_app = WebAppSection( - full_url, - asset_id, - asset_name, - asset_id, - asset_name, - practice_id, - practice_annotation_name, - practice_map.at(practice_annotation_name), - log_trigger_annotation, - default_rule.getMode(), - parsed_trusted_sources - ); - - parsed_web_apps_set.insert(web_app); - parsed_rules.push_back(rules_config); - generated_apps.insert(full_url); - } - } - - string exception_name; - if (!default_rule.getExceptions().empty()) { - exception_name = default_rule.getExceptions()[0]; - if (!extractExceptions(exception_name, exception_map, parsed_exeptions)) return ""; - } - - string trigger_name; - if (!default_rule.getLogTriggers().empty()) { - trigger_name = default_rule.getLogTriggers()[0]; - if (!extractTriggers( - trigger_name, - log_triggers_map, - parsed_log_triggers, - syslog_address, - syslog_port)) return ""; - } - - vector> default_web_user_res_vec; - string web_user_res_annotation_name = default_rule.getCustomResponse(); - if (!extractWebUserResponse( - web_user_res_annotation_name, - web_user_res_map, - default_web_user_res_vec, - parsed_web_user_res) - ) return ""; - - AppSecTrustedSources default_parsed_trusted_sources; - string trusted_sources_annotation_name = default_rule.getTrustedSources(); - string source_identifiers_annotation_name = default_rule.getSourceIdentifiers(); - if (!extractTrustedSources( - "Any", - trusted_sources_annotation_name, - source_identifiers_annotation_name, - trusted_sources_map, - source_identifiers_map, - default_parsed_trusted_sources) - ) { - dbgWarning(D_LOCAL_POLICY) - << "Failed extracting trused sources. Trusted source name: " - << trusted_sources_annotation_name - << ", Source identifiers annotation name: " - << source_identifiers_annotation_name; - return ""; - } - - string practice_name; - if (!default_rule.getPractices().empty()) { - practice_name = default_rule.getPractices()[0]; - } - if (!practice_name.empty() && practice_map.count(practice_name) == 0) { - auto maybe_appsec_practice = getObjectFromCluster>( - "/apis/openappsec.io/v1beta1/practices/" + practice_name - ); - - if (!maybe_appsec_practice.ok()) { - dbgError(D_LOCAL_POLICY) - << "Failed to retrieve AppSec practice for the dafult practice. Error: " - << maybe_appsec_practice.getErr(); - return ""; - } - - AppsecSpecParser appsec_practice = maybe_appsec_practice.unpack(); - practice_map.emplace(practice_name, appsec_practice.getSpec()); - } - - if (item.getSpec().isDefaultBackendExists()) { - dbgTrace(D_LOCAL_POLICY) << "Default Backend exists in the ingress"; - bool should_create_rule = false; - if (cleanup_rule_mode != "Prevent") { - if (default_rule.getMode().find("prevent") != string::npos) { - cleanup_rule_mode = "Prevent"; - should_create_rule = true; - } - } else if (cleanup_rule_mode == "Inactive") { - if (default_rule.getMode().find("detect") != string::npos) { - cleanup_rule_mode = "Detect"; - should_create_rule = true; - } - } - - if (should_create_rule) { - dbgTrace(D_LOCAL_POLICY) << "Cleanup rule mode: " << cleanup_rule_mode; - specific_assets_from_ingress.insert({"Any", "Any"}); - } - } - - // TBD: fix this to support multiple exceptions! - for (const pair &asset : specific_assets_from_ingress) { - string log_trigger_id; - LogTriggerSection log_trigger_section; - if (log_triggers_map.count(trigger_name) > 0) { - log_trigger_id = log_triggers_map.at(trigger_name).getTriggerId(); - log_trigger_section = log_triggers_map.at(trigger_name); - } - string exception_id; - if ( - !default_rule.getExceptions().empty() && exception_map.count(default_rule.getExceptions()[0]) > 0 - ) { - exception_id = exception_map.at(default_rule.getExceptions()[0]).getBehaviorId(); - } - string asset_name = asset.first == "Any" && asset.second == "Any" ? "Any" : asset.first + asset.second; - RulesConfigRulebase default_rule_config = createMultiRulesSections( - asset.first, - asset.second, - practice_name, - "WebApplication", - trigger_name, - log_trigger_id, - "log", - default_web_user_res_vec, - asset_name, - exception_name, - exception_id - ); - if (asset_name == "Any") { - cleanup_rule = default_rule_config; - } else { - parsed_rules.push_back(default_rule_config); - } - - string asset_id = default_rule_config.getAssetId(); - string practice_id = default_rule_config.getPracticeId(); - - if (!generated_apps.count(asset.first + asset.second)) { - WebAppSection web_app = WebAppSection( - asset.first + asset.second, - asset_id, - "Any", - asset_id, - "Any", - practice_id, - practice_name, - practice_map.at(practice_name), - log_trigger_section, - default_rule.getMode(), - default_parsed_trusted_sources - ); - parsed_web_apps_set.insert(web_app); - generated_apps.insert(asset.first + asset.second); - } - } } - if (cleanup_rule_mode != "Inactive") { - dbgTrace(D_LOCAL_POLICY) << "Pushing a cleanup rule"; - parsed_rules.push_back(cleanup_rule); - } - - for (const auto & parsed_web_app : parsed_web_apps_set) { - parsed_web_apps.push_back(parsed_web_app); - } - - dbgTrace(D_LOCAL_POLICY) - << "Policy creation summery:" << endl - << "Web applications ammount: " - << parsed_web_apps.size() - << endl << "Rules ammount: " - << parsed_rules.size() - << endl << "Triggers ammount: " - << parsed_log_triggers.size() - << endl << "Web user response ammount: " - << parsed_web_user_res.size(); - - TriggersWrapper triggers_section(TriggersRulebase(parsed_log_triggers, parsed_web_user_res)); - AppSecWrapper waap_section = createMultipleAppSecSections(parsed_web_apps); - RulesConfigWrapper rules_config_section(parsed_rules, users_identifiers); - - ExceptionsWrapper exceptions_section = createExceptionSection(parsed_exeptions); - SecurityAppsWrapper security_app_section = SecurityAppsWrapper( - waap_section, - triggers_section, - rules_config_section, - exceptions_section, - policy_version + PolicyWrapper policy_wrapper = policy_maker_utils.combineElementsToPolicy(policy_version); + return policy_maker_utils.dumpPolicyToFile( + policy_wrapper, + local_appsec_policy_path ); - - SettingsWrapper profiles_section = createProfilesSection(); - PolicyWrapper k8s_policy = PolicyWrapper(profiles_section, security_app_section); - - return dumpPolicyToFile(k8s_policy); } string parsePolicy(const string &policy_version) { - return env_type == LocalPolicyEnv::K8S ? parseK8sPolicy(policy_version) : parseLinuxPolicy(policy_version); + return isK8sEnv() ? parseK8sPolicy(policy_version) : parseLinuxPolicy(policy_version); } - SettingsWrapper - createProfilesSection() - { - string agent_settings_key = "agent.test.k8s.policy"; - string agent_settings_value = "k8s policy"; - AgentSettingsSection agent_setting_1 = AgentSettingsSection(agent_settings_key, agent_settings_value); - - SettingsRulebase settings_rulebase_1 = SettingsRulebase({agent_setting_1}); - return SettingsWrapper(settings_rulebase_1); - } - - LogTriggerSection - createLogTriggersSection( - const string &trigger_name, - bool is_syslog = false, - const string &syslog_port = string(), - const AppsecTriggerSpec &trigger_spec = AppsecTriggerSpec()) - { - string verbosity = "Standard"; - string extendLoggingMinSeverity = - trigger_spec.getAppsecTriggerAdditionalSuspiciousEventsLogging().getMinimumSeverity(); - bool tpDetect = trigger_spec.getAppsecTriggerLogging().isDetectEvents(); - bool tpPrevent = trigger_spec.getAppsecTriggerLogging().isPreventEvents(); - bool webRequests = trigger_spec.getAppsecTriggerLogging().isAllWebRequests(); - bool webUrlPath = trigger_spec.getAppsecTriggerExtendedLogging().isUrlPath(); - bool webUrlQuery = trigger_spec.getAppsecTriggerExtendedLogging().isUrlQuery(); - bool webHeaders = trigger_spec.getAppsecTriggerExtendedLogging().isHttpHeaders(); - bool webBody = trigger_spec.getAppsecTriggerExtendedLogging().isRequestBody(); - bool logToCloud = trigger_spec.getAppsecTriggerLogDestination().getCloud(); - bool logToAgent = trigger_spec.getAppsecTriggerLogDestination().isAgentLocal(); - bool beautify_logs = trigger_spec.getAppsecTriggerLogDestination().shouldBeautifyLogs(); - bool logToCef = trigger_spec.getAppsecTriggerLogDestination().isCefNeeded(); - bool logToSyslog = is_syslog ? is_syslog : trigger_spec.getAppsecTriggerLogDestination().isSyslogNeeded(); - bool responseBody = trigger_spec.getAppsecTriggerAdditionalSuspiciousEventsLogging().isResponseBody(); - bool extendLogging = trigger_spec.getAppsecTriggerAdditionalSuspiciousEventsLogging().isEnabled(); - int cefPortNum = logToCef ? trigger_spec.getAppsecTriggerLogDestination().getCefServerUdpPort() : 0; - string cefIpAddress = - logToCef ? trigger_spec.getAppsecTriggerLogDestination().getCefServerIpv4Address() : ""; - int syslogPortNum; - try { - syslogPortNum = - is_syslog ? - stoi(syslog_port) : - logToSyslog ? - trigger_spec.getAppsecTriggerLogDestination().getSyslogServerUdpPort() : - 514; - } catch (const exception &err) { - dbgWarning(D_LOCAL_POLICY) - << "Failed to convert port number from string. Port: " - << syslog_port - << ". Setting default value 514"; - syslogPortNum = 514; - } - string syslogIpAddress = - is_syslog ? - trigger_name : - logToSyslog ? - trigger_spec.getAppsecTriggerLogDestination().getSyslogServerIpv4Address() : - ""; - - LogTriggerSection log( - trigger_name, - verbosity, - extendLoggingMinSeverity, - extendLogging, - logToAgent, - logToCef, - logToCloud, - logToSyslog, - responseBody, - tpDetect, - tpPrevent, - webBody, - webHeaders, - webRequests, - webUrlPath, - webUrlQuery, - cefPortNum, - cefIpAddress, - syslogPortNum, - syslogIpAddress, - beautify_logs - ); - return log; - } - - WebUserResponseTriggerSection - createWebUserResponseTriggerSection( - const string &trigger_name, - const AppSecCustomResponseSpec &trigger_spec) - { - string mode = trigger_spec.getMode(); - string response_body = trigger_spec.getMessageBody(); - string response_title = trigger_spec.getMessageTitle(); - int response_code = trigger_spec.getHttpResponseCode(); - - WebUserResponseTriggerSection web_user_res( - trigger_name, - mode, - response_body, - response_code, - response_title - ); - - return web_user_res; - } - - ExceptionsWrapper - createExceptionSection(const set &_exeptions) - { - vector exeptions(_exeptions.begin(), _exeptions.end()); - ExceptionsRulebase exception_1(exeptions); - return ExceptionsWrapper({exception_1}); - } - - RulesConfigRulebase - createMultiRulesSections( - const string &url, - const string &uri, - const string &practice_name, - const string &practice_type, - const string &trigger_name, - const string &trigger_id, - const string &trigger_type, - const vector> &web_user_res_vec, - const string &asset_name, - const string &exception_name, - const string &exception_id) - { - string practice_id; - if (practice_name_to_id_map.count(practice_name)) { - practice_id = practice_name_to_id_map[practice_name]; - } else { - try { - practice_id = to_string(boost::uuids::random_generator()()); - } catch (const boost::uuids::entropy_error &e) { - dbgWarning(D_LOCAL_POLICY) << "Failed to generate Practice ID. Error: " << e.what(); - //TBD: return Maybe as part of future error handling - } - } - - PracticeSection practice = PracticeSection(practice_id, practice_type, practice_name); - ParametersSection exception_param = ParametersSection(exception_id, exception_name); - - vector triggers; - if (!trigger_id.empty()) { - triggers.push_back(RulesTriggerSection(trigger_name, trigger_id, trigger_type)); - } - for (const pair &web_user_res : web_user_res_vec) { - triggers.push_back(RulesTriggerSection(web_user_res.first, web_user_res.second, "WebUserResponse")); - } - - RulesConfigRulebase rules_config_1 = RulesConfigRulebase( - asset_name, - url, - uri, - {practice}, - {exception_param}, - triggers - ); - return rules_config_1; - } - - AppSecWrapper - createMultipleAppSecSections(vector &web_apps) - { - AppSecRulebase app_sec_rulebase = AppSecRulebase(web_apps, {}); - return AppSecWrapper(app_sec_rulebase); - } + const string & getPolicyPath(void) const override { return local_appsec_policy_path; } private: - I_Messaging* messaging = nullptr; - Flags conn_flags; - const string cluster_url = "https://kubernetes.default.svc"; - const string service_account = "/var/run/secrets/kubernetes.io/serviceaccount"; - const string cacert_path = service_account + "/ca.crt"; - string token = ""; - LocalPolicyEnv env_type; - map practice_name_to_id_map; - bool - isPlaygroundEnv() + isK8sEnv() { - string playground_variable = "PLAYGROUND"; - const char *env_string = getenv(playground_variable.c_str()); - - if (env_string) { - string env_value = env_string; - transform( - env_value.begin(), - env_value.end(), - env_value.begin(), - [](unsigned char c) { return tolower(c); } - ); - return env_value == "true"; - } - - return false; + return env_type == EnvType::K8S; } - bool - getClusterId() - { - string playground_uid = isPlaygroundEnv() ? "playground-" : ""; - - dbgTrace(D_LOCAL_POLICY) << "Getting cluster UID"; - auto maybe_namespaces_data = getObjectFromCluster("/api/v1/namespaces/"); - - if (!maybe_namespaces_data.ok()) { - dbgError(D_LOCAL_POLICY) - << "Failed to retrieve K8S namespace data. Error: " - << maybe_namespaces_data.getErr(); - return false; - } - - NamespaceData namespaces_data = maybe_namespaces_data.unpack(); - - string uid; - for (const SingleNamespaceData &ns : namespaces_data.getItems()) { - if (ns.getMetadata().getName() == "kube-system") { - uid = ns.getMetadata().getUID(); - dbgTrace(D_LOCAL_POLICY) << "Found k8s cluster UID: " << uid; - I_Environment *env = Singleton::Consume::by(); - env->getConfigurationContext().registerValue( - "k8sClusterId", - uid, - EnvKeyAttr::LogSection::SOURCE - ); - auto i_agent_details = Singleton::Consume::by(); - i_agent_details->setClusterId(playground_uid + uid); - return true; - } - } - return false; - } - - const string - dumpPolicyToFile(const PolicyWrapper &policy) const - { - stringstream ss; - { - cereal::JSONOutputArchive ar(ss); - policy.save(ar); - } - string policy_str = ss.str(); - ofstream policy_file(local_appsec_policy_path); - policy_file << policy_str; - policy_file.close(); - return policy_str; - } - - string - readFileContent(const string&file_path) - { - try { - ifstream file(file_path); - stringstream buffer; - buffer << file.rdbuf(); - return buffer.str(); - } catch (ifstream::failure &f) { - dbgWarning(D_ORCHESTRATOR) - << "Cannot read the file" - << " File: " << file_path - << " Error: " << f.what(); - return ""; - } - } - - string - retrieveToken() - { - return readFileContent(service_account + "/token"); - } - - void - extractExceptions( - const string &exception_annotation_name, - map &exception_map, - set &parsed_exeptions, - const vector &appsec_excepetion_specs) - { - if (!exception_annotation_name.empty() && exception_map.count(exception_annotation_name) == 0) { - for (const AppsecExceptionSpec &parsed_exeption : appsec_excepetion_specs) { - ExceptionMatch exception_match(parsed_exeption); - string behavior = - parsed_exeption.getAction() == "skip" ? - "ignore" : - parsed_exeption.getAction(); - ExceptionBehavior exception_behavior("action", behavior); - InnerException inner_exception(exception_behavior, exception_match); - exception_map.emplace(exception_annotation_name, inner_exception); - parsed_exeptions.insert(inner_exception); - } - } - } - - bool - extractExceptions( - const string &exception_annotation_name, - map &exception_map, - set &parsed_exeptions) - { - if (!exception_annotation_name.empty() && exception_map.count(exception_annotation_name) == 0) { - dbgTrace(D_LOCAL_POLICY) << "Trying to retrieve exceptions for " << exception_annotation_name; - - auto maybe_appsec_exception = getObjectFromCluster>>( - "/apis/openappsec.io/v1beta1/exceptions/" + exception_annotation_name - ); - - if (!maybe_appsec_exception.ok()) { - dbgError(D_LOCAL_POLICY) - << "Failed to retrieve AppSec exception. Error: " - << maybe_appsec_exception.getErr(); - return false; - } - - AppsecSpecParser> appsec_exception = maybe_appsec_exception.unpack(); - dbgTrace(D_LOCAL_POLICY) - << "Successfuly retrieved AppSec exceptions for " - << exception_annotation_name; - - extractExceptions(exception_annotation_name, exception_map, parsed_exeptions, appsec_exception.getSpec()); - } - return true; - } - - Maybe - getAppsecTriggerSpec(const string &trigger_annotation_name) - { - string error_message; - if (getEnvType() == LocalPolicyEnv::K8S) { - auto maybe_appsec_trigger = getObjectFromCluster>( - "/apis/openappsec.io/v1beta1/logtriggers/" + trigger_annotation_name - ); - - if (!maybe_appsec_trigger.ok()) { - error_message = "Failed to retrieve AppSec triggers. Error: " + maybe_appsec_trigger.getErr(); - dbgError(D_LOCAL_POLICY) << error_message; - return genError(error_message); - } - - return maybe_appsec_trigger.unpack().getSpec(); - } - - auto maybe_appsec_policy = Singleton::Consume::by()-> - get("get_linux_local_policy"); - if (!maybe_appsec_policy.ok()) { - error_message = "Failed to retrieve AppSec triggers"; - dbgDebug(D_LOCAL_POLICY) << error_message; - return genError(error_message); - } - - auto triggers_vec = maybe_appsec_policy.unpack().getAppsecTriggerSpecs(); - auto trigger_it = extractElement(triggers_vec.begin(), triggers_vec.end(), trigger_annotation_name); - if (trigger_it == triggers_vec.end()) { - error_message = "Failed to retrieve AppSec triggers"; - dbgDebug(D_LOCAL_POLICY) << error_message; - return genError(error_message); - } - - return *trigger_it; - } - - bool - extractTriggers( - const string &trigger_annotation_name, - map &log_triggers_map, - vector &parsed_log_triggers, - const string &syslog_address = string(), - const string &syslog_port = string()) - { - if (trigger_annotation_name.empty() && !syslog_address.empty()) { - if (!IPAddr::isValidIPAddr(syslog_address)) { - dbgWarning(D_LOCAL_POLICY) << "Syslog address is invalid. Address: " << syslog_address; - return false; - } - dbgTrace(D_LOCAL_POLICY) - << "Creating default syslog log section with syslog service address: " - << syslog_address - << ", Port: " - << syslog_port; - - LogTriggerSection log_triggers_section = - createLogTriggersSection(syslog_address, true, syslog_port); - log_triggers_map.emplace(trigger_annotation_name, log_triggers_section); - parsed_log_triggers.push_back(log_triggers_section); - } else if (!trigger_annotation_name.empty() && log_triggers_map.count(trigger_annotation_name) == 0) { - dbgTrace(D_LOCAL_POLICY) << "Trying to retrieve triggers for " << trigger_annotation_name; - - Maybe maybe_appsec_trigger_spec = getAppsecTriggerSpec(trigger_annotation_name); - - if (!maybe_appsec_trigger_spec.ok()) { - dbgWarning(D_LOCAL_POLICY) << "Error: " << maybe_appsec_trigger_spec.getErr(); - return false; - } - - LogTriggerSection log_triggers_section = - createLogTriggersSection(trigger_annotation_name, false, "", *maybe_appsec_trigger_spec); - log_triggers_map.emplace(trigger_annotation_name, log_triggers_section); - parsed_log_triggers.push_back(log_triggers_section); - } - return true; - } - - Maybe - getAppsecTrustedSourceSpecs(const string &trusted_sources_name) - { - string error_message; - if (getEnvType() == LocalPolicyEnv::K8S) { - auto maybe_trusted_sources_from_ingress = getObjectFromCluster>( - "/apis/openappsec.io/v1beta1/trustedsources/" + trusted_sources_name - ); - - if (!maybe_trusted_sources_from_ingress.ok()) { - error_message = "Failed to retrieve trusted sources. Error: " + - maybe_trusted_sources_from_ingress.getErr(); - dbgError(D_LOCAL_POLICY) << error_message; - return genError(error_message); - } - - return maybe_trusted_sources_from_ingress.unpack().getSpec(); - } - - auto maybe_appsec_policy = Singleton::Consume::by()-> - get("get_linux_local_policy"); - - if (!maybe_appsec_policy.ok()) { - error_message = "Failed to retrieve AppSec triggers"; - dbgDebug(D_LOCAL_POLICY) << error_message; - return genError(error_message); - } - - auto trusted_sources_vec = maybe_appsec_policy.unpack().getAppsecTrustedSourceSpecs(); - auto trusted_sources_it = extractElement( - trusted_sources_vec.begin(), - trusted_sources_vec.end(), - trusted_sources_name); - - if (trusted_sources_it == trusted_sources_vec.end()) { - error_message = "Failed to retrieve AppSec triggers"; - dbgDebug(D_LOCAL_POLICY) << error_message; - return genError(error_message); - } - - return *trusted_sources_it; - } - - Maybe> - getAppsecSourceIdentifierSpecs(const string &source_identifiers_name) - { - string error_message; - if (getEnvType() == LocalPolicyEnv::K8S) { - auto maybe_source_identifier = getObjectFromCluster>>( - "/apis/openappsec.io/v1beta1/sourcesidentifiers/" + source_identifiers_name - ); - - if (!maybe_source_identifier.ok()) { - error_message = "Failed to retrieve trusted sources. Error: " + maybe_source_identifier.getErr(); - dbgError(D_LOCAL_POLICY) << error_message; - return genError(error_message); - } - - return maybe_source_identifier.unpack().getSpec(); - } - - auto maybe_appsec_policy = Singleton::Consume::by()-> - get("get_linux_local_policy"); - - if (!maybe_appsec_policy.ok()) { - error_message = "Failed to retrieve AppSec triggers"; - dbgDebug(D_LOCAL_POLICY) << error_message; - return genError(error_message); - } - - auto source_identifiers_vec = maybe_appsec_policy.unpack().getAppsecSourceIdentifierSpecs(); - auto source_identifier_it = extractElement( - source_identifiers_vec.begin(), - source_identifiers_vec.end(), - source_identifiers_name - ); - - if (source_identifier_it == source_identifiers_vec.end()) { - error_message = "Failed to retrieve AppSec triggers"; - dbgDebug(D_LOCAL_POLICY) << error_message; - return genError(error_message); - } - - return (*source_identifier_it).getIdentifiers(); - } - - bool - extractTrustedSources( - const string &asset_name, - const string &trusted_sources_name, - const string &source_identifiers_name, - map &trusted_sources_map, - map> &source_identifiers_map, - AppSecTrustedSources &parsedTrustedSources) - { - if (trusted_sources_name.empty() && source_identifiers_name.empty()) return true; - if (trusted_sources_name.empty() ^ source_identifiers_name.empty()) { - dbgInfo(D_LOCAL_POLICY) - << "Trusted Sources or Source Identifier were not provided. Truster Sources: " - << trusted_sources_name - << ", Source Identidier: " - << source_identifiers_name; - return false; - } - - // Parsing trusted sources from the k8s API - if (!trusted_sources_map.count(trusted_sources_name)) { - dbgTrace(D_LOCAL_POLICY) << "Trying to retrieve trusted sources for: " << trusted_sources_name; - - auto trusted_sources_from_ingress_spec = getAppsecTrustedSourceSpecs(trusted_sources_name); - if (!trusted_sources_from_ingress_spec.ok()) { - dbgWarning(D_LOCAL_POLICY) << trusted_sources_from_ingress_spec.getErr(); - return false; - } - - trusted_sources_map[trusted_sources_name] = trusted_sources_from_ingress_spec.unpack(); - } - - // Parsing source identifiers from the k8s API - if (!source_identifiers_map.count(source_identifiers_name)) { - dbgTrace(D_LOCAL_POLICY) << "Trying to retrieve sources identifiers for: " << source_identifiers_name; - - auto source_identifier_from_ingress_spec = getAppsecSourceIdentifierSpecs(source_identifiers_name); - - if (!source_identifier_from_ingress_spec.ok()) { - dbgWarning(D_LOCAL_POLICY) << "Error: " << source_identifier_from_ingress_spec.getErr(); - return false; - } - - source_identifiers_map[source_identifiers_name] = source_identifier_from_ingress_spec.unpack(); - } - - // Generating the (Trusted Sources X Source Identifiers) matrix - vector generated_trusted_json; - for (const SourceIdentifierSpec &src_ident : source_identifiers_map[source_identifiers_name]) { - for (const string &trusted_src : trusted_sources_map[trusted_sources_name].getSourcesIdentifiers()) { - if (src_ident.getValues().empty()) { - generated_trusted_json.push_back(SourcesIdentifiers(src_ident.getSourceIdentifier(), trusted_src)); - } else { - for (const string &val : src_ident.getValues()) { - string src_key = src_ident.getSourceIdentifier() + ":" + val; - generated_trusted_json.push_back(SourcesIdentifiers(src_key, trusted_src)); - } - } - } - } - - parsedTrustedSources = AppSecTrustedSources( - asset_name, - trusted_sources_map[trusted_sources_name].getMinNumOfSources(), - generated_trusted_json - ); - - return true; - } - - Maybe - getAppSecCustomResponseSpecs(const string &web_user_res_annotation_name) - { - string error_message; - if (getEnvType() == LocalPolicyEnv::K8S) { - auto maybe_appsec_web_user_res = getObjectFromCluster>( - "/apis/openappsec.io/v1beta1/customresponses/" + web_user_res_annotation_name - ); - - if (!maybe_appsec_web_user_res.ok()) { - error_message = "Failed to retrieve appsec web user res. Error: " + - maybe_appsec_web_user_res.getErr(); - dbgError(D_LOCAL_POLICY) << error_message; - return genError(error_message); - } - return maybe_appsec_web_user_res.unpack().getSpec(); - } - - auto maybe_appsec_policy = Singleton::Consume::by()-> - get("get_linux_local_policy"); - - if (!maybe_appsec_policy.ok()) { - error_message = "Failed to retrieve appsec web user response."; - dbgDebug(D_LOCAL_POLICY) << error_message; - return genError(error_message); - } - - auto web_user_res_vec = maybe_appsec_policy.unpack().getAppSecCustomResponseSpecs(); - auto web_user_res_it = extractElement( - web_user_res_vec.begin(), - web_user_res_vec.end(), - web_user_res_annotation_name); - - if (web_user_res_it == web_user_res_vec.end()) { - error_message = "Failed to retrieve appsec web user response."; - dbgDebug(D_LOCAL_POLICY) << error_message; - return genError(error_message); - } - - return *web_user_res_it; - - } - - bool - extractWebUserResponse( - const string &web_user_res_annotation_name, - map &web_user_res_map, - vector> &web_user_res_vec, - vector &parsed_web_user_res) - { - if (!web_user_res_annotation_name.empty()) { - dbgTrace(D_LOCAL_POLICY) << "Trying to retrieve web user response for: " << web_user_res_annotation_name; - auto maybe_appsec_web_user_res_spec = getAppSecCustomResponseSpecs(web_user_res_annotation_name); - - if (!maybe_appsec_web_user_res_spec.ok()) { - dbgWarning(D_LOCAL_POLICY) << maybe_appsec_web_user_res_spec.getErr(); - return false; - } - - AppSecCustomResponseSpec appsec_web_user_res_spec = maybe_appsec_web_user_res_spec.unpack(); - - if (web_user_res_map.count(web_user_res_annotation_name) == 0) { - WebUserResponseTriggerSection web_user_res_section = createWebUserResponseTriggerSection( - web_user_res_annotation_name, - appsec_web_user_res_spec); - - web_user_res_map.emplace(web_user_res_annotation_name, web_user_res_section); - parsed_web_user_res.push_back(web_user_res_section); - web_user_res_vec.push_back( - pair( - web_user_res_section.getTriggerName(), - web_user_res_section.getTriggerId() - ) - ); - } else { - web_user_res_vec.push_back( - pair( - web_user_res_map.at(web_user_res_annotation_name).getTriggerName(), - web_user_res_map.at(web_user_res_annotation_name).getTriggerId() - ) - ); - } - } - return true; - } - -private: + I_EnvDetails* env_details = nullptr; + EnvType env_type; PolicyMakerUtils policy_maker_utils; + K8sPolicyUtils k8s_policy_utils; + }; LocalPolicyMgmtGenerator::LocalPolicyMgmtGenerator() @@ -1363,8 +197,3 @@ LocalPolicyMgmtGenerator::init() { pimpl->init(); } - -void -LocalPolicyMgmtGenerator::preload() -{} -// LCOV_EXCL_STOP diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/namespace_data.cc b/components/security_apps/orchestration/local_policy_mgmt_gen/namespace_data.cc new file mode 100644 index 0000000..c4b65b3 --- /dev/null +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/namespace_data.cc @@ -0,0 +1,97 @@ +// 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 "namespace_data.h" +#include "local_policy_common.h" + +using namespace std; + +USE_DEBUG_FLAG(D_LOCAL_POLICY); + +class NamespaceMetadata +{ +public: + void + load(cereal::JSONInputArchive &archive_in) + { + dbgFlow(D_LOCAL_POLICY); + parseAppsecJSONKey("name", name, archive_in); + parseAppsecJSONKey("uid", uid, archive_in); + } + + const string & + getName() const + { + return name; + } + + const string & + getUID() const + { + return uid; + } + +private: + string name; + string uid; +}; + +class SingleNamespaceData +{ +public: + void + load(cereal::JSONInputArchive &archive_in) + { + parseAppsecJSONKey("metadata", metadata, archive_in); + } + + const NamespaceMetadata & + getMetadata() const + { + return metadata; + } + +private: + NamespaceMetadata metadata; +}; + +bool +NamespaceData::loadJson(const string &json) +{ + dbgFlow(D_LOCAL_POLICY); + string modified_json = json; + modified_json.pop_back(); + stringstream in; + in.str(modified_json); + try { + cereal::JSONInputArchive in_ar(in); + vector items; + in_ar(cereal::make_nvp("items", items)); + for (const SingleNamespaceData &single_ns_data : items) { + ns_name_to_uid[single_ns_data.getMetadata().getName()] = single_ns_data.getMetadata().getUID(); + } + } catch (cereal::Exception &e) { + dbgWarning(D_LOCAL_POLICY) << "Failed to load namespace data JSON. Error: " << e.what(); + return false; + } + return true; +} + +Maybe +NamespaceData::getNamespaceUidByName(const string &name) +{ + if (ns_name_to_uid.find(name) == ns_name_to_uid.end()) { + return genError("Namespace doesn't exist. Name: " + name); + } + return ns_name_to_uid.at(name); +} diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/policy_maker_utils.cc b/components/security_apps/orchestration/local_policy_mgmt_gen/policy_maker_utils.cc index 240bc88..17bbab3 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/policy_maker_utils.cc +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/policy_maker_utils.cc @@ -17,8 +17,6 @@ using namespace std; USE_DEBUG_FLAG(D_NGINX_POLICY); -// LCOV_EXCL_START Reason: no test exist - void SecurityAppsWrapper::save(cereal::JSONOutputArchive &out_ar) const { @@ -40,12 +38,16 @@ PolicyWrapper::save(cereal::JSONOutputArchive &out_ar) const string PolicyMakerUtils::getPolicyName(const string &policy_path) { + string policy_name; if (policy_path.find_last_of("/") != string::npos) { - string policy_name = policy_path.substr(policy_path.find_last_of("/") + 1); - if (policy_name.find(".") != string::npos) return policy_name.substr(0, policy_name.find(".")); - return policy_name; + policy_name = policy_path.substr(policy_path.find_last_of("/") + 1); + } else { + policy_name = policy_path; } - return policy_path; + if (policy_name.find(".") != string::npos) { + return policy_name.substr(0, policy_name.find(".")); + } + return policy_name; } Maybe @@ -83,6 +85,7 @@ PolicyMakerUtils::clearElementsMaps() rules_config.clear(); } +// LCOV_EXCL_START Reason: no test exist - needed for NGINX config bool PolicyMakerUtils::startsWith(const string &str, const string &prefix) { @@ -95,6 +98,7 @@ PolicyMakerUtils::endsWith(const string &str, const string &suffix) return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; } +// LCOV_EXCL_STOP tuple PolicyMakerUtils::splitHostName(const string &host_name) @@ -130,8 +134,10 @@ PolicyMakerUtils::splitHostName(const string &host_name) } string -PolicyMakerUtils::dumpPolicyToFile(const PolicyWrapper &policy, const string &policy_path) const +PolicyMakerUtils::dumpPolicyToFile(const PolicyWrapper &policy, const string &policy_path) { + clearElementsMaps(); + stringstream ss; { cereal::JSONOutputArchive ar(ss); @@ -147,6 +153,7 @@ PolicyMakerUtils::dumpPolicyToFile(const PolicyWrapper &policy, const string &po dbgDebug(D_NGINX_POLICY) << "Error while writing new policy to " << policy_path << ", Error: " << e.what(); return ""; } + return policy_str; } @@ -488,6 +495,7 @@ createExceptionSection( exception_spec.getAction() == "skip" ? "ignore" : exception_spec.getAction(); + ExceptionBehavior exception_behavior("action", behavior); InnerException inner_exception(exception_behavior, exception_match); return inner_exception; @@ -672,45 +680,55 @@ PolicyMakerUtils::createPolicyElementsByRule( !rule_annotations[AnnotationTypes::PRACTICE].empty() && !web_apps.count(rule_annotations[AnnotationTypes::PRACTICE]) ) { - string practice_id = ""; - try { - practice_id = to_string(boost::uuids::random_generator()()); - } catch (const boost::uuids::entropy_error &e) { - //TBD: return Maybe as part of future error handling - } - tuple splited_host_name = splitHostName(rule.getHost()); - string full_url = rule.getHost() == "*" - ? "Any" - : rule.getHost(); - - - RulesConfigRulebase rule_config = createMultiRulesSections( - std::get<0>(splited_host_name), - std::get<2>(splited_host_name), - practice_id, - rule_annotations[AnnotationTypes::PRACTICE], - "WebApplication", - rule_annotations[AnnotationTypes::TRIGGER], - log_triggers[rule_annotations[AnnotationTypes::TRIGGER]].getTriggerId(), - "log", - rule_annotations[AnnotationTypes::WEB_USER_RES], - web_user_res_triggers[rule_annotations[AnnotationTypes::WEB_USER_RES]].getTriggerId(), - "WebUserResponse", - full_url, - rule_annotations[AnnotationTypes::EXCEPTION], - inner_exceptions[rule_annotations[AnnotationTypes::EXCEPTION]].getBehaviorId() + trusted_sources[rule_annotations[AnnotationTypes::TRUSTED_SOURCES]] = + createTrustedSourcesSection( + rule_annotations[AnnotationTypes::TRUSTED_SOURCES], + rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS], + policy ); - rules_config[rule_config.getAssetName()] = rule_config; + } - if (!rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS].empty()) { - UsersIdentifiersRulebase user_identifiers = createUserIdentifiers( - rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS], - policy, - rule_config.getContext() - ); - users_identifiers[rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS]] = user_identifiers; - } + if (!rule_annotations[AnnotationTypes::PRACTICE].empty()) { + string practice_id = ""; + try { + practice_id = to_string(boost::uuids::random_generator()()); + } catch (const boost::uuids::entropy_error &e) { + //TBD: return Maybe as part of future error handling + } + tuple splited_host_name = splitHostName(rule.getHost()); + string full_url = rule.getHost() == "*" + ? "Any" + : rule.getHost(); + + RulesConfigRulebase rule_config = createMultiRulesSections( + std::get<0>(splited_host_name), + std::get<2>(splited_host_name), + practice_id, + rule_annotations[AnnotationTypes::PRACTICE], + "WebApplication", + rule_annotations[AnnotationTypes::TRIGGER], + log_triggers[rule_annotations[AnnotationTypes::TRIGGER]].getTriggerId(), + "log", + rule_annotations[AnnotationTypes::WEB_USER_RES], + web_user_res_triggers[rule_annotations[AnnotationTypes::WEB_USER_RES]].getTriggerId(), + "WebUserResponse", + full_url, + rule_annotations[AnnotationTypes::EXCEPTION], + inner_exceptions[rule_annotations[AnnotationTypes::EXCEPTION]].getBehaviorId() + ); + rules_config[rule_config.getAssetName()] = rule_config; + + if (!rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS].empty()) { + UsersIdentifiersRulebase user_identifiers = createUserIdentifiers( + rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS], + policy, + rule_config.getContext() + ); + users_identifiers[rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS]] = user_identifiers; + } + + if (!web_apps.count(rule_annotations[AnnotationTypes::PRACTICE])) { WebAppSection web_app = WebAppSection( full_url == "Any" ? "" : full_url, rule_config.getAssetId(), @@ -726,6 +744,7 @@ PolicyMakerUtils::createPolicyElementsByRule( ); web_apps[rule_annotations[AnnotationTypes::PRACTICE]] = web_app; } + } } void @@ -739,5 +758,3 @@ PolicyMakerUtils::createPolicyElements( createPolicyElementsByRule(rule, default_rule, policy, policy_name); } } - -// LCOV_EXCL_STOP diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/rules_config_section.cc b/components/security_apps/orchestration/local_policy_mgmt_gen/rules_config_section.cc index 33b17b7..cc73d18 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/rules_config_section.cc +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/rules_config_section.cc @@ -17,7 +17,6 @@ using namespace std; USE_DEBUG_FLAG(D_LOCAL_POLICY); -// LCOV_EXCL_START Reason: no test exist AssetUrlParser AssetUrlParser::parse(const string &uri) { @@ -99,18 +98,6 @@ PracticeSection::save(cereal::JSONOutputArchive &out_ar) const ); } -const string & -PracticeSection::getPracticeId() const -{ - return id; -} - -const string & -PracticeSection::getPracticeName() const -{ - return name; -} - ParametersSection::ParametersSection( const string &_id, const string &_name) @@ -134,12 +121,6 @@ ParametersSection::save(cereal::JSONOutputArchive &out_ar) const ); } -const string & -ParametersSection::getId() const -{ - return id; -} - RulesTriggerSection::RulesTriggerSection( const string &_name, const string &_id, @@ -170,18 +151,6 @@ RulesTriggerSection::save(cereal::JSONOutputArchive &out_ar) const ); } -const string & -RulesTriggerSection::getId() const -{ - return id; -} - -const string & -RulesTriggerSection::getName() const -{ - return id; -} - RulesConfigRulebase::RulesConfigRulebase( const string &_name, const string &_url, @@ -256,12 +225,6 @@ RulesConfigRulebase::save(cereal::JSONOutputArchive &out_ar) const ); } -const string & -RulesConfigRulebase::getRuleId() const -{ - return id; -} - const string & RulesConfigRulebase::getContext() const { @@ -274,48 +237,12 @@ RulesConfigRulebase::getAssetName() const return name; } -const string & -RulesConfigRulebase::getRuleName() const -{ - return name; -} - const string & RulesConfigRulebase::getAssetId() const { return id; } -const string & -RulesConfigRulebase::getPracticeId() const -{ - return practices[0].getPracticeId(); -} - -const string & -RulesConfigRulebase::getPracticeName() const -{ - return practices[0].getPracticeName(); -} - -const vector & -RulesConfigRulebase::getPractice() const -{ - return practices; -} - -const vector & -RulesConfigRulebase::getParameters() const -{ - return parameters; -} - -const vector & -RulesConfigRulebase::getTriggers() const -{ - return triggers; -} - UsersIdentifier::UsersIdentifier(const string &_source_identifier, vector _identifier_values) : source_identifier(_source_identifier), @@ -334,8 +261,8 @@ UsersIdentifier::save(cereal::JSONOutputArchive &out_ar) const UsersIdentifiersRulebase::UsersIdentifiersRulebase( const string &_context, const string &_source_identifier, - vector _identifier_values, - vector _source_identifiers) + const vector &_identifier_values, + const vector &_source_identifiers) : context(_context), source_identifier(_source_identifier), @@ -422,5 +349,3 @@ RulesConfigWrapper::save(cereal::JSONOutputArchive &out_ar) const cereal::make_nvp("rulebase", rules_config_rulebase) ); } - -// LCOV_EXCL_STOP diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/triggers_section.cc b/components/security_apps/orchestration/local_policy_mgmt_gen/triggers_section.cc index c68a0cc..8f63a2c 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/triggers_section.cc +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/triggers_section.cc @@ -16,7 +16,11 @@ using namespace std; USE_DEBUG_FLAG(D_LOCAL_POLICY); -// LCOV_EXCL_START Reason: no test exist + +static const set valid_modes = {"block-page", "response-code-only"}; +static const set valid_severities = {"high", "critical"}; +static const set valid_protocols = {"tcp", "udp"}; +static const set valid_formats = {"json", "json-formatted"}; LogTriggerSection::LogTriggerSection( const string &_name, @@ -119,12 +123,6 @@ LogTriggerSection::getTriggerName() const return name; } -bool -LogTriggerSection::operator<(const LogTriggerSection &other) const -{ - return getTriggerName() < other.getTriggerName(); -} - WebUserResponseTriggerSection::WebUserResponseTriggerSection( const string &_name, const string &_details_level, @@ -166,24 +164,15 @@ WebUserResponseTriggerSection::getTriggerId() const return id; } -const string & -WebUserResponseTriggerSection::getTriggerName() const -{ - return name; -} - -bool -WebUserResponseTriggerSection::operator<(const WebUserResponseTriggerSection &other) const -{ - return getTriggerName() < other.getTriggerName(); -} - void AppSecCustomResponseSpec::load(cereal::JSONInputArchive &archive_in) { dbgTrace(D_LOCAL_POLICY) << "Loading AppSec web user response spec"; parseAppsecJSONKey("http-response-code", httpResponseCode, archive_in, 403); parseAppsecJSONKey("mode", mode, archive_in, "block-page"); + if (valid_modes.count(mode) == 0) { + dbgWarning(D_LOCAL_POLICY) << "AppSec web user response mode invalid: " << mode; + } parseAppsecJSONKey("name", name, archive_in); if (mode == "block-page") { parseAppsecJSONKey( @@ -201,6 +190,12 @@ AppSecCustomResponseSpec::load(cereal::JSONInputArchive &archive_in) } } +void +AppSecCustomResponseSpec::setName(const string &_name) +{ + name = _name; +} + int AppSecCustomResponseSpec::getHttpResponseCode() const { @@ -248,18 +243,6 @@ AppsecTriggerAccessControlLogging::load(cereal::JSONInputArchive &archive_in) parseAppsecJSONKey("drop-events", drop_events, archive_in, false); } -bool -AppsecTriggerAccessControlLogging::isAllowEvents() const -{ - return allow_events; -} - -bool -AppsecTriggerAccessControlLogging::isDropEvents() const -{ - return drop_events; -} - void AppsecTriggerAdditionalSuspiciousEventsLogging::load(cereal::JSONInputArchive &archive_in) { @@ -267,6 +250,11 @@ AppsecTriggerAdditionalSuspiciousEventsLogging::load(cereal::JSONInputArchive &a parseAppsecJSONKey("enabled", enabled, archive_in, true); parseAppsecJSONKey("response-body", response_body, archive_in, false); parseAppsecJSONKey("minimum-severity", minimum_severity, archive_in, "high"); + if (valid_severities.count(minimum_severity) == 0) { + dbgWarning(D_LOCAL_POLICY) + << "AppSec AppSec Trigger - Additional Suspicious Events Logging minimum severity invalid: " + << minimum_severity; + } } bool @@ -353,6 +341,10 @@ LoggingService::load(cereal::JSONInputArchive &archive_in) { parseAppsecJSONKey("address", address, archive_in); parseAppsecJSONKey("proto", proto, archive_in); + if (valid_protocols.count(proto) == 0) { + dbgWarning(D_LOCAL_POLICY) << "AppSec Logging Service - proto invalid: " << proto; + } + parseAppsecJSONKey("port", port, archive_in, 514); } @@ -362,12 +354,6 @@ LoggingService::getAddress() const return address; } -const string & -LoggingService::getProto() const -{ - return proto; -} - int LoggingService::getPort() const { @@ -379,6 +365,9 @@ void StdoutLogging::load(cereal::JSONInputArchive &archive_in) { parseAppsecJSONKey("format", format, archive_in, "json"); + if (valid_formats.count(format) == 0) { + dbgWarning(D_LOCAL_POLICY) << "AppSec Stdout Logging - format invalid: " << format; + } } const string & @@ -488,10 +477,10 @@ AppsecTriggerSpec::load(cereal::JSONInputArchive &archive_in) parseAppsecJSONKey("name", name, archive_in); } -const AppsecTriggerAccessControlLogging & -AppsecTriggerSpec::getAppsecTriggerAccessControlLogging() const +void +AppsecTriggerSpec::setName(const string &_name) { - return access_control_logging; + name = _name; } const string & @@ -531,5 +520,3 @@ TriggersWrapper::save(cereal::JSONOutputArchive &out_ar) const cereal::make_nvp("rulebase", triggers_rulebase) ); } - -// LCOV_EXCL_STOP diff --git a/components/security_apps/orchestration/local_policy_mgmt_gen/trusted_sources_section.cc b/components/security_apps/orchestration/local_policy_mgmt_gen/trusted_sources_section.cc index 3ed8e23..f8053a4 100644 --- a/components/security_apps/orchestration/local_policy_mgmt_gen/trusted_sources_section.cc +++ b/components/security_apps/orchestration/local_policy_mgmt_gen/trusted_sources_section.cc @@ -16,7 +16,8 @@ using namespace std; USE_DEBUG_FLAG(D_LOCAL_POLICY); -// LCOV_EXCL_START Reason: no test exist + +static const set valid_source_identifiers = {"headerkey", "JWTKey", "cookie", "sourceip", "x-forwarded-for"}; void TrustedSourcesSpec::load(cereal::JSONInputArchive &archive_in) @@ -27,6 +28,12 @@ TrustedSourcesSpec::load(cereal::JSONInputArchive &archive_in) parseAppsecJSONKey("name", name, archive_in); } +void +TrustedSourcesSpec::setName(const string &_name) +{ + name = _name; +} + int TrustedSourcesSpec::getMinNumOfSources() const { @@ -63,8 +70,11 @@ SourcesIdentifiers::getSourceIdent() const void SourceIdentifierSpec::load(cereal::JSONInputArchive &archive_in) { - dbgTrace(D_LOCAL_POLICY) << "Loading trusted sources spec"; + dbgTrace(D_LOCAL_POLICY) << "Loading source identifiers spec"; parseAppsecJSONKey("sourceIdentifier", source_identifier, archive_in); + if (valid_source_identifiers.count(source_identifier) == 0) { + dbgWarning(D_LOCAL_POLICY) << "AppSec source identifier invalid: " << source_identifier; + } parseAppsecJSONKey>("value", value, archive_in); } @@ -88,6 +98,12 @@ SourceIdentifierSpecWrapper::load(cereal::JSONInputArchive &archive_in) parseAppsecJSONKey("name", name, archive_in); } +void +SourceIdentifierSpecWrapper::setName(const string &_name) +{ + name = _name; +} + const string & SourceIdentifierSpecWrapper::getName() const { @@ -134,5 +150,3 @@ AppSecTrustedSources::getSourcesIdentifiers() const { return sources_identifiers; } - -// LCOV_EXCL_STOP diff --git a/components/security_apps/orchestration/orchestration_comp.cc b/components/security_apps/orchestration/orchestration_comp.cc index 9d27474..6adffe9 100755 --- a/components/security_apps/orchestration/orchestration_comp.cc +++ b/components/security_apps/orchestration/orchestration_comp.cc @@ -38,6 +38,8 @@ #include "hybrid_mode_telemetry.h" #include "telemetry.h" #include "tenant_profile_pair.h" +#include "env_details.h" +#include "hybrid_communication.h" using namespace std; using namespace chrono; @@ -1342,49 +1344,11 @@ private: << LogField("agentType", "Orchestration") << LogField("agentVersion", Version::get()); - auto email = getSettingWithDefault("", "email-address"); - if (email == "") { - auto env_email = getenv("user_email"); - if (env_email != nullptr) email = env_email; - } - if (email != "") { - dbgInfo(D_ORCHESTRATOR) << "Sending registration data"; - Singleton::Consume::by()->addOneTimeRoutine( - I_MainLoop::RoutineType::Offline, - // LCOV_EXCL_START Reason: to be refactored - [email] () - { - Report registration_report( - "Local Agent Data", - Singleton::Consume::by()->getWalltime(), - Type::EVENT, - Level::LOG, - LogLevel::INFO, - Audience::INTERNAL, - AudienceTeam::NONE, - Severity::INFO, - Priority::LOW, - chrono::seconds(0), - LogField("agentId", Singleton::Consume::by()->getAgentId()), - Tags::ORCHESTRATOR - ); - registration_report << LogField("userDefinedId", email); - - LogRest registration_report_rest(registration_report); - - Singleton::Consume::by()->sendObjectWithPersistence( - registration_report_rest, - I_Messaging::Method::POST, - "/api/v1/agents/events", - "", - true, - MessageTypeTag::REPORT - ); - }, - // LCOV_EXCL_STOP - "Send registration data" - ); - } + Singleton::Consume::by()->addOneTimeRoutine( + I_MainLoop::RoutineType::Offline, + sendRegistrationData, + "Send registration data" + ); reportAgentDetailsMetaData(); @@ -1453,6 +1417,72 @@ private: } } + static void + sendRegistrationData() + { + dbgInfo(D_ORCHESTRATOR) << "Sending registration data"; + + set tags{ Tags::ORCHESTRATOR }; + + auto deployment_type = Singleton::Consume::by()->getEnvType(); + switch (deployment_type) { + case EnvType::LINUX: { + tags.insert(Tags::DEPLOYMENT_EMBEDDED); + break; + } + case EnvType::K8S: { + tags.insert(Tags::DEPLOYMENT_K8S); + break; + } + case EnvType::COUNT: { + dbgWarning(D_ORCHESTRATOR) << "Could not identify deployment type"; + break; + } + } + + string server_name = getAttribute("registered-server", "registered_server"); + auto server = TagAndEnumManagement::convertStringToTag(server_name); + if (server.ok()) tags.insert(*server); + + Report registration_report( + "Local Agent Data", + Singleton::Consume::by()->getWalltime(), + Type::EVENT, + Level::LOG, + LogLevel::INFO, + Audience::INTERNAL, + AudienceTeam::NONE, + Severity::INFO, + Priority::LOW, + chrono::seconds(0), + LogField("agentId", Singleton::Consume::by()->getAgentId()), + tags + ); + + auto email = getAttribute("email-address", "user_email"); + if (email != "") registration_report << LogField("userDefinedId", email); + + LogRest registration_report_rest(registration_report); + Singleton::Consume::by()->sendObjectWithPersistence( + registration_report_rest, + I_Messaging::Method::POST, + "/api/v1/agents/events", + "", + true, + MessageTypeTag::REPORT + ); + } + + static string + getAttribute(const string &setting, const string &env) + { + auto res = getSetting(setting); + if (res.ok()) return res.unpack(); + auto env_res = getenv(env.c_str()); + if (env_res != nullptr) return env_res; + return ""; + } + // LCOV_EXCL_START Reason: future changes will be done void restoreToBackup() @@ -1672,6 +1702,7 @@ private: OrchestrationPolicy policy; HealthCheckStatusListener health_check_status_listener; HybridModeMetric hybrid_mode_metric; + EnvDetails env_details; string filesystem_prefix = ""; }; @@ -1728,6 +1759,7 @@ OrchestrationComp::preload() registerExpectedSetting("agentType"); registerExpectedSetting("upgradeMode"); registerExpectedSetting("email-address"); + registerExpectedSetting("registered-server"); registerExpectedConfigFile("orchestration", Config::ConfigFileType::Policy); registerExpectedConfigFile("registration-data", Config::ConfigFileType::Policy); } diff --git a/components/security_apps/orchestration/orchestration_ut/CMakeLists.txt b/components/security_apps/orchestration/orchestration_ut/CMakeLists.txt index 07d9ae1..d50db79 100755 --- a/components/security_apps/orchestration/orchestration_ut/CMakeLists.txt +++ b/components/security_apps/orchestration/orchestration_ut/CMakeLists.txt @@ -5,11 +5,11 @@ link_directories(${BOOST_ROOT}/lib) add_unit_test( orchestration_ut "orchestration_ut.cc" - "orchestration;rest;manifest_controller;service_controller;orchestration_downloader;agent_details;package_handler;orchestration_modules;orchestration_tools;environment;config;logging;version;shell_cmd;message;update_communication;agent_details_reporter;connkey;encryptor;metric;ip_utilities;event_is;-lcrypto;-lboost_filesystem;-lboost_regex;-lssl" + "orchestration;rest;manifest_controller;service_controller;orchestration_downloader;agent_details;package_handler;orchestration_modules;orchestration_tools;env_details;environment;config;logging;version;shell_cmd;message;update_communication;agent_details_reporter;connkey;encryptor;metric;ip_utilities;event_is;-lcrypto;-lboost_filesystem;-lboost_regex;-lssl" ) add_unit_test( orchestration_multitenant_ut "orchestration_multitenant_ut.cc" - "orchestration;rest;manifest_controller;service_controller;orchestration_downloader;agent_details;package_handler;orchestration_modules;orchestration_tools;environment;config;logging;version;shell_cmd;message;update_communication;agent_details_reporter;connkey;encryptor;metric;ip_utilities;event_is;-lcrypto;-lboost_filesystem;-lboost_regex;-lssl;curl" + "orchestration;rest;manifest_controller;service_controller;orchestration_downloader;agent_details;package_handler;orchestration_modules;orchestration_tools;env_details;environment;config;logging;version;shell_cmd;message;update_communication;agent_details_reporter;connkey;encryptor;metric;ip_utilities;event_is;-lcrypto;-lboost_filesystem;-lboost_regex;-lssl;curl" ) diff --git a/components/security_apps/orchestration/orchestration_ut/orchestration_multitenant_ut.cc b/components/security_apps/orchestration/orchestration_ut/orchestration_multitenant_ut.cc index eca3c5a..bdebc35 100644 --- a/components/security_apps/orchestration/orchestration_ut/orchestration_multitenant_ut.cc +++ b/components/security_apps/orchestration/orchestration_ut/orchestration_multitenant_ut.cc @@ -44,6 +44,10 @@ public: mock_ml, addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Configuration update registration", false) ).WillOnce(Return(0)); + EXPECT_CALL( + mock_ml, + addOneTimeRoutine(I_MainLoop::RoutineType::Offline, _, "Send registration data", false) + ).WillRepeatedly(Return(0)); config_comp.preload(); config_comp.init(); diff --git a/components/security_apps/orchestration/orchestration_ut/orchestration_ut.cc b/components/security_apps/orchestration/orchestration_ut/orchestration_ut.cc index a11a165..6a01003 100755 --- a/components/security_apps/orchestration/orchestration_ut/orchestration_ut.cc +++ b/components/security_apps/orchestration/orchestration_ut/orchestration_ut.cc @@ -84,7 +84,6 @@ public: mockRestCall(RestAction::SET, "agent-uninstall", _) ).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandlerAgentUninstall))); - string message_body; EXPECT_CALL(mock_message, mockSendPersistentMessage( false, _, @@ -221,6 +220,11 @@ public: void runRoutine() { + EXPECT_CALL( + mock_ml, + addOneTimeRoutine(I_MainLoop::RoutineType::Offline, _, "Send registration data", false) + ).WillOnce(DoAll(SaveArg<1>(&sending_routine), Return(1))); + routine(); } @@ -288,6 +292,8 @@ public: NiceMock tenant_manager; OrchestrationComp orchestration_comp; AgentDetails agent_details; + I_MainLoop::Routine sending_routine; + string message_body; private: bool @@ -466,15 +472,74 @@ TEST_F(OrchestrationTest, registertion_data_config) string config_json = "{\n" - " \"email-address\": \"fake@example.com\"\n" + " \"email-address\": \"fake@example.com\",\n" + " \"registered-server\": \"NGINX Server\"\n" "}"; istringstream ss(config_json); Singleton::Consume::from(config_comp)->loadConfiguration(ss); EXPECT_THAT(getSetting("email-address"), IsValue("fake@example.com")); + EXPECT_THAT(getSetting("registered-server"), IsValue("NGINX Server")); env.fini(); } +TEST_F(OrchestrationTest, check_sending_registration_data) +{ + EXPECT_CALL(rest, mockRestCall(_, _, _)).WillRepeatedly(Return(true)); + + preload(); + env.init(); + init(); + + EXPECT_CALL(mock_orchestration_tools, doesFileExist(_)).WillOnce(Return(false)); + Maybe response( + string( + "{\n" + " \"fog-address\": \"" + host_url + "\",\n" + " \"agent-type\": \"test\",\n" + " \"pulling-interval\": 25,\n" + " \"error-pulling-interval\": 15\n" + "}" + ) + ); + EXPECT_CALL(mock_orchestration_tools, readFile(_)).WillOnce(Return(response)); + EXPECT_CALL(mock_service_controller, updateServiceConfiguration(_, _, _, _, _, _)).WillOnce(Return(true)); + EXPECT_CALL(mock_message, setActiveFog(_, _, _, _)).WillOnce(Return(true)); + EXPECT_CALL(mock_orchestration_tools, calculateChecksum(_, _)).WillRepeatedly(Return(string())); + EXPECT_CALL(mock_service_controller, getPolicyVersion()).WillRepeatedly(ReturnRef(first_policy_version)); + EXPECT_CALL(mock_shell_cmd, getExecOutput(_, _, _)).WillRepeatedly(Return(string())); + EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe())); + EXPECT_CALL(mock_update_communication, setAddressExtenesion(_)); + EXPECT_CALL(mock_status, setFogAddress(_)); + EXPECT_CALL(mock_manifest_controller, loadAfterSelfUpdate()).WillOnce(Return(false)); + expectDetailsResolver(); + EXPECT_CALL(mock_update_communication, getUpdate(_)); + EXPECT_CALL(mock_status, setLastUpdateAttempt()); + EXPECT_CALL(mock_status, setFieldStatus(_, _, _)); + EXPECT_CALL(mock_status, setIsConfigurationUpdated(_)); + + EXPECT_CALL(mock_ml, yield(A())) + .WillOnce(Return()) + .WillOnce(Invoke([] (chrono::microseconds) { throw invalid_argument("stop while loop"); })); + try { + runRoutine(); + } catch (const invalid_argument& e) {} + + string config_json = + "{\n" + " \"email-address\": \"fake@example.com\",\n" + " \"registered-server\": \"NGINX Server\"\n" + "}"; + + istringstream ss(config_json); + Singleton::Consume::from(config_comp)->loadConfiguration(ss); + sending_routine(); + + EXPECT_THAT(message_body, HasSubstr("\"userDefinedId\": \"fake@example.com\"")); + EXPECT_THAT(message_body, AnyOf(HasSubstr("\"Embedded Deployment\""), HasSubstr("\"Kubernetes Deployment\""))); + EXPECT_THAT(message_body, HasSubstr("\"NGINX Server\"")); +} + TEST_F(OrchestrationTest, orchestrationPolicyUpdate) { waitForRestCall(); diff --git a/components/security_apps/orchestration/update_communication/declarative_policy_utils.cc b/components/security_apps/orchestration/update_communication/declarative_policy_utils.cc index ba300e0..38ea9bf 100755 --- a/components/security_apps/orchestration/update_communication/declarative_policy_utils.cc +++ b/components/security_apps/orchestration/update_communication/declarative_policy_utils.cc @@ -35,8 +35,8 @@ DeclarativePolicyUtils::upon(const ApplyPolicyEvent &) bool DeclarativePolicyUtils::shouldApplyPolicy() { - auto env_type = Singleton::Consume::by()->getEnvType(); - return env_type == I_LocalPolicyMgmtGen::LocalPolicyEnv::K8S ? true : should_apply_policy; + auto env_type = Singleton::Consume::by()->getEnvType(); + return env_type == EnvType::K8S ? true : should_apply_policy; } void @@ -49,8 +49,8 @@ Maybe DeclarativePolicyUtils::getLocalPolicyChecksum() { I_OrchestrationTools *orchestration_tools = Singleton::Consume::by(); - auto env_type = Singleton::Consume::by()->getEnvType(); - if (env_type == I_LocalPolicyMgmtGen::LocalPolicyEnv::K8S) { + auto env_type = Singleton::Consume::by()->getEnvType(); + if (env_type == EnvType::K8S) { return orchestration_tools->readFile("/etc/cp/conf/k8s-policy-check.trigger"); } @@ -121,8 +121,8 @@ DeclarativePolicyUtils::sendUpdatesToFog( + " --access_token " + access_token + " --tenant_id " + tenant_id + " --profile_id " + profile_id; - auto env = Singleton::Consume::by()->getEnvType(); - if (env == I_LocalPolicyMgmtGen::LocalPolicyEnv::K8S) { + auto env = Singleton::Consume::by()->getEnvType(); + if (env == EnvType::K8S) { exec_command = getFilesystemPathConfig() + "/scripts/open-appsec-cloud-mgmt-k8s" diff --git a/components/security_apps/orchestration/update_communication/hybrid_communication.cc b/components/security_apps/orchestration/update_communication/hybrid_communication.cc index b402f5e..997d806 100755 --- a/components/security_apps/orchestration/update_communication/hybrid_communication.cc +++ b/components/security_apps/orchestration/update_communication/hybrid_communication.cc @@ -78,8 +78,8 @@ HybridCommunication::getUpdate(CheckUpdateRequest &request) string policy_response = declarative_policy_utils.getUpdate(request); - auto env = Singleton::Consume::by()->getEnvType(); - if (env == I_LocalPolicyMgmtGen::LocalPolicyEnv::K8S && !policy_response.empty()) { + auto env = Singleton::Consume::by()->getEnvType(); + if (env == EnvType::K8S && !policy_response.empty()) { dbgDebug(D_ORCHESTRATOR) << "Policy has changes, sending notification to tuning host"; I_AgentDetails *agentDetails = Singleton::Consume::by(); I_Messaging *messaging = Singleton::Consume::by(); diff --git a/components/security_apps/waap/include/i_serialize.h b/components/security_apps/waap/include/i_serialize.h index d47e07d..ee1c43d 100755 --- a/components/security_apps/waap/include/i_serialize.h +++ b/components/security_apps/waap/include/i_serialize.h @@ -21,6 +21,7 @@ #include "i_agent_details.h" static const uint max_send_obj_retries = 3; +static const std::chrono::microseconds wait_next_attempt(5000000); USE_DEBUG_FLAG(D_WAAP); @@ -189,7 +190,7 @@ protected: return true; } dbgWarning(D_WAAP) << "Failed to send object. Attempt: " << i; - mainloop->yield(true); + mainloop->yield(wait_next_attempt); } dbgError(D_WAAP) << "Failed to send object to " << uri << ", reached maximum attempts: " << max_send_obj_retries; @@ -243,7 +244,7 @@ protected: return true; } dbgWarning(D_WAAP) << "Failed to send object. Attempt: " << i; - mainloop->yield(true); + mainloop->yield(wait_next_attempt); } dbgError(D_WAAP) << "Failed to send object to " << uri << ", reached maximum attempts: " << max_send_obj_retries; diff --git a/components/security_apps/waap/waap_clib/DeepParser.cc b/components/security_apps/waap/waap_clib/DeepParser.cc index 331c2e4..36fb493 100755 --- a/components/security_apps/waap/waap_clib/DeepParser.cc +++ b/components/security_apps/waap/waap_clib/DeepParser.cc @@ -323,6 +323,8 @@ int DeepParser::onKv(const char* k, size_t k_len, const char* v, size_t v_len, i if (shouldUpdateKeyStack) { m_key.pop("deep parser key"); } + + m_depth--; return rc; } @@ -1013,6 +1015,7 @@ void DeepParser::createInternalParser(const char *k, size_t k_len, std::string& } } + void DeepParser::apiProcessKey(const char* v, size_t v_len) { // Build dot-formatted full keyword name diff --git a/components/security_apps/waap/waap_clib/WaapAssetState.cc b/components/security_apps/waap/waap_clib/WaapAssetState.cc index 55dd107..493b308 100755 --- a/components/security_apps/waap/waap_clib/WaapAssetState.cc +++ b/components/security_apps/waap/waap_clib/WaapAssetState.cc @@ -102,8 +102,6 @@ static const boost::regex utf_evasion_for_dot_regex(utf_evasion_for_dot_helper); static const std::string sqli_comma_evasion_regex_helper = "\"\\s*,\\s*\""; static const boost::regex sqli_comma_evasion_regex(sqli_comma_evasion_regex_helper); -static const boost::regex space_evasion_regex("[[:space:]]{2,}"); - WaapAssetState::WaapAssetState(const std::shared_ptr& pWaapAssetState, const std::string& waapDataFileName, const std::string& id) : @@ -279,10 +277,6 @@ WaapAssetState::WaapAssetState(std::shared_ptr signatures, return; } - boost::cmatch what; - if (!boost::regex_search(text.c_str(), what, space_evasion_regex)) - return; - dbgTrace(D_WAAP) << "Boost regex passed"; for (;position < text.size(); position++) { code = text[position]; switch (code) { diff --git a/components/security_apps/waap/waap_clib/WaapConfigApi.cc b/components/security_apps/waap/waap_clib/WaapConfigApi.cc index c75c5ae..c2502e6 100755 --- a/components/security_apps/waap/waap_clib/WaapConfigApi.cc +++ b/components/security_apps/waap/waap_clib/WaapConfigApi.cc @@ -56,47 +56,14 @@ WaapConfigAPI::clearAssetsCount() WaapConfigAPI::assets_ids_aggregation.clear(); } -#if 0 // maybe will be used in the future -WaapConfigAPI::WaapConfigAPI( - bool autonomousSecurity, - string autonomousSecurityLevel, - string assetId, - string assetName, - string practiceId, - string practiceName, - string ruleId, - string ruleName, - bool schemaValidation) : - WaapConfigBase( - autonomousSecurity, - autonomousSecurityLevel, - assetId, - assetName, - practiceId, - practiceName, - ruleId, - ruleName), - m_schemaValidation(schemaValidation) -{ -} -#endif - void WaapConfigAPI::load(cereal::JSONInputArchive& ar) { // order has affect - we need to call base last because of triggers and overrides - readJSONByCereal(ar); - - WaapConfigBase::load(ar); assets_ids_aggregation.insert(m_assetId); } -void WaapConfigAPI::readJSONByCereal(cereal::JSONInputArchive &ar) -{ -} - - bool WaapConfigAPI::operator==(const WaapConfigAPI& other) const { const WaapConfigBase* configBase = this; @@ -114,4 +81,3 @@ const string& WaapConfigAPI::get_PracticeSubType() const { return s_PracticeSubType; } - diff --git a/components/security_apps/waap/waap_clib/WaapConfigApi.h b/components/security_apps/waap/waap_clib/WaapConfigApi.h index 936108d..7c16d07 100755 --- a/components/security_apps/waap/waap_clib/WaapConfigApi.h +++ b/components/security_apps/waap/waap_clib/WaapConfigApi.h @@ -18,7 +18,6 @@ #include #include "WaapConfigBase.h" - #include "log_generator.h" #include "debug.h" @@ -26,18 +25,6 @@ class WaapConfigAPI : public WaapConfigBase { public: WaapConfigAPI(); -#if 0 // maybe will be used in the future - WaapConfigAPI( - bool autonomousSecurity, - std::string autonomousSecurityLevel, - std::string assetId, - std::string assetName, - std::string practiceId, - std::string practiceName, - std::string ruleId, - std::string ruleName, - bool schemaValidation); -#endif void load(cereal::JSONInputArchive& ar); bool operator==(const WaapConfigAPI& other) const; @@ -49,10 +36,6 @@ public: static void clearAssetsCount(); private: - void readJSONByCereal(cereal::JSONInputArchive&ar); - - - std::string m_schemaValidationPoicyStatusMessage; static const std::string s_PracticeSubType; static std::set assets_ids; diff --git a/components/security_apps/waap/waap_clib/WaapConfigApplication.cc b/components/security_apps/waap/waap_clib/WaapConfigApplication.cc index 9a26df6..6a0de36 100755 --- a/components/security_apps/waap/waap_clib/WaapConfigApplication.cc +++ b/components/security_apps/waap/waap_clib/WaapConfigApplication.cc @@ -72,12 +72,15 @@ const string& WaapConfigApplication::get_PracticeSubType() const void WaapConfigApplication::load(cereal::JSONInputArchive& ar) { - WaapConfigBase::load(ar); + // order has affect - we need to call base last because of triggers and overrides + + loadOpenRedirectPolicy(ar); loadErrorDisclosurePolicy(ar); loadCsrfPolicy(ar); loadSecurityHeadersPolicy(ar); + WaapConfigBase::load(ar); assets_ids_aggregation.insert(m_assetId); } diff --git a/components/security_apps/waap/waap_clib/WaapConfigApplication.h b/components/security_apps/waap/waap_clib/WaapConfigApplication.h index b866abe..b22f3d4 100755 --- a/components/security_apps/waap/waap_clib/WaapConfigApplication.h +++ b/components/security_apps/waap/waap_clib/WaapConfigApplication.h @@ -29,18 +29,6 @@ class WaapConfigApplication { public: WaapConfigApplication(); -#if 0 // maybe will be used in the future - WaapConfigApplication( - bool autonomousSecurity, - std::string autonomousSecurityLevel, - std::string assetId, - std::string assetName, - std::string practiceId, - std::string practiceName, - std::string ruleId, - std::string ruleName, - bool botProtection); -#endif bool operator==(const WaapConfigApplication& other) const; diff --git a/components/security_apps/waap/waap_clib/WaapConfigBase.cc b/components/security_apps/waap/waap_clib/WaapConfigBase.cc index 0f34e93..74f29e3 100755 --- a/components/security_apps/waap/waap_clib/WaapConfigBase.cc +++ b/components/security_apps/waap/waap_clib/WaapConfigBase.cc @@ -23,7 +23,9 @@ #include "Waf2Util.h" USE_DEBUG_FLAG(D_WAAP_ULIMITS); +USE_DEBUG_FLAG(D_WAAP); using boost::algorithm::to_lower_copy; +using namespace std; WaapConfigBase::WaapConfigBase() : diff --git a/components/security_apps/waap/waap_clib/WaapConfigBase.h b/components/security_apps/waap/waap_clib/WaapConfigBase.h index cc15ebf..3a15bc5 100755 --- a/components/security_apps/waap/waap_clib/WaapConfigBase.h +++ b/components/security_apps/waap/waap_clib/WaapConfigBase.h @@ -96,6 +96,7 @@ private: std::shared_ptr m_waapParameters; std::shared_ptr m_openRedirectPolicy; std::shared_ptr m_errorDisclosurePolicy; + std::string m_schemaValidationPoicyStatusMessage; std::shared_ptr m_csrfPolicy; std::shared_ptr m_rateLimitingPolicy; std::shared_ptr m_errorLimitingPolicy; diff --git a/components/security_apps/waap/waap_clib/Waf2Engine.cc b/components/security_apps/waap/waap_clib/Waf2Engine.cc index 4bf3315..7541503 100755 --- a/components/security_apps/waap/waap_clib/Waf2Engine.cc +++ b/components/security_apps/waap/waap_clib/Waf2Engine.cc @@ -553,7 +553,6 @@ bool Waf2Transaction::checkIsScanningRequired() auto csrfPolicy = m_siteConfig ? m_siteConfig->get_CsrfPolicy() : NULL; auto userLimitsPolicy = m_siteConfig ? m_siteConfig->get_UserLimitsPolicy() : nullptr; result |= m_siteConfig->get_WebAttackMitigation(); - if (rateLimitingPolicy) { result |= m_siteConfig->get_RateLimitingPolicy()->getRateLimitingEnforcementStatus(); } @@ -1007,7 +1006,6 @@ void Waf2Transaction::add_request_hdr(const char* name, int name_len, const char } void Waf2Transaction::end_request_hdrs() { - dbgFlow(D_WAAP) << "[transaction:" << this << "] end_request_hdrs"; m_isScanningRequired = setCurrentAssetContext(); if (m_siteConfig != NULL) @@ -1468,23 +1466,20 @@ Waf2Transaction::decideFinal( sitePolicy = &ngenAPIConfig; m_overrideState = getOverrideState(sitePolicy); - // User limits - shouldBlock = (getUserLimitVerdict() == ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP); } else if (WaapConfigApplication::getWaapSiteConfig(ngenSiteConfig)) { dbgTrace(D_WAAP) << "Waf2Transaction::decideFinal(): got relevant Application configuration from the I/S"; sitePolicy = &ngenSiteConfig; m_overrideState = getOverrideState(sitePolicy); - // Autonomus Security shouldBlock = decideAutonomousSecurity( *sitePolicy, mode, false, transactionResult, realPoolName, - fpClassification - ); + fpClassification); + // CSRF Protection auto csrfPolicy = m_siteConfig ? m_siteConfig->get_CsrfPolicy() : nullptr; if(csrfPolicy && csrfPolicy->enable) { diff --git a/components/security_apps/waap/waap_clib/Waf2Engine.h b/components/security_apps/waap/waap_clib/Waf2Engine.h index 514f8ff..e8114ca 100755 --- a/components/security_apps/waap/waap_clib/Waf2Engine.h +++ b/components/security_apps/waap/waap_clib/Waf2Engine.h @@ -184,7 +184,6 @@ public: void handleSecurityHeadersInjection(std::vector>& injectHeaderStrs); void disableShouldInjectSecurityHeaders(); - bool shouldSendExtendedLog(const std::shared_ptr &trigger_log) const; // query diff --git a/components/utils/pm/pm_hook.cc b/components/utils/pm/pm_hook.cc index 5ecb239..21f071a 100644 --- a/components/utils/pm/pm_hook.cc +++ b/components/utils/pm/pm_hook.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include "kiss_patterns.h" #include "kiss_thin_nfa_impl.h" @@ -100,12 +101,10 @@ PMHook::prepare(const set &inputs) return Maybe(); } - set PMHook::scanBuf(const Buffer &buf) const { dbgAssert(handle != nullptr) << "Unusable Pattern Matcher"; - vector> pm_matches; kiss_thin_nfa_exec(handle.get(), buf, pm_matches); dbgTrace(D_PM) << pm_matches.size() << " raw matches found"; @@ -118,7 +117,7 @@ PMHook::scanBuf(const Buffer &buf) const return res; } -set> +set> PMHook::scanBufWithOffset(const Buffer &buf) const { dbgAssert(handle != nullptr) << "Unusable Pattern Matcher"; @@ -127,10 +126,7 @@ PMHook::scanBufWithOffset(const Buffer &buf) const kiss_thin_nfa_exec(handle.get(), buf, pm_matches); dbgTrace(D_PM) << pm_matches.size() << " raw matches found"; - set> res; - for (auto &match : pm_matches) { - res.emplace(match.second, patterns.at(match.first)); - } + set> res(pm_matches.begin(), pm_matches.end()); dbgTrace(D_PM) << res.size() << " matches found"; return res; } @@ -138,9 +134,14 @@ PMHook::scanBufWithOffset(const Buffer &buf) const void PMHook::scanBufWithOffsetLambda(const Buffer &buf, function cb) const { + dbgAssert(handle != nullptr) << "Unusable Pattern Matcher"; - for (auto &res : scanBufWithOffset(buf)) { - cb(res.first, res.second); + vector> pm_matches; + kiss_thin_nfa_exec(handle.get(), buf, pm_matches); + dbgTrace(D_PM) << pm_matches.size() << " raw matches found"; + + for (auto &res : pm_matches) { + cb(res.second, patterns.at(res.first)); } } diff --git a/components/utils/pm/pm_ut/pm_scan_ut.cc b/components/utils/pm/pm_ut/pm_scan_ut.cc index 12961e8..ab8f38c 100644 --- a/components/utils/pm/pm_ut/pm_scan_ut.cc +++ b/components/utils/pm/pm_ut/pm_scan_ut.cc @@ -16,6 +16,18 @@ push_pat(set &pats, const string &hex_pat) pats.insert(*pat); } + +static uint +get_index_in_set(const set &input_set, const PMPattern &input_elem) +{ + uint index = 1; + for (auto &elem : input_set) { + if (input_elem == elem) return index; + index++; + } + return index; +} + static set getPatternSet(const string &pattern) { @@ -262,9 +274,9 @@ TEST(pm_scan, scan_with_offsets) PMHook pm; ASSERT_TRUE(pm.prepare(pats).ok()); - set> res; - res.emplace(2, PMHook::lineToPattern("ABC").unpackMove()); - res.emplace(8, PMHook::lineToPattern("ABC").unpackMove()); + set> res; + res.emplace(get_index_in_set(pats, PMHook::lineToPattern("ABC").unpackMove()), 2); + res.emplace(get_index_in_set(pats, PMHook::lineToPattern("ABC").unpackMove()), 8); EXPECT_THAT(pm.scanBufWithOffset(buf3), ContainerEq(res)); } @@ -305,14 +317,14 @@ TEST(pm_scan, pm_offsets_test_multiple_matches) ASSERT_TRUE(pm.prepare(initPatts).ok()); Buffer buf("hex()"); - std::set> results = pm.scanBufWithOffset(buf); + std::set> results = pm.scanBufWithOffset(buf); - std::set> expected{ - {1, {"he", false, false, 0}}, - {2, {"ex", false, false, 0}}, - {2, {"hex", false, false, 2}}, - {3, {"(", false, false, 5}}, - {4, {")", false, false, 7}} + std::set> expected{ + {get_index_in_set(initPatts, {"he", false, false, 0}), 1}, + {get_index_in_set(initPatts, {"ex", false, false, 0}), 2}, + {get_index_in_set(initPatts, {"hex", false, false, 2}), 2}, + {get_index_in_set(initPatts, {"(", false, false, 5}), 3}, + {get_index_in_set(initPatts, {")", false, false, 7}), 4} }; EXPECT_EQ(results, expected); @@ -327,10 +339,10 @@ TEST(pm_scan, pm_offsets_test_one_char_match) ASSERT_TRUE(pm.prepare(initPatts).ok()); Buffer buf("/"); - std::set> results = pm.scanBufWithOffset(buf); + std::set> results = pm.scanBufWithOffset(buf); - std::set> expected{ - {0, {"/", false, false, 0}} + std::set> expected{ + {get_index_in_set(initPatts, {"/", false, false, 0}), 0} }; EXPECT_EQ(results, expected); @@ -345,10 +357,10 @@ TEST(pm_scan, pm_offsets_test_one_char_at_end_match) ASSERT_TRUE(pm.prepare(initPatts).ok()); Buffer buf("abc/"); - std::set> results = pm.scanBufWithOffset(buf); + std::set> results = pm.scanBufWithOffset(buf); - std::set> expected{ - {3, {"/", false, false, 0}} + std::set> expected{ + {get_index_in_set(initPatts, {"/", false, false, 0}), 3} }; EXPECT_EQ(results, expected); @@ -363,10 +375,10 @@ TEST(pm_scan, pm_offsets_test_one_char_at_start_match) ASSERT_TRUE(pm.prepare(initPatts).ok()); Buffer buf("/abc"); - std::set> results = pm.scanBufWithOffset(buf); + std::set> results = pm.scanBufWithOffset(buf); - std::set> expected{ - {0, {"/", false, false, 0}} + std::set> expected{ + {get_index_in_set(initPatts, {"/", false, false, 0}), 0} }; EXPECT_EQ(results, expected); @@ -381,10 +393,10 @@ TEST(pm_scan, pm_offsets_test_word_full_match) ASSERT_TRUE(pm.prepare(initPatts).ok()); Buffer buf("abc"); - std::set> results = pm.scanBufWithOffset(buf); + std::set> results = pm.scanBufWithOffset(buf); - std::set> expected{ - {2, {"abc", false, false, 0}} + std::set> expected{ + {get_index_in_set(initPatts, {"abc", false, false, 0}), 2} }; EXPECT_EQ(results, expected); @@ -399,10 +411,10 @@ TEST(pm_scan, pm_offsets_test_word_at_start_match) ASSERT_TRUE(pm.prepare(initPatts).ok()); Buffer buf("application/x-www-form-urlencoded"); - std::set> results = pm.scanBufWithOffset(buf); + std::set> results = pm.scanBufWithOffset(buf); - std::set> expected{ - {10, {"application", false, false, 0}} + std::set> expected{ + {get_index_in_set(initPatts, {"application", false, false, 0}), 10} }; EXPECT_EQ(results, expected); @@ -417,10 +429,10 @@ TEST(pm_scan, pm_offsets_test_word_at_end_match) ASSERT_TRUE(pm.prepare(initPatts).ok()); Buffer buf("application/x-www-form-urlencoded"); - std::set> results = pm.scanBufWithOffset(buf); + std::set> results = pm.scanBufWithOffset(buf); - std::set> expected{ - {32, {"x-www-form-urlencoded", false, false, 0}} + std::set> expected{ + {get_index_in_set(initPatts, {"x-www-form-urlencoded", false, false, 0}), 32} }; EXPECT_EQ(results, expected); @@ -436,12 +448,12 @@ TEST(pm_scan, pm_offsets_test_pat_getIndex_method) EXPECT_TRUE(pm.prepare(initPatts).ok()); Buffer buf("12345ABCDEF5678"); - std::set> results = pm.scanBufWithOffset(buf); + std::set> results = pm.scanBufWithOffset(buf); - std::set> expected{ - {7, {"ABC", false, false, 0}}, - {8, {"ABCD", false, false, 4}}, - {9, {"CDE", false, false, 7}} + std::set> expected{ + {get_index_in_set(initPatts, {"ABC", false, false, 0}), 7}, + {get_index_in_set(initPatts, {"ABCD", false, false, 4}), 8}, + {get_index_in_set(initPatts, {"CDE", false, false, 7}), 9} }; EXPECT_EQ(results, expected); } @@ -456,12 +468,12 @@ TEST(pm_scan, pm_offsets_lambda_test_pat_getIndex_method) EXPECT_TRUE(pm.prepare(initPatts).ok()); Buffer buf("12345ABCDEF5678"); - std::vector> results; - pm.scanBufWithOffsetLambda(buf, [&] (uint offset, const PMPattern &pat) { results.emplace_back(offset, pat); }); + std::set> results; + pm.scanBufWithOffsetLambda(buf, [&] (uint offset, const PMPattern &pat) { results.emplace(offset, pat); }); - std::vector> expected{ - {7, {"ABC", false, false, 0}}, + std::set> expected{ {8, {"ABCD", false, false, 4}}, + {7, {"ABC", false, false, 0}}, {9, {"CDE", false, false, 7}} }; diff --git a/core/include/services_sdk/interfaces/i_env_details.h b/core/include/services_sdk/interfaces/i_env_details.h new file mode 100644 index 0000000..5348436 --- /dev/null +++ b/core/include/services_sdk/interfaces/i_env_details.h @@ -0,0 +1,32 @@ +// 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 __I_ENV_DETAILS_H__ +#define __I_ENV_DETAILS_H__ + +#include +#include + +enum class EnvType { LINUX, K8S, COUNT }; + +class I_EnvDetails +{ +public: + virtual EnvType getEnvType() = 0; + virtual std::string getToken() = 0; + +protected: + virtual ~I_EnvDetails() {} +}; + +#endif // __I_ENV_DETAILS_H__ diff --git a/core/include/services_sdk/resources/debug_flags.h b/core/include/services_sdk/resources/debug_flags.h index 6e0e546..11357b8 100755 --- a/core/include/services_sdk/resources/debug_flags.h +++ b/core/include/services_sdk/resources/debug_flags.h @@ -130,7 +130,7 @@ DEFINE_FLAG(D_COMPONENT, D_ALL) DEFINE_FLAG(D_SDWAN, D_COMPONENT) DEFINE_FLAG(D_SDWAN_POLICY, D_SDWAN) DEFINE_FLAG(D_SDWAN_DATA, D_SDWAN) - DEFINE_FLAG(D_SDWAN_LOGGER, D_SDWAN) + DEFINE_FLAG(D_LOGGER_SDWAN, D_SDWAN) DEFINE_FLAG(D_REVERSE_PROXY, D_COMPONENT) DEFINE_FLAG(D_PLATFORM, D_REVERSE_PROXY) DEFINE_FLAG(D_NGINX_MESSAGE_READER, D_REVERSE_PROXY) @@ -148,11 +148,12 @@ DEFINE_FLAG(D_COMPONENT, D_ALL) DEFINE_FLAG(D_IOT_ENFORCE_ASSETS, D_IOT_ENFORCE) DEFINE_FLAG(D_IOT_DOCTOR, D_IOT_NEXT) DEFINE_FLAG(D_IOT_RISK, D_IOT_NEXT) + DEFINE_FLAG(D_IOT_INDICATOR_DATA, D_IOT_RISK) + DEFINE_FLAG(D_IOT_INDICATORS, D_IOT_RISK) DEFINE_FLAG(D_IOT_DISCOVERY, D_IOT_NEXT) - DEFINE_FLAG(D_IOT_DISCOVERY_UTILS, D_IOT_DISCOVERY) - DEFINE_FLAG(D_IOT_PROBE, D_IOT_DISCOVERY_UTILS) - DEFINE_FLAG(D_IOT_ASSETS_DATA, D_IOT_DISCOVERY_UTILS) - DEFINE_FLAG(D_IOT_INTEGRATIONS, D_IOT_DISCOVERY_UTILS) + DEFINE_FLAG(D_IOT_PROBE, D_IOT_DISCOVERY) + DEFINE_FLAG(D_IOT_ASSETS_DATA, D_IOT_DISCOVERY) + DEFINE_FLAG(D_IOT_INTEGRATIONS, D_IOT_DISCOVERY) DEFINE_FLAG(D_HTTP_EVENT_RECORD, D_COMPONENT) DEFINE_FLAG(D_GEO_DB, D_COMPONENT) DEFINE_FLAG(D_CPVIEW_METRIC_PROVIDER, D_COMPONENT) diff --git a/core/include/services_sdk/resources/report/report_enums.h b/core/include/services_sdk/resources/report/report_enums.h index 70f6b4f..628d49a 100755 --- a/core/include/services_sdk/resources/report/report_enums.h +++ b/core/include/services_sdk/resources/report/report_enums.h @@ -57,6 +57,10 @@ enum class Tags { FILE_UPLOAD, IDENTITY_AWARENESS, RATE_LIMIT, + WEB_SERVER_NGINX, + WEB_SERVER_KONG, + DEPLOYMENT_EMBEDDED, + DEPLOYMENT_K8S, COUNT }; diff --git a/core/include/services_sdk/resources/tag_and_enum_management.h b/core/include/services_sdk/resources/tag_and_enum_management.h index 1d22520..b730223 100644 --- a/core/include/services_sdk/resources/tag_and_enum_management.h +++ b/core/include/services_sdk/resources/tag_and_enum_management.h @@ -43,7 +43,6 @@ public: static Maybe convertStringToTag(const std::string &tag); private: - static EnumArray tags_hierarchy; static EnumArray tags_translation_arr; static EnumArray audience_team_translation; }; diff --git a/core/message/http_decoder.cc b/core/message/http_decoder.cc index 2cbfd3f..a194e03 100755 --- a/core/message/http_decoder.cc +++ b/core/message/http_decoder.cc @@ -130,10 +130,10 @@ HTTPDecoder::handleBody() if (maybe_transfer_encoding.ok()) { auto transfer_encoding_type = maybe_transfer_encoding.unpack(); if (transfer_encoding_type == "chunked") { - if (Singleton::exists()) { - I_Environment *env = Singleton::Consume::by(); - auto is_k8s_env = env->get("k8s_env"); - if (is_k8s_env.ok() && *is_k8s_env) { + if (Singleton::exists()) { + I_EnvDetails *env_details = Singleton::Consume::by(); + EnvType env_type = env_details->getEnvType(); + if (env_type == EnvType::K8S) { dbgDebug(D_COMMUNICATION) << "Getting Chunked Response in a k8s env"; return getChunkedResponseK8s(); } diff --git a/core/message/http_decoder.h b/core/message/http_decoder.h index 25e8755..352c4c8 100755 --- a/core/message/http_decoder.h +++ b/core/message/http_decoder.h @@ -21,12 +21,12 @@ #include "messaging/http_core.h" #include "i_message_decoder.h" #include "i_messaging.h" -#include "i_environment.h" +#include "i_env_details.h" class HTTPDecoder : public I_MessageDecoder , - Singleton::Consume + Singleton::Consume { public: HTTPDecoder(I_Messaging::Method _method); diff --git a/core/report/tag_and_enum_management.cc b/core/report/tag_and_enum_management.cc index 0ca3a52..dcf3190 100755 --- a/core/report/tag_and_enum_management.cc +++ b/core/report/tag_and_enum_management.cc @@ -99,7 +99,11 @@ TagAndEnumManagement::convertStringToTag(const string &tag) {"Http Geo Filter", ReportIS::Tags::HTTP_GEO_FILTER}, {"File Upload", ReportIS::Tags::FILE_UPLOAD}, {"Identity Awareness", ReportIS::Tags::IDENTITY_AWARENESS}, - {"Rate Limit", ReportIS::Tags::RATE_LIMIT} + {"Rate Limit", ReportIS::Tags::RATE_LIMIT}, + {"NGINX Server", ReportIS::Tags::WEB_SERVER_NGINX}, + {"Kong Server", ReportIS::Tags::WEB_SERVER_KONG}, + {"Embedded Deployment", ReportIS::Tags::DEPLOYMENT_EMBEDDED}, + {"Kubernetes Deployment", ReportIS::Tags::DEPLOYMENT_K8S} }; auto report_is_tag = strings_to_tags.find(tag); @@ -266,25 +270,6 @@ TagAndEnumManagement::convertToString(const IssuingEngine &issuing_engine) } -EnumArray TagAndEnumManagement::tags_hierarchy { - Tags::THREAT_PREVENTION, - Tags::THREAT_PREVENTION, - Tags::THREAT_PREVENTION, - Tags::NEW_CONNECTION, - Tags::POLICY_INSTALLATION, - Tags::ACCESS_CONTROL, - Tags::ACCESS_CONTROL, - Tags::ACCESS_CONTROL, - Tags::FW, - Tags::WAF, - Tags::IPS, - Tags::URLF, - Tags::INFORMATIONAL, - Tags::ORCHESTRATOR, - Tags::COMPLIANCE, - Tags::REVERSE_PROXY -}; - EnumArray TagAndEnumManagement::tags_translation_arr { "Threat Prevention", "Remote Code Execution", @@ -311,7 +296,11 @@ EnumArray TagAndEnumManagement::tags_translation_arr { "Http Geo Filter", "File Upload", "Identity Awareness", - "Rate Limit" + "Rate Limit", + "NGINX Server", + "Kong Server", + "Embedded Deployment", + "Kubernetes Deployment" }; EnumArray TagAndEnumManagement::audience_team_translation { diff --git a/core/shm_pkt_queue/shared_string_wrapper.h b/core/shm_pkt_queue/shared_string_wrapper.h new file mode 100644 index 0000000..f436af8 --- /dev/null +++ b/core/shm_pkt_queue/shared_string_wrapper.h @@ -0,0 +1,46 @@ +// 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 __SHARED_STRING_WRAPPER_H__ +#define __SHARED_STRING_WRAPPER_H__ + +#include +#include +#include +#include + +using char_alloc = boost::interprocess::allocator; +using shared_string = boost::interprocess::basic_string, char_alloc>; + +class SharedStringWrapper +{ +public: + static void setAlloc(boost::interprocess::managed_shared_memory::segment_manager *_alloc) { alloc = _alloc; } + + SharedStringWrapper() : str(alloc) {} + + void reserve(size_t size) { str.reserve(size); } + void append(const u_char *data, size_t len) { str.append(data, len); } + size_t size() const { return str.size(); } + shared_string::iterator begin() { return str.begin(); } + shared_string::iterator end() { return str.end(); } + u_char * data() { return str.data(); } + +private: + static boost::interprocess::managed_shared_memory::segment_manager *alloc; + shared_string str; +}; + +using ring_buffer = boost::lockfree::spsc_queue>; + +#endif // __SHARED_STRING_WRAPPER_H__ diff --git a/core/shm_pkt_queue/shm_pkt_queue.cc b/core/shm_pkt_queue/shm_pkt_queue.cc index 0bd6290..277ee76 100644 --- a/core/shm_pkt_queue/shm_pkt_queue.cc +++ b/core/shm_pkt_queue/shm_pkt_queue.cc @@ -16,42 +16,16 @@ #include #include #include -#include -#include -#include -#include #include #include "common.h" -static const int queue_size = 200; +#include "shared_string_wrapper.h" + const int shm_pkt_queue_bad_alloc = -2; namespace bip = boost::interprocess; -using char_alloc = bip::allocator; -using shared_string = bip::basic_string, char_alloc>; - -class SharedStringWrapper -{ -public: - static void setAlloc(bip::managed_shared_memory::segment_manager *_alloc) { alloc = _alloc; } - - SharedStringWrapper() : str(alloc) {} - - void reserve(size_t size) { str.reserve(size); } - void append(const u_char *data, size_t len) { str.append(data, len); } - size_t size() const { return str.size(); } - shared_string::iterator begin() { return str.begin(); } - shared_string::iterator end() { return str.end(); } - -private: - static bip::managed_shared_memory::segment_manager *alloc; - shared_string str; -}; - bip::managed_shared_memory::segment_manager *SharedStringWrapper::alloc = nullptr; -using ring_buffer = boost::lockfree::spsc_queue>; - class Impl { public: diff --git a/core/shm_pkt_queue/shm_pkt_queue_ut/shm_pkt_queue_ut.cc b/core/shm_pkt_queue/shm_pkt_queue_ut/shm_pkt_queue_ut.cc index 12a05d3..62b8854 100644 --- a/core/shm_pkt_queue/shm_pkt_queue_ut/shm_pkt_queue_ut.cc +++ b/core/shm_pkt_queue/shm_pkt_queue_ut/shm_pkt_queue_ut.cc @@ -1,22 +1,25 @@ +// 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 "shmpktqueue.h" #include #include -#include -#include -#include -#include - #include "cptest.h" #include "maybe_res.h" +#include "../shared_string_wrapper.h" namespace bip = boost::interprocess; - -static const int queue_size = 200; -using char_alloc = bip::allocator; -using shared_string = bip::basic_string, char_alloc>; -using ring_buffer = boost::lockfree::spsc_queue>; - using namespace std; static const int segment_name_len = 128; @@ -103,8 +106,7 @@ class ShmPktQueueTest : public ::testing::Test { pop_packet_via_boost() { ring_buffer *queue = segment->find_or_construct(queue_name)(); - char_alloc char_alloc(segment->get_segment_manager()); - shared_string node_content(char_alloc); + SharedStringWrapper node_content; PacketInfo packet_pop_by_boost; if (queue->pop(node_content)) { diff --git a/nodes/orchestration/CMakeLists.txt b/nodes/orchestration/CMakeLists.txt index 9317a80..4bc010a 100755 --- a/nodes/orchestration/CMakeLists.txt +++ b/nodes/orchestration/CMakeLists.txt @@ -26,6 +26,7 @@ target_link_libraries( orchestration_downloader update_communication orchestration_tools + env_details messaging_downloader_client local_policy_mgmt_gen curl diff --git a/nodes/orchestration/package/cpnano_debug/cpnano_debug.cc b/nodes/orchestration/package/cpnano_debug/cpnano_debug.cc index b949e02..f55761f 100755 --- a/nodes/orchestration/package/cpnano_debug/cpnano_debug.cc +++ b/nodes/orchestration/package/cpnano_debug/cpnano_debug.cc @@ -75,7 +75,7 @@ enum class Service { REVERSE_PROXY_MANAGER, CAPSULE8, SDWAN, - SDWAN_LOGGER, + LOGGER_SDWAN, IOT_ENFORCE, IOT_DOCTOR, IOT_RISK, @@ -166,7 +166,7 @@ getServiceString(const Service service) case (Service::DEDICATED_NETWORK_HANDLER): return "dedicated-network-handler"; case (Service::MESSAGING_PROXY): return "messaging-proxy"; case (Service::SDWAN): return "sdwan"; - case (Service::SDWAN_LOGGER): return "sdwan-logger"; + case (Service::LOGGER_SDWAN): return "logger-sdwan"; case (Service::IOT_WLP): return "workload-protection"; case (Service::HELLO_WORLD): return "hello-world"; case (Service::IDA): return "identity-awareness"; @@ -329,7 +329,7 @@ getServiceConfig (const Service service) filesystem_path + "/conf/cp-nano-sdwan-debug-conf.json", log_files_path + "/nano_agent/cp-nano-sdwan.dbg" ); - case (Service::SDWAN_LOGGER): + case (Service::LOGGER_SDWAN): return ServiceConfig( filesystem_path + "/conf/cp-nano-logger-sdwan-debug-conf.json", log_files_path + "/nano_agent/cp-nano-logger-sdwan.dbg" @@ -1279,8 +1279,8 @@ extractServices(const vector &args) services.push_back(Service::MESSAGING_PROXY); } else if (getServiceString(Service::SDWAN).find(maybe_service) == 0) { services.push_back(Service::SDWAN); - } else if (getServiceString(Service::SDWAN_LOGGER).find(maybe_service) == 0) { - services.push_back(Service::SDWAN_LOGGER); + } else if (getServiceString(Service::LOGGER_SDWAN).find(maybe_service) == 0) { + services.push_back(Service::LOGGER_SDWAN); } else if (getServiceString(Service::IOT_WLP).find(maybe_service) == 0) { services.push_back(Service::IOT_WLP); } else if (getServiceString(Service::IDA).find(maybe_service) == 0) { diff --git a/nodes/orchestration/package/open-appsec-ctl.sh b/nodes/orchestration/package/open-appsec-ctl.sh index ef18776..b1b8c1c 100644 --- a/nodes/orchestration/package/open-appsec-ctl.sh +++ b/nodes/orchestration/package/open-appsec-ctl.sh @@ -953,13 +953,34 @@ run_status() # Initials - rs fi if [ -n "$(cat /etc/cp/conf/agent_details.json | grep "hybrid_mode")" ]; then + add_policy_file=true rs_mgmt_mode_text="Local management" else - rs_mgmt_mode_text="Cloud management" + if [ -n "$(cat /etc/cp/conf/settings.json | grep "\"profileManagedMode\":\"management\"")" ]; then + add_policy_file=false + rs_mgmt_mode_text="Cloud management (Fully managed)" + else + add_policy_file=true + rs_mgmt_mode_text="Cloud management (Visibility mode)" + fi fi echo "Management mode: ${rs_mgmt_mode_text}" - echo "Policy files: " - echo " /etc/cp/conf/local_policy.yaml" + + if [ "${add_policy_file}" = "true" ]; then + echo "Policy files: " + echo " /etc/cp/conf/local_policy.yaml" + else + policy=`cat /etc/cp/conf/policy.json` + version="version" + policy_version=${policy#*version} + policy_version=`echo $policy_version | cut -d"\"" -f3` + + if [ -n "$policy_version" ] && [ "$policy_version" -eq "$policy_version" ] 2>/dev/null; then + echo "Policy version: ${policy_version}" + else + echo "Policy version: Updating policy. Please try again in a few seconds" + fi + fi if [ -n "$(echo ${rs_temp_old_status} | grep "Last update status" | grep "Fail")" ]; then rs_policy_load_status="Error" diff --git a/nodes/orchestration/package/orchestration_package.sh b/nodes/orchestration/package/orchestration_package.sh index 7ccec87..9e4e7f1 100755 --- a/nodes/orchestration/package/orchestration_package.sh +++ b/nodes/orchestration/package/orchestration_package.sh @@ -51,6 +51,7 @@ var_error_sleep_interval=30 var_upgrade_mode= var_token= var_email= +var_server= var_installation_debug_mode=false var_startup_service= var_arch_flag= @@ -227,6 +228,9 @@ while true; do elif [ "$1" = "--email" ]; then shift var_email=$1 + elif [ "$1" = "--server" ]; then + shift + var_server=$1 elif [ "$1" = "--offline_mode" ]; then var_offline_mode=true var_orchestration_mode="offline_mode" @@ -896,7 +900,7 @@ install_orchestration() echo '{"'$ORCHESTRATION_NAME'": { "fog-address":"'$var_fog_address'", ' > ${FILESYSTEM_PATH}/${CONF_PATH}/policy.json echo '"pulling-interval":'$var_sleep_interval', ' >> ${FILESYSTEM_PATH}/${CONF_PATH}/policy.json echo '"error-pulling-interval":'$var_error_sleep_interval'},' >> ${FILESYSTEM_PATH}/${CONF_PATH}/policy.json - echo '"registration-data": { "email-address": "'$var_email'"}}' >> ${FILESYSTEM_PATH}/${CONF_PATH}/policy.json + echo '"registration-data": { "email-address": "'$var_email'", "registered-server": "'$var_server'"}}' >> ${FILESYSTEM_PATH}/${CONF_PATH}/policy.json copy_orchestration_executable copy_k8s_executable