mirror of
https://github.com/openappsec/openappsec.git
synced 2025-06-28 16:41:02 +03:00
Sep_24_2023-Dev
This commit is contained in:
parent
a4d1fb6f7f
commit
582791e37a
@ -104,12 +104,13 @@ Before compiling the services, you'll need to ensure the latest development vers
|
||||
* GTest
|
||||
* GMock
|
||||
* cURL
|
||||
* Hiredis
|
||||
|
||||
An example of installing the packages on Alpine:
|
||||
|
||||
```bash
|
||||
$ apk update
|
||||
$ apk add boost-dev openssl-dev pcre2-dev libxml2-dev gtest-dev curl-dev
|
||||
$ apk add boost-dev openssl-dev pcre2-dev libxml2-dev gtest-dev curl-dev hiredis-dev
|
||||
```
|
||||
|
||||
## Compiling and packaging the agent code
|
||||
|
@ -20,6 +20,9 @@
|
||||
#include "environment/evaluator_templates.h"
|
||||
#include "i_environment.h"
|
||||
#include "singleton.h"
|
||||
#include "debug.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
using namespace std;
|
||||
using namespace EnvironmentHelper;
|
||||
@ -55,6 +58,51 @@ EqualHost::evalVariable() const
|
||||
return lower_host_ctx == lower_host;
|
||||
}
|
||||
|
||||
WildcardHost::WildcardHost(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams("WildcardHost", params.size(), 1, 1);
|
||||
host = params[0];
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
WildcardHost::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<WildcardHost>();
|
||||
auto host_ctx = env->get<string>(HttpTransactionData::host_name_ctx);
|
||||
|
||||
if (!host_ctx.ok())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string lower_host_ctx = host_ctx.unpack();
|
||||
transform(lower_host_ctx.begin(), lower_host_ctx.end(), lower_host_ctx.begin(), ::tolower);
|
||||
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "found host in current context: " << lower_host_ctx;
|
||||
|
||||
size_t pos = lower_host_ctx.find_first_of(".");
|
||||
if (pos == string::npos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lower_host_ctx = "*" + lower_host_ctx.substr(pos, lower_host_ctx.length());
|
||||
|
||||
string lower_host = host;
|
||||
transform(lower_host.begin(), lower_host.end(), lower_host.begin(), ::tolower);
|
||||
|
||||
dbgTrace(D_RULEBASE_CONFIG)
|
||||
<< "trying to match host context with its corresponding wildcard address: "
|
||||
<< lower_host_ctx
|
||||
<< ". Matcher host: "
|
||||
<< lower_host;
|
||||
|
||||
if (lower_host_ctx == lower_host) return true;
|
||||
pos = lower_host_ctx.find_last_of(':');
|
||||
if (pos == string::npos) return false;
|
||||
lower_host_ctx = string(lower_host_ctx.data(), pos);
|
||||
return lower_host_ctx == lower_host;
|
||||
}
|
||||
|
||||
EqualListeningIP::EqualListeningIP(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams("EqualListeningIP", params.size(), 1, 1);
|
||||
|
@ -75,6 +75,7 @@ GenericRulebase::Impl::preload()
|
||||
addMatcher<IpProtocolMatcher>();
|
||||
addMatcher<UrlMatcher>();
|
||||
addMatcher<EqualHost>();
|
||||
addMatcher<WildcardHost>();
|
||||
addMatcher<EqualListeningIP>();
|
||||
addMatcher<EqualListeningPort>();
|
||||
addMatcher<BeginWithUri>();
|
||||
|
@ -32,6 +32,19 @@ private:
|
||||
std::string host;
|
||||
};
|
||||
|
||||
class WildcardHost : public EnvironmentEvaluator<bool>, Singleton::Consume<I_Environment>
|
||||
{
|
||||
public:
|
||||
WildcardHost(const std::vector<std::string> ¶ms);
|
||||
|
||||
static std::string getName() { return "WildcardHost"; }
|
||||
|
||||
Maybe<bool, Context::Error> evalVariable() const override;
|
||||
|
||||
private:
|
||||
std::string host;
|
||||
};
|
||||
|
||||
class EqualListeningIP : public EnvironmentEvaluator<bool>, Singleton::Consume<I_Environment>
|
||||
{
|
||||
public:
|
||||
|
@ -14,13 +14,15 @@
|
||||
#ifndef __I_LOCAL_POLICY_MGMT_GEN_H__
|
||||
#define __I_LOCAL_POLICY_MGMT_GEN_H__
|
||||
|
||||
#include "i_env_details.h"
|
||||
|
||||
class I_LocalPolicyMgmtGen
|
||||
{
|
||||
public:
|
||||
virtual std::string parsePolicy(const std::string &policy_version) = 0;
|
||||
virtual const std::string & getAgentPolicyPath(void) const = 0;
|
||||
virtual const std::string & getLocalPolicyPath(void) const = 0;
|
||||
virtual void setPolicyPath(const std::string &new_local_policy_path) = 0;
|
||||
virtual std::string generateAppSecLocalPolicy(
|
||||
EnvType env_type,
|
||||
const std::string &policy_version,
|
||||
const std::string &local_policy_path) = 0;
|
||||
|
||||
protected:
|
||||
~I_LocalPolicyMgmtGen() {}
|
||||
|
@ -34,6 +34,7 @@ public:
|
||||
virtual const std::string & getUpdateTime() const = 0;
|
||||
virtual const std::string & getLastManifestUpdate() const = 0;
|
||||
virtual const std::string & getPolicyVersion() const = 0;
|
||||
virtual const std::string & getWaapModelVersion() const = 0;
|
||||
virtual const std::string & getLastPolicyUpdate() const = 0;
|
||||
virtual const std::string & getLastSettingsUpdate() const = 0;
|
||||
virtual const std::string & getUpgradeMode() const = 0;
|
||||
|
@ -106,8 +106,9 @@ public:
|
||||
const std::string &profile_id = "") const = 0;
|
||||
|
||||
virtual bool isNonEmptyFile(const std::string &path) const = 0;
|
||||
virtual std::shared_ptr<std::ifstream> fileStreamWrapper(const std::string &path) const = 0;
|
||||
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 writeFile(const std::string &text, const std::string &path, bool append_mode = false) 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(
|
||||
@ -116,6 +117,7 @@ public:
|
||||
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 getClusterId() const = 0;
|
||||
virtual void fillKeyInJson(
|
||||
const std::string &filename,
|
||||
const std::string &_key,
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "i_environment.h"
|
||||
#include "i_tenant_manager.h"
|
||||
#include "i_package_handler.h"
|
||||
#include "i_env_details.h"
|
||||
#include "component.h"
|
||||
|
||||
class OrchestrationComp
|
||||
@ -52,7 +53,8 @@ class OrchestrationComp
|
||||
Singleton::Consume<I_ServiceController>,
|
||||
Singleton::Consume<I_UpdateCommunication>,
|
||||
Singleton::Consume<I_Downloader>,
|
||||
Singleton::Consume<I_ManifestController>
|
||||
Singleton::Consume<I_ManifestController>,
|
||||
Singleton::Consume<I_EnvDetails>
|
||||
{
|
||||
public:
|
||||
OrchestrationComp();
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "i_time_get.h"
|
||||
#include "i_mainloop.h"
|
||||
#include "i_agent_details.h"
|
||||
#include "i_details_resolver.h"
|
||||
#include "customized_cereal_map.h"
|
||||
|
||||
class OrchestrationStatus
|
||||
@ -32,6 +33,7 @@ class OrchestrationStatus
|
||||
Singleton::Provide<I_OrchestrationStatus>,
|
||||
Singleton::Consume<I_TimeGet>,
|
||||
Singleton::Consume<I_AgentDetails>,
|
||||
Singleton::Consume<I_DetailsResolver>,
|
||||
Singleton::Consume<I_OrchestrationTools>,
|
||||
Singleton::Consume<I_MainLoop>
|
||||
{
|
||||
|
@ -20,13 +20,23 @@
|
||||
#include "i_shell_cmd.h"
|
||||
#include "i_tenant_manager.h"
|
||||
#include "component.h"
|
||||
#include "i_env_details.h"
|
||||
#include "i_messaging.h"
|
||||
#include "i_environment.h"
|
||||
#include "i_agent_details.h"
|
||||
#include "i_mainloop.h"
|
||||
|
||||
class OrchestrationTools
|
||||
:
|
||||
public Component,
|
||||
Singleton::Provide<I_OrchestrationTools>,
|
||||
Singleton::Consume<I_ShellCmd>,
|
||||
Singleton::Consume<I_TenantManager>
|
||||
Singleton::Consume<I_TenantManager>,
|
||||
Singleton::Consume<I_EnvDetails>,
|
||||
Singleton::Consume<I_Messaging>,
|
||||
Singleton::Consume<I_Environment>,
|
||||
Singleton::Consume<I_MainLoop>,
|
||||
Singleton::Consume<I_AgentDetails>
|
||||
{
|
||||
public:
|
||||
OrchestrationTools();
|
||||
|
@ -111,6 +111,26 @@ public:
|
||||
public:
|
||||
UpgradeSchedule() = default;
|
||||
|
||||
UpgradeSchedule(const UpgradeSchedule &other)
|
||||
{
|
||||
mode = other.mode;
|
||||
time = other.time;
|
||||
duration_hours = other.duration_hours;
|
||||
days = other.days;
|
||||
}
|
||||
|
||||
UpgradeSchedule &
|
||||
operator=(const UpgradeSchedule &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
mode = other.mode;
|
||||
time = other.time;
|
||||
duration_hours = other.duration_hours;
|
||||
days = other.days;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void init(const std::string &_upgrade_mode) { mode = _upgrade_mode; }
|
||||
|
||||
void
|
||||
@ -142,6 +162,22 @@ public:
|
||||
C2S_LABEL_OPTIONAL_PARAM(std::vector<std::string>, days, "upgradeDay");
|
||||
};
|
||||
|
||||
class LocalConfigurationSettings : public ClientRest
|
||||
{
|
||||
public:
|
||||
LocalConfigurationSettings() = default;
|
||||
|
||||
void
|
||||
setUpgradeSchedule(const UpgradeSchedule &schedule)
|
||||
{
|
||||
upgrade_schedule.setActive(true);
|
||||
upgrade_schedule.get() = schedule;
|
||||
}
|
||||
|
||||
private:
|
||||
C2S_LABEL_OPTIONAL_PARAM(UpgradeSchedule, upgrade_schedule, "upgradeSchedule");
|
||||
};
|
||||
|
||||
CheckUpdateRequest(
|
||||
const std::string &_manifest,
|
||||
const std::string &_policy,
|
||||
@ -224,8 +260,10 @@ public:
|
||||
void
|
||||
setUpgradeFields(const std::string &_upgrade_mode)
|
||||
{
|
||||
upgrade_schedule.setActive(true);
|
||||
upgrade_schedule.get().init(_upgrade_mode);
|
||||
UpgradeSchedule upgrade_schedule;
|
||||
upgrade_schedule.init(_upgrade_mode);
|
||||
local_configuration_settings.setActive(true);
|
||||
local_configuration_settings.get().setUpgradeSchedule(upgrade_schedule);
|
||||
}
|
||||
|
||||
void
|
||||
@ -235,12 +273,14 @@ public:
|
||||
const uint &_upgrade_duration_hours,
|
||||
const std::vector<std::string> &_upgrade_days)
|
||||
{
|
||||
upgrade_schedule.setActive(true);
|
||||
UpgradeSchedule upgrade_schedule;
|
||||
if (!_upgrade_days.empty()) {
|
||||
upgrade_schedule.get().init(_upgrade_mode, _upgrade_time, _upgrade_duration_hours, _upgrade_days);
|
||||
return;
|
||||
upgrade_schedule.init(_upgrade_mode, _upgrade_time, _upgrade_duration_hours, _upgrade_days);
|
||||
} else {
|
||||
upgrade_schedule.init(_upgrade_mode, _upgrade_time, _upgrade_duration_hours);
|
||||
}
|
||||
upgrade_schedule.get().init(_upgrade_mode, _upgrade_time, _upgrade_duration_hours);
|
||||
local_configuration_settings.setActive(true);
|
||||
local_configuration_settings.get().setUpgradeSchedule(upgrade_schedule);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -297,7 +337,7 @@ 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");
|
||||
C2S_LABEL_OPTIONAL_PARAM(LocalConfigurationSettings, local_configuration_settings, "localConfigurationSettings");
|
||||
|
||||
S2C_LABEL_OPTIONAL_PARAM(VirtualConfig, in_virtual_policy, "virtualPolicy");
|
||||
S2C_LABEL_OPTIONAL_PARAM(VirtualConfig, in_virtual_settings, "virtualSettings");
|
||||
|
32
components/include/rate_limit.h
Executable file
32
components/include/rate_limit.h
Executable file
@ -0,0 +1,32 @@
|
||||
#ifndef __RATE_LIMIT_H_
|
||||
#define __RATE_LIMIT_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "component.h"
|
||||
#include "singleton.h"
|
||||
#include "i_mainloop.h"
|
||||
#include "i_environment.h"
|
||||
|
||||
class RateLimit
|
||||
:
|
||||
public Component,
|
||||
Singleton::Consume<I_MainLoop>,
|
||||
Singleton::Consume<I_TimeGet>,
|
||||
Singleton::Consume<I_Environment>
|
||||
{
|
||||
public:
|
||||
RateLimit();
|
||||
~RateLimit();
|
||||
|
||||
void preload() override;
|
||||
|
||||
void init() override;
|
||||
void fini() override;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> pimpl;
|
||||
};
|
||||
|
||||
#endif // __RATE_LIMIT_H_
|
142
components/include/rate_limit_config.h
Executable file
142
components/include/rate_limit_config.h
Executable file
@ -0,0 +1,142 @@
|
||||
#ifndef __RATE_LIMIT_CONFIG_H__
|
||||
#define __RATE_LIMIT_CONFIG_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cereal/archives/json.hpp>
|
||||
|
||||
#include "debug.h"
|
||||
#include "generic_rulebase/rulebase_config.h"
|
||||
#include "generic_rulebase/triggers_config.h"
|
||||
#include "generic_rulebase/evaluators/trigger_eval.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_REVERSE_PROXY);
|
||||
|
||||
class RateLimitTrigger
|
||||
{
|
||||
public:
|
||||
void
|
||||
load(cereal::JSONInputArchive &ar);
|
||||
|
||||
const std::string & getTriggerId() const { return id; }
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
};
|
||||
|
||||
class RateLimitRule
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &ar);
|
||||
void prepare(const std::string &asset_id, int zone_id);
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
if (uri.empty()) {
|
||||
dbgTrace(D_REVERSE_PROXY) << "Recived empty URI in rate-limit rule";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (uri.at(0) != '/') {
|
||||
dbgWarning(D_REVERSE_PROXY)
|
||||
<< "Recived invalid rate-limit URI in rate-limit rule: "
|
||||
<< uri
|
||||
<< " rate-limit URI must start with /";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (limit <= 0) {
|
||||
dbgWarning(D_REVERSE_PROXY)
|
||||
<< "Recived invalid rate-limit limit in rate-limit rule: "
|
||||
<< limit
|
||||
<< " rate-limit rule limit must be positive";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
friend std::ostream &
|
||||
operator<<(std::ostream &os, const RateLimitRule &rule)
|
||||
{
|
||||
os << "Uri: " << rule.uri << ", Rate scope: " << rule.scope << ", Limit: " << rule.limit;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
int getRateLimit() const { return limit; }
|
||||
const std::string & getRateLimitZone() const { return limit_req_zone_template_value; }
|
||||
const std::string & getRateLimitReq() const { return limit_req_template_value; }
|
||||
const std::string & getRateLimitUri() const { return uri; }
|
||||
const std::string & getRateLimitScope() const { return scope; }
|
||||
const LogTriggerConf & getRateLimitTrigger() const { return trigger; }
|
||||
const std::vector<RateLimitTrigger> & getRateLimitTriggers() const { return rate_limit_triggers; }
|
||||
|
||||
bool isRootLocation() const;
|
||||
|
||||
bool operator==(const RateLimitRule &rhs) { return uri == rhs.uri; }
|
||||
bool operator<(const RateLimitRule &rhs) { return uri < rhs.uri; }
|
||||
bool isExactMatch() const { return exact_match || (!uri.empty() && uri.back() != '/'); }
|
||||
void setExactMatch() { exact_match = true; }
|
||||
void appendSlash() { uri += '/'; }
|
||||
|
||||
private:
|
||||
std::string uri;
|
||||
std::string scope;
|
||||
std::string limit_req_template_value;
|
||||
std::string limit_req_zone_template_value;
|
||||
std::string cache_size = "5m";
|
||||
std::vector<RateLimitTrigger> rate_limit_triggers;
|
||||
LogTriggerConf trigger;
|
||||
int limit;
|
||||
bool exact_match = false;
|
||||
};
|
||||
|
||||
class RateLimitConfig
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &ar);
|
||||
void addSiblingRateLimitRule(RateLimitRule &rule);
|
||||
void prepare();
|
||||
|
||||
const std::vector<RateLimitRule> & getRateLimitRules() const { return rate_limit_rules; }
|
||||
const std::string & getRateLimitMode() const { return mode; }
|
||||
|
||||
const LogTriggerConf
|
||||
getRateLimitTrigger(const std::string &nginx_uri) const
|
||||
{
|
||||
const RateLimitRule rule = findLongestMatchingRule(nginx_uri);
|
||||
|
||||
std::set<std::string> rate_limit_triggers_set;
|
||||
for (const RateLimitTrigger &rate_limit_trigger : rule.getRateLimitTriggers()) {
|
||||
dbgTrace(D_REVERSE_PROXY)
|
||||
<< "Adding trigger ID: "
|
||||
<< rate_limit_trigger.getTriggerId()
|
||||
<< " of rule URI: "
|
||||
<< rule.getRateLimitUri()
|
||||
<< " to the context set";
|
||||
rate_limit_triggers_set.insert(rate_limit_trigger.getTriggerId());
|
||||
}
|
||||
|
||||
ScopedContext ctx;
|
||||
ctx.registerValue<std::set<GenericConfigId>>(TriggerMatcher::ctx_key, rate_limit_triggers_set);
|
||||
return getConfigurationWithDefault(LogTriggerConf(), "rulebase", "log");
|
||||
}
|
||||
|
||||
static void setIsActive(bool _is_active) { is_active |= _is_active; }
|
||||
|
||||
static void resetIsActive() { is_active = false; }
|
||||
|
||||
static bool isActive() { return is_active; }
|
||||
|
||||
private:
|
||||
const RateLimitRule
|
||||
findLongestMatchingRule(const std::string &nginx_uri) const;
|
||||
|
||||
static bool is_active;
|
||||
std::string mode;
|
||||
std::vector<RateLimitRule> rate_limit_rules;
|
||||
};
|
||||
|
||||
#endif // __RATE_LIMIT_CONFIG_H__
|
@ -1,4 +1,6 @@
|
||||
add_subdirectory(ips)
|
||||
add_subdirectory(layer_7_access_control)
|
||||
add_subdirectory(local_policy_mgmt_gen)
|
||||
add_subdirectory(orchestration)
|
||||
add_subdirectory(rate_limit)
|
||||
add_subdirectory(waap)
|
||||
|
@ -74,7 +74,7 @@ public:
|
||||
getCrowdsecEventId() const
|
||||
{
|
||||
if (!crowdsec_event_id) return genError("Empty ID");
|
||||
return LogField("externalVendorRecommendationId", crowdsec_event_id);
|
||||
return LogField("externalVendorRecommendationId", to_string(crowdsec_event_id));
|
||||
}
|
||||
|
||||
bool isMalicious() const { return type == "ban"; }
|
||||
@ -280,6 +280,8 @@ Layer7AccessControl::Impl::generateLog(const string &source_ip, const Intelligen
|
||||
<< LogField("sourceIP", source_ip)
|
||||
<< LogField("externalVendorName", "CrowdSec")
|
||||
<< LogField("waapIncidentType", "CrowdSec")
|
||||
<< LogField("practiceSubType", "Web Access Control")
|
||||
<< LogField("practiceType", "Access Control")
|
||||
<< ip_reputation.getCrowdsecEventId()
|
||||
<< ip_reputation.getType()
|
||||
<< ip_reputation.getOrigin()
|
||||
|
@ -248,7 +248,7 @@ Layer7AccessControlTest::verifyReport(
|
||||
EXPECT_THAT(log, HasSubstr("\"destinationIP\": \"5.6.7.8\""));
|
||||
EXPECT_THAT(log, HasSubstr("\"externalVendorName\": \"CrowdSec\""));
|
||||
EXPECT_THAT(log, HasSubstr("\"waapIncidentType\": \"CrowdSec\""));
|
||||
EXPECT_THAT(log, HasSubstr("\"externalVendorRecommendationId\": 2253734"));
|
||||
EXPECT_THAT(log, HasSubstr("\"externalVendorRecommendationId\": \"2253734\""));
|
||||
EXPECT_THAT(log, HasSubstr("\"externalVendorRecommendedAction\": \"ban\""));
|
||||
EXPECT_THAT(log, HasSubstr("\"externalVendorRecommendationOrigin\": \"cscli\""));
|
||||
EXPECT_THAT(log, HasSubstr("\"externalVendorRecommendedAffectedScope\": \"1.2.3.4\""));
|
||||
|
@ -0,0 +1,23 @@
|
||||
include_directories(include)
|
||||
add_library(local_policy_mgmt_gen
|
||||
appsec_practice_section.cc
|
||||
exceptions_section.cc
|
||||
ingress_data.cc
|
||||
rules_config_section.cc
|
||||
settings_section.cc
|
||||
snort_section.cc
|
||||
triggers_section.cc
|
||||
trusted_sources_section.cc
|
||||
policy_maker_utils.cc
|
||||
k8s_policy_utils.cc
|
||||
local_policy_mgmt_gen.cc
|
||||
new_appsec_policy_crd_parser.cc
|
||||
new_appsec_linux_policy.cc
|
||||
new_custom_response.cc
|
||||
new_trusted_sources.cc
|
||||
new_log_trigger.cc
|
||||
new_practice.cc
|
||||
new_exceptions.cc
|
||||
access_control_practice.cc
|
||||
configmaps.cc
|
||||
)
|
245
components/security_apps/local_policy_mgmt_gen/access_control_practice.cc
Executable file
245
components/security_apps/local_policy_mgmt_gen/access_control_practice.cc
Executable file
@ -0,0 +1,245 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "access_control_practice.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
|
||||
static const set<string> valid_modes = {"prevent", "detect", "inactive"};
|
||||
static const set<string> valid_units = {"minute", "second"};
|
||||
|
||||
static const std::unordered_map<std::string, std::string> key_to_mode_val = {
|
||||
{ "prevent-learn", "Prevent"},
|
||||
{ "detect-learn", "Detect"},
|
||||
{ "prevent", "Prevent"},
|
||||
{ "detect", "Detect"},
|
||||
{ "inactive", "Inactive"}
|
||||
};
|
||||
|
||||
static const std::unordered_map<std::string, std::string> key_to_units_val = {
|
||||
{ "second", "Second"},
|
||||
{ "minute", "Minute"}
|
||||
};
|
||||
|
||||
void
|
||||
RateLimitRulesTriggerSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("id", id),
|
||||
cereal::make_nvp("name", name),
|
||||
cereal::make_nvp("type", type)
|
||||
);
|
||||
}
|
||||
|
||||
const string &
|
||||
RateLimitRulesTriggerSection::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void
|
||||
RateLimitRulesSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("id", id),
|
||||
cereal::make_nvp("URI", uri),
|
||||
cereal::make_nvp("scope", key_to_units_val.at(scope)),
|
||||
cereal::make_nvp("triggers", triggers),
|
||||
cereal::make_nvp("limit", limit)
|
||||
);
|
||||
}
|
||||
|
||||
RateLimitSection::RateLimitSection(
|
||||
const string &asset_name,
|
||||
const string &url,
|
||||
const string &uri,
|
||||
const std::string &_mode,
|
||||
const std::string &_practice_id,
|
||||
const std::string &_name,
|
||||
const std::vector<RateLimitRulesSection> &_rules)
|
||||
:
|
||||
mode(_mode),
|
||||
practice_id(_practice_id),
|
||||
name(_name),
|
||||
rules(_rules)
|
||||
{
|
||||
bool any = asset_name == "Any" && url == "Any" && uri == "Any";
|
||||
string asset_id = any ? "Any" : url+uri;
|
||||
context = "assetId(" + asset_id + ")";
|
||||
}
|
||||
|
||||
void
|
||||
RateLimitSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("context", context),
|
||||
cereal::make_nvp("mode", key_to_mode_val.at(mode)),
|
||||
cereal::make_nvp("practiceId", practice_id),
|
||||
cereal::make_nvp("name", name),
|
||||
cereal::make_nvp("rules", rules)
|
||||
);
|
||||
}
|
||||
|
||||
const string &
|
||||
RateLimitSection::getId() const
|
||||
{
|
||||
return practice_id;
|
||||
}
|
||||
|
||||
const string &
|
||||
RateLimitSection::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const string &
|
||||
RateLimitSection::getMode() const
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
void
|
||||
AccessControlRulebaseSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
vector<string> empty;
|
||||
out_ar(
|
||||
cereal::make_nvp("accessControl", empty),
|
||||
cereal::make_nvp("traditionalFirewall", empty),
|
||||
cereal::make_nvp("l4firewall", empty),
|
||||
cereal::make_nvp("rateLimit", rate_limit)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
AccessControlRulebaseWrapper::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("rulebase", rule_base)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
AccessControlRateLimiteRules::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading Access control rate limite rules";
|
||||
parseAppsecJSONKey<int>("limit", limit, archive_in);
|
||||
parseAppsecJSONKey<string>("uri", uri, archive_in);
|
||||
parseAppsecJSONKey<string>("unit", unit, archive_in);
|
||||
if (valid_units.count(unit) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY)
|
||||
<< "Access control rate limite rules units invalid: "
|
||||
<< unit;
|
||||
}
|
||||
parseAppsecJSONKey<string>("comment", comment, archive_in);
|
||||
parseAppsecJSONKey<vector<string>>("triggers", triggers, archive_in);
|
||||
}
|
||||
|
||||
const vector<string>
|
||||
AccessControlRateLimiteRules::getTriggers() const
|
||||
{
|
||||
return triggers;
|
||||
}
|
||||
|
||||
RateLimitRulesSection
|
||||
AccessControlRateLimiteRules::createRateLimitRulesSection(const RateLimitRulesTriggerSection &trigger) const
|
||||
{
|
||||
string id = "";
|
||||
try {
|
||||
id = to_string(boost::uuids::random_generator()());
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to create random id";
|
||||
}
|
||||
vector<RateLimitRulesTriggerSection> triggers_section;
|
||||
string trigger_name = trigger.getName().substr(trigger.getName().find("/") + 1);
|
||||
if (find(triggers.begin(), triggers.end(), trigger_name) != triggers.end()) {
|
||||
triggers_section.push_back(trigger);
|
||||
}
|
||||
return RateLimitRulesSection(
|
||||
limit,
|
||||
id,
|
||||
uri,
|
||||
unit,
|
||||
triggers_section
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
AccessControlRateLimit::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading Access control rate limit";
|
||||
parseAppsecJSONKey<string>("overrideMode", mode, archive_in, "Inactive");
|
||||
if (valid_modes.count(mode) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec access control rate limit override mode invalid: " << mode;
|
||||
}
|
||||
parseAppsecJSONKey<std::vector<AccessControlRateLimiteRules>>("rules", rules, archive_in);
|
||||
}
|
||||
|
||||
vector<RateLimitRulesSection>
|
||||
AccessControlRateLimit::createRateLimitRulesSection(const RateLimitRulesTriggerSection &trigger) const
|
||||
{
|
||||
vector<RateLimitRulesSection> rules_section;
|
||||
for (const AccessControlRateLimiteRules &rule : rules) {
|
||||
rules_section.push_back(rule.createRateLimitRulesSection(trigger));
|
||||
}
|
||||
return rules_section;
|
||||
}
|
||||
|
||||
const vector<AccessControlRateLimiteRules> &
|
||||
AccessControlRateLimit::getRules() const
|
||||
{
|
||||
return rules;
|
||||
}
|
||||
|
||||
const string &
|
||||
AccessControlRateLimit::getMode() const
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
void
|
||||
AccessControlPracticeSpec::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec";
|
||||
|
||||
parseAppsecJSONKey<string>("name", practice_name, archive_in);
|
||||
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
||||
parseAppsecJSONKey<AccessControlRateLimit>("rateLimit", rate_limit, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
AccessControlPracticeSpec::setName(const string &_name)
|
||||
{
|
||||
practice_name = _name;
|
||||
}
|
||||
|
||||
const AccessControlRateLimit &
|
||||
AccessControlPracticeSpec::geRateLimit() const
|
||||
{
|
||||
return rate_limit;
|
||||
}
|
||||
|
||||
const string &
|
||||
AccessControlPracticeSpec::getAppSecClassName() const
|
||||
{
|
||||
return appsec_class_name;
|
||||
}
|
||||
|
||||
const string &
|
||||
AccessControlPracticeSpec::getName() const
|
||||
{
|
||||
return practice_name;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
752
components/security_apps/local_policy_mgmt_gen/appsec_practice_section.cc
Executable file
752
components/security_apps/local_policy_mgmt_gen/appsec_practice_section.cc
Executable file
@ -0,0 +1,752 @@
|
||||
// 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 "appsec_practice_section.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"};
|
||||
static const set<string> valid_confidences = {"medium", "high", "critical"};
|
||||
|
||||
void
|
||||
AppSecWebBotsURI::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Web Bots URI";
|
||||
parseAppsecJSONKey<string>("uri", uri, archive_in);
|
||||
}
|
||||
|
||||
const string &
|
||||
AppSecWebBotsURI::getURI() const
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
|
||||
vector<string>
|
||||
AppSecPracticeAntiBot::getIjectedUris() const
|
||||
{
|
||||
vector<string> injected;
|
||||
for (const AppSecWebBotsURI &uri : injected_uris) {
|
||||
injected.push_back(uri.getURI());
|
||||
}
|
||||
return injected;
|
||||
}
|
||||
|
||||
vector<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)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Web Bots";
|
||||
parseAppsecJSONKey<vector<AppSecWebBotsURI>>("injected-URIs", injected_uris, archive_in);
|
||||
parseAppsecJSONKey<vector<AppSecWebBotsURI>>("validated-URIs", validated_uris, archive_in);
|
||||
parseAppsecJSONKey<string>("override-mode", override_mode, archive_in, "Inactive");
|
||||
if (valid_modes.count(override_mode) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec Web Bots override mode invalid: " << override_mode;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
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) validated.push_back(uri.getURI());
|
||||
out_ar(
|
||||
cereal::make_nvp("injected", injected),
|
||||
cereal::make_nvp("validated", validated)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
AppSecWebAttackProtections::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Web Attack Protections";
|
||||
parseAppsecJSONKey<string>("csrf-enabled", csrf_protection, archive_in, "inactive");
|
||||
parseAppsecJSONKey<string>("error-disclosure-enabled", error_disclosure, archive_in, "inactive");
|
||||
parseAppsecJSONKey<string>("open-redirect-enabled", open_redirect, archive_in, "inactive");
|
||||
parseAppsecJSONKey<bool>("non-valid-http-methods", non_valid_http_methods, archive_in, false);
|
||||
}
|
||||
|
||||
const string
|
||||
AppSecWebAttackProtections::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 &
|
||||
AppSecWebAttackProtections::getErrorDisclosureMode() const
|
||||
{
|
||||
return error_disclosure;
|
||||
}
|
||||
|
||||
bool
|
||||
AppSecWebAttackProtections::getNonValidHttpMethods() const
|
||||
{
|
||||
return non_valid_http_methods;
|
||||
}
|
||||
|
||||
const string
|
||||
AppSecWebAttackProtections::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
|
||||
AppSecPracticeWebAttacks::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec";
|
||||
parseAppsecJSONKey<AppSecWebAttackProtections>("protections", protections, archive_in);
|
||||
parseAppsecJSONKey<string>("override-mode", mode, archive_in, "Unset");
|
||||
if (valid_modes.count(mode) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec practice override mode invalid: " << mode;
|
||||
}
|
||||
|
||||
if (getMode() == "Prevent") {
|
||||
parseAppsecJSONKey<string>("minimum-confidence", minimum_confidence, archive_in, "critical");
|
||||
if (valid_confidences.count(minimum_confidence) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY)
|
||||
<< "AppSec practice override minimum confidence invalid: "
|
||||
<< minimum_confidence;
|
||||
}
|
||||
} else {
|
||||
minimum_confidence = "Transparent";
|
||||
}
|
||||
parseAppsecJSONKey<int>("max-body-size-kb", max_body_size_kb, archive_in, 1000000);
|
||||
parseAppsecJSONKey<int>("max-header-size-bytes", max_header_size_bytes, archive_in, 102400);
|
||||
parseAppsecJSONKey<int>("max-object-depth", max_object_depth, archive_in, 40);
|
||||
parseAppsecJSONKey<int>("max-url-size-bytes", max_url_size_bytes, archive_in, 32768);
|
||||
}
|
||||
|
||||
int
|
||||
AppSecPracticeWebAttacks::getMaxBodySizeKb() const
|
||||
{
|
||||
return max_body_size_kb;
|
||||
}
|
||||
|
||||
int
|
||||
AppSecPracticeWebAttacks::getMaxHeaderSizeBytes() const
|
||||
{
|
||||
return max_header_size_bytes;
|
||||
}
|
||||
|
||||
int
|
||||
AppSecPracticeWebAttacks::getMaxObjectDepth() const
|
||||
{
|
||||
return max_object_depth;
|
||||
}
|
||||
|
||||
int
|
||||
AppSecPracticeWebAttacks::getMaxUrlSizeBytes() const
|
||||
{
|
||||
return max_url_size_bytes;
|
||||
}
|
||||
|
||||
const string &
|
||||
AppSecPracticeWebAttacks::getMinimumConfidence() const
|
||||
{
|
||||
return minimum_confidence;
|
||||
}
|
||||
|
||||
const string &
|
||||
AppSecPracticeWebAttacks::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
|
||||
AppSecPracticeSnortSignatures::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Snort Signatures practice";
|
||||
parseAppsecJSONKey<string>("override-mode", 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 &
|
||||
AppSecPracticeSnortSignatures::getOverrideMode() const
|
||||
{
|
||||
return override_mode;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
AppSecPracticeSnortSignatures::getConfigMap() const
|
||||
{
|
||||
return config_map;
|
||||
}
|
||||
|
||||
void
|
||||
AppSecPracticeOpenSchemaAPI::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Practice OpenSchemaAPI practice";
|
||||
parseAppsecJSONKey<vector<string>>("configmap", config_map, archive_in);
|
||||
parseAppsecJSONKey<string>("override-mode", override_mode, archive_in, "Inactive");
|
||||
if (valid_modes.count(override_mode) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec Open Schema API override mode invalid: " << override_mode;
|
||||
}
|
||||
}
|
||||
|
||||
const string &
|
||||
AppSecPracticeOpenSchemaAPI::getOverrideMode() const
|
||||
{
|
||||
return override_mode;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
AppSecPracticeOpenSchemaAPI::getConfigMap() const
|
||||
{
|
||||
return config_map;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
void
|
||||
AppSecPracticeSpec::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec";
|
||||
parseAppsecJSONKey<AppSecPracticeOpenSchemaAPI>(
|
||||
"openapi-schema-validation",
|
||||
openapi_schema_validation,
|
||||
archive_in
|
||||
);
|
||||
parseAppsecJSONKey<AppSecPracticeSnortSignatures>("snort-signatures", snort_signatures, archive_in);
|
||||
parseAppsecJSONKey<AppSecPracticeWebAttacks>("web-attacks", web_attacks, archive_in);
|
||||
parseAppsecJSONKey<AppSecPracticeAntiBot>("anti-bot", anti_bot, archive_in);
|
||||
parseAppsecJSONKey<string>("name", practice_name, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
AppSecPracticeSpec::setName(const string &_name)
|
||||
{
|
||||
practice_name = _name;
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
const AppSecPracticeOpenSchemaAPI &
|
||||
AppSecPracticeSpec::getOpenSchemaValidation() const
|
||||
{
|
||||
return openapi_schema_validation;
|
||||
}
|
||||
|
||||
const AppSecPracticeSnortSignatures &
|
||||
AppSecPracticeSpec::getSnortSignatures() const
|
||||
{
|
||||
return snort_signatures;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
const AppSecPracticeWebAttacks &
|
||||
AppSecPracticeSpec::getWebAttacks() const
|
||||
{
|
||||
return web_attacks;
|
||||
}
|
||||
|
||||
const AppSecPracticeAntiBot &
|
||||
AppSecPracticeSpec::getAntiBot() const
|
||||
{
|
||||
return anti_bot;
|
||||
}
|
||||
|
||||
const string &
|
||||
AppSecPracticeSpec::getName() const
|
||||
{
|
||||
return practice_name;
|
||||
}
|
||||
|
||||
void
|
||||
PracticeAdvancedConfig::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("httpHeaderMaxSize", http_header_max_size),
|
||||
cereal::make_nvp("httpIllegalMethodsAllowed", http_illegal_methods_allowed),
|
||||
cereal::make_nvp("httpRequestBodyMaxSize", http_request_body_max_size),
|
||||
cereal::make_nvp("jsonMaxObjectDepth", json_max_object_depth),
|
||||
cereal::make_nvp("urlMaxSize", url_max_size)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
TriggersInWaapSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("$triggerType", trigger_type),
|
||||
cereal::make_nvp("id", id),
|
||||
cereal::make_nvp("name", name),
|
||||
cereal::make_nvp("log", log)
|
||||
);
|
||||
}
|
||||
|
||||
ParsedMatch::ParsedMatch(const string &_operator, const string &_tag, const string &_value)
|
||||
:
|
||||
operator_type(_operator),
|
||||
tag(_tag),
|
||||
value(_value)
|
||||
{
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
ParsedMatch::ParsedMatch(const ExceptionMatch &exceptions)
|
||||
{
|
||||
if (exceptions.getOperator() == "equals") {
|
||||
operator_type = "basic";
|
||||
tag = exceptions.getKey();
|
||||
value = exceptions.getValue();
|
||||
} else {
|
||||
operator_type = exceptions.getOperator();
|
||||
}
|
||||
for (const ExceptionMatch &exception_match : exceptions.getMatch()) {
|
||||
parsed_match.push_back(ParsedMatch(exception_match));
|
||||
}
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
void
|
||||
ParsedMatch::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
if (parsed_match.size() > 0) {
|
||||
out_ar(cereal::make_nvp("operator", operator_type));
|
||||
int i = 0;
|
||||
for (const ParsedMatch &operand : parsed_match) {
|
||||
i++;
|
||||
out_ar(cereal::make_nvp("operand" + to_string(i), operand));
|
||||
}
|
||||
} else {
|
||||
out_ar(
|
||||
cereal::make_nvp("operator", operator_type),
|
||||
cereal::make_nvp("tag", tag),
|
||||
cereal::make_nvp("value", value)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AppSecOverride::AppSecOverride(const SourcesIdentifiers &parsed_trusted_sources)
|
||||
{
|
||||
string source_ident = parsed_trusted_sources.getSourceIdent();
|
||||
map<string, string> behavior = {{"httpSourceId", source_ident}};
|
||||
parsed_behavior.push_back(behavior);
|
||||
parsed_match = ParsedMatch("BASIC", "sourceip", "0.0.0.0/0");
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
AppSecOverride::AppSecOverride(const InnerException &parsed_exceptions)
|
||||
:
|
||||
id(parsed_exceptions.getBehaviorId()),
|
||||
parsed_match(parsed_exceptions.getMatch())
|
||||
{
|
||||
map<string, string> behavior = {{parsed_exceptions.getBehaviorKey(), parsed_exceptions.getBehaviorValue()}};
|
||||
parsed_behavior.push_back(behavior);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
void
|
||||
AppSecOverride::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
if (!id.empty()) {
|
||||
out_ar(cereal::make_nvp("id", id));
|
||||
}
|
||||
out_ar(
|
||||
cereal::make_nvp("parsedBehavior", parsed_behavior),
|
||||
cereal::make_nvp("parsedMatch", parsed_match)
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
const string &_asset_name,
|
||||
const string &_rule_id,
|
||||
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,
|
||||
const AppSecTrustedSources &parsed_trusted_sources,
|
||||
const vector<InnerException> &parsed_exceptions)
|
||||
:
|
||||
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(parsed_appsec_spec.getWebAttacks().getMinimumConfidence()),
|
||||
web_attack_mitigation_mode(parsed_appsec_spec.getWebAttacks().getMode(default_mode)),
|
||||
practice_advanced_config(parsed_appsec_spec),
|
||||
anti_bots(parsed_appsec_spec.getAntiBot()),
|
||||
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));
|
||||
}
|
||||
|
||||
for (const InnerException &exception : parsed_exceptions) {
|
||||
overrides.push_back(AppSecOverride(exception));
|
||||
}
|
||||
}
|
||||
|
||||
WebAppSection::WebAppSection(
|
||||
const string &_application_urls,
|
||||
const string &_asset_id,
|
||||
const string &_asset_name,
|
||||
const string &_rule_id,
|
||||
const string &_rule_name,
|
||||
const string &_practice_id,
|
||||
const string &_practice_name,
|
||||
const string &_context,
|
||||
const string &_web_attack_mitigation_severity,
|
||||
const 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
|
||||
{
|
||||
string disabled_str = "Disabled";
|
||||
string detect_str = "Detect";
|
||||
vector<string> empty_list;
|
||||
out_ar(
|
||||
cereal::make_nvp("context", context),
|
||||
cereal::make_nvp("webAttackMitigation", web_attack_mitigation),
|
||||
cereal::make_nvp("webAttackMitigationSeverity", web_attack_mitigation_severity),
|
||||
cereal::make_nvp("webAttackMitigationAction", web_attack_mitigation_action),
|
||||
cereal::make_nvp("webAttackMitigationMode", web_attack_mitigation_mode),
|
||||
cereal::make_nvp("practiceAdvancedConfig", practice_advanced_config),
|
||||
cereal::make_nvp("csrfProtection", disabled_str),
|
||||
cereal::make_nvp("openRedirect", disabled_str),
|
||||
cereal::make_nvp("errorDisclosure", disabled_str),
|
||||
cereal::make_nvp("practiceId", practice_id),
|
||||
cereal::make_nvp("practiceName", practice_name),
|
||||
cereal::make_nvp("assetId", asset_id),
|
||||
cereal::make_nvp("assetName", asset_name),
|
||||
cereal::make_nvp("ruleId", rule_id),
|
||||
cereal::make_nvp("ruleName", rule_name),
|
||||
cereal::make_nvp("schemaValidation", false),
|
||||
cereal::make_nvp("schemaValidation_v2", disabled_str),
|
||||
cereal::make_nvp("oas", empty_list),
|
||||
cereal::make_nvp("triggers", triggers),
|
||||
cereal::make_nvp("applicationUrls", application_urls),
|
||||
cereal::make_nvp("overrides", overrides),
|
||||
cereal::make_nvp("trustedSources", trusted_sources),
|
||||
cereal::make_nvp("waapParameters", empty_list),
|
||||
cereal::make_nvp("botProtection", false),
|
||||
cereal::make_nvp("antiBot", anti_bots),
|
||||
cereal::make_nvp("botProtection_v2", detect_str)
|
||||
);
|
||||
}
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
void
|
||||
WebAPISection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
string disabled_str = "Disabled";
|
||||
vector<string> empty_list;
|
||||
out_ar(
|
||||
cereal::make_nvp("application_urls", application_urls),
|
||||
cereal::make_nvp("asset_id", asset_id),
|
||||
cereal::make_nvp("asset_name", asset_name),
|
||||
cereal::make_nvp("context", context),
|
||||
cereal::make_nvp("practiceAdvancedConfig", practice_advanced_config),
|
||||
cereal::make_nvp("practice_id", practice_id),
|
||||
cereal::make_nvp("practice_name", practice_name),
|
||||
cereal::make_nvp("ruleId", rule_id),
|
||||
cereal::make_nvp("ruleName", rule_name),
|
||||
cereal::make_nvp("schemaValidation", false),
|
||||
cereal::make_nvp("schemaValidation_v2", disabled_str),
|
||||
cereal::make_nvp("web_attack_mitigation", web_attack_mitigation),
|
||||
cereal::make_nvp("web_attack_mitigation_action", web_attack_mitigation_action),
|
||||
cereal::make_nvp("web_attack_mitigation_severity", web_attack_mitigation_severity),
|
||||
cereal::make_nvp("web_attack_mitigation_mode", web_attack_mitigation_mode),
|
||||
cereal::make_nvp("oas", empty_list),
|
||||
cereal::make_nvp("trustedSources", empty_list),
|
||||
cereal::make_nvp("triggers", empty_list),
|
||||
cereal::make_nvp("waapParameters", empty_list),
|
||||
cereal::make_nvp("overrides", empty_list)
|
||||
);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
void
|
||||
AppSecRulebase::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("WebAPISecurity", webAPIPractices),
|
||||
cereal::make_nvp("WebApplicationSecurity", webApplicationPractices)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
AppSecWrapper::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(cereal::make_nvp("WAAP", app_sec_rulebase));
|
||||
}
|
||||
|
||||
void
|
||||
ParsedRule::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec ParsedRule";
|
||||
parseAppsecJSONKey<vector<string>>("exceptions", exceptions, archive_in);
|
||||
parseAppsecJSONKey<vector<string>>("triggers", log_triggers, archive_in);
|
||||
parseAppsecJSONKey<vector<string>>("practices", practices, archive_in);
|
||||
parseAppsecJSONKey<string>("mode", mode, archive_in);
|
||||
if (valid_modes.count(mode) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec Parsed Rule mode invalid: " << mode;
|
||||
}
|
||||
parseAppsecJSONKey<string>("custom-response", custom_response, archive_in);
|
||||
parseAppsecJSONKey<string>("source-identifiers", source_identifiers, archive_in);
|
||||
parseAppsecJSONKey<string>("trusted-sources", trusted_sources, archive_in);
|
||||
try {
|
||||
archive_in(cereal::make_nvp("host", host));
|
||||
} catch (const cereal::Exception &e)
|
||||
{} // The default ParsedRule does not hold a host, so no error handling
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
ParsedRule::getExceptions() const
|
||||
{
|
||||
return exceptions;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
ParsedRule::getLogTriggers() const
|
||||
{
|
||||
return log_triggers;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
ParsedRule::getPractices() const
|
||||
{
|
||||
return practices;
|
||||
}
|
||||
|
||||
const string &
|
||||
ParsedRule::getHost() const
|
||||
{
|
||||
return host;
|
||||
}
|
||||
|
||||
const string &
|
||||
ParsedRule::getMode() const
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
void
|
||||
ParsedRule::setHost(const string &_host)
|
||||
{
|
||||
host = _host;
|
||||
}
|
||||
|
||||
void
|
||||
ParsedRule::setMode(const string &_mode)
|
||||
{
|
||||
mode = _mode;
|
||||
}
|
||||
|
||||
const string &
|
||||
ParsedRule::getCustomResponse() const
|
||||
{
|
||||
return custom_response;
|
||||
}
|
||||
|
||||
const string &
|
||||
ParsedRule::getSourceIdentifiers() const
|
||||
{
|
||||
return source_identifiers;
|
||||
}
|
||||
|
||||
const string &
|
||||
ParsedRule::getTrustedSources() const
|
||||
{
|
||||
return trusted_sources;
|
||||
}
|
||||
|
||||
void
|
||||
AppsecPolicySpec::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec policy spec";
|
||||
parseAppsecJSONKey<ParsedRule>("default", default_rule, archive_in);
|
||||
default_rule.setHost("*");
|
||||
parseAppsecJSONKey<vector<ParsedRule>>("specific-rules", specific_rules, archive_in);
|
||||
}
|
||||
|
||||
const ParsedRule &
|
||||
AppsecPolicySpec::getDefaultRule() const
|
||||
{
|
||||
return default_rule;
|
||||
}
|
||||
|
||||
const vector<ParsedRule> &
|
||||
AppsecPolicySpec::getSpecificRules() const
|
||||
{
|
||||
return specific_rules;
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecPolicySpec::isAssetHostExist(const string &full_url) const
|
||||
{
|
||||
for (const ParsedRule &rule : specific_rules) {
|
||||
if (rule.getHost() == full_url) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
AppsecPolicySpec::addSpecificRule(const ParsedRule &_rule)
|
||||
{
|
||||
specific_rules.push_back(_rule);
|
||||
}
|
||||
|
||||
void
|
||||
AppsecLinuxPolicy::serialize(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading Appsec Linux Policy";
|
||||
parseAppsecJSONKey<AppsecPolicySpec>("policies", policies, archive_in);
|
||||
parseAppsecJSONKey<vector<AppSecPracticeSpec>>("practices", practices, archive_in);
|
||||
parseAppsecJSONKey<vector<AppsecTriggerSpec>>("log-triggers", log_triggers, archive_in);
|
||||
parseAppsecJSONKey<vector<AppSecCustomResponseSpec>>("custom-responses", custom_responses, archive_in);
|
||||
parseAppsecJSONKey<vector<AppsecException>>("exceptions", exceptions, archive_in);
|
||||
parseAppsecJSONKey<vector<TrustedSourcesSpec>>("trusted-sources", trusted_sources, archive_in);
|
||||
parseAppsecJSONKey<vector<SourceIdentifierSpecWrapper>>(
|
||||
"source-identifiers",
|
||||
sources_identifiers,
|
||||
archive_in
|
||||
);
|
||||
}
|
||||
|
||||
const AppsecPolicySpec &
|
||||
AppsecLinuxPolicy::getAppsecPolicySpec() const
|
||||
{
|
||||
return policies;
|
||||
}
|
||||
|
||||
const vector<AppSecPracticeSpec> &
|
||||
AppsecLinuxPolicy::getAppSecPracticeSpecs() const
|
||||
{
|
||||
return practices;
|
||||
}
|
||||
|
||||
const vector<AppsecTriggerSpec> &
|
||||
AppsecLinuxPolicy::getAppsecTriggerSpecs() const
|
||||
{
|
||||
return log_triggers;
|
||||
}
|
||||
|
||||
const vector<AppSecCustomResponseSpec> &
|
||||
AppsecLinuxPolicy::getAppSecCustomResponseSpecs() const
|
||||
{
|
||||
return custom_responses;
|
||||
}
|
||||
|
||||
const vector<AppsecException> &
|
||||
AppsecLinuxPolicy::getAppsecExceptions() const
|
||||
{
|
||||
return exceptions;
|
||||
}
|
||||
|
||||
const vector<TrustedSourcesSpec> &
|
||||
AppsecLinuxPolicy::getAppsecTrustedSourceSpecs() const
|
||||
{
|
||||
return trusted_sources;
|
||||
}
|
||||
|
||||
const vector<SourceIdentifierSpecWrapper> &
|
||||
AppsecLinuxPolicy::getAppsecSourceIdentifierSpecs() const
|
||||
{
|
||||
return sources_identifiers;
|
||||
}
|
||||
|
||||
void
|
||||
AppsecLinuxPolicy::addSpecificRule(const ParsedRule &_rule)
|
||||
{
|
||||
policies.addSpecificRule(_rule);
|
||||
}
|
58
components/security_apps/local_policy_mgmt_gen/configmaps.cc
Executable file
58
components/security_apps/local_policy_mgmt_gen/configmaps.cc
Executable file
@ -0,0 +1,58 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "configmaps.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
bool
|
||||
ConfigMaps::loadJson(const std::string &json)
|
||||
{
|
||||
string modified_json = json;
|
||||
modified_json.pop_back();
|
||||
stringstream in;
|
||||
in.str(modified_json);
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading ConfigMaps data";
|
||||
try {
|
||||
cereal::JSONInputArchive in_ar(in);
|
||||
in_ar(
|
||||
cereal::make_nvp("data", data)
|
||||
);
|
||||
} catch (cereal::Exception &e) {
|
||||
dbgError(D_LOCAL_POLICY) << "Failed to load ConfigMaps JSON. Error: " << e.what();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
string
|
||||
ConfigMaps::getFileContent() const
|
||||
{
|
||||
if (data.size()) {
|
||||
return data.begin()->second;
|
||||
}
|
||||
return string();
|
||||
}
|
||||
|
||||
string
|
||||
ConfigMaps::getFileName() const
|
||||
{
|
||||
if (data.size()) {
|
||||
return data.begin()->first;
|
||||
}
|
||||
return string();
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
418
components/security_apps/local_policy_mgmt_gen/exceptions_section.cc
Executable file
418
components/security_apps/local_policy_mgmt_gen/exceptions_section.cc
Executable file
@ -0,0 +1,418 @@
|
||||
// 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 "exceptions_section.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
using AttributeGetter = function<vector<string>(const AppsecExceptionSpec&)>;
|
||||
static const vector<pair<string, AttributeGetter>> attributes = {
|
||||
{"countryCode", [](const AppsecExceptionSpec& e){ return e.getCountryCode(); }},
|
||||
{"countryName", [](const AppsecExceptionSpec& e){ return e.getCountryName(); }},
|
||||
{"hostName", [](const AppsecExceptionSpec& e){ return e.getHostName(); }},
|
||||
{"paramName", [](const AppsecExceptionSpec& e){ return e.getParamName(); }},
|
||||
{"paramValue", [](const AppsecExceptionSpec& e){ return e.getParamValue(); }},
|
||||
{"protectionName", [](const AppsecExceptionSpec& e){ return e.getProtectionName(); }},
|
||||
{"sourceIdentifier", [](const AppsecExceptionSpec& e){ return e.getSourceIdentifier(); }},
|
||||
{"sourceIp", [](const AppsecExceptionSpec& e){ return e.getSourceIp(); }},
|
||||
{"url", [](const AppsecExceptionSpec& e){ return e.getUrl(); }}
|
||||
};
|
||||
static const set<string> valid_actions = {"skip", "accept", "drop", "suppressLog"};
|
||||
static const unordered_map<string, string> key_to_action = {
|
||||
{ "accept", "accept"},
|
||||
{ "drop", "reject"},
|
||||
{ "skip", "ignore"},
|
||||
{ "suppressLog", "ignore"}
|
||||
};
|
||||
|
||||
void
|
||||
AppsecExceptionSpec::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec exception spec";
|
||||
parseAppsecJSONKey<string>("action", action, archive_in, "skip");
|
||||
if (valid_actions.count(action) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec exception action invalid: " << action;
|
||||
}
|
||||
|
||||
parseAppsecJSONKey<vector<string>>("countryCode", country_code, archive_in);
|
||||
if (!country_code.empty()) conditions_number++;
|
||||
|
||||
parseAppsecJSONKey<vector<string>>("countryName", country_name, archive_in);
|
||||
if (!country_name.empty()) conditions_number++;
|
||||
|
||||
parseAppsecJSONKey<vector<string>>("hostName", host_name, archive_in);
|
||||
if (!host_name.empty()) conditions_number++;
|
||||
|
||||
parseAppsecJSONKey<vector<string>>("paramName", param_name, archive_in);
|
||||
if (!param_name.empty()) conditions_number++;
|
||||
|
||||
parseAppsecJSONKey<vector<string>>("paramValue", param_value, archive_in);
|
||||
if (!param_value.empty()) conditions_number++;
|
||||
|
||||
parseAppsecJSONKey<vector<string>>("protectionName", protection_name, archive_in);
|
||||
if (!protection_name.empty()) conditions_number++;
|
||||
|
||||
parseAppsecJSONKey<vector<string>>("sourceIdentifier", source_identifier, archive_in);
|
||||
if (!source_identifier.empty()) conditions_number++;
|
||||
|
||||
parseAppsecJSONKey<vector<string>>("sourceIp", source_ip, archive_in);
|
||||
if (!source_ip.empty()) conditions_number++;
|
||||
|
||||
parseAppsecJSONKey<vector<string>>("url", url, archive_in);
|
||||
if (!url.empty()) conditions_number++;
|
||||
}
|
||||
|
||||
const string &
|
||||
AppsecExceptionSpec::getAction() const
|
||||
{
|
||||
return action;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
AppsecExceptionSpec::getCountryCode() const
|
||||
{
|
||||
return country_code;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
AppsecExceptionSpec::getCountryName() const
|
||||
{
|
||||
return country_name;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
AppsecExceptionSpec::getHostName() const
|
||||
{
|
||||
return host_name;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
AppsecExceptionSpec::getParamName() const
|
||||
{
|
||||
return param_name;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
AppsecExceptionSpec::getParamValue() const
|
||||
{
|
||||
return param_value;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
AppsecExceptionSpec::getProtectionName() const
|
||||
{
|
||||
return protection_name;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
AppsecExceptionSpec::getSourceIdentifier() const
|
||||
{
|
||||
return source_identifier;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
AppsecExceptionSpec::getSourceIp() const
|
||||
{
|
||||
return source_ip;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
AppsecExceptionSpec::getUrl() const
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecExceptionSpec::isOneCondition() const
|
||||
{
|
||||
return conditions_number == 1;
|
||||
}
|
||||
|
||||
void
|
||||
AppsecException::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec exception";
|
||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||
archive_in(CEREAL_NVP(exception_spec));
|
||||
}
|
||||
|
||||
void
|
||||
AppsecException::setName(const string &_name)
|
||||
{
|
||||
name = _name;
|
||||
}
|
||||
|
||||
const string &
|
||||
AppsecException::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const vector<AppsecExceptionSpec> &
|
||||
AppsecException::getExceptions() const
|
||||
{
|
||||
return exception_spec;
|
||||
}
|
||||
|
||||
ExceptionMatch::ExceptionMatch(const AppsecExceptionSpec &parsed_exception)
|
||||
:
|
||||
match_type(MatchType::Operator),
|
||||
op("and")
|
||||
{
|
||||
bool single_condition = parsed_exception.isOneCondition();
|
||||
for (auto &attrib : attributes) {
|
||||
auto &attrib_name = attrib.first;
|
||||
auto &attrib_getter = attrib.second;
|
||||
auto exceptions_value = attrib_getter(parsed_exception);
|
||||
if (exceptions_value.empty()) continue;
|
||||
if (single_condition) {
|
||||
if (exceptions_value.size() == 1) {
|
||||
match_type = MatchType::Condition;
|
||||
op = "equals";
|
||||
key = attrib_name;
|
||||
value = exceptions_value;
|
||||
return;
|
||||
} else {
|
||||
match_type = MatchType::Operator;
|
||||
op = "or";
|
||||
for (auto new_value : exceptions_value) {
|
||||
items.push_back(ExceptionMatch(attrib_name, {new_value}));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
items.push_back(ExceptionMatch(attrib_name, exceptions_value));
|
||||
}
|
||||
}
|
||||
|
||||
ExceptionMatch::ExceptionMatch(const std::string &_key, const std::vector<std::string> &values)
|
||||
{
|
||||
if (values.size() == 1) {
|
||||
match_type = MatchType::Condition;
|
||||
op = "equals";
|
||||
key = _key;
|
||||
value = values;
|
||||
} else {
|
||||
match_type = MatchType::Operator;
|
||||
op = "or";
|
||||
for (auto new_value : values) {
|
||||
items.push_back(ExceptionMatch(_key, {new_value}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
switch (match_type) {
|
||||
case (MatchType::Condition): {
|
||||
string type_str = "condition";
|
||||
out_ar(
|
||||
cereal::make_nvp("key", key),
|
||||
cereal::make_nvp("op", op),
|
||||
cereal::make_nvp("type", type_str),
|
||||
cereal::make_nvp("value", value)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case (MatchType::Operator): {
|
||||
string type_str = "operator";
|
||||
out_ar(
|
||||
cereal::make_nvp("op", op),
|
||||
cereal::make_nvp("type", type_str),
|
||||
cereal::make_nvp("items", items)
|
||||
);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
dbgError(D_LOCAL_POLICY) << "No match for exception match type: " << static_cast<int>(match_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const string &
|
||||
ExceptionMatch::getOperator() const
|
||||
{
|
||||
return op;
|
||||
}
|
||||
|
||||
const string &
|
||||
ExceptionMatch::getKey() const
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
const string &
|
||||
ExceptionMatch::getValue() const
|
||||
{
|
||||
return value[0];
|
||||
}
|
||||
|
||||
const vector<ExceptionMatch> &
|
||||
ExceptionMatch::getMatch() const
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
ExceptionBehavior::ExceptionBehavior(const string &_value)
|
||||
{
|
||||
key = _value == "suppressLog" ? "log" : "action";
|
||||
value = key_to_action.at(_value);
|
||||
try {
|
||||
id = to_string(boost::uuids::random_generator()());
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to generate exception behavior UUID. Error: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ExceptionBehavior::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("key", key),
|
||||
cereal::make_nvp("value", value),
|
||||
cereal::make_nvp("id", id)
|
||||
);
|
||||
}
|
||||
|
||||
const string &
|
||||
ExceptionBehavior::getBehaviorId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
const string &
|
||||
ExceptionBehavior::getBehaviorKey() const
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
const string &
|
||||
ExceptionBehavior::getBehaviorValue() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
InnerException::InnerException(ExceptionBehavior _behavior, ExceptionMatch _match)
|
||||
:
|
||||
behavior(_behavior),
|
||||
match(_match)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
InnerException::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("behavior", behavior),
|
||||
cereal::make_nvp("match", match)
|
||||
);
|
||||
}
|
||||
|
||||
const string &
|
||||
InnerException::getBehaviorId() const
|
||||
{
|
||||
return behavior.getBehaviorId();
|
||||
}
|
||||
|
||||
const string &
|
||||
InnerException::getBehaviorKey() const
|
||||
{
|
||||
return behavior.getBehaviorKey();
|
||||
}
|
||||
|
||||
const string &
|
||||
InnerException::getBehaviorValue() const
|
||||
{
|
||||
return behavior.getBehaviorValue();
|
||||
}
|
||||
|
||||
const ExceptionMatch &
|
||||
InnerException::getMatch() const
|
||||
{
|
||||
return match;
|
||||
}
|
||||
|
||||
ExceptionsRulebase::ExceptionsRulebase(
|
||||
vector<InnerException> _exceptions)
|
||||
:
|
||||
exceptions(_exceptions)
|
||||
{
|
||||
string context_id_str = "";
|
||||
for (const InnerException & exception : exceptions) {
|
||||
string curr_id = "parameterId(" + exception.getBehaviorId() + "), ";
|
||||
context_id_str += curr_id;
|
||||
}
|
||||
context_id_str = context_id_str.substr(0, context_id_str.size() - 2);
|
||||
context = "Any(" + context_id_str + ")";
|
||||
}
|
||||
|
||||
void
|
||||
ExceptionsRulebase::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("context", context),
|
||||
cereal::make_nvp("exceptions", exceptions)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
ExceptionsWrapper::Exception::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(cereal::make_nvp("exception", exception));
|
||||
}
|
||||
|
||||
void
|
||||
ExceptionsWrapper::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("rulebase", exception_rulebase)
|
||||
);
|
||||
}
|
192
components/security_apps/local_policy_mgmt_gen/include/access_control_practice.h
Executable file
192
components/security_apps/local_policy_mgmt_gen/include/access_control_practice.h
Executable file
@ -0,0 +1,192 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __ACCESS_CONTROL_PRACTICE_H__
|
||||
#define __ACCESS_CONTROL_PRACTICE_H__
|
||||
|
||||
#include <string>
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "local_policy_common.h"
|
||||
|
||||
class RateLimitRulesTriggerSection
|
||||
{
|
||||
public:
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
RateLimitRulesTriggerSection() {};
|
||||
|
||||
RateLimitRulesTriggerSection(
|
||||
const std::string &_id,
|
||||
const std::string &_name,
|
||||
const std::string &_type
|
||||
)
|
||||
:
|
||||
id(_id),
|
||||
name(_name),
|
||||
type(_type)
|
||||
{};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
const std::string & getName() const;
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
std::string name;
|
||||
std::string type;;
|
||||
};
|
||||
|
||||
class RateLimitRulesSection
|
||||
{
|
||||
public:
|
||||
RateLimitRulesSection() {};
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
RateLimitRulesSection(
|
||||
const int _limit,
|
||||
const std::string &_id,
|
||||
const std::string &_uri,
|
||||
const std::string &_scope,
|
||||
const std::vector<RateLimitRulesTriggerSection> &_triggers
|
||||
)
|
||||
:
|
||||
limit(_limit),
|
||||
id(_id),
|
||||
uri(_uri),
|
||||
scope(_scope),
|
||||
triggers(_triggers)
|
||||
{};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
int limit;
|
||||
std::string id;
|
||||
std::string uri;
|
||||
std::string scope;
|
||||
std::vector<RateLimitRulesTriggerSection> triggers;
|
||||
};
|
||||
|
||||
class RateLimitSection
|
||||
{
|
||||
public:
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
RateLimitSection() {};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
RateLimitSection(
|
||||
const std::string &asset_name,
|
||||
const std::string &url,
|
||||
const std::string &uri,
|
||||
const std::string &_mode,
|
||||
const std::string &_practice_id,
|
||||
const std::string &_name,
|
||||
const std::vector<RateLimitRulesSection> &_rules);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
const std::string & getId() const;
|
||||
const std::string & getName() const;
|
||||
const std::string & getMode() const;
|
||||
|
||||
private:
|
||||
std::string context;
|
||||
std::string mode;
|
||||
std::string practice_id;
|
||||
std::string name;
|
||||
std::vector<RateLimitRulesSection> rules;
|
||||
};
|
||||
|
||||
class AccessControlRulebaseSection
|
||||
{
|
||||
public:
|
||||
AccessControlRulebaseSection() {};
|
||||
|
||||
AccessControlRulebaseSection(const std::vector<RateLimitSection> &_rate_limit) : rate_limit(_rate_limit) {};
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::vector<RateLimitSection> rate_limit;
|
||||
};
|
||||
|
||||
class AccessControlRulebaseWrapper
|
||||
{
|
||||
public:
|
||||
AccessControlRulebaseWrapper() {};
|
||||
|
||||
AccessControlRulebaseWrapper(
|
||||
const std::vector<RateLimitSection> &rate_limits
|
||||
)
|
||||
:
|
||||
rule_base(AccessControlRulebaseSection(rate_limits))
|
||||
{};
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
AccessControlRulebaseSection rule_base;
|
||||
};
|
||||
|
||||
class AccessControlRateLimiteRules
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::vector<std::string> getTriggers() const;
|
||||
RateLimitRulesSection createRateLimitRulesSection(const RateLimitRulesTriggerSection &trigger) const;
|
||||
|
||||
private:
|
||||
int limit;
|
||||
std::string uri;
|
||||
std::string unit;
|
||||
std::string comment;
|
||||
std::vector<std::string> triggers;
|
||||
};
|
||||
|
||||
class AccessControlRateLimit
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::vector<AccessControlRateLimiteRules> & getRules() const;
|
||||
const std::string & getMode() const;
|
||||
std::vector<RateLimitRulesSection> createRateLimitRulesSection(const RateLimitRulesTriggerSection &trigger) const;
|
||||
|
||||
private:
|
||||
std::string mode;
|
||||
std::vector<AccessControlRateLimiteRules> rules;
|
||||
};
|
||||
|
||||
class AccessControlPracticeSpec
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const AccessControlRateLimit & geRateLimit() const;
|
||||
const std::string & getAppSecClassName() const;
|
||||
const std::string & getName() const;
|
||||
void setName(const std::string &_name);
|
||||
|
||||
private:
|
||||
AccessControlRateLimit rate_limit;
|
||||
std::string appsec_class_name;
|
||||
std::string practice_name;
|
||||
};
|
||||
|
||||
#endif // __ACCESS_CONTROL_PRACTICE_H__
|
@ -0,0 +1,486 @@
|
||||
// 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 __APPSEC_PRACTICE_SECTION_H__
|
||||
#define __APPSEC_PRACTICE_SECTION_H__
|
||||
|
||||
#include <list>
|
||||
#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 "local_policy_common.h"
|
||||
#include "triggers_section.h"
|
||||
#include "exceptions_section.h"
|
||||
#include "trusted_sources_section.h"
|
||||
#include "new_practice.h"
|
||||
|
||||
class AppSecWebBotsURI
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getURI() const;
|
||||
|
||||
private:
|
||||
std::string uri;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
std::string override_mode;
|
||||
std::vector<AppSecWebBotsURI> injected_uris;
|
||||
std::vector<AppSecWebBotsURI> validated_uris;
|
||||
};
|
||||
|
||||
class AppSecWebAttackProtections
|
||||
{
|
||||
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 AppSecPracticeWebAttacks
|
||||
{
|
||||
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 AppSecWebAttackProtections & 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;
|
||||
AppSecWebAttackProtections protections;
|
||||
};
|
||||
|
||||
class AppSecPracticeSnortSignatures
|
||||
{
|
||||
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 AppSecPracticeOpenSchemaAPI
|
||||
{
|
||||
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 AppSecPracticeSpec
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const AppSecPracticeOpenSchemaAPI & getOpenSchemaValidation() const;
|
||||
const AppSecPracticeSnortSignatures & getSnortSignatures() const;
|
||||
const AppSecPracticeWebAttacks & getWebAttacks() const;
|
||||
const AppSecPracticeAntiBot & getAntiBot() const;
|
||||
const std::string & getName() const;
|
||||
void setName(const std::string &_name);
|
||||
|
||||
private:
|
||||
AppSecPracticeOpenSchemaAPI openapi_schema_validation;
|
||||
AppSecPracticeSnortSignatures snort_signatures;
|
||||
AppSecPracticeWebAttacks web_attacks;
|
||||
AppSecPracticeAntiBot anti_bot;
|
||||
std::string practice_name;
|
||||
};
|
||||
|
||||
class PracticeAdvancedConfig
|
||||
{
|
||||
public:
|
||||
PracticeAdvancedConfig() {}
|
||||
|
||||
PracticeAdvancedConfig(const AppSecPracticeSpec &parsed_appsec_spec)
|
||||
:
|
||||
http_header_max_size(parsed_appsec_spec.getWebAttacks().getMaxHeaderSizeBytes()),
|
||||
http_illegal_methods_allowed(0),
|
||||
http_request_body_max_size(parsed_appsec_spec.getWebAttacks().getMaxBodySizeKb()),
|
||||
json_max_object_depth(parsed_appsec_spec.getWebAttacks().getMaxObjectDepth()),
|
||||
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:
|
||||
int http_header_max_size;
|
||||
int http_illegal_methods_allowed;
|
||||
int http_request_body_max_size;
|
||||
int json_max_object_depth;
|
||||
int url_max_size;
|
||||
};
|
||||
|
||||
class TriggersInWaapSection
|
||||
{
|
||||
public:
|
||||
TriggersInWaapSection(const LogTriggerSection &log_section)
|
||||
:
|
||||
trigger_type("log"),
|
||||
id(log_section.getTriggerId()),
|
||||
name(log_section.getTriggerName()),
|
||||
log(log_section)
|
||||
{}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string trigger_type;
|
||||
std::string id;
|
||||
std::string name;
|
||||
LogTriggerSection log;
|
||||
};
|
||||
|
||||
class ParsedMatch
|
||||
{
|
||||
public:
|
||||
ParsedMatch() {}
|
||||
ParsedMatch(const std::string &_operator, const std::string &_tag, const std::string &_value);
|
||||
|
||||
ParsedMatch(const ExceptionMatch &exceptions);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string operator_type;
|
||||
std::string tag;
|
||||
std::string value;
|
||||
std::vector<ParsedMatch> parsed_match;
|
||||
};
|
||||
|
||||
class AppSecOverride
|
||||
{
|
||||
public:
|
||||
AppSecOverride(const SourcesIdentifiers &parsed_trusted_sources);
|
||||
AppSecOverride(const InnerException &parsed_exceptions);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
std::vector<std::map<std::string, std::string>> parsed_behavior;
|
||||
ParsedMatch 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:
|
||||
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 std::string &_context,
|
||||
const AppSecPracticeSpec &parsed_appsec_spec,
|
||||
const LogTriggerSection &parsed_log_trigger,
|
||||
const std::string &default_mode,
|
||||
const AppSecTrustedSources &parsed_trusted_sources,
|
||||
const std::vector<InnerException> &parsed_exceptions
|
||||
);
|
||||
|
||||
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:
|
||||
std::string application_urls;
|
||||
std::string asset_id;
|
||||
std::string asset_name;
|
||||
std::string rule_id;
|
||||
std::string rule_name;
|
||||
std::string practice_id;
|
||||
std::string practice_name;
|
||||
std::string context;
|
||||
std::string web_attack_mitigation_action;
|
||||
std::string web_attack_mitigation_severity;
|
||||
std::string web_attack_mitigation_mode;
|
||||
bool web_attack_mitigation;
|
||||
std::vector<TriggersInWaapSection> triggers;
|
||||
PracticeAdvancedConfig practice_advanced_config;
|
||||
AppsecPracticeAntiBotSection anti_bots;
|
||||
std::vector<AppSecTrustedSources> trusted_sources;
|
||||
std::vector<AppSecOverride> overrides;
|
||||
};
|
||||
|
||||
class WebAPISection
|
||||
{
|
||||
public:
|
||||
WebAPISection(
|
||||
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 &_web_attack_mitigation_action,
|
||||
const std::string &_web_attack_mitigation_severity,
|
||||
const std::string &_web_attack_mitigation_mode,
|
||||
bool _web_attack_mitigation,
|
||||
const PracticeAdvancedConfig &_practice_advanced_config)
|
||||
:
|
||||
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("practiceId(" + practice_id +")"),
|
||||
web_attack_mitigation_action(_web_attack_mitigation_action),
|
||||
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(_practice_advanced_config)
|
||||
{}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string application_urls;
|
||||
std::string asset_id;
|
||||
std::string asset_name;
|
||||
std::string rule_id;
|
||||
std::string rule_name;
|
||||
std::string practice_id;
|
||||
std::string practice_name;
|
||||
std::string context;
|
||||
std::string web_attack_mitigation_action;
|
||||
std::string web_attack_mitigation_severity;
|
||||
std::string web_attack_mitigation_mode;
|
||||
bool web_attack_mitigation;
|
||||
PracticeAdvancedConfig practice_advanced_config;
|
||||
};
|
||||
|
||||
class AppSecRulebase
|
||||
{
|
||||
public:
|
||||
AppSecRulebase(
|
||||
std::vector<WebAppSection> _webApplicationPractices,
|
||||
std::vector<WebAPISection> _webAPIPractices)
|
||||
:
|
||||
webApplicationPractices(_webApplicationPractices),
|
||||
webAPIPractices(_webAPIPractices) {}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::vector<WebAppSection> webApplicationPractices;
|
||||
std::vector<WebAPISection> webAPIPractices;
|
||||
};
|
||||
|
||||
|
||||
class AppSecWrapper
|
||||
{
|
||||
public:
|
||||
AppSecWrapper(const AppSecRulebase &_app_sec)
|
||||
:
|
||||
app_sec_rulebase(_app_sec)
|
||||
{}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
AppSecRulebase app_sec_rulebase;
|
||||
};
|
||||
|
||||
class ParsedRule
|
||||
{
|
||||
public:
|
||||
ParsedRule() {}
|
||||
ParsedRule(const std::string &_host) : host(_host) {}
|
||||
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
const std::vector<std::string> & getExceptions() const;
|
||||
const std::vector<std::string> & getLogTriggers() const;
|
||||
const std::vector<std::string> & getPractices() const;
|
||||
const std::string & getHost() const;
|
||||
const std::string & getMode() const;
|
||||
void setHost(const std::string &_host);
|
||||
void setMode(const std::string &_mode);
|
||||
const std::string & getCustomResponse() const;
|
||||
const std::string & getSourceIdentifiers() const;
|
||||
const std::string & getTrustedSources() const;
|
||||
|
||||
private:
|
||||
std::vector<std::string> exceptions;
|
||||
std::vector<std::string> log_triggers;
|
||||
std::vector<std::string> practices;
|
||||
std::string host;
|
||||
std::string mode;
|
||||
std::string custom_response;
|
||||
std::string source_identifiers;
|
||||
std::string trusted_sources;
|
||||
};
|
||||
|
||||
class AppsecPolicySpec : Singleton::Consume<I_Environment>
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const ParsedRule & getDefaultRule() const;
|
||||
const std::vector<ParsedRule> & getSpecificRules() const;
|
||||
bool isAssetHostExist(const std::string &full_url) const;
|
||||
void addSpecificRule(const ParsedRule &_rule);
|
||||
|
||||
private:
|
||||
ParsedRule default_rule;
|
||||
std::vector<ParsedRule> specific_rules;
|
||||
};
|
||||
|
||||
class AppsecLinuxPolicy : Singleton::Consume<I_Environment>
|
||||
{
|
||||
public:
|
||||
AppsecLinuxPolicy() {}
|
||||
AppsecLinuxPolicy(
|
||||
const AppsecPolicySpec &_policies,
|
||||
const std::vector<AppSecPracticeSpec> &_practices,
|
||||
const std::vector<AppsecTriggerSpec> &_log_triggers,
|
||||
const std::vector<AppSecCustomResponseSpec> &_custom_responses,
|
||||
const std::vector<AppsecException> &_exceptions,
|
||||
const std::vector<TrustedSourcesSpec> &_trusted_sources,
|
||||
const std::vector<SourceIdentifierSpecWrapper> &_sources_identifiers)
|
||||
:
|
||||
policies(_policies),
|
||||
practices(_practices),
|
||||
log_triggers(_log_triggers),
|
||||
custom_responses(_custom_responses),
|
||||
exceptions(_exceptions),
|
||||
trusted_sources(_trusted_sources),
|
||||
sources_identifiers(_sources_identifiers) {}
|
||||
|
||||
void serialize(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const AppsecPolicySpec & getAppsecPolicySpec() const;
|
||||
const std::vector<AppSecPracticeSpec> & getAppSecPracticeSpecs() const;
|
||||
const std::vector<AppsecTriggerSpec> & getAppsecTriggerSpecs() const;
|
||||
const std::vector<AppSecCustomResponseSpec> & getAppSecCustomResponseSpecs() const;
|
||||
const std::vector<AppsecException> & getAppsecExceptions() const;
|
||||
const std::vector<TrustedSourcesSpec> & getAppsecTrustedSourceSpecs() const;
|
||||
const std::vector<SourceIdentifierSpecWrapper> & getAppsecSourceIdentifierSpecs() const;
|
||||
void addSpecificRule(const ParsedRule &_rule);
|
||||
|
||||
private:
|
||||
AppsecPolicySpec policies;
|
||||
std::vector<AppSecPracticeSpec> practices;
|
||||
std::vector<AppsecTriggerSpec> log_triggers;
|
||||
std::vector<AppSecCustomResponseSpec> custom_responses;
|
||||
std::vector<AppsecException> exceptions;
|
||||
std::vector<TrustedSourcesSpec> trusted_sources;
|
||||
std::vector<SourceIdentifierSpecWrapper> sources_identifiers;
|
||||
};
|
||||
|
||||
#endif // __APPSEC_PRACTICE_SECTION_H__
|
41
components/security_apps/local_policy_mgmt_gen/include/configmaps.h
Executable file
41
components/security_apps/local_policy_mgmt_gen/include/configmaps.h
Executable file
@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __CONFIGMAPS_H__
|
||||
#define __CONFIGMAPS_H__
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "rest.h"
|
||||
#include "cereal/archives/json.hpp"
|
||||
#include <cereal/types/map.hpp>
|
||||
#include "customized_cereal_map.h"
|
||||
|
||||
#include "local_policy_common.h"
|
||||
|
||||
class ConfigMaps : public ClientRest
|
||||
{
|
||||
public:
|
||||
bool loadJson(const std::string &json);
|
||||
|
||||
std::string getFileContent() const;
|
||||
std::string getFileName() const;
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> data;
|
||||
};
|
||||
|
||||
#endif // __CONFIGMAPS_H__
|
@ -0,0 +1,171 @@
|
||||
// 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 __EXCEPTPIONS_SECTION_H__
|
||||
#define __EXCEPTPIONS_SECTION_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"
|
||||
#include "new_exceptions.h"
|
||||
|
||||
class AppsecExceptionSpec
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getAction() 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;
|
||||
bool isOneCondition() const;
|
||||
|
||||
private:
|
||||
int conditions_number;
|
||||
std::string action;
|
||||
std::vector<std::string> country_code;
|
||||
std::vector<std::string> country_name;
|
||||
std::vector<std::string> host_name;
|
||||
std::vector<std::string> param_name;
|
||||
std::vector<std::string> param_value;
|
||||
std::vector<std::string> protection_name;
|
||||
std::vector<std::string> source_identifier;
|
||||
std::vector<std::string> source_ip;
|
||||
std::vector<std::string> url;
|
||||
};
|
||||
|
||||
class AppsecException
|
||||
{
|
||||
public:
|
||||
AppsecException() {};
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
AppsecException(const std::string &_name, const std::vector<AppsecExceptionSpec> &_exception_spec)
|
||||
:
|
||||
name(_name),
|
||||
exception_spec(_exception_spec) {};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getName() const;
|
||||
const std::vector<AppsecExceptionSpec> & getExceptions() const;
|
||||
void setName(const std::string &_name);
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::vector<AppsecExceptionSpec> exception_spec;
|
||||
};
|
||||
|
||||
class ExceptionMatch
|
||||
{
|
||||
public:
|
||||
ExceptionMatch() {}
|
||||
ExceptionMatch(const AppsecExceptionSpec &parsed_exception);
|
||||
ExceptionMatch(const std::string &_key, const std::vector<std::string> &_value);
|
||||
ExceptionMatch(const NewAppsecException &parsed_exception);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
const std::string & getOperator() const;
|
||||
const std::string & getKey() const;
|
||||
const std::string & getValue() const;
|
||||
const std::vector<ExceptionMatch> & getMatch() const;
|
||||
|
||||
private:
|
||||
MatchType match_type;
|
||||
std::string key;
|
||||
std::string op;
|
||||
std::vector<std::string> value;
|
||||
std::vector<ExceptionMatch> items;
|
||||
};
|
||||
|
||||
class ExceptionBehavior
|
||||
{
|
||||
public:
|
||||
ExceptionBehavior() {}
|
||||
ExceptionBehavior(const std::string &_value);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
const std::string & getBehaviorId() const;
|
||||
const std::string & getBehaviorKey() const;
|
||||
const std::string & getBehaviorValue() const;
|
||||
|
||||
private:
|
||||
std::string key;
|
||||
std::string id;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
class InnerException
|
||||
{
|
||||
public:
|
||||
InnerException() {}
|
||||
InnerException(ExceptionBehavior _behavior, ExceptionMatch _match);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
const std::string & getBehaviorId() const;
|
||||
const std::string & getBehaviorKey() const;
|
||||
const std::string & getBehaviorValue() const;
|
||||
const ExceptionMatch & getMatch() const;
|
||||
|
||||
private:
|
||||
ExceptionBehavior behavior;
|
||||
ExceptionMatch match;
|
||||
};
|
||||
|
||||
class ExceptionsRulebase
|
||||
{
|
||||
public:
|
||||
ExceptionsRulebase(std::vector<InnerException> _exceptions);
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string context;
|
||||
std::vector<InnerException> exceptions;
|
||||
};
|
||||
|
||||
class ExceptionsWrapper
|
||||
{
|
||||
public:
|
||||
class Exception
|
||||
{
|
||||
public:
|
||||
Exception(const std::vector<ExceptionsRulebase> &_exception) : exception(_exception) {}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::vector<ExceptionsRulebase> exception;
|
||||
};
|
||||
ExceptionsWrapper(const std::vector<ExceptionsRulebase> &_exception) : exception_rulebase(Exception(_exception))
|
||||
{}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
Exception exception_rulebase;
|
||||
};
|
||||
#endif // __EXCEPTPIONS_SECTION_H__
|
@ -0,0 +1,125 @@
|
||||
// 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 __INGRESS_DATA_H__
|
||||
#define __INGRESS_DATA_H__
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "rest.h"
|
||||
#include "cereal/archives/json.hpp"
|
||||
#include <cereal/types/map.hpp>
|
||||
#include "customized_cereal_map.h"
|
||||
|
||||
#include "local_policy_common.h"
|
||||
|
||||
class IngressMetadata
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::map<std::string, std::string> & getAnnotations() const;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::string resourceVersion;
|
||||
std::string namespace_name;
|
||||
std::map<std::string, std::string> annotations;
|
||||
};
|
||||
|
||||
class IngressRulePath
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getPath() const;
|
||||
|
||||
private:
|
||||
std::string path;
|
||||
};
|
||||
|
||||
class IngressRulePathsWrapper
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::vector<IngressRulePath> & getRulePaths() const;
|
||||
|
||||
private:
|
||||
std::vector<IngressRulePath> paths;
|
||||
};
|
||||
|
||||
class IngressDefinedRule
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getHost() const;
|
||||
const IngressRulePathsWrapper & getPathsWrapper() const;
|
||||
|
||||
private:
|
||||
std::string host;
|
||||
IngressRulePathsWrapper paths_wrapper;
|
||||
};
|
||||
|
||||
class DefaultBackend
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &);
|
||||
|
||||
private:
|
||||
bool is_exists = false;
|
||||
};
|
||||
|
||||
class IngressSpec
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::vector<IngressDefinedRule> & getRules() const;
|
||||
|
||||
private:
|
||||
std::string ingress_class_name;
|
||||
std::vector<IngressDefinedRule> rules;
|
||||
DefaultBackend default_backend;
|
||||
};
|
||||
|
||||
class SingleIngressData
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const IngressMetadata & getMetadata() const;
|
||||
const IngressSpec & getSpec() const;
|
||||
|
||||
private:
|
||||
IngressMetadata metadata;
|
||||
IngressSpec spec;
|
||||
};
|
||||
|
||||
|
||||
class IngressData : public ClientRest
|
||||
{
|
||||
public:
|
||||
bool loadJson(const std::string &json);
|
||||
|
||||
const std::vector<SingleIngressData> & getItems() const;
|
||||
|
||||
private:
|
||||
std::string apiVersion;
|
||||
std::vector<SingleIngressData> items;
|
||||
};
|
||||
#endif // __INGRESS_DATA_H__
|
@ -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.
|
||||
|
||||
#ifndef __K8S_POLICY_UTILS_H__
|
||||
#define __K8S_POLICY_UTILS_H__
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <utility>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <cereal/archives/json.hpp>
|
||||
|
||||
#include "maybe_res.h"
|
||||
#include "i_orchestration_tools.h"
|
||||
#include "i_shell_cmd.h"
|
||||
#include "i_messaging.h"
|
||||
#include "i_env_details.h"
|
||||
#include "i_agent_details.h"
|
||||
#include "appsec_practice_section.h"
|
||||
#include "new_appsec_linux_policy.h"
|
||||
#include "policy_maker_utils.h"
|
||||
|
||||
enum class AnnotationKeys { PolicyKey, OpenAppsecIo, SyslogAddressKey, SyslogPortKey, ModeKey };
|
||||
|
||||
class K8sPolicyUtils
|
||||
:
|
||||
Singleton::Consume<I_Environment>,
|
||||
Singleton::Consume<I_OrchestrationTools>,
|
||||
Singleton::Consume<I_Messaging>,
|
||||
Singleton::Consume<I_ShellCmd>,
|
||||
Singleton::Consume<I_EnvDetails>,
|
||||
Singleton::Consume<I_AgentDetails>
|
||||
{
|
||||
public:
|
||||
void init();
|
||||
|
||||
std::tuple<std::map<std::string, AppsecLinuxPolicy>, std::map<std::string, V1beta2AppsecLinuxPolicy>>
|
||||
createAppsecPoliciesFromIngresses();
|
||||
void getClusterId() const;
|
||||
|
||||
private:
|
||||
std::map<AnnotationKeys, std::string> parseIngressAnnotations(
|
||||
const std::map<std::string, std::string> &annotations
|
||||
) const;
|
||||
|
||||
template<class T>
|
||||
Maybe<T, std::string> getObjectFromCluster(const std::string &path) const;
|
||||
|
||||
std::map<AnnotationTypes, std::unordered_set<std::string>> extractElementsNames(
|
||||
const std::vector<ParsedRule> &specific_rules,
|
||||
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;
|
||||
|
||||
std::vector<AppsecException> extractExceptionsFromCluster(
|
||||
const std::string &crd_plural,
|
||||
const std::unordered_set<std::string> &elements_names
|
||||
) const;
|
||||
|
||||
template<class T>
|
||||
std::vector<T> extractElementsFromCluster(
|
||||
const std::string &crd_plural,
|
||||
const std::unordered_set<std::string> &elements_names
|
||||
) const;
|
||||
|
||||
void createSnortFile(std::vector<NewAppSecPracticeSpec> &practices) const;
|
||||
|
||||
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;
|
||||
|
||||
I_EnvDetails* env_details = nullptr;
|
||||
I_Messaging* messaging = nullptr;
|
||||
EnvType env_type;
|
||||
Flags<MessageConnConfig> conn_flags;
|
||||
std::string token;
|
||||
};
|
||||
|
||||
#endif // __K8S_POLICY_UTILS_H__
|
@ -0,0 +1,144 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __LOCAL_POLICY_COMMON_H__
|
||||
#define __LOCAL_POLICY_COMMON_H__
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <cereal/archives/json.hpp>
|
||||
|
||||
#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, RateLimit };
|
||||
enum class TriggerType { Log, WebUserResponse };
|
||||
enum class MatchType { Condition, Operator };
|
||||
|
||||
static const std::unordered_map<std::string, MatchType> string_to_match_type = {
|
||||
{ "condition", MatchType::Condition },
|
||||
{ "operator", MatchType::Operator }
|
||||
};
|
||||
|
||||
static const std::unordered_map<std::string, PracticeType> string_to_practice_type = {
|
||||
{ "WebApplication", PracticeType::WebApplication },
|
||||
{ "WebAPI", PracticeType::WebAPI },
|
||||
{ "RateLimit", PracticeType::RateLimit }
|
||||
};
|
||||
|
||||
static const std::unordered_map<std::string, TriggerType> string_to_trigger_type = {
|
||||
{ "log", TriggerType::Log },
|
||||
{ "WebUserResponse", TriggerType::WebUserResponse }
|
||||
};
|
||||
|
||||
static const std::unordered_map<std::string, std::string> key_to_practices_val = {
|
||||
{ "prevent-learn", "Prevent"},
|
||||
{ "detect-learn", "Detect"},
|
||||
{ "prevent", "Prevent"},
|
||||
{ "detect", "Detect"},
|
||||
{ "inactive", "Inactive"}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
parseAppsecJSONKey(
|
||||
const std::string &key_name,
|
||||
T &value,
|
||||
cereal::JSONInputArchive &archive_in,
|
||||
const T &default_value = T())
|
||||
{
|
||||
try {
|
||||
archive_in(cereal::make_nvp(key_name, value));
|
||||
} catch (const cereal::Exception &e) {
|
||||
archive_in.setNextName(nullptr);
|
||||
value = default_value;
|
||||
dbgDebug(D_LOCAL_POLICY)
|
||||
<< "Could not parse the required key. Key: "
|
||||
<< key_name
|
||||
<< ", Error: "
|
||||
<< e.what();
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
AppsecSpecParser() = default;
|
||||
AppsecSpecParser(const T &_spec) : spec(_spec) {}
|
||||
|
||||
bool
|
||||
loadJson(const std::string &json)
|
||||
{
|
||||
std::string modified_json = json;
|
||||
modified_json.pop_back();
|
||||
std::stringstream ss;
|
||||
ss.str(modified_json);
|
||||
try {
|
||||
cereal::JSONInputArchive in_ar(ss);
|
||||
in_ar(cereal::make_nvp("spec", spec));
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
setName(const std::string &_name)
|
||||
{
|
||||
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> & getAppsecExceptions() 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
|
51
components/security_apps/local_policy_mgmt_gen/include/new_custom_response.h
Executable file
51
components/security_apps/local_policy_mgmt_gen/include/new_custom_response.h
Executable file
@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __NEW_CUSTOM_RESPONSE_H__
|
||||
#define __NEW_CUSTOM_RESPONSE_H__
|
||||
|
||||
#include <string>
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "local_policy_common.h"
|
||||
|
||||
class NewAppSecCustomResponse
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
int getHttpResponseCode() const;
|
||||
const std::string & getMessageBody() const;
|
||||
const std::string & getMessageTitle() const;
|
||||
const std::string & getAppSecClassName() const;
|
||||
const std::string & getMode() const;
|
||||
const std::string & getName() const;
|
||||
void setName(const std::string &_name);
|
||||
|
||||
private:
|
||||
bool redirect_add_x_event_id;
|
||||
int http_response_code;
|
||||
std::string appsec_class_name;
|
||||
std::string redirect_url;
|
||||
std::string message_title;
|
||||
std::string message_body;
|
||||
std::string mode;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
#endif // __NEW_CUSTOM_RESPONSE_H__
|
67
components/security_apps/local_policy_mgmt_gen/include/new_exceptions.h
Executable file
67
components/security_apps/local_policy_mgmt_gen/include/new_exceptions.h
Executable file
@ -0,0 +1,67 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __NEW_EXCEPTIONS_H__
|
||||
#define __NEW_EXCEPTIONS_H__
|
||||
|
||||
#include <string>
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "rest.h"
|
||||
#include "local_policy_common.h"
|
||||
|
||||
class NewAppsecExceptionCondition
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getKey() const;
|
||||
const std::string & getvalue() const;
|
||||
|
||||
private:
|
||||
std::string key;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
class NewAppsecException
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getName() const;
|
||||
const std::string & getAction() const;
|
||||
const std::string & getAppSecClassName() const;
|
||||
const std::vector<std::string> getCountryCode() const;
|
||||
const std::vector<std::string> getCountryName() const;
|
||||
const std::vector<std::string> getHostName() const;
|
||||
const std::vector<std::string> getParamName() const;
|
||||
const std::vector<std::string> getParamValue() const;
|
||||
const std::vector<std::string> getProtectionName() const;
|
||||
const std::vector<std::string> getSourceIdentifier() const;
|
||||
const std::vector<std::string> getSourceIp() const;
|
||||
const std::vector<std::string> getUrl() const;
|
||||
void setName(const std::string &_name);
|
||||
|
||||
private:
|
||||
std::string appsec_class_name;
|
||||
std::string name;
|
||||
std::string action;
|
||||
std::vector<NewAppsecExceptionCondition> conditions;
|
||||
};
|
||||
|
||||
#endif // __NEW_EXCEPTIONS_H__
|
172
components/security_apps/local_policy_mgmt_gen/include/new_log_trigger.h
Executable file
172
components/security_apps/local_policy_mgmt_gen/include/new_log_trigger.h
Executable file
@ -0,0 +1,172 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __NEW_LOG_TRIGGERS_H__
|
||||
#define __NEW_LOG_TRIGGERS_H__
|
||||
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "local_policy_common.h"
|
||||
#include "i_agent_details.h"
|
||||
#include "i_env_details.h"
|
||||
|
||||
class NewAppsecTriggerAccessControlLogging
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
private:
|
||||
bool allow_events = false;
|
||||
bool drop_events = false;
|
||||
};
|
||||
|
||||
class NewAppsecTriggerAdditionalSuspiciousEventsLogging : public ClientRest
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
bool isEnabled() const;
|
||||
bool isResponseBody() const;
|
||||
const std::string & getMinimumSeverity() const;
|
||||
|
||||
private:
|
||||
bool enabled = true;
|
||||
bool response_body = false;
|
||||
bool response_code = false;
|
||||
std::string minimum_severity = "high";
|
||||
};
|
||||
|
||||
class NewAppsecTriggerLogging : public ClientRest
|
||||
{
|
||||
public:
|
||||
void
|
||||
load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
bool isAllWebRequests() const;
|
||||
bool isDetectEvents() const;
|
||||
bool isPreventEvents() const;
|
||||
|
||||
private:
|
||||
bool all_web_requests = false;
|
||||
bool detect_events = false;
|
||||
bool prevent_events = true;
|
||||
};
|
||||
|
||||
class NewAppsecTriggerExtendedLogging : public ClientRest
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
bool isHttpHeaders() const;
|
||||
bool isRequestBody() const;
|
||||
bool isUrlPath() const;
|
||||
bool isUrlQuery() const;
|
||||
|
||||
private:
|
||||
bool http_headers = false;
|
||||
bool request_body = false;
|
||||
bool url_path = false;
|
||||
bool url_query = false;
|
||||
};
|
||||
|
||||
class NewLoggingService
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getAddress() const;
|
||||
int getPort() const;
|
||||
|
||||
private:
|
||||
std::string address;
|
||||
std::string proto;
|
||||
int port = 514;
|
||||
};
|
||||
|
||||
class NewStdoutLogging
|
||||
{
|
||||
public:
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
NewStdoutLogging() : format("json") {}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
const std::string & getFormat() const;
|
||||
|
||||
private:
|
||||
std::string format;
|
||||
};
|
||||
|
||||
class NewAppsecTriggerLogDestination
|
||||
:
|
||||
public ClientRest,
|
||||
Singleton::Consume<I_AgentDetails>,
|
||||
Singleton::Consume<I_EnvDetails>
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
int getCefServerUdpPort() const;
|
||||
int getSyslogServerUdpPort() const;
|
||||
bool isAgentLocal() const;
|
||||
bool shouldBeautifyLogs() const;
|
||||
|
||||
bool getCloud() const;
|
||||
bool isK8SNeeded() const;
|
||||
bool isCefNeeded() const;
|
||||
bool isSyslogNeeded() const;
|
||||
const std::string & getSyslogServerIpv4Address() const;
|
||||
const std::string & getCefServerIpv4Address() const;
|
||||
|
||||
private:
|
||||
const NewLoggingService & getSyslogServiceData() const;
|
||||
const NewLoggingService & getCefServiceData() const;
|
||||
|
||||
bool cloud = false;
|
||||
bool k8s_service = false;
|
||||
bool agent_local = true;
|
||||
bool beautify_logs = true;
|
||||
NewLoggingService syslog_service;
|
||||
NewLoggingService cef_service;
|
||||
};
|
||||
|
||||
class NewAppsecLogTrigger
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getName() const;
|
||||
const std::string & getAppSecClassName() const;
|
||||
void setName(const std::string &_name);
|
||||
const NewAppsecTriggerAdditionalSuspiciousEventsLogging &
|
||||
getAppsecTriggerAdditionalSuspiciousEventsLogging() const;
|
||||
const NewAppsecTriggerLogging & getAppsecTriggerLogging() const;
|
||||
const NewAppsecTriggerExtendedLogging & getAppsecTriggerExtendedLogging() const;
|
||||
const NewAppsecTriggerLogDestination & getAppsecTriggerLogDestination() const;
|
||||
|
||||
private:
|
||||
NewAppsecTriggerAccessControlLogging access_control_logging;
|
||||
NewAppsecTriggerAdditionalSuspiciousEventsLogging additional_suspicious_events_logging;
|
||||
NewAppsecTriggerLogging appsec_logging;
|
||||
NewAppsecTriggerExtendedLogging extended_logging;
|
||||
NewAppsecTriggerLogDestination log_destination;
|
||||
std::string name;
|
||||
std::string appsec_class_name;
|
||||
};
|
||||
|
||||
#endif // __NEW_LOG_TRIGGERS_H__
|
589
components/security_apps/local_policy_mgmt_gen/include/new_practice.h
Executable file
589
components/security_apps/local_policy_mgmt_gen/include/new_practice.h
Executable file
@ -0,0 +1,589 @@
|
||||
// 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 &_file_size_limit_action,
|
||||
const std::string &_multi_level_archive_action,
|
||||
const std::string &_unopened_archive_action
|
||||
);
|
||||
|
||||
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 std::string & getOverrideMode() const;
|
||||
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 SnortProtectionsSection
|
||||
{
|
||||
public:
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
SnortProtectionsSection() {};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
SnortProtectionsSection(
|
||||
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<std::string> &_files
|
||||
);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string context;
|
||||
std::string asset_name;
|
||||
std::string asset_id;
|
||||
std::string practice_name;
|
||||
std::string practice_id;
|
||||
std::string source_identifier;
|
||||
std::string mode;
|
||||
std::vector<std::string> files;
|
||||
};
|
||||
|
||||
class DetectionRules
|
||||
{
|
||||
public:
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
DetectionRules() {};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
DetectionRules(
|
||||
const std::string &_type,
|
||||
const std::string &_SSM,
|
||||
const std::string &_keywords,
|
||||
const std::vector<std::string> &_context
|
||||
);
|
||||
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string type;
|
||||
std::string SSM;
|
||||
std::string keywords;
|
||||
std::vector<std::string> context;
|
||||
};
|
||||
|
||||
class ProtectionMetadata
|
||||
{
|
||||
public:
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
ProtectionMetadata() {};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
ProtectionMetadata(
|
||||
bool _silent,
|
||||
const std::string &_protection_name,
|
||||
const std::string &_severity,
|
||||
const std::string &_confidence_level,
|
||||
const std::string &_performance_impact,
|
||||
const std::string &_last_update,
|
||||
const std::string &_maintrain_id,
|
||||
const std::vector<std::string> &_tags,
|
||||
const std::vector<std::string> &_cve_list
|
||||
);
|
||||
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
bool silent;
|
||||
std::string protection_name;
|
||||
std::string severity;
|
||||
std::string confidence_level;
|
||||
std::string performance_impact;
|
||||
std::string last_update;
|
||||
std::string maintrain_id;
|
||||
std::vector<std::string> tags;
|
||||
std::vector<std::string> cve_list;
|
||||
};
|
||||
|
||||
class ProtectionsProtectionsSection
|
||||
{
|
||||
public:
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
ProtectionsProtectionsSection() {};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
ProtectionsProtectionsSection(
|
||||
const ProtectionMetadata &_protection_metadata,
|
||||
const DetectionRules &_detection_rules
|
||||
);
|
||||
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
ProtectionMetadata protection_metadata;
|
||||
DetectionRules detection_rules;
|
||||
};
|
||||
|
||||
class ProtectionsSection
|
||||
{
|
||||
public:
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
ProtectionsSection() {};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
ProtectionsSection(
|
||||
const std::vector<ProtectionsProtectionsSection> &_protections,
|
||||
const std::string &_name = "",
|
||||
const std::string &_modification_time = ""
|
||||
);
|
||||
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
const std::vector<ProtectionsProtectionsSection> & getProtections() const;
|
||||
|
||||
private:
|
||||
std::vector<ProtectionsProtectionsSection> protections;
|
||||
std::string name;
|
||||
std::string modification_time;
|
||||
};
|
||||
|
||||
class ProtectionsSectionWrapper
|
||||
{
|
||||
public:
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
ProtectionsSectionWrapper() {};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
void serialize(cereal::JSONInputArchive &archive_in);
|
||||
const std::vector<ProtectionsProtectionsSection> & getProtections() const;
|
||||
|
||||
private:
|
||||
ProtectionsSection protections;
|
||||
};
|
||||
|
||||
class SnortSection
|
||||
{
|
||||
public:
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
SnortSection() {};
|
||||
|
||||
SnortSection(
|
||||
const std::vector<SnortProtectionsSection> &_snort,
|
||||
const std::vector<ProtectionsSection> &_protections)
|
||||
:
|
||||
snort_protections(_snort),
|
||||
protections(_protections)
|
||||
{};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
const std::vector<ProtectionsSection> & getProtections() const;
|
||||
|
||||
private:
|
||||
std::vector<SnortProtectionsSection> snort_protections;
|
||||
std::vector<ProtectionsSection> protections;
|
||||
};
|
||||
|
||||
class SnortSectionWrapper
|
||||
{
|
||||
public:
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
SnortSectionWrapper() {};
|
||||
|
||||
SnortSectionWrapper(
|
||||
const std::vector<SnortProtectionsSection> &_snort,
|
||||
const std::vector<ProtectionsSection> &_protections)
|
||||
:
|
||||
snort(SnortSection(_snort, _protections))
|
||||
{};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
SnortSection snort;
|
||||
};
|
||||
|
||||
class NewSnortSignaturesAndOpenSchemaAPI
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
void addFile(const std::string &file_name);
|
||||
const std::string & getOverrideMode() const;
|
||||
const std::vector<std::string> & getConfigMap() const;
|
||||
const std::vector<std::string> & getFiles() const;
|
||||
|
||||
private:
|
||||
std::string override_mode;
|
||||
std::vector<std::string> config_map;
|
||||
std::vector<std::string> files;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
NewSnortSignaturesAndOpenSchemaAPI & getSnortSignatures();
|
||||
const NewSnortSignaturesAndOpenSchemaAPI & getOpenSchemaValidation() 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__
|
74
components/security_apps/local_policy_mgmt_gen/include/new_trusted_sources.h
Executable file
74
components/security_apps/local_policy_mgmt_gen/include/new_trusted_sources.h
Executable file
@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __NEW_TRUSTED_SOURCES_H__
|
||||
#define __NEW_TRUSTED_SOURCES_H__
|
||||
|
||||
#include <string>
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "local_policy_common.h"
|
||||
|
||||
class NewTrustedSourcesSpec
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
int getMinNumOfSources() const;
|
||||
const std::vector<std::string> & getSourcesIdentifiers() const;
|
||||
const std::string & getAppSecClassName() const;
|
||||
const std::string & getName() const;
|
||||
void setName(const std::string &_name);
|
||||
|
||||
private:
|
||||
int min_num_of_sources = 0;
|
||||
std::string name;
|
||||
std::vector<std::string> sources_identifiers;
|
||||
std::string appsec_class_name;
|
||||
};
|
||||
|
||||
class Identifier
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getIdentifier() const;
|
||||
const std::vector<std::string> & getValues() const;
|
||||
|
||||
private:
|
||||
std::string identifier;
|
||||
std::vector<std::string> value;
|
||||
};
|
||||
|
||||
class NewSourcesIdentifiers
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getName() const;
|
||||
const std::string & getAppSecClassName() const;
|
||||
const std::vector<Identifier> & getSourcesIdentifiers() const;
|
||||
void setName(const std::string &_name);
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::string appsec_class_name;
|
||||
std::vector<Identifier> sources_identifiers;
|
||||
};
|
||||
|
||||
#endif // __NEW_TRUSTED_SOURCES_H__
|
266
components/security_apps/local_policy_mgmt_gen/include/policy_maker_utils.h
Executable file
266
components/security_apps/local_policy_mgmt_gen/include/policy_maker_utils.h
Executable file
@ -0,0 +1,266 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __POLICY_MAKER_UTILS_H__
|
||||
#define __POLICY_MAKER_UTILS_H__
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <utility>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
||||
#include "debug.h"
|
||||
#include "common.h"
|
||||
#include "maybe_res.h"
|
||||
#include "i_orchestration_tools.h"
|
||||
#include "i_shell_cmd.h"
|
||||
#include "i_messaging.h"
|
||||
#include "appsec_practice_section.h"
|
||||
#include "ingress_data.h"
|
||||
#include "settings_section.h"
|
||||
#include "triggers_section.h"
|
||||
#include "local_policy_common.h"
|
||||
#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,
|
||||
SOURCE_IDENTIFIERS,
|
||||
TRUSTED_SOURCES,
|
||||
COUNT
|
||||
};
|
||||
|
||||
class SecurityAppsWrapper
|
||||
{
|
||||
public:
|
||||
SecurityAppsWrapper(
|
||||
const AppSecWrapper &_waap,
|
||||
const TriggersWrapper &_trrigers,
|
||||
const RulesConfigWrapper &_rules,
|
||||
const IntrusionPreventionWrapper &_ips,
|
||||
const SnortSectionWrapper &_snort,
|
||||
const AccessControlRulebaseWrapper &_rate_limit,
|
||||
const FileSecurityWrapper &_file_security,
|
||||
const ExceptionsWrapper &_exceptions,
|
||||
const std::string &_policy_version)
|
||||
:
|
||||
waap(_waap),
|
||||
trrigers(_trrigers),
|
||||
rules(_rules),
|
||||
ips(_ips),
|
||||
snort(_snort),
|
||||
rate_limit(_rate_limit),
|
||||
file_security(_file_security),
|
||||
exceptions(_exceptions),
|
||||
policy_version(_policy_version) {}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
AppSecWrapper waap;
|
||||
TriggersWrapper trrigers;
|
||||
RulesConfigWrapper rules;
|
||||
IntrusionPreventionWrapper ips;
|
||||
SnortSectionWrapper snort;
|
||||
AccessControlRulebaseWrapper rate_limit;
|
||||
FileSecurityWrapper file_security;
|
||||
ExceptionsWrapper exceptions;
|
||||
std::string policy_version;
|
||||
};
|
||||
|
||||
class PolicyWrapper
|
||||
{
|
||||
public:
|
||||
PolicyWrapper(
|
||||
const SettingsWrapper &_settings,
|
||||
const SecurityAppsWrapper &_security_apps)
|
||||
:
|
||||
settings(_settings),
|
||||
security_apps(_security_apps) {}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
SettingsWrapper settings;
|
||||
SecurityAppsWrapper security_apps;
|
||||
};
|
||||
|
||||
class PolicyMakerUtils
|
||||
:
|
||||
Singleton::Consume<I_Environment>,
|
||||
Singleton::Consume<I_OrchestrationTools>,
|
||||
Singleton::Consume<I_Messaging>,
|
||||
Singleton::Consume<I_ShellCmd>
|
||||
{
|
||||
public:
|
||||
std::string proccesSingleAppsecPolicy(
|
||||
const std::string &policy_path,
|
||||
const std::string &policy_version,
|
||||
const std::string &local_appsec_policy_path
|
||||
);
|
||||
|
||||
template<class T, class R>
|
||||
std::string proccesMultipleAppsecPolicies(
|
||||
const std::map<std::string, T> &appsec_policies,
|
||||
const std::string &policy_version,
|
||||
const std::string &local_appsec_policy_path
|
||||
);
|
||||
|
||||
private:
|
||||
std::string getPolicyName(const std::string &policy_path);
|
||||
|
||||
template<class T>
|
||||
Maybe<T> openFileAsJson(const std::string &path);
|
||||
|
||||
void clearElementsMaps();
|
||||
|
||||
bool startsWith(const std::string &str, const std::string &prefix);
|
||||
|
||||
bool endsWith(const std::string &str, const std::string &suffix);
|
||||
|
||||
std::tuple<std::string, std::string, std::string> splitHostName(const std::string &host_name);
|
||||
|
||||
std::string dumpPolicyToFile(const PolicyWrapper &policy, const std::string &policy_path);
|
||||
|
||||
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 createSnortProtecionsSection(const std::string &file_name, const std::string &practic_name);
|
||||
|
||||
void
|
||||
createSnortSections(
|
||||
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 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 R &rule,
|
||||
const R &default_rule,
|
||||
const T &policy,
|
||||
const std::string &policy_name
|
||||
);
|
||||
|
||||
template<class T, class R>
|
||||
void createPolicyElements(
|
||||
const std::vector<R> &rules,
|
||||
const R &default_rule,
|
||||
const T &policy,
|
||||
const std::string &policy_name
|
||||
);
|
||||
|
||||
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, std::vector<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, SnortProtectionsSection> snort;
|
||||
std::map<std::string, ProtectionsSection> snort_protections;
|
||||
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__
|
@ -0,0 +1,190 @@
|
||||
// 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 __RULES_CONFIG_SECTION_H__
|
||||
#define __RULES_CONFIG_SECTION_H__
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#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 AssetUrlParser
|
||||
{
|
||||
public:
|
||||
AssetUrlParser() {}
|
||||
|
||||
static AssetUrlParser parse(const std::string &uri);
|
||||
std::string query_string, asset_uri, protocol, asset_url, port;
|
||||
};
|
||||
|
||||
class PracticeSection
|
||||
{
|
||||
public:
|
||||
PracticeSection(
|
||||
const std::string &_id,
|
||||
const std::string &_type,
|
||||
const std::string &_practice_name
|
||||
);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
std::string name;
|
||||
std::string type;
|
||||
};
|
||||
|
||||
class ParametersSection
|
||||
{
|
||||
public:
|
||||
ParametersSection(const std::string &_id, const std::string &_name);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::string id;
|
||||
std::string type = "Exception";
|
||||
};
|
||||
|
||||
class RulesTriggerSection
|
||||
{
|
||||
public:
|
||||
RulesTriggerSection(
|
||||
const std::string &_name,
|
||||
const std::string &_id,
|
||||
const std::string &_type
|
||||
);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::string id;
|
||||
std::string type;
|
||||
};
|
||||
|
||||
class RulesConfigRulebase
|
||||
{
|
||||
public:
|
||||
RulesConfigRulebase()
|
||||
{}
|
||||
|
||||
RulesConfigRulebase(
|
||||
const std::string &_name,
|
||||
const std::string &_url,
|
||||
const std::string &_uri,
|
||||
std::vector<PracticeSection> _practices,
|
||||
std::vector<ParametersSection> _parameters,
|
||||
std::vector<RulesTriggerSection> _triggers
|
||||
);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
const std::string & getAssetName() const;
|
||||
const std::string & getAssetId() const;
|
||||
const std::string & getContext() const;
|
||||
|
||||
private:
|
||||
std::string context;
|
||||
std::string id;
|
||||
std::string name;
|
||||
std::vector<PracticeSection> practices;
|
||||
std::vector<ParametersSection> parameters;
|
||||
std::vector<RulesTriggerSection> triggers;
|
||||
};
|
||||
|
||||
class UsersIdentifier
|
||||
{
|
||||
public:
|
||||
UsersIdentifier() {}
|
||||
|
||||
UsersIdentifier(
|
||||
const std::string &_source_identifier,
|
||||
std::vector<std::string> _identifier_values
|
||||
);
|
||||
|
||||
const std::string & getIdentifier() const;
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string source_identifier;
|
||||
std::vector<std::string> identifier_values;
|
||||
};
|
||||
|
||||
class UsersIdentifiersRulebase
|
||||
{
|
||||
public:
|
||||
UsersIdentifiersRulebase()
|
||||
{}
|
||||
|
||||
UsersIdentifiersRulebase(
|
||||
const std::string &_context,
|
||||
const std::string &_source_identifier,
|
||||
const std::vector<std::string> &_identifier_values,
|
||||
const std::vector<UsersIdentifier> &_source_identifiers
|
||||
);
|
||||
|
||||
const std::string & getIdentifier() const;
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string context;
|
||||
std::string source_identifier;
|
||||
std::vector<std::string> identifier_values;
|
||||
std::vector<UsersIdentifier> source_identifiers;
|
||||
};
|
||||
|
||||
class RulesRulebase
|
||||
{
|
||||
public:
|
||||
RulesRulebase(
|
||||
const std::vector<RulesConfigRulebase> &_rules_config,
|
||||
const std::vector<UsersIdentifiersRulebase> &_users_identifiers
|
||||
);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
static bool sortBySpecific(const RulesConfigRulebase &first, const RulesConfigRulebase &second);
|
||||
static bool sortBySpecificAux(const std::string &first, const std::string &second);
|
||||
|
||||
std::vector<RulesConfigRulebase> rules_config;
|
||||
std::vector<UsersIdentifiersRulebase> users_identifiers;
|
||||
};
|
||||
|
||||
class RulesConfigWrapper
|
||||
{
|
||||
public:
|
||||
RulesConfigWrapper(
|
||||
const std::vector<RulesConfigRulebase> &_rules_config,
|
||||
const std::vector<UsersIdentifiersRulebase> &_users_identifiers)
|
||||
:
|
||||
rules_config_rulebase(RulesRulebase(_rules_config, _users_identifiers))
|
||||
{}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
RulesRulebase rules_config_rulebase;
|
||||
};
|
||||
#endif // __RULES_CONFIG_SECTION_H__
|
@ -0,0 +1,68 @@
|
||||
// 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 __SETTINGS_SECTION_H__
|
||||
#define __SETTINGS_SECTION_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"
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
class AgentSettingsSection
|
||||
{
|
||||
public:
|
||||
AgentSettingsSection(const std::string &_key, const std::string &_value);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
const std::string & getSettingId() const;
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
std::string key;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
class SettingsRulebase
|
||||
{
|
||||
public:
|
||||
SettingsRulebase(std::vector<AgentSettingsSection> _agentSettings) : agentSettings(_agentSettings) {}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::vector<AgentSettingsSection> agentSettings;
|
||||
};
|
||||
|
||||
class SettingsWrapper
|
||||
{
|
||||
public:
|
||||
SettingsWrapper(SettingsRulebase _agent);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string profileType = "agent";
|
||||
bool isToken = true;
|
||||
std::string tokenType = "sameToken";
|
||||
std::string id;
|
||||
std::string name = "Kubernetes Agents";
|
||||
SettingsRulebase agent;
|
||||
};
|
||||
// LCOV_EXCL_STOP
|
||||
#endif // __SETTINGS_SECTION_H__
|
@ -0,0 +1,50 @@
|
||||
// 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 __SNORT_SECTION_H__
|
||||
#define __SNORT_SECTION_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"
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
class AgentSettingsSection
|
||||
{
|
||||
public:
|
||||
AgentSettingsSection(std::string _key, std::string _value);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
std::string key;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
class IpsSnortSigsRulebase
|
||||
{
|
||||
public:
|
||||
IpsSnortSigsRulebase(std::vector<AgentSettingsSection> _agentSettings) : agentSettings(_agentSettings) {}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::vector<AgentSettingsSection> agentSettings;
|
||||
};
|
||||
// LCOV_EXCL_STOP
|
||||
#endif // __SNORT_SECTION_H__
|
@ -0,0 +1,305 @@
|
||||
// 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 __TRIGGERS_SECTION_H__
|
||||
#define __TRIGGERS_SECTION_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 LogTriggerSection
|
||||
{
|
||||
public:
|
||||
LogTriggerSection()
|
||||
{}
|
||||
|
||||
LogTriggerSection(
|
||||
const std::string &_name,
|
||||
const std::string &_verbosity,
|
||||
const std::string &_extendloggingMinSeverity,
|
||||
bool _extendlogging,
|
||||
bool _logToAgent,
|
||||
bool _logToCef,
|
||||
bool _logToCloud,
|
||||
bool _logToK8sService,
|
||||
bool _logToSyslog,
|
||||
bool _responseBody,
|
||||
bool _tpDetect,
|
||||
bool _tpPrevent,
|
||||
bool _webBody,
|
||||
bool _webHeaders,
|
||||
bool _webRequests,
|
||||
bool _webUrlPath,
|
||||
bool _webUrlQuery,
|
||||
int _cefPortNum,
|
||||
const std::string &_cefIpAddress,
|
||||
int _syslogPortNum,
|
||||
const std::string &_syslogIpAddress,
|
||||
bool _beautify_logs
|
||||
);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
const std::string & getTriggerId() const;
|
||||
const std::string & getTriggerName() const;
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
std::string name;
|
||||
std::string context;
|
||||
std::string verbosity;
|
||||
std::string extendloggingMinSeverity;
|
||||
bool extendlogging;
|
||||
bool logToAgent;
|
||||
bool logToCef;
|
||||
bool logToCloud;
|
||||
bool logToK8sService;
|
||||
bool logToSyslog;
|
||||
bool responseBody;
|
||||
bool tpDetect;
|
||||
bool tpPrevent;
|
||||
bool webBody;
|
||||
bool webHeaders;
|
||||
bool webRequests;
|
||||
bool webUrlPath;
|
||||
bool webUrlQuery;
|
||||
int cefPortNum;
|
||||
std::string cefIpAddress;
|
||||
int syslogPortNum;
|
||||
std::string syslogIpAddress;
|
||||
bool beautify_logs;
|
||||
};
|
||||
|
||||
class WebUserResponseTriggerSection
|
||||
{
|
||||
public:
|
||||
WebUserResponseTriggerSection() {}
|
||||
|
||||
WebUserResponseTriggerSection(
|
||||
const std::string &_name,
|
||||
const std::string &_details_level,
|
||||
const std::string &_response_body,
|
||||
int _response_code,
|
||||
const std::string &_response_title
|
||||
);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
const std::string & getTriggerId() const;
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
std::string name;
|
||||
std::string context;
|
||||
std::string details_level;
|
||||
std::string response_body;
|
||||
std::string response_title;
|
||||
int response_code;
|
||||
};
|
||||
|
||||
class AppSecCustomResponseSpec
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
int getHttpResponseCode() const;
|
||||
const std::string & getMessageBody() const;
|
||||
const std::string & getMessageTitle() const;
|
||||
const std::string & getMode() const;
|
||||
const std::string & getName() const;
|
||||
void setName(const std::string &_name);
|
||||
|
||||
private:
|
||||
int httpResponseCode;
|
||||
std::string messageBody;
|
||||
std::string messageTitle;
|
||||
std::string mode;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class TriggersRulebase
|
||||
{
|
||||
public:
|
||||
TriggersRulebase(
|
||||
std::vector<LogTriggerSection> _logTriggers,
|
||||
std::vector<WebUserResponseTriggerSection> _webUserResponseTriggers)
|
||||
:
|
||||
logTriggers(_logTriggers),
|
||||
webUserResponseTriggers(_webUserResponseTriggers) {}
|
||||
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
std::vector<LogTriggerSection> logTriggers;
|
||||
std::vector<WebUserResponseTriggerSection> webUserResponseTriggers;
|
||||
};
|
||||
|
||||
class AppsecTriggerAccessControlLogging
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
private:
|
||||
bool allow_events = false;
|
||||
bool drop_events = false;
|
||||
};
|
||||
|
||||
class AppsecTriggerAdditionalSuspiciousEventsLogging : 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;
|
||||
std::string minimum_severity = "high";
|
||||
};
|
||||
|
||||
class AppsecTriggerLogging : 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 AppsecTriggerExtendedLogging : 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 LoggingService
|
||||
{
|
||||
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 StdoutLogging
|
||||
{
|
||||
public:
|
||||
StdoutLogging() : format("json") {}
|
||||
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
const std::string & getFormat() const;
|
||||
|
||||
private:
|
||||
std::string format;
|
||||
};
|
||||
|
||||
class AppsecTriggerLogDestination
|
||||
:
|
||||
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 LoggingService & getSyslogServiceData() const;
|
||||
const LoggingService & getCefServiceData() const;
|
||||
|
||||
bool cloud = false;
|
||||
bool k8s_service = false;
|
||||
bool agent_local = true;
|
||||
bool beautify_logs = true;
|
||||
LoggingService syslog_service;
|
||||
LoggingService cef_service;
|
||||
};
|
||||
|
||||
class AppsecTriggerSpec
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getName() const;
|
||||
void setName(const std::string &_name);
|
||||
const AppsecTriggerAdditionalSuspiciousEventsLogging & getAppsecTriggerAdditionalSuspiciousEventsLogging() const;
|
||||
const AppsecTriggerLogging & getAppsecTriggerLogging() const;
|
||||
const AppsecTriggerExtendedLogging & getAppsecTriggerExtendedLogging() const;
|
||||
const AppsecTriggerLogDestination & getAppsecTriggerLogDestination() const;
|
||||
|
||||
private:
|
||||
AppsecTriggerAccessControlLogging access_control_logging;
|
||||
AppsecTriggerAdditionalSuspiciousEventsLogging additional_suspicious_events_logging;
|
||||
AppsecTriggerLogging appsec_logging;
|
||||
AppsecTriggerExtendedLogging extended_logging;
|
||||
AppsecTriggerLogDestination log_destination;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class TriggersWrapper
|
||||
{
|
||||
public:
|
||||
TriggersWrapper(const TriggersRulebase &_triggers) : triggers_rulebase(_triggers)
|
||||
{}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
TriggersRulebase triggers_rulebase;
|
||||
};
|
||||
#endif // __TRIGGERS_SECTION_H__
|
108
components/security_apps/local_policy_mgmt_gen/include/trusted_sources_section.h
Executable file
108
components/security_apps/local_policy_mgmt_gen/include/trusted_sources_section.h
Executable file
@ -0,0 +1,108 @@
|
||||
// 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 __TRUSTED_SOURCES_SECTION_H__
|
||||
#define __TRUSTED_SOURCES_SECTION_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 TrustedSourcesSpec
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
int getMinNumOfSources() const;
|
||||
const std::vector<std::string> & getSourcesIdentifiers() 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;
|
||||
};
|
||||
|
||||
class SourcesIdentifiers
|
||||
{
|
||||
public:
|
||||
SourcesIdentifiers(const std::string &_source_identifier, const std::string &_value)
|
||||
:
|
||||
source_identifier(_source_identifier),
|
||||
value(_value)
|
||||
{}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
const std::string & getSourceIdent() const;
|
||||
|
||||
private:
|
||||
std::string source_identifier;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
class SourceIdentifierSpec
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getSourceIdentifier() const;
|
||||
const std::vector<std::string> & getValues() const;
|
||||
|
||||
private:
|
||||
std::string source_identifier;
|
||||
std::vector<std::string> value;
|
||||
};
|
||||
|
||||
class SourceIdentifierSpecWrapper
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getName() const;
|
||||
const std::vector<SourceIdentifierSpec> & getIdentifiers() const;
|
||||
void setName(const std::string &_name);
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::vector<SourceIdentifierSpec> identifiers;
|
||||
};
|
||||
|
||||
class AppSecTrustedSources
|
||||
{
|
||||
public:
|
||||
AppSecTrustedSources()
|
||||
{}
|
||||
|
||||
AppSecTrustedSources(
|
||||
const std::string &_name,
|
||||
int _num_of_sources,
|
||||
const std::vector<SourcesIdentifiers> &_sources_identifiers
|
||||
);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
const std::vector<SourcesIdentifiers> & getSourcesIdentifiers() const;
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
std::string name;
|
||||
int num_of_sources = 0;
|
||||
std::vector<SourcesIdentifiers> sources_identifiers;
|
||||
};
|
||||
#endif // __TRUSTED_SOURCES_SECTION_H__
|
149
components/security_apps/local_policy_mgmt_gen/ingress_data.cc
Executable file
149
components/security_apps/local_policy_mgmt_gen/ingress_data.cc
Executable file
@ -0,0 +1,149 @@
|
||||
// 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 "ingress_data.h"
|
||||
#include "customized_cereal_map.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
void
|
||||
IngressMetadata::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "IngressMetadata load";
|
||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||
parseAppsecJSONKey<string>("resourceVersion", resourceVersion, archive_in);
|
||||
parseAppsecJSONKey<string>("namespace", namespace_name, archive_in);
|
||||
parseAppsecJSONKey<map<string, string>>("annotations", annotations, archive_in);
|
||||
}
|
||||
|
||||
const map<string, string> &
|
||||
IngressMetadata::getAnnotations() const
|
||||
{
|
||||
return annotations;
|
||||
}
|
||||
|
||||
void
|
||||
IngressRulePath::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading ingress defined rule path";
|
||||
parseAppsecJSONKey<string>("path", path, archive_in);
|
||||
}
|
||||
|
||||
const string &
|
||||
IngressRulePath::getPath() const
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
void
|
||||
IngressRulePathsWrapper::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading ingress defined rule path wrapper";
|
||||
parseAppsecJSONKey<vector<IngressRulePath>>("paths", paths, archive_in);
|
||||
}
|
||||
|
||||
const vector<IngressRulePath> &
|
||||
IngressRulePathsWrapper::getRulePaths() const
|
||||
{
|
||||
return paths;
|
||||
}
|
||||
|
||||
void
|
||||
IngressDefinedRule::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading ingress defined rule";
|
||||
parseAppsecJSONKey<string>("host", host, archive_in);
|
||||
parseAppsecJSONKey<IngressRulePathsWrapper>("http", paths_wrapper, archive_in);
|
||||
}
|
||||
|
||||
const string &
|
||||
IngressDefinedRule::getHost() const
|
||||
{
|
||||
return host;
|
||||
}
|
||||
|
||||
const IngressRulePathsWrapper &
|
||||
IngressDefinedRule::getPathsWrapper() const
|
||||
{
|
||||
return paths_wrapper;
|
||||
}
|
||||
|
||||
void
|
||||
DefaultBackend::load(cereal::JSONInputArchive &)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading Default Backend";
|
||||
is_exists = true;
|
||||
}
|
||||
|
||||
void
|
||||
IngressSpec::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading single ingress spec";
|
||||
parseAppsecJSONKey<string>("ingressClassName", ingress_class_name, archive_in);
|
||||
parseAppsecJSONKey<vector<IngressDefinedRule>>("rules", rules, archive_in);
|
||||
parseAppsecJSONKey<DefaultBackend>("defaultBackend", default_backend, archive_in);
|
||||
}
|
||||
|
||||
const vector<IngressDefinedRule> &
|
||||
IngressSpec::getRules() const
|
||||
{
|
||||
return rules;
|
||||
}
|
||||
|
||||
void
|
||||
SingleIngressData::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading single ingress data";
|
||||
parseAppsecJSONKey<IngressMetadata>("metadata", metadata, archive_in);
|
||||
parseAppsecJSONKey<IngressSpec>("spec", spec, archive_in);
|
||||
}
|
||||
|
||||
const IngressMetadata &
|
||||
SingleIngressData::getMetadata() const
|
||||
{
|
||||
return metadata;
|
||||
}
|
||||
|
||||
const IngressSpec &
|
||||
SingleIngressData::getSpec() const
|
||||
{
|
||||
return spec;
|
||||
}
|
||||
|
||||
bool
|
||||
IngressData::loadJson(const string &json)
|
||||
{
|
||||
string modified_json = json;
|
||||
modified_json.pop_back();
|
||||
stringstream in;
|
||||
in.str(modified_json);
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading ingress data";
|
||||
try {
|
||||
cereal::JSONInputArchive in_ar(in);
|
||||
in_ar(
|
||||
cereal::make_nvp("apiVersion", apiVersion),
|
||||
cereal::make_nvp("items", items)
|
||||
);
|
||||
} catch (cereal::Exception &e) {
|
||||
dbgError(D_LOCAL_POLICY) << "Failed to load ingress data JSON. Error: " << e.what();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const vector<SingleIngressData> &
|
||||
IngressData::getItems() const
|
||||
{
|
||||
return items;
|
||||
}
|
@ -0,0 +1,587 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "k8s_policy_utils.h"
|
||||
#include "configmaps.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_NGINX_POLICY);
|
||||
|
||||
string
|
||||
convertAnnotationKeysTostring(const AnnotationKeys &key)
|
||||
{
|
||||
switch (key) {
|
||||
case AnnotationKeys::PolicyKey:
|
||||
return "policy";
|
||||
case AnnotationKeys::OpenAppsecIo:
|
||||
return "openappsec.io/";
|
||||
case AnnotationKeys::SyslogAddressKey:
|
||||
return "syslog";
|
||||
case AnnotationKeys::ModeKey:
|
||||
return "mode";
|
||||
default:
|
||||
return "Irrelevant key";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
K8sPolicyUtils::init()
|
||||
{
|
||||
env_details = Singleton::Consume<I_EnvDetails>::by<K8sPolicyUtils>();
|
||||
env_type = env_details->getEnvType();
|
||||
if (env_type == EnvType::K8S) {
|
||||
token = env_details->getToken();
|
||||
messaging = Singleton::Consume<I_Messaging>::by<K8sPolicyUtils>();
|
||||
conn_flags.setFlag(MessageConnConfig::SECURE_CONN);
|
||||
conn_flags.setFlag(MessageConnConfig::IGNORE_SSL_VALIDATION);
|
||||
}
|
||||
}
|
||||
|
||||
map<AnnotationKeys, string>
|
||||
K8sPolicyUtils::parseIngressAnnotations(const map<string, string> &annotations) const
|
||||
{
|
||||
map<AnnotationKeys, string> annotations_values;
|
||||
for (const auto &annotation : annotations) {
|
||||
string annotation_key = annotation.first;
|
||||
string annotation_val = annotation.second;
|
||||
if (annotation_key.find(convertAnnotationKeysTostring(AnnotationKeys::OpenAppsecIo)) != string::npos) {
|
||||
if (annotation_key.find(convertAnnotationKeysTostring(AnnotationKeys::PolicyKey)) != string::npos) {
|
||||
annotations_values[AnnotationKeys::PolicyKey] = annotation_val;
|
||||
} else if (
|
||||
annotation_key.find(convertAnnotationKeysTostring(AnnotationKeys::SyslogAddressKey)) != string::npos
|
||||
) {
|
||||
bool has_port = annotation_val.find(":");
|
||||
annotations_values[AnnotationKeys::SyslogAddressKey] =
|
||||
annotation_val.substr(0, annotation_val.find(":"));
|
||||
annotations_values[AnnotationKeys::SyslogPortKey] =
|
||||
has_port ? annotation_val.substr(annotation_val.find(":") + 1) : "";
|
||||
} else if (annotation_key.find(convertAnnotationKeysTostring(AnnotationKeys::ModeKey)) != string::npos) {
|
||||
annotations_values[AnnotationKeys::ModeKey] = annotation_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
return annotations_values;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Maybe<T, string>
|
||||
K8sPolicyUtils::getObjectFromCluster(const string &path) const
|
||||
{
|
||||
T object;
|
||||
bool res = messaging->sendObject(
|
||||
object,
|
||||
I_Messaging::Method::GET,
|
||||
"kubernetes.default.svc",
|
||||
443,
|
||||
conn_flags,
|
||||
path,
|
||||
"Authorization: Bearer " + token + "\nConnection: close"
|
||||
);
|
||||
|
||||
if (res) return object;
|
||||
|
||||
return genError(string("Was not able to get object form k8s cluser in path: " + path));
|
||||
}
|
||||
|
||||
map<AnnotationTypes, unordered_set<string>>
|
||||
K8sPolicyUtils::extractElementsNames(const vector<ParsedRule> &specific_rules, const ParsedRule &default_rule) const
|
||||
{
|
||||
map<AnnotationTypes, unordered_set<string>> policy_elements_names;
|
||||
for (const ParsedRule &specific_rule : specific_rules) {
|
||||
policy_elements_names[AnnotationTypes::EXCEPTION].insert(
|
||||
specific_rule.getExceptions().begin(),
|
||||
specific_rule.getExceptions().end()
|
||||
);
|
||||
policy_elements_names[AnnotationTypes::PRACTICE].insert(
|
||||
specific_rule.getPractices().begin(),
|
||||
specific_rule.getPractices().end()
|
||||
);
|
||||
policy_elements_names[AnnotationTypes::TRIGGER].insert(
|
||||
specific_rule.getLogTriggers().begin(),
|
||||
specific_rule.getLogTriggers().end()
|
||||
);
|
||||
policy_elements_names[AnnotationTypes::WEB_USER_RES].insert(specific_rule.getCustomResponse());
|
||||
policy_elements_names[AnnotationTypes::SOURCE_IDENTIFIERS].insert(specific_rule.getSourceIdentifiers());
|
||||
policy_elements_names[AnnotationTypes::TRUSTED_SOURCES].insert(specific_rule.getTrustedSources());
|
||||
}
|
||||
policy_elements_names[AnnotationTypes::EXCEPTION].insert(
|
||||
default_rule.getExceptions().begin(),
|
||||
default_rule.getExceptions().end()
|
||||
);
|
||||
policy_elements_names[AnnotationTypes::PRACTICE].insert(
|
||||
default_rule.getPractices().begin(),
|
||||
default_rule.getPractices().end()
|
||||
);
|
||||
policy_elements_names[AnnotationTypes::TRIGGER].insert(
|
||||
default_rule.getLogTriggers().begin(),
|
||||
default_rule.getLogTriggers().end()
|
||||
);
|
||||
policy_elements_names[AnnotationTypes::WEB_USER_RES].insert(default_rule.getCustomResponse());
|
||||
policy_elements_names[AnnotationTypes::SOURCE_IDENTIFIERS].insert(default_rule.getSourceIdentifiers());
|
||||
policy_elements_names[AnnotationTypes::TRUSTED_SOURCES].insert(default_rule.getTrustedSources());
|
||||
|
||||
return policy_elements_names;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
vector<AppsecException>
|
||||
K8sPolicyUtils::extractExceptionsFromCluster(
|
||||
const string &crd_plural,
|
||||
const unordered_set<string> &elements_names) const
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Retrieve AppSec elements. type: " << crd_plural;
|
||||
vector<AppsecException> elements;
|
||||
for (const string &element_name : elements_names) {
|
||||
dbgTrace(D_LOCAL_POLICY) << "AppSec element name: " << element_name;
|
||||
auto maybe_appsec_element = getObjectFromCluster<AppsecSpecParser<vector<AppsecExceptionSpec>>>(
|
||||
"/apis/openappsec.io/v1beta1/" + crd_plural + "/" + element_name
|
||||
);
|
||||
|
||||
if (!maybe_appsec_element.ok()) {
|
||||
dbgWarning(D_LOCAL_POLICY)
|
||||
<< "Failed to retrieve AppSec element. type: "
|
||||
<< crd_plural
|
||||
<< ", name: "
|
||||
<< element_name
|
||||
<< ". Error: "
|
||||
<< maybe_appsec_element.getErr();
|
||||
continue;
|
||||
}
|
||||
|
||||
AppsecSpecParser<vector<AppsecExceptionSpec>> appsec_element = maybe_appsec_element.unpack();
|
||||
elements.push_back(AppsecException(element_name, appsec_element.getSpec()));
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
vector<T>
|
||||
K8sPolicyUtils::extractElementsFromCluster(
|
||||
const string &crd_plural,
|
||||
const unordered_set<string> &elements_names) const
|
||||
{
|
||||
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/v1beta1/" + crd_plural + "/" + element_name
|
||||
);
|
||||
|
||||
if (!maybe_appsec_element.ok()) {
|
||||
dbgWarning(D_LOCAL_POLICY)
|
||||
<< "Failed to retrieve AppSec element. type: "
|
||||
<< crd_plural
|
||||
<< ", name: "
|
||||
<< element_name
|
||||
<< ". Error: "
|
||||
<< maybe_appsec_element.getErr();
|
||||
continue;
|
||||
}
|
||||
|
||||
AppsecSpecParser<T> appsec_element = maybe_appsec_element.unpack();
|
||||
if (appsec_element.getSpec().getName() == "") {
|
||||
appsec_element.setName(element_name);
|
||||
}
|
||||
elements.push_back(appsec_element.getSpec());
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
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());
|
||||
}
|
||||
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();
|
||||
|
||||
if (!ingress_mode.empty() && default_rule.getMode().empty()) {
|
||||
default_rule.setMode(ingress_mode);
|
||||
}
|
||||
|
||||
map<AnnotationTypes, unordered_set<string>> policy_elements_names = extractElementsNames(
|
||||
specific_rules,
|
||||
default_rule
|
||||
);
|
||||
|
||||
|
||||
vector<AppSecPracticeSpec> practices = extractElementsFromCluster<AppSecPracticeSpec>(
|
||||
"practices",
|
||||
policy_elements_names[AnnotationTypes::PRACTICE]
|
||||
);
|
||||
|
||||
vector<AppsecTriggerSpec> log_triggers = extractElementsFromCluster<AppsecTriggerSpec>(
|
||||
"logtriggers",
|
||||
policy_elements_names[AnnotationTypes::TRIGGER]
|
||||
);
|
||||
|
||||
vector<AppSecCustomResponseSpec> web_user_responses = extractElementsFromCluster<AppSecCustomResponseSpec>(
|
||||
"customresponses",
|
||||
policy_elements_names[AnnotationTypes::WEB_USER_RES]
|
||||
);
|
||||
|
||||
|
||||
vector<AppsecException> exceptions = extractExceptionsFromCluster(
|
||||
"exceptions",
|
||||
policy_elements_names[AnnotationTypes::EXCEPTION]
|
||||
);
|
||||
|
||||
vector<SourceIdentifierSpecWrapper> source_identifiers = extractElementsFromCluster<SourceIdentifierSpecWrapper>(
|
||||
"sourcesidentifiers",
|
||||
policy_elements_names[AnnotationTypes::SOURCE_IDENTIFIERS]
|
||||
);
|
||||
|
||||
vector<TrustedSourcesSpec> trusted_sources = extractElementsFromCluster<TrustedSourcesSpec>(
|
||||
"trustedsources",
|
||||
policy_elements_names[AnnotationTypes::TRUSTED_SOURCES]
|
||||
);
|
||||
|
||||
AppsecLinuxPolicy appsec_policy = AppsecLinuxPolicy(
|
||||
appsec_policy_spec.getSpec(),
|
||||
practices,
|
||||
log_triggers,
|
||||
web_user_responses,
|
||||
exceptions,
|
||||
trusted_sources,
|
||||
source_identifiers
|
||||
);
|
||||
return appsec_policy;
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
void
|
||||
K8sPolicyUtils::createSnortFile(vector<NewAppSecPracticeSpec> &practices) const
|
||||
{
|
||||
for (NewAppSecPracticeSpec &practice : practices) {
|
||||
auto orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<K8sPolicyUtils>();
|
||||
auto path = "/etc/cp/conf/snort/snort_k8s_" + practice.getName() + ".rule";
|
||||
bool append_mode = false;
|
||||
for (const string &config_map : practice.getSnortSignatures().getConfigMap())
|
||||
{
|
||||
auto maybe_configmap = getObjectFromCluster<ConfigMaps>(
|
||||
"/api/v1/namespaces/default/configmaps/" + config_map
|
||||
);
|
||||
if (!maybe_configmap.ok()) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to get configMaps from the cluster.";
|
||||
continue;
|
||||
}
|
||||
string file_content = maybe_configmap.unpack().getFileContent();
|
||||
string file_name = maybe_configmap.unpack().getFileName();
|
||||
if (!orchestration_tools->writeFile(file_content, path, append_mode)) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to update the snort_k8s_rules file.";
|
||||
continue;
|
||||
}
|
||||
append_mode = true;
|
||||
practice.getSnortSignatures().addFile(file_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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]
|
||||
);
|
||||
|
||||
createSnortFile(threat_prevention_practices);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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> v1bet1_policies;
|
||||
map<string, V1beta2AppsecLinuxPolicy> v1bet2_policies;
|
||||
auto maybe_ingress = getObjectFromCluster<IngressData>("/apis/networking.k8s.io/v1/ingresses");
|
||||
|
||||
if (!maybe_ingress.ok()) {
|
||||
// TBD: Error handling : INXT-31444
|
||||
dbgWarning(D_LOCAL_POLICY)
|
||||
<< "Failed to retrieve K8S Ingress configurations. Error: "
|
||||
<< maybe_ingress.getErr();
|
||||
return make_tuple(v1bet1_policies, v1bet2_policies);
|
||||
}
|
||||
|
||||
|
||||
IngressData ingress = maybe_ingress.unpack();
|
||||
for (const SingleIngressData &item : ingress.getItems()) {
|
||||
map<AnnotationKeys, string> annotations_values = parseIngressAnnotations(
|
||||
item.getMetadata().getAnnotations()
|
||||
);
|
||||
|
||||
if (annotations_values[AnnotationKeys::PolicyKey].empty()) {
|
||||
dbgInfo(D_LOCAL_POLICY) << "No policy was found in this ingress";
|
||||
continue;
|
||||
}
|
||||
|
||||
auto maybe_appsec_policy = createAppsecPolicyK8s(
|
||||
annotations_values[AnnotationKeys::PolicyKey],
|
||||
annotations_values[AnnotationKeys::ModeKey]
|
||||
);
|
||||
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: "
|
||||
<< std::get<1>(maybe_appsec_policy).getErr();
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
return make_tuple(v1bet1_policies, v1bet2_policies);
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
// 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 "local_policy_mgmt_gen.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <streambuf>
|
||||
#include <cereal/types/vector.hpp>
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
|
||||
#include "rest.h"
|
||||
#include "debug.h"
|
||||
#include "config.h"
|
||||
#include "connkey.h"
|
||||
#include "url_parser.h"
|
||||
#include "i_agent_details.h"
|
||||
#include "customized_cereal_map.h"
|
||||
#include "include/appsec_practice_section.h"
|
||||
#include "include/ingress_data.h"
|
||||
#include "include/settings_section.h"
|
||||
#include "include/triggers_section.h"
|
||||
#include "include/local_policy_common.h"
|
||||
#include "include/exceptions_section.h"
|
||||
#include "include/rules_config_section.h"
|
||||
#include "include/trusted_sources_section.h"
|
||||
#include "include/policy_maker_utils.h"
|
||||
#include "k8s_policy_utils.h"
|
||||
#include "i_env_details.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
|
||||
const static string default_local_appsec_policy_path = "/tmp/local_appsec.policy";
|
||||
const static string default_local_mgmt_policy_path = "/conf/local_policy.yaml";
|
||||
|
||||
class LocalPolicyMgmtGenerator::Impl
|
||||
:
|
||||
public Singleton::Provide<I_LocalPolicyMgmtGen>::From<LocalPolicyMgmtGenerator>,
|
||||
public Singleton::Consume<I_MainLoop>,
|
||||
public Singleton::Consume<I_EnvDetails>
|
||||
{
|
||||
|
||||
public:
|
||||
void
|
||||
init()
|
||||
{
|
||||
}
|
||||
|
||||
string
|
||||
parseLinuxPolicy(const string &policy_version, const string &local_policy_path)
|
||||
{
|
||||
dbgFlow(D_LOCAL_POLICY) << "Starting to parse policy - embedded environment";
|
||||
|
||||
return policy_maker_utils.proccesSingleAppsecPolicy(
|
||||
local_policy_path,
|
||||
policy_version,
|
||||
default_local_appsec_policy_path
|
||||
);
|
||||
}
|
||||
|
||||
string
|
||||
parseK8sPolicy(const string &policy_version)
|
||||
{
|
||||
dbgFlow(D_LOCAL_POLICY) << "Starting to parse policy - K8S environment";
|
||||
|
||||
dbgInfo(D_LOCAL_POLICY) << "Initializing K8S policy generator";
|
||||
K8sPolicyUtils k8s_policy_utils;
|
||||
k8s_policy_utils.init();
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
string
|
||||
generateAppSecLocalPolicy(EnvType env_type, const string &policy_version, const string &local_policy_paths)
|
||||
{
|
||||
return env_type == EnvType::K8S ?
|
||||
parseK8sPolicy(policy_version) : parseLinuxPolicy(policy_version, local_policy_paths);
|
||||
}
|
||||
|
||||
private:
|
||||
PolicyMakerUtils policy_maker_utils;
|
||||
|
||||
};
|
||||
|
||||
LocalPolicyMgmtGenerator::LocalPolicyMgmtGenerator()
|
||||
:
|
||||
Component("LocalPolicyMgmtGenerator"),
|
||||
pimpl(make_unique<LocalPolicyMgmtGenerator::Impl>()) {}
|
||||
|
||||
LocalPolicyMgmtGenerator::~LocalPolicyMgmtGenerator() {}
|
||||
|
||||
void
|
||||
LocalPolicyMgmtGenerator::init()
|
||||
{
|
||||
pimpl->init();
|
||||
}
|
72
components/security_apps/local_policy_mgmt_gen/new_appsec_linux_policy.cc
Executable file
72
components/security_apps/local_policy_mgmt_gen/new_appsec_linux_policy.cc
Executable file
@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "new_appsec_linux_policy.h"
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
|
||||
using namespace std;
|
||||
|
||||
const NewAppsecPolicySpec &
|
||||
V1beta2AppsecLinuxPolicy::getAppsecPolicySpec() const
|
||||
{
|
||||
return policies;
|
||||
}
|
||||
|
||||
const vector<NewAppSecPracticeSpec> &
|
||||
V1beta2AppsecLinuxPolicy::getAppSecPracticeSpecs() const
|
||||
{
|
||||
return threat_prevection_practices;
|
||||
}
|
||||
|
||||
const vector<AccessControlPracticeSpec> &
|
||||
V1beta2AppsecLinuxPolicy::getAccessControlPracticeSpecs() const
|
||||
{
|
||||
return access_control_practices;
|
||||
}
|
||||
|
||||
const vector<NewAppsecLogTrigger> &
|
||||
V1beta2AppsecLinuxPolicy::getAppsecTriggerSpecs() const
|
||||
{
|
||||
return log_triggers;
|
||||
}
|
||||
|
||||
const vector<NewAppSecCustomResponse> &
|
||||
V1beta2AppsecLinuxPolicy::getAppSecCustomResponseSpecs() const
|
||||
{
|
||||
return custom_responses;
|
||||
}
|
||||
|
||||
const vector<NewAppsecException> &
|
||||
V1beta2AppsecLinuxPolicy::getAppsecExceptions() 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
|
154
components/security_apps/local_policy_mgmt_gen/new_appsec_policy_crd_parser.cc
Executable file
154
components/security_apps/local_policy_mgmt_gen/new_appsec_policy_crd_parser.cc
Executable file
@ -0,0 +1,154 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "new_appsec_policy_crd_parser.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
|
||||
static const set<string> valid_modes = {"prevent-learn", "detect-learn", "prevent", "detect", "inactive"};
|
||||
|
||||
void
|
||||
NewParsedRule::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec NewParsedRule";
|
||||
parseAppsecJSONKey<vector<string>>("exceptions", exceptions, archive_in);
|
||||
parseAppsecJSONKey<vector<string>>("triggers", log_triggers, archive_in);
|
||||
parseAppsecJSONKey<vector<string>>("threatPreventionPractices", threat_prevention_practices, archive_in);
|
||||
parseAppsecJSONKey<vector<string>>("accessControlPractices", access_control_practices, archive_in);
|
||||
parseAppsecJSONKey<string>("mode", mode, archive_in);
|
||||
if (valid_modes.count(mode) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec New Parsed Rule mode invalid: " << mode;
|
||||
}
|
||||
parseAppsecJSONKey<string>("customResponse", custom_response, archive_in);
|
||||
parseAppsecJSONKey<string>("sourceIdentifiers", source_identifiers, archive_in);
|
||||
parseAppsecJSONKey<string>("trustedSources", trusted_sources, archive_in);
|
||||
try {
|
||||
archive_in(cereal::make_nvp("host", host));
|
||||
} catch (const cereal::Exception &e)
|
||||
{
|
||||
// The default NewParsedRule does not hold a host, so by default it will be *
|
||||
host = "*";
|
||||
}
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
NewParsedRule::getLogTriggers() const
|
||||
{
|
||||
return log_triggers;
|
||||
}
|
||||
const vector<string> &
|
||||
|
||||
NewParsedRule::getExceptions() const
|
||||
{
|
||||
return exceptions;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
NewParsedRule::getPractices() const
|
||||
{
|
||||
return threat_prevention_practices;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
NewParsedRule::getAccessControlPractices() const
|
||||
{
|
||||
return access_control_practices;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewParsedRule::getSourceIdentifiers() const
|
||||
{
|
||||
return source_identifiers;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewParsedRule::getCustomResponse() const
|
||||
{
|
||||
return custom_response;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewParsedRule::getTrustedSources() const
|
||||
{
|
||||
return trusted_sources;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewParsedRule::getHost() const
|
||||
{
|
||||
return host;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewParsedRule::getMode() const
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
void
|
||||
NewParsedRule::setHost(const string &_host)
|
||||
{
|
||||
host = _host;
|
||||
}
|
||||
|
||||
void
|
||||
NewParsedRule::setMode(const string &_mode)
|
||||
{
|
||||
mode = _mode;
|
||||
}
|
||||
|
||||
void
|
||||
NewAppsecPolicySpec::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec policy spec";
|
||||
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
||||
parseAppsecJSONKey<NewParsedRule>("default", default_rule, archive_in);
|
||||
parseAppsecJSONKey<vector<NewParsedRule>>("specificRules", specific_rules, archive_in);
|
||||
}
|
||||
|
||||
const NewParsedRule &
|
||||
NewAppsecPolicySpec::getDefaultRule() const
|
||||
{
|
||||
return default_rule;
|
||||
}
|
||||
|
||||
const vector<NewParsedRule> &
|
||||
NewAppsecPolicySpec::getSpecificRules() const
|
||||
{
|
||||
return specific_rules;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppsecPolicySpec::getAppSecClassName() const
|
||||
{
|
||||
return appsec_class_name;
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecPolicySpec::isAssetHostExist(const std::string &full_url) const
|
||||
{
|
||||
for (const NewParsedRule &rule : specific_rules) {
|
||||
if (rule.getHost() == full_url) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
NewAppsecPolicySpec::addSpecificRule(const NewParsedRule &_rule)
|
||||
{
|
||||
specific_rules.push_back(_rule);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
99
components/security_apps/local_policy_mgmt_gen/new_custom_response.cc
Executable file
99
components/security_apps/local_policy_mgmt_gen/new_custom_response.cc
Executable file
@ -0,0 +1,99 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "new_custom_response.h"
|
||||
|
||||
#define MIN_RESPONSE_CODE 100
|
||||
#define MAX_RESPOMSE_CODE 599
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
|
||||
static const set<string> valid_modes = {"block-page", "response-code-only", "redirect"};
|
||||
|
||||
void
|
||||
NewAppSecCustomResponse::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec web user response spec";
|
||||
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
||||
parseAppsecJSONKey<int>("httpResponseCode", http_response_code, archive_in, 403);
|
||||
if (http_response_code < MIN_RESPONSE_CODE || http_response_code > MAX_RESPOMSE_CODE) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec web user response code invalid: " << http_response_code;
|
||||
}
|
||||
parseAppsecJSONKey<string>("mode", mode, archive_in, "block-page");
|
||||
if (valid_modes.count(mode) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec web user response mode invalid: " << mode;
|
||||
}
|
||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||
parseAppsecJSONKey<string>("redirectUrl", redirect_url, archive_in);
|
||||
parseAppsecJSONKey<bool>("redirectAddXEventId", redirect_add_x_event_id, archive_in);
|
||||
if (mode == "block-page") {
|
||||
parseAppsecJSONKey<string>(
|
||||
"messageBody",
|
||||
message_body,
|
||||
archive_in,
|
||||
"Openappsec's <b>Application Security</b> has detected an attack and blocked it."
|
||||
);
|
||||
parseAppsecJSONKey<string>(
|
||||
"messageTitle",
|
||||
message_title,
|
||||
archive_in,
|
||||
"Attack blocked by web application protection"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NewAppSecCustomResponse::setName(const string &_name)
|
||||
{
|
||||
name = _name;
|
||||
}
|
||||
|
||||
int
|
||||
NewAppSecCustomResponse::getHttpResponseCode() const
|
||||
{
|
||||
return http_response_code;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppSecCustomResponse::getMessageBody() const
|
||||
{
|
||||
return message_body;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppSecCustomResponse::getMessageTitle() const
|
||||
{
|
||||
return message_title;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppSecCustomResponse::getAppSecClassName() const
|
||||
{
|
||||
return appsec_class_name;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppSecCustomResponse::getMode() const
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppSecCustomResponse::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
187
components/security_apps/local_policy_mgmt_gen/new_exceptions.cc
Executable file
187
components/security_apps/local_policy_mgmt_gen/new_exceptions.cc
Executable file
@ -0,0 +1,187 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "new_exceptions.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
static const set<string> valid_actions = {"skip", "accept", "drop", "suppressLog"};
|
||||
|
||||
void
|
||||
NewAppsecExceptionCondition::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading New AppSec exception condition";
|
||||
parseAppsecJSONKey<string>("key", key, archive_in);
|
||||
parseAppsecJSONKey<string>("value", value, archive_in);
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppsecExceptionCondition::getKey() const
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppsecExceptionCondition::getvalue() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
NewAppsecException::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading New AppSec exception";
|
||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||
parseAppsecJSONKey<string>("action", action, archive_in);
|
||||
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
||||
if (valid_actions.count(action) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec exception action invalid: " << action;
|
||||
}
|
||||
parseAppsecJSONKey<vector<NewAppsecExceptionCondition>>("condition", conditions, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
NewAppsecException::setName(const string &_name)
|
||||
{
|
||||
name = _name;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppsecException::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppsecException::getAction() const
|
||||
{
|
||||
return action;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppsecException::getAppSecClassName() const
|
||||
{
|
||||
return appsec_class_name;
|
||||
}
|
||||
|
||||
const vector<string>
|
||||
NewAppsecException::getCountryCode() const
|
||||
{
|
||||
vector<string> country_codes;
|
||||
for (const NewAppsecExceptionCondition &condition : conditions) {
|
||||
if (condition.getKey() == "countryCode") {
|
||||
country_codes.push_back(condition.getvalue());
|
||||
}
|
||||
}
|
||||
return country_codes;
|
||||
}
|
||||
|
||||
const vector<string>
|
||||
NewAppsecException::getCountryName() const
|
||||
{
|
||||
vector<string> country_names;
|
||||
for (const NewAppsecExceptionCondition &condition : conditions) {
|
||||
if (condition.getKey() == "countryName") {
|
||||
country_names.push_back(condition.getvalue());
|
||||
}
|
||||
}
|
||||
return country_names;
|
||||
}
|
||||
|
||||
const vector<string>
|
||||
NewAppsecException::getHostName() const
|
||||
{
|
||||
vector<string> host_names;
|
||||
for (const NewAppsecExceptionCondition &condition : conditions) {
|
||||
if (condition.getKey() == "hostName") {
|
||||
host_names.push_back(condition.getvalue());
|
||||
}
|
||||
}
|
||||
return host_names;
|
||||
}
|
||||
|
||||
const vector<string>
|
||||
NewAppsecException::getParamName() const
|
||||
{
|
||||
vector<string> param_names;
|
||||
for (const NewAppsecExceptionCondition &condition : conditions) {
|
||||
if (condition.getKey() == "paramName") {
|
||||
param_names.push_back(condition.getvalue());
|
||||
}
|
||||
}
|
||||
return param_names;
|
||||
}
|
||||
|
||||
const vector<string>
|
||||
NewAppsecException::getParamValue() const
|
||||
{
|
||||
vector<string> param_values;
|
||||
for (const NewAppsecExceptionCondition &condition : conditions) {
|
||||
if (condition.getKey() == "paramValue") {
|
||||
param_values.push_back(condition.getvalue());
|
||||
}
|
||||
}
|
||||
return param_values;
|
||||
}
|
||||
|
||||
const vector<string>
|
||||
NewAppsecException::getProtectionName() const
|
||||
{
|
||||
vector<string> protection_names;
|
||||
for (const NewAppsecExceptionCondition &condition : conditions) {
|
||||
if (condition.getKey() == "protectionName") {
|
||||
protection_names.push_back(condition.getvalue());
|
||||
}
|
||||
}
|
||||
return protection_names;
|
||||
}
|
||||
|
||||
const vector<string>
|
||||
NewAppsecException::getSourceIdentifier() const
|
||||
{
|
||||
vector<string> source_identifiers;
|
||||
for (const NewAppsecExceptionCondition &condition : conditions) {
|
||||
if (condition.getKey() == "sourceIdentifier") {
|
||||
source_identifiers.push_back(condition.getvalue());
|
||||
}
|
||||
}
|
||||
return source_identifiers;
|
||||
}
|
||||
|
||||
const vector<string>
|
||||
NewAppsecException::getSourceIp() const
|
||||
{
|
||||
vector<string> source_ips;
|
||||
for (const NewAppsecExceptionCondition &condition : conditions) {
|
||||
if (condition.getKey() == "sourceIp") {
|
||||
source_ips.push_back(condition.getvalue());
|
||||
}
|
||||
}
|
||||
return source_ips;
|
||||
}
|
||||
|
||||
const vector<string>
|
||||
NewAppsecException::getUrl() const
|
||||
{
|
||||
vector<string> urls;
|
||||
for (const NewAppsecExceptionCondition &condition : conditions) {
|
||||
if (condition.getKey() == "url") {
|
||||
urls.push_back(condition.getvalue());
|
||||
}
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
321
components/security_apps/local_policy_mgmt_gen/new_log_trigger.cc
Executable file
321
components/security_apps/local_policy_mgmt_gen/new_log_trigger.cc
Executable file
@ -0,0 +1,321 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "new_log_trigger.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
|
||||
static const set<string> valid_severities = {"high", "critical"};
|
||||
static const set<string> valid_protocols = {"tcp", "udp"};
|
||||
static const set<string> valid_formats = {"json", "json-formatted"};
|
||||
|
||||
void
|
||||
NewAppsecTriggerAccessControlLogging::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger - Access Control Logging";
|
||||
parseAppsecJSONKey<bool>("allowEvents", allow_events, archive_in, false);
|
||||
parseAppsecJSONKey<bool>("dropEvents", drop_events, archive_in, false);
|
||||
}
|
||||
|
||||
void
|
||||
NewAppsecTriggerAdditionalSuspiciousEventsLogging::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger - Additional Suspicious Events Logging";
|
||||
parseAppsecJSONKey<bool>("enabled", enabled, archive_in, true);
|
||||
parseAppsecJSONKey<bool>("responseBody", response_body, archive_in, false);
|
||||
//the old code didn't parse the responsecode so ask Noam what is the currenct default value for it
|
||||
parseAppsecJSONKey<bool>("responseCode", response_code, archive_in, false);
|
||||
parseAppsecJSONKey<string>("minSeverity", minimum_severity, archive_in, "high");
|
||||
if (valid_severities.count(minimum_severity) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY)
|
||||
<< "AppSec AppSec Trigger - Additional Suspicious Events Logging minimum severity invalid: "
|
||||
<< minimum_severity;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerAdditionalSuspiciousEventsLogging::isEnabled() const
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerAdditionalSuspiciousEventsLogging::isResponseBody() const
|
||||
{
|
||||
return response_body;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppsecTriggerAdditionalSuspiciousEventsLogging::getMinimumSeverity() const
|
||||
{
|
||||
return minimum_severity;
|
||||
}
|
||||
|
||||
void
|
||||
NewAppsecTriggerLogging::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger Logging";
|
||||
parseAppsecJSONKey<bool>("detectEvents", detect_events, archive_in, false);
|
||||
parseAppsecJSONKey<bool>("preventEvents", prevent_events, archive_in, true);
|
||||
parseAppsecJSONKey<bool>("allWebRequests", all_web_requests, archive_in, false);
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerLogging::isAllWebRequests() const
|
||||
{
|
||||
return all_web_requests;
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerLogging::isDetectEvents() const
|
||||
{
|
||||
return detect_events;
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerLogging::isPreventEvents() const
|
||||
{
|
||||
return prevent_events;
|
||||
}
|
||||
|
||||
void
|
||||
NewAppsecTriggerExtendedLogging::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger Extended Logging";
|
||||
parseAppsecJSONKey<bool>("httpHeaders", http_headers, archive_in, false);
|
||||
parseAppsecJSONKey<bool>("requestBody", request_body, archive_in, false);
|
||||
parseAppsecJSONKey<bool>("urlPath", url_path, archive_in, false);
|
||||
parseAppsecJSONKey<bool>("urlQuery", url_query, archive_in, false);
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerExtendedLogging::isHttpHeaders() const
|
||||
{
|
||||
return http_headers;
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerExtendedLogging::isRequestBody() const
|
||||
{
|
||||
return request_body;
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerExtendedLogging::isUrlPath() const
|
||||
{
|
||||
return url_path;
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerExtendedLogging::isUrlQuery() const
|
||||
{
|
||||
return url_query;
|
||||
}
|
||||
|
||||
void
|
||||
NewLoggingService::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
parseAppsecJSONKey<string>("address", address, archive_in);
|
||||
parseAppsecJSONKey<string>("proto", proto, archive_in);
|
||||
if (valid_protocols.count(proto) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec Logging Service - proto invalid: " << proto;
|
||||
}
|
||||
|
||||
parseAppsecJSONKey<int>("port", port, archive_in, 514);
|
||||
}
|
||||
|
||||
const string &
|
||||
NewLoggingService::getAddress() const
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
int
|
||||
NewLoggingService::getPort() const
|
||||
{
|
||||
return port;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NewStdoutLogging::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
parseAppsecJSONKey<string>("format", format, archive_in, "json");
|
||||
if (valid_formats.count(format) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec Stdout Logging - format invalid: " << format;
|
||||
}
|
||||
}
|
||||
|
||||
const string &
|
||||
NewStdoutLogging::getFormat() const
|
||||
{
|
||||
return format;
|
||||
}
|
||||
|
||||
void
|
||||
NewAppsecTriggerLogDestination::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger LogDestination";
|
||||
// TBD: support "file"
|
||||
parseAppsecJSONKey<bool>("cloud", cloud, archive_in, false);
|
||||
auto mode = Singleton::Consume<I_AgentDetails>::by<NewAppsecTriggerLogDestination>()->getOrchestrationMode();
|
||||
auto env_type = Singleton::Consume<I_EnvDetails>::by<NewAppsecTriggerLogDestination>()->getEnvType();
|
||||
bool k8s_service_default = (mode == OrchestrationMode::HYBRID && env_type == EnvType::K8S);
|
||||
parseAppsecJSONKey<bool>("k8s-service", k8s_service, archive_in, k8s_service_default);
|
||||
|
||||
NewStdoutLogging stdout_log;
|
||||
parseAppsecJSONKey<NewStdoutLogging>("stdout", stdout_log, archive_in);
|
||||
agent_local = !(stdout_log.getFormat().empty());
|
||||
beautify_logs = stdout_log.getFormat() == "json-formatted";
|
||||
parseAppsecJSONKey<NewLoggingService>("syslogService", syslog_service, archive_in);
|
||||
parseAppsecJSONKey<NewLoggingService>("cefService", cef_service, archive_in);
|
||||
}
|
||||
|
||||
int
|
||||
NewAppsecTriggerLogDestination::getCefServerUdpPort() const
|
||||
{
|
||||
return getCefServiceData().getPort();
|
||||
}
|
||||
|
||||
int
|
||||
NewAppsecTriggerLogDestination::getSyslogServerUdpPort() const
|
||||
{
|
||||
return getSyslogServiceData().getPort();
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerLogDestination::isAgentLocal() const
|
||||
{
|
||||
return agent_local;
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerLogDestination::shouldBeautifyLogs() const
|
||||
{
|
||||
return beautify_logs;
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerLogDestination::getCloud() const
|
||||
{
|
||||
return cloud;
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerLogDestination::isK8SNeeded() const
|
||||
{
|
||||
return k8s_service;
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerLogDestination::isCefNeeded() const
|
||||
{
|
||||
return !getCefServiceData().getAddress().empty();
|
||||
}
|
||||
|
||||
bool
|
||||
NewAppsecTriggerLogDestination::isSyslogNeeded() const
|
||||
{
|
||||
return !getSyslogServiceData().getAddress().empty();
|
||||
}
|
||||
|
||||
const
|
||||
string & NewAppsecTriggerLogDestination::getSyslogServerIpv4Address() const
|
||||
{
|
||||
return getSyslogServiceData().getAddress();
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppsecTriggerLogDestination::getCefServerIpv4Address() const
|
||||
{
|
||||
return getCefServiceData().getAddress();
|
||||
}
|
||||
|
||||
const NewLoggingService &
|
||||
NewAppsecTriggerLogDestination::getSyslogServiceData() const
|
||||
{
|
||||
return syslog_service;
|
||||
}
|
||||
|
||||
const NewLoggingService &
|
||||
NewAppsecTriggerLogDestination::getCefServiceData() const
|
||||
{
|
||||
return cef_service;
|
||||
}
|
||||
|
||||
void
|
||||
NewAppsecLogTrigger::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec log trigger";
|
||||
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
||||
parseAppsecJSONKey<NewAppsecTriggerAccessControlLogging>(
|
||||
"accessControlLogging",
|
||||
access_control_logging,
|
||||
archive_in
|
||||
);
|
||||
parseAppsecJSONKey<NewAppsecTriggerAdditionalSuspiciousEventsLogging>(
|
||||
"additionalSuspiciousEventsLogging",
|
||||
additional_suspicious_events_logging,
|
||||
archive_in
|
||||
);
|
||||
parseAppsecJSONKey<NewAppsecTriggerLogging>("appsecLogging", appsec_logging, archive_in);
|
||||
parseAppsecJSONKey<NewAppsecTriggerExtendedLogging>("extendedLogging", extended_logging, archive_in);
|
||||
parseAppsecJSONKey<NewAppsecTriggerLogDestination>("logDestination", log_destination, archive_in);
|
||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
NewAppsecLogTrigger::setName(const string &_name)
|
||||
{
|
||||
name = _name;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppsecLogTrigger::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppsecLogTrigger::getAppSecClassName() const
|
||||
{
|
||||
return appsec_class_name;
|
||||
}
|
||||
|
||||
const NewAppsecTriggerAdditionalSuspiciousEventsLogging &
|
||||
NewAppsecLogTrigger::getAppsecTriggerAdditionalSuspiciousEventsLogging() const
|
||||
{
|
||||
return additional_suspicious_events_logging;
|
||||
}
|
||||
|
||||
const NewAppsecTriggerLogging &
|
||||
NewAppsecLogTrigger::getAppsecTriggerLogging() const
|
||||
{
|
||||
return appsec_logging;
|
||||
}
|
||||
|
||||
const NewAppsecTriggerExtendedLogging &
|
||||
NewAppsecLogTrigger::getAppsecTriggerExtendedLogging() const
|
||||
{
|
||||
return extended_logging;
|
||||
}
|
||||
|
||||
const NewAppsecTriggerLogDestination &
|
||||
NewAppsecLogTrigger::getAppsecTriggerLogDestination() const
|
||||
{
|
||||
return log_destination;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
986
components/security_apps/local_policy_mgmt_gen/new_practice.cc
Executable file
986
components/security_apps/local_policy_mgmt_gen/new_practice.cc
Executable file
@ -0,0 +1,986 @@
|
||||
// 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);
|
||||
}
|
||||
|
||||
SnortProtectionsSection::SnortProtectionsSection(
|
||||
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<std::string> &_files)
|
||||
:
|
||||
context(_context),
|
||||
asset_name(_asset_name),
|
||||
asset_id(_asset_id),
|
||||
practice_name(_practice_name),
|
||||
practice_id(_practice_id),
|
||||
source_identifier(_source_identifier),
|
||||
mode(_mode),
|
||||
files(_files)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SnortProtectionsSection::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("files", files),
|
||||
cereal::make_nvp("assetName", asset_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)
|
||||
);
|
||||
}
|
||||
|
||||
DetectionRules::DetectionRules(
|
||||
const std::string &_type,
|
||||
const std::string &_SSM,
|
||||
const std::string &_keywords,
|
||||
const std::vector<std::string> &_context)
|
||||
:
|
||||
type(_type),
|
||||
SSM(_SSM),
|
||||
keywords(_keywords),
|
||||
context(_context)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
DetectionRules::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading Snort protections protections detection rules section";
|
||||
parseAppsecJSONKey<string>("type", type, archive_in);
|
||||
parseAppsecJSONKey<string>("SSM", SSM, archive_in);
|
||||
parseAppsecJSONKey<string>("keywords", keywords, archive_in);
|
||||
parseAppsecJSONKey<vector<string>>("context", context, archive_in);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
DetectionRules::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("type", type),
|
||||
cereal::make_nvp("SSM", SSM),
|
||||
cereal::make_nvp("keywords", keywords),
|
||||
cereal::make_nvp("context", context)
|
||||
);
|
||||
}
|
||||
|
||||
ProtectionMetadata::ProtectionMetadata(
|
||||
bool _silent,
|
||||
const std::string &_protection_name,
|
||||
const std::string &_severity,
|
||||
const std::string &_confidence_level,
|
||||
const std::string &_performance_impact,
|
||||
const std::string &_last_update,
|
||||
const std::string &_maintrain_id,
|
||||
const std::vector<std::string> &_tags,
|
||||
const std::vector<std::string> &_cve_list)
|
||||
:
|
||||
silent(_silent),
|
||||
protection_name(_protection_name),
|
||||
severity(_severity),
|
||||
confidence_level(_confidence_level),
|
||||
performance_impact(_performance_impact),
|
||||
last_update(_last_update),
|
||||
maintrain_id(_maintrain_id),
|
||||
tags(_tags),
|
||||
cve_list(_cve_list)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProtectionMetadata::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading Snort protections protections metadata section";
|
||||
parseAppsecJSONKey<bool>("silent", silent, archive_in);
|
||||
parseAppsecJSONKey<string>("protectionName", protection_name, archive_in);
|
||||
parseAppsecJSONKey<string>("severity", severity, archive_in);
|
||||
parseAppsecJSONKey<string>("confidenceLevel", confidence_level, archive_in);
|
||||
parseAppsecJSONKey<string>("performanceImpact", performance_impact, archive_in);
|
||||
parseAppsecJSONKey<string>("lastUpdate", last_update, archive_in);
|
||||
parseAppsecJSONKey<string>("maintrainId", maintrain_id, archive_in);
|
||||
parseAppsecJSONKey<vector<string>>("tags", tags, archive_in);
|
||||
parseAppsecJSONKey<vector<string>>("cveList", cve_list, archive_in);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ProtectionMetadata::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("protectionName", protection_name),
|
||||
cereal::make_nvp("severity", severity),
|
||||
cereal::make_nvp("confidenceLevel", confidence_level),
|
||||
cereal::make_nvp("performanceImpact", performance_impact),
|
||||
cereal::make_nvp("lastUpdate", last_update),
|
||||
cereal::make_nvp("maintrainId", maintrain_id),
|
||||
cereal::make_nvp("tags", tags),
|
||||
cereal::make_nvp("cveList", cve_list),
|
||||
cereal::make_nvp("silent", silent)
|
||||
);
|
||||
}
|
||||
|
||||
ProtectionsProtectionsSection::ProtectionsProtectionsSection(
|
||||
const ProtectionMetadata &_protection_metadata,
|
||||
const DetectionRules &_detection_rules)
|
||||
:
|
||||
protection_metadata(_protection_metadata),
|
||||
detection_rules(_detection_rules)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProtectionsProtectionsSection::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading Snort protections protections section";
|
||||
parseAppsecJSONKey<ProtectionMetadata>("protectionMetadata", protection_metadata, archive_in);
|
||||
parseAppsecJSONKey<DetectionRules>("detectionRules", detection_rules, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
ProtectionsProtectionsSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("protectionMetadata", protection_metadata),
|
||||
cereal::make_nvp("detectionRules", detection_rules)
|
||||
);
|
||||
}
|
||||
|
||||
ProtectionsSection::ProtectionsSection(
|
||||
const std::vector<ProtectionsProtectionsSection> &_protections,
|
||||
const std::string &_name,
|
||||
const std::string &_modification_time)
|
||||
:
|
||||
protections(_protections),
|
||||
name(_name),
|
||||
modification_time(_modification_time)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProtectionsSection::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading Snort protections section";
|
||||
parseAppsecJSONKey<vector<ProtectionsProtectionsSection>>("protections", protections, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
ProtectionsSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("name", name),
|
||||
cereal::make_nvp("modificationTime", modification_time),
|
||||
cereal::make_nvp("protections", protections)
|
||||
);
|
||||
}
|
||||
|
||||
const vector<ProtectionsProtectionsSection> &
|
||||
ProtectionsSection::getProtections() const
|
||||
{
|
||||
return protections;
|
||||
}
|
||||
|
||||
void
|
||||
ProtectionsSectionWrapper::serialize(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading Snort Section";
|
||||
parseAppsecJSONKey<ProtectionsSection>("IPSSnortSigs", protections, archive_in);
|
||||
}
|
||||
|
||||
const vector<ProtectionsProtectionsSection> &
|
||||
ProtectionsSectionWrapper::getProtections() const
|
||||
{
|
||||
return protections.getProtections();
|
||||
}
|
||||
|
||||
void
|
||||
SnortSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
string version = "LocalVersion";
|
||||
out_ar(
|
||||
cereal::make_nvp("VersionId", version),
|
||||
cereal::make_nvp("SnortProtections", snort_protections),
|
||||
cereal::make_nvp("protections", protections)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
SnortSectionWrapper::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("IPSSnortSigs", snort)
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NewSnortSignaturesAndOpenSchemaAPI::addFile(const string &file_name)
|
||||
{
|
||||
files.push_back(file_name);
|
||||
}
|
||||
|
||||
const string &
|
||||
NewSnortSignaturesAndOpenSchemaAPI::getOverrideMode() const
|
||||
{
|
||||
return override_mode;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
NewSnortSignaturesAndOpenSchemaAPI::getFiles() const
|
||||
{
|
||||
return files;
|
||||
}
|
||||
|
||||
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 string &
|
||||
NewFileSecurity::getOverrideMode() const
|
||||
{
|
||||
return override_mode;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
NewSnortSignaturesAndOpenSchemaAPI &
|
||||
NewAppSecPracticeSpec::getSnortSignatures()
|
||||
{
|
||||
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
|
118
components/security_apps/local_policy_mgmt_gen/new_trusted_sources.cc
Executable file
118
components/security_apps/local_policy_mgmt_gen/new_trusted_sources.cc
Executable file
@ -0,0 +1,118 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "new_trusted_sources.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
|
||||
static const set<string> valid_identifiers = {"headerkey", "JWTKey", "cookie", "sourceip", "x-forwarded-for"};
|
||||
|
||||
void
|
||||
NewTrustedSourcesSpec::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading trusted sources spec";
|
||||
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
||||
parseAppsecJSONKey<int>("minNumOfSources", min_num_of_sources, archive_in, 3);
|
||||
parseAppsecJSONKey<vector<string>>("sourcesIdentifiers", sources_identifiers, archive_in);
|
||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
NewTrustedSourcesSpec::setName(const string &_name)
|
||||
{
|
||||
name = _name;
|
||||
}
|
||||
|
||||
int
|
||||
NewTrustedSourcesSpec::getMinNumOfSources() const
|
||||
{
|
||||
return min_num_of_sources;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
NewTrustedSourcesSpec::getSourcesIdentifiers() const
|
||||
{
|
||||
return sources_identifiers;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewTrustedSourcesSpec::getAppSecClassName() const
|
||||
{
|
||||
return appsec_class_name;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewTrustedSourcesSpec::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void
|
||||
Identifier::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading source identifiers spec";
|
||||
parseAppsecJSONKey<string>("sourceIdentifier", identifier, archive_in);
|
||||
if (valid_identifiers.count(identifier) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec identifier invalid: " << identifier;
|
||||
}
|
||||
parseAppsecJSONKey<vector<string>>("value", value, archive_in);
|
||||
}
|
||||
|
||||
const string &
|
||||
Identifier::getIdentifier() const
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
Identifier::getValues() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
NewSourcesIdentifiers::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading Sources Identifiers";
|
||||
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
||||
parseAppsecJSONKey<vector<Identifier>>("sourcesIdentifiers", sources_identifiers, archive_in);
|
||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
NewSourcesIdentifiers::setName(const string &_name)
|
||||
{
|
||||
name = _name;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewSourcesIdentifiers::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewSourcesIdentifiers::getAppSecClassName() const
|
||||
{
|
||||
return appsec_class_name;
|
||||
}
|
||||
|
||||
const vector<Identifier> &
|
||||
NewSourcesIdentifiers::getSourcesIdentifiers() const
|
||||
{
|
||||
return sources_identifiers;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
1590
components/security_apps/local_policy_mgmt_gen/policy_maker_utils.cc
Executable file
1590
components/security_apps/local_policy_mgmt_gen/policy_maker_utils.cc
Executable file
File diff suppressed because it is too large
Load Diff
369
components/security_apps/local_policy_mgmt_gen/rules_config_section.cc
Executable file
369
components/security_apps/local_policy_mgmt_gen/rules_config_section.cc
Executable file
@ -0,0 +1,369 @@
|
||||
// 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 "rules_config_section.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
|
||||
AssetUrlParser
|
||||
AssetUrlParser::parse(const string &uri)
|
||||
{
|
||||
AssetUrlParser result;
|
||||
|
||||
using iterator_t = string::const_iterator;
|
||||
|
||||
if (uri.length() == 0) return result;
|
||||
|
||||
iterator_t uri_end = uri.end();
|
||||
|
||||
// get query start
|
||||
iterator_t query_start = find(uri.begin(), uri_end, '?');
|
||||
|
||||
// protocol
|
||||
iterator_t protocol_start = uri.begin();
|
||||
iterator_t protocol_end = find(protocol_start, uri_end, ':'); //"://");
|
||||
|
||||
if (protocol_end != uri_end) {
|
||||
string http_protocol = &*(protocol_end);
|
||||
if ((http_protocol.length() > 3) && (http_protocol.substr(0, 3) == "://")) {
|
||||
result.protocol = string(protocol_start, protocol_end);
|
||||
protocol_end += 3; // ://
|
||||
} else {
|
||||
protocol_end = uri.begin(); // no protocol
|
||||
}
|
||||
} else {
|
||||
protocol_end = uri.begin(); // no protocol
|
||||
}
|
||||
|
||||
// URL
|
||||
iterator_t host_start = protocol_end;
|
||||
iterator_t path_start = find(host_start, uri_end, '/');
|
||||
|
||||
iterator_t host_end = find(protocol_end, (path_start != uri_end) ? path_start : query_start, ':');
|
||||
|
||||
result.asset_url = string(host_start, host_end);
|
||||
|
||||
// port
|
||||
if ((host_end != uri_end) && ((&*(host_end))[0] == ':')) { // we have a port
|
||||
host_end++;
|
||||
iterator_t portEnd = (path_start != uri_end) ? path_start : query_start;
|
||||
result.port = string(host_end, portEnd);
|
||||
}
|
||||
|
||||
// URI
|
||||
if (path_start != uri_end) result.asset_uri = string(path_start, query_start);
|
||||
|
||||
// query
|
||||
if (query_start != uri_end) result.query_string = string(query_start, uri.end());
|
||||
|
||||
return result;
|
||||
} // Parse
|
||||
|
||||
PracticeSection::PracticeSection(
|
||||
const string &_id,
|
||||
const string &_type,
|
||||
const string &_practice_name
|
||||
)
|
||||
{
|
||||
auto maybe_type = string_to_practice_type.find(_type);
|
||||
if (maybe_type == string_to_practice_type.end()) {
|
||||
dbgError(D_LOCAL_POLICY) << "Illegal pracrtice type: " << _type;
|
||||
return;
|
||||
}
|
||||
|
||||
type = _type;
|
||||
name = _practice_name;
|
||||
id = _id;
|
||||
}
|
||||
|
||||
void
|
||||
PracticeSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("practiceId", id),
|
||||
cereal::make_nvp("practiceName", name),
|
||||
cereal::make_nvp("practiceType", type)
|
||||
);
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
ParametersSection::ParametersSection(
|
||||
const string &_id,
|
||||
const string &_name)
|
||||
:
|
||||
name(_name),
|
||||
id(_id)
|
||||
{
|
||||
if (_id.empty() && _name.empty()) {
|
||||
dbgError(D_LOCAL_POLICY) << "Illegal Parameter values. Name and ID are empty";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ParametersSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("parameterId", id),
|
||||
cereal::make_nvp("parameterName", name),
|
||||
cereal::make_nvp("parameterType", type)
|
||||
);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
RulesTriggerSection::RulesTriggerSection(
|
||||
const string &_name,
|
||||
const string &_id,
|
||||
const string &_type)
|
||||
:
|
||||
name(_name),
|
||||
id(_id)
|
||||
{
|
||||
if (_name.empty() && _id.empty()) {
|
||||
dbgError(D_LOCAL_POLICY) << "Illegal values for trigger. Name and ID are empty";
|
||||
return;
|
||||
}
|
||||
auto maybe_type = string_to_trigger_type.find(_type);
|
||||
if (maybe_type == string_to_trigger_type.end()) {
|
||||
dbgError(D_LOCAL_POLICY) << "Illegal trigger type in rule: " << _type;
|
||||
return;
|
||||
}
|
||||
type = _type;
|
||||
}
|
||||
|
||||
void
|
||||
RulesTriggerSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("triggerId", id),
|
||||
cereal::make_nvp("triggerName", name),
|
||||
cereal::make_nvp("triggerType", type)
|
||||
);
|
||||
}
|
||||
|
||||
RulesConfigRulebase::RulesConfigRulebase(
|
||||
const string &_name,
|
||||
const string &_url,
|
||||
const string &_uri,
|
||||
vector<PracticeSection> _practices,
|
||||
vector<ParametersSection> _parameters,
|
||||
vector<RulesTriggerSection> _triggers)
|
||||
:
|
||||
name(_name),
|
||||
practices(_practices),
|
||||
parameters(_parameters),
|
||||
triggers(_triggers)
|
||||
{
|
||||
try {
|
||||
bool any = _name == "Any" && _url == "Any" && _uri == "Any";
|
||||
id = any ? "Any" : _url+_uri;
|
||||
if (_uri != "/") {
|
||||
context = any ? "All()" : "Any("
|
||||
"All("
|
||||
"Any("
|
||||
"EqualHost(" + _url + ")"
|
||||
"),"
|
||||
"EqualListeningPort(80)" +
|
||||
string(_uri.empty() ? "" : ",BeginWithUri(" + _uri + ")") +
|
||||
"),"
|
||||
"All("
|
||||
"Any("
|
||||
"EqualHost(" + _url + ")"
|
||||
"),"
|
||||
"EqualListeningPort(443)" +
|
||||
string(_uri.empty() ? "" : ",BeginWithUri(" + _uri + ")") +
|
||||
")"
|
||||
")";
|
||||
} else {
|
||||
context = any ? "All()" : "Any("
|
||||
"All("
|
||||
"Any("
|
||||
"EqualHost(" + _url + ")"
|
||||
"),"
|
||||
"EqualListeningPort(80)"
|
||||
"),"
|
||||
"All("
|
||||
"Any("
|
||||
"EqualHost(" + _url + ")"
|
||||
"),"
|
||||
"EqualListeningPort(443)"
|
||||
")"
|
||||
")";
|
||||
}
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to generate rule UUID. Error: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RulesConfigRulebase::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
string empty_str = "";
|
||||
out_ar(
|
||||
cereal::make_nvp("assetId", id),
|
||||
cereal::make_nvp("assetName", name),
|
||||
cereal::make_nvp("ruleId", id),
|
||||
cereal::make_nvp("ruleName", name),
|
||||
cereal::make_nvp("context", context),
|
||||
cereal::make_nvp("priority", 1),
|
||||
cereal::make_nvp("isCleanup", false),
|
||||
cereal::make_nvp("parameters", parameters),
|
||||
cereal::make_nvp("practices", practices),
|
||||
cereal::make_nvp("triggers", triggers),
|
||||
cereal::make_nvp("zoneId", empty_str),
|
||||
cereal::make_nvp("zoneName", empty_str)
|
||||
);
|
||||
}
|
||||
|
||||
const string &
|
||||
RulesConfigRulebase::getContext() const
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
const string &
|
||||
RulesConfigRulebase::getAssetName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const string &
|
||||
RulesConfigRulebase::getAssetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
UsersIdentifier::UsersIdentifier(const string &_source_identifier, vector<string> _identifier_values)
|
||||
:
|
||||
source_identifier(_source_identifier),
|
||||
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
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("sourceIdentifier", source_identifier),
|
||||
cereal::make_nvp("identifierValues", identifier_values)
|
||||
);
|
||||
}
|
||||
|
||||
UsersIdentifiersRulebase::UsersIdentifiersRulebase(
|
||||
const string &_context,
|
||||
const string &_source_identifier,
|
||||
const vector<string> &_identifier_values,
|
||||
const vector<UsersIdentifier> &_source_identifiers)
|
||||
:
|
||||
context(_context),
|
||||
source_identifier(_source_identifier),
|
||||
identifier_values(_identifier_values),
|
||||
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
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("context", context),
|
||||
cereal::make_nvp("sourceIdentifier", source_identifier),
|
||||
cereal::make_nvp("identifierValues", identifier_values),
|
||||
cereal::make_nvp("sourceIdentifiers", source_identifiers)
|
||||
);
|
||||
}
|
||||
|
||||
RulesRulebase::RulesRulebase(
|
||||
const vector<RulesConfigRulebase> &_rules_config,
|
||||
const vector<UsersIdentifiersRulebase> &_users_identifiers)
|
||||
:
|
||||
rules_config(_rules_config),
|
||||
users_identifiers(_users_identifiers)
|
||||
{
|
||||
sort(rules_config.begin(), rules_config.end(), sortBySpecific);
|
||||
}
|
||||
|
||||
void
|
||||
RulesRulebase::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("rulesConfig", rules_config),
|
||||
cereal::make_nvp("usersIdentifiers", users_identifiers)
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
RulesRulebase::sortBySpecific(
|
||||
const RulesConfigRulebase &first,
|
||||
const RulesConfigRulebase &second
|
||||
)
|
||||
{
|
||||
return sortBySpecificAux(first.getAssetName(), second.getAssetName());
|
||||
}
|
||||
|
||||
bool
|
||||
RulesRulebase::sortBySpecificAux(const string &first, const string &second)
|
||||
{
|
||||
if (first.empty()) return false;
|
||||
if (second.empty()) return true;
|
||||
|
||||
AssetUrlParser first_parsed = AssetUrlParser::parse(first);
|
||||
AssetUrlParser second_parsed = AssetUrlParser::parse(second);
|
||||
|
||||
// sort by URL
|
||||
if (first_parsed.asset_url == "Any" && second_parsed.asset_url != "Any") return false;
|
||||
if (second_parsed.asset_url == "Any" && first_parsed.asset_url != "Any") return true;
|
||||
|
||||
// sort by port
|
||||
if (first_parsed.port == "*" && second_parsed.port != "*") return false;
|
||||
if (second_parsed.port == "*" && first_parsed.port != "*") return true;
|
||||
|
||||
// sort by URI
|
||||
if (first_parsed.asset_uri == "*" && second_parsed.asset_uri != "*") return false;
|
||||
if (second_parsed.asset_uri == "*" && first_parsed.asset_uri != "*") return true;
|
||||
|
||||
if (first_parsed.asset_uri.empty()) return false;
|
||||
if (second_parsed.asset_uri.empty()) return true;
|
||||
|
||||
if (second_parsed.asset_uri.find(first_parsed.asset_uri) != string::npos) return false;
|
||||
if (first_parsed.asset_uri.find(second_parsed.asset_uri) != string::npos) return true;
|
||||
|
||||
if (first_parsed.asset_url.empty()) return false;
|
||||
if (second_parsed.asset_url.empty()) return false;
|
||||
|
||||
return second < first;
|
||||
}
|
||||
|
||||
void
|
||||
RulesConfigWrapper::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("rulebase", rules_config_rulebase)
|
||||
);
|
||||
}
|
87
components/security_apps/local_policy_mgmt_gen/settings_section.cc
Executable file
87
components/security_apps/local_policy_mgmt_gen/settings_section.cc
Executable file
@ -0,0 +1,87 @@
|
||||
// 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 "settings_section.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
|
||||
AgentSettingsSection::AgentSettingsSection(
|
||||
const string &_key,
|
||||
const string &_value)
|
||||
:
|
||||
key(_key),
|
||||
value(_value)
|
||||
{
|
||||
try {
|
||||
id = to_string(boost::uuids::random_generator()());
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to generate agent setting UUID. Error: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AgentSettingsSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("id", id),
|
||||
cereal::make_nvp("key", key),
|
||||
cereal::make_nvp("value", value)
|
||||
);
|
||||
}
|
||||
|
||||
const string &
|
||||
AgentSettingsSection::getSettingId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
void
|
||||
SettingsRulebase::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
string profile_type = "Kubernetes";
|
||||
string upgrade_mode = "automatic";
|
||||
out_ar(
|
||||
cereal::make_nvp("agentSettings", agentSettings),
|
||||
cereal::make_nvp("agentType", profile_type),
|
||||
cereal::make_nvp("allowOnlyDefinedApplications", false),
|
||||
cereal::make_nvp("anyFog", true),
|
||||
cereal::make_nvp("maxNumberOfAgents", 10),
|
||||
cereal::make_nvp("upgradeMode", upgrade_mode)
|
||||
);
|
||||
}
|
||||
|
||||
SettingsWrapper::SettingsWrapper(SettingsRulebase _agent) : agent(_agent)
|
||||
{
|
||||
try {
|
||||
id = to_string(boost::uuids::random_generator()());
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to generate Settings Wrapper UUID. Error: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SettingsWrapper::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("profileType", profileType),
|
||||
cereal::make_nvp("tokenType", isToken),
|
||||
cereal::make_nvp("tokenType", tokenType),
|
||||
cereal::make_nvp("name", name),
|
||||
cereal::make_nvp("id", id),
|
||||
cereal::make_nvp("agent", agent)
|
||||
);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
54
components/security_apps/local_policy_mgmt_gen/snort_section.cc
Executable file
54
components/security_apps/local_policy_mgmt_gen/snort_section.cc
Executable file
@ -0,0 +1,54 @@
|
||||
// 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 "snort_section.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
|
||||
AgentSettingsSection::AgentSettingsSection(string _key, string _value) : key(_key), value(_value)
|
||||
{
|
||||
try {
|
||||
id = to_string(boost::uuids::random_generator()());
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to generate agent setting UUID. Error: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AgentSettingsSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("id", id),
|
||||
cereal::make_nvp("key", key),
|
||||
cereal::make_nvp("value", value)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
IpsSnortSigsRulebase::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
string profile_type = "KubernetesProfile";
|
||||
string upgrade_mode = "automatic";
|
||||
out_ar(
|
||||
cereal::make_nvp("agentSettings", agentSettings),
|
||||
cereal::make_nvp("agentType", profile_type),
|
||||
cereal::make_nvp("allowOnlyDefinedApplications", false),
|
||||
cereal::make_nvp("anyFog", true),
|
||||
cereal::make_nvp("maxNumberOfAgents", 10),
|
||||
cereal::make_nvp("upgradeMode", upgrade_mode)
|
||||
);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
535
components/security_apps/local_policy_mgmt_gen/triggers_section.cc
Executable file
535
components/security_apps/local_policy_mgmt_gen/triggers_section.cc
Executable file
@ -0,0 +1,535 @@
|
||||
// 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 "triggers_section.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
|
||||
static const set<string> valid_modes = {"block-page", "response-code-only"};
|
||||
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"};
|
||||
|
||||
LogTriggerSection::LogTriggerSection(
|
||||
const string &_name,
|
||||
const string &_verbosity,
|
||||
const string &_extendloggingMinSeverity,
|
||||
bool _extendlogging,
|
||||
bool _logToAgent,
|
||||
bool _logToCef,
|
||||
bool _logToCloud,
|
||||
bool _logToK8sService,
|
||||
bool _logToSyslog,
|
||||
bool _responseBody,
|
||||
bool _tpDetect,
|
||||
bool _tpPrevent,
|
||||
bool _webBody,
|
||||
bool _webHeaders,
|
||||
bool _webRequests,
|
||||
bool _webUrlPath,
|
||||
bool _webUrlQuery,
|
||||
int _cefPortNum,
|
||||
const string &_cefIpAddress,
|
||||
int _syslogPortNum,
|
||||
const string &_syslogIpAddress,
|
||||
bool _beautify_logs)
|
||||
:
|
||||
name(_name),
|
||||
verbosity(_verbosity),
|
||||
extendloggingMinSeverity(_extendloggingMinSeverity),
|
||||
extendlogging(_extendlogging),
|
||||
logToAgent(_logToAgent),
|
||||
logToCef(_logToCef),
|
||||
logToCloud(_logToCloud),
|
||||
logToK8sService(_logToK8sService),
|
||||
logToSyslog(_logToSyslog),
|
||||
responseBody(_responseBody),
|
||||
tpDetect(_tpDetect),
|
||||
tpPrevent(_tpPrevent),
|
||||
webBody(_webBody),
|
||||
webHeaders(_webHeaders),
|
||||
webRequests(_webRequests),
|
||||
webUrlPath(_webUrlPath),
|
||||
webUrlQuery(_webUrlQuery),
|
||||
cefPortNum (_cefPortNum),
|
||||
cefIpAddress (_cefIpAddress),
|
||||
syslogPortNum (_syslogPortNum),
|
||||
syslogIpAddress (_syslogIpAddress),
|
||||
beautify_logs(_beautify_logs)
|
||||
{
|
||||
try {
|
||||
id = to_string(boost::uuids::random_generator()());
|
||||
context = "triggerId(" + id + ")";
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to generate log trigger UUID. Error: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LogTriggerSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
string trigger_type = "log";
|
||||
string urlForSyslog = syslogIpAddress + ":" + to_string(syslogPortNum);
|
||||
string urlForCef = cefIpAddress + ":" + to_string(cefPortNum);
|
||||
out_ar(
|
||||
cereal::make_nvp("context", context),
|
||||
cereal::make_nvp("triggerName", name),
|
||||
cereal::make_nvp("triggerType", trigger_type),
|
||||
cereal::make_nvp("verbosity", verbosity),
|
||||
cereal::make_nvp("acAllow", false),
|
||||
cereal::make_nvp("acDrop", false),
|
||||
cereal::make_nvp("complianceViolations", false),
|
||||
cereal::make_nvp("complianceWarnings", false),
|
||||
cereal::make_nvp("extendloggingMinSeverity", extendloggingMinSeverity),
|
||||
cereal::make_nvp("extendlogging", extendlogging),
|
||||
cereal::make_nvp("logToAgent", logToAgent),
|
||||
cereal::make_nvp("logToCef", logToCef),
|
||||
cereal::make_nvp("logToCloud", logToCloud),
|
||||
cereal::make_nvp("logToK8sService", logToK8sService),
|
||||
cereal::make_nvp("logToSyslog", logToSyslog),
|
||||
cereal::make_nvp("responseBody", responseBody),
|
||||
cereal::make_nvp("responseCode", false),
|
||||
cereal::make_nvp("tpDetect", tpDetect),
|
||||
cereal::make_nvp("tpPrevent", tpPrevent),
|
||||
cereal::make_nvp("webBody", webBody),
|
||||
cereal::make_nvp("webHeaders", webHeaders),
|
||||
cereal::make_nvp("webRequests", webRequests),
|
||||
cereal::make_nvp("webUrlPath", webUrlPath),
|
||||
cereal::make_nvp("webUrlQuery", webUrlQuery),
|
||||
cereal::make_nvp("urlForSyslog", urlForSyslog),
|
||||
cereal::make_nvp("urlForCef", urlForCef),
|
||||
cereal::make_nvp("formatLoggingOutput", beautify_logs)
|
||||
);
|
||||
}
|
||||
|
||||
const string &
|
||||
LogTriggerSection::getTriggerId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
const string &
|
||||
LogTriggerSection::getTriggerName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
WebUserResponseTriggerSection::WebUserResponseTriggerSection(
|
||||
const string &_name,
|
||||
const string &_details_level,
|
||||
const string &_response_body,
|
||||
int _response_code,
|
||||
const string &_response_title)
|
||||
:
|
||||
name(_name),
|
||||
context(),
|
||||
details_level(_details_level),
|
||||
response_body(_response_body),
|
||||
response_title(_response_title),
|
||||
response_code(_response_code)
|
||||
{
|
||||
try {
|
||||
id = to_string(boost::uuids::random_generator()());
|
||||
context = "triggerId(" + id + ")";
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to generate webUserResponse trigger UUID. Error: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebUserResponseTriggerSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("context", context),
|
||||
cereal::make_nvp("triggerName", name),
|
||||
cereal::make_nvp("details level", details_level),
|
||||
cereal::make_nvp("response body", response_body),
|
||||
cereal::make_nvp("response code", response_code),
|
||||
cereal::make_nvp("response title", response_title)
|
||||
);
|
||||
}
|
||||
|
||||
const string &
|
||||
WebUserResponseTriggerSection::getTriggerId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
void
|
||||
AppSecCustomResponseSpec::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec web user response spec";
|
||||
parseAppsecJSONKey<int>("http-response-code", httpResponseCode, archive_in, 403);
|
||||
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);
|
||||
if (mode == "block-page") {
|
||||
parseAppsecJSONKey<string>(
|
||||
"message-body",
|
||||
messageBody,
|
||||
archive_in,
|
||||
"Openappsec's <b>Application Security</b> has detected an attack and blocked it."
|
||||
);
|
||||
parseAppsecJSONKey<string>(
|
||||
"message-title",
|
||||
messageTitle,
|
||||
archive_in,
|
||||
"Attack blocked by web application protection"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AppSecCustomResponseSpec::setName(const string &_name)
|
||||
{
|
||||
name = _name;
|
||||
}
|
||||
|
||||
int
|
||||
AppSecCustomResponseSpec::getHttpResponseCode() const
|
||||
{
|
||||
return httpResponseCode;
|
||||
}
|
||||
|
||||
const string &
|
||||
AppSecCustomResponseSpec::getMessageBody() const
|
||||
{
|
||||
return messageBody;
|
||||
}
|
||||
|
||||
const string &
|
||||
AppSecCustomResponseSpec::getMessageTitle() const
|
||||
{
|
||||
return messageTitle;
|
||||
}
|
||||
|
||||
const string &
|
||||
AppSecCustomResponseSpec::getMode() const
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
const string &
|
||||
AppSecCustomResponseSpec::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void
|
||||
TriggersRulebase::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("log", logTriggers),
|
||||
cereal::make_nvp("webUserResponse", webUserResponseTriggers)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
AppsecTriggerAccessControlLogging::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger - Access Control Logging";
|
||||
parseAppsecJSONKey<bool>("allow-events", allow_events, archive_in, false);
|
||||
parseAppsecJSONKey<bool>("drop-events", drop_events, archive_in, false);
|
||||
}
|
||||
|
||||
void
|
||||
AppsecTriggerAdditionalSuspiciousEventsLogging::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>("response-body", response_body, archive_in, false);
|
||||
parseAppsecJSONKey<string>("minimum-severity", minimum_severity, archive_in, "high");
|
||||
if (valid_severities.count(minimum_severity) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY)
|
||||
<< "AppSec AppSec Trigger - Additional Suspicious Events Logging minimum severity invalid: "
|
||||
<< minimum_severity;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerAdditionalSuspiciousEventsLogging::isEnabled() const
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerAdditionalSuspiciousEventsLogging::isResponseBody() const
|
||||
{
|
||||
return response_body;
|
||||
}
|
||||
|
||||
const string &
|
||||
AppsecTriggerAdditionalSuspiciousEventsLogging::getMinimumSeverity() const
|
||||
{
|
||||
return minimum_severity;
|
||||
}
|
||||
|
||||
void
|
||||
AppsecTriggerLogging::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger Logging";
|
||||
parseAppsecJSONKey<bool>("all-web-requests", all_web_requests, archive_in, false);
|
||||
parseAppsecJSONKey<bool>("detect-events", detect_events, archive_in, false);
|
||||
parseAppsecJSONKey<bool>("prevent-events", prevent_events, archive_in, true);
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerLogging::isAllWebRequests() const
|
||||
{
|
||||
return all_web_requests;
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerLogging::isDetectEvents() const
|
||||
{
|
||||
return detect_events;
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerLogging::isPreventEvents() const
|
||||
{
|
||||
return prevent_events;
|
||||
}
|
||||
|
||||
void
|
||||
AppsecTriggerExtendedLogging::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger Extended Logging";
|
||||
parseAppsecJSONKey<bool>("http-headers", http_headers, archive_in, false);
|
||||
parseAppsecJSONKey<bool>("request-body", request_body, archive_in, false);
|
||||
parseAppsecJSONKey<bool>("url-path", url_path, archive_in, false);
|
||||
parseAppsecJSONKey<bool>("url-query", url_query, archive_in, false);
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerExtendedLogging::isHttpHeaders() const
|
||||
{
|
||||
return http_headers;
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerExtendedLogging::isRequestBody() const
|
||||
{
|
||||
return request_body;
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerExtendedLogging::isUrlPath() const
|
||||
{
|
||||
return url_path;
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerExtendedLogging::isUrlQuery() const
|
||||
{
|
||||
return url_query;
|
||||
}
|
||||
|
||||
void
|
||||
LoggingService::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 &
|
||||
LoggingService::getAddress() const
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
int
|
||||
LoggingService::getPort() const
|
||||
{
|
||||
return port;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StdoutLogging::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 &
|
||||
StdoutLogging::getFormat() const
|
||||
{
|
||||
return format;
|
||||
}
|
||||
|
||||
void
|
||||
AppsecTriggerLogDestination::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<AppsecTriggerLogDestination>()->getOrchestrationMode();
|
||||
auto env_type = Singleton::Consume<I_EnvDetails>::by<AppsecTriggerLogDestination>()->getEnvType();
|
||||
bool k8s_service_default = (mode == OrchestrationMode::HYBRID && env_type == EnvType::K8S);
|
||||
parseAppsecJSONKey<bool>("k8s-service", k8s_service, archive_in, k8s_service_default);
|
||||
|
||||
StdoutLogging stdout_log;
|
||||
parseAppsecJSONKey<StdoutLogging>("stdout", stdout_log, archive_in);
|
||||
agent_local = !(stdout_log.getFormat().empty());
|
||||
beautify_logs = stdout_log.getFormat() == "json-formatted";
|
||||
parseAppsecJSONKey<LoggingService>("syslog-service", syslog_service, archive_in);
|
||||
parseAppsecJSONKey<LoggingService>("cef-service", cef_service, archive_in);
|
||||
}
|
||||
|
||||
int
|
||||
AppsecTriggerLogDestination::getCefServerUdpPort() const
|
||||
{
|
||||
return getCefServiceData().getPort();
|
||||
}
|
||||
|
||||
int
|
||||
AppsecTriggerLogDestination::getSyslogServerUdpPort() const
|
||||
{
|
||||
return getSyslogServiceData().getPort();
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerLogDestination::isAgentLocal() const
|
||||
{
|
||||
return agent_local;
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerLogDestination::shouldBeautifyLogs() const
|
||||
{
|
||||
return beautify_logs;
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerLogDestination::getCloud() const
|
||||
{
|
||||
return cloud;
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerLogDestination::isK8SNeeded() const
|
||||
{
|
||||
return k8s_service;
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerLogDestination::isCefNeeded() const
|
||||
{
|
||||
return !getCefServiceData().getAddress().empty();
|
||||
}
|
||||
|
||||
bool
|
||||
AppsecTriggerLogDestination::isSyslogNeeded() const
|
||||
{
|
||||
return !getSyslogServiceData().getAddress().empty();
|
||||
}
|
||||
|
||||
const
|
||||
string & AppsecTriggerLogDestination::getSyslogServerIpv4Address() const
|
||||
{
|
||||
return getSyslogServiceData().getAddress();
|
||||
}
|
||||
|
||||
const string &
|
||||
AppsecTriggerLogDestination::getCefServerIpv4Address() const
|
||||
{
|
||||
return getCefServiceData().getAddress();
|
||||
}
|
||||
|
||||
const LoggingService &
|
||||
AppsecTriggerLogDestination::getSyslogServiceData() const
|
||||
{
|
||||
return syslog_service;
|
||||
}
|
||||
|
||||
const LoggingService &
|
||||
AppsecTriggerLogDestination::getCefServiceData() const
|
||||
{
|
||||
return cef_service;
|
||||
}
|
||||
|
||||
void
|
||||
AppsecTriggerSpec::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec trigger spec";
|
||||
parseAppsecJSONKey<AppsecTriggerAccessControlLogging>(
|
||||
"access-control-logging",
|
||||
access_control_logging,
|
||||
archive_in
|
||||
);
|
||||
parseAppsecJSONKey<AppsecTriggerAdditionalSuspiciousEventsLogging>(
|
||||
"additional-suspicious-events-logging",
|
||||
additional_suspicious_events_logging,
|
||||
archive_in
|
||||
);
|
||||
parseAppsecJSONKey<AppsecTriggerLogging>("appsec-logging", appsec_logging, archive_in);
|
||||
parseAppsecJSONKey<AppsecTriggerExtendedLogging>("extended-logging", extended_logging, archive_in);
|
||||
parseAppsecJSONKey<AppsecTriggerLogDestination>("log-destination", log_destination, archive_in);
|
||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
AppsecTriggerSpec::setName(const string &_name)
|
||||
{
|
||||
name = _name;
|
||||
}
|
||||
|
||||
const string &
|
||||
AppsecTriggerSpec::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const AppsecTriggerAdditionalSuspiciousEventsLogging &
|
||||
AppsecTriggerSpec::getAppsecTriggerAdditionalSuspiciousEventsLogging() const
|
||||
{
|
||||
return additional_suspicious_events_logging;
|
||||
}
|
||||
|
||||
const AppsecTriggerLogging &
|
||||
AppsecTriggerSpec::getAppsecTriggerLogging() const
|
||||
{
|
||||
return appsec_logging;
|
||||
}
|
||||
|
||||
const AppsecTriggerExtendedLogging &
|
||||
AppsecTriggerSpec::getAppsecTriggerExtendedLogging() const
|
||||
{
|
||||
return extended_logging;
|
||||
}
|
||||
|
||||
const AppsecTriggerLogDestination &
|
||||
AppsecTriggerSpec::getAppsecTriggerLogDestination() const
|
||||
{
|
||||
return log_destination;
|
||||
}
|
||||
|
||||
void
|
||||
TriggersWrapper::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("rulebase", triggers_rulebase)
|
||||
);
|
||||
}
|
152
components/security_apps/local_policy_mgmt_gen/trusted_sources_section.cc
Executable file
152
components/security_apps/local_policy_mgmt_gen/trusted_sources_section.cc
Executable file
@ -0,0 +1,152 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "policy_maker_utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
|
||||
static const set<string> valid_source_identifiers = {"headerkey", "JWTKey", "cookie", "sourceip", "x-forwarded-for"};
|
||||
|
||||
void
|
||||
TrustedSourcesSpec::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading trusted sources spec";
|
||||
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
|
||||
TrustedSourcesSpec::setName(const string &_name)
|
||||
{
|
||||
name = _name;
|
||||
}
|
||||
|
||||
int
|
||||
TrustedSourcesSpec::getMinNumOfSources() const
|
||||
{
|
||||
return min_num_of_sources;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
TrustedSourcesSpec::getSourcesIdentifiers() const
|
||||
{
|
||||
return sources_identifiers;
|
||||
}
|
||||
|
||||
const string &
|
||||
TrustedSourcesSpec::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void
|
||||
SourcesIdentifiers::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
out_ar(
|
||||
cereal::make_nvp("sourceIdentifier", source_identifier),
|
||||
cereal::make_nvp("value", value)
|
||||
);
|
||||
}
|
||||
|
||||
const string &
|
||||
SourcesIdentifiers::getSourceIdent() const
|
||||
{
|
||||
return source_identifier;
|
||||
}
|
||||
|
||||
void
|
||||
SourceIdentifierSpec::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading source identifiers spec";
|
||||
parseAppsecJSONKey<string>("sourceIdentifier", source_identifier, archive_in);
|
||||
if (valid_source_identifiers.count(source_identifier) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec source identifier invalid: " << source_identifier;
|
||||
}
|
||||
parseAppsecJSONKey<vector<string>>("value", value, archive_in);
|
||||
}
|
||||
|
||||
const string &
|
||||
SourceIdentifierSpec::getSourceIdentifier() const
|
||||
{
|
||||
return source_identifier;
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
SourceIdentifierSpec::getValues() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
SourceIdentifierSpecWrapper::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading Source Identifier Spec Wrapper";
|
||||
parseAppsecJSONKey<vector<SourceIdentifierSpec>>("identifiers", identifiers, archive_in);
|
||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
SourceIdentifierSpecWrapper::setName(const string &_name)
|
||||
{
|
||||
name = _name;
|
||||
}
|
||||
|
||||
const string &
|
||||
SourceIdentifierSpecWrapper::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const vector<SourceIdentifierSpec> &
|
||||
SourceIdentifierSpecWrapper::getIdentifiers() const
|
||||
{
|
||||
return identifiers;
|
||||
}
|
||||
|
||||
AppSecTrustedSources::AppSecTrustedSources(
|
||||
const string &_name,
|
||||
int _num_of_sources,
|
||||
const vector<SourcesIdentifiers> &_sources_identifiers)
|
||||
:
|
||||
name(_name),
|
||||
num_of_sources(_num_of_sources),
|
||||
sources_identifiers(_sources_identifiers)
|
||||
{
|
||||
try {
|
||||
id = to_string(boost::uuids::random_generator()());
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to generate Trusted Sources ID. Error: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AppSecTrustedSources::save(cereal::JSONOutputArchive &out_ar) const
|
||||
{
|
||||
string parameter_type = "TrustedSource";
|
||||
out_ar(
|
||||
cereal::make_nvp("id", id),
|
||||
cereal::make_nvp("name", name),
|
||||
cereal::make_nvp("numOfSources", num_of_sources),
|
||||
cereal::make_nvp("sourcesIdentifiers", sources_identifiers),
|
||||
cereal::make_nvp("parameterType", parameter_type)
|
||||
);
|
||||
}
|
||||
|
||||
const vector<SourcesIdentifiers> &
|
||||
AppSecTrustedSources::getSourcesIdentifiers() const
|
||||
{
|
||||
return sources_identifiers;
|
||||
}
|
@ -12,7 +12,6 @@ add_subdirectory(manifest_controller)
|
||||
add_subdirectory(update_communication)
|
||||
add_subdirectory(details_resolver)
|
||||
add_subdirectory(health_check)
|
||||
add_subdirectory(local_policy_mgmt_gen)
|
||||
add_subdirectory(env_details)
|
||||
|
||||
#add_subdirectory(orchestration_ut)
|
||||
|
@ -42,6 +42,16 @@ checkSamlPortal(const string &command_output)
|
||||
return genError("Current host does not have SAML Portal configured");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getIDAGaia(const string &command_output)
|
||||
{
|
||||
if (command_output.find("Portal is running") != string::npos) {
|
||||
return string("ida_gaia");
|
||||
}
|
||||
|
||||
return genError("Current host does not have SAML Portal configured");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
checkIDP(shared_ptr<istream> file_stream)
|
||||
{
|
||||
@ -226,58 +236,24 @@ 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)
|
||||
{
|
||||
string line;
|
||||
bool found_parent_obj = false;
|
||||
while (getline(*file_stream, line)) {
|
||||
size_t parent_obj_pos = line.find(parent_obj);
|
||||
if (parent_obj_pos != string::npos) found_parent_obj = true;
|
||||
if (!found_parent_obj) continue;
|
||||
|
||||
size_t attr_pos = line.find(attr);
|
||||
if (attr_pos == string::npos) continue;
|
||||
line = line.substr(attr_pos + attr.size());
|
||||
return line;
|
||||
}
|
||||
return genError("Parent object attribute was not found. Attr: " + attr);
|
||||
}
|
||||
#endif // gaia || smb
|
||||
|
||||
#if defined(gaia)
|
||||
Maybe<string>
|
||||
getMgmtParentObjUid(shared_ptr<istream> file_stream)
|
||||
getMgmtParentObjUid(const string &command_output)
|
||||
{
|
||||
auto maybe_unparsed_uid = getMgmtParentObjAttr(file_stream, "cluster_object", "Uid ");
|
||||
if (!maybe_unparsed_uid.ok()) {
|
||||
return maybe_unparsed_uid;
|
||||
}
|
||||
const string &unparsed_uid = maybe_unparsed_uid.unpack();
|
||||
auto maybe_uid = chopHeadAndTail(unparsed_uid, "(\"{", "}\")");
|
||||
if (!maybe_uid.ok()) {
|
||||
return maybe_uid;
|
||||
}
|
||||
string uid = maybe_uid.unpack();
|
||||
transform(uid.begin(), uid.end(), uid.begin(), ::tolower);
|
||||
return uid;
|
||||
return getAttr(command_output, "Parent object uuid was not found");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getMgmtParentObjName(shared_ptr<istream> file_stream)
|
||||
getMgmtParentObjName(const string &command_output)
|
||||
{
|
||||
auto maybe_unparsed_name = getMgmtParentObjAttr(file_stream, "cluster_object", "Name ");
|
||||
if (!maybe_unparsed_name.ok()) {
|
||||
return maybe_unparsed_name;
|
||||
}
|
||||
const string &unparsed_name = maybe_unparsed_name.unpack();
|
||||
return chopHeadAndTail(unparsed_name, "(", ")");
|
||||
return getAttr(command_output, "Parent object name was not found");
|
||||
}
|
||||
|
||||
#elif defined(smb)
|
||||
Maybe<string>
|
||||
getMgmtParentObjUid(const string &command_output)
|
||||
getSmbMgmtParentObjUid(const string &command_output)
|
||||
{
|
||||
if (!command_output.empty()) {
|
||||
return command_output;
|
||||
@ -286,7 +262,7 @@ getMgmtParentObjUid(const string &command_output)
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getMgmtParentObjName(const string &command_output)
|
||||
getSmbMgmtParentObjName(const string &command_output)
|
||||
{
|
||||
if (!command_output.empty()) {
|
||||
return command_output;
|
||||
@ -314,6 +290,34 @@ getOsRelease(shared_ptr<istream> file_stream)
|
||||
return genError("Os release was not found");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getWaapModelVersion(shared_ptr<istream> file_stream)
|
||||
{
|
||||
string line;
|
||||
static const int max_lines = 5;
|
||||
int i = 0;
|
||||
bool found_key = false;
|
||||
while (i < max_lines && getline(*file_stream, line)) {
|
||||
if (!found_key) {
|
||||
size_t index = line.find("\"model_version\":");
|
||||
if (index != string::npos) {
|
||||
found_key = true;
|
||||
}
|
||||
} else {
|
||||
size_t start = line.find_first_of('"');
|
||||
size_t end = line.find_last_of('"');
|
||||
if (start != string::npos && end != string::npos && end > start) {
|
||||
return line.substr(start + 1, end - start - 1);
|
||||
} else {
|
||||
return genError("Model version value unreadable");
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return genError("Model version was not found");
|
||||
}
|
||||
|
||||
#if defined(alpine)
|
||||
string &
|
||||
ltrim(string &s)
|
||||
|
@ -55,6 +55,19 @@ SHELL_CMD_HANDLER(
|
||||
#if defined(gaia)
|
||||
SHELL_CMD_HANDLER("hasSupportedBlade", "enabled_blades", checkHasSupportedBlade)
|
||||
SHELL_CMD_HANDLER("hasSamlPortal", "mpclient status saml-vpn", checkSamlPortal)
|
||||
SHELL_CMD_HANDLER("requiredNanoServices", "mpclient status saml-vpn", getIDAGaia)
|
||||
SHELL_CMD_HANDLER(
|
||||
"cpProductIntegrationMgmtParentObjectName",
|
||||
"cat $FWDIR/database/myself_objects.C "
|
||||
"| awk -F '[:()]' '/:cluster_object/ {found=1; next} found && /:Name/ {print $3; exit}'",
|
||||
getMgmtParentObjName
|
||||
)
|
||||
SHELL_CMD_HANDLER(
|
||||
"cpProductIntegrationMgmtParentObjectUid",
|
||||
"cat $FWDIR/database/myself_objects.C "
|
||||
"| awk -F'[{}]' '/:cluster_object/ { found=1; next } found && /:Uid/ { uid=tolower($2); print uid; exit }'",
|
||||
getMgmtParentObjUid
|
||||
)
|
||||
SHELL_CMD_HANDLER(
|
||||
"Hardware",
|
||||
"cat $FWDIR/database/myself_objects.C | awk -F '[:()]' '/:appliance_type/ {print $3}' | head -n 1",
|
||||
@ -81,12 +94,12 @@ SHELL_CMD_HANDLER(
|
||||
SHELL_CMD_HANDLER(
|
||||
"cpProductIntegrationMgmtParentObjectName",
|
||||
"cpsdwan get_data | jq -r .cluster_name",
|
||||
getMgmtParentObjName
|
||||
getSmbMgmtParentObjName
|
||||
)
|
||||
SHELL_CMD_HANDLER(
|
||||
"cpProductIntegrationMgmtParentObjectUid",
|
||||
"cpsdwan get_data | jq -r .cluster_uuid",
|
||||
getMgmtParentObjUid
|
||||
getSmbMgmtParentObjUid
|
||||
)
|
||||
SHELL_CMD_HANDLER(
|
||||
"cpProductIntegrationMgmtObjectName",
|
||||
@ -143,4 +156,6 @@ FILE_CONTENT_HANDLER(
|
||||
FILE_CONTENT_HANDLER("os_release", "/etc/os-release", getOsRelease)
|
||||
#endif // gaia || smb
|
||||
|
||||
FILE_CONTENT_HANDLER("AppSecModelVersion", "/etc/cp/conf/waap/waap.data", getWaapModelVersion)
|
||||
|
||||
#endif // FILE_CONTENT_HANDLER
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "maybe_res.h"
|
||||
#include "enum_array.h"
|
||||
#include "i_shell_cmd.h"
|
||||
#include "i_orchestration_tools.h"
|
||||
#include "config.h"
|
||||
|
||||
using namespace std;
|
||||
@ -77,7 +78,8 @@ DetailsResolvingHanlder::Impl::getResolvedDetails() const
|
||||
const string &path = file_handler.second.first;
|
||||
FileContentHandler handler = file_handler.second.second;
|
||||
|
||||
shared_ptr<ifstream> in_file = make_shared<ifstream>(path);
|
||||
shared_ptr<ifstream> in_file =
|
||||
Singleton::Consume<I_OrchestrationTools>::by<DetailsResolvingHanlder>()->fileStreamWrapper(path);
|
||||
if (!in_file->is_open()) {
|
||||
dbgWarning(D_AGENT_DETAILS) << "Could not open file for processing. Path: " << path;
|
||||
continue;
|
||||
|
@ -18,11 +18,13 @@
|
||||
#include <map>
|
||||
|
||||
#include "i_shell_cmd.h"
|
||||
#include "i_orchestration_tools.h"
|
||||
#include "i_agent_details_reporter.h"
|
||||
|
||||
class DetailsResolvingHanlder
|
||||
:
|
||||
Singleton::Consume<I_ShellCmd>,
|
||||
Singleton::Consume<I_OrchestrationTools>,
|
||||
Singleton::Consume<I_AgentDetailsReporter>
|
||||
{
|
||||
public:
|
||||
|
@ -278,6 +278,36 @@ HttpsCurl::HttpsCurl(const HttpsCurl &other) :
|
||||
HttpCurl(other),
|
||||
ca_path(other.ca_path) {}
|
||||
|
||||
bool
|
||||
HttpsCurl::downloadOpenAppsecPackages()
|
||||
{
|
||||
char errorstr[CURL_ERROR_SIZE];
|
||||
CURL* curl_handle = curl_easy_init();
|
||||
if (!curl_handle) return false;
|
||||
|
||||
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 1);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 2);
|
||||
|
||||
curl_easy_setopt(curl_handle, CURLOPT_URL, ("https://" + curl_url).c_str());
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeResponseCallback);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &out_file);
|
||||
|
||||
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, errorstr);
|
||||
|
||||
CURLcode res = curl_easy_perform(curl_handle);
|
||||
if (res == CURLE_OK) {
|
||||
dbgTrace(D_HTTP_REQUEST) << "CURL HTTP request successfully completed.";
|
||||
} else {
|
||||
dbgWarning(D_HTTP_REQUEST) << "CURL result " + string(curl_easy_strerror(res));
|
||||
curl_easy_cleanup(curl_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
HttpsCurl::setCurlOpts(long timeout, HTTP_VERSION http_version)
|
||||
{
|
||||
@ -299,9 +329,9 @@ HttpsCurl::setCurlOpts(long timeout, HTTP_VERSION http_version)
|
||||
curl_easy_setopt(curl_handle, CURLOPT_HTTP_VERSION, http_version);
|
||||
|
||||
//SSL options
|
||||
if (getProfileAgentSettingWithDefault<bool>(
|
||||
false,
|
||||
"agent.config.message.ignoreSslValidation") == false)
|
||||
if (
|
||||
getProfileAgentSettingWithDefault<bool>(false, "agent.config.message.ignoreSslValidation") == false
|
||||
)
|
||||
{
|
||||
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 1L);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_SSL_CTX_FUNCTION, ssl_ctx_verify_certificate);
|
||||
|
@ -105,6 +105,7 @@ public:
|
||||
static CURLcode ssl_ctx_verify_certificate(CURL *curl, void *ssl_ctx, void *opq);
|
||||
static int verify_certificate(int preverify_ok, X509_STORE_CTX *ctx);
|
||||
void setCurlOpts(long timeout = 60L, HTTP_VERSION http_version = HTTP_VERSION::HTTP_VERSION_1_1) override;
|
||||
bool downloadOpenAppsecPackages();
|
||||
|
||||
private:
|
||||
std::string ca_path;
|
||||
|
@ -51,7 +51,7 @@ TEST_F(DownloaderTest, downloadFileFromFog)
|
||||
calculateChecksum(Package::ChecksumTypes::SHA256, "/tmp/virtualSettings.download")
|
||||
).WillOnce(Return(string("123")));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(fog_response, "/tmp/virtualSettings.download"))
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(fog_response, "/tmp/virtualSettings.download", false))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile("/tmp/virtualSettings.download")).WillOnce(Return(true));
|
||||
|
||||
@ -183,7 +183,7 @@ TEST_F(DownloaderTest, downloadEmptyFileFromFog)
|
||||
|
||||
EXPECT_CALL(mock_communication, downloadAttributeFile(resourse_file)).WillOnce(Return(fog_response));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(fog_response, "/tmp/manifest.download"))
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(fog_response, "/tmp/manifest.download", false))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile("/tmp/manifest.download")).WillOnce(Return(false));
|
||||
|
||||
@ -342,13 +342,23 @@ TEST_F(DownloaderTest, download_virtual_policy)
|
||||
|
||||
EXPECT_CALL(mock_communication, downloadAttributeFile(resourse_file)).WillOnce(Return(fog_response));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(tenant_0000_file, "/tmp/virtualPolicy_0000_profile_1234.download"))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(
|
||||
mock_orchestration_tools,
|
||||
writeFile(
|
||||
tenant_0000_file,
|
||||
"/tmp/virtualPolicy_0000_profile_1234.download",
|
||||
false)
|
||||
).WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, fillKeyInJson(_, _, _)).WillRepeatedly(Return());
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(tenant_1111_file, "/tmp/virtualPolicy_1111_profile_1235.download"))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(
|
||||
mock_orchestration_tools,
|
||||
writeFile(
|
||||
tenant_1111_file,
|
||||
"/tmp/virtualPolicy_1111_profile_1235.download",
|
||||
false)
|
||||
).WillOnce(Return(true));
|
||||
|
||||
map<pair<string, string>, string> expected_downloaded_files =
|
||||
{
|
||||
@ -427,7 +437,8 @@ TEST_F(DownloaderTest, download_virtual_settings)
|
||||
mock_orchestration_tools,
|
||||
writeFile(
|
||||
tenant_0000_file,
|
||||
tenant_0000_path.str()
|
||||
tenant_0000_path.str(),
|
||||
false
|
||||
)
|
||||
).WillOnce(Return(true));
|
||||
|
||||
|
@ -37,8 +37,8 @@ private:
|
||||
std::string loadCAChainDir();
|
||||
Maybe<void> getFileSSL(const URLParser &url, std::ofstream &out_file, const std::string &_token);
|
||||
Maybe<void> getFileHttp(const URLParser &url, std::ofstream &out_file, const std::string &_token);
|
||||
Maybe<void> curlGetFileOverSSL(const URLParser &url, std::ofstream &out_file, const std::string &_token);
|
||||
Maybe<void> curlGetFileOverHttp(const URLParser &url, std::ofstream &out_file, const std::string &_token);
|
||||
Maybe<void> curlGetFileOverSSL(const URLParser &url, std::ofstream &out_file, const std::string &_token);
|
||||
};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
|
@ -592,8 +592,13 @@ HTTPClient::curlGetFileOverSSL(const URLParser &url, ofstream &out_file, const s
|
||||
proxy_config->getProxyCredentials(ProxyProtocol::HTTPS),
|
||||
cert_file_path);
|
||||
|
||||
ssl_curl_client.setCurlOpts();
|
||||
bool connection_ok = ssl_curl_client.connect();
|
||||
bool connection_ok;
|
||||
if (url.getBaseURL().unpack() == "downloads.openappsec.io") {
|
||||
connection_ok = ssl_curl_client.downloadOpenAppsecPackages();
|
||||
} else {
|
||||
ssl_curl_client.setCurlOpts();
|
||||
connection_ok = ssl_curl_client.connect();
|
||||
}
|
||||
if (!connection_ok)
|
||||
{
|
||||
stringstream url_s;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "config.h"
|
||||
#include "log_generator.h"
|
||||
#include "health_check_manager.h"
|
||||
#include "agent_core_utilities.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ReportIS;
|
||||
@ -145,9 +146,11 @@ private:
|
||||
initCloudVendorConfig()
|
||||
{
|
||||
static const map<string, pair<string, int>> ip_port_defaults_map = {
|
||||
{"Azure", make_pair("168.63.129.16", 8117)},
|
||||
{"Aws", make_pair("", 8117)}
|
||||
{"Azure", make_pair(getenv("DOCKER_RPM_ENABLED") ? "" : "168.63.129.16", 8117)},
|
||||
{"Aws", make_pair("", 8117)},
|
||||
{"Local", make_pair("", 8117)}
|
||||
};
|
||||
|
||||
auto cloud_vendor_maybe = getSetting<string>("reverseProxy", "cloudVendorName");
|
||||
if (cloud_vendor_maybe.ok()) {
|
||||
const string cloud_vendor = cloud_vendor_maybe.unpack();
|
||||
@ -247,13 +250,36 @@ private:
|
||||
);
|
||||
}
|
||||
|
||||
HealthCheckStatus
|
||||
getStandaloneHealthStatus()
|
||||
{
|
||||
if (!getenv("DOCKER_RPM_ENABLED")) return HealthCheckStatus::IGNORED;
|
||||
|
||||
static const string standalone_cmd = "/usr/sbin/cpnano -s --docker-rpm; echo $?";
|
||||
dbgTrace(D_HEALTH_CHECK) << "Checking the standalone docker health status with command: " << standalone_cmd;
|
||||
|
||||
auto maybe_result = Singleton::Consume<I_ShellCmd>::by<HealthChecker>()->getExecOutput(standalone_cmd, 1000);
|
||||
if (!maybe_result.ok()) {
|
||||
dbgWarning(D_HEALTH_CHECK) << "Unable to get the standalone docker status. Returning unhealthy status.";
|
||||
return HealthCheckStatus::UNHEALTHY;
|
||||
}
|
||||
dbgTrace(D_HEALTH_CHECK) << "Got response: " << maybe_result.unpack();
|
||||
|
||||
auto response = NGEN::Strings::removeTrailingWhitespaces(maybe_result.unpack());
|
||||
|
||||
if (response.back() == '0') return HealthCheckStatus::HEALTHY;
|
||||
if (response.back() == '1') return HealthCheckStatus::UNHEALTHY;
|
||||
|
||||
return HealthCheckStatus::DEGRADED;
|
||||
}
|
||||
|
||||
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;
|
||||
dbgTrace(D_HEALTH_CHECK) << "Checking if the container is running with the command: " << cmd_running;
|
||||
|
||||
auto maybe_result = Singleton::Consume<I_ShellCmd>::by<HealthChecker>()->getExecOutput(cmd_running);
|
||||
if (!maybe_result.ok()) {
|
||||
@ -263,7 +289,6 @@ private:
|
||||
}
|
||||
|
||||
return (*maybe_result).find(nginx_container_name) != string::npos;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -279,7 +304,7 @@ private:
|
||||
{
|
||||
if (open_connections_counter >= max_connections) {
|
||||
dbgDebug(D_HEALTH_CHECK)
|
||||
<< "Cannot serve new client, reached maximun open connections bound which is:"
|
||||
<< "Cannot serve new client, reached maximum open connections bound which is:"
|
||||
<< open_connections_counter
|
||||
<< "maximum allowed: "
|
||||
<< max_connections;
|
||||
@ -331,6 +356,42 @@ private:
|
||||
"health check failed\r\n";
|
||||
static const vector<char> failure_response_buffer(failure_response.begin(), failure_response.end());
|
||||
|
||||
static const string degraded_response =
|
||||
"HTTP/1.1 202 OK\r\n"
|
||||
"Content-Length: 22\r\n"
|
||||
"Content-Type: text/plain\r\n"
|
||||
"\r\n"
|
||||
"health check partial\r\n";
|
||||
static const vector<char> degraded_response_buffer(degraded_response.begin(), degraded_response.end());
|
||||
|
||||
HealthCheckStatus standalone_status = getStandaloneHealthStatus();
|
||||
if (standalone_status != HealthCheckStatus::IGNORED) {
|
||||
if (standalone_status == HealthCheckStatus::HEALTHY) {
|
||||
dbgDebug(D_HEALTH_CHECK)
|
||||
<< "Standalone status is healthy, returning the following response: "
|
||||
<< success_response;
|
||||
i_socket->writeData(curr_client_socket, success_response_buffer);
|
||||
closeCurrentSocket(curr_client_socket, curr_routine_id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (standalone_status == HealthCheckStatus::UNHEALTHY) {
|
||||
dbgDebug(D_HEALTH_CHECK)
|
||||
<< "Standalone status in unhealthy, returning the following response: "
|
||||
<< failure_response;
|
||||
i_socket->writeData(curr_client_socket, failure_response_buffer);
|
||||
closeCurrentSocket(curr_client_socket, curr_routine_id);
|
||||
return;
|
||||
}
|
||||
|
||||
dbgDebug(D_HEALTH_CHECK)
|
||||
<< "Standalone status was partially loaded, returning the following response: "
|
||||
<< degraded_response;
|
||||
i_socket->writeData(curr_client_socket, degraded_response_buffer);
|
||||
closeCurrentSocket(curr_client_socket, curr_routine_id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nginxContainerIsRunning()) {
|
||||
dbgDebug(D_HEALTH_CHECK)
|
||||
<< "nginx conatiner is running, returning the following response: "
|
||||
|
@ -194,7 +194,7 @@ TEST_F(HealthCheckerTest, connectionsLimit)
|
||||
connection_handler_routine();
|
||||
|
||||
EXPECT_THAT(
|
||||
capture_debug.str(), HasSubstr("Cannot serve new client, reached maximun open connections")
|
||||
capture_debug.str(), HasSubstr("Cannot serve new client, reached maximum open connections")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,14 @@ class ApplyPolicyEvent : public Event<ApplyPolicyEvent>
|
||||
{
|
||||
public:
|
||||
ApplyPolicyEvent() {}
|
||||
ApplyPolicyEvent(const std::string &path) : local_policy_path(path) {}
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
std::string getPolicyPath() const { return local_policy_path; }
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
private:
|
||||
std::string local_policy_path;
|
||||
};
|
||||
|
||||
class DeclarativePolicyUtils
|
||||
@ -40,6 +48,7 @@ class DeclarativePolicyUtils
|
||||
Singleton::Consume<I_EnvDetails>,
|
||||
Singleton::Consume<I_AgentDetails>,
|
||||
Singleton::Consume<I_OrchestrationTools>,
|
||||
public Singleton::Consume<I_MainLoop>,
|
||||
Singleton::Consume<I_RestApi>,
|
||||
public Listener<ApplyPolicyEvent>
|
||||
{
|
||||
@ -50,8 +59,7 @@ public:
|
||||
void
|
||||
doCall() override
|
||||
{
|
||||
Singleton::Consume<I_LocalPolicyMgmtGen>::by<DeclarativePolicyUtils>()->setPolicyPath(policy_path.get());
|
||||
ApplyPolicyEvent().notify();
|
||||
ApplyPolicyEvent(policy_path.get()).notify();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -80,6 +88,7 @@ public:
|
||||
private:
|
||||
std::string getCleanChecksum(const std::string &unclean_checksum);
|
||||
|
||||
std::string local_policy_path;
|
||||
std::string curr_version;
|
||||
std::string curr_policy;
|
||||
bool should_apply_policy;
|
||||
|
@ -142,6 +142,7 @@ protected:
|
||||
std::string base64Encode(const std::string &in) const;
|
||||
std::string buildBasicAuthHeader(const std::string &username, const std::string &pass) const;
|
||||
std::string buildOAuth2Header(const std::string &token) const;
|
||||
std::string getUserEdition() const;
|
||||
|
||||
// This apps which the orchestrations requires them from Fog.
|
||||
std::vector<std::string> required_security_apps;
|
||||
|
@ -54,6 +54,7 @@ public:
|
||||
last_update = i_orch_status->getUpdateTime();
|
||||
last_update_status = i_orch_status->getUpdateStatus();
|
||||
policy_version = i_orch_status->getPolicyVersion();
|
||||
waap_model_version = i_orch_status->getWaapModelVersion();
|
||||
last_policy_update = i_orch_status->getLastPolicyUpdate();
|
||||
last_manifest_update = i_orch_status->getLastManifestUpdate();
|
||||
last_settings_update = i_orch_status->getLastSettingsUpdate();
|
||||
@ -72,6 +73,7 @@ private:
|
||||
S2C_LABEL_PARAM(std::string, last_update, "Last update");
|
||||
S2C_LABEL_PARAM(std::string, last_update_status, "Last update status");
|
||||
S2C_LABEL_PARAM(std::string, policy_version, "Policy version");
|
||||
S2C_LABEL_PARAM(std::string, waap_model_version, "AI model version");
|
||||
S2C_LABEL_PARAM(std::string, last_policy_update, "Last policy update");
|
||||
S2C_LABEL_PARAM(std::string, last_manifest_update, "Last manifest update");
|
||||
S2C_LABEL_PARAM(std::string, last_settings_update, "Last settings update");
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
MOCK_CONST_METHOD0(getUpdateTime, const std::string&());
|
||||
MOCK_CONST_METHOD0(getLastManifestUpdate, const std::string&());
|
||||
MOCK_CONST_METHOD0(getPolicyVersion, const std::string&());
|
||||
MOCK_CONST_METHOD0(getWaapModelVersion, const std::string&());
|
||||
MOCK_CONST_METHOD0(getLastPolicyUpdate, const std::string&());
|
||||
MOCK_CONST_METHOD0(getLastSettingsUpdate, const std::string&());
|
||||
MOCK_CONST_METHOD0(getUpgradeMode, const std::string&());
|
||||
|
@ -0,0 +1,35 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __NAMESPACE_DATA_H__
|
||||
#define __NAMESPACE_DATA_H__
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "cereal/archives/json.hpp"
|
||||
#include <cereal/types/map.hpp>
|
||||
|
||||
#include "rest.h"
|
||||
|
||||
class NamespaceData : public ClientRest
|
||||
{
|
||||
public:
|
||||
bool loadJson(const std::string &json);
|
||||
Maybe<std::string> getNamespaceUidByName(const std::string &name);
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> ns_name_to_uid;
|
||||
};
|
||||
|
||||
#endif // __NAMESPACE_DATA_H__
|
@ -76,6 +76,7 @@ public:
|
||||
|
||||
private:
|
||||
bool changeManifestFile(const string &new_manifest_file);
|
||||
bool updateIgnoreListForNSaaS();
|
||||
|
||||
bool
|
||||
handlePackage(
|
||||
@ -155,12 +156,36 @@ ManifestController::Impl::init()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ManifestController::Impl::updateIgnoreListForNSaaS()
|
||||
{
|
||||
if (!getProfileAgentSettingWithDefault<bool>(false, "accessControl.isAwsNSaaS")) return false;
|
||||
|
||||
auto ignore_packages_path = getConfigurationWithDefault<string>(
|
||||
getFilesystemPathConfig() + "/conf/ignore-packages.txt",
|
||||
"orchestration",
|
||||
"Ignore packages list file path"
|
||||
);
|
||||
ofstream ignore_file(ignore_packages_path);
|
||||
if (!ignore_file.is_open()) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Unable to open file " << ignore_packages_path << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
ignore_file << "all";
|
||||
ignore_file.close();
|
||||
dbgInfo(D_ORCHESTRATOR) << "Updated " << ignore_packages_path << " to ignore all packages";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ManifestController::Impl::updateManifest(const string &new_manifest_file)
|
||||
{
|
||||
auto i_env = Singleton::Consume<I_Environment>::by<ManifestController>();
|
||||
auto span_scope = i_env->startNewSpanScope(Span::ContextType::CHILD_OF);
|
||||
auto orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<ManifestController>();
|
||||
static bool ignore_packages_update = false;
|
||||
|
||||
if (isIgnoreFile(new_manifest_file)) {
|
||||
if (!orchestration_tools->copyFile(new_manifest_file, manifest_file_path)) {
|
||||
@ -173,9 +198,12 @@ ManifestController::Impl::updateManifest(const string &new_manifest_file)
|
||||
dbgDebug(D_ORCHESTRATOR) << "Starting to update manifest file";
|
||||
auto ignored_settings_packages = getProfileAgentSetting<IgnoredPackages>("orchestration.IgnoredPackagesList");
|
||||
set<string> packages_to_ignore = ignore_packages;
|
||||
if (ignored_settings_packages.ok()) packages_to_ignore = *(*ignored_settings_packages);
|
||||
if (ignored_settings_packages.ok()) {
|
||||
packages_to_ignore = *(*ignored_settings_packages);
|
||||
ignore_packages_update = false;
|
||||
}
|
||||
|
||||
if (packages_to_ignore.count("all") > 0) {
|
||||
if (ignore_packages_update || packages_to_ignore.count("all") > 0) {
|
||||
dbgTrace(D_ORCHESTRATOR) << "Nothing to update (\"ignore all\" turned on)";
|
||||
|
||||
if (!orchestration_tools->copyFile(new_manifest_file, manifest_file_path)) {
|
||||
@ -315,6 +343,8 @@ ManifestController::Impl::updateManifest(const string &new_manifest_file)
|
||||
|
||||
if (all_installed && (any_installed || no_change) && no_corrupted_package) {
|
||||
manifest_file_update = changeManifestFile(new_manifest_file);
|
||||
// In NSaaS - set ignore packages to any
|
||||
ignore_packages_update = updateIgnoreListForNSaaS();
|
||||
} else if (any_installed) {
|
||||
manifest_file_update = orchestration_tools->packagesToJsonFile(current_packages, manifest_file_path);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mock/mock_time_get.h"
|
||||
#include "mock/mock_orchestration_tools.h"
|
||||
#include "mock/mock_agent_details.h"
|
||||
#include "mock/mock_details_resolver.h"
|
||||
#include "mock/mock_mainloop.h"
|
||||
#include "mock/mock_rest_api.h"
|
||||
|
||||
@ -38,9 +39,17 @@ public:
|
||||
.WillOnce(DoAll(SaveArg<2>(&routine), Return(1))
|
||||
);
|
||||
EXPECT_CALL(mock_tools, readFile(file_path)).WillOnce(Return(start_file_content));
|
||||
prepareResolvedDetails();
|
||||
orchestration_status.init();
|
||||
}
|
||||
|
||||
void
|
||||
prepareResolvedDetails()
|
||||
{
|
||||
map<string, string> resolved_details({{"AppSecModelVersion", waap_model}});
|
||||
EXPECT_CALL(mock_details_resolver, getResolvedDetails()).WillRepeatedly(Return(resolved_details));
|
||||
}
|
||||
|
||||
string
|
||||
orchestrationStatusFileToString()
|
||||
{
|
||||
@ -82,7 +91,8 @@ public:
|
||||
const string ®istration_details_architecture = "",
|
||||
const string &agent_id = "None",
|
||||
const string &profile_id = "None",
|
||||
const string &tenant_id = "None"
|
||||
const string &tenant_id = "None",
|
||||
const string &waap_model_version = "Advanced model"
|
||||
)
|
||||
{
|
||||
return "{\n"
|
||||
@ -91,6 +101,7 @@ public:
|
||||
" \"Last update\": \"" + last_update + "\",\n"
|
||||
" \"Last manifest update\": \"" + last_manifest_update + "\",\n"
|
||||
" \"Policy version\": \"" + policy_version + "\",\n"
|
||||
" \"AI model version\": \"" + waap_model_version + "\",\n"
|
||||
" \"Last policy update\": \"" + last_policy_update + "\",\n"
|
||||
" \"Last settings update\": \"" + last_settings_update + "\",\n"
|
||||
" \"Upgrade mode\": \"" + upgrade_mode + "\",\n"
|
||||
@ -118,12 +129,14 @@ public:
|
||||
ostringstream capture_debug;
|
||||
StrictMock<MockOrchestrationTools> mock_tools;
|
||||
StrictMock<MockAgentDetails> mock_agent_details;
|
||||
StrictMock<MockDetailsResolver> mock_details_resolver;
|
||||
OrchestrationStatus orchestration_status;
|
||||
I_OrchestrationStatus * i_orchestration_status =
|
||||
Singleton::Consume<I_OrchestrationStatus>::from(orchestration_status);
|
||||
string file_path;
|
||||
Maybe<string> start_file_content = genError("No file");
|
||||
I_MainLoop::Routine routine;
|
||||
string waap_model = "Advanced model";
|
||||
};
|
||||
|
||||
TEST_F(OrchestrationStatusTest, doNothing)
|
||||
@ -147,6 +160,7 @@ TEST_F(OrchestrationStatusTest, recoverFields)
|
||||
|
||||
TEST_F(OrchestrationStatusTest, loadFromFile)
|
||||
{
|
||||
prepareResolvedDetails();
|
||||
Maybe<string> status = genError("No file");;
|
||||
CPTestTempfile status_file;
|
||||
file_path = status_file.fname;
|
||||
@ -214,12 +228,14 @@ TEST_F(OrchestrationStatusTest, recoveryFields)
|
||||
const string agent_id = "AgentId";
|
||||
const string profile_id = "ProfileId";
|
||||
const string tenant_id = "TenantId";
|
||||
|
||||
auto fog_addr = Maybe<string>(string("FogDomain"));
|
||||
|
||||
EXPECT_CALL(mock_agent_details, getAgentId()).WillOnce(Return(agent_id));
|
||||
EXPECT_CALL(mock_agent_details, getProfileId()).WillOnce(Return(profile_id));
|
||||
EXPECT_CALL(mock_agent_details, getTenantId()).WillOnce(Return(tenant_id));
|
||||
EXPECT_CALL(mock_agent_details, getFogDomain()).WillOnce(Return(fog_addr));
|
||||
|
||||
i_orchestration_status->writeStatusToFile();
|
||||
EXPECT_THAT(capture_debug.str(), HasSubstr("Repairing status fields"));
|
||||
|
||||
@ -227,6 +243,7 @@ TEST_F(OrchestrationStatusTest, recoveryFields)
|
||||
EXPECT_EQ(i_orchestration_status->getProfileId(), profile_id);
|
||||
EXPECT_EQ(i_orchestration_status->getTenantId(), tenant_id);
|
||||
EXPECT_EQ(i_orchestration_status->getFogAddress(), fog_addr.unpack());
|
||||
EXPECT_EQ(i_orchestration_status->getWaapModelVersion(), waap_model);
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationStatusTest, updateAllLastUpdatesTypes)
|
||||
@ -419,6 +436,7 @@ TEST_F(OrchestrationStatusTest, setAllFields)
|
||||
" \"Last update\": \"current time\",\n"
|
||||
" \"Last manifest update\": \"current time\",\n"
|
||||
" \"Policy version\": \"12\",\n"
|
||||
" \"AI model version\": \"Advanced model\",\n"
|
||||
" \"Last policy update\": \"current time\",\n"
|
||||
" \"Last settings update\": \"current time\",\n"
|
||||
" \"Upgrade mode\": \"Test Mode\",\n"
|
||||
|
@ -108,6 +108,7 @@ public:
|
||||
last_update_attempt = from.last_update_attempt;
|
||||
last_manifest_update = from.last_manifest_update;
|
||||
policy_version = from.policy_version;
|
||||
waap_model_version = from.waap_model_version;
|
||||
last_policy_update = from.last_policy_update;
|
||||
last_settings_update = from.last_settings_update;
|
||||
upgrade_mode = from.upgrade_mode;
|
||||
@ -128,6 +129,7 @@ public:
|
||||
const string & getUpdateTime() const { return last_update_time; }
|
||||
const string & getLastManifestUpdate() const { return last_manifest_update; }
|
||||
const string & getPolicyVersion() const { return policy_version; }
|
||||
const string & getWaapModelVersion() const { return waap_model_version; }
|
||||
const string & getLastPolicyUpdate() const { return last_policy_update; }
|
||||
const string & getLastSettingsUpdate() const { return last_settings_update; }
|
||||
const string & getUpgradeMode() const { return upgrade_mode; }
|
||||
@ -142,6 +144,16 @@ public:
|
||||
const map<string, string> & getServicePolicies() const { return service_policies; }
|
||||
const map<string, string> & getServiceSettings() const { return service_settings; }
|
||||
|
||||
void updateWaapModelVersion() {
|
||||
map<string, string> details_resolver =
|
||||
Singleton::Consume<I_DetailsResolver>::by<OrchestrationStatus>()->getResolvedDetails();
|
||||
if (details_resolver.find("AppSecModelVersion") != details_resolver.end()) {
|
||||
waap_model_version = details_resolver["AppSecModelVersion"];
|
||||
} else {
|
||||
waap_model_version = "None";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
insertServicePolicy(const string &key, const string &value)
|
||||
{
|
||||
@ -267,12 +279,13 @@ public:
|
||||
last_manifest_update = "None";
|
||||
last_policy_update = "None";
|
||||
last_settings_update = "None";
|
||||
waap_model_version = "None";
|
||||
fog_address = "None";
|
||||
agent_id = "None";
|
||||
profile_id = "None";
|
||||
tenant_id = "None";
|
||||
registration_status = "None";
|
||||
manifest_status = "None";
|
||||
manifest_status = getenv("CLOUDGUARD_APPSEC_STANDALONE") ? "Succeeded" : "None";
|
||||
upgrade_mode = "None";
|
||||
}
|
||||
|
||||
@ -292,6 +305,7 @@ public:
|
||||
} else {
|
||||
fog_address = "None";
|
||||
}
|
||||
updateWaapModelVersion();
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,6 +318,7 @@ public:
|
||||
archive(cereal::make_nvp("Last update", last_update_time));
|
||||
archive(cereal::make_nvp("Last manifest update", last_manifest_update));
|
||||
archive(cereal::make_nvp("Policy version", policy_version));
|
||||
archive(cereal::make_nvp("AI model version", waap_model_version));
|
||||
archive(cereal::make_nvp("Last policy update", last_policy_update));
|
||||
archive(cereal::make_nvp("Last settings update", last_settings_update));
|
||||
archive(cereal::make_nvp("Upgrade mode", upgrade_mode));
|
||||
@ -331,6 +346,7 @@ public:
|
||||
archive.setNextName(nullptr);
|
||||
}
|
||||
|
||||
archive(cereal::make_nvp("AI model version", waap_model_version));
|
||||
archive(cereal::make_nvp("Last policy update", last_policy_update));
|
||||
archive(cereal::make_nvp("Last settings update", last_settings_update));
|
||||
|
||||
@ -368,6 +384,7 @@ private:
|
||||
string last_update_attempt;
|
||||
string last_manifest_update;
|
||||
string policy_version;
|
||||
string waap_model_version;
|
||||
string last_policy_update;
|
||||
string last_settings_update;
|
||||
string upgrade_mode;
|
||||
@ -387,13 +404,14 @@ class OrchestrationStatus::Impl : Singleton::Provide<I_OrchestrationStatus>::Fro
|
||||
{
|
||||
public:
|
||||
void
|
||||
writeStatusToFile()
|
||||
writeStatusToFile() override
|
||||
{
|
||||
auto orchestration_status_path = getConfigurationWithDefault<string>(
|
||||
filesystem_prefix + "/conf/orchestration_status.json",
|
||||
"orchestration",
|
||||
"Orchestration status path"
|
||||
);
|
||||
status.updateWaapModelVersion();
|
||||
auto write_result =
|
||||
orchestration_tools->objectToJsonFile<Status>(status, orchestration_status_path);
|
||||
if (!write_result) {
|
||||
@ -497,6 +515,7 @@ private:
|
||||
const string & getUpdateTime() const override { return status.getUpdateTime(); }
|
||||
const string & getLastManifestUpdate() const override { return status.getLastManifestUpdate(); }
|
||||
const string & getPolicyVersion() const override { return status.getPolicyVersion(); }
|
||||
const string & getWaapModelVersion() const override { return status.getWaapModelVersion(); }
|
||||
const string & getLastPolicyUpdate() const override { return status.getLastPolicyUpdate(); }
|
||||
const string & getLastSettingsUpdate() const override { return status.getLastSettingsUpdate(); }
|
||||
const string & getUpgradeMode() const override { return status.getUpgradeMode(); }
|
||||
|
@ -189,6 +189,10 @@ public:
|
||||
"Orchestration runner",
|
||||
true
|
||||
);
|
||||
|
||||
auto orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<OrchestrationComp>();
|
||||
orchestration_tools->getClusterId();
|
||||
|
||||
hybrid_mode_metric.init(
|
||||
"Watchdog Metrics",
|
||||
ReportIS::AudienceTeam::AGENT_CORE,
|
||||
@ -198,7 +202,6 @@ public:
|
||||
ReportIS::Audience::INTERNAL
|
||||
);
|
||||
hybrid_mode_metric.registerListener();
|
||||
auto orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<OrchestrationComp>();
|
||||
orchestration_tools->loadTenantsFromDir(
|
||||
getConfigurationWithDefault<string>(getFilesystemPathConfig() + "/conf/", "orchestration", "Conf dir")
|
||||
);
|
||||
@ -1485,6 +1488,9 @@ private:
|
||||
if (i_details_resolver->compareCheckpointVersion(8100, greater_equal<int>())) {
|
||||
agent_data_report << AgentReportFieldWithLabel("isCheckpointVersionGER81", "true");
|
||||
}
|
||||
if (i_details_resolver->compareCheckpointVersion(8200, greater_equal<int>())) {
|
||||
agent_data_report << AgentReportFieldWithLabel("isCheckpointVersionGER82", "true");
|
||||
}
|
||||
#endif // gaia || smb
|
||||
|
||||
if (agent_data_report == curr_agent_data_report) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
ADD_DEFINITIONS(-Wno-deprecated-declarations)
|
||||
|
||||
add_library(orchestration_tools orchestration_tools.cc)
|
||||
add_library(orchestration_tools orchestration_tools.cc namespace_data.cc)
|
||||
|
||||
#add_subdirectory(orchestration_tools_ut)
|
||||
|
@ -0,0 +1,117 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "namespace_data.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_ORCHESTRATOR);
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
parseNameSpaceJSONKey(
|
||||
const string &key_name,
|
||||
T &value,
|
||||
cereal::JSONInputArchive &archive_in,
|
||||
const T &default_value = T())
|
||||
{
|
||||
try {
|
||||
archive_in(cereal::make_nvp(key_name, value));
|
||||
} catch (const cereal::Exception &e) {
|
||||
archive_in.setNextName(nullptr);
|
||||
value = default_value;
|
||||
dbgDebug(D_ORCHESTRATOR)
|
||||
<< "Could not parse the required key. Key: "
|
||||
<< key_name
|
||||
<< ", Error: "
|
||||
<< e.what();
|
||||
}
|
||||
}
|
||||
|
||||
class NamespaceMetadata
|
||||
{
|
||||
public:
|
||||
void
|
||||
load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgFlow(D_ORCHESTRATOR);
|
||||
parseNameSpaceJSONKey<string>("name", name, archive_in);
|
||||
parseNameSpaceJSONKey<string>("uid", uid, archive_in);
|
||||
}
|
||||
|
||||
const string &
|
||||
getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const string &
|
||||
getUID() const
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
|
||||
private:
|
||||
string name;
|
||||
string uid;
|
||||
};
|
||||
|
||||
class SingleNamespaceData
|
||||
{
|
||||
public:
|
||||
void
|
||||
load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
parseNameSpaceJSONKey<NamespaceMetadata>("metadata", metadata, archive_in);
|
||||
}
|
||||
|
||||
const NamespaceMetadata &
|
||||
getMetadata() const
|
||||
{
|
||||
return metadata;
|
||||
}
|
||||
|
||||
private:
|
||||
NamespaceMetadata metadata;
|
||||
};
|
||||
|
||||
bool
|
||||
NamespaceData::loadJson(const string &json)
|
||||
{
|
||||
dbgFlow(D_ORCHESTRATOR);
|
||||
string modified_json = json;
|
||||
modified_json.pop_back();
|
||||
stringstream in;
|
||||
in.str(modified_json);
|
||||
try {
|
||||
cereal::JSONInputArchive in_ar(in);
|
||||
vector<SingleNamespaceData> items;
|
||||
in_ar(cereal::make_nvp("items", items));
|
||||
for (const SingleNamespaceData &single_ns_data : items) {
|
||||
ns_name_to_uid[single_ns_data.getMetadata().getName()] = single_ns_data.getMetadata().getUID();
|
||||
}
|
||||
} catch (cereal::Exception &e) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to load namespace data JSON. Error: " << e.what();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
NamespaceData::getNamespaceUidByName(const string &name)
|
||||
{
|
||||
if (ns_name_to_uid.find(name) == ns_name_to_uid.end()) {
|
||||
return genError("Namespace doesn't exist. Name: " + name);
|
||||
}
|
||||
return ns_name_to_uid.at(name);
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
#include "cereal/types/vector.hpp"
|
||||
#include "cereal/types/set.hpp"
|
||||
#include "agent_core_utilities.h"
|
||||
#include "namespace_data.h"
|
||||
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
@ -47,11 +48,13 @@ public:
|
||||
const string &tenant_id,
|
||||
const string &profile_id) const override;
|
||||
|
||||
shared_ptr<ifstream> fileStreamWrapper(const std::string &path) const override;
|
||||
Maybe<string> readFile(const string &path) const override;
|
||||
bool writeFile(const string &text, const string &path) const override;
|
||||
bool writeFile(const string &text, const string &path, bool append_mode = false) const override;
|
||||
bool removeFile(const string &path) const override;
|
||||
bool copyFile(const string &src_path, const string &dst_path) const override;
|
||||
bool doesFileExist(const string &file_path) const override;
|
||||
void getClusterId() const override;
|
||||
void fillKeyInJson(const string &filename, const string &_key, const string &_val) const override;
|
||||
bool createDirectory(const string &directory_path) const override;
|
||||
bool doesDirectoryExist(const string &dir_path) const override;
|
||||
@ -127,6 +130,98 @@ OrchestrationTools::Impl::fillKeyInJson(const string &filename, const string &_k
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
bool
|
||||
isPlaygroundEnv()
|
||||
{
|
||||
const char *env_string = getenv("PLAYGROUND");
|
||||
|
||||
if (env_string == nullptr) return false;
|
||||
string env_value = env_string;
|
||||
transform(env_value.begin(), env_value.end(), env_value.begin(), ::tolower);
|
||||
|
||||
return env_value == "true";
|
||||
}
|
||||
|
||||
Maybe<NamespaceData, string>
|
||||
getNamespaceDataFromCluster(const string &path)
|
||||
{
|
||||
NamespaceData name_space;
|
||||
string token = Singleton::Consume<I_EnvDetails>::by<OrchestrationTools>()->getToken();
|
||||
Flags<MessageConnConfig> conn_flags;
|
||||
conn_flags.setFlag(MessageConnConfig::SECURE_CONN);
|
||||
conn_flags.setFlag(MessageConnConfig::IGNORE_SSL_VALIDATION);
|
||||
auto messaging = Singleton::Consume<I_Messaging>::by<OrchestrationTools>();
|
||||
bool res = messaging->sendObject(
|
||||
name_space,
|
||||
I_Messaging::Method::GET,
|
||||
"kubernetes.default.svc",
|
||||
443,
|
||||
conn_flags,
|
||||
path,
|
||||
"Authorization: Bearer " + token + "\nConnection: close"
|
||||
);
|
||||
|
||||
if (res) return name_space;
|
||||
|
||||
return genError(string("Was not able to get object form k8s cluser in path: " + path));
|
||||
}
|
||||
|
||||
bool
|
||||
doesClusterIdExists()
|
||||
{
|
||||
string playground_uid = isPlaygroundEnv() ? "playground-" : "";
|
||||
|
||||
dbgTrace(D_ORCHESTRATOR) << "Getting cluster UID";
|
||||
|
||||
auto maybe_namespaces_data = getNamespaceDataFromCluster("/api/v1/namespaces/");
|
||||
|
||||
if (!maybe_namespaces_data.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR)
|
||||
<< "Failed to retrieve K8S namespace data. Error: "
|
||||
<< maybe_namespaces_data.getErr();
|
||||
return false;
|
||||
}
|
||||
|
||||
NamespaceData namespaces_data = maybe_namespaces_data.unpack();
|
||||
|
||||
Maybe<string> maybe_ns_uid = namespaces_data.getNamespaceUidByName("kube-system");
|
||||
if (!maybe_ns_uid.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR) << maybe_ns_uid.getErr();
|
||||
return false;
|
||||
}
|
||||
string uid = playground_uid + maybe_ns_uid.unpack();
|
||||
dbgTrace(D_ORCHESTRATOR) << "Found k8s cluster UID: " << uid;
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<OrchestrationTools>();
|
||||
env->getConfigurationContext().registerValue<string>(
|
||||
"k8sClusterId",
|
||||
uid,
|
||||
EnvKeyAttr::LogSection::SOURCE
|
||||
);
|
||||
I_AgentDetails *i_agent_details = Singleton::Consume<I_AgentDetails>::by<OrchestrationTools>();
|
||||
i_agent_details->setClusterId(uid);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
OrchestrationTools::Impl::getClusterId() const
|
||||
{
|
||||
auto env_type = Singleton::Consume<I_EnvDetails>::by<OrchestrationTools>()->getEnvType();
|
||||
|
||||
if (env_type == EnvType::K8S) {
|
||||
Singleton::Consume<I_MainLoop>::by<OrchestrationTools>()->addOneTimeRoutine(
|
||||
I_MainLoop::RoutineType::Offline,
|
||||
[this] ()
|
||||
{
|
||||
while(!doesClusterIdExists()) {
|
||||
Singleton::Consume<I_MainLoop>::by<OrchestrationTools>()->yield(chrono::seconds(1));
|
||||
}
|
||||
return;
|
||||
},
|
||||
"Get k8s cluster ID"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
OrchestrationTools::Impl::doesFileExist(const string &file_path) const
|
||||
{
|
||||
@ -140,7 +235,7 @@ OrchestrationTools::Impl::doesDirectoryExist(const string &dir_path) const
|
||||
}
|
||||
|
||||
bool
|
||||
OrchestrationTools::Impl::writeFile(const string &text, const string &path) const
|
||||
OrchestrationTools::Impl::writeFile(const string &text, const string &path, bool append_mode) const
|
||||
{
|
||||
dbgDebug(D_ORCHESTRATOR) << "Writing file: text = " << text << ", path = " << path;
|
||||
if (path.find('/') != string::npos) {
|
||||
@ -151,8 +246,15 @@ OrchestrationTools::Impl::writeFile(const string &text, const string &path) cons
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ofstream fout;
|
||||
|
||||
if (append_mode) {
|
||||
fout.open(path, std::ios::app);
|
||||
} else {
|
||||
fout.open(path);
|
||||
}
|
||||
try {
|
||||
ofstream fout(path);
|
||||
fout << text;
|
||||
return true;
|
||||
} catch (const ofstream::failure &e) {
|
||||
@ -186,6 +288,12 @@ OrchestrationTools::Impl::isNonEmptyFile(const string &path) const
|
||||
return false;
|
||||
}
|
||||
|
||||
shared_ptr<ifstream>
|
||||
OrchestrationTools::Impl::fileStreamWrapper(const std::string &path) const
|
||||
{
|
||||
return make_shared<ifstream>(path);
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
OrchestrationTools::Impl::readFile(const string &path) const
|
||||
{
|
||||
|
@ -1,8 +1,13 @@
|
||||
#include "orchestration_tools.h"
|
||||
|
||||
#include "cptest.h"
|
||||
#include "config_component.h"
|
||||
#include "mock/mock_tenant_manager.h"
|
||||
#include "mock/mock_shell_cmd.h"
|
||||
#include "mock/mock_messaging.h"
|
||||
#include "mock/mock_env_details.h"
|
||||
#include "mock/mock_agent_details.h"
|
||||
#include "mock/mock_mainloop.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace testing;
|
||||
@ -14,6 +19,17 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
string
|
||||
getResource(const string &path)
|
||||
{
|
||||
string resource_path = cptestFnameInSrcDir(path);
|
||||
ifstream resource_file(resource_path);
|
||||
EXPECT_TRUE(resource_file.is_open());
|
||||
stringstream resource_file_content;
|
||||
resource_file_content << resource_file.rdbuf();
|
||||
return resource_file_content.str();
|
||||
}
|
||||
|
||||
void
|
||||
cleanSpaces(string &str)
|
||||
{
|
||||
@ -47,27 +63,74 @@ public:
|
||||
|
||||
OrchestrationTools orchestration_tools;
|
||||
I_OrchestrationTools *i_orchestration_tools = Singleton::Consume<I_OrchestrationTools>::from(orchestration_tools);
|
||||
StrictMock<MockTenantManager> mock_tenant_manager;
|
||||
NiceMock<MockMessaging> mock_messaging;
|
||||
NiceMock<MockAgentDetails> mock_agent_details;
|
||||
NiceMock<MockMainLoop> mock_mainloop;
|
||||
StrictMock<MockShellCmd> mock_shell_cmd;
|
||||
StrictMock<EnvDetailsMocker> mock_env_details;
|
||||
StrictMock<MockTenantManager> mock_tenant_manager;
|
||||
::Environment env;
|
||||
|
||||
};
|
||||
|
||||
TEST_F(OrchestrationToolsTest, doNothing)
|
||||
{
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationToolsTest, getClusterId)
|
||||
{
|
||||
EXPECT_CALL(mock_env_details, getToken()).WillOnce(Return("123"));
|
||||
EXPECT_CALL(mock_env_details, getEnvType()).WillOnce(Return(EnvType::K8S));
|
||||
I_MainLoop::Routine routine;
|
||||
EXPECT_CALL(
|
||||
mock_mainloop,
|
||||
addOneTimeRoutine(I_MainLoop::RoutineType::Offline, _, "Get k8s cluster ID", _)
|
||||
).WillOnce(DoAll(SaveArg<1>(&routine), Return(1)));
|
||||
|
||||
string namespaces = getResource("k8s_namespaces.json");
|
||||
EXPECT_CALL(
|
||||
mock_messaging,
|
||||
sendMessage(
|
||||
true,
|
||||
"",
|
||||
I_Messaging::Method::GET,
|
||||
"kubernetes.default.svc",
|
||||
443,
|
||||
_,
|
||||
"/api/v1/namespaces/",
|
||||
"Authorization: Bearer 123\nConnection: close",
|
||||
_,
|
||||
_
|
||||
)
|
||||
).WillRepeatedly(Return(Maybe<string>(namespaces)));
|
||||
i_orchestration_tools->getClusterId();
|
||||
routine();
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationToolsTest, writeReadTextToFile)
|
||||
{
|
||||
EXPECT_TRUE(i_orchestration_tools->writeFile(manifest_text, manifest_file));
|
||||
EXPECT_TRUE(i_orchestration_tools->writeFile(manifest_text, manifest_file, false));
|
||||
EXPECT_TRUE(i_orchestration_tools->doesFileExist(manifest_file));
|
||||
EXPECT_TRUE(i_orchestration_tools->isNonEmptyFile(manifest_file));
|
||||
EXPECT_TRUE(i_orchestration_tools->fileStreamWrapper(manifest_file)->is_open());
|
||||
EXPECT_EQ(manifest_text, i_orchestration_tools->readFile(manifest_file).unpack());
|
||||
|
||||
EXPECT_FALSE(i_orchestration_tools->isNonEmptyFile("no_such_file"));
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationToolsTest, writeAndAppendToFile)
|
||||
{
|
||||
EXPECT_TRUE(i_orchestration_tools->writeFile("blabla", "in_test.json", false));
|
||||
EXPECT_TRUE(i_orchestration_tools->doesFileExist("in_test.json"));
|
||||
EXPECT_TRUE(i_orchestration_tools->isNonEmptyFile("in_test.json"));
|
||||
EXPECT_TRUE(i_orchestration_tools->writeFile(" Appending Text", "in_test.json", true));
|
||||
|
||||
EXPECT_EQ("blabla Appending Text", i_orchestration_tools->readFile("in_test.json").unpack());;
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationToolsTest, loadPackagesFromJsonTest)
|
||||
{
|
||||
EXPECT_TRUE(i_orchestration_tools->writeFile("blabla", "in_test.json"));
|
||||
EXPECT_TRUE(i_orchestration_tools->writeFile("blabla", "in_test.json", false));
|
||||
string file_name = "in_test.json";
|
||||
Maybe<map<string, Package>> packages = i_orchestration_tools->loadPackagesFromJson(file_name);
|
||||
EXPECT_FALSE(packages.ok());
|
||||
@ -83,7 +146,7 @@ TEST_F(OrchestrationToolsTest, loadPackagesFromJsonTest)
|
||||
|
||||
TEST_F(OrchestrationToolsTest, copyFile)
|
||||
{
|
||||
EXPECT_TRUE(i_orchestration_tools->writeFile("blabla", "in_test.json"));
|
||||
EXPECT_TRUE(i_orchestration_tools->writeFile("blabla", "in_test.json", false));
|
||||
EXPECT_TRUE(i_orchestration_tools->copyFile("in_test.json", "cpy_test.json"));
|
||||
EXPECT_EQ("blabla", i_orchestration_tools->readFile("cpy_test.json").unpack());
|
||||
EXPECT_FALSE(i_orchestration_tools->copyFile("NOT_EXISTS_FILE", "cpy2_test.json"));
|
||||
@ -199,7 +262,7 @@ TEST_F(OrchestrationToolsTest, jsonFileToPackages)
|
||||
" }"
|
||||
" ]"
|
||||
"}";
|
||||
i_orchestration_tools->writeFile(string_stream.str(), "packages_tmp.json");
|
||||
i_orchestration_tools->writeFile(string_stream.str(), "packages_tmp.json", false);
|
||||
Maybe<map<string, Package>> packages = i_orchestration_tools->loadPackagesFromJson("packages_tmp.json");
|
||||
EXPECT_TRUE(packages.ok());
|
||||
EXPECT_TRUE(packages.unpack().find("nano-agent") != packages.unpack().end());
|
||||
@ -222,7 +285,7 @@ TEST_F(OrchestrationToolsTest, packagesToJsonFile)
|
||||
" }"
|
||||
" ]"
|
||||
"}";
|
||||
i_orchestration_tools->writeFile(string_stream.str(), "packages.json");
|
||||
i_orchestration_tools->writeFile(string_stream.str(), "packages.json", false);
|
||||
Maybe<map<string, Package>> packages = i_orchestration_tools->loadPackagesFromJson("packages.json");
|
||||
EXPECT_TRUE(packages.ok());
|
||||
EXPECT_TRUE(i_orchestration_tools->packagesToJsonFile(packages.unpack(), "packages.json"));
|
||||
@ -277,8 +340,8 @@ TEST_F(OrchestrationToolsTest, deleteVirtualTenantFiles)
|
||||
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);
|
||||
i_orchestration_tools->writeFile(string_stream.str(), settings_file_path, false);
|
||||
i_orchestration_tools->writeFile(string_stream.str(), policy_file_path, false);
|
||||
|
||||
EXPECT_TRUE(i_orchestration_tools->doesFileExist(settings_file_path));
|
||||
EXPECT_TRUE(i_orchestration_tools->doesFileExist(policy_file_path));
|
||||
@ -301,16 +364,16 @@ TEST_F(OrchestrationToolsTest, loadTenants)
|
||||
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);
|
||||
i_orchestration_tools->writeFile(string_stream.str(), settings_file_path1, false);
|
||||
|
||||
string settings_file_path2 = conf_path + "/tenant_123456_profile_654321_settings.json";
|
||||
i_orchestration_tools->writeFile(string_stream.str(), settings_file_path2);
|
||||
i_orchestration_tools->writeFile(string_stream.str(), settings_file_path2, false);
|
||||
|
||||
string policy_file_path1 = policy_folder_path1 + "/policy.json";
|
||||
i_orchestration_tools->writeFile(string_stream.str(), policy_file_path1);
|
||||
i_orchestration_tools->writeFile(string_stream.str(), policy_file_path1, false);
|
||||
|
||||
string policy_file_path2 = policy_folder_path2 + "/policy.json";
|
||||
i_orchestration_tools->writeFile(string_stream.str(), policy_file_path2);
|
||||
i_orchestration_tools->writeFile(string_stream.str(), policy_file_path2, false);
|
||||
|
||||
EXPECT_TRUE(i_orchestration_tools->doesFileExist(settings_file_path1));
|
||||
EXPECT_TRUE(i_orchestration_tools->doesFileExist(settings_file_path2));
|
||||
|
@ -62,6 +62,8 @@ public:
|
||||
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Orchestration runner", true)
|
||||
).WillOnce(DoAll(SaveArg<1>(&routine), Return(1)));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, getClusterId());
|
||||
|
||||
EXPECT_CALL(mock_shell_cmd, getExecOutput("openssl version -d | cut -d\" \" -f2 | cut -d\"\\\"\" -f2", _, _))
|
||||
.WillOnce(Return(string("OpenSSL certificates Directory")));
|
||||
|
||||
@ -91,11 +93,11 @@ public:
|
||||
Maybe<string> err = genError("No file exist");
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile("/etc/cp/conf/user-cred.json")).WillOnce(Return(err));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile("This is fake", "/etc/cp/data/data1.a")).WillOnce(
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile("This is fake", "/etc/cp/data/data1.a", false)).WillOnce(
|
||||
Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile("0000 is fake", "/etc/cp/data/data4.a")).WillOnce(
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile("0000 is fake", "/etc/cp/data/data4.a", false)).WillOnce(
|
||||
Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile("This is 3333", "/etc/cp/data/data6.a")).WillOnce(
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile("This is 3333", "/etc/cp/data/data6.a", false)).WillOnce(
|
||||
Return(true));
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,8 @@ public:
|
||||
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Orchestration runner", true)
|
||||
).WillOnce(DoAll(SaveArg<1>(&routine), Return(1)));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, getClusterId());
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_shell_cmd,
|
||||
getExecOutput("openssl version -d | cut -d\" \" -f2 | cut -d\"\\\"\" -f2", _, _)
|
||||
@ -118,11 +120,11 @@ public:
|
||||
Maybe<string> err = genError("No file exist");
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile("/etc/cp/conf/user-cred.json")).WillOnce(Return(err));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile("This is fake", "/etc/cp/data/data1.a")).WillOnce(
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile("This is fake", "/etc/cp/data/data1.a", false)).WillOnce(
|
||||
Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile("0000 is fake", "/etc/cp/data/data4.a")).WillOnce(
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile("0000 is fake", "/etc/cp/data/data4.a", false)).WillOnce(
|
||||
Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile("This is 3333", "/etc/cp/data/data6.a")).WillOnce(
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile("This is 3333", "/etc/cp/data/data6.a", false)).WillOnce(
|
||||
Return(true));
|
||||
}
|
||||
|
||||
@ -1333,26 +1335,6 @@ TEST_F(OrchestrationTest, manifestUpdate)
|
||||
} catch (const invalid_argument& e) {}
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationTest, loadFromOrchestrationPolicy)
|
||||
{
|
||||
EXPECT_CALL(
|
||||
rest,
|
||||
mockRestCall(RestAction::ADD, "proxy", _)
|
||||
).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandler)));
|
||||
waitForRestCall();
|
||||
init();
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationTest, loadFromOrchestrationBackupPolicy)
|
||||
{
|
||||
EXPECT_CALL(
|
||||
rest,
|
||||
mockRestCall(RestAction::ADD, "proxy", _)
|
||||
).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandler)));
|
||||
waitForRestCall();
|
||||
init();
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationTest, getBadPolicyUpdate)
|
||||
{
|
||||
EXPECT_CALL(
|
||||
@ -1815,6 +1797,7 @@ TEST_F(OrchestrationTest, GetRestOrchStatus)
|
||||
" \"Last update\": \"" + test_str + "\",\n"
|
||||
" \"Last update status\": \"" + test_str + "\",\n"
|
||||
" \"Policy version\": \"" + test_str + "\",\n"
|
||||
" \"AI model version\": \"" + test_str + "\",\n"
|
||||
" \"Last policy update\": \"" + test_str + "\",\n"
|
||||
" \"Last manifest update\": \"" + test_str + "\",\n"
|
||||
" \"Last settings update\": \"" + test_str + "\",\n"
|
||||
@ -1841,6 +1824,7 @@ TEST_F(OrchestrationTest, GetRestOrchStatus)
|
||||
EXPECT_CALL(mock_status, getUpdateTime()).WillOnce(ReturnRef(test_str));
|
||||
EXPECT_CALL(mock_status, getLastManifestUpdate()).WillOnce(ReturnRef(test_str));
|
||||
EXPECT_CALL(mock_status, getPolicyVersion()).WillOnce(ReturnRef(test_str));
|
||||
EXPECT_CALL(mock_status, getWaapModelVersion()).WillOnce(ReturnRef(test_str));
|
||||
EXPECT_CALL(mock_status, getLastPolicyUpdate()).WillOnce(ReturnRef(test_str));
|
||||
EXPECT_CALL(mock_status, getLastSettingsUpdate()).WillOnce(ReturnRef(test_str));
|
||||
EXPECT_CALL(mock_status, getUpgradeMode()).WillOnce(ReturnRef(test_str));
|
||||
|
@ -246,7 +246,8 @@ TEST_F(ServiceControllerTest, UpdateConfiguration)
|
||||
EXPECT_CALL(mock_orchestration_tools, jsonObjectSplitter(new_configuration, _, _))
|
||||
.WillOnce(Return(json_parser_return));
|
||||
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(l4_firewall, l4_firewall_policy_path, false))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_status,
|
||||
setServiceConfiguration("l4_firewall", l4_firewall_policy_path, OrchestrationStatusConfigType::POLICY));
|
||||
|
||||
@ -357,8 +358,9 @@ TEST_F(ServiceControllerTest, supportVersions)
|
||||
.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_tools, writeFile(l4_firewall, l4_firewall_policy_path, false))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(versions, policy_versions_path, false)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_status,
|
||||
setServiceConfiguration("versions", policy_versions_path, OrchestrationStatusConfigType::POLICY));
|
||||
EXPECT_CALL(mock_orchestration_status,
|
||||
@ -455,7 +457,8 @@ TEST_F(ServiceControllerTest, TimeOutUpdateConfiguration)
|
||||
EXPECT_CALL(mock_orchestration_tools, jsonObjectSplitter(new_configuration, _, _))
|
||||
.WillOnce(Return(json_parser_return));
|
||||
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(l4_firewall, l4_firewall_policy_path, false))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_status,
|
||||
setServiceConfiguration("l4_firewall", l4_firewall_policy_path, OrchestrationStatusConfigType::POLICY));
|
||||
|
||||
@ -575,7 +578,8 @@ TEST_F(ServiceControllerTest, writeRegisteredServicesFromFile)
|
||||
EXPECT_CALL(mock_orchestration_tools, jsonObjectSplitter(new_configuration, _, _))
|
||||
.WillOnce(Return(json_parser_return));
|
||||
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(l4_firewall, l4_firewall_policy_path, false))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_status,
|
||||
setServiceConfiguration("l4_firewall", l4_firewall_policy_path, OrchestrationStatusConfigType::POLICY));
|
||||
|
||||
@ -807,7 +811,8 @@ TEST_F(ServiceControllerTest, SettingsAndPolicyUpdateCombinations)
|
||||
EXPECT_CALL(mock_orchestration_tools, jsonObjectSplitter(new_configuration, _, _))
|
||||
.WillOnce(Return(json_parser_return));
|
||||
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(l4_firewall, l4_firewall_policy_path, false))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_status,
|
||||
setServiceConfiguration("l4_firewall", l4_firewall_policy_path, OrchestrationStatusConfigType::POLICY));
|
||||
|
||||
@ -965,7 +970,7 @@ TEST_F(ServiceControllerTest, backup)
|
||||
).WillOnce(Return(true));
|
||||
EXPECT_CALL(
|
||||
mock_orchestration_tools,
|
||||
writeFile(l4_firewall, l4_firewall_policy_path)).WillOnce(Return(true)
|
||||
writeFile(l4_firewall, l4_firewall_policy_path, false)).WillOnce(Return(true)
|
||||
);
|
||||
EXPECT_CALL(mock_orchestration_tools, copyFile(policy_file_path, policy_file_path + backup_extension))
|
||||
.WillOnce(Return(true));
|
||||
@ -1078,7 +1083,7 @@ TEST_F(ServiceControllerTest, backup_file_doesnt_exist)
|
||||
).WillOnce(Return(true));
|
||||
EXPECT_CALL(
|
||||
mock_orchestration_tools,
|
||||
writeFile(l4_firewall, l4_firewall_policy_path)).WillOnce(Return(true)
|
||||
writeFile(l4_firewall, l4_firewall_policy_path, false)).WillOnce(Return(true)
|
||||
);
|
||||
|
||||
// backup file doesn't exist so the copyFile function should be called 0 times
|
||||
@ -1194,7 +1199,7 @@ TEST_F(ServiceControllerTest, backupAttempts)
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_orchestration_tools,
|
||||
writeFile(l4_firewall, l4_firewall_policy_path)).WillOnce(Return(true)
|
||||
writeFile(l4_firewall, l4_firewall_policy_path, false)).WillOnce(Return(true)
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, copyFile(policy_file_path, policy_file_path + backup_extension))
|
||||
@ -1311,8 +1316,10 @@ TEST_F(ServiceControllerTest, MultiUpdateConfiguration)
|
||||
EXPECT_CALL(mock_orchestration_status,
|
||||
setServiceConfiguration("orchestration", orchestration_policy_path, OrchestrationStatusConfigType::POLICY));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(l4_firewall, l4_firewall_policy_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(orchestration, orchestration_policy_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(l4_firewall, l4_firewall_policy_path, false))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(orchestration, orchestration_policy_path, false))
|
||||
.WillOnce(Return(true));
|
||||
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));
|
||||
@ -1560,7 +1567,12 @@ TEST_F(ServiceControllerTest, ErrorUpdateConfigurationRest)
|
||||
EXPECT_CALL(mock_orchestration_tools, jsonObjectSplitter(new_configuration, _, _))
|
||||
.WillOnce(Return(json_parser_return));
|
||||
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(
|
||||
l4_firewall,
|
||||
l4_firewall_policy_path,
|
||||
false)).WillOnce(Return(true));
|
||||
EXPECT_CALL(
|
||||
mock_orchestration_status,
|
||||
setServiceConfiguration("l4_firewall", l4_firewall_policy_path, OrchestrationStatusConfigType::POLICY)
|
||||
@ -1667,7 +1679,7 @@ TEST_F(ServiceControllerTest, errorWhileWrtingNewConfiguration)
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_orchestration_tools,
|
||||
writeFile(l4_firewall, l4_firewall_policy_path)).WillOnce(Return(false)
|
||||
writeFile(l4_firewall, l4_firewall_policy_path, false)).WillOnce(Return(false)
|
||||
);
|
||||
|
||||
EXPECT_FALSE(i_service_controller->updateServiceConfiguration(file_name, "").ok());
|
||||
@ -1782,7 +1794,7 @@ TEST_F(ServiceControllerTest, testMultitenantConfFiles)
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(l4_firewall_policy_path_new)).WillOnce(Return(false));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(l4_firewall, l4_firewall_policy_path_new))
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(l4_firewall, l4_firewall_policy_path_new, false))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_status, setServiceConfiguration(
|
||||
@ -1889,7 +1901,7 @@ TEST_F(ServiceControllerTest, test_delayed_reconf)
|
||||
EXPECT_CALL(mock_orchestration_tools, jsonObjectSplitter(new_configuration, _, _))
|
||||
.WillOnce(Return(json_parser_return));
|
||||
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)).
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(l4_firewall, l4_firewall_policy_path, false)).
|
||||
WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_status,
|
||||
setServiceConfiguration("l4_firewall", l4_firewall_policy_path, OrchestrationStatusConfigType::POLICY));
|
||||
|
@ -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_library(update_communication update_communication.cc hybrid_communication.cc fog_communication.cc fog_authenticator.cc local_communication.cc declarative_policy_utils.cc fog_helper_open_source.cc)
|
||||
#add_subdirectory(update_communication_ut)
|
||||
|
@ -16,6 +16,7 @@ USE_DEBUG_FLAG(D_ORCHESTRATOR);
|
||||
void
|
||||
DeclarativePolicyUtils::init()
|
||||
{
|
||||
local_policy_path = getFilesystemPathConfig() + "/conf/local_policy.yaml";
|
||||
should_apply_policy = true;
|
||||
Singleton::Consume<I_RestApi>::by<DeclarativePolicyUtils>()->addRestCall<ApplyPolicyRest>(
|
||||
RestAction::SET, "apply-policy"
|
||||
@ -25,9 +26,10 @@ DeclarativePolicyUtils::init()
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
void
|
||||
DeclarativePolicyUtils::upon(const ApplyPolicyEvent &)
|
||||
DeclarativePolicyUtils::upon(const ApplyPolicyEvent &event)
|
||||
{
|
||||
dbgTrace(D_ORCHESTRATOR) << "Apply policy event";
|
||||
local_policy_path = event.getPolicyPath();
|
||||
should_apply_policy = true;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
@ -54,11 +56,9 @@ DeclarativePolicyUtils::getLocalPolicyChecksum()
|
||||
return orchestration_tools->readFile("/etc/cp/conf/k8s-policy-check.trigger");
|
||||
}
|
||||
|
||||
string policy_path = Singleton::Consume<I_LocalPolicyMgmtGen>::by<DeclarativePolicyUtils>()->getLocalPolicyPath();
|
||||
|
||||
Maybe<string> file_checksum = orchestration_tools->calculateChecksum(
|
||||
I_OrchestrationTools::SELECTED_CHECKSUM_TYPE,
|
||||
policy_path
|
||||
local_policy_path
|
||||
);
|
||||
|
||||
if (!file_checksum.ok()) {
|
||||
@ -83,8 +83,11 @@ void
|
||||
DeclarativePolicyUtils::updateCurrentPolicy(const string &policy_checksum)
|
||||
{
|
||||
string clean_policy_checksum = getCleanChecksum(policy_checksum);
|
||||
curr_policy = Singleton::Consume<I_LocalPolicyMgmtGen>::by<DeclarativePolicyUtils>()->parsePolicy(
|
||||
clean_policy_checksum
|
||||
auto env = Singleton::Consume<I_EnvDetails>::by<DeclarativePolicyUtils>()->getEnvType();
|
||||
curr_policy = Singleton::Consume<I_LocalPolicyMgmtGen>::by<DeclarativePolicyUtils>()->generateAppSecLocalPolicy(
|
||||
env,
|
||||
clean_policy_checksum,
|
||||
local_policy_path
|
||||
);
|
||||
}
|
||||
|
||||
@ -94,7 +97,7 @@ DeclarativePolicyUtils::getPolicyChecksum()
|
||||
I_OrchestrationTools *orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<DeclarativePolicyUtils>();
|
||||
Maybe<string> file_checksum = orchestration_tools->calculateChecksum(
|
||||
I_OrchestrationTools::SELECTED_CHECKSUM_TYPE,
|
||||
Singleton::Consume<I_LocalPolicyMgmtGen>::by<DeclarativePolicyUtils>()->getAgentPolicyPath()
|
||||
"/tmp/local_appsec.policy"
|
||||
);
|
||||
|
||||
if (!file_checksum.ok()) {
|
||||
|
@ -187,6 +187,8 @@ FogAuthenticator::registerAgent(
|
||||
request << make_pair("managedMode", "management");
|
||||
}
|
||||
|
||||
request << make_pair("userEdition", getUserEdition());
|
||||
|
||||
if (details_resolver->isReverseProxy()) {
|
||||
request << make_pair("reverse_proxy", "true");
|
||||
}
|
||||
@ -207,6 +209,9 @@ FogAuthenticator::registerAgent(
|
||||
if (details_resolver->compareCheckpointVersion(8100, std::greater_equal<int>())) {
|
||||
request << make_pair("isCheckpointVersionGER81", "true");
|
||||
}
|
||||
if (details_resolver->compareCheckpointVersion(8200, std::greater_equal<int>())) {
|
||||
request << make_pair("isCheckpointVersionGER82", "true");
|
||||
}
|
||||
#endif // gaia || smb
|
||||
|
||||
auto fog_messaging = Singleton::Consume<I_Messaging>::by<FogAuthenticator>();
|
||||
|
@ -0,0 +1,9 @@
|
||||
#include "fog_authenticator.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string
|
||||
FogAuthenticator::getUserEdition() const
|
||||
{
|
||||
return "community";
|
||||
}
|
6
components/security_apps/rate_limit/CMakeLists.txt
Normal file
6
components/security_apps/rate_limit/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
include_directories(../waap/waap_clib)
|
||||
include_directories(../waap/include)
|
||||
|
||||
add_library(rate_limit_comp rate_limit.cc)
|
||||
|
||||
add_library(rate_limit_config rate_limit_config.cc)
|
535
components/security_apps/rate_limit/rate_limit.cc
Executable file
535
components/security_apps/rate_limit/rate_limit.cc
Executable file
@ -0,0 +1,535 @@
|
||||
#include "rate_limit.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "debug.h"
|
||||
#include "i_environment.h"
|
||||
#include "i_mainloop.h"
|
||||
#include "i_time_get.h"
|
||||
#include "rate_limit_config.h"
|
||||
#include "nginx_attachment_common.h"
|
||||
#include "http_inspection_events.h"
|
||||
#include "Waf2Util.h"
|
||||
#include "generic_rulebase/evaluators/asset_eval.h"
|
||||
#include "WaapConfigApi.h"
|
||||
#include "WaapConfigApplication.h"
|
||||
#include "PatternMatcher.h"
|
||||
#include "i_waapConfig.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/sem.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "hiredis/hiredis.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_RATE_LIMIT);
|
||||
|
||||
using namespace std;
|
||||
|
||||
enum class RateLimitVedict { ACCEPT, DROP, DROP_AND_LOG };
|
||||
|
||||
class RateLimit::Impl
|
||||
:
|
||||
public Listener<HttpRequestHeaderEvent>
|
||||
{
|
||||
public:
|
||||
Impl() = default;
|
||||
~Impl() = default;
|
||||
|
||||
Maybe<string>
|
||||
extractUri(const string &address)
|
||||
{
|
||||
size_t protocolPos = address.find("://");
|
||||
if (protocolPos == std::string::npos) return genError("Invalid URI format: " + address);
|
||||
|
||||
size_t domainPos = address.find('/', protocolPos + 3);
|
||||
if (domainPos == std::string::npos) return string("");
|
||||
|
||||
return address.substr(domainPos);
|
||||
}
|
||||
|
||||
bool
|
||||
isRuleMatchingUri(const string &rule_uri, const string &request_uri, bool should_rule_be_exact_match)
|
||||
{
|
||||
if (rule_uri.find("*") != string::npos) {
|
||||
// first condition is for 'exact match with wildcard'
|
||||
// second is for when the rule serves as a prefix
|
||||
bool wildcard_match =
|
||||
!should_rule_be_exact_match && PatternMatcherWildcard(rule_uri + "*").match(request_uri + "/");
|
||||
wildcard_match |= PatternMatcherWildcard(rule_uri).match(request_uri);
|
||||
return wildcard_match;
|
||||
}
|
||||
|
||||
return !should_rule_be_exact_match && str_starts_with(request_uri, rule_uri);
|
||||
}
|
||||
|
||||
Maybe<RateLimitRule>
|
||||
findRateLimitRule(const string &matched_uri, string &asset_id)
|
||||
{
|
||||
WaapConfigAPI api_config;
|
||||
WaapConfigApplication application_config;
|
||||
IWaapConfig* site_config = nullptr;
|
||||
|
||||
if (WaapConfigAPI::getWaapAPIConfig(api_config)) {
|
||||
site_config = &api_config;
|
||||
} else if (WaapConfigApplication::getWaapSiteConfig(application_config)) {
|
||||
site_config = &application_config;
|
||||
}
|
||||
|
||||
if (site_config == nullptr) return genError("Failed to get asset configuration. Skipping rate limit check.");
|
||||
|
||||
asset_id = site_config->get_AssetId();
|
||||
ScopedContext rate_limit_ctx;
|
||||
rate_limit_ctx.registerValue<GenericConfigId>(AssetMatcher::ctx_key, site_config->get_AssetId());
|
||||
auto maybe_rate_limit_config = getConfiguration<RateLimitConfig>("rulebase", "rateLimit");
|
||||
if (!maybe_rate_limit_config.ok())
|
||||
return genError("Failed to get rate limit configuration. Skipping rate limit check.");
|
||||
|
||||
const auto &rate_limit_config = maybe_rate_limit_config.unpack();
|
||||
mode = rate_limit_config.getRateLimitMode();
|
||||
|
||||
if (mode == "Inactive") return genError("Rate limit mode is Inactive in policy");
|
||||
|
||||
set<string> rule_set;
|
||||
Maybe<RateLimitRule> matched_rule = genError("URI did not match any rate limit rule.");
|
||||
int rate_limit_longest_match = 0;
|
||||
for (const auto &application_url : site_config->get_applicationUrls()) {
|
||||
dbgTrace(D_RATE_LIMIT) << "Application URL: " << application_url;
|
||||
|
||||
auto maybe_uri = extractUri(application_url);
|
||||
if (!maybe_uri.ok()) {
|
||||
dbgWarning(D_RATE_LIMIT) << "Failed to extract URI from application URL: " << maybe_uri.getErr();
|
||||
continue;
|
||||
}
|
||||
|
||||
string application_uri = maybe_uri.unpack();
|
||||
if (application_uri.back() == '/') application_uri.pop_back();
|
||||
|
||||
for (const auto &rule : rate_limit_config.getRateLimitRules()) {
|
||||
string full_rule_uri = application_uri + rule.getRateLimitUri();
|
||||
int full_rule_uri_length = full_rule_uri.length();
|
||||
|
||||
// avoiding duplicates
|
||||
if (!rule_set.insert(full_rule_uri).second) continue;
|
||||
|
||||
dbgTrace(D_RATE_LIMIT)
|
||||
<< "Trying to match rule uri: "
|
||||
<< full_rule_uri
|
||||
<< " with request uri: "
|
||||
<< matched_uri;
|
||||
|
||||
if (full_rule_uri_length < rate_limit_longest_match) {
|
||||
dbgDebug(D_RATE_LIMIT)
|
||||
<< "rule is shorter then already matched rule. current rule length: "
|
||||
<< full_rule_uri_length
|
||||
<< ", previously longest matched rule length: "
|
||||
<< rate_limit_longest_match;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (full_rule_uri == matched_uri ||
|
||||
full_rule_uri == matched_uri + "/" ||
|
||||
full_rule_uri + "/" == matched_uri) {
|
||||
dbgDebug(D_RATE_LIMIT)
|
||||
<< "Found Exact match to request uri: "
|
||||
<< matched_uri
|
||||
<< ", rule uri: "
|
||||
<< full_rule_uri;
|
||||
return rule;
|
||||
}
|
||||
|
||||
if (rule.getRateLimitUri() == "/") {
|
||||
dbgDebug(D_RATE_LIMIT)
|
||||
<< "Matched new longest rule, request uri: "
|
||||
<< matched_uri
|
||||
<< ", rule uri: "
|
||||
<< full_rule_uri;
|
||||
matched_rule = rule;
|
||||
rate_limit_longest_match = full_rule_uri_length;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isRuleMatchingUri(full_rule_uri, matched_uri, rule.isExactMatch())) {
|
||||
dbgDebug(D_RATE_LIMIT)
|
||||
<< "Matched new longest rule, request uri: "
|
||||
<< matched_uri
|
||||
<< ", rule uri: "
|
||||
<< full_rule_uri;
|
||||
matched_rule = rule;
|
||||
rate_limit_longest_match = full_rule_uri_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matched_rule;
|
||||
}
|
||||
|
||||
EventVerdict
|
||||
respond(const HttpRequestHeaderEvent &event) override
|
||||
{
|
||||
if (!event.isLastHeader()) return INSPECT;
|
||||
|
||||
auto uri_ctx = Singleton::Consume<I_Environment>::by<RateLimit>()->get<string>(HttpTransactionData::uri_ctx);
|
||||
if (!uri_ctx.ok()) {
|
||||
dbgWarning(D_RATE_LIMIT) << "Unable to get URL from context, Not enforcing rate limit";
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
string asset_id;
|
||||
auto uri = uri_ctx.unpack();
|
||||
transform(uri.begin(), uri.end(), uri.begin(), [](unsigned char c) { return tolower(c); });
|
||||
auto maybe_rule = findRateLimitRule(uri, asset_id);
|
||||
if (!maybe_rule.ok()) {
|
||||
dbgDebug(D_RATE_LIMIT) << "Not Enforcing Rate Limit: " << maybe_rule.getErr();
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
const auto &rule = maybe_rule.unpack();
|
||||
burst = rule.getRateLimit();
|
||||
limit = static_cast<float>(rule.getRateLimit()) / (rule.getRateLimitScope() == "Minute" ? 60 : 1);
|
||||
|
||||
dbgTrace(D_RATE_LIMIT)
|
||||
<< "found rate limit rule with: "
|
||||
<< rule.getRateLimit()
|
||||
<< " per "
|
||||
<< (rule.getRateLimitScope() == "Minute" ? 60 : 1)
|
||||
<< " seconds";
|
||||
|
||||
auto maybe_source_identifier =
|
||||
Singleton::Consume<I_Environment>::by<RateLimit>()->get<string>(HttpTransactionData::source_identifier);
|
||||
if (!maybe_source_identifier.ok()) {
|
||||
dbgWarning(D_RATE_LIMIT) << "Unable to get source identifier from context, not enforcing rate limit";
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
auto &source_identifier = maybe_source_identifier.unpack();
|
||||
dbgDebug(D_RATE_LIMIT) << "source identifier value: " << source_identifier;
|
||||
|
||||
string unique_key = asset_id + ":" + source_identifier + ":" + uri;
|
||||
if (unique_key.back() == '/') unique_key.pop_back();
|
||||
|
||||
auto verdict = decide(unique_key);
|
||||
if (verdict == RateLimitVedict::ACCEPT) {
|
||||
dbgTrace(D_RATE_LIMIT) << "Received ACCEPT verdict.";
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
if (verdict == RateLimitVedict::DROP_AND_LOG) sendLog(uri, source_identifier, rule);
|
||||
|
||||
if (mode == "Active") {
|
||||
dbgTrace(D_RATE_LIMIT) << "Received DROP verdict, this request will be blocked by rate limit";
|
||||
return DROP;
|
||||
}
|
||||
|
||||
dbgTrace(D_RATE_LIMIT) << "Received DROP in detect mode, will not block.";
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
string
|
||||
getListenerName() const override
|
||||
{
|
||||
return "rate limit";
|
||||
}
|
||||
|
||||
RateLimitVedict
|
||||
decide(const std::string &key) {
|
||||
if (redis == nullptr) {
|
||||
dbgDebug(D_RATE_LIMIT)
|
||||
<< "there is no connection to the redis at the moment, unable to enforce rate limit";
|
||||
reconnectRedis();
|
||||
return RateLimitVedict::ACCEPT;
|
||||
}
|
||||
|
||||
redisReply* reply = static_cast<redisReply*>(redisCommand(redis, "EVALSHA %s 1 %s %f %d",
|
||||
rate_limit_lua_script_hash.c_str(), key.c_str(), limit, burst));
|
||||
|
||||
if (reply == NULL || redis->err) {
|
||||
dbgDebug(D_RATE_LIMIT)
|
||||
<< "Error executing Redis command: No reply received, unable to enforce rate limit";
|
||||
reconnectRedis();
|
||||
return RateLimitVedict::ACCEPT;
|
||||
}
|
||||
|
||||
// redis's lua script returned true - accept
|
||||
if (reply->type == REDIS_REPLY_INTEGER) {
|
||||
freeReplyObject(reply);
|
||||
return RateLimitVedict::ACCEPT;
|
||||
}
|
||||
|
||||
// redis's lua script returned false - drop, no need to log
|
||||
if (reply->type == REDIS_REPLY_NIL) {
|
||||
freeReplyObject(reply);
|
||||
return RateLimitVedict::DROP;
|
||||
}
|
||||
|
||||
// redis's lua script returned string - drop and send log
|
||||
const char* log_str = "BLOCK AND LOG";
|
||||
if (reply->type == REDIS_REPLY_STRING && strncmp(reply->str, log_str, strlen(log_str)) == 0) {
|
||||
freeReplyObject(reply);
|
||||
return RateLimitVedict::DROP_AND_LOG;
|
||||
}
|
||||
|
||||
dbgDebug(D_RATE_LIMIT)
|
||||
<< "Got unexected reply from redis. reply type: "
|
||||
<< reply->type
|
||||
<< ". not enforcing rate limit for this request.";
|
||||
freeReplyObject(reply);
|
||||
return RateLimitVedict::ACCEPT;
|
||||
}
|
||||
|
||||
void
|
||||
sendLog(const string &uri, const string &source_identifier, const RateLimitRule& rule)
|
||||
{
|
||||
set<string> rate_limit_triggers_set;
|
||||
for (const auto &trigger : rule.getRateLimitTriggers()) {
|
||||
rate_limit_triggers_set.insert(trigger.getTriggerId());
|
||||
}
|
||||
|
||||
ScopedContext ctx;
|
||||
ctx.registerValue<std::set<GenericConfigId>>(TriggerMatcher::ctx_key, rate_limit_triggers_set);
|
||||
auto log_trigger = getConfigurationWithDefault(LogTriggerConf(), "rulebase", "log");
|
||||
|
||||
if (!log_trigger.isPreventLogActive(LogTriggerConf::SecurityType::AccessControl)) {
|
||||
dbgTrace(D_RATE_LIMIT) << "Not sending rate-limit log as it is not required";
|
||||
return;
|
||||
}
|
||||
|
||||
auto maybe_rule_by_ctx = getConfiguration<BasicRuleConfig>("rulebase", "rulesConfig");
|
||||
if (!maybe_rule_by_ctx.ok()) {
|
||||
dbgWarning(D_RATE_LIMIT)
|
||||
<< "rule was not found by the given context. Reason: "
|
||||
<< maybe_rule_by_ctx.getErr();
|
||||
return;
|
||||
}
|
||||
|
||||
string event_name = "Rate limit";
|
||||
|
||||
LogGen log = log_trigger(
|
||||
event_name,
|
||||
LogTriggerConf::SecurityType::AccessControl,
|
||||
ReportIS::Severity::HIGH,
|
||||
ReportIS::Priority::HIGH,
|
||||
true,
|
||||
LogField("practiceType", "Rate Limit"),
|
||||
ReportIS::Tags::RATE_LIMIT
|
||||
);
|
||||
|
||||
const auto &rule_by_ctx = maybe_rule_by_ctx.unpack();
|
||||
|
||||
log
|
||||
<< LogField("assetId", rule_by_ctx.getAssetId())
|
||||
<< LogField("assetName", rule_by_ctx.getAssetName())
|
||||
<< LogField("ruleId", rule_by_ctx.getRuleId())
|
||||
<< LogField("ruleName", rule_by_ctx.getRuleName())
|
||||
<< LogField("httpUriPath", uri)
|
||||
<< LogField("httpSourceId", source_identifier)
|
||||
<< LogField("securityAction", (mode == "Active" ? "Prevent" : "Detect"))
|
||||
<< LogField("waapIncidentType", "Rate Limit");
|
||||
|
||||
auto http_method =
|
||||
Singleton::Consume<I_Environment>::by<RateLimit>()->get<string>(HttpTransactionData::method_ctx);
|
||||
if (http_method.ok()) log << LogField("httpMethod", http_method.unpack());
|
||||
|
||||
auto http_host =
|
||||
Singleton::Consume<I_Environment>::by<RateLimit>()->get<string>(HttpTransactionData::host_name_ctx);
|
||||
if (http_host.ok()) log << LogField("httpHostName", http_host.unpack());
|
||||
|
||||
auto source_ip =
|
||||
Singleton::Consume<I_Environment>::by<RateLimit>()->get<IPAddr>(HttpTransactionData::client_ip_ctx);
|
||||
if (source_ip.ok()) log << LogField("sourceIP", ipAddrToStr(source_ip.unpack()));
|
||||
|
||||
auto proxy_ip =
|
||||
Singleton::Consume<I_Environment>::by<RateLimit>()->get<std::string>(HttpTransactionData::proxy_ip_ctx);
|
||||
if (proxy_ip.ok() && source_ip.ok() && ipAddrToStr(source_ip.unpack()) != proxy_ip.unpack()) {
|
||||
log << LogField("proxyIP", static_cast<std::string>(proxy_ip.unpack()));
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
ipAddrToStr(const IPAddr& ip_address) const
|
||||
{
|
||||
char str[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &(ip_address), str, INET_ADDRSTRLEN);
|
||||
return string(str);
|
||||
}
|
||||
|
||||
Maybe<void>
|
||||
connectRedis()
|
||||
{
|
||||
disconnectRedis();
|
||||
|
||||
redisOptions options;
|
||||
memset(&options, 0, sizeof(redisOptions));
|
||||
REDIS_OPTIONS_SET_TCP(
|
||||
&options,
|
||||
"127.0.0.1",
|
||||
getConfigurationWithDefault<int>(6379, "connection", "Redis Port")
|
||||
);
|
||||
|
||||
timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = getConfigurationWithDefault<int>(30000, "connection", "Redis Timeout");
|
||||
options.connect_timeout = &timeout;
|
||||
options.command_timeout = &timeout;
|
||||
|
||||
redisContext* context = redisConnectWithOptions(&options);
|
||||
if (context != nullptr && context->err) {
|
||||
dbgDebug(D_RATE_LIMIT)
|
||||
<< "Error connecting to Redis: "
|
||||
<< context->errstr;
|
||||
redisFree(context);
|
||||
return genError("");
|
||||
}
|
||||
|
||||
if (context == nullptr) return genError("");
|
||||
|
||||
redis = context;
|
||||
static string luaScript = R"(
|
||||
local key = KEYS[1]
|
||||
local rateLimit = tonumber(ARGV[1])
|
||||
local burstLimit = tonumber(ARGV[2])
|
||||
local currentTimeSeconds = tonumber(redis.call('time')[1])
|
||||
local lastRequestTimeSeconds = tonumber(redis.call('get', key .. ':lastRequestTime') or "0")
|
||||
local elapsedTimeSeconds = currentTimeSeconds - lastRequestTimeSeconds
|
||||
local tokens = tonumber(redis.call('get', key .. ':tokens') or burstLimit)
|
||||
local was_blocked = tonumber(redis.call('get', key .. ':block') or "0")
|
||||
|
||||
tokens = math.min(tokens + (elapsedTimeSeconds * rateLimit), burstLimit)
|
||||
|
||||
if tokens >= 1 then
|
||||
tokens = tokens - 1
|
||||
redis.call('set', key .. ':tokens', tokens)
|
||||
redis.call('set', key .. ':lastRequestTime', currentTimeSeconds)
|
||||
redis.call('expire', key .. ':tokens', 60)
|
||||
redis.call('expire', key .. ':lastRequestTime', 60)
|
||||
return true
|
||||
elseif was_blocked == 1 then
|
||||
redis.call('set', key .. ':block', 1)
|
||||
redis.call('expire', key .. ':block', 60)
|
||||
return false
|
||||
else
|
||||
redis.call('set', key .. ':block', 1)
|
||||
redis.call('expire', key .. ':block', 60)
|
||||
return "BLOCK AND LOG"
|
||||
end
|
||||
)";
|
||||
|
||||
// Load the Lua script in Redis and retrieve its SHA1 hash
|
||||
redisReply* loadReply =
|
||||
static_cast<redisReply*>(redisCommand(redis, "SCRIPT LOAD %s", luaScript.c_str()));
|
||||
if (loadReply != nullptr && loadReply->type == REDIS_REPLY_STRING) {
|
||||
rate_limit_lua_script_hash = loadReply->str;
|
||||
freeReplyObject(loadReply);
|
||||
}
|
||||
|
||||
return Maybe<void>();
|
||||
}
|
||||
|
||||
void
|
||||
reconnectRedis()
|
||||
{
|
||||
dbgFlow(D_RATE_LIMIT) << "Trying to reconnect to redis after failure to invoke a redis command";
|
||||
static bool is_reconnecting = false;
|
||||
if (!is_reconnecting) {
|
||||
is_reconnecting = true;
|
||||
Singleton::Consume<I_MainLoop>::by<RateLimit>()->addOneTimeRoutine(
|
||||
I_MainLoop::RoutineType::System,
|
||||
[this] ()
|
||||
{
|
||||
connectRedis();
|
||||
is_reconnecting = false;
|
||||
},
|
||||
"Reconnect redis",
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
handleNewPolicy()
|
||||
{
|
||||
if (RateLimitConfig::isActive() && !redis) {
|
||||
connectRedis();
|
||||
registerListener();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RateLimitConfig::isActive()) {
|
||||
disconnectRedis();
|
||||
unregisterListener();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
disconnectRedis()
|
||||
{
|
||||
if (redis) {
|
||||
redisFree(redis);
|
||||
redis = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
init()
|
||||
{
|
||||
Singleton::Consume<I_MainLoop>::by<RateLimit>()->addOneTimeRoutine(
|
||||
I_MainLoop::RoutineType::System,
|
||||
[this] ()
|
||||
{
|
||||
handleNewPolicy();
|
||||
registerConfigLoadCb([this]() { handleNewPolicy(); });
|
||||
},
|
||||
"Initialize rate limit component",
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
fini()
|
||||
{
|
||||
disconnectRedis();
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr auto DROP = ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP;
|
||||
static constexpr auto ACCEPT = ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT;
|
||||
static constexpr auto INSPECT = ngx_http_cp_verdict_e::TRAFFIC_VERDICT_INSPECT;
|
||||
|
||||
string mode;
|
||||
string rate_limit_lua_script_hash;
|
||||
int burst;
|
||||
float limit;
|
||||
redisContext* redis = nullptr;
|
||||
};
|
||||
|
||||
RateLimit::RateLimit() : Component("RateLimit"), pimpl(make_unique<Impl>()) {}
|
||||
|
||||
RateLimit::~RateLimit() = default;
|
||||
|
||||
void
|
||||
RateLimit::preload()
|
||||
{
|
||||
registerExpectedConfiguration<WaapConfigApplication>("WAAP", "WebApplicationSecurity");
|
||||
registerExpectedConfiguration<WaapConfigAPI>("WAAP", "WebAPISecurity");
|
||||
registerExpectedConfigFile("waap", Config::ConfigFileType::Policy);
|
||||
registerExpectedConfiguration<RateLimitConfig>("rulebase", "rateLimit");
|
||||
registerExpectedConfigFile("accessControlV2", Config::ConfigFileType::Policy);
|
||||
registerConfigPrepareCb([]() { RateLimitConfig::resetIsActive(); });
|
||||
}
|
||||
|
||||
void
|
||||
RateLimit::init() { pimpl->init(); }
|
||||
|
||||
void
|
||||
RateLimit::fini() { pimpl->fini(); }
|
157
components/security_apps/rate_limit/rate_limit_config.cc
Executable file
157
components/security_apps/rate_limit/rate_limit_config.cc
Executable file
@ -0,0 +1,157 @@
|
||||
#include "rate_limit_config.h"
|
||||
|
||||
bool RateLimitConfig::is_active = false;
|
||||
|
||||
void
|
||||
RateLimitTrigger::load(cereal::JSONInputArchive &ar)
|
||||
{
|
||||
dbgTrace(D_REVERSE_PROXY) << "Serializing single Rate Limit rule's triggers";
|
||||
try {
|
||||
ar(cereal::make_nvp("id", id));
|
||||
} catch (const cereal::Exception &e) {
|
||||
dbgWarning(D_REVERSE_PROXY)
|
||||
<< "Failed to load single Rate Limit JSON rule's triggers. Error: " << e.what();
|
||||
ar.setNextName(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RateLimitRule::load(cereal::JSONInputArchive &ar)
|
||||
{
|
||||
dbgTrace(D_REVERSE_PROXY) << "Serializing single Rate Limit rule";
|
||||
try {
|
||||
ar(cereal::make_nvp("URI", uri));
|
||||
ar(cereal::make_nvp("scope", scope));
|
||||
ar(cereal::make_nvp("limit", limit));
|
||||
ar(cereal::make_nvp("triggers", rate_limit_triggers));
|
||||
} catch (const cereal::Exception &e) {
|
||||
dbgWarning(D_REVERSE_PROXY) << "Failed to load single Rate Limit JSON rule. Error: " << e.what();
|
||||
ar.setNextName(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RateLimitRule::prepare(const std::string &asset_id, int zone_id)
|
||||
{
|
||||
std::string zone_id_s = std::to_string(zone_id);
|
||||
std::string zone;
|
||||
if (isRootLocation()) {
|
||||
zone = "root_zone_" + asset_id + "_" + zone_id_s;
|
||||
} else {
|
||||
std::string zone_name_suffix = uri;
|
||||
std::replace(zone_name_suffix.begin(), zone_name_suffix.end(), '/', '_');
|
||||
zone = "zone" + zone_name_suffix + "_" + zone_id_s;
|
||||
}
|
||||
|
||||
limit_req_template_value = "zone=" + zone + " burst=" + std::to_string(limit) + " nodelay";
|
||||
|
||||
// nginx conf will look like: limit_req_zone <sourceIdentifier> zone=<location>_<id>:10m rate=<limit>r/<scope>;
|
||||
std::string rate_unit = scope == "Minute" ? "r/m" : "r/s";
|
||||
limit_req_zone_template_value =
|
||||
"zone=" + zone + ":" + cache_size + " rate=" + std::to_string(limit) + rate_unit;
|
||||
|
||||
dbgTrace(D_REVERSE_PROXY)
|
||||
<< "limit_req_zone nginx template value: "
|
||||
<< limit_req_zone_template_value
|
||||
<< ", limit_req nginx template value: "
|
||||
<< limit_req_template_value;
|
||||
}
|
||||
|
||||
bool
|
||||
RateLimitRule::isRootLocation() const
|
||||
{
|
||||
if (uri.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto non_root = uri.find_first_not_of("/");
|
||||
if (non_root != std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RateLimitConfig::load(cereal::JSONInputArchive &ar)
|
||||
{
|
||||
dbgTrace(D_REVERSE_PROXY) << "Serializing Rate Limit config";
|
||||
try {
|
||||
ar(cereal::make_nvp("rules", rate_limit_rules));
|
||||
ar(cereal::make_nvp("mode", mode));
|
||||
prepare();
|
||||
} catch (const cereal::Exception &e) {
|
||||
dbgWarning(D_REVERSE_PROXY) << "Failed to load single Rate Limit JSON config. Error: " << e.what();
|
||||
ar.setNextName(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RateLimitConfig::addSiblingRateLimitRule(RateLimitRule &rule) {
|
||||
rule.setExactMatch();
|
||||
RateLimitRule sibling_rule(rule);
|
||||
sibling_rule.appendSlash();
|
||||
sibling_rule.setExactMatch();
|
||||
rate_limit_rules.push_back(sibling_rule);
|
||||
}
|
||||
|
||||
void
|
||||
RateLimitConfig::prepare()
|
||||
{
|
||||
// Removes invalid rules
|
||||
auto last_valid_rule =
|
||||
std::remove_if(
|
||||
rate_limit_rules.begin(),
|
||||
rate_limit_rules.end(),
|
||||
[](const RateLimitRule &rule) { return !rule; }
|
||||
);
|
||||
|
||||
rate_limit_rules.erase(last_valid_rule, rate_limit_rules.end());
|
||||
|
||||
// Removes duplicates
|
||||
sort(rate_limit_rules.begin(), rate_limit_rules.end());
|
||||
rate_limit_rules.erase(std::unique(rate_limit_rules.begin(), rate_limit_rules.end()), rate_limit_rules.end());
|
||||
|
||||
std::for_each(
|
||||
rate_limit_rules.begin(),
|
||||
rate_limit_rules.end(),
|
||||
[this](RateLimitRule &rule) { if (rule.isExactMatch()) { addSiblingRateLimitRule(rule); } }
|
||||
);
|
||||
|
||||
dbgTrace(D_REVERSE_PROXY)
|
||||
<< "Final rate-limit rules: "
|
||||
<< makeSeparatedStr(rate_limit_rules, "; ")
|
||||
<< "; Mode: "
|
||||
<< mode;
|
||||
|
||||
setIsActive(mode != "Inactive");
|
||||
}
|
||||
|
||||
const RateLimitRule
|
||||
RateLimitConfig::findLongestMatchingRule(const std::string &nginx_uri) const
|
||||
{
|
||||
dbgFlow(D_REVERSE_PROXY) << "Trying to find a matching rat-limit rule for NGINX URI: " << nginx_uri;
|
||||
|
||||
size_t longest_len = 0;
|
||||
RateLimitRule longest_matching_rule;
|
||||
for (const RateLimitRule &rule : rate_limit_rules) {
|
||||
if (rule.getRateLimitUri() == nginx_uri) {
|
||||
dbgTrace(D_REVERSE_PROXY) << "Found exact rate-limit match: " << rule;
|
||||
return rule;
|
||||
}
|
||||
|
||||
if (nginx_uri.size() < rule.getRateLimitUri().size()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (std::equal(rule.getRateLimitUri().rbegin(), rule.getRateLimitUri().rend(), nginx_uri.rbegin())) {
|
||||
if (rule.getRateLimitUri().size() > longest_len) {
|
||||
longest_matching_rule = rule;
|
||||
longest_len = rule.getRateLimitUri().size();
|
||||
dbgTrace(D_REVERSE_PROXY) << "Longest matching rate-limit rule so far: " << rule;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbgTrace(D_REVERSE_PROXY) << "Longest matching rate-limit rule: " << longest_matching_rule;
|
||||
return longest_matching_rule;
|
||||
}
|
@ -52,6 +52,7 @@ public:
|
||||
virtual const std::string& get_RuleName() const = 0;
|
||||
virtual const bool& get_WebAttackMitigation() const = 0;
|
||||
virtual const std::string& get_WebAttackMitigationAction() const = 0;
|
||||
virtual const std::vector<std::string> & get_applicationUrls() const = 0;
|
||||
|
||||
virtual const std::shared_ptr<Waap::Override::Policy>& get_OverridePolicy() const = 0;
|
||||
virtual const std::shared_ptr<Waap::Trigger::Policy>& get_TriggerPolicy() const = 0;
|
||||
|
@ -253,6 +253,12 @@ void WaapConfigBase::loadOpenRedirectPolicy(cereal::JSONInputArchive& ar)
|
||||
}
|
||||
|
||||
|
||||
const std::vector<std::string> &
|
||||
WaapConfigBase::get_applicationUrls() const
|
||||
{
|
||||
return m_applicationUrls;
|
||||
}
|
||||
|
||||
void WaapConfigBase::loadErrorDisclosurePolicy(cereal::JSONInputArchive& ar)
|
||||
{
|
||||
std::string failMessage = "Failed to load the WAAP Information Disclosure policy";
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
virtual const std::string& get_RuleName() const;
|
||||
virtual const bool& get_WebAttackMitigation() const;
|
||||
virtual const std::string& get_WebAttackMitigationAction() const;
|
||||
virtual const std::vector<std::string> & get_applicationUrls() const;
|
||||
|
||||
virtual const std::shared_ptr<Waap::Override::Policy>& get_OverridePolicy() const;
|
||||
virtual const std::shared_ptr<Waap::Trigger::Policy>& get_TriggerPolicy() const;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <sys/syscall.h>
|
||||
#include <dirent.h>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
@ -49,6 +50,24 @@ exists(const string &path)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
isDirectory(const string &path)
|
||||
{
|
||||
dbgFlow(D_INFRA_UTILS) << "Checking if path is a directory. Path: " << path;
|
||||
struct stat buffer;
|
||||
if (stat(path.c_str(), &buffer) != 0) {
|
||||
dbgTrace(D_INFRA_UTILS) << "Path does not exists. Path: " << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buffer.st_mode & S_IFDIR) {
|
||||
dbgTrace(D_INFRA_UTILS) << "Path is a directory. Path: " << path;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
makeDir(const string &path, mode_t permission)
|
||||
{
|
||||
@ -356,4 +375,20 @@ regexReplace(const char *file, int line, const string &sample, const regex ®e
|
||||
|
||||
}// namespace Regex
|
||||
|
||||
namespace Strings
|
||||
{
|
||||
|
||||
string
|
||||
removeTrailingWhitespaces(string str)
|
||||
{
|
||||
str.erase(
|
||||
find_if(str.rbegin(), str.rend(), [] (char c) { return !isspace(c); }).base(),
|
||||
str.end()
|
||||
);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
} // namespace Strings
|
||||
|
||||
} // namespace NGEN
|
||||
|
@ -98,8 +98,20 @@ TEST_F(AgentCoreUtilUT, printTest)
|
||||
EXPECT_EQ(NGEN::Filesystem::convertToHumanReadable(1024*gigabyte), "1024.00 GB");
|
||||
}
|
||||
|
||||
|
||||
TEST_F(AgentCoreUtilUT, fileBasenameTest)
|
||||
{
|
||||
EXPECT_EQ(NGEN::Filesystem::getFileName("/test/base/file/name"), "name");
|
||||
}
|
||||
|
||||
TEST_F(AgentCoreUtilUT, isDirectoryTest)
|
||||
{
|
||||
mkdir("./test", 0400);
|
||||
EXPECT_EQ(NGEN::Filesystem::isDirectory("/test/base/file/name"), false);
|
||||
EXPECT_EQ(NGEN::Filesystem::isDirectory("./test"), true);
|
||||
}
|
||||
|
||||
TEST_F(AgentCoreUtilUT, removeTrailingWhitespacesTest)
|
||||
{
|
||||
string str_with_trailing_whitespace = "str_with_trailing_whitespace\n\n\n\r \n\n\r";
|
||||
EXPECT_EQ(NGEN::Strings::removeTrailingWhitespaces(str_with_trailing_whitespace), "str_with_trailing_whitespace");
|
||||
}
|
||||
|
@ -141,7 +141,6 @@ Environment::Impl::init()
|
||||
void
|
||||
Environment::Impl::fini()
|
||||
{
|
||||
global.deactivate();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -143,7 +143,8 @@ enum class Notification {
|
||||
SDWAN_POLICY_UPDATE,
|
||||
SDWAN_POLICY_UPDATE_ERROR,
|
||||
SDWAN_POLICY_UPDATE_LOG,
|
||||
SDWAN_POLICY_UPDATE_ERROR_LOG
|
||||
SDWAN_POLICY_UPDATE_ERROR_LOG,
|
||||
SDWAN_POLICY_WARNING_LOG
|
||||
};
|
||||
|
||||
enum class IssuingEngine {
|
||||
|
@ -25,6 +25,7 @@ namespace Filesystem
|
||||
{
|
||||
|
||||
bool exists(const std::string &path);
|
||||
bool isDirectory(const std::string &path);
|
||||
|
||||
bool makeDir(const std::string &path, mode_t permission = S_IRWXU);
|
||||
bool makeDirRecursive(const std::string &path, mode_t permission = S_IRWXU);
|
||||
@ -75,6 +76,13 @@ regexReplace(
|
||||
|
||||
} // namespace Regex
|
||||
|
||||
namespace Strings
|
||||
{
|
||||
|
||||
std::string removeTrailingWhitespaces(std::string str);
|
||||
|
||||
} // namespace Strings
|
||||
|
||||
} // namespace NGEN
|
||||
|
||||
#endif // __AGENT_CORE_UTILITIES_H__
|
||||
|
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