mirror of
https://github.com/openappsec/openappsec.git
synced 2025-06-28 16:41:02 +03:00
commit
a9b6d2e715
@ -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]" : "")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -15,4 +15,4 @@ add_subdirectory(health_check)
|
||||
add_subdirectory(local_policy_mgmt_gen)
|
||||
add_subdirectory(env_details)
|
||||
|
||||
add_subdirectory(orchestration_ut)
|
||||
#add_subdirectory(orchestration_ut)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -2,4 +2,4 @@ ADD_DEFINITIONS(-Wno-deprecated-declarations -Dalpine)
|
||||
|
||||
add_library(orchestration_downloader curl_client.cc downloader.cc http_client.cc https_client.cc)
|
||||
|
||||
add_subdirectory(downloader_ut)
|
||||
#add_subdirectory(downloader_ut)
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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__
|
||||
|
@ -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
|
||||
)
|
||||
);
|
||||
|
@ -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__
|
||||
|
@ -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)
|
||||
|
@ -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
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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__
|
@ -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:
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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__
|
||||
|
@ -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__
|
@ -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
|
@ -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__
|
@ -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__
|
@ -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__
|
@ -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__
|
@ -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__
|
@ -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__
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
);
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
{
|
||||
|
@ -1,3 +1,3 @@
|
||||
add_library(manifest_controller manifest_controller.cc manifest_diff_calculator.cc manifest_handler.cc)
|
||||
|
||||
add_subdirectory(manifest_controller_ut)
|
||||
#add_subdirectory(manifest_controller_ut)
|
||||
|
@ -7,4 +7,4 @@ add_library(
|
||||
data.cc
|
||||
)
|
||||
|
||||
add_subdirectory(modules_ut)
|
||||
#add_subdirectory(modules_ut)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -1,3 +1,3 @@
|
||||
add_library(package_handler package_handler.cc)
|
||||
|
||||
add_subdirectory(package_handler_ut)
|
||||
#add_subdirectory(package_handler_ut)
|
||||
|
@ -1,3 +1,3 @@
|
||||
add_library(service_controller service_controller.cc)
|
||||
|
||||
add_subdirectory(service_controller_ut)
|
||||
#add_subdirectory(service_controller_ut)
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
add_library(update_communication update_communication.cc hybrid_communication.cc fog_communication.cc fog_authenticator.cc local_communication.cc declarative_policy_utils.cc)
|
||||
add_subdirectory(update_communication_ut)
|
||||
#add_subdirectory(update_communication_ut)
|
||||
|
@ -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()));
|
||||
}
|
||||
|
@ -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>();
|
||||
|
@ -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();
|
||||
|
@ -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>();
|
||||
|
@ -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>
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ add_library(waap_clib
|
||||
LogGenWrapper.cc
|
||||
WaapSampleValue.cc
|
||||
ParserGql.cc
|
||||
ParserPercentEncode.cc
|
||||
)
|
||||
|
||||
add_definitions("-Wno-unused-function")
|
||||
|
@ -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))
|
||||
|
@ -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; }
|
||||
|
326
components/security_apps/waap/waap_clib/ParserPercentEncode.cc
Normal file
326
components/security_apps/waap/waap_clib/ParserPercentEncode.cc
Normal 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;
|
||||
}
|
@ -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
|
@ -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];
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ struct ValueStatsAnalyzer
|
||||
bool canSplitPipe;
|
||||
bool hasSpace;
|
||||
bool isUrlEncoded;
|
||||
std::string textual;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 ®ex_name = found_pattern.first; // the regex name (key)
|
||||
m_found_patterns.insert(regex_name);
|
||||
|
@ -1044,14 +1044,14 @@ namespace Util {
|
||||
// trim from start
|
||||
static inline std::string <rim(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;
|
||||
}
|
||||
|
||||
|
@ -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>();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user