From 108abdb35ec853b3b8d7fb962532a0088cf21b48 Mon Sep 17 00:00:00 2001 From: Ned Wright Date: Sun, 29 Dec 2024 12:47:25 +0000 Subject: [PATCH] sync code --- .../include/policy_activation_data.h | 90 ++++++++++++ .../policy_activation_data.cc | 116 ++++++++++++++++ core/env_details/CMakeLists.txt | 1 + core/env_details/env_details.cc | 105 ++++++++++++++ .../services_sdk/resources/env_details.h | 49 +++++++ core/logging/log_connector.cc | 131 ++++++++++++++++++ 6 files changed, 492 insertions(+) create mode 100755 components/security_apps/local_policy_mgmt_gen/include/policy_activation_data.h create mode 100755 components/security_apps/local_policy_mgmt_gen/policy_activation_data.cc create mode 100644 core/env_details/CMakeLists.txt create mode 100644 core/env_details/env_details.cc create mode 100644 core/include/services_sdk/resources/env_details.h create mode 100755 core/logging/log_connector.cc diff --git a/components/security_apps/local_policy_mgmt_gen/include/policy_activation_data.h b/components/security_apps/local_policy_mgmt_gen/include/policy_activation_data.h new file mode 100755 index 0000000..e765227 --- /dev/null +++ b/components/security_apps/local_policy_mgmt_gen/include/policy_activation_data.h @@ -0,0 +1,90 @@ +// 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 __POLICY_ACTIVATION_DATA_H__ +#define __POLICY_ACTIVATION_DATA_H__ + +#include +#include + +#include "config.h" +#include "debug.h" +#include "rest.h" +#include "cereal/archives/json.hpp" +#include +#include "customized_cereal_map.h" + +#include "local_policy_common.h" + +class PolicyActivationMetadata +{ +public: + void load(cereal::JSONInputArchive &archive_in); + +private: + std::string name; +}; + +class EnabledPolicy +{ +public: + void load(cereal::JSONInputArchive &archive_in); + + const std::string & getName() const; + const std::vector & getHosts() const; + +private: + std::string name; + std::string mode; + std::vector hosts; +}; + +class PolicyActivationSpec +{ +public: + void load(cereal::JSONInputArchive &archive_in); + + const std::vector & getPolicies() const; + +private: + std::string appsec_class_name; + std::vector policies; +}; + +class SinglePolicyActivationData +{ +public: + void load(cereal::JSONInputArchive &archive_in); + + const PolicyActivationSpec & getSpec() const; + +private: + std::string api_version; + std::string kind; + PolicyActivationMetadata metadata; + PolicyActivationSpec spec; +}; + +class PolicyActivationData : public ClientRest +{ +public: + bool loadJson(const std::string &json); + + const std::vector & getItems() const; + +private: + std::string api_version; + std::vector items; +}; + +#endif // __POLICY_ACTIVATION_DATA_H__ diff --git a/components/security_apps/local_policy_mgmt_gen/policy_activation_data.cc b/components/security_apps/local_policy_mgmt_gen/policy_activation_data.cc new file mode 100755 index 0000000..9b64b5c --- /dev/null +++ b/components/security_apps/local_policy_mgmt_gen/policy_activation_data.cc @@ -0,0 +1,116 @@ +// 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 "policy_activation_data.h" +#include "customized_cereal_map.h" + +using namespace std; + +USE_DEBUG_FLAG(D_LOCAL_POLICY); + +static const set valid_modes = { + "prevent-learn", + "detect-learn", + "prevent", + "detect", + "inactive" +}; + +void +PolicyActivationMetadata::load(cereal::JSONInputArchive &archive_in) +{ + dbgTrace(D_LOCAL_POLICY) << "PolicyActivationMetadata load"; + parseAppsecJSONKey("name", name, archive_in); +} + +void +EnabledPolicy::load(cereal::JSONInputArchive &archive_in) +{ + dbgTrace(D_LOCAL_POLICY) << "Loading policyActivation enabled policy"; + parseMandatoryAppsecJSONKey>("hosts", hosts, archive_in); + parseAppsecJSONKey("name", name, archive_in); + parseAppsecJSONKey("mode", mode, archive_in, "detect"); + if (valid_modes.count(mode) == 0) { + dbgWarning(D_LOCAL_POLICY) << "AppSec policy activation mode invalid: " << mode; + mode = "detect"; + } +} + +const string & +EnabledPolicy::getName() const +{ + return name; +} + +const vector & +EnabledPolicy::getHosts() const +{ + return hosts; +} + +void +PolicyActivationSpec::load(cereal::JSONInputArchive &archive_in) +{ + dbgTrace(D_LOCAL_POLICY) << "PolicyActivationSpec load"; + parseAppsecJSONKey("appsecClassName", appsec_class_name, archive_in); + parseMandatoryAppsecJSONKey>("enabledPolicies", policies, archive_in); +} + +const vector & +PolicyActivationSpec::getPolicies() const +{ + return policies; +} + +void +SinglePolicyActivationData::load(cereal::JSONInputArchive &archive_in) +{ + dbgTrace(D_LOCAL_POLICY) << "Loading single policy activation data"; + parseAppsecJSONKey("apiVersion", api_version, archive_in); + parseAppsecJSONKey("kind", kind, archive_in); + parseAppsecJSONKey("metadata", metadata, archive_in); + parseAppsecJSONKey("spec", spec, archive_in); +} + +const PolicyActivationSpec & +SinglePolicyActivationData::getSpec() const +{ + return spec; +} + +bool +PolicyActivationData::loadJson(const string &json) +{ + string modified_json = json; + modified_json.pop_back(); + stringstream in; + in.str(modified_json); + dbgTrace(D_LOCAL_POLICY) << "Loading policy activations data"; + try { + cereal::JSONInputArchive in_ar(in); + in_ar( + cereal::make_nvp("apiVersion", api_version), + cereal::make_nvp("items", items) + ); + } catch (cereal::Exception &e) { + dbgError(D_LOCAL_POLICY) << "Failed to load policy activations data JSON. Error: " << e.what(); + return false; + } + return true; +} + +const vector & +PolicyActivationData::getItems() const +{ + return items; +} diff --git a/core/env_details/CMakeLists.txt b/core/env_details/CMakeLists.txt new file mode 100644 index 0000000..91f3232 --- /dev/null +++ b/core/env_details/CMakeLists.txt @@ -0,0 +1 @@ +add_library(env_details env_details.cc) diff --git a/core/env_details/env_details.cc b/core/env_details/env_details.cc new file mode 100644 index 0000000..3937ffc --- /dev/null +++ b/core/env_details/env_details.cc @@ -0,0 +1,105 @@ +// 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" + +#include + +using namespace std; + +USE_DEBUG_FLAG(D_LOCAL_POLICY); + +static const string k8s_service_account = "/var/run/secrets/kubernetes.io/serviceaccount"; + +static bool +checkExistence(const string &path, bool is_dir) +{ + try { + struct stat info; + if (stat(path.c_str(), &info) != 0) return false; + int flag = is_dir ? S_IFDIR : S_IFREG; + return info.st_mode & flag; + } catch (exception &e) { + return false; + } +} + +// LCOV_EXCL_START Reason: can't use on the pipline environment +EnvDetails::EnvDetails() : Component("EnvDetails") +{ + if (doesFileExist("/.dockerenv")) env_type = EnvType::DOCKER; + token = retrieveToken(); + agent_namespace = retrieveNamespace(); + if (!token.empty()) { + auto env_res = getenv("deployment_type"); + env_type = env_res != nullptr && env_res == string("non_crd_k8s") ? EnvType::NON_CRD_K8S : EnvType::K8S; + } +} + +EnvType +EnvDetails::getEnvType() +{ + return env_type; +} + +string +EnvDetails::getToken() +{ + return token; +} + +string +EnvDetails::getNameSpace() +{ + return agent_namespace; +} + +string +EnvDetails::retrieveToken() +{ + return readFileContent(k8s_service_account + "/token"); +} + +string +EnvDetails::retrieveNamespace() +{ + return readFileContent(k8s_service_account + "/namespace"); +} + +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 ""; + } +} + +bool +EnvDetails::doesFileExist(const string &file_path) const +{ + return checkExistence(file_path, false); +} + +// LCOV_EXCL_STOP diff --git a/core/include/services_sdk/resources/env_details.h b/core/include/services_sdk/resources/env_details.h new file mode 100644 index 0000000..fc91d60 --- /dev/null +++ b/core/include/services_sdk/resources/env_details.h @@ -0,0 +1,49 @@ +// 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" +#include "component.h" + +class EnvDetails + : + public Component, + Singleton::Provide::SelfInterface +{ +public: + EnvDetails(); + + virtual EnvType getEnvType() override; + virtual std::string getToken() override; + virtual std::string getNameSpace() override; + +private: + std::string retrieveToken(); + std::string retrieveNamespace(); + std::string readFileContent(const std::string &file_path); + bool doesFileExist(const std::string &file_path) const; + + std::string token; + std::string agent_namespace; + EnvType env_type = EnvType::LINUX; +}; + +#endif // __ENV_DETAILS_H__ diff --git a/core/logging/log_connector.cc b/core/logging/log_connector.cc new file mode 100755 index 0000000..c1b82c6 --- /dev/null +++ b/core/logging/log_connector.cc @@ -0,0 +1,131 @@ +// 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 "log_streams.h" + +void +LogStreamConnector::maintainConnection() +{ + dbgTrace(D_REPORT) + << "Check if the connection is alive:" + << (socket.ok() ? " socket ok" : " socket not ok") + << (did_write_fail_in_this_window ? " previous write failed" : " previous write succeeded"); + if (!socket.ok() || did_write_fail_in_this_window) { + dbgTrace(D_REPORT) + << (socket.ok() ? "" : "The current socket is not ok, trying to connect."); + connect(); + did_write_fail_in_this_window = false; + if (!socket.ok()) { + dbgWarning(D_REPORT) << "Failed to connect to the server, logs will not be sent"; + return; + } + } +} + +void +LogStreamConnector::addLogToQueue(const std::vector &data) +{ + if (logs_in_queue.size() < max_data_in_queue) { + dbgTrace(D_REPORT) + << "Adding log to queue, Amount of logs in queue: " + << logs_in_queue.size(); + logs_in_queue.push_back(data); + } else { + dbgWarning(D_REPORT) << "Queue is full, dropping log"; + } +} + +void +LogStreamConnector::writeFail() +{ + if (!socket.ok()) { + dbgTrace(D_REPORT) << "Socket is not ok, stopping the connect after write failure"; + return; + } + dbgTrace(D_REPORT) << (did_write_fail_in_this_window ? "Previous write failed" : "Previous write succeeded"); + if (!did_write_fail_in_this_window) { + dbgTrace(D_REPORT) + << "First time in window that write failed, trying to reconnect to server"; + connect(); + } + did_write_fail_in_this_window = true; +} + +bool +LogStreamConnector::basicWriteLog(const std::vector &data) +{ + for (size_t tries = 0; tries < 3; tries++) { + if (socket.ok() && i_socket->writeData(socket.unpack(), data)) { + dbgTrace(D_REPORT) << "log was sent to server"; + return true; + } else { + dbgTrace(D_REPORT) << "Failed to send log to server"; + writeFail(); + } + } + return false; +} + +void +LogStreamConnector::sendLogWithQueue(const std::vector &data) +{ + if (!socket.ok()) { + dbgTrace(D_REPORT) + << "Socket not ok. Size of logs in queue: " + << logs_in_queue.size() + << ". Adding logs to the queue until the connection is established."; + addLogToQueue(data); + return; + } + + if (logs_in_queue.empty() && basicWriteLog(data)) return; + + addLogToQueue(data); + + int write_iterations = 0; + + while (write_iterations < max_logs_per_send && !logs_in_queue.empty()) { + dbgTrace(D_REPORT) + << " Iteration: " + << write_iterations + << " to try and write a log from queue to server" + << log_name; + int i = 0; + bool write_success = false; + while ( + socket.ok() && + (i < 3) && + !(write_success = i_socket->writeData(socket.unpack(), logs_in_queue.front()))) { + i++; + } + if (write_success) { + dbgTrace(D_REPORT) << "log was written to " << log_name << " server"; + logs_in_queue.erase(logs_in_queue.begin()); + write_iterations++; + } else { + dbgTrace(D_REPORT) << "Failed to send log to " << log_name << " server"; + writeFail(); + return; + } + } +} + +void +LogStreamConnector::sendAllLogs() +{ + dbgTrace(D_REPORT) << "Sending all logs from queue to server"; + for(auto &log : logs_in_queue) { + basicWriteLog(log); + } + logs_in_queue.clear(); +}