mirror of
https://github.com/openappsec/openappsec.git
synced 2025-06-28 16:41:02 +03:00
Compare commits
No commits in common. "main" and "1.1.21" have entirely different histories.
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
name: "Bug Report"
|
|
||||||
about: "Report a bug with open-appsec"
|
|
||||||
labels: [bug]
|
|
||||||
---
|
|
||||||
|
|
||||||
**Checklist**
|
|
||||||
- Have you checked the open-appsec troubleshooting guides - https://docs.openappsec.io/troubleshooting/troubleshooting
|
|
||||||
- Yes / No
|
|
||||||
- Have you checked the existing issues and discussions in github for the same issue
|
|
||||||
- Yes / No
|
|
||||||
- Have you checked the knwon limitations same issue - https://docs.openappsec.io/release-notes#limitations
|
|
||||||
- Yes / No
|
|
||||||
|
|
||||||
**Describe the bug**
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
**To Reproduce**
|
|
||||||
Steps to reproduce the behavior:
|
|
||||||
1. Go to '...'
|
|
||||||
2. Run '...'
|
|
||||||
3. See error '...'
|
|
||||||
|
|
||||||
**Expected behavior**
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
|
|
||||||
**Screenshots or Logs**
|
|
||||||
If applicable, add screenshots or logs to help explain the issue.
|
|
||||||
|
|
||||||
**Environment (please complete the following information):**
|
|
||||||
- open-appsec version:
|
|
||||||
- Deployment type (Docker, Kubernetes, etc.):
|
|
||||||
- OS:
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context about the problem here.
|
|
8
.github/ISSUE_TEMPLATE/config.yml
vendored
8
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,8 +0,0 @@
|
|||||||
blank_issues_enabled: false
|
|
||||||
contact_links:
|
|
||||||
- name: "Documentation & Troubleshooting"
|
|
||||||
url: "https://docs.openappsec.io/"
|
|
||||||
about: "Check the documentation before submitting an issue."
|
|
||||||
- name: "Feature Requests & Discussions"
|
|
||||||
url: "https://github.com/openappsec/openappsec/discussions"
|
|
||||||
about: "Please open a discussion for feature requests."
|
|
17
.github/ISSUE_TEMPLATE/nginx_version_support.md
vendored
17
.github/ISSUE_TEMPLATE/nginx_version_support.md
vendored
@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
name: "Nginx Version Support Request"
|
|
||||||
about: "Request for a specific Nginx version to be supported"
|
|
||||||
---
|
|
||||||
|
|
||||||
**Nginx & OS Version:**
|
|
||||||
Which Nginx and OS version are you using?
|
|
||||||
|
|
||||||
**Output of nginx -V**
|
|
||||||
Share the output of nginx -v
|
|
||||||
|
|
||||||
**Expected Behavior:**
|
|
||||||
What do you expect to happen with this version?
|
|
||||||
|
|
||||||
**Checklist**
|
|
||||||
- Have you considered a docker based deployment - find more information here https://docs.openappsec.io/getting-started/start-with-docker?
|
|
||||||
- Yes / No
|
|
@ -177,7 +177,7 @@ open-appsec code was audited by an independent third party in September-October
|
|||||||
See the [full report](https://github.com/openappsec/openappsec/blob/main/LEXFO-CHP20221014-Report-Code_audit-OPEN-APPSEC-v1.2.pdf).
|
See the [full report](https://github.com/openappsec/openappsec/blob/main/LEXFO-CHP20221014-Report-Code_audit-OPEN-APPSEC-v1.2.pdf).
|
||||||
|
|
||||||
### Reporting security vulnerabilities
|
### Reporting security vulnerabilities
|
||||||
If you've found a vulnerability or a potential vulnerability in open-appsec please let us know at security-alert@openappsec.io. We'll send a confirmation email to acknowledge your report within 24 hours, and we'll send an additional email when we've identified the issue positively or negatively.
|
If you've found a vulnerability or a potential vulnerability in open-appsec please let us know at securityalert@openappsec.io. We'll send a confirmation email to acknowledge your report within 24 hours, and we'll send an additional email when we've identified the issue positively or negatively.
|
||||||
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
@ -95,18 +95,6 @@ getFailOpenHoldTimeout()
|
|||||||
return conf_data.getNumericalValue("fail_open_hold_timeout");
|
return conf_data.getNumericalValue("fail_open_hold_timeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
|
||||||
getHoldVerdictPollingTime()
|
|
||||||
{
|
|
||||||
return conf_data.getNumericalValue("hold_verdict_polling_time");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int
|
|
||||||
getHoldVerdictRetries()
|
|
||||||
{
|
|
||||||
return conf_data.getNumericalValue("hold_verdict_retries");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
getMaxSessionsPerMinute()
|
getMaxSessionsPerMinute()
|
||||||
{
|
{
|
||||||
|
@ -66,8 +66,6 @@ TEST_F(HttpAttachmentUtilTest, GetValidAttachmentConfiguration)
|
|||||||
"\"static_resources_path\": \"" + static_resources_path + "\",\n"
|
"\"static_resources_path\": \"" + static_resources_path + "\",\n"
|
||||||
"\"min_retries_for_verdict\": 1,\n"
|
"\"min_retries_for_verdict\": 1,\n"
|
||||||
"\"max_retries_for_verdict\": 3,\n"
|
"\"max_retries_for_verdict\": 3,\n"
|
||||||
"\"hold_verdict_retries\": 3,\n"
|
|
||||||
"\"hold_verdict_polling_time\": 1,\n"
|
|
||||||
"\"body_size_trigger\": 777,\n"
|
"\"body_size_trigger\": 777,\n"
|
||||||
"\"remove_server_header\": 1\n"
|
"\"remove_server_header\": 1\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
@ -99,8 +97,6 @@ TEST_F(HttpAttachmentUtilTest, GetValidAttachmentConfiguration)
|
|||||||
EXPECT_EQ(getWaitingForVerdictThreadTimeout(), 75u);
|
EXPECT_EQ(getWaitingForVerdictThreadTimeout(), 75u);
|
||||||
EXPECT_EQ(getInspectionMode(), ngx_http_inspection_mode::BLOCKING_THREAD);
|
EXPECT_EQ(getInspectionMode(), ngx_http_inspection_mode::BLOCKING_THREAD);
|
||||||
EXPECT_EQ(getRemoveResServerHeader(), 1u);
|
EXPECT_EQ(getRemoveResServerHeader(), 1u);
|
||||||
EXPECT_EQ(getHoldVerdictRetries(), 3u);
|
|
||||||
EXPECT_EQ(getHoldVerdictPollingTime(), 1u);
|
|
||||||
|
|
||||||
EXPECT_EQ(isDebugContext("1.2.3.4", "5.6.7.8", 80, "GET", "test", "/abc"), 1);
|
EXPECT_EQ(isDebugContext("1.2.3.4", "5.6.7.8", 80, "GET", "test", "/abc"), 1);
|
||||||
EXPECT_EQ(isDebugContext("1.2.3.9", "5.6.7.8", 80, "GET", "test", "/abc"), 0);
|
EXPECT_EQ(isDebugContext("1.2.3.9", "5.6.7.8", 80, "GET", "test", "/abc"), 0);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
install(FILES Dockerfile entry.sh install-cp-agent-intelligence-service.sh install-cp-crowdsec-aux.sh self_managed_openappsec_manifest.json DESTINATION .)
|
install(FILES Dockerfile entry.sh install-cp-agent-intelligence-service.sh install-cp-crowdsec-aux.sh DESTINATION .)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${CMAKE_INSTALL_PREFIX}/agent-docker.img
|
OUTPUT ${CMAKE_INSTALL_PREFIX}/agent-docker.img
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
FROM alpine
|
FROM alpine
|
||||||
|
|
||||||
ENV OPENAPPSEC_NANO_AGENT=TRUE
|
|
||||||
|
|
||||||
RUN apk add --no-cache -u busybox
|
RUN apk add --no-cache -u busybox
|
||||||
RUN apk add --no-cache -u zlib
|
RUN apk add --no-cache -u zlib
|
||||||
RUN apk add --no-cache bash
|
RUN apk add --no-cache bash
|
||||||
@ -15,8 +13,6 @@ RUN apk add --no-cache libxml2
|
|||||||
RUN apk add --no-cache pcre2
|
RUN apk add --no-cache pcre2
|
||||||
RUN apk add --update coreutils
|
RUN apk add --update coreutils
|
||||||
|
|
||||||
COPY self_managed_openappsec_manifest.json /tmp/self_managed_openappsec_manifest.json
|
|
||||||
|
|
||||||
COPY install*.sh /nano-service-installers/
|
COPY install*.sh /nano-service-installers/
|
||||||
COPY entry.sh /entry.sh
|
COPY entry.sh /entry.sh
|
||||||
|
|
||||||
|
@ -6,8 +6,6 @@ HTTP_TRANSACTION_HANDLER_SERVICE="install-cp-nano-service-http-transaction-handl
|
|||||||
ATTACHMENT_REGISTRATION_SERVICE="install-cp-nano-attachment-registration-manager.sh"
|
ATTACHMENT_REGISTRATION_SERVICE="install-cp-nano-attachment-registration-manager.sh"
|
||||||
ORCHESTRATION_INSTALLATION_SCRIPT="install-cp-nano-agent.sh"
|
ORCHESTRATION_INSTALLATION_SCRIPT="install-cp-nano-agent.sh"
|
||||||
CACHE_INSTALLATION_SCRIPT="install-cp-nano-agent-cache.sh"
|
CACHE_INSTALLATION_SCRIPT="install-cp-nano-agent-cache.sh"
|
||||||
PROMETHEUS_INSTALLATION_SCRIPT="install-cp-nano-service-prometheus.sh"
|
|
||||||
NGINX_CENTRAL_MANAGER_INSTALLATION_SCRIPT="install-cp-nano-central-nginx-manager.sh"
|
|
||||||
|
|
||||||
var_fog_address=
|
var_fog_address=
|
||||||
var_proxy=
|
var_proxy=
|
||||||
@ -83,14 +81,6 @@ fi
|
|||||||
/nano-service-installers/$CACHE_INSTALLATION_SCRIPT --install
|
/nano-service-installers/$CACHE_INSTALLATION_SCRIPT --install
|
||||||
/nano-service-installers/$HTTP_TRANSACTION_HANDLER_SERVICE --install
|
/nano-service-installers/$HTTP_TRANSACTION_HANDLER_SERVICE --install
|
||||||
|
|
||||||
if [ "$PROMETHEUS" == "true" ]; then
|
|
||||||
/nano-service-installers/$PROMETHEUS_INSTALLATION_SCRIPT --install
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$CENTRAL_NGINX_MANAGER" == "true" ]; then
|
|
||||||
/nano-service-installers/$NGINX_CENTRAL_MANAGER_INSTALLATION_SCRIPT --install
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$CROWDSEC_ENABLED" == "true" ]; then
|
if [ "$CROWDSEC_ENABLED" == "true" ]; then
|
||||||
/nano-service-installers/$INTELLIGENCE_INSTALLATION_SCRIPT --install
|
/nano-service-installers/$INTELLIGENCE_INSTALLATION_SCRIPT --install
|
||||||
/nano-service-installers/$CROWDSEC_INSTALLATION_SCRIPT --install
|
/nano-service-installers/$CROWDSEC_INSTALLATION_SCRIPT --install
|
||||||
@ -103,16 +93,25 @@ if [ -f "$FILE" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
touch /etc/cp/watchdog/wd.startup
|
touch /etc/cp/watchdog/wd.startup
|
||||||
/etc/cp/watchdog/cp-nano-watchdog >/dev/null 2>&1 &
|
|
||||||
active_watchdog_pid=$!
|
|
||||||
while true; do
|
while true; do
|
||||||
if [ -f /tmp/restart_watchdog ]; then
|
if [ -z "$init" ]; then
|
||||||
rm -f /tmp/restart_watchdog
|
init=true
|
||||||
kill -9 ${active_watchdog_pid}
|
|
||||||
fi
|
|
||||||
if [ ! "$(ps -f | grep cp-nano-watchdog | grep ${active_watchdog_pid})" ]; then
|
|
||||||
/etc/cp/watchdog/cp-nano-watchdog >/dev/null 2>&1 &
|
/etc/cp/watchdog/cp-nano-watchdog >/dev/null 2>&1 &
|
||||||
active_watchdog_pid=$!
|
sleep 5
|
||||||
|
active_watchdog_pid=$(pgrep -f -x -o "/bin/bash /etc/cp/watchdog/cp-nano-watchdog")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
current_watchdog_pid=$(pgrep -f -x -o "/bin/bash /etc/cp/watchdog/cp-nano-watchdog")
|
||||||
|
if [ ! -f /tmp/restart_watchdog ] && [ "$current_watchdog_pid" != "$active_watchdog_pid" ]; then
|
||||||
|
echo "Error: Watchdog exited abnormally"
|
||||||
|
exit 1
|
||||||
|
elif [ -f /tmp/restart_watchdog ]; then
|
||||||
|
rm -f /tmp/restart_watchdog
|
||||||
|
kill -9 "$(pgrep -f -x -o "/bin/bash /etc/cp/watchdog/cp-nano-watchdog")"
|
||||||
|
/etc/cp/watchdog/cp-nano-watchdog >/dev/null 2>&1 &
|
||||||
|
sleep 5
|
||||||
|
active_watchdog_pid=$(pgrep -f -x -o "/bin/bash /etc/cp/watchdog/cp-nano-watchdog")
|
||||||
|
fi
|
||||||
|
|
||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include <boost/range/iterator_range.hpp>
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
#include <boost/regex.hpp>
|
#include <boost/regex.hpp>
|
||||||
|
|
||||||
#include "nginx_attachment_config.h"
|
#include "nginx_attachment_config.h"
|
||||||
@ -261,22 +260,6 @@ public:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ignored_headers_env = getenv("SAAS_IGNORED_UPSTREAM_HEADERS");
|
|
||||||
if (ignored_headers_env) {
|
|
||||||
string ignored_headers_str = ignored_headers_env;
|
|
||||||
ignored_headers_str = NGEN::Strings::trim(ignored_headers_str);
|
|
||||||
|
|
||||||
if (!ignored_headers_str.empty()) {
|
|
||||||
dbgInfo(D_HTTP_MANAGER)
|
|
||||||
<< "Ignoring SAAS_IGNORED_UPSTREAM_HEADERS environment variable: "
|
|
||||||
<< ignored_headers_str;
|
|
||||||
|
|
||||||
vector<string> ignored_headers_vec;
|
|
||||||
boost::split(ignored_headers_vec, ignored_headers_str, boost::is_any_of(";"));
|
|
||||||
for (const string &header : ignored_headers_vec) ignored_headers.insert(header);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dbgInfo(D_NGINX_ATTACHMENT) << "Successfully initialized NGINX Attachment";
|
dbgInfo(D_NGINX_ATTACHMENT) << "Successfully initialized NGINX Attachment";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1051,11 +1034,7 @@ private:
|
|||||||
case ChunkType::REQUEST_START:
|
case ChunkType::REQUEST_START:
|
||||||
return handleStartTransaction(data, opaque);
|
return handleStartTransaction(data, opaque);
|
||||||
case ChunkType::REQUEST_HEADER:
|
case ChunkType::REQUEST_HEADER:
|
||||||
return handleMultiModifiableChunks(
|
return handleMultiModifiableChunks(NginxParser::parseRequestHeaders(data), "request header", true);
|
||||||
NginxParser::parseRequestHeaders(data, ignored_headers),
|
|
||||||
"request header",
|
|
||||||
true
|
|
||||||
);
|
|
||||||
case ChunkType::REQUEST_BODY:
|
case ChunkType::REQUEST_BODY:
|
||||||
return handleModifiableChunk(NginxParser::parseRequestBody(data), "request body", true);
|
return handleModifiableChunk(NginxParser::parseRequestBody(data), "request body", true);
|
||||||
case ChunkType::REQUEST_END: {
|
case ChunkType::REQUEST_END: {
|
||||||
@ -1835,7 +1814,6 @@ private:
|
|||||||
HttpAttachmentConfig attachment_config;
|
HttpAttachmentConfig attachment_config;
|
||||||
I_MainLoop::RoutineID attachment_routine_id = 0;
|
I_MainLoop::RoutineID attachment_routine_id = 0;
|
||||||
bool traffic_indicator = false;
|
bool traffic_indicator = false;
|
||||||
unordered_set<string> ignored_headers;
|
|
||||||
|
|
||||||
// Interfaces
|
// Interfaces
|
||||||
I_Socket *i_socket = nullptr;
|
I_Socket *i_socket = nullptr;
|
||||||
|
@ -240,21 +240,6 @@ HttpAttachmentConfig::setRetriesForVerdict()
|
|||||||
"Max retries for verdict"
|
"Max retries for verdict"
|
||||||
));
|
));
|
||||||
|
|
||||||
conf_data.setNumericalValue("hold_verdict_retries", getAttachmentConf<uint>(
|
|
||||||
3,
|
|
||||||
"agent.retriesForHoldVerdict.nginxModule",
|
|
||||||
"HTTP manager",
|
|
||||||
"Retries for hold verdict"
|
|
||||||
));
|
|
||||||
|
|
||||||
conf_data.setNumericalValue("hold_verdict_polling_time", getAttachmentConf<uint>(
|
|
||||||
1,
|
|
||||||
"agent.holdVerdictPollingInterval.nginxModule",
|
|
||||||
"HTTP manager",
|
|
||||||
"Hold verdict polling interval seconds"
|
|
||||||
));
|
|
||||||
|
|
||||||
|
|
||||||
conf_data.setNumericalValue("body_size_trigger", getAttachmentConf<uint>(
|
conf_data.setNumericalValue("body_size_trigger", getAttachmentConf<uint>(
|
||||||
200000,
|
200000,
|
||||||
"agent.reqBodySizeTrigger.nginxModule",
|
"agent.reqBodySizeTrigger.nginxModule",
|
||||||
|
@ -19,15 +19,12 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "virtual_modifiers.h"
|
#include "virtual_modifiers.h"
|
||||||
#include "agent_core_utilities.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost::uuids;
|
using namespace boost::uuids;
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_HTTP_MANAGER);
|
USE_DEBUG_FLAG(D_HTTP_MANAGER);
|
||||||
|
|
||||||
extern bool is_keep_alive_ctx;
|
|
||||||
|
|
||||||
NginxAttachmentOpaque::NginxAttachmentOpaque(HttpTransactionData _transaction_data)
|
NginxAttachmentOpaque::NginxAttachmentOpaque(HttpTransactionData _transaction_data)
|
||||||
:
|
:
|
||||||
TableOpaqueSerialize<NginxAttachmentOpaque>(this),
|
TableOpaqueSerialize<NginxAttachmentOpaque>(this),
|
||||||
@ -122,47 +119,3 @@ NginxAttachmentOpaque::setSavedData(const string &name, const string &data, EnvK
|
|||||||
saved_data[name] = data;
|
saved_data[name] = data;
|
||||||
ctx.registerValue(name, data, log_ctx);
|
ctx.registerValue(name, data, log_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
NginxAttachmentOpaque::setKeepAliveCtx(const string &hdr_key, const string &hdr_val)
|
|
||||||
{
|
|
||||||
if (!is_keep_alive_ctx) return false;
|
|
||||||
|
|
||||||
static pair<string, string> keep_alive_hdr;
|
|
||||||
static bool keep_alive_hdr_initialized = false;
|
|
||||||
|
|
||||||
if (keep_alive_hdr_initialized) {
|
|
||||||
if (!keep_alive_hdr.first.empty() && hdr_key == keep_alive_hdr.first && hdr_val == keep_alive_hdr.second) {
|
|
||||||
dbgTrace(D_HTTP_MANAGER) << "Registering keep alive context";
|
|
||||||
ctx.registerValue("keep_alive_request_ctx", true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* saas_keep_alive_hdr_name_env = getenv("SAAS_KEEP_ALIVE_HDR_NAME");
|
|
||||||
if (saas_keep_alive_hdr_name_env) {
|
|
||||||
keep_alive_hdr.first = NGEN::Strings::trim(saas_keep_alive_hdr_name_env);
|
|
||||||
dbgInfo(D_HTTP_MANAGER) << "Using SAAS_KEEP_ALIVE_HDR_NAME environment variable: " << keep_alive_hdr.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!keep_alive_hdr.first.empty()) {
|
|
||||||
const char* saas_keep_alive_hdr_value_env = getenv("SAAS_KEEP_ALIVE_HDR_VALUE");
|
|
||||||
if (saas_keep_alive_hdr_value_env) {
|
|
||||||
keep_alive_hdr.second = NGEN::Strings::trim(saas_keep_alive_hdr_value_env);
|
|
||||||
dbgInfo(D_HTTP_MANAGER)
|
|
||||||
<< "Using SAAS_KEEP_ALIVE_HDR_VALUE environment variable: "
|
|
||||||
<< keep_alive_hdr.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!keep_alive_hdr.second.empty() && (hdr_key == keep_alive_hdr.first && hdr_val == keep_alive_hdr.second)) {
|
|
||||||
dbgTrace(D_HTTP_MANAGER) << "Registering keep alive context";
|
|
||||||
ctx.registerValue("keep_alive_request_ctx", true);
|
|
||||||
keep_alive_hdr_initialized = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
keep_alive_hdr_initialized = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
@ -85,7 +85,6 @@ public:
|
|||||||
EnvKeyAttr::LogSection log_ctx = EnvKeyAttr::LogSection::NONE
|
EnvKeyAttr::LogSection log_ctx = EnvKeyAttr::LogSection::NONE
|
||||||
);
|
);
|
||||||
void setApplicationState(const ApplicationState &app_state) { application_state = app_state; }
|
void setApplicationState(const ApplicationState &app_state) { application_state = app_state; }
|
||||||
bool setKeepAliveCtx(const std::string &hdr_key, const std::string &hdr_val);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CompressionStream *response_compression_stream;
|
CompressionStream *response_compression_stream;
|
||||||
|
@ -28,9 +28,7 @@ USE_DEBUG_FLAG(D_NGINX_ATTACHMENT_PARSER);
|
|||||||
|
|
||||||
Buffer NginxParser::tenant_header_key = Buffer();
|
Buffer NginxParser::tenant_header_key = Buffer();
|
||||||
static const Buffer proxy_ip_header_key("X-Forwarded-For", 15, Buffer::MemoryType::STATIC);
|
static const Buffer proxy_ip_header_key("X-Forwarded-For", 15, Buffer::MemoryType::STATIC);
|
||||||
static const Buffer waf_tag_key("x-waf-tag", 9, Buffer::MemoryType::STATIC);
|
|
||||||
static const Buffer source_ip("sourceip", 8, Buffer::MemoryType::STATIC);
|
static const Buffer source_ip("sourceip", 8, Buffer::MemoryType::STATIC);
|
||||||
bool is_keep_alive_ctx = getenv("SAAS_KEEP_ALIVE_HDR_NAME") != nullptr;
|
|
||||||
|
|
||||||
map<Buffer, CompressionType> NginxParser::content_encodings = {
|
map<Buffer, CompressionType> NginxParser::content_encodings = {
|
||||||
{Buffer("identity"), CompressionType::NO_COMPRESSION},
|
{Buffer("identity"), CompressionType::NO_COMPRESSION},
|
||||||
@ -179,73 +177,38 @@ getActivetenantAndProfile(const string &str, const string &deli = ",")
|
|||||||
}
|
}
|
||||||
|
|
||||||
Maybe<vector<HttpHeader>>
|
Maybe<vector<HttpHeader>>
|
||||||
NginxParser::parseRequestHeaders(const Buffer &data, const unordered_set<string> &ignored_headers)
|
NginxParser::parseRequestHeaders(const Buffer &data)
|
||||||
{
|
{
|
||||||
auto maybe_parsed_headers = genHeaders(data);
|
auto parsed_headers = genHeaders(data);
|
||||||
if (!maybe_parsed_headers.ok()) return maybe_parsed_headers.passErr();
|
if (!parsed_headers.ok()) return parsed_headers.passErr();
|
||||||
|
|
||||||
auto i_transaction_table = Singleton::Consume<I_TableSpecific<SessionID>>::by<NginxAttachment>();
|
auto i_transaction_table = Singleton::Consume<I_TableSpecific<SessionID>>::by<NginxAttachment>();
|
||||||
auto parsed_headers = maybe_parsed_headers.unpack();
|
|
||||||
NginxAttachmentOpaque &opaque = i_transaction_table->getState<NginxAttachmentOpaque>();
|
|
||||||
|
|
||||||
if (is_keep_alive_ctx || !ignored_headers.empty()) {
|
for (const HttpHeader &header : *parsed_headers) {
|
||||||
bool is_last_header_removed = false;
|
|
||||||
parsed_headers.erase(
|
|
||||||
remove_if(
|
|
||||||
parsed_headers.begin(),
|
|
||||||
parsed_headers.end(),
|
|
||||||
[&opaque, &is_last_header_removed, &ignored_headers](const HttpHeader &header)
|
|
||||||
{
|
|
||||||
string hdr_key = static_cast<string>(header.getKey());
|
|
||||||
string hdr_val = static_cast<string>(header.getValue());
|
|
||||||
if (
|
|
||||||
opaque.setKeepAliveCtx(hdr_key, hdr_val)
|
|
||||||
|| ignored_headers.find(hdr_key) != ignored_headers.end()
|
|
||||||
) {
|
|
||||||
dbgTrace(D_NGINX_ATTACHMENT_PARSER) << "Header was removed from headers list: " << hdr_key;
|
|
||||||
if (header.isLastHeader()) {
|
|
||||||
dbgTrace(D_NGINX_ATTACHMENT_PARSER) << "Last header was removed from headers list";
|
|
||||||
is_last_header_removed = true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
),
|
|
||||||
parsed_headers.end()
|
|
||||||
);
|
|
||||||
if (is_last_header_removed) {
|
|
||||||
dbgTrace(D_NGINX_ATTACHMENT_PARSER) << "Adjusting last header flag";
|
|
||||||
if (!parsed_headers.empty()) parsed_headers.back().setIsLastHeader();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const HttpHeader &header : parsed_headers) {
|
|
||||||
auto source_identifiers = getConfigurationWithDefault<UsersAllIdentifiersConfig>(
|
auto source_identifiers = getConfigurationWithDefault<UsersAllIdentifiersConfig>(
|
||||||
UsersAllIdentifiersConfig(),
|
UsersAllIdentifiersConfig(),
|
||||||
"rulebase",
|
"rulebase",
|
||||||
"usersIdentifiers"
|
"usersIdentifiers"
|
||||||
);
|
);
|
||||||
source_identifiers.parseRequestHeaders(header);
|
source_identifiers.parseRequestHeaders(header);
|
||||||
|
|
||||||
|
NginxAttachmentOpaque &opaque = i_transaction_table->getState<NginxAttachmentOpaque>();
|
||||||
opaque.addToSavedData(
|
opaque.addToSavedData(
|
||||||
HttpTransactionData::req_headers,
|
HttpTransactionData::req_headers,
|
||||||
static_cast<string>(header.getKey()) + ": " + static_cast<string>(header.getValue()) + "\r\n"
|
static_cast<string>(header.getKey()) + ": " + static_cast<string>(header.getValue()) + "\r\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
const auto &header_key = header.getKey();
|
if (NginxParser::tenant_header_key == header.getKey()) {
|
||||||
if (NginxParser::tenant_header_key == header_key) {
|
|
||||||
dbgDebug(D_NGINX_ATTACHMENT_PARSER)
|
dbgDebug(D_NGINX_ATTACHMENT_PARSER)
|
||||||
<< "Identified active tenant header. Key: "
|
<< "Identified active tenant header. Key: "
|
||||||
<< dumpHex(header_key)
|
<< dumpHex(header.getKey())
|
||||||
<< ", Value: "
|
<< ", Value: "
|
||||||
<< dumpHex(header.getValue());
|
<< dumpHex(header.getValue());
|
||||||
|
|
||||||
auto active_tenant_and_profile = getActivetenantAndProfile(header.getValue());
|
auto active_tenant_and_profile = getActivetenantAndProfile(header.getValue());
|
||||||
opaque.setSessionTenantAndProfile(active_tenant_and_profile[0], active_tenant_and_profile[1]);
|
opaque.setSessionTenantAndProfile(active_tenant_and_profile[0], active_tenant_and_profile[1]);
|
||||||
} else if (proxy_ip_header_key == header_key) {
|
} else if (proxy_ip_header_key == header.getKey()) {
|
||||||
source_identifiers.setXFFValuesToOpaqueCtx(header, UsersAllIdentifiersConfig::ExtractType::PROXYIP);
|
source_identifiers.setXFFValuesToOpaqueCtx(header, UsersAllIdentifiersConfig::ExtractType::PROXYIP);
|
||||||
} else if (waf_tag_key == header_key) {
|
|
||||||
source_identifiers.setWafTagValuesToOpaqueCtx(header);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,10 +28,7 @@ public:
|
|||||||
static Maybe<HttpTransactionData> parseStartTrasaction(const Buffer &data);
|
static Maybe<HttpTransactionData> parseStartTrasaction(const Buffer &data);
|
||||||
static Maybe<ResponseCode> parseResponseCode(const Buffer &data);
|
static Maybe<ResponseCode> parseResponseCode(const Buffer &data);
|
||||||
static Maybe<uint64_t> parseContentLength(const Buffer &data);
|
static Maybe<uint64_t> parseContentLength(const Buffer &data);
|
||||||
static Maybe<std::vector<HttpHeader>> parseRequestHeaders(
|
static Maybe<std::vector<HttpHeader>> parseRequestHeaders(const Buffer &data);
|
||||||
const Buffer &data,
|
|
||||||
const std::unordered_set<std::string> &ignored_headers
|
|
||||||
);
|
|
||||||
static Maybe<std::vector<HttpHeader>> parseResponseHeaders(const Buffer &data);
|
static Maybe<std::vector<HttpHeader>> parseResponseHeaders(const Buffer &data);
|
||||||
static Maybe<HttpBody> parseRequestBody(const Buffer &data);
|
static Maybe<HttpBody> parseRequestBody(const Buffer &data);
|
||||||
static Maybe<HttpBody> parseResponseBody(const Buffer &raw_response_body, CompressionStream *compression_stream);
|
static Maybe<HttpBody> parseResponseBody(const Buffer &raw_response_body, CompressionStream *compression_stream);
|
||||||
|
@ -285,21 +285,17 @@ Maybe<string>
|
|||||||
UsersAllIdentifiersConfig::parseXForwardedFor(const string &str, ExtractType type) const
|
UsersAllIdentifiersConfig::parseXForwardedFor(const string &str, ExtractType type) const
|
||||||
{
|
{
|
||||||
vector<string> header_values = split(str);
|
vector<string> header_values = split(str);
|
||||||
|
|
||||||
if (header_values.empty()) return genError("No IP found in the xff header list");
|
if (header_values.empty()) return genError("No IP found in the xff header list");
|
||||||
|
|
||||||
vector<string> xff_values = getHeaderValuesFromConfig("x-forwarded-for");
|
vector<string> xff_values = getHeaderValuesFromConfig("x-forwarded-for");
|
||||||
vector<CIDRSData> cidr_values(xff_values.begin(), xff_values.end());
|
vector<CIDRSData> cidr_values(xff_values.begin(), xff_values.end());
|
||||||
string last_valid_ip;
|
|
||||||
|
|
||||||
for (auto it = header_values.rbegin(); it != header_values.rend() - 1; ++it) {
|
for (auto it = header_values.rbegin(); it != header_values.rend() - 1; ++it) {
|
||||||
if (!IPAddr::createIPAddr(*it).ok()) {
|
if (!IPAddr::createIPAddr(*it).ok()) {
|
||||||
dbgWarning(D_NGINX_ATTACHMENT_PARSER) << "Invalid IP address found in the xff header IPs list: " << *it;
|
dbgWarning(D_NGINX_ATTACHMENT_PARSER) << "Invalid IP address found in the xff header IPs list: " << *it;
|
||||||
if (last_valid_ip.empty()) {
|
|
||||||
return genError("Invalid IP address");
|
return genError("Invalid IP address");
|
||||||
}
|
}
|
||||||
return last_valid_ip;
|
|
||||||
}
|
|
||||||
last_valid_ip = *it;
|
|
||||||
if (type == ExtractType::PROXYIP) continue;
|
if (type == ExtractType::PROXYIP) continue;
|
||||||
if (!isIpTrusted(*it, cidr_values)) {
|
if (!isIpTrusted(*it, cidr_values)) {
|
||||||
dbgDebug(D_NGINX_ATTACHMENT_PARSER) << "Found untrusted IP in the xff header IPs list: " << *it;
|
dbgDebug(D_NGINX_ATTACHMENT_PARSER) << "Found untrusted IP in the xff header IPs list: " << *it;
|
||||||
@ -311,10 +307,7 @@ UsersAllIdentifiersConfig::parseXForwardedFor(const string &str, ExtractType typ
|
|||||||
dbgWarning(D_NGINX_ATTACHMENT_PARSER)
|
dbgWarning(D_NGINX_ATTACHMENT_PARSER)
|
||||||
<< "Invalid IP address found in the xff header IPs list: "
|
<< "Invalid IP address found in the xff header IPs list: "
|
||||||
<< header_values[0];
|
<< header_values[0];
|
||||||
if (last_valid_ip.empty()) {
|
return genError("Invalid IP address");
|
||||||
return genError("No Valid Ip address was found");
|
|
||||||
}
|
|
||||||
return last_valid_ip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return header_values[0];
|
return header_values[0];
|
||||||
@ -366,24 +359,6 @@ UsersAllIdentifiersConfig::setCustomHeaderToOpaqueCtx(const HttpHeader &header)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
UsersAllIdentifiersConfig::setWafTagValuesToOpaqueCtx(const HttpHeader &header) const
|
|
||||||
{
|
|
||||||
auto i_transaction_table = Singleton::Consume<I_TableSpecific<SessionID>>::by<NginxAttachment>();
|
|
||||||
if (!i_transaction_table || !i_transaction_table->hasState<NginxAttachmentOpaque>()) {
|
|
||||||
dbgDebug(D_NGINX_ATTACHMENT_PARSER) << "Can't get the transaction table";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NginxAttachmentOpaque &opaque = i_transaction_table->getState<NginxAttachmentOpaque>();
|
|
||||||
opaque.setSavedData(HttpTransactionData::waf_tag_ctx, static_cast<string>(header.getValue()));
|
|
||||||
|
|
||||||
dbgDebug(D_NGINX_ATTACHMENT_PARSER)
|
|
||||||
<< "Added waf tag to context: "
|
|
||||||
<< static_cast<string>(header.getValue());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<string>
|
Maybe<string>
|
||||||
UsersAllIdentifiersConfig::parseCookieElement(
|
UsersAllIdentifiersConfig::parseCookieElement(
|
||||||
const string::const_iterator &start,
|
const string::const_iterator &start,
|
||||||
|
@ -15,14 +15,18 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <climits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "table_opaque.h"
|
||||||
#include "http_manager_opaque.h"
|
#include "http_manager_opaque.h"
|
||||||
#include "log_generator.h"
|
#include "log_generator.h"
|
||||||
#include "http_inspection_events.h"
|
#include "http_inspection_events.h"
|
||||||
@ -65,6 +69,22 @@ public:
|
|||||||
i_transaction_table = Singleton::Consume<I_Table>::by<HttpManager>();
|
i_transaction_table = Singleton::Consume<I_Table>::by<HttpManager>();
|
||||||
|
|
||||||
Singleton::Consume<I_Logging>::by<HttpManager>()->addGeneralModifier(compressAppSecLogs);
|
Singleton::Consume<I_Logging>::by<HttpManager>()->addGeneralModifier(compressAppSecLogs);
|
||||||
|
|
||||||
|
const char* ignored_headers_env = getenv("SAAS_IGNORED_UPSTREAM_HEADERS");
|
||||||
|
if (ignored_headers_env) {
|
||||||
|
string ignored_headers_str = ignored_headers_env;
|
||||||
|
ignored_headers_str = NGEN::Strings::removeTrailingWhitespaces(ignored_headers_str);
|
||||||
|
|
||||||
|
if (!ignored_headers_str.empty()) {
|
||||||
|
dbgInfo(D_HTTP_MANAGER)
|
||||||
|
<< "Ignoring SAAS_IGNORED_UPSTREAM_HEADERS environment variable: "
|
||||||
|
<< ignored_headers_str;
|
||||||
|
|
||||||
|
vector<string> ignored_headers_vec;
|
||||||
|
boost::split(ignored_headers_vec, ignored_headers_str, boost::is_any_of(";"));
|
||||||
|
for (const string &header : ignored_headers_vec) ignored_headers.insert(header);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterVerdict
|
FilterVerdict
|
||||||
@ -89,12 +109,19 @@ public:
|
|||||||
return FilterVerdict(default_verdict);
|
return FilterVerdict(default_verdict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_request && ignored_headers.find(static_cast<string>(event.getKey())) != ignored_headers.end()) {
|
||||||
|
dbgTrace(D_HTTP_MANAGER)
|
||||||
|
<< "Ignoring header key - "
|
||||||
|
<< static_cast<string>(event.getKey())
|
||||||
|
<< " - as it is in the ignored headers list";
|
||||||
|
return FilterVerdict(ngx_http_cp_verdict_e::TRAFFIC_VERDICT_INSPECT);
|
||||||
|
}
|
||||||
|
|
||||||
ScopedContext ctx;
|
ScopedContext ctx;
|
||||||
ctx.registerValue(app_sec_marker_key, i_transaction_table->keyToString(), EnvKeyAttr::LogSection::MARKER);
|
ctx.registerValue(app_sec_marker_key, i_transaction_table->keyToString(), EnvKeyAttr::LogSection::MARKER);
|
||||||
|
|
||||||
HttpManagerOpaque &state = i_transaction_table->getState<HttpManagerOpaque>();
|
HttpManagerOpaque &state = i_transaction_table->getState<HttpManagerOpaque>();
|
||||||
string event_key = static_cast<string>(event.getKey());
|
string event_key = static_cast<string>(event.getKey());
|
||||||
|
|
||||||
if (event_key == getProfileAgentSettingWithDefault<string>("", "agent.customHeaderValueLogging")) {
|
if (event_key == getProfileAgentSettingWithDefault<string>("", "agent.customHeaderValueLogging")) {
|
||||||
string event_value = static_cast<string>(event.getValue());
|
string event_value = static_cast<string>(event.getValue());
|
||||||
dbgTrace(D_HTTP_MANAGER)
|
dbgTrace(D_HTTP_MANAGER)
|
||||||
@ -394,6 +421,7 @@ private:
|
|||||||
I_Table *i_transaction_table;
|
I_Table *i_transaction_table;
|
||||||
static const ngx_http_cp_verdict_e default_verdict;
|
static const ngx_http_cp_verdict_e default_verdict;
|
||||||
static const string app_sec_marker_key;
|
static const string app_sec_marker_key;
|
||||||
|
unordered_set<string> ignored_headers;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ngx_http_cp_verdict_e HttpManager::Impl::default_verdict(ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP);
|
const ngx_http_cp_verdict_e HttpManager::Impl::default_verdict(ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP);
|
||||||
|
@ -45,19 +45,6 @@ private:
|
|||||||
std::string host;
|
std::string host;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EqualWafTag : public EnvironmentEvaluator<bool>, Singleton::Consume<I_Environment>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EqualWafTag(const std::vector<std::string> ¶ms);
|
|
||||||
|
|
||||||
static std::string getName() { return "EqualWafTag"; }
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error> evalVariable() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string waf_tag;
|
|
||||||
};
|
|
||||||
|
|
||||||
class EqualListeningIP : public EnvironmentEvaluator<bool>, Singleton::Consume<I_Environment>
|
class EqualListeningIP : public EnvironmentEvaluator<bool>, Singleton::Consume<I_Environment>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -239,7 +239,6 @@ public:
|
|||||||
const Buffer & getValue() const { return value; }
|
const Buffer & getValue() const { return value; }
|
||||||
|
|
||||||
bool isLastHeader() const { return is_last_header; }
|
bool isLastHeader() const { return is_last_header; }
|
||||||
void setIsLastHeader() { is_last_header = true; }
|
|
||||||
uint8_t getHeaderIndex() const { return header_index; }
|
uint8_t getHeaderIndex() const { return header_index; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -137,7 +137,6 @@ public:
|
|||||||
static const std::string source_identifier;
|
static const std::string source_identifier;
|
||||||
static const std::string proxy_ip_ctx;
|
static const std::string proxy_ip_ctx;
|
||||||
static const std::string xff_vals_ctx;
|
static const std::string xff_vals_ctx;
|
||||||
static const std::string waf_tag_ctx;
|
|
||||||
|
|
||||||
static const CompressionType default_response_content_encoding;
|
static const CompressionType default_response_content_encoding;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ public:
|
|||||||
virtual bool isVersionAboveR8110() = 0;
|
virtual bool isVersionAboveR8110() = 0;
|
||||||
virtual bool isReverseProxy() = 0;
|
virtual bool isReverseProxy() = 0;
|
||||||
virtual bool isCloudStorageEnabled() = 0;
|
virtual bool isCloudStorageEnabled() = 0;
|
||||||
virtual Maybe<std::tuple<std::string, std::string, std::string, std::string>> parseNginxMetadata() = 0;
|
virtual Maybe<std::tuple<std::string, std::string, std::string>> parseNginxMetadata() = 0;
|
||||||
virtual Maybe<std::tuple<std::string, std::string, std::string, std::string, std::string>> readCloudMetadata() = 0;
|
virtual Maybe<std::tuple<std::string, std::string, std::string, std::string, std::string>> readCloudMetadata() = 0;
|
||||||
virtual std::map<std::string, std::string> getResolvedDetails() = 0;
|
virtual std::map<std::string, std::string> getResolvedDetails() = 0;
|
||||||
#if defined(gaia) || defined(smb)
|
#if defined(gaia) || defined(smb)
|
||||||
|
@ -62,7 +62,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Maybe<std::string> downloadPackage(const Package &package, bool is_clean_installation);
|
Maybe<std::string> downloadPackage(const Package &package, bool is_clean_installation);
|
||||||
std::string getCurrentTimestamp();
|
|
||||||
|
|
||||||
std::string manifest_file_path;
|
std::string manifest_file_path;
|
||||||
std::string temp_ext;
|
std::string temp_ext;
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
#ifndef __PROMETHEUS_COMP_H__
|
|
||||||
#define __PROMETHEUS_COMP_H__
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "component.h"
|
|
||||||
#include "singleton.h"
|
|
||||||
|
|
||||||
#include "i_rest_api.h"
|
|
||||||
#include "i_messaging.h"
|
|
||||||
#include "generic_metric.h"
|
|
||||||
|
|
||||||
class PrometheusComp
|
|
||||||
:
|
|
||||||
public Component,
|
|
||||||
Singleton::Consume<I_RestApi>,
|
|
||||||
Singleton::Consume<I_Messaging>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PrometheusComp();
|
|
||||||
~PrometheusComp();
|
|
||||||
|
|
||||||
void init() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Impl;
|
|
||||||
std::unique_ptr<Impl> pimpl;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __PROMETHEUS_COMP_H__
|
|
@ -30,7 +30,6 @@
|
|||||||
#include "generic_metric.h"
|
#include "generic_metric.h"
|
||||||
|
|
||||||
#define LOGGING_INTERVAL_IN_MINUTES 10
|
#define LOGGING_INTERVAL_IN_MINUTES 10
|
||||||
USE_DEBUG_FLAG(D_WAAP);
|
|
||||||
enum class AssetType { API, WEB, ALL, COUNT };
|
enum class AssetType { API, WEB, ALL, COUNT };
|
||||||
|
|
||||||
class WaapTelemetryEvent : public Event<WaapTelemetryEvent>
|
class WaapTelemetryEvent : public Event<WaapTelemetryEvent>
|
||||||
@ -133,7 +132,6 @@ private:
|
|||||||
std::map<std::string, std::shared_ptr<T>>& telemetryMap
|
std::map<std::string, std::shared_ptr<T>>& telemetryMap
|
||||||
) {
|
) {
|
||||||
if (!telemetryMap.count(asset_id)) {
|
if (!telemetryMap.count(asset_id)) {
|
||||||
dbgTrace(D_WAAP) << "creating telemetry data for asset: " << data.assetName;
|
|
||||||
telemetryMap.emplace(asset_id, std::make_shared<T>());
|
telemetryMap.emplace(asset_id, std::make_shared<T>());
|
||||||
telemetryMap[asset_id]->init(
|
telemetryMap[asset_id]->init(
|
||||||
telemetryName,
|
telemetryName,
|
||||||
@ -141,9 +139,7 @@ private:
|
|||||||
ReportIS::IssuingEngine::AGENT_CORE,
|
ReportIS::IssuingEngine::AGENT_CORE,
|
||||||
std::chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
|
std::chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
|
||||||
true,
|
true,
|
||||||
ReportIS::Audience::SECURITY,
|
ReportIS::Audience::SECURITY
|
||||||
false,
|
|
||||||
asset_id
|
|
||||||
);
|
);
|
||||||
|
|
||||||
telemetryMap[asset_id]->template registerContext<std::string>(
|
telemetryMap[asset_id]->template registerContext<std::string>(
|
||||||
@ -156,10 +152,6 @@ private:
|
|||||||
std::string("Web Application"),
|
std::string("Web Application"),
|
||||||
EnvKeyAttr::LogSection::SOURCE
|
EnvKeyAttr::LogSection::SOURCE
|
||||||
);
|
);
|
||||||
telemetryMap[asset_id]->registerListener();
|
|
||||||
}
|
|
||||||
dbgTrace(D_WAAP) << "updating telemetry data for asset: " << data.assetName;
|
|
||||||
|
|
||||||
telemetryMap[asset_id]->template registerContext<std::string>(
|
telemetryMap[asset_id]->template registerContext<std::string>(
|
||||||
"assetId",
|
"assetId",
|
||||||
asset_id,
|
asset_id,
|
||||||
@ -180,6 +172,9 @@ private:
|
|||||||
data.practiceName,
|
data.practiceName,
|
||||||
EnvKeyAttr::LogSection::SOURCE
|
EnvKeyAttr::LogSection::SOURCE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
telemetryMap[asset_id]->registerListener();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@ public:
|
|||||||
void parseRequestHeaders(const HttpHeader &header) const;
|
void parseRequestHeaders(const HttpHeader &header) const;
|
||||||
std::vector<std::string> getHeaderValuesFromConfig(const std::string &header_key) const;
|
std::vector<std::string> getHeaderValuesFromConfig(const std::string &header_key) const;
|
||||||
void setXFFValuesToOpaqueCtx(const HttpHeader &header, ExtractType type) const;
|
void setXFFValuesToOpaqueCtx(const HttpHeader &header, ExtractType type) const;
|
||||||
void setWafTagValuesToOpaqueCtx(const HttpHeader &header) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class UsersIdentifiersConfig
|
class UsersIdentifiersConfig
|
||||||
|
@ -33,7 +33,6 @@ class I_WaapAssetStatesManager;
|
|||||||
class I_Messaging;
|
class I_Messaging;
|
||||||
class I_AgentDetails;
|
class I_AgentDetails;
|
||||||
class I_Encryptor;
|
class I_Encryptor;
|
||||||
class I_WaapModelResultLogger;
|
|
||||||
|
|
||||||
const std::string WAAP_APPLICATION_NAME = "waap application";
|
const std::string WAAP_APPLICATION_NAME = "waap application";
|
||||||
|
|
||||||
@ -51,8 +50,7 @@ class WaapComponent
|
|||||||
Singleton::Consume<I_AgentDetails>,
|
Singleton::Consume<I_AgentDetails>,
|
||||||
Singleton::Consume<I_Messaging>,
|
Singleton::Consume<I_Messaging>,
|
||||||
Singleton::Consume<I_Encryptor>,
|
Singleton::Consume<I_Encryptor>,
|
||||||
Singleton::Consume<I_Environment>,
|
Singleton::Consume<I_Environment>
|
||||||
Singleton::Consume<I_WaapModelResultLogger>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WaapComponent();
|
WaapComponent();
|
||||||
|
@ -3,7 +3,6 @@ add_subdirectory(ips)
|
|||||||
add_subdirectory(layer_7_access_control)
|
add_subdirectory(layer_7_access_control)
|
||||||
add_subdirectory(local_policy_mgmt_gen)
|
add_subdirectory(local_policy_mgmt_gen)
|
||||||
add_subdirectory(orchestration)
|
add_subdirectory(orchestration)
|
||||||
add_subdirectory(prometheus)
|
|
||||||
add_subdirectory(rate_limit)
|
add_subdirectory(rate_limit)
|
||||||
add_subdirectory(waap)
|
add_subdirectory(waap)
|
||||||
add_subdirectory(central_nginx_manager)
|
add_subdirectory(central_nginx_manager)
|
||||||
|
@ -179,7 +179,7 @@ private:
|
|||||||
Maybe<void>
|
Maybe<void>
|
||||||
configureSyslog()
|
configureSyslog()
|
||||||
{
|
{
|
||||||
if (!getProfileAgentSettingWithDefault<bool>(false, "centralNginxManagement.syslogEnabled")) {
|
if (!getProfileAgentSettingWithDefault<bool>(true, "centralNginxManagement.syslogEnabled")) {
|
||||||
dbgTrace(D_NGINX_MANAGER) << "Syslog is disabled via settings";
|
dbgTrace(D_NGINX_MANAGER) << "Syslog is disabled via settings";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -331,8 +331,6 @@ public:
|
|||||||
logError("Could not reload central NGINX configuration. Error: " + reload_result.getErr());
|
logError("Could not reload central NGINX configuration. Error: " + reload_result.getErr());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logInfo("Central NGINX configuration has been successfully reloaded");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -353,37 +351,11 @@ private:
|
|||||||
{
|
{
|
||||||
LogGen log(
|
LogGen log(
|
||||||
error,
|
error,
|
||||||
ReportIS::Level::ACTION,
|
|
||||||
ReportIS::Audience::SECURITY,
|
ReportIS::Audience::SECURITY,
|
||||||
ReportIS::Severity::CRITICAL,
|
ReportIS::Severity::CRITICAL,
|
||||||
ReportIS::Priority::URGENT,
|
ReportIS::Priority::HIGH,
|
||||||
ReportIS::Tags::POLICY_INSTALLATION
|
ReportIS::Tags::POLICY_INSTALLATION
|
||||||
);
|
);
|
||||||
|
|
||||||
log.addToOrigin(LogField("eventTopic", "Central NGINX Management"));
|
|
||||||
log << LogField("notificationId", "4165c3b1-e9bc-44c3-888b-863e204c1bfb");
|
|
||||||
log << LogField(
|
|
||||||
"eventRemediation",
|
|
||||||
"Please verify your NGINX configuration and enforce policy again. "
|
|
||||||
"Contact Check Point support if the issue persists."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
logInfo(const string &info)
|
|
||||||
{
|
|
||||||
LogGen log(
|
|
||||||
info,
|
|
||||||
ReportIS::Level::ACTION,
|
|
||||||
ReportIS::Audience::SECURITY,
|
|
||||||
ReportIS::Severity::INFO,
|
|
||||||
ReportIS::Priority::LOW,
|
|
||||||
ReportIS::Tags::POLICY_INSTALLATION
|
|
||||||
);
|
|
||||||
|
|
||||||
log.addToOrigin(LogField("eventTopic", "Central NGINX Management"));
|
|
||||||
log << LogField("notificationId", "4165c3b1-e9bc-44c3-888b-863e204c1bfb");
|
|
||||||
log << LogField("eventRemediation", "No action required");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
I_MainLoop *i_mainloop = nullptr;
|
I_MainLoop *i_mainloop = nullptr;
|
||||||
|
@ -497,8 +497,7 @@ WebAppSection::WebAppSection(
|
|||||||
const AppsecPracticeAntiBotSection &_anti_bots,
|
const AppsecPracticeAntiBotSection &_anti_bots,
|
||||||
const LogTriggerSection &parsed_log_trigger,
|
const LogTriggerSection &parsed_log_trigger,
|
||||||
const AppSecTrustedSources &parsed_trusted_sources,
|
const AppSecTrustedSources &parsed_trusted_sources,
|
||||||
const NewAppSecWebAttackProtections &protections,
|
const NewAppSecWebAttackProtections &protections)
|
||||||
const vector<InnerException> &exceptions)
|
|
||||||
:
|
:
|
||||||
application_urls(_application_urls),
|
application_urls(_application_urls),
|
||||||
asset_id(_asset_id),
|
asset_id(_asset_id),
|
||||||
@ -542,10 +541,6 @@ WebAppSection::WebAppSection(
|
|||||||
overrides.push_back(AppSecOverride(source_ident));
|
overrides.push_back(AppSecOverride(source_ident));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &exception : exceptions) {
|
|
||||||
overrides.push_back(AppSecOverride(exception));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
@ -298,8 +298,7 @@ public:
|
|||||||
const AppsecPracticeAntiBotSection &_anti_bots,
|
const AppsecPracticeAntiBotSection &_anti_bots,
|
||||||
const LogTriggerSection &parsed_log_trigger,
|
const LogTriggerSection &parsed_log_trigger,
|
||||||
const AppSecTrustedSources &parsed_trusted_sources,
|
const AppSecTrustedSources &parsed_trusted_sources,
|
||||||
const NewAppSecWebAttackProtections &protections,
|
const NewAppSecWebAttackProtections &protections);
|
||||||
const std::vector<InnerException> &exceptions);
|
|
||||||
|
|
||||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string name;
|
std::string name;
|
||||||
|
std::string mode;
|
||||||
std::vector<std::string> hosts;
|
std::vector<std::string> hosts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -206,8 +206,7 @@ private:
|
|||||||
const RulesConfigRulebase& rule_config,
|
const RulesConfigRulebase& rule_config,
|
||||||
const std::string &practice_id, const std::string &full_url,
|
const std::string &practice_id, const std::string &full_url,
|
||||||
const std::string &default_mode,
|
const std::string &default_mode,
|
||||||
std::map<AnnotationTypes, std::string> &rule_annotations,
|
std::map<AnnotationTypes, std::string> &rule_annotations
|
||||||
std::vector<InnerException>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -698,12 +698,8 @@ K8sPolicyUtils::createAppsecPolicies()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto maybe_policy_activation =
|
||||||
string ns_suffix = getAppSecScopeType() == "namespaced" ? "ns" : "";
|
getObjectFromCluster<PolicyActivationData>("/apis/openappsec.io/v1beta2/policyactivations");
|
||||||
string ns = getAppSecScopeType() == "namespaced" ? "namespaces/" : "";
|
|
||||||
auto maybe_policy_activation = getObjectFromCluster<PolicyActivationData>(
|
|
||||||
"/apis/openappsec.io/v1beta2/" + ns + agent_ns + "policyactivations" + ns_suffix
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!maybe_policy_activation.ok()) {
|
if (!maybe_policy_activation.ok()) {
|
||||||
dbgWarning(D_LOCAL_POLICY)
|
dbgWarning(D_LOCAL_POLICY)
|
||||||
|
@ -69,7 +69,7 @@ Identifier::load(cereal::JSONInputArchive &archive_in)
|
|||||||
dbgWarning(D_LOCAL_POLICY) << "AppSec identifier invalid: " << identifier;
|
dbgWarning(D_LOCAL_POLICY) << "AppSec identifier invalid: " << identifier;
|
||||||
identifier = "sourceip";
|
identifier = "sourceip";
|
||||||
}
|
}
|
||||||
parseAppsecJSONKey<vector<string>>("value", value, archive_in);
|
parseMandatoryAppsecJSONKey<vector<string>>("value", value, archive_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
const string &
|
const string &
|
||||||
|
@ -18,6 +18,14 @@ using namespace std;
|
|||||||
|
|
||||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||||
|
|
||||||
|
static const set<string> valid_modes = {
|
||||||
|
"prevent-learn",
|
||||||
|
"detect-learn",
|
||||||
|
"prevent",
|
||||||
|
"detect",
|
||||||
|
"inactive"
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
PolicyActivationMetadata::load(cereal::JSONInputArchive &archive_in)
|
PolicyActivationMetadata::load(cereal::JSONInputArchive &archive_in)
|
||||||
{
|
{
|
||||||
@ -31,6 +39,11 @@ EnabledPolicy::load(cereal::JSONInputArchive &archive_in)
|
|||||||
dbgTrace(D_LOCAL_POLICY) << "Loading policyActivation enabled policy";
|
dbgTrace(D_LOCAL_POLICY) << "Loading policyActivation enabled policy";
|
||||||
parseMandatoryAppsecJSONKey<vector<string>>("hosts", hosts, archive_in);
|
parseMandatoryAppsecJSONKey<vector<string>>("hosts", hosts, archive_in);
|
||||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||||
|
parseAppsecJSONKey<string>("mode", mode, archive_in, "detect");
|
||||||
|
if (valid_modes.count(mode) == 0) {
|
||||||
|
dbgWarning(D_LOCAL_POLICY) << "AppSec policy activation mode invalid: " << mode;
|
||||||
|
mode = "detect";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const string &
|
const string &
|
||||||
|
@ -928,6 +928,7 @@ createMultiRulesSections(
|
|||||||
PracticeSection practice = PracticeSection(practice_id, practice_type, practice_name);
|
PracticeSection practice = PracticeSection(practice_id, practice_type, practice_name);
|
||||||
vector<ParametersSection> exceptions_result;
|
vector<ParametersSection> exceptions_result;
|
||||||
for (auto exception : exceptions) {
|
for (auto exception : exceptions) {
|
||||||
|
|
||||||
const auto &exception_name = exception.first;
|
const auto &exception_name = exception.first;
|
||||||
for (const auto &inner_exception : exception.second) {
|
for (const auto &inner_exception : exception.second) {
|
||||||
exceptions_result.push_back(ParametersSection(inner_exception.getBehaviorId(), exception_name));
|
exceptions_result.push_back(ParametersSection(inner_exception.getBehaviorId(), exception_name));
|
||||||
@ -1219,8 +1220,7 @@ PolicyMakerUtils::createWebAppSection(
|
|||||||
const string &practice_id,
|
const string &practice_id,
|
||||||
const string &full_url,
|
const string &full_url,
|
||||||
const string &default_mode,
|
const string &default_mode,
|
||||||
map<AnnotationTypes, string> &rule_annotations,
|
map<AnnotationTypes, string> &rule_annotations)
|
||||||
vector<InnerException> rule_inner_exceptions)
|
|
||||||
{
|
{
|
||||||
auto apssec_practice =
|
auto apssec_practice =
|
||||||
getAppsecPracticeSpec<V1beta2AppsecLinuxPolicy, NewAppSecPracticeSpec>(
|
getAppsecPracticeSpec<V1beta2AppsecLinuxPolicy, NewAppSecPracticeSpec>(
|
||||||
@ -1255,8 +1255,7 @@ PolicyMakerUtils::createWebAppSection(
|
|||||||
apssec_practice.getAntiBot(),
|
apssec_practice.getAntiBot(),
|
||||||
log_triggers[rule_annotations[AnnotationTypes::TRIGGER]],
|
log_triggers[rule_annotations[AnnotationTypes::TRIGGER]],
|
||||||
trusted_sources[rule_annotations[AnnotationTypes::TRUSTED_SOURCES]],
|
trusted_sources[rule_annotations[AnnotationTypes::TRUSTED_SOURCES]],
|
||||||
apssec_practice.getWebAttacks().getProtections(),
|
apssec_practice.getWebAttacks().getProtections()
|
||||||
rule_inner_exceptions
|
|
||||||
);
|
);
|
||||||
web_apps[rule_config.getAssetName()] = web_app;
|
web_apps[rule_config.getAssetName()] = web_app;
|
||||||
}
|
}
|
||||||
@ -1367,8 +1366,7 @@ PolicyMakerUtils::createThreatPreventionPracticeSections(
|
|||||||
practice_id,
|
practice_id,
|
||||||
asset_name,
|
asset_name,
|
||||||
default_mode,
|
default_mode,
|
||||||
rule_annotations,
|
rule_annotations);
|
||||||
inner_exceptions[rule_annotations[AnnotationTypes::EXCEPTION]]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
bool isReverseProxy() override;
|
bool isReverseProxy() override;
|
||||||
bool isCloudStorageEnabled() override;
|
bool isCloudStorageEnabled() override;
|
||||||
Maybe<tuple<string, string, string, string, string>> readCloudMetadata() override;
|
Maybe<tuple<string, string, string, string, string>> readCloudMetadata() override;
|
||||||
Maybe<tuple<string, string, string, string>> parseNginxMetadata() override;
|
Maybe<tuple<string, string, string>> parseNginxMetadata() override;
|
||||||
#if defined(gaia) || defined(smb)
|
#if defined(gaia) || defined(smb)
|
||||||
bool compareCheckpointVersion(int cp_version, std::function<bool(int, int)> compare_operator) const override;
|
bool compareCheckpointVersion(int cp_version, std::function<bool(int, int)> compare_operator) const override;
|
||||||
#endif // gaia || smb
|
#endif // gaia || smb
|
||||||
@ -80,9 +80,7 @@ DetailsResolver::Impl::getHostname()
|
|||||||
Maybe<string>
|
Maybe<string>
|
||||||
DetailsResolver::Impl::getPlatform()
|
DetailsResolver::Impl::getPlatform()
|
||||||
{
|
{
|
||||||
#if defined(gaia_arm)
|
#if defined(gaia)
|
||||||
return string("gaia_arm");
|
|
||||||
#elif defined(gaia)
|
|
||||||
return string("gaia");
|
return string("gaia");
|
||||||
#elif defined(arm32_rpi)
|
#elif defined(arm32_rpi)
|
||||||
return string("glibc");
|
return string("glibc");
|
||||||
@ -230,7 +228,7 @@ isNoResponse(const string &cmd)
|
|||||||
return !res.ok() || res.unpack().empty();
|
return !res.ok() || res.unpack().empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<tuple<string, string, string, string>>
|
Maybe<tuple<string, string, string>>
|
||||||
DetailsResolver::Impl::parseNginxMetadata()
|
DetailsResolver::Impl::parseNginxMetadata()
|
||||||
{
|
{
|
||||||
auto output_path = getConfigurationWithDefault<string>(
|
auto output_path = getConfigurationWithDefault<string>(
|
||||||
@ -243,11 +241,6 @@ DetailsResolver::Impl::parseNginxMetadata()
|
|||||||
"/scripts/cp-nano-makefile-generator.sh -f -o " +
|
"/scripts/cp-nano-makefile-generator.sh -f -o " +
|
||||||
output_path;
|
output_path;
|
||||||
|
|
||||||
const string script_fresh_exe_cmd =
|
|
||||||
getFilesystemPathConfig() +
|
|
||||||
"/scripts/cp-nano-makefile-generator-fresh.sh save --save-location " +
|
|
||||||
output_path;
|
|
||||||
|
|
||||||
dbgTrace(D_ORCHESTRATOR) << "Details resolver, srcipt exe cmd: " << srcipt_exe_cmd;
|
dbgTrace(D_ORCHESTRATOR) << "Details resolver, srcipt exe cmd: " << srcipt_exe_cmd;
|
||||||
if (isNoResponse("which nginx") && isNoResponse("which kong")) {
|
if (isNoResponse("which nginx") && isNoResponse("which kong")) {
|
||||||
return genError("Nginx or Kong isn't installed");
|
return genError("Nginx or Kong isn't installed");
|
||||||
@ -284,37 +277,7 @@ DetailsResolver::Impl::parseNginxMetadata()
|
|||||||
<< " Error: " << exception.what();
|
<< " Error: " << exception.what();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isNoResponse("which nginx")) {
|
|
||||||
auto script_output = DetailsResolvingHanlder::getCommandOutput(script_fresh_exe_cmd);
|
|
||||||
if (!script_output.ok()) {
|
|
||||||
return genError("Failed to generate nginx fresh metadata, Error: " + script_output.getErr());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
ifstream input_stream(output_path);
|
|
||||||
if (!input_stream) {
|
|
||||||
return genError("Cannot open the file with nginx fresh metadata, File: " + output_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
string line;
|
|
||||||
while (getline(input_stream, line)) {
|
|
||||||
if (line.find("NGX_MODULE_SIGNATURE") == 0) {
|
|
||||||
lines.push_back(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
input_stream.close();
|
|
||||||
|
|
||||||
orchestration_tools->removeFile(output_path);
|
|
||||||
} catch (const ifstream::failure &exception) {
|
|
||||||
dbgWarning(D_ORCHESTRATOR)
|
|
||||||
<< "Cannot read the file with required nginx fresh metadata."
|
|
||||||
<< " File: " << output_path
|
|
||||||
<< " Error: " << exception.what();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lines.size() == 0) return genError("Failed to read nginx metadata file");
|
if (lines.size() == 0) return genError("Failed to read nginx metadata file");
|
||||||
string nginx_signature;
|
|
||||||
string nginx_version;
|
string nginx_version;
|
||||||
string config_opt;
|
string config_opt;
|
||||||
string cc_opt;
|
string cc_opt;
|
||||||
@ -329,11 +292,6 @@ DetailsResolver::Impl::parseNginxMetadata()
|
|||||||
nginx_version = "nginx-" + line.substr(eq_index + 1);
|
nginx_version = "nginx-" + line.substr(eq_index + 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.find("NGX_MODULE_SIGNATURE") != string::npos) {
|
|
||||||
auto eq_index = line.find("=");
|
|
||||||
nginx_signature = line.substr(eq_index + 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (line.find("EXTRA_CC_OPT") != string::npos) {
|
if (line.find("EXTRA_CC_OPT") != string::npos) {
|
||||||
auto eq_index = line.find("=");
|
auto eq_index = line.find("=");
|
||||||
cc_opt = line.substr(eq_index + 1);
|
cc_opt = line.substr(eq_index + 1);
|
||||||
@ -343,7 +301,7 @@ DetailsResolver::Impl::parseNginxMetadata()
|
|||||||
if (line.back() == '\\') line.pop_back();
|
if (line.back() == '\\') line.pop_back();
|
||||||
config_opt += line;
|
config_opt += line;
|
||||||
}
|
}
|
||||||
return make_tuple(config_opt, cc_opt, nginx_version, nginx_signature);
|
return make_tuple(config_opt, cc_opt, nginx_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<tuple<string, string, string, string, string>>
|
Maybe<tuple<string, string, string, string, string>>
|
||||||
|
@ -71,18 +71,7 @@ checkPepIdaIdnStatus(const string &command_output)
|
|||||||
Maybe<string>
|
Maybe<string>
|
||||||
getRequiredNanoServices(const string &command_output)
|
getRequiredNanoServices(const string &command_output)
|
||||||
{
|
{
|
||||||
string idaRequiredServices[2] = {"idaSaml", "idaIdn"};
|
return command_output;
|
||||||
string platform_str = "gaia";
|
|
||||||
#if defined(gaia_arm)
|
|
||||||
platform_str = "gaia_arm";
|
|
||||||
#endif // gaia_arm
|
|
||||||
string result = "";
|
|
||||||
for(const string &serv : idaRequiredServices) {
|
|
||||||
string add_service = serv + "_" + platform_str;
|
|
||||||
result = result + add_service + ";";
|
|
||||||
}
|
|
||||||
command_output.empty(); // overcome unused variable
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<string>
|
Maybe<string>
|
||||||
@ -353,28 +342,6 @@ getSMCBasedMgmtName(const string &command_output)
|
|||||||
return getAttr(command_output, "Mgmt object Name was not found");
|
return getAttr(command_output, "Mgmt object Name was not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<string>
|
|
||||||
getSmbObjectUid(const string &command_output)
|
|
||||||
{
|
|
||||||
static const char centrally_managed_comd_output = '0';
|
|
||||||
|
|
||||||
if (command_output.empty() || command_output[0] != centrally_managed_comd_output) {
|
|
||||||
return genError("Object UUID was not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<string> obj_uuid = getAttrFromCpsdwanGetDataJson("uuid");
|
|
||||||
if (obj_uuid.ok()) {
|
|
||||||
return obj_uuid.unpack();
|
|
||||||
}
|
|
||||||
|
|
||||||
static const string obj_path = (getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myown.C";
|
|
||||||
auto file_stream = std::make_shared<std::ifstream>(obj_path);
|
|
||||||
if (!file_stream->is_open()) {
|
|
||||||
return genError("Failed to open the object file");
|
|
||||||
}
|
|
||||||
return getMgmtObjAttr(file_stream, "uuid ");
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<string>
|
Maybe<string>
|
||||||
getSmbObjectName(const string &command_output)
|
getSmbObjectName(const string &command_output)
|
||||||
{
|
{
|
||||||
|
@ -42,6 +42,11 @@ SHELL_PRE_CMD("gunzip local.cfg", "gunzip -c $FWDIR/state/local/FW1/local.cfg.gz
|
|||||||
#ifdef SHELL_CMD_HANDLER
|
#ifdef SHELL_CMD_HANDLER
|
||||||
#if defined(gaia) || defined(smb) || defined(smb_thx_v3) || defined(smb_sve_v2) || defined(smb_mrv_v1)
|
#if defined(gaia) || defined(smb) || defined(smb_thx_v3) || defined(smb_sve_v2) || defined(smb_mrv_v1)
|
||||||
SHELL_CMD_HANDLER("cpProductIntegrationMgmtObjectType", "cpprod_util CPPROD_IsMgmtMachine", getMgmtObjType)
|
SHELL_CMD_HANDLER("cpProductIntegrationMgmtObjectType", "cpprod_util CPPROD_IsMgmtMachine", getMgmtObjType)
|
||||||
|
SHELL_CMD_HANDLER(
|
||||||
|
"cpProductIntegrationMgmtObjectUid",
|
||||||
|
"mgmt_cli --format json -r true show-session | jq -r '.[\"connected-server\"].uid'",
|
||||||
|
getMgmtObjUid
|
||||||
|
)
|
||||||
SHELL_CMD_HANDLER("prerequisitesForHorizonTelemetry",
|
SHELL_CMD_HANDLER("prerequisitesForHorizonTelemetry",
|
||||||
"FS_PATH=<FILESYSTEM-PREFIX>; [ -f ${FS_PATH}/cp-nano-horizon-telemetry-prerequisites.log ] "
|
"FS_PATH=<FILESYSTEM-PREFIX>; [ -f ${FS_PATH}/cp-nano-horizon-telemetry-prerequisites.log ] "
|
||||||
"&& head -1 ${FS_PATH}/cp-nano-horizon-telemetry-prerequisites.log || echo ''",
|
"&& head -1 ${FS_PATH}/cp-nano-horizon-telemetry-prerequisites.log || echo ''",
|
||||||
@ -145,17 +150,12 @@ SHELL_CMD_HANDLER("hasSAMLSupportedBlade", "enabled_blades", checkSAMLSupportedB
|
|||||||
SHELL_CMD_HANDLER("hasIDABlade", "enabled_blades", checkIDABlade)
|
SHELL_CMD_HANDLER("hasIDABlade", "enabled_blades", checkIDABlade)
|
||||||
SHELL_CMD_HANDLER("hasSAMLPortal", "mpclient status nac", checkSAMLPortal)
|
SHELL_CMD_HANDLER("hasSAMLPortal", "mpclient status nac", checkSAMLPortal)
|
||||||
SHELL_CMD_HANDLER("hasIdaIdnEnabled", "fw ctl get int nac_pep_identity_next_enabled", checkPepIdaIdnStatus)
|
SHELL_CMD_HANDLER("hasIdaIdnEnabled", "fw ctl get int nac_pep_identity_next_enabled", checkPepIdaIdnStatus)
|
||||||
SHELL_CMD_HANDLER("requiredNanoServices", "echo ida", getRequiredNanoServices)
|
SHELL_CMD_HANDLER("requiredNanoServices", "echo 'idaSaml_gaia;idaIdn_gaia;'", getRequiredNanoServices)
|
||||||
SHELL_CMD_HANDLER(
|
SHELL_CMD_HANDLER(
|
||||||
"cpProductIntegrationMgmtObjectName",
|
"cpProductIntegrationMgmtObjectName",
|
||||||
"mgmt_cli --format json -r true show-session | jq -r '.[\"connected-server\"].name'",
|
"mgmt_cli --format json -r true show-session | jq -r '.[\"connected-server\"].name'",
|
||||||
getMgmtObjName
|
getMgmtObjName
|
||||||
)
|
)
|
||||||
SHELL_CMD_HANDLER(
|
|
||||||
"cpProductIntegrationMgmtObjectUid",
|
|
||||||
"mgmt_cli --format json -r true show-session | jq -r '.[\"connected-server\"].uid'",
|
|
||||||
getMgmtObjUid
|
|
||||||
)
|
|
||||||
SHELL_CMD_HANDLER(
|
SHELL_CMD_HANDLER(
|
||||||
"cpProductIntegrationMgmtParentObjectName",
|
"cpProductIntegrationMgmtParentObjectName",
|
||||||
"cat $FWDIR/database/myself_objects.C "
|
"cat $FWDIR/database/myself_objects.C "
|
||||||
@ -227,11 +227,6 @@ SHELL_CMD_HANDLER(
|
|||||||
"cpprod_util FwIsLocalMgmt",
|
"cpprod_util FwIsLocalMgmt",
|
||||||
getSmbObjectName
|
getSmbObjectName
|
||||||
)
|
)
|
||||||
SHELL_CMD_HANDLER(
|
|
||||||
"cpProductIntegrationMgmtObjectUid",
|
|
||||||
"cpprod_util FwIsLocalMgmt",
|
|
||||||
getSmbObjectUid
|
|
||||||
)
|
|
||||||
SHELL_CMD_HANDLER(
|
SHELL_CMD_HANDLER(
|
||||||
"Application Control",
|
"Application Control",
|
||||||
"cat $FWDIR/conf/active_blades.txt | grep -o 'APCL [01]' | cut -d ' ' -f2",
|
"cat $FWDIR/conf/active_blades.txt | grep -o 'APCL [01]' | cut -d ' ' -f2",
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include "maybe_res.h"
|
#include "maybe_res.h"
|
||||||
|
|
||||||
std::ostream &
|
std::ostream &
|
||||||
operator<<(std::ostream &os, const Maybe<std::tuple<std::string, std::string, std::string, std::string>> &)
|
operator<<(std::ostream &os, const Maybe<std::tuple<std::string, std::string, std::string>> &)
|
||||||
{
|
{
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ public:
|
|||||||
MOCK_METHOD0(isGwNotVsx, bool());
|
MOCK_METHOD0(isGwNotVsx, bool());
|
||||||
MOCK_METHOD0(getResolvedDetails, std::map<std::string, std::string>());
|
MOCK_METHOD0(getResolvedDetails, std::map<std::string, std::string>());
|
||||||
MOCK_METHOD0(isVersionAboveR8110, bool());
|
MOCK_METHOD0(isVersionAboveR8110, bool());
|
||||||
MOCK_METHOD0(parseNginxMetadata, Maybe<std::tuple<std::string, std::string, std::string, std::string>>());
|
MOCK_METHOD0(parseNginxMetadata, Maybe<std::tuple<std::string, std::string, std::string>>());
|
||||||
MOCK_METHOD0(
|
MOCK_METHOD0(
|
||||||
readCloudMetadata, Maybe<std::tuple<std::string, std::string, std::string, std::string, std::string>>());
|
readCloudMetadata, Maybe<std::tuple<std::string, std::string, std::string, std::string, std::string>>());
|
||||||
};
|
};
|
||||||
|
@ -100,7 +100,6 @@ private:
|
|||||||
string packages_dir;
|
string packages_dir;
|
||||||
string orch_service_name;
|
string orch_service_name;
|
||||||
set<string> ignore_packages;
|
set<string> ignore_packages;
|
||||||
Maybe<string> forbidden_versions = genError("Forbidden versions file does not exist");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -136,8 +135,7 @@ ManifestController::Impl::init()
|
|||||||
"Ignore packages list file path"
|
"Ignore packages list file path"
|
||||||
);
|
);
|
||||||
|
|
||||||
auto orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<ManifestController>();
|
if (Singleton::Consume<I_OrchestrationTools>::by<ManifestController>()->doesFileExist(ignore_packages_path)) {
|
||||||
if (orchestration_tools->doesFileExist(ignore_packages_path)) {
|
|
||||||
try {
|
try {
|
||||||
ifstream input_stream(ignore_packages_path);
|
ifstream input_stream(ignore_packages_path);
|
||||||
if (!input_stream) {
|
if (!input_stream) {
|
||||||
@ -158,9 +156,6 @@ ManifestController::Impl::init()
|
|||||||
<< " Error: " << f.what();
|
<< " Error: " << f.what();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const string forbidden_versions_path = getFilesystemPathConfig() + "/revert/forbidden_versions";
|
|
||||||
forbidden_versions = orchestration_tools->readFile(forbidden_versions_path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -276,17 +271,6 @@ ManifestController::Impl::updateManifest(const string &new_manifest_file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
map<string, Package> new_packages = parsed_manifest.unpack();
|
map<string, Package> new_packages = parsed_manifest.unpack();
|
||||||
if (!new_packages.empty()) {
|
|
||||||
const Package &package = new_packages.begin()->second;
|
|
||||||
if (forbidden_versions.ok() &&
|
|
||||||
forbidden_versions.unpack().find(package.getVersion()) != string::npos
|
|
||||||
) {
|
|
||||||
dbgWarning(D_ORCHESTRATOR)
|
|
||||||
<< "Packages version is in the forbidden versions list. No upgrade will be performed.";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
map<string, Package> all_packages = parsed_manifest.unpack();
|
map<string, Package> all_packages = parsed_manifest.unpack();
|
||||||
map<string, Package> current_packages;
|
map<string, Package> current_packages;
|
||||||
parsed_manifest = orchestration_tools->loadPackagesFromJson(manifest_file_path);
|
parsed_manifest = orchestration_tools->loadPackagesFromJson(manifest_file_path);
|
||||||
|
@ -58,9 +58,6 @@ public:
|
|||||||
Debug::setUnitTestFlag(D_ORCHESTRATOR, Debug::DebugLevel::TRACE);
|
Debug::setUnitTestFlag(D_ORCHESTRATOR, Debug::DebugLevel::TRACE);
|
||||||
const string ignore_packages_file = "/etc/cp/conf/ignore-packages.txt";
|
const string ignore_packages_file = "/etc/cp/conf/ignore-packages.txt";
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(ignore_packages_file)).WillOnce(Return(false));
|
EXPECT_CALL(mock_orchestration_tools, doesFileExist(ignore_packages_file)).WillOnce(Return(false));
|
||||||
Maybe<string> forbidden_versions(string("a1\na2"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, readFile("/etc/cp/revert/forbidden_versions"))
|
|
||||||
.WillOnce(Return(forbidden_versions));
|
|
||||||
manifest_controller.init();
|
manifest_controller.init();
|
||||||
manifest_file_path = getConfigurationWithDefault<string>(
|
manifest_file_path = getConfigurationWithDefault<string>(
|
||||||
"/etc/cp/conf/manifest.json",
|
"/etc/cp/conf/manifest.json",
|
||||||
@ -227,10 +224,6 @@ TEST_F(ManifestControllerTest, createNewManifest)
|
|||||||
EXPECT_CALL(mock_orchestration_tools, copyFile(file_name, manifest_file_path)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, copyFile(file_name, manifest_file_path)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillOnce(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,11 +363,6 @@ TEST_F(ManifestControllerTest, updateManifest)
|
|||||||
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).Times(2).WillRepeatedly(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).Times(2).WillRepeatedly(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).Times(2).WillRepeatedly(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).Times(2).WillRepeatedly(Return(true));
|
||||||
|
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillOnce(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
|
|
||||||
manifest =
|
manifest =
|
||||||
@ -429,9 +417,6 @@ TEST_F(ManifestControllerTest, updateManifest)
|
|||||||
EXPECT_CALL(mock_orchestration_tools, loadPackagesFromJson(file_name)).WillOnce(Return(new_services));
|
EXPECT_CALL(mock_orchestration_tools, loadPackagesFromJson(file_name)).WillOnce(Return(new_services));
|
||||||
EXPECT_CALL(mock_orchestration_tools,
|
EXPECT_CALL(mock_orchestration_tools,
|
||||||
loadPackagesFromJson(manifest_file_path)).WillOnce(Return(old_services));
|
loadPackagesFromJson(manifest_file_path)).WillOnce(Return(old_services));
|
||||||
|
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillOnce(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillRepeatedly(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,11 +478,6 @@ TEST_F(ManifestControllerTest, selfUpdate)
|
|||||||
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, copyFile("/tmp/temp_file", path +
|
EXPECT_CALL(mock_orchestration_tools, copyFile("/tmp/temp_file", path +
|
||||||
temp_ext)).WillOnce(Return(true));
|
temp_ext)).WillOnce(Return(true));
|
||||||
|
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillOnce(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,10 +607,6 @@ TEST_F(ManifestControllerTest, removeCurrentErrorPackage)
|
|||||||
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).WillOnce(Return(true));
|
||||||
|
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillOnce(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
corrupted_packages.clear();
|
corrupted_packages.clear();
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
@ -690,10 +666,6 @@ TEST_F(ManifestControllerTest, selfUpdateWithOldCopy)
|
|||||||
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, copyFile("/tmp/temp_file", path +
|
EXPECT_CALL(mock_orchestration_tools, copyFile("/tmp/temp_file", path +
|
||||||
temp_ext)).WillOnce(Return(true));
|
temp_ext)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillOnce(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,10 +722,6 @@ TEST_F(ManifestControllerTest, selfUpdateWithOldCopyWithError)
|
|||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(path)).WillOnce(Return(false)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, doesFileExist(path)).WillOnce(Return(false)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, copyFile(path, path + backup_ext + temp_ext)).WillOnce(Return(false));
|
EXPECT_CALL(mock_orchestration_tools, copyFile(path, path + backup_ext + temp_ext)).WillOnce(Return(false));
|
||||||
EXPECT_CALL(mock_details_resolver, getHostname()).WillOnce(Return(hostname));
|
EXPECT_CALL(mock_details_resolver, getHostname()).WillOnce(Return(hostname));
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillOnce(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_FALSE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_FALSE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -830,10 +798,6 @@ TEST_F(ManifestControllerTest, installAndRemove)
|
|||||||
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).Times(2).WillRepeatedly(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).Times(2).WillRepeatedly(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).Times(2).WillRepeatedly(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).Times(2).WillRepeatedly(Return(true));
|
||||||
|
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillOnce(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
|
|
||||||
string new_manifest =
|
string new_manifest =
|
||||||
@ -894,63 +858,6 @@ TEST_F(ManifestControllerTest, installAndRemove)
|
|||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/packages/my1/my1")).Times(2)
|
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/packages/my1/my1")).Times(2)
|
||||||
.WillOnce(Return(false));
|
.WillOnce(Return(false));
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillOnce(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillRepeatedly(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ManifestControllerTest, manifestWithForbiddenVersion)
|
|
||||||
{
|
|
||||||
new_services.clear();
|
|
||||||
old_services.clear();
|
|
||||||
|
|
||||||
string manifest =
|
|
||||||
"{"
|
|
||||||
" \"packages\": ["
|
|
||||||
" {"
|
|
||||||
" \"download-path\": \"http://172.23.92.135/my.sh\","
|
|
||||||
" \"relative-path\": \"\","
|
|
||||||
" \"name\": \"my\","
|
|
||||||
" \"version\": \"a1\","
|
|
||||||
" \"checksum-type\": \"sha1sum\","
|
|
||||||
" \"checksum\": \"a58bbab8020b0e6d08568714b5e582a3adf9c805\","
|
|
||||||
" \"package-type\": \"service\","
|
|
||||||
" \"require\": []"
|
|
||||||
" },"
|
|
||||||
" {"
|
|
||||||
" \"download-path\": \"http://172.23.92.135/my.sh\","
|
|
||||||
" \"relative-path\": \"\","
|
|
||||||
" \"name\": \"orchestration\","
|
|
||||||
" \"version\": \"a1\","
|
|
||||||
" \"checksum-type\": \"sha1sum\","
|
|
||||||
" \"checksum\": \"a58bbab8020b0e6d08568714b5e582a3adf9c805\","
|
|
||||||
" \"package-type\": \"service\","
|
|
||||||
" \"require\": []"
|
|
||||||
" },"
|
|
||||||
" {"
|
|
||||||
" \"download-path\": \"\","
|
|
||||||
" \"relative-path\": \"\","
|
|
||||||
" \"name\": \"waap\","
|
|
||||||
" \"version\": \"a1\","
|
|
||||||
" \"checksum-type\": \"sha1sum\","
|
|
||||||
" \"checksum\": \"\","
|
|
||||||
" \"package-type\": \"service\","
|
|
||||||
" \"status\": false,\n"
|
|
||||||
" \"message\": \"This security app isn't valid for this agent\"\n"
|
|
||||||
" }"
|
|
||||||
" ]"
|
|
||||||
"}";
|
|
||||||
|
|
||||||
map<string, Package> manifest_services;
|
|
||||||
load(manifest, manifest_services);
|
|
||||||
checkIfFileExistsCall(manifest_services.at("my"));
|
|
||||||
|
|
||||||
|
|
||||||
load(manifest, new_services);
|
|
||||||
load(old_manifest, old_services);
|
|
||||||
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, loadPackagesFromJson(file_name)).WillOnce(Return(new_services));
|
|
||||||
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1040,10 +947,6 @@ TEST_F(ManifestControllerTest, badInstall)
|
|||||||
EXPECT_CALL(mock_orchestration_tools,
|
EXPECT_CALL(mock_orchestration_tools,
|
||||||
packagesToJsonFile(corrupted_packages, corrupted_file_list)).WillOnce(Return(true));
|
packagesToJsonFile(corrupted_packages, corrupted_file_list)).WillOnce(Return(true));
|
||||||
|
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillOnce(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_FALSE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_FALSE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1209,12 +1112,6 @@ TEST_F(ManifestControllerTest, requireUpdate)
|
|||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, removeFile("new_manifest.json")).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, removeFile("new_manifest.json")).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillRepeatedly(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status"))
|
|
||||||
.WillOnce(Return(false))
|
|
||||||
.WillRepeatedly(Return(true));;
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1315,10 +1212,6 @@ TEST_F(ManifestControllerTest, sharedObjectNotInstalled)
|
|||||||
).WillOnce(Return(true));
|
).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, copyFile("/tmp/temp_file1", path +
|
EXPECT_CALL(mock_orchestration_tools, copyFile("/tmp/temp_file1", path +
|
||||||
temp_ext)).WillOnce(Return(true));
|
temp_ext)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillOnce(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1420,12 +1313,6 @@ TEST_F(ManifestControllerTest, requireSharedObjectUpdate)
|
|||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, removeFile("new_manifest.json"))
|
EXPECT_CALL(mock_orchestration_tools, removeFile("new_manifest.json"))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillRepeatedly(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status"))
|
|
||||||
.WillOnce(Return(false))
|
|
||||||
.WillRepeatedly(Return(true));;
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1502,7 +1389,6 @@ TEST_F(ManifestControllerTest, failureOnDownloadSharedObject)
|
|||||||
EXPECT_CALL(mock_details_resolver, getHostname()).WillOnce(Return(string("hostname")));
|
EXPECT_CALL(mock_details_resolver, getHostname()).WillOnce(Return(string("hostname")));
|
||||||
EXPECT_CALL(mock_orchestration_tools, removeFile("/tmp/temp_file1")).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, removeFile("/tmp/temp_file1")).WillOnce(Return(true));
|
||||||
|
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillRepeatedly(Return("b"));
|
|
||||||
EXPECT_FALSE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_FALSE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1638,12 +1524,6 @@ TEST_F(ManifestControllerTest, multiRequireUpdate)
|
|||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, removeFile("new_manifest.json"))
|
EXPECT_CALL(mock_orchestration_tools, removeFile("new_manifest.json"))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillRepeatedly(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status"))
|
|
||||||
.WillOnce(Return(false))
|
|
||||||
.WillRepeatedly(Return(true));;
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1730,12 +1610,6 @@ TEST_F(ManifestControllerTest, createNewManifestWithUninstallablePackage)
|
|||||||
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).WillOnce(Return(true));
|
||||||
|
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillRepeatedly(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status"))
|
|
||||||
.WillOnce(Return(false))
|
|
||||||
.WillRepeatedly(Return(true));;
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1750,7 +1624,7 @@ TEST_F(ManifestControllerTest, updateUninstallPackage)
|
|||||||
" \"download-path\": \"\","
|
" \"download-path\": \"\","
|
||||||
" \"relative-path\": \"\","
|
" \"relative-path\": \"\","
|
||||||
" \"name\": \"my\","
|
" \"name\": \"my\","
|
||||||
" \"version\": \"c\","
|
" \"version\": \"\","
|
||||||
" \"checksum-type\": \"sha1sum\","
|
" \"checksum-type\": \"sha1sum\","
|
||||||
" \"checksum\": \"\","
|
" \"checksum\": \"\","
|
||||||
" \"package-type\": \"service\","
|
" \"package-type\": \"service\","
|
||||||
@ -1847,11 +1721,6 @@ TEST_F(ManifestControllerTest, updateUninstallPackage)
|
|||||||
EXPECT_CALL(mock_orchestration_tools, loadPackagesFromJson(file_name)).WillOnce(Return(new_services));
|
EXPECT_CALL(mock_orchestration_tools, loadPackagesFromJson(file_name)).WillOnce(Return(new_services));
|
||||||
EXPECT_CALL(mock_orchestration_tools,
|
EXPECT_CALL(mock_orchestration_tools,
|
||||||
loadPackagesFromJson(manifest_file_path)).WillOnce(Return(old_services));
|
loadPackagesFromJson(manifest_file_path)).WillOnce(Return(old_services));
|
||||||
|
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillOnce(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1875,9 +1744,6 @@ public:
|
|||||||
setConfiguration<string>(ignore_packages_file, "orchestration", "Ignore packages list file path");
|
setConfiguration<string>(ignore_packages_file, "orchestration", "Ignore packages list file path");
|
||||||
writeIgnoreList(ignore_packages_file, ignore_services);
|
writeIgnoreList(ignore_packages_file, ignore_services);
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(ignore_packages_file)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, doesFileExist(ignore_packages_file)).WillOnce(Return(true));
|
||||||
Maybe<string> forbidden_versions(string("a1\na2"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, readFile("/etc/cp/revert/forbidden_versions"))
|
|
||||||
.WillOnce(Return(forbidden_versions));
|
|
||||||
manifest_controller.init();
|
manifest_controller.init();
|
||||||
manifest_file_path = getConfigurationWithDefault<string>(
|
manifest_file_path = getConfigurationWithDefault<string>(
|
||||||
"/etc/cp/conf/manifest.json",
|
"/etc/cp/conf/manifest.json",
|
||||||
@ -1973,7 +1839,6 @@ public:
|
|||||||
StrictMock<MockOrchestrationStatus> mock_status;
|
StrictMock<MockOrchestrationStatus> mock_status;
|
||||||
StrictMock<MockDownloader> mock_downloader;
|
StrictMock<MockDownloader> mock_downloader;
|
||||||
StrictMock<MockOrchestrationTools> mock_orchestration_tools;
|
StrictMock<MockOrchestrationTools> mock_orchestration_tools;
|
||||||
StrictMock<MockDetailsResolver> mock_details_resolver;
|
|
||||||
NiceMock<MockShellCmd> mock_shell_cmd;
|
NiceMock<MockShellCmd> mock_shell_cmd;
|
||||||
|
|
||||||
ManifestController manifest_controller;
|
ManifestController manifest_controller;
|
||||||
@ -2257,12 +2122,6 @@ TEST_F(ManifestControllerIgnorePakckgeTest, addIgnorePackageAndUpdateNormal)
|
|||||||
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).WillOnce(Return(true));
|
||||||
|
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillRepeatedly(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status"))
|
|
||||||
.WillOnce(Return(false))
|
|
||||||
.WillRepeatedly(Return(true));;
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2528,12 +2387,6 @@ TEST_F(ManifestControllerIgnorePakckgeTest, overrideIgnoredPackageFromProfileSet
|
|||||||
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, isNonEmptyFile(manifest_file_path)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).WillOnce(Return(true));
|
EXPECT_CALL(mock_orchestration_tools, removeFile(file_name)).WillOnce(Return(true));
|
||||||
|
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillRepeatedly(Return("b"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status"))
|
|
||||||
.WillOnce(Return(false))
|
|
||||||
.WillRepeatedly(Return(true));;
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, writeFile(_, "/etc/cp/revert/upgrade_status", false))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
EXPECT_TRUE(i_manifest_controller->updateManifest(file_name));
|
||||||
|
|
||||||
EXPECT_THAT(capture_debug.str(), Not(HasSubstr("Ignoring a package from the manifest. Package name: my")));
|
EXPECT_THAT(capture_debug.str(), Not(HasSubstr("Ignoring a package from the manifest. Package name: my")));
|
||||||
@ -2558,9 +2411,6 @@ public:
|
|||||||
doesFileExist("/etc/cp/conf/ignore-packages.txt")
|
doesFileExist("/etc/cp/conf/ignore-packages.txt")
|
||||||
).WillOnce(Return(false));
|
).WillOnce(Return(false));
|
||||||
|
|
||||||
Maybe<string> forbidden_versions(string("a1\na2"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, readFile("/etc/cp/revert/forbidden_versions"))
|
|
||||||
.WillOnce(Return(forbidden_versions));
|
|
||||||
manifest_controller.init();
|
manifest_controller.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "manifest_handler.h"
|
#include "manifest_handler.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <ctime>
|
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -202,29 +201,18 @@ ManifestHandler::installPackage(
|
|||||||
auto span_scope = i_env->startNewSpanScope(Span::ContextType::CHILD_OF);
|
auto span_scope = i_env->startNewSpanScope(Span::ContextType::CHILD_OF);
|
||||||
auto orchestration_status = Singleton::Consume<I_OrchestrationStatus>::by<ManifestHandler>();
|
auto orchestration_status = Singleton::Consume<I_OrchestrationStatus>::by<ManifestHandler>();
|
||||||
|
|
||||||
auto details_resolver = Singleton::Consume<I_DetailsResolver>::by<ManifestHandler>();
|
|
||||||
auto orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<ManifestHandler>();
|
|
||||||
|
|
||||||
auto &package = package_downloaded_file.first;
|
auto &package = package_downloaded_file.first;
|
||||||
auto &package_name = package.getName();
|
auto &package_name = package.getName();
|
||||||
auto &package_handler_path = package_downloaded_file.second;
|
auto &package_handler_path = package_downloaded_file.second;
|
||||||
|
|
||||||
dbgInfo(D_ORCHESTRATOR) << "Handling package installation. Package: " << package_name;
|
dbgInfo(D_ORCHESTRATOR) << "Handling package installation. Package: " << package_name;
|
||||||
|
|
||||||
string upgrade_info =
|
|
||||||
details_resolver->getAgentVersion() + " " + package.getVersion() + " " + getCurrentTimestamp();
|
|
||||||
if (!orchestration_tools->doesFileExist(getFilesystemPathConfig() + "/revert/upgrade_status") &&
|
|
||||||
!orchestration_tools->writeFile(upgrade_info, getFilesystemPathConfig() + "/revert/upgrade_status")
|
|
||||||
) {
|
|
||||||
dbgWarning(D_ORCHESTRATOR) << "Failed to write to " + getFilesystemPathConfig() + "/revert/upgrade_status";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (package_name.compare(orch_service_name) == 0) {
|
if (package_name.compare(orch_service_name) == 0) {
|
||||||
orchestration_status->writeStatusToFile();
|
orchestration_status->writeStatusToFile();
|
||||||
bool self_update_status = selfUpdate(package, current_packages, package_handler_path);
|
bool self_update_status = selfUpdate(package, current_packages, package_handler_path);
|
||||||
if (!self_update_status) {
|
if (!self_update_status) {
|
||||||
auto details = Singleton::Consume<I_AgentDetails>::by<ManifestHandler>();
|
auto details = Singleton::Consume<I_AgentDetails>::by<ManifestHandler>();
|
||||||
auto hostname = details_resolver->getHostname();
|
auto hostname = Singleton::Consume<I_DetailsResolver>::by<ManifestHandler>()->getHostname();
|
||||||
string err_hostname = (hostname.ok() ? "on host '" + *hostname : "'" + details->getAgentId()) + "'";
|
string err_hostname = (hostname.ok() ? "on host '" + *hostname : "'" + details->getAgentId()) + "'";
|
||||||
string install_error =
|
string install_error =
|
||||||
"Warning: Agent/Gateway " +
|
"Warning: Agent/Gateway " +
|
||||||
@ -258,6 +246,7 @@ ManifestHandler::installPackage(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
string current_installation_file = packages_dir + "/" + package_name + "/" + package_name;
|
string current_installation_file = packages_dir + "/" + package_name + "/" + package_name;
|
||||||
|
auto orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<ManifestHandler>();
|
||||||
bool is_clean_installation = !orchestration_tools->doesFileExist(current_installation_file);
|
bool is_clean_installation = !orchestration_tools->doesFileExist(current_installation_file);
|
||||||
|
|
||||||
|
|
||||||
@ -379,13 +368,3 @@ ManifestHandler::selfUpdate(
|
|||||||
package_handler->preInstallPackage(orch_service_name, current_installation_file) &&
|
package_handler->preInstallPackage(orch_service_name, current_installation_file) &&
|
||||||
package_handler->installPackage(orch_service_name, current_installation_file, false);
|
package_handler->installPackage(orch_service_name, current_installation_file, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
string
|
|
||||||
ManifestHandler::getCurrentTimestamp()
|
|
||||||
{
|
|
||||||
time_t now = time(nullptr);
|
|
||||||
tm* now_tm = localtime(&now);
|
|
||||||
char timestamp[20];
|
|
||||||
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", now_tm);
|
|
||||||
return string(timestamp);
|
|
||||||
}
|
|
||||||
|
@ -55,8 +55,6 @@ USE_DEBUG_FLAG(D_ORCHESTRATOR);
|
|||||||
static string fw_last_update_time = "";
|
static string fw_last_update_time = "";
|
||||||
#endif // gaia || smb
|
#endif // gaia || smb
|
||||||
|
|
||||||
static const size_t MAX_SERVER_NAME_LENGTH = 253;
|
|
||||||
|
|
||||||
class SetAgentUninstall
|
class SetAgentUninstall
|
||||||
:
|
:
|
||||||
public ServerRest,
|
public ServerRest,
|
||||||
@ -105,19 +103,6 @@ public:
|
|||||||
<< "Initializing Orchestration component, file system path prefix: "
|
<< "Initializing Orchestration component, file system path prefix: "
|
||||||
<< filesystem_prefix;
|
<< filesystem_prefix;
|
||||||
|
|
||||||
int check_upgrade_success_interval = getSettingWithDefault<uint>(10, "successUpgradeInterval");
|
|
||||||
Singleton::Consume<I_MainLoop>::by<OrchestrationComp>()->addOneTimeRoutine(
|
|
||||||
I_MainLoop::RoutineType::Timer,
|
|
||||||
[this, check_upgrade_success_interval]()
|
|
||||||
{
|
|
||||||
Singleton::Consume<I_MainLoop>::by<OrchestrationComp>()->yield(
|
|
||||||
std::chrono::minutes(check_upgrade_success_interval)
|
|
||||||
);
|
|
||||||
processUpgradeCompletion();
|
|
||||||
},
|
|
||||||
"Orchestration successfully updated (One-Time After Interval)",
|
|
||||||
true
|
|
||||||
);
|
|
||||||
auto orch_policy = loadDefaultOrchestrationPolicy();
|
auto orch_policy = loadDefaultOrchestrationPolicy();
|
||||||
if (!orch_policy.ok()) {
|
if (!orch_policy.ok()) {
|
||||||
dbgWarning(D_ORCHESTRATOR) << "Failed to load Orchestration Policy. Error: " << orch_policy.getErr();
|
dbgWarning(D_ORCHESTRATOR) << "Failed to load Orchestration Policy. Error: " << orch_policy.getErr();
|
||||||
@ -156,113 +141,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void
|
|
||||||
saveLastKnownOrchInfo(string curr_agent_version)
|
|
||||||
{
|
|
||||||
static const string upgrades_dir = filesystem_prefix + "/revert";
|
|
||||||
static const string last_known_orchestrator = upgrades_dir + "/last_known_working_orchestrator";
|
|
||||||
static const string current_orchestration_package =
|
|
||||||
filesystem_prefix + "/packages/orchestration/orchestration";
|
|
||||||
static const string last_known_manifest = upgrades_dir + "/last_known_manifest";
|
|
||||||
static const string current_manifest_file = getConfigurationWithDefault<string>(
|
|
||||||
filesystem_prefix + "/conf/manifest.json",
|
|
||||||
"orchestration",
|
|
||||||
"Manifest file path"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!i_orchestration_tools->copyFile(current_orchestration_package, last_known_orchestrator)) {
|
|
||||||
dbgWarning(D_ORCHESTRATOR) << "Failed to copy the orchestration package to " << upgrades_dir;
|
|
||||||
} else {
|
|
||||||
dbgInfo(D_ORCHESTRATOR) << "last known orchestrator version updated to: " << curr_agent_version;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!i_orchestration_tools->copyFile(current_manifest_file, last_known_manifest)) {
|
|
||||||
dbgWarning(D_ORCHESTRATOR) << "Failed to copy " << current_manifest_file << " to " << upgrades_dir;
|
|
||||||
} else {
|
|
||||||
dbgInfo(D_ORCHESTRATOR) << "last known manifest updated";
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
processUpgradeCompletion()
|
|
||||||
{
|
|
||||||
if (!is_first_check_update_success) {
|
|
||||||
int check_upgrade_success_interval = getSettingWithDefault<uint>(10, "successUpgradeInterval");
|
|
||||||
// LCOV_EXCL_START
|
|
||||||
Singleton::Consume<I_MainLoop>::by<OrchestrationComp>()->addOneTimeRoutine(
|
|
||||||
I_MainLoop::RoutineType::Timer,
|
|
||||||
[this, check_upgrade_success_interval]()
|
|
||||||
{
|
|
||||||
Singleton::Consume<I_MainLoop>::by<OrchestrationComp>()->yield(
|
|
||||||
std::chrono::minutes(check_upgrade_success_interval)
|
|
||||||
);
|
|
||||||
processUpgradeCompletion();
|
|
||||||
},
|
|
||||||
"Orchestration successfully updated",
|
|
||||||
true
|
|
||||||
);
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const string upgrades_dir = filesystem_prefix + "/revert";
|
|
||||||
static const string upgrade_status = upgrades_dir + "/upgrade_status";
|
|
||||||
static const string last_known_orchestrator = upgrades_dir + "/last_known_working_orchestrator";
|
|
||||||
static const string upgrade_failure_info_path = upgrades_dir + "/failed_upgrade_info";
|
|
||||||
|
|
||||||
I_DetailsResolver *i_details_resolver = Singleton::Consume<I_DetailsResolver>::by<OrchestrationComp>();
|
|
||||||
|
|
||||||
bool is_upgrade_status_exist = i_orchestration_tools->doesFileExist(upgrade_status);
|
|
||||||
bool is_last_known_orchestrator_exist = i_orchestration_tools->doesFileExist(last_known_orchestrator);
|
|
||||||
|
|
||||||
if (!is_upgrade_status_exist) {
|
|
||||||
if (!is_last_known_orchestrator_exist) {
|
|
||||||
saveLastKnownOrchInfo(i_details_resolver->getAgentVersion());
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto maybe_upgrade_data = i_orchestration_tools->readFile(upgrade_status);
|
|
||||||
string upgrade_data, from_version, to_version;
|
|
||||||
if (maybe_upgrade_data.ok()) {
|
|
||||||
upgrade_data = maybe_upgrade_data.unpack();
|
|
||||||
istringstream stream(upgrade_data);
|
|
||||||
stream >> from_version >> to_version;
|
|
||||||
}
|
|
||||||
i_orchestration_tools->removeFile(upgrade_status);
|
|
||||||
|
|
||||||
if (i_orchestration_tools->doesFileExist(upgrade_failure_info_path)) {
|
|
||||||
string info = "Orchestration revert. ";
|
|
||||||
auto failure_info = i_orchestration_tools->readFile(upgrade_failure_info_path);
|
|
||||||
if (failure_info.ok()) info.append(failure_info.unpack());
|
|
||||||
LogGen(
|
|
||||||
info,
|
|
||||||
ReportIS::Level::ACTION,
|
|
||||||
ReportIS::Audience::INTERNAL,
|
|
||||||
ReportIS::Severity::CRITICAL,
|
|
||||||
ReportIS::Priority::URGENT,
|
|
||||||
ReportIS::Tags::ORCHESTRATOR
|
|
||||||
);
|
|
||||||
dbgError(D_ORCHESTRATOR) <<
|
|
||||||
"Error in orchestration version: " << to_version <<
|
|
||||||
". Orchestration reverted to version: " << i_details_resolver->getAgentVersion();
|
|
||||||
i_orchestration_tools->removeFile(upgrade_failure_info_path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
saveLastKnownOrchInfo(i_details_resolver->getAgentVersion());
|
|
||||||
i_orchestration_tools->writeFile(
|
|
||||||
upgrade_data + "\n",
|
|
||||||
getLogFilesPathConfig() + "/nano_agent/prev_upgrades",
|
|
||||||
true
|
|
||||||
);
|
|
||||||
dbgWarning(D_ORCHESTRATOR) <<
|
|
||||||
"Upgrade process from version: " << from_version <<
|
|
||||||
" to version: " << to_version <<
|
|
||||||
" completed successfully";
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<void>
|
Maybe<void>
|
||||||
registerToTheFog()
|
registerToTheFog()
|
||||||
{
|
{
|
||||||
@ -1144,7 +1022,6 @@ private:
|
|||||||
UpdatesProcessResult::SUCCESS,
|
UpdatesProcessResult::SUCCESS,
|
||||||
UpdatesConfigType::GENERAL
|
UpdatesConfigType::GENERAL
|
||||||
).notify();
|
).notify();
|
||||||
if (!is_first_check_update_success) is_first_check_update_success = true;
|
|
||||||
return Maybe<void>();
|
return Maybe<void>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1465,14 +1342,11 @@ private:
|
|||||||
|
|
||||||
auto nginx_data = i_details_resolver->parseNginxMetadata();
|
auto nginx_data = i_details_resolver->parseNginxMetadata();
|
||||||
if (nginx_data.ok()) {
|
if (nginx_data.ok()) {
|
||||||
string nginx_signature;
|
|
||||||
string nginx_version;
|
string nginx_version;
|
||||||
string config_opt;
|
string config_opt;
|
||||||
string cc_opt;
|
string cc_opt;
|
||||||
tie(config_opt, cc_opt, nginx_version, nginx_signature) = nginx_data.unpack();
|
tie(config_opt, cc_opt, nginx_version) = nginx_data.unpack();
|
||||||
agent_data_report
|
agent_data_report
|
||||||
<< make_pair("attachmentVersion", "Legacy")
|
|
||||||
<< make_pair("nginxSignature", nginx_signature)
|
|
||||||
<< make_pair("nginxVersion", nginx_version)
|
<< make_pair("nginxVersion", nginx_version)
|
||||||
<< make_pair("configureOpt", config_opt)
|
<< make_pair("configureOpt", config_opt)
|
||||||
<< make_pair("extraCompilerOpt", cc_opt);
|
<< make_pair("extraCompilerOpt", cc_opt);
|
||||||
@ -1515,8 +1389,6 @@ private:
|
|||||||
|
|
||||||
agent_data_report << AgentReportFieldWithLabel("userEdition", FogCommunication::getUserEdition());
|
agent_data_report << AgentReportFieldWithLabel("userEdition", FogCommunication::getUserEdition());
|
||||||
|
|
||||||
agent_data_report << make_pair("registeredServer", i_agent_details->getRegisteredServer());
|
|
||||||
|
|
||||||
#if defined(gaia) || defined(smb)
|
#if defined(gaia) || defined(smb)
|
||||||
if (i_details_resolver->compareCheckpointVersion(8100, greater_equal<int>())) {
|
if (i_details_resolver->compareCheckpointVersion(8100, greater_equal<int>())) {
|
||||||
agent_data_report << AgentReportFieldWithLabel("isCheckpointVersionGER81", "true");
|
agent_data_report << AgentReportFieldWithLabel("isCheckpointVersionGER81", "true");
|
||||||
@ -1677,11 +1549,6 @@ private:
|
|||||||
<< LogField("agentType", "Orchestration")
|
<< LogField("agentType", "Orchestration")
|
||||||
<< LogField("agentVersion", Version::get());
|
<< LogField("agentVersion", Version::get());
|
||||||
|
|
||||||
string registered_server = getAttribute("registered-server", "registered_server");
|
|
||||||
dbgTrace(D_ORCHESTRATOR) << "Registered server: " << registered_server;
|
|
||||||
if (!registered_server.empty()) {
|
|
||||||
i_agent_details->setRegisteredServer(registered_server.substr(0, MAX_SERVER_NAME_LENGTH));
|
|
||||||
}
|
|
||||||
auto mainloop = Singleton::Consume<I_MainLoop>::by<OrchestrationComp>();
|
auto mainloop = Singleton::Consume<I_MainLoop>::by<OrchestrationComp>();
|
||||||
mainloop->addOneTimeRoutine(
|
mainloop->addOneTimeRoutine(
|
||||||
I_MainLoop::RoutineType::Offline,
|
I_MainLoop::RoutineType::Offline,
|
||||||
@ -1762,7 +1629,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string server_name = Singleton::Consume<I_AgentDetails>::by<OrchestrationComp>()->getRegisteredServer();
|
string server_name = getAttribute("registered-server", "registered_server");
|
||||||
auto server = TagAndEnumManagement::convertStringToTag(server_name);
|
auto server = TagAndEnumManagement::convertStringToTag(server_name);
|
||||||
if (server_name == "'SWAG'" || server_name == "'SWAG Server'") server = Tags::WEB_SERVER_SWAG;
|
if (server_name == "'SWAG'" || server_name == "'SWAG Server'") server = Tags::WEB_SERVER_SWAG;
|
||||||
if (server.ok()) tags.insert(*server);
|
if (server.ok()) tags.insert(*server);
|
||||||
@ -1786,7 +1653,7 @@ private:
|
|||||||
tags
|
tags
|
||||||
);
|
);
|
||||||
|
|
||||||
registration_report.addToOrigin(LogField("eventCategory", server_name));
|
if (server_name != "") registration_report.addToOrigin(LogField("eventCategory", server_name));
|
||||||
|
|
||||||
auto email = getAttribute("email-address", "user_email");
|
auto email = getAttribute("email-address", "user_email");
|
||||||
if (email != "") registration_report << LogField("userDefinedId", email);
|
if (email != "") registration_report << LogField("userDefinedId", email);
|
||||||
@ -2198,7 +2065,6 @@ private:
|
|||||||
int failure_count = 0;
|
int failure_count = 0;
|
||||||
unsigned int sleep_interval = 0;
|
unsigned int sleep_interval = 0;
|
||||||
bool is_new_success = false;
|
bool is_new_success = false;
|
||||||
bool is_first_check_update_success = false;
|
|
||||||
OrchestrationPolicy policy;
|
OrchestrationPolicy policy;
|
||||||
UpdatesProcessReporter updates_process_reporter_listener;
|
UpdatesProcessReporter updates_process_reporter_listener;
|
||||||
HybridModeMetric hybrid_mode_metric;
|
HybridModeMetric hybrid_mode_metric;
|
||||||
@ -2264,7 +2130,6 @@ OrchestrationComp::preload()
|
|||||||
registerExpectedSetting<vector<string>>("upgradeDay");
|
registerExpectedSetting<vector<string>>("upgradeDay");
|
||||||
registerExpectedSetting<string>("email-address");
|
registerExpectedSetting<string>("email-address");
|
||||||
registerExpectedSetting<string>("registered-server");
|
registerExpectedSetting<string>("registered-server");
|
||||||
registerExpectedSetting<uint>("successUpgradeInterval");
|
|
||||||
registerExpectedConfigFile("orchestration", Config::ConfigFileType::Policy);
|
registerExpectedConfigFile("orchestration", Config::ConfigFileType::Policy);
|
||||||
registerExpectedConfigFile("registration-data", Config::ConfigFileType::Policy);
|
registerExpectedConfigFile("registration-data", Config::ConfigFileType::Policy);
|
||||||
}
|
}
|
||||||
|
@ -89,11 +89,6 @@ public:
|
|||||||
|
|
||||||
EXPECT_CALL(mock_service_controller, isServiceInstalled("Access Control")).WillRepeatedly(Return(false));
|
EXPECT_CALL(mock_service_controller, isServiceInstalled("Access Control")).WillRepeatedly(Return(false));
|
||||||
|
|
||||||
EXPECT_CALL(
|
|
||||||
mock_ml,
|
|
||||||
addOneTimeRoutine(_, _, "Orchestration successfully updated (One-Time After Interval)", true)
|
|
||||||
).WillOnce(DoAll(SaveArg<1>(&upgrade_routine), Return(0)));
|
|
||||||
|
|
||||||
// This Holding the Main Routine of the Orchestration.
|
// This Holding the Main Routine of the Orchestration.
|
||||||
EXPECT_CALL(
|
EXPECT_CALL(
|
||||||
mock_ml,
|
mock_ml,
|
||||||
@ -140,7 +135,7 @@ public:
|
|||||||
void
|
void
|
||||||
expectDetailsResolver()
|
expectDetailsResolver()
|
||||||
{
|
{
|
||||||
Maybe<tuple<string, string, string, string>> no_nginx(genError("No nginx"));
|
Maybe<tuple<string, string, string>> no_nginx(genError("No nginx"));
|
||||||
EXPECT_CALL(mock_details_resolver, getPlatform()).WillRepeatedly(Return(string("linux")));
|
EXPECT_CALL(mock_details_resolver, getPlatform()).WillRepeatedly(Return(string("linux")));
|
||||||
EXPECT_CALL(mock_details_resolver, getArch()).WillRepeatedly(Return(string("x86_64")));
|
EXPECT_CALL(mock_details_resolver, getArch()).WillRepeatedly(Return(string("x86_64")));
|
||||||
EXPECT_CALL(mock_details_resolver, isReverseProxy()).WillRepeatedly(Return(false));
|
EXPECT_CALL(mock_details_resolver, isReverseProxy()).WillRepeatedly(Return(false));
|
||||||
@ -161,7 +156,6 @@ public:
|
|||||||
runRoutine()
|
runRoutine()
|
||||||
{
|
{
|
||||||
routine();
|
routine();
|
||||||
upgrade_routine();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -241,7 +235,6 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
I_MainLoop::Routine routine;
|
I_MainLoop::Routine routine;
|
||||||
I_MainLoop::Routine upgrade_routine;
|
|
||||||
I_MainLoop::Routine status_routine;
|
I_MainLoop::Routine status_routine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,12 +83,6 @@ public:
|
|||||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path)).WillOnce(Return(response));
|
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path)).WillOnce(Return(response));
|
||||||
EXPECT_CALL(mock_status, setFogAddress(host_url)).WillRepeatedly(Return());
|
EXPECT_CALL(mock_status, setFogAddress(host_url)).WillRepeatedly(Return());
|
||||||
EXPECT_CALL(mock_orchestration_tools, setClusterId());
|
EXPECT_CALL(mock_orchestration_tools, setClusterId());
|
||||||
|
|
||||||
EXPECT_CALL(
|
|
||||||
mock_ml,
|
|
||||||
addOneTimeRoutine(_, _, "Orchestration successfully updated (One-Time After Interval)", true)
|
|
||||||
).WillOnce(DoAll(SaveArg<1>(&upgrade_routine), Return(0)));
|
|
||||||
|
|
||||||
EXPECT_CALL(
|
EXPECT_CALL(
|
||||||
mock_ml,
|
mock_ml,
|
||||||
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Orchestration runner", true)
|
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Orchestration runner", true)
|
||||||
@ -168,7 +162,7 @@ public:
|
|||||||
void
|
void
|
||||||
expectDetailsResolver()
|
expectDetailsResolver()
|
||||||
{
|
{
|
||||||
Maybe<tuple<string, string, string, string>> no_nginx(genError("No nginx"));
|
Maybe<tuple<string, string, string>> no_nginx(genError("No nginx"));
|
||||||
EXPECT_CALL(mock_details_resolver, getPlatform()).WillRepeatedly(Return(string("linux")));
|
EXPECT_CALL(mock_details_resolver, getPlatform()).WillRepeatedly(Return(string("linux")));
|
||||||
EXPECT_CALL(mock_details_resolver, getArch()).WillRepeatedly(Return(string("x86_64")));
|
EXPECT_CALL(mock_details_resolver, getArch()).WillRepeatedly(Return(string("x86_64")));
|
||||||
EXPECT_CALL(mock_details_resolver, isReverseProxy()).WillRepeatedly(Return(false));
|
EXPECT_CALL(mock_details_resolver, isReverseProxy()).WillRepeatedly(Return(false));
|
||||||
@ -287,12 +281,6 @@ public:
|
|||||||
status_routine();
|
status_routine();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
runUpgradeRoutine()
|
|
||||||
{
|
|
||||||
upgrade_routine();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
preload()
|
preload()
|
||||||
{
|
{
|
||||||
@ -371,7 +359,6 @@ private:
|
|||||||
|
|
||||||
I_MainLoop::Routine routine;
|
I_MainLoop::Routine routine;
|
||||||
I_MainLoop::Routine status_routine;
|
I_MainLoop::Routine status_routine;
|
||||||
I_MainLoop::Routine upgrade_routine;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -614,6 +601,14 @@ TEST_F(OrchestrationTest, check_sending_registration_data)
|
|||||||
|
|
||||||
string version = "1";
|
string version = "1";
|
||||||
EXPECT_CALL(mock_service_controller, getUpdatePolicyVersion()).WillOnce(ReturnRef(version));
|
EXPECT_CALL(mock_service_controller, getUpdatePolicyVersion()).WillOnce(ReturnRef(version));
|
||||||
|
|
||||||
|
EXPECT_CALL(mock_ml, yield(A<chrono::microseconds>()))
|
||||||
|
.WillOnce(Return())
|
||||||
|
.WillOnce(Invoke([] (chrono::microseconds) { throw invalid_argument("stop while loop"); }));
|
||||||
|
try {
|
||||||
|
runRoutine();
|
||||||
|
} catch (const invalid_argument& e) {}
|
||||||
|
|
||||||
string config_json =
|
string config_json =
|
||||||
"{\n"
|
"{\n"
|
||||||
" \"email-address\": \"fake@example.com\",\n"
|
" \"email-address\": \"fake@example.com\",\n"
|
||||||
@ -622,19 +617,9 @@ TEST_F(OrchestrationTest, check_sending_registration_data)
|
|||||||
|
|
||||||
istringstream ss(config_json);
|
istringstream ss(config_json);
|
||||||
Singleton::Consume<Config::I_Config>::from(config_comp)->loadConfiguration(ss);
|
Singleton::Consume<Config::I_Config>::from(config_comp)->loadConfiguration(ss);
|
||||||
EXPECT_CALL(mock_ml, yield(A<chrono::microseconds>()))
|
|
||||||
.WillOnce(Return())
|
|
||||||
.WillOnce(Invoke([] (chrono::microseconds) { throw invalid_argument("stop while loop"); }));
|
|
||||||
try {
|
|
||||||
runRoutine();
|
|
||||||
} catch (const invalid_argument& e) {}
|
|
||||||
|
|
||||||
|
|
||||||
sending_routine();
|
sending_routine();
|
||||||
|
|
||||||
EXPECT_THAT(message_body, HasSubstr("\"userDefinedId\": \"fake@example.com\""));
|
EXPECT_THAT(message_body, HasSubstr("\"userDefinedId\": \"fake@example.com\""));
|
||||||
EXPECT_THAT(message_body, HasSubstr("\"eventCategory\""));
|
|
||||||
|
|
||||||
EXPECT_THAT(message_body, AnyOf(HasSubstr("\"Embedded Deployment\""), HasSubstr("\"Kubernetes Deployment\"")));
|
EXPECT_THAT(message_body, AnyOf(HasSubstr("\"Embedded Deployment\""), HasSubstr("\"Kubernetes Deployment\"")));
|
||||||
EXPECT_THAT(message_body, HasSubstr("\"NGINX Server\""));
|
EXPECT_THAT(message_body, HasSubstr("\"NGINX Server\""));
|
||||||
}
|
}
|
||||||
@ -1019,11 +1004,6 @@ TEST_F(OrchestrationTest, loadOrchestrationPolicyFromBackup)
|
|||||||
);
|
);
|
||||||
waitForRestCall();
|
waitForRestCall();
|
||||||
|
|
||||||
EXPECT_CALL(
|
|
||||||
mock_ml,
|
|
||||||
addOneTimeRoutine(_, _, "Orchestration successfully updated (One-Time After Interval)", true)
|
|
||||||
);
|
|
||||||
|
|
||||||
EXPECT_CALL(
|
EXPECT_CALL(
|
||||||
mock_ml,
|
mock_ml,
|
||||||
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Orchestration runner", true)
|
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Orchestration runner", true)
|
||||||
@ -1190,29 +1170,6 @@ TEST_F(OrchestrationTest, manifestUpdate)
|
|||||||
try {
|
try {
|
||||||
runRoutine();
|
runRoutine();
|
||||||
} catch (const invalid_argument& e) {}
|
} catch (const invalid_argument& e) {}
|
||||||
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/upgrade_status")).WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/last_known_working_orchestrator"))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
|
|
||||||
Maybe<string> upgrade_status(string("1.1.1 1.1.2 2025-01-28 07:53:23"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, readFile("/etc/cp/revert/upgrade_status"))
|
|
||||||
.WillOnce(Return(upgrade_status));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, removeFile("/etc/cp/revert/upgrade_status")).WillOnce(Return(true));
|
|
||||||
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/revert/failed_upgrade_info"))
|
|
||||||
.WillOnce(Return(false));
|
|
||||||
|
|
||||||
EXPECT_CALL(mock_details_resolver, getAgentVersion()).WillRepeatedly(Return("1.1.2"));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, copyFile(_, "/etc/cp/revert/last_known_working_orchestrator"))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(mock_orchestration_tools, copyFile(_, "/etc/cp/revert/last_known_manifest")).WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(
|
|
||||||
mock_orchestration_tools,
|
|
||||||
writeFile("1.1.1 1.1.2 2025-01-28 07:53:23\n", "/var/log/nano_agent/prev_upgrades", true)
|
|
||||||
).WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(mock_ml, yield(A<chrono::microseconds>())).WillOnce(Return());
|
|
||||||
runUpgradeRoutine();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OrchestrationTest, getBadPolicyUpdate)
|
TEST_F(OrchestrationTest, getBadPolicyUpdate)
|
||||||
|
@ -208,7 +208,6 @@ ServiceDetails::sendNewConfigurations(int configuration_id, const string &policy
|
|||||||
MessageMetadata new_config_req_md("127.0.0.1", service_port);
|
MessageMetadata new_config_req_md("127.0.0.1", service_port);
|
||||||
new_config_req_md.setConnectioFlag(MessageConnectionConfig::ONE_TIME_CONN);
|
new_config_req_md.setConnectioFlag(MessageConnectionConfig::ONE_TIME_CONN);
|
||||||
new_config_req_md.setConnectioFlag(MessageConnectionConfig::UNSECURE_CONN);
|
new_config_req_md.setConnectioFlag(MessageConnectionConfig::UNSECURE_CONN);
|
||||||
new_config_req_md.setSuspension(false);
|
|
||||||
auto res = messaging->sendSyncMessage(
|
auto res = messaging->sendSyncMessage(
|
||||||
HTTPMethod::POST,
|
HTTPMethod::POST,
|
||||||
"/set-new-configuration",
|
"/set-new-configuration",
|
||||||
|
@ -168,12 +168,10 @@ FogAuthenticator::registerAgent(
|
|||||||
auto nginx_data = details_resolver->parseNginxMetadata();
|
auto nginx_data = details_resolver->parseNginxMetadata();
|
||||||
|
|
||||||
if (nginx_data.ok()) {
|
if (nginx_data.ok()) {
|
||||||
string nginx_signature;
|
|
||||||
string nginx_version;
|
string nginx_version;
|
||||||
string config_opt;
|
string config_opt;
|
||||||
string cc_opt;
|
string cc_opt;
|
||||||
tie(config_opt, cc_opt, nginx_version, nginx_signature) = nginx_data.unpack();
|
tie(config_opt, cc_opt, nginx_version) = nginx_data.unpack();
|
||||||
request << make_pair("nginxSignature", nginx_signature);
|
|
||||||
request << make_pair("nginxVersion", nginx_version);
|
request << make_pair("nginxVersion", nginx_version);
|
||||||
request << make_pair("configureOpt", config_opt);
|
request << make_pair("configureOpt", config_opt);
|
||||||
request << make_pair("extraCompilerOpt", cc_opt);
|
request << make_pair("extraCompilerOpt", cc_opt);
|
||||||
@ -379,13 +377,9 @@ FogAuthenticator::registerLocalAgentToFog()
|
|||||||
{
|
{
|
||||||
auto local_reg_token = getRegistrationToken();
|
auto local_reg_token = getRegistrationToken();
|
||||||
if (!local_reg_token.ok()) return;
|
if (!local_reg_token.ok()) return;
|
||||||
|
|
||||||
string reg_token = local_reg_token.unpack().getData();
|
|
||||||
if (reg_token.empty()) return;
|
|
||||||
|
|
||||||
dbgInfo(D_ORCHESTRATOR) << "Start local agent registration to the fog";
|
dbgInfo(D_ORCHESTRATOR) << "Start local agent registration to the fog";
|
||||||
|
|
||||||
string exec_command = "open-appsec-ctl --set-mode --online_mode --token " + reg_token;
|
string exec_command = "open-appsec-ctl --set-mode --online_mode --token " + local_reg_token.unpack().getData();
|
||||||
|
|
||||||
auto i_agent_details = Singleton::Consume<I_AgentDetails>::by<FogAuthenticator>();
|
auto i_agent_details = Singleton::Consume<I_AgentDetails>::by<FogAuthenticator>();
|
||||||
auto fog_address = i_agent_details->getFogDomain();
|
auto fog_address = i_agent_details->getFogDomain();
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
add_library(prometheus_comp prometheus_comp.cc)
|
|
||||||
add_subdirectory(prometheus_ut)
|
|
@ -1,200 +0,0 @@
|
|||||||
#include "prometheus_comp.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include <cereal/types/map.hpp>
|
|
||||||
#include <cereal/types/vector.hpp>
|
|
||||||
#include <cereal/types/string.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "report/base_field.h"
|
|
||||||
#include "report/report_enums.h"
|
|
||||||
#include "log_generator.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "rest.h"
|
|
||||||
#include "customized_cereal_map.h"
|
|
||||||
#include "i_messaging.h"
|
|
||||||
#include "prometheus_metric_names.h"
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_PROMETHEUS);
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace ReportIS;
|
|
||||||
|
|
||||||
struct ServiceData
|
|
||||||
{
|
|
||||||
template <typename Archive>
|
|
||||||
void
|
|
||||||
serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(cereal::make_nvp("Service port", service_port));
|
|
||||||
}
|
|
||||||
|
|
||||||
int service_port;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PrometheusMetricData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PrometheusMetricData(const string &n, const string &t, const string &d) : name(n), type(t), description(d) {}
|
|
||||||
|
|
||||||
void
|
|
||||||
addElement(const string &labels, const string &value)
|
|
||||||
{
|
|
||||||
metric_labels_to_values[labels] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ostream &
|
|
||||||
print(ostream &os)
|
|
||||||
{
|
|
||||||
if (metric_labels_to_values.empty()) return os;
|
|
||||||
|
|
||||||
string representative_name = "";
|
|
||||||
if (!name.empty()) {
|
|
||||||
auto metric_name = convertMetricName(name);
|
|
||||||
!metric_name.empty() ? representative_name = metric_name : representative_name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!description.empty()) os << "# HELP " << representative_name << ' ' << description << '\n';
|
|
||||||
if (!name.empty()) os << "# TYPE " << representative_name << ' ' << type << '\n';
|
|
||||||
for (auto &entry : metric_labels_to_values) {
|
|
||||||
os << representative_name << entry.first << ' ' << entry.second << '\n';
|
|
||||||
}
|
|
||||||
os << '\n';
|
|
||||||
metric_labels_to_values.clear();
|
|
||||||
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
string name;
|
|
||||||
string type;
|
|
||||||
string description;
|
|
||||||
map<string, string> metric_labels_to_values;
|
|
||||||
};
|
|
||||||
|
|
||||||
static ostream & operator<<(ostream &os, PrometheusMetricData &metric) { return metric.print(os); }
|
|
||||||
|
|
||||||
class PrometheusComp::Impl
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void
|
|
||||||
init()
|
|
||||||
{
|
|
||||||
Singleton::Consume<I_RestApi>::by<PrometheusComp>()->addGetCall(
|
|
||||||
"metrics",
|
|
||||||
[&] () { return getFormatedPrometheusMetrics(); }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
addMetrics(const vector<PrometheusData> &metrics)
|
|
||||||
{
|
|
||||||
for(auto &metric : metrics) {
|
|
||||||
auto &metric_object = getDataObject(
|
|
||||||
metric.name,
|
|
||||||
metric.type,
|
|
||||||
metric.description
|
|
||||||
);
|
|
||||||
metric_object.addElement(metric.label, metric.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PrometheusMetricData &
|
|
||||||
getDataObject(const string &name, const string &type, const string &description)
|
|
||||||
{
|
|
||||||
auto elem = prometheus_metrics.find(name);
|
|
||||||
if (elem == prometheus_metrics.end()) {
|
|
||||||
elem = prometheus_metrics.emplace(name, PrometheusMetricData(name, type, description)).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
return elem->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
map<string, ServiceData>
|
|
||||||
getServiceDetails()
|
|
||||||
{
|
|
||||||
map<string, ServiceData> registeredServices;
|
|
||||||
auto registered_services_file = getConfigurationWithDefault<string>(
|
|
||||||
getFilesystemPathConfig() + "/conf/orchestrations_registered_services.json",
|
|
||||||
"orchestration",
|
|
||||||
"Orchestration registered services"
|
|
||||||
);
|
|
||||||
ifstream file(registered_services_file);
|
|
||||||
if (!file.is_open()) {
|
|
||||||
dbgWarning(D_PROMETHEUS) << "Failed to open file: " << registered_services_file;
|
|
||||||
return registeredServices;
|
|
||||||
}
|
|
||||||
stringstream buffer;
|
|
||||||
buffer << file.rdbuf();
|
|
||||||
try {
|
|
||||||
cereal::JSONInputArchive archive(buffer);
|
|
||||||
archive(cereal::make_nvp("Registered Services", registeredServices));
|
|
||||||
} catch (const exception& e) {
|
|
||||||
dbgWarning(D_PROMETHEUS) << "Error parsing Registered Services JSON file: " << e.what();
|
|
||||||
}
|
|
||||||
|
|
||||||
return registeredServices;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
getServicesMetrics()
|
|
||||||
{
|
|
||||||
dbgTrace(D_PROMETHEUS) << "Get all registered services metrics";
|
|
||||||
map<string, ServiceData> service_names_to_ports = getServiceDetails();
|
|
||||||
for (const auto &service : service_names_to_ports) {
|
|
||||||
I_Messaging *messaging = Singleton::Consume<I_Messaging>::by<PrometheusComp>();
|
|
||||||
MessageMetadata servie_metric_req_md("127.0.0.1", service.second.service_port);
|
|
||||||
servie_metric_req_md.setConnectioFlag(MessageConnectionConfig::ONE_TIME_CONN);
|
|
||||||
servie_metric_req_md.setConnectioFlag(MessageConnectionConfig::UNSECURE_CONN);
|
|
||||||
auto res = messaging->sendSyncMessage(
|
|
||||||
HTTPMethod::GET,
|
|
||||||
"/service-metrics",
|
|
||||||
string(""),
|
|
||||||
MessageCategory::GENERIC,
|
|
||||||
servie_metric_req_md
|
|
||||||
);
|
|
||||||
if (!res.ok()) {
|
|
||||||
dbgWarning(D_PROMETHEUS) << "Failed to get service metrics. Service: " << service.first;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stringstream buffer;
|
|
||||||
buffer << res.unpack().getBody();
|
|
||||||
cereal::JSONInputArchive archive(buffer);
|
|
||||||
vector<PrometheusData> metrics;
|
|
||||||
archive(cereal::make_nvp("metrics", metrics));
|
|
||||||
addMetrics(metrics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string
|
|
||||||
getFormatedPrometheusMetrics()
|
|
||||||
{
|
|
||||||
MetricScrapeEvent().notify();
|
|
||||||
getServicesMetrics();
|
|
||||||
stringstream result;
|
|
||||||
for (auto &metric : prometheus_metrics) {
|
|
||||||
result << metric.second;
|
|
||||||
}
|
|
||||||
dbgTrace(D_PROMETHEUS) << "Prometheus metrics: " << result.str();
|
|
||||||
return result.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
map<string, PrometheusMetricData> prometheus_metrics;
|
|
||||||
};
|
|
||||||
|
|
||||||
PrometheusComp::PrometheusComp() : Component("Prometheus"), pimpl(make_unique<Impl>()) {}
|
|
||||||
|
|
||||||
PrometheusComp::~PrometheusComp() {}
|
|
||||||
|
|
||||||
void
|
|
||||||
PrometheusComp::init()
|
|
||||||
{
|
|
||||||
pimpl->init();
|
|
||||||
}
|
|
@ -1,143 +0,0 @@
|
|||||||
#ifndef __PROMETHEUS_METRIC_NAMES_H__
|
|
||||||
#define __PROMETHEUS_METRIC_NAMES_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_PROMETHEUS);
|
|
||||||
|
|
||||||
std::string
|
|
||||||
convertMetricName(const std::string &original_metric_name)
|
|
||||||
{
|
|
||||||
static const std::unordered_map<std::string, std::string> original_to_representative_names = {
|
|
||||||
// HybridModeMetric
|
|
||||||
{"watchdogProcessStartupEventsSum", "nano_service_restarts_counter"},
|
|
||||||
// nginxAttachmentMetric
|
|
||||||
{"inspectVerdictSum", "traffic_inspection_verdict_inspect_counter"},
|
|
||||||
{"acceptVeridctSum", "traffic_inspection_verdict_accept_counter"},
|
|
||||||
{"dropVerdictSum", "traffic_inspection_verdict_drop_counter"},
|
|
||||||
{"injectVerdictSum", "traffic_inspection_verdict_inject_counter"},
|
|
||||||
{"irrelevantVerdictSum", "traffic_inspection_verdict_irrelevant_counter"},
|
|
||||||
{"irrelevantVerdictSum", "traffic_inspection_verdict_irrelevant_counter"},
|
|
||||||
{"reconfVerdictSum", "traffic_inspection_verdict_reconf_counter"},
|
|
||||||
{"responseInspection", "response_body_inspection_counter"},
|
|
||||||
// nginxIntakerMetric
|
|
||||||
{"successfullInspectionTransactionsSum", "successful_Inspection_counter"},
|
|
||||||
{"failopenTransactionsSum", "fail_open_Inspection_counter"},
|
|
||||||
{"failcloseTransactionsSum", "fail_close_Inspection_counter"},
|
|
||||||
{"transparentModeTransactionsSum", "transparent_mode_counter"},
|
|
||||||
{"totalTimeInTransparentModeSum", "total_time_in_transparent_mode_counter"},
|
|
||||||
{"reachInspectVerdictSum", "inspect_verdict_counter"},
|
|
||||||
{"reachAcceptVerdictSum", "accept_verdict_counter"},
|
|
||||||
{"reachDropVerdictSum", "drop_verdict_counter"},
|
|
||||||
{"reachInjectVerdictSum", "inject_verdict_counter"},
|
|
||||||
{"reachIrrelevantVerdictSum", "irrelevant_verdict_counter"},
|
|
||||||
{"reachReconfVerdictSum", "reconf_verdict_counter"},
|
|
||||||
{"requestCompressionFailureSum", "failed_requests_compression_counter"},
|
|
||||||
{"responseCompressionFailureSum", "failed_response_compression_counter"},
|
|
||||||
{"requestDecompressionFailureSum", "failed_requests_decompression_counter"},
|
|
||||||
{"responseDecompressionFailureSum", "failed_response_decompression_counter"},
|
|
||||||
{"requestCompressionSuccessSum", "successful_request_compression_counter"},
|
|
||||||
{"responseCompressionSuccessSum", "successful_response_compression_counter"},
|
|
||||||
{"requestDecompressionSuccessSum", "successful_request_decompression_counter"},
|
|
||||||
{"responseDecompressionSuccessSum", "successful_response_decompression_counter"},
|
|
||||||
{"skippedSessionsUponCorruptedZipSum", "corrupted_zip_skipped_session_counter"},
|
|
||||||
{"attachmentThreadReachedTimeoutSum", "thread_exceeded_processing_time_counter"},
|
|
||||||
{"registrationThreadReachedTimeoutSum", "failed_registration_thread_counter"},
|
|
||||||
{"requestHeaderThreadReachedTimeoutSum", "request_headers_processing_thread_timeouts_counter"},
|
|
||||||
{"requestBodyThreadReachedTimeoutSum", "request_body_processing_thread_timeouts_counter"},
|
|
||||||
{"respondHeaderThreadReachedTimeoutSum", "response_headers_processing_thread_timeouts_counter"},
|
|
||||||
{"respondBodyThreadReachedTimeoutSum", "response_body_processing_thread_timeouts_counter"},
|
|
||||||
{"attachmentThreadFailureSum", "thread_failures_counter"},
|
|
||||||
{"httpRequestProcessingReachedTimeoutSum", "request_processing_timeouts_counter"},
|
|
||||||
{"httpRequestsSizeSum", "requests_total_size_counter"},
|
|
||||||
{"httpResponsesSizeSum", "response_total_size_counter"},
|
|
||||||
{"httpRequestFailedToReachWebServerUpstreamSum", "requests_failed_reach_upstram_counter"},
|
|
||||||
{"overallSessionProcessTimeToVerdictAvgSample", "overall_processing_time_until_verdict_average"},
|
|
||||||
{"overallSessionProcessTimeToVerdictMaxSample", "overall_processing_time_until_verdict_max"},
|
|
||||||
{"overallSessionProcessTimeToVerdictMinSample", "overall_processing_time_until_verdict_min"},
|
|
||||||
{"requestProcessTimeToVerdictAvgSample", "requests_processing_time_until_verdict_average"},
|
|
||||||
{"requestProcessTimeToVerdictMaxSample", "requests_processing_time_until_verdict_max"},
|
|
||||||
{"requestProcessTimeToVerdictMinSample", "requests_processing_time_until_verdict_min"},
|
|
||||||
{"responseProcessTimeToVerdictAvgSample", "response_processing_time_until_verdict_average"},
|
|
||||||
{"responseProcessTimeToVerdictMaxSample", "response_processing_time_until_verdict_max"},
|
|
||||||
{"responseProcessTimeToVerdictMinSample", "response_processing_time_until_verdict_min"},
|
|
||||||
{"requestBodySizeUponTimeoutAvgSample", "request_body_size_average"},
|
|
||||||
{"requestBodySizeUponTimeoutMaxSample", "request_body_size_max"},
|
|
||||||
{"requestBodySizeUponTimeoutMinSample", "request_body_size_min"},
|
|
||||||
{"responseBodySizeUponTimeoutAvgSample", "response_body_size_average"},
|
|
||||||
{"responseBodySizeUponTimeoutMaxSample", "response_body_size_max"},
|
|
||||||
{"responseBodySizeUponTimeoutMinSample", "response_body_size_min"},
|
|
||||||
// WaapTelemetrics
|
|
||||||
{"reservedNgenA", "total_requests_counter"},
|
|
||||||
{"reservedNgenB", "unique_sources_counter"},
|
|
||||||
{"reservedNgenC", "requests_blocked_by_force_and_exception_counter"},
|
|
||||||
{"reservedNgenD", "requests_blocked_by_waf_counter"},
|
|
||||||
{"reservedNgenE", "requests_blocked_by_open_api_counter"},
|
|
||||||
{"reservedNgenF", "requests_blocked_by_bot_protection_counter"},
|
|
||||||
{"reservedNgenG", "requests_threat_level_info_and_no_threat_counter"},
|
|
||||||
{"reservedNgenH", "requests_threat_level_low_counter"},
|
|
||||||
{"reservedNgenI", "requests_threat_level_medium_counter"},
|
|
||||||
{"reservedNgenJ", "requests_threat_level_high_counter"},
|
|
||||||
// WaapTrafficTelemetrics
|
|
||||||
{"reservedNgenA", "post_requests_counter"},
|
|
||||||
{"reservedNgenB", "get_requests_counter"},
|
|
||||||
{"reservedNgenC", "put_requests_counter"},
|
|
||||||
{"reservedNgenD", "patch_requests_counter"},
|
|
||||||
{"reservedNgenE", "delete_requests_counter"},
|
|
||||||
{"reservedNgenF", "other_requests_counter"},
|
|
||||||
{"reservedNgenG", "2xx_status_code_responses_counter"},
|
|
||||||
{"reservedNgenH", "4xx_status_code_responses_counter"},
|
|
||||||
{"reservedNgenI", "5xx_status_code_responses_counter"},
|
|
||||||
{"reservedNgenJ", "requests_time_latency_average"},
|
|
||||||
// WaapAttackTypesMetrics
|
|
||||||
{"reservedNgenA", "sql_injection_attacks_type_counter"},
|
|
||||||
{"reservedNgenB", "vulnerability_scanning_attacks_type_counter"},
|
|
||||||
{"reservedNgenC", "path_traversal_attacks_type_counter"},
|
|
||||||
{"reservedNgenD", "ldap_injection_attacks_type_counter"},
|
|
||||||
{"reservedNgenE", "evasion_techniques_attacks_type_counter"},
|
|
||||||
{"reservedNgenF", "remote_code_execution_attacks_type_counter"},
|
|
||||||
{"reservedNgenG", "xml_extern_entity_attacks_type_counter"},
|
|
||||||
{"reservedNgenH", "cross_site_scripting_attacks_type_counter"},
|
|
||||||
{"reservedNgenI", "general_attacks_type_counter"},
|
|
||||||
// AssetsMetric
|
|
||||||
{"numberOfProtectedApiAssetsSample", "api_assets_counter"},
|
|
||||||
{"numberOfProtectedWebAppAssetsSample", "web_api_assets_counter"},
|
|
||||||
{"numberOfProtectedAssetsSample", "all_assets_counter"},
|
|
||||||
// IPSMetric
|
|
||||||
{"preventEngineMatchesSample", "prevent_action_matches_counter"},
|
|
||||||
{"detectEngineMatchesSample", "detect_action_matches_counter"},
|
|
||||||
{"ignoreEngineMatchesSample", "ignore_action_matches_counter"},
|
|
||||||
// CPUMetric
|
|
||||||
{"cpuMaxSample", "cpu_usage_percentage_max"},
|
|
||||||
{"cpuAvgSample", "cpu_usage_percentage_average"},
|
|
||||||
{"cpuSample", "cpu_usage_percentage_last_value"},
|
|
||||||
// LogMetric
|
|
||||||
{"logQueueMaxSizeSample", "logs_queue_size_max"},
|
|
||||||
{"logQueueAvgSizeSample", "logs_queue_size_average"},
|
|
||||||
{"logQueueCurrentSizeSample", "logs_queue_size_last_value"},
|
|
||||||
{"sentLogsSum", "logs_sent_counter"},
|
|
||||||
{"sentLogsBulksSum", "bulk_logs_sent_counter"},
|
|
||||||
// MemoryMetric
|
|
||||||
{"serviceVirtualMemorySizeMaxSample", "service_virtual_memory_size_kb_max"},
|
|
||||||
{"serviceVirtualMemorySizeMinSample", "service_virtual_memory_size_kb_min"},
|
|
||||||
{"serviceVirtualMemorySizeAvgSample", "service_virtual_memory_size_kb_average"},
|
|
||||||
{"serviceRssMemorySizeMaxSample", "service_physical_memory_size_kb_max"},
|
|
||||||
{"serviceRssMemorySizeMinSample", "service_physical_memory_size_kb_min"},
|
|
||||||
{"serviceRssMemorySizeAvgSample", "service_physical_memory_size_kb_average"},
|
|
||||||
{"generalTotalMemorySizeMaxSample", "general_total_used_memory_max"},
|
|
||||||
{"generalTotalMemorySizeMinSample", "general_total_used_memory_min"},
|
|
||||||
{"generalTotalMemorySizeAvgSample", "general_total_used_memory_average"},
|
|
||||||
};
|
|
||||||
|
|
||||||
auto metric_names = original_to_representative_names.find(original_metric_name);
|
|
||||||
if (metric_names != original_to_representative_names.end()) return metric_names->second;
|
|
||||||
dbgDebug(D_PROMETHEUS)
|
|
||||||
<< "Metric don't have a representative name, originl name: "
|
|
||||||
<< original_metric_name;
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __PROMETHEUS_METRIC_NAMES_H__
|
|
@ -1,8 +0,0 @@
|
|||||||
link_directories(${BOOST_ROOT}/lib)
|
|
||||||
link_directories(${BOOST_ROOT}/lib ${CMAKE_BINARY_DIR}/core/shmem_ipc)
|
|
||||||
|
|
||||||
add_unit_test(
|
|
||||||
prometheus_ut
|
|
||||||
"prometheus_ut.cc"
|
|
||||||
"prometheus_comp;logging;agent_details;waap_clib;table;singleton;time_proxy;metric;event_is;connkey;http_transaction_data;generic_rulebase;generic_rulebase_evaluators;ip_utilities;intelligence_is_v2;-lboost_regex;messaging;"
|
|
||||||
)
|
|
@ -1,79 +0,0 @@
|
|||||||
#include "prometheus_comp.h"
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "cmock.h"
|
|
||||||
#include "cptest.h"
|
|
||||||
#include "maybe_res.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "environment.h"
|
|
||||||
#include "config_component.h"
|
|
||||||
#include "agent_details.h"
|
|
||||||
#include "time_proxy.h"
|
|
||||||
#include "mock/mock_mainloop.h"
|
|
||||||
#include "mock/mock_rest_api.h"
|
|
||||||
#include "mock/mock_messaging.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace testing;
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_PROMETHEUS);
|
|
||||||
|
|
||||||
class PrometheusCompTest : public Test
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PrometheusCompTest()
|
|
||||||
{
|
|
||||||
EXPECT_CALL(mock_rest, mockRestCall(_, "declare-boolean-variable", _)).WillOnce(Return(false));
|
|
||||||
env.preload();
|
|
||||||
config.preload();
|
|
||||||
env.init();
|
|
||||||
|
|
||||||
EXPECT_CALL(
|
|
||||||
mock_rest,
|
|
||||||
addGetCall("metrics", _)
|
|
||||||
).WillOnce(DoAll(SaveArg<1>(&get_metrics_func), Return(true)));
|
|
||||||
|
|
||||||
prometheus_comp.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
::Environment env;
|
|
||||||
ConfigComponent config;
|
|
||||||
PrometheusComp prometheus_comp;
|
|
||||||
StrictMock<MockRestApi> mock_rest;
|
|
||||||
StrictMock<MockMainLoop> mock_ml;
|
|
||||||
NiceMock<MockMessaging> mock_messaging;
|
|
||||||
unique_ptr<ServerRest> agent_uninstall;
|
|
||||||
function<string()> get_metrics_func;
|
|
||||||
CPTestTempfile status_file;
|
|
||||||
string registered_services_file_path;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F(PrometheusCompTest, checkAddingMetric)
|
|
||||||
{
|
|
||||||
registered_services_file_path = cptestFnameInSrcDir(string("registered_services.json"));
|
|
||||||
setConfiguration(registered_services_file_path, "orchestration", "Orchestration registered services");
|
|
||||||
string metric_body = "{\n"
|
|
||||||
" \"metrics\": [\n"
|
|
||||||
" {\n"
|
|
||||||
" \"metric_name\": \"watchdogProcessStartupEventsSum\",\n"
|
|
||||||
" \"metric_type\": \"counter\",\n"
|
|
||||||
" \"metric_description\": \"\",\n"
|
|
||||||
" \"labels\": \"{method=\\\"post\\\",code=\\\"200\\\"}\",\n"
|
|
||||||
" \"value\": \"1534\"\n"
|
|
||||||
" }\n"
|
|
||||||
" ]\n"
|
|
||||||
"}";
|
|
||||||
|
|
||||||
string message_body;
|
|
||||||
EXPECT_CALL(mock_messaging, sendSyncMessage(_, "/service-metrics", _, _, _))
|
|
||||||
.Times(2).WillRepeatedly(Return(HTTPResponse(HTTPStatusCode::HTTP_OK, metric_body)));
|
|
||||||
|
|
||||||
string metric_str = "# TYPE nano_service_restarts_counter counter\n"
|
|
||||||
"nano_service_restarts_counter{method=\"post\",code=\"200\"} 1534\n\n";
|
|
||||||
EXPECT_EQ(metric_str, get_metrics_func());
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"Registered Services": {
|
|
||||||
"cp-nano-orchestration": {
|
|
||||||
"Service name": "cp-nano-orchestration",
|
|
||||||
"Service ID": "cp-nano-orchestration",
|
|
||||||
"Service port": 7777,
|
|
||||||
"Relevant configs": [
|
|
||||||
"zones",
|
|
||||||
"triggers",
|
|
||||||
"rules",
|
|
||||||
"registration-data",
|
|
||||||
"parameters",
|
|
||||||
"orchestration",
|
|
||||||
"exceptions",
|
|
||||||
"agent-intelligence"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"cp-nano-prometheus": {
|
|
||||||
"Service name": "cp-nano-prometheus",
|
|
||||||
"Service ID": "cp-nano-prometheus",
|
|
||||||
"Service port": 7465,
|
|
||||||
"Relevant configs": [
|
|
||||||
"zones",
|
|
||||||
"triggers",
|
|
||||||
"rules",
|
|
||||||
"parameters",
|
|
||||||
"exceptions",
|
|
||||||
"agent-intelligence"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -137,13 +137,9 @@ public:
|
|||||||
void setRemoteSyncEnabled(bool enabled);
|
void setRemoteSyncEnabled(bool enabled);
|
||||||
protected:
|
protected:
|
||||||
void mergeProcessedFromRemote();
|
void mergeProcessedFromRemote();
|
||||||
std::string getWindowId();
|
|
||||||
void waitSync();
|
|
||||||
std::string getPostDataUrl();
|
std::string getPostDataUrl();
|
||||||
std::string getUri();
|
std::string getUri();
|
||||||
size_t getIntervalsCount();
|
size_t getIntervalsCount();
|
||||||
void incrementIntervalsCount();
|
|
||||||
bool isBase();
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool sendObject(T &obj, HTTPMethod method, std::string uri)
|
bool sendObject(T &obj, HTTPMethod method, std::string uri)
|
||||||
@ -256,13 +252,14 @@ protected:
|
|||||||
const std::string m_remotePath; // Created from tenentId + / + assetId + / + class
|
const std::string m_remotePath; // Created from tenentId + / + assetId + / + class
|
||||||
std::chrono::seconds m_interval;
|
std::chrono::seconds m_interval;
|
||||||
std::string m_owner;
|
std::string m_owner;
|
||||||
const std::string m_assetId;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool localSyncAndProcess();
|
bool localSyncAndProcess();
|
||||||
void updateStateFromRemoteService();
|
void updateStateFromRemoteService();
|
||||||
RemoteFilesList getProcessedFilesList();
|
RemoteFilesList getProcessedFilesList();
|
||||||
RemoteFilesList getRemoteProcessedFilesList();
|
RemoteFilesList getRemoteProcessedFilesList();
|
||||||
|
std::string getWindowId();
|
||||||
|
bool isBase();
|
||||||
std::string getLearningHost();
|
std::string getLearningHost();
|
||||||
std::string getSharedStorageHost();
|
std::string getSharedStorageHost();
|
||||||
|
|
||||||
@ -273,6 +270,7 @@ private:
|
|||||||
size_t m_windowsCount;
|
size_t m_windowsCount;
|
||||||
size_t m_intervalsCounter;
|
size_t m_intervalsCounter;
|
||||||
bool m_remoteSyncEnabled;
|
bool m_remoteSyncEnabled;
|
||||||
|
const std::string m_assetId;
|
||||||
const bool m_isAssetIdUuid;
|
const bool m_isAssetIdUuid;
|
||||||
std::string m_type;
|
std::string m_type;
|
||||||
std::string m_lastProcessedModified;
|
std::string m_lastProcessedModified;
|
||||||
|
@ -19,14 +19,12 @@
|
|||||||
#include "../waap_clib/WaapParameters.h"
|
#include "../waap_clib/WaapParameters.h"
|
||||||
#include "../waap_clib/WaapOpenRedirectPolicy.h"
|
#include "../waap_clib/WaapOpenRedirectPolicy.h"
|
||||||
#include "../waap_clib/WaapErrorDisclosurePolicy.h"
|
#include "../waap_clib/WaapErrorDisclosurePolicy.h"
|
||||||
#include "../waap_clib/DecisionType.h"
|
|
||||||
#include "../waap_clib/CsrfPolicy.h"
|
#include "../waap_clib/CsrfPolicy.h"
|
||||||
#include "../waap_clib/UserLimitsPolicy.h"
|
#include "../waap_clib/UserLimitsPolicy.h"
|
||||||
#include "../waap_clib/RateLimiting.h"
|
#include "../waap_clib/RateLimiting.h"
|
||||||
#include "../waap_clib/SecurityHeadersPolicy.h"
|
#include "../waap_clib/SecurityHeadersPolicy.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
enum class BlockingLevel {
|
enum class BlockingLevel {
|
||||||
NO_BLOCKING = 0,
|
NO_BLOCKING = 0,
|
||||||
LOW_BLOCKING_LEVEL,
|
LOW_BLOCKING_LEVEL,
|
||||||
@ -46,8 +44,8 @@ public:
|
|||||||
virtual const std::string& get_AssetId() const = 0;
|
virtual const std::string& get_AssetId() const = 0;
|
||||||
virtual const std::string& get_AssetName() const = 0;
|
virtual const std::string& get_AssetName() const = 0;
|
||||||
virtual const BlockingLevel& get_BlockingLevel() const = 0;
|
virtual const BlockingLevel& get_BlockingLevel() const = 0;
|
||||||
virtual const std::string& get_PracticeIdByPactice(DecisionType practiceType) const = 0;
|
virtual const std::string& get_PracticeId() const = 0;
|
||||||
virtual const std::string& get_PracticeNameByPactice(DecisionType practiceType) const = 0;
|
virtual const std::string& get_PracticeName() const = 0;
|
||||||
virtual const std::string& get_PracticeSubType() const = 0;
|
virtual const std::string& get_PracticeSubType() const = 0;
|
||||||
virtual const std::string& get_RuleId() const = 0;
|
virtual const std::string& get_RuleId() const = 0;
|
||||||
virtual const std::string& get_RuleName() const = 0;
|
virtual const std::string& get_RuleName() const = 0;
|
||||||
|
@ -91,7 +91,6 @@ add_library(waap_clib
|
|||||||
ParserScreenedJson.cc
|
ParserScreenedJson.cc
|
||||||
ParserBinaryFile.cc
|
ParserBinaryFile.cc
|
||||||
RegexComparator.cc
|
RegexComparator.cc
|
||||||
RequestsMonitor.cc
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_definitions("-Wno-unused-function")
|
add_definitions("-Wno-unused-function")
|
||||||
|
@ -41,7 +41,6 @@ static in6_addr applyMaskV6(const in6_addr& addr, uint8_t prefixLength) {
|
|||||||
in6_addr maskedAddr = addr;
|
in6_addr maskedAddr = addr;
|
||||||
int fullBytes = prefixLength / 8;
|
int fullBytes = prefixLength / 8;
|
||||||
int remainingBits = prefixLength % 8;
|
int remainingBits = prefixLength % 8;
|
||||||
uint8_t partialByte = maskedAddr.s6_addr[fullBytes];
|
|
||||||
|
|
||||||
// Mask full bytes
|
// Mask full bytes
|
||||||
for (int i = fullBytes; i < 16; ++i) {
|
for (int i = fullBytes; i < 16; ++i) {
|
||||||
@ -51,7 +50,7 @@ static in6_addr applyMaskV6(const in6_addr& addr, uint8_t prefixLength) {
|
|||||||
// Mask remaining bits
|
// Mask remaining bits
|
||||||
if (remainingBits > 0) {
|
if (remainingBits > 0) {
|
||||||
uint8_t mask = ~((1 << (8 - remainingBits)) - 1);
|
uint8_t mask = ~((1 << (8 - remainingBits)) - 1);
|
||||||
maskedAddr.s6_addr[fullBytes] = partialByte & mask;
|
maskedAddr.s6_addr[fullBytes] &= mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
return maskedAddr;
|
return maskedAddr;
|
||||||
|
@ -113,9 +113,6 @@ DeepParser::onKv(const char *k, size_t k_len, const char *v, size_t v_len, int f
|
|||||||
<< parser_depth
|
<< parser_depth
|
||||||
<< " v_len = "
|
<< " v_len = "
|
||||||
<< v_len;
|
<< v_len;
|
||||||
|
|
||||||
dbgTrace(D_WAAP_DEEP_PARSER) << m_key;
|
|
||||||
|
|
||||||
// Decide whether to push/pop the value in the keystack.
|
// Decide whether to push/pop the value in the keystack.
|
||||||
bool shouldUpdateKeyStack = (flags & BUFFERED_RECEIVER_F_UNNAMED) == 0;
|
bool shouldUpdateKeyStack = (flags & BUFFERED_RECEIVER_F_UNNAMED) == 0;
|
||||||
|
|
||||||
@ -278,23 +275,13 @@ DeepParser::onKv(const char *k, size_t k_len, const char *v, size_t v_len, int f
|
|||||||
// Detect and decode potential base64 chunks in the value before further processing
|
// Detect and decode potential base64 chunks in the value before further processing
|
||||||
|
|
||||||
bool base64ParamFound = false;
|
bool base64ParamFound = false;
|
||||||
size_t base64_offset = 0;
|
|
||||||
Waap::Util::BinaryFileType base64BinaryFileType = Waap::Util::BinaryFileType::FILE_TYPE_NONE;
|
Waap::Util::BinaryFileType base64BinaryFileType = Waap::Util::BinaryFileType::FILE_TYPE_NONE;
|
||||||
if (m_depth == 1 && flags == BUFFERED_RECEIVER_F_MIDDLE && m_key.depth() == 1 && m_key.first() != "#base64"){
|
if (m_depth == 1 && flags == BUFFERED_RECEIVER_F_MIDDLE && m_key.depth() == 1 && m_key.first() != "#base64"){
|
||||||
dbgTrace(D_WAAP_DEEP_PARSER) << " === will not check base64 since prev data block was not b64-encoded ===";
|
dbgTrace(D_WAAP_DEEP_PARSER) << " === will not check base64 since prev data block was not b64-encoded ===";
|
||||||
} else {
|
} else {
|
||||||
dbgTrace(D_WAAP_DEEP_PARSER) << " ===Processing potential base64===";
|
dbgTrace(D_WAAP_DEEP_PARSER) << " ===Processing potential base64===";
|
||||||
if (isUrlPayload && m_depth == 1 && cur_val[0] == '/') {
|
|
||||||
dbgTrace(D_WAAP_DEEP_PARSER) << "removing leading '/' from URL param value";
|
|
||||||
base64_offset = 1;
|
|
||||||
}
|
|
||||||
std::string decoded_val, decoded_key;
|
std::string decoded_val, decoded_key;
|
||||||
base64_variants base64_status = Waap::Util::b64Test(
|
base64_variants base64_status = Waap::Util::b64Test(cur_val, decoded_key, decoded_val, base64BinaryFileType);
|
||||||
cur_val,
|
|
||||||
decoded_key,
|
|
||||||
decoded_val,
|
|
||||||
base64BinaryFileType,
|
|
||||||
base64_offset);
|
|
||||||
|
|
||||||
dbgTrace(D_WAAP_DEEP_PARSER)
|
dbgTrace(D_WAAP_DEEP_PARSER)
|
||||||
<< " status = "
|
<< " status = "
|
||||||
@ -302,50 +289,16 @@ DeepParser::onKv(const char *k, size_t k_len, const char *v, size_t v_len, int f
|
|||||||
<< " key = "
|
<< " key = "
|
||||||
<< decoded_key
|
<< decoded_key
|
||||||
<< " value = "
|
<< " value = "
|
||||||
<< decoded_val
|
<< decoded_val;
|
||||||
<< "m_depth = "
|
|
||||||
<< m_depth;
|
|
||||||
|
|
||||||
switch (base64_status) {
|
switch (base64_status) {
|
||||||
case SINGLE_B64_CHUNK_CONVERT:
|
case SINGLE_B64_CHUNK_CONVERT:
|
||||||
if (base64_offset) {
|
|
||||||
cur_val = "/" + decoded_val;
|
|
||||||
} else {
|
|
||||||
cur_val = decoded_val;
|
cur_val = decoded_val;
|
||||||
}
|
|
||||||
base64ParamFound = true;
|
base64ParamFound = true;
|
||||||
break;
|
break;
|
||||||
case CONTINUE_DUAL_SCAN:
|
|
||||||
if (decoded_val.size() > 0) {
|
|
||||||
decoded_key = "#base64";
|
|
||||||
base64ParamFound = false;
|
|
||||||
if (base64_offset) {
|
|
||||||
decoded_val = "/" + decoded_val;
|
|
||||||
}
|
|
||||||
dbgTrace(D_WAAP_DEEP_PARSER) << m_key;
|
|
||||||
rc = onKv(
|
|
||||||
decoded_key.c_str(),
|
|
||||||
decoded_key.size(),
|
|
||||||
decoded_val.data(),
|
|
||||||
decoded_val.size(),
|
|
||||||
flags,
|
|
||||||
parser_depth
|
|
||||||
);
|
|
||||||
dbgTrace(D_WAAP_DEEP_PARSER) << "After call to onKv with suspected value rc = " << rc;
|
|
||||||
dbgTrace(D_WAAP_DEEP_PARSER) << m_key;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
dbgTrace(D_WAAP) << "base64 decode suspected and empty value. Skipping.";
|
|
||||||
base64ParamFound = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case KEY_VALUE_B64_PAIR:
|
case KEY_VALUE_B64_PAIR:
|
||||||
// going deep with new pair in case value is not empty
|
// going deep with new pair in case value is not empty
|
||||||
if (decoded_val.size() > 0) {
|
if (decoded_val.size() > 0) {
|
||||||
if (base64_offset) {
|
|
||||||
decoded_key = "/" + decoded_key;
|
|
||||||
}
|
|
||||||
cur_val = decoded_val;
|
cur_val = decoded_val;
|
||||||
base64ParamFound = true;
|
base64ParamFound = true;
|
||||||
rc = onKv(
|
rc = onKv(
|
||||||
@ -356,13 +309,9 @@ DeepParser::onKv(const char *k, size_t k_len, const char *v, size_t v_len, int f
|
|||||||
flags,
|
flags,
|
||||||
parser_depth
|
parser_depth
|
||||||
);
|
);
|
||||||
dbgTrace(D_WAAP_DEEP_PARSER) << "After call to onKv with suspected value rc = " << rc;
|
|
||||||
dbgTrace(D_WAAP_DEEP_PARSER) << m_key;
|
dbgTrace(D_WAAP_DEEP_PARSER) << " rc = " << rc;
|
||||||
if (rc != CONTINUE_PARSING) {
|
if (rc != CONTINUE_PARSING) {
|
||||||
if (shouldUpdateKeyStack) {
|
|
||||||
m_key.pop("deep parser key");
|
|
||||||
}
|
|
||||||
m_depth--;
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -374,7 +323,7 @@ DeepParser::onKv(const char *k, size_t k_len, const char *v, size_t v_len, int f
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (base64ParamFound) {
|
if (base64ParamFound) {
|
||||||
dbgTrace(D_WAAP_DEEP_PARSER) << "pushing #base64 prefix to the key.";
|
dbgTrace(D_WAAP_DEEP_PARSER) << "DeepParser::onKv(): pushing #base64 prefix to the key.";
|
||||||
m_key.push("#base64", 7, false);
|
m_key.push("#base64", 7, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -488,6 +437,7 @@ DeepParser::onKv(const char *k, size_t k_len, const char *v, size_t v_len, int f
|
|||||||
if (shouldUpdateKeyStack) {
|
if (shouldUpdateKeyStack) {
|
||||||
m_key.pop("deep parser key");
|
m_key.pop("deep parser key");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_depth--;
|
m_depth--;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -637,6 +587,7 @@ DeepParser::parseBuffer(
|
|||||||
if (shouldUpdateKeyStack) {
|
if (shouldUpdateKeyStack) {
|
||||||
m_key.pop("deep parser key");
|
m_key.pop("deep parser key");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_depth--;
|
m_depth--;
|
||||||
return DONE_PARSING;
|
return DONE_PARSING;
|
||||||
}
|
}
|
||||||
@ -958,6 +909,7 @@ DeepParser::parseAfterMisleadingMultipartBoundaryCleaned(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1129,7 +1081,7 @@ DeepParser::createInternalParser(
|
|||||||
<< " isBodyPayload = "
|
<< " isBodyPayload = "
|
||||||
<< isBodyPayload;
|
<< isBodyPayload;
|
||||||
//Detect sensor_data format in body and just use dedicated filter for it
|
//Detect sensor_data format in body and just use dedicated filter for it
|
||||||
if ((m_depth == 1)
|
if (m_depth == 1
|
||||||
&& isBodyPayload
|
&& isBodyPayload
|
||||||
&& Waap::Util::detectKnownSource(cur_val) == Waap::Util::SOURCE_TYPE_SENSOR_DATA) {
|
&& Waap::Util::detectKnownSource(cur_val) == Waap::Util::SOURCE_TYPE_SENSOR_DATA) {
|
||||||
m_parsersDeque.push_back(
|
m_parsersDeque.push_back(
|
||||||
|
@ -37,24 +37,14 @@ void KeyStack::push(const char* subkey, size_t subkeySize, bool countDepth) {
|
|||||||
m_nameDepth++;
|
m_nameDepth++;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgTrace(D_WAAP)
|
dbgTrace(D_WAAP) << "KeyStack(" << m_name << ")::push(): '" << std::string(subkey, subkeySize) <<
|
||||||
<< "KeyStack("
|
"' => full_key='" << std::string(m_key.data(), m_key.size()) << "'";
|
||||||
<< m_name
|
|
||||||
<< ")::push(): '"
|
|
||||||
<< std::string(subkey, subkeySize)
|
|
||||||
<< "' => full_key='"
|
|
||||||
<< std::string(m_key.data(), m_key.size())
|
|
||||||
<< "'";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyStack::pop(const char* log, bool countDepth) {
|
void KeyStack::pop(const char* log, bool countDepth) {
|
||||||
// Keep depth balanced even if m_key[] buffer is full
|
// Keep depth balanced even if m_key[] buffer is full
|
||||||
if (m_key.empty() || m_stack.empty()) {
|
if (m_key.empty() || m_stack.empty()) {
|
||||||
dbgDebug(D_WAAP)
|
dbgDebug(D_WAAP) << "KeyStack(" << m_name << ")::pop(): [ERROR] ATTEMPT TO POP FROM EMPTY KEY STACK! " << log;
|
||||||
<< "KeyStack("
|
|
||||||
<< m_name
|
|
||||||
<< ")::pop(): [ERROR] ATTEMPT TO POP FROM EMPTY KEY STACK! "
|
|
||||||
<< log;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,22 +55,6 @@ void KeyStack::pop(const char* log, bool countDepth) {
|
|||||||
// Remove last subkey.
|
// Remove last subkey.
|
||||||
m_key.erase(m_stack.back());
|
m_key.erase(m_stack.back());
|
||||||
m_stack.pop_back();
|
m_stack.pop_back();
|
||||||
dbgTrace(D_WAAP)
|
dbgTrace(D_WAAP) << "KeyStack(" << m_name << ")::pop(): full_key='" <<
|
||||||
<< "KeyStack("
|
std::string(m_key.data(), (int)m_key.size()) << "': pop_key=" << log << "'";
|
||||||
<< m_name
|
|
||||||
<< ")::pop(): full_key='"
|
|
||||||
<< std::string(m_key.data(), (int)m_key.size())
|
|
||||||
<< "': pop_key="
|
|
||||||
<< log
|
|
||||||
<< "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyStack::print(std::ostream &os) const
|
|
||||||
{
|
|
||||||
os
|
|
||||||
<< "KeyStack("
|
|
||||||
<< m_name
|
|
||||||
<< ")::show(): full_key='"
|
|
||||||
<< std::string(m_key.data(), (int)m_key.size())
|
|
||||||
<< "'";
|
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ public:
|
|||||||
void pop(const char* log, bool countDepth=true);
|
void pop(const char* log, bool countDepth=true);
|
||||||
bool empty() const { return m_key.empty(); }
|
bool empty() const { return m_key.empty(); }
|
||||||
void clear() { m_key.clear(); m_stack.clear(); }
|
void clear() { m_key.clear(); m_stack.clear(); }
|
||||||
void print(std::ostream &os) const;
|
|
||||||
size_t depth() const { return m_nameDepth; }
|
size_t depth() const { return m_nameDepth; }
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
return str().size();
|
return str().size();
|
||||||
|
@ -111,7 +111,8 @@ int BufferedReceiver::onKvDone()
|
|||||||
// This must be called even if m_value is empty in order to signal the BUFFERED_RECEIVER_F_LAST flag to the
|
// This must be called even if m_value is empty in order to signal the BUFFERED_RECEIVER_F_LAST flag to the
|
||||||
// receiver!
|
// receiver!
|
||||||
dbgTrace(D_WAAP_PARSER)
|
dbgTrace(D_WAAP_PARSER)
|
||||||
<< " Call onKv on the remainder of the buffer not yet pushed to the receiver calling onKv()";
|
<< " Call onKv on the remainder of the buffer not yet pushed to the receiver "
|
||||||
|
<< "calling onKv()";
|
||||||
int rc = onKv(m_key.data(), m_key.size(), m_value.data(), m_value.size(), m_flags, m_parser_depth);
|
int rc = onKv(m_key.data(), m_key.size(), m_value.data(), m_value.size(), m_flags, m_parser_depth);
|
||||||
|
|
||||||
// Reset the object's state to allow reuse for other parsers
|
// Reset the object's state to allow reuse for other parsers
|
||||||
|
@ -21,7 +21,6 @@ USE_DEBUG_FLAG(D_WAAP);
|
|||||||
|
|
||||||
const std::string ParserPDF::m_parserName = "ParserPDF";
|
const std::string ParserPDF::m_parserName = "ParserPDF";
|
||||||
const char* PDF_TAIL = "%%EOF";
|
const char* PDF_TAIL = "%%EOF";
|
||||||
const size_t PDF_TAIL_LEN = 5;
|
|
||||||
|
|
||||||
ParserPDF::ParserPDF(
|
ParserPDF::ParserPDF(
|
||||||
IParserStreamReceiver &receiver,
|
IParserStreamReceiver &receiver,
|
||||||
@ -45,13 +44,42 @@ ParserPDF::push(const char *buf, size_t len)
|
|||||||
<< "' len="
|
<< "' len="
|
||||||
<< len;
|
<< len;
|
||||||
|
|
||||||
|
const char *c;
|
||||||
|
|
||||||
if (m_state == s_error) {
|
if (m_state == s_error) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (len == 0)
|
||||||
if (len == 0) {
|
{
|
||||||
dbgTrace(D_WAAP_PARSER_PDF) << "ParserPDF::push(): end of stream. m_state=" << m_state;
|
dbgTrace(D_WAAP_PARSER_PDF) << "ParserPDF::push(): end of stream. m_state=" << m_state;
|
||||||
if (m_state == s_body && m_tailOffset >= PDF_TAIL_LEN) {
|
|
||||||
|
if (m_state == s_end) {
|
||||||
|
m_receiver.onKvDone();
|
||||||
|
} else {
|
||||||
|
m_state = s_error;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_state) {
|
||||||
|
case s_start:
|
||||||
|
m_state = s_body;
|
||||||
|
CP_FALL_THROUGH;
|
||||||
|
case s_body:
|
||||||
|
{
|
||||||
|
size_t tail_lookup_offset = (len > MAX_PDF_TAIL_LOOKUP) ? len - MAX_PDF_TAIL_LOOKUP : 0;
|
||||||
|
c = strstr(buf + tail_lookup_offset, PDF_TAIL);
|
||||||
|
dbgTrace(D_WAAP_PARSER_PDF)
|
||||||
|
<< "string to search: " << std::string(buf + tail_lookup_offset)
|
||||||
|
<< " c=" << c;
|
||||||
|
if (c) {
|
||||||
|
m_state = s_end;
|
||||||
|
CP_FALL_THROUGH;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case s_end:
|
||||||
if (m_receiver.onKey("PDF", 3) != 0) {
|
if (m_receiver.onKey("PDF", 3) != 0) {
|
||||||
m_state = s_error;
|
m_state = s_error;
|
||||||
return 0;
|
return 0;
|
||||||
@ -60,50 +88,11 @@ ParserPDF::push(const char *buf, size_t len)
|
|||||||
m_state = s_error;
|
m_state = s_error;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
m_receiver.onKvDone();
|
|
||||||
} else {
|
|
||||||
m_state = s_error;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t start = (len > MAX_PDF_TAIL_LOOKUP) ? len - MAX_PDF_TAIL_LOOKUP : 0;
|
|
||||||
switch (m_state) {
|
|
||||||
case s_start:
|
|
||||||
m_state = s_body;
|
|
||||||
CP_FALL_THROUGH;
|
|
||||||
case s_body:
|
|
||||||
for (size_t i = start; i < len; i++) {
|
|
||||||
dbgTrace(D_WAAP_PARSER_PDF)
|
|
||||||
<< "ParserPDF::push(): m_tailOffset="
|
|
||||||
<< m_tailOffset
|
|
||||||
<< " buf[i]="
|
|
||||||
<< buf[i];
|
|
||||||
if (m_tailOffset <= PDF_TAIL_LEN - 1) {
|
|
||||||
if (buf[i] == PDF_TAIL[m_tailOffset]) {
|
|
||||||
m_tailOffset++;
|
|
||||||
} else {
|
|
||||||
m_tailOffset = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (buf[i] == '\r' || buf[i] == '\n' || buf[i] == ' ' || buf[i] == 0) {
|
|
||||||
m_tailOffset++;
|
|
||||||
} else {
|
|
||||||
m_tailOffset = 0;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dbgTrace(D_WAAP_PARSER_PDF)
|
|
||||||
<< "ParserPDF::push()->s_body: m_tailOffset="
|
|
||||||
<< m_tailOffset;
|
|
||||||
break;
|
break;
|
||||||
case s_error:
|
case s_error:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dbgTrace(D_WAAP_PARSER_PDF)
|
dbgTrace(D_WAAP_PARSER_PDF) << "ParserPDF::push(): unknown state: " << m_state;
|
||||||
<< "ParserPDF::push(): unknown state: "
|
|
||||||
<< m_state;
|
|
||||||
m_state = s_error;
|
m_state = s_error;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ private:
|
|||||||
enum state {
|
enum state {
|
||||||
s_start,
|
s_start,
|
||||||
s_body,
|
s_body,
|
||||||
|
s_end,
|
||||||
s_error
|
s_error
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,7 +42,6 @@ private:
|
|||||||
enum state m_state;
|
enum state m_state;
|
||||||
static const std::string m_parserName;
|
static const std::string m_parserName;
|
||||||
size_t m_parser_depth;
|
size_t m_parser_depth;
|
||||||
size_t m_tailOffset = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __PARSER_PDF_H__
|
#endif // __PARSER_PDF_H__
|
||||||
|
@ -1,158 +0,0 @@
|
|||||||
#include "RequestsMonitor.h"
|
|
||||||
#include "waap.h"
|
|
||||||
#include "SyncLearningNotification.h"
|
|
||||||
#include "report_messaging.h"
|
|
||||||
#include "customized_cereal_map.h"
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_WAAP_CONFIDENCE_CALCULATOR);
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
SourcesRequestMonitor::SourcesRequestMonitor(
|
|
||||||
const string& filePath,
|
|
||||||
const string& remotePath,
|
|
||||||
const string& assetId,
|
|
||||||
const string& owner) :
|
|
||||||
SerializeToLocalAndRemoteSyncBase(
|
|
||||||
chrono::minutes(10),
|
|
||||||
chrono::seconds(30),
|
|
||||||
filePath,
|
|
||||||
remotePath != "" ? remotePath + "/Monitor" : remotePath,
|
|
||||||
assetId,
|
|
||||||
owner
|
|
||||||
), m_sourcesRequests()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SourcesRequestMonitor::~SourcesRequestMonitor()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SourcesRequestMonitor::syncWorker()
|
|
||||||
{
|
|
||||||
dbgInfo(D_WAAP_CONFIDENCE_CALCULATOR) << "Running the sync worker for assetId='" << m_assetId << "', owner='" <<
|
|
||||||
m_owner << "'";
|
|
||||||
incrementIntervalsCount();
|
|
||||||
OrchestrationMode mode = Singleton::exists<I_AgentDetails>() ?
|
|
||||||
Singleton::Consume<I_AgentDetails>::by<WaapComponent>()->getOrchestrationMode() : OrchestrationMode::ONLINE;
|
|
||||||
|
|
||||||
bool enabled = getProfileAgentSettingWithDefault<bool>(false, "appsec.sourceRequestsMonitor.enabled");
|
|
||||||
|
|
||||||
if (mode == OrchestrationMode::OFFLINE || !enabled || isBase() || !postData()) {
|
|
||||||
dbgInfo(D_WAAP_CONFIDENCE_CALCULATOR)
|
|
||||||
<< "Did not report data. for asset: "
|
|
||||||
<< m_assetId
|
|
||||||
<< " Remote URL: "
|
|
||||||
<< m_remotePath
|
|
||||||
<< " is enabled: "
|
|
||||||
<< to_string(enabled)
|
|
||||||
<< ", mode: " << int(mode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbgTrace(D_WAAP_CONFIDENCE_CALCULATOR) << "Waiting for all agents to post their data";
|
|
||||||
waitSync();
|
|
||||||
|
|
||||||
if (mode == OrchestrationMode::HYBRID) {
|
|
||||||
dbgDebug(D_WAAP_CONFIDENCE_CALCULATOR) << "detected running in standalone mode. not sending sync notification";
|
|
||||||
} else {
|
|
||||||
SyncLearningNotificationObject syncNotification(m_assetId, "Monitor", getWindowId());
|
|
||||||
|
|
||||||
dbgDebug(D_WAAP_CONFIDENCE_CALCULATOR) << "sending sync notification: " << syncNotification;
|
|
||||||
|
|
||||||
ReportMessaging(
|
|
||||||
"sync notification for '" + m_assetId + "'",
|
|
||||||
ReportIS::AudienceTeam::WAAP,
|
|
||||||
syncNotification,
|
|
||||||
MessageCategory::GENERIC,
|
|
||||||
ReportIS::Tags::WAF,
|
|
||||||
ReportIS::Notification::SYNC_LEARNING
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SourcesRequestMonitor::logSourceHit(const string& source)
|
|
||||||
{
|
|
||||||
m_sourcesRequests[chrono::duration_cast<chrono::minutes>(
|
|
||||||
Singleton::Consume<I_TimeGet>::by<WaapComponent>()->getWalltime()
|
|
||||||
).count()][source]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// LCOV_EXCL_START Reason: internal functions not used
|
|
||||||
|
|
||||||
void SourcesRequestMonitor::pullData(const vector<string> &data)
|
|
||||||
{
|
|
||||||
// not used. report only
|
|
||||||
}
|
|
||||||
|
|
||||||
void SourcesRequestMonitor::processData()
|
|
||||||
{
|
|
||||||
// not used. report only
|
|
||||||
}
|
|
||||||
|
|
||||||
void SourcesRequestMonitor::postProcessedData()
|
|
||||||
{
|
|
||||||
// not used. report only
|
|
||||||
}
|
|
||||||
|
|
||||||
void SourcesRequestMonitor::pullProcessedData(const vector<string> &data)
|
|
||||||
{
|
|
||||||
// not used. report only
|
|
||||||
}
|
|
||||||
|
|
||||||
void SourcesRequestMonitor::updateState(const vector<string> &data)
|
|
||||||
{
|
|
||||||
// not used. report only
|
|
||||||
}
|
|
||||||
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
|
|
||||||
typedef map<string, map<string, size_t>> MonitorJsonData;
|
|
||||||
|
|
||||||
class SourcesRequestsReport : public RestGetFile
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SourcesRequestsReport(MonitorData& _sourcesRequests, const string& _agentId)
|
|
||||||
: sourcesRequests(), agentId(_agentId)
|
|
||||||
{
|
|
||||||
MonitorJsonData montiorData;
|
|
||||||
for (const auto& window : _sourcesRequests) {
|
|
||||||
for (const auto& source : window.second) {
|
|
||||||
montiorData[to_string(window.first)][source.first] = source.second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sourcesRequests = montiorData;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
C2S_PARAM(MonitorJsonData, sourcesRequests);
|
|
||||||
C2S_PARAM(string, agentId);
|
|
||||||
};
|
|
||||||
|
|
||||||
bool SourcesRequestMonitor::postData()
|
|
||||||
{
|
|
||||||
dbgInfo(D_WAAP_CONFIDENCE_CALCULATOR) << "Sending the data to remote";
|
|
||||||
// send collected data to remote and clear the local data
|
|
||||||
string url = getPostDataUrl();
|
|
||||||
string agentId = Singleton::Consume<I_AgentDetails>::by<WaapComponent>()->getAgentId();
|
|
||||||
SourcesRequestsReport currentWindow(m_sourcesRequests, agentId);
|
|
||||||
bool ok = sendNoReplyObjectWithRetry(currentWindow,
|
|
||||||
HTTPMethod::PUT,
|
|
||||||
url);
|
|
||||||
if (!ok) {
|
|
||||||
dbgError(D_WAAP_CONFIDENCE_CALCULATOR) << "Failed to post collected data to: " << url;
|
|
||||||
}
|
|
||||||
dbgInfo(D_WAAP_CONFIDENCE_CALCULATOR) << "Data sent to remote: " << ok;
|
|
||||||
m_sourcesRequests.clear();
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SourcesRequestMonitor::serialize(ostream& stream)
|
|
||||||
{
|
|
||||||
cereal::JSONOutputArchive archive(stream);
|
|
||||||
archive(m_sourcesRequests);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SourcesRequestMonitor::deserialize(istream& stream)
|
|
||||||
{
|
|
||||||
cereal::JSONInputArchive archive(stream);
|
|
||||||
archive(m_sourcesRequests);
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
#ifndef __REQUESTS_MONITOR_H__
|
|
||||||
#define __REQUESTS_MONITOR_H__
|
|
||||||
#include "i_serialize.h"
|
|
||||||
|
|
||||||
typedef std::map<uint64_t, std::map<std::string, size_t>> MonitorData;
|
|
||||||
|
|
||||||
class SourcesRequestMonitor : public SerializeToLocalAndRemoteSyncBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SourcesRequestMonitor(
|
|
||||||
const std::string& filePath,
|
|
||||||
const std::string& remotePath,
|
|
||||||
const std::string& assetId,
|
|
||||||
const std::string& owner);
|
|
||||||
virtual ~SourcesRequestMonitor();
|
|
||||||
virtual void syncWorker() override;
|
|
||||||
void logSourceHit(const std::string& source);
|
|
||||||
protected:
|
|
||||||
virtual void pullData(const std::vector<std::string> &data) override;
|
|
||||||
virtual void processData() override;
|
|
||||||
virtual void postProcessedData() override;
|
|
||||||
virtual void pullProcessedData(const std::vector<std::string> &data) override;
|
|
||||||
virtual void updateState(const std::vector<std::string> &data) override;
|
|
||||||
virtual bool postData() override;
|
|
||||||
|
|
||||||
void serialize(std::ostream& stream);
|
|
||||||
void deserialize(std::istream& stream);
|
|
||||||
private:
|
|
||||||
// map of sources and their requests per minute (UNIX)
|
|
||||||
MonitorData m_sourcesRequests;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __REQUESTS_MONITOR_H__
|
|
@ -407,7 +407,6 @@ SerializeToLocalAndRemoteSyncBase::SerializeToLocalAndRemoteSyncBase(
|
|||||||
m_remotePath(replaceAllCopy(remotePath, "//", "/")),
|
m_remotePath(replaceAllCopy(remotePath, "//", "/")),
|
||||||
m_interval(0),
|
m_interval(0),
|
||||||
m_owner(owner),
|
m_owner(owner),
|
||||||
m_assetId(replaceAllCopy(assetId, "/", "")),
|
|
||||||
m_pMainLoop(nullptr),
|
m_pMainLoop(nullptr),
|
||||||
m_waitForSync(waitForSync),
|
m_waitForSync(waitForSync),
|
||||||
m_workerRoutineId(0),
|
m_workerRoutineId(0),
|
||||||
@ -415,6 +414,7 @@ SerializeToLocalAndRemoteSyncBase::SerializeToLocalAndRemoteSyncBase(
|
|||||||
m_windowsCount(0),
|
m_windowsCount(0),
|
||||||
m_intervalsCounter(0),
|
m_intervalsCounter(0),
|
||||||
m_remoteSyncEnabled(true),
|
m_remoteSyncEnabled(true),
|
||||||
|
m_assetId(replaceAllCopy(assetId, "/", "")),
|
||||||
m_isAssetIdUuid(Waap::Util::isUuid(assetId)),
|
m_isAssetIdUuid(Waap::Util::isUuid(assetId)),
|
||||||
m_shared_storage_host(genError("not set")),
|
m_shared_storage_host(genError("not set")),
|
||||||
m_learning_host(genError("not set"))
|
m_learning_host(genError("not set"))
|
||||||
@ -469,15 +469,6 @@ bool SerializeToLocalAndRemoteSyncBase::isBase()
|
|||||||
return m_remotePath == "";
|
return m_remotePath == "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializeToLocalAndRemoteSyncBase::waitSync()
|
|
||||||
{
|
|
||||||
if (m_pMainLoop == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_pMainLoop->yield(m_waitForSync);
|
|
||||||
}
|
|
||||||
|
|
||||||
string SerializeToLocalAndRemoteSyncBase::getUri()
|
string SerializeToLocalAndRemoteSyncBase::getUri()
|
||||||
{
|
{
|
||||||
static const string hybridModeUri = "/api";
|
static const string hybridModeUri = "/api";
|
||||||
@ -493,11 +484,6 @@ size_t SerializeToLocalAndRemoteSyncBase::getIntervalsCount()
|
|||||||
return m_intervalsCounter;
|
return m_intervalsCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializeToLocalAndRemoteSyncBase::incrementIntervalsCount()
|
|
||||||
{
|
|
||||||
m_intervalsCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
SerializeToLocalAndRemoteSyncBase::~SerializeToLocalAndRemoteSyncBase()
|
SerializeToLocalAndRemoteSyncBase::~SerializeToLocalAndRemoteSyncBase()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -617,17 +603,6 @@ void SerializeToLocalAndRemoteSyncBase::setInterval(ch::seconds newInterval)
|
|||||||
|
|
||||||
bool SerializeToLocalAndRemoteSyncBase::localSyncAndProcess()
|
bool SerializeToLocalAndRemoteSyncBase::localSyncAndProcess()
|
||||||
{
|
{
|
||||||
bool isBackupSyncEnabled = getProfileAgentSettingWithDefault<bool>(
|
|
||||||
true,
|
|
||||||
"appsecLearningSettings.backupLocalSync");
|
|
||||||
|
|
||||||
if (!isBackupSyncEnabled) {
|
|
||||||
dbgInfo(D_WAAP_CONFIDENCE_CALCULATOR) << "Local sync is disabled";
|
|
||||||
processData();
|
|
||||||
saveData();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoteFilesList rawDataFiles;
|
RemoteFilesList rawDataFiles;
|
||||||
|
|
||||||
dbgTrace(D_WAAP_CONFIDENCE_CALCULATOR) << "Getting files of all agents";
|
dbgTrace(D_WAAP_CONFIDENCE_CALCULATOR) << "Getting files of all agents";
|
||||||
@ -684,7 +659,7 @@ void SerializeToLocalAndRemoteSyncBase::syncWorker()
|
|||||||
{
|
{
|
||||||
dbgInfo(D_WAAP_CONFIDENCE_CALCULATOR) << "Running the sync worker for assetId='" << m_assetId << "', owner='" <<
|
dbgInfo(D_WAAP_CONFIDENCE_CALCULATOR) << "Running the sync worker for assetId='" << m_assetId << "', owner='" <<
|
||||||
m_owner << "'" << " last modified state: " << m_lastProcessedModified;
|
m_owner << "'" << " last modified state: " << m_lastProcessedModified;
|
||||||
incrementIntervalsCount();
|
m_intervalsCounter++;
|
||||||
OrchestrationMode mode = Singleton::exists<I_AgentDetails>() ?
|
OrchestrationMode mode = Singleton::exists<I_AgentDetails>() ?
|
||||||
Singleton::Consume<I_AgentDetails>::by<WaapComponent>()->getOrchestrationMode() : OrchestrationMode::ONLINE;
|
Singleton::Consume<I_AgentDetails>::by<WaapComponent>()->getOrchestrationMode() : OrchestrationMode::ONLINE;
|
||||||
|
|
||||||
@ -703,7 +678,7 @@ void SerializeToLocalAndRemoteSyncBase::syncWorker()
|
|||||||
}
|
}
|
||||||
|
|
||||||
dbgTrace(D_WAAP_CONFIDENCE_CALCULATOR) << "Waiting for all agents to post their data";
|
dbgTrace(D_WAAP_CONFIDENCE_CALCULATOR) << "Waiting for all agents to post their data";
|
||||||
waitSync();
|
m_pMainLoop->yield(m_waitForSync);
|
||||||
// check if learning service is operational
|
// check if learning service is operational
|
||||||
if (m_lastProcessedModified == "")
|
if (m_lastProcessedModified == "")
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,6 @@ WaapTelemetryBase::sendLog(const LogRest &metric_client_rest) const
|
|||||||
OrchestrationMode mode = Singleton::Consume<I_AgentDetails>::by<GenericMetric>()->getOrchestrationMode();
|
OrchestrationMode mode = Singleton::Consume<I_AgentDetails>::by<GenericMetric>()->getOrchestrationMode();
|
||||||
|
|
||||||
GenericMetric::sendLog(metric_client_rest);
|
GenericMetric::sendLog(metric_client_rest);
|
||||||
dbgTrace(D_WAAP) << "Waap telemetry log sent: " << metric_client_rest.genJson().unpack();
|
|
||||||
|
|
||||||
if (mode == OrchestrationMode::ONLINE) {
|
if (mode == OrchestrationMode::ONLINE) {
|
||||||
return;
|
return;
|
||||||
@ -80,16 +79,7 @@ void
|
|||||||
WaapTelemetrics::updateMetrics(const string &asset_id, const DecisionTelemetryData &data)
|
WaapTelemetrics::updateMetrics(const string &asset_id, const DecisionTelemetryData &data)
|
||||||
{
|
{
|
||||||
initMetrics();
|
initMetrics();
|
||||||
|
|
||||||
auto is_keep_alive_ctx = Singleton::Consume<I_Environment>::by<GenericMetric>()->get<bool>(
|
|
||||||
"keep_alive_request_ctx"
|
|
||||||
);
|
|
||||||
if (!is_keep_alive_ctx.ok() || !*is_keep_alive_ctx) {
|
|
||||||
requests.report(1);
|
requests.report(1);
|
||||||
} else {
|
|
||||||
dbgTrace(D_WAAP) << "Not increasing the number of requests due to keep alive";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sources_seen.find(data.source) == sources_seen.end()) {
|
if (sources_seen.find(data.source) == sources_seen.end()) {
|
||||||
if (sources.getCounter() == 0) sources_seen.clear();
|
if (sources.getCounter() == 0) sources_seen.clear();
|
||||||
sources_seen.insert(data.source);
|
sources_seen.insert(data.source);
|
||||||
@ -284,9 +274,7 @@ WaapMetricWrapper::upon(const WaapTelemetryEvent &event)
|
|||||||
ReportIS::IssuingEngine::AGENT_CORE,
|
ReportIS::IssuingEngine::AGENT_CORE,
|
||||||
chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
|
chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
|
||||||
true,
|
true,
|
||||||
ReportIS::Audience::INTERNAL,
|
ReportIS::Audience::INTERNAL
|
||||||
false,
|
|
||||||
asset_id
|
|
||||||
);
|
);
|
||||||
metrics[asset_id]->registerListener();
|
metrics[asset_id]->registerListener();
|
||||||
}
|
}
|
||||||
@ -298,9 +286,7 @@ WaapMetricWrapper::upon(const WaapTelemetryEvent &event)
|
|||||||
ReportIS::IssuingEngine::AGENT_CORE,
|
ReportIS::IssuingEngine::AGENT_CORE,
|
||||||
chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
|
chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
|
||||||
true,
|
true,
|
||||||
ReportIS::Audience::INTERNAL,
|
ReportIS::Audience::INTERNAL
|
||||||
false,
|
|
||||||
asset_id
|
|
||||||
);
|
);
|
||||||
attack_types[asset_id]->registerListener();
|
attack_types[asset_id]->registerListener();
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,6 @@ WaapAssetState::WaapAssetState(std::shared_ptr<Signatures> signatures,
|
|||||||
m_Signatures(signatures),
|
m_Signatures(signatures),
|
||||||
m_waapDataFileName(waapDataFileName),
|
m_waapDataFileName(waapDataFileName),
|
||||||
m_assetId(assetId),
|
m_assetId(assetId),
|
||||||
m_requestsMonitor(nullptr),
|
|
||||||
scoreBuilder(this),
|
scoreBuilder(this),
|
||||||
m_rateLimitingState(nullptr),
|
m_rateLimitingState(nullptr),
|
||||||
m_errorLimitingState(nullptr),
|
m_errorLimitingState(nullptr),
|
||||||
@ -153,14 +152,10 @@ WaapAssetState::WaapAssetState(std::shared_ptr<Signatures> signatures,
|
|||||||
I_AgentDetails* agentDetails = Singleton::Consume<I_AgentDetails>::by<WaapComponent>();
|
I_AgentDetails* agentDetails = Singleton::Consume<I_AgentDetails>::by<WaapComponent>();
|
||||||
std::string path = agentDetails->getTenantId() + "/" + assetId;
|
std::string path = agentDetails->getTenantId() + "/" + assetId;
|
||||||
m_filtersMngr = std::make_shared<IndicatorsFiltersManager>(path, assetId, this);
|
m_filtersMngr = std::make_shared<IndicatorsFiltersManager>(path, assetId, this);
|
||||||
m_requestsMonitor = std::make_shared<SourcesRequestMonitor>
|
|
||||||
(getWaapDataDir() + "/monitor.data", path, assetId, "State");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_filtersMngr = std::make_shared<IndicatorsFiltersManager>("", "", this);
|
m_filtersMngr = std::make_shared<IndicatorsFiltersManager>("", "", this);
|
||||||
m_requestsMonitor = std::make_shared<SourcesRequestMonitor>
|
|
||||||
(getWaapDataDir() + "/monitor.data", "", assetId, "State");
|
|
||||||
}
|
}
|
||||||
// Load keyword scores - copy from ScoreBuilder
|
// Load keyword scores - copy from ScoreBuilder
|
||||||
updateScores();
|
updateScores();
|
||||||
@ -424,8 +419,6 @@ WaapAssetState::WaapAssetState(std::shared_ptr<Signatures> signatures,
|
|||||||
|
|
||||||
std::string unescape(const std::string & s) {
|
std::string unescape(const std::string & s) {
|
||||||
std::string text = s;
|
std::string text = s;
|
||||||
size_t orig_size = text.size();
|
|
||||||
size_t orig_capacity = text.capacity();
|
|
||||||
dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (0) '" << text << "'";
|
dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (0) '" << text << "'";
|
||||||
|
|
||||||
fixBreakingSpace(text);
|
fixBreakingSpace(text);
|
||||||
@ -435,17 +428,7 @@ WaapAssetState::WaapAssetState(std::shared_ptr<Signatures> signatures,
|
|||||||
filterUnicode(text);
|
filterUnicode(text);
|
||||||
dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (1) '" << text << "'";
|
dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (1) '" << text << "'";
|
||||||
|
|
||||||
// inplace unescaping must result in a string of the same size or smaller
|
|
||||||
dbgAssertOpt(text.size() <= orig_size && text.size() <= text.capacity() && text.capacity() <= orig_capacity)
|
|
||||||
<< AlertInfo(AlertTeam::CORE, "WAAP sample processing")
|
|
||||||
<< "unescape: original size=" << orig_size << " capacity=" << orig_capacity
|
|
||||||
<< " new size=" << text.size() << " capacity=" << text.capacity()
|
|
||||||
<< " text='" << text << "'";
|
|
||||||
|
|
||||||
text = filterUTF7(text);
|
text = filterUTF7(text);
|
||||||
// update orig_size and orig_capacity after string copy
|
|
||||||
orig_size = text.size();
|
|
||||||
orig_capacity = text.capacity();
|
|
||||||
dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (1) (after filterUTF7) '" << text << "'";
|
dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (1) (after filterUTF7) '" << text << "'";
|
||||||
|
|
||||||
// 2. Replace %xx sequences by their single-character equivalents.
|
// 2. Replace %xx sequences by their single-character equivalents.
|
||||||
@ -524,14 +507,6 @@ WaapAssetState::WaapAssetState(std::shared_ptr<Signatures> signatures,
|
|||||||
}
|
}
|
||||||
|
|
||||||
dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (12) '" << text << "'";
|
dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (12) '" << text << "'";
|
||||||
|
|
||||||
// inplace unescaping must result in a string of the same size or smaller
|
|
||||||
dbgAssertOpt(text.size() <= orig_size && text.size() <= text.capacity() && text.capacity() <= orig_capacity)
|
|
||||||
<< AlertInfo(AlertTeam::CORE, "WAAP sample processing")
|
|
||||||
<< "unescape: original size=" << orig_size << " capacity=" << orig_capacity
|
|
||||||
<< " new size=" << text.size() << " capacity=" << text.capacity()
|
|
||||||
<< " text='" << text << "'";
|
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
#include "KeywordTypeValidator.h"
|
#include "KeywordTypeValidator.h"
|
||||||
#include "ScanResult.h"
|
#include "ScanResult.h"
|
||||||
#include "WaapSampleValue.h"
|
#include "WaapSampleValue.h"
|
||||||
#include "RequestsMonitor.h"
|
|
||||||
|
|
||||||
enum space_stage {SPACE_SYNBOL, BR_SYMBOL, BN_SYMBOL, BRN_SEQUENCE, BNR_SEQUENCE, NO_SPACES};
|
enum space_stage {SPACE_SYNBOL, BR_SYMBOL, BN_SYMBOL, BRN_SEQUENCE, BNR_SEQUENCE, NO_SPACES};
|
||||||
|
|
||||||
@ -68,8 +67,6 @@ public:
|
|||||||
|
|
||||||
const std::string m_assetId;
|
const std::string m_assetId;
|
||||||
|
|
||||||
std::shared_ptr<SourcesRequestMonitor> m_requestsMonitor;
|
|
||||||
|
|
||||||
ScoreBuilder scoreBuilder;
|
ScoreBuilder scoreBuilder;
|
||||||
std::shared_ptr<Waap::RateLimiting::State> m_rateLimitingState;
|
std::shared_ptr<Waap::RateLimiting::State> m_rateLimitingState;
|
||||||
std::shared_ptr<Waap::RateLimiting::State> m_errorLimitingState;
|
std::shared_ptr<Waap::RateLimiting::State> m_errorLimitingState;
|
||||||
@ -93,7 +90,6 @@ public:
|
|||||||
void logIndicatorsInFilters(const std::string ¶m, Waap::Keywords::KeywordsSet& keywords,
|
void logIndicatorsInFilters(const std::string ¶m, Waap::Keywords::KeywordsSet& keywords,
|
||||||
IWaf2Transaction* pTransaction);
|
IWaf2Transaction* pTransaction);
|
||||||
void logParamHit(Waf2ScanResult& res, IWaf2Transaction* pTransaction);
|
void logParamHit(Waf2ScanResult& res, IWaf2Transaction* pTransaction);
|
||||||
void logSourceHit(const std::string& source);
|
|
||||||
void filterKeywords(const std::string ¶m, Waap::Keywords::KeywordsSet& keywords,
|
void filterKeywords(const std::string ¶m, Waap::Keywords::KeywordsSet& keywords,
|
||||||
std::vector<std::string>& filteredKeywords);
|
std::vector<std::string>& filteredKeywords);
|
||||||
void clearFilterVerbose();
|
void clearFilterVerbose();
|
||||||
|
@ -329,37 +329,14 @@ const std::string& WaapConfigBase::get_AssetName() const
|
|||||||
return m_assetName;
|
return m_assetName;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& WaapConfigBase::get_PracticeIdByPactice(DecisionType practiceType) const
|
const std::string& WaapConfigBase::get_PracticeId() const
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (practiceType)
|
|
||||||
{
|
|
||||||
case DecisionType::AUTONOMOUS_SECURITY_DECISION:
|
|
||||||
return m_practiceId;
|
|
||||||
default:
|
|
||||||
dbgError(D_WAAP)
|
|
||||||
<< "Can't find practice type for practice ID by practice: "
|
|
||||||
<< practiceType
|
|
||||||
<< ", return web app practice ID";
|
|
||||||
return m_practiceId;
|
return m_practiceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
const std::string& WaapConfigBase::get_PracticeName() const
|
||||||
|
|
||||||
const std::string& WaapConfigBase::get_PracticeNameByPactice(DecisionType practiceType) const
|
|
||||||
{
|
{
|
||||||
switch (practiceType)
|
|
||||||
{
|
|
||||||
case DecisionType::AUTONOMOUS_SECURITY_DECISION:
|
|
||||||
return m_practiceName;
|
return m_practiceName;
|
||||||
default:
|
|
||||||
dbgError(D_WAAP)
|
|
||||||
<< "Can't find practice type for practice name by practice: "
|
|
||||||
<< practiceType
|
|
||||||
<< ", return web app practice name";
|
|
||||||
return m_practiceName;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& WaapConfigBase::get_RuleId() const
|
const std::string& WaapConfigBase::get_RuleId() const
|
||||||
|
@ -39,8 +39,8 @@ public:
|
|||||||
virtual const std::string& get_AssetId() const;
|
virtual const std::string& get_AssetId() const;
|
||||||
virtual const std::string& get_AssetName() const;
|
virtual const std::string& get_AssetName() const;
|
||||||
virtual const BlockingLevel& get_BlockingLevel() const;
|
virtual const BlockingLevel& get_BlockingLevel() const;
|
||||||
virtual const std::string& get_PracticeIdByPactice(DecisionType practiceType) const;
|
virtual const std::string& get_PracticeId() const;
|
||||||
virtual const std::string& get_PracticeNameByPactice(DecisionType practiceType) const;
|
virtual const std::string& get_PracticeName() const;
|
||||||
virtual const std::string& get_RuleId() const;
|
virtual const std::string& get_RuleId() const;
|
||||||
virtual const std::string& get_RuleName() const;
|
virtual const std::string& get_RuleName() const;
|
||||||
virtual const bool& get_WebAttackMitigation() const;
|
virtual const bool& get_WebAttackMitigation() const;
|
||||||
|
@ -89,7 +89,7 @@ bool WaapOverrideFunctor::operator()(
|
|||||||
}
|
}
|
||||||
else if (tagLower == "url") {
|
else if (tagLower == "url") {
|
||||||
for (const auto &rx : rxes) {
|
for (const auto &rx : rxes) {
|
||||||
if (W2T_REGX_MATCH(getUri)) return true;
|
if (W2T_REGX_MATCH(getUriStr)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ ResponseInjectReasons::ResponseInjectReasons()
|
|||||||
:
|
:
|
||||||
csrf(false),
|
csrf(false),
|
||||||
antibot(false),
|
antibot(false),
|
||||||
captcha(false),
|
|
||||||
securityHeaders(false)
|
securityHeaders(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -54,13 +53,6 @@ ResponseInjectReasons::setAntibot(bool flag)
|
|||||||
antibot = flag;
|
antibot = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ResponseInjectReasons::setCaptcha(bool flag)
|
|
||||||
{
|
|
||||||
dbgTrace(D_WAAP) << "Change ResponseInjectReasons(Captcha) " << captcha << " to " << flag;
|
|
||||||
captcha = flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ResponseInjectReasons::setCsrf(bool flag)
|
ResponseInjectReasons::setCsrf(bool flag)
|
||||||
{
|
{
|
||||||
@ -82,13 +74,6 @@ ResponseInjectReasons::shouldInjectAntibot() const
|
|||||||
return antibot;
|
return antibot;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
ResponseInjectReasons::shouldInjectCaptcha() const
|
|
||||||
{
|
|
||||||
dbgTrace(D_WAAP) << "shouldInjectCaptcha():: " << captcha;
|
|
||||||
return captcha;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ResponseInjectReasons::shouldInjectCsrf() const
|
ResponseInjectReasons::shouldInjectCsrf() const
|
||||||
{
|
{
|
||||||
|
@ -21,17 +21,14 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
bool shouldInject() const;
|
bool shouldInject() const;
|
||||||
void setAntibot(bool flag);
|
void setAntibot(bool flag);
|
||||||
void setCaptcha(bool flag);
|
|
||||||
void setCsrf(bool flag);
|
void setCsrf(bool flag);
|
||||||
void setSecurityHeaders(bool flag);
|
void setSecurityHeaders(bool flag);
|
||||||
bool shouldInjectAntibot() const;
|
bool shouldInjectAntibot() const;
|
||||||
bool shouldInjectCaptcha() const;
|
|
||||||
bool shouldInjectCsrf() const;
|
bool shouldInjectCsrf() const;
|
||||||
bool shouldInjectSecurityHeaders() const;
|
bool shouldInjectSecurityHeaders() const;
|
||||||
private:
|
private:
|
||||||
bool csrf;
|
bool csrf;
|
||||||
bool antibot;
|
bool antibot;
|
||||||
bool captcha;
|
|
||||||
bool securityHeaders;
|
bool securityHeaders;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,9 +97,7 @@ calcIndividualKeywords(
|
|||||||
std::sort(keywords.begin(), keywords.end());
|
std::sort(keywords.begin(), keywords.end());
|
||||||
|
|
||||||
for (auto pKeyword = keywords.begin(); pKeyword != keywords.end(); ++pKeyword) {
|
for (auto pKeyword = keywords.begin(); pKeyword != keywords.end(); ++pKeyword) {
|
||||||
addKeywordScore(
|
addKeywordScore(scoreBuilder, poolName, *pKeyword, 2.0f, 0.3f, scoresArray, coefArray);
|
||||||
scoreBuilder, poolName, *pKeyword, DEFAULT_KEYWORD_SCORE, DEFAULT_KEYWORD_COEF, scoresArray, coefArray
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +112,8 @@ calcCombinations(
|
|||||||
std::vector<std::string>& keyword_combinations)
|
std::vector<std::string>& keyword_combinations)
|
||||||
{
|
{
|
||||||
keyword_combinations.clear();
|
keyword_combinations.clear();
|
||||||
|
static const double max_combi_score = 1.0f;
|
||||||
|
double default_coef = 0.8f;
|
||||||
|
|
||||||
for (size_t i = 0; i < keyword_matches.size(); ++i) {
|
for (size_t i = 0; i < keyword_matches.size(); ++i) {
|
||||||
std::vector<std::string> combinations;
|
std::vector<std::string> combinations;
|
||||||
@ -137,10 +137,8 @@ calcCombinations(
|
|||||||
default_score += scoreBuilder.getSnapshotKeywordScore(*it, 0.0f, poolName);
|
default_score += scoreBuilder.getSnapshotKeywordScore(*it, 0.0f, poolName);
|
||||||
}
|
}
|
||||||
// set default combination score to be the sum of its keywords, bounded by 1
|
// set default combination score to be the sum of its keywords, bounded by 1
|
||||||
default_score = std::min(default_score, DEFAULT_COMBI_SCORE);
|
default_score = std::min(default_score, max_combi_score);
|
||||||
addKeywordScore(
|
addKeywordScore(scoreBuilder, poolName, combination, default_score, default_coef, scoresArray, coefArray);
|
||||||
scoreBuilder, poolName, combination, default_score, DEFAULT_COMBI_COEF, scoresArray, coefArray
|
|
||||||
);
|
|
||||||
keyword_combinations.push_back(combination);
|
keyword_combinations.push_back(combination);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,7 +155,7 @@ calcArrayScore(std::vector<double>& scoreArray)
|
|||||||
// *pScore is always positive and there's a +10 offset
|
// *pScore is always positive and there's a +10 offset
|
||||||
score = 10.0f - left * 10.0f / divisor;
|
score = 10.0f - left * 10.0f / divisor;
|
||||||
}
|
}
|
||||||
dbgDebug(D_WAAP_SCORE_BUILDER) << "calculated score: " << score;
|
dbgTrace(D_WAAP_SCORE_BUILDER) << "calculated score: " << score;
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,9 +171,7 @@ calcLogisticRegressionScore(std::vector<double> &coefArray, double intercept, do
|
|||||||
}
|
}
|
||||||
// Apply the expit function to the log-odds to obtain the probability,
|
// Apply the expit function to the log-odds to obtain the probability,
|
||||||
// and multiply by 10 to obtain a 'score' in the range [0, 10]
|
// and multiply by 10 to obtain a 'score' in the range [0, 10]
|
||||||
double score = 1.0f / (1.0f + exp(-log_odds)) * 10.0f;
|
return 1.0f / (1.0f + exp(-log_odds)) * 10.0f;
|
||||||
dbgDebug(D_WAAP_SCORE_BUILDER) << "calculated score (log_odds): " << score << " (" << log_odds << ")";
|
|
||||||
return score;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,6 @@ struct ModelLoggingSettings {
|
|||||||
bool logToStream;
|
bool logToStream;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const double DEFAULT_KEYWORD_COEF = 0.3f;
|
|
||||||
static const double DEFAULT_KEYWORD_SCORE = 2.0f;
|
|
||||||
static const double DEFAULT_COMBI_COEF = 0.8f;
|
|
||||||
static const double DEFAULT_COMBI_SCORE = 1.0f;
|
|
||||||
|
|
||||||
std::string getScorePoolNameByLocation(const std::string &location);
|
std::string getScorePoolNameByLocation(const std::string &location);
|
||||||
std::string getOtherScorePoolName();
|
std::string getOtherScorePoolName();
|
||||||
ModelLoggingSettings getModelLoggingSettings();
|
ModelLoggingSettings getModelLoggingSettings();
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
#include "WaapOpenRedirectPolicy.h"
|
#include "WaapOpenRedirectPolicy.h"
|
||||||
#include "WaapErrorDisclosurePolicy.h"
|
#include "WaapErrorDisclosurePolicy.h"
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/regex.hpp>
|
|
||||||
#include "generic_rulebase/parameters_config.h"
|
#include "generic_rulebase/parameters_config.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "ParserDelimiter.h"
|
#include "ParserDelimiter.h"
|
||||||
@ -1093,10 +1092,12 @@ void Waf2Transaction::add_request_hdr(const char* name, int name_len, const char
|
|||||||
void Waf2Transaction::end_request_hdrs() {
|
void Waf2Transaction::end_request_hdrs() {
|
||||||
dbgFlow(D_WAAP) << "[transaction:" << this << "] end_request_hdrs";
|
dbgFlow(D_WAAP) << "[transaction:" << this << "] end_request_hdrs";
|
||||||
m_isScanningRequired = setCurrentAssetContext();
|
m_isScanningRequired = setCurrentAssetContext();
|
||||||
|
if (m_siteConfig != NULL)
|
||||||
extractEnvSourceIdentifier();
|
{
|
||||||
|
// getOverrideState also extracts the source identifier and populates m_source_identifier
|
||||||
m_pWaapAssetState->m_requestsMonitor->logSourceHit(m_source_identifier);
|
// but the State itself is not needed now
|
||||||
|
Waap::Override::State overrideState = getOverrideState(m_siteConfig);
|
||||||
|
}
|
||||||
IdentifiersEvent ids(m_source_identifier, m_pWaapAssetState->m_assetId);
|
IdentifiersEvent ids(m_source_identifier, m_pWaapAssetState->m_assetId);
|
||||||
ids.notify();
|
ids.notify();
|
||||||
// Read relevant headers and extract meta information such as host name
|
// Read relevant headers and extract meta information such as host name
|
||||||
@ -1388,20 +1389,6 @@ Waf2Transaction::findHtmlTagToInject(const char* data, int data_len, int& pos)
|
|||||||
size_t tagHistPosCheck = m_tagHistPos;
|
size_t tagHistPosCheck = m_tagHistPos;
|
||||||
for (size_t i=0; i < tagSize; ++i) {
|
for (size_t i=0; i < tagSize; ++i) {
|
||||||
if (tag[i] != ::tolower(m_tagHist[tagHistPosCheck])) {
|
if (tag[i] != ::tolower(m_tagHist[tagHistPosCheck])) {
|
||||||
if (i == tagSize - 1 && m_tagHist[tagHistPosCheck] == ' ') {
|
|
||||||
// match regex on head element with attributes
|
|
||||||
string dataStr = Waap::Util::charToString(data + pos, data_len - pos);
|
|
||||||
dataStr = dataStr.substr(0, dataStr.find('>')+1);
|
|
||||||
tagMatches = NGEN::Regex::regexMatch(
|
|
||||||
__FILE__,
|
|
||||||
__LINE__,
|
|
||||||
dataStr,
|
|
||||||
boost::regex("(?:\\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\\s*=\\s*(\"[^\"]*\"|'[^']*'|[^\\s\"'>]*))?)*\\s*>")
|
|
||||||
);
|
|
||||||
pos += dataStr.length() - 1;
|
|
||||||
dbgTrace(D_WAAP_BOT_PROTECTION) << "matching head element with attributes: " << dataStr << ". match: " << tagMatches;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tagMatches = false;
|
tagMatches = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1415,8 +1402,12 @@ Waf2Transaction::findHtmlTagToInject(const char* data, int data_len, int& pos)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgTrace(D_WAAP_BOT_PROTECTION) << "head element tag found: " << headFound;
|
if(!headFound)
|
||||||
return headFound;
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1430,15 +1421,6 @@ Waf2Transaction::completeInjectionResponseBody(std::string& strInjection)
|
|||||||
m_responseInjectReasons.setAntibot(false);
|
m_responseInjectReasons.setAntibot(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_responseInjectReasons.shouldInjectCaptcha()) {
|
|
||||||
dbgTrace(D_WAAP_BOT_PROTECTION) <<
|
|
||||||
"Waf2Transaction::completeInjectionResponseBody(): Injecting data (captcha)";
|
|
||||||
//todo add captcha script
|
|
||||||
strInjection += "<script src=\"cp-cp.js\"></script>";
|
|
||||||
// No need to inject more than once
|
|
||||||
m_responseInjectReasons.setCaptcha(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_responseInjectReasons.shouldInjectCsrf()) {
|
if (m_responseInjectReasons.shouldInjectCsrf()) {
|
||||||
dbgTrace(D_WAAP) << "Waf2Transaction::completeInjectionResponseBody(): Injecting data (csrf)";
|
dbgTrace(D_WAAP) << "Waf2Transaction::completeInjectionResponseBody(): Injecting data (csrf)";
|
||||||
strInjection += "<script src=\"cp-csrf.js\"></script>";
|
strInjection += "<script src=\"cp-csrf.js\"></script>";
|
||||||
@ -1586,8 +1568,6 @@ Waf2Transaction::decideFinal(
|
|||||||
sitePolicy = &ngenAPIConfig;
|
sitePolicy = &ngenAPIConfig;
|
||||||
m_overrideState = getOverrideState(sitePolicy);
|
m_overrideState = getOverrideState(sitePolicy);
|
||||||
|
|
||||||
// User limits
|
|
||||||
shouldBlock = (getUserLimitVerdict() == ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP);
|
|
||||||
}
|
}
|
||||||
else if (WaapConfigApplication::getWaapSiteConfig(ngenSiteConfig)) {
|
else if (WaapConfigApplication::getWaapSiteConfig(ngenSiteConfig)) {
|
||||||
dbgTrace(D_WAAP) << "Waf2Transaction::decideFinal(): got relevant Application configuration from the I/S";
|
dbgTrace(D_WAAP) << "Waf2Transaction::decideFinal(): got relevant Application configuration from the I/S";
|
||||||
@ -1666,9 +1646,7 @@ void Waf2Transaction::appendCommonLogFields(LogGen& waapLog,
|
|||||||
const std::shared_ptr<Waap::Trigger::Log> &triggerLog,
|
const std::shared_ptr<Waap::Trigger::Log> &triggerLog,
|
||||||
bool shouldBlock,
|
bool shouldBlock,
|
||||||
const std::string& logOverride,
|
const std::string& logOverride,
|
||||||
const std::string& incidentType,
|
const std::string& incidentType) const
|
||||||
const std::string& practiceID,
|
|
||||||
const std::string& practiceName) const
|
|
||||||
{
|
{
|
||||||
auto env = Singleton::Consume<I_Environment>::by<WaapComponent>();
|
auto env = Singleton::Consume<I_Environment>::by<WaapComponent>();
|
||||||
auto active_id = env->get<std::string>("ActiveTenantId");
|
auto active_id = env->get<std::string>("ActiveTenantId");
|
||||||
@ -1759,8 +1737,8 @@ void Waf2Transaction::appendCommonLogFields(LogGen& waapLog,
|
|||||||
waapLog << LogField("practiceType", "Threat Prevention");
|
waapLog << LogField("practiceType", "Threat Prevention");
|
||||||
waapLog << LogField("practiceSubType", m_siteConfig->get_PracticeSubType());
|
waapLog << LogField("practiceSubType", m_siteConfig->get_PracticeSubType());
|
||||||
waapLog << LogField("ruleName", m_siteConfig->get_RuleName());
|
waapLog << LogField("ruleName", m_siteConfig->get_RuleName());
|
||||||
waapLog << LogField("practiceId", practiceID);
|
waapLog << LogField("practiceId", m_siteConfig->get_PracticeId());
|
||||||
waapLog << LogField("practiceName", practiceName);
|
waapLog << LogField("practiceName", m_siteConfig->get_PracticeName());
|
||||||
waapLog << LogField("waapIncidentType", incidentType);
|
waapLog << LogField("waapIncidentType", incidentType);
|
||||||
|
|
||||||
// Registering this value would append the list of matched override IDs to the unified log
|
// Registering this value would append the list of matched override IDs to the unified log
|
||||||
@ -1827,8 +1805,8 @@ Waf2Transaction::sendLog()
|
|||||||
|
|
||||||
telemetryData.source = getSourceIdentifier();
|
telemetryData.source = getSourceIdentifier();
|
||||||
telemetryData.assetName = m_siteConfig->get_AssetName();
|
telemetryData.assetName = m_siteConfig->get_AssetName();
|
||||||
telemetryData.practiceId = m_siteConfig->get_PracticeIdByPactice(AUTONOMOUS_SECURITY_DECISION);
|
telemetryData.practiceId = m_siteConfig->get_PracticeId();
|
||||||
telemetryData.practiceName = m_siteConfig->get_PracticeNameByPactice(AUTONOMOUS_SECURITY_DECISION);
|
telemetryData.practiceName = m_siteConfig->get_PracticeName();
|
||||||
if (m_scanResult) {
|
if (m_scanResult) {
|
||||||
telemetryData.attackTypes = m_scanResult->attack_types;
|
telemetryData.attackTypes = m_scanResult->attack_types;
|
||||||
}
|
}
|
||||||
@ -1969,11 +1947,7 @@ Waf2Transaction::sendLog()
|
|||||||
shouldBlock);
|
shouldBlock);
|
||||||
|
|
||||||
LogGen& waap_log = logGenWrapper.getLogGen();
|
LogGen& waap_log = logGenWrapper.getLogGen();
|
||||||
appendCommonLogFields(
|
appendCommonLogFields(waap_log, triggerLog, shouldBlock, logOverride, incidentType);
|
||||||
waap_log, triggerLog, shouldBlock, logOverride, incidentType,
|
|
||||||
m_siteConfig->get_PracticeIdByPactice(AUTONOMOUS_SECURITY_DECISION),
|
|
||||||
m_siteConfig->get_PracticeNameByPactice(AUTONOMOUS_SECURITY_DECISION)
|
|
||||||
);
|
|
||||||
waap_log << LogField("waapIncidentDetails", incidentDetails);
|
waap_log << LogField("waapIncidentDetails", incidentDetails);
|
||||||
waap_log << LogField("eventConfidence", "High");
|
waap_log << LogField("eventConfidence", "High");
|
||||||
break;
|
break;
|
||||||
@ -2006,11 +1980,7 @@ Waf2Transaction::sendLog()
|
|||||||
waap_log << LogField("waapFoundIndicators", getKeywordMatchesStr(), LogFieldOption::XORANDB64);
|
waap_log << LogField("waapFoundIndicators", getKeywordMatchesStr(), LogFieldOption::XORANDB64);
|
||||||
}
|
}
|
||||||
|
|
||||||
appendCommonLogFields(
|
appendCommonLogFields(waap_log, triggerLog, shouldBlock, logOverride, incidentType);
|
||||||
waap_log, triggerLog, shouldBlock, logOverride, incidentType,
|
|
||||||
m_siteConfig->get_PracticeIdByPactice(AUTONOMOUS_SECURITY_DECISION),
|
|
||||||
m_siteConfig->get_PracticeNameByPactice(AUTONOMOUS_SECURITY_DECISION)
|
|
||||||
);
|
|
||||||
|
|
||||||
waap_log << LogField("waapIncidentDetails", incidentDetails);
|
waap_log << LogField("waapIncidentDetails", incidentDetails);
|
||||||
break;
|
break;
|
||||||
@ -2026,11 +1996,7 @@ Waf2Transaction::sendLog()
|
|||||||
shouldBlock);
|
shouldBlock);
|
||||||
|
|
||||||
LogGen& waap_log = logGenWrapper.getLogGen();
|
LogGen& waap_log = logGenWrapper.getLogGen();
|
||||||
appendCommonLogFields(
|
appendCommonLogFields(waap_log, triggerLog, shouldBlock, logOverride, "Cross Site Request Forgery");
|
||||||
waap_log, triggerLog, shouldBlock, logOverride, "Cross Site Request Forgery",
|
|
||||||
m_siteConfig->get_PracticeIdByPactice(AUTONOMOUS_SECURITY_DECISION),
|
|
||||||
m_siteConfig->get_PracticeNameByPactice(AUTONOMOUS_SECURITY_DECISION)
|
|
||||||
);
|
|
||||||
waap_log << LogField("waapIncidentDetails", "CSRF Attack discovered.");
|
waap_log << LogField("waapIncidentDetails", "CSRF Attack discovered.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2211,13 +2177,14 @@ Waf2Transaction::decideAutonomousSecurity(
|
|||||||
" effective overrides count: " << m_effectiveOverrideIds.size() <<
|
" effective overrides count: " << m_effectiveOverrideIds.size() <<
|
||||||
" learned overrides count: " << m_exceptionLearned.size();
|
" learned overrides count: " << m_exceptionLearned.size();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool log_all = false;
|
bool log_all = false;
|
||||||
const std::shared_ptr<Waap::Trigger::Policy> triggerPolicy = sitePolicy.get_TriggerPolicy();
|
const std::shared_ptr<Waap::Trigger::Policy> triggerPolicy = sitePolicy.get_TriggerPolicy();
|
||||||
if (triggerPolicy) {
|
if (triggerPolicy) {
|
||||||
const std::shared_ptr<Waap::Trigger::Log> triggerLog = getTriggerLog(triggerPolicy);
|
const std::shared_ptr<Waap::Trigger::Log> triggerLog = getTriggerLog(triggerPolicy);
|
||||||
if (triggerLog && triggerLog->webRequests) log_all = true;
|
if (triggerLog && triggerLog->webRequests) log_all = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(decision->getThreatLevel() <= ThreatLevel::THREAT_INFO && !log_all) {
|
if(decision->getThreatLevel() <= ThreatLevel::THREAT_INFO && !log_all) {
|
||||||
decision->setLog(false);
|
decision->setLog(false);
|
||||||
} else {
|
} else {
|
||||||
@ -2332,11 +2299,10 @@ bool Waf2Transaction::decideResponse()
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
Waf2Transaction::reportScanResult(const Waf2ScanResult &res) {
|
Waf2Transaction::reportScanResult(const Waf2ScanResult &res) {
|
||||||
if ((get_ignoreScore() || res.score >= SCORE_THRESHOLD) &&
|
if (get_ignoreScore() || (res.score >= SCORE_THRESHOLD &&
|
||||||
(m_scanResult == nullptr || res.score > m_scanResult->score))
|
(m_scanResult == nullptr || res.score > m_scanResult->score)))
|
||||||
{
|
{
|
||||||
dbgTrace(D_WAAP) << "Setting scan result. New score: " << res.score;
|
// Forget any previous scan result and replace with new
|
||||||
// Forget any previous scan result and replace wit, h new
|
|
||||||
delete m_scanResult;
|
delete m_scanResult;
|
||||||
m_scanResult = new Waf2ScanResult(res);
|
m_scanResult = new Waf2ScanResult(res);
|
||||||
return true;
|
return true;
|
||||||
|
@ -247,9 +247,7 @@ private:
|
|||||||
const std::shared_ptr<Waap::Trigger::Log> &triggerLog,
|
const std::shared_ptr<Waap::Trigger::Log> &triggerLog,
|
||||||
bool shouldBlock,
|
bool shouldBlock,
|
||||||
const std::string& logOverride,
|
const std::string& logOverride,
|
||||||
const std::string& incidentType,
|
const std::string& incidentType) const;
|
||||||
const std::string& practiceID,
|
|
||||||
const std::string& practiceName) const;
|
|
||||||
std::string getUserReputationStr(double relativeReputation) const;
|
std::string getUserReputationStr(double relativeReputation) const;
|
||||||
bool isTrustedSource() const;
|
bool isTrustedSource() const;
|
||||||
|
|
||||||
|
@ -381,11 +381,7 @@ void Waf2Transaction::sendAutonomousSecurityLog(
|
|||||||
waap_log << LogField("eventConfidence", confidence);
|
waap_log << LogField("eventConfidence", confidence);
|
||||||
}
|
}
|
||||||
|
|
||||||
appendCommonLogFields(
|
appendCommonLogFields(waap_log, triggerLog, shouldBlock, logOverride, attackTypes);
|
||||||
waap_log, triggerLog, shouldBlock, logOverride, attackTypes,
|
|
||||||
m_siteConfig->get_PracticeIdByPactice(AUTONOMOUS_SECURITY_DECISION),
|
|
||||||
m_siteConfig->get_PracticeNameByPactice(AUTONOMOUS_SECURITY_DECISION)
|
|
||||||
);
|
|
||||||
|
|
||||||
std::string sampleString = getSample();
|
std::string sampleString = getSample();
|
||||||
if (sampleString.length() > MAX_LOG_FIELD_SIZE) {
|
if (sampleString.length() > MAX_LOG_FIELD_SIZE) {
|
||||||
@ -594,6 +590,8 @@ Waap::Override::State Waf2Transaction::getOverrideState(IWaapConfig* sitePolicy)
|
|||||||
overrideState.applyOverride(*overridePolicy, WaapOverrideFunctor(*this), m_matchedOverrideIds, true);
|
overrideState.applyOverride(*overridePolicy, WaapOverrideFunctor(*this), m_matchedOverrideIds, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extractEnvSourceIdentifier();
|
||||||
|
|
||||||
if (overridePolicy) { // later we will run response overrides
|
if (overridePolicy) { // later we will run response overrides
|
||||||
m_overrideState.applyOverride(*overridePolicy, WaapOverrideFunctor(*this), m_matchedOverrideIds, false);
|
m_overrideState.applyOverride(*overridePolicy, WaapOverrideFunctor(*this), m_matchedOverrideIds, false);
|
||||||
}
|
}
|
||||||
|
@ -952,145 +952,6 @@ string filterUTF7(const string& text) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decides the status of a Base64 decoded string based on various parameters.
|
|
||||||
// @param decoded The decoded string.
|
|
||||||
// @param entropy The entropy of the original encoded string.
|
|
||||||
// @param decoded_entropy The entropy of the decoded string.
|
|
||||||
// @param spacer_count The number of spacer characters in the decoded string.
|
|
||||||
// @param nonPrintableCharsCount The count of non-printable characters in the decoded string.
|
|
||||||
// @param clear_on_error Flag indicating whether to clear the decoded string on error.
|
|
||||||
// @param terminatorCharsSeen The number of terminator characters seen.
|
|
||||||
// @param called_with_prefix Flag indicating if the function was called with a prefix.
|
|
||||||
// @return The status of the Base64 decoding process.
|
|
||||||
//
|
|
||||||
// Idea:
|
|
||||||
// Check if input chunk should be replaced by decoded, suspected to be checked both as encoded and decoded
|
|
||||||
// or cleaned as binary data. Additional case - define as not base64 encoded.
|
|
||||||
// - in case decoded size less 5 - return invalid
|
|
||||||
// - check entropy delta based on that base64 encoded data has higher entropy than decoded, usually delta = 0.25
|
|
||||||
// - this check should rize suspect but cannot work vice versa
|
|
||||||
// check if decoded chunk has more than 10% of non-printable characters - this is supect for binary data encoded
|
|
||||||
// - if no suspect for binary data and entropy is suspected, check empiric conditions to decide if this binary data
|
|
||||||
// or invalid decoding
|
|
||||||
// - if suspect for binary data, first check is we have entropy suspection
|
|
||||||
// - if entropy is suspected and chunk is short and it have more than 25% of nonprintables, return invalid
|
|
||||||
// since this is not base64 encoded data
|
|
||||||
// - if entropy is not suspected and chunk is short and it have more than 50% of nonprintables, return invalid
|
|
||||||
// since this is not base64 encoded data
|
|
||||||
// - if entropy is suspected and chunk size is between 64-1024, perform additional empiric test
|
|
||||||
// This test will define if returm value should be treated as suspected or as binary data(cleared)
|
|
||||||
|
|
||||||
base64_decode_status decideStatusBase64Decoded(
|
|
||||||
string& decoded,
|
|
||||||
double entropy,
|
|
||||||
double decoded_entropy,
|
|
||||||
size_t spacer_count,
|
|
||||||
size_t nonPrintableCharsCount,
|
|
||||||
bool clear_on_error,
|
|
||||||
double terminatorCharsSeen,
|
|
||||||
bool called_with_prefix
|
|
||||||
)
|
|
||||||
{
|
|
||||||
base64_decode_status tmp_status = B64_DECODE_OK;
|
|
||||||
if (entropy - decoded_entropy + terminatorCharsSeen < BASE64_ENTROPY_THRESHOLD_DELTA) {
|
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< "The chunk is under suspect to be base64,"
|
|
||||||
<< "use dual processing because entropy delta is too low";
|
|
||||||
tmp_status = B64_DECODE_SUSPECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empiric_condition = false;
|
|
||||||
if (decoded.size() >= 5) {
|
|
||||||
if (spacer_count > 1) {
|
|
||||||
nonPrintableCharsCount = nonPrintableCharsCount - spacer_count + 1;
|
|
||||||
}
|
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< "(before test for unprintables): decoded.size="
|
|
||||||
<< decoded.size()
|
|
||||||
<< ", nonPrintableCharsCount="
|
|
||||||
<< nonPrintableCharsCount
|
|
||||||
<< ", clear_on_error="
|
|
||||||
<< clear_on_error
|
|
||||||
<< ", called_with_prefix="
|
|
||||||
<< called_with_prefix;
|
|
||||||
if (nonPrintableCharsCount * 10 < decoded.size()) {
|
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< "(decode/replace due to small amount of nonprintables): will decide based on entropy values";
|
|
||||||
} else { // more than 10% of non-printable characters
|
|
||||||
dbgTrace(D_WAAP_BASE64) << "large amount of nonporintables";
|
|
||||||
if (tmp_status == B64_DECODE_SUSPECTED) {
|
|
||||||
// entropy - decoded_entropy + terminatorCharsSeen < 0.25
|
|
||||||
if (decoded.size() < 16 && nonPrintableCharsCount * 4 > decoded.size()) {
|
|
||||||
decoded.clear();
|
|
||||||
return B64_DECODE_INVALID;
|
|
||||||
}
|
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< "(large amount of nonporintables + entropy suspect), check emprirics because decoded."
|
|
||||||
<< " terminatorCharsSeen="
|
|
||||||
<< terminatorCharsSeen;
|
|
||||||
// empiric test based on investigation of real payloads
|
|
||||||
empiric_condition = entropy < decoded_entropy
|
|
||||||
&& entropy > BASE64_ENTROPY_BASE_THRESHOLD
|
|
||||||
&& decoded_entropy > BASE64_ENTROPY_DECODED_THRESHOLD
|
|
||||||
&& !called_with_prefix
|
|
||||||
&& decoded.size() > BASE64_MIN_SIZE_LIMIT
|
|
||||||
&& decoded.size() < BASE64_MAX_SIZE_LIMIT
|
|
||||||
&& terminatorCharsSeen != 0;
|
|
||||||
if (!empiric_condition) {
|
|
||||||
if (clear_on_error) decoded.clear();
|
|
||||||
return B64_DECODE_SUSPECTED;
|
|
||||||
} else {
|
|
||||||
if (clear_on_error) decoded.clear();
|
|
||||||
tmp_status = B64_DECODE_OK;
|
|
||||||
}
|
|
||||||
} else { // entropy - decoded_entropy + terminatorCharsSeen >= 0.25
|
|
||||||
// one more empiric based on uT and real payloads
|
|
||||||
if (decoded.size() < 16
|
|
||||||
&& nonPrintableCharsCount * 2 > decoded.size()
|
|
||||||
&& terminatorCharsSeen == 0) {
|
|
||||||
decoded.clear();
|
|
||||||
return B64_DECODE_INVALID;
|
|
||||||
}
|
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< "(delete as binary content) because decoded. Return B64_DECODE_INCOMPLETE";
|
|
||||||
if (clear_on_error) decoded.clear();
|
|
||||||
return B64_DECODE_INCOMPLETE;
|
|
||||||
}
|
|
||||||
} // less than 10% of non-printable characters
|
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< "After handling unprintables checking status";
|
|
||||||
if (tmp_status == B64_DECODE_OK) {
|
|
||||||
dbgTrace(D_WAAP_BASE64) << "replacing with decoded data, return B64_DECODE_OK";
|
|
||||||
return B64_DECODE_OK;
|
|
||||||
} else { // tmp_status == B64_DECODE_SUSPECTED, entropy - decoded_entropy + terminatorCharsSeen < 0.25
|
|
||||||
dbgTrace(D_WAAP_BASE64) << "Suspected due to entropy, making empiric test";
|
|
||||||
// and one more empiric test based on investigation of real payloads
|
|
||||||
empiric_condition = entropy < decoded_entropy
|
|
||||||
&& entropy > BASE64_ENTROPY_BASE_THRESHOLD
|
|
||||||
&& decoded_entropy > BASE64_ENTROPY_DECODED_THRESHOLD
|
|
||||||
&& !called_with_prefix
|
|
||||||
&& decoded.size() > BASE64_MIN_SIZE_LIMIT
|
|
||||||
&& decoded.size() < BASE64_MAX_SIZE_LIMIT;
|
|
||||||
if (empiric_condition) {
|
|
||||||
dbgTrace(D_WAAP_BASE64) << "Empiric test failed, non-base64 chunk, return B64_DECODE_INVALID";
|
|
||||||
decoded.clear();
|
|
||||||
return B64_DECODE_INVALID;
|
|
||||||
}
|
|
||||||
dbgTrace(D_WAAP_BASE64) << "Empiric test passed, return B64_DECODE_SUSPECTED";
|
|
||||||
return B64_DECODE_SUSPECTED;
|
|
||||||
}
|
|
||||||
return B64_DECODE_OK; // successfully decoded. Returns decoded data in "decoded" parameter
|
|
||||||
}
|
|
||||||
|
|
||||||
// If decoded size is too small - leave the encoded value (return false)
|
|
||||||
decoded.clear(); // discard partial data
|
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< "(leave as-is) because decoded too small. decoded.size="
|
|
||||||
<< decoded.size();
|
|
||||||
return B64_DECODE_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Attempts to validate and decode base64-encoded chunk.
|
// Attempts to validate and decode base64-encoded chunk.
|
||||||
// Value is the full value inside which potential base64-encoded chunk was found,
|
// Value is the full value inside which potential base64-encoded chunk was found,
|
||||||
// it and end point to start and end of that chunk.
|
// it and end point to start and end of that chunk.
|
||||||
@ -1119,28 +980,18 @@ base64_decode_status decodeBase64Chunk(
|
|||||||
uint32_t spacer_count = 0;
|
uint32_t spacer_count = 0;
|
||||||
uint32_t length = end - it;
|
uint32_t length = end - it;
|
||||||
|
|
||||||
dbgTrace(D_WAAP)
|
dbgTrace(D_WAAP) << "decodeBase64Chunk: value='" << value << "' match='" << string(it, end) << "'";
|
||||||
<< "value='"
|
|
||||||
<< value
|
|
||||||
<< "' match='"
|
|
||||||
<< string(it, end)
|
|
||||||
<< "' clear_on_error='"
|
|
||||||
<< clear_on_error
|
|
||||||
<< "' called_with_prefix='"
|
|
||||||
<< called_with_prefix
|
|
||||||
<< "'";
|
|
||||||
string::const_iterator begin = it;
|
string::const_iterator begin = it;
|
||||||
|
|
||||||
// The encoded data length (without the "base64," prefix) should be exactly divisible by 4
|
// The encoded data length (without the "base64," prefix) should be exactly divisible by 4
|
||||||
// len % 4 is not 0 i.e. this is not base64
|
// len % 4 is not 0 i.e. this is not base64
|
||||||
if ((end - it) % 4 == 1) {
|
if ((end - it) % 4 != 0) {
|
||||||
dbgTrace(D_WAAP_BASE64)
|
dbgTrace(D_WAAP_BASE64) <<
|
||||||
<< "(leave as-is) because encoded data length should not be <4*x + 1>.";
|
"b64DecodeChunk: (leave as-is) because encoded data length should be exactly divisible by 4.";
|
||||||
return B64_DECODE_INVALID;
|
return B64_DECODE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<char, double> original_occurences_counter;
|
std::unordered_map<char, double> frequency;
|
||||||
std::unordered_map<char, double> decoded_occurences_counter;
|
|
||||||
|
|
||||||
while (it != end) {
|
while (it != end) {
|
||||||
unsigned char c = *it;
|
unsigned char c = *it;
|
||||||
@ -1148,8 +999,9 @@ base64_decode_status decodeBase64Chunk(
|
|||||||
if (terminatorCharsSeen) {
|
if (terminatorCharsSeen) {
|
||||||
// terminator characters must all be '=', until end of match.
|
// terminator characters must all be '=', until end of match.
|
||||||
if (c != '=') {
|
if (c != '=') {
|
||||||
dbgTrace(D_WAAP_BASE64)
|
dbgTrace(D_WAAP_BASE64) <<
|
||||||
<< "(leave as-is) because terminator characters must all be '=' until end of match.";
|
"decodeBase64Chunk: (leave as-is) because terminator characters must all be '='," <<
|
||||||
|
"until end of match.";
|
||||||
return B64_DECODE_INVALID;
|
return B64_DECODE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1157,13 +1009,13 @@ base64_decode_status decodeBase64Chunk(
|
|||||||
terminatorCharsSeen++;
|
terminatorCharsSeen++;
|
||||||
|
|
||||||
if (terminatorCharsSeen > 2) {
|
if (terminatorCharsSeen > 2) {
|
||||||
dbgTrace(D_WAAP_BASE64) << "(leave as-is) because terminatorCharsSeen > 2";
|
dbgTrace(D_WAAP_BASE64) << "decodeBase64Chunk: (leave as-is) because terminatorCharsSeen > 2";
|
||||||
return B64_DECODE_INVALID;
|
return B64_DECODE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow for more terminator characters
|
// allow for more terminator characters
|
||||||
it++;
|
it++;
|
||||||
original_occurences_counter[c]++;
|
frequency[c]++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1188,18 +1040,12 @@ base64_decode_status decodeBase64Chunk(
|
|||||||
// Start tracking terminator characters
|
// Start tracking terminator characters
|
||||||
terminatorCharsSeen++;
|
terminatorCharsSeen++;
|
||||||
it++;
|
it++;
|
||||||
original_occurences_counter[c]++;
|
frequency[c]++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dbgTrace(D_WAAP_BASE64)
|
dbgTrace(D_WAAP_BASE64) << "decodeBase64Chunk: (leave as-is) because of non-base64 character ('" <<
|
||||||
<< "(leave as-is) because of non-base64 character ('"
|
c << "', ASCII " << (unsigned int)c << ", offset " << (it-begin) << ")";
|
||||||
<< c
|
|
||||||
<< "', ASCII "
|
|
||||||
<< (unsigned int)c
|
|
||||||
<< ", offset "
|
|
||||||
<< (it-begin)
|
|
||||||
<< ")";
|
|
||||||
return B64_DECODE_INVALID; // non-base64 character
|
return B64_DECODE_INVALID; // non-base64 character
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1222,19 +1068,18 @@ base64_decode_status decodeBase64Chunk(
|
|||||||
}
|
}
|
||||||
|
|
||||||
decoded += (char)code;
|
decoded += (char)code;
|
||||||
decoded_occurences_counter[(char)code]++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it++;
|
it++;
|
||||||
original_occurences_counter[c]++;
|
frequency[c]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// end of encoded sequence decoded.
|
// end of encoded sequence decoded.
|
||||||
|
|
||||||
dbgTrace(D_WAAP_BASE64)
|
dbgTrace(D_WAAP_BASE64)
|
||||||
<< "decoding done: decoded.size="
|
<< "decodeBase64Chunk: decoded.size="
|
||||||
<< decoded.size()
|
<< decoded.size()
|
||||||
<< ", uncorrected nonPrintableCharsCount="
|
<< ", nonPrintableCharsCount="
|
||||||
<< nonPrintableCharsCount
|
<< nonPrintableCharsCount
|
||||||
<< ", spacer_count = "
|
<< ", spacer_count = "
|
||||||
<< spacer_count
|
<< spacer_count
|
||||||
@ -1243,42 +1088,56 @@ base64_decode_status decodeBase64Chunk(
|
|||||||
<< "; decoded='"
|
<< "; decoded='"
|
||||||
<< decoded << "'";
|
<< decoded << "'";
|
||||||
|
|
||||||
|
// Check if entropy is correlates with b64 threshold (initially > 4.5)
|
||||||
|
if (!called_with_prefix) {
|
||||||
double entropy = 0;
|
double entropy = 0;
|
||||||
double p = 0;
|
double p = 0;
|
||||||
double decoded_entropy = 0;
|
for (const auto& pair : frequency) {
|
||||||
for (const auto& pair : original_occurences_counter) {
|
|
||||||
p = pair.second / length;
|
p = pair.second / length;
|
||||||
entropy -= p * std::log2(p);
|
entropy -= p * std::log2(p);
|
||||||
}
|
}
|
||||||
for (const auto &pair : decoded_occurences_counter) {
|
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: base entropy = " << entropy << "length = " << length;
|
||||||
p = pair.second / decoded.size();
|
// Add short payload factor
|
||||||
decoded_entropy -= p * std::log2(p);
|
if (length < 16)
|
||||||
|
entropy = entropy * 16 / length;
|
||||||
|
// Enforce tailoring '=' characters
|
||||||
|
entropy+=terminatorCharsSeen;
|
||||||
|
|
||||||
|
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: corrected entropy = " << entropy << "length = " << length;
|
||||||
|
if (entropy <= base64_entropy_threshold) {
|
||||||
|
return B64_DECODE_INVALID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< "Base entropy = "
|
|
||||||
<< entropy
|
|
||||||
<< " Decoded_entropy = "
|
|
||||||
<< decoded_entropy
|
|
||||||
<< "length = "
|
|
||||||
<< length;
|
|
||||||
|
|
||||||
base64_decode_status return_status = decideStatusBase64Decoded(
|
// Return success only if decoded.size>=5 and there are less than 10% of non-printable
|
||||||
decoded,
|
// characters in output.
|
||||||
entropy,
|
if (decoded.size() >= 5) {
|
||||||
decoded_entropy,
|
if (spacer_count > 1) {
|
||||||
spacer_count,
|
nonPrintableCharsCount = nonPrintableCharsCount - spacer_count + 1;
|
||||||
nonPrintableCharsCount,
|
}
|
||||||
clear_on_error,
|
if (nonPrintableCharsCount * 10 < decoded.size()) {
|
||||||
terminatorCharsSeen,
|
dbgTrace(D_WAAP_BASE64) << "decodeBase64Chunk: (decode/replace) decoded.size=" << decoded.size() <<
|
||||||
called_with_prefix
|
", nonPrintableCharsCount=" << nonPrintableCharsCount << ": replacing with decoded data";
|
||||||
);
|
}
|
||||||
|
else {
|
||||||
dbgTrace(D_WAAP_BASE64)
|
dbgTrace(D_WAAP_BASE64) << "decodeBase64Chunk: (delete) because decoded.size=" << decoded.size() <<
|
||||||
<< "After decideStatusBase64Decoded return_status="
|
", nonPrintableCharsCount=" << nonPrintableCharsCount <<
|
||||||
<< return_status;
|
", clear_on_error=" << clear_on_error;
|
||||||
|
if (clear_on_error) decoded.clear();
|
||||||
return return_status;
|
return B64_DECODE_INCOMPLETE;
|
||||||
|
}
|
||||||
|
dbgTrace(D_WAAP_BASE64) << "returning true: successfully decoded."
|
||||||
|
<< " Returns decoded data in \"decoded\" parameter";
|
||||||
|
return B64_DECODE_OK; // successfully decoded. Returns decoded data in "decoded" parameter
|
||||||
|
}
|
||||||
|
|
||||||
|
// If decoded size is too small - leave the encoded value (return false)
|
||||||
|
decoded.clear(); // discard partial data
|
||||||
|
dbgTrace(D_WAAP_BASE64) << "decodeBase64Chunk: (leave as-is) because decoded too small. decoded.size=" <<
|
||||||
|
decoded.size() <<
|
||||||
|
", nonPrintableCharsCount=" << nonPrintableCharsCount <<
|
||||||
|
", clear_on_error=" << clear_on_error;
|
||||||
|
return B64_DECODE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempts to detect and validate base64 chunk.
|
// Attempts to detect and validate base64 chunk.
|
||||||
@ -1321,9 +1180,8 @@ b64DecodeChunk(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
base64_decode_status status = decodeBase64Chunk(value, it, end, decoded);
|
|
||||||
dbgTrace(D_WAAP_BASE64) << "b64DecodeChunk: status = " << status;
|
return decodeBase64Chunk(value, it, end, decoded) != B64_DECODE_INVALID;
|
||||||
return status != B64_DECODE_INVALID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<string> split(const string& s, char delim) {
|
vector<string> split(const string& s, char delim) {
|
||||||
@ -1423,7 +1281,6 @@ static void b64TestChunk(const string &s,
|
|||||||
int &deletedCount,
|
int &deletedCount,
|
||||||
string &outStr)
|
string &outStr)
|
||||||
{
|
{
|
||||||
dbgTrace(D_WAAP_BASE64) << " ===b64TestChunk===: starting with = '" << s << "'";
|
|
||||||
size_t chunkLen = (chunkEnd - chunkStart);
|
size_t chunkLen = (chunkEnd - chunkStart);
|
||||||
|
|
||||||
if ((chunkEnd - chunkStart) > static_cast<int>(b64_prefix.size()) &&
|
if ((chunkEnd - chunkStart) > static_cast<int>(b64_prefix.size()) &&
|
||||||
@ -1432,9 +1289,11 @@ static void b64TestChunk(const string &s,
|
|||||||
chunkLen -= b64_prefix.size();
|
chunkLen -= b64_prefix.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t chunkRem = chunkLen % 4;
|
||||||
|
|
||||||
|
// Only match chunk whose length is divisible by 4
|
||||||
string repl;
|
string repl;
|
||||||
dbgTrace(D_WAAP_BASE64) << " ===b64TestChunk===: chunkLen = " << chunkLen;
|
if (chunkRem == 0 && cb(s, chunkStart, chunkEnd, repl)) {
|
||||||
if (cb(s, chunkStart, chunkEnd, repl)) {
|
|
||||||
// Succesfully matched b64 chunk
|
// Succesfully matched b64 chunk
|
||||||
if (!repl.empty()) {
|
if (!repl.empty()) {
|
||||||
outStr += repl;
|
outStr += repl;
|
||||||
@ -1481,8 +1340,10 @@ bool detectBase64Chunk(
|
|||||||
dbgTrace(D_WAAP_BASE64) << " ===detectBase64Chunk===: isB64AlphaChar = true, '" << *it << "'";
|
dbgTrace(D_WAAP_BASE64) << " ===detectBase64Chunk===: isB64AlphaChar = true, '" << *it << "'";
|
||||||
start = it;
|
start = it;
|
||||||
end = s.end();
|
end = s.end();
|
||||||
|
if ((end - start) % 4 == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// non base64 before supposed chunk - will not process
|
// non base64 before supposed chunk - will not process
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1520,31 +1381,17 @@ bool isBase64PrefixProcessingOK (
|
|||||||
if (detectBase64Chunk(s, start, end)) {
|
if (detectBase64Chunk(s, start, end)) {
|
||||||
dbgTrace(D_WAAP_BASE64) << " ===isBase64PrefixProcessingOK===: chunk detected";
|
dbgTrace(D_WAAP_BASE64) << " ===isBase64PrefixProcessingOK===: chunk detected";
|
||||||
if ((start != s.end()) && (end == s.end())) {
|
if ((start != s.end()) && (end == s.end())) {
|
||||||
dbgTrace(D_WAAP_BASE64) << " ===isBase64PrefixProcessingOK===: chunk detected but not complete";
|
|
||||||
retVal = processDecodedChunk(s, start, end, value, binaryFileType, true);
|
retVal = processDecodedChunk(s, start, end, value, binaryFileType, true);
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< " ===isBase64PrefixProcessingOK===: after processDecodedChunk retVal = "
|
|
||||||
<< retVal
|
|
||||||
<< " binaryFileType = "
|
|
||||||
<< binaryFileType;
|
|
||||||
}
|
}
|
||||||
} else if (start != s.end()) {
|
} else if (start != s.end()) {
|
||||||
dbgTrace(D_WAAP_BASE64)
|
dbgTrace(D_WAAP_BASE64) << " ===isBase64PrefixProcessingOK===: chunk not detected."
|
||||||
<< " ===isBase64PrefixProcessingOK===: chunk not detected. searching for known file header only";
|
" searching for known file header only";
|
||||||
end = (start + MAX_HEADER_LOOKUP < s.end()) ? start + MAX_HEADER_LOOKUP : s.end();
|
end = (start + MAX_HEADER_LOOKUP < s.end()) ? start + MAX_HEADER_LOOKUP : s.end();
|
||||||
processDecodedChunk(s, start, end, value, binaryFileType);
|
processDecodedChunk(s, start, end, value, binaryFileType);
|
||||||
value.clear();
|
value.clear();
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< " ===isBase64PrefixProcessingOK===: after processDecodedChunk binaryFileType = "
|
|
||||||
<< binaryFileType;
|
|
||||||
return binaryFileType != Waap::Util::BinaryFileType::FILE_TYPE_NONE;
|
return binaryFileType != Waap::Util::BinaryFileType::FILE_TYPE_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< " ===isBase64PrefixProcessingOK===: retVal = "
|
|
||||||
<< retVal
|
|
||||||
<< " binaryFileType = "
|
|
||||||
<< binaryFileType;
|
|
||||||
return retVal != B64_DECODE_INVALID;
|
return retVal != B64_DECODE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1552,31 +1399,23 @@ base64_variants b64Test (
|
|||||||
const string &s,
|
const string &s,
|
||||||
string &key,
|
string &key,
|
||||||
string &value,
|
string &value,
|
||||||
BinaryFileType &binaryFileType,
|
BinaryFileType &binaryFileType)
|
||||||
const size_t offset)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
key.clear();
|
key.clear();
|
||||||
|
bool retVal;
|
||||||
binaryFileType = Waap::Util::BinaryFileType::FILE_TYPE_NONE;
|
binaryFileType = Waap::Util::BinaryFileType::FILE_TYPE_NONE;
|
||||||
auto begin = s.begin() + offset;
|
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< " ===b64Test===: string = "
|
|
||||||
<< s
|
|
||||||
<< " key = "
|
|
||||||
<< key
|
|
||||||
<< " value = "
|
|
||||||
<< value
|
|
||||||
<< " offset = "
|
|
||||||
<< offset;
|
|
||||||
|
|
||||||
|
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: string = " << s
|
||||||
|
<< " key = " << key << " value = " << value;
|
||||||
// Minimal length
|
// Minimal length
|
||||||
if (s.size() < 8 + offset) {
|
if (s.size() < 8) {
|
||||||
return CONTINUE_AS_IS;
|
return CONTINUE_AS_IS;
|
||||||
}
|
}
|
||||||
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: minimal lenght test passed";
|
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: minimal lenght test passed";
|
||||||
|
|
||||||
std::string prefix_decoded_val;
|
std::string prefix_decoded_val;
|
||||||
auto it = begin;
|
string::const_iterator it = s.begin();
|
||||||
|
|
||||||
// 1st check if we have key candidate
|
// 1st check if we have key candidate
|
||||||
if (base64_key_value_detector_re.hasMatch(s)) {
|
if (base64_key_value_detector_re.hasMatch(s)) {
|
||||||
@ -1594,7 +1433,7 @@ base64_variants b64Test (
|
|||||||
break;
|
break;
|
||||||
case EQUAL:
|
case EQUAL:
|
||||||
if (*it == '=') {
|
if (*it == '=') {
|
||||||
it = begin;
|
it = s.begin();
|
||||||
state=MISDETECT;
|
state=MISDETECT;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1616,7 +1455,7 @@ base64_variants b64Test (
|
|||||||
if (it == s.end() || state == MISDETECT) {
|
if (it == s.end() || state == MISDETECT) {
|
||||||
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: detected *it = s.end()" << *it;
|
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: detected *it = s.end()" << *it;
|
||||||
if (key.size() > 0) {
|
if (key.size() > 0) {
|
||||||
it = begin;
|
it = s.begin();
|
||||||
key.clear();
|
key.clear();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1640,7 +1479,7 @@ base64_variants b64Test (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto start = s.end();
|
string::const_iterator start = s.end();
|
||||||
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: B64 itself = " << *it << " =======";
|
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: B64 itself = " << *it << " =======";
|
||||||
bool isB64AlphaChar = Waap::Util::isAlphaAsciiFast(*it) || isdigit(*it) || *it=='/' || *it=='+';
|
bool isB64AlphaChar = Waap::Util::isAlphaAsciiFast(*it) || isdigit(*it) || *it=='/' || *it=='+';
|
||||||
if (isB64AlphaChar) {
|
if (isB64AlphaChar) {
|
||||||
@ -1648,6 +1487,11 @@ base64_variants b64Test (
|
|||||||
dbgTrace(D_WAAP_BASE64) <<
|
dbgTrace(D_WAAP_BASE64) <<
|
||||||
" ===b64Test===: Start tracking potential b64 chunk = " << *it << " =======";
|
" ===b64Test===: Start tracking potential b64 chunk = " << *it << " =======";
|
||||||
start = it;
|
start = it;
|
||||||
|
if ((s.end() - start) % 4 != 0) {
|
||||||
|
key.clear();
|
||||||
|
value.clear();
|
||||||
|
return CONTINUE_AS_IS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dbgTrace(D_WAAP_BASE64) <<
|
dbgTrace(D_WAAP_BASE64) <<
|
||||||
@ -1668,37 +1512,17 @@ base64_variants b64Test (
|
|||||||
key.pop_back();
|
key.pop_back();
|
||||||
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: FINAL key = '" << key << "'";
|
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: FINAL key = '" << key << "'";
|
||||||
}
|
}
|
||||||
base64_decode_status decode_chunk_status = decodeBase64Chunk(s, start, s.end(), value);
|
retVal = decodeBase64Chunk(s, start, s.end(), value) != B64_DECODE_INVALID;
|
||||||
|
|
||||||
dbgTrace(D_WAAP_BASE64)
|
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: After testing and conversion value = "
|
||||||
<< " ===b64Test===: After testing and conversion value = "
|
<< value << "retVal = '" << retVal <<"'";
|
||||||
<< value
|
if (!retVal) {
|
||||||
<< "decode_chunk_status = '"
|
|
||||||
<< decode_chunk_status
|
|
||||||
<<"'";
|
|
||||||
if (decode_chunk_status == B64_DECODE_INVALID) {
|
|
||||||
key.clear();
|
key.clear();
|
||||||
value.clear();
|
value.clear();
|
||||||
return CONTINUE_AS_IS;
|
return CONTINUE_AS_IS;
|
||||||
}
|
}
|
||||||
|
dbgTrace(D_WAAP_BASE64) << " ===b64Test===: After tpassed retVal check = "
|
||||||
if (decode_chunk_status == B64_DECODE_INCOMPLETE) {
|
<< value << "retVal = '" << retVal <<"'" << "key = '" << key << "'";
|
||||||
value.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decode_chunk_status == B64_DECODE_SUSPECTED) {
|
|
||||||
return CONTINUE_DUAL_SCAN;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< " ===b64Test===: After tpassed retVal check = "
|
|
||||||
<< value
|
|
||||||
<< "decode_chunk_status = '"
|
|
||||||
<< decode_chunk_status
|
|
||||||
<<"'"
|
|
||||||
<< "key = '"
|
|
||||||
<< key
|
|
||||||
<< "'";
|
|
||||||
if (key.empty()) {
|
if (key.empty()) {
|
||||||
return SINGLE_B64_CHUNK_CONVERT;
|
return SINGLE_B64_CHUNK_CONVERT;
|
||||||
} else {
|
} else {
|
||||||
@ -1724,7 +1548,7 @@ void b64Decode(
|
|||||||
deletedCount = 0;
|
deletedCount = 0;
|
||||||
outStr = "";
|
outStr = "";
|
||||||
int offsetFix = 0;
|
int offsetFix = 0;
|
||||||
dbgTrace(D_WAAP_BASE64) << " ===b64Decode===: starting with = '" << s << "'";
|
|
||||||
string::const_iterator it = s.begin();
|
string::const_iterator it = s.begin();
|
||||||
|
|
||||||
// Minimal length
|
// Minimal length
|
||||||
@ -1772,11 +1596,6 @@ void b64Decode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decode and add chunk
|
// Decode and add chunk
|
||||||
dbgTrace(D_WAAP_BASE64)
|
|
||||||
<< " ===b64Decode===: chunkStart = "
|
|
||||||
<< *chunkStart
|
|
||||||
<< " it = "
|
|
||||||
<< *it;
|
|
||||||
b64TestChunk(s, chunkStart, it, cb, decodedCount, deletedCount, outStr);
|
b64TestChunk(s, chunkStart, it, cb, decodedCount, deletedCount, outStr);
|
||||||
|
|
||||||
// stop tracking b64 chunk
|
// stop tracking b64 chunk
|
||||||
@ -1788,7 +1607,6 @@ void b64Decode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (chunkStart != s.end()) {
|
if (chunkStart != s.end()) {
|
||||||
dbgTrace(D_WAAP_BASE64) << " ===b64Decode===: chunkStart = " << *chunkStart;
|
|
||||||
b64TestChunk(s, chunkStart, it, cb, decodedCount, deletedCount, outStr);
|
b64TestChunk(s, chunkStart, it, cb, decodedCount, deletedCount, outStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,15 +32,9 @@
|
|||||||
|
|
||||||
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||||
|
|
||||||
enum base64_variants {SINGLE_B64_CHUNK_CONVERT, KEY_VALUE_B64_PAIR, CONTINUE_AS_IS, CONTINUE_DUAL_SCAN};
|
enum base64_variants {SINGLE_B64_CHUNK_CONVERT, KEY_VALUE_B64_PAIR, CONTINUE_AS_IS};
|
||||||
enum base64_stage {BEFORE_EQUAL, EQUAL, DONE, MISDETECT};
|
enum base64_stage {BEFORE_EQUAL, EQUAL, DONE, MISDETECT};
|
||||||
enum base64_decode_status {B64_DECODE_INVALID, B64_DECODE_OK, B64_DECODE_INCOMPLETE, B64_DECODE_SUSPECTED};
|
enum base64_decode_status {B64_DECODE_INVALID, B64_DECODE_OK, B64_DECODE_INCOMPLETE};
|
||||||
|
|
||||||
#define BASE64_ENTROPY_BASE_THRESHOLD 5.0
|
|
||||||
#define BASE64_ENTROPY_DECODED_THRESHOLD 5.4
|
|
||||||
#define BASE64_ENTROPY_THRESHOLD_DELTA 0.25
|
|
||||||
#define BASE64_MIN_SIZE_LIMIT 16
|
|
||||||
#define BASE64_MAX_SIZE_LIMIT 1024
|
|
||||||
|
|
||||||
// This is portable version of stricmp(), which is non-standard function (not even in C).
|
// This is portable version of stricmp(), which is non-standard function (not even in C).
|
||||||
// Contrary to stricmp(), for a slight optimization, s2 is ASSUMED to be already in lowercase.
|
// Contrary to stricmp(), for a slight optimization, s2 is ASSUMED to be already in lowercase.
|
||||||
@ -227,66 +221,59 @@ inline bool isHexDigit(const char ch) {
|
|||||||
|
|
||||||
template<class _IT>
|
template<class _IT>
|
||||||
_IT escape_backslashes(_IT first, _IT last) {
|
_IT escape_backslashes(_IT first, _IT last) {
|
||||||
_IT src = first;
|
_IT result = first;
|
||||||
_IT dst = first;
|
|
||||||
_IT mark = first;
|
|
||||||
|
|
||||||
enum { STATE_COPY, STATE_ESCAPE, STATE_OCTAL, STATE_HEX } state = STATE_COPY;
|
enum { STATE_COPY, STATE_ESCAPE, STATE_OCTAL, STATE_HEX } state = STATE_COPY;
|
||||||
unsigned char accVal = 0;
|
unsigned char accVal = 0;
|
||||||
unsigned char digitsCount = 0;
|
unsigned char digitsCount = 0;
|
||||||
|
_IT mark = first;
|
||||||
|
|
||||||
for (; src != last && dst < last; ++src) {
|
for (; first != last; ++first) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_COPY:
|
case STATE_COPY:
|
||||||
if (*src == '\\') {
|
if (*first == '\\') {
|
||||||
mark = src;
|
mark = first;
|
||||||
state = STATE_ESCAPE;
|
state = STATE_ESCAPE;
|
||||||
} else {
|
}
|
||||||
*dst++ = *src;
|
else {
|
||||||
|
*result++ = *first;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_ESCAPE: {
|
case STATE_ESCAPE: {
|
||||||
if (*src >= '0' && *src <= '7') {
|
if (*first >= '0' && *first <= '7') {
|
||||||
accVal = *src - '0';
|
accVal = *first - '0';
|
||||||
digitsCount = 1;
|
digitsCount = 1;
|
||||||
state = STATE_OCTAL;
|
state = STATE_OCTAL;
|
||||||
break;
|
break;
|
||||||
} else if (*src == 'x') {
|
} else if (*first == 'x') {
|
||||||
accVal = 0;
|
accVal = 0;
|
||||||
digitsCount = 0;
|
digitsCount = 0;
|
||||||
state = STATE_HEX;
|
state = STATE_HEX;
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
switch (*src) {
|
else {
|
||||||
// Copy a matching character without the backslash before it
|
switch (*first) {
|
||||||
case 'a': *dst++ = 7; break; // BELL
|
case 'a': *result++ = 7; break; // BELL
|
||||||
case 'b': *dst++ = 8; break; // BACKSPACE
|
case 'b': *result++ = 8; break; // BACKSPACE
|
||||||
case 'e': *dst++ = 27; break; // ESCAPE
|
case 't': *result++ = 9; break; // HORIZONTAL TAB
|
||||||
case 't': *dst++ = 9; break; // HORIZONTAL TAB
|
case 'n': *result++ = 10; break; // LINEFEED
|
||||||
case 'n': *dst++ = 10; break; // LINEFEED
|
case 'v': *result++ = 11; break; // VERTICAL TAB
|
||||||
case 'v': *dst++ = 11; break; // VERTICAL TAB
|
case 'f': *result++ = 12; break; // FORMFEED
|
||||||
case 'f': *dst++ = 12; break; // FORMFEED
|
case 'r': *result++ = 13; break; // CARRIAGE RETURN
|
||||||
case 'r': *dst++ = 13; break; // CARRIAGE RETURN
|
case '\\': *result++ = '\\'; break; // upon seeing double backslash - output only one
|
||||||
case '\?': *dst++ = '\?'; break; // QUESTION MARK
|
case '\"': *result++ = '"'; break; // backslash followed by '"' - output only '"'
|
||||||
case '\\': *dst++ = '\\'; break; // upon seeing double backslash - output only one
|
|
||||||
case '\"': *dst++ = '\"'; break; // DOUBLE QUOTE
|
|
||||||
case '\'': *dst++ = '\''; break; // SINGLE QUOTE
|
|
||||||
default:
|
default:
|
||||||
// invalid escape sequence - do not replace it (return original characters)
|
// invalid escape sequence - do not replace it (return original characters)
|
||||||
// Copy from back-track, not including current character, and continue
|
// Copy from back-track, not including current character, and continue
|
||||||
while (dst <= mark && mark < src) {
|
while (mark < first) {
|
||||||
*dst++ = *mark++;
|
*result++ = *mark++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy current (terminator) character which is not "escape" and return to copy state
|
// Copy current (terminator) character which is not "escape" and return to copy state
|
||||||
// If current character is escape - stay is "escape" state
|
// If current character is escape - stay is "escape" state
|
||||||
if (*src != '\\') {
|
if (*first != '\\') {
|
||||||
*dst++ = *src;
|
*result++ = *mark++;
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
} else {
|
|
||||||
mark = src;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
@ -295,26 +282,28 @@ _IT escape_backslashes(_IT first, _IT last) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STATE_OCTAL: {
|
case STATE_OCTAL: {
|
||||||
if (*src >= '0' && *src <= '7') {
|
if (*first >='0' && *first<='7') {
|
||||||
accVal = (accVal << 3) | (*src - '0');
|
accVal = (accVal << 3) | (*first - '0');
|
||||||
digitsCount++;
|
digitsCount++;
|
||||||
|
|
||||||
// Up to 3 octal digits imposed by C standard, so after 3 digits accumulation stops.
|
// Up to 3 octal digits imposed by C standard, so after 3 digits accumulation stops.
|
||||||
if (digitsCount == 3) {
|
if (digitsCount == 3) {
|
||||||
*dst++ = accVal; // output character corresponding to collected accumulated value
|
*result++ = accVal; // output character corresponding to collected accumulated value
|
||||||
digitsCount = 0;
|
digitsCount = 0;
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// invalid octal digit stops the accumulation
|
// invalid octal digit stops the accumulation
|
||||||
*dst++ = accVal; // output character corresponding to collected accumulated value
|
*result++ = accVal; // output character corresponding to collected accumulated value
|
||||||
digitsCount = 0;
|
digitsCount = 0;
|
||||||
if (*src != '\\') {
|
if (*first != '\\') {
|
||||||
// If terminating character is not backslash output the terminating character
|
// If terminating character is not backslash output the terminating character
|
||||||
*dst++ = *src;
|
*result++ = *first;
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// If terminating character is backslash start next escape sequence
|
// If terminating character is backslash start next escape sequence
|
||||||
mark = src;
|
|
||||||
state = STATE_ESCAPE;
|
state = STATE_ESCAPE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,33 +311,36 @@ _IT escape_backslashes(_IT first, _IT last) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STATE_HEX: {
|
case STATE_HEX: {
|
||||||
if (!isHexDigit(*src)) {
|
if (!isHexDigit(*first)) {
|
||||||
// Copy from back-track, not including *src character (which is absent), and continue
|
// Copy from back-track, not including current character (which is absent), and continue
|
||||||
while (dst <= mark && mark < src) {
|
while (mark < first) {
|
||||||
*dst++ = *mark++;
|
*result++ = *mark++;
|
||||||
}
|
}
|
||||||
if (*src != '\\') {
|
if (*first != '\\') {
|
||||||
// If terminating character is not backslash output the terminating character
|
// If terminating character is not backslash output the terminating character
|
||||||
*dst++ = *src;
|
*result++ = *first;
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// If terminating character is backslash start next escape sequence
|
// If terminating character is backslash start next escape sequence
|
||||||
mark = src;
|
|
||||||
state = STATE_ESCAPE;
|
state = STATE_ESCAPE;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
accVal = accVal << 4;
|
accVal = accVal << 4;
|
||||||
if (isdigit(*src)) {
|
if (isdigit(*first)) {
|
||||||
accVal += *src - '0';
|
accVal += *first - '0';
|
||||||
} else if (*src >= 'a' && *src <= 'f') {
|
}
|
||||||
accVal += *src - 'a' + 10;
|
else if (*first >= 'a' && *first <= 'f') {
|
||||||
} else if (*src >= 'A' && *src <= 'F') {
|
accVal += *first - 'a' + 10;
|
||||||
accVal += *src - 'A' + 10;
|
}
|
||||||
|
else if (*first >= 'A' && *first <= 'F') {
|
||||||
|
accVal += *first - 'A' + 10;
|
||||||
}
|
}
|
||||||
digitsCount++;
|
digitsCount++;
|
||||||
// exactly 2 hex digits are anticipated, so after 2 digits accumulation stops.
|
// exactly 2 hex digits are anticipated, so after 2 digits accumulation stops.
|
||||||
if (digitsCount == 2) {
|
if (digitsCount == 2) {
|
||||||
*dst++ = accVal; // output character corresponding to collected accumulated value
|
*result++ = accVal; // output character corresponding to collected accumulated value
|
||||||
digitsCount = 0;
|
digitsCount = 0;
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
}
|
}
|
||||||
@ -358,7 +350,6 @@ _IT escape_backslashes(_IT first, _IT last) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dst < last) {
|
|
||||||
// Handle state at end of input
|
// Handle state at end of input
|
||||||
bool copyBackTrack = true;
|
bool copyBackTrack = true;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -368,7 +359,7 @@ _IT escape_backslashes(_IT first, _IT last) {
|
|||||||
break;
|
break;
|
||||||
case STATE_OCTAL:
|
case STATE_OCTAL:
|
||||||
// this can only happen when less than 3 octal digits are found at the value end, like '\1' or '\12'
|
// this can only happen when less than 3 octal digits are found at the value end, like '\1' or '\12'
|
||||||
*dst++ = accVal; // output character corresponding to collected accumulated value
|
*result++ = accVal; // output character corresponding to collected accumulated value
|
||||||
copyBackTrack = false;
|
copyBackTrack = false;
|
||||||
break;
|
break;
|
||||||
case STATE_COPY:
|
case STATE_COPY:
|
||||||
@ -381,13 +372,12 @@ _IT escape_backslashes(_IT first, _IT last) {
|
|||||||
if (copyBackTrack) {
|
if (copyBackTrack) {
|
||||||
// invalid escape sequence - do not replace it (return original characters)
|
// invalid escape sequence - do not replace it (return original characters)
|
||||||
// Copy from back-track
|
// Copy from back-track
|
||||||
while (dst <= mark && mark < src) {
|
while (mark < first) {
|
||||||
*dst++ = *mark++;
|
*result++ = *mark++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dst;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool str_contains(const std::string &haystack, const std::string &needle)
|
inline bool str_contains(const std::string &haystack, const std::string &needle)
|
||||||
@ -405,8 +395,7 @@ extern const size_t g_htmlEntitiesCount;
|
|||||||
|
|
||||||
template<class _IT>
|
template<class _IT>
|
||||||
_IT escape_html(_IT first, _IT last) {
|
_IT escape_html(_IT first, _IT last) {
|
||||||
_IT dst = first;
|
_IT result = first;
|
||||||
_IT src = first;
|
|
||||||
enum {
|
enum {
|
||||||
STATE_COPY,
|
STATE_COPY,
|
||||||
STATE_ESCAPE,
|
STATE_ESCAPE,
|
||||||
@ -419,26 +408,26 @@ _IT escape_html(_IT first, _IT last) {
|
|||||||
std::list<size_t> potentialMatchIndices;
|
std::list<size_t> potentialMatchIndices;
|
||||||
size_t matchLength = 0;
|
size_t matchLength = 0;
|
||||||
size_t lastKnownMatchIndex = -1;
|
size_t lastKnownMatchIndex = -1;
|
||||||
_IT mark = src;
|
_IT mark = first;
|
||||||
|
|
||||||
for (; src != last && dst < last; ++src) {
|
for (; first != last; ++first) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_COPY:
|
case STATE_COPY:
|
||||||
if (*src == '&') {
|
if (*first == '&') {
|
||||||
mark = src;
|
mark = first;
|
||||||
state = STATE_ESCAPE;
|
state = STATE_ESCAPE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*dst++ = *src;
|
*result++ = *first;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_ESCAPE:
|
case STATE_ESCAPE:
|
||||||
if (isalpha(*src)) {
|
if (isalpha(*first)) {
|
||||||
// initialize potential matches list
|
// initialize potential matches list
|
||||||
potentialMatchIndices.clear();
|
potentialMatchIndices.clear();
|
||||||
|
|
||||||
for (size_t index = 0; index < g_htmlEntitiesCount; ++index) {
|
for (size_t index = 0; index < g_htmlEntitiesCount; ++index) {
|
||||||
if (*src == g_htmlEntities[index].name[0]) {
|
if (*first == g_htmlEntities[index].name[0]) {
|
||||||
potentialMatchIndices.push_back(index);
|
potentialMatchIndices.push_back(index);
|
||||||
lastKnownMatchIndex = index;
|
lastKnownMatchIndex = index;
|
||||||
}
|
}
|
||||||
@ -446,8 +435,8 @@ _IT escape_html(_IT first, _IT last) {
|
|||||||
|
|
||||||
// No potential matches - send ampersand and current character to output
|
// No potential matches - send ampersand and current character to output
|
||||||
if (potentialMatchIndices.size() == 0) {
|
if (potentialMatchIndices.size() == 0) {
|
||||||
*dst++ = '&';
|
*result++ = '&';
|
||||||
*dst++ = *src;
|
*result++ = *first;
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -456,7 +445,7 @@ _IT escape_html(_IT first, _IT last) {
|
|||||||
matchLength = 1;
|
matchLength = 1;
|
||||||
state = STATE_NAMED_CHARACTER_REFERENCE;
|
state = STATE_NAMED_CHARACTER_REFERENCE;
|
||||||
}
|
}
|
||||||
else if (*src == '#') {
|
else if (*first == '#') {
|
||||||
digitsSeen = 0;
|
digitsSeen = 0;
|
||||||
accVal = 0;
|
accVal = 0;
|
||||||
state = STATE_NUMERIC_START;
|
state = STATE_NUMERIC_START;
|
||||||
@ -464,8 +453,8 @@ _IT escape_html(_IT first, _IT last) {
|
|||||||
else {
|
else {
|
||||||
// not isalpha and not '#' - this is invalid character reference - do not replace it
|
// not isalpha and not '#' - this is invalid character reference - do not replace it
|
||||||
// (return original characters)
|
// (return original characters)
|
||||||
*dst++ = '&';
|
*result++ = '&';
|
||||||
*dst++ = *src;
|
*result++ = *first;
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -484,7 +473,7 @@ _IT escape_html(_IT first, _IT last) {
|
|||||||
|
|
||||||
// If there are no more characters in the potntial match name,
|
// If there are no more characters in the potntial match name,
|
||||||
// or the next tested character doesn't match - kill the match
|
// or the next tested character doesn't match - kill the match
|
||||||
if ((matchName[matchLength] == '\0') || (matchName[matchLength] != *src)) {
|
if ((matchName[matchLength] == '\0') || (matchName[matchLength] != *first)) {
|
||||||
// remove current element from the list of potential matches
|
// remove current element from the list of potential matches
|
||||||
pPotentialMatchIndex = potentialMatchIndices.erase(pPotentialMatchIndex);
|
pPotentialMatchIndex = potentialMatchIndices.erase(pPotentialMatchIndex);
|
||||||
}
|
}
|
||||||
@ -500,15 +489,15 @@ _IT escape_html(_IT first, _IT last) {
|
|||||||
// No more potential matches: unsuccesful match -> flush all consumed characters back to output stream
|
// No more potential matches: unsuccesful match -> flush all consumed characters back to output stream
|
||||||
if (potentialMatchIndices.size() == 0) {
|
if (potentialMatchIndices.size() == 0) {
|
||||||
// Send consumed ampersand to the output
|
// Send consumed ampersand to the output
|
||||||
*dst++ = '&';
|
*result++ = '&';
|
||||||
|
|
||||||
// Send those matched characters (these are the same that we consumed) - to the output
|
// Send those matched characters (these are the same that we consumed) - to the output
|
||||||
for (size_t i = 0; i < matchLength; i++) {
|
for (size_t i = 0; i < matchLength; i++) {
|
||||||
*dst++ = g_htmlEntities[lastKnownMatchIndex].name[i];
|
*result++ = g_htmlEntities[lastKnownMatchIndex].name[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the character that terminated our search for possible matches
|
// Send the character that terminated our search for possible matches
|
||||||
*dst++ = *src;
|
*result++ = *first;
|
||||||
|
|
||||||
// Continue copying text verbatim
|
// Continue copying text verbatim
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
@ -516,23 +505,23 @@ _IT escape_html(_IT first, _IT last) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// There are still potential matches and ';' is hit
|
// There are still potential matches and ';' is hit
|
||||||
if (*src == ';') {
|
if (*first == ';') {
|
||||||
// longest match found for the named character reference.
|
// longest match found for the named character reference.
|
||||||
// translate it into output character(s) and we're done.
|
// translate it into output character(s) and we're done.
|
||||||
unsigned short value = g_htmlEntities[lastKnownMatchIndex].value;
|
unsigned short value = g_htmlEntities[lastKnownMatchIndex].value;
|
||||||
|
|
||||||
// Encode UTF code point as UTF-8 bytes
|
// Encode UTF code point as UTF-8 bytes
|
||||||
if (value < 0x80) {
|
if (value < 0x80) {
|
||||||
*dst++ = value;
|
*result++ = value;
|
||||||
}
|
}
|
||||||
else if (value < 0x800 ) {
|
else if (value < 0x800 ) {
|
||||||
*dst++ = (value >> 6) | 0xC0;
|
*result++ = (value >> 6) | 0xC0;
|
||||||
*dst++ = (value & 0x3F) | 0x80;
|
*result++ = (value & 0x3F) | 0x80;
|
||||||
}
|
}
|
||||||
else { // (value <= 0xFFFF : always true because value type is unsigned short which is 16-bit
|
else { // (value <= 0xFFFF : always true because value type is unsigned short which is 16-bit
|
||||||
*dst++ = (value >> 12) | 0xE0;
|
*result++ = (value >> 12) | 0xE0;
|
||||||
*dst++ = ((value >> 6) & 0x3F) | 0x80;
|
*result++ = ((value >> 6) & 0x3F) | 0x80;
|
||||||
*dst++ = (value & 0x3F) | 0x80;
|
*result++ = (value & 0x3F) | 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Continue copying text verbatim
|
// Continue copying text verbatim
|
||||||
@ -543,179 +532,178 @@ _IT escape_html(_IT first, _IT last) {
|
|||||||
case STATE_NUMERIC_START:
|
case STATE_NUMERIC_START:
|
||||||
digitsSeen = false;
|
digitsSeen = false;
|
||||||
accVal = 0;
|
accVal = 0;
|
||||||
if (*src == 'x' || *src == 'X') {
|
if (*first == 'x' || *first == 'X') {
|
||||||
state = STATE_HEX;
|
state = STATE_HEX;
|
||||||
}
|
}
|
||||||
else if (isdigit(*src)) {
|
else if (isdigit(*first)) {
|
||||||
digitsSeen = true;
|
digitsSeen = true;
|
||||||
accVal = *src - '0';
|
accVal = *first - '0';
|
||||||
state = STATE_NUMERIC;
|
state = STATE_NUMERIC;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Sequence started with these two characters: '&#', and here is the third, non-digit character
|
// Sequence started with these two characters: '&#', and here is the third, non-digit character
|
||||||
|
|
||||||
// Copy from back-track, not including current character, and continue
|
// Copy from back-track, not including current character, and continue
|
||||||
while (dst <= mark && mark < src) {
|
while (mark < first) {
|
||||||
*dst++ = *mark++;
|
*result++ = *mark++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*src == '&') {
|
if (*first == '&') {
|
||||||
// Terminator is also start of next escape sequence
|
// Terminator is also start of next escape sequence
|
||||||
mark = src;
|
mark = first;
|
||||||
state = STATE_ESCAPE;
|
state = STATE_ESCAPE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Copy the terminating character too
|
// Copy the terminating character too
|
||||||
*dst++ = *src;
|
*result++ = *first;
|
||||||
}
|
}
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_NUMERIC:
|
case STATE_NUMERIC:
|
||||||
if (!isdigit(*src)) {
|
if (!isdigit(*first)) {
|
||||||
if (digitsSeen) {
|
if (digitsSeen) {
|
||||||
// Encode UTF code point as UTF-8 bytes
|
// Encode UTF code point as UTF-8 bytes
|
||||||
if (accVal < 0x80) {
|
if (accVal < 0x80) {
|
||||||
*dst++ = accVal;
|
*result++ = accVal;
|
||||||
}
|
}
|
||||||
else if (accVal < 0x800 ) {
|
else if (accVal < 0x800 ) {
|
||||||
*dst++ = (accVal >> 6) | 0xC0;
|
*result++ = (accVal >> 6) | 0xC0;
|
||||||
*dst++ = (accVal & 0x3F) | 0x80;
|
*result++ = (accVal & 0x3F) | 0x80;
|
||||||
}
|
}
|
||||||
else { // (accVal <= 0xFFFF : always true because accVal type is unsigned short which is 16-bit
|
else { // (accVal <= 0xFFFF : always true because accVal type is unsigned short which is 16-bit
|
||||||
*dst++ = (accVal >> 12) | 0xE0;
|
*result++ = (accVal >> 12) | 0xE0;
|
||||||
*dst++ = ((accVal >> 6) & 0x3F) | 0x80;
|
*result++ = ((accVal >> 6) & 0x3F) | 0x80;
|
||||||
*dst++ = (accVal & 0x3F) | 0x80;
|
*result++ = (accVal & 0x3F) | 0x80;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Copy from back-track, not including current character (which is absent), and continue
|
// Copy from back-track, not including current character (which is absent), and continue
|
||||||
while (dst <= mark && mark < src) {
|
while (mark < first) {
|
||||||
*dst++ = *mark++;
|
*result++ = *mark++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*src == '&') {
|
if (*first == '&') {
|
||||||
// Terminator is also start of next escape sequence
|
// Terminator is also start of next escape sequence
|
||||||
mark = src;
|
mark = first;
|
||||||
state = STATE_ESCAPE;
|
state = STATE_ESCAPE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (!digitsSeen || *src != ';') {
|
else if (!digitsSeen || *first != ';') {
|
||||||
// Do not copy the ';' but do copy any other terminator
|
// Do not copy the ';' but do copy any other terminator
|
||||||
// Note: the ';' should remain in the output if there were no digits seen.
|
// Note: the ';' should remain in the output if there were no digits seen.
|
||||||
*dst++ = *src;
|
*result++ = *first;
|
||||||
}
|
}
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
digitsSeen = true;
|
digitsSeen = true;
|
||||||
accVal = accVal * 10 + *src - '0'; // TODO:: beware of integer overflow?
|
accVal = accVal * 10 + *first - '0'; // TODO:: beware of integer overflow?
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_HEX:
|
case STATE_HEX:
|
||||||
if (!isHexDigit(*src)) {
|
if (!isHexDigit(*first)) {
|
||||||
if (digitsSeen) {
|
if (digitsSeen) {
|
||||||
// Encode UTF code point as UTF-8 bytes
|
// Encode UTF code point as UTF-8 bytes
|
||||||
if (accVal < 0x80) {
|
if (accVal < 0x80) {
|
||||||
*dst++ = accVal;
|
*result++ = accVal;
|
||||||
}
|
}
|
||||||
else if (accVal < 0x800 ) {
|
else if (accVal < 0x800 ) {
|
||||||
*dst++ = (accVal >> 6) | 0xC0;
|
*result++ = (accVal >> 6) | 0xC0;
|
||||||
*dst++ = (accVal & 0x3F) | 0x80;
|
*result++ = (accVal & 0x3F) | 0x80;
|
||||||
}
|
}
|
||||||
else { // (accVal <= 0xFFFF : always true because accVal type is unsigned short which is 16-bit
|
else { // (accVal <= 0xFFFF : always true because accVal type is unsigned short which is 16-bit
|
||||||
*dst++ = (accVal >> 12) | 0xE0;
|
*result++ = (accVal >> 12) | 0xE0;
|
||||||
*dst++ = ((accVal >> 6) & 0x3F) | 0x80;
|
*result++ = ((accVal >> 6) & 0x3F) | 0x80;
|
||||||
*dst++ = (accVal & 0x3F) | 0x80;
|
*result++ = (accVal & 0x3F) | 0x80;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Copy from back-track, not including current character (which is absent), and continue
|
// Copy from back-track, not including current character (which is absent), and continue
|
||||||
while (dst <= mark && mark < src) {
|
while (mark < first) {
|
||||||
*dst++ = *mark++;
|
*result++ = *mark++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*src == '&') {
|
if (*first == '&') {
|
||||||
// Terminator is also start of next escape sequence
|
// Terminator is also start of next escape sequence
|
||||||
mark = src;
|
mark = first;
|
||||||
state = STATE_ESCAPE;
|
state = STATE_ESCAPE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (!digitsSeen || *src != ';') {
|
else if (!digitsSeen || *first != ';') {
|
||||||
// Do not copy the ';' but do copy any other terminator
|
// Do not copy the ';' but do copy any other terminator
|
||||||
// Note: the ';' should remain in the output if there were no digits seen.
|
// Note: the ';' should remain in the output if there were no digits seen.
|
||||||
*dst++ = *src;
|
*result++ = *first;
|
||||||
}
|
}
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
digitsSeen = true;
|
digitsSeen = true;
|
||||||
accVal = accVal << 4;
|
accVal = accVal << 4;
|
||||||
if (isdigit(*src)) {
|
if (isdigit(*first)) {
|
||||||
accVal += *src - '0';
|
accVal += *first - '0';
|
||||||
}
|
}
|
||||||
else if (*src >= 'a' && *src <= 'f') {
|
else if (*first >= 'a' && *first <= 'f') {
|
||||||
accVal += *src - 'a' + 10;
|
accVal += *first - 'a' + 10;
|
||||||
}
|
}
|
||||||
else if (*src >= 'A' && *src <= 'F') {
|
else if (*first >= 'A' && *first <= 'F') {
|
||||||
accVal += *src - 'A' + 10;
|
accVal += *first - 'A' + 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == STATE_ESCAPE && dst < last) {
|
if (state == STATE_ESCAPE) {
|
||||||
*dst++ = '&';
|
*result++ = '&';
|
||||||
}
|
}
|
||||||
else if (state == STATE_NAMED_CHARACTER_REFERENCE && potentialMatchIndices.size() > 0 && dst < last) {
|
else if (state == STATE_NAMED_CHARACTER_REFERENCE && potentialMatchIndices.size() > 0) {
|
||||||
// Send consumed ampersand to the output
|
// Send consumed ampersand to the output
|
||||||
*dst++ = '&';
|
*result++ = '&';
|
||||||
|
|
||||||
// Send those matched characters (these are the same that we consumed) - to the output
|
// Send those matched characters (these are the same that we consumed) - to the output
|
||||||
for (size_t i = 0; i < matchLength && dst < last; i++) {
|
for (size_t i = 0; i < matchLength; i++) {
|
||||||
// Even if there are multiple potential matches, all of them start with the same
|
// Even if there are multiple potential matches, all of them start with the same
|
||||||
// matchLength characters that we consumed!
|
// matchLength characters that we consumed!
|
||||||
*dst++ = g_htmlEntities[lastKnownMatchIndex].name[i];
|
*result++ = g_htmlEntities[lastKnownMatchIndex].name[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (state == STATE_HEX && !digitsSeen) { // Special case of "&#x"
|
if (state == STATE_HEX && !digitsSeen) { // Special case of "&#x"
|
||||||
// Copy from back-track, not including current character (which is absent), and continue
|
// Copy from back-track, not including current character (which is absent), and continue
|
||||||
while (dst <= mark && mark < src) {
|
while (mark < first) {
|
||||||
*dst++ = *mark++;
|
*result++ = *mark++;
|
||||||
}
|
}
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
}
|
}
|
||||||
else if (state == STATE_HEX || state == STATE_NUMERIC || state == STATE_NUMERIC_START) {
|
else if (state == STATE_HEX || state == STATE_NUMERIC || state == STATE_NUMERIC_START) {
|
||||||
if (digitsSeen && dst < last) {
|
if (digitsSeen) {
|
||||||
// Encode UTF code point as UTF-8 bytes
|
// Encode UTF code point as UTF-8 bytes
|
||||||
if (accVal < 0x80) {
|
if (accVal < 0x80) {
|
||||||
*dst++ = accVal;
|
*result++ = accVal;
|
||||||
}
|
}
|
||||||
else if (accVal < 0x800 && std::distance(dst, last) >= 2) {
|
else if (accVal < 0x800 ) {
|
||||||
*dst++ = (accVal >> 6) | 0xC0;
|
*result++ = (accVal >> 6) | 0xC0;
|
||||||
*dst++ = (accVal & 0x3F) | 0x80;
|
*result++ = (accVal & 0x3F) | 0x80;
|
||||||
}
|
}
|
||||||
// (accVal <= 0xFFFF : always true because accVal type is unsigned short which is 16-bit
|
else { // (accVal <= 0xFFFF : always true because accVal type is unsigned short which is 16-bit
|
||||||
else if (std::distance(dst, last) >= 3) {
|
*result++ = (accVal >> 12) | 0xE0;
|
||||||
*dst++ = (accVal >> 12) | 0xE0;
|
*result++ = ((accVal >> 6) & 0x3F) | 0x80;
|
||||||
*dst++ = ((accVal >> 6) & 0x3F) | 0x80;
|
*result++ = (accVal & 0x3F) | 0x80;
|
||||||
*dst++ = (accVal & 0x3F) | 0x80;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Copy from back-track, not including current character (which is absent), and continue
|
// Copy from back-track, not including current character (which is absent), and continue
|
||||||
while (dst <= mark && mark < src) {
|
while (mark < first) {
|
||||||
*dst++ = *mark++;
|
*result++ = *mark++;
|
||||||
}
|
}
|
||||||
state = STATE_COPY;
|
state = STATE_COPY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dst;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare two buffers, case insensitive. Return true if they are equal (case-insensitive)
|
// Compare two buffers, case insensitive. Return true if they are equal (case-insensitive)
|
||||||
@ -877,17 +865,6 @@ void unescapeUnicode(std::string &text);
|
|||||||
// Try to find and decode UTF7 chunks
|
// Try to find and decode UTF7 chunks
|
||||||
std::string filterUTF7(const std::string &text);
|
std::string filterUTF7(const std::string &text);
|
||||||
|
|
||||||
base64_decode_status
|
|
||||||
decideStatusBase64Decoded(
|
|
||||||
std::string& decoded,
|
|
||||||
double entropy,
|
|
||||||
double decoded_entropy,
|
|
||||||
size_t spacer_count,
|
|
||||||
size_t nonPrintableCharsCount,
|
|
||||||
bool clear_on_error,
|
|
||||||
double terminatorCharsSeen,
|
|
||||||
bool called_with_prefix);
|
|
||||||
|
|
||||||
base64_decode_status
|
base64_decode_status
|
||||||
decodeBase64Chunk(
|
decodeBase64Chunk(
|
||||||
const std::string &value,
|
const std::string &value,
|
||||||
@ -949,8 +926,7 @@ namespace Util {
|
|||||||
const std::string &s,
|
const std::string &s,
|
||||||
std::string &key,
|
std::string &key,
|
||||||
std::string &value,
|
std::string &value,
|
||||||
BinaryFileType &binaryFileType,
|
BinaryFileType &binaryFileType);
|
||||||
size_t offset = 0);
|
|
||||||
|
|
||||||
// The original stdlib implementation of isalpha() supports locale settings which we do not really need.
|
// The original stdlib implementation of isalpha() supports locale settings which we do not really need.
|
||||||
// It is also proven to contribute to slow performance in some of the algorithms using it.
|
// It is also proven to contribute to slow performance in some of the algorithms using it.
|
||||||
|
@ -43,7 +43,6 @@
|
|||||||
#include "agent_core_utilities.h"
|
#include "agent_core_utilities.h"
|
||||||
|
|
||||||
#define stack_trace_max_len 64
|
#define stack_trace_max_len 64
|
||||||
#define STACK_SIZE (1024 * 1024) // 1 MB stack size
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ReportIS;
|
using namespace ReportIS;
|
||||||
@ -58,12 +57,6 @@ public:
|
|||||||
{
|
{
|
||||||
if (out_trace_file_fd != -1) close(out_trace_file_fd);
|
if (out_trace_file_fd != -1) close(out_trace_file_fd);
|
||||||
out_trace_file_fd = -1;
|
out_trace_file_fd = -1;
|
||||||
|
|
||||||
if (alt_stack.ss_sp != nullptr) {
|
|
||||||
free(alt_stack.ss_sp);
|
|
||||||
alt_stack.ss_sp = nullptr;
|
|
||||||
alt_stack_initialized = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -76,7 +69,6 @@ public:
|
|||||||
void
|
void
|
||||||
init()
|
init()
|
||||||
{
|
{
|
||||||
alt_stack.ss_sp = nullptr;
|
|
||||||
addSignalHandlerRoutine();
|
addSignalHandlerRoutine();
|
||||||
addReloadConfigurationRoutine();
|
addReloadConfigurationRoutine();
|
||||||
}
|
}
|
||||||
@ -252,28 +244,6 @@ private:
|
|||||||
setHandlerPerSignalNum();
|
setHandlerPerSignalNum();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
setupAlternateSignalStack()
|
|
||||||
{
|
|
||||||
if (alt_stack_initialized) return true;
|
|
||||||
alt_stack.ss_sp = malloc(STACK_SIZE);
|
|
||||||
if (alt_stack.ss_sp == nullptr) {
|
|
||||||
dbgWarning(D_SIGNAL_HANDLER) << "Failed to allocate alternate stack";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
alt_stack.ss_size = STACK_SIZE;
|
|
||||||
alt_stack.ss_flags = 0;
|
|
||||||
|
|
||||||
if (sigaltstack(&alt_stack, nullptr) == -1) {
|
|
||||||
dbgWarning(D_SIGNAL_HANDLER) << "Failed to set up alternate stack";
|
|
||||||
free(alt_stack.ss_sp);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dbgInfo(D_SIGNAL_HANDLER) << "Alternate stack allocated successfully. Allocated size: " << STACK_SIZE;
|
|
||||||
alt_stack_initialized = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
setHandlerPerSignalNum()
|
setHandlerPerSignalNum()
|
||||||
{
|
{
|
||||||
@ -291,30 +261,9 @@ private:
|
|||||||
SIGUSR2
|
SIGUSR2
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!setupAlternateSignalStack()) {
|
|
||||||
dbgWarning(D_SIGNAL_HANDLER) << "Failed to set up alternate signal stack";
|
|
||||||
for (int sig : signals) {
|
for (int sig : signals) {
|
||||||
signal(sig, signalHandlerCB);
|
signal(sig, signalHandlerCB);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sigaction sa;
|
|
||||||
memset(&sa, 0, sizeof(sa));
|
|
||||||
sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
|
|
||||||
sa.sa_sigaction = signalActionHandlerCB;
|
|
||||||
|
|
||||||
sigemptyset(&sa.sa_mask);
|
|
||||||
|
|
||||||
for (int sig : signals) {
|
|
||||||
if (sig == SIGKILL || sig == SIGSTOP) {
|
|
||||||
signal(sig, signalHandlerCB);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (sigaction(sig, &sa, nullptr) == -1) {
|
|
||||||
dbgError(D_SIGNAL_HANDLER) << "Failed to set signal handler for signal " << sig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LCOV_EXCL_START Reason: Cannot crash unitest or send signal during execution
|
// LCOV_EXCL_START Reason: Cannot crash unitest or send signal during execution
|
||||||
@ -335,30 +284,55 @@ private:
|
|||||||
static void
|
static void
|
||||||
signalHandlerCB(int _signal)
|
signalHandlerCB(int _signal)
|
||||||
{
|
{
|
||||||
const char *signal_name = strsignal(_signal);
|
const char *signal_name = "";
|
||||||
char signal_num[3];
|
char signal_num[3];
|
||||||
snprintf(signal_num, sizeof(signal_num), "%d", _signal);
|
|
||||||
|
|
||||||
if (out_trace_file_fd == -1) exit(_signal);
|
|
||||||
|
|
||||||
reset_signal_handler = true;
|
reset_signal_handler = true;
|
||||||
|
|
||||||
switch(_signal) {
|
switch(_signal) {
|
||||||
case SIGABRT:
|
case SIGABRT: {
|
||||||
case SIGKILL:
|
signal_name = "SIGABRT";
|
||||||
case SIGQUIT:
|
|
||||||
case SIGINT:
|
|
||||||
case SIGTERM: {
|
|
||||||
fini_signal_flag = true;
|
fini_signal_flag = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case SIGSEGV:
|
case SIGKILL: {
|
||||||
case SIGBUS:
|
signal_name = "SIGKILL";
|
||||||
case SIGILL:
|
fini_signal_flag = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case SIGQUIT: {
|
||||||
|
signal_name = "SIGQUIT";
|
||||||
|
fini_signal_flag = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case SIGINT: {
|
||||||
|
signal_name = "SIGINT";
|
||||||
|
fini_signal_flag = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case SIGTERM: {
|
||||||
|
signal_name = "SIGTERM";
|
||||||
|
fini_signal_flag = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case SIGSEGV: {
|
||||||
|
signal_name = "SIGSEGV";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SIGBUS: {
|
||||||
|
signal_name = "SIGBUS";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SIGILL: {
|
||||||
|
signal_name = "SIGILL";
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SIGFPE: {
|
case SIGFPE: {
|
||||||
|
signal_name = "SIGFPE";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SIGPIPE: {
|
case SIGPIPE: {
|
||||||
|
signal_name = "SIGPIPE";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case SIGUSR2: {
|
case SIGUSR2: {
|
||||||
@ -367,6 +341,13 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (out_trace_file_fd == -1) exit(_signal);
|
||||||
|
|
||||||
|
for (uint i = 0; i < sizeof(signal_num); ++i) {
|
||||||
|
uint placement = sizeof(signal_num) - 1 - i;
|
||||||
|
signal_num[placement] = _signal%10 + '0';
|
||||||
|
_signal /= 10;
|
||||||
|
}
|
||||||
const char *signal_error_prefix = "Caught signal ";
|
const char *signal_error_prefix = "Caught signal ";
|
||||||
writeData(signal_error_prefix, strlen(signal_error_prefix));
|
writeData(signal_error_prefix, strlen(signal_error_prefix));
|
||||||
writeData(signal_num, sizeof(signal_num));
|
writeData(signal_num, sizeof(signal_num));
|
||||||
@ -386,12 +367,6 @@ private:
|
|||||||
exit(_signal);
|
exit(_signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
signalActionHandlerCB(int signum, siginfo_t *, void *)
|
|
||||||
{
|
|
||||||
signalHandlerCB(signum);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printStackTrace()
|
printStackTrace()
|
||||||
{
|
{
|
||||||
@ -416,22 +391,16 @@ private:
|
|||||||
for (uint i = 0 ; i < stack_trace_max_len ; i++) {
|
for (uint i = 0 ; i < stack_trace_max_len ; i++) {
|
||||||
unw_get_reg(&cursor, UNW_REG_IP, &ip);
|
unw_get_reg(&cursor, UNW_REG_IP, &ip);
|
||||||
unw_get_reg(&cursor, UNW_REG_SP, &sp);
|
unw_get_reg(&cursor, UNW_REG_SP, &sp);
|
||||||
int procNameRc = unw_get_proc_name(&cursor, name, sizeof(name), &off);
|
|
||||||
if (procNameRc == 0 || procNameRc == -UNW_ENOMEM) {
|
if (unw_get_proc_name(&cursor, name, sizeof(name), &off) == 0) {
|
||||||
const char *open_braces = "<";
|
const char *open_braces = "<";
|
||||||
writeData(open_braces, strlen(open_braces));
|
writeData(open_braces, strlen(open_braces));
|
||||||
writeData(name, strnlen(name, sizeof(name)));
|
writeData(name, strlen(name));
|
||||||
if (procNameRc != 0) {
|
|
||||||
const char *dots = "...";
|
|
||||||
writeData(dots, strlen(dots));
|
|
||||||
}
|
|
||||||
const char *close_braces = ">\n";
|
const char *close_braces = ">\n";
|
||||||
writeData(close_braces, strlen(close_braces));
|
writeData(close_braces, strlen(close_braces));
|
||||||
} else {
|
|
||||||
const char *error = " -- error: unable to obtain symbol name for this frame\n";
|
|
||||||
writeData(error, strlen(error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (unw_step(&cursor) <= 0) return;
|
if (unw_step(&cursor) <= 0) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,16 +444,12 @@ private:
|
|||||||
static bool reload_settings_flag;
|
static bool reload_settings_flag;
|
||||||
static bool reset_signal_handler;
|
static bool reset_signal_handler;
|
||||||
static int out_trace_file_fd;
|
static int out_trace_file_fd;
|
||||||
static stack_t alt_stack;
|
|
||||||
static bool alt_stack_initialized;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
string SignalHandler::Impl::trace_file_path;
|
string SignalHandler::Impl::trace_file_path;
|
||||||
bool SignalHandler::Impl::reload_settings_flag = false;
|
bool SignalHandler::Impl::reload_settings_flag = false;
|
||||||
bool SignalHandler::Impl::reset_signal_handler = false;
|
bool SignalHandler::Impl::reset_signal_handler = false;
|
||||||
int SignalHandler::Impl::out_trace_file_fd = -1;
|
int SignalHandler::Impl::out_trace_file_fd = -1;
|
||||||
stack_t SignalHandler::Impl::alt_stack;
|
|
||||||
bool SignalHandler::Impl::alt_stack_initialized = false;
|
|
||||||
|
|
||||||
SignalHandler::SignalHandler() : Component("SignalHandler"), pimpl(make_unique<Impl>()) {}
|
SignalHandler::SignalHandler() : Component("SignalHandler"), pimpl(make_unique<Impl>()) {}
|
||||||
SignalHandler::~SignalHandler() {}
|
SignalHandler::~SignalHandler() {}
|
||||||
|
@ -103,35 +103,6 @@ WildcardHost::evalVariable() const
|
|||||||
return lower_host_ctx == lower_host;
|
return lower_host_ctx == lower_host;
|
||||||
}
|
}
|
||||||
|
|
||||||
EqualWafTag::EqualWafTag(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != 1) reportWrongNumberOfParams("EqualWafTag", params.size(), 1, 1);
|
|
||||||
waf_tag = params[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
EqualWafTag::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<EqualWafTag>();
|
|
||||||
auto maybe_waf_tag_ctx = env->get<string>(HttpTransactionData::waf_tag_ctx);
|
|
||||||
|
|
||||||
if (!maybe_waf_tag_ctx.ok())
|
|
||||||
{
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "didnt find waf tag in current context";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto waf_tag_ctx = maybe_waf_tag_ctx.unpack();
|
|
||||||
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG)
|
|
||||||
<< "trying to match waf tag context with its corresponding waf tag: "
|
|
||||||
<< waf_tag_ctx
|
|
||||||
<< ". Matcher waf tag: "
|
|
||||||
<< waf_tag;
|
|
||||||
|
|
||||||
return waf_tag_ctx == waf_tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
EqualListeningIP::EqualListeningIP(const vector<string> ¶ms)
|
EqualListeningIP::EqualListeningIP(const vector<string> ¶ms)
|
||||||
{
|
{
|
||||||
if (params.size() != 1) reportWrongNumberOfParams("EqualListeningIP", params.size(), 1, 1);
|
if (params.size() != 1) reportWrongNumberOfParams("EqualListeningIP", params.size(), 1, 1);
|
||||||
|
@ -80,7 +80,6 @@ GenericRulebase::Impl::preload()
|
|||||||
addMatcher<IpProtocolMatcher>();
|
addMatcher<IpProtocolMatcher>();
|
||||||
addMatcher<UrlMatcher>();
|
addMatcher<UrlMatcher>();
|
||||||
addMatcher<EqualHost>();
|
addMatcher<EqualHost>();
|
||||||
addMatcher<EqualWafTag>();
|
|
||||||
addMatcher<WildcardHost>();
|
addMatcher<WildcardHost>();
|
||||||
addMatcher<EqualListeningIP>();
|
addMatcher<EqualListeningIP>();
|
||||||
addMatcher<EqualListeningPort>();
|
addMatcher<EqualListeningPort>();
|
||||||
|
@ -53,7 +53,6 @@ const string HttpTransactionData::req_body = "transaction_request_body
|
|||||||
const string HttpTransactionData::source_identifier = "sourceIdentifiers";
|
const string HttpTransactionData::source_identifier = "sourceIdentifiers";
|
||||||
const string HttpTransactionData::proxy_ip_ctx = "proxy_ip";
|
const string HttpTransactionData::proxy_ip_ctx = "proxy_ip";
|
||||||
const string HttpTransactionData::xff_vals_ctx = "xff_vals";
|
const string HttpTransactionData::xff_vals_ctx = "xff_vals";
|
||||||
const string HttpTransactionData::waf_tag_ctx = "waf_tag";
|
|
||||||
|
|
||||||
const CompressionType HttpTransactionData::default_response_content_encoding = CompressionType::NO_COMPRESSION;
|
const CompressionType HttpTransactionData::default_response_content_encoding = CompressionType::NO_COMPRESSION;
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <boost/regex.hpp>
|
#include <boost/regex.hpp>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "maybe_res.h"
|
#include "maybe_res.h"
|
||||||
@ -76,13 +75,13 @@ NginxConfCollector::expandIncludes(const string &include_pattern) const {
|
|||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
while ((entry = readdir(dir)) != nullptr) {
|
while ((entry = readdir(dir)) != nullptr) {
|
||||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
|
||||||
|
|
||||||
if (NGEN::Regex::regexMatch(__FILE__, __LINE__, entry->d_name, pattern)) {
|
if (NGEN::Regex::regexMatch(__FILE__, __LINE__, entry->d_name, pattern)) {
|
||||||
matching_files.push_back(maybe_directory + "/" + entry->d_name);
|
matching_files.push_back(maybe_directory + "/" + entry->d_name);
|
||||||
dbgTrace(D_NGINX_MANAGER) << "Matched file: " << maybe_directory << '/' << entry->d_name;
|
dbgTrace(D_NGINX_MANAGER) << "Matched file: " << maybe_directory << '/' << entry->d_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
sort(matching_files.begin(), matching_files.end());
|
|
||||||
|
|
||||||
return matching_files;
|
return matching_files;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
apiVersion: apiextensions.k8s.io/v1
|
Enter file contents hereapiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata :
|
metadata :
|
||||||
name : customresponses.openappsec.io
|
name : customresponses.openappsec.io
|
||||||
|
@ -137,10 +137,6 @@ spec:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: object
|
type: object
|
||||||
required:
|
|
||||||
- mode
|
|
||||||
- threatPreventionPractices
|
|
||||||
- accessControlPractices
|
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
@ -1177,929 +1173,3 @@ spec:
|
|||||||
kind: TrustedSource
|
kind: TrustedSource
|
||||||
shortNames:
|
shortNames:
|
||||||
- trustedsource
|
- trustedsource
|
||||||
|
|
||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata :
|
|
||||||
name: policyactivations.openappsec.io
|
|
||||||
spec:
|
|
||||||
group: openappsec.io
|
|
||||||
versions:
|
|
||||||
- name: v1beta2
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
spec:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
enabledPolicies:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
hosts:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- hosts
|
|
||||||
required:
|
|
||||||
- enabledPolicies
|
|
||||||
scope: Cluster
|
|
||||||
names:
|
|
||||||
plural: policyactivations
|
|
||||||
singular: policyactivation
|
|
||||||
kind: PolicyActivation
|
|
||||||
shortNames:
|
|
||||||
- policyactivation
|
|
||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata :
|
|
||||||
name : policiesns.openappsec.io
|
|
||||||
creationTimestamp: null
|
|
||||||
spec:
|
|
||||||
group: openappsec.io
|
|
||||||
versions:
|
|
||||||
- name: v1beta2
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
spec:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
default:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- mode
|
|
||||||
- threatPreventionPractices
|
|
||||||
- accessControlPractices
|
|
||||||
properties:
|
|
||||||
mode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
default: detect-learn
|
|
||||||
threatPreventionPractices:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
accessControlPractices:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
customResponse:
|
|
||||||
type: string
|
|
||||||
default: "403"
|
|
||||||
triggers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
sourceIdentifiers:
|
|
||||||
type: string
|
|
||||||
trustedSources:
|
|
||||||
type: string
|
|
||||||
exceptions:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
specificRules:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
host:
|
|
||||||
type: string
|
|
||||||
mode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
default: detect-learn
|
|
||||||
threatPreventionPractices:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
accessControlPractices:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
triggers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
customResponse:
|
|
||||||
type: string
|
|
||||||
sourceIdentifiers:
|
|
||||||
type: string
|
|
||||||
trustedSources:
|
|
||||||
type: string
|
|
||||||
exceptions:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: policiesns
|
|
||||||
singular: policyns
|
|
||||||
kind: PolicyNS
|
|
||||||
shortNames:
|
|
||||||
- policyns
|
|
||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata :
|
|
||||||
name : accesscontrolpracticesns.openappsec.io
|
|
||||||
creationTimestamp: null
|
|
||||||
spec:
|
|
||||||
group: openappsec.io
|
|
||||||
versions:
|
|
||||||
- name: v1beta2
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
spec:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- rateLimit
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
practiceMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- inherited
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
default: inherited
|
|
||||||
rateLimit:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
rules:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
action:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- inherited
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
default: inherited
|
|
||||||
condition:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- key
|
|
||||||
- value
|
|
||||||
properties:
|
|
||||||
key:
|
|
||||||
type: string
|
|
||||||
value:
|
|
||||||
type: string
|
|
||||||
uri:
|
|
||||||
type: string
|
|
||||||
limit:
|
|
||||||
type: integer
|
|
||||||
unit:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- minute
|
|
||||||
- second
|
|
||||||
default: minute
|
|
||||||
triggers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
comment:
|
|
||||||
type: string
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: accesscontrolpracticesns
|
|
||||||
singular: accesscontrolpracticens
|
|
||||||
kind: AccessControlPracticeNS
|
|
||||||
shortNames:
|
|
||||||
- acpns
|
|
||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
name : customresponsesns.openappsec.io
|
|
||||||
creationTimestamp: null
|
|
||||||
spec:
|
|
||||||
group: openappsec.io
|
|
||||||
versions:
|
|
||||||
- name: v1beta2
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
spec:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- mode
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
mode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- block-page
|
|
||||||
- redirect
|
|
||||||
- response-code-only
|
|
||||||
default: response-code-only
|
|
||||||
messageTitle:
|
|
||||||
type: string
|
|
||||||
messageBody:
|
|
||||||
type: string
|
|
||||||
httpResponseCode:
|
|
||||||
type: integer
|
|
||||||
minimum: 100
|
|
||||||
maximum: 599
|
|
||||||
default: 403
|
|
||||||
redirectUrl:
|
|
||||||
type: string
|
|
||||||
redirectAddXEventId:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
required:
|
|
||||||
- mode
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: customresponsesns
|
|
||||||
singular: customresponsens
|
|
||||||
kind: CustomResponseNS
|
|
||||||
shortNames:
|
|
||||||
- customresponsens
|
|
||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata :
|
|
||||||
name: exceptionsns.openappsec.io
|
|
||||||
spec:
|
|
||||||
group: openappsec.io
|
|
||||||
versions:
|
|
||||||
- name: v1beta2
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
spec:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- action
|
|
||||||
- condition
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
action:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- skip
|
|
||||||
- accept
|
|
||||||
- drop
|
|
||||||
- suppressLog
|
|
||||||
default: accept
|
|
||||||
condition:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- key
|
|
||||||
- value
|
|
||||||
properties:
|
|
||||||
key:
|
|
||||||
type: string
|
|
||||||
value:
|
|
||||||
type: string
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: exceptionsns
|
|
||||||
singular: exceptionns
|
|
||||||
kind: ExceptionNS
|
|
||||||
shortNames:
|
|
||||||
- exceptionns
|
|
||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata :
|
|
||||||
name : logtriggersns.openappsec.io
|
|
||||||
creationTimestamp: null
|
|
||||||
spec:
|
|
||||||
group: openappsec.io
|
|
||||||
versions:
|
|
||||||
- name: v1beta2
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
spec:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- accessControlLogging
|
|
||||||
- appsecLogging
|
|
||||||
- additionalSuspiciousEventsLogging
|
|
||||||
- extendedLogging
|
|
||||||
- logDestination
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
accessControlLogging:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
allowEvents:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
dropEvents:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
appsecLogging:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
detectEvents:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
preventEvents:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
allWebRequests:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
additionalSuspiciousEventsLogging:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
enabled:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
minSeverity:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- high
|
|
||||||
- critical
|
|
||||||
default: high
|
|
||||||
responseBody:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
responseCode:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
extendedLogging:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
urlPath:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
urlQuery:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
httpHeaders:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
requestBody:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
logDestination:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
cloud:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
syslogService:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
address:
|
|
||||||
type: string
|
|
||||||
port:
|
|
||||||
type: integer
|
|
||||||
logToAgent:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
stdout:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
format:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- json
|
|
||||||
- json-formatted
|
|
||||||
default: json
|
|
||||||
local-tuning:
|
|
||||||
type: boolean
|
|
||||||
cefService:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
address:
|
|
||||||
type: string
|
|
||||||
port:
|
|
||||||
type: integer
|
|
||||||
proto:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- tcp
|
|
||||||
- udp
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: logtriggersns
|
|
||||||
singular: logtriggerns
|
|
||||||
kind: LogTriggerNS
|
|
||||||
shortNames:
|
|
||||||
- logtriggerns
|
|
||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata :
|
|
||||||
name : sourcesidentifiersns.openappsec.io
|
|
||||||
creationTimestamp: null
|
|
||||||
spec:
|
|
||||||
group: openappsec.io
|
|
||||||
versions:
|
|
||||||
- name: v1beta2
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
spec:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- sourcesIdentifiers
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
sourcesIdentifiers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- identifier
|
|
||||||
properties:
|
|
||||||
identifier:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- headerkey
|
|
||||||
- JWTKey
|
|
||||||
- cookie
|
|
||||||
- sourceip
|
|
||||||
- x-forwarded-for
|
|
||||||
default: sourceip
|
|
||||||
value:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: sourcesidentifiersns
|
|
||||||
singular: sourcesidentifierns
|
|
||||||
kind: SourcesIdentifierNS
|
|
||||||
shortNames:
|
|
||||||
- sourcesidentifierns
|
|
||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata :
|
|
||||||
name : threatpreventionpracticesns.openappsec.io
|
|
||||||
creationTimestamp: null
|
|
||||||
spec:
|
|
||||||
group: openappsec.io
|
|
||||||
versions:
|
|
||||||
- name: v1beta2
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
spec:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- webAttacks
|
|
||||||
- intrusionPrevention
|
|
||||||
- fileSecurity
|
|
||||||
- snortSignatures
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
practiceMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- inherited
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
default: inherited
|
|
||||||
webAttacks:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
minimumConfidence:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- medium
|
|
||||||
- high
|
|
||||||
- critical
|
|
||||||
default: high
|
|
||||||
maxUrlSizeBytes:
|
|
||||||
type: integer
|
|
||||||
default: 32768
|
|
||||||
maxObjectDepth:
|
|
||||||
type: integer
|
|
||||||
default: 40
|
|
||||||
maxBodySizeKb:
|
|
||||||
type: integer
|
|
||||||
default: 1000000
|
|
||||||
maxHeaderSizeBytes:
|
|
||||||
type: integer
|
|
||||||
default: 102400
|
|
||||||
protections:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
csrfProtection:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
errorDisclosure:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
openRedirect:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
nonValidHttpMethods:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
antiBot:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
injectedUris:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
uri:
|
|
||||||
type: string
|
|
||||||
validatedUris:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
uri:
|
|
||||||
type: string
|
|
||||||
snortSignatures:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
configmap:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
files:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
schemaValidation:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
enforcementLevel:
|
|
||||||
type: string
|
|
||||||
configmap:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
files:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
intrusionPrevention:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
maxPerformanceImpact:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- low
|
|
||||||
- medium
|
|
||||||
- high
|
|
||||||
default: medium
|
|
||||||
minSeverityLevel:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- low
|
|
||||||
- medium
|
|
||||||
- high
|
|
||||||
- critical
|
|
||||||
default: medium
|
|
||||||
minCveYear:
|
|
||||||
type: integer
|
|
||||||
default: 2016
|
|
||||||
highConfidenceEventAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inherited
|
|
||||||
mediumConfidenceEventAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inherited
|
|
||||||
lowConfidenceEventAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: detect
|
|
||||||
fileSecurity:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
minSeverityLevel:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- low
|
|
||||||
- medium
|
|
||||||
- high
|
|
||||||
- critical
|
|
||||||
default: medium
|
|
||||||
highConfidenceEventAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inherited
|
|
||||||
mediumConfidenceEventAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inherited
|
|
||||||
lowConfidenceEventAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: detect
|
|
||||||
archiveInspection:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
extractArchiveFiles:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
scanMaxFileSize:
|
|
||||||
type: integer
|
|
||||||
default: 10
|
|
||||||
scanMaxFileSizeUnit:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- bytes
|
|
||||||
- KB
|
|
||||||
- MB
|
|
||||||
- GB
|
|
||||||
default: MB
|
|
||||||
archivedFilesWithinArchivedFiles:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inherited
|
|
||||||
archivedFilesWhereContentExtractionFailed:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inherited
|
|
||||||
largeFileInspection:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
fileSizeLimit:
|
|
||||||
type: integer
|
|
||||||
default: 10
|
|
||||||
fileSizeLimitUnit:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- bytes
|
|
||||||
- KB
|
|
||||||
- MB
|
|
||||||
- GB
|
|
||||||
default: MB
|
|
||||||
filesExceedingSizeLimitAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inherited
|
|
||||||
unnamedFilesAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inherited
|
|
||||||
threatEmulationEnabled:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: threatpreventionpracticesns
|
|
||||||
singular: threatpreventionpracticens
|
|
||||||
kind: ThreatPreventionPracticeNS
|
|
||||||
shortNames:
|
|
||||||
- tppns
|
|
||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata :
|
|
||||||
name : trustedsourcesns.openappsec.io
|
|
||||||
creationTimestamp: null
|
|
||||||
spec:
|
|
||||||
group: openappsec.io
|
|
||||||
versions:
|
|
||||||
- name: v1beta2
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
spec:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- minNumOfSources
|
|
||||||
- sourcesIdentifiers
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
minNumOfSources:
|
|
||||||
type: integer
|
|
||||||
default: 3
|
|
||||||
sourcesIdentifiers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: trustedsourcesns
|
|
||||||
singular: trustedsourcens
|
|
||||||
kind: TrustedSourceNS
|
|
||||||
shortNames:
|
|
||||||
- trustedsourcens
|
|
||||||
|
@ -11,58 +11,3 @@ spec:
|
|||||||
source-identifiers: ""
|
source-identifiers: ""
|
||||||
trusted-sources: ""
|
trusted-sources: ""
|
||||||
exceptions: []
|
exceptions: []
|
||||||
---
|
|
||||||
apiVersion: openappsec.io/v1beta1
|
|
||||||
kind: LogTrigger
|
|
||||||
metadata:
|
|
||||||
name: appsec-log-trigger
|
|
||||||
spec:
|
|
||||||
access-control-logging:
|
|
||||||
allow-events: false
|
|
||||||
drop-events: true
|
|
||||||
appsec-logging:
|
|
||||||
detect-events: false
|
|
||||||
prevent-events: true
|
|
||||||
all-web-requests: false
|
|
||||||
additional-suspicious-events-logging:
|
|
||||||
enabled: true
|
|
||||||
minimum-severity: high
|
|
||||||
response-body: false
|
|
||||||
extended-logging:
|
|
||||||
url-path: false
|
|
||||||
url-query: false
|
|
||||||
http-headers: false
|
|
||||||
request-body: false
|
|
||||||
log-destination:
|
|
||||||
cloud: true
|
|
||||||
syslog-service: []
|
|
||||||
file: ""
|
|
||||||
stdout:
|
|
||||||
format: json
|
|
||||||
cef-service: []
|
|
||||||
--
|
|
||||||
apiVersion: openappsec.io/v1beta1
|
|
||||||
kind: Practice
|
|
||||||
metadata:
|
|
||||||
name: appsec-best-practice
|
|
||||||
spec:
|
|
||||||
anti-bot:
|
|
||||||
injected-URIs: []
|
|
||||||
validated-URIs: []
|
|
||||||
openapi-schema-validation:
|
|
||||||
configmap: []
|
|
||||||
snort-signatures:
|
|
||||||
configmap: []
|
|
||||||
web-attacks:
|
|
||||||
minimum-confidence: high
|
|
||||||
override-mode: detect-learn
|
|
||||||
--
|
|
||||||
apiVersion: openappsec.io/v1beta1
|
|
||||||
kind: CustomResponse
|
|
||||||
metadata:
|
|
||||||
name: 403-forbidden
|
|
||||||
spec:
|
|
||||||
http-response-code: 403
|
|
||||||
message-body: ""
|
|
||||||
message-title: ""
|
|
||||||
mode: response-code-only
|
|
||||||
|
@ -11,58 +11,3 @@ spec:
|
|||||||
source-identifiers: ""
|
source-identifiers: ""
|
||||||
trusted-sources: ""
|
trusted-sources: ""
|
||||||
exceptions: []
|
exceptions: []
|
||||||
---
|
|
||||||
apiVersion: openappsec.io/v1beta1
|
|
||||||
kind: LogTrigger
|
|
||||||
metadata:
|
|
||||||
name: appsec-log-trigger
|
|
||||||
spec:
|
|
||||||
access-control-logging:
|
|
||||||
allow-events: false
|
|
||||||
drop-events: true
|
|
||||||
appsec-logging:
|
|
||||||
detect-events: false
|
|
||||||
prevent-events: true
|
|
||||||
all-web-requests: false
|
|
||||||
additional-suspicious-events-logging:
|
|
||||||
enabled: true
|
|
||||||
minimum-severity: high
|
|
||||||
response-body: false
|
|
||||||
extended-logging:
|
|
||||||
url-path: false
|
|
||||||
url-query: false
|
|
||||||
http-headers: false
|
|
||||||
request-body: false
|
|
||||||
log-destination:
|
|
||||||
cloud: true
|
|
||||||
syslog-service: []
|
|
||||||
file: ""
|
|
||||||
stdout:
|
|
||||||
format: json
|
|
||||||
cef-service: []
|
|
||||||
--
|
|
||||||
apiVersion: openappsec.io/v1beta1
|
|
||||||
kind: Practice
|
|
||||||
metadata:
|
|
||||||
name: appsec-best-practice
|
|
||||||
spec:
|
|
||||||
anti-bot:
|
|
||||||
injected-URIs: []
|
|
||||||
validated-URIs: []
|
|
||||||
openapi-schema-validation:
|
|
||||||
configmap: []
|
|
||||||
snort-signatures:
|
|
||||||
configmap: []
|
|
||||||
web-attacks:
|
|
||||||
minimum-confidence: high
|
|
||||||
override-mode: prevent-learn
|
|
||||||
--
|
|
||||||
apiVersion: openappsec.io/v1beta1
|
|
||||||
kind: CustomResponse
|
|
||||||
metadata:
|
|
||||||
name: 403-forbidden
|
|
||||||
spec:
|
|
||||||
http-response-code: 403
|
|
||||||
message-body: ""
|
|
||||||
message-title: ""
|
|
||||||
mode: response-code-only
|
|
||||||
|
@ -17,6 +17,16 @@ spec:
|
|||||||
customResponse: default-web-user-response
|
customResponse: default-web-user-response
|
||||||
triggers:
|
triggers:
|
||||||
- default-log-trigger
|
- default-log-trigger
|
||||||
|
specificRules:
|
||||||
|
- host: www.example.com
|
||||||
|
# this is an example for specific rule, adjust the values as required for the protected app
|
||||||
|
mode: detect-learn
|
||||||
|
threatPreventionPractices:
|
||||||
|
- default-threat-prevention-practice
|
||||||
|
accessControlPractices:
|
||||||
|
- default-access-control-practice
|
||||||
|
triggers:
|
||||||
|
- default-log-trigger
|
||||||
---
|
---
|
||||||
apiVersion: openappsec.io/v1beta2
|
apiVersion: openappsec.io/v1beta2
|
||||||
kind: ThreatPreventionPractice
|
kind: ThreatPreventionPractice
|
||||||
@ -102,7 +112,7 @@ spec:
|
|||||||
responseCode: true
|
responseCode: true
|
||||||
logDestination:
|
logDestination:
|
||||||
cloud: true
|
cloud: true
|
||||||
logToAgent: true
|
logToAgent: false
|
||||||
stdout:
|
stdout:
|
||||||
format: json
|
format: json
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ kind: AccessControlPractice
|
|||||||
metadata:
|
metadata:
|
||||||
name: access-control-practice-example
|
name: access-control-practice-example
|
||||||
spec:
|
spec:
|
||||||
practiceMode: inherited
|
practiceMode: prevent
|
||||||
rateLimit:
|
rateLimit:
|
||||||
overrideMode: inherited
|
overrideMode: inherited
|
||||||
rules:
|
rules:
|
||||||
@ -80,24 +80,13 @@ metadata:
|
|||||||
name: policy-example
|
name: policy-example
|
||||||
spec:
|
spec:
|
||||||
default:
|
default:
|
||||||
mode: detect-learn
|
|
||||||
accessControlPractices: [access-control-practice-example]
|
|
||||||
threatPreventionPractices: [threat-prevention-practice-example]
|
|
||||||
triggers: [log-trigger-example]
|
|
||||||
customResponse: custom-response-code-example
|
|
||||||
sourceIdentifiers: ""
|
|
||||||
trustedSources: ""
|
|
||||||
exceptions:
|
|
||||||
- exception-example
|
|
||||||
specificRules:
|
|
||||||
- host: "example.com"
|
|
||||||
mode: prevent-learn
|
mode: prevent-learn
|
||||||
threatPreventionPractices: [threat-prevention-practice-example]
|
|
||||||
accessControlPractices: [access-control-practice-example]
|
accessControlPractices: [access-control-practice-example]
|
||||||
|
threatPreventionPractices: [threat-prevention-practice-example]
|
||||||
triggers: [log-trigger-example]
|
triggers: [log-trigger-example]
|
||||||
customResponse: custom-response-code-example
|
customResponse: custom-response-block-page-example
|
||||||
sourceIdentifiers: ""
|
sourceIdentifiers: sources-identifier-example
|
||||||
trustedSources: ""
|
trustedSources: trusted-sources-example
|
||||||
exceptions:
|
exceptions:
|
||||||
- exception-example
|
- exception-example
|
||||||
---
|
---
|
||||||
|
@ -17,6 +17,16 @@ spec:
|
|||||||
customResponse: default-web-user-response
|
customResponse: default-web-user-response
|
||||||
triggers:
|
triggers:
|
||||||
- default-log-trigger
|
- default-log-trigger
|
||||||
|
specificRules:
|
||||||
|
- host: www.example.com
|
||||||
|
# this is an example for specific rule, adjust the values as required for the protected app
|
||||||
|
mode: prevent-learn
|
||||||
|
threatPreventionPractices:
|
||||||
|
- default-threat-prevention-practice
|
||||||
|
accessControlPractices:
|
||||||
|
- default-access-control-practice
|
||||||
|
triggers:
|
||||||
|
- default-log-trigger
|
||||||
---
|
---
|
||||||
apiVersion: openappsec.io/v1beta2
|
apiVersion: openappsec.io/v1beta2
|
||||||
kind: ThreatPreventionPractice
|
kind: ThreatPreventionPractice
|
||||||
@ -102,7 +112,7 @@ spec:
|
|||||||
responseCode: true
|
responseCode: true
|
||||||
logDestination:
|
logDestination:
|
||||||
cloud: true
|
cloud: true
|
||||||
logToAgent: true
|
logToAgent: false
|
||||||
stdout:
|
stdout:
|
||||||
format: json
|
format: json
|
||||||
|
|
||||||
|
@ -1,434 +0,0 @@
|
|||||||
ype: object
|
|
||||||
properties:
|
|
||||||
policies:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
default:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
custom-response:
|
|
||||||
type: string
|
|
||||||
exceptions:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
mode:
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
type: string
|
|
||||||
practices:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
source-identifiers:
|
|
||||||
type: string
|
|
||||||
triggers:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
trusted-sources:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- mode
|
|
||||||
- practices
|
|
||||||
- triggers
|
|
||||||
specific-rules:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
properties:
|
|
||||||
host:
|
|
||||||
type: string
|
|
||||||
custom-response:
|
|
||||||
type: string
|
|
||||||
exceptions:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
mode:
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
type: string
|
|
||||||
practices:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
source-identifiers:
|
|
||||||
type: string
|
|
||||||
triggers:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
trusted-sources:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- mode
|
|
||||||
- host
|
|
||||||
- practices
|
|
||||||
- triggers
|
|
||||||
type: object
|
|
||||||
practices:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
anti-bot:
|
|
||||||
properties:
|
|
||||||
injected-URIs:
|
|
||||||
items:
|
|
||||||
properties:
|
|
||||||
uri:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
override-mode:
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- as-top-level
|
|
||||||
type: string
|
|
||||||
default: "inactive"
|
|
||||||
validated-URIs:
|
|
||||||
items:
|
|
||||||
properties:
|
|
||||||
uri:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
type: object
|
|
||||||
openapi-schema-validation:
|
|
||||||
properties:
|
|
||||||
files:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
override-mode:
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- as-top-level
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
snort-signatures:
|
|
||||||
properties:
|
|
||||||
files:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
override-mode:
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- as-top-level
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
web-attacks:
|
|
||||||
properties:
|
|
||||||
max-body-size-kb:
|
|
||||||
type: integer
|
|
||||||
max-header-size-bytes:
|
|
||||||
type: integer
|
|
||||||
max-object-depth:
|
|
||||||
type: integer
|
|
||||||
max-url-size-bytes:
|
|
||||||
type: integer
|
|
||||||
minimum-confidence:
|
|
||||||
enum:
|
|
||||||
- medium
|
|
||||||
- high
|
|
||||||
- critical
|
|
||||||
type: string
|
|
||||||
override-mode:
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- as-top-level
|
|
||||||
type: string
|
|
||||||
protections:
|
|
||||||
properties:
|
|
||||||
csrf-enabled:
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
type: string
|
|
||||||
error-disclosure-enabled:
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
type: string
|
|
||||||
non-valid-http-methods:
|
|
||||||
type: boolean
|
|
||||||
open-redirect-enabled:
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
custom-responses:
|
|
||||||
type: array
|
|
||||||
minItems: 0
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
http-response-code:
|
|
||||||
maximum: 599
|
|
||||||
minimum: 100
|
|
||||||
default: 403
|
|
||||||
type: integer
|
|
||||||
message-body:
|
|
||||||
type: string
|
|
||||||
default: "Attack blocked by web application protection"
|
|
||||||
message-title:
|
|
||||||
type: string
|
|
||||||
default: "Openappsec's <b>Application Security</b> has detected an attack and blocked it."
|
|
||||||
mode:
|
|
||||||
enum:
|
|
||||||
- block-page
|
|
||||||
- response-code-only
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
log-triggers:
|
|
||||||
type: array
|
|
||||||
minItems: 0
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
access-control-logging:
|
|
||||||
properties:
|
|
||||||
allow-events:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
drop-events:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
type: object
|
|
||||||
additional-suspicious-events-logging:
|
|
||||||
properties:
|
|
||||||
enabled:
|
|
||||||
type: boolean
|
|
||||||
default true:
|
|
||||||
minimum-severity:
|
|
||||||
enum:
|
|
||||||
- high
|
|
||||||
- critical
|
|
||||||
type: string
|
|
||||||
default: "high"
|
|
||||||
response-body:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
response-code:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
type: object
|
|
||||||
appsec-logging:
|
|
||||||
properties:
|
|
||||||
all-web-requests:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
detect-events:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
prevent-events:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
type: object
|
|
||||||
extended-logging:
|
|
||||||
properties:
|
|
||||||
http-headers:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
request-body:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
url-path:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
url-query:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
type: object
|
|
||||||
log-destination:
|
|
||||||
properties:
|
|
||||||
cef-service:
|
|
||||||
minItems: 0
|
|
||||||
items:
|
|
||||||
properties:
|
|
||||||
address:
|
|
||||||
type: string
|
|
||||||
port:
|
|
||||||
type: integer
|
|
||||||
proto:
|
|
||||||
enum:
|
|
||||||
- tcp
|
|
||||||
- udp
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
cloud:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
stdout:
|
|
||||||
properties:
|
|
||||||
format:
|
|
||||||
enum:
|
|
||||||
- json
|
|
||||||
- json-formatted
|
|
||||||
type: string
|
|
||||||
default: json
|
|
||||||
type: object
|
|
||||||
syslog-service:
|
|
||||||
minItems: 0
|
|
||||||
items:
|
|
||||||
properties:
|
|
||||||
address:
|
|
||||||
type: string
|
|
||||||
port:
|
|
||||||
type: integer
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
exceptions:
|
|
||||||
type: array
|
|
||||||
minItems: 0
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
action:
|
|
||||||
enum:
|
|
||||||
- skip
|
|
||||||
- accept
|
|
||||||
- drop
|
|
||||||
- suppressLog
|
|
||||||
type: string
|
|
||||||
comment:
|
|
||||||
type: string
|
|
||||||
countryCode:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
countryName:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
hostName:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
paramName:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
paramValue:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
protectionName:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
sourceIdentifier:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
sourceIp:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
url:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
- action
|
|
||||||
trusted-sources:
|
|
||||||
type: array
|
|
||||||
minItems: 0
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
minNumOfSources:
|
|
||||||
type: integer
|
|
||||||
minimum: 1
|
|
||||||
default: 3
|
|
||||||
sources-identifiers:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
- sources-identifiers
|
|
||||||
source-identifiers:
|
|
||||||
type: array
|
|
||||||
minItems: 0
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
identifiers:
|
|
||||||
type: array
|
|
||||||
minItems: 1
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
source-identifier:
|
|
||||||
enum:
|
|
||||||
- headerkey
|
|
||||||
- JWTKey
|
|
||||||
- cookie
|
|
||||||
- sourceip
|
|
||||||
- x-forwarded-for
|
|
||||||
type: string
|
|
||||||
value:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
required:
|
|
||||||
- source-identifier
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
- identifiers
|
|
||||||
additionalProperties: false
|
|
@ -1,113 +0,0 @@
|
|||||||
apiVersion: v1beta2
|
|
||||||
|
|
||||||
policies:
|
|
||||||
default:
|
|
||||||
mode: detect-learn
|
|
||||||
accessControlPractices: [access-control-practice-example]
|
|
||||||
threatPreventionPractices: [threat-prevention-practice-example]
|
|
||||||
triggers: [log-trigger-example]
|
|
||||||
customResponse: web-user-response-exmaple
|
|
||||||
sourceIdentifiers: ""
|
|
||||||
trustedSources: ""
|
|
||||||
exceptions:
|
|
||||||
- exception-example
|
|
||||||
specificRules:
|
|
||||||
- host: "example.com"
|
|
||||||
mode: prevent-learn
|
|
||||||
threatPreventionPractices: [threat-prevention-practice-example]
|
|
||||||
accessControlPractices: [access-control-practice-example]
|
|
||||||
triggers: [log-trigger-example]
|
|
||||||
customResponse: web-user-response-exmaple
|
|
||||||
sourceIdentifiers: ""
|
|
||||||
trustedSources: ""
|
|
||||||
exceptions:
|
|
||||||
- exception-example
|
|
||||||
|
|
||||||
threatPreventionPractices:
|
|
||||||
- name: threat-prevention-practice-example
|
|
||||||
practiceMode: inherited
|
|
||||||
webAttacks:
|
|
||||||
overrideMode: inherited
|
|
||||||
minimumConfidence: high
|
|
||||||
intrusionPrevention:
|
|
||||||
# intrusion prevention (IPS) requires "Premium Edition"
|
|
||||||
overrideMode: inherited
|
|
||||||
maxPerformanceImpact: medium
|
|
||||||
minSeverityLevel: medium
|
|
||||||
minCveYear: 2016
|
|
||||||
highConfidenceEventAction: inherited
|
|
||||||
mediumConfidenceEventAction: inherited
|
|
||||||
lowConfidenceEventAction: detect
|
|
||||||
fileSecurity:
|
|
||||||
# file security requires "Premium Edition"
|
|
||||||
overrideMode: inherited
|
|
||||||
minSeverityLevel: medium
|
|
||||||
highConfidenceEventAction: inherited
|
|
||||||
mediumConfidenceEventAction: inherited
|
|
||||||
lowConfidenceEventAction: detect
|
|
||||||
snortSignatures:
|
|
||||||
# you must specify snort signatures in configmap or file to activate snort inspection
|
|
||||||
overrideMode: inherited
|
|
||||||
configmap: []
|
|
||||||
# relevant for deployments on kubernetes
|
|
||||||
# 0 or 1 configmaps supported in array
|
|
||||||
files: []
|
|
||||||
# relevant for docker and linux embedded deployments
|
|
||||||
# 0 or 1 files supported in array
|
|
||||||
schemaValidation: # schema validation requires "Premium Edition"
|
|
||||||
overrideMode: inherited
|
|
||||||
configmap: []
|
|
||||||
# relevant for deployments on kubernetes
|
|
||||||
# 0 or 1 configmaps supported in array
|
|
||||||
files: []
|
|
||||||
# relevant for docker and linux embedded deployments
|
|
||||||
# 0 or 1 files supported in array
|
|
||||||
antiBot: # antibot requires "Premium Edition"
|
|
||||||
overrideMode: inherited
|
|
||||||
injectedUris: []
|
|
||||||
validatedUris: []
|
|
||||||
|
|
||||||
accessControlPractices:
|
|
||||||
- name: access-control-practice-example
|
|
||||||
practiceMode: inherited
|
|
||||||
rateLimit:
|
|
||||||
# specify one or more rules below to use rate limiting
|
|
||||||
overrideMode: inherited
|
|
||||||
rules: []
|
|
||||||
|
|
||||||
customResponses:
|
|
||||||
- name: web-user-response-exmaple
|
|
||||||
mode: response-code-only
|
|
||||||
httpResponseCode: 403
|
|
||||||
|
|
||||||
logTriggers:
|
|
||||||
- name: log-trigger-example
|
|
||||||
accessControlLogging:
|
|
||||||
allowEvents: false
|
|
||||||
dropEvents: true
|
|
||||||
appsecLogging:
|
|
||||||
detectEvents: true
|
|
||||||
preventEvents: true
|
|
||||||
allWebRequests: false
|
|
||||||
extendedLogging:
|
|
||||||
urlPath: true
|
|
||||||
urlQuery: true
|
|
||||||
httpHeaders: false
|
|
||||||
requestBody: false
|
|
||||||
additionalSuspiciousEventsLogging:
|
|
||||||
enabled: true
|
|
||||||
minSeverity: high
|
|
||||||
responseBody: false
|
|
||||||
responseCode: true
|
|
||||||
logDestination:
|
|
||||||
cloud: true
|
|
||||||
logToAgent: false
|
|
||||||
stdout:
|
|
||||||
format: json
|
|
||||||
|
|
||||||
exceptions:
|
|
||||||
- name: exception-example
|
|
||||||
action: "accept"
|
|
||||||
condition:
|
|
||||||
- key: "countryCode"
|
|
||||||
value: "US"
|
|
@ -1,752 +0,0 @@
|
|||||||
type: object
|
|
||||||
properties:
|
|
||||||
apiVersion:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- v1beta1
|
|
||||||
- v1beta2
|
|
||||||
policies:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
default:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- mode
|
|
||||||
- threatPreventionPractices
|
|
||||||
- accessControlPractices
|
|
||||||
properties:
|
|
||||||
mode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
default: detect-learn
|
|
||||||
threatPreventionPractices:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
accessControlPractices:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
customResponse:
|
|
||||||
type: string
|
|
||||||
default: "403"
|
|
||||||
triggers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
sourceIdentifiers:
|
|
||||||
type: string
|
|
||||||
trustedSources:
|
|
||||||
type: string
|
|
||||||
exceptions:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
specificRules:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
host:
|
|
||||||
type: string
|
|
||||||
mode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
default: detect-learn
|
|
||||||
threatPreventionPractices:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
accessControlPractices:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
triggers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
customResponse:
|
|
||||||
type: string
|
|
||||||
sourceIdentifiers:
|
|
||||||
type: string
|
|
||||||
trustedSources:
|
|
||||||
type: string
|
|
||||||
exceptions:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
logTriggers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- accessControlLogging
|
|
||||||
- appsecLogging
|
|
||||||
- additionalSuspiciousEventsLogging
|
|
||||||
- extendedLogging
|
|
||||||
- logDestination
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
accessControlLogging:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
allowEvents:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
dropEvents:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
appsecLogging:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
detectEvents:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
preventEvents:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
allWebRequests:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
additionalSuspiciousEventsLogging:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
enabled:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
minSeverity:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- high
|
|
||||||
- critical
|
|
||||||
default: high
|
|
||||||
responseBody:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
responseCode:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
extendedLogging:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
urlPath:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
urlQuery:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
httpHeaders:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
requestBody:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
logDestination:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
cloud:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
local-tuning:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
syslogService:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
address:
|
|
||||||
type: string
|
|
||||||
port:
|
|
||||||
type: integer
|
|
||||||
logToAgent:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
stdout:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
format:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- json
|
|
||||||
- json-formatted
|
|
||||||
default: json
|
|
||||||
cefService:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
address:
|
|
||||||
type: string
|
|
||||||
port:
|
|
||||||
type: integer
|
|
||||||
proto:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- tcp
|
|
||||||
- udp
|
|
||||||
threatPreventionPractices:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- webAttacks
|
|
||||||
- intrusionPrevention
|
|
||||||
- fileSecurity
|
|
||||||
- snortSignatures
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
practiceMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- inherited
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
default: inherited
|
|
||||||
webAttacks:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
minimumConfidence:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- medium
|
|
||||||
- high
|
|
||||||
- critical
|
|
||||||
default: high
|
|
||||||
maxUrlSizeBytes:
|
|
||||||
type: integer
|
|
||||||
default: 32768
|
|
||||||
maxObjectDepth:
|
|
||||||
type: integer
|
|
||||||
default: 40
|
|
||||||
maxBodySizeKb:
|
|
||||||
type: integer
|
|
||||||
default: 1000000
|
|
||||||
maxHeaderSizeBytes:
|
|
||||||
type: integer
|
|
||||||
default: 102400
|
|
||||||
protections:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
csrfProtection:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
errorDisclosure:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
openRedirect:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
nonValidHttpMethods:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
antiBot:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
injectedUris:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
uri:
|
|
||||||
type: string
|
|
||||||
validatedUris:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
uri:
|
|
||||||
type: string
|
|
||||||
snortSignatures:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
configmap:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
files:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
schemaValidation:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
enforcementLevel:
|
|
||||||
type: string
|
|
||||||
configmap:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
files:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
intrusionPrevention:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
maxPerformanceImpact:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- low
|
|
||||||
- medium
|
|
||||||
- high
|
|
||||||
default: medium
|
|
||||||
minSeverityLevel:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- low
|
|
||||||
- medium
|
|
||||||
- high
|
|
||||||
- critical
|
|
||||||
default: medium
|
|
||||||
minCveYear:
|
|
||||||
type: integer
|
|
||||||
default: 2016
|
|
||||||
highConfidenceEventAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inherited
|
|
||||||
mediumConfidenceEventAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inherited
|
|
||||||
lowConfidenceEventAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: detect
|
|
||||||
fileSecurity:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent-learn
|
|
||||||
- detect-learn
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
minSeverityLevel:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- low
|
|
||||||
- medium
|
|
||||||
- high
|
|
||||||
- critical
|
|
||||||
default: medium
|
|
||||||
highConfidenceEventAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inherited
|
|
||||||
mediumConfidenceEventAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inherited
|
|
||||||
lowConfidenceEventAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: detect
|
|
||||||
archiveInspection:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
extractArchiveFiles:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
scanMaxFileSize:
|
|
||||||
type: integer
|
|
||||||
default: 10
|
|
||||||
scanMaxFileSizeUnit:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- bytes
|
|
||||||
- KB
|
|
||||||
- MB
|
|
||||||
- GB
|
|
||||||
default: MB
|
|
||||||
archivedFilesWithinArchivedFiles:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited #as set in overrideMode for fileSecurity
|
|
||||||
default: inherited
|
|
||||||
archivedFilesWhereContentExtractionFailed:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited #as set in overrideMode for fileSecurity
|
|
||||||
default: inherited
|
|
||||||
largeFileInspection:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
fileSizeLimit:
|
|
||||||
type: integer
|
|
||||||
default: 10
|
|
||||||
fileSizeLimitUnit:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- bytes
|
|
||||||
- KB
|
|
||||||
- MB
|
|
||||||
- GB
|
|
||||||
default: MB
|
|
||||||
filesExceedingSizeLimitAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited #as set in overrideMode for fileSecurity
|
|
||||||
default: inherited
|
|
||||||
unnamedFilesAction:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited #as set in overrideMode for fileSecurity
|
|
||||||
default: inherited
|
|
||||||
threatEmulationEnabled:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
accessControlPractices:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- rateLimit
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
practiceMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- inherited #inherited from mode set in policy
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
default: inherited
|
|
||||||
rateLimit:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- overrideMode
|
|
||||||
properties:
|
|
||||||
overrideMode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
- inactive
|
|
||||||
- inherited
|
|
||||||
default: inactive
|
|
||||||
rules:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
action: # currently not supported
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- inherited
|
|
||||||
- prevent
|
|
||||||
- detect
|
|
||||||
default: inherited
|
|
||||||
condition: # currently not supported
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- key
|
|
||||||
- value
|
|
||||||
properties:
|
|
||||||
key:
|
|
||||||
type: string
|
|
||||||
value:
|
|
||||||
type: string
|
|
||||||
uri:
|
|
||||||
type: string
|
|
||||||
limit:
|
|
||||||
type: integer
|
|
||||||
unit:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- minute
|
|
||||||
- second
|
|
||||||
default: minute
|
|
||||||
triggers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
comment:
|
|
||||||
type: string
|
|
||||||
customResponses:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- mode
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
mode:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- block-page
|
|
||||||
- redirect
|
|
||||||
- response-code-only
|
|
||||||
default: response-code-only
|
|
||||||
messageTitle:
|
|
||||||
type: string
|
|
||||||
messageBody:
|
|
||||||
type: string
|
|
||||||
httpResponseCode:
|
|
||||||
type: integer
|
|
||||||
minimum: 100
|
|
||||||
maximum: 599
|
|
||||||
default: 403
|
|
||||||
redirectUrl:
|
|
||||||
type: string
|
|
||||||
redirectAddXEventId:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
sourcesIdentifiers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- sourcesIdentifiers
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
sourcesIdentifiers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- identifier
|
|
||||||
properties:
|
|
||||||
identifier:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- headerkey
|
|
||||||
- JWTKey
|
|
||||||
- cookie
|
|
||||||
- sourceip
|
|
||||||
- x-forwarded-for
|
|
||||||
default: sourceip
|
|
||||||
value:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
exceptions:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- action
|
|
||||||
- condition
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
action:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- skip
|
|
||||||
- accept
|
|
||||||
- drop
|
|
||||||
- suppressLog
|
|
||||||
default: accept
|
|
||||||
condition:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- key
|
|
||||||
- value
|
|
||||||
properties:
|
|
||||||
key:
|
|
||||||
type: string
|
|
||||||
value:
|
|
||||||
type: string
|
|
||||||
trustedSources:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- minNumOfSources
|
|
||||||
- sourcesIdentifiers
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
minNumOfSources:
|
|
||||||
type: integer
|
|
||||||
default: 3
|
|
||||||
sourcesIdentifiers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
policyActivations:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
appsecClassName:
|
|
||||||
type: string
|
|
||||||
enabledPolicies:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
hosts:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- hosts
|
|
||||||
required:
|
|
||||||
- enabledPolicies
|
|
||||||
additionalProperties: false
|
|
@ -237,12 +237,6 @@ AgentDetails::getAgentId() const
|
|||||||
return agent_id;
|
return agent_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
string
|
|
||||||
AgentDetails::getRegisteredServer() const
|
|
||||||
{
|
|
||||||
return server;
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<string>
|
Maybe<string>
|
||||||
AgentDetails::getProxy() const
|
AgentDetails::getProxy() const
|
||||||
{
|
{
|
||||||
@ -276,7 +270,6 @@ void
|
|||||||
AgentDetails::preload()
|
AgentDetails::preload()
|
||||||
{
|
{
|
||||||
registerExpectedConfiguration<string>("orchestration", "Agent details path");
|
registerExpectedConfiguration<string>("orchestration", "Agent details path");
|
||||||
registerExpectedConfiguration<string>("Agent details", "File path");
|
|
||||||
registerConfigLoadCb([this] () { readAgentDetails(); });
|
registerConfigLoadCb([this] () { readAgentDetails(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,7 +430,6 @@ AgentDetails::loadProxyType(const string &proxy_type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef gaia
|
#ifdef gaia
|
||||||
(void)proxy_type;
|
|
||||||
I_ShellCmd *shell_cmd = Singleton::Consume<I_ShellCmd>::by<AgentDetails>();
|
I_ShellCmd *shell_cmd = Singleton::Consume<I_ShellCmd>::by<AgentDetails>();
|
||||||
auto proxy_ip = shell_cmd->getExecOutput("dbget proxy:ip-address| tr -d '\n'");
|
auto proxy_ip = shell_cmd->getExecOutput("dbget proxy:ip-address| tr -d '\n'");
|
||||||
if (!proxy_ip.ok()) return proxy_ip;
|
if (!proxy_ip.ok()) return proxy_ip;
|
||||||
|
@ -68,7 +68,6 @@ public:
|
|||||||
const Maybe<string> &agent_version
|
const Maybe<string> &agent_version
|
||||||
) override;
|
) override;
|
||||||
|
|
||||||
pair<string, string> generateTimeStamp();
|
|
||||||
bool addAttr(const string &key, const string &val, bool allow_override = false) override;
|
bool addAttr(const string &key, const string &val, bool allow_override = false) override;
|
||||||
bool addAttr(const map<string, string> &attr, bool allow_override = false) override;
|
bool addAttr(const map<string, string> &attr, bool allow_override = false) override;
|
||||||
void deleteAttr(const string &key) override;
|
void deleteAttr(const string &key) override;
|
||||||
@ -219,13 +218,6 @@ AgentDetailsReporter::Impl::isPersistantAttr(const std::string &key)
|
|||||||
return persistant_attributes.count(key) > 0;
|
return persistant_attributes.count(key) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pair<string, string>
|
|
||||||
AgentDetailsReporter::Impl::generateTimeStamp()
|
|
||||||
{
|
|
||||||
auto time_stamp = Singleton::Consume<I_TimeGet>::by<AgentDetailsReporter>()->getWalltimeStr();
|
|
||||||
return make_pair("timestamp", time_stamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AgentDetailsReporter::Impl::sendAttributes()
|
AgentDetailsReporter::Impl::sendAttributes()
|
||||||
{
|
{
|
||||||
@ -240,10 +232,11 @@ AgentDetailsReporter::Impl::sendAttributes()
|
|||||||
attributes[new_attr.first] = new_attr.second;
|
attributes[new_attr.first] = new_attr.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AttributesSender attr_to_send(attributes);
|
AttributesSender attr_to_send(attributes);
|
||||||
if (is_server) {
|
if (is_server) {
|
||||||
AttrSerializer<ofstream, cereal::JSONOutputArchive>(attributes, "save");
|
AttrSerializer<ofstream, cereal::JSONOutputArchive>(attributes, "save");
|
||||||
attr_to_send.attributes.get().insert(generateTimeStamp());
|
|
||||||
messaging->sendAsyncMessage(HTTPMethod::PATCH, "/agents", attr_to_send);
|
messaging->sendAsyncMessage(HTTPMethod::PATCH, "/agents", attr_to_send);
|
||||||
dbgDebug(D_AGENT_DETAILS) << "Triggered persistent message request with attributes to the Fog";
|
dbgDebug(D_AGENT_DETAILS) << "Triggered persistent message request with attributes to the Fog";
|
||||||
new_attributes.clear();
|
new_attributes.clear();
|
||||||
@ -329,36 +322,6 @@ public:
|
|||||||
attributes = attr;
|
attributes = attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
addAttr(const string &key, const string &val, bool allow_override = false)
|
|
||||||
{
|
|
||||||
dbgDebug(D_AGENT_DETAILS)
|
|
||||||
<< "Trying to add new attribute. Key: "
|
|
||||||
<< key
|
|
||||||
<< ", Value: "
|
|
||||||
<< val
|
|
||||||
<< " Should allow override: "
|
|
||||||
<< (allow_override ? "true" : "false");
|
|
||||||
auto &attr = attributes.get();
|
|
||||||
if (!allow_override) {
|
|
||||||
if (attr.count(key) > 0) {
|
|
||||||
dbgWarning(D_AGENT_DETAILS)
|
|
||||||
<< "Cannot override an existing value with a new one. Existing Value: "
|
|
||||||
<< (attr.count(key) > 0 ? attr[key] : "");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
attr[key] = val;
|
|
||||||
if (!attributes.isActive()) attributes.setActive(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
addAttr(const pair<string, string> &attr, bool allow_override = false)
|
|
||||||
{
|
|
||||||
addAttr(attr.first, attr.second, allow_override);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
C2S_PARAM(metaDataReport, additionalMetaData);
|
C2S_PARAM(metaDataReport, additionalMetaData);
|
||||||
C2S_OPTIONAL_PARAM(string, agentVersion);
|
C2S_OPTIONAL_PARAM(string, agentVersion);
|
||||||
@ -439,7 +402,6 @@ AgentDetailsReporter::Impl::sendReport(
|
|||||||
additional_metadata.setAdditionalAttributes(attributes);
|
additional_metadata.setAdditionalAttributes(attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
additional_metadata.addAttr(generateTimeStamp());
|
|
||||||
messaging->sendAsyncMessage(HTTPMethod::PATCH, "/agents", additional_metadata);
|
messaging->sendAsyncMessage(HTTPMethod::PATCH, "/agents", additional_metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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