Merge pull request #17 from openappsec/Mar_13_2023-Dev

Mar 13th 2023 update
This commit is contained in:
WrightNed 2023-03-13 21:04:46 +02:00 committed by GitHub
commit 5848f1d7e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 587 additions and 532 deletions

View File

@ -26,6 +26,7 @@ enum class ReconfStatus { SUCCEEDED, IN_PROGRESS, FAILED, INACTIVE };
class I_ServiceController
{
public:
virtual void refreshPendingServices() = 0;
virtual const std::string & getPolicyVersion() const = 0;
virtual const std::string & getUpdatePolicyVersion() const = 0;
virtual void updateReconfStatus(int id, ReconfStatus status) = 0;

View File

@ -48,7 +48,13 @@ private:
DecisionTelemetryData data;
};
class WaapTelemetrics : public GenericMetric
class WaapTelemetryBase : public GenericMetric
{
protected:
virtual void sendLog(const LogRest &metric_client_rest) const override;
};
class WaapTelemetrics : public WaapTelemetryBase
{
public:
void updateMetrics(const std::string &asset_id, const DecisionTelemetryData &data);
@ -68,7 +74,7 @@ private:
std::unordered_set<std::string> sources_seen;
};
class WaapAttackTypesMetrics : public GenericMetric
class WaapAttackTypesMetrics : public WaapTelemetryBase
{
public:
void updateMetrics(const std::string &asset_id, const DecisionTelemetryData &data);

View File

@ -18,6 +18,7 @@
#include "i_environment.h"
#include "i_rest_api.h"
#include "i_mainloop.h"
#include "i_service_controller.h"
#include "i_orchestration_tools.h"
#include "component.h"
@ -27,6 +28,7 @@ class UpdateCommunication
Singleton::Provide<I_UpdateCommunication>,
Singleton::Consume<I_RestApi>,
Singleton::Consume<I_MainLoop>,
Singleton::Consume<I_ServiceController>,
Singleton::Consume<I_OrchestrationTools>
{
public:

View File

@ -24,6 +24,8 @@ class MockServiceController :
{
public:
MOCK_METHOD0(refreshPendingServices, void());
MOCK_CONST_METHOD0(getPolicyVersion, const std::string &());
MOCK_CONST_METHOD0(getUpdatePolicyVersion, const std::string &());

View File

@ -15,12 +15,12 @@
using namespace std;
USE_DEBUG_FLAG(D_K8S_POLICY);
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
void
AppSecWebBotsURI::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec Web Bots URI";
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Web Bots URI";
parseAppsecJSONKey<string>("uri", uri, archive_in);
}
@ -33,7 +33,7 @@ AppSecWebBotsURI::getURI() const
void
AppSecPracticeAntiBot::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec Web Bots";
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");
@ -55,7 +55,7 @@ AppSecPracticeAntiBot::save(cereal::JSONOutputArchive &out_ar) const
void
AppSecWebAttackProtections::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec Web Attack Protections";
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");
@ -66,7 +66,7 @@ const string
AppSecWebAttackProtections::getCsrfProtectionMode() const
{
if (key_to_practices_val.find(csrf_protection) == key_to_practices_val.end()) {
dbgError(D_K8S_POLICY)
dbgError(D_LOCAL_POLICY)
<< "Failed to find a value for "
<< csrf_protection
<< ". Setting CSRF protection to Inactive";
@ -91,7 +91,7 @@ const string
AppSecWebAttackProtections::getOpenRedirectMode() const
{
if (key_to_practices_val.find(open_redirect) == key_to_practices_val.end()) {
dbgError(D_K8S_POLICY)
dbgError(D_LOCAL_POLICY)
<< "Failed to find a value for "
<< open_redirect
<< ". Setting Open Redirect mode to Inactive";
@ -103,7 +103,7 @@ AppSecWebAttackProtections::getOpenRedirectMode() const
void
AppSecPracticeWebAttacks::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec practice spec";
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec";
parseAppsecJSONKey<AppSecWebAttackProtections>("protections", protections, archive_in);
parseAppsecJSONKey<string>("override-mode", mode, archive_in, "Unset");
if (getMode() == "Prevent") {
@ -151,7 +151,7 @@ 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_K8S_POLICY) << "Couldn't find a value for key: " << mode << ". Returning " << default_mode;
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);
@ -160,7 +160,7 @@ AppSecPracticeWebAttacks::getMode(const string &default_mode) const
void
AppSecPracticeSnortSignatures::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec Snort Signatures practice";
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);
}
@ -180,7 +180,7 @@ AppSecPracticeSnortSignatures::getConfigMap() const
void
AppSecPracticeOpenSchemaAPI::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSecPracticeOpenSchemaAPI practice";
dbgTrace(D_LOCAL_POLICY) << "Loading AppSecPracticeOpenSchemaAPI practice";
parseAppsecJSONKey<string>("override-mode", override_mode, archive_in, "Inactive");
parseAppsecJSONKey<vector<string>>("configmap", config_map, archive_in);
}
@ -200,7 +200,7 @@ AppSecPracticeOpenSchemaAPI::getConfigMap() const
void
AppSecPracticeSpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec practice spec";
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec";
parseAppsecJSONKey<AppSecPracticeOpenSchemaAPI>(
"openapi-schema-validation",
openapi_schema_validation,
@ -421,7 +421,7 @@ AppSecWrapper::save(cereal::JSONOutputArchive &out_ar) const
void
ParsedRule::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec ParsedRule";
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);
@ -498,7 +498,7 @@ ParsedRule::getTrustedSources() const
void
AppsecPolicySpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec policy spec";
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec policy spec";
parseAppsecJSONKey<ParsedRule>("default", default_rule, archive_in);
auto default_mode_annot =
Singleton::Consume<I_Environment>::by<AppsecPolicySpec>()->get<string>("default mode annotation");
@ -506,8 +506,7 @@ AppsecPolicySpec::load(cereal::JSONInputArchive &archive_in)
default_rule.setMode(default_mode_annot.unpack());
}
default_rule.setHost("*");
parseAppsecJSONKey<list<ParsedRule>>("specific-rules", specific_rules, archive_in);
specific_rules.push_front(default_rule);
parseAppsecJSONKey<vector<ParsedRule>>("specific-rules", specific_rules, archive_in);
}
const ParsedRule &
@ -516,7 +515,7 @@ AppsecPolicySpec::getDefaultRule() const
return default_rule;
}
const list<ParsedRule> &
const vector<ParsedRule> &
AppsecPolicySpec::getSpecificRules() const
{
return specific_rules;
@ -525,7 +524,7 @@ AppsecPolicySpec::getSpecificRules() const
void
AppsecLinuxPolicy::serialize(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading Appsec Linux Policy";
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);
@ -533,8 +532,8 @@ AppsecLinuxPolicy::serialize(cereal::JSONInputArchive &archive_in)
parseAppsecJSONKey<vector<AppsecExceptionSpec>>("exceptions", exceptions, archive_in);
parseAppsecJSONKey<vector<TrustedSourcesSpec>>("trusted-sources", trusted_sources, archive_in);
parseAppsecJSONKey<vector<SourceIdentifierSpecWrapper>>(
"source-identifier",
sources_identifier,
"source-identifiers",
sources_identifiers,
archive_in
);
}
@ -578,7 +577,7 @@ AppsecLinuxPolicy::getAppsecTrustedSourceSpecs() const
const vector<SourceIdentifierSpecWrapper> &
AppsecLinuxPolicy::getAppsecSourceIdentifierSpecs() const
{
return sources_identifier;
return sources_identifiers;
}
// LCOV_EXCL_STOP

View File

@ -15,13 +15,13 @@
using namespace std;
USE_DEBUG_FLAG(D_K8S_POLICY);
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
void
AppsecExceptionSpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec exception spec";
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec exception spec";
parseAppsecJSONKey<string>("name", name, archive_in);
parseAppsecJSONKey<string>("action", action, archive_in);
parseAppsecJSONKey<vector<string>>("countryCode", country_code, archive_in);
@ -159,7 +159,7 @@ ExceptionMatch::save(cereal::JSONOutputArchive &out_ar) const
break;
}
default: {
dbgError(D_K8S_POLICY) << "No match for exception match type: " << static_cast<int>(match_type);
dbgError(D_LOCAL_POLICY) << "No match for exception match type: " << static_cast<int>(match_type);
}
}
}
@ -174,7 +174,7 @@ ExceptionBehavior::ExceptionBehavior(
try {
id = to_string(boost::uuids::random_generator()());
} catch (const boost::uuids::entropy_error &e) {
dbgWarning(D_K8S_POLICY) << "Failed to generate exception behavior UUID. Error: " << e.what();
dbgWarning(D_LOCAL_POLICY) << "Failed to generate exception behavior UUID. Error: " << e.what();
}
}

View File

@ -29,8 +29,6 @@
#include "exceptions_section.h"
#include "trusted_sources_section.h"
USE_DEBUG_FLAG(D_K8S_POLICY);
// LCOV_EXCL_START Reason: no test exist
class AppSecWebBotsURI
{
@ -355,11 +353,11 @@ public:
void load(cereal::JSONInputArchive &archive_in);
const ParsedRule & getDefaultRule() const;
const std::list<ParsedRule> & getSpecificRules() const;
const std::vector<ParsedRule> & getSpecificRules() const;
private:
ParsedRule default_rule;
std::list<ParsedRule> specific_rules;
std::vector<ParsedRule> specific_rules;
};
class AppsecLinuxPolicy : Singleton::Consume<I_Environment>
@ -383,7 +381,7 @@ private:
std::vector<AppSecCustomResponseSpec> custom_responses;
std::vector<AppsecExceptionSpec> exceptions;
std::vector<TrustedSourcesSpec> trusted_sources;
std::vector<SourceIdentifierSpecWrapper> sources_identifier;
std::vector<SourceIdentifierSpecWrapper> sources_identifiers;
};
// LCOV_EXCL_STOP

View File

@ -25,7 +25,6 @@
#include "rest.h"
#include "k8s_policy_common.h"
USE_DEBUG_FLAG(D_K8S_POLICY);
// LCOV_EXCL_START Reason: no test exist
class AppsecExceptionSpec
{

View File

@ -25,7 +25,6 @@
#include "k8s_policy_common.h"
USE_DEBUG_FLAG(D_K8S_POLICY);
// LCOV_EXCL_START Reason: no test exist
class IngressMetadata
{

View File

@ -23,7 +23,7 @@
#include "debug.h"
#include "rest.h"
USE_DEBUG_FLAG(D_K8S_POLICY);
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
enum class PracticeType { WebApplication, WebAPI };
enum class TriggerType { Log, WebUserResponse };
@ -65,7 +65,7 @@ parseAppsecJSONKey(
} catch (const cereal::Exception &e) {
archive_in.setNextName(nullptr);
value = default_value;
dbgDebug(D_K8S_POLICY)
dbgDebug(D_LOCAL_POLICY)
<< "Could not parse the required key. Key: "
<< key_name
<< ", Error: "
@ -91,7 +91,7 @@ public:
cereal::JSONInputArchive in_ar(ss);
in_ar(cereal::make_nvp("spec", spec));
} catch (cereal::Exception &e) {
dbgError(D_K8S_POLICY) << "Failed to load spec JSON. Error: " << e.what();
dbgError(D_LOCAL_POLICY) << "Failed to load spec JSON. Error: " << e.what();
return false;
}
return true;

View File

@ -27,6 +27,8 @@
#include "debug.h"
#include "common.h"
#include "maybe_res.h"
#include "i_orchestration_tools.h"
#include "i_shell_cmd.h"
#include "appsec_practice_section.h"
#include "ingress_data.h"
#include "settings_section.h"
@ -93,8 +95,16 @@ private:
};
// LCOV_EXCL_STOP
class PolicyMakerUtils
:
Singleton::Consume<I_Environment>,
Singleton::Consume<I_OrchestrationTools>,
Singleton::Consume<I_ShellCmd>
{
public:
std::string getPolicyName(const std::string &policy_path);
Maybe<AppsecLinuxPolicy> openPolicyAsJson(const std::string &policy_path);
void clearElementsMaps();
bool startsWith(const std::string &str, const std::string &prefix);
@ -127,6 +137,8 @@ private:
std::map<std::string, InnerException> inner_exceptions;
std::map<std::string, WebAppSection> web_apps;
std::map<std::string, RulesConfigRulebase> rules_config;
std::map<std::string, UsersIdentifiersRulebase> users_identifiers;
std::map<std::string, AppSecTrustedSources> trusted_sources;
};
#endif // __POLICY_MAKER_UTILS_H__

View File

@ -25,7 +25,6 @@
#include "debug.h"
#include "k8s_policy_common.h"
USE_DEBUG_FLAG(D_K8S_POLICY);
// LCOV_EXCL_START Reason: no test exist
class AssetUrlParser
{
@ -110,6 +109,7 @@ public:
const std::string & getAssetId() const;
const std::string & getPracticeId() const;
const std::string & getPracticeName() const;
const std::string & getContext() const;
const std::vector<PracticeSection> & getPractice() const;
const std::vector<ParametersSection> & getParameters() const;
const std::vector<RulesTriggerSection> & getTriggers() const;
@ -123,13 +123,49 @@ private:
std::vector<RulesTriggerSection> triggers;
};
class RulesConfigWrapper
class UsersIdentifier
{
public:
class RulesConfig
UsersIdentifier() {}
UsersIdentifier(
const std::string &_source_identifier,
std::vector<std::string> _identifier_values);
void save(cereal::JSONOutputArchive &out_ar) const;
private:
std::string source_identifier;
std::vector<std::string> identifier_values;
};
class UsersIdentifiersRulebase
{
public:
RulesConfig(const std::vector<RulesConfigRulebase> &_rules_config);
UsersIdentifiersRulebase()
{}
UsersIdentifiersRulebase(
const std::string &_context,
const std::string &_source_identifier,
std::vector<std::string> _identifier_values,
std::vector<UsersIdentifier> _source_identifiers);
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;
@ -138,17 +174,23 @@ public:
static bool sortBySpecificAux(const std::string &first, const std::string &second);
std::vector<RulesConfigRulebase> rules_config;
std::vector<UsersIdentifiersRulebase> users_identifiers;
};
RulesConfigWrapper(const std::vector<RulesConfigRulebase> &_rules_config)
class RulesConfigWrapper
{
public:
RulesConfigWrapper(
const std::vector<RulesConfigRulebase> &_rules_config,
const std::vector<UsersIdentifiersRulebase> &_users_identifiers)
:
rules_config_rulebase(RulesConfig(_rules_config))
rules_config_rulebase(RulesRulebase(_rules_config, _users_identifiers))
{}
void save(cereal::JSONOutputArchive &out_ar) const;
private:
RulesConfig rules_config_rulebase;
RulesRulebase rules_config_rulebase;
};
// LCOV_EXCL_STOP
#endif // __RULES_CONFIG_SECTION_H__

View File

@ -23,7 +23,6 @@
#include "debug.h"
#include "k8s_policy_common.h"
USE_DEBUG_FLAG(D_K8S_POLICY);
// LCOV_EXCL_START Reason: no test exist
class AgentSettingsSection
{

View File

@ -22,7 +22,6 @@
#include "config.h"
#include "debug.h"
USE_DEBUG_FLAG(D_K8S_POLICY);
// LCOV_EXCL_START Reason: no test exist
class AgentSettingsSection
{

View File

@ -23,7 +23,6 @@
#include "debug.h"
#include "k8s_policy_common.h"
USE_DEBUG_FLAG(D_K8S_POLICY);
// LCOV_EXCL_START Reason: no test exist
class LogTriggerSection
{

View File

@ -24,7 +24,6 @@
#include "debug.h"
#include "k8s_policy_common.h"
USE_DEBUG_FLAG(D_K8S_POLICY);
// LCOV_EXCL_START Reason: no test exist
class TrustedSourcesSpec
{

View File

@ -12,15 +12,16 @@
// limitations under the License.
#include "ingress_data.h"
#include "customized_cereal_map.h"
using namespace std;
USE_DEBUG_FLAG(D_K8S_POLICY);
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
void
IngressMetadata::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "IngressMetadata load";
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);
@ -54,7 +55,7 @@ IngressMetadata::getAnnotations() const
void
IngressRulePath::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading ingress defined rule path";
dbgTrace(D_LOCAL_POLICY) << "Loading ingress defined rule path";
parseAppsecJSONKey<string>("path", path, archive_in);
}
@ -67,7 +68,7 @@ IngressRulePath::getPath() const
void
IngressRulePathsWrapper::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading ingress defined rule path wrapper";
dbgTrace(D_LOCAL_POLICY) << "Loading ingress defined rule path wrapper";
parseAppsecJSONKey<vector<IngressRulePath>>("paths", paths, archive_in);
}
@ -80,7 +81,7 @@ IngressRulePathsWrapper::getRulePaths() const
void
IngressDefinedRule::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading ingress defined rule";
dbgTrace(D_LOCAL_POLICY) << "Loading ingress defined rule";
parseAppsecJSONKey<string>("host", host, archive_in);
parseAppsecJSONKey<IngressRulePathsWrapper>("http", paths_wrapper, archive_in);
}
@ -100,7 +101,7 @@ IngressDefinedRule::getPathsWrapper() const
void
DefaultBackend::load(cereal::JSONInputArchive &)
{
dbgTrace(D_K8S_POLICY) << "Loading Default Backend";
dbgTrace(D_LOCAL_POLICY) << "Loading Default Backend";
is_exists = true;
}
@ -113,7 +114,7 @@ DefaultBackend::isExists() const
void
IngressSpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading single ingress spec";
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);
@ -139,7 +140,7 @@ IngressSpec::isDefaultBackendExists() const
void
SingleIngressData::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading single ingress data";
dbgTrace(D_LOCAL_POLICY) << "Loading single ingress data";
parseAppsecJSONKey<IngressMetadata>("metadata", metadata, archive_in);
parseAppsecJSONKey<IngressSpec>("spec", spec, archive_in);
}
@ -163,7 +164,7 @@ IngressData::loadJson(const string &json)
modified_json.pop_back();
stringstream in;
in.str(modified_json);
dbgTrace(D_K8S_POLICY) << "Loading ingress data";
dbgTrace(D_LOCAL_POLICY) << "Loading ingress data";
try {
cereal::JSONInputArchive in_ar(in);
in_ar(
@ -171,7 +172,7 @@ IngressData::loadJson(const string &json)
cereal::make_nvp("items", items)
);
} catch (cereal::Exception &e) {
dbgError(D_K8S_POLICY) << "Failed to load ingress data JSON. Error: " << e.what();
dbgError(D_LOCAL_POLICY) << "Failed to load ingress data JSON. Error: " << e.what();
return false;
}
return true;

View File

@ -48,7 +48,7 @@
using namespace std;
USE_DEBUG_FLAG(D_K8S_POLICY);
USE_DEBUG_FLAG(D_LOCAL_POLICY);
const static string local_appsec_policy_path = "/tmp/local_appsec.policy";
const static string open_appsec_io = "openappsec.io/";
@ -64,7 +64,7 @@ public:
void
load(cereal::JSONInputArchive &archive_in)
{
dbgInfo(D_K8S_POLICY) << "NamespaceMetadata load";
dbgInfo(D_LOCAL_POLICY) << "NamespaceMetadata load";
parseAppsecJSONKey<string>("name", name, archive_in);
parseAppsecJSONKey<string>("uid", uid, archive_in);
}
@ -98,7 +98,7 @@ public:
bool
loadJson(const string &json)
{
dbgTrace(D_K8S_POLICY) << "Loading namespace data";
dbgTrace(D_LOCAL_POLICY) << "Loading namespace data";
string modified_json = json;
modified_json.pop_back();
stringstream in;
@ -109,7 +109,7 @@ public:
cereal::make_nvp("items", items)
);
} catch (cereal::Exception &e) {
dbgError(D_K8S_POLICY) << "Failed to load namespace data JSON. Error: " << e.what();
dbgError(D_LOCAL_POLICY) << "Failed to load namespace data JSON. Error: " << e.what();
return false;
}
return true;
@ -137,12 +137,12 @@ public:
{
token = retrieveToken();
if (token.empty()) {
dbgInfo(D_K8S_POLICY) << "Initializing Linux Local-Policy generator";
dbgInfo(D_LOCAL_POLICY) << "Initializing Linux Local-Policy generator";
env_type = LocalPolicyEnv::LINUX;
return;
}
env_type = LocalPolicyEnv::K8S;
dbgInfo(D_K8S_POLICY) << "Initializing K8S policy generator";
dbgInfo(D_LOCAL_POLICY) << "Initializing K8S policy generator";
conn_flags.setFlag(MessageConnConfig::SECURE_CONN);
conn_flags.setFlag(MessageConnConfig::IGNORE_SSL_VALIDATION);
@ -169,14 +169,14 @@ public:
container_it
extractElement(container_it begin, container_it end, const string &element_name)
{
dbgTrace(D_K8S_POLICY) << "Tryting to find element: " << element_name;
dbgTrace(D_LOCAL_POLICY) << "Tryting to find element: " << element_name;
for (container_it it = begin; it < end; it++) {
if (element_name == it->getName()) {
dbgTrace(D_K8S_POLICY) << "Element with name " << element_name << "was found";
dbgTrace(D_LOCAL_POLICY) << "Element with name " << element_name << "was found";
return it;
}
}
dbgTrace(D_K8S_POLICY) << "Element with name " << element_name << "was not found";
dbgTrace(D_LOCAL_POLICY) << "Element with name " << element_name << "was not found";
return end;
}
@ -203,314 +203,38 @@ public:
string
parseLinuxPolicy(const string &policy_version)
{
dbgFlow(D_K8S_POLICY);
dbgFlow(D_LOCAL_POLICY);
string policy_path = getConfigurationFlagWithDefault(
getFilesystemPathConfig() + local_mgmt_policy_path,
"local_mgmt_policy"
);
auto maybe_policy_as_json = Singleton::Consume<I_ShellCmd>::by<LocalPolicyMgmtGenerator::Impl>()->
getExecOutput(getFilesystemPathConfig() + "/bin/yq " + policy_path + " -o json");
if (!maybe_policy_as_json.ok()) {
dbgWarning(D_K8S_POLICY) << "Could not convert policy from yaml to json";
return "";
}
auto i_orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<LocalPolicyMgmtGenerator::Impl>();
auto maybe_policy = i_orchestration_tools->jsonStringToObject<AppsecLinuxPolicy>(
maybe_policy_as_json.unpack()
);
Maybe<AppsecLinuxPolicy> maybe_policy = policy_maker_utils.openPolicyAsJson(policy_path);
if (!maybe_policy.ok()){
dbgWarning(D_K8S_POLICY) << "Policy was not loaded. Error: " << maybe_policy.getErr();
dbgWarning(D_LOCAL_POLICY) << maybe_policy.getErr();
return "";
}
AppsecLinuxPolicy policy = maybe_policy.unpack();
string policy_name = policy_maker_utils.getPolicyName(policy_path);
AppsecLinuxPolicy appsec_policy = maybe_policy.unpack();
ScopedContext ctx;
ctx.registerFunc<AppsecLinuxPolicy>("get_linux_local_policy", [&appsec_policy](){
return appsec_policy;
});
ParsedRule default_rule = policy.getAppsecPolicySpec().getDefaultRule();
list<ParsedRule> specific_rules = appsec_policy.getAppsecPolicySpec().getSpecificRules();
ParsedRule default_rule = appsec_policy.getAppsecPolicySpec().getDefaultRule();
// add default rule to policy
policy_maker_utils.createPolicyElementsByRule(default_rule, default_rule, policy, policy_name);
string asset;
string annotation_type;
string annotation_name;
string policy_annotation;
string syslog_address;
string syslog_port;
set<string> generated_apps;
set<WebAppSection> parsed_web_apps_set;
vector<RulesConfigRulebase> parsed_rules;
vector<LogTriggerSection> parsed_log_triggers;
set<InnerException> parsed_exeptions;
vector<WebUserResponseTriggerSection> parsed_web_user_res;
map<string, AppSecPracticeSpec> practice_map;
map<string, LogTriggerSection> log_triggers_map;
map<string, InnerException> exception_map;
map<string, WebUserResponseTriggerSection> web_user_res_map;
map<string, TrustedSourcesSpec> trusted_sources_map;
map<string, vector<SourceIdentifierSpec>> source_identifiers_map;
RulesConfigRulebase cleanup_rule;
string cleanup_rule_mode = "Inactive";
for (const ParsedRule &parsed_rule : specific_rules) {
string asset_name = parsed_rule.getHost();
dbgTrace(D_K8S_POLICY) << "Handling specific rule for asset: " << asset_name;
string practice_annotation_name;
// TBD: support multiple practices
if (parsed_rule.getPractices().size() > 0 && !parsed_rule.getPractices()[0].empty()) {
practice_annotation_name = parsed_rule.getPractices()[0];
} else if (default_rule.getPractices().size() > 0 && !default_rule.getPractices()[0].empty()) {
practice_annotation_name = default_rule.getPractices()[0];
}
string trigger_annotation_name;
// TBD: support multiple triggers
if (parsed_rule.getLogTriggers().size() > 0 && !parsed_rule.getLogTriggers()[0].empty()) {
trigger_annotation_name = parsed_rule.getLogTriggers()[0];
} else if (default_rule.getLogTriggers().size() > 0 && !default_rule.getLogTriggers()[0].empty()) {
trigger_annotation_name = default_rule.getLogTriggers()[0];
}
string exception_annotation_name;
// TBD: support multiple exceptions
if (parsed_rule.getExceptions().size() > 0 && !parsed_rule.getExceptions()[0].empty()) {
exception_annotation_name = parsed_rule.getExceptions()[0];
} else if (default_rule.getExceptions().size() > 0 && !default_rule.getExceptions()[0].empty()) {
exception_annotation_name = default_rule.getExceptions()[0];
}
string web_user_res_annotation_name =
parsed_rule.getCustomResponse().empty() ?
default_rule.getCustomResponse() :
parsed_rule.getCustomResponse();
string source_identifiers_annotation_name =
parsed_rule.getSourceIdentifiers().empty() ?
default_rule.getSourceIdentifiers() :
parsed_rule.getSourceIdentifiers();
string trusted_sources_annotation_name =
parsed_rule.getTrustedSources ().empty() ?
default_rule.getTrustedSources() :
parsed_rule.getTrustedSources();
auto pos = asset_name.find("/");
string url;
string uri;
if (pos != string::npos) {
url = asset_name.substr(0, asset_name.find("/"));
uri = asset_name.substr(asset_name.find("/"));
} else {
url = asset_name;
uri = "";
}
vector<pair<string, string>> web_user_res_vec;
extractExceptions(
exception_annotation_name,
exception_map,
parsed_exeptions,
appsec_policy.getAppsecExceptionSpecs());
if (!extractTriggers(
trigger_annotation_name,
log_triggers_map,
parsed_log_triggers,
syslog_address,
syslog_port)
) {
dbgWarning(D_K8S_POLICY)
<< "Failed extracting triggers. Trigger name: "
<< trigger_annotation_name;
return "";
}
if (!extractWebUserResponse(
web_user_res_annotation_name,
web_user_res_map,
web_user_res_vec,
parsed_web_user_res)
) {
dbgWarning(D_K8S_POLICY)
<< "Failed extracting custom response. Custom response name: "
<< web_user_res_annotation_name;
return "";
}
AppSecTrustedSources parsed_trusted_sources;
if (!extractTrustedSources(
asset_name,
trusted_sources_annotation_name,
source_identifiers_annotation_name,
trusted_sources_map,
source_identifiers_map,
parsed_trusted_sources)
) {
dbgWarning(D_K8S_POLICY)
<< "Failed extracting trused sources. Trusted source name: "
<< trusted_sources_annotation_name
<< ", Source identifiers annotation name: "
<< source_identifiers_annotation_name;
return "";
}
if (!practice_annotation_name.empty() && practice_map.count(practice_annotation_name) == 0) {
vector<AppSecPracticeSpec> appsec_practice = appsec_policy.getAppSecPracticeSpecs();
auto it = extractElement(appsec_practice.begin(), appsec_practice.end(), practice_annotation_name);
if (it == appsec_practice.end()) {
dbgWarning(D_K8S_POLICY) << "Unable to find practice. Practice name: " << practice_annotation_name;
return "";
}
practice_map.emplace(practice_annotation_name, *it);
dbgTrace(D_K8S_POLICY)
<< "Successfully retrieved AppSec practice "
<< practice_annotation_name;
}
string log_trigger_id;
LogTriggerSection log_trigger_annotation;
if (log_triggers_map.count(trigger_annotation_name) > 0) {
log_trigger_id = log_triggers_map.at(trigger_annotation_name).getTriggerId();
log_trigger_annotation = log_triggers_map.at(trigger_annotation_name);
}
string exception_id;
if (exception_map.count(exception_annotation_name) > 0) {
exception_id = exception_map.at(exception_annotation_name).getBehaviorId();
}
if (asset_name == "*") {
asset_name = "Any";
url = "Any";
uri = "Any";
}
RulesConfigRulebase rules_config = createMultiRulesSections(
url,
uri,
practice_annotation_name,
"WebApplication",
trigger_annotation_name,
log_trigger_id,
"log",
web_user_res_vec,
asset_name,
exception_annotation_name,
exception_id
vector<ParsedRule> specific_rules = policy.getAppsecPolicySpec().getSpecificRules();
policy_maker_utils.createPolicyElements(
specific_rules,
default_rule,
policy,
policy_name
);
string port = "80";
string full_url = asset_name == "Any" ? "" : url + uri + ":" + port;
string asset_id = rules_config.getAssetId();
string practice_id = rules_config.getPracticeId();
if (!generated_apps.count(full_url)) {
WebAppSection web_app = WebAppSection(
full_url,
asset_id,
asset_name,
asset_id,
asset_name,
practice_id,
practice_annotation_name,
practice_map.at(practice_annotation_name),
log_trigger_annotation,
default_rule.getMode(),
parsed_trusted_sources
PolicyWrapper policy_wrapper = policy_maker_utils.combineElementsToPolicy(policy_version);
return policy_maker_utils.dumpPolicyToFile(
policy_wrapper,
local_appsec_policy_path
);
parsed_web_apps_set.insert(web_app);
parsed_rules.push_back(rules_config);
generated_apps.insert(full_url);
}
} //end specific rules
string exception_name;
if (!default_rule.getExceptions().empty()) {
exception_name = default_rule.getExceptions()[0];
if (!extractExceptions(exception_name, exception_map, parsed_exeptions)) return "";
}
string trigger_name;
if (!default_rule.getLogTriggers().empty()) {
trigger_name = default_rule.getLogTriggers()[0];
if (!extractTriggers(
trigger_name,
log_triggers_map,
parsed_log_triggers,
syslog_address,
syslog_port)) return "";
}
vector<pair<string, string>> default_web_user_res_vec;
string web_user_res_annotation_name = default_rule.getCustomResponse();
if (!extractWebUserResponse(
web_user_res_annotation_name,
web_user_res_map,
default_web_user_res_vec,
parsed_web_user_res)
) return "";
AppSecTrustedSources default_parsed_trusted_sources;
string trusted_sources_annotation_name = default_rule.getTrustedSources();
string source_identifiers_annotation_name = default_rule.getSourceIdentifiers();
if (!extractTrustedSources(
"Any",
trusted_sources_annotation_name,
source_identifiers_annotation_name,
trusted_sources_map,
source_identifiers_map,
default_parsed_trusted_sources)
) {
dbgWarning(D_K8S_POLICY)
<< "Failed extracting trused sources. Trusted source name: "
<< trusted_sources_annotation_name
<< ", Source identifiers annotation name: "
<< source_identifiers_annotation_name;
return "";
}
string practice_name;
if (!default_rule.getPractices().empty()) {
practice_name = default_rule.getPractices()[0];
}
if (!practice_name.empty() && practice_map.count(practice_name) == 0) {
vector<AppSecPracticeSpec> appsec_practice = appsec_policy.getAppSecPracticeSpecs();
auto it = extractElement(appsec_practice.begin(), appsec_practice.end(), practice_name);
if(it == appsec_practice.end()) {
dbgWarning(D_K8S_POLICY) << "Failed to retrieve AppSec practice for the dafult practice";
return "";
}
practice_map.emplace(practice_name, *it);
dbgTrace(D_K8S_POLICY)
<< "Successfully retrieved AppSec practice"
<< practice_name;
}
vector<WebAppSection> parsed_web_apps(parsed_web_apps_set.begin(), parsed_web_apps_set.end());
TriggersWrapper triggers_section(TriggersRulebase(parsed_log_triggers, parsed_web_user_res));
AppSecWrapper waap_section = createMultipleAppSecSections(parsed_web_apps);
RulesConfigWrapper rules_config_section(parsed_rules);
ExceptionsWrapper exceptions_section = createExceptionSection(parsed_exeptions);
SecurityAppsWrapper security_app_section = SecurityAppsWrapper(
waap_section,
triggers_section,
rules_config_section,
exceptions_section,
policy_version
);
SettingsWrapper profiles_section = createProfilesSection();
PolicyWrapper policy_wrapper = PolicyWrapper(profiles_section, security_app_section);
return dumpPolicyToFile(policy_wrapper);
}
LocalPolicyEnv getEnvType() const { return env_type;}
@ -525,7 +249,7 @@ public:
if (!maybe_ingress.ok()) {
// TBD: Error handling : INXT-31444
dbgError(D_K8S_POLICY)
dbgError(D_LOCAL_POLICY)
<< "Failed to retrieve K8S Ingress configurations. Error: "
<< maybe_ingress.getErr();
return "";
@ -537,6 +261,7 @@ public:
set<WebAppSection> parsed_web_apps_set;
vector<WebAppSection> parsed_web_apps;
vector<RulesConfigRulebase> parsed_rules;
vector<UsersIdentifiersRulebase> users_identifiers;
vector<LogTriggerSection> parsed_log_triggers;
set<InnerException> parsed_exeptions;
vector<WebUserResponseTriggerSection> parsed_web_user_res;
@ -549,8 +274,8 @@ public:
RulesConfigRulebase cleanup_rule;
string cleanup_rule_mode = "Inactive";
dbgTrace(D_K8S_POLICY) << "Received Ingress apiVersion: " << ingress.getapiVersion();
dbgTrace(D_K8S_POLICY) << "Ingress items ammount: " << ingress.getItems().size();
dbgTrace(D_LOCAL_POLICY) << "Received Ingress apiVersion: " << ingress.getapiVersion();
dbgTrace(D_LOCAL_POLICY) << "Ingress items ammount: " << ingress.getItems().size();
// TBD: break to methods : INXT-31445
for (const SingleIngressData &item : ingress.getItems()) {
set<pair<string, string>> specific_assets_from_ingress;
@ -558,7 +283,7 @@ public:
string url = rule.getHost();
for (const IngressRulePath &uri : rule.getPathsWrapper().getRulePaths()) {
specific_assets_from_ingress.insert({url, uri.getPath()});
dbgTrace(D_K8S_POLICY)
dbgTrace(D_LOCAL_POLICY)
<< "Inserting Host data to the specific asset set:"
<< "URL: '"
<< url
@ -592,28 +317,30 @@ public:
}
}
if (policy_annotation.empty()) {
dbgInfo(D_K8S_POLICY) << "No policy was found in this ingress";
dbgInfo(D_LOCAL_POLICY) << "No policy was found in this ingress";
continue;
}
dbgTrace(D_K8S_POLICY) << "Trying to parse policy for " << policy_annotation;
dbgTrace(D_LOCAL_POLICY) << "Trying to parse policy for " << policy_annotation;
auto maybe_appsec_policy = getObjectFromCluster<AppsecSpecParser<AppsecPolicySpec>>(
"/apis/openappsec.io/v1beta1/policies/" + policy_annotation
);
if (!maybe_appsec_policy.ok()) {
dbgError(D_K8S_POLICY) << "Failed to retrieve AppSec policy. Error: " << maybe_appsec_policy.getErr();
dbgError(D_LOCAL_POLICY)
<< "Failed to retrieve AppSec policy. Error: "
<< maybe_appsec_policy.getErr();
return "";
}
AppsecSpecParser<AppsecPolicySpec> appsec_policy = maybe_appsec_policy.unpack();
list<ParsedRule> specific_rules = appsec_policy.getSpec().getSpecificRules();
vector<ParsedRule> specific_rules = appsec_policy.getSpec().getSpecificRules();
ParsedRule default_rule = appsec_policy.getSpec().getDefaultRule();
for (const ParsedRule &parsed_rule : specific_rules) {
string asset_name = parsed_rule.getHost();
dbgTrace(D_K8S_POLICY) << "Handling specific rule for asset: " << asset_name;
dbgTrace(D_LOCAL_POLICY) << "Handling specific rule for asset: " << asset_name;
string practice_annotation_name;
// TBD: support multiple practices
@ -671,7 +398,7 @@ public:
vector<pair<string, string>> web_user_res_vec;
if (!extractExceptions(exception_annotation_name, exception_map, parsed_exeptions)) {
dbgWarning(D_K8S_POLICY)
dbgWarning(D_LOCAL_POLICY)
<< "Failed extracting exceptions. Exception name: "
<< exception_annotation_name;
return "";
@ -684,7 +411,7 @@ public:
syslog_address,
syslog_port)
) {
dbgWarning(D_K8S_POLICY)
dbgWarning(D_LOCAL_POLICY)
<< "Failed extracting triggers. Trigger name: "
<< trigger_annotation_name;
return "";
@ -696,7 +423,7 @@ public:
web_user_res_vec,
parsed_web_user_res)
) {
dbgWarning(D_K8S_POLICY)
dbgWarning(D_LOCAL_POLICY)
<< "Failed extracting custom response. Custom response name: "
<< web_user_res_annotation_name;
return "";
@ -711,7 +438,7 @@ public:
source_identifiers_map,
parsed_trusted_sources)
) {
dbgWarning(D_K8S_POLICY)
dbgWarning(D_LOCAL_POLICY)
<< "Failed extracting trused sources. Trusted source name: "
<< trusted_sources_annotation_name
<< ", Source identifiers annotation name: "
@ -725,7 +452,7 @@ public:
);
if (!maybe_appsec_practice.ok()) {
dbgError(D_K8S_POLICY)
dbgError(D_LOCAL_POLICY)
<< "Failed to retrieve AppSec practice for asset "
<< asset_name
<< ". Error: "
@ -823,7 +550,7 @@ public:
source_identifiers_map,
default_parsed_trusted_sources)
) {
dbgWarning(D_K8S_POLICY)
dbgWarning(D_LOCAL_POLICY)
<< "Failed extracting trused sources. Trusted source name: "
<< trusted_sources_annotation_name
<< ", Source identifiers annotation name: "
@ -841,7 +568,7 @@ public:
);
if (!maybe_appsec_practice.ok()) {
dbgError(D_K8S_POLICY)
dbgError(D_LOCAL_POLICY)
<< "Failed to retrieve AppSec practice for the dafult practice. Error: "
<< maybe_appsec_practice.getErr();
return "";
@ -852,7 +579,7 @@ public:
}
if (item.getSpec().isDefaultBackendExists()) {
dbgTrace(D_K8S_POLICY) << "Default Backend exists in the ingress";
dbgTrace(D_LOCAL_POLICY) << "Default Backend exists in the ingress";
bool should_create_rule = false;
if (cleanup_rule_mode != "Prevent") {
if (default_rule.getMode().find("prevent") != string::npos) {
@ -867,7 +594,7 @@ public:
}
if (should_create_rule) {
dbgTrace(D_K8S_POLICY) << "Cleanup rule mode: " << cleanup_rule_mode;
dbgTrace(D_LOCAL_POLICY) << "Cleanup rule mode: " << cleanup_rule_mode;
specific_assets_from_ingress.insert({"Any", "Any"});
}
}
@ -930,7 +657,7 @@ public:
}
if (cleanup_rule_mode != "Inactive") {
dbgTrace(D_K8S_POLICY) << "Pushing a cleanup rule";
dbgTrace(D_LOCAL_POLICY) << "Pushing a cleanup rule";
parsed_rules.push_back(cleanup_rule);
}
@ -938,7 +665,7 @@ public:
parsed_web_apps.push_back(parsed_web_app);
}
dbgTrace(D_K8S_POLICY)
dbgTrace(D_LOCAL_POLICY)
<< "Policy creation summery:" << endl
<< "Web applications ammount: "
<< parsed_web_apps.size()
@ -951,7 +678,7 @@ public:
TriggersWrapper triggers_section(TriggersRulebase(parsed_log_triggers, parsed_web_user_res));
AppSecWrapper waap_section = createMultipleAppSecSections(parsed_web_apps);
RulesConfigWrapper rules_config_section(parsed_rules);
RulesConfigWrapper rules_config_section(parsed_rules, users_identifiers);
ExceptionsWrapper exceptions_section = createExceptionSection(parsed_exeptions);
SecurityAppsWrapper security_app_section = SecurityAppsWrapper(
@ -1021,7 +748,7 @@ public:
trigger_spec.getAppsecTriggerLogDestination().getSyslogServerUdpPort() :
514;
} catch (const exception &err) {
dbgWarning(D_K8S_POLICY)
dbgWarning(D_LOCAL_POLICY)
<< "Failed to convert port number from string. Port: "
<< syslog_port
<< ". Setting default value 514";
@ -1110,7 +837,7 @@ public:
try {
practice_id = to_string(boost::uuids::random_generator()());
} catch (const boost::uuids::entropy_error &e) {
dbgWarning(D_K8S_POLICY) << "Failed to generate Practice ID. Error: " << e.what();
dbgWarning(D_LOCAL_POLICY) << "Failed to generate Practice ID. Error: " << e.what();
//TBD: return Maybe as part of future error handling
}
}
@ -1179,11 +906,11 @@ private:
{
string playground_uid = isPlaygroundEnv() ? "playground-" : "";
dbgTrace(D_K8S_POLICY) << "Getting cluster UID";
dbgTrace(D_LOCAL_POLICY) << "Getting cluster UID";
auto maybe_namespaces_data = getObjectFromCluster<NamespaceData>("/api/v1/namespaces/");
if (!maybe_namespaces_data.ok()) {
dbgError(D_K8S_POLICY)
dbgError(D_LOCAL_POLICY)
<< "Failed to retrieve K8S namespace data. Error: "
<< maybe_namespaces_data.getErr();
return false;
@ -1195,7 +922,7 @@ private:
for (const SingleNamespaceData &ns : namespaces_data.getItems()) {
if (ns.getMetadata().getName() == "kube-system") {
uid = ns.getMetadata().getUID();
dbgTrace(D_K8S_POLICY) << "Found k8s cluster UID: " << uid;
dbgTrace(D_LOCAL_POLICY) << "Found k8s cluster UID: " << uid;
I_Environment *env = Singleton::Consume<I_Environment>::by<LocalPolicyMgmtGenerator::Impl>();
env->getConfigurationContext().registerValue<string>(
"k8sClusterId",
@ -1277,21 +1004,21 @@ private:
set<InnerException> &parsed_exeptions)
{
if (!exception_annotation_name.empty() && exception_map.count(exception_annotation_name) == 0) {
dbgTrace(D_K8S_POLICY) << "Trying to retrieve exceptions for " << exception_annotation_name;
dbgTrace(D_LOCAL_POLICY) << "Trying to retrieve exceptions for " << exception_annotation_name;
auto maybe_appsec_exception = getObjectFromCluster<AppsecSpecParser<vector<AppsecExceptionSpec>>>(
"/apis/openappsec.io/v1beta1/exceptions/" + exception_annotation_name
);
if (!maybe_appsec_exception.ok()) {
dbgError(D_K8S_POLICY)
dbgError(D_LOCAL_POLICY)
<< "Failed to retrieve AppSec exception. Error: "
<< maybe_appsec_exception.getErr();
return false;
}
AppsecSpecParser<vector<AppsecExceptionSpec>> appsec_exception = maybe_appsec_exception.unpack();
dbgTrace(D_K8S_POLICY)
dbgTrace(D_LOCAL_POLICY)
<< "Successfuly retrieved AppSec exceptions for "
<< exception_annotation_name;
@ -1311,7 +1038,7 @@ private:
if (!maybe_appsec_trigger.ok()) {
error_message = "Failed to retrieve AppSec triggers. Error: " + maybe_appsec_trigger.getErr();
dbgError(D_K8S_POLICY) << error_message;
dbgError(D_LOCAL_POLICY) << error_message;
return genError(error_message);
}
@ -1322,7 +1049,7 @@ private:
get<AppsecLinuxPolicy>("get_linux_local_policy");
if (!maybe_appsec_policy.ok()) {
error_message = "Failed to retrieve AppSec triggers";
dbgDebug(D_K8S_POLICY) << error_message;
dbgDebug(D_LOCAL_POLICY) << error_message;
return genError(error_message);
}
@ -1330,7 +1057,7 @@ private:
auto trigger_it = extractElement(triggers_vec.begin(), triggers_vec.end(), trigger_annotation_name);
if (trigger_it == triggers_vec.end()) {
error_message = "Failed to retrieve AppSec triggers";
dbgDebug(D_K8S_POLICY) << error_message;
dbgDebug(D_LOCAL_POLICY) << error_message;
return genError(error_message);
}
@ -1347,10 +1074,10 @@ private:
{
if (trigger_annotation_name.empty() && !syslog_address.empty()) {
if (!IPAddr::isValidIPAddr(syslog_address)) {
dbgWarning(D_K8S_POLICY) << "Syslog address is invalid. Address: " << syslog_address;
dbgWarning(D_LOCAL_POLICY) << "Syslog address is invalid. Address: " << syslog_address;
return false;
}
dbgTrace(D_K8S_POLICY)
dbgTrace(D_LOCAL_POLICY)
<< "Creating default syslog log section with syslog service address: "
<< syslog_address
<< ", Port: "
@ -1361,12 +1088,12 @@ private:
log_triggers_map.emplace(trigger_annotation_name, log_triggers_section);
parsed_log_triggers.push_back(log_triggers_section);
} else if (!trigger_annotation_name.empty() && log_triggers_map.count(trigger_annotation_name) == 0) {
dbgTrace(D_K8S_POLICY) << "Trying to retrieve triggers for " << trigger_annotation_name;
dbgTrace(D_LOCAL_POLICY) << "Trying to retrieve triggers for " << trigger_annotation_name;
Maybe<AppsecTriggerSpec> maybe_appsec_trigger_spec = getAppsecTriggerSpec(trigger_annotation_name);
if (!maybe_appsec_trigger_spec.ok()) {
dbgWarning(D_K8S_POLICY) << "Error: " << maybe_appsec_trigger_spec.getErr();
dbgWarning(D_LOCAL_POLICY) << "Error: " << maybe_appsec_trigger_spec.getErr();
return false;
}
@ -1390,7 +1117,7 @@ private:
if (!maybe_trusted_sources_from_ingress.ok()) {
error_message = "Failed to retrieve trusted sources. Error: " +
maybe_trusted_sources_from_ingress.getErr();
dbgError(D_K8S_POLICY) << error_message;
dbgError(D_LOCAL_POLICY) << error_message;
return genError(error_message);
}
@ -1402,7 +1129,7 @@ private:
if (!maybe_appsec_policy.ok()) {
error_message = "Failed to retrieve AppSec triggers";
dbgDebug(D_K8S_POLICY) << error_message;
dbgDebug(D_LOCAL_POLICY) << error_message;
return genError(error_message);
}
@ -1414,7 +1141,7 @@ private:
if (trusted_sources_it == trusted_sources_vec.end()) {
error_message = "Failed to retrieve AppSec triggers";
dbgDebug(D_K8S_POLICY) << error_message;
dbgDebug(D_LOCAL_POLICY) << error_message;
return genError(error_message);
}
@ -1432,7 +1159,7 @@ private:
if (!maybe_source_identifier.ok()) {
error_message = "Failed to retrieve trusted sources. Error: " + maybe_source_identifier.getErr();
dbgError(D_K8S_POLICY) << error_message;
dbgError(D_LOCAL_POLICY) << error_message;
return genError(error_message);
}
@ -1444,7 +1171,7 @@ private:
if (!maybe_appsec_policy.ok()) {
error_message = "Failed to retrieve AppSec triggers";
dbgDebug(D_K8S_POLICY) << error_message;
dbgDebug(D_LOCAL_POLICY) << error_message;
return genError(error_message);
}
@ -1457,7 +1184,7 @@ private:
if (source_identifier_it == source_identifiers_vec.end()) {
error_message = "Failed to retrieve AppSec triggers";
dbgDebug(D_K8S_POLICY) << error_message;
dbgDebug(D_LOCAL_POLICY) << error_message;
return genError(error_message);
}
@ -1475,7 +1202,7 @@ private:
{
if (trusted_sources_name.empty() && source_identifiers_name.empty()) return true;
if (trusted_sources_name.empty() ^ source_identifiers_name.empty()) {
dbgInfo(D_K8S_POLICY)
dbgInfo(D_LOCAL_POLICY)
<< "Trusted Sources or Source Identifier were not provided. Truster Sources: "
<< trusted_sources_name
<< ", Source Identidier: "
@ -1485,11 +1212,11 @@ private:
// Parsing trusted sources from the k8s API
if (!trusted_sources_map.count(trusted_sources_name)) {
dbgTrace(D_K8S_POLICY) << "Trying to retrieve trusted sources for: " << trusted_sources_name;
dbgTrace(D_LOCAL_POLICY) << "Trying to retrieve trusted sources for: " << trusted_sources_name;
auto trusted_sources_from_ingress_spec = getAppsecTrustedSourceSpecs(trusted_sources_name);
if (!trusted_sources_from_ingress_spec.ok()) {
dbgWarning(D_K8S_POLICY) << trusted_sources_from_ingress_spec.getErr();
dbgWarning(D_LOCAL_POLICY) << trusted_sources_from_ingress_spec.getErr();
return false;
}
@ -1498,12 +1225,12 @@ private:
// Parsing source identifiers from the k8s API
if (!source_identifiers_map.count(source_identifiers_name)) {
dbgTrace(D_K8S_POLICY) << "Trying to retrieve sources identifiers for: " << source_identifiers_name;
dbgTrace(D_LOCAL_POLICY) << "Trying to retrieve sources identifiers for: " << source_identifiers_name;
auto source_identifier_from_ingress_spec = getAppsecSourceIdentifierSpecs(source_identifiers_name);
if (!source_identifier_from_ingress_spec.ok()) {
dbgWarning(D_K8S_POLICY) << "Error: " << source_identifier_from_ingress_spec.getErr();
dbgWarning(D_LOCAL_POLICY) << "Error: " << source_identifier_from_ingress_spec.getErr();
return false;
}
@ -1546,7 +1273,7 @@ private:
if (!maybe_appsec_web_user_res.ok()) {
error_message = "Failed to retrieve appsec web user res. Error: " +
maybe_appsec_web_user_res.getErr();
dbgError(D_K8S_POLICY) << error_message;
dbgError(D_LOCAL_POLICY) << error_message;
return genError(error_message);
}
return maybe_appsec_web_user_res.unpack().getSpec();
@ -1557,7 +1284,7 @@ private:
if (!maybe_appsec_policy.ok()) {
error_message = "Failed to retrieve appsec web user response.";
dbgDebug(D_K8S_POLICY) << error_message;
dbgDebug(D_LOCAL_POLICY) << error_message;
return genError(error_message);
}
@ -1569,7 +1296,7 @@ private:
if (web_user_res_it == web_user_res_vec.end()) {
error_message = "Failed to retrieve appsec web user response.";
dbgDebug(D_K8S_POLICY) << error_message;
dbgDebug(D_LOCAL_POLICY) << error_message;
return genError(error_message);
}
@ -1585,11 +1312,11 @@ private:
vector<WebUserResponseTriggerSection> &parsed_web_user_res)
{
if (!web_user_res_annotation_name.empty()) {
dbgTrace(D_K8S_POLICY) << "Trying to retrieve web user response for: " << web_user_res_annotation_name;
dbgTrace(D_LOCAL_POLICY) << "Trying to retrieve web user response for: " << web_user_res_annotation_name;
auto maybe_appsec_web_user_res_spec = getAppSecCustomResponseSpecs(web_user_res_annotation_name);
if (!maybe_appsec_web_user_res_spec.ok()) {
dbgWarning(D_K8S_POLICY) << maybe_appsec_web_user_res_spec.getErr();
dbgWarning(D_LOCAL_POLICY) << maybe_appsec_web_user_res_spec.getErr();
return false;
}
@ -1619,8 +1346,10 @@ private:
}
return true;
}
};
private:
PolicyMakerUtils policy_maker_utils;
};
LocalPolicyMgmtGenerator::LocalPolicyMgmtGenerator()
:

View File

@ -37,6 +37,42 @@ PolicyWrapper::save(cereal::JSONOutputArchive &out_ar) const
security_apps.save(out_ar);
}
string
PolicyMakerUtils::getPolicyName(const string &policy_path)
{
if (policy_path.find_last_of("/") != string::npos) {
string policy_name = policy_path.substr(policy_path.find_last_of("/") + 1);
if (policy_name.find(".") != string::npos) return policy_name.substr(0, policy_name.find("."));
return policy_name;
}
return policy_path;
}
Maybe<AppsecLinuxPolicy>
PolicyMakerUtils::openPolicyAsJson(const string &policy_path)
{
auto maybe_policy_as_json = Singleton::Consume<I_ShellCmd>::by<PolicyMakerUtils>()->getExecOutput(
getFilesystemPathConfig() + "/bin/yq " + policy_path + " -o json"
);
if (!maybe_policy_as_json.ok()) {
dbgDebug(D_NGINX_POLICY) << "Could not convert policy from yaml to json";
return genError("Could not convert policy from yaml to json. Error: " + maybe_policy_as_json.getErr());
}
auto i_orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<PolicyMakerUtils>();
auto maybe_policy = i_orchestration_tools->jsonStringToObject<AppsecLinuxPolicy>(
maybe_policy_as_json.unpack()
);
if (!maybe_policy.ok()) {
string error = "Policy in path: " + policy_path + " was not loaded. Error: " + maybe_policy.getErr();
dbgDebug(D_NGINX_POLICY) << error;
return genError(error);
}
return maybe_policy.unpack();
}
void
PolicyMakerUtils::clearElementsMaps()
{
@ -388,6 +424,59 @@ createWebUserResponseTriggerSection(
return web_user_res;
}
vector<SourcesIdentifiers>
addSourceIdentifiersToTrustedSource(
const string &source_identifeir_from_trust,
const SourceIdentifierSpec &src_ident
)
{
vector<SourcesIdentifiers> generated_trusted_json;
if (src_ident.getValues().empty()) {
generated_trusted_json.push_back(
SourcesIdentifiers(src_ident.getSourceIdentifier(), source_identifeir_from_trust)
);
} else {
for (const string &val : src_ident.getValues()) {
string src_key = src_ident.getSourceIdentifier() + ":" + val;
generated_trusted_json.push_back(SourcesIdentifiers(src_key, source_identifeir_from_trust));
}
}
return generated_trusted_json;
}
AppSecTrustedSources
createTrustedSourcesSection(
const string &treusted_sources_annotation_name,
const string &source_identifier_annotation_name,
const AppsecLinuxPolicy &policy)
{
TrustedSourcesSpec treusted_sources_spec = getAppsecTrustedSourceSpecs(treusted_sources_annotation_name, policy);
SourceIdentifierSpecWrapper source_identifiers_spec = getAppsecSourceIdentifierSpecs(
source_identifier_annotation_name,
policy
);
vector<SourcesIdentifiers> generated_trusted_json;
for (const SourceIdentifierSpec &src_ident : source_identifiers_spec.getIdentifiers()) {
for (const string &source_identifeir_from_trust : treusted_sources_spec.getSourcesIdentifiers()) {
vector<SourcesIdentifiers> tmp_trusted = addSourceIdentifiersToTrustedSource(
source_identifeir_from_trust,
src_ident
);
generated_trusted_json.insert(generated_trusted_json.end(), tmp_trusted.begin(), tmp_trusted.end());
}
}
AppSecTrustedSources treusted_sources(
treusted_sources_spec.getName(),
treusted_sources_spec.getMinNumOfSources(),
generated_trusted_json
);
return treusted_sources;
}
InnerException
createExceptionSection(
const string &exception_annotation_name,
@ -404,6 +493,44 @@ createExceptionSection(
return inner_exception;
}
UsersIdentifiersRulebase
createUserIdentifiers (
const string &source_identifier_annotation_name,
const AppsecLinuxPolicy &policy,
const string &context
)
{
string jwt_identifier = "";
vector<string> jwt_identifier_values;
vector<UsersIdentifier> user_ident_vec;
SourceIdentifierSpecWrapper source_identifiers_spec = getAppsecSourceIdentifierSpecs(
source_identifier_annotation_name,
policy
);
for (const SourceIdentifierSpec &src_ident : source_identifiers_spec.getIdentifiers()) {
if (src_ident.getSourceIdentifier() == "JWTKey") {
jwt_identifier = "JWTKey";
jwt_identifier_values.insert(
jwt_identifier_values.end(),
src_ident.getValues().begin(),
src_ident.getValues().end()
);
user_ident_vec.push_back(UsersIdentifier("authorization", src_ident.getValues()));
} else {
user_ident_vec.push_back(UsersIdentifier(src_ident.getSourceIdentifier(), src_ident.getValues()));
}
}
UsersIdentifiersRulebase users_ident = UsersIdentifiersRulebase(
context,
jwt_identifier,
jwt_identifier_values,
user_ident_vec
);
return users_ident;
}
RulesConfigRulebase
createMultiRulesSections(
const string &url,
@ -444,6 +571,7 @@ createMultiRulesSections(
{exception_param},
triggers
);
return rules_config;
}
@ -471,7 +599,7 @@ PolicyMakerUtils::combineElementsToPolicy(const string &policy_version)
});
AppSecWrapper appses_section(AppSecRulebase(convertMapToVector(web_apps), {}));
RulesConfigWrapper rules_config_section(convertMapToVector(rules_config));
RulesConfigWrapper rules_config_section(convertMapToVector(rules_config), convertMapToVector(users_identifiers));
SecurityAppsWrapper security_app_section = SecurityAppsWrapper(
appses_section,
triggers_section,
@ -527,6 +655,19 @@ PolicyMakerUtils::createPolicyElementsByRule(
);
}
if (
!rule_annotations[AnnotationTypes::TRUSTED_SOURCES].empty() &&
!rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS].empty() &&
!trusted_sources.count(rule_annotations[AnnotationTypes::TRUSTED_SOURCES])
) {
trusted_sources[rule_annotations[AnnotationTypes::TRUSTED_SOURCES]] =
createTrustedSourcesSection(
rule_annotations[AnnotationTypes::TRUSTED_SOURCES],
rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS],
policy
);
}
if (
!rule_annotations[AnnotationTypes::PRACTICE].empty() &&
!web_apps.count(rule_annotations[AnnotationTypes::PRACTICE])
@ -561,6 +702,15 @@ PolicyMakerUtils::createPolicyElementsByRule(
);
rules_config[rule_config.getAssetName()] = rule_config;
if (!rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS].empty()) {
UsersIdentifiersRulebase user_identifiers = createUserIdentifiers(
rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS],
policy,
rule_config.getContext()
);
users_identifiers[rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS]] = user_identifiers;
}
WebAppSection web_app = WebAppSection(
full_url == "Any" ? "" : full_url,
rule_config.getAssetId(),
@ -572,7 +722,7 @@ PolicyMakerUtils::createPolicyElementsByRule(
getAppsecPracticeSpec(rule_annotations[AnnotationTypes::PRACTICE], policy),
log_triggers[rule_annotations[AnnotationTypes::TRIGGER]],
rule.getMode(),
AppSecTrustedSources()
trusted_sources[rule_annotations[AnnotationTypes::TRUSTED_SOURCES]]
);
web_apps[rule_annotations[AnnotationTypes::PRACTICE]] = web_app;
}
@ -589,4 +739,5 @@ PolicyMakerUtils::createPolicyElements(
createPolicyElementsByRule(rule, default_rule, policy, policy_name);
}
}
// LCOV_EXCL_STOP

View File

@ -15,7 +15,7 @@
using namespace std;
USE_DEBUG_FLAG(D_K8S_POLICY);
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
AssetUrlParser
@ -80,7 +80,7 @@ PracticeSection::PracticeSection(
{
auto maybe_type = string_to_practice_type.find(_type);
if (maybe_type == string_to_practice_type.end()) {
dbgError(D_K8S_POLICY) << "Illegal pracrtice type: " << _type;
dbgError(D_LOCAL_POLICY) << "Illegal pracrtice type: " << _type;
return;
}
@ -119,7 +119,7 @@ ParametersSection::ParametersSection(
id(_id)
{
if (_id.empty() && _name.empty()) {
dbgError(D_K8S_POLICY) << "Illegal Parameter values. Name and ID are empty";
dbgError(D_LOCAL_POLICY) << "Illegal Parameter values. Name and ID are empty";
return;
}
}
@ -149,12 +149,12 @@ RulesTriggerSection::RulesTriggerSection(
id(_id)
{
if (_name.empty() && _id.empty()) {
dbgError(D_K8S_POLICY) << "Illegal values for trigger. Name and ID are 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_K8S_POLICY) << "Illegal trigger type in rule: " << _type;
dbgError(D_LOCAL_POLICY) << "Illegal trigger type in rule: " << _type;
return;
}
type = _type;
@ -232,7 +232,7 @@ RulesConfigRulebase::RulesConfigRulebase(
")";
}
} catch (const boost::uuids::entropy_error &e) {
dbgWarning(D_K8S_POLICY) << "Failed to generate rule UUID. Error: " << e.what();
dbgWarning(D_LOCAL_POLICY) << "Failed to generate rule UUID. Error: " << e.what();
}
}
@ -262,6 +262,12 @@ RulesConfigRulebase::getRuleId() const
return id;
}
const string &
RulesConfigRulebase::getContext() const
{
return context;
}
const string &
RulesConfigRulebase::getAssetName() const
{
@ -310,23 +316,65 @@ RulesConfigRulebase::getTriggers() const
return triggers;
}
RulesConfigWrapper::RulesConfig::RulesConfig(const vector<RulesConfigRulebase> &_rules_config)
UsersIdentifier::UsersIdentifier(const string &_source_identifier, vector<string> _identifier_values)
:
rules_config(_rules_config)
source_identifier(_source_identifier),
identifier_values(_identifier_values)
{}
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,
vector<string> _identifier_values,
vector<UsersIdentifier> _source_identifiers)
:
context(_context),
source_identifier(_source_identifier),
identifier_values(_identifier_values),
source_identifiers(_source_identifiers)
{}
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
RulesConfigWrapper::RulesConfig::save(cereal::JSONOutputArchive &out_ar) const
RulesRulebase::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("rulesConfig", rules_config)
cereal::make_nvp("rulesConfig", rules_config),
cereal::make_nvp("usersIdentifiers", users_identifiers)
);
}
bool
RulesConfigWrapper::RulesConfig::sortBySpecific(
RulesRulebase::sortBySpecific(
const RulesConfigRulebase &first,
const RulesConfigRulebase &second
)
@ -335,7 +383,7 @@ RulesConfigWrapper::RulesConfig::sortBySpecific(
}
bool
RulesConfigWrapper::RulesConfig::sortBySpecificAux(const string &first, const string &second)
RulesRulebase::sortBySpecificAux(const string &first, const string &second)
{
if (first.empty()) return false;
if (second.empty()) return true;

View File

@ -15,7 +15,7 @@
using namespace std;
USE_DEBUG_FLAG(D_K8S_POLICY);
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
AgentSettingsSection::AgentSettingsSection(
@ -28,7 +28,7 @@ AgentSettingsSection::AgentSettingsSection(
try {
id = to_string(boost::uuids::random_generator()());
} catch (const boost::uuids::entropy_error &e) {
dbgWarning(D_K8S_POLICY) << "Failed to generate agent setting UUID. Error: " << e.what();
dbgWarning(D_LOCAL_POLICY) << "Failed to generate agent setting UUID. Error: " << e.what();
}
}
@ -68,7 +68,7 @@ SettingsWrapper::SettingsWrapper(SettingsRulebase _agent) : agent(_agent)
try {
id = to_string(boost::uuids::random_generator()());
} catch (const boost::uuids::entropy_error &e) {
dbgWarning(D_K8S_POLICY) << "Failed to generate Settings Wrapper UUID. Error: " << e.what();
dbgWarning(D_LOCAL_POLICY) << "Failed to generate Settings Wrapper UUID. Error: " << e.what();
}
}

View File

@ -15,7 +15,7 @@
using namespace std;
USE_DEBUG_FLAG(D_K8S_POLICY);
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
AgentSettingsSection::AgentSettingsSection(string _key, string _value) : key(_key), value(_value)
@ -23,7 +23,7 @@ AgentSettingsSection::AgentSettingsSection(string _key, string _value) : key(_ke
try {
id = to_string(boost::uuids::random_generator()());
} catch (const boost::uuids::entropy_error &e) {
dbgWarning(D_K8S_POLICY) << "Failed to generate agent setting UUID. Error: " << e.what();
dbgWarning(D_LOCAL_POLICY) << "Failed to generate agent setting UUID. Error: " << e.what();
}
}

View File

@ -15,7 +15,7 @@
using namespace std;
USE_DEBUG_FLAG(D_K8S_POLICY);
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
LogTriggerSection::LogTriggerSection(
@ -67,7 +67,7 @@ LogTriggerSection::LogTriggerSection(
id = to_string(boost::uuids::random_generator()());
context = "triggerId(" + id + ")";
} catch (const boost::uuids::entropy_error &e) {
dbgWarning(D_K8S_POLICY) << "Failed to generate log trigger UUID. Error: " << e.what();
dbgWarning(D_LOCAL_POLICY) << "Failed to generate log trigger UUID. Error: " << e.what();
}
}
@ -143,7 +143,7 @@ WebUserResponseTriggerSection::WebUserResponseTriggerSection(
id = to_string(boost::uuids::random_generator()());
context = "triggerId(" + id + ")";
} catch (const boost::uuids::entropy_error &e) {
dbgWarning(D_K8S_POLICY) << "Failed to generate webUserResponse trigger UUID. Error: " << e.what();
dbgWarning(D_LOCAL_POLICY) << "Failed to generate webUserResponse trigger UUID. Error: " << e.what();
}
}
@ -181,7 +181,7 @@ WebUserResponseTriggerSection::operator<(const WebUserResponseTriggerSection &ot
void
AppSecCustomResponseSpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec web user response spec";
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");
parseAppsecJSONKey<string>("name", name, archive_in);
@ -243,7 +243,7 @@ TriggersRulebase::save(cereal::JSONOutputArchive &out_ar) const
void
AppsecTriggerAccessControlLogging::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec Trigger - Access Control Logging";
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);
}
@ -263,7 +263,7 @@ AppsecTriggerAccessControlLogging::isDropEvents() const
void
AppsecTriggerAdditionalSuspiciousEventsLogging::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec Trigger - Additional Suspicious Events Logging";
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");
@ -290,7 +290,7 @@ AppsecTriggerAdditionalSuspiciousEventsLogging::getMinimumSeverity() const
void
AppsecTriggerLogging::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec Trigger Logging";
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);
@ -317,7 +317,7 @@ AppsecTriggerLogging::isPreventEvents() const
void
AppsecTriggerExtendedLogging::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec Trigger Extended Logging";
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);
@ -390,7 +390,7 @@ StdoutLogging::getFormat() const
void
AppsecTriggerLogDestination::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec Trigger LogDestination";
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger LogDestination";
// TBD: support "file"
parseAppsecJSONKey<bool>("cloud", cloud, archive_in, false);
@ -471,7 +471,7 @@ AppsecTriggerLogDestination::getCefServiceData() const
void
AppsecTriggerSpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading AppSec trigger spec";
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec trigger spec";
parseAppsecJSONKey<AppsecTriggerAccessControlLogging>(
"access-control-logging",
access_control_logging,

View File

@ -15,13 +15,13 @@
using namespace std;
USE_DEBUG_FLAG(D_K8S_POLICY);
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
void
TrustedSourcesSpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading trusted sources spec";
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);
@ -63,7 +63,7 @@ SourcesIdentifiers::getSourceIdent() const
void
SourceIdentifierSpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading trusted sources spec";
dbgTrace(D_LOCAL_POLICY) << "Loading trusted sources spec";
parseAppsecJSONKey<string>("sourceIdentifier", source_identifier, archive_in);
parseAppsecJSONKey<vector<string>>("value", value, archive_in);
}
@ -83,7 +83,7 @@ SourceIdentifierSpec::getValues() const
void
SourceIdentifierSpecWrapper::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_K8S_POLICY) << "Loading Source Identifier Spec Wrapper";
dbgTrace(D_LOCAL_POLICY) << "Loading Source Identifier Spec Wrapper";
parseAppsecJSONKey<vector<SourceIdentifierSpec>>("identifiers", identifiers, archive_in);
parseAppsecJSONKey<string>("name", name, archive_in);
}
@ -112,7 +112,7 @@ AppSecTrustedSources::AppSecTrustedSources(
try {
id = to_string(boost::uuids::random_generator()());
} catch (const boost::uuids::entropy_error &e) {
dbgWarning(D_K8S_POLICY) << "Failed to generate Trusted Sources ID. Error: " << e.what();
dbgWarning(D_LOCAL_POLICY) << "Failed to generate Trusted Sources ID. Error: " << e.what();
}
}

View File

@ -1351,10 +1351,9 @@ private:
dbgInfo(D_ORCHESTRATOR) << "Sending registration data";
Singleton::Consume<I_MainLoop>::by<OrchestrationComp>()->addOneTimeRoutine(
I_MainLoop::RoutineType::Offline,
// LCOV_EXCL_START Reason: to be refactored
[email] ()
{
chrono::microseconds curr_time = Singleton::Consume<I_TimeGet>::by<OrchestrationComp>()->getWalltime();
Report registration_report(
"Local Agent Data",
Singleton::Consume<I_TimeGet>::by<OrchestrationComp>()->getWalltime(),
@ -1382,6 +1381,7 @@ private:
MessageTypeTag::REPORT
);
},
// LCOV_EXCL_STOP
"Send registration data"
);
}

View File

@ -285,6 +285,7 @@ public:
const string &service_id
) override;
void refreshPendingServices() override;
const string & getPolicyVersion() const override;
const string & getUpdatePolicyVersion() const override;
void updateReconfStatus(int id, ReconfStatus status) override;
@ -297,7 +298,6 @@ public:
private:
void cleanUpVirtualFiles();
void refreshPendingServices();
bool sendSignalForServices(const set<string> &nano_services_to_update, const string &policy_version);

View File

@ -25,6 +25,7 @@
#include "i_encryptor.h"
#include "fog_authenticator.h"
#include "fog_communication.h"
#include "service_controller.h"
#include "local_communication.h"
#include "hybrid_communication.h"
@ -40,6 +41,7 @@ public:
void
doCall() override
{
Singleton::Consume<I_ServiceController>::by<UpdateCommunication>()->refreshPendingServices();
Singleton::Consume<I_MainLoop>::by<UpdateCommunication>()->stopAll();
status = "Operation mode had changed successfully";
}

View File

@ -27,6 +27,35 @@ USE_DEBUG_FLAG(D_WAAP);
using namespace std;
const static string default_host = "open-appsec-tuning-svc";
void
WaapTelemetryBase::sendLog(const LogRest &metric_client_rest) const
{
OrchestrationMode mode = Singleton::Consume<I_AgentDetails>::by<GenericMetric>()->getOrchestrationMode();
if (mode == OrchestrationMode::ONLINE) {
GenericMetric::sendLog(metric_client_rest);
return;
}
auto svc_host = getConfigurationWithDefault(default_host, "Logging", "K8sSvc Log host");
Flags<MessageConnConfig> conn_flags;
conn_flags.setFlag(MessageConnConfig::EXTERNAL);
string fog_metric_uri = getConfigurationWithDefault<string>("/api/v1/agents/events", "metric", "fogMetricUri");
std::string tenant_header = "X-Tenant-Id: " +
Singleton::Consume<I_AgentDetails>::by<GenericMetric>()->getTenantId();
Singleton::Consume<I_Messaging>::by<GenericMetric>()->sendNoReplyObject(
metric_client_rest,
I_Messaging::Method::POST,
svc_host,
80,
conn_flags,
fog_metric_uri,
tenant_header,
nullptr,
MessageTypeTag::METRIC);
}
void
WaapTelemetrics::initMetrics()
{
@ -172,7 +201,7 @@ WaapMetricWrapper::upon(const WaapTelemetryEvent &event)
"WAAP telemetry",
ReportIS::AudienceTeam::WAAP,
ReportIS::IssuingEngine::AGENT_CORE,
chrono::minutes(10),
chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
true,
ReportIS::Audience::SECURITY
);
@ -204,7 +233,7 @@ WaapMetricWrapper::upon(const WaapTelemetryEvent &event)
"WAAP attack type telemetry",
ReportIS::AudienceTeam::WAAP,
ReportIS::IssuingEngine::AGENT_CORE,
chrono::minutes(10),
chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
true,
ReportIS::Audience::SECURITY
);
@ -255,7 +284,7 @@ WaapMetricWrapper::upon(const WaapTelemetryEvent &event)
"Waap Metrics",
ReportIS::AudienceTeam::WAAP,
ReportIS::IssuingEngine::AGENT_CORE,
chrono::minutes(10),
chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
true,
ReportIS::Audience::INTERNAL
);
@ -267,7 +296,7 @@ WaapMetricWrapper::upon(const WaapTelemetryEvent &event)
"WAAP Attack Type Metrics",
ReportIS::AudienceTeam::WAAP,
ReportIS::IssuingEngine::AGENT_CORE,
chrono::minutes(10),
chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
true,
ReportIS::Audience::INTERNAL
);

View File

@ -260,7 +260,6 @@ void TrustedSourcesConfidenceCalculator::log(Key key, Val value, Source source)
<< " from the source: "
<< source;
m_logger[key][value].insert(source);
saveData();
}
void TrustedSourcesConfidenceCalculator::reset()

View File

@ -16,11 +16,17 @@
#include "i_serialize.h"
#include "waap.h"
static const std::string BASE_URI = "/storage/waap/";
using namespace std;
static const string defaultSharedStorageHost = "appsec-shared-storage-svc";
#define SHARED_STORAGE_HOST_ENV_NAME "SHARED_STORAGE_HOST"
USE_DEBUG_FLAG(D_WAAP);
TuningDecision::TuningDecision(const std::string& remotePath) :
m_remotePath(remotePath + "/tuning")
TuningDecision::TuningDecision(const string& remotePath)
:
m_remotePath(remotePath + "/tuning"),
m_baseUri()
{
if (remotePath == "")
{
@ -28,7 +34,7 @@ TuningDecision::TuningDecision(const std::string& remotePath) :
}
Singleton::Consume<I_MainLoop>::by<WaapComponent>()->addRecurringRoutine(
I_MainLoop::RoutineType::System,
std::chrono::minutes(10),
chrono::minutes(10),
[&]() { updateDecisions(); },
"Get tuning updates"
);
@ -48,9 +54,9 @@ struct TuningEvent
ar(cereal::make_nvp("eventType", eventType));
ar(cereal::make_nvp("eventTitle", eventTitle));
}
std::string decision;
std::string eventType;
std::string eventTitle;
string decision;
string eventType;
string eventTitle;
};
class TuningEvents : public RestGetFile
@ -61,16 +67,16 @@ public:
}
Maybe<std::vector<TuningEvent>> getTuningEvents()
Maybe<vector<TuningEvent>> getTuningEvents()
{
return decisions.get();
}
private:
S2C_PARAM(std::vector<TuningEvent>, decisions);
S2C_PARAM(vector<TuningEvent>, decisions);
};
TuningDecisionEnum TuningDecision::convertDecision(std::string decisionStr)
TuningDecisionEnum TuningDecision::convertDecision(string decisionStr)
{
if (decisionStr == "benign")
{
@ -87,7 +93,7 @@ TuningDecisionEnum TuningDecision::convertDecision(std::string decisionStr)
return NO_DECISION;
}
TuningDecisionType TuningDecision::convertDecisionType(std::string decisionTypeStr)
TuningDecisionType TuningDecision::convertDecisionType(string decisionTypeStr)
{
if (decisionTypeStr == "source")
{
@ -112,9 +118,18 @@ void TuningDecision::updateDecisions()
{
TuningEvents tuningEvents;
RemoteFilesList tuningDecisionFiles;
if (m_baseUri == "") {
I_AgentDetails *agentDetails = Singleton::Consume<I_AgentDetails>::by<WaapComponent>();
if (agentDetails->getOrchestrationMode() != OrchestrationMode::ONLINE) {
m_baseUri = "/api/";
} else {
m_baseUri = "/storage/waap/";
}
dbgTrace(D_WAAP) << "URI prefix: " << m_baseUri;
}
bool isSuccessful = sendObject(tuningDecisionFiles,
I_Messaging::Method::GET,
BASE_URI + "?list-type=2&prefix=" + m_remotePath);
m_baseUri + "?list-type=2&prefix=" + m_remotePath);
if (!isSuccessful || tuningDecisionFiles.getFilesList().empty())
{
@ -124,12 +139,12 @@ void TuningDecision::updateDecisions()
if (!sendObject(tuningEvents,
I_Messaging::Method::GET,
BASE_URI + tuningDecisionFiles.getFilesList()[0]))
m_baseUri + tuningDecisionFiles.getFilesList()[0]))
{
return;
}
m_decisions.clear();
Maybe<std::vector<TuningEvent>> events = tuningEvents.getTuningEvents();
Maybe<vector<TuningEvent>> events = tuningEvents.getTuningEvents();
if (!events.ok())
{
dbgDebug(D_WAAP) << "failed to parse events";
@ -142,7 +157,7 @@ void TuningDecision::updateDecisions()
}
}
TuningDecisionEnum TuningDecision::getDecision(std::string tuningValue, TuningDecisionType tuningType)
TuningDecisionEnum TuningDecision::getDecision(string tuningValue, TuningDecisionType tuningType)
{
const auto& typeDecisionsItr = m_decisions.find(tuningType);
if (typeDecisionsItr == m_decisions.cend())
@ -156,3 +171,20 @@ TuningDecisionEnum TuningDecision::getDecision(std::string tuningValue, TuningDe
}
return decisionItr->second;
}
string
TuningDecision::getSharedStorageHost()
{
static string shared_storage_host;
if (!shared_storage_host.empty()) {
return shared_storage_host;
}
char* sharedStorageHost = getenv(SHARED_STORAGE_HOST_ENV_NAME);
if (sharedStorageHost != NULL) {
shared_storage_host = string(sharedStorageHost);
dbgInfo(D_WAAP) << "shared storage host is set to " << shared_storage_host;
return shared_storage_host;
}
dbgWarning(D_WAAP) << "shared storage host is not set. using default: " << defaultSharedStorageHost;
return defaultSharedStorageHost;
}

View File

@ -49,7 +49,7 @@ private:
void updateDecisions();
TuningDecisionType convertDecisionType(std::string decisionTypeStr);
TuningDecisionEnum convertDecision(std::string decisionStr);
std::string getSharedStorageHost();
template<typename T>
bool sendObject(T &obj, I_Messaging::Method method, std::string uri)
@ -64,7 +64,7 @@ private:
return messaging->sendObject(
obj,
method,
"fog-msrv-appsec-shared-files-svc",
getSharedStorageHost(),
80,
conn_flags,
uri,
@ -83,6 +83,7 @@ private:
}
std::string m_remotePath;
std::string m_baseUri;
std::map<TuningDecisionType, std::map<std::string, TuningDecisionEnum>> m_decisions;
};

View File

@ -24,6 +24,7 @@ bool checkUrlEncoded(const char *buf, size_t len)
dbgFlow(D_WAAP);
size_t i = 0;
int hex_characters_to_follow = 0;
bool has_encoded_value = false;
for (; i < len; i++) {
char ch = buf[i];
@ -38,6 +39,7 @@ bool checkUrlEncoded(const char *buf, size_t len)
}
return false;
} else if (ch == '%') {
has_encoded_value = true;
hex_characters_to_follow = 2;
continue;
}
@ -75,7 +77,7 @@ bool checkUrlEncoded(const char *buf, size_t len)
}
}
return true;
return has_encoded_value;
}
ValueStatsAnalyzer::ValueStatsAnalyzer(const std::string &cur_val)
@ -139,6 +141,10 @@ ValueStatsAnalyzer::ValueStatsAnalyzer(const std::string &cur_val)
break;
}
if (isspace(ch)) {
hasSpace = true;
}
// The index will be 0 for even, and 1 for odd offsets
int index = i % 2;
@ -225,40 +231,6 @@ ValueStatsAnalyzer::ValueStatsAnalyzer(const std::string &cur_val)
if (longestZerosSeq[0] <= 2 && longestZerosSeq[1] <= 2) {
isUTF16 = false;
}
// Detect URLEncode value
size_t ofs = 0;
for (size_t i = 0 ; i < cur_val.size(); ++i) {
char ch = cur_val[i];
if (isspace(ch)) {
hasSpace = true;
isUrlEncoded = false;
break;
}
if (ofs == 0) {
if (ch == '%') {
ofs++;
}
}
else if (ofs <= 2) {
if (!isHexDigit(ch)) {
isUrlEncoded = false;
break; // at least one broken URLEncode sequence detected
}
if (ofs == 2) {
isUrlEncoded = true; // complete '%hh' sequence
ofs = 0; // search for next '%' character
}
else {
ofs++;
}
}
}
// Cancel url decoding if partial match after '%' is found, or if potential specific utf8 evasion is suspected
if (ofs != 0) {
isUrlEncoded = false;
}
isUrlEncoded = checkUrlEncoded(cur_val.data(), cur_val.size());
}

View File

@ -280,6 +280,8 @@ Debug::Debug(
:
do_assert(false)
{
isCommunicationFlag(flag1);
auto current_configuration =
Singleton::exists<Config::I_Config>() ? getConfigurationWithDefault(default_config, "Debug") : default_config;
for (auto &stream : current_configuration.streams_in_context) {
@ -309,6 +311,9 @@ Debug::Debug(
:
do_assert(false)
{
isCommunicationFlag(flag1);
isCommunicationFlag(flag2);
auto current_configuration =
Singleton::exists<Config::I_Config>() ? getConfigurationWithDefault(default_config, "Debug") : default_config;
@ -344,6 +349,10 @@ Debug::Debug(
:
do_assert(false)
{
isCommunicationFlag(flag1);
isCommunicationFlag(flag2);
isCommunicationFlag(flag3);
auto current_configuration =
Singleton::exists<Config::I_Config>() ? getConfigurationWithDefault(default_config, "Debug") : default_config;
@ -382,6 +391,11 @@ Debug::Debug(
:
do_assert(false)
{
isCommunicationFlag(flag1);
isCommunicationFlag(flag2);
isCommunicationFlag(flag3);
isCommunicationFlag(flag4);
auto current_configuration =
Singleton::exists<Config::I_Config>() ? getConfigurationWithDefault(default_config, "Debug") : default_config;
@ -694,6 +708,7 @@ Debug::findDebugFilePrefix(const string &file_name)
void
Debug::addActiveStream(const string &name)
{
if (is_communication && name == "FOG") return;
auto stream_entry = active_streams.find(name);
if (stream_entry != active_streams.end()) {
current_active_streams.insert(stream_entry->second);
@ -735,6 +750,12 @@ Debug::startStreams(
is_debug_running = true;
}
void
Debug::isCommunicationFlag(const DebugFlags &flag)
{
is_communication |= (flag == D_HTTP_REQUEST || flag == D_COMMUNICATION);
}
Debug::DebugLevel Debug::lowest_global_level = default_level;
I_TimeGet *Debug::time = nullptr;
I_MainLoop *Debug::mainloop = nullptr;

View File

@ -24,6 +24,7 @@ USE_DEBUG_FLAG(D_FW);
USE_DEBUG_FLAG(D_PM);
USE_DEBUG_FLAG(D_PM_EXEC);
USE_DEBUG_FLAG(D_TRACE);
USE_DEBUG_FLAG(D_HTTP_REQUEST);
string line = "";

View File

@ -201,6 +201,8 @@ private:
const uint &line
);
void isCommunicationFlag(const DebugFlags &flag);
static DebugLevel lowest_global_level;
static I_TimeGet *time;
static I_MainLoop *mainloop;
@ -212,6 +214,7 @@ private:
static std::vector<std::string> streams_from_mgmt;
bool do_assert;
bool is_communication = false;
DebugStreamAggr stream;
std::set<std::shared_ptr<DebugStream>> current_active_streams;
};

View File

@ -122,7 +122,7 @@ DEFINE_FLAG(D_COMPONENT, D_ALL)
DEFINE_FLAG(D_ORCHESTRATOR, D_COMPONENT)
DEFINE_FLAG(D_HEALTH_CHECK, D_ORCHESTRATOR)
DEFINE_FLAG(D_AGENT_DETAILS, D_ORCHESTRATOR)
DEFINE_FLAG(D_K8S_POLICY, D_ORCHESTRATOR)
DEFINE_FLAG(D_LOCAL_POLICY, D_ORCHESTRATOR)
DEFINE_FLAG(D_NGINX_POLICY, D_ORCHESTRATOR)
DEFINE_FLAG(D_GRADUAL_DEPLOYMENT, D_COMPONENT)

View File

@ -38,6 +38,8 @@ namespace MetricCalculations
template <typename PrintableKey, typename Metric> class MetricMap;
} // MetricCalculations
class LogRest;
class GenericMetric
:
Singleton::Consume<I_MainLoop>,
@ -84,6 +86,9 @@ public:
std::string getMetricName() const;
std::chrono::seconds getReportInterval() const;
protected:
virtual void sendLog(const LogRest &metric_client_rest) const;
private:
class MetricsRest;

View File

@ -220,9 +220,15 @@ GenericMetric::generateLog()
}
}
string fog_metric_uri = getConfigurationWithDefault<string>("/api/v1/agents/events", "metric", "fogMetricUri");
LogRest metric_client_rest(metric_to_fog);
sendLog(metric_client_rest);
}
void
GenericMetric::sendLog(const LogRest &metric_client_rest) const
{
string fog_metric_uri = getConfigurationWithDefault<string>("/api/v1/agents/events", "metric", "fogMetricUri");
Singleton::Consume<I_Messaging>::by<GenericMetric>()->sendObjectWithPersistence(
metric_client_rest,
I_Messaging::Method::POST,

View File

@ -562,10 +562,9 @@ install_cp_nano_ctl()
cp_exec "cp -f $CP_NANO_CLI ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/$CP_NANO_AGENT_CTL"
cp_exec "chmod 700 ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/$CP_NANO_AGENT_CTL"
if ! [ -f $USR_SBIN_PATH/${CP_NANO_CTL} ]; then
cp_exec "ln -s ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/$CP_NANO_AGENT_CTL $USR_SBIN_PATH/${CP_NANO_CTL}"
cp_exec "ln -s ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/${OPEN_APPSEC_CTL}.sh $USR_SBIN_PATH/${OPEN_APPSEC_CTL}"
fi
cp_exec "cp -f ${CP_NANO_DEBUG} ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/${CP_NANO_DEBUG}"
cp_exec "chmod 700 ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/${CP_NANO_DEBUG}"
@ -987,7 +986,7 @@ install_orchestration()
install_watchdog
cp_print "Note: in order for the agent to remain active and effective it must connect to the Fog/Cloud at least every 45 days" ${FORCE_STDOUT}
cp_print "open-appsec Nano Agent installation completed successfully" ${FORCE_STDOUT}
cp_print "open-appsec Orchestration Nano Service installation completed successfully" ${FORCE_STDOUT}
if [ $var_hybrid_mode = false ] && [ $var_offline_mode = false ] && [ $var_no_otp = false ] && [ $var_skip_registration = false ]; then
time_sleep=2