Aug_23_2023-Dev

This commit is contained in:
Ned Wright 2023-08-23 14:15:32 +00:00
parent 702c1184ea
commit b25fd8def5
115 changed files with 8292 additions and 1189 deletions

View File

@ -1762,8 +1762,8 @@ private:
&did_fail_on_purpose
)) {
return genError(
"Failed to read the attachment's User ID or Group ID" +
did_fail_on_purpose ? "[Intentional Failure]" : ""
string("Failed to read the attachment's User ID or Group ID") +
(did_fail_on_purpose ? "[Intentional Failure]" : "")
);
}

View File

@ -156,7 +156,7 @@ Zone::contains(const Asset &asset)
{
QueryRequest request;
for (const pair<Context::MetaDataType, string> &main_attr : asset.getAttrs()) {
for (const auto &main_attr : asset.getAttrs()) {
request.addCondition(Condition::EQUALS, contextKeyToString(main_attr.first), main_attr.second);
}

View File

@ -83,13 +83,13 @@ public:
:
status(raw_status)
{
for (const pair<string, HealthCheckStatusReply> &single_stat : descriptions) {
for (const auto &single_stat : descriptions) {
if (single_stat.second.getStatus() == HealthCheckStatus::HEALTHY) {
dbgTrace(D_HEALTH_CHECK_MANAGER) << "Ignoring healthy status reply. Comp name: " << single_stat.first;
continue;
}
for (const pair<string, string> &status : single_stat.second.getExtendedStatus()) {
for (const auto &status : single_stat.second.getExtendedStatus()) {
errors.push_back(HealthCheckError(single_stat.first + " " + status.first, status.second));
}
}
@ -190,7 +190,7 @@ private:
{
general_health_aggregated_status = HealthCheckStatus::HEALTHY;
for (const pair<string, HealthCheckStatusReply> &reply : all_comps_health_status) {
for (const auto &reply : all_comps_health_status) {
HealthCheckStatus status = reply.second.getStatus();
dbgTrace(D_HEALTH_CHECK_MANAGER)

View File

@ -48,7 +48,7 @@ HttpManagerOpaque::getCurrVerdict() const
uint accepted_apps = 0;
ngx_http_cp_verdict_e verdict = ngx_http_cp_verdict_e::TRAFFIC_VERDICT_INSPECT;
for (const pair<string, ngx_http_cp_verdict_e> &app_verdic_pair : applications_verdicts) {
for (const auto &app_verdic_pair : applications_verdicts) {
switch (app_verdic_pair.second) {
case ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP:
return app_verdic_pair.second;

View File

@ -11,52 +11,108 @@
// See the License for the specific language governing permissions and
// limitations under the License.
/// \file triggers_config.h
/// \brief Declaration of classes WebTriggerConf and LogTriggerConf, and related functions.
/// \author Check Point Software Technologies Ltd.
/// \date 2022
#ifndef __TRIGGERS_CONFIG_H__
#define __TRIGGERS_CONFIG_H__
#include <vector>
#include <string>
#include <vector>
#include "environment/evaluator_templates.h"
#include "cereal/archives/json.hpp"
#include "cereal/types/string.hpp"
#include "cereal/types/vector.hpp"
#include "cereal/archives/json.hpp"
#include "config.h"
#include "environment/evaluator_templates.h"
#include "generic_rulebase_utils.h"
#include "i_environment.h"
#include "i_logging.h"
#include "singleton.h"
#include "maybe_res.h"
#include "config.h"
#include "log_generator.h"
#include "generic_rulebase_utils.h"
#include "maybe_res.h"
#include "singleton.h"
/// \class WebTriggerConf
/// \brief Represents the configuration for a web trigger.
class WebTriggerConf
{
public:
/// \brief Default constructor for WebTriggerConf.
WebTriggerConf();
/// \brief Constructor for WebTriggerConf.
/// \param title The title of the trigger.
/// \param body The body of the trigger.
/// \param code The response code for the trigger.
WebTriggerConf(const std::string &title, const std::string &body, uint code);
/// \brief Preload function to register expected configuration.
static void
preload()
{
registerExpectedConfiguration<WebTriggerConf>("rulebase", "webUserResponse");
}
/// \brief Load function to deserialize configuration from JSONInputArchive.
/// \param archive_in The JSON input archive.
void load(cereal::JSONInputArchive &archive_in);
/// \brief Equality operator for WebTriggerConf.
/// \param other The WebTriggerConf to compare.
/// \return True if the two WebTriggerConf objects are equal, otherwise false.
bool operator==(const WebTriggerConf &other) const;
uint getResponseCode() const { return response_code; }
/// \brief Get the response code for the trigger.
/// \return The response code.
uint
getResponseCode() const
{
return response_code;
}
const std::string & getResponseTitle() const { return response_title; }
/// \brief Get the response title for the trigger.
/// \return The response title.
const std::string &
getResponseTitle() const
{
return response_title;
}
const std::string & getResponseBody() const { return response_body; }
/// \brief Get the response body for the trigger.
/// \return The response body.
const std::string &
getResponseBody() const
{
return response_body;
}
const std::string & getDetailsLevel() const { return details_level; }
/// \brief Get the details level for the trigger.
/// \return The details level.
const std::string &
getDetailsLevel() const
{
return details_level;
}
const std::string & getRedirectURL() const { return redirect_url; }
/// \brief Get the redirect URL for the trigger.
/// \return The redirect URL.
const std::string &
getRedirectURL() const
{
return redirect_url;
}
bool getAddEventId() const { return add_event_id_to_header; }
/// \brief Check if the trigger should add an event ID to the header.
/// \return True if the trigger should add an event ID, otherwise false.
bool
getAddEventId() const
{
return add_event_id_to_header;
}
/// \brief Default trigger configuration for WebTriggerConf.
static WebTriggerConf default_trigger_conf;
private:
@ -64,17 +120,38 @@ private:
std::string details_level;
std::string response_body;
std::string redirect_url;
uint response_code;
bool add_event_id_to_header = false;
uint response_code;
bool add_event_id_to_header = false;
};
/// \class LogTriggerConf
/// \brief Represents the configuration for a log trigger.
class LogTriggerConf : Singleton::Consume<I_Logging>
{
public:
enum class SecurityType { AccessControl, ThreatPrevention, Compliance, COUNT };
enum class extendLoggingSeverity { None, High, Critical };
/// \enum SecurityType
/// \brief Enumerates the security types for LogTriggerConf.
enum class SecurityType
{
AccessControl,
ThreatPrevention,
Compliance,
COUNT
};
enum class WebLogFields {
/// \enum extendLoggingSeverity
/// \brief Enumerates the extended logging severity for LogTriggerConf.
enum class extendLoggingSeverity
{
None,
High,
Critical
};
/// \enum WebLogFields
/// \brief Enumerates the web log fields for LogTriggerConf.
enum class WebLogFields
{
webBody,
webHeaders,
webRequests,
@ -85,17 +162,31 @@ public:
COUNT
};
/// \brief Default constructor for LogTriggerConf.
LogTriggerConf() {}
/// \brief Constructor for LogTriggerConf.
/// \param trigger_name The name of the trigger.
/// \param log_detect Flag indicating whether to log on detect.
/// \param log_prevent Flag indicating whether to log on prevent.
LogTriggerConf(std::string trigger_name, bool log_detect, bool log_prevent);
/// \brief Preload function to register expected configuration.
static void
preload()
{
registerExpectedConfiguration<LogTriggerConf>("rulebase", "log");
}
template <typename ...Tags>
/// \brief LogGen operator for LogTriggerConf.
/// \param title The title of the log.
/// \param security The security type of the log.
/// \param severity The severity of the log.
/// \param priority The priority of the log.
/// \param is_action_drop_or_prevent Flag indicating if the action is drop or prevent.
/// \param tags Tags for the log.
/// \return The LogGen object.
template <typename... Tags>
LogGen
operator()(
const std::string &title,
@ -103,7 +194,8 @@ public:
ReportIS::Severity severity,
ReportIS::Priority priority,
bool is_action_drop_or_prevent,
Tags ...tags) const
Tags... tags
) const
{
return LogGen(
title,
@ -117,11 +209,17 @@ public:
);
}
template <typename ...Tags>
/// \brief LogGen operator for LogTriggerConf.
/// \param title The title of the log.
/// \param security The security type of the log.
/// \param is_action_drop_or_prevent Flag indicating if the action is drop or prevent.
/// \param tags Tags for the log.
/// \return The LogGen object.
template <typename... Tags>
LogGen
operator()(const std::string &title, SecurityType security, bool is_action_drop_or_prevent, Tags ...tags) const
operator()(const std::string &title, SecurityType security, bool is_action_drop_or_prevent, Tags... tags) const
{
return (*this)(
return operator()(
title,
security,
getSeverity(is_action_drop_or_prevent),
@ -131,30 +229,98 @@ public:
);
}
/// \brief Load function to deserialize configuration from JSONInputArchive.
/// \param archive_in The JSON input archive.
void load(cereal::JSONInputArchive &archive_in);
bool isWebLogFieldActive(WebLogFields log_field) const { return log_web_fields.isSet(log_field); }
/// \brief Check if the web log field is active for the trigger.
/// \param log_field The web log field to check.
/// \return True if the web log field is active, otherwise false.
bool
isWebLogFieldActive(WebLogFields log_field) const
{
return log_web_fields.isSet(log_field);
}
bool isLogStreamActive(ReportIS::StreamType stream_type) const { return active_streams.isSet(stream_type); }
/// \brief Check if the log stream is active for the trigger.
/// \param stream_type The log stream type to check.
/// \return True if the log stream is active, otherwise false.
bool
isLogStreamActive(ReportIS::StreamType stream_type) const
{
return active_streams.isSet(stream_type);
}
bool isPreventLogActive(SecurityType security_type) const { return should_log_on_prevent.isSet(security_type); }
/// \brief Check if the log is active on prevent for the given security type.
/// \param security_type The security type to check.
/// \return True if the log is active on prevent, otherwise false.
bool
isPreventLogActive(SecurityType security_type) const
{
return should_log_on_prevent.isSet(security_type);
}
bool isDetectLogActive(SecurityType security_type) const { return should_log_on_detect.isSet(security_type); }
/// \brief Check if the log is active on detect for the given security type.
/// \param security_type The security type to check.
/// \return True if the log is active on detect, otherwise false.
bool
isDetectLogActive(SecurityType security_type) const
{
return should_log_on_detect.isSet(security_type);
}
bool isLogGeoLocationActive(SecurityType security_type) const { return log_geo_location.isSet(security_type); }
/// \brief Check if the geo-location log is active for the given security type.
/// \param security_type The security type to check.
/// \return True if the geo-location log is active, otherwise false.
bool
isLogGeoLocationActive(SecurityType security_type) const
{
return log_geo_location.isSet(security_type);
}
extendLoggingSeverity getExtendLoggingSeverity() const { return extend_logging_severity; }
/// \brief Get the extended logging severity.
/// \return The extended logging severity.
extendLoggingSeverity
getExtendLoggingSeverity() const
{
return extend_logging_severity;
}
const std::string & getVerbosity() const { return verbosity; }
const std::string & getName() const { return name; }
/// \brief Get the verbosity.
/// \return The verbosity.
const std::string &
getVerbosity() const
{
return verbosity;
}
const std::string & getUrlForSyslog() const { return url_for_syslog; }
const std::string & getUrlForCef() const { return url_for_cef; }
/// \brief Get the name.
/// \return The name.
const std::string &
getName() const
{
return name;
}
/// \brief Get the URL for syslog.
/// \return The URL for syslog.
const std::string &
getUrlForSyslog() const
{
return url_for_syslog;
}
/// \brief Get the URL for CEF.
/// \return The URL for CEF.
const std::string &
getUrlForCef() const
{
return url_for_cef;
}
private:
ReportIS::Severity getSeverity(bool is_action_drop_or_prevent) const;
ReportIS::Priority getPriority(bool is_action_drop_or_prevent) const;
Flags<ReportIS::StreamType> getStreams(SecurityType security_type, bool is_action_drop_or_prevent) const;
Flags<ReportIS::Enreachments> getEnrechments(SecurityType security_type) const;

View File

@ -18,6 +18,7 @@
#include "i_mainloop.h"
#include "i_socket_is.h"
#include "i_health_check_manager.h"
#include "i_shell_cmd.h"
#include "component.h"
class HealthChecker
@ -25,7 +26,8 @@ class HealthChecker
public Component,
Singleton::Consume<I_MainLoop>,
Singleton::Consume<I_Socket>,
Singleton::Consume<I_Health_Check_Manager>
Singleton::Consume<I_Health_Check_Manager>,
Singleton::Consume<I_ShellCmd>
{
public:
HealthChecker();

View File

@ -109,6 +109,11 @@ public:
virtual Maybe<std::string> readFile(const std::string &path) const = 0;
virtual bool writeFile(const std::string &text, const std::string &path) const = 0;
virtual bool removeFile(const std::string &path) const = 0;
virtual bool removeDirectory(const std::string &path, bool delete_content) const = 0;
virtual void deleteVirtualTenantProfileFiles(
const std::string &tenant_id,
const std::string &profile_id,
const std::string &conf_path) const = 0;
virtual bool copyFile(const std::string &src_path, const std::string &dst_path) const = 0;
virtual bool doesFileExist(const std::string &file_path) const = 0;
virtual void fillKeyInJson(
@ -118,6 +123,7 @@ public:
virtual bool createDirectory(const std::string &directory_path) const = 0;
virtual bool doesDirectoryExist(const std::string &dir_path) const = 0;
virtual bool executeCmd(const std::string &cmd) const = 0;
virtual void loadTenantsFromDir(const std::string &dir_path) const = 0;
virtual std::string base64Encode(const std::string &input) const = 0;
virtual std::string base64Decode(const std::string &input) const = 0;

View File

@ -19,6 +19,7 @@
#include <map>
#include "connkey.h"
#include "maybe_res.h"
#include "rest.h"
enum class ReconfStatus { SUCCEEDED, IN_PROGRESS, FAILED, INACTIVE };
@ -27,6 +28,7 @@ class I_ServiceController
{
public:
virtual void refreshPendingServices() = 0;
virtual const std::string & getPolicyVersions() const = 0;
virtual const std::string & getPolicyVersion() const = 0;
virtual const std::string & getUpdatePolicyVersion() const = 0;
virtual void updateReconfStatus(int id, ReconfStatus status) = 0;
@ -37,13 +39,13 @@ public:
const std::string &service_id
) = 0;
virtual bool
virtual Maybe<void>
updateServiceConfiguration(
const std::string &new_policy_path,
const std::string &new_settings_path,
const std::vector<std::string> &new_data_files = {},
const std::string &tenant_id = "",
const std::string &profile_id = "",
const std::string &child_tenant_id = "",
const std::string &child_profile_id = "",
const bool last_iteration = false
) = 0;

View File

@ -26,9 +26,12 @@ using OrchData = Maybe<std::string>;
class I_UpdateCommunication
{
public:
virtual Maybe<void> sendPolicyVersion(
const std::string &policy_version,
const std::string &policy_versions
) const = 0;
virtual Maybe<void> authenticateAgent() = 0;
virtual Maybe<void> getUpdate(CheckUpdateRequest &request) = 0;
virtual Maybe<void> sendPolicyVersion(const std::string &policy_version) const = 0;
virtual Maybe<std::string> downloadAttributeFile(const GetResourceFile &resourse_file) = 0;
virtual void setAddressExtenesion(const std::string &extension) = 0;
};

View File

@ -17,9 +17,16 @@
#include <fstream>
#include "i_orchestration_tools.h"
#include "i_shell_cmd.h"
#include "i_tenant_manager.h"
#include "component.h"
class OrchestrationTools : public Component, Singleton::Provide<I_OrchestrationTools>
class OrchestrationTools
:
public Component,
Singleton::Provide<I_OrchestrationTools>,
Singleton::Consume<I_ShellCmd>,
Singleton::Consume<I_TenantManager>
{
public:
OrchestrationTools();

View File

@ -106,6 +106,42 @@ public:
BOTH_LABEL_OPTIONAL_PARAM(TenantError, error, "error");
};
class UpgradeSchedule : public ClientRest
{
public:
UpgradeSchedule() = default;
void init(const std::string &_upgrade_mode) { mode = _upgrade_mode; }
void
init(
const std::string &_upgrade_mode,
const std::string &_upgrade_time,
const uint &_upgrade_duration_hours)
{
init(_upgrade_mode);
time = _upgrade_time;
duration_hours = _upgrade_duration_hours;
}
void
init(
const std::string &_upgrade_mode,
const std::string &_upgrade_time,
const uint &_upgrade_duration_hours,
const std::vector<std::string> &_upgrade_days)
{
init(_upgrade_mode, _upgrade_time, _upgrade_duration_hours);
days = _upgrade_days;
}
private:
C2S_LABEL_PARAM(std::string, mode, "upgradeMode");
C2S_LABEL_OPTIONAL_PARAM(std::string, time, "upgradeTime");
C2S_LABEL_OPTIONAL_PARAM(uint, duration_hours, "upgradeDurationHours");
C2S_LABEL_OPTIONAL_PARAM(std::vector<std::string>, days, "upgradeDay");
};
CheckUpdateRequest(
const std::string &_manifest,
const std::string &_policy,
@ -185,6 +221,28 @@ public:
void setGreedyMode() { check_all_tenants = true; }
void
setUpgradeFields(const std::string &_upgrade_mode)
{
upgrade_schedule.setActive(true);
upgrade_schedule.get().init(_upgrade_mode);
}
void
setUpgradeFields(
const std::string &_upgrade_mode,
const std::string &_upgrade_time,
const uint &_upgrade_duration_hours,
const std::vector<std::string> &_upgrade_days)
{
upgrade_schedule.setActive(true);
if (!_upgrade_days.empty()) {
upgrade_schedule.get().init(_upgrade_mode, _upgrade_time, _upgrade_duration_hours, _upgrade_days);
return;
}
upgrade_schedule.get().init(_upgrade_mode, _upgrade_time, _upgrade_duration_hours);
}
private:
class VirtualConfig : public ClientRest
{
@ -239,6 +297,8 @@ private:
C2S_LABEL_PARAM(std::string, checksum_type, "checksum-type");
C2S_LABEL_PARAM(std::string, policy_version, "policyVersion");
C2S_LABEL_OPTIONAL_PARAM(UpgradeSchedule, upgrade_schedule, "upgradeSchedule");
S2C_LABEL_OPTIONAL_PARAM(VirtualConfig, in_virtual_policy, "virtualPolicy");
S2C_LABEL_OPTIONAL_PARAM(VirtualConfig, in_virtual_settings, "virtualSettings");
};

View File

@ -1,54 +1,176 @@
// 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.
/// \file ips_signatures.h
/// \brief Declaration of classes IPSSignatureSubTypes, IPSSignaturesPerContext, IPSSignatures, SnortSignatures, and
/// related functions. \author Check Point Software Technologies Ltd. \date 2022
#ifndef __IPS_SIGNATURES_H__
#define __IPS_SIGNATURES_H__
#include <vector>
#include "config.h"
#include "parsed_context.h"
#include "log_generator.h"
#include "pm_hook.h"
#include "ips_enums.h"
#include "ips_entry.h"
#include "i_first_tier_agg.h"
#include "ips_entry.h"
#include "ips_enums.h"
#include "log_generator.h"
#include "parsed_context.h"
#include "pm_hook.h"
/// \namespace IPSSignatureSubTypes
/// \brief Namespace containing subtypes for IPS signatures.
namespace IPSSignatureSubTypes
{
using ActionResults = std::tuple<IPSSignatureSubTypes::SignatureAction, std::string, std::vector<std::string>>;
/// \class BaseSignature
/// \brief Represents the base signature class.
class BaseSignature
{
public:
enum class MatchType { NO_MATCH, CACHE_MATCH, MATCH };
/// \enum MatchType
/// \brief Enumerates the types of matches for BaseSignature.
enum class MatchType
{
NO_MATCH,
CACHE_MATCH,
MATCH
};
virtual const std::string & getSigId() const = 0;
/// \brief Get the ID of the signature.
virtual const std::string &getSigId() const = 0;
/// \brief Get the match type for the signature.
/// \param matched The set of patterns that matched.
virtual MatchType getMatch(const std::set<PMPattern> &matched) const = 0;
/// \brief Get the set of patterns in the signature.
virtual std::set<PMPattern> patternsInSignature() const = 0;
virtual const std::vector<std::string> & getContext() const = 0;
/// \brief Get the context of the signature.
virtual const std::vector<std::string> &getContext() const = 0;
};
/// \class IPSSignatureMetaData
/// \brief Represents the metadata for an IPS signature.
class IPSSignatureMetaData
{
public:
/// \brief Load the metadata from a JSON archive.
/// \param ar The JSON input archive.
void load(cereal::JSONInputArchive &ar);
/// \brief Set the indicators for the metadata.
/// \param source The source indicator.
/// \param version The version indicator.
void setIndicators(const std::string &source, const std::string &version);
const std::string & getId() const { return protection_id; }
const std::string & getName() const { return sig_name; }
const std::string & getUpdateVersion() const { return update; }
const std::string & getLogTitle() const { return event_log; }
const std::string & getSource() const { return source; }
const std::string & getFeedVersion() const { return version; }
const std::vector<std::string> & getCveList() const { return cve_list; }
IPSLevel getSeverity() const { return severity; }
std::string getSeverityString() const;
IPSLevel getConfidence() const { return confidence; }
std::string getConfidenceString() const;
IPSLevel getPerformance() const { return performance; }
std::string getPerformanceString() const;
bool isSilent() const { return is_silent; }
std::string getIncidentType() const;
bool isYearAtLeast(const Maybe<int> &year) const;
Maybe<int> getYear() const;
/// \brief Get the ID of the signature.
const std::string &
getId() const
{
return protection_id;
}
/// \brief Get the name of the signature.
const std::string &
getName() const
{
return sig_name;
}
/// \brief Get the update version of the signature.
const std::string &
getUpdateVersion() const
{
return update;
}
/// \brief Get the log title of the signature.
const std::string &
getLogTitle() const
{
return event_log;
}
/// \brief Get the source indicator of the signature.
const std::string &
getSource() const
{
return source;
}
/// \brief Get the feed version of the signature.
const std::string &
getFeedVersion() const
{
return version;
}
/// \brief Get the CVE list of the signature.
const std::vector<std::string> &
getCveList() const
{
return cve_list;
}
/// \brief Get the severity level of the signature.
IPSLevel
getSeverity() const
{
return severity;
}
/// \brief Get the severity level as a string of the signature.
std::string getSeverityString() const;
/// \brief Get the confidence level of the signature.
IPSLevel
getConfidence() const
{
return confidence;
}
/// \brief Get the confidence level as a string of the signature.
std::string getConfidenceString() const;
/// \brief Get the performance level of the signature.
IPSLevel
getPerformance() const
{
return performance;
}
/// \brief Get the performance level as a string of the signature.
std::string getPerformanceString() const;
/// \brief Check if the signature is silent.
bool
isSilent() const
{
return is_silent;
}
/// \brief Get the incident type of the signature.
std::string getIncidentType() const;
/// \brief Check if the signature is from a specific year or later.
/// \param year The year to compare with.
bool isYearAtLeast(const Maybe<int> &year) const;
/// \brief Get the year of the signature.
Maybe<int> getYear() const;
private:
std::string protection_id;
@ -65,69 +187,224 @@ private:
bool is_silent = false;
};
/// \class CompleteSignature
/// \brief Represents a complete signature.
class CompleteSignature
{
public:
/// \brief Load the complete signature from a JSON archive.
/// \param ar The JSON input archive.
void load(cereal::JSONInputArchive &ar);
/// \brief Get the match type for the signature.
/// \param matches The set of patterns that matched.
BaseSignature::MatchType getMatch(const std::set<PMPattern> &matches) const;
/// \brief Get the set of patterns in the signature.
std::set<PMPattern> patternsInSignature() const;
/// \brief Set the indicators for the complete signature.
/// \param source The source indicator.
/// \param version The version indicator.
void setIndicators(const std::string &source, const std::string &version);
const std::vector<std::string> & getContext() const { return rule->getContext(); }
const std::string & getId() const { return metadata.getId(); }
const std::string & getLogTitle() const { return metadata.getLogTitle(); }
const std::string & getName() const { return metadata.getName(); }
const std::string & getUpdateVersion() const { return metadata.getUpdateVersion(); }
const std::string & getSource() const { return metadata.getSource(); }
const std::string & getFeedVersion() const { return metadata.getFeedVersion(); }
const std::vector<std::string> & getCveList() const { return metadata.getCveList(); }
IPSLevel getSeverity() const { return metadata.getSeverity(); }
std::string getSeverityString() const { return metadata.getSeverityString(); }
IPSLevel getConfidence() const { return metadata.getConfidence(); }
std::string getConfidenceString() const { return metadata.getConfidenceString(); }
IPSLevel getPerformance() const { return metadata.getPerformance(); }
std::string getPerformanceString() const { return metadata.getPerformanceString(); }
bool isSilent() const { return metadata.isSilent(); }
std::string getIncidentType() const { return metadata.getIncidentType(); }
/// \brief Get the context of the signature.
const std::vector<std::string> &
getContext() const
{
return rule->getContext();
}
bool isYearAtLeast(const Maybe<int> &year) const { return metadata.isYearAtLeast(year); }
Maybe<int> getYear() const { return metadata.getYear(); }
/// \brief Get the ID of the signature.
const std::string &
getId() const
{
return metadata.getId();
}
/// \brief Get the log title of the signature.
const std::string &
getLogTitle() const
{
return metadata.getLogTitle();
}
/// \brief Get the name of the signature.
const std::string &
getName() const
{
return metadata.getName();
}
/// \brief Get the update version of the signature.
const std::string &
getUpdateVersion() const
{
return metadata.getUpdateVersion();
}
/// \brief Get the source indicator of the signature.
const std::string &
getSource() const
{
return metadata.getSource();
}
/// \brief Get the feed version of the signature.
const std::string &
getFeedVersion() const
{
return metadata.getFeedVersion();
}
/// \brief Get the CVE list of the signature.
const std::vector<std::string> &
getCveList() const
{
return metadata.getCveList();
}
/// \brief Get the severity level of the signature.
IPSLevel
getSeverity() const
{
return metadata.getSeverity();
}
/// \brief Get the severity level as a string of the signature.
std::string
getSeverityString() const
{
return metadata.getSeverityString();
}
/// \brief Get the confidence level of the signature.
IPSLevel
getConfidence() const
{
return metadata.getConfidence();
}
/// \brief Get the confidence level as a string of the signature.
std::string
getConfidenceString() const
{
return metadata.getConfidenceString();
}
/// \brief Get the performance level of the signature.
IPSLevel
getPerformance() const
{
return metadata.getPerformance();
}
/// \brief Get the performance level as a string of the signature.
std::string
getPerformanceString() const
{
return metadata.getPerformanceString();
}
/// \brief Check if the signature is silent.
bool
isSilent() const
{
return metadata.isSilent();
}
/// \brief Get the incident type of the signature.
std::string
getIncidentType() const
{
return metadata.getIncidentType();
}
/// \brief Check if the signature is from a specific year or later.
/// \param year The year to compare with.
bool
isYearAtLeast(const Maybe<int> &year) const
{
return metadata.isYearAtLeast(year);
}
/// \brief Get the year of the signature.
Maybe<int>
getYear() const
{
return metadata.getYear();
}
private:
IPSSignatureMetaData metadata;
std::shared_ptr<BaseSignature> rule;
};
/// \class SignatureAndAction
/// \brief Represents a signature and its associated action.
class SignatureAndAction
{
public:
SignatureAndAction(std::shared_ptr<CompleteSignature> _signature, SignatureAction _action)
:
signature(_signature),
action(_action)
/// \brief Construct a SignatureAndAction object.
/// \param _signature The complete signature.
/// \param _action The signature action.
SignatureAndAction(std::shared_ptr<CompleteSignature> _signature, SignatureAction _action) :
signature(_signature), action(_action)
{}
/// \brief Check if the signature is matched for prevention.
/// \param context_buffer The context buffer.
/// \param pattern The set of patterns to match.
bool isMatchedPrevent(const Buffer &context_buffer, const std::set<PMPattern> &pattern) const;
/// \brief Check if the signature is matched silently.
/// \param context_buffer The context buffer.
bool matchSilent(const Buffer &context_buffer) const;
/// \brief Get the set of patterns in the signature.
std::set<PMPattern>
patternsInSignature() const
{
return signature->patternsInSignature();
}
bool isMatchedPrevent(const Buffer &context_buffer, const std::set<PMPattern> &pattern) const;
bool matchSilent(const Buffer &context_buffer) const;
std::set<PMPattern> patternsInSignature() const { return signature->patternsInSignature(); }
const std::vector<std::string> & getContext() const { return signature->getContext(); }
/// \brief Get the context of the signature.
const std::vector<std::string> &
getContext() const
{
return signature->getContext();
}
private:
/// \brief Get the action results for the IPS state.
/// \param ips_state The IPS entry.
ActionResults getAction(const IPSEntry &ips_state) const;
std::shared_ptr<CompleteSignature> signature;
SignatureAction action;
};
} // IPSSignatureSubTypes
} // namespace IPSSignatureSubTypes
/// \class IPSSignaturesPerContext
/// \brief Represents IPS signatures per context.
class IPSSignaturesPerContext : public Singleton::Consume<I_FirstTierAgg>
{
public:
/// \brief Add a signature to the context.
/// \param sig The signature and its associated action.
void addSignature(const IPSSignatureSubTypes::SignatureAndAction &sig);
/// \brief Check if the context is matched for prevention.
/// \param context_buffer The context buffer.
bool isMatchedPrevent(const Buffer &context_buffer) const;
/// \brief Calculate the first tier for the given context name.
/// \param ctx_name The context name.
void calcFirstTier(const std::string &ctx_name);
private:
/// \brief Get the first tier matches for the buffer.
/// \param buffer The buffer to match.
std::set<PMPattern> getFirstTierMatches(const Buffer &buffer) const;
std::map<PMPattern, std::vector<IPSSignatureSubTypes::SignatureAndAction>> signatures_per_lss;
@ -135,11 +412,17 @@ private:
std::shared_ptr<PMHook> first_tier;
};
/// \class IPSSignaturesResource
/// \brief Represents IPS signatures resource.
class IPSSignaturesResource
{
public:
/// \brief Load the IPS signatures resource from a JSON archive.
/// \param ar The JSON input archive.
void load(cereal::JSONInputArchive &ar);
/// \brief Get all the signatures.
/// \return A vector of shared pointers to CompleteSignature.
const std::vector<std::shared_ptr<IPSSignatureSubTypes::CompleteSignature>> &
getSignatures() const
{
@ -150,11 +433,26 @@ private:
std::vector<std::shared_ptr<IPSSignatureSubTypes::CompleteSignature>> all_signatures;
};
/// \class SnortSignaturesResourceFile
/// \brief Represents Snort signatures resource file.
class SnortSignaturesResourceFile
{
public:
/// \brief Load the Snort signatures resource file from a JSON archive.
/// \param ar The JSON input archive.
void load(cereal::JSONInputArchive &ar);
bool isFile(const std::string &file_name) const { return file_name == name; }
/// \brief Check if the file name matches.
/// \param file_name The name of the file.
/// \return True if the file name matches, otherwise false.
bool
isFile(const std::string &file_name) const
{
return file_name == name;
}
/// \brief Get all the signatures.
/// \return A vector of shared pointers to CompleteSignature.
const std::vector<std::shared_ptr<IPSSignatureSubTypes::CompleteSignature>> &
getSignatures() const
{
@ -166,11 +464,18 @@ private:
std::vector<std::shared_ptr<IPSSignatureSubTypes::CompleteSignature>> all_signatures;
};
/// \class SnortSignaturesResource
/// \brief Represents Snort signatures resource.
class SnortSignaturesResource
{
public:
/// \brief Load the Snort signatures resource from a JSON archive.
/// \param ar The JSON input archive.
void load(cereal::JSONInputArchive &ar);
/// \brief Get all the signatures for the given file name.
/// \param file_name The name of the file.
/// \return A vector of shared pointers to CompleteSignature.
const std::vector<std::shared_ptr<IPSSignatureSubTypes::CompleteSignature>> &
getSignatures(const std::string &file_name) const
{
@ -185,21 +490,74 @@ private:
std::vector<SnortSignaturesResourceFile> files;
};
/// \class IPSSignatures
/// \brief Represents IPS signatures.
class IPSSignatures
{
std::set<PMPattern> getFirstTier(const ParsedContext &context);
public:
/// \brief Load the IPS signatures from a JSON archive.
/// \param ar The JSON input archive.
void load(cereal::JSONInputArchive &ar);
/// \brief Check if the context is matched for prevention.
/// \param context_name The name of the context.
/// \param context_buffer The context buffer.
bool isMatchedPrevent(const std::string &context_name, const Buffer &context_buffer) const;
bool isEmpty() const { return signatures_per_context.empty(); }
/// \brief Check if the IPS signatures are empty.
/// \return True if the signatures are empty, otherwise false.
bool
isEmpty() const
{
return signatures_per_context.empty();
}
/// \brief Check if the IPS signatures for the given context are empty.
/// \param context The name of the context.
/// \return True if the signatures for the context are empty, otherwise false.
bool isEmpty(const std::string &context) const;
const std::string & getAsset() const { return asset_name; }
const std::string & getAssetId() const { return asset_id; }
const std::string & getPractice() const { return practice_name; }
const std::string & getPracticeId() const { return practice_id; }
const std::string & getSourceIdentifier() const { return source_id; }
/// \brief Get the asset name.
/// \return The asset name.
const std::string &
getAsset() const
{
return asset_name;
}
/// \brief Get the asset ID.
/// \return The asset ID.
const std::string &
getAssetId() const
{
return asset_id;
}
/// \brief Get the practice name.
/// \return The practice name.
const std::string &
getPractice() const
{
return practice_name;
}
/// \brief Get the practice ID.
/// \return The practice ID.
const std::string &
getPracticeId() const
{
return practice_id;
}
/// \brief Get the source identifier.
/// \return The source identifier.
const std::string &
getSourceIdentifier() const
{
return source_id;
}
private:
std::map<std::string, IPSSignaturesPerContext> signatures_per_context;
@ -210,21 +568,74 @@ private:
std::string source_id;
};
/// \class SnortSignatures
/// \brief Represents Snort signatures.
class SnortSignatures
{
std::set<PMPattern> getFirstTier(const ParsedContext &context);
public:
/// \brief Load the Snort signatures from a JSON archive.
/// \param ar The JSON input archive.
void load(cereal::JSONInputArchive &ar);
/// \brief Check if the context is matched for prevention.
/// \param context_name The name of the context.
/// \param context_buffer The context buffer.
bool isMatchedPrevent(const std::string &context_name, const Buffer &context_buffer) const;
bool isEmpty() const { return signatures_per_context.empty(); }
/// \brief Check if the Snort signatures are empty.
/// \return True if the signatures are empty, otherwise false.
bool
isEmpty() const
{
return signatures_per_context.empty();
}
/// \brief Check if the Snort signatures for the given context are empty.
/// \param context The name of the context.
/// \return True if the signatures for the context are empty, otherwise false.
bool isEmpty(const std::string &context) const;
const std::string & getAsset() const { return asset_name; }
const std::string & getAssetId() const { return asset_id; }
const std::string & getPractice() const { return practice_name; }
const std::string & getPracticeId() const { return practice_id; }
const std::string & getSourceIdentifier() const { return source_id; }
/// \brief Get the asset name.
/// \return The asset name.
const std::string &
getAsset() const
{
return asset_name;
}
/// \brief Get the asset ID.
/// \return The asset ID.
const std::string &
getAssetId() const
{
return asset_id;
}
/// \brief Get the practice name.
/// \return The practice name.
const std::string &
getPractice() const
{
return practice_name;
}
/// \brief Get the practice ID.
/// \return The practice ID.
const std::string &
getPracticeId() const
{
return practice_id;
}
/// \brief Get the source identifier.
/// \return The source identifier.
const std::string &
getSourceIdentifier() const
{
return source_id;
}
private:
std::map<std::string, IPSSignaturesPerContext> signatures_per_context;

View File

@ -23,6 +23,8 @@ using namespace ReportIS;
using namespace std;
using MatchType = BaseSignature::MatchType;
static const LogTriggerConf default_triger;
static const map<IPSLevel, Severity> severities = {
{ IPSLevel::CRITICAL, Severity::CRITICAL },
{ IPSLevel::HIGH, Severity::HIGH },
@ -396,7 +398,7 @@ SignatureAndAction::isMatchedPrevent(const Buffer &context_buffer, const set<PMP
dbgDebug(D_IPS) << "Signature matched - sending log";
auto &trigger = getConfigurationWithDefault(LogTriggerConf(), "rulebase", "log");
auto &trigger = getConfigurationWithDefault(default_triger, "rulebase", "log");
bool is_prevent = get<0>(override_action) == IPSSignatureSubTypes::SignatureAction::PREVENT;
auto severity = signature->getSeverity() < IPSLevel::HIGH ? Severity::HIGH : Severity::CRITICAL;

View File

@ -131,7 +131,7 @@ DetailsResolver::Impl::isReverseProxy()
return is_reverse_proxy.unpack().front() == '1';
}
#endif
return false;
return getenv("DOCKER_RPM_ENABLED") && getenv("DOCKER_RPM_ENABLED") == string("true");
}
bool

View File

@ -125,44 +125,54 @@ getMgmtObjName(shared_ptr<istream> file_stream)
}
Maybe<string>
getGWIPAddress(shared_ptr<istream> file_stream)
getGWHardware(const string &command_output)
{
return getMgmtObjAttr(file_stream, "ipaddr ");
}
Maybe<string>
getGWHardware(shared_ptr<istream> file_stream)
{
Maybe<string> 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");
if (!command_output.empty()) {
if (command_output == "software") return string("Open server");
if (command_output == "Maestro Gateway") return string("Maestro");
return string(command_output);
}
return val;
return genError("GW Hardware was not found");
}
Maybe<string>
getGWApplicationControlBlade(shared_ptr<istream> file_stream)
getAttr(const string &command_output, const string &error)
{
return getMgmtObjAttr(file_stream, "application_firewall_blade ");
if (!command_output.empty()) {
return string(command_output);
}
return genError(error);
}
Maybe<string>
getGWURLFilteringBlade(shared_ptr<istream> file_stream)
getGWApplicationControlBlade(const string &command_output)
{
return getMgmtObjAttr(file_stream, "advanced_uf_blade ");
return getAttr(command_output, "Application Control Blade was not found");
}
Maybe<string>
getGWIPSecVPNBlade(shared_ptr<istream> file_stream)
getGWURLFilteringBlade(const string &command_output)
{
return getMgmtObjAttr(file_stream, "VPN_1 ");
return getAttr(command_output, "URL Filtering Blade was not found");
}
Maybe<string>
getGWVersion(shared_ptr<istream> file_stream)
getGWIPSecVPNBlade(const string &command_output)
{
return getMgmtObjAttr(file_stream, "svn_version_name ");
return getAttr(command_output, "IPSec VPN Blade was not found");
}
Maybe<string>
getGWIPAddress(const string &command_output)
{
return getAttr(command_output, "IP Address was not found");
}
Maybe<string>
getGWVersion(const string &command_output)
{
return getAttr(command_output, "GW Version was not found");
}
Maybe<string>
@ -190,6 +200,33 @@ getSmbObjectName(const string &command_output)
return getMgmtObjAttr(ifs, "name ");
}
Maybe<string>
getSmbBlade(const string &command_output, const string &error)
{
if (command_output.front() == '1') return string("installed");
if (command_output.front() == '0') return string("not-installed");
return genError(error);
}
Maybe<string>
getSmbGWApplicationControlBlade(const string &command_output)
{
return getSmbBlade(command_output, "Application Control Blade was not found");
}
Maybe<string>
getSmbGWURLFilteringBlade(const string &command_output)
{
return getSmbBlade(command_output, "URL Filterin Blade was not found");
}
Maybe<string>
getSmbGWIPSecVPNBlade(const string &command_output)
{
return getSmbBlade(command_output, "IPSec VPN Blade was not found");
}
Maybe<string>
getMgmtParentObjAttr(shared_ptr<istream> file_stream, const string &parent_obj, const string &attr)
{

View File

@ -31,16 +31,50 @@
#if defined(gaia) || defined(smb)
SHELL_CMD_HANDLER("cpProductIntegrationMgmtObjectType", "cpprod_util CPPROD_IsMgmtMachine", getMgmtObjType)
SHELL_CMD_HANDLER("hasSDWan", "[ -f $FWDIR/bin/sdwan_steering ] && echo '1' || echo '0'", checkHasSDWan)
SHELL_CMD_HANDLER("canUpdateSDWanData", "cpsdwan get_data | jq -r .can_update_sdwan_data", checkCanUpdateSDWanData)
SHELL_CMD_HANDLER(
"canUpdateSDWanData",
"CPSDWAN_NOLOGS=1 cpsdwan get_data -f can_update_sdwan_data | jq -r .can_update_sdwan_data",
checkCanUpdateSDWanData
)
SHELL_CMD_HANDLER(
"isSdwanRunning",
"[ -v $(pidof cp-nano-sdwan) ] && echo 'false' || echo 'true'",
checkIfSdwanRunning)
SHELL_CMD_HANDLER(
"IP Address",
"cpsdwan get_data | jq -r .main_ip",
getGWIPAddress
)
SHELL_CMD_HANDLER(
"Version",
"cat /etc/cp-release | grep -oE 'R[0-9]+(\\.[0-9]+)?'",
getGWVersion
)
#endif //gaia || smb
#if defined(gaia)
SHELL_CMD_HANDLER("hasSupportedBlade", "enabled_blades", checkHasSupportedBlade)
SHELL_CMD_HANDLER("hasSamlPortal", "mpclient status saml-vpn", checkSamlPortal)
SHELL_CMD_HANDLER(
"Hardware",
"cat $FWDIR/database/myself_objects.C | awk -F '[:()]' '/:appliance_type/ {print $3}' | head -n 1",
getGWHardware
)
SHELL_CMD_HANDLER(
"Application Control",
"cat $FWDIR/database/myself_objects.C | awk -F '[:()]' '/:application_firewall_blade/ {print $3}' | head -n 1",
getGWApplicationControlBlade
)
SHELL_CMD_HANDLER(
"URL Filtering",
"cat $FWDIR/database/myself_objects.C | awk -F '[:()]' '/:advanced_uf_blade/ {print $3}' | head -n 1",
getGWURLFilteringBlade
)
SHELL_CMD_HANDLER(
"IPSec VPN",
"cat $FWDIR/database/myself_objects.C | awk -F '[:()]' '/:VPN_1/ {print $3}' | head -n 1",
getGWIPSecVPNBlade
)
#endif //gaia
#if defined(smb)
@ -59,6 +93,21 @@ SHELL_CMD_HANDLER(
"cpprod_util FwIsLocalMgmt",
getSmbObjectName
)
SHELL_CMD_HANDLER(
"Application Control",
"cat $FWDIR/conf/active_blades.txt | grep -o 'APCL [01]' | cut -d ' ' -f2",
getSmbGWApplicationControlBlade
)
SHELL_CMD_HANDLER(
"URL Filtering",
"cat $FWDIR/conf/active_blades.txt | grep -o 'URLF [01]' | cut -d ' ' -f2",
getSmbGWURLFilteringBlade
)
SHELL_CMD_HANDLER(
"IPSec VPN",
"cat $FWDIR/conf/active_blades.txt | grep -o 'IPS [01]' | cut -d ' ' -f2",
getSmbGWIPSecVPNBlade
)
#endif//smb
SHELL_CMD_OUTPUT("kernel_version", "uname -r")
@ -73,17 +122,6 @@ SHELL_CMD_OUTPUT("helloWorld", "cat /tmp/agentHelloWorld 2>/dev/null")
#if defined(gaia)
FILE_CONTENT_HANDLER("hasIdpConfigured", "/opt/CPSamlPortal/phpincs/spPortal/idpPolicy.xml", checkIDP)
FILE_CONTENT_HANDLER(
"cpProductIntegrationMgmtParentObjectUid",
(getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myself_objects.C",
getMgmtParentObjUid
)
FILE_CONTENT_HANDLER(
"cpProductIntegrationMgmtParentObjectName",
(getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myself_objects.C",
getMgmtParentObjName
)
FILE_CONTENT_HANDLER(
"cpProductIntegrationMgmtObjectName",
(getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myown.C",
@ -101,37 +139,6 @@ 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

View File

@ -179,14 +179,13 @@ private:
Maybe<void>
HTTPClient::getFile(const URLParser &url, ofstream &out_file, bool auth_required)
{
auto message = Singleton::Consume<I_Messaging>::by<HTTPClient>();
auto load_env_proxy = message->loadProxy();
auto proxy_config = Singleton::Consume<I_ProxyConfiguration>::by<HTTPClient>();
auto load_env_proxy = proxy_config->loadProxy();
if (!load_env_proxy.ok()) return load_env_proxy;
string token = "";
if (auth_required) {
auto message = Singleton::Consume<I_Messaging>::by<HTTPClient>();
token = message->getAccessToken();
token = Singleton::Consume<I_AgentDetails>::by<HTTPClient>()->getAccessToken();
}
if (url.isOverSSL()) {
@ -214,15 +213,15 @@ Maybe<void>
HTTPClient::curlGetFileOverHttp(const URLParser &url, ofstream &out_file, const string &token)
{
try {
auto message = Singleton::Consume<I_Messaging>::by<HTTPClient>();
auto proxy_config = Singleton::Consume<I_ProxyConfiguration>::by<HTTPClient>();
HttpCurl http_curl_client(
url,
out_file,
token,
message->getProxyDomain(ProxyProtocol::HTTPS),
message->getProxyPort(ProxyProtocol::HTTPS),
message->getProxyCredentials(ProxyProtocol::HTTPS));
proxy_config->getProxyDomain(ProxyProtocol::HTTPS),
proxy_config->getProxyPort(ProxyProtocol::HTTPS),
proxy_config->getProxyCredentials(ProxyProtocol::HTTPS));
http_curl_client.setCurlOpts();
bool connection_ok = http_curl_client.connect();
@ -247,12 +246,12 @@ Maybe<void>
HTTPClient::getFileHttp(const URLParser &url, ofstream &out_file, const string &token)
{
try {
auto message = Singleton::Consume<I_Messaging>::by<HTTPClient>();
auto proxy_config = Singleton::Consume<I_ProxyConfiguration>::by<HTTPClient>();
ClientConnection client_connection(
url,
message->getProxyDomain(ProxyProtocol::HTTP),
message->getProxyPort(ProxyProtocol::HTTP),
message->getProxyCredentials(ProxyProtocol::HTTP),
proxy_config->getProxyDomain(ProxyProtocol::HTTP),
proxy_config->getProxyPort(ProxyProtocol::HTTP),
proxy_config->getProxyCredentials(ProxyProtocol::HTTP),
token
);
auto handle_connect_res = client_connection.handleConnect();

View File

@ -18,9 +18,15 @@
#include "maybe_res.h"
#include "url_parser.h"
#include "i_messaging.h"
#include "i_agent_details.h"
#include "i_proxy_configuration.h"
// LCOV_EXCL_START Reason: Depends on real download server.
class HTTPClient : public Singleton::Consume<I_Messaging>
class HTTPClient
:
public Singleton::Consume<I_Messaging>,
public Singleton::Consume<I_AgentDetails>,
public Singleton::Consume<I_ProxyConfiguration>
{
public:
HTTPClient() = default;

View File

@ -535,16 +535,16 @@ HTTPClient::getFileSSL(const URLParser &url, ofstream &out_file, const string &t
}
}
boost::asio::io_service io_service;
auto message = Singleton::Consume<I_Messaging>::by<HTTPClient>();
auto proxy_config = Singleton::Consume<I_ProxyConfiguration>::by<HTTPClient>();
Client client(
out_file,
io_service,
ctx,
url,
message->getProxyDomain(ProxyProtocol::HTTPS),
message->getProxyPort(ProxyProtocol::HTTPS),
message->getProxyCredentials(ProxyProtocol::HTTPS),
proxy_config->getProxyDomain(ProxyProtocol::HTTPS),
proxy_config->getProxyPort(ProxyProtocol::HTTPS),
proxy_config->getProxyCredentials(ProxyProtocol::HTTPS),
token
);
@ -581,15 +581,15 @@ HTTPClient::curlGetFileOverSSL(const URLParser &url, ofstream &out_file, const s
);
}
auto message = Singleton::Consume<I_Messaging>::by<HTTPClient>();
auto proxy_config = Singleton::Consume<I_ProxyConfiguration>::by<HTTPClient>();
HttpsCurl ssl_curl_client(
url,
out_file,
token,
message->getProxyDomain(ProxyProtocol::HTTPS),
message->getProxyPort(ProxyProtocol::HTTPS),
message->getProxyCredentials(ProxyProtocol::HTTPS),
proxy_config->getProxyDomain(ProxyProtocol::HTTPS),
proxy_config->getProxyPort(ProxyProtocol::HTTPS),
proxy_config->getProxyCredentials(ProxyProtocol::HTTPS),
cert_file_path);
ssl_curl_client.setCurlOpts();

View File

@ -247,6 +247,33 @@ private:
);
}
bool
nginxContainerIsRunning()
{
static const string nginx_container_name = "cp_nginx_gaia";
static const string cmd_running =
"docker ps --filter name=" + nginx_container_name + " --filter status=running";
dbgTrace(D_HEALTH_CHECK) << "Checking if the container is running with the commmand: " << cmd_running;
auto maybe_result = Singleton::Consume<I_ShellCmd>::by<HealthChecker>()->getExecOutput(cmd_running);
if (!maybe_result.ok()) {
dbgWarning(D_HEALTH_CHECK)
<< "Unable to get status of nginx container. return false and failing health check.";
return false;
}
return (*maybe_result).find(nginx_container_name) != string::npos;
}
void
closeCurrentSocket(I_Socket::socketFd fd, I_MainLoop::RoutineID curr_routine) {
dbgDebug(D_HEALTH_CHECK) << "Connection with client closed, client fd: " << fd;
open_connections_counter--;
i_socket->closeSocket(fd);
client_sockets_routines.erase(curr_routine);
}
void
handleConnection()
{
@ -254,7 +281,7 @@ private:
dbgDebug(D_HEALTH_CHECK)
<< "Cannot serve new client, reached maximun open connections bound which is:"
<< open_connections_counter
<< "maximun allowed: "
<< "maximum allowed: "
<< max_connections;
return;
}
@ -276,21 +303,48 @@ private:
dbgDebug(D_HEALTH_CHECK) << "Successfully accepted client, client fd: " << new_client_socket;
open_connections_counter++;
auto curr_routine = i_mainloop->addFileRoutine(
auto curr_routine = i_mainloop->addOneTimeRoutine(
I_MainLoop::RoutineType::RealTime,
new_client_socket,
[this] ()
{
auto curr_routine_id = i_mainloop->getCurrentRoutineId().unpack();
auto curr_client_socket = client_sockets_routines[curr_routine_id];
auto data_recieved = i_socket->receiveData(curr_client_socket, sizeof(uint8_t), false);
if (!data_recieved.ok()) {
dbgDebug(D_HEALTH_CHECK) << "Connection with client closed, client fd: " << curr_client_socket;
open_connections_counter--;
i_socket->closeSocket(curr_client_socket);
client_sockets_routines.erase(curr_routine_id);
closeCurrentSocket(curr_client_socket, curr_routine_id);
i_mainloop->stop();
}
static const string success_response =
"HTTP/1.1 200 OK\r\n"
"Content-Length: 25\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"health check successful\r\n";
static const vector<char> success_response_buffer(success_response.begin(), success_response.end());
static const string failure_response =
"HTTP/1.1 500 Internal Server Error\r\n"
"Content-Length: 21\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"health check failed\r\n";
static const vector<char> failure_response_buffer(failure_response.begin(), failure_response.end());
if (nginxContainerIsRunning()) {
dbgDebug(D_HEALTH_CHECK)
<< "nginx conatiner is running, returning the following response: "
<< success_response;
i_socket->writeData(curr_client_socket, success_response_buffer);
closeCurrentSocket(curr_client_socket, curr_routine_id);
return;
}
dbgDebug(D_HEALTH_CHECK)
<< "nginx conatiner is not running, returning the following response: "
<< failure_response;
i_socket->writeData(curr_client_socket, failure_response_buffer);
closeCurrentSocket(curr_client_socket, curr_routine_id);
},
"Health check probe connection handler",
true

View File

@ -6,6 +6,7 @@
#include "mock/mock_time_get.h"
#include "mock/mock_socket_is.h"
#include "mock/mock_mainloop.h"
#include "mock/mock_shell_cmd.h"
#include "health_check_manager.h"
#include "config.h"
@ -18,6 +19,22 @@ using namespace testing;
USE_DEBUG_FLAG(D_HEALTH_CHECK);
static const string response =
"HTTP/1.1 200 OK\r\n"
"Content-Length: 25\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"health check successful\r\n";
static const vector<char> response_buffer(response.begin(), response.end());
static const string failure_response =
"HTTP/1.1 500 Internal Server Error\r\n"
"Content-Length: 21\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"health check failed\r\n";
static const vector<char> failure_response_buffer(failure_response.begin(), failure_response.end());
class HealthCheckerTest : public testing::Test
{
public:
@ -47,6 +64,7 @@ public:
NiceMock<MockLogging> mock_log;
AgentDetails agent_details;
StrictMock<MockSocketIS> mock_socket;
NiceMock<MockShellCmd> mock_shell_cmd;
I_Socket::socketFd server_socket = -1;
Context ctx;
ConfigComponent config;
@ -82,7 +100,7 @@ TEST_F(HealthCheckerTest, clientConnection)
EXPECT_CALL(
mock_mainloop,
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, _, false)
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Health check probe listener startup", false)
).WillOnce(DoAll(SaveArg<1>(&handle_probe_routine), Return(0)));
EXPECT_CALL(
@ -95,11 +113,19 @@ TEST_F(HealthCheckerTest, clientConnection)
addFileRoutine(I_MainLoop::RoutineType::RealTime, _, _, _, true)
).WillRepeatedly(DoAll(SaveArg<2>(&connection_handler_routine), Return(0)));
EXPECT_CALL(
mock_mainloop,
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Health check probe connection handler", true)
).WillOnce(DoAll(SaveArg<1>(&connection_handler_routine), Return(0)));
int socket = 1;
EXPECT_CALL(mock_socket, acceptSocket(1, false, ip)).WillOnce(Return(socket));
EXPECT_CALL(mock_mainloop, getCurrentRoutineId()).WillRepeatedly(Return(0));
EXPECT_CALL(mock_socket, receiveData(_, 1, false)).WillOnce(Return(vector<char>()));
EXPECT_CALL(mock_shell_cmd, getExecOutput(_, _, _)).WillRepeatedly(Return(string("cp_nginx_gaia")));
EXPECT_CALL(mock_socket, writeData(_, response_buffer)).WillOnce(Return(true));
EXPECT_CALL(mock_socket, closeSocket(socket)).Times(2);
health_checker.init();
handle_probe_routine();
connection_handler_routine();
@ -194,10 +220,17 @@ TEST_F(HealthCheckerTest, disablingAfterEnabled)
addFileRoutine(I_MainLoop::RoutineType::RealTime, _, _, _, true)
).WillRepeatedly(DoAll(SaveArg<2>(&connection_handler_routine), Return(0)));
EXPECT_CALL(
mock_mainloop,
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Health check probe connection handler", true)
).WillOnce(DoAll(SaveArg<1>(&connection_handler_routine), Return(0)));
int socket = 1;
EXPECT_CALL(mock_socket, acceptSocket(1, false, ip)).WillOnce(Return(socket));
EXPECT_CALL(mock_mainloop, getCurrentRoutineId()).WillRepeatedly(Return(0));
EXPECT_CALL(mock_socket, receiveData(_, 1, false)).WillOnce(Return(vector<char>()));
EXPECT_CALL(mock_shell_cmd, getExecOutput(_, _, _)).WillOnce(Return(string("cp_nginx_gaia")));
EXPECT_CALL(mock_socket, writeData(_, response_buffer)).WillOnce(Return(true));
EXPECT_CALL(mock_socket, closeSocket(socket)).Times(2);
health_checker.init();
handle_probe_routine();
@ -242,11 +275,20 @@ TEST_F(HealthCheckerTest, changePortIpConfig)
addFileRoutine(I_MainLoop::RoutineType::RealTime, _, _, _, true)
).WillRepeatedly(DoAll(SaveArg<2>(&connection_handler_routine), Return(0)));
EXPECT_CALL(
mock_mainloop,
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Health check probe connection handler", true)
).WillOnce(DoAll(SaveArg<1>(&connection_handler_routine), Return(0)));
int socket = 1;
int socket2 = 0;
EXPECT_CALL(mock_socket, acceptSocket(1, false, ip)).WillOnce(Return(socket));
EXPECT_CALL(mock_mainloop, getCurrentRoutineId()).WillRepeatedly(Return(0));
EXPECT_CALL(mock_socket, receiveData(_, 1, false)).Times(2).WillRepeatedly(Return(vector<char>()));
EXPECT_CALL(mock_shell_cmd, getExecOutput(_, _, _)).Times(2).WillRepeatedly(Return(string("cp_nginx_gaia")));
EXPECT_CALL(mock_socket, writeData(_, response_buffer)).Times(2).WillRepeatedly(Return(true));
EXPECT_CALL(mock_socket, closeSocket(socket)).Times(2);
EXPECT_CALL(mock_socket, closeSocket(socket2));
health_checker.init();
handle_probe_routine();
connection_handler_routine();
@ -258,3 +300,44 @@ TEST_F(HealthCheckerTest, changePortIpConfig)
setConfiguration(new_port, "Health Check", "Probe port");
connection_handler_routine();
}
TEST_F(HealthCheckerTest, FailedHealthCheck)
{
string ip = "1.2.3.4";
setConfiguration(ip, "Health Check", "Probe IP");
uint port = 11600;
setConfiguration(port, "Health Check", "Probe port");
EXPECT_CALL(
mock_mainloop,
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, _, false)
).WillOnce(DoAll(SaveArg<1>(&handle_probe_routine), Return(0)));
EXPECT_CALL(
mock_socket,
genSocket(I_Socket::SocketType::TCP, false, true, _)
).WillRepeatedly(Return(1));
EXPECT_CALL(
mock_mainloop,
addFileRoutine(I_MainLoop::RoutineType::RealTime, _, _, _, true)
).WillRepeatedly(DoAll(SaveArg<2>(&connection_handler_routine), Return(0)));
EXPECT_CALL(
mock_mainloop,
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Health check probe connection handler", true)
).WillOnce(DoAll(SaveArg<1>(&connection_handler_routine), Return(0)));
int socket = 1;
EXPECT_CALL(mock_socket, acceptSocket(1, false, ip)).WillOnce(Return(socket));
EXPECT_CALL(mock_mainloop, getCurrentRoutineId()).WillRepeatedly(Return(0));
EXPECT_CALL(mock_socket, receiveData(_, 1, false)).WillOnce(Return(vector<char>()));
EXPECT_CALL(mock_shell_cmd, getExecOutput(_, _, _)).WillOnce(Return(string("")));
EXPECT_CALL(mock_socket, writeData(_, failure_response_buffer)).WillOnce(Return(true));
EXPECT_CALL(mock_socket, closeSocket(socket)).Times(2);
health_checker.init();
handle_probe_routine();
connection_handler_routine();
connection_handler_routine();
setConfiguration(false, "Health Check", "Probe enabled");
}

View File

@ -24,8 +24,8 @@ USE_DEBUG_FLAG(D_ORCHESTRATOR);
static inline string &
trim(string &in)
{
in.erase(in.begin(), find_if(in.begin(), in.end(), not1(ptr_fun<int, int>(isspace))));
in.erase(find_if(in.rbegin(), in.rend(), not1(ptr_fun<int, int>(isspace))).base(), in.end());
in.erase(in.begin(), find_if(in.begin(), in.end(), [] (char c) { return !isspace(c); }));
in.erase(find_if(in.rbegin(), in.rend(), [] (char c) { return !isspace(c); }).base(), in.end());
return in;
}

View File

@ -266,17 +266,25 @@ private:
S2C_PARAM(std::string, agentId);
};
class PolicyVersionPatchRequest : public ClientRest
class PolicyVersionPatchRequest
{
public:
PolicyVersionPatchRequest(const std::string &_policy_version)
PolicyVersionPatchRequest(const std::string &_policy_version, const std::string &_policy_versions)
:
policy_version(_policy_version)
policy_version(_policy_version),
policy_versions(_policy_versions)
{
}
Maybe<std::string>
genJson() const
{
return "{ \"policyVersion\" :\"" + policy_version + "\", \"versions\": " + policy_versions + "}";
}
private:
C2S_LABEL_PARAM(std::string, policy_version, "policyVersion");
std::string policy_version;
std::string policy_versions;
};
class TokenRequest : public ClientRest

View File

@ -41,7 +41,10 @@ public:
void init() override;
Maybe<void> getUpdate(CheckUpdateRequest &request) override;
Maybe<std::string> downloadAttributeFile(const GetResourceFile &resourse_file) override;
Maybe<void> sendPolicyVersion(const std::string &policy_version) const override;
Maybe<void> sendPolicyVersion(
const std::string &policy_version,
const std::string &policy_versions
) const override;
private:
DeclarativePolicyUtils declarative_policy_utils;

View File

@ -46,7 +46,10 @@ public:
void init() override;
Maybe<void> getUpdate(CheckUpdateRequest &request) override;
Maybe<std::string> downloadAttributeFile(const GetResourceFile &resourse_file) override;
Maybe<void> sendPolicyVersion(const std::string &policy_version) const override;
Maybe<void> sendPolicyVersion(
const std::string &policy_version,
const std::string &policy_versions
) const override;
private:
Maybe<std::string> getNewVersion();

View File

@ -33,7 +33,10 @@ public:
Maybe<std::string> downloadAttributeFile(const GetResourceFile &resourse_file) override;
void setAddressExtenesion(const std::string &extension) override;
Maybe<void> sendPolicyVersion(const std::string &policy_version) const override;
Maybe<void> sendPolicyVersion(
const std::string &policy_version,
const std::string &policy_versions
) const override;
private:
std::string getChecksum(const std::string &file_path);

View File

@ -55,5 +55,11 @@ public:
MOCK_CONST_METHOD1(executeCmd, bool(const std::string &));
MOCK_CONST_METHOD1(base64Encode, std::string(const std::string &));
MOCK_CONST_METHOD1(base64Decode, std::string(const std::string &));
MOCK_CONST_METHOD2(removeDirectory, bool(const std::string &, bool delete_content));
MOCK_CONST_METHOD1(loadTenantsFromDir, void(const std::string &));
MOCK_CONST_METHOD3(
deleteVirtualTenantProfileFiles,
void(const std::string &tenant_id, const std::string &profile_id, const std::string &conf_path)
);
};
#endif // __MOCK_ORCHESTRATION_TOOLS_H__

View File

@ -38,14 +38,16 @@ public:
MOCK_CONST_METHOD0(getUpdatePolicyVersion, const std::string &());
MOCK_CONST_METHOD0(getPolicyVersions, const std::string &());
MOCK_METHOD6(
updateServiceConfiguration,
bool(
Maybe<void>(
const std::string &new_policy_path,
const std::string &new_settings_path,
const std::vector<std::string> &new_data_files,
const std::string &tenant_id,
const std::string &profile_id,
const std::string &child_tenant_id,
const std::string &child_profile_id,
const bool last_iteration
)
);

View File

@ -31,7 +31,7 @@ public:
MOCK_METHOD1(getUpdate, Maybe<void>(CheckUpdateRequest &));
MOCK_METHOD1(downloadAttributeFile, Maybe<std::string>(const GetResourceFile &));
MOCK_METHOD1(setAddressExtenesion, void(const std::string &));
MOCK_CONST_METHOD1(sendPolicyVersion, Maybe<void>(const std::string &));
MOCK_CONST_METHOD2(sendPolicyVersion, Maybe<void>(const std::string &, const std::string &));
};
#endif // __MOCK_UPDATE_COMMUNICATION_H__

View File

@ -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 k8s_policy_utils.cc namespace_data.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 new_appsec_linux_policy.cc new_appsec_policy_crd_parser.cc new_custom_response.cc new_exceptions.cc new_log_trigger.cc new_practice.cc new_trusted_sources.cc access_control_practice.cc)

View File

@ -0,0 +1,245 @@
// 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 "access_control_practice.h"
using namespace std;
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
static const set<string> valid_modes = {"prevent", "detect", "inactive"};
static const set<string> valid_units = {"minute", "second"};
static const std::unordered_map<std::string, std::string> key_to_mode_val = {
{ "prevent-learn", "Prevent"},
{ "detect-learn", "Detect"},
{ "prevent", "Prevent"},
{ "detect", "Detect"},
{ "inactive", "Inactive"}
};
static const std::unordered_map<std::string, std::string> key_to_units_val = {
{ "second", "Second"},
{ "minute", "Minute"}
};
void
RateLimitRulesTriggerSection::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("id", id),
cereal::make_nvp("name", name),
cereal::make_nvp("type", type)
);
}
const string &
RateLimitRulesTriggerSection::getName() const
{
return name;
}
void
RateLimitRulesSection::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("id", id),
cereal::make_nvp("URI", uri),
cereal::make_nvp("scope", key_to_units_val.at(scope)),
cereal::make_nvp("triggers", triggers),
cereal::make_nvp("limit", limit)
);
}
RateLimitSection::RateLimitSection(
const string &asset_name,
const string &url,
const string &uri,
const std::string &_mode,
const std::string &_practice_id,
const std::string &_name,
const std::vector<RateLimitRulesSection> &_rules)
:
mode(_mode),
practice_id(_practice_id),
name(_name),
rules(_rules)
{
bool any = asset_name == "Any" && url == "Any" && uri == "Any";
string asset_id = any ? "Any" : url+uri;
context = "assetId(" + asset_id + ")";
}
void
RateLimitSection::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("context", context),
cereal::make_nvp("mode", key_to_mode_val.at(mode)),
cereal::make_nvp("practiceId", practice_id),
cereal::make_nvp("name", name),
cereal::make_nvp("rules", rules)
);
}
const string &
RateLimitSection::getId() const
{
return practice_id;
}
const string &
RateLimitSection::getName() const
{
return name;
}
const string &
RateLimitSection::getMode() const
{
return mode;
}
void
AccessControlRulebaseSection::save(cereal::JSONOutputArchive &out_ar) const
{
vector<string> empty;
out_ar(
cereal::make_nvp("accessControl", empty),
cereal::make_nvp("traditionalFirewall", empty),
cereal::make_nvp("l4firewall", empty),
cereal::make_nvp("rateLimit", rate_limit)
);
}
void
AccessControlRulebaseWrapper::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("rulebase", rule_base)
);
}
void
AccessControlRateLimiteRules::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading Access control rate limite rules";
parseAppsecJSONKey<int>("limit", limit, archive_in);
parseAppsecJSONKey<string>("uri", uri, archive_in);
parseAppsecJSONKey<string>("unit", unit, archive_in);
if (valid_units.count(unit) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "Access control rate limite rules units invalid: "
<< unit;
}
parseAppsecJSONKey<string>("comment", comment, archive_in);
parseAppsecJSONKey<vector<string>>("triggers", triggers, archive_in);
}
const vector<string>
AccessControlRateLimiteRules::getTriggers() const
{
return triggers;
}
RateLimitRulesSection
AccessControlRateLimiteRules::createRateLimitRulesSection(const RateLimitRulesTriggerSection &trigger) const
{
string id = "";
try {
id = to_string(boost::uuids::random_generator()());
} catch (const boost::uuids::entropy_error &e) {
dbgWarning(D_LOCAL_POLICY) << "Failed to create random id";
}
vector<RateLimitRulesTriggerSection> triggers_section;
string trigger_name = trigger.getName().substr(trigger.getName().find("/") + 1);
if (find(triggers.begin(), triggers.end(), trigger_name) != triggers.end()) {
triggers_section.push_back(trigger);
}
return RateLimitRulesSection(
limit,
id,
uri,
unit,
triggers_section
);
}
void
AccessControlRateLimit::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading Access control rate limit";
parseAppsecJSONKey<string>("overrideMode", mode, archive_in, "Inactive");
if (valid_modes.count(mode) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec access control rate limit override mode invalid: " << mode;
}
parseAppsecJSONKey<std::vector<AccessControlRateLimiteRules>>("rules", rules, archive_in);
}
vector<RateLimitRulesSection>
AccessControlRateLimit::createRateLimitRulesSection(const RateLimitRulesTriggerSection &trigger) const
{
vector<RateLimitRulesSection> rules_section;
for (const AccessControlRateLimiteRules &rule : rules) {
rules_section.push_back(rule.createRateLimitRulesSection(trigger));
}
return rules_section;
}
const vector<AccessControlRateLimiteRules> &
AccessControlRateLimit::getRules() const
{
return rules;
}
const string &
AccessControlRateLimit::getMode() const
{
return mode;
}
void
AccessControlPracticeSpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec";
parseAppsecJSONKey<string>("name", practice_name, archive_in);
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
parseAppsecJSONKey<AccessControlRateLimit>("rateLimit", rate_limit, archive_in);
}
void
AccessControlPracticeSpec::setName(const string &_name)
{
practice_name = _name;
}
const AccessControlRateLimit &
AccessControlPracticeSpec::geRateLimit() const
{
return rate_limit;
}
const string &
AccessControlPracticeSpec::getAppSecClassName() const
{
return appsec_class_name;
}
const string &
AccessControlPracticeSpec::getName() const
{
return practice_name;
}
// LCOV_EXCL_STOP

View File

@ -34,6 +34,26 @@ AppSecWebBotsURI::getURI() const
return uri;
}
std::vector<std::string>
AppSecPracticeAntiBot::getIjectedUris() const
{
vector<string> injected;
for (const AppSecWebBotsURI &uri : injected_uris) {
injected.push_back(uri.getURI());
}
return injected;
}
std::vector<std::string>
AppSecPracticeAntiBot::getValidatedUris() const
{
vector<string> validated;
for (const AppSecWebBotsURI &uri : validated_uris) {
validated.push_back(uri.getURI());
}
return validated;
}
void
AppSecPracticeAntiBot::load(cereal::JSONInputArchive &archive_in)
{
@ -52,7 +72,7 @@ AppSecPracticeAntiBot::save(cereal::JSONOutputArchive &out_ar) const
vector<string> injected;
vector<string> validated;
for (const AppSecWebBotsURI &uri : injected_uris) injected.push_back(uri.getURI());
for (const AppSecWebBotsURI &uri : validated_uris) injected.push_back(uri.getURI());
for (const AppSecWebBotsURI &uri : validated_uris) validated.push_back(uri.getURI());
out_ar(
cereal::make_nvp("injected", injected),
cereal::make_nvp("validated", validated)
@ -313,6 +333,16 @@ AppSecOverride::save(cereal::JSONOutputArchive &out_ar) const
);
}
void
AppsecPracticeAntiBotSection::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("injected", injected_uris),
cereal::make_nvp("validated", validated_uris)
);
}
// LCOV_EXCL_START Reason: no test exist
WebAppSection::WebAppSection(
const string &_application_urls,
const string &_asset_id,
@ -321,6 +351,7 @@ WebAppSection::WebAppSection(
const string &_rule_name,
const string &_practice_id,
const string &_practice_name,
const string &_context,
const AppSecPracticeSpec &parsed_appsec_spec,
const LogTriggerSection &parsed_log_trigger,
const string &default_mode,
@ -333,7 +364,7 @@ WebAppSection::WebAppSection(
rule_name(_rule_name),
practice_id(_practice_id),
practice_name(_practice_name),
context("practiceId(" + practice_id +")"),
context(_context),
web_attack_mitigation_severity(parsed_appsec_spec.getWebAttacks().getMinimumConfidence()),
web_attack_mitigation_mode(parsed_appsec_spec.getWebAttacks().getMode(default_mode)),
practice_advanced_config(parsed_appsec_spec),
@ -353,6 +384,50 @@ WebAppSection::WebAppSection(
}
}
WebAppSection::WebAppSection(
const std::string &_application_urls,
const std::string &_asset_id,
const std::string &_asset_name,
const std::string &_rule_id,
const std::string &_rule_name,
const std::string &_practice_id,
const std::string &_practice_name,
const string &_context,
const std::string &_web_attack_mitigation_severity,
const std::string &_web_attack_mitigation_mode,
const PracticeAdvancedConfig &_practice_advanced_config,
const AppsecPracticeAntiBotSection &_anti_bots,
const LogTriggerSection &parsed_log_trigger,
const AppSecTrustedSources &parsed_trusted_sources)
:
application_urls(_application_urls),
asset_id(_asset_id),
asset_name(_asset_name),
rule_id(_rule_id),
rule_name(_rule_name),
practice_id(_practice_id),
practice_name(_practice_name),
context(_context),
web_attack_mitigation_severity(_web_attack_mitigation_severity),
web_attack_mitigation_mode(_web_attack_mitigation_mode),
practice_advanced_config(_practice_advanced_config),
anti_bots(_anti_bots),
trusted_sources({parsed_trusted_sources})
{
web_attack_mitigation = true;
web_attack_mitigation_action =
web_attack_mitigation_severity == "critical" ? "low" :
web_attack_mitigation_severity == "high" ? "balanced" :
web_attack_mitigation_severity == "medium" ? "high" :
"Error";
triggers.push_back(TriggersInWaapSection(parsed_log_trigger));
for (const SourcesIdentifiers &source_ident : parsed_trusted_sources.getSourcesIdentifiers()) {
overrides.push_back(AppSecOverride(source_ident));
}
}
// LCOV_EXCL_STOP
void
WebAppSection::save(cereal::JSONOutputArchive &out_ar) const
{

View File

@ -147,6 +147,40 @@ ExceptionMatch::ExceptionMatch(const AppsecExceptionSpec &parsed_exception)
}
}
ExceptionMatch::ExceptionMatch(const NewAppsecException &parsed_exception)
:
match_type(MatchType::Operator),
op("and")
{
if (!parsed_exception.getCountryCode().empty()) {
items.push_back(ExceptionMatch("countryCode", parsed_exception.getCountryCode()));
}
if (!parsed_exception.getCountryName().empty()) {
items.push_back(ExceptionMatch("countryName", parsed_exception.getCountryName()));
}
if (!parsed_exception.getHostName().empty()) {
items.push_back(ExceptionMatch("hostName", parsed_exception.getHostName()));
}
if (!parsed_exception.getParamName().empty()) {
items.push_back(ExceptionMatch("paramName", parsed_exception.getParamName()));
}
if (!parsed_exception.getParamValue().empty()) {
items.push_back(ExceptionMatch("paramValue", parsed_exception.getParamValue()));
}
if (!parsed_exception.getProtectionName().empty()) {
items.push_back(ExceptionMatch("protectionName", parsed_exception.getProtectionName()));
}
if (!parsed_exception.getSourceIdentifier().empty()) {
items.push_back(ExceptionMatch("sourceIdentifier", parsed_exception.getSourceIdentifier()));
}
if (!parsed_exception.getSourceIp().empty()) {
items.push_back(ExceptionMatch("sourceIp", parsed_exception.getSourceIp()));
}
if (!parsed_exception.getUrl().empty()) {
items.push_back(ExceptionMatch("url", parsed_exception.getUrl()));
}
}
void
ExceptionMatch::save(cereal::JSONOutputArchive &out_ar) const
{

View File

@ -0,0 +1,192 @@
// 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 __ACCESS_CONTROL_PRACTICE_H__
#define __ACCESS_CONTROL_PRACTICE_H__
#include <string>
#include <cereal/archives/json.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include "config.h"
#include "debug.h"
#include "local_policy_common.h"
class RateLimitRulesTriggerSection
{
public:
// LCOV_EXCL_START Reason: no test exist
RateLimitRulesTriggerSection() {};
RateLimitRulesTriggerSection(
const std::string &_id,
const std::string &_name,
const std::string &_type
)
:
id(_id),
name(_name),
type(_type)
{};
// LCOV_EXCL_STOP
void save(cereal::JSONOutputArchive &out_ar) const;
const std::string & getName() const;
private:
std::string id;
std::string name;
std::string type;;
};
class RateLimitRulesSection
{
public:
RateLimitRulesSection() {};
// LCOV_EXCL_START Reason: no test exist
RateLimitRulesSection(
const int _limit,
const std::string &_id,
const std::string &_uri,
const std::string &_scope,
const std::vector<RateLimitRulesTriggerSection> &_triggers
)
:
limit(_limit),
id(_id),
uri(_uri),
scope(_scope),
triggers(_triggers)
{};
// LCOV_EXCL_STOP
void save(cereal::JSONOutputArchive &out_ar) const;
private:
int limit;
std::string id;
std::string uri;
std::string scope;
std::vector<RateLimitRulesTriggerSection> triggers;
};
class RateLimitSection
{
public:
// LCOV_EXCL_START Reason: no test exist
RateLimitSection() {};
// LCOV_EXCL_STOP
RateLimitSection(
const std::string &asset_name,
const std::string &url,
const std::string &uri,
const std::string &_mode,
const std::string &_practice_id,
const std::string &_name,
const std::vector<RateLimitRulesSection> &_rules);
void save(cereal::JSONOutputArchive &out_ar) const;
const std::string & getId() const;
const std::string & getName() const;
const std::string & getMode() const;
private:
std::string context;
std::string mode;
std::string practice_id;
std::string name;
std::vector<RateLimitRulesSection> rules;
};
class AccessControlRulebaseSection
{
public:
AccessControlRulebaseSection() {};
AccessControlRulebaseSection(const std::vector<RateLimitSection> &_rate_limit) : rate_limit(_rate_limit) {};
void save(cereal::JSONOutputArchive &out_ar) const;
private:
std::vector<RateLimitSection> rate_limit;
};
class AccessControlRulebaseWrapper
{
public:
AccessControlRulebaseWrapper() {};
AccessControlRulebaseWrapper(
const std::vector<RateLimitSection> &rate_limits
)
:
rule_base(AccessControlRulebaseSection(rate_limits))
{};
void save(cereal::JSONOutputArchive &out_ar) const;
private:
AccessControlRulebaseSection rule_base;
};
class AccessControlRateLimiteRules
{
public:
void load(cereal::JSONInputArchive &archive_in);
const std::vector<std::string> getTriggers() const;
RateLimitRulesSection createRateLimitRulesSection(const RateLimitRulesTriggerSection &trigger) const;
private:
int limit;
std::string uri;
std::string unit;
std::string comment;
std::vector<std::string> triggers;
};
class AccessControlRateLimit
{
public:
void load(cereal::JSONInputArchive &archive_in);
const std::vector<AccessControlRateLimiteRules> & getRules() const;
const std::string & getMode() const;
std::vector<RateLimitRulesSection> createRateLimitRulesSection(const RateLimitRulesTriggerSection &trigger) const;
private:
std::string mode;
std::vector<AccessControlRateLimiteRules> rules;
};
class AccessControlPracticeSpec
{
public:
void load(cereal::JSONInputArchive &archive_in);
const AccessControlRateLimit & geRateLimit() const;
const std::string & getAppSecClassName() const;
const std::string & getName() const;
void setName(const std::string &_name);
private:
AccessControlRateLimit rate_limit;
std::string appsec_class_name;
std::string practice_name;
};
#endif // __ACCESS_CONTROL_PRACTICE_H__

View File

@ -28,6 +28,7 @@
#include "triggers_section.h"
#include "exceptions_section.h"
#include "trusted_sources_section.h"
#include "new_practice.h"
class AppSecWebBotsURI
{
@ -43,6 +44,9 @@ private:
class AppSecPracticeAntiBot
{
public:
std::vector<std::string> getIjectedUris() const;
std::vector<std::string> getValidatedUris() const;
void load(cereal::JSONInputArchive &archive_in);
void save(cereal::JSONOutputArchive &out_ar) const;
@ -152,6 +156,22 @@ public:
url_max_size(parsed_appsec_spec.getWebAttacks().getMaxUrlSizeBytes())
{}
// LCOV_EXCL_START Reason: no test exist
PracticeAdvancedConfig(
int _http_header_max_size,
int _http_request_body_max_size,
int _json_max_object_depth,
int _url_max_size)
:
http_header_max_size(_http_header_max_size),
http_illegal_methods_allowed(0),
http_request_body_max_size(_http_request_body_max_size),
json_max_object_depth(_json_max_object_depth),
url_max_size(_url_max_size)
{}
// LCOV_EXCL_STOP
void save(cereal::JSONOutputArchive &out_ar) const;
private:
@ -194,6 +214,29 @@ private:
std::map<std::string, std::string> parsed_match;
};
class AppsecPracticeAntiBotSection
{
public:
AppsecPracticeAntiBotSection() {};
// LCOV_EXCL_START Reason: no test exist
AppsecPracticeAntiBotSection(const NewAppSecPracticeAntiBot &anti_bot) :
injected_uris(anti_bot.getIjectedUris()),
validated_uris(anti_bot.getValidatedUris())
{};
// LCOV_EXCL_STOP
AppsecPracticeAntiBotSection(const AppSecPracticeAntiBot &anti_bot) :
injected_uris(anti_bot.getIjectedUris()),
validated_uris(anti_bot.getValidatedUris())
{};
void save(cereal::JSONOutputArchive &out_ar) const;
private:
std::vector<std::string> injected_uris;
std::vector<std::string> validated_uris;
};
class WebAppSection
{
public:
@ -207,12 +250,29 @@ public:
const std::string &_rule_name,
const std::string &_practice_id,
const std::string &_practice_name,
const std::string &_context,
const AppSecPracticeSpec &parsed_appsec_spec,
const LogTriggerSection &parsed_log_trigger,
const std::string &default_mode,
const AppSecTrustedSources &parsed_trusted_sources
);
WebAppSection(
const std::string &_application_urls,
const std::string &_asset_id,
const std::string &_asset_name,
const std::string &_rule_id,
const std::string &_rule_name,
const std::string &_practice_id,
const std::string &_practice_name,
const std::string &_context,
const std::string &_web_attack_mitigation_severity,
const std::string &_web_attack_mitigation_mode,
const PracticeAdvancedConfig &_practice_advanced_config,
const AppsecPracticeAntiBotSection &_anti_bots,
const LogTriggerSection &parsed_log_trigger,
const AppSecTrustedSources &parsed_trusted_sources);
void save(cereal::JSONOutputArchive &out_ar) const;
private:
@ -230,7 +290,7 @@ private:
bool web_attack_mitigation;
std::vector<TriggersInWaapSection> triggers;
PracticeAdvancedConfig practice_advanced_config;
AppSecPracticeAntiBot anti_bots;
AppsecPracticeAntiBotSection anti_bots;
std::vector<AppSecTrustedSources> trusted_sources;
std::vector<AppSecOverride> overrides;
};
@ -250,7 +310,7 @@ public:
const std::string &_web_attack_mitigation_severity,
const std::string &_web_attack_mitigation_mode,
bool _web_attack_mitigation,
const AppSecPracticeSpec &parsed_appsec_spec)
const PracticeAdvancedConfig &_practice_advanced_config)
:
application_urls(_application_urls),
asset_id(_asset_id),
@ -264,7 +324,7 @@ public:
web_attack_mitigation_severity(_web_attack_mitigation_severity),
web_attack_mitigation_mode(_web_attack_mitigation_mode),
web_attack_mitigation(_web_attack_mitigation),
practice_advanced_config(parsed_appsec_spec)
practice_advanced_config(_practice_advanced_config)
{}
void save(cereal::JSONOutputArchive &out_ar) const;
@ -302,6 +362,7 @@ private:
std::vector<WebAPISection> webAPIPractices;
};
class AppSecWrapper
{
public:

View File

@ -24,6 +24,7 @@
#include "debug.h"
#include "rest.h"
#include "local_policy_common.h"
#include "new_exceptions.h"
class AppsecExceptionSpec
{
@ -62,6 +63,7 @@ class ExceptionMatch
public:
ExceptionMatch() {}
ExceptionMatch(const AppsecExceptionSpec &parsed_exception);
ExceptionMatch(const NewAppsecException &parsed_exception);
ExceptionMatch(const std::string &_key, const std::vector<std::string> &_value)
:
match_type(MatchType::Condition),

View File

@ -28,6 +28,7 @@
#include "i_env_details.h"
#include "i_agent_details.h"
#include "appsec_practice_section.h"
#include "new_appsec_linux_policy.h"
#include "policy_maker_utils.h"
enum class AnnotationKeys { PolicyKey, OpenAppsecIo, SyslogAddressKey, SyslogPortKey, ModeKey };
@ -44,7 +45,8 @@ class K8sPolicyUtils
public:
void init();
std::map<std::string, AppsecLinuxPolicy> createAppsecPoliciesFromIngresses();
std::tuple<std::map<std::string, AppsecLinuxPolicy>, std::map<std::string, V1beta2AppsecLinuxPolicy>>
createAppsecPoliciesFromIngresses();
bool getClusterId() const;
private:
@ -60,13 +62,41 @@ private:
const ParsedRule &default_rule
) const;
std::map<AnnotationTypes, std::unordered_set<std::string>> extractElementsNamesV1beta2(
const std::vector<NewParsedRule> &specific_rules,
const NewParsedRule &default_rule
) const;
template<class T>
std::vector<T> extractElementsFromCluster(
const std::string &crd_plural,
const std::unordered_set<std::string> &elements_names
) const;
Maybe<AppsecLinuxPolicy> createAppsecPolicyK8s(
template<class T>
std::vector<T> extractV1Beta2ElementsFromCluster(
const std::string &crd_plural,
const std::unordered_set<std::string> &elements_names
) const;
Maybe<AppsecLinuxPolicy> createAppsecPolicyK8sFromV1beta1Crds(
const AppsecSpecParser<AppsecPolicySpec> &appsec_policy_spe,
const std::string &ingress_mode
) const;
Maybe<V1beta2AppsecLinuxPolicy> createAppsecPolicyK8sFromV1beta2Crds(
const AppsecSpecParser<NewAppsecPolicySpec> &appsec_policy_spe,
const std::string &ingress_mode
) const;
template<class T, class K>
void createPolicy(
T &appsec_policy,
std::map<std::string, T> &policies,
std::map<AnnotationKeys, std::string> &annotations_values,
const SingleIngressData &item) const;
std::tuple<Maybe<AppsecLinuxPolicy>, Maybe<V1beta2AppsecLinuxPolicy>> createAppsecPolicyK8s(
const std::string &policy_name,
const std::string &ingress_mode
) const;

View File

@ -22,10 +22,13 @@
#include "config.h"
#include "debug.h"
#include "rest.h"
#include "cereal/archives/json.hpp"
#include <cereal/types/map.hpp>
#include "customized_cereal_map.h"
USE_DEBUG_FLAG(D_LOCAL_POLICY);
enum class PracticeType { WebApplication, WebAPI };
enum class PracticeType { WebApplication, WebAPI, RateLimit };
enum class TriggerType { Log, WebUserResponse };
enum class MatchType { Condition, Operator };
@ -36,7 +39,8 @@ static const std::unordered_map<std::string, MatchType> string_to_match_type = {
static const std::unordered_map<std::string, PracticeType> string_to_practice_type = {
{ "WebApplication", PracticeType::WebApplication },
{ "WebAPI", PracticeType::WebAPI }
{ "WebAPI", PracticeType::WebAPI },
{ "RateLimit", PracticeType::RateLimit }
};
static const std::unordered_map<std::string, TriggerType> string_to_trigger_type = {
@ -73,6 +77,26 @@ parseAppsecJSONKey(
}
}
class AppsecSpecParserMetaData
{
public:
void
load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "AppsecSpecParserMetaData load";
parseAppsecJSONKey<std::map<std::string, std::string>>("annotations", annotations, archive_in);
}
const std::map<std::string, std::string> &
getAnnotations() const
{
return annotations;
}
private:
std::map<std::string, std::string> annotations;
};
template <typename T>
class AppsecSpecParser : public ClientRest
{
@ -90,6 +114,7 @@ public:
try {
cereal::JSONInputArchive in_ar(ss);
in_ar(cereal::make_nvp("spec", spec));
in_ar(cereal::make_nvp("metadata", meta_data));
} catch (cereal::Exception &e) {
dbgWarning(D_LOCAL_POLICY) << "Failed to load spec JSON. Error: " << e.what();
return false;
@ -103,10 +128,17 @@ public:
spec.setName(_name);
}
const AppsecSpecParserMetaData &
getMetaData() const
{
return meta_data;
}
const T & getSpec() const { return spec; }
private:
T spec;
AppsecSpecParserMetaData meta_data;
};
#endif // __LOCAL_POLICY_COMMON_H__

View File

@ -0,0 +1,84 @@
// 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 __NEW_APPSEC_LINUX_POLICY_H__
#define __NEW_APPSEC_LINUX_POLICY_H__
#include <list>
#include <vector>
#include <cereal/archives/json.hpp>
#include <cereal/types/list.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include "config.h"
#include "debug.h"
#include "customized_cereal_map.h"
#include "new_appsec_policy_crd_parser.h"
#include "new_custom_response.h"
#include "new_exceptions.h"
#include "new_log_trigger.h"
#include "new_practice.h"
#include "access_control_practice.h"
#include "new_trusted_sources.h"
class V1beta2AppsecLinuxPolicy : Singleton::Consume<I_Environment>
{
public:
// LCOV_EXCL_START Reason: no test exist
V1beta2AppsecLinuxPolicy() {}
V1beta2AppsecLinuxPolicy(
const NewAppsecPolicySpec &_policies,
const std::vector<NewAppSecPracticeSpec> &_threat_prevention_practices,
const std::vector<AccessControlPracticeSpec> &_access_control_practices,
const std::vector<NewAppsecLogTrigger> &_log_triggers,
const std::vector<NewAppSecCustomResponse> &_custom_responses,
const std::vector<NewAppsecException> &_exceptions,
const std::vector<NewTrustedSourcesSpec> &_trusted_sources,
const std::vector<NewSourcesIdentifiers> &_sources_identifiers)
:
policies(_policies),
threat_prevection_practices(_threat_prevention_practices),
access_control_practices(_access_control_practices),
log_triggers(_log_triggers),
custom_responses(_custom_responses),
exceptions(_exceptions),
trusted_sources(_trusted_sources),
sources_identifiers(_sources_identifiers) {}
// LCOV_EXCL_STOP
const NewAppsecPolicySpec & getAppsecPolicySpec() const;
const std::vector<NewAppSecPracticeSpec> & getAppSecPracticeSpecs() const;
const std::vector<AccessControlPracticeSpec> & getAccessControlPracticeSpecs() const;
const std::vector<NewAppsecLogTrigger> & getAppsecTriggerSpecs() const;
const std::vector<NewAppSecCustomResponse> & getAppSecCustomResponseSpecs() const;
const std::vector<NewAppsecException> & getAppsecExceptionSpecs() const;
const std::vector<NewTrustedSourcesSpec> & getAppsecTrustedSourceSpecs() const;
const std::vector<NewSourcesIdentifiers> & getAppsecSourceIdentifierSpecs() const;
void addSpecificRule(const NewParsedRule &_rule);
private:
NewAppsecPolicySpec policies;
std::vector<NewAppSecPracticeSpec> threat_prevection_practices;
std::vector<AccessControlPracticeSpec> access_control_practices;
std::vector<NewAppsecLogTrigger> log_triggers;
std::vector<NewAppSecCustomResponse> custom_responses;
std::vector<NewAppsecException> exceptions;
std::vector<NewTrustedSourcesSpec> trusted_sources;
std::vector<NewSourcesIdentifiers> sources_identifiers;
};
#endif // __NEW_APPSEC_LINUX_POLICY_H__

View File

@ -0,0 +1,82 @@
// 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 __NEW_APPSEC_POLICY_CRD_PARSER_H__
#define __NEW_APPSEC_POLICY_CRD_PARSER_H__
#include <string>
#include <cereal/archives/json.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include "config.h"
#include "debug.h"
#include "rest.h"
#include "local_policy_common.h"
// LCOV_EXCL_START Reason: no test exist
class NewParsedRule
{
public:
NewParsedRule() {}
NewParsedRule(const std::string &_host) : host(_host) {}
void load(cereal::JSONInputArchive &archive_in);
const std::vector<std::string> & getLogTriggers() const;
const std::vector<std::string> & getExceptions() const;
const std::vector<std::string> & getPractices() const;
const std::vector<std::string> & getAccessControlPractices() const;
const std::string & getSourceIdentifiers() const;
const std::string & getCustomResponse() const;
const std::string & getTrustedSources() const;
const std::string & getHost() const;
const std::string & getMode() const;
void setHost(const std::string &_host);
void setMode(const std::string &_mode);
private:
std::vector<std::string> log_triggers;
std::vector<std::string> exceptions;
std::vector<std::string> threat_prevention_practices;
std::vector<std::string> access_control_practices;
std::string source_identifiers;
std::string custom_response;
std::string trusted_sources;
std::string host;
std::string mode;
};
class NewAppsecPolicySpec : Singleton::Consume<I_Environment>
{
public:
void load(cereal::JSONInputArchive &archive_in);
const NewParsedRule & getDefaultRule() const;
const std::vector<NewParsedRule> & getSpecificRules() const;
const std::string & getAppSecClassName() const;
bool isAssetHostExist(const std::string &full_url) const;
void addSpecificRule(const NewParsedRule &_rule);
private:
std::string appsec_class_name;
NewParsedRule default_rule;
std::vector<NewParsedRule> specific_rules;
};
#endif // __NEW_APPSEC_POLICY_CRD_PARSER_H__
// LCOV_EXCL_STOP

View File

@ -0,0 +1,51 @@
// 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 __NEW_CUSTOM_RESPONSE_H__
#define __NEW_CUSTOM_RESPONSE_H__
#include <string>
#include <cereal/archives/json.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include "config.h"
#include "debug.h"
#include "local_policy_common.h"
class NewAppSecCustomResponse
{
public:
void load(cereal::JSONInputArchive &archive_in);
int getHttpResponseCode() const;
const std::string & getMessageBody() const;
const std::string & getMessageTitle() const;
const std::string & getAppSecClassName() const;
const std::string & getMode() const;
const std::string & getName() const;
void setName(const std::string &_name);
private:
bool redirect_add_x_event_id;
int http_response_code;
std::string appsec_class_name;
std::string redirect_url;
std::string message_title;
std::string message_body;
std::string mode;
std::string name;
};
#endif // __NEW_CUSTOM_RESPONSE_H__

View File

@ -0,0 +1,67 @@
// 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 __NEW_EXCEPTIONS_H__
#define __NEW_EXCEPTIONS_H__
#include <string>
#include <cereal/archives/json.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include "config.h"
#include "debug.h"
#include "rest.h"
#include "local_policy_common.h"
class NewAppsecExceptionCondition
{
public:
void load(cereal::JSONInputArchive &archive_in);
const std::string & getKey() const;
const std::string & getvalue() const;
private:
std::string key;
std::string value;
};
class NewAppsecException
{
public:
void load(cereal::JSONInputArchive &archive_in);
const std::string & getName() const;
const std::string & getAction() const;
const std::string & getAppSecClassName() const;
const std::vector<std::string> getCountryCode() const;
const std::vector<std::string> getCountryName() const;
const std::vector<std::string> getHostName() const;
const std::vector<std::string> getParamName() const;
const std::vector<std::string> getParamValue() const;
const std::vector<std::string> getProtectionName() const;
const std::vector<std::string> getSourceIdentifier() const;
const std::vector<std::string> getSourceIp() const;
const std::vector<std::string> getUrl() const;
void setName(const std::string &_name);
private:
std::string appsec_class_name;
std::string name;
std::string action;
std::vector<NewAppsecExceptionCondition> conditions;
};
#endif // __NEW_EXCEPTIONS_H__

View File

@ -0,0 +1,172 @@
// 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 __NEW_LOG_TRIGGERS_H__
#define __NEW_LOG_TRIGGERS_H__
#include <cereal/archives/json.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include "config.h"
#include "debug.h"
#include "local_policy_common.h"
#include "i_agent_details.h"
#include "i_env_details.h"
class NewAppsecTriggerAccessControlLogging
{
public:
void load(cereal::JSONInputArchive &archive_in);
private:
bool allow_events = false;
bool drop_events = false;
};
class NewAppsecTriggerAdditionalSuspiciousEventsLogging : public ClientRest
{
public:
void load(cereal::JSONInputArchive &archive_in);
bool isEnabled() const;
bool isResponseBody() const;
const std::string & getMinimumSeverity() const;
private:
bool enabled = true;
bool response_body = false;
bool response_code = false;
std::string minimum_severity = "high";
};
class NewAppsecTriggerLogging : public ClientRest
{
public:
void
load(cereal::JSONInputArchive &archive_in);
bool isAllWebRequests() const;
bool isDetectEvents() const;
bool isPreventEvents() const;
private:
bool all_web_requests = false;
bool detect_events = false;
bool prevent_events = true;
};
class NewAppsecTriggerExtendedLogging : public ClientRest
{
public:
void load(cereal::JSONInputArchive &archive_in);
bool isHttpHeaders() const;
bool isRequestBody() const;
bool isUrlPath() const;
bool isUrlQuery() const;
private:
bool http_headers = false;
bool request_body = false;
bool url_path = false;
bool url_query = false;
};
class NewLoggingService
{
public:
void load(cereal::JSONInputArchive &archive_in);
const std::string & getAddress() const;
int getPort() const;
private:
std::string address;
std::string proto;
int port = 514;
};
class NewStdoutLogging
{
public:
// LCOV_EXCL_START Reason: no test exist
NewStdoutLogging() : format("json") {}
// LCOV_EXCL_STOP
void load(cereal::JSONInputArchive &archive_in);
const std::string & getFormat() const;
private:
std::string format;
};
class NewAppsecTriggerLogDestination
:
public ClientRest,
Singleton::Consume<I_AgentDetails>,
Singleton::Consume<I_EnvDetails>
{
public:
void load(cereal::JSONInputArchive &archive_in);
int getCefServerUdpPort() const;
int getSyslogServerUdpPort() const;
bool isAgentLocal() const;
bool shouldBeautifyLogs() const;
bool getCloud() const;
bool isK8SNeeded() const;
bool isCefNeeded() const;
bool isSyslogNeeded() const;
const std::string & getSyslogServerIpv4Address() const;
const std::string & getCefServerIpv4Address() const;
private:
const NewLoggingService & getSyslogServiceData() const;
const NewLoggingService & getCefServiceData() const;
bool cloud = false;
bool k8s_service = false;
bool agent_local = true;
bool beautify_logs = true;
NewLoggingService syslog_service;
NewLoggingService cef_service;
};
class NewAppsecLogTrigger
{
public:
void load(cereal::JSONInputArchive &archive_in);
const std::string & getName() const;
const std::string & getAppSecClassName() const;
void setName(const std::string &_name);
const NewAppsecTriggerAdditionalSuspiciousEventsLogging &
getAppsecTriggerAdditionalSuspiciousEventsLogging() const;
const NewAppsecTriggerLogging & getAppsecTriggerLogging() const;
const NewAppsecTriggerExtendedLogging & getAppsecTriggerExtendedLogging() const;
const NewAppsecTriggerLogDestination & getAppsecTriggerLogDestination() const;
private:
NewAppsecTriggerAccessControlLogging access_control_logging;
NewAppsecTriggerAdditionalSuspiciousEventsLogging additional_suspicious_events_logging;
NewAppsecTriggerLogging appsec_logging;
NewAppsecTriggerExtendedLogging extended_logging;
NewAppsecTriggerLogDestination log_destination;
std::string name;
std::string appsec_class_name;
};
#endif // __NEW_LOG_TRIGGERS_H__

View File

@ -0,0 +1,395 @@
// 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 __NEW_PRACTICE_H__
#define __NEW_PRACTICE_H__
#include <string>
#include <cereal/archives/json.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include "config.h"
#include "debug.h"
#include "local_policy_common.h"
class IpsProtectionsRulesSection
{
public:
// LCOV_EXCL_START Reason: no test exist
IpsProtectionsRulesSection() {};
IpsProtectionsRulesSection(
const int _protections_from_year,
const std::string &_action,
const std::string &_confidence_level,
const std::string &_performance_impact,
const std::string &_source_identifier,
const std::string &_severity_level
)
:
protections_from_year(_protections_from_year),
action(_action),
confidence_level(_confidence_level),
performance_impact(_performance_impact),
source_identifier(_source_identifier),
severity_level(_severity_level)
{};
// LCOV_EXCL_STOP
void save(cereal::JSONOutputArchive &out_ar) const;
private:
int protections_from_year;
std::string action;
std::string confidence_level;
std::string performance_impact;
std::string source_identifier;
std::string severity_level;
};
class IpsProtectionsSection
{
public:
// LCOV_EXCL_START Reason: no test exist
IpsProtectionsSection() {};
// LCOV_EXCL_STOP
IpsProtectionsSection(
const std::string &_context,
const std::string &asset_name,
const std::string &_asset_id,
const std::string &_practice_name,
const std::string &_practice_id,
const std::string &_source_identifier,
const std::string &_mode,
const std::vector<IpsProtectionsRulesSection> &_rules);
std::string & getMode();
void save(cereal::JSONOutputArchive &out_ar) const;
private:
std::string context;
std::string name;
std::string asset_id;
std::string practice_name;
std::string practice_id;
std::string source_identifier;
std::string mode;
std::vector<IpsProtectionsRulesSection> rules;
};
class IPSSection
{
public:
// LCOV_EXCL_START Reason: no test exist
IPSSection() {};
IPSSection(const std::vector<IpsProtectionsSection> &_ips) : ips(_ips) {};
// LCOV_EXCL_STOP
void save(cereal::JSONOutputArchive &out_ar) const;
private:
std::vector<IpsProtectionsSection> ips;
};
class IntrusionPreventionWrapper
{
public:
// LCOV_EXCL_START Reason: no test exist
IntrusionPreventionWrapper() {};
IntrusionPreventionWrapper(const std::vector<IpsProtectionsSection> &_ips) : ips(IPSSection(_ips)) {};
// LCOV_EXCL_STOP
void save(cereal::JSONOutputArchive &out_ar) const;
private:
IPSSection ips;
};
class NewIntrusionPrevention
{
public:
void load(cereal::JSONInputArchive &archive_in);
std::vector<IpsProtectionsRulesSection> createIpsRules() const;
const std::string & getMode() const;
private:
std::string override_mode;
std::string max_performance_impact;
std::string min_severity_level;
std::string high_confidence_event_action;
std::string medium_confidence_event_action;
std::string low_confidence_event_action;
int min_cve_Year;
};
class FileSecurityProtectionsSection
{
public:
// LCOV_EXCL_START Reason: no test exist
FileSecurityProtectionsSection() {};
// LCOV_EXCL_STOP
FileSecurityProtectionsSection(
int file_size_limit,
int archive_file_size_limit,
bool allow_files_without_name,
bool required_file_size_limit,
bool required_archive_extraction,
const std::string &context,
const std::string &name,
const std::string &asset_id,
const std::string &practice_name,
const std::string &practice_id,
const std::string &action,
const std::string &files_without_name_action,
const std::string &high_confidence_action,
const std::string &medium_confidence_action,
const std::string &low_confidence_action,
const std::string &severity_level,
const std::string &fileSize_limit_action,
const std::string &multi_level_archive_action,
const std::string &unopened_archive_actio
);
void save(cereal::JSONOutputArchive &out_ar) const;
private:
int file_size_limit;
int archive_file_size_limit;
bool allow_files_without_name;
bool required_file_size_limit;
bool required_archive_extraction;
std::string context;
std::string name;
std::string asset_id;
std::string practice_name;
std::string practice_id;
std::string action;
std::string files_without_name_action;
std::string high_confidence_action;
std::string medium_confidence_action;
std::string low_confidence_action;
std::string severity_level;
std::string file_size_limit_action;
std::string file_size_limit_unit;
std::string scan_max_file_size_unit;
std::string multi_level_archive_action;
std::string unopened_archive_action;
};
class FileSecuritySection
{
public:
// LCOV_EXCL_START Reason: no test exist
FileSecuritySection() {};
FileSecuritySection(const std::vector<FileSecurityProtectionsSection> &_file_security)
:
file_security(_file_security) {};
// LCOV_EXCL_STOP
void save(cereal::JSONOutputArchive &out_ar) const;
private:
std::vector<FileSecurityProtectionsSection> file_security;
};
class FileSecurityWrapper
{
public:
// LCOV_EXCL_START Reason: no test exist
FileSecurityWrapper() {};
FileSecurityWrapper(const std::vector<FileSecurityProtectionsSection> &_file_security)
:
file_security(FileSecuritySection(_file_security)) {};
// LCOV_EXCL_STOP
void save(cereal::JSONOutputArchive &out_ar) const;
private:
FileSecuritySection file_security;
};
class NewFileSecurityArchiveInspection
{
public:
void load(cereal::JSONInputArchive &archive_in);
int getArchiveFileSizeLimit() const;
bool getrequiredArchiveExtraction() const;
const std::string & getMultiLevelArchiveAction() const;
const std::string & getUnopenedArchiveAction() const;
private:
int scan_max_file_size;
bool extract_archive_files;
std::string scan_max_file_size_unit;
std::string archived_files_within_archived_files;
std::string archived_files_where_content_extraction_failed;
};
class NewFileSecurityLargeFileInspection
{
public:
void load(cereal::JSONInputArchive &archive_in);
int getFileSizeLimit() const;
const std::string & getFileSizeLimitAction() const;
private:
int file_size_limit;
std::string file_size_limit_unit;
std::string files_exceeding_size_limit_action;
};
class NewFileSecurity
{
public:
void load(cereal::JSONInputArchive &archive_in);
const NewFileSecurityArchiveInspection & getArchiveInspection() const;
const NewFileSecurityLargeFileInspection & getLargeFileInspection() const;
FileSecurityProtectionsSection createFileSecurityProtectionsSection(
const std::string &context,
const std::string &asset_name,
const std::string &asset_id,
const std::string &practice_name,
const std::string &practice_id
) const;
private:
bool threat_emulation_enabled;
std::string override_mode;
std::string min_severity_level;
std::string high_confidence_event_action;
std::string medium_confidence_event_action;
std::string low_confidence_event_action;
std::string unnamed_files_action;
NewFileSecurityArchiveInspection archive_inspection;
NewFileSecurityLargeFileInspection large_file_inspection;
};
class NewSnortSignaturesAndOpenSchemaAPI
{
public:
void load(cereal::JSONInputArchive &archive_in);
const std::string & getOverrideMode() const;
const std::vector<std::string> & getConfigMap() const;
private:
std::string override_mode;
std::vector<std::string> config_map;
};
class NewAppSecWebBotsURI
{
public:
void load(cereal::JSONInputArchive &archive_in);
const std::string & getURI() const;
private:
std::string uri;
};
class NewAppSecPracticeAntiBot
{
public:
std::vector<std::string> getIjectedUris() const;
std::vector<std::string> getValidatedUris() const;
void load(cereal::JSONInputArchive &archive_in);
void save(cereal::JSONOutputArchive &out_ar) const;
private:
std::string override_mode;
std::vector<NewAppSecWebBotsURI> injected_uris;
std::vector<NewAppSecWebBotsURI> validated_uris;
};
class NewAppSecWebAttackProtections
{
public:
void load(cereal::JSONInputArchive &archive_in);
const std::string getCsrfProtectionMode() const;
const std::string & getErrorDisclosureMode() const;
bool getNonValidHttpMethods() const;
const std::string getOpenRedirectMode() const;
private:
std::string csrf_protection;
std::string open_redirect;
std::string error_disclosure;
bool non_valid_http_methods;
};
class NewAppSecPracticeWebAttacks
{
public:
void load(cereal::JSONInputArchive &archive_in);
int getMaxBodySizeKb() const;
int getMaxHeaderSizeBytes() const;
int getMaxObjectDepth() const;
int getMaxUrlSizeBytes() const;
const std::string & getMinimumConfidence() const;
const NewAppSecWebAttackProtections & getprotections() const;
const std::string & getMode(const std::string &default_mode = "Inactive") const;
private:
int max_body_size_kb;
int max_header_size_bytes;
int max_object_depth;
int max_url_size_bytes;
std::string mode;
std::string minimum_confidence;
NewAppSecWebAttackProtections protections;
};
class NewAppSecPracticeSpec
{
public:
void load(cereal::JSONInputArchive &archive_in);
const NewSnortSignaturesAndOpenSchemaAPI & getOpenSchemaValidation() const;
const NewSnortSignaturesAndOpenSchemaAPI & getSnortSignatures() const;
const NewAppSecPracticeWebAttacks & getWebAttacks() const;
const NewAppSecPracticeAntiBot & getAntiBot() const;
const NewIntrusionPrevention & getIntrusionPrevention() const;
const NewFileSecurity & getFileSecurity() const;
const std::string & getAppSecClassName() const;
const std::string & getName() const;
void setName(const std::string &_name);
private:
NewFileSecurity file_security;
NewIntrusionPrevention intrusion_prevention;
NewSnortSignaturesAndOpenSchemaAPI openapi_schema_validation;
NewSnortSignaturesAndOpenSchemaAPI snort_signatures;
NewAppSecPracticeWebAttacks web_attacks;
NewAppSecPracticeAntiBot anti_bot;
std::string appsec_class_name;
std::string practice_name;
};
#endif // __NEW_PRACTICE_H__

View File

@ -0,0 +1,74 @@
// 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 __NEW_TRUSTED_SOURCES_H__
#define __NEW_TRUSTED_SOURCES_H__
#include <string>
#include <cereal/archives/json.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include "config.h"
#include "debug.h"
#include "local_policy_common.h"
class NewTrustedSourcesSpec
{
public:
void load(cereal::JSONInputArchive &archive_in);
int getMinNumOfSources() const;
const std::vector<std::string> & getSourcesIdentifiers() const;
const std::string & getAppSecClassName() const;
const std::string & getName() const;
void setName(const std::string &_name);
private:
int min_num_of_sources = 0;
std::string name;
std::vector<std::string> sources_identifiers;
std::string appsec_class_name;
};
class Identifier
{
public:
void load(cereal::JSONInputArchive &archive_in);
const std::string & getIdentifier() const;
const std::vector<std::string> & getValues() const;
private:
std::string identifier;
std::vector<std::string> value;
};
class NewSourcesIdentifiers
{
public:
void load(cereal::JSONInputArchive &archive_in);
const std::string & getName() const;
const std::string & getAppSecClassName() const;
const std::vector<Identifier> & getSourcesIdentifiers() const;
void setName(const std::string &_name);
private:
std::string name;
std::string appsec_class_name;
std::vector<Identifier> sources_identifiers;
};
#endif // __NEW_TRUSTED_SOURCES_H__

View File

@ -38,9 +38,13 @@
#include "exceptions_section.h"
#include "rules_config_section.h"
#include "trusted_sources_section.h"
#include "new_appsec_linux_policy.h"
#include "access_control_practice.h"
enum class AnnotationTypes {
PRACTICE,
THREAT_PREVENTION_PRACTICE,
ACCESS_CONTROL_PRACTICE,
TRIGGER,
EXCEPTION,
WEB_USER_RES,
@ -56,12 +60,18 @@ public:
const AppSecWrapper &_waap,
const TriggersWrapper &_trrigers,
const RulesConfigWrapper &_rules,
const IntrusionPreventionWrapper &_ips,
const AccessControlRulebaseWrapper &_rate_limit,
const FileSecurityWrapper &_file_security,
const ExceptionsWrapper &_exceptions,
const std::string &_policy_version)
:
waap(_waap),
trrigers(_trrigers),
rules(_rules),
ips(_ips),
rate_limit(_rate_limit),
file_security(_file_security),
exceptions(_exceptions),
policy_version(_policy_version) {}
@ -71,6 +81,9 @@ private:
AppSecWrapper waap;
TriggersWrapper trrigers;
RulesConfigWrapper rules;
IntrusionPreventionWrapper ips;
AccessControlRulebaseWrapper rate_limit;
FileSecurityWrapper file_security;
ExceptionsWrapper exceptions;
std::string policy_version;
};
@ -106,8 +119,9 @@ public:
const std::string &local_appsec_policy_path
);
template<class T, class R>
std::string proccesMultipleAppsecPolicies(
const std::map<std::string, AppsecLinuxPolicy> &appsec_policies,
const std::map<std::string, T> &appsec_policies,
const std::string &policy_version,
const std::string &local_appsec_policy_path
);
@ -129,29 +143,104 @@ private:
PolicyWrapper combineElementsToPolicy(const std::string &policy_version);
void
createIpsSections(
const std::string &asset_id,
const std::string &asset_name,
const std::string &practice_id,
const std::string &practice_name,
const std::string &source_identifier,
const std::string & context,
const V1beta2AppsecLinuxPolicy &policy,
std::map<AnnotationTypes, std::string> &rule_annotations
);
void
createFileSecuritySections(
const std::string &asset_id,
const std::string &asset_name,
const std::string &practice_id,
const std::string &practice_name,
const std::string & context,
const V1beta2AppsecLinuxPolicy &policy,
std::map<AnnotationTypes, std::string> &rule_annotations
);
void
createRateLimitSection(
const std::string &asset_name,
const std::string &url,
const std::string &uri,
const std::string &trigger_id,
const V1beta2AppsecLinuxPolicy &policy,
std::map<AnnotationTypes, std::string> &rule_annotations
);
void createWebAppSection(
const V1beta2AppsecLinuxPolicy &policy,
const RulesConfigRulebase& rule_config,
const std::string &practice_id, const std::string &full_url,
const std::string &default_mode,
std::map<AnnotationTypes, std::string> &rule_annotations
);
void
createThreatPreventionPracticeSections(
const std::string &asset_name,
const std::string &url,
const std::string &uri,
const std::string &default_mode,
const V1beta2AppsecLinuxPolicy &policy,
std::map<AnnotationTypes, std::string> &rule_annotations
);
template<class T, class R>
void createPolicyElementsByRule(
const ParsedRule &rule,
const ParsedRule &default_rule,
const AppsecLinuxPolicy &policy,
const R &rule,
const R &default_rule,
const T &policy,
const std::string &policy_name
);
template<class T, class R>
void createPolicyElements(
const std::vector<ParsedRule> &rules,
const ParsedRule &default_rule,
const AppsecLinuxPolicy &policy,
const std::vector<R> &rules,
const R &default_rule,
const T &policy,
const std::string &policy_name
);
void createAgentPolicyFromAppsecPolicy(const std::string &policy_name, const AppsecLinuxPolicy &appsec_policy);
template<class T, class R>
void createAgentPolicyFromAppsecPolicy(const std::string &policy_name, const T &appsec_policy);
std::map<std::string, LogTriggerSection> log_triggers;
std::map<std::string, WebUserResponseTriggerSection> web_user_res_triggers;
std::map<std::string, InnerException> inner_exceptions;
std::map<std::string, WebAppSection> web_apps;
std::map<std::string, RulesConfigRulebase> rules_config;
std::map<std::string, IpsProtectionsSection> ips;
std::map<std::string, FileSecurityProtectionsSection> file_security;
std::map<std::string, RateLimitSection> rate_limit;
std::map<std::string, UsersIdentifiersRulebase> users_identifiers;
std::map<std::string, AppSecTrustedSources> trusted_sources;
};
template<class T, class R>
std::string
PolicyMakerUtils::proccesMultipleAppsecPolicies(
const std::map<std::string, T> &appsec_policies,
const std::string &policy_version,
const std::string &local_appsec_policy_path)
{
for (const auto &appsec_policy : appsec_policies) {
createAgentPolicyFromAppsecPolicy<T, R>(appsec_policy.first, appsec_policy.second);
}
PolicyWrapper policy_wrapper = combineElementsToPolicy(policy_version);
return dumpPolicyToFile(
policy_wrapper,
local_appsec_policy_path
);
}
#endif // __POLICY_MAKER_UTILS_H__

View File

@ -121,6 +121,8 @@ public:
std::vector<std::string> _identifier_values
);
const std::string & getIdentifier() const;
void save(cereal::JSONOutputArchive &out_ar) const;
private:
@ -141,6 +143,8 @@ public:
const std::vector<UsersIdentifier> &_source_identifiers
);
const std::string & getIdentifier() const;
void save(cereal::JSONOutputArchive &out_ar) const;
private:

View File

@ -52,7 +52,7 @@ map<AnnotationKeys, string>
K8sPolicyUtils::parseIngressAnnotations(const map<string, string> &annotations) const
{
map<AnnotationKeys, string> annotations_values;
for (const pair<string, string> &annotation : annotations) {
for (const auto &annotation : annotations) {
string annotation_key = annotation.first;
string annotation_val = annotation.second;
if (annotation_key.find(convertAnnotationKeysTostring(AnnotationKeys::OpenAppsecIo)) != string::npos) {
@ -134,6 +134,56 @@ K8sPolicyUtils::extractElementsNames(const vector<ParsedRule> &specific_rules, c
return policy_elements_names;
}
// LCOV_EXCL_START Reason: no test exist
void
extractElementsFromNewRule(
const NewParsedRule &rule,
map<AnnotationTypes, unordered_set<string>> &policy_elements_names)
{
policy_elements_names[AnnotationTypes::EXCEPTION].insert(
rule.getExceptions().begin(),
rule.getExceptions().end()
);
policy_elements_names[AnnotationTypes::THREAT_PREVENTION_PRACTICE].insert(
rule.getPractices().begin(),
rule.getPractices().end()
);
policy_elements_names[AnnotationTypes::ACCESS_CONTROL_PRACTICE].insert(
rule.getAccessControlPractices().begin(),
rule.getAccessControlPractices().end()
);
policy_elements_names[AnnotationTypes::TRIGGER].insert(
rule.getLogTriggers().begin(),
rule.getLogTriggers().end()
);
policy_elements_names[AnnotationTypes::WEB_USER_RES].insert(rule.getCustomResponse());
policy_elements_names[AnnotationTypes::SOURCE_IDENTIFIERS].insert(rule.getSourceIdentifiers());
policy_elements_names[AnnotationTypes::TRUSTED_SOURCES].insert(rule.getTrustedSources());
}
map<AnnotationTypes, unordered_set<string>>
K8sPolicyUtils::extractElementsNamesV1beta2(
const vector<NewParsedRule> &specific_rules,
const NewParsedRule &default_rule) const
{
map<AnnotationTypes, unordered_set<string>> policy_elements_names;
for (const NewParsedRule &specific_rule : specific_rules) {
extractElementsFromNewRule(specific_rule, policy_elements_names);
}
extractElementsFromNewRule(default_rule, policy_elements_names);
return policy_elements_names;
}
string
getAppSecClassNameFromCluster()
{
auto env_res = getenv("appsecClassName");
if (env_res != nullptr) return env_res;
return "";
}
// LCOV_EXCL_STOP
template<class T>
vector<T>
K8sPolicyUtils::extractElementsFromCluster(
@ -168,19 +218,52 @@ K8sPolicyUtils::extractElementsFromCluster(
return elements;
}
Maybe<AppsecLinuxPolicy>
K8sPolicyUtils::createAppsecPolicyK8s(const string &policy_name, const string &ingress_mode) const
// LCOV_EXCL_START Reason: no test exist
template<class T>
vector<T>
K8sPolicyUtils::extractV1Beta2ElementsFromCluster(
const string &crd_plural,
const unordered_set<string> &elements_names) const
{
auto maybe_appsec_policy_spec = getObjectFromCluster<AppsecSpecParser<AppsecPolicySpec>>(
"/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());
dbgTrace(D_LOCAL_POLICY) << "Retrieve AppSec elements. type: " << crd_plural;
vector<T> elements;
for (const string &element_name : elements_names) {
dbgTrace(D_LOCAL_POLICY) << "AppSec element name: " << element_name;
auto maybe_appsec_element = getObjectFromCluster<AppsecSpecParser<T>>(
"/apis/openappsec.io/v1beta2/" + 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<T> appsec_element = maybe_appsec_element.unpack();
if (getAppSecClassNameFromCluster() != "" &&
appsec_element.getSpec().getAppSecClassName() != getAppSecClassNameFromCluster()) {
continue;
}
if (appsec_element.getSpec().getName() == "") {
appsec_element.setName(element_name);
}
elements.push_back(appsec_element.getSpec());
}
AppsecSpecParser<AppsecPolicySpec> appsec_policy_spec = maybe_appsec_policy_spec.unpack();
return elements;
}
// LCOV_EXCL_STOP
Maybe<AppsecLinuxPolicy>
K8sPolicyUtils::createAppsecPolicyK8sFromV1beta1Crds(
const AppsecSpecParser<AppsecPolicySpec> &appsec_policy_spec,
const string &ingress_mode) const
{
ParsedRule default_rule = appsec_policy_spec.getSpec().getDefaultRule();
vector<ParsedRule> specific_rules = appsec_policy_spec.getSpec().getSpecificRules();
@ -236,11 +319,160 @@ K8sPolicyUtils::createAppsecPolicyK8s(const string &policy_name, const string &i
return appsec_policy;
}
map<string, AppsecLinuxPolicy>
// LCOV_EXCL_START Reason: no test exist
Maybe<V1beta2AppsecLinuxPolicy>
K8sPolicyUtils::createAppsecPolicyK8sFromV1beta2Crds(
const AppsecSpecParser<NewAppsecPolicySpec> &appsec_policy_spec,
const string &ingress_mode) const
{
NewParsedRule default_rule = appsec_policy_spec.getSpec().getDefaultRule();
vector<NewParsedRule> specific_rules = appsec_policy_spec.getSpec().getSpecificRules();
string appsec_class_name = appsec_policy_spec.getSpec().getAppSecClassName();
if (getAppSecClassNameFromCluster() != "" &&
appsec_class_name != getAppSecClassNameFromCluster()) {
return genError("Unmached appsec class name!");
}
if (default_rule.getMode().empty() && !ingress_mode.empty()) {
default_rule.setMode(ingress_mode);
}
map<AnnotationTypes, unordered_set<string>> policy_elements_names = extractElementsNamesV1beta2(
specific_rules,
default_rule
);
vector<NewAppSecPracticeSpec> threat_prevention_practices =
extractV1Beta2ElementsFromCluster<NewAppSecPracticeSpec>(
"threatpreventionpractices",
policy_elements_names[AnnotationTypes::THREAT_PREVENTION_PRACTICE]
);
vector<AccessControlPracticeSpec> access_control_practices =
extractV1Beta2ElementsFromCluster<AccessControlPracticeSpec>(
"accesscontrolpractice",
policy_elements_names[AnnotationTypes::ACCESS_CONTROL_PRACTICE]
);
vector<NewAppsecLogTrigger> log_triggers = extractV1Beta2ElementsFromCluster<NewAppsecLogTrigger>(
"logtriggers",
policy_elements_names[AnnotationTypes::TRIGGER]
);
vector<NewAppSecCustomResponse> web_user_responses = extractV1Beta2ElementsFromCluster<NewAppSecCustomResponse>(
"customresponses",
policy_elements_names[AnnotationTypes::WEB_USER_RES]
);
vector<NewAppsecException> exceptions = extractV1Beta2ElementsFromCluster<NewAppsecException>(
"exceptions",
policy_elements_names[AnnotationTypes::EXCEPTION]
);
vector<NewSourcesIdentifiers> source_identifiers = extractV1Beta2ElementsFromCluster<NewSourcesIdentifiers>(
"sourcesidentifiers",
policy_elements_names[AnnotationTypes::SOURCE_IDENTIFIERS]
);
vector<NewTrustedSourcesSpec> trusted_sources = extractV1Beta2ElementsFromCluster<NewTrustedSourcesSpec>(
"trustedsources",
policy_elements_names[AnnotationTypes::TRUSTED_SOURCES]
);
V1beta2AppsecLinuxPolicy appsec_policy = V1beta2AppsecLinuxPolicy(
appsec_policy_spec.getSpec(),
threat_prevention_practices,
access_control_practices,
log_triggers,
web_user_responses,
exceptions,
trusted_sources,
source_identifiers
);
return appsec_policy;
}
// LCOV_EXCL_STOP
bool
doesVersionExist(const map<string, string> &annotations, const string &version)
{
for (auto annotation : annotations) {
if(annotation.second.find(version) != std::string::npos) {
return true;
}
}
return false;
}
//need to refactor don't forget that
std::tuple<Maybe<AppsecLinuxPolicy>, Maybe<V1beta2AppsecLinuxPolicy>>
K8sPolicyUtils::createAppsecPolicyK8s(const string &policy_name, const string &ingress_mode) const
{
auto maybe_appsec_policy_spec = getObjectFromCluster<AppsecSpecParser<AppsecPolicySpec>>(
"/apis/openappsec.io/v1beta1/policies/" + policy_name
);
if (!maybe_appsec_policy_spec.ok() ||
!doesVersionExist(maybe_appsec_policy_spec.unpack().getMetaData().getAnnotations(), "v1beta1")
) {
dbgWarning(D_LOCAL_POLICY)
<< "Failed to retrieve Appsec policy with crds version: v1beta1, Trying version: v1beta2";
auto maybe_v1beta2_appsec_policy_spec = getObjectFromCluster<AppsecSpecParser<NewAppsecPolicySpec>>(
"/apis/openappsec.io/v1beta2/policies/" + policy_name
);
if(!maybe_v1beta2_appsec_policy_spec.ok()) {
dbgWarning(D_LOCAL_POLICY)
<< "Failed to retrieve AppSec policy. Error: "
<< maybe_v1beta2_appsec_policy_spec.getErr();
return std::make_tuple(
genError("Failed to retrieve AppSec v1beta1 policy. Error: " + maybe_appsec_policy_spec.getErr()),
genError(
"Failed to retrieve AppSec v1beta2 policy. Error: " + maybe_v1beta2_appsec_policy_spec.getErr()));
}
return std::make_tuple(
genError("There is no v1beta1 policy"),
createAppsecPolicyK8sFromV1beta2Crds(maybe_v1beta2_appsec_policy_spec.unpack(), ingress_mode));
}
return std::make_tuple(
createAppsecPolicyK8sFromV1beta1Crds(maybe_appsec_policy_spec.unpack(), ingress_mode),
genError("There is no v1beta2 policy"));
}
template<class T, class K>
void
K8sPolicyUtils::createPolicy(
T &appsec_policy,
map<std::string, T> &policies,
map<AnnotationKeys, string> &annotations_values,
const SingleIngressData &item) const
{
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()
<< "'";
K ingress_rule = K(url + uri.getPath());
appsec_policy.addSpecificRule(ingress_rule);
}
}
}
policies[annotations_values[AnnotationKeys::PolicyKey]] = appsec_policy;
}
std::tuple<map<string, AppsecLinuxPolicy>, map<string, V1beta2AppsecLinuxPolicy>>
K8sPolicyUtils::createAppsecPoliciesFromIngresses()
{
dbgFlow(D_LOCAL_POLICY) << "Getting all policy object from Ingresses";
map<string, AppsecLinuxPolicy> policies;
map<string, AppsecLinuxPolicy> v1bet1_policies;
map<string, V1beta2AppsecLinuxPolicy> v1bet2_policies;
auto maybe_ingress = getObjectFromCluster<IngressData>("/apis/networking.k8s.io/v1/ingresses");
if (!maybe_ingress.ok()) {
@ -248,9 +480,10 @@ K8sPolicyUtils::createAppsecPoliciesFromIngresses()
dbgWarning(D_LOCAL_POLICY)
<< "Failed to retrieve K8S Ingress configurations. Error: "
<< maybe_ingress.getErr();
return policies;
return make_tuple(v1bet1_policies, v1bet2_policies);
}
IngressData ingress = maybe_ingress.unpack();
for (const SingleIngressData &item : ingress.getItems()) {
map<AnnotationKeys, string> annotations_values = parseIngressAnnotations(
@ -262,37 +495,34 @@ K8sPolicyUtils::createAppsecPoliciesFromIngresses()
continue;
}
Maybe<AppsecLinuxPolicy> maybe_appsec_policy = createAppsecPolicyK8s(
auto maybe_appsec_policy = createAppsecPolicyK8s(
annotations_values[AnnotationKeys::PolicyKey],
annotations_values[AnnotationKeys::ModeKey]
);
if (!maybe_appsec_policy.ok()) {
if (!std::get<0>(maybe_appsec_policy).ok() && !std::get<1>(maybe_appsec_policy).ok()) {
dbgWarning(D_LOCAL_POLICY)
<< "Failed to create appsec policy. Error: "
<< maybe_appsec_policy.getErr();
<< std::get<1>(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);
}
}
if (!std::get<0>(maybe_appsec_policy).ok()) {
auto appsec_policy=std::get<1>(maybe_appsec_policy).unpack();
createPolicy<V1beta2AppsecLinuxPolicy, NewParsedRule>(
appsec_policy,
v1bet2_policies,
annotations_values,
item);
} else {
auto appsec_policy=std::get<0>(maybe_appsec_policy).unpack();
createPolicy<AppsecLinuxPolicy, ParsedRule>(
appsec_policy,
v1bet1_policies,
annotations_values,
item);
}
policies[annotations_values[AnnotationKeys::PolicyKey]] = appsec_policy;
}
return policies;
return make_tuple(v1bet1_policies, v1bet2_policies);
}
bool

View File

@ -104,9 +104,16 @@ public:
{
dbgFlow(D_LOCAL_POLICY) << "Starting to parse policy - K8S environment";
map<string, AppsecLinuxPolicy> appsec_policies = k8s_policy_utils.createAppsecPoliciesFromIngresses();
return policy_maker_utils.proccesMultipleAppsecPolicies(
appsec_policies,
auto appsec_policies = k8s_policy_utils.createAppsecPoliciesFromIngresses();
if (!std::get<0>(appsec_policies).empty()) {
return policy_maker_utils.proccesMultipleAppsecPolicies<AppsecLinuxPolicy, ParsedRule>(
std::get<0>(appsec_policies),
policy_version,
default_local_appsec_policy_path
);
}
return policy_maker_utils.proccesMultipleAppsecPolicies<V1beta2AppsecLinuxPolicy, NewParsedRule>(
std::get<1>(appsec_policies),
policy_version,
default_local_appsec_policy_path
);

View File

@ -0,0 +1,72 @@
// 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 "new_appsec_linux_policy.h"
// LCOV_EXCL_START Reason: no test exist
using namespace std;
const NewAppsecPolicySpec &
V1beta2AppsecLinuxPolicy::getAppsecPolicySpec() const
{
return policies;
}
const vector<NewAppSecPracticeSpec> &
V1beta2AppsecLinuxPolicy::getAppSecPracticeSpecs() const
{
return threat_prevection_practices;
}
const vector<AccessControlPracticeSpec> &
V1beta2AppsecLinuxPolicy::getAccessControlPracticeSpecs() const
{
return access_control_practices;
}
const vector<NewAppsecLogTrigger> &
V1beta2AppsecLinuxPolicy::getAppsecTriggerSpecs() const
{
return log_triggers;
}
const vector<NewAppSecCustomResponse> &
V1beta2AppsecLinuxPolicy::getAppSecCustomResponseSpecs() const
{
return custom_responses;
}
const vector<NewAppsecException> &
V1beta2AppsecLinuxPolicy::getAppsecExceptionSpecs() const
{
return exceptions;
}
const vector<NewTrustedSourcesSpec> &
V1beta2AppsecLinuxPolicy::getAppsecTrustedSourceSpecs() const
{
return trusted_sources;
}
const vector<NewSourcesIdentifiers> &
V1beta2AppsecLinuxPolicy::getAppsecSourceIdentifierSpecs() const
{
return sources_identifiers;
}
void
V1beta2AppsecLinuxPolicy::addSpecificRule(const NewParsedRule &_rule)
{
policies.addSpecificRule(_rule);
}
// LCOV_EXCL_STOP

View File

@ -0,0 +1,154 @@
// 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 "new_appsec_policy_crd_parser.h"
using namespace std;
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
static const set<string> valid_modes = {"prevent-learn", "detect-learn", "prevent", "detect", "inactive"};
void
NewParsedRule::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec NewParsedRule";
parseAppsecJSONKey<vector<string>>("exceptions", exceptions, archive_in);
parseAppsecJSONKey<vector<string>>("triggers", log_triggers, archive_in);
parseAppsecJSONKey<vector<string>>("threatPreventionPractices", threat_prevention_practices, archive_in);
parseAppsecJSONKey<vector<string>>("accessControlPractices", access_control_practices, archive_in);
parseAppsecJSONKey<string>("mode", mode, archive_in);
if (valid_modes.count(mode) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec New Parsed Rule mode invalid: " << mode;
}
parseAppsecJSONKey<string>("customResponse", custom_response, archive_in);
parseAppsecJSONKey<string>("sourceIdentifiers", source_identifiers, archive_in);
parseAppsecJSONKey<string>("trustedSources", trusted_sources, archive_in);
try {
archive_in(cereal::make_nvp("host", host));
} catch (const cereal::Exception &e)
{
// The default NewParsedRule does not hold a host, so by default it will be *
host = "*";
}
}
const vector<string> &
NewParsedRule::getLogTriggers() const
{
return log_triggers;
}
const vector<string> &
NewParsedRule::getExceptions() const
{
return exceptions;
}
const vector<string> &
NewParsedRule::getPractices() const
{
return threat_prevention_practices;
}
const vector<string> &
NewParsedRule::getAccessControlPractices() const
{
return access_control_practices;
}
const string &
NewParsedRule::getSourceIdentifiers() const
{
return source_identifiers;
}
const string &
NewParsedRule::getCustomResponse() const
{
return custom_response;
}
const string &
NewParsedRule::getTrustedSources() const
{
return trusted_sources;
}
const string &
NewParsedRule::getHost() const
{
return host;
}
const string &
NewParsedRule::getMode() const
{
return mode;
}
void
NewParsedRule::setHost(const string &_host)
{
host = _host;
}
void
NewParsedRule::setMode(const string &_mode)
{
mode = _mode;
}
void
NewAppsecPolicySpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec policy spec";
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
parseAppsecJSONKey<NewParsedRule>("default", default_rule, archive_in);
parseAppsecJSONKey<vector<NewParsedRule>>("specificRules", specific_rules, archive_in);
}
const NewParsedRule &
NewAppsecPolicySpec::getDefaultRule() const
{
return default_rule;
}
const vector<NewParsedRule> &
NewAppsecPolicySpec::getSpecificRules() const
{
return specific_rules;
}
const string &
NewAppsecPolicySpec::getAppSecClassName() const
{
return appsec_class_name;
}
bool
NewAppsecPolicySpec::isAssetHostExist(const std::string &full_url) const
{
for (const NewParsedRule &rule : specific_rules) {
if (rule.getHost() == full_url) return true;
}
return false;
}
void
NewAppsecPolicySpec::addSpecificRule(const NewParsedRule &_rule)
{
specific_rules.push_back(_rule);
}
// LCOV_EXCL_STOP

View File

@ -0,0 +1,99 @@
// 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 "new_custom_response.h"
#define MIN_RESPONSE_CODE 100
#define MAX_RESPOMSE_CODE 599
using namespace std;
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
static const set<string> valid_modes = {"block-page", "response-code-only", "redirect"};
void
NewAppSecCustomResponse::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec web user response spec";
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
parseAppsecJSONKey<int>("httpResponseCode", http_response_code, archive_in, 403);
if (http_response_code < MIN_RESPONSE_CODE || http_response_code > MAX_RESPOMSE_CODE) {
dbgWarning(D_LOCAL_POLICY) << "AppSec web user response code invalid: " << http_response_code;
}
parseAppsecJSONKey<string>("mode", mode, archive_in, "block-page");
if (valid_modes.count(mode) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec web user response mode invalid: " << mode;
}
parseAppsecJSONKey<string>("name", name, archive_in);
parseAppsecJSONKey<string>("redirectUrl", redirect_url, archive_in);
parseAppsecJSONKey<bool>("redirectAddXEventId", redirect_add_x_event_id, archive_in);
if (mode == "block-page") {
parseAppsecJSONKey<string>(
"messageBody",
message_body,
archive_in,
"Openappsec's <b>Application Security</b> has detected an attack and blocked it."
);
parseAppsecJSONKey<string>(
"messageTitle",
message_title,
archive_in,
"Attack blocked by web application protection"
);
}
}
void
NewAppSecCustomResponse::setName(const string &_name)
{
name = _name;
}
int
NewAppSecCustomResponse::getHttpResponseCode() const
{
return http_response_code;
}
const string &
NewAppSecCustomResponse::getMessageBody() const
{
return message_body;
}
const string &
NewAppSecCustomResponse::getMessageTitle() const
{
return message_title;
}
const string &
NewAppSecCustomResponse::getAppSecClassName() const
{
return appsec_class_name;
}
const string &
NewAppSecCustomResponse::getMode() const
{
return mode;
}
const string &
NewAppSecCustomResponse::getName() const
{
return name;
}
// LCOV_EXCL_STOP

View File

@ -0,0 +1,187 @@
// 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 "new_exceptions.h"
using namespace std;
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
static const set<string> valid_actions = {"skip", "accept", "drop", "suppressLog"};
void
NewAppsecExceptionCondition::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading New AppSec exception condition";
parseAppsecJSONKey<string>("key", key, archive_in);
parseAppsecJSONKey<string>("value", value, archive_in);
}
const string &
NewAppsecExceptionCondition::getKey() const
{
return key;
}
const string &
NewAppsecExceptionCondition::getvalue() const
{
return value;
}
void
NewAppsecException::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading New AppSec exception";
parseAppsecJSONKey<string>("name", name, archive_in);
parseAppsecJSONKey<string>("action", action, archive_in);
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
if (valid_actions.count(action) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec exception action invalid: " << action;
}
parseAppsecJSONKey<vector<NewAppsecExceptionCondition>>("condition", conditions, archive_in);
}
void
NewAppsecException::setName(const string &_name)
{
name = _name;
}
const string &
NewAppsecException::getName() const
{
return name;
}
const string &
NewAppsecException::getAction() const
{
return action;
}
const string &
NewAppsecException::getAppSecClassName() const
{
return appsec_class_name;
}
const vector<string>
NewAppsecException::getCountryCode() const
{
vector<string> country_codes;
for (const NewAppsecExceptionCondition &condition : conditions) {
if (condition.getKey() == "countryCode") {
country_codes.push_back(condition.getvalue());
}
}
return country_codes;
}
const vector<string>
NewAppsecException::getCountryName() const
{
vector<string> country_names;
for (const NewAppsecExceptionCondition &condition : conditions) {
if (condition.getKey() == "countryName") {
country_names.push_back(condition.getvalue());
}
}
return country_names;
}
const vector<string>
NewAppsecException::getHostName() const
{
vector<string> host_names;
for (const NewAppsecExceptionCondition &condition : conditions) {
if (condition.getKey() == "hostName") {
host_names.push_back(condition.getvalue());
}
}
return host_names;
}
const vector<string>
NewAppsecException::getParamName() const
{
vector<string> param_names;
for (const NewAppsecExceptionCondition &condition : conditions) {
if (condition.getKey() == "paramName") {
param_names.push_back(condition.getvalue());
}
}
return param_names;
}
const vector<string>
NewAppsecException::getParamValue() const
{
vector<string> param_values;
for (const NewAppsecExceptionCondition &condition : conditions) {
if (condition.getKey() == "paramValue") {
param_values.push_back(condition.getvalue());
}
}
return param_values;
}
const vector<string>
NewAppsecException::getProtectionName() const
{
vector<string> protection_names;
for (const NewAppsecExceptionCondition &condition : conditions) {
if (condition.getKey() == "protectionName") {
protection_names.push_back(condition.getvalue());
}
}
return protection_names;
}
const vector<string>
NewAppsecException::getSourceIdentifier() const
{
vector<string> source_identifiers;
for (const NewAppsecExceptionCondition &condition : conditions) {
if (condition.getKey() == "sourceIdentifier") {
source_identifiers.push_back(condition.getvalue());
}
}
return source_identifiers;
}
const vector<string>
NewAppsecException::getSourceIp() const
{
vector<string> source_ips;
for (const NewAppsecExceptionCondition &condition : conditions) {
if (condition.getKey() == "sourceIp") {
source_ips.push_back(condition.getvalue());
}
}
return source_ips;
}
const vector<string>
NewAppsecException::getUrl() const
{
vector<string> urls;
for (const NewAppsecExceptionCondition &condition : conditions) {
if (condition.getKey() == "url") {
urls.push_back(condition.getvalue());
}
}
return urls;
}
// LCOV_EXCL_STOP

View File

@ -0,0 +1,321 @@
// 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 "new_log_trigger.h"
using namespace std;
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
static const set<string> valid_severities = {"high", "critical"};
static const set<string> valid_protocols = {"tcp", "udp"};
static const set<string> valid_formats = {"json", "json-formatted"};
void
NewAppsecTriggerAccessControlLogging::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger - Access Control Logging";
parseAppsecJSONKey<bool>("allowEvents", allow_events, archive_in, false);
parseAppsecJSONKey<bool>("dropEvents", drop_events, archive_in, false);
}
void
NewAppsecTriggerAdditionalSuspiciousEventsLogging::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger - Additional Suspicious Events Logging";
parseAppsecJSONKey<bool>("enabled", enabled, archive_in, true);
parseAppsecJSONKey<bool>("responseBody", response_body, archive_in, false);
//the old code didn't parse the responsecode so ask Noam what is the currenct default value for it
parseAppsecJSONKey<bool>("responseCode", response_code, archive_in, false);
parseAppsecJSONKey<string>("minSeverity", 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
NewAppsecTriggerAdditionalSuspiciousEventsLogging::isEnabled() const
{
return enabled;
}
bool
NewAppsecTriggerAdditionalSuspiciousEventsLogging::isResponseBody() const
{
return response_body;
}
const string &
NewAppsecTriggerAdditionalSuspiciousEventsLogging::getMinimumSeverity() const
{
return minimum_severity;
}
void
NewAppsecTriggerLogging::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger Logging";
parseAppsecJSONKey<bool>("detectEvents", detect_events, archive_in, false);
parseAppsecJSONKey<bool>("preventEvents", prevent_events, archive_in, true);
parseAppsecJSONKey<bool>("allWebRequests", all_web_requests, archive_in, false);
}
bool
NewAppsecTriggerLogging::isAllWebRequests() const
{
return all_web_requests;
}
bool
NewAppsecTriggerLogging::isDetectEvents() const
{
return detect_events;
}
bool
NewAppsecTriggerLogging::isPreventEvents() const
{
return prevent_events;
}
void
NewAppsecTriggerExtendedLogging::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger Extended Logging";
parseAppsecJSONKey<bool>("httpHeaders", http_headers, archive_in, false);
parseAppsecJSONKey<bool>("requestBody", request_body, archive_in, false);
parseAppsecJSONKey<bool>("urlPath", url_path, archive_in, false);
parseAppsecJSONKey<bool>("urlQuery", url_query, archive_in, false);
}
bool
NewAppsecTriggerExtendedLogging::isHttpHeaders() const
{
return http_headers;
}
bool
NewAppsecTriggerExtendedLogging::isRequestBody() const
{
return request_body;
}
bool
NewAppsecTriggerExtendedLogging::isUrlPath() const
{
return url_path;
}
bool
NewAppsecTriggerExtendedLogging::isUrlQuery() const
{
return url_query;
}
void
NewLoggingService::load(cereal::JSONInputArchive &archive_in)
{
parseAppsecJSONKey<string>("address", address, archive_in);
parseAppsecJSONKey<string>("proto", proto, archive_in);
if (valid_protocols.count(proto) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec Logging Service - proto invalid: " << proto;
}
parseAppsecJSONKey<int>("port", port, archive_in, 514);
}
const string &
NewLoggingService::getAddress() const
{
return address;
}
int
NewLoggingService::getPort() const
{
return port;
}
void
NewStdoutLogging::load(cereal::JSONInputArchive &archive_in)
{
parseAppsecJSONKey<string>("format", format, archive_in, "json");
if (valid_formats.count(format) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec Stdout Logging - format invalid: " << format;
}
}
const string &
NewStdoutLogging::getFormat() const
{
return format;
}
void
NewAppsecTriggerLogDestination::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger LogDestination";
// TBD: support "file"
parseAppsecJSONKey<bool>("cloud", cloud, archive_in, false);
auto mode = Singleton::Consume<I_AgentDetails>::by<NewAppsecTriggerLogDestination>()->getOrchestrationMode();
auto env_type = Singleton::Consume<I_EnvDetails>::by<NewAppsecTriggerLogDestination>()->getEnvType();
bool k8s_service_default = (mode == OrchestrationMode::HYBRID && env_type == EnvType::K8S);
parseAppsecJSONKey<bool>("k8s-service", k8s_service, archive_in, k8s_service_default);
NewStdoutLogging stdout_log;
parseAppsecJSONKey<NewStdoutLogging>("stdout", stdout_log, archive_in);
agent_local = !(stdout_log.getFormat().empty());
beautify_logs = stdout_log.getFormat() == "json-formatted";
parseAppsecJSONKey<NewLoggingService>("syslogService", syslog_service, archive_in);
parseAppsecJSONKey<NewLoggingService>("cefService", cef_service, archive_in);
}
int
NewAppsecTriggerLogDestination::getCefServerUdpPort() const
{
return getCefServiceData().getPort();
}
int
NewAppsecTriggerLogDestination::getSyslogServerUdpPort() const
{
return getSyslogServiceData().getPort();
}
bool
NewAppsecTriggerLogDestination::isAgentLocal() const
{
return agent_local;
}
bool
NewAppsecTriggerLogDestination::shouldBeautifyLogs() const
{
return beautify_logs;
}
bool
NewAppsecTriggerLogDestination::getCloud() const
{
return cloud;
}
bool
NewAppsecTriggerLogDestination::isK8SNeeded() const
{
return k8s_service;
}
bool
NewAppsecTriggerLogDestination::isCefNeeded() const
{
return !getCefServiceData().getAddress().empty();
}
bool
NewAppsecTriggerLogDestination::isSyslogNeeded() const
{
return !getSyslogServiceData().getAddress().empty();
}
const
string & NewAppsecTriggerLogDestination::getSyslogServerIpv4Address() const
{
return getSyslogServiceData().getAddress();
}
const string &
NewAppsecTriggerLogDestination::getCefServerIpv4Address() const
{
return getCefServiceData().getAddress();
}
const NewLoggingService &
NewAppsecTriggerLogDestination::getSyslogServiceData() const
{
return syslog_service;
}
const NewLoggingService &
NewAppsecTriggerLogDestination::getCefServiceData() const
{
return cef_service;
}
void
NewAppsecLogTrigger::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec log trigger";
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
parseAppsecJSONKey<NewAppsecTriggerAccessControlLogging>(
"accessControlLogging",
access_control_logging,
archive_in
);
parseAppsecJSONKey<NewAppsecTriggerAdditionalSuspiciousEventsLogging>(
"additionalSuspiciousEventsLogging",
additional_suspicious_events_logging,
archive_in
);
parseAppsecJSONKey<NewAppsecTriggerLogging>("appsecLogging", appsec_logging, archive_in);
parseAppsecJSONKey<NewAppsecTriggerExtendedLogging>("extendedLogging", extended_logging, archive_in);
parseAppsecJSONKey<NewAppsecTriggerLogDestination>("logDestination", log_destination, archive_in);
parseAppsecJSONKey<string>("name", name, archive_in);
}
void
NewAppsecLogTrigger::setName(const string &_name)
{
name = _name;
}
const string &
NewAppsecLogTrigger::getName() const
{
return name;
}
const string &
NewAppsecLogTrigger::getAppSecClassName() const
{
return appsec_class_name;
}
const NewAppsecTriggerAdditionalSuspiciousEventsLogging &
NewAppsecLogTrigger::getAppsecTriggerAdditionalSuspiciousEventsLogging() const
{
return additional_suspicious_events_logging;
}
const NewAppsecTriggerLogging &
NewAppsecLogTrigger::getAppsecTriggerLogging() const
{
return appsec_logging;
}
const NewAppsecTriggerExtendedLogging &
NewAppsecLogTrigger::getAppsecTriggerExtendedLogging() const
{
return extended_logging;
}
const NewAppsecTriggerLogDestination &
NewAppsecLogTrigger::getAppsecTriggerLogDestination() const
{
return log_destination;
}
// LCOV_EXCL_STOP

View File

@ -0,0 +1,751 @@
// 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 "new_practice.h"
using namespace std;
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
static const set<string> performance_impacts = {"low", "medium", "high"};
static const set<string> severity_levels = {"low", "medium", "high", "critical"};
static const set<string> size_unit = {"bytes", "KB", "MB", "GB"};
static const set<string> confidences_actions = {"prevent", "detect", "inactive"};
static const set<string> valid_modes = {"prevent", "detect", "inactive", "prevent-learn", "detect-learn"};
static const set<string> valid_confidences = {"medium", "high", "critical"};
static const std::unordered_map<std::string, std::string> key_to_performance_impact_val = {
{ "low", "Low or lower"},
{ "medium", "Medium or lower"},
{ "high", "High or lower"}
};
static const std::unordered_map<std::string, std::string> key_to_severity_level_val = {
{ "low", "Low or above"},
{ "medium", "Medium or above"},
{ "high", "High or above"},
{ "critical", "Critical"}
};
static const std::unordered_map<std::string, std::string> key_to_mode_val = {
{ "prevent-learn", "Prevent"},
{ "detect-learn", "Detect"},
{ "prevent", "Prevent"},
{ "detect", "Detect"},
{ "inactive", "Inactive"}
};
static const std::unordered_map<std::string, int> unit_to_int = {
{ "bytes", 1},
{ "KB", 1024},
{ "MB", 1048576},
{ "GB", 1073741824}
};
void
NewAppSecWebBotsURI::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Web Bots URI";
parseAppsecJSONKey<string>("uri", uri, archive_in);
}
const string &
NewAppSecWebBotsURI::getURI() const
{
return uri;
}
std::vector<std::string>
NewAppSecPracticeAntiBot::getIjectedUris() const
{
vector<string> injected;
for (const NewAppSecWebBotsURI &uri : injected_uris) injected.push_back(uri.getURI());
return injected;
}
std::vector<std::string>
NewAppSecPracticeAntiBot::getValidatedUris() const
{
vector<string> validated;
for (const NewAppSecWebBotsURI &uri : validated_uris) validated.push_back(uri.getURI());
return validated;
}
void
NewAppSecPracticeAntiBot::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Web Bots";
parseAppsecJSONKey<vector<NewAppSecWebBotsURI>>("injectedUris", injected_uris, archive_in);
parseAppsecJSONKey<vector<NewAppSecWebBotsURI>>("validatedUris", validated_uris, archive_in);
parseAppsecJSONKey<string>("overrideMode", 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
NewAppSecPracticeAntiBot::save(cereal::JSONOutputArchive &out_ar) const
{
vector<string> injected;
vector<string> validated;
for (const NewAppSecWebBotsURI &uri : injected_uris) injected.push_back(uri.getURI());
for (const NewAppSecWebBotsURI &uri : validated_uris) validated.push_back(uri.getURI());
out_ar(
cereal::make_nvp("injected", injected),
cereal::make_nvp("validated", validated)
);
}
void
NewAppSecWebAttackProtections::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Web Attack Protections";
parseAppsecJSONKey<string>("csrfEnabled", csrf_protection, archive_in, "inactive");
parseAppsecJSONKey<string>("errorDisclosureEnabled", error_disclosure, archive_in, "inactive");
parseAppsecJSONKey<string>("openRedirectEnabled", open_redirect, archive_in, "inactive");
parseAppsecJSONKey<bool>("nonValidHttpMethods", non_valid_http_methods, archive_in, false);
}
const string
NewAppSecWebAttackProtections::getCsrfProtectionMode() const
{
if (key_to_practices_val.find(csrf_protection) == key_to_practices_val.end()) {
dbgError(D_LOCAL_POLICY)
<< "Failed to find a value for "
<< csrf_protection
<< ". Setting CSRF protection to Inactive";
return "Inactive";
}
return key_to_practices_val.at(csrf_protection);
}
const string &
NewAppSecWebAttackProtections::getErrorDisclosureMode() const
{
return error_disclosure;
}
bool
NewAppSecWebAttackProtections::getNonValidHttpMethods() const
{
return non_valid_http_methods;
}
const string
NewAppSecWebAttackProtections::getOpenRedirectMode() const
{
if (key_to_practices_val.find(open_redirect) == key_to_practices_val.end()) {
dbgError(D_LOCAL_POLICY)
<< "Failed to find a value for "
<< open_redirect
<< ". Setting Open Redirect mode to Inactive";
return "Inactive";
}
return key_to_practices_val.at(open_redirect);
}
void
NewAppSecPracticeWebAttacks::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice web attacks spec";
parseAppsecJSONKey<NewAppSecWebAttackProtections>("protections", protections, archive_in);
parseAppsecJSONKey<string>("overrideMode", mode, archive_in, "Unset");
if (valid_modes.count(mode) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec practice override mode invalid: " << mode;
}
if (getMode() == "Prevent") {
parseAppsecJSONKey<string>("minimumConfidence", 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";
}
parseAppsecJSONKey<int>("maxBodySizeKb", max_body_size_kb, archive_in, 1000000);
parseAppsecJSONKey<int>("maxHeaderSizeBytes", max_header_size_bytes, archive_in, 102400);
parseAppsecJSONKey<int>("maxObjectDepth", max_object_depth, archive_in, 40);
parseAppsecJSONKey<int>("maxUrlSizeBytes", max_url_size_bytes, archive_in, 32768);
}
int
NewAppSecPracticeWebAttacks::getMaxBodySizeKb() const
{
return max_body_size_kb;
}
int
NewAppSecPracticeWebAttacks::getMaxHeaderSizeBytes() const
{
return max_header_size_bytes;
}
int
NewAppSecPracticeWebAttacks::getMaxObjectDepth() const
{
return max_object_depth;
}
int
NewAppSecPracticeWebAttacks::getMaxUrlSizeBytes() const
{
return max_url_size_bytes;
}
const string &
NewAppSecPracticeWebAttacks::getMinimumConfidence() const
{
return minimum_confidence;
}
const string &
NewAppSecPracticeWebAttacks::getMode(const string &default_mode) const
{
if (mode == "Unset" || (key_to_practices_val.find(mode) == key_to_practices_val.end())) {
dbgError(D_LOCAL_POLICY) << "Couldn't find a value for key: " << mode << ". Returning " << default_mode;
return default_mode;
}
return key_to_practices_val.at(mode);
}
void
NewSnortSignaturesAndOpenSchemaAPI::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Snort Signatures practice";
parseAppsecJSONKey<string>("overrideMode", override_mode, archive_in, "Inactive");
parseAppsecJSONKey<vector<string>>("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 &
NewSnortSignaturesAndOpenSchemaAPI::getOverrideMode() const
{
return override_mode;
}
const vector<string> &
NewSnortSignaturesAndOpenSchemaAPI::getConfigMap() const
{
return config_map;
}
void
IpsProtectionsRulesSection::save(cereal::JSONOutputArchive &out_ar) const
{
vector<string> protections;
out_ar(
cereal::make_nvp("action", key_to_mode_val.at(action)),
cereal::make_nvp("confidenceLevel", confidence_level),
cereal::make_nvp("clientProtections", true),
cereal::make_nvp("serverProtections", true),
cereal::make_nvp("protectionTags", protections),
cereal::make_nvp("protectionIds", protections),
cereal::make_nvp("performanceImpact", key_to_performance_impact_val.at(performance_impact)),
cereal::make_nvp("severityLevel", key_to_severity_level_val.at(severity_level)),
cereal::make_nvp("protectionsFromYear", protections_from_year)
);
}
IpsProtectionsSection::IpsProtectionsSection(
const string &_context,
const string &asset_name,
const string &_asset_id,
const string &_practice_name,
const string &_practice_id,
const string &_source_identifier,
const string &_mode,
const vector<IpsProtectionsRulesSection> &_rules)
:
context(_context),
name(asset_name),
asset_id(_asset_id),
practice_name(_practice_name),
practice_id(_practice_id),
source_identifier(_source_identifier),
mode(_mode),
rules(_rules)
{
}
std::string &
IpsProtectionsSection::getMode()
{
return mode;
}
void
IpsProtectionsSection::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("context", context),
cereal::make_nvp("ruleName", name),
cereal::make_nvp("assetName", name),
cereal::make_nvp("assetId", asset_id),
cereal::make_nvp("practiceName", practice_name),
cereal::make_nvp("practiceId", practice_id),
cereal::make_nvp("sourceIdentifier", source_identifier),
cereal::make_nvp("defaultAction", key_to_mode_val.at(mode)),
cereal::make_nvp("rules", rules)
);
}
void
IPSSection::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("IpsProtections", ips)
);
}
void
IntrusionPreventionWrapper::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("IPS", ips)
);
}
void
NewIntrusionPrevention::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Intrusion Prevention practice";
parseAppsecJSONKey<string>("overrideMode", override_mode, archive_in, "Inactive");
if (valid_modes.count(override_mode) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec Intrusion Prevention override mode invalid: " << override_mode;
}
parseAppsecJSONKey<string>("maxPerformanceImpact", max_performance_impact, archive_in, "low");
if (performance_impacts.count(max_performance_impact) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec Intrusion Prevention max performance impact invalid: "
<< max_performance_impact;
}
parseAppsecJSONKey<string>("minSeverityLevel", min_severity_level, archive_in, "low");
if (severity_levels.count(min_severity_level) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec Intrusion Prevention min severity level invalid: "
<< min_severity_level;
}
parseAppsecJSONKey<string>("highConfidenceEventAction", high_confidence_event_action, archive_in, "inactive");
if (confidences_actions.count(high_confidence_event_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec Intrusion Prevention high confidence event invalid: "
<< high_confidence_event_action;
}
parseAppsecJSONKey<string>("mediumConfidenceEventAction", medium_confidence_event_action, archive_in, "inactive");
if (confidences_actions.count(medium_confidence_event_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec Intrusion Prevention medium confidence event invalid: "
<< medium_confidence_event_action;
}
parseAppsecJSONKey<string>("lowConfidenceEventAction", low_confidence_event_action, archive_in, "inactive");
if (confidences_actions.count(low_confidence_event_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec Intrusion Prevention low confidence event action invalid: "
<< low_confidence_event_action;
}
parseAppsecJSONKey<int>("minCveYear", min_cve_Year, archive_in);
}
vector<IpsProtectionsRulesSection>
NewIntrusionPrevention::createIpsRules() const
{
vector<IpsProtectionsRulesSection> ips_rules;
IpsProtectionsRulesSection high_rule(
min_cve_Year,
high_confidence_event_action,
string("High"),
max_performance_impact,
string(""),
min_severity_level
);
ips_rules.push_back(high_rule);
IpsProtectionsRulesSection med_rule(
min_cve_Year,
medium_confidence_event_action,
string("Medium"),
max_performance_impact,
string(""),
min_severity_level
);
ips_rules.push_back(med_rule);
IpsProtectionsRulesSection low_rule(
min_cve_Year,
low_confidence_event_action,
string("Low"),
max_performance_impact,
string(""),
min_severity_level
);
ips_rules.push_back(low_rule);
return ips_rules;
}
const std::string &
NewIntrusionPrevention::getMode() const
{
return override_mode;
}
FileSecurityProtectionsSection::FileSecurityProtectionsSection(
int _file_size_limit,
int _archive_file_size_limit,
bool _allow_files_without_name,
bool _required_file_size_limit,
bool _required_archive_extraction,
const std::string &_context,
const std::string &_name,
const std::string &_asset_id,
const std::string &_practice_name,
const std::string &_practice_id,
const std::string &_action,
const std::string &_files_without_name_action,
const std::string &_high_confidence_action,
const std::string &_medium_confidence_action,
const std::string &_low_confidence_action,
const std::string &_severity_level,
const std::string &_file_size_limit_action,
const std::string &_multi_level_archive_action,
const std::string &_unopened_archive_action)
:
file_size_limit(_file_size_limit),
archive_file_size_limit(_archive_file_size_limit),
allow_files_without_name(_allow_files_without_name),
required_file_size_limit(_required_file_size_limit),
required_archive_extraction(_required_archive_extraction),
context(_context),
name(_name),
asset_id(_asset_id),
practice_name(_practice_name),
practice_id(_practice_id),
action(_action),
files_without_name_action(_files_without_name_action),
high_confidence_action(_high_confidence_action),
medium_confidence_action(_medium_confidence_action),
low_confidence_action(_low_confidence_action),
severity_level(_severity_level),
file_size_limit_action(_file_size_limit_action),
multi_level_archive_action(_multi_level_archive_action),
unopened_archive_action(_unopened_archive_action)
{}
void
FileSecurityProtectionsSection::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("context", context),
cereal::make_nvp("ruleName", name),
cereal::make_nvp("assetName", name),
cereal::make_nvp("assetId", asset_id),
cereal::make_nvp("practiceName", practice_name),
cereal::make_nvp("practiceId", practice_id),
cereal::make_nvp("action", key_to_mode_val.at(action)),
cereal::make_nvp("filesWithoutNameAction", key_to_mode_val.at(files_without_name_action)),
cereal::make_nvp("allowFilesWithoutName", allow_files_without_name),
cereal::make_nvp("highConfidence", key_to_mode_val.at(high_confidence_action)),
cereal::make_nvp("mediumConfidence", key_to_mode_val.at(medium_confidence_action)),
cereal::make_nvp("lowConfidence", key_to_mode_val.at(low_confidence_action)),
cereal::make_nvp("severityLevel", key_to_severity_level_val.at(severity_level)),
cereal::make_nvp("fileSizeLimitAction", key_to_mode_val.at(file_size_limit_action)),
cereal::make_nvp("fileSizeLimit", file_size_limit),
cereal::make_nvp("requiredFileSizeLimit", required_file_size_limit),
cereal::make_nvp("requiredArchiveExtraction", required_archive_extraction),
cereal::make_nvp("archiveFileSizeLimit", archive_file_size_limit),
cereal::make_nvp("MultiLevelArchiveAction", key_to_mode_val.at(multi_level_archive_action)),
cereal::make_nvp("UnopenedArchiveAction", key_to_mode_val.at(unopened_archive_action))
);
}
void
FileSecuritySection::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("FileSecurityProtections", file_security)
);
}
void
FileSecurityWrapper::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("FileSecurity", file_security)
);
}
void
NewFileSecurityArchiveInspection::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec File Security Archive Inspection practice";
parseAppsecJSONKey<bool>("extractArchiveFiles", extract_archive_files, archive_in);
parseAppsecJSONKey<int>("scanMaxFileSize", scan_max_file_size, archive_in, 0);
parseAppsecJSONKey<string>("scanMaxFileSizeUnit", scan_max_file_size_unit, archive_in, "bytes");
if (size_unit.count(scan_max_file_size_unit) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security Archive Inspection scan max file size unit invalid: "
<< scan_max_file_size_unit;
}
parseAppsecJSONKey<string>(
"archivedFilesWithinArchivedFiles",
archived_files_within_archived_files,
archive_in,
"inactive");
if (confidences_actions.count(archived_files_within_archived_files) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security Archive Inspection archived files within archived files invalid: "
<< archived_files_within_archived_files;
}
parseAppsecJSONKey<string>(
"archivedFilesWhereContentExtractionFailed",
archived_files_where_content_extraction_failed,
archive_in,
"inactive");
if (confidences_actions.count(archived_files_where_content_extraction_failed) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security Archive Inspection archived files within archived file invalid: "
<< archived_files_where_content_extraction_failed;
}
}
int
NewFileSecurityArchiveInspection::getArchiveFileSizeLimit() const
{
if (unit_to_int.find(scan_max_file_size_unit) == unit_to_int.end()) {
dbgError(D_LOCAL_POLICY)
<< "Failed to find a value for "
<< scan_max_file_size_unit
<< ". Setting scan max file size unit to 0";
return 0;
}
return (scan_max_file_size * unit_to_int.at(scan_max_file_size_unit));
}
bool
NewFileSecurityArchiveInspection::getrequiredArchiveExtraction() const
{
return extract_archive_files;
}
const std::string &
NewFileSecurityArchiveInspection::getMultiLevelArchiveAction() const
{
return archived_files_within_archived_files;
}
const std::string &
NewFileSecurityArchiveInspection::getUnopenedArchiveAction() const
{
return archived_files_where_content_extraction_failed;
}
void
NewFileSecurityLargeFileInspection::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec File Security large File Inspection practice";
parseAppsecJSONKey<int>("fileSizeLimit", file_size_limit, archive_in);
parseAppsecJSONKey<string>("fileSizeLimitUnit", file_size_limit_unit, archive_in, "bytes");
if (size_unit.count(file_size_limit_unit) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security large File Inspection file size limit unit invalid: "
<< file_size_limit_unit;
}
parseAppsecJSONKey<string>(
"filesExceedingSizeLimitAction",
files_exceeding_size_limit_action,
archive_in,
"inactive");
if (confidences_actions.count(files_exceeding_size_limit_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security Archive Inspection archived files within archived files invalid: "
<< files_exceeding_size_limit_action;
}
}
int
NewFileSecurityLargeFileInspection::getFileSizeLimit() const
{
if (unit_to_int.find(file_size_limit_unit) == unit_to_int.end()) {
dbgError(D_LOCAL_POLICY)
<< "Failed to find a value for "
<< file_size_limit_unit
<< ". Setting file size limit unit to 0";
return 0;
}
return (file_size_limit * unit_to_int.at(file_size_limit_unit));
}
const std::string &
NewFileSecurityLargeFileInspection::getFileSizeLimitAction() const
{
return files_exceeding_size_limit_action;
}
void
NewFileSecurity::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec File Security practice";
parseAppsecJSONKey<string>("overrideMode", override_mode, archive_in, "Inactive");
if (valid_modes.count(override_mode) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec File Security override mode invalid: " << override_mode;
}
parseAppsecJSONKey<string>("minSeverityLevel", min_severity_level, archive_in, "low");
if (severity_levels.count(min_severity_level) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec File Security min severity level invalid: " << min_severity_level;
}
parseAppsecJSONKey<string>("highConfidenceEventAction", high_confidence_event_action, archive_in, "inactive");
if (confidences_actions.count(high_confidence_event_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security high confidence event invalid: "
<< high_confidence_event_action;
}
parseAppsecJSONKey<string>("mediumConfidenceEventAction", medium_confidence_event_action, archive_in, "inactive");
if (confidences_actions.count(medium_confidence_event_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security medium confidence event invalid: "
<< medium_confidence_event_action;
}
parseAppsecJSONKey<string>("lowConfidenceEventAction", low_confidence_event_action, archive_in, "inactive");
if (confidences_actions.count(low_confidence_event_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security low confidence event action invalid: "
<< low_confidence_event_action;
}
parseAppsecJSONKey<string>("unnamedFilesAction", unnamed_files_action, archive_in, "inactive");
if (confidences_actions.count(unnamed_files_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security low unnamed files action invalid: "
<< unnamed_files_action;
}
parseAppsecJSONKey<bool>("threatEmulationEnabled", threat_emulation_enabled, archive_in);
parseAppsecJSONKey<NewFileSecurityArchiveInspection>("archiveInspection", archive_inspection, archive_in);
parseAppsecJSONKey<NewFileSecurityLargeFileInspection>("largeFileInspection", large_file_inspection, archive_in);
}
const NewFileSecurityArchiveInspection &
NewFileSecurity::getArchiveInspection() const
{
return archive_inspection;
}
const NewFileSecurityLargeFileInspection &
NewFileSecurity::getLargeFileInspection() const
{
return large_file_inspection;
}
FileSecurityProtectionsSection
NewFileSecurity::createFileSecurityProtectionsSection(
const string &context,
const string &asset_name,
const string &asset_id,
const string &practice_name,
const string &practice_id) const
{
return FileSecurityProtectionsSection(
getLargeFileInspection().getFileSizeLimit(),
getArchiveInspection().getArchiveFileSizeLimit(),
unnamed_files_action == "prevent" ? true : false,
getLargeFileInspection().getFileSizeLimitAction() == "prevent" ? true : false,
getArchiveInspection().getrequiredArchiveExtraction(),
context,
asset_name,
asset_id,
practice_name,
practice_id,
override_mode,
unnamed_files_action,
high_confidence_event_action,
medium_confidence_event_action,
low_confidence_event_action,
min_severity_level,
getLargeFileInspection().getFileSizeLimitAction(),
getArchiveInspection().getMultiLevelArchiveAction(),
getArchiveInspection().getUnopenedArchiveAction()
);
}
void
NewAppSecPracticeSpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec";
parseAppsecJSONKey<NewSnortSignaturesAndOpenSchemaAPI>(
"openapi-schema-validation",
openapi_schema_validation,
archive_in
);
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
parseAppsecJSONKey<NewFileSecurity>("fileSecurity", file_security, archive_in);
parseAppsecJSONKey<NewIntrusionPrevention>("intrusionPrevention", intrusion_prevention, archive_in);
parseAppsecJSONKey<NewSnortSignaturesAndOpenSchemaAPI>("snortSignatures", snort_signatures, archive_in);
parseAppsecJSONKey<NewAppSecPracticeWebAttacks>("webAttacks", web_attacks, archive_in);
parseAppsecJSONKey<NewAppSecPracticeAntiBot>("antiBot", anti_bot, archive_in);
parseAppsecJSONKey<string>("name", practice_name, archive_in);
}
void
NewAppSecPracticeSpec::setName(const string &_name)
{
practice_name = _name;
}
const NewSnortSignaturesAndOpenSchemaAPI &
NewAppSecPracticeSpec::getOpenSchemaValidation() const
{
return openapi_schema_validation;
}
const NewSnortSignaturesAndOpenSchemaAPI &
NewAppSecPracticeSpec::getSnortSignatures() const
{
return snort_signatures;
}
const NewAppSecPracticeWebAttacks &
NewAppSecPracticeSpec::getWebAttacks() const
{
return web_attacks;
}
const NewAppSecPracticeAntiBot &
NewAppSecPracticeSpec::getAntiBot() const
{
return anti_bot;
}
const NewIntrusionPrevention &
NewAppSecPracticeSpec::getIntrusionPrevention() const
{
return intrusion_prevention;
}
const NewFileSecurity &
NewAppSecPracticeSpec::getFileSecurity() const
{
return file_security;
}
const string &
NewAppSecPracticeSpec::getAppSecClassName() const
{
return appsec_class_name;
}
const string &
NewAppSecPracticeSpec::getName() const
{
return practice_name;
}
// LCOV_EXCL_STOP

View File

@ -0,0 +1,118 @@
// 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 "new_trusted_sources.h"
using namespace std;
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
static const set<string> valid_identifiers = {"headerkey", "JWTKey", "cookie", "sourceip", "x-forwarded-for"};
void
NewTrustedSourcesSpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading trusted sources spec";
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
parseAppsecJSONKey<int>("minNumOfSources", min_num_of_sources, archive_in, 3);
parseAppsecJSONKey<vector<string>>("sourcesIdentifiers", sources_identifiers, archive_in);
parseAppsecJSONKey<string>("name", name, archive_in);
}
void
NewTrustedSourcesSpec::setName(const string &_name)
{
name = _name;
}
int
NewTrustedSourcesSpec::getMinNumOfSources() const
{
return min_num_of_sources;
}
const vector<string> &
NewTrustedSourcesSpec::getSourcesIdentifiers() const
{
return sources_identifiers;
}
const string &
NewTrustedSourcesSpec::getAppSecClassName() const
{
return appsec_class_name;
}
const string &
NewTrustedSourcesSpec::getName() const
{
return name;
}
void
Identifier::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading source identifiers spec";
parseAppsecJSONKey<string>("sourceIdentifier", identifier, archive_in);
if (valid_identifiers.count(identifier) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec identifier invalid: " << identifier;
}
parseAppsecJSONKey<vector<string>>("value", value, archive_in);
}
const string &
Identifier::getIdentifier() const
{
return identifier;
}
const vector<string> &
Identifier::getValues() const
{
return value;
}
void
NewSourcesIdentifiers::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading Sources Identifiers";
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
parseAppsecJSONKey<vector<Identifier>>("sourcesIdentifiers", sources_identifiers, archive_in);
parseAppsecJSONKey<string>("name", name, archive_in);
}
void
NewSourcesIdentifiers::setName(const string &_name)
{
name = _name;
}
const string &
NewSourcesIdentifiers::getName() const
{
return name;
}
const string &
NewSourcesIdentifiers::getAppSecClassName() const
{
return appsec_class_name;
}
const vector<Identifier> &
NewSourcesIdentifiers::getSourcesIdentifiers() const
{
return sources_identifiers;
}
// LCOV_EXCL_STOP

View File

@ -249,6 +249,14 @@ UsersIdentifier::UsersIdentifier(const string &_source_identifier, vector<string
identifier_values(_identifier_values)
{}
// LCOV_EXCL_START Reason: no test exist
const string &
UsersIdentifier::getIdentifier() const
{
return source_identifier;
}
// LCOV_EXCL_STOP
void
UsersIdentifier::save(cereal::JSONOutputArchive &out_ar) const
{
@ -270,6 +278,14 @@ UsersIdentifiersRulebase::UsersIdentifiersRulebase(
source_identifiers(_source_identifiers)
{}
// LCOV_EXCL_START Reason: no test exist
const string &
UsersIdentifiersRulebase::getIdentifier() const
{
return source_identifiers[0].getIdentifier();
}
// LCOV_EXCL_STOP
void
UsersIdentifiersRulebase::save(cereal::JSONOutputArchive &out_ar) const
{

View File

@ -449,7 +449,7 @@ public:
<< filesystem_prefix;
map<string, string> service_policies_copy = status.getServicePolicies();
for (const pair<string, string> &policy: service_policies_copy) {
for (const auto &policy: service_policies_copy) {
setServiceConfiguration(policy.first, policy.second, OrchestrationStatusConfigType::POLICY);
}

View File

@ -49,13 +49,9 @@ using namespace ReportIS;
USE_DEBUG_FLAG(D_ORCHESTRATOR);
static const string ls_prefix = "ls ";
static const string extract_tenant_profile_suffix =
"| grep tenant "
"| cut -d '_' -f 2,4 "
"| sort --unique "
"| awk -F '_' '{ printf \"%s %s \",$1,$2 }'";
#if defined(gaia) || defined(smb)
static string fw_last_update_time = "";
#endif // gaia || smb
class HealthCheckStatusListener : public Listener<HealthCheckStatusEvent>
{
@ -202,7 +198,10 @@ public:
ReportIS::Audience::INTERNAL
);
hybrid_mode_metric.registerListener();
loadExistingTenantsFromConfDir();
auto orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<OrchestrationComp>();
orchestration_tools->loadTenantsFromDir(
getConfigurationWithDefault<string>(getFilesystemPathConfig() + "/conf/", "orchestration", "Conf dir")
);
}
void
@ -242,8 +241,14 @@ private:
);
auto service_controller = Singleton::Consume<I_ServiceController>::by<OrchestrationComp>();
if (!service_controller->updateServiceConfiguration(policy_file_path, settings_file_path)) {
dbgWarning(D_ORCHESTRATOR) << "Failed to load the policy and settings";
auto is_update_config = service_controller->updateServiceConfiguration(
policy_file_path,
settings_file_path
);
if (!is_update_config.ok()) {
dbgWarning(D_ORCHESTRATOR)
<< "Failed to load the policy and settings, Error: "
<< is_update_config.getErr();
}
policy_version = service_controller->getPolicyVersion();
@ -276,7 +281,9 @@ private:
auto update_communication = Singleton::Consume<I_UpdateCommunication>::by<OrchestrationComp>();
auto authentication_res = update_communication->authenticateAgent();
if (authentication_res.ok() && !policy_version.empty()) {
auto path_policy_version = update_communication->sendPolicyVersion(policy_version);
auto service_controller = Singleton::Consume<I_ServiceController>::by<OrchestrationComp>();
const string &policy_versions = service_controller->getPolicyVersions();
auto path_policy_version = update_communication->sendPolicyVersion(policy_version, policy_versions);
if (!path_policy_version.ok()) {
dbgWarning(D_ORCHESTRATOR) << path_policy_version.getErr();
}
@ -289,59 +296,6 @@ private:
return authentication_res;
}
void
loadExistingTenantsFromConfDir()
{
dbgTrace(D_ORCHESTRATOR) << "Load existing tenants and profiles from the configuration folder";
string global_conf_dir = getConfigurationWithDefault<string>(
getFilesystemPathConfig()+ "/conf/",
"orchestration",
"Conf dir"
);
string shell_cmd_string = ls_prefix + global_conf_dir + extract_tenant_profile_suffix;
auto shell = Singleton::Consume<I_ShellCmd>::by<OrchestrationComp>();
Maybe<string> output_res = shell->getExecOutput(shell_cmd_string);
if (!output_res.ok()) {
dbgWarning(D_ORCHESTRATOR)
<< "Failed to load existing tenants from configuration folder: " + output_res.getErr();
return;
}
auto tenant_manager = Singleton::Consume<I_TenantManager>::by<OrchestrationComp>();
stringstream ss(output_res.unpack());
string tenant_id;
string profile_id;
while (!ss.eof() && getline(ss, tenant_id, ' ') && !ss.eof() && getline(ss, profile_id, ' ')) {
dbgTrace(D_ORCHESTRATOR) << "Add existing tenant_" + tenant_id + "_profile_" + profile_id;
tenant_manager->addActiveTenantAndProfile(tenant_id, profile_id);
}
}
void
deleteInactiveTenantProfileFiles(const string &tenant_id, const string &profile_id)
{
string global_conf_dir = getConfigurationWithDefault<string>(
getFilesystemPathConfig()+ "/conf/",
"orchestration",
"Conf dir"
);
string tenant_and_profile_suffix = "tenant_" + tenant_id + "_profile_" + profile_id;
string virtual_policy_dir = global_conf_dir + tenant_and_profile_suffix;
dbgTrace(D_ORCHESTRATOR) << "Delete virtual policy folder : " << virtual_policy_dir;
if (!NGEN::Filesystem::deleteDirectory(virtual_policy_dir, true)) {
dbgWarning(D_ORCHESTRATOR) << "Failed to delete virtual policy folder : " << virtual_policy_dir;
}
string settings_file_path = virtual_policy_dir + "_settings.json";
dbgTrace(D_ORCHESTRATOR) << "Delete settings file " << settings_file_path;
if (!NGEN::Filesystem::deleteFile(settings_file_path)) {
dbgWarning(D_ORCHESTRATOR) << "Failed to delete virtual policy settings file : " << settings_file_path;
}
}
Maybe<OrchestrationPolicy>
loadOrchestrationPolicy()
{
@ -416,10 +370,11 @@ private:
auto orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<OrchestrationComp>();
auto service_controller = Singleton::Consume<I_ServiceController>::by<OrchestrationComp>();
if (service_controller->updateServiceConfiguration(policy_file_path, settings_file_path)) {
auto is_update_config = service_controller->updateServiceConfiguration(policy_file_path, settings_file_path);
if (is_update_config.ok()) {
maybe_policy = orchestration_tools->jsonFileToObject<OrchestrationPolicy>(orchestration_policy_file);
} else {
dbgWarning(D_ORCHESTRATOR) << "Failed to enforce Orchestration policy. File: " << policy_file_path;
dbgWarning(D_ORCHESTRATOR) << is_update_config.getErr();
}
if (!maybe_policy.ok()) {
@ -435,8 +390,11 @@ private:
return genError("Failed to copy orchestration policy from backup policy.json file.");
}
// Try to use the backup policy.json file and re-write the services's policies.
if (service_controller->updateServiceConfiguration(policy_file_path, settings_file_path)) {
maybe_policy= orchestration_tools->jsonFileToObject<OrchestrationPolicy>(orchestration_policy_file);
is_update_config = service_controller->updateServiceConfiguration(policy_file_path, settings_file_path);
if (is_update_config.ok()) {
maybe_policy = orchestration_tools->jsonFileToObject<OrchestrationPolicy>(orchestration_policy_file);
} else {
dbgWarning(D_ORCHESTRATOR) << is_update_config.getErr();
}
}
@ -613,18 +571,22 @@ private:
// Try to use the backup policy.json file and re-write the services's policies.
dbgInfo(D_ORCHESTRATOR) << "Updating services with the new policy.";
if (service_controller->updateServiceConfiguration(policy_file_path + backup_ext, settings_file_path)) {
dbgInfo(D_ORCHESTRATOR) << "Recovering the policy file from backup.";
if (!orchestration_tools->copyFile(policy_file_path + backup_ext, policy_file_path)) {
dbgWarning (D_ORCHESTRATOR)
<< "Failed to recover policy file from backup. File: "
<< policy_file_path + backup_ext;
return false;
}
return true;
auto is_update_config = service_controller->updateServiceConfiguration(
policy_file_path + backup_ext,
settings_file_path
);
if (!is_update_config.ok()) {
dbgWarning (D_ORCHESTRATOR) << "Failed to load Orchestration policy. Error: " << is_update_config.getErr();
return false;
}
dbgWarning (D_ORCHESTRATOR) << "Failed to load Orchestration policy.";
return false;
dbgInfo(D_ORCHESTRATOR) << "Recovering the policy file from backup.";
if (!orchestration_tools->copyFile(policy_file_path + backup_ext, policy_file_path)) {
dbgWarning (D_ORCHESTRATOR)
<< "Failed to recover policy file from backup. File: "
<< policy_file_path + backup_ext;
return false;
}
return true;
}
string
@ -646,7 +608,8 @@ private:
Singleton::Consume<I_OrchestrationStatus>::by<OrchestrationComp>()->setPolicyVersion(new_policy_version);
}
auto update_communication = Singleton::Consume<I_UpdateCommunication>::by<OrchestrationComp>();
auto path_policy_version = update_communication->sendPolicyVersion(new_policy_version);
const string &policy_versions = service_controller->getPolicyVersions();
auto path_policy_version = update_communication->sendPolicyVersion(new_policy_version, policy_versions);
if (!path_policy_version.ok()) {
dbgWarning(D_ORCHESTRATOR) << path_policy_version.getErr();
}
@ -685,19 +648,21 @@ private:
// Calculate the changes between the existing policy to the new one.
auto service_controller = Singleton::Consume<I_ServiceController>::by<OrchestrationComp>();
string old_policy_version = service_controller->getPolicyVersion();
bool res = service_controller->updateServiceConfiguration(
auto res = service_controller->updateServiceConfiguration(
new_policy_file.unpack(),
settings_path,
data_updates
);
if (!res) {
if (!res.ok()) {
string updated_policy_version = service_controller->getUpdatePolicyVersion();
string error_str =
"Failed to update services' policy configuration files. Previous version: " +
old_policy_version +
". New version: " +
updated_policy_version;
updated_policy_version +
". Error: " +
res.getErr();
auto policy_file = getConfigurationWithDefault<string>(
filesystem_prefix + "/conf/policy.json",
@ -987,6 +952,22 @@ private:
policy_version
);
auto agent_mode = Singleton::Consume<I_AgentDetails>::by<OrchestrationComp>()->getOrchestrationMode();
auto policy_mgmt_mode = getSettingWithDefault<string>("management", "profileManagedMode");
if (agent_mode == OrchestrationMode::HYBRID || policy_mgmt_mode == "declarative") {
auto upgrade_mode = getSettingWithDefault<string>("manual", "upgradeMode");
if (upgrade_mode != "scheduled") {
request.setUpgradeFields(upgrade_mode);
} else {
request.setUpgradeFields(
upgrade_mode,
getSettingWithDefault<string>("0:00", "upgradeTime"),
getSettingWithDefault<uint>(4, "upgradeDurationHours"),
getSettingWithDefault<vector<string>>({}, "upgradeDay")
);
}
}
auto greedy_update = getProfileAgentSettingWithDefault<bool>(false, "orchestration.multitenancy.greedymode");
greedy_update = getConfigurationWithDefault<bool>(greedy_update, "orchestration", "Multitenancy Greedy mode");
@ -1095,16 +1076,16 @@ private:
data_updates
);
}
if (!orch_policy.ok() && (data_updates.size() > 0 || settings_path != "")) {
if (!orch_policy.ok() && (!data_updates.empty() || !settings_path.empty())) {
auto service_controller = Singleton::Consume<I_ServiceController>::by<OrchestrationComp>();
bool res = service_controller->updateServiceConfiguration(
auto res = service_controller->updateServiceConfiguration(
"",
settings_path,
data_updates
);
if (!res) {
dbgWarning(D_ORCHESTRATOR) << "Failed to update new service configuration";
if (!res.ok()) {
dbgWarning(D_ORCHESTRATOR) << res.getErr();
}
}
@ -1271,7 +1252,12 @@ private:
}
}
}
auto orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<OrchestrationComp>();
auto conf_dir = getConfigurationWithDefault<string>(
getFilesystemPathConfig() + "/conf/",
"orchestration",
"Conf dir"
);
for (const auto &tenant_profile_set : profiles_to_be_deleted) {
auto tenant_id = tenant_profile_set.first;
for (const auto &profile_id: tenant_profile_set.second) {
@ -1282,7 +1268,11 @@ private:
<< ", Profile ID: "
<< profile_id;
tenant_manager->deactivateTenant(tenant_id, profile_id);
deleteInactiveTenantProfileFiles(tenant_id, profile_id);
orchestration_tools->deleteVirtualTenantProfileFiles(
tenant_id,
profile_id,
conf_dir
);
}
}
@ -1481,6 +1471,16 @@ private:
agent_data_report << AgentReportFieldWithLabel("isVersionEqualOrAboveR8110", "true");
}
auto i_agent_details = Singleton::Consume<I_AgentDetails>::by<OrchestrationComp>();
if (
i_agent_details->getOrchestrationMode() == OrchestrationMode::HYBRID ||
getSettingWithDefault<string>("management", "profileManagedMode") == "declarative"
) {
agent_data_report << AgentReportFieldWithLabel("managedMode", "declarative");
} else {
agent_data_report << AgentReportFieldWithLabel("managedMode", "management");
}
#if defined(gaia) || defined(smb)
if (i_details_resolver->compareCheckpointVersion(8100, greater_equal<int>())) {
agent_data_report << AgentReportFieldWithLabel("isCheckpointVersionGER81", "true");
@ -1584,7 +1584,9 @@ private:
while (true) {
static int failure_count = 0;
Singleton::Consume<I_Environment>::by<OrchestrationComp>()->startNewTrace(false);
reportAgentDetailsMetaData();
if (shouldReportAgentDetailsMetadata()) {
reportAgentDetailsMetaData();
}
auto check_update_result = checkUpdate();
if (!check_update_result.ok()) {
failure_count++;
@ -1900,6 +1902,32 @@ private:
}
}
bool
shouldReportAgentDetailsMetadata()
{
bool should_report_agent_details_metadata = true;
#if defined(gaia) || defined(smb)
auto i_shell_cmd = Singleton::Consume<I_ShellCmd>::by<OrchestrationComp>();
auto result = i_shell_cmd->getExecOutput("stat -c %Y $FWDIR/state/local/FW1");
if (!result.ok()) return should_report_agent_details_metadata;
string current_update_time = result.unpack();
fw_last_update_time = fw_last_update_time.empty() ? current_update_time : fw_last_update_time;
try {
bool is_fw_dir_changed = stoi(current_update_time) > stoi(fw_last_update_time);
if (!is_fw_dir_changed) {
should_report_agent_details_metadata = false;
} else {
fw_last_update_time = current_update_time;
}
} catch (const exception& err) {
dbgWarning(D_ORCHESTRATOR)
<< "Failed to check if access policy was recently updated , Error:"
<< err.what();
}
#endif // gaia || smb
return should_report_agent_details_metadata;
}
class AddProxyRest : public ServerRest
{
public:
@ -1976,6 +2004,9 @@ OrchestrationComp::preload()
registerExpectedSetting<vector<string>>("orchestration", "Orchestration status ignored policies");
registerExpectedSetting<string>("agentType");
registerExpectedSetting<string>("upgradeMode");
registerExpectedSetting<string>("upgradeTime");
registerExpectedSetting<uint>("upgradeDurationHours");
registerExpectedSetting<vector<string>>("upgradeDay");
registerExpectedSetting<string>("email-address");
registerExpectedSetting<string>("registered-server");
registerExpectedConfigFile("orchestration", Config::ConfigFileType::Policy);

View File

@ -18,6 +18,7 @@
#include "cereal/external/rapidjson/document.h"
#include "cereal/types/vector.hpp"
#include "cereal/types/set.hpp"
#include "agent_core_utilities.h"
#include <netdb.h>
#include <arpa/inet.h>
@ -27,6 +28,12 @@ using namespace std;
using namespace rapidjson;
static const string base64_base_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const string ls_prefix = "ls ";
static const string extract_tenant_profile_suffix =
"| grep tenant "
"| cut -d '_' -f 2,4 "
"| sort --unique "
"| awk -F '_' '{ printf \"%s %s \",$1,$2 }'";
class OrchestrationTools::Impl : Singleton::Provide<I_OrchestrationTools>::From<OrchestrationTools>
{
@ -50,6 +57,12 @@ public:
bool doesDirectoryExist(const string &dir_path) const override;
bool executeCmd(const string &cmd) const override;
bool isNonEmptyFile(const string &path) const override;
void loadTenantsFromDir(const string &dir_path) const override;
bool removeDirectory(const string &path, bool delete_content) const override;
void deleteVirtualTenantProfileFiles(
const std::string &tenant_id,
const std::string &profile_id,
const std::string &conf_path) const override;
Maybe<string> calculateChecksum(Package::ChecksumTypes checksum_type, const string &path) const override;
@ -206,6 +219,64 @@ OrchestrationTools::Impl::removeFile(const string &path) const
return true;
}
bool
OrchestrationTools::Impl::removeDirectory(const string &path, bool delete_content) const
{
if (!NGEN::Filesystem::deleteDirectory(path, delete_content)) {
dbgDebug(D_ORCHESTRATOR) << "Deletion of the folder at path " << path << " failed.";
return false;
}
dbgDebug(D_ORCHESTRATOR) << "Successfully deleted folder at path " << path;
return true;
}
void
OrchestrationTools::Impl::deleteVirtualTenantProfileFiles(
const string &tenant_id,
const string &profile_id,
const string &conf_path) const
{
string tenant_and_profile_suffix = "tenant_" + tenant_id + "_profile_" + profile_id;
string virtual_policy_dir = conf_path + "/" + tenant_and_profile_suffix;
if (!removeDirectory(virtual_policy_dir, true)) {
dbgWarning(D_ORCHESTRATOR) << "Failed to delete virtual policy folder : " << virtual_policy_dir;
} else {
dbgDebug(D_ORCHESTRATOR) << "Virtual policy folder " << virtual_policy_dir << " deleted successfully.";
}
string settings_file_path = virtual_policy_dir + "_settings.json";
if (!removeFile(settings_file_path)) {
dbgWarning(D_ORCHESTRATOR) << "Failed to delete virtual policy settings file : " << settings_file_path;
} else {
dbgDebug(D_ORCHESTRATOR) << "Virtual policy settings file " << settings_file_path << " deleted successfully.";
}
}
void
OrchestrationTools::Impl::loadTenantsFromDir(const string &dir_path) const
{
dbgTrace(D_ORCHESTRATOR) << "Load existing tenants and profiles from the configuration folder";
string shell_cmd_string = ls_prefix + dir_path + extract_tenant_profile_suffix;
auto shell = Singleton::Consume<I_ShellCmd>::by<OrchestrationTools>();
Maybe<string> output_res = shell->getExecOutput(shell_cmd_string);
if (!output_res.ok()) {
dbgWarning(D_ORCHESTRATOR)
<< "Failed to load existing tenants from configuration folder: " + output_res.getErr();
return;
}
auto tenant_manager = Singleton::Consume<I_TenantManager>::by<OrchestrationTools>();
stringstream ss(output_res.unpack());
string tenant_id;
string profile_id;
while (!ss.eof() && getline(ss, tenant_id, ' ') && !ss.eof() && getline(ss, profile_id, ' ')) {
dbgTrace(D_ORCHESTRATOR) << "Add existing tenant_" + tenant_id + "_profile_" + profile_id;
tenant_manager->addActiveTenantAndProfile(tenant_id, profile_id);
}
}
Maybe<string>
OrchestrationTools::Impl::calculateChecksum(Package::ChecksumTypes checksum_type, const string &path) const
{

View File

@ -1,6 +1,8 @@
#include "orchestration_tools.h"
#include "cptest.h"
#include "mock/mock_tenant_manager.h"
#include "mock/mock_shell_cmd.h"
using namespace std;
using namespace testing;
@ -17,9 +19,6 @@ public:
{
str.erase(remove(str.begin(), str.end(), ' '), str.end());
}
OrchestrationTools orchestration_tools;
I_OrchestrationTools *i_orchestration_tools = Singleton::Consume<I_OrchestrationTools>::from(orchestration_tools);
string manifest_file = "manifest.json";
string manifest_text = "{"
" \"packages\": ["
@ -45,6 +44,11 @@ public:
" }"
" ]"
"}";
OrchestrationTools orchestration_tools;
I_OrchestrationTools *i_orchestration_tools = Singleton::Consume<I_OrchestrationTools>::from(orchestration_tools);
StrictMock<MockTenantManager> mock_tenant_manager;
StrictMock<MockShellCmd> mock_shell_cmd;
};
TEST_F(OrchestrationToolsTest, doNothing)
@ -241,6 +245,97 @@ TEST_F(OrchestrationToolsTest, createDirectory)
EXPECT_TRUE(i_orchestration_tools->createDirectory(path));
}
TEST_F(OrchestrationToolsTest, removeDirectory)
{
string dir_path = "/tmp/temp_dir2";
EXPECT_TRUE(i_orchestration_tools->createDirectory(dir_path));
EXPECT_TRUE(i_orchestration_tools->doesDirectoryExist(dir_path));
stringstream string_stream;
string_stream << "blah blah blah";
string file_path = dir_path + "/packages.json";
i_orchestration_tools->writeFile(string_stream.str(), file_path);
EXPECT_TRUE(i_orchestration_tools->doesFileExist(file_path));
EXPECT_FALSE(i_orchestration_tools->removeDirectory(dir_path, false));
EXPECT_TRUE(i_orchestration_tools->doesFileExist(file_path));
EXPECT_TRUE(i_orchestration_tools->removeDirectory(dir_path, true));
EXPECT_FALSE(i_orchestration_tools->doesFileExist(file_path));
EXPECT_FALSE(i_orchestration_tools->doesDirectoryExist(dir_path));
}
TEST_F(OrchestrationToolsTest, deleteVirtualTenantFiles)
{
stringstream string_stream;
string_stream << "policy policy policy";
string conf_path = "/tmp/temp_conf";
EXPECT_TRUE(i_orchestration_tools->createDirectory(conf_path));
string policy_folder_path = conf_path + "/tenant_3fdbdd33_profile_c4c498d8";
string policy_file_path = policy_folder_path + "/policy.json";
EXPECT_TRUE(i_orchestration_tools->createDirectory(policy_folder_path));
string settings_file_path = conf_path + "/tenant_3fdbdd33_profile_c4c498d8_settings.json";
i_orchestration_tools->writeFile(string_stream.str(), settings_file_path);
i_orchestration_tools->writeFile(string_stream.str(), policy_file_path);
EXPECT_TRUE(i_orchestration_tools->doesFileExist(settings_file_path));
EXPECT_TRUE(i_orchestration_tools->doesFileExist(policy_file_path));
i_orchestration_tools->deleteVirtualTenantProfileFiles("3fdbdd33", "c4c498d8", conf_path);
EXPECT_FALSE(i_orchestration_tools->doesFileExist(settings_file_path));
EXPECT_FALSE(i_orchestration_tools->doesFileExist(policy_file_path));
}
TEST_F(OrchestrationToolsTest, loadTenants)
{
stringstream string_stream;
string_stream << "policy policy policy";
string conf_path = "/tmp/temp_conf";
EXPECT_TRUE(i_orchestration_tools->createDirectory(conf_path));
string policy_folder_path1 = conf_path + "/tenant_3fdbdd33_profile_c4c498d8";
EXPECT_TRUE(i_orchestration_tools->createDirectory(policy_folder_path1));
string policy_folder_path2 = conf_path + "/tenant_123456_profile_654321";
EXPECT_TRUE(i_orchestration_tools->createDirectory(policy_folder_path2));
string settings_file_path1 = conf_path + "/tenant_3fdbdd33_profile_c4c498d8_settings.json";
i_orchestration_tools->writeFile(string_stream.str(), settings_file_path1);
string settings_file_path2 = conf_path + "/tenant_123456_profile_654321_settings.json";
i_orchestration_tools->writeFile(string_stream.str(), settings_file_path2);
string policy_file_path1 = policy_folder_path1 + "/policy.json";
i_orchestration_tools->writeFile(string_stream.str(), policy_file_path1);
string policy_file_path2 = policy_folder_path2 + "/policy.json";
i_orchestration_tools->writeFile(string_stream.str(), policy_file_path2);
EXPECT_TRUE(i_orchestration_tools->doesFileExist(settings_file_path1));
EXPECT_TRUE(i_orchestration_tools->doesFileExist(settings_file_path2));
EXPECT_TRUE(i_orchestration_tools->doesFileExist(policy_file_path1));
EXPECT_TRUE(i_orchestration_tools->doesFileExist(policy_file_path2));
EXPECT_CALL(
mock_shell_cmd,
getExecOutput(
"ls /tmp/temp_conf| grep tenant "
"| cut -d '_' -f 2,4 | sort --unique "
"| awk -F '_' '{ printf \"%s %s \",$1,$2 }'",
200,
false
)
).WillOnce(Return(string("3fdbdd33 c4c498d8 123456 654321")));
EXPECT_CALL(mock_tenant_manager, addActiveTenantAndProfile("3fdbdd33", "c4c498d8")).Times(1);
EXPECT_CALL(mock_tenant_manager, addActiveTenantAndProfile("123456", "654321")).Times(1);
i_orchestration_tools->loadTenantsFromDir(conf_path);
i_orchestration_tools->deleteVirtualTenantProfileFiles("3fdbdd33", "c4c498d8", conf_path);
EXPECT_FALSE(i_orchestration_tools->doesFileExist(settings_file_path1));
EXPECT_FALSE(i_orchestration_tools->doesFileExist(policy_file_path1));
}
TEST_F(OrchestrationToolsTest, base64DecodeEncode)
{
string clear_text = "{\n"

View File

@ -74,17 +74,7 @@ public:
).WillOnce(Return(true));
doEncrypt();
EXPECT_CALL(
mock_shell_cmd,
getExecOutput(
"ls /etc/cp/conf/"
"| grep tenant "
"| cut -d '_' -f 2,4 "
"| sort --unique "
"| awk -F '_' '{ printf \"%s %s \",$1,$2 }'",
_,
_
)).WillOnce(Return(Maybe<string>(string(""))));
EXPECT_CALL(mock_orchestration_tools, loadTenantsFromDir(_)).Times(1);
orchestration_comp.init();
}
@ -446,7 +436,7 @@ TEST_F(OrchestrationMultitenancyTest, handle_virtual_resource)
"",
false
)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(
mock_service_controller,
@ -458,7 +448,7 @@ TEST_F(OrchestrationMultitenancyTest, handle_virtual_resource)
"2611",
false
)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(
mock_service_controller,
@ -470,7 +460,7 @@ TEST_F(OrchestrationMultitenancyTest, handle_virtual_resource)
"2311",
true
)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(mock_ml, yield(A<chrono::microseconds>()))
.WillOnce(
@ -494,12 +484,10 @@ TEST_F(OrchestrationMultitenancyTest, handle_virtual_resource)
mock_shell_cmd,
getExecOutput(_, _, _)
).WillRepeatedly(Return(string("daniel\n1\n")));
EXPECT_CALL(mock_orchestration_tools, deleteVirtualTenantProfileFiles("321321", "123123", "/etc/cp/conf/"))
.Times(1);
try {
runRoutine();
} catch (const invalid_argument& e) {}
string debug_str_folder = "Delete virtual policy folder : /etc/cp/conf/tenant_321321_profile_123123";
string debug_str_settings = "Delete settings file /etc/cp/conf/tenant_321321_profile_123123_settings.json";
EXPECT_THAT(debug_output.str(), HasSubstr(debug_str_folder));
EXPECT_THAT(debug_output.str(), HasSubstr(debug_str_settings));
Debug::setNewDefaultStdout(&cout);
}

View File

@ -94,17 +94,7 @@ public:
)).WillRepeatedly(DoAll(SaveArg<1>(&message_body), Return(Maybe<string>(string("")))));
doEncrypt();
EXPECT_CALL(
mock_shell_cmd,
getExecOutput(
"ls /etc/cp/conf/"
"| grep tenant "
"| cut -d '_' -f 2,4 "
"| sort --unique "
"| awk -F '_' '{ printf \"%s %s \",$1,$2 }'",
_,
_
)).WillOnce(Return(Maybe<string>(string(""))));
EXPECT_CALL(mock_orchestration_tools, loadTenantsFromDir(_)).Times(1);
orchestration_comp.init();
}
@ -511,7 +501,8 @@ TEST_F(OrchestrationTest, check_sending_registration_data)
)
);
EXPECT_CALL(mock_orchestration_tools, readFile(_)).WillOnce(Return(response));
EXPECT_CALL(mock_service_controller, updateServiceConfiguration(_, _, _, _, _, _)).WillOnce(Return(true));
EXPECT_CALL(mock_service_controller, updateServiceConfiguration(_, _, _, _, _, _))
.WillOnce(Return(Maybe<void>()));
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));
@ -666,9 +657,12 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdatRollback)
);
EXPECT_CALL(mock_status, setPolicyVersion(third_val));
EXPECT_CALL(mock_status, setPolicyVersion(second_val));
EXPECT_CALL(mock_update_communication, sendPolicyVersion("13")).Times(1).WillOnce(Return(Maybe<void>()));
string policy_versions;
EXPECT_CALL(mock_service_controller, getPolicyVersions()).WillRepeatedly(ReturnRef(policy_versions));
EXPECT_CALL(mock_update_communication, sendPolicyVersion("13", _)).Times(1).WillOnce(Return(Maybe<void>()));
// Rollback related test: The old policy version 12 is restored
EXPECT_CALL(mock_update_communication, sendPolicyVersion("12")).Times(1).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(mock_update_communication, sendPolicyVersion("12", _)).Times(1).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(mock_update_communication, getUpdate(_)).WillOnce(
Invoke(
@ -694,12 +688,12 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdatRollback)
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(policy_file_path, setting_file_path, expected_data_types, "", "", _)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(new_policy_path, "", expected_data_types, "", "", _)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(
mock_message,
@ -751,7 +745,7 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdatRollback)
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(policy_file_path_bk, _, _, _, _, _)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(
mock_orchestration_tools,
@ -858,7 +852,10 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdate)
.WillOnce(ReturnRef(third_val)
);
EXPECT_CALL(mock_status, setPolicyVersion(third_val));
EXPECT_CALL(mock_update_communication, sendPolicyVersion("13")).Times(1).WillOnce(Return(Maybe<void>()));
string policy_versions;
EXPECT_CALL(mock_service_controller, getPolicyVersions()).WillRepeatedly(ReturnRef(policy_versions));
EXPECT_CALL(mock_update_communication, sendPolicyVersion("13", _)).Times(1).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(mock_update_communication, getUpdate(_)).WillOnce(
Invoke(
@ -884,12 +881,12 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdate)
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(policy_file_path, setting_file_path, expected_data_types, "", "", _)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(new_policy_path, "", expected_data_types, "", "", _)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(
mock_message,
@ -988,7 +985,7 @@ TEST_F(OrchestrationTest, startOrchestrationPoliceWithFailures)
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(policy_file_path, setting_file_path, expected_data_types, "", "", _)
).Times(2).WillRepeatedly(Return(true));
).Times(2).WillRepeatedly(Return(Maybe<void>()));
EXPECT_CALL(mock_message, setActiveFog(host_address, 443, true, MessageTypeTag::GENERIC)).WillOnce(Return(true));
EXPECT_CALL(mock_update_communication, setAddressExtenesion(""));
@ -1108,7 +1105,7 @@ TEST_F(OrchestrationTest, loadOrchestrationPolicyFromBackup)
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(policy_file_path, setting_file_path, expected_data_types, "", "", _)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path))
@ -1242,7 +1239,7 @@ TEST_F(OrchestrationTest, manifestUpdate)
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(policy_file_path, setting_file_path, expected_data_types, "", "", _)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path)).WillOnce(Return(response));
@ -1394,7 +1391,7 @@ TEST_F(OrchestrationTest, getBadPolicyUpdate)
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(policy_file_path, setting_file_path, expected_data_types, "", "", _)
).Times(2).WillRepeatedly(Return(true));
).Times(2).WillRepeatedly(Return(Maybe<void>()));
set<string> expected_changed_policies = {};
EXPECT_CALL(mock_service_controller, mockMoveChangedPolicies()).WillOnce(Return(expected_changed_policies));
@ -1478,7 +1475,7 @@ TEST_F(OrchestrationTest, getBadPolicyUpdate)
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(string("policy path"), "", expected_data_types, "", "", _)
).WillOnce(Return(false));
).WillOnce(Return(Maybe<void>(genError(string("")))));
EXPECT_CALL(mock_ml, yield(A<chrono::microseconds>()))
.WillOnce(
@ -1544,7 +1541,7 @@ TEST_F(OrchestrationTest, failedDownloadSettings)
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(policy_file_path, setting_file_path, expected_data_types, "", "", _)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path)).WillOnce(Return(response));
@ -1754,7 +1751,7 @@ TEST_P(OrchestrationTest, orchestrationFirstRun)
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(policy_file_path, setting_file_path, expected_data_types, "", "", _)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(mock_ml, yield(A<chrono::microseconds>()))
.WillOnce(
@ -1936,13 +1933,13 @@ TEST_F(OrchestrationTest, dataUpdate)
ExpectationSet expectation_set = EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration(policy_file_path, setting_file_path, expected_empty_data_types, "", "", _)
).WillOnce(Return(true));
).WillOnce(Return(Maybe<void>()));
vector<string> expected_ips_data_types = { "ips" };
EXPECT_CALL(
mock_service_controller,
updateServiceConfiguration("", "", expected_ips_data_types, "", "", _)
).After(expectation_set).WillOnce(Return(true));
).After(expectation_set).WillOnce(Return(Maybe<void>()));
EXPECT_CALL(mock_orchestration_tools, doesDirectoryExist("/etc/cp/conf/data")).WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path)).WillOnce(Return(policy_response));

View File

@ -269,13 +269,13 @@ class ServiceController::Impl
public:
void init();
bool
Maybe<void>
updateServiceConfiguration(
const string &new_policy_path,
const string &new_settings_path,
const vector<string> &new_data_files,
const string &tenant_id,
const string &profile_id,
const string &child_tenant_id,
const string &child_profile_id,
const bool last_iteration
) override;
@ -291,6 +291,7 @@ public:
void refreshPendingServices() override;
const string & getPolicyVersion() const override;
const string & getUpdatePolicyVersion() const override;
const string & getPolicyVersions() const override;
void updateReconfStatus(int id, ReconfStatus status) override;
void startReconfStatus(
int id,
@ -308,9 +309,11 @@ public:
private:
void cleanUpVirtualFiles();
bool sendSignalForServices(const set<string> &nano_services_to_update, const string &policy_version);
Maybe<void> sendSignalForServices(
const set<string> &nano_services_to_update,
const string &policy_version_to_update);
bool updateServiceConfigurationFile(
Maybe<void> updateServiceConfigurationFile(
const string &configuration_name,
const string &configuration_file_path,
const string &new_configuration_path);
@ -326,10 +329,12 @@ private:
void writeRegisteredServicesToFile();
bool backupConfigurationFile(const string &configuration_file_path);
bool createDirectoryForChildTenant(const string &child_tenant_id, const string &child_profile_id) const;
int configuration_id = 0;
map<string, ServiceDetails> registered_services;
map<string, ServiceDetails> pending_services;
string policy_versions;
string policy_version;
string update_policy_version;
string settings_path;
@ -657,14 +662,45 @@ ServiceController::Impl::backupConfigurationFile(const string &config_file_path)
}
bool
ServiceController::Impl::createDirectoryForChildTenant(
const string &child_tenant_id,
const string &child_profile_id) const
{
if (child_tenant_id == "") return true;
auto orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<ServiceController>();
string dir = getConfigurationWithDefault<string>(
filesystem_prefix + "/conf",
"orchestration",
"Configuration directory"
);
dir = dir + "/tenant_" + child_tenant_id + "_profile_" + child_profile_id;
if (orchestration_tools->doesDirectoryExist(dir)) return true;
if (!orchestration_tools->createDirectory(dir)) {
dbgError(D_ORCHESTRATOR)
<< "Failed to create configuration directory for tenant "
<< child_tenant_id;
return false;
}
dbgTrace(D_ORCHESTRATOR) << "Created new configuration directory for tenant " << child_tenant_id;
return true;
}
Maybe<void>
ServiceController::Impl::updateServiceConfiguration(
const string &new_policy_path,
const string &new_settings_path,
const vector<string> &new_data_files,
const string &tenant_id,
const string &profile_id,
const string &child_tenant_id,
const string &child_profile_id,
const bool last_iteration)
{
string tenant_and_profile_ids = "";
if (!child_tenant_id.empty()) {
tenant_and_profile_ids = " Child tenant id: " + child_tenant_id + ", Child profile id: " + child_profile_id;
}
dbgFlow(D_ORCHESTRATOR)
<< "new_policy_path: "
<< new_policy_path
@ -672,10 +708,8 @@ ServiceController::Impl::updateServiceConfiguration(
<< new_settings_path
<< ", new_data_files: "
<< makeSeparatedStr(new_data_files, ",")
<< ". tenant_id: "
<< tenant_id
<< ". profile_id: "
<< profile_id;
<< "."
<< tenant_and_profile_ids;
if (!new_settings_path.empty()) {
settings_path = new_settings_path;
@ -704,8 +738,9 @@ ServiceController::Impl::updateServiceConfiguration(
if (new_policy_path == "") {
dbgDebug(D_ORCHESTRATOR) << "Policy file was not updated. Sending reload command regarding settings and data";
return sendSignalForServices(nano_services_to_update, "");
auto signal_services = sendSignalForServices(nano_services_to_update, "");
if (!signal_services.ok()) return signal_services.passErr();
return Maybe<void>();
}
Maybe<string> loaded_policy_json = orchestration_tools->readFile(new_policy_path);
@ -716,14 +751,13 @@ ServiceController::Impl::updateServiceConfiguration(
<< ". Error: "
<< loaded_policy_json.getErr();
return false;
return genError("Failed to load new file: " + new_policy_path + ". Error: " + loaded_policy_json.getErr());
}
auto all_security_policies = orchestration_tools->jsonObjectSplitter(
loaded_policy_json.unpack(),
tenant_id,
profile_id
child_tenant_id,
child_profile_id
);
if (!all_security_policies.ok()) {
@ -733,12 +767,18 @@ ServiceController::Impl::updateServiceConfiguration(
<< ". Error: "
<< all_security_policies.getErr();
return false;
return genError("Failed to parse json file: " +
new_policy_path +
". Error: " +
all_security_policies.getErr()
);
}
bool was_policy_updated = true;
const string version_param = "version";
const string versions_param = "versions";
string version_value;
string send_signal_for_services_err;
for (auto &single_policy : all_security_policies.unpack()) {
if (single_policy.first == version_param) {
@ -747,33 +787,27 @@ ServiceController::Impl::updateServiceConfiguration(
update_policy_version = version_value;
continue;
}
if (child_tenant_id.empty() && single_policy.first == versions_param) {
//In a multi-tenant env, only the parent should handle the versions parameter
policy_versions = single_policy.second;
dbgWarning(D_ORCHESTRATOR) << "Found versions parameter in policy file:" << policy_versions;
}
dbgDebug(D_ORCHESTRATOR) << "Starting to update policy file. Policy type: " << single_policy.first;
string dir = getConfigurationWithDefault<string>(
filesystem_prefix + "/conf",
"orchestration",
"Configuration directory"
);
if (tenant_id != "") {
dir = dir + "/tenant_" + tenant_id + "_profile_" + profile_id;
if (!orchestration_tools->doesDirectoryExist(dir)) {
if (orchestration_tools->createDirectory(dir)) {
dbgTrace(D_ORCHESTRATOR) << "Created new configuration directory for tenant " << tenant_id;
} else {
dbgError(D_ORCHESTRATOR) << "Failed to create configuration directory for tenant "<< tenant_id;
return false;
}
}
if (!createDirectoryForChildTenant(child_tenant_id, child_profile_id)) {
dbgWarning(D_ORCHESTRATOR)
<< "Failed to create directory for child. Tenant id: " << child_tenant_id
<< ", Profile id: " << child_profile_id;
return genError("Failed to create directory for child tenant");
}
string policy_file_path =
getPolicyConfigPath(
single_policy.first,
Config::ConfigFileType::Policy,
tenant_id,
profile_id
child_tenant_id,
child_profile_id
);
auto update_config_result = updateServiceConfigurationFile(
@ -782,8 +816,11 @@ ServiceController::Impl::updateServiceConfiguration(
single_policy.second
);
if (!update_config_result) {
dbgWarning(D_ORCHESTRATOR) << "Failed to update policy file. Policy name: " << single_policy.first;
if (!update_config_result.ok()) {
send_signal_for_services_err = "Failed to update policy file. Policy name: " +
single_policy.first +
". Error: " +
update_config_result.getErr();
was_policy_updated = false;
continue;
}
@ -798,10 +835,10 @@ ServiceController::Impl::updateServiceConfiguration(
OrchestrationStatusConfigType::POLICY
);
if (tenant_id != "") {
if (child_tenant_id != "") {
auto instances = Singleton::Consume<I_TenantManager>::by<ServiceController>()->getInstances(
tenant_id,
profile_id
child_tenant_id,
child_profile_id
);
for (const auto &instance_id: instances) {
auto relevant_service = registered_services.find(instance_id);
@ -823,18 +860,20 @@ ServiceController::Impl::updateServiceConfiguration(
}
// In a multi-tenant env, we send the signal to the services only on the last iteration
was_policy_updated &= (is_multi_tenant_env && !last_iteration) ?
true :
sendSignalForServices(nano_services_to_update, version_value);
if (!is_multi_tenant_env || last_iteration) {
auto is_send_signal_for_services = sendSignalForServices(nano_services_to_update, version_value);
was_policy_updated &= is_send_signal_for_services.ok();
if (!is_send_signal_for_services.ok()) send_signal_for_services_err = is_send_signal_for_services.getErr();
}
dbgTrace(D_ORCHESTRATOR) << "was policy updated: " << (was_policy_updated ? "true" : "false");
if (was_policy_updated) {
string config_file_path;
string base_path =
filesystem_prefix + "/conf/" +
(tenant_id != "" ? "tenant_" + tenant_id + "_profile_" + profile_id + "/" : "");
config_file_path = getConfigurationWithDefault<string>(
(child_tenant_id != "" ? "tenant_" + child_tenant_id + "_profile_" + child_profile_id + "/" : "");
string config_file_path = getConfigurationWithDefault<string>(
base_path + "policy.json",
"orchestration",
"Policy file path"
@ -843,12 +882,12 @@ ServiceController::Impl::updateServiceConfiguration(
if (new_policy_path.compare(config_file_path) == 0) {
dbgDebug(D_ORCHESTRATOR) << "Enforcing the default policy file";
policy_version = version_value;
return true;
return Maybe<void>();
}
if (!backupConfigurationFile(config_file_path)) {
dbgWarning(D_ORCHESTRATOR) << "Failed to backup the policy file.";
return false;
return genError("Failed to backup the policy file.");
}
policy_version = version_value;
@ -856,17 +895,18 @@ ServiceController::Impl::updateServiceConfiguration(
// Save the new configuration file.
if (!orchestration_tools->copyFile(new_policy_path, config_file_path)) {
dbgWarning(D_ORCHESTRATOR) << "Failed to save the policy file.";
return false;
return genError("Failed to save the policy file.");
}
}
return was_policy_updated;
if (!was_policy_updated && !send_signal_for_services_err.empty()) return genError(send_signal_for_services_err);
return Maybe<void>();
}
bool
Maybe<void>
ServiceController::Impl::sendSignalForServices(
const set<string> &nano_services_to_update,
const string &policy_version)
const string &policy_version_to_update)
{
dbgFlow(D_ORCHESTRATOR);
for (auto &service_id : nano_services_to_update) {
@ -877,7 +917,7 @@ ServiceController::Impl::sendSignalForServices(
}
++configuration_id;
auto reconf_status = nano_service->second.sendNewConfigurations(configuration_id, policy_version);
auto reconf_status = nano_service->second.sendNewConfigurations(configuration_id, policy_version_to_update);
if (reconf_status == ReconfStatus::INACTIVE) {
dbgWarning(D_ORCHESTRATOR) << "Erasing details regarding inactive service " << service_id;
@ -889,7 +929,7 @@ ServiceController::Impl::sendSignalForServices(
dbgDebug(D_ORCHESTRATOR) << "The reconfiguration failed for serivce: " << service_id;
services_reconf_status.clear();
services_reconf_names.clear();
return false;
return genError("The reconfiguration failed for serivce: " + service_id);
}
}
@ -910,7 +950,7 @@ ServiceController::Impl::sendSignalForServices(
dbgDebug(D_ORCHESTRATOR) << "The reconfiguration was successfully completed for all the services";
services_reconf_status.clear();
services_reconf_names.clear();
return true;
return Maybe<void>();
}
case ReconfStatus::IN_PROGRESS: {
dbgTrace(D_ORCHESTRATOR) << "Reconfiguration in progress...";
@ -918,8 +958,10 @@ ServiceController::Impl::sendSignalForServices(
break;
}
case ReconfStatus::FAILED: {
vector<string> failed_services_vec;
for(auto &status : services_reconf_status) {
if (status.second == ReconfStatus::FAILED) {
failed_services_vec.push_back(services_reconf_names[status.first]);
dbgDebug(D_ORCHESTRATOR)
<< "The reconfiguration failed for serivce "
<< services_reconf_names[status.first];
@ -927,13 +969,16 @@ ServiceController::Impl::sendSignalForServices(
}
services_reconf_status.clear();
services_reconf_names.clear();
return false;
string failed_services = makeSeparatedStr(failed_services_vec, ", ");
return genError("The reconfiguration failed for serivces: " + failed_services);
}
case ReconfStatus::INACTIVE: {
dbgError(D_ORCHESTRATOR) << "Reached inactive state in the middle of reconfiguration!";
services_reconf_status.clear();
services_reconf_names.clear();
return false;
return genError("Reached inactive state in the middle of reconfiguration!");
}
}
}
@ -941,10 +986,10 @@ ServiceController::Impl::sendSignalForServices(
dbgDebug(D_ORCHESTRATOR) << "The reconfiguration has reached a timeout";
services_reconf_status.clear();
services_reconf_names.clear();
return false;
return genError("The reconfiguration has reached a timeout");
}
bool
Maybe<void>
ServiceController::Impl::updateServiceConfigurationFile(
const string &configuration_name,
const string &configuration_file_path,
@ -959,7 +1004,7 @@ ServiceController::Impl::updateServiceConfigurationFile(
bool service_changed = old_configuration.unpack().compare(new_configuration_path) != 0;
if (service_changed == false) {
dbgDebug(D_ORCHESTRATOR) << "There is no update for policy file: " << configuration_file_path;
return true;
return Maybe<void>();
}
dbgDebug(D_ORCHESTRATOR)
<< "Starting to update " << configuration_file_path << " to " << new_configuration_path;
@ -972,7 +1017,7 @@ ServiceController::Impl::updateServiceConfigurationFile(
dbgDebug(D_ORCHESTRATOR) << "Backup of policy file has been created in: " << configuration_file_path;
} else {
dbgWarning(D_ORCHESTRATOR) << "Failed to backup policy file";
return false;
return genError("Failed to backup policy file");
}
} else {
dbgWarning(D_ORCHESTRATOR)
@ -981,7 +1026,12 @@ ServiceController::Impl::updateServiceConfigurationFile(
<< ". Error: "
<< old_configuration.getErr();
return false;
return genError(
"Failed to read current policy file " +
configuration_file_path +
". Error: " +
old_configuration.getErr()
);
}
}
@ -989,12 +1039,12 @@ ServiceController::Impl::updateServiceConfigurationFile(
dbgDebug(D_ORCHESTRATOR) << "New policy file has been saved in: " << configuration_file_path;
} else {
dbgWarning(D_ORCHESTRATOR) << "Failed to save new policy file";
return false;
return genError("Failed to save new policy file");
}
dbgInfo(D_ORCHESTRATOR) << "Successfully updated policy file: " << configuration_file_path;
return true;
return Maybe<void>();
}
ServiceController::ServiceController() : Component("ServiceController"), pimpl(make_unique<Impl>()) {}
@ -1013,6 +1063,12 @@ ServiceController::Impl::getPolicyVersion() const
return policy_version;
}
const string &
ServiceController::Impl::getPolicyVersions() const
{
return policy_versions;
}
const string &
ServiceController::Impl::getUpdatePolicyVersion() const
{

View File

@ -251,6 +251,7 @@ TEST_F(ServiceControllerTest, UpdateConfiguration)
setServiceConfiguration("l4_firewall", l4_firewall_policy_path, OrchestrationStatusConfigType::POLICY));
EXPECT_EQ(i_service_controller->getPolicyVersion(), "");
EXPECT_EQ(i_service_controller->getPolicyVersions(), "");
EXPECT_CALL(mock_orchestration_tools, copyFile(policy_file_path, policy_file_path + backup_extension))
.WillOnce(Return(true));
@ -288,8 +289,123 @@ TEST_F(ServiceControllerTest, UpdateConfiguration)
)
).WillRepeatedly(Return(string("registered and running")));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path).ok());
EXPECT_EQ(i_service_controller->getPolicyVersion(), version_value);
EXPECT_EQ(i_service_controller->getPolicyVersions(), "");
EXPECT_EQ(i_service_controller->getUpdatePolicyVersion(), version_value);
}
TEST_F(ServiceControllerTest, supportVersions)
{
string versions = "["
" {"
" \"id\" : \"40c4a460-eb24-f002-decb-f4a7f00423fc\","
" \"name\" : \"Linux Embedded Agents\","
" \"version\" : 1"
" },"
" {"
" \"id\" : \"93788960-6969-11ee-be56-0242ac120002\","
" \"name\" : \"Linux SUPER Embedded Agents\","
" \"version\" : 420"
" }"
"]";
string new_configuration = "{"
" \"version\": \"" + version_value + "\""
" \"versions\": " + versions +
" \"l4_firewall\":"
" {"
" \"app\": \"netfilter\","
" \"l4_firewall_rules\": ["
" {"
" \"name\": \"allow_statefull_conns\","
" \"flags\": [\"established\"],"
" \"action\": \"accept\""
" },"
" {"
" \"name\": \"icmp drop\","
" \"flags\": [\"log\"],"
" \"services\": [{\"name\":\"icmp\"}],"
" \"action\": \"drop\""
" }"
" ]"
" }"
"}";
string l4_firewall = "{"
" \"app\": \"netfilter\","
" \"l4_firewall_rules\": ["
" {"
" \"name\": \"allow_statefull_conns\","
" \"flags\": [\"established\"],"
" \"action\": \"accept\""
" },"
" {"
" \"name\": \"icmp drop\","
" \"flags\": [\"log\"],"
" \"services\": [{\"name\":\"icmp\"}],"
" \"action\": \"drop\""
" }"
" ]"
"}";
string policy_versions_path = "/etc/cp/conf/versions/versions.policy";
Maybe<map<string, string>> json_parser_return =
map<string, string>({{"l4_firewall", l4_firewall}, {"version", version_value}, {"versions", versions}});
EXPECT_CALL(mock_orchestration_tools, readFile(file_name)).WillOnce(Return(new_configuration));
EXPECT_CALL(mock_orchestration_tools, jsonObjectSplitter(new_configuration, _, _))
.WillOnce(Return(json_parser_return));
EXPECT_CALL(mock_orchestration_tools, doesFileExist(policy_versions_path)).WillOnce(Return(false));
EXPECT_CALL(mock_orchestration_tools, doesFileExist(l4_firewall_policy_path)).WillOnce(Return(false));
EXPECT_CALL(mock_orchestration_tools, writeFile(l4_firewall, l4_firewall_policy_path)).WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, writeFile(versions, policy_versions_path)).WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_status,
setServiceConfiguration("versions", policy_versions_path, OrchestrationStatusConfigType::POLICY));
EXPECT_CALL(mock_orchestration_status,
setServiceConfiguration("l4_firewall", l4_firewall_policy_path, OrchestrationStatusConfigType::POLICY));
EXPECT_EQ(i_service_controller->getPolicyVersion(), "");
EXPECT_EQ(i_service_controller->getPolicyVersions(), "");
EXPECT_CALL(mock_orchestration_tools, copyFile(policy_file_path, policy_file_path + backup_extension))
.WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, copyFile(file_name, policy_file_path)).WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, doesFileExist(policy_file_path)).WillOnce(Return(true));
string general_settings_path = "/my/settings/path";
string reply_msg = "{\"id\": 1, \"error\": false, \"finished\": true, \"error_message\": \"\"}";
Flags<MessageConnConfig> conn_flags;
conn_flags.setFlag(MessageConnConfig::ONE_TIME_CONN);
EXPECT_CALL(
mock_message,
sendMessage(
true,
"{\n \"id\": 1,\n \"policy_version\": \"1.0.2\"\n}",
I_Messaging::Method::POST,
string("127.0.0.1"),
l4_firewall_service_port,
conn_flags,
string("/set-new-configuration"),
string(),
_,
MessageTypeTag::GENERIC
)
).WillOnce(Return(Maybe<string>(reply_msg)));
EXPECT_CALL(
mock_shell_cmd,
getExecOutput(
"/etc/cp/watchdog/cp-nano-watchdog --status --verbose --service mock access control"
" --family family1 --id id2",
_,
_
)
).WillRepeatedly(Return(string("registered and running")));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path).ok());
EXPECT_EQ(i_service_controller->getPolicyVersion(), version_value);
EXPECT_EQ(i_service_controller->getPolicyVersions(), versions);
EXPECT_EQ(i_service_controller->getUpdatePolicyVersion(), version_value);
}
@ -393,7 +509,7 @@ TEST_F(ServiceControllerTest, TimeOutUpdateConfiguration)
)
).WillOnce(Return(Maybe<string>(reply_msg)));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path).ok());
EXPECT_EQ(i_service_controller->getPolicyVersion(), version_value);
EXPECT_EQ(i_service_controller->getUpdatePolicyVersion(), version_value);
}
@ -501,7 +617,7 @@ TEST_F(ServiceControllerTest, writeRegisteredServicesFromFile)
)
).WillRepeatedly(Return(string("registered and running")));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path).ok());
EXPECT_EQ(i_service_controller->getPolicyVersion(), version_value);
EXPECT_EQ(i_service_controller->getUpdatePolicyVersion(), version_value);
EXPECT_EQ(orchestrationRegisteredServicesFileToString(registered_services_file_path), expected_json);
@ -641,7 +757,7 @@ TEST_F(ServiceControllerTest, noPolicyUpdate)
)
).WillRepeatedly(Return(string("registered and running")));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, ""));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, "").ok());
EXPECT_EQ(i_service_controller->getPolicyVersion(), version_value);
}
@ -734,7 +850,7 @@ TEST_F(ServiceControllerTest, SettingsAndPolicyUpdateCombinations)
).WillOnce(Return(Maybe<string>(reply_msg1)));
// both policy and settings now being updated
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path).ok());
EXPECT_EQ(i_service_controller->getPolicyVersion(), version_value);
EXPECT_EQ(i_service_controller->getUpdatePolicyVersion(), version_value);
@ -771,7 +887,7 @@ TEST_F(ServiceControllerTest, SettingsAndPolicyUpdateCombinations)
)
).WillRepeatedly(Return(Maybe<string>(reply_msg2)));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path).ok());
EXPECT_EQ(i_service_controller->getPolicyVersion(), version_value);
}
@ -884,7 +1000,7 @@ TEST_F(ServiceControllerTest, backup)
).WillOnce(Return(Maybe<string>(reply_msg)));
EXPECT_EQ(i_service_controller->getPolicyVersion(), "");
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, ""));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, "").ok());
EXPECT_EQ(i_service_controller->getPolicyVersion(), version_value);
}
@ -999,7 +1115,7 @@ TEST_F(ServiceControllerTest, backup_file_doesnt_exist)
).WillOnce(Return(Maybe<string>(reply_msg)));
EXPECT_EQ(i_service_controller->getPolicyVersion(), "");
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, ""));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, "").ok());
EXPECT_EQ(i_service_controller->getPolicyVersion(), version_value);
}
@ -1117,7 +1233,7 @@ TEST_F(ServiceControllerTest, backupAttempts)
EXPECT_CALL(mock_orchestration_tools, copyFile(file_name, policy_file_path)).WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, doesFileExist(policy_file_path)).WillOnce(Return(true));
EXPECT_EQ(i_service_controller->getPolicyVersion(), "");
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, ""));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, "").ok());
EXPECT_EQ(i_service_controller->getPolicyVersion(), version_value);
}
@ -1231,7 +1347,7 @@ TEST_F(ServiceControllerTest, MultiUpdateConfiguration)
)
).WillOnce(Return(Maybe<string>(reply_msg)));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, ""));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, "").ok());
set<string> changed_policies = {
"/etc/cp/conf/l4_firewall/l4_firewall.policy",
"/etc/cp/conf/orchestration/orchestration.policy"
@ -1249,7 +1365,7 @@ TEST_F(ServiceControllerTest, badJsonFile)
{
Maybe<string> err = genError("Error");
EXPECT_CALL(mock_orchestration_tools, readFile(file_name)).Times(1).WillRepeatedly(Return(err));
EXPECT_FALSE(i_service_controller->updateServiceConfiguration(file_name, ""));
EXPECT_FALSE(i_service_controller->updateServiceConfiguration(file_name, "").ok());
}
TEST_F(ServiceControllerTest, emptyServices)
@ -1266,7 +1382,7 @@ TEST_F(ServiceControllerTest, emptyServices)
EXPECT_CALL(mock_orchestration_tools, copyFile(file_name, policy_file_path)).WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, doesFileExist(policy_file_path)).WillOnce(Return(true));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, ""));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, "").ok());
}
TEST_F(ServiceControllerTest, failingWhileLoadingCurrentConfiguration)
@ -1317,7 +1433,7 @@ TEST_F(ServiceControllerTest, failingWhileLoadingCurrentConfiguration)
.WillOnce(Return(json_parser_return));
EXPECT_CALL(mock_orchestration_tools, doesFileExist(l4_firewall_policy_path)).WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, readFile(l4_firewall_policy_path)).WillOnce(Return(err));
EXPECT_FALSE(i_service_controller->updateServiceConfiguration(file_name, ""));
EXPECT_FALSE(i_service_controller->updateServiceConfiguration(file_name, "").ok());
}
TEST_F(ServiceControllerTest, failingWhileCopyingCurrentConfiguration)
@ -1392,7 +1508,7 @@ TEST_F(ServiceControllerTest, failingWhileCopyingCurrentConfiguration)
).WillOnce(Return(false));
EXPECT_EQ(i_service_controller->getPolicyVersion(), "");
EXPECT_FALSE(i_service_controller->updateServiceConfiguration(file_name, ""));
EXPECT_FALSE(i_service_controller->updateServiceConfiguration(file_name, "").ok());
EXPECT_EQ(i_service_controller->getPolicyVersion(), "");
}
@ -1468,7 +1584,7 @@ TEST_F(ServiceControllerTest, ErrorUpdateConfigurationRest)
EXPECT_CALL(mock_orchestration_tools, copyFile(file_name, policy_file_path)).WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, doesFileExist(policy_file_path)).WillOnce(Return(true));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, ""));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, "").ok());
EXPECT_THAT(
capture_debug.str(),
HasSubstr("Service mock access control is inactive")
@ -1554,7 +1670,7 @@ TEST_F(ServiceControllerTest, errorWhileWrtingNewConfiguration)
writeFile(l4_firewall, l4_firewall_policy_path)).WillOnce(Return(false)
);
EXPECT_FALSE(i_service_controller->updateServiceConfiguration(file_name, ""));
EXPECT_FALSE(i_service_controller->updateServiceConfiguration(file_name, "").ok());
}
TEST_F(ServiceControllerTest, testPortsRest)
@ -1690,7 +1806,13 @@ TEST_F(ServiceControllerTest, testMultitenantConfFiles)
).WillRepeatedly(Return(string("registered and running")));
EXPECT_TRUE(
i_service_controller->updateServiceConfiguration(conf_file_name, settings_file_name, {}, tenant, profile)
i_service_controller->updateServiceConfiguration(
conf_file_name,
settings_file_name,
{},
tenant,
profile
).ok()
);
}
}
@ -1821,7 +1943,7 @@ TEST_F(ServiceControllerTest, test_delayed_reconf)
EXPECT_CALL(mock_ml, yield(chrono::microseconds(2000000))).WillOnce(Invoke(func));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path));
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path).ok());
EXPECT_EQ(i_service_controller->getPolicyVersion(), version_value);
EXPECT_EQ(i_service_controller->getUpdatePolicyVersion(), version_value);
}

View File

@ -177,6 +177,16 @@ FogAuthenticator::registerAgent(
request << details;
}
auto i_agent_details = Singleton::Consume<I_AgentDetails>::by<FogAuthenticator>();
if (
i_agent_details->getOrchestrationMode() == OrchestrationMode::HYBRID ||
getSettingWithDefault<string>("management", "profileManagedMode") == "declarative"
) {
request << make_pair("managedMode", "declarative");
} else {
request << make_pair("managedMode", "management");
}
if (details_resolver->isReverseProxy()) {
request << make_pair("reverse_proxy", "true");
}
@ -202,7 +212,6 @@ FogAuthenticator::registerAgent(
auto fog_messaging = Singleton::Consume<I_Messaging>::by<FogAuthenticator>();
if (fog_messaging->sendObject(request, HTTPMethod::POST, fog_address_ex + "/agents")) {
dbgDebug(D_ORCHESTRATOR) << "Agent has registered successfully.";
auto i_agent_details = Singleton::Consume<I_AgentDetails>::by<FogAuthenticator>();
i_agent_details->setAgentId(request.getAgentId());
i_agent_details->setProfileId(request.getProfileId());
i_agent_details->setTenantId(request.getTenantId());
@ -252,7 +261,7 @@ FogAuthenticator::getAccessToken(const UserCredentials &user_credentials) const
}
dbgInfo(D_ORCHESTRATOR) << "New access token was saved";
fog_messaging->loadAccessToken();
Singleton::Consume<I_AgentDetails>::by<FogAuthenticator>()->loadAccessToken();
return AccessToken(request.getAccessToken(), chrono::seconds(request.getExpirationTime()));
}

View File

@ -117,13 +117,20 @@ FogCommunication::downloadAttributeFile(const GetResourceFile &resourse_file)
}
Maybe<void>
FogCommunication::sendPolicyVersion(const string &policy_version) const
FogCommunication::sendPolicyVersion(const string &policy_version, const string &policy_versions) const
{
PolicyVersionPatchRequest request(policy_version);
PolicyVersionPatchRequest request(policy_version, policy_versions);
auto fog_messaging = Singleton::Consume<I_Messaging>::by<FogCommunication>();
dbgTrace(D_ORCHESTRATOR)
<< "Sending patch request to the fog. Policy version: "
<< policy_version
<< " , Policy versions: "
<< policy_versions;
if (fog_messaging->sendNoReplyObject(request, HTTPMethod::PATCH, fog_address_ex + "/agents")) {
dbgInfo(D_ORCHESTRATOR)
dbgTrace(D_ORCHESTRATOR)
<< "Patch request was sent successfully to the fog."
<< " Policy versions: "
<< policy_versions
<< " Policy version: "
<< policy_version;
return Maybe<void>();

View File

@ -157,7 +157,7 @@ HybridCommunication::downloadAttributeFile(const GetResourceFile &resourse_file)
}
Maybe<void>
HybridCommunication::sendPolicyVersion(const string &policy_version) const
HybridCommunication::sendPolicyVersion(const string &policy_version, const string &) const
{
dbgFlow(D_ORCHESTRATOR);
policy_version.empty();

View File

@ -175,7 +175,7 @@ LocalCommunication::setAddressExtenesion(const string &)
}
Maybe<void>
LocalCommunication::sendPolicyVersion(const string &) const
LocalCommunication::sendPolicyVersion(const string &, const string &) const
{
dbgTrace(D_ORCHESTRATOR) << "Agent in offline mode, no need to send policy version";
return Maybe<void>();

View File

@ -75,9 +75,9 @@ public:
}
Maybe<void>
sendPolicyVersion(const string &policy_version) const override
sendPolicyVersion(const string &policy_version, const string &policy_versions) const override
{
return i_update_comm_impl->sendPolicyVersion(policy_version);
return i_update_comm_impl->sendPolicyVersion(policy_version, policy_versions);
}
Maybe<string>

View File

@ -39,9 +39,9 @@ public:
}
Maybe<void>
sendPolicyVersion(const string &version)
sendPolicyVersion(const string &version, const string &policy_versions)
{
return local_communication.sendPolicyVersion(version);
return local_communication.sendPolicyVersion(version, policy_versions);
}
Maybe<string>
@ -228,6 +228,6 @@ TEST_F(LocalCommunicationTest, setAddressExtenesion)
TEST_F(LocalCommunicationTest, sendPolicyVersion)
{
auto res = sendPolicyVersion("12");
auto res = sendPolicyVersion("12", "");
EXPECT_TRUE(res.ok());
}

View File

@ -83,6 +83,7 @@ add_library(waap_clib
LogGenWrapper.cc
WaapSampleValue.cc
ParserGql.cc
ParserPercentEncode.cc
)
add_definitions("-Wno-unused-function")

View File

@ -23,6 +23,7 @@
#include "ParserHTML.h"
#include "ParserBinary.h"
#include "ParserMultipartForm.h"
#include "ParserPercentEncode.h"
#include "ParserDelimiter.h"
#include "WaapAssetState.h"
#include "Waf2Regex.h"
@ -232,16 +233,16 @@ int DeepParser::onKv(const char* k, size_t k_len, const char* v, size_t v_len, i
bool base64ParamFound = false;
dbgTrace(D_WAAP_DEEP_PARSER) << " ===Processing potential base64===";
std::string decoded_val, key;
std::string decoded_val, decoded_key;
base64_variants base64_status = Waap::Util::b64Test (cur_val,
key,
decoded_key,
decoded_val);
dbgTrace(D_WAAP_DEEP_PARSER)
<< " status = "
<< base64_status
<< " key = "
<< key
<< decoded_key
<< " value = "
<< decoded_val;
@ -255,7 +256,7 @@ int DeepParser::onKv(const char* k, size_t k_len, const char* v, size_t v_len, i
if (decoded_val.size() > 0) {
cur_val = decoded_val;
base64ParamFound = true;
rc = onKv(key.c_str(), key.size(), cur_val.data(), cur_val.size(), flags);
rc = onKv(decoded_key.c_str(), decoded_key.size(), cur_val.data(), cur_val.size(), flags);
dbgTrace(D_WAAP_DEEP_PARSER) << " rc = " << rc;
if (rc != CONTINUE_PARSING) {
return rc;
@ -284,11 +285,6 @@ int DeepParser::onKv(const char* k, size_t k_len, const char* v, size_t v_len, i
// Calculate various statistics over currently processed value
ValueStatsAnalyzer valueStats(cur_val_html_escaped);
if (valueStats.isUrlEncoded && !Waap::Util::testUrlBareUtf8Evasion(cur_val) &&
!Waap::Util::testUrlBadUtf8Evasion(cur_val)) {
Waap::Util::decodePercentEncoding(cur_val);
}
if (valueStats.canSplitPipe || valueStats.canSplitSemicolon)
{
std::string key = IndicatorsFiltersManager::generateKey(m_key.first(), m_key.str(), m_pTransaction);
@ -373,14 +369,14 @@ int DeepParser::onKv(const char* k, size_t k_len, const char* v, size_t v_len, i
return rc;
}
if (Waap::Util::detectJSONasParameter(cur_val, key, decoded_val)) {
if (Waap::Util::detectJSONasParameter(cur_val, decoded_key, decoded_val)) {
dbgTrace(D_WAAP_DEEP_PARSER)
<< " detectJSONasParameter was true: key = "
<< key
<< decoded_key
<< " value = "
<< decoded_val;
rc = onKv(key.c_str(), key.size(), decoded_val.data(), decoded_val.size(), flags);
rc = onKv(decoded_key.c_str(), decoded_key.size(), decoded_val.data(), decoded_val.size(), flags);
dbgTrace(D_WAAP_DEEP_PARSER) << " After processing potential JSON rc = " << rc;
if (rc != CONTINUE_PARSING) {
@ -746,6 +742,13 @@ void DeepParser::createInternalParser(const char *k, size_t k_len, std::string&
bool isUrlParamPayload,
int flags)
{
dbgTrace(D_WAAP_DEEP_PARSER)
<< "Starting create parsers for value: >>>"
<< cur_val
<< "<<<";
dbgTrace(D_WAAP_DEEP_PARSER)
<< "Stats:\n "
<< valueStats.textual;
bool isPipesType = false, isSemicolonType = false, isAsteriskType = false,
isCommaType = false, isAmperType = false;
bool isKeyValDelimited = false;
@ -887,27 +890,36 @@ void DeepParser::createInternalParser(const char *k, size_t k_len, std::string&
// Note that this function must not add more than one parser
// because only the topmost parser will run on the value.
// Normally, DeepParser will take care of recursively run other parsers.
if (isHtmlType &&
if (valueStats.isUrlEncoded &&
!Waap::Util::testUrlBareUtf8Evasion(cur_val)) {
if (!valueStats.hasSpace &&
valueStats.hasCharAmpersand &&
valueStats.hasTwoCharsEqual &&
!isBinaryData()) {
dbgTrace(D_WAAP_DEEP_PARSER) << " Starting to parse an Url-encoded data";
m_parsersDeque.push_front(std::make_shared<BufferedParser<ParserUrlEncode>>(*this));
} else if (!Waap::Util::testUrlBadUtf8Evasion(cur_val)) {
dbgTrace(D_WAAP_DEEP_PARSER) << "Starting to parse an percent decoding";
m_parsersDeque.push_front(std::make_shared<BufferedParser<ParserPercentEncode>>(*this));
}
} else if (isHtmlType &&
!isRefererPayload &&
!isUrlPayload)
{
!isUrlPayload) {
// HTML detected
dbgTrace(D_WAAP_DEEP_PARSER) << "Starting to parse an HTML file";
m_parsersDeque.push_front(std::make_shared<BufferedParser<ParserHTML>>(*this));
}
else if (cur_val.size() > 0 && signatures->php_serialize_identifier.hasMatch(cur_val))
{
} else if (cur_val.size() > 0 &&
signatures->php_serialize_identifier.hasMatch(cur_val)) {
// PHP value detected
dbgTrace(D_WAAP_DEEP_PARSER) << "Starting to parse phpSerializedData";
m_parsersDeque.push_front(std::make_shared<BufferedParser<PHPSerializedDataParser>>(*this));
}
else if (isPotentialGqlQuery && cur_val.size() > 0 && !validateJson(cur_val.data(), cur_val.size())) {
} else if (isPotentialGqlQuery &&
cur_val.size() > 0 &&
!validateJson(cur_val.data(), cur_val.size())) {
// Graphql value detected
dbgTrace(D_WAAP_DEEP_PARSER) << "Starting to parse graphql";
m_parsersDeque.push_front(std::make_shared<BufferedParser<ParserGql>>(*this));
}
else if (cur_val.length() > 0 && (cur_val[0] == '[' || cur_val[0] == '{'))
{
} else if (cur_val.length() > 0 && (cur_val[0] == '[' || cur_val[0] == '{')) {
boost::smatch confulence_match;
if (NGEN::Regex::regexMatch(__FILE__, __LINE__, cur_val, confulence_match, signatures->confluence_macro_re))

View File

@ -34,6 +34,7 @@ public:
virtual int onKv(const char *k, size_t k_len, const char *v, size_t v_len, int flags);
void clear();
void showStats(std::string& buff, const ValueStatsAnalyzer& valueStats);
void apiProcessKey(const char *v, size_t v_len);
size_t depth() const;
void setGlobalMaxObjectDepth(size_t depth) { m_globalMaxObjectDepth = depth; }

View File

@ -0,0 +1,326 @@
// 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 "ParserPercentEncode.h"
#include "Waf2Util.h"
#include "debug.h"
USE_DEBUG_FLAG(D_WAAP_PARSER_PERCENT);
const std::string ParserPercentEncode::m_parserName = "ParserPercentEncode";
ParserPercentEncode::ParserPercentEncode(IParserStreamReceiver &receiver) :
m_receiver(receiver),
m_state(s_start),
m_escapedLen(0),
m_escapedCharCandidate(0)
{
memset(m_escaped, 0, sizeof(m_escaped));
}
ParserPercentEncode::~ParserPercentEncode()
{}
size_t
ParserPercentEncode::push(const char *buf, size_t len)
{
size_t i = 0;
size_t pointer_in_buffer = 0;
char c;
int is_last = 0;
dbgTrace(D_WAAP_PARSER_PERCENT) << "ParserPercentEncode::push(): starting (len=" << len << ")";
if (len == 0) {
dbgTrace(D_WAAP_PARSER_PERCENT) << "ParserPercentEncode::push(): end of data signal! m_state=" << m_state;
// flush unescaped data collected (if any)
if (m_escapedLen > 0)
{
if (m_state == s_value_start)
{
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): call onValue with m_escaped = >>>"
<< m_escaped
<< "<<<";
if (m_receiver.onValue(m_escaped, m_escapedLen) != 0) {
m_state = s_error;
return i;
}
}
m_escapedLen = 0;
}
if (m_receiver.onKvDone() != 0)
{
m_state = s_error;
return i;
}
return 0;
}
while (i < len)
{
c = buf[i];
is_last = (i == (len - 1));
// Checking valid char urlencode
if (c < VALID_URL_CODE_START)
{
dbgDebug(D_WAAP_PARSER_PERCENT)
<< "invalid URL encoding character: "
<< c;
m_state = s_error;
return i;
}
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): state="
<< m_state
<< "; ch='"
<< c
<< "'";
switch (m_state)
{
case s_start:
{
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): s_start";
// fallthrough //
CP_FALL_THROUGH;
}
case s_value_start:
{
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): s_value_start";
pointer_in_buffer = i;
m_state = s_value;
// fallthrough //
CP_FALL_THROUGH;
}
case s_value:
{
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): s_value";
if (c == '%')
{
if (i - pointer_in_buffer > 0)
{
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): call onValue with m_escaped = >>>"
<< (buf + pointer_in_buffer)
<< "<<<";
if (m_receiver.onValue(buf + pointer_in_buffer, i - pointer_in_buffer) != 0)
{
m_state = s_error;
return i;
}
}
m_state = s_value_escaped1;
break;
}
else
{
// flush unescaped data collected (if any)
if (m_escapedLen > 0)
{
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): call onValue with m_escaped = >>>"
<< m_escaped
<< "<<<";
if (m_receiver.onValue(m_escaped, m_escapedLen) != 0)
{
m_state = s_error;
return i;
}
m_escapedLen = 0;
pointer_in_buffer = i;
}
}
if (is_last)
{
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): call onValue with m_escaped = >>>"
<< (buf + pointer_in_buffer)
<< "<<<";
if (m_receiver.onValue(buf + pointer_in_buffer, (i - pointer_in_buffer) + 1) != 0)
{
m_state = s_error;
return i;
}
}
break;
}
case s_value_escaped1:
{
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): s_value_escaped1";
bool valid;
unsigned char v = from_hex(c, valid);
// character right after the '%' is not a valid hex char.
if (!valid)
{
// dump escaped chars
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): call onValue with m_escaped = >>>"
<< m_escaped
<< "<<<";
if (m_escapedLen > 0
&& m_receiver.onValue(m_escaped, m_escapedLen) != 0)
{
m_state = s_error;
return i;
}
m_escapedLen = 0;
// return the '%' character back to the output.
dbgTrace(D_WAAP_PARSER_PERCENT) << "ParserPercentEncode::push(): call onValue with m_escaped = >>>"
<< "%"
<< "<<<";
if (m_receiver.onValue("%", 1) != 0)
{
return i;
}
// If the character is '%' - stay in the same state (correctly treat '%%%%hhh' sequences)
if (c != '%')
{
// pass the non-hex character back to the output too.
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): call onValue with m_escaped = >>>"
<< c
<< "<<<";
if (m_receiver.onValue(&c, 1) != 0)
{
return i;
}
// otherwise (the character is not '%'), switch back to the s_value state
m_state = s_value_start;
}
break;
}
m_escapedCharCandidate = c;
m_escaped[m_escapedLen] = v << 4;
m_state = s_value_escaped2;
break;
}
case s_value_escaped2:
{
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): s_value_escaped2";
bool valid;
unsigned char v = from_hex(c, valid);
if (!valid)
{
// This situation (2nd character is not valid hex) is not treated right now.
// In this case, v will be equal to 0 and output character will be invalid one.
// dump escaped chars
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): call onValue with m_escaped = >>>"
<< m_escaped
<< "<<<";
if (m_escapedLen > 0
&& m_receiver.onValue(m_escaped, m_escapedLen) != 0)
{
m_state = s_error;
return i;
}
m_escapedLen = 0;
// return the '%' character back to the output.
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): call onValue with m_escaped = >>>"
<< "%"
<< "<<<";
if (m_receiver.onValue("%", 1) != 0)
{
return i;
}
// add the character that was thought to be escaped value
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): call onValue with m_escaped = >>>"
<< m_escapedCharCandidate
<< "<<<";
if (m_receiver.onValue(&m_escapedCharCandidate, 1))
{
return i;
}
// re parse the character as a key (i is incremented back to current value)
i--;
m_state = s_value_start;
break;
}
m_escapedCharCandidate = 0;
m_escaped[m_escapedLen] |= v;
m_escapedLen++;
if (m_escapedLen >= MAX_PERCENT_ENCODED_SIZE)
{
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): call onValue with m_escaped = >>>"
<< m_escaped
<< "<<<";
if (m_receiver.onValue(m_escaped, m_escapedLen) != 0)
{
m_state = s_error;
return i;
}
m_escapedLen = 0;
}
m_state = s_value_start;
break;
}
case s_error:
{
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): s_error";
return 0;
}
default:
{
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): URL parser unrecoverable error";
m_state = s_error;
return 0;
}
}
++i;
}
dbgTrace(D_WAAP_PARSER_PERCENT)
<< "ParserPercentEncode::push(): finished: len="
<< len;
return len;
}
void
ParserPercentEncode::finish()
{
push(NULL, 0);
}
const std::string &
ParserPercentEncode::name() const
{
return m_parserName;
}
bool
ParserPercentEncode::error() const
{
return m_state == s_error;
}

View File

@ -0,0 +1,58 @@
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __PARSER_PERCENT_ENCODE_H_
#define __PARSER_PERCENT_ENCODE_H_
#include "ParserBase.h"
#include <string.h>
#define MAX_PERCENT_ENCODED_SIZE 255
#define VALID_URL_CODE_START 32
class ParserPercentEncode : public ParserBase {
public:
ParserPercentEncode(IParserStreamReceiver &receiver);
virtual ~ParserPercentEncode();
size_t push(const char *data, size_t data_len);
void finish();
virtual const std::string &name() const;
bool error() const;
virtual size_t
depth()
{
return 1;
}
private:
enum state
{
s_start,
s_value_start,
s_value,
s_value_escaped1,
s_value_escaped2,
s_end,
s_error
};
IParserStreamReceiver &m_receiver;
enum state m_state;
unsigned char m_escapedLen;
char m_escaped[MAX_PERCENT_ENCODED_SIZE];
char m_escapedCharCandidate;
static const std::string m_parserName;
};
#endif

View File

@ -348,12 +348,12 @@ void ScoreBuilder::calcScore(const std::string &poolName)
void ScoreBuilder::snap()
{
// Copy data from all mutable score pools to "snapshot" keyword->scores map
for (const std::pair<std::string, KeywordsScorePool> &pool : m_keywordsScorePools) {
for (const auto &pool : m_keywordsScorePools) {
const std::string &poolName = pool.first;
const KeywordsScorePool& keywordScorePool = pool.second;
m_snapshotKwScoreMap[poolName];
for (const std::pair<std::string, KeywordData> &kwData : keywordScorePool.m_keywordsDataMap)
for (const auto &kwData : keywordScorePool.m_keywordsDataMap)
{
const std::string &kwName = kwData.first;
double kwScore = kwData.second.score;
@ -408,7 +408,7 @@ unsigned int ScoreBuilder::getFpStoreCount()
void ScoreBuilder::mergeScores(const ScoreBuilder& baseScores)
{
for (const std::pair<std::string, KeywordsScorePool> &pool : baseScores.m_keywordsScorePools) {
for (const auto &pool : baseScores.m_keywordsScorePools) {
const std::string &poolName = pool.first;
if (m_keywordsScorePools.find(poolName) == m_keywordsScorePools.end()) {
m_keywordsScorePools[poolName];

View File

@ -78,6 +78,15 @@ void WaapConfigBase::readJSONByCereal(cereal::JSONInputArchive& ar)
cereal::make_nvp("ruleName", m_ruleName)
);
try {
std::string application_urls;
ar(cereal::make_nvp("applicationUrls", application_urls));
m_applicationUrls = split(application_urls, ';');
} catch (std::runtime_error& e) {
dbgWarning(D_WAAP) << "Error to load applicationUrls field in policy" << e.what();
ar.setNextName(nullptr);
}
m_blockingLevel = blockingLevelBySensitivityStr(m_autonomousSecurityLevel);
}

View File

@ -95,6 +95,7 @@ private:
std::shared_ptr<Waap::TrustedSources::TrustedSourcesParameter> m_trustedSourcesPolicy;
std::shared_ptr<Waap::Parameters::WaapParameters> m_waapParameters;
std::shared_ptr<Waap::OpenRedirect::Policy> m_openRedirectPolicy;
std::vector<std::string> m_applicationUrls;
std::shared_ptr<Waap::ErrorDisclosure::Policy> m_errorDisclosurePolicy;
std::string m_schemaValidationPoicyStatusMessage;
std::shared_ptr<Waap::Csrf::Policy> m_csrfPolicy;

View File

@ -233,4 +233,30 @@ ValueStatsAnalyzer::ValueStatsAnalyzer(const std::string &cur_val)
}
// Detect URLEncode value
isUrlEncoded = checkUrlEncoded(cur_val.data(), cur_val.size());
textual.clear();
textual.append("hasCharSlash = ");
textual +=(hasCharSlash ? "true" : "false");
textual.append("\nhasCharColon = ");
textual +=(hasCharColon ? "true" : "false");
textual.append("\nhasCharAmpersand = ");
textual +=(hasCharAmpersand ? "true" : "false");
textual.append("\nhasCharEqual = ");
textual +=(hasCharEqual ? "true" : "false");
textual.append("\nhasTwoCharsEqual = ");
textual +=(hasTwoCharsEqual ? "true" : "false");
textual.append("\nhasCharSemicolon = ");
textual +=(hasCharSemicolon ? "true" : "false");
textual.append("\nhasCharPipe = ");
textual +=(hasCharPipe ? "true" : "false");
textual.append("\nisUTF16 = ");
textual +=(isUTF16 ? "true" : "false");
textual.append("\ncanSplitSemicolon = ");
textual +=(canSplitSemicolon ? "true" : "false");
textual.append("\ncanSplitPipe = ");
textual +=(canSplitPipe ? "true" : "false");
textual.append("\nhasSpace = ");
textual +=(hasSpace ? "true" : "false");
textual.append("\nisUrlEncoded = ");
textual +=(isUrlEncoded ? "true" : "false");
}

View File

@ -34,6 +34,7 @@ struct ValueStatsAnalyzer
bool canSplitPipe;
bool hasSpace;
bool isUrlEncoded;
std::string textual;
};

View File

@ -2277,7 +2277,7 @@ void Waf2Transaction::collectFoundPatterns()
{
if (m_scanResult)
{
for (const std::pair<std::string, std::vector<std::string>> &found_pattern : m_scanResult->found_patterns)
for (const auto &found_pattern : m_scanResult->found_patterns)
{
const std::string &regex_name = found_pattern.first; // the regex name (key)
m_found_patterns.insert(regex_name);

View File

@ -1044,14 +1044,14 @@ namespace Util {
// trim from start
static inline std::string &ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
[] (char c) { return !std::isspace(c); }));
return s;
}
// trim from end
static inline std::string &rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
[] (char c) { return !std::isspace(c); }).base(), s.end());
return s;
}

View File

@ -17,6 +17,8 @@
#include <sstream>
#include <string>
#include <sys/stat.h>
#include <boost/regex.hpp>
#include <boost/algorithm/string.hpp>
#include "config.h"
#include "debug.h"
@ -36,6 +38,46 @@ void
AgentDetails::init()
{
registerMachineType();
loadAccessToken();
Singleton::Consume<I_MainLoop>::by<AgentDetails>()->addRecurringRoutine(
I_MainLoop::RoutineType::System,
chrono::seconds(60),
[this] () { loadAccessToken(); },
"Load access token"
);
proxies = {
{ProxyProtocol::HTTP, ProxyData()},
{ProxyProtocol::HTTPS, ProxyData()}
};
auto proxy_config = getProfileAgentSetting<string>("agent.config.message.proxy");
if (proxy_config.ok()) {
setProxy(*proxy_config);
writeAgentDetails();
}
registerConfigLoadCb(
[&]()
{
auto proxy_config = getProfileAgentSetting<string>("agent.config.message.proxy");
if (proxy_config.ok()) {
is_proxy_configured_via_settings = true;
setProxy(*proxy_config);
writeAgentDetails();
} else if (is_proxy_configured_via_settings) {
is_proxy_configured_via_settings = false;
setProxy(string(""));
writeAgentDetails();
}
}
);
auto load_env_proxy = loadProxy();
if (!load_env_proxy.ok()) {
dbgDebug(D_ORCHESTRATOR)
<< "Could not initialize load proxy from environment, Error: "
<< load_env_proxy.getErr();
}
}
bool
@ -260,6 +302,36 @@ AgentDetails::getOrchestrationMode() const
return orchestration_mode;
}
string
AgentDetails::getAccessToken() const
{
return access_token;
}
void
AgentDetails::loadAccessToken()
{
readAgentDetails();
auto data_path = getConfigurationWithDefault<string>(
getFilesystemPathConfig() + "/data/",
"encryptor",
"Data files directory"
);
ifstream token_file(data_path + session_token_file_name);
if (!token_file.is_open()) {
dbgWarning(D_ORCHESTRATOR) << "Failed to open session token file: " << data_path + session_token_file_name;
return;
}
stringstream token_steam;
token_steam << token_file.rdbuf();
auto new_token = token_steam.str();
if (access_token != new_token) {
access_token = new_token;
dbgTrace(D_ORCHESTRATOR) << "Loaded the new token";
}
}
Maybe<I_AgentDetails::MachineType>
AgentDetails::getMachineTypeFromDmiTable()
{
@ -300,3 +372,235 @@ AgentDetails::registerMachineType()
);
dbgInfo(D_ORCHESTRATOR) << "Setting machine type " << static_cast<int>(machine_type.unpack());
}
string
AgentDetails::convertProxyProtocolToString(ProxyProtocol proto) const
{
switch(proto) {
case ProxyProtocol::HTTP: return "http";
case ProxyProtocol::HTTPS: return "https";
}
dbgAssert(false) << "Unsupported Proxy Protocol " << static_cast<int>(proto);
return "";
}
Maybe<void>
AgentDetails::verifyProxySyntax(
const string &protocol,
const string &auth,
const string &domain,
const string &port,
const string &env_proxy)
{
stringstream verify_string;
verify_string
<< protocol
<< "://"
<< (!auth.empty() ? auth + string("@") : "")
<< domain
<< ":"
<< port
<< (env_proxy.back() == '/' ? "/" : "");
if (env_proxy.compare(verify_string.str()) != 0) {
return genError(string("Provided proxy has the wrong syntax:" ) + env_proxy);
}
return Maybe<void>();
}
Maybe<string>
AgentDetails::loadProxyType(const string &proxy_type)
{
readAgentDetails();
auto proxy_config = getProxy();
if (proxy_config.ok()) {
if (proxy_config.unpack() == "none") {
return Maybe<string>(string());
}
return proxy_config;
}
#ifdef gaia
I_ShellCmd *shell_cmd = Singleton::Consume<I_ShellCmd>::by<AgentDetails>();
auto proxy_ip = shell_cmd->getExecOutput("dbget proxy:ip-address| tr -d '\n'");
if (!proxy_ip.ok()) return proxy_ip;
auto proxy_port = shell_cmd->getExecOutput("dbget proxy:port| tr -d '\n'");
if (!proxy_port.ok()) return proxy_port;
if (*proxy_port != "" && *proxy_ip != "") return ("http://" + *proxy_ip + ":" + *proxy_port);
const string umis_file_path(string(getenv("CPDIR")) + "/tmp/umis_objects.C");
{
ifstream umis_file(umis_file_path.c_str());
if (!umis_file.good()) return Maybe<string>(string());
}
const string read_umis_cmd = "cat " + umis_file_path + " | grep -w \"";
const string parse_value_command = "\" | awk -F \"[ \\t]+\" '{printf $NF}' | tr -d \"()\"";
auto use_proxy = shell_cmd->getExecOutput(read_umis_cmd + "use_proxy" + parse_value_command);
if (!use_proxy.ok())
return genError("Failed to read use_proxy from " + umis_file_path + ": " + use_proxy.getErr());
if (use_proxy.unpack() == "true") {
auto umis_proxy_add = shell_cmd->getExecOutput(read_umis_cmd + "proxy_address" + parse_value_command);
if (!umis_proxy_add.ok() || *umis_proxy_add == "") return umis_proxy_add;
auto umis_proxy_port = shell_cmd->getExecOutput(read_umis_cmd + "proxy_port" + parse_value_command);
if (!umis_proxy_port.ok() || *umis_proxy_port == "") return umis_proxy_port;
return ("http://" + *umis_proxy_add + ":" + *umis_proxy_port);
} else {
dbgTrace(D_ORCHESTRATOR) << "Smart Console Proxy is turned off";
}
return Maybe<string>(string());
#else // not gaia
char *proxy = getenv(proxy_type.c_str());
if (proxy) return string(proxy);
proxy = getenv(boost::algorithm::to_upper_copy(proxy_type).c_str());
if (proxy) return string(proxy);
return Maybe<string>(string());
#endif // gaia
}
Maybe<void>
AgentDetails::loadProxyType(ProxyProtocol protocol)
{
dbgAssert(protocol == ProxyProtocol::HTTP || protocol == ProxyProtocol::HTTPS)
<< "Unsupported Proxy Protocol " << static_cast<int>(protocol);
static const map<ProxyProtocol, string> env_var_name = {
{ProxyProtocol::HTTPS, "https_proxy"},
{ProxyProtocol::HTTP, "http_proxy"}
};
auto env_proxy = loadProxyType(env_var_name.at(protocol));
if (!env_proxy.ok()) return genError(env_proxy.getErr());
if (env_proxy.unpack().empty()) {
return Maybe<void>();
}
string protocol_regex = "(http|https)://";
const static boost::regex no_auth_proxy_regex(protocol_regex + "(.)*:[0-9]{0,5}(/|)");
const static boost::regex auth_proxy_regex(protocol_regex + "(.)*:(.)*@(.)*:[0-9]{0,5}(/|)");
ProxyData env_proxy_data;
env_proxy_data.is_exists = true;
string proxy_copy;
if (!NGEN::Regex::regexMatch(__FILE__, __LINE__, env_proxy.unpack(), boost::regex(protocol_regex + "(.)*"))) {
env_proxy = "http://" + env_proxy.unpack();
}
proxy_copy.assign(env_proxy.unpack());
env_proxy_data.protocol = env_proxy.unpack().substr(0, proxy_copy.find(":"));
proxy_copy.erase(0, proxy_copy.find(":") + 3); //remove "http://" or "https://"
if (NGEN::Regex::regexMatch(__FILE__, __LINE__, env_proxy.unpack(), auth_proxy_regex)) {
env_proxy_data.auth = string(&proxy_copy[0], &proxy_copy[proxy_copy.find("@")]);
proxy_copy.erase(0, proxy_copy.find("@") + 1); // remove "user:pass@"
} else if (!NGEN::Regex::regexMatch(__FILE__, __LINE__, env_proxy.unpack(), no_auth_proxy_regex)) {
return genError(string("Provided proxy has wrong syntax: ") + env_proxy.unpack());
}
env_proxy_data.domain = proxy_copy.substr(0, proxy_copy.find(":"));
proxy_copy.erase(0, proxy_copy.find(":") + 1); // remove "host:"
env_proxy_data.port = static_cast<uint16_t>(stoi(proxy_copy));
auto proxy_syntax = verifyProxySyntax(
env_proxy_data.protocol,
env_proxy_data.auth,
env_proxy_data.domain,
to_string(env_proxy_data.port),
env_proxy.unpack()
);
if (!proxy_syntax.ok()) return proxy_syntax;
if (env_proxy_data == proxies.at(protocol)) {
return Maybe<void>();
}
proxies.at(protocol) = env_proxy_data;
dbgInfo(D_ORCHESTRATOR)
<< convertProxyProtocolToString(protocol)
<< " proxy was successfully loaded, "
<< getProxyAddress(protocol).unpack();
return Maybe<void>();
}
Maybe<string>
AgentDetails::getProxyDomain(ProxyProtocol protocol) const
{
if (proxies.find(protocol) == proxies.end()) {
return genError("Proxy type is not loaded in map, type: " + convertProxyProtocolToString(protocol));
}
if (proxies.at(protocol).domain.empty()) return genError(
convertProxyProtocolToString(protocol) + string(" proxy domain is unset")
);
return proxies.at(protocol).domain;
}
Maybe<string>
AgentDetails::getProxyCredentials(ProxyProtocol protocol) const
{
if (proxies.find(protocol) == proxies.end()) {
return genError("Proxy type is not loaded in map, type: " + convertProxyProtocolToString(protocol));
}
if (proxies.at(protocol).auth.empty()) return genError(
convertProxyProtocolToString(protocol) + string(" proxy auth is unset")
);
return proxies.at(protocol).auth;
}
Maybe<uint16_t>
AgentDetails::getProxyPort(ProxyProtocol protocol) const
{
if (proxies.find(protocol) == proxies.end()) {
return genError("Proxy type is not loaded in map, type: " + convertProxyProtocolToString(protocol));
}
if (proxies.at(protocol).port == 0) return genError(
convertProxyProtocolToString(protocol) + string(" proxy port is unset")
);
return proxies.at(protocol).port;
}
bool
AgentDetails::getProxyExists(ProxyProtocol protocol) const
{
if (proxies.find(protocol) == proxies.end()) {
dbgInfo(D_ORCHESTRATOR)
<< "Proxy type is not loaded in map, type: "
<< convertProxyProtocolToString(protocol);
return false;
}
return proxies.at(protocol).is_exists;
}
Maybe<string>
AgentDetails::getProxyAddress(ProxyProtocol protocol) const
{
if (proxies.find(protocol) == proxies.end()) {
return genError("Proxy type is not loaded in map, type: " + convertProxyProtocolToString(protocol));
}
if (proxies.at(protocol).protocol.empty() ||
proxies.at(protocol).domain.empty() ||
proxies.at(protocol).port == 0) {
return genError(
string("Can't construct ") +
convertProxyProtocolToString(protocol) +
string(" proxy address")
);
}
return proxies.at(protocol).protocol +
"://" +
proxies.at(protocol).domain +
":" +
to_string(proxies.at(protocol).port);
}
Maybe<void>
AgentDetails::loadProxy()
{
if (getConfigurationFlag("orchestration-mode") == "offline_mode") return Maybe<void>();
for (const auto &proxy_type : proxies) {
auto loaded_proxy = loadProxyType(proxy_type.first);
if (!loaded_proxy.ok()) return loaded_proxy;
}
return Maybe<void>();
}

View File

@ -1,7 +1,11 @@
#include "agent_details.h"
#include <boost/regex.hpp>
#include <boost/algorithm/string.hpp>
#include "mock/mock_encryptor.h"
#include "mock/mock_shell_cmd.h"
#include "mock/mock_mainloop.h"
#include "cptest.h"
#include "config.h"
#include "config_component.h"
@ -24,133 +28,6 @@ public:
StrictMock<MockEncryptor> mock_encryptor;
StrictMock<MockShellCmd> mock_shell_cmd;
Config::I_Config *config = nullptr;
StrictMock<MockMainLoop> mock_ml;
};
TEST_F(AgentDetailsTest, doNothing)
{
}
TEST_F(AgentDetailsTest, basicTest)
{
const vector<string> agent_details_vec {
"{",
" \"Fog domain\": \"fog.com\",",
" \"Agent ID\": \"fdfdf-5454-dfd\",",
" \"Fog port\": 443,",
" \"Encrypted connection\": false,",
" \"Orchestration mode\": \"offline_mode\",",
" \"Tenant ID\": \"tenant_id\",",
" \"Profile ID\": \"profile\",",
" \"Proxy\": \"http://proxy.checkpoint.com/\",",
" \"OpenSSL certificates directory\": \"\"",
"}"
};
AgentDetails agent_details;
env.preload();
agent_details.preload();
EXPECT_CALL(
mock_shell_cmd,
getExecOutput("dmidecode -s system-manufacturer | tr -d '\\n'", _, _)
).WillOnce(Return(string("Microsoft Corporation")));
env.init();
agent_details.init();
auto i_conf = Singleton::Consume<Config::I_Config>::from(conf);
i_conf->reloadConfiguration();
CPTestTempfile agent_details_file(agent_details_vec);
setConfiguration(agent_details_file.fname, "Agent details", "File path");
EXPECT_TRUE(agent_details.readAgentDetails());
EXPECT_EQ(agent_details.getFogDomain().unpack(), "fog.com");
EXPECT_EQ(agent_details.getFogPort().unpack(), 443);
EXPECT_EQ(agent_details.getAgentId(), "fdfdf-5454-dfd");
EXPECT_FALSE(agent_details.getSSLFlag());
agent_details.setSSLFlag(true);
agent_details.setFogPort(80);
agent_details.setFogDomain("fog.checkpoint.com");
agent_details.setAgentId("dfdfdf-dfd");
agent_details.setClusterId("d5bd7949-554e-4fac-86c3-6e4e5d46a034");
EXPECT_EQ(agent_details.getFogDomain().unpack(), "fog.checkpoint.com");
EXPECT_EQ(agent_details.getFogPort().unpack(), 80);
EXPECT_EQ(agent_details.getAgentId(), "dfdfdf-dfd");
EXPECT_EQ(agent_details.getTenantId(), "tenant_id");
EXPECT_EQ(agent_details.getProfileId(), "profile");
EXPECT_EQ(agent_details.getClusterId(), "d5bd7949-554e-4fac-86c3-6e4e5d46a034");
EXPECT_TRUE(agent_details.writeAgentDetails());
EXPECT_TRUE(agent_details.readAgentDetails());
EXPECT_EQ(agent_details.getFogDomain().unpack(), "fog.checkpoint.com");
EXPECT_EQ(agent_details.getFogPort().unpack(), 80);
EXPECT_EQ(agent_details.getAgentId(), "dfdfdf-dfd");
EXPECT_EQ(agent_details.getClusterId(), "d5bd7949-554e-4fac-86c3-6e4e5d46a034");
EXPECT_TRUE(agent_details.getSSLFlag());
EXPECT_THAT(agent_details.getProxy(), IsValue("http://proxy.checkpoint.com/"));
agent_details.setProxy("none");
EXPECT_THAT(agent_details.getProxy(), IsValue("none"));
EXPECT_TRUE(agent_details.getOrchestrationMode() == OrchestrationMode::OFFLINE);
agent_details.setOrchestrationMode(OrchestrationMode::ONLINE);
EXPECT_TRUE(agent_details.getOrchestrationMode() == OrchestrationMode::ONLINE);
auto machine_type = Singleton::Consume<I_Environment>::from(env)->get<I_AgentDetails::MachineType>("MachineType");
EXPECT_EQ(machine_type.unpack(), I_AgentDetails::MachineType::AZURE);
}
TEST_F(AgentDetailsTest, openSSL)
{
const vector<string> agent_details_vec {
"{",
" \"Fog domain\": \"fog.com\",",
" \"Agent ID\": \"fdfdf-5454-dfd\",",
" \"Fog port\": 443,",
" \"Encrypted connection\": false,",
" \"Tenant ID\": \"tenant_id\",",
" \"Profile ID\": \"profile\",",
" \"OpenSSL certificates directory\": \"\"",
"}"
};
AgentDetails agent_details;
agent_details.preload();
CPTestTempfile agent_details_file(agent_details_vec);
setConfiguration(agent_details_file.fname, "Agent details", "File path");
EXPECT_FALSE(agent_details.getSSLFlag());
EXPECT_THAT(agent_details.getOpenSSLDir(), IsError("OpenSSL certificates directory was not set"));
agent_details.setOpenSSLDir("a/b/c");
EXPECT_THAT(agent_details.getOpenSSLDir(), IsValue("a/b/c"));
agent_details.setFogPort(10);
agent_details.setSSLFlag(false);
agent_details.setFogDomain("www.fog.checkpoint.com");
agent_details.setOpenSSLDir("");
EXPECT_THAT(agent_details.getFogPort(), IsValue(10));
EXPECT_FALSE(agent_details.getSSLFlag());
EXPECT_THAT(agent_details.getFogDomain(), IsValue("www.fog.checkpoint.com"));
EXPECT_THAT(agent_details.getOpenSSLDir(), IsError("OpenSSL certificates directory was not set"));
EXPECT_FALSE(agent_details.getOrchestrationMode() == OrchestrationMode::OFFLINE);
agent_details.setOrchestrationMode(OrchestrationMode::OFFLINE);
EXPECT_TRUE(agent_details.getOrchestrationMode() == OrchestrationMode::OFFLINE);
}
TEST_F(AgentDetailsTest, unrecognizedMachineType)
{
env.preload();
env.init();
AgentDetails agent_details;
EXPECT_CALL(
mock_shell_cmd,
getExecOutput("dmidecode -s system-manufacturer | tr -d '\\n'", _, _)
).WillOnce(Return(string("Skynet")));
agent_details.preload();
agent_details.init();
auto machine_type = Singleton::Consume<I_Environment>::from(env)->get<I_AgentDetails::MachineType>("MachineType");
EXPECT_EQ(machine_type.unpack(), I_AgentDetails::MachineType::UNRECOGNIZED);
}

View File

@ -192,7 +192,7 @@ AgentDetailsReporter::Impl::addAttr(const map<string, string> &attr, bool allow_
{
dbgFlow(D_AGENT_DETAILS);
bool ret = true;
for (const pair<string, string> &single_attr : attr) {
for (const auto &single_attr : attr) {
if (!addAttr(single_attr.first, single_attr.second, allow_override)) ret = false;
}
@ -219,7 +219,7 @@ AgentDetailsReporter::Impl::sendAttributes()
return true;
}
for (const pair<string, string> &new_attr : new_attributes) {
for (const auto &new_attr : new_attributes) {
attributes[new_attr.first] = new_attr.second;
}
@ -354,7 +354,7 @@ void
AgentDetailsReporter::Impl::fini()
{
if (!new_attributes.empty()) {
for (const pair<string, string> &new_attr : new_attributes) {
for (const auto &new_attr : new_attributes) {
attributes[new_attr.first] = new_attr.second;
}
}
@ -382,7 +382,7 @@ AgentDetailsReporter::Impl::sendReport(
if (agent_version.ok()) additional_metadata.setAgentVersion(*agent_version);
if (!new_attributes.empty()) {
for (const pair<string, string> &new_attr : new_attributes) {
for (const auto &new_attr : new_attributes) {
attributes[new_attr.first] = new_attr.second;
}
AttrSerializer<ofstream, cereal::JSONOutputArchive>(attributes, "save");

View File

@ -823,7 +823,7 @@ ConfigComponent::Impl::fillMultiTenantExpectedConfigFiles(const map<string, set<
auto global_path = getPolicyConfigPath(config_file.first, type);
auto it = find(files.begin(), files.end(), global_path);
if (it == files.end()) files.push_back(global_path);
for (const pair<string, set<string>> &tenant_profiles : active_tenants) {
for (const auto &tenant_profiles : active_tenants) {
const string &tenant = tenant_profiles.first;
const set<string> &profile_ids = tenant_profiles.second;
for (const auto &profile_id : profile_ids) {

View File

@ -12,6 +12,7 @@
// limitations under the License.
#include <stdio.h>
#include <bitset>
#include <string.h>
#include <arpa/inet.h>
@ -142,6 +143,130 @@ IPAddr::isInRange(const IPAddr &left, const IPAddr &right) const
return (*this >= left) && (*this <= right);
}
Maybe<string>
IPAddr::calculateSubnetStart(int subnet_value)
{
if (type == IPType::V4) {
return calculateSubnetStartV4(subnet_value);
} else {
return calculateSubnetStartV6(subnet_value);
}
}
Maybe<string>
IPAddr::calculateSubnetEnd(int subnet_value)
{
if (type == IPType::V4) {
return calculateSubnetEndV4(subnet_value);
} else {
return calculateSubnetEndV6(subnet_value);
}
}
Maybe<string>
IPAddr::calculateSubnetStartV4(int subnet_value)
{
if (subnet_value < 0 || subnet_value > 32) {
return genError("Invalid subnet value: ");
}
uint32_t ip = ntohl(v4.s_addr);
uint32_t mask = (0xFFFFFFFF << (32 - subnet_value));
uint32_t subnet = ip & mask;
subnet = ntohl(subnet);
return string(inet_ntoa(*(struct in_addr *)&subnet));
}
Maybe<string>
IPAddr::calculateSubnetStartV6(int subnet_value)
{
if (subnet_value < 0 || subnet_value > 128) {
return genError("Invalid subnet value: ");
}
// represent IPV6 as a binary
bitset<128> mask;
for (int i = 0; i < 16; ++i) {
for (int j = 0; j < 8; ++j) {
mask[i * 8 + j] = (v6.s6_addr[i] >> (7 - j)) & 1;
}
}
// set the subnet bits to 0
for (int i = subnet_value; i < 128; i++) {
mask.reset(i);
}
// convert the binary to IPV6
for (int i = 0; i < 16; ++i) {
uint8_t byteValue = 0;
for (int j = 0; j < 8; ++j) {
byteValue |= (mask[i * 8 + j] << (7 - j));
}
v6.s6_addr[i] = byteValue;
}
// convert to string
ostringstream oss;
for (int i = 0; i < 16; i+=2) {
if (i > 0)
oss << ":";
oss << hex << ((v6.s6_addr[i] << 8) + v6.s6_addr[i+1]);
}
return oss.str();
}
Maybe<string>
IPAddr::calculateSubnetEndV4(int subnet_value)
{
if (subnet_value < 0 || subnet_value > 32) {
return genError("Invalid subnet value: ");
}
uint32_t ip = ntohl(v4.s_addr);
uint32_t mask = (0xFFFFFFFF << (32 - subnet_value));
uint32_t subnet = ip & mask;
subnet |= ~mask;
subnet = ntohl(subnet);
return string(inet_ntoa(*(struct in_addr *)&subnet));
}
Maybe<string>
IPAddr::calculateSubnetEndV6(int subnet_value)
{
if (subnet_value < 0 || subnet_value > 128) {
return genError("Invalid subnet value: ");
}
// represent IPV6 as a binary
bitset<128> mask;
for (int i = 0; i < 16; ++i) {
for (int j = 0; j < 8; ++j) {
mask[i * 8 + j] = (v6.s6_addr[i] >> (7 - j)) & 1;
}
}
// set the host bits to 1
for (int i = subnet_value; i < 128; i++) {
mask.set(i);
}
// convert the binary to IPV6
for (int i = 0; i < 16; ++i) {
uint8_t byteValue = 0;
for (int j = 0; j < 8; ++j) {
byteValue |= (mask[i * 8 + j] << (7 - j));
}
v6.s6_addr[i] = byteValue;
}
// convert to string
ostringstream oss;
for (int i = 0; i < 16; i += 2) {
if (i > 0) oss << ":";
oss << hex << ((v6.s6_addr[i] << 8) + v6.s6_addr[i + 1]);
}
return oss.str();
}
Maybe<IPAddr>
IPAddr::createIPAddr(const string &ip_text)
{

View File

@ -544,7 +544,7 @@ Debug::applyOverrides()
}
} else {
auto should_add_file_stream = true;
for (const pair<string, shared_ptr<Debug::DebugStream>> &elem : active_streams) {
for (const auto &elem : active_streams) {
if (elem.first != "STDOUT" && elem.first != "FOG") should_add_file_stream = false;
break;
}

View File

@ -17,6 +17,7 @@
#include <vector>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include "cpnano_base64/base64.h"
#include "config.h"

View File

@ -22,8 +22,8 @@
#include <memory>
#include <iostream>
#include "debug.h"
#include "time_print.h"
#include "debug.h"
#include "singleton.h"
#include "context.h"
#include "table/table_helpers.h"

View File

@ -25,8 +25,13 @@ public:
:
tenant_id(_tenant_id),
profile_id(_profile_id)
{
}
{}
TenantProfilePair(const std::pair<std::string, std::string> &tenant_profile_pair)
:
tenant_id(tenant_profile_pair.first),
profile_id(tenant_profile_pair.second)
{}
size_t
hash() const

View File

@ -26,6 +26,7 @@
#include "i_rest_api.h"
#include "i_messaging_buffer.h"
#include "i_shell_cmd.h"
#include "i_proxy_configuration.h"
#include "component.h"
class ProtoMessageComp
@ -38,7 +39,8 @@ class ProtoMessageComp
Singleton::Consume<I_Encryptor>,
Singleton::Consume<I_Environment>,
Singleton::Consume<I_MessagingBuffer>,
Singleton::Consume<I_ShellCmd>
Singleton::Consume<I_ShellCmd>,
Singleton::Consume<I_ProxyConfiguration>
{
public:
ProtoMessageComp();

View File

@ -38,12 +38,14 @@ public:
virtual std::string getProfileId() const = 0;
// Agent Details
virtual Maybe<std::string> getProxy() const = 0;
virtual void setProxy(const std::string &_proxy) = 0;
virtual void setAgentId(const std::string &_agent_id) = 0;
virtual std::string getAgentId() const = 0;
virtual Maybe<std::string> getProxy() const = 0;
virtual void setProxy(const std::string &_proxy) = 0;
virtual void setAgentId(const std::string &_agent_id) = 0;
virtual std::string getAgentId() const = 0;
virtual void setOrchestrationMode(OrchestrationMode _orchstration_mode) = 0;
virtual OrchestrationMode getOrchestrationMode() const = 0;
virtual OrchestrationMode getOrchestrationMode() const = 0;
virtual std::string getAccessToken() const = 0;
virtual void loadAccessToken() = 0;
// OpenSSL
virtual void setOpenSSLDir(const std::string &openssl_dir) = 0;

View File

@ -31,12 +31,6 @@
USE_DEBUG_FLAG(D_COMMUNICATION);
enum class ProxyProtocol
{
HTTP,
HTTPS
};
enum class MessageTypeTag
{
GENERIC,
@ -141,16 +135,8 @@ public:
return genError("Failed to download file. Error: " + response.getErr());
}
virtual Maybe<std::string> getProxyDomain(ProxyProtocol protocol) const = 0;
virtual Maybe<std::string> getProxyCredentials(ProxyProtocol protocol) const = 0;
virtual Maybe<uint16_t> getProxyPort(ProxyProtocol protocol) const = 0;
virtual bool getProxyExists(ProxyProtocol protocol) const = 0;
virtual Maybe<std::string> getProxyAddress(ProxyProtocol protocol) const = 0;
virtual Maybe<void> loadProxy() = 0;
virtual bool setActiveFog(MessageTypeTag tag) = 0;
virtual void loadAccessToken() = 0;
virtual bool setActiveFog(const string &host, const uint16_t port, bool is_secure, MessageTypeTag tag) = 0;
virtual std::string getAccessToken() = 0;
protected:
~I_Messaging() {}

View File

@ -0,0 +1,38 @@
// 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_PROXY_CONFIGURATION_H__
#define __I_PROXY_CONFIGURATION_H__
#include <string>
#include "maybe_res.h"
enum class ProxyProtocol
{
HTTP,
HTTPS
};
class I_ProxyConfiguration
{
public:
virtual Maybe<std::string> getProxyDomain(ProxyProtocol protocol) const = 0;
virtual Maybe<std::string> getProxyCredentials(ProxyProtocol protocol) const = 0;
virtual Maybe<uint16_t> getProxyPort(ProxyProtocol protocol) const = 0;
virtual bool getProxyExists(ProxyProtocol protocol) const = 0;
virtual Maybe<std::string> getProxyAddress(ProxyProtocol protocol) const = 0;
virtual Maybe<void> loadProxy() = 0;
};
#endif // __I_PROXY_CONFIGURATION_H__

View File

@ -26,6 +26,8 @@ public:
MOCK_METHOD1(setProxy, void(const std::string&));
MOCK_METHOD1(setAgentId, void(const std::string&));
MOCK_CONST_METHOD0(getAgentId, std::string());
MOCK_METHOD0(loadAccessToken, void());
MOCK_CONST_METHOD0(getAccessToken, std::string());
// OpenSSL
MOCK_METHOD1(setOpenSSLDir, void(const std::string&));

View File

@ -57,20 +57,12 @@ public:
)
);
MOCK_METHOD0(loadAccessToken, void());
MOCK_METHOD0(setActiveFog, bool());
MOCK_METHOD1(setActiveFog, bool(MessageTypeTag));
MOCK_METHOD0(unsetFogProxy, void());
MOCK_METHOD0(loadFogProxy, void());
MOCK_METHOD4(setActiveFog, bool(const string &, const uint16_t, const bool, MessageTypeTag));
MOCK_METHOD0(getAccessToken, string());
MOCK_CONST_METHOD1(getProxyDomain, Maybe<std::string>(ProxyProtocol protocol));
MOCK_CONST_METHOD1(getProxyCredentials, Maybe<std::string>(ProxyProtocol protocol));
MOCK_CONST_METHOD1(getProxyPort, Maybe<uint16_t>(ProxyProtocol protocol));
MOCK_CONST_METHOD1(getProxyExists, bool(ProxyProtocol protocol));
MOCK_CONST_METHOD1(getProxyAddress, Maybe<std::string>(ProxyProtocol protocol));
MOCK_METHOD0(loadProxy, Maybe<void>());
};
#endif // __MOCK_MESSAGING_H__

View File

@ -20,17 +20,42 @@
#include "i_encryptor.h"
#include "i_shell_cmd.h"
#include "i_environment.h"
#include "i_mainloop.h"
#include "i_proxy_configuration.h"
#include "singleton.h"
#include "component.h"
#include "enum_array.h"
#include "agent_core_utilities.h"
class ProxyData
{
public:
bool
operator==(const ProxyData &other) const
{
return protocol==other.protocol &&
domain==other.domain &&
is_exists==other.is_exists &&
port==other.port &&
auth==other.auth;
}
std::string protocol = "";
std::string domain = "";
std::string auth = "";
bool is_exists = false;
uint16_t port = 0;
};
class AgentDetails
:
public Component,
Singleton::Provide<I_AgentDetails>::SelfInterface,
Singleton::Provide<I_ProxyConfiguration>::SelfInterface,
Singleton::Consume<I_Encryptor>,
Singleton::Consume<I_ShellCmd>,
Singleton::Consume<I_Environment>
Singleton::Consume<I_Environment>,
Singleton::Consume<I_MainLoop>
{
public:
AgentDetails() : Component("AgentDetails") {}
@ -39,15 +64,17 @@ public:
void init();
Maybe<std::string> getProxy() const;
Maybe<std::string> getFogDomain() const;
Maybe<uint16_t> getFogPort() const;
std::string getAgentId() const;
std::string getTenantId() const;
std::string getProfileId() const;
Maybe<std::string> getOpenSSLDir() const;
std::string getClusterId() const;
OrchestrationMode getOrchestrationMode() const;
Maybe<std::string> getProxy() const;
Maybe<std::string> getFogDomain() const;
Maybe<uint16_t> getFogPort() const;
std::string getAgentId() const;
std::string getTenantId() const;
std::string getProfileId() const;
Maybe<std::string> getOpenSSLDir() const;
std::string getClusterId() const;
OrchestrationMode getOrchestrationMode() const;
std::string getAccessToken() const;
void loadAccessToken();
void setFogDomain(const std::string &_fog_domain) { fog_domain = _fog_domain; }
void setFogPort(const uint16_t _fog_port) { fog_port = _fog_port; }
@ -67,6 +94,14 @@ public:
void serialize(cereal::JSONInputArchive &ar);
void setClusterId(const std::string &_cluster_id);
Maybe<std::string> getProxyDomain(ProxyProtocol protocol) const;
Maybe<std::string> getProxyCredentials(ProxyProtocol protocol) const;
Maybe<uint16_t> getProxyPort(ProxyProtocol protocol) const;
bool getProxyExists(ProxyProtocol protocol) const;
Maybe<std::string> getProxyAddress(ProxyProtocol protocol) const;
Maybe<void> loadProxy();
private:
std::string fog_domain = "";
std::string agent_id = "";
@ -77,13 +112,27 @@ private:
std::string cluster_id = "";
std::string filesystem_path = "/etc/cp";
std::string log_files_path = "/var/log";
std::string access_token = "";
uint16_t fog_port = 0;
bool encrypted_connection = false;
OrchestrationMode orchestration_mode = OrchestrationMode::ONLINE;
bool is_proxy_configured_via_settings = false;
std::map<ProxyProtocol, ProxyData> proxies;
static const std::map<std::string, I_AgentDetails::MachineType> machineTypes;
void registerMachineType();
Maybe<I_AgentDetails::MachineType> getMachineTypeFromDmiTable();
std::string convertProxyProtocolToString(ProxyProtocol proto) const;
Maybe<void> verifyProxySyntax(
const std::string &protocol,
const std::string &auth,
const std::string &domain,
const std::string &port,
const std::string &env_proxy
);
Maybe<std::string> loadProxyType(const std::string &proxy_type);
Maybe<void> loadProxyType(ProxyProtocol protocol);
};
#endif // __AGENT_DETAILS_H__

Some files were not shown because too many files have changed in this diff Show More