mirror of
https://github.com/openappsec/openappsec.git
synced 2025-11-16 17:31:52 +03:00
Compare commits
135 Commits
1.1.8
...
oriane-23.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
923a8a804b | ||
|
|
b1731237d1 | ||
|
|
3d3d6e73b9 | ||
|
|
d2b9bc8c9c | ||
|
|
886a5befe1 | ||
|
|
1f2502f9e4 | ||
|
|
9e4c5014ce | ||
|
|
024423cce9 | ||
|
|
dc4b546bd1 | ||
|
|
a86aca13b4 | ||
|
|
87b34590d4 | ||
|
|
e0198a1a95 | ||
|
|
d024ad5845 | ||
|
|
46d42c8fa3 | ||
|
|
f6c36f3363 | ||
|
|
63541a4c3c | ||
|
|
d14fa7a468 | ||
|
|
ae0de5bf14 | ||
|
|
d39919f348 | ||
|
|
4f215e1409 | ||
|
|
f05b5f8cee | ||
|
|
949b656b13 | ||
|
|
bbe293d215 | ||
|
|
2c91793f08 | ||
|
|
72a263d25a | ||
|
|
4e14ff9a58 | ||
|
|
1fb28e14d6 | ||
|
|
e38bb9525c | ||
|
|
63b8bb22c2 | ||
|
|
11c97330f5 | ||
|
|
e56fb0bc1a | ||
|
|
4571d563f4 | ||
|
|
02c1db01f6 | ||
|
|
c557affd9b | ||
|
|
8889c3c054 | ||
|
|
f67eff87bc | ||
|
|
fa6a2e4233 | ||
|
|
b7e2efbf7e | ||
|
|
96ce290e5f | ||
|
|
de8e2d9970 | ||
|
|
0048708af1 | ||
|
|
4fe0f44e88 | ||
|
|
5f139d13d7 | ||
|
|
919d775a73 | ||
|
|
ac8e353598 | ||
|
|
0663f20691 | ||
|
|
2dda6231f6 | ||
|
|
1c1f0b7e29 | ||
|
|
6255e1f30d | ||
|
|
454aacf622 | ||
|
|
c91ccba5a8 | ||
|
|
b1f897191c | ||
|
|
027ddfea21 | ||
|
|
d1a2906b29 | ||
|
|
b1ade9bba0 | ||
|
|
36d302b77e | ||
|
|
1d7d38b0a6 | ||
|
|
1b7eafaa23 | ||
|
|
c2ea2cda6d | ||
|
|
b58f7781e6 | ||
|
|
7153d222c0 | ||
|
|
f1ec8959b7 | ||
|
|
4a7336b276 | ||
|
|
4d0042e933 | ||
|
|
015915497a | ||
|
|
586150fe4f | ||
|
|
3fe0b42fcd | ||
|
|
84e10c7129 | ||
|
|
eddd250409 | ||
|
|
294cb600f8 | ||
|
|
f4bad4c4d9 | ||
|
|
6e916599d9 | ||
|
|
24d53aed53 | ||
|
|
93fb3da2f8 | ||
|
|
e7378c9a5f | ||
|
|
110f0c8bd2 | ||
|
|
ca31aac08a | ||
|
|
161b6dd180 | ||
|
|
84327e0b19 | ||
|
|
b9723ba6ce | ||
|
|
00e183b8c6 | ||
|
|
e859c167ed | ||
|
|
384b59cc87 | ||
|
|
805e958cb9 | ||
|
|
5bcd7cfcf1 | ||
|
|
ae6f2faeec | ||
|
|
705a5e6061 | ||
|
|
c33b74a970 | ||
|
|
2da9fbc385 | ||
|
|
f58e9a6128 | ||
|
|
57ea5c72c5 | ||
|
|
962bd31d46 | ||
|
|
01770475ec | ||
|
|
78b114a274 | ||
|
|
81b1aec487 | ||
|
|
be6591a670 | ||
|
|
663782009c | ||
|
|
9392bbb26c | ||
|
|
46682bcdce | ||
|
|
057bc42375 | ||
|
|
88e0ccd308 | ||
|
|
4241b9c574 | ||
|
|
4af9f18ada | ||
|
|
3b533608b1 | ||
|
|
74bb3086ec | ||
|
|
504d1415a5 | ||
|
|
18b1b63c42 | ||
|
|
ded2a5ffc2 | ||
|
|
1254bb37b2 | ||
|
|
cf16343caa | ||
|
|
78c4209406 | ||
|
|
3c8672c565 | ||
|
|
48d6baed3b | ||
|
|
8770257a60 | ||
|
|
fd5d093b24 | ||
|
|
d6debf8d8d | ||
|
|
395b754575 | ||
|
|
dc000372c4 | ||
|
|
941c641174 | ||
|
|
fdc148aa9b | ||
|
|
307fd8897d | ||
|
|
afd2b4930b | ||
|
|
1fb9a29223 | ||
|
|
253ca70de6 | ||
|
|
938f625535 | ||
|
|
183d14fc55 | ||
|
|
1f3d4ed5e1 | ||
|
|
fdbd6d3786 | ||
|
|
4504138a4a | ||
|
|
66ed4a8d81 | ||
|
|
189c9209c9 | ||
|
|
1a1580081c | ||
|
|
942b2ef8b4 | ||
|
|
7a7f65a77a | ||
|
|
ecbb34bc17 |
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required (VERSION 2.8.4)
|
cmake_minimum_required (VERSION 2.8.4)
|
||||||
project (ngen)
|
project (ngen)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wall -Wno-terminate")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -fPIC -Wall -Wno-terminate")
|
||||||
|
|
||||||
execute_process(COMMAND grep -c "Alpine Linux" /etc/os-release OUTPUT_VARIABLE IS_ALPINE)
|
execute_process(COMMAND grep -c "Alpine Linux" /etc/os-release OUTPUT_VARIABLE IS_ALPINE)
|
||||||
if(NOT IS_ALPINE EQUAL "0")
|
if(NOT IS_ALPINE EQUAL "0")
|
||||||
|
|||||||
@@ -155,6 +155,24 @@ getWaitingForVerdictThreadTimeout()
|
|||||||
return conf_data.getNumericalValue("waiting_for_verdict_thread_timeout_msec");
|
return conf_data.getNumericalValue("waiting_for_verdict_thread_timeout_msec");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
getMinRetriesForVerdict()
|
||||||
|
{
|
||||||
|
return conf_data.getNumericalValue("min_retries_for_verdict");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
getMaxRetriesForVerdict()
|
||||||
|
{
|
||||||
|
return conf_data.getNumericalValue("max_retries_for_verdict");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
getReqBodySizeTrigger()
|
||||||
|
{
|
||||||
|
return conf_data.getNumericalValue("body_size_trigger");
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
isIPAddress(c_str ip_str)
|
isIPAddress(c_str ip_str)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -63,31 +63,37 @@ TEST_F(HttpAttachmentUtilTest, GetValidAttachmentConfiguration)
|
|||||||
"\"waiting_for_verdict_thread_timeout_msec\": 75,\n"
|
"\"waiting_for_verdict_thread_timeout_msec\": 75,\n"
|
||||||
"\"req_header_thread_timeout_msec\": 10,\n"
|
"\"req_header_thread_timeout_msec\": 10,\n"
|
||||||
"\"ip_ranges\": " + createIPRangesString(ip_ranges) + ",\n"
|
"\"ip_ranges\": " + createIPRangesString(ip_ranges) + ",\n"
|
||||||
"\"static_resources_path\": \"" + static_resources_path + "\""
|
"\"static_resources_path\": \"" + static_resources_path + "\",\n"
|
||||||
|
"\"min_retries_for_verdict\": 1,\n"
|
||||||
|
"\"max_retries_for_verdict\": 3,\n"
|
||||||
|
"\"body_size_trigger\": 777\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ofstream valid_configuration_file(attachment_configuration_file_name);
|
ofstream valid_configuration_file(attachment_configuration_file_name);
|
||||||
valid_configuration_file << valid_configuration;
|
valid_configuration_file << valid_configuration;
|
||||||
valid_configuration_file.close();
|
valid_configuration_file.close();
|
||||||
|
|
||||||
EXPECT_EQ(initAttachmentConfig(attachment_configuration_file_name.c_str()), 1);
|
EXPECT_EQ(initAttachmentConfig(attachment_configuration_file_name.c_str()), 1);
|
||||||
EXPECT_EQ(getDbgLevel(), 2);
|
EXPECT_EQ(getDbgLevel(), 2u);
|
||||||
EXPECT_EQ(getStaticResourcesPath(), static_resources_path);
|
EXPECT_EQ(getStaticResourcesPath(), static_resources_path);
|
||||||
EXPECT_EQ(isFailOpenMode(), 0);
|
EXPECT_EQ(isFailOpenMode(), 0);
|
||||||
EXPECT_EQ(getFailOpenTimeout(), 1234);
|
EXPECT_EQ(getFailOpenTimeout(), 1234u);
|
||||||
EXPECT_EQ(isFailOpenHoldMode(), 1);
|
EXPECT_EQ(isFailOpenHoldMode(), 1);
|
||||||
EXPECT_EQ(getFailOpenHoldTimeout(), 4321);
|
EXPECT_EQ(getFailOpenHoldTimeout(), 4321u);
|
||||||
EXPECT_EQ(isFailOpenOnSessionLimit(), 1);
|
EXPECT_EQ(isFailOpenOnSessionLimit(), 1);
|
||||||
EXPECT_EQ(getMaxSessionsPerMinute(), 0);
|
EXPECT_EQ(getMaxSessionsPerMinute(), 0u);
|
||||||
EXPECT_EQ(getNumOfNginxIpcElements(), 200);
|
EXPECT_EQ(getNumOfNginxIpcElements(), 200u);
|
||||||
EXPECT_EQ(getKeepAliveIntervalMsec(), 10000);
|
EXPECT_EQ(getKeepAliveIntervalMsec(), 10000u);
|
||||||
EXPECT_EQ(getResProccessingTimeout(), 420);
|
EXPECT_EQ(getResProccessingTimeout(), 420u);
|
||||||
EXPECT_EQ(getReqProccessingTimeout(), 42);
|
EXPECT_EQ(getReqProccessingTimeout(), 42u);
|
||||||
EXPECT_EQ(getRegistrationThreadTimeout(), 101);
|
EXPECT_EQ(getRegistrationThreadTimeout(), 101u);
|
||||||
EXPECT_EQ(getReqHeaderThreadTimeout(), 10);
|
EXPECT_EQ(getReqHeaderThreadTimeout(), 10u);
|
||||||
EXPECT_EQ(getReqBodyThreadTimeout(), 155);
|
EXPECT_EQ(getReqBodyThreadTimeout(), 155u);
|
||||||
EXPECT_EQ(getResHeaderThreadTimeout(), 1);
|
EXPECT_EQ(getResHeaderThreadTimeout(), 1u);
|
||||||
EXPECT_EQ(getResBodyThreadTimeout(), 0);
|
EXPECT_EQ(getResBodyThreadTimeout(), 0u);
|
||||||
EXPECT_EQ(getWaitingForVerdictThreadTimeout(), 75);
|
EXPECT_EQ(getMinRetriesForVerdict(), 1u);
|
||||||
|
EXPECT_EQ(getMaxRetriesForVerdict(), 3u);
|
||||||
|
EXPECT_EQ(getReqBodySizeTrigger(), 777u);
|
||||||
|
EXPECT_EQ(getWaitingForVerdictThreadTimeout(), 75u);
|
||||||
EXPECT_EQ(getInspectionMode(), ngx_http_inspection_mode::BLOCKING_THREAD);
|
EXPECT_EQ(getInspectionMode(), ngx_http_inspection_mode::BLOCKING_THREAD);
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
# Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// You may obtain a copy of the License at
|
# You may obtain a copy of the License at
|
||||||
//
|
#
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
#
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
version: "3"
|
version: "3"
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ var_fog_address=
|
|||||||
var_proxy=
|
var_proxy=
|
||||||
var_mode=
|
var_mode=
|
||||||
var_token=
|
var_token=
|
||||||
|
var_ignore=
|
||||||
init=
|
init=
|
||||||
|
|
||||||
if [ ! -f /nano-service-installers/$ORCHESTRATION_INSTALLATION_SCRIPT ]; then
|
if [ ! -f /nano-service-installers/$ORCHESTRATION_INSTALLATION_SCRIPT ]; then
|
||||||
@@ -33,6 +34,8 @@ while true; do
|
|||||||
var_proxy="$1"
|
var_proxy="$1"
|
||||||
elif [ "$1" == "--hybrid-mode" ] || [ "$1" == "--standalone" ]; then
|
elif [ "$1" == "--hybrid-mode" ] || [ "$1" == "--standalone" ]; then
|
||||||
var_mode="--hybrid_mode"
|
var_mode="--hybrid_mode"
|
||||||
|
elif [ "$1" == "--no-upgrade" ]; then
|
||||||
|
var_ignore="--ignore all"
|
||||||
elif [ "$1" == "--token" ]; then
|
elif [ "$1" == "--token" ]; then
|
||||||
shift
|
shift
|
||||||
var_token="$1"
|
var_token="$1"
|
||||||
@@ -41,12 +44,16 @@ while true; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z $var_token ] && [ $var_mode != "--hybrid_mode" ]; then
|
if [ -z $var_token ] && [ $var_mode != "--hybrid_mode" ]; then
|
||||||
echo "Error: Token was not provided as input argument."
|
var_token=$(env | grep 'AGENT_TOKEN=' | cut -d'=' -f2-)
|
||||||
exit 1
|
if [ -z $var_token ]; then
|
||||||
|
echo "Error: Token was not provided as input argument."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
orchestration_service_installation_flags="--container_mode --skip_registration"
|
orchestration_service_installation_flags="--container_mode --skip_registration"
|
||||||
if [ ! -z $var_token ]; then
|
if [ ! -z $var_token ]; then
|
||||||
|
export AGENT_TOKEN="$var_token"
|
||||||
orchestration_service_installation_flags="$orchestration_service_installation_flags --token $var_token"
|
orchestration_service_installation_flags="$orchestration_service_installation_flags --token $var_token"
|
||||||
fi
|
fi
|
||||||
if [ ! -z $var_fog_address ]; then
|
if [ ! -z $var_fog_address ]; then
|
||||||
@@ -59,6 +66,9 @@ fi
|
|||||||
if [ ! -z $var_mode ]; then
|
if [ ! -z $var_mode ]; then
|
||||||
orchestration_service_installation_flags="$orchestration_service_installation_flags $var_mode"
|
orchestration_service_installation_flags="$orchestration_service_installation_flags $var_mode"
|
||||||
fi
|
fi
|
||||||
|
if [ ! -z "$var_ignore" ]; then
|
||||||
|
orchestration_service_installation_flags="$orchestration_service_installation_flags $var_ignore"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
/nano-service-installers/$ORCHESTRATION_INSTALLATION_SCRIPT --install $orchestration_service_installation_flags
|
/nano-service-installers/$ORCHESTRATION_INSTALLATION_SCRIPT --install $orchestration_service_installation_flags
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,10 +1,8 @@
|
|||||||
add_subdirectory(report_messaging)
|
|
||||||
add_subdirectory(http_manager)
|
add_subdirectory(http_manager)
|
||||||
add_subdirectory(signal_handler)
|
add_subdirectory(signal_handler)
|
||||||
add_subdirectory(gradual_deployment)
|
add_subdirectory(gradual_deployment)
|
||||||
add_subdirectory(packet)
|
add_subdirectory(packet)
|
||||||
add_subdirectory(pending_key)
|
add_subdirectory(pending_key)
|
||||||
add_subdirectory(health_check_manager)
|
|
||||||
|
|
||||||
add_subdirectory(utils)
|
add_subdirectory(utils)
|
||||||
add_subdirectory(attachment-intakers)
|
add_subdirectory(attachment-intakers)
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ USE_DEBUG_FLAG(D_ATTACHMENT_REGISTRATION);
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
static const AlertInfo alert(AlertTeam::CORE, "attachment registrator");
|
||||||
|
|
||||||
class AttachmentRegistrator::Impl
|
class AttachmentRegistrator::Impl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -163,7 +165,7 @@ private:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
dbgAssert(false) << "Unsupported Attachment " << static_cast<int>(type);
|
dbgAssert(false) << alert << "Unsupported Attachment " << static_cast<int>(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!family_id.empty()) handler_path << family_id << "_";
|
if (!family_id.empty()) handler_path << family_id << "_";
|
||||||
@@ -175,7 +177,9 @@ private:
|
|||||||
string
|
string
|
||||||
genRegCommand(const string &family_id, const uint num_of_members, const AttachmentType type) const
|
genRegCommand(const string &family_id, const uint num_of_members, const AttachmentType type) const
|
||||||
{
|
{
|
||||||
dbgAssert(num_of_members > 0) << "Failed to generate a registration command for an empty group of attachments";
|
dbgAssert(num_of_members > 0)
|
||||||
|
<< alert
|
||||||
|
<< "Failed to generate a registration command for an empty group of attachments";
|
||||||
|
|
||||||
static const string registration_format = "/etc/cp/watchdog/cp-nano-watchdog --register ";
|
static const string registration_format = "/etc/cp/watchdog/cp-nano-watchdog --register ";
|
||||||
stringstream registration_command;
|
stringstream registration_command;
|
||||||
@@ -187,7 +191,7 @@ private:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
dbgAssert(false) << "Unsupported Attachment " << static_cast<int>(type);
|
dbgAssert(false) << alert << "Unsupported Attachment " << static_cast<int>(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!family_id.empty()) registration_command << " --family " << family_id;
|
if (!family_id.empty()) registration_command << " --family " << family_id;
|
||||||
@@ -265,7 +269,7 @@ private:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgAssert(new_socket.unpack() > 0) << "Generated socket is OK yet negative";
|
dbgAssert(new_socket.unpack() > 0) << alert << "Generated socket is OK yet negative";
|
||||||
return new_socket.unpack();
|
return new_socket.unpack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +285,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
I_Socket::socketFd client_socket = accepted_socket.unpack();
|
I_Socket::socketFd client_socket = accepted_socket.unpack();
|
||||||
dbgAssert(client_socket > 0) << "Generated client socket is OK yet negative";
|
dbgAssert(client_socket > 0) << alert << "Generated client socket is OK yet negative";
|
||||||
auto close_socket_on_exit = make_scope_exit([&]() { i_socket->closeSocket(client_socket); });
|
auto close_socket_on_exit = make_scope_exit([&]() { i_socket->closeSocket(client_socket); });
|
||||||
|
|
||||||
Maybe<uint8_t> attachment_id = readNumericParam(client_socket);
|
Maybe<uint8_t> attachment_id = readNumericParam(client_socket);
|
||||||
@@ -375,7 +379,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
I_Socket::socketFd client_socket = accepted_socket.unpack();
|
I_Socket::socketFd client_socket = accepted_socket.unpack();
|
||||||
dbgAssert(client_socket > 0) << "Generated client socket is OK yet negative";
|
dbgAssert(client_socket > 0) << alert << "Generated client socket is OK yet negative";
|
||||||
auto close_socket_on_exit = make_scope_exit([&]() { i_socket->closeSocket(client_socket); });
|
auto close_socket_on_exit = make_scope_exit([&]() { i_socket->closeSocket(client_socket); });
|
||||||
|
|
||||||
Maybe<AttachmentType> attachment_type = readAttachmentType(client_socket);
|
Maybe<AttachmentType> attachment_type = readAttachmentType(client_socket);
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ using namespace std;
|
|||||||
using ChunkType = ngx_http_chunk_type_e;
|
using ChunkType = ngx_http_chunk_type_e;
|
||||||
|
|
||||||
static const uint32_t corrupted_session_id = CORRUPTED_SESSION_ID;
|
static const uint32_t corrupted_session_id = CORRUPTED_SESSION_ID;
|
||||||
|
static const AlertInfo alert(AlertTeam::CORE, "nginx attachment");
|
||||||
|
|
||||||
class FailopenModeListener : public Listener<FailopenModeEvent>
|
class FailopenModeListener : public Listener<FailopenModeEvent>
|
||||||
{
|
{
|
||||||
@@ -410,7 +411,10 @@ private:
|
|||||||
bool
|
bool
|
||||||
registerAttachmentProcess(uint32_t nginx_user_id, uint32_t nginx_group_id, I_Socket::socketFd new_socket)
|
registerAttachmentProcess(uint32_t nginx_user_id, uint32_t nginx_group_id, I_Socket::socketFd new_socket)
|
||||||
{
|
{
|
||||||
dbgAssert(server_sock > 0) << "Registration attempt occurred while registration socket is uninitialized";
|
dbgAssert(server_sock > 0)
|
||||||
|
<< alert
|
||||||
|
<< "Registration attempt occurred while registration socket is uninitialized";
|
||||||
|
|
||||||
#ifdef FAILURE_TEST
|
#ifdef FAILURE_TEST
|
||||||
bool did_fail_on_purpose = false;
|
bool did_fail_on_purpose = false;
|
||||||
#endif
|
#endif
|
||||||
@@ -802,10 +806,10 @@ private:
|
|||||||
case ChunkType::HOLD_DATA:
|
case ChunkType::HOLD_DATA:
|
||||||
return "HOLD_DATA";
|
return "HOLD_DATA";
|
||||||
case ChunkType::COUNT:
|
case ChunkType::COUNT:
|
||||||
dbgAssert(false) << "Invalid 'COUNT' ChunkType";
|
dbgAssert(false) << alert << "Invalid 'COUNT' ChunkType";
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
dbgAssert(false) << "ChunkType was not handled by the switch case";
|
dbgAssert(false) << alert << "ChunkType was not handled by the switch case";
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1131,7 +1135,11 @@ private:
|
|||||||
"webUserResponse"
|
"webUserResponse"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
bool remove_event_id_param =
|
||||||
|
getProfileAgentSettingWithDefault<string>("false", "nginxAttachment.removeRedirectEventId") == "true";
|
||||||
|
|
||||||
string uuid;
|
string uuid;
|
||||||
|
string redirectUrl;
|
||||||
if (i_transaction_table->hasState<NginxAttachmentOpaque>()) {
|
if (i_transaction_table->hasState<NginxAttachmentOpaque>()) {
|
||||||
NginxAttachmentOpaque &opaque = i_transaction_table->getState<NginxAttachmentOpaque>();
|
NginxAttachmentOpaque &opaque = i_transaction_table->getState<NginxAttachmentOpaque>();
|
||||||
uuid = opaque.getSessionUUID();
|
uuid = opaque.getSessionUUID();
|
||||||
@@ -1141,7 +1149,12 @@ private:
|
|||||||
if (web_trigger_conf.getDetailsLevel() == "Redirect") {
|
if (web_trigger_conf.getDetailsLevel() == "Redirect") {
|
||||||
web_response_data.response_data.redirect_data.redirect_location_size =
|
web_response_data.response_data.redirect_data.redirect_location_size =
|
||||||
web_trigger_conf.getRedirectURL().size();
|
web_trigger_conf.getRedirectURL().size();
|
||||||
web_response_data.response_data.redirect_data.add_event_id = web_trigger_conf.getAddEventId() ? 1 : 0;
|
bool add_event = web_trigger_conf.getAddEventId();
|
||||||
|
if (add_event && !remove_event_id_param) {
|
||||||
|
web_response_data.response_data.redirect_data.redirect_location_size +=
|
||||||
|
strlen("?event_id=") + uuid.size();
|
||||||
|
}
|
||||||
|
web_response_data.response_data.redirect_data.add_event_id = add_event ? 1 : 0;
|
||||||
web_response_data.web_repsonse_type = static_cast<uint8_t>(ngx_web_response_type_e::REDIRECT_WEB_RESPONSE);
|
web_response_data.web_repsonse_type = static_cast<uint8_t>(ngx_web_response_type_e::REDIRECT_WEB_RESPONSE);
|
||||||
} else {
|
} else {
|
||||||
web_response_data.response_data.custom_response_data.title_size =
|
web_response_data.response_data.custom_response_data.title_size =
|
||||||
@@ -1155,8 +1168,13 @@ private:
|
|||||||
verdict_data_sizes.push_back(sizeof(ngx_http_cp_web_response_data_t));
|
verdict_data_sizes.push_back(sizeof(ngx_http_cp_web_response_data_t));
|
||||||
|
|
||||||
if (web_trigger_conf.getDetailsLevel() == "Redirect") {
|
if (web_trigger_conf.getDetailsLevel() == "Redirect") {
|
||||||
verdict_data.push_back(reinterpret_cast<const char *>(web_trigger_conf.getRedirectURL().data()));
|
redirectUrl = web_trigger_conf.getRedirectURL();
|
||||||
verdict_data_sizes.push_back(web_trigger_conf.getRedirectURL().size());
|
if (!remove_event_id_param && web_trigger_conf.getAddEventId()) {
|
||||||
|
redirectUrl += "?event-id=" + uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
verdict_data.push_back(reinterpret_cast<const char *>(redirectUrl.data()));
|
||||||
|
verdict_data_sizes.push_back(redirectUrl.size());
|
||||||
} else {
|
} else {
|
||||||
verdict_data.push_back(reinterpret_cast<const char *>(web_trigger_conf.getResponseTitle().data()));
|
verdict_data.push_back(reinterpret_cast<const char *>(web_trigger_conf.getResponseTitle().data()));
|
||||||
verdict_data_sizes.push_back(web_trigger_conf.getResponseTitle().size());
|
verdict_data_sizes.push_back(web_trigger_conf.getResponseTitle().size());
|
||||||
@@ -1582,7 +1600,7 @@ private:
|
|||||||
case WAIT:
|
case WAIT:
|
||||||
return "WAIT";
|
return "WAIT";
|
||||||
}
|
}
|
||||||
dbgAssert(false) << "Invalid EventVerdict enum: " << static_cast<int>(verdict.getVerdict());
|
dbgAssert(false) << alert << "Invalid EventVerdict enum: " << static_cast<int>(verdict.getVerdict());
|
||||||
return string();
|
return string();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1633,13 +1651,14 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgAssert(sock.unpack() > 0) << "The generated server socket is OK, yet negative";
|
dbgAssert(sock.unpack() > 0) << alert << "The generated server socket is OK, yet negative";
|
||||||
server_sock = sock.unpack();
|
server_sock = sock.unpack();
|
||||||
|
|
||||||
I_MainLoop::Routine accept_attachment_routine =
|
I_MainLoop::Routine accept_attachment_routine =
|
||||||
[this] ()
|
[this] ()
|
||||||
{
|
{
|
||||||
dbgAssert(inst_awareness->getUniqueID().ok())
|
dbgAssert(inst_awareness->getUniqueID().ok())
|
||||||
|
<< alert
|
||||||
<< "NGINX attachment Initialized without Instance Awareness";
|
<< "NGINX attachment Initialized without Instance Awareness";
|
||||||
|
|
||||||
bool did_fail_on_purpose = false;
|
bool did_fail_on_purpose = false;
|
||||||
@@ -1652,7 +1671,7 @@ private:
|
|||||||
<< (did_fail_on_purpose ? "Intentional Failure" : new_sock.getErr());
|
<< (did_fail_on_purpose ? "Intentional Failure" : new_sock.getErr());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dbgAssert(new_sock.unpack() > 0) << "The generated client socket is OK, yet negative";
|
dbgAssert(new_sock.unpack() > 0) << alert << "The generated client socket is OK, yet negative";
|
||||||
I_Socket::socketFd new_attachment_socket = new_sock.unpack();
|
I_Socket::socketFd new_attachment_socket = new_sock.unpack();
|
||||||
|
|
||||||
Maybe<string> uid = getUidFromSocket(new_attachment_socket);
|
Maybe<string> uid = getUidFromSocket(new_attachment_socket);
|
||||||
@@ -1698,7 +1717,7 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
mainloop->addFileRoutine(
|
mainloop->addFileRoutine(
|
||||||
I_MainLoop::RoutineType::RealTime,
|
I_MainLoop::RoutineType::System,
|
||||||
server_sock,
|
server_sock,
|
||||||
accept_attachment_routine,
|
accept_attachment_routine,
|
||||||
"Nginx Attachment registration listener",
|
"Nginx Attachment registration listener",
|
||||||
@@ -1711,7 +1730,9 @@ private:
|
|||||||
Maybe<string>
|
Maybe<string>
|
||||||
getUidFromSocket(I_Socket::socketFd new_attachment_socket)
|
getUidFromSocket(I_Socket::socketFd new_attachment_socket)
|
||||||
{
|
{
|
||||||
dbgAssert(server_sock > 0) << "Registration attempt occurred while registration socket is uninitialized";
|
dbgAssert(server_sock > 0)
|
||||||
|
<< alert
|
||||||
|
<< "Registration attempt occurred while registration socket is uninitialized";
|
||||||
|
|
||||||
bool did_fail_on_purpose = false;
|
bool did_fail_on_purpose = false;
|
||||||
DELAY_IF_NEEDED(IntentionalFailureHandler::FailureType::ReceiveDataFromSocket);
|
DELAY_IF_NEEDED(IntentionalFailureHandler::FailureType::ReceiveDataFromSocket);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ HttpAttachmentConfig::init()
|
|||||||
setNumOfNginxIpcElements();
|
setNumOfNginxIpcElements();
|
||||||
setDebugByContextValues();
|
setDebugByContextValues();
|
||||||
setKeepAliveIntervalMsec();
|
setKeepAliveIntervalMsec();
|
||||||
|
setRetriesForVerdict();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -215,6 +216,31 @@ HttpAttachmentConfig::setFailOpenTimeout()
|
|||||||
conf_data.setNumericalValue("nginx_inspection_mode", inspection_mode);
|
conf_data.setNumericalValue("nginx_inspection_mode", inspection_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HttpAttachmentConfig::setRetriesForVerdict()
|
||||||
|
{
|
||||||
|
conf_data.setNumericalValue("min_retries_for_verdict", getAttachmentConf<uint>(
|
||||||
|
3,
|
||||||
|
"agent.minRetriesForVerdict.nginxModule",
|
||||||
|
"HTTP manager",
|
||||||
|
"Min retries for verdict"
|
||||||
|
));
|
||||||
|
|
||||||
|
conf_data.setNumericalValue("max_retries_for_verdict", getAttachmentConf<uint>(
|
||||||
|
15,
|
||||||
|
"agent.maxRetriesForVerdict.nginxModule",
|
||||||
|
"HTTP manager",
|
||||||
|
"Max retries for verdict"
|
||||||
|
));
|
||||||
|
|
||||||
|
conf_data.setNumericalValue("body_size_trigger", getAttachmentConf<uint>(
|
||||||
|
200000,
|
||||||
|
"agent.reqBodySizeTrigger.nginxModule",
|
||||||
|
"HTTP manager",
|
||||||
|
"Request body size trigger"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HttpAttachmentConfig::setFailOpenWaitMode()
|
HttpAttachmentConfig::setFailOpenWaitMode()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ private:
|
|||||||
|
|
||||||
void setDebugByContextValues();
|
void setDebugByContextValues();
|
||||||
|
|
||||||
|
void setRetriesForVerdict();
|
||||||
|
|
||||||
WebTriggerConf web_trigger_conf;
|
WebTriggerConf web_trigger_conf;
|
||||||
HttpAttachmentConfiguration conf_data;
|
HttpAttachmentConfiguration conf_data;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ isIpTrusted(const string &value, const vector<CIDRSData> &cidr_values)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Maybe<string>
|
Maybe<string>
|
||||||
UsersAllIdentifiersConfig::parseXForwardedFor(const string &str) const
|
UsersAllIdentifiersConfig::parseXForwardedFor(const string &str, ExtractType type) const
|
||||||
{
|
{
|
||||||
vector<string> header_values = split(str);
|
vector<string> header_values = split(str);
|
||||||
|
|
||||||
@@ -291,12 +291,23 @@ UsersAllIdentifiersConfig::parseXForwardedFor(const string &str) const
|
|||||||
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());
|
||||||
|
|
||||||
for (const string &value : header_values) {
|
for (auto it = header_values.rbegin(); it != header_values.rend() - 1; ++it) {
|
||||||
if (!IPAddr::createIPAddr(value).ok()) {
|
if (!IPAddr::createIPAddr(*it).ok()) {
|
||||||
dbgWarning(D_NGINX_ATTACHMENT_PARSER) << "Invalid IP address found in the xff header IPs list: " << value;
|
dbgWarning(D_NGINX_ATTACHMENT_PARSER) << "Invalid IP address found in the xff header IPs list: " << *it;
|
||||||
return genError("Invalid IP address");
|
return genError("Invalid IP address");
|
||||||
}
|
}
|
||||||
if (!isIpTrusted(value, cidr_values)) return genError("Untrusted Ip found");
|
if (type == ExtractType::PROXYIP) continue;
|
||||||
|
if (!isIpTrusted(*it, cidr_values)) {
|
||||||
|
dbgDebug(D_NGINX_ATTACHMENT_PARSER) << "Found untrusted IP in the xff header IPs list: " << *it;
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IPAddr::createIPAddr(header_values[0]).ok()) {
|
||||||
|
dbgWarning(D_NGINX_ATTACHMENT_PARSER)
|
||||||
|
<< "Invalid IP address found in the xff header IPs list: "
|
||||||
|
<< header_values[0];
|
||||||
|
return genError("Invalid IP address");
|
||||||
}
|
}
|
||||||
|
|
||||||
return header_values[0];
|
return header_values[0];
|
||||||
@@ -306,22 +317,28 @@ UsersAllIdentifiersConfig::parseXForwardedFor(const string &str) const
|
|||||||
void
|
void
|
||||||
UsersAllIdentifiersConfig::setXFFValuesToOpaqueCtx(const HttpHeader &header, ExtractType type) const
|
UsersAllIdentifiersConfig::setXFFValuesToOpaqueCtx(const HttpHeader &header, ExtractType type) const
|
||||||
{
|
{
|
||||||
auto value = parseXForwardedFor(header.getValue());
|
auto i_transaction_table = Singleton::Consume<I_TableSpecific<SessionID>>::by<NginxAttachment>();
|
||||||
|
if (!i_transaction_table || !i_transaction_table->hasState<NginxAttachmentOpaque>()) {
|
||||||
|
dbgTrace(D_NGINX_ATTACHMENT_PARSER) << "Can't get the transaction table";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NginxAttachmentOpaque &opaque = i_transaction_table->getState<NginxAttachmentOpaque>();
|
||||||
|
auto value = parseXForwardedFor(header.getValue(), type);
|
||||||
if (!value.ok()) {
|
if (!value.ok()) {
|
||||||
dbgTrace(D_NGINX_ATTACHMENT_PARSER) << "Could not extract source identifier from X-Forwarded-For header";
|
dbgTrace(D_NGINX_ATTACHMENT_PARSER) << "Could not extract source identifier from X-Forwarded-For header";
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
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>();
|
|
||||||
if (type == ExtractType::SOURCEIDENTIFIER) {
|
if (type == ExtractType::SOURCEIDENTIFIER) {
|
||||||
opaque.setSourceIdentifier(header.getKey(), value.unpack());
|
opaque.setSourceIdentifier(header.getKey(), value.unpack());
|
||||||
dbgDebug(D_NGINX_ATTACHMENT_PARSER)
|
dbgDebug(D_NGINX_ATTACHMENT_PARSER)
|
||||||
<< "Added source identifir to XFF "
|
<< "Added source identifier from XFF header"
|
||||||
<< value.unpack();
|
<< value.unpack();
|
||||||
|
opaque.setSavedData(HttpTransactionData::xff_vals_ctx, header.getValue());
|
||||||
|
opaque.setSavedData(HttpTransactionData::source_identifier, value.unpack());
|
||||||
|
dbgTrace(D_NGINX_ATTACHMENT_PARSER)
|
||||||
|
<< "XFF found, set ctx with value from header: "
|
||||||
|
<< static_cast<string>(header.getValue());
|
||||||
} else {
|
} else {
|
||||||
opaque.setSavedData(HttpTransactionData::proxy_ip_ctx, value.unpack());
|
opaque.setSavedData(HttpTransactionData::proxy_ip_ctx, value.unpack());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,137 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/assets_config.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
#include "generic_rulebase/generic_rulebase_utils.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "ip_utilities.h"
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
void
|
|
||||||
RuleAsset::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
archive_in(cereal::make_nvp("assetId", asset_id));
|
|
||||||
archive_in(cereal::make_nvp("assetName", asset_name));
|
|
||||||
archive_in(cereal::make_nvp("assetUrls", asset_urls));
|
|
||||||
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Adding asset with UID: " << asset_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RuleAsset::AssetUrl::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
archive_in(cereal::make_nvp("protocol", protocol));
|
|
||||||
transform(protocol.begin(), protocol.end(), protocol.begin(), [](unsigned char c) { return tolower(c); });
|
|
||||||
|
|
||||||
archive_in(cereal::make_nvp("ip", ip));
|
|
||||||
archive_in(cereal::make_nvp("port", port));
|
|
||||||
|
|
||||||
int value;
|
|
||||||
if (protocol == "*") {
|
|
||||||
is_any_proto = true;
|
|
||||||
} else {
|
|
||||||
is_any_proto = false;
|
|
||||||
try {
|
|
||||||
value = 0;
|
|
||||||
if(protocol == "udp") value = IPPROTO_UDP;
|
|
||||||
if(protocol == "tcp") value = IPPROTO_TCP;
|
|
||||||
if(protocol == "dccp") value = IPPROTO_DCCP;
|
|
||||||
if(protocol == "sctp") value = IPPROTO_SCTP;
|
|
||||||
if(protocol == "icmp") value = IPPROTO_ICMP;
|
|
||||||
if(protocol == "icmpv6") value = IPPROTO_ICMP;
|
|
||||||
|
|
||||||
if (value > static_cast<int>(UINT8_MAX) || value < 0) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG)
|
|
||||||
<< "provided value is not a legal IP protocol number. Value: "
|
|
||||||
<< protocol;
|
|
||||||
} else {
|
|
||||||
parsed_proto = value;
|
|
||||||
}
|
|
||||||
} catch (...) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "provided value is not a legal IP protocol. Value: " << protocol;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port == "*") {
|
|
||||||
is_any_port = true;
|
|
||||||
} else {
|
|
||||||
is_any_port = false;
|
|
||||||
try {
|
|
||||||
value = stoi(port);
|
|
||||||
if (value > static_cast<int>(UINT16_MAX) || value < 0) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "provided value is not a legal port number. Value: " << port;
|
|
||||||
} else {
|
|
||||||
parsed_port = value;
|
|
||||||
}
|
|
||||||
} catch (...) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "provided value is not a legal port. Value: " << port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ip == "*") {
|
|
||||||
is_any_ip = true;
|
|
||||||
} else {
|
|
||||||
is_any_ip = false;
|
|
||||||
auto ip_addr = IPAddr::createIPAddr(ip);
|
|
||||||
if (!ip_addr.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Could not create IP address. Error: " << ip_addr.getErr();
|
|
||||||
} else {
|
|
||||||
parsed_ip = ConvertToIpAddress(ip_addr.unpackMove());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IpAddress
|
|
||||||
RuleAsset::AssetUrl::ConvertToIpAddress(const IPAddr &addr)
|
|
||||||
{
|
|
||||||
IpAddress address;
|
|
||||||
switch (addr.getType()) {
|
|
||||||
case IPType::UNINITIALIZED: {
|
|
||||||
address.addr4_t = {0};
|
|
||||||
address.ip_type = IP_VERSION_ANY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IPType::V4: {
|
|
||||||
address.addr4_t = addr.getIPv4();
|
|
||||||
address.ip_type = IP_VERSION_4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IPType::V6: {
|
|
||||||
address.addr6_t = addr.getIPv6();
|
|
||||||
address.ip_type = IP_VERSION_6;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
address.addr4_t = {0};
|
|
||||||
address.ip_type = IP_VERSION_ANY;
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Unsupported IP type: " << static_cast<int>(addr.getType());
|
|
||||||
}
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Assets Assets::empty_assets_config = Assets();
|
|
||||||
|
|
||||||
void
|
|
||||||
Assets::preload()
|
|
||||||
{
|
|
||||||
registerExpectedSetting<Assets>("rulebase", "usedAssets");
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/evaluators/asset_eval.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "generic_rulebase/assets_config.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
string AssetMatcher::ctx_key = "asset_id";
|
|
||||||
|
|
||||||
AssetMatcher::AssetMatcher(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != 1) reportWrongNumberOfParams(AssetMatcher::getName(), params.size(), 1, 1);
|
|
||||||
asset_id = params[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
AssetMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<AssetMatcher>();
|
|
||||||
auto bc_asset_id_ctx = env->get<GenericConfigId>(AssetMatcher::ctx_key);
|
|
||||||
|
|
||||||
if (bc_asset_id_ctx.ok()) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG)
|
|
||||||
<< "Asset ID: "
|
|
||||||
<< asset_id
|
|
||||||
<< "; Current set assetId context: "
|
|
||||||
<< *bc_asset_id_ctx;
|
|
||||||
} else {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Asset ID: " << asset_id << ". Empty context";
|
|
||||||
}
|
|
||||||
|
|
||||||
return bc_asset_id_ctx.ok() && *bc_asset_id_ctx == asset_id;
|
|
||||||
}
|
|
||||||
@@ -1,299 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/evaluators/connection_eval.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "generic_rulebase/rulebase_config.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "ip_utilities.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
string IpAddressMatcher::ctx_key = "ipAddress";
|
|
||||||
string SourceIpMatcher::ctx_key = "sourceIP";
|
|
||||||
string DestinationIpMatcher::ctx_key = "destinationIP";
|
|
||||||
string SourcePortMatcher::ctx_key = "sourcePort";
|
|
||||||
string ListeningPortMatcher::ctx_key = "listeningPort";
|
|
||||||
string IpProtocolMatcher::ctx_key = "ipProtocol";
|
|
||||||
string UrlMatcher::ctx_key = "url";
|
|
||||||
|
|
||||||
Maybe<IPAddr>
|
|
||||||
getIpAddrFromEnviroment(I_Environment *env, Context::MetaDataType enum_data_type, const string &str_data_type)
|
|
||||||
{
|
|
||||||
auto ip_str = env->get<string>(enum_data_type);
|
|
||||||
if (!ip_str.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to get " << str_data_type << " from the enviroment.";
|
|
||||||
return genError("Failed to get " + str_data_type + " from the enviroment.");
|
|
||||||
}
|
|
||||||
return IPAddr::createIPAddr(ip_str.unpack());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
checkIfIpInRangesVec(const vector<CustomRange<IPAddr>> &values, const IPAddr &ip_to_check)
|
|
||||||
{
|
|
||||||
if (values.size() == 0) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Ip addersses vector empty. Match is true.";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (const CustomRange<IPAddr> &range : values) {
|
|
||||||
if (range.contains(ip_to_check)) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Ip adderss matched: " << ip_to_check;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Ip adderss not match: " << ip_to_check;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
IpAddressMatcher::IpAddressMatcher(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
for (const string ¶m : params) {
|
|
||||||
Maybe<CustomRange<IPAddr>> ip_range = CustomRange<IPAddr>::createRange(param);
|
|
||||||
if (!ip_range.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to create ip. Error: " + ip_range.getErr();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
values.push_back(ip_range.unpack());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
IpAddressMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<IpAddressMatcher>();
|
|
||||||
Maybe<IPAddr> subject_ip = getIpAddrFromEnviroment(
|
|
||||||
env,
|
|
||||||
Context::MetaDataType::SubjectIpAddr,
|
|
||||||
"subject ip address"
|
|
||||||
);
|
|
||||||
if (subject_ip.ok() && checkIfIpInRangesVec(values, subject_ip.unpack())) return true;
|
|
||||||
|
|
||||||
Maybe<IPAddr> other_ip = getIpAddrFromEnviroment(
|
|
||||||
env,
|
|
||||||
Context::MetaDataType::OtherIpAddr,
|
|
||||||
"other ip address"
|
|
||||||
);
|
|
||||||
if (other_ip.ok() && checkIfIpInRangesVec(values, other_ip.unpack())) return true;
|
|
||||||
if (!subject_ip.ok() && !other_ip.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Error in getting subject ip and other ip from the enviroment";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Ip adderss didn't match";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SourceIpMatcher::SourceIpMatcher(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
for (const string ¶m : params) {
|
|
||||||
Maybe<CustomRange<IPAddr>> ip_range = CustomRange<IPAddr>::createRange(param);
|
|
||||||
if (!ip_range.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to create source ip. Error: " + ip_range.getErr();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
values.push_back(ip_range.unpack());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
SourceIpMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<SourceIpMatcher>();
|
|
||||||
auto direction_maybe = env->get<string>(Context::MetaDataType::Direction);
|
|
||||||
if (!direction_maybe.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to get direction from the enviroment.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
string direction = direction_maybe.unpack();
|
|
||||||
if (direction == "incoming") {
|
|
||||||
Maybe<IPAddr> other_ip = getIpAddrFromEnviroment(
|
|
||||||
env,
|
|
||||||
Context::MetaDataType::OtherIpAddr,
|
|
||||||
"other ip address"
|
|
||||||
);
|
|
||||||
return other_ip.ok() && checkIfIpInRangesVec(values, other_ip.unpack());
|
|
||||||
} else if (direction == "outgoing") {
|
|
||||||
Maybe<IPAddr> subject_ip = getIpAddrFromEnviroment(
|
|
||||||
env,
|
|
||||||
Context::MetaDataType::SubjectIpAddr,
|
|
||||||
"subject ip address"
|
|
||||||
);
|
|
||||||
return subject_ip.ok() && checkIfIpInRangesVec(values, subject_ip.unpack());
|
|
||||||
}
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Source ip adderss didn't match";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DestinationIpMatcher::DestinationIpMatcher(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
for (const string ¶m : params) {
|
|
||||||
Maybe<CustomRange<IPAddr>> ip_range = CustomRange<IPAddr>::createRange(param);
|
|
||||||
if (!ip_range.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to create destination ip. Error: " + ip_range.getErr();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
values.push_back(ip_range.unpack());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
DestinationIpMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<DestinationIpMatcher>();
|
|
||||||
auto direction_maybe = env->get<string>(Context::MetaDataType::Direction);
|
|
||||||
if (!direction_maybe.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to get direction.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
string direction = direction_maybe.unpack();
|
|
||||||
if (direction == "outgoing") {
|
|
||||||
Maybe<IPAddr> other_ip = getIpAddrFromEnviroment(
|
|
||||||
env,
|
|
||||||
Context::MetaDataType::OtherIpAddr,
|
|
||||||
"other ip address"
|
|
||||||
);
|
|
||||||
return other_ip.ok() && checkIfIpInRangesVec(values, other_ip.unpack());
|
|
||||||
} else if (direction == "incoming") {
|
|
||||||
Maybe<IPAddr> subject_ip = getIpAddrFromEnviroment(
|
|
||||||
env,
|
|
||||||
Context::MetaDataType::SubjectIpAddr,
|
|
||||||
"subject ip address"
|
|
||||||
);
|
|
||||||
return subject_ip.ok() && checkIfIpInRangesVec(values, subject_ip.unpack());
|
|
||||||
}
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Destination ip adderss didn't match";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SourcePortMatcher::SourcePortMatcher(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
for (const string ¶m : params) {
|
|
||||||
Maybe<CustomRange<PortNumber>> port_range = CustomRange<PortNumber>::createRange(param);
|
|
||||||
if (!port_range.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to create source port.";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
values.push_back(port_range.unpack());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
SourcePortMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Source is not a match";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ListeningPortMatcher::ListeningPortMatcher(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
for (const string ¶m : params) {
|
|
||||||
Maybe<CustomRange<PortNumber>> port_range = CustomRange<PortNumber>::createRange(param);
|
|
||||||
if (!port_range.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to create listening port range.";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
values.push_back(port_range.unpack());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
ListeningPortMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<ListeningPortMatcher>();
|
|
||||||
auto port_str = env->get<string>(Context::MetaDataType::Port);
|
|
||||||
if (!port_str.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to get port from the enviroment.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
PortNumber port;
|
|
||||||
if (ConnKeyUtil::fromString(port_str.unpack(), port)) {
|
|
||||||
if (values.size() == 0) return true;
|
|
||||||
for (const CustomRange<PortNumber> &port_range : values) {
|
|
||||||
if (port_range.contains(port)) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Listening port is a match. Value: " << port_str.unpack();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Listening port is not a match. Value: " << port_str.unpack();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
IpProtocolMatcher::IpProtocolMatcher(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
for (const string ¶m : params) {
|
|
||||||
Maybe<CustomRange<IPProto>> proto_range = CustomRange<IPProto>::createRange(param);
|
|
||||||
if (!proto_range.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to create ip protocol.";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
values.push_back(proto_range.unpack());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
IpProtocolMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<IpProtocolMatcher>();
|
|
||||||
auto proto_str = env->get<string>(Context::MetaDataType::Protocol);
|
|
||||||
if (!proto_str.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to get ip protocol from the enviroment.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
IPProto protocol;
|
|
||||||
if (ConnKeyUtil::fromString(proto_str.unpack(), protocol)) {
|
|
||||||
if (values.size() == 0) return true;
|
|
||||||
for (const CustomRange<IPProto> &proto_range : values) {
|
|
||||||
if (proto_range.contains(protocol)) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Ip protocol is a match. Value: " << proto_str.unpack();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Source port is not a match. Value: " << proto_str.unpack();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
UrlMatcher::UrlMatcher(const vector<string> ¶ms) : values(params) {}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
UrlMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<UrlMatcher>();
|
|
||||||
auto curr_url_ctx = env->get<string>(Context::MetaDataType::Url);
|
|
||||||
if (!curr_url_ctx.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to get URL from the enviroment.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (values.size() == 0) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Matched URL on \"any\". Url: " << *curr_url_ctx;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const string &url : values) {
|
|
||||||
if (*curr_url_ctx == url) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Matched URL. Value: " << *curr_url_ctx;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "URL is not a match. Value: " << *curr_url_ctx;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/evaluators/http_transaction_data_eval.h"
|
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "http_transaction_data.h"
|
|
||||||
#include "environment/evaluator_templates.h"
|
|
||||||
#include "i_environment.h"
|
|
||||||
#include "singleton.h"
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace EnvironmentHelper;
|
|
||||||
|
|
||||||
EqualHost::EqualHost(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != 1) reportWrongNumberOfParams("EqualHost", params.size(), 1, 1);
|
|
||||||
host = params[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
EqualHost::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<EqualHost>();
|
|
||||||
auto host_ctx = env->get<string>(HttpTransactionData::host_name_ctx);
|
|
||||||
|
|
||||||
if (!host_ctx.ok())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string lower_host_ctx = host_ctx.unpack();
|
|
||||||
std::transform(lower_host_ctx.begin(), lower_host_ctx.end(), lower_host_ctx.begin(), ::tolower);
|
|
||||||
|
|
||||||
std::string lower_host = host;
|
|
||||||
std::transform(lower_host.begin(), lower_host.end(), lower_host.begin(), ::tolower);
|
|
||||||
|
|
||||||
|
|
||||||
if (lower_host_ctx == lower_host) return true;
|
|
||||||
size_t pos = lower_host_ctx.find_last_of(':');
|
|
||||||
if (pos == string::npos) return false;
|
|
||||||
lower_host_ctx = string(lower_host_ctx.data(), pos);
|
|
||||||
return lower_host_ctx == lower_host;
|
|
||||||
}
|
|
||||||
|
|
||||||
WildcardHost::WildcardHost(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != 1) reportWrongNumberOfParams("WildcardHost", params.size(), 1, 1);
|
|
||||||
host = params[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
WildcardHost::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<WildcardHost>();
|
|
||||||
auto host_ctx = env->get<string>(HttpTransactionData::host_name_ctx);
|
|
||||||
|
|
||||||
if (!host_ctx.ok())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string lower_host_ctx = host_ctx.unpack();
|
|
||||||
transform(lower_host_ctx.begin(), lower_host_ctx.end(), lower_host_ctx.begin(), ::tolower);
|
|
||||||
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "found host in current context: " << lower_host_ctx;
|
|
||||||
|
|
||||||
size_t pos = lower_host_ctx.find_first_of(".");
|
|
||||||
if (pos == string::npos) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lower_host_ctx = "*" + lower_host_ctx.substr(pos, lower_host_ctx.length());
|
|
||||||
|
|
||||||
string lower_host = host;
|
|
||||||
transform(lower_host.begin(), lower_host.end(), lower_host.begin(), ::tolower);
|
|
||||||
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG)
|
|
||||||
<< "trying to match host context with its corresponding wildcard address: "
|
|
||||||
<< lower_host_ctx
|
|
||||||
<< ". Matcher host: "
|
|
||||||
<< lower_host;
|
|
||||||
|
|
||||||
if (lower_host_ctx == lower_host) return true;
|
|
||||||
pos = lower_host_ctx.find_last_of(':');
|
|
||||||
if (pos == string::npos) return false;
|
|
||||||
lower_host_ctx = string(lower_host_ctx.data(), pos);
|
|
||||||
return lower_host_ctx == lower_host;
|
|
||||||
}
|
|
||||||
|
|
||||||
EqualListeningIP::EqualListeningIP(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != 1) reportWrongNumberOfParams("EqualListeningIP", params.size(), 1, 1);
|
|
||||||
|
|
||||||
auto maybe_ip = IPAddr::createIPAddr(params[0]);
|
|
||||||
if (!maybe_ip.ok()) reportWrongParamType(getName(), params[0], "Not a valid IP Address");
|
|
||||||
|
|
||||||
listening_ip = maybe_ip.unpack();
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
EqualListeningIP::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<EqualListeningIP>();
|
|
||||||
auto listening_ip_ctx = env->get<IPAddr>(HttpTransactionData::listening_ip_ctx);
|
|
||||||
return listening_ip_ctx.ok() && listening_ip_ctx.unpack() == listening_ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
EqualListeningPort::EqualListeningPort(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != 1) reportWrongNumberOfParams("EqualListeningPort", params.size(), 1, 1);
|
|
||||||
|
|
||||||
try {
|
|
||||||
listening_port = boost::lexical_cast<PortNumber>(params[0]);
|
|
||||||
} catch (boost::bad_lexical_cast const&) {
|
|
||||||
reportWrongParamType(getName(), params[0], "Not a valid port number");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
EqualListeningPort::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<EqualListeningPort>();
|
|
||||||
auto port_ctx = env->get<PortNumber>(HttpTransactionData::listening_port_ctx);
|
|
||||||
|
|
||||||
return port_ctx.ok() && port_ctx.unpack() == listening_port;
|
|
||||||
}
|
|
||||||
|
|
||||||
BeginWithUri::BeginWithUri(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != 1) reportWrongNumberOfParams("BeginWithUri", params.size(), 1, 1);
|
|
||||||
uri_prefix = params[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
BeginWithUri::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<BeginWithUri>();
|
|
||||||
auto uri_ctx = env->get<string>(HttpTransactionData::uri_ctx);
|
|
||||||
|
|
||||||
if (!uri_ctx.ok())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string lower_uri_ctx = uri_ctx.unpack();
|
|
||||||
std::transform(lower_uri_ctx.begin(), lower_uri_ctx.end(), lower_uri_ctx.begin(), ::tolower);
|
|
||||||
|
|
||||||
std::string lower_uri_prefix = uri_prefix;
|
|
||||||
std::transform(lower_uri_prefix.begin(), lower_uri_prefix.end(), lower_uri_prefix.begin(), ::tolower);
|
|
||||||
|
|
||||||
return lower_uri_ctx.find(lower_uri_prefix) == 0;
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/evaluators/parameter_eval.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "generic_rulebase/rulebase_config.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
string ParameterMatcher::ctx_key = "parameters";
|
|
||||||
|
|
||||||
ParameterMatcher::ParameterMatcher(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != 1) reportWrongNumberOfParams(ParameterMatcher::getName(), params.size(), 1, 1);
|
|
||||||
parameter_id = params[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
ParameterMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
auto rule = getConfiguration<BasicRuleConfig>("rulebase", "rulesConfig");
|
|
||||||
return rule.ok() && rule.unpack().isParameterActive(parameter_id);
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/evaluators/practice_eval.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "generic_rulebase/rulebase_config.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
string PracticeMatcher::ctx_key = "practices";
|
|
||||||
|
|
||||||
PracticeMatcher::PracticeMatcher(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != 1) reportWrongNumberOfParams(PracticeMatcher::getName(), params.size(), 1, 1);
|
|
||||||
practice_id = params[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
PracticeMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<PracticeMatcher>();
|
|
||||||
auto bc_practice_id_ctx = env->get<set<GenericConfigId>>(PracticeMatcher::ctx_key);
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG)
|
|
||||||
<< "Trying to match practice. ID: "
|
|
||||||
<< practice_id << ", Current set IDs: "
|
|
||||||
<< makeSeparatedStr(bc_practice_id_ctx.ok() ? *bc_practice_id_ctx : set<GenericConfigId>(), ", ");
|
|
||||||
if (bc_practice_id_ctx.ok()) {
|
|
||||||
return bc_practice_id_ctx.unpack().count(practice_id) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto rule = getConfiguration<BasicRuleConfig>("rulebase", "rulesConfig");
|
|
||||||
return rule.ok() && rule.unpack().isPracticeActive(practice_id);
|
|
||||||
}
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/evaluators/query_eval.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "generic_rulebase/rulebase_config.h"
|
|
||||||
#include "generic_rulebase/zones_config.h"
|
|
||||||
#include "i_environment.h"
|
|
||||||
#include "singleton.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "enum_range.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
QueryMatcher::QueryMatcher(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() < 1) reportWrongNumberOfParams(QueryMatcher::getName(), params.size(), 1);
|
|
||||||
|
|
||||||
key = params.front();
|
|
||||||
if (key == "any") {
|
|
||||||
is_any = true;
|
|
||||||
} else {
|
|
||||||
values.reserve(params.size() - 1);
|
|
||||||
for (uint i = 1; i < params.size() ; i++) {
|
|
||||||
if (params[i] == "any") {
|
|
||||||
values.clear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
values.insert(params[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const string
|
|
||||||
QueryMatcher::contextKeyToString(Context::MetaDataType type)
|
|
||||||
{
|
|
||||||
if (type == Context::MetaDataType::SubjectIpAddr || type == Context::MetaDataType::OtherIpAddr) return "ip";
|
|
||||||
return Context::convertToString(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
class QueryMatchSerializer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static const string req_attr_ctx_key;
|
|
||||||
|
|
||||||
template <typename Archive>
|
|
||||||
void
|
|
||||||
serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<QueryMatcher>();
|
|
||||||
auto req_attr = env->get<string>(req_attr_ctx_key);
|
|
||||||
if (!req_attr.ok()) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
ar(cereal::make_nvp(*req_attr, value));
|
|
||||||
dbgDebug(D_RULEBASE_CONFIG)
|
|
||||||
<< "Found value for requested attribute. Tag: "
|
|
||||||
<< *req_attr
|
|
||||||
<< ", Value: "
|
|
||||||
<< value;
|
|
||||||
} catch (exception &e) {
|
|
||||||
dbgDebug(D_RULEBASE_CONFIG) << "Could not find values for requested attribute. Tag: " << *req_attr;
|
|
||||||
ar.finishNode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Values>
|
|
||||||
bool
|
|
||||||
matchValues(const Values &requested_vals) const
|
|
||||||
{
|
|
||||||
return value != "" && (requested_vals.empty() || requested_vals.count(value) > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
string value;
|
|
||||||
};
|
|
||||||
|
|
||||||
const string QueryMatchSerializer::req_attr_ctx_key = "requested attribute key";
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
QueryMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
if (is_any) return true;
|
|
||||||
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<QueryMatcher>();
|
|
||||||
auto local_asset_ctx = env->get<bool>("is local asset");
|
|
||||||
bool is_remote_asset = local_asset_ctx.ok() && !(*local_asset_ctx);
|
|
||||||
|
|
||||||
QueryRequest request;
|
|
||||||
for (Context::MetaDataType name : makeRange<Context::MetaDataType>()) {
|
|
||||||
auto val = env->get<string>(name);
|
|
||||||
if (val.ok()) {
|
|
||||||
if ((name == Context::MetaDataType::SubjectIpAddr && is_remote_asset) ||
|
|
||||||
(name == Context::MetaDataType::OtherIpAddr && !is_remote_asset)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
request.addCondition(Condition::EQUALS, contextKeyToString(name), *val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request.empty()) return false;
|
|
||||||
|
|
||||||
request.setRequestedAttr(key);
|
|
||||||
ScopedContext req_attr_key;
|
|
||||||
req_attr_key.registerValue<string>(QueryMatchSerializer::req_attr_ctx_key, key);
|
|
||||||
|
|
||||||
I_Intelligence_IS_V2 *intelligence = Singleton::Consume<I_Intelligence_IS_V2>::by<Zone>();
|
|
||||||
auto query_res = intelligence->queryIntelligence<QueryMatchSerializer>(request);
|
|
||||||
if (!query_res.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to perform intelligence query. Error: " << query_res.getErr();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const AssetReply<QueryMatchSerializer> &asset : query_res.unpack()) {
|
|
||||||
if (asset.matchValues<unordered_set<string>>(values)) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/evaluators/trigger_eval.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "generic_rulebase/rulebase_config.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
string TriggerMatcher::ctx_key = "triggers";
|
|
||||||
|
|
||||||
TriggerMatcher::TriggerMatcher(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != 1) reportWrongNumberOfParams(TriggerMatcher::getName(), params.size(), 1, 1);
|
|
||||||
trigger_id = params[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
TriggerMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<TriggerMatcher>();
|
|
||||||
auto ac_bc_trigger_id_ctx = env->get<set<GenericConfigId>>("ac_trigger_id");
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG)
|
|
||||||
<< "Trying to match trigger for access control rule. ID: "
|
|
||||||
<< trigger_id << ", Current set IDs: "
|
|
||||||
<< makeSeparatedStr(ac_bc_trigger_id_ctx.ok() ? *ac_bc_trigger_id_ctx : set<GenericConfigId>(), ", ");
|
|
||||||
if (ac_bc_trigger_id_ctx.ok()) {
|
|
||||||
return ac_bc_trigger_id_ctx.unpack().count(trigger_id) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto bc_trigger_id_ctx = env->get<set<GenericConfigId>>(TriggerMatcher::ctx_key);
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG)
|
|
||||||
<< "Trying to match trigger. ID: "
|
|
||||||
<< trigger_id << ", Current set IDs: "
|
|
||||||
<< makeSeparatedStr(bc_trigger_id_ctx.ok() ? *bc_trigger_id_ctx : set<GenericConfigId>(), ", ");
|
|
||||||
if (bc_trigger_id_ctx.ok() && bc_trigger_id_ctx.unpack().count(trigger_id) > 0 ) return true;
|
|
||||||
|
|
||||||
auto rule = getConfiguration<BasicRuleConfig>("rulebase", "rulesConfig");
|
|
||||||
return rule.ok() && rule.unpack().isTriggerActive(trigger_id);
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/evaluators/zone_eval.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "generic_rulebase/zone.h"
|
|
||||||
#include "generic_rulebase/rulebase_config.h"
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
string ZoneMatcher::ctx_key = "zone_id";
|
|
||||||
|
|
||||||
ZoneMatcher::ZoneMatcher(const vector<string> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != 1) reportWrongNumberOfParams(ZoneMatcher::getName(), params.size(), 1, 1);
|
|
||||||
zone_id = params[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<bool, Context::Error>
|
|
||||||
ZoneMatcher::evalVariable() const
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<ZoneMatcher>();
|
|
||||||
auto bc_zone_id_ctx = env->get<GenericConfigId>(ZoneMatcher::ctx_key);
|
|
||||||
if (bc_zone_id_ctx.ok() && *bc_zone_id_ctx == zone_id) return true;
|
|
||||||
|
|
||||||
if (!getProfileAgentSettingWithDefault<bool>(false, "rulebase.enableQueryBasedMatch")) return false;
|
|
||||||
|
|
||||||
auto zone = getConfiguration<Zone>("rulebase", "zones");
|
|
||||||
return zone.ok() && zone.unpack().getId() == zone_id;
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/generic_rulebase.h"
|
|
||||||
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
#include "generic_rulebase/evaluators/trigger_eval.h"
|
|
||||||
#include "generic_rulebase/evaluators/practice_eval.h"
|
|
||||||
#include "generic_rulebase/evaluators/parameter_eval.h"
|
|
||||||
#include "generic_rulebase/evaluators/zone_eval.h"
|
|
||||||
#include "generic_rulebase/evaluators/asset_eval.h"
|
|
||||||
#include "generic_rulebase/evaluators/query_eval.h"
|
|
||||||
#include "generic_rulebase/evaluators/connection_eval.h"
|
|
||||||
#include "generic_rulebase/evaluators/http_transaction_data_eval.h"
|
|
||||||
#include "generic_rulebase/zone.h"
|
|
||||||
#include "generic_rulebase/triggers_config.h"
|
|
||||||
#include "singleton.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "cache.h"
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
class GenericRulebase::Impl : Singleton::Provide<I_GenericRulebase>::From<GenericRulebase>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void init() {}
|
|
||||||
void fini() {}
|
|
||||||
|
|
||||||
void preload();
|
|
||||||
|
|
||||||
Maybe<Zone, Config::Errors> getLocalZone() const override { return getZoneConfig(true); }
|
|
||||||
Maybe<Zone, Config::Errors> getOtherZone() const override { return getZoneConfig(false); }
|
|
||||||
|
|
||||||
set<ParameterBehavior> getBehavior(const ParameterKeyValues &key_value_pairs) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Maybe<Zone, Config::Errors>
|
|
||||||
getZoneConfig(bool is_local_zone) const
|
|
||||||
{
|
|
||||||
ScopedContext asset_location_ctx;
|
|
||||||
asset_location_ctx.registerValue<bool>("is local asset", is_local_zone);
|
|
||||||
return getConfiguration<Zone>("rulebase", "zones");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
GenericRulebase::Impl::preload()
|
|
||||||
{
|
|
||||||
addMatcher<TriggerMatcher>();
|
|
||||||
addMatcher<PracticeMatcher>();
|
|
||||||
addMatcher<ParameterMatcher>();
|
|
||||||
addMatcher<ZoneMatcher>();
|
|
||||||
addMatcher<AssetMatcher>();
|
|
||||||
addMatcher<QueryMatcher>();
|
|
||||||
addMatcher<IpAddressMatcher>();
|
|
||||||
addMatcher<SourceIpMatcher>();
|
|
||||||
addMatcher<DestinationIpMatcher>();
|
|
||||||
addMatcher<SourcePortMatcher>();
|
|
||||||
addMatcher<ListeningPortMatcher>();
|
|
||||||
addMatcher<IpProtocolMatcher>();
|
|
||||||
addMatcher<UrlMatcher>();
|
|
||||||
addMatcher<EqualHost>();
|
|
||||||
addMatcher<WildcardHost>();
|
|
||||||
addMatcher<EqualListeningIP>();
|
|
||||||
addMatcher<EqualListeningPort>();
|
|
||||||
addMatcher<BeginWithUri>();
|
|
||||||
BasicRuleConfig::preload();
|
|
||||||
LogTriggerConf::preload();
|
|
||||||
ParameterException::preload();
|
|
||||||
registerExpectedConfiguration<Zone>("rulebase", "zones");
|
|
||||||
registerExpectedConfigFile("zones", Config::ConfigFileType::Policy);
|
|
||||||
registerExpectedConfigFile("triggers", Config::ConfigFileType::Policy);
|
|
||||||
registerExpectedConfigFile("rules", Config::ConfigFileType::Policy);
|
|
||||||
registerExpectedConfigFile("parameters", Config::ConfigFileType::Policy);
|
|
||||||
registerExpectedConfigFile("exceptions", Config::ConfigFileType::Policy);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
set<ParameterBehavior>
|
|
||||||
GenericRulebase::Impl::getBehavior(const ParameterKeyValues &key_value_pairs) const
|
|
||||||
{
|
|
||||||
auto &exceptions = getConfiguration<ParameterException>("rulebase", "exception");
|
|
||||||
|
|
||||||
if (!exceptions.ok()) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Could not find any exception with the current rule's context";
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return (*exceptions).getBehavior(key_value_pairs);
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericRulebase::GenericRulebase() : Component("GenericRulebase"), pimpl(make_unique<Impl>()) {}
|
|
||||||
|
|
||||||
GenericRulebase::~GenericRulebase() {}
|
|
||||||
|
|
||||||
void
|
|
||||||
GenericRulebase::init()
|
|
||||||
{
|
|
||||||
pimpl->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
GenericRulebase::fini()
|
|
||||||
{
|
|
||||||
pimpl->fini();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
GenericRulebase::preload()
|
|
||||||
{
|
|
||||||
pimpl->preload();
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/generic_rulebase_context.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "context.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "generic_rulebase/evaluators/trigger_eval.h"
|
|
||||||
#include "generic_rulebase/evaluators/parameter_eval.h"
|
|
||||||
#include "generic_rulebase/evaluators/practice_eval.h"
|
|
||||||
#include "generic_rulebase/evaluators/zone_eval.h"
|
|
||||||
#include "generic_rulebase/evaluators/asset_eval.h"
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
template<typename Configs>
|
|
||||||
set<GenericConfigId>
|
|
||||||
extractIds(const vector<Configs> &configurations)
|
|
||||||
{
|
|
||||||
set<GenericConfigId> ids;
|
|
||||||
for (const Configs &conf : configurations) {
|
|
||||||
ids.insert(conf.getId());
|
|
||||||
}
|
|
||||||
return ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
GenericRulebaseContext::activate(const BasicRuleConfig &rule)
|
|
||||||
{
|
|
||||||
switch(registration_state) {
|
|
||||||
case RuleRegistrationState::UNINITIALIZED: {
|
|
||||||
registration_state = RuleRegistrationState::REGISTERED;
|
|
||||||
ctx.registerValue<set<GenericConfigId>>(
|
|
||||||
TriggerMatcher::ctx_key,
|
|
||||||
extractIds<RuleTrigger>(rule.getTriggers())
|
|
||||||
);
|
|
||||||
ctx.registerValue<set<GenericConfigId>>(
|
|
||||||
PracticeMatcher::ctx_key,
|
|
||||||
extractIds<RulePractice>(rule.getPractices())
|
|
||||||
);
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG)
|
|
||||||
<< "Activating current practices. Current practice IDs: "
|
|
||||||
<< makeSeparatedStr(extractIds<RulePractice>(rule.getPractices()), ", ");
|
|
||||||
|
|
||||||
ctx.registerValue<set<GenericConfigId>>(
|
|
||||||
ParameterMatcher::ctx_key,
|
|
||||||
extractIds<RuleParameter>(rule.getParameters())
|
|
||||||
);
|
|
||||||
ctx.registerValue<GenericConfigId>(
|
|
||||||
ZoneMatcher::ctx_key,
|
|
||||||
rule.getZoneId()
|
|
||||||
);
|
|
||||||
ctx.registerValue<GenericConfigId>(
|
|
||||||
AssetMatcher::ctx_key,
|
|
||||||
rule.getAssetId()
|
|
||||||
);
|
|
||||||
ctx.activate();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RuleRegistrationState::REGISTERED: {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Activating registered rule values";
|
|
||||||
ctx.activate();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RuleRegistrationState::UNREGISTERED: {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Failed to register rule values";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
GenericRulebaseContext::activate()
|
|
||||||
{
|
|
||||||
switch(registration_state) {
|
|
||||||
case RuleRegistrationState::UNINITIALIZED: {
|
|
||||||
auto maybe_rule = getConfiguration<BasicRuleConfig>("rulebase", "rulesConfig");
|
|
||||||
if (!maybe_rule.ok()) {
|
|
||||||
registration_state = RuleRegistrationState::UNREGISTERED;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Registering new rule values";
|
|
||||||
activate(maybe_rule.unpack());
|
|
||||||
registration_state = RuleRegistrationState::REGISTERED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RuleRegistrationState::REGISTERED: {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Activating registered rule values";
|
|
||||||
ctx.activate();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RuleRegistrationState::UNREGISTERED: {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Failed to register rule values";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,347 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/match_query.h"
|
|
||||||
|
|
||||||
#include "cereal/types/set.hpp"
|
|
||||||
|
|
||||||
#include "generic_rulebase/generic_rulebase_utils.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "ip_utilities.h"
|
|
||||||
#include "agent_core_utilities.h"
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
static const unordered_map<string, MatchQuery::MatchType> string_to_match_type = {
|
|
||||||
{ "condition", MatchQuery::MatchType::Condition },
|
|
||||||
{ "operator", MatchQuery::MatchType::Operator }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unordered_map<string, MatchQuery::Operators> string_to_operator = {
|
|
||||||
{ "and", MatchQuery::Operators::And },
|
|
||||||
{ "or", MatchQuery::Operators::Or }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unordered_map<string, MatchQuery::Conditions> string_to_condition = {
|
|
||||||
{ "equals", MatchQuery::Conditions::Equals },
|
|
||||||
{ "not-equals", MatchQuery::Conditions::NotEquals },
|
|
||||||
{ "not equals", MatchQuery::Conditions::NotEquals },
|
|
||||||
{ "in", MatchQuery::Conditions::In },
|
|
||||||
{ "not-in", MatchQuery::Conditions::NotIn },
|
|
||||||
{ "not in", MatchQuery::Conditions::NotIn },
|
|
||||||
{ "exist", MatchQuery::Conditions::Exist }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const string ip_addr_type_name = "IP address";
|
|
||||||
static const string port_type_name = "port";
|
|
||||||
static const string ip_proto_type_name = "IP protocol";
|
|
||||||
|
|
||||||
static const unordered_map<string, MatchQuery::StaticKeys> string_to_key = {
|
|
||||||
{ "sourceIP", MatchQuery::StaticKeys::SrcIpAddress },
|
|
||||||
{ "sourceIpAddr", MatchQuery::StaticKeys::SrcIpAddress },
|
|
||||||
{ "destinationIP", MatchQuery::StaticKeys::DstIpAddress },
|
|
||||||
{ "destinationIpAddr", MatchQuery::StaticKeys::DstIpAddress },
|
|
||||||
{ "ipAddress", MatchQuery::StaticKeys::IpAddress },
|
|
||||||
{ "sourcePort", MatchQuery::StaticKeys::SrcPort },
|
|
||||||
{ "listeningPort", MatchQuery::StaticKeys::ListeningPort },
|
|
||||||
{ "ipProtocol", MatchQuery::StaticKeys::IpProtocol },
|
|
||||||
{ "domain", MatchQuery::StaticKeys::Domain }
|
|
||||||
};
|
|
||||||
|
|
||||||
MatchQuery::MatchQuery(const string &match) : is_specific_label(false), is_ignore_keyword(false)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
stringstream ss;
|
|
||||||
ss.str(match);
|
|
||||||
cereal::JSONInputArchive archive_in(ss);
|
|
||||||
load(archive_in);
|
|
||||||
} catch (const exception &e) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG)
|
|
||||||
<< "Unable to load match query JSON. JSON content: "
|
|
||||||
<< match
|
|
||||||
<< ", Error: "
|
|
||||||
<< e.what();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
MatchQuery::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
string type_as_string;
|
|
||||||
archive_in(cereal::make_nvp("type", type_as_string));
|
|
||||||
|
|
||||||
string op_as_string;
|
|
||||||
archive_in(cereal::make_nvp("op", op_as_string));
|
|
||||||
|
|
||||||
auto maybe_type = string_to_match_type.find(type_as_string);
|
|
||||||
if (maybe_type == string_to_match_type.end()) {
|
|
||||||
reportConfigurationError("Illegal Zone match query type. Provided type in configuration: " + type_as_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
type = maybe_type->second;
|
|
||||||
switch (type) {
|
|
||||||
case (MatchType::Condition): {
|
|
||||||
auto maybe_condition = string_to_condition.find(op_as_string);
|
|
||||||
if (maybe_condition == string_to_condition.end()) {
|
|
||||||
reportConfigurationError(
|
|
||||||
"Illegal op provided for condition. Provided op in configuration: " +
|
|
||||||
op_as_string
|
|
||||||
);
|
|
||||||
}
|
|
||||||
condition_type = maybe_condition->second;
|
|
||||||
operator_type = Operators::None;
|
|
||||||
archive_in(cereal::make_nvp("key", key));
|
|
||||||
key_type = getKeyByName(key);
|
|
||||||
if (key_type == StaticKeys::NotStatic) {
|
|
||||||
if (key.rfind("containerLabels.", 0) == 0) {
|
|
||||||
is_specific_label = true;
|
|
||||||
} else {
|
|
||||||
is_specific_label = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is_ignore_keyword = (key == "indicator");
|
|
||||||
|
|
||||||
if (condition_type != Conditions::Exist) {
|
|
||||||
archive_in(cereal::make_nvp("value", value));
|
|
||||||
for(const auto &val: value) {
|
|
||||||
if (isKeyTypeIp()) {
|
|
||||||
auto ip_range = IPUtilities::createRangeFromString<IPRange, IpAddress>(val, ip_addr_type_name);
|
|
||||||
if (ip_range.ok()) {
|
|
||||||
ip_addr_value.push_back(ip_range.unpack());
|
|
||||||
} else {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG)
|
|
||||||
<< "Failed to parse IP address range. Error: "
|
|
||||||
<< ip_range.getErr();
|
|
||||||
}
|
|
||||||
} else if (isKeyTypePort()) {
|
|
||||||
auto port_range = IPUtilities::createRangeFromString<PortsRange, uint16_t>(
|
|
||||||
val,
|
|
||||||
port_type_name
|
|
||||||
);
|
|
||||||
if (port_range.ok()) {
|
|
||||||
port_value.push_back(port_range.unpack());
|
|
||||||
} else {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG)
|
|
||||||
<< "Failed to parse port range. Error: "
|
|
||||||
<< port_range.getErr();
|
|
||||||
}
|
|
||||||
} else if (isKeyTypeProtocol()) {
|
|
||||||
auto proto_range = IPUtilities::createRangeFromString<IpProtoRange, uint8_t>(
|
|
||||||
val,
|
|
||||||
ip_proto_type_name
|
|
||||||
);
|
|
||||||
if (proto_range.ok()) {
|
|
||||||
ip_proto_value.push_back(proto_range.unpack());
|
|
||||||
} else {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG)
|
|
||||||
<< "Failed to parse IP protocol range. Error: "
|
|
||||||
<< proto_range.getErr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
regex_values.insert(boost::regex(val));
|
|
||||||
} catch (const exception &e) {
|
|
||||||
dbgDebug(D_RULEBASE_CONFIG) << "Failed to compile regex. Error: " << e.what();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
first_value = *(value.begin());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (MatchType::Operator): {
|
|
||||||
auto maybe_operator = string_to_operator.find(op_as_string);
|
|
||||||
if (maybe_operator == string_to_operator.end()) {
|
|
||||||
reportConfigurationError(
|
|
||||||
"Illegal op provided for operator. Provided op in configuration: " +
|
|
||||||
op_as_string
|
|
||||||
);
|
|
||||||
}
|
|
||||||
operator_type = maybe_operator->second;
|
|
||||||
condition_type = Conditions::None;
|
|
||||||
archive_in(cereal::make_nvp("items", items));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MatchQuery::StaticKeys
|
|
||||||
MatchQuery::getKeyByName(const string &key_type_name)
|
|
||||||
{
|
|
||||||
auto key = string_to_key.find(key_type_name);
|
|
||||||
if (key == string_to_key.end()) return StaticKeys::NotStatic;
|
|
||||||
return key->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
MatchQuery::isKeyTypeIp() const
|
|
||||||
{
|
|
||||||
return (key_type >= StaticKeys::IpAddress && key_type <= StaticKeys::DstIpAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
MatchQuery::isKeyTypePort() const
|
|
||||||
{
|
|
||||||
return (key_type == StaticKeys::SrcPort || key_type == StaticKeys::ListeningPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
MatchQuery::isKeyTypeProtocol() const
|
|
||||||
{
|
|
||||||
return (key_type == StaticKeys::IpProtocol);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
MatchQuery::isKeyTypeDomain() const
|
|
||||||
{
|
|
||||||
return (key_type == StaticKeys::Domain);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
MatchQuery::isKeyTypeSpecificLabel() const
|
|
||||||
{
|
|
||||||
return is_specific_label;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
MatchQuery::isKeyTypeStatic() const
|
|
||||||
{
|
|
||||||
return (key_type != StaticKeys::NotStatic);
|
|
||||||
}
|
|
||||||
|
|
||||||
set<string>
|
|
||||||
MatchQuery::getAllKeys() const
|
|
||||||
{
|
|
||||||
set<string> keys;
|
|
||||||
if (type == MatchType::Condition) {
|
|
||||||
if (!key.empty()) keys.insert(key);
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const MatchQuery &inner_match: items) {
|
|
||||||
set<string> iner_keys = inner_match.getAllKeys();
|
|
||||||
keys.insert(iner_keys.begin(), iner_keys.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
MatchQuery::matchAttributes(
|
|
||||||
const unordered_map<string, set<string>> &key_value_pairs,
|
|
||||||
set<string> &matched_override_keywords ) const
|
|
||||||
{
|
|
||||||
|
|
||||||
if (type == MatchType::Condition) {
|
|
||||||
auto key_value_pair = key_value_pairs.find(key);
|
|
||||||
if (key_value_pair == key_value_pairs.end()) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Ignoring irrelevant key: " << key;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return matchAttributes(key_value_pair->second, matched_override_keywords);
|
|
||||||
} else if (type == MatchType::Operator && operator_type == Operators::And) {
|
|
||||||
for (const MatchQuery &inner_match: items) {
|
|
||||||
if (!inner_match.matchAttributes(key_value_pairs, matched_override_keywords)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else if (type == MatchType::Operator && operator_type == Operators::Or) {
|
|
||||||
// With 'or' condition, evaluate matched override keywords first and add the ones that were fully matched
|
|
||||||
set<string> inner_override_keywords;
|
|
||||||
bool res = false;
|
|
||||||
for (const MatchQuery &inner_match: items) {
|
|
||||||
inner_override_keywords.clear();
|
|
||||||
if (inner_match.matchAttributes(key_value_pairs, inner_override_keywords)) {
|
|
||||||
matched_override_keywords.insert(inner_override_keywords.begin(), inner_override_keywords.end());
|
|
||||||
res = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
} else {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Unsupported match query type";
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MatchQuery::MatchResult
|
|
||||||
MatchQuery::getMatch( const unordered_map<string, set<string>> &key_value_pairs) const
|
|
||||||
{
|
|
||||||
MatchQuery::MatchResult matches;
|
|
||||||
matches.matched_keywords = make_shared<set<string>>();
|
|
||||||
matches.is_match = matchAttributes(key_value_pairs, *matches.matched_keywords);
|
|
||||||
return matches;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
MatchQuery::matchAttributes(
|
|
||||||
const unordered_map<string, set<string>> &key_value_pairs) const
|
|
||||||
{
|
|
||||||
return getMatch(key_value_pairs).is_match;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
MatchQuery::matchAttributes(
|
|
||||||
const set<string> &values,
|
|
||||||
set<string> &matched_override_keywords) const
|
|
||||||
{
|
|
||||||
auto &type = condition_type;
|
|
||||||
bool negate = type == MatchQuery::Conditions::NotEquals || type == MatchQuery::Conditions::NotIn;
|
|
||||||
bool match = isRegEx() ? matchAttributesRegEx(values, matched_override_keywords) : matchAttributesString(values);
|
|
||||||
return negate ? !match : match;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
MatchQuery::matchAttributesRegEx(
|
|
||||||
const set<string> &values,
|
|
||||||
set<string> &matched_override_keywords) const
|
|
||||||
{
|
|
||||||
bool res = false;
|
|
||||||
boost::cmatch value_matcher;
|
|
||||||
for (const boost::regex &val_regex : regex_values) {
|
|
||||||
for (const string &requested_match_value : values) {
|
|
||||||
if (NGEN::Regex::regexMatch(
|
|
||||||
__FILE__,
|
|
||||||
__LINE__,
|
|
||||||
requested_match_value.c_str(),
|
|
||||||
value_matcher,
|
|
||||||
val_regex))
|
|
||||||
{
|
|
||||||
res = true;
|
|
||||||
if (is_ignore_keyword) {
|
|
||||||
matched_override_keywords.insert(requested_match_value);
|
|
||||||
} else {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
MatchQuery::matchAttributesString(const set<string> &values) const
|
|
||||||
{
|
|
||||||
for (const string &requested_value : values) {
|
|
||||||
if (value.find(requested_value) != value.end()) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
MatchQuery::isRegEx() const
|
|
||||||
{
|
|
||||||
return key != "protectionName";
|
|
||||||
}
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/parameters_config.h"
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
bool ParameterException::is_geo_location_exception_exists(false);
|
|
||||||
bool ParameterException::is_geo_location_exception_being_loaded(false);
|
|
||||||
|
|
||||||
void
|
|
||||||
ParameterOverrides::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
parseJSONKey<vector<ParsedBehavior>>("parsedBehavior", parsed_behaviors, archive_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ParameterTrustedSources::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
parseJSONKey<uint>("numOfSources", num_of_sources, archive_in);
|
|
||||||
parseJSONKey<vector<SourcesIdentifier>>("sourcesIdentifiers", sources_identidiers, archive_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ParameterBehavior::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
string key_string;
|
|
||||||
string val_string;
|
|
||||||
parseJSONKey<string>("id", id, archive_in);
|
|
||||||
parseJSONKey<string>("key", key_string, archive_in);
|
|
||||||
parseJSONKey<string>("value", val_string, archive_in);
|
|
||||||
if (string_to_behavior_key.find(key_string) == string_to_behavior_key.end()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Unsupported behavior key: " << key_string;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
key = string_to_behavior_key.at(key_string);
|
|
||||||
|
|
||||||
if (string_to_behavior_val.find(val_string) == string_to_behavior_val.end()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Unsupported behavior value: " << val_string;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
value = string_to_behavior_val.at(val_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ParameterAntiBot::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
parseJSONKey<vector<string>>("injected", injected, archive_in);
|
|
||||||
parseJSONKey<vector<string>>("validated", validated, archive_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ParameterOAS::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
parseJSONKey<string>("value", value, archive_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ParameterException::MatchBehaviorPair::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
parseJSONKey<MatchQuery>("match", match, archive_in);
|
|
||||||
parseJSONKey<ParameterBehavior>("behavior", behavior, archive_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ParameterException::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
archive_in(
|
|
||||||
cereal::make_nvp("match", match),
|
|
||||||
cereal::make_nvp("behavior", behavior)
|
|
||||||
);
|
|
||||||
} catch (...) {
|
|
||||||
parseJSONKey<vector<MatchBehaviorPair>>("exceptions", match_queries, archive_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
function<bool(const MatchQuery &)> isGeoLocationExists =
|
|
||||||
[&](const MatchQuery &query)
|
|
||||||
{
|
|
||||||
if (query.getKey() == "countryCode" || query.getKey() == "countryName") {
|
|
||||||
is_geo_location_exception_being_loaded = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const MatchQuery &query_item : query.getItems()) {
|
|
||||||
if (isGeoLocationExists(query_item)) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isGeoLocationExists(match)) return;
|
|
||||||
for (const MatchBehaviorPair &match_query : match_queries) {
|
|
||||||
if (isGeoLocationExists(match_query.match)) return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set<ParameterBehavior>
|
|
||||||
ParameterException::getBehavior(
|
|
||||||
const unordered_map<string, set<string>> &key_value_pairs,
|
|
||||||
set<string> &matched_override_keywords) const
|
|
||||||
{
|
|
||||||
set<ParameterBehavior> matched_behaviors;
|
|
||||||
|
|
||||||
matched_override_keywords.clear();
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Matching exception";
|
|
||||||
for (const MatchBehaviorPair &match_behavior_pair: match_queries) {
|
|
||||||
MatchQuery::MatchResult match_res = match_behavior_pair.match.getMatch(key_value_pairs);
|
|
||||||
if (match_res.is_match) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Successfully matched an exception from a list of matches.";
|
|
||||||
// When matching indicators with action=ignore, we expect no behavior override.
|
|
||||||
// Instead, a matched keywords list should be returned which will be later removed from score calculation
|
|
||||||
if (match_res.matched_keywords->size() > 0 && match_behavior_pair.behavior == action_ignore) {
|
|
||||||
matched_override_keywords.insert(match_res.matched_keywords->begin(),
|
|
||||||
match_res.matched_keywords->end());
|
|
||||||
} else {
|
|
||||||
matched_behaviors.insert(match_behavior_pair.behavior);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match_queries.empty()) {
|
|
||||||
MatchQuery::MatchResult match_res = match.getMatch(key_value_pairs);
|
|
||||||
if (match_res.is_match) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Successfully matched an exception.";
|
|
||||||
// When matching indicators with action=ignore, we expect no behavior override.
|
|
||||||
// Instead, a matched keywords list should be returned which will be later removed from score calculation
|
|
||||||
if (match_res.matched_keywords->size() > 0 && behavior == action_ignore) {
|
|
||||||
matched_override_keywords.insert(match_res.matched_keywords->begin(),
|
|
||||||
match_res.matched_keywords->end());
|
|
||||||
} else {
|
|
||||||
matched_behaviors.insert(behavior);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return matched_behaviors;
|
|
||||||
}
|
|
||||||
|
|
||||||
set<ParameterBehavior>
|
|
||||||
ParameterException::getBehavior(const unordered_map<string, set<string>> &key_value_pairs) const
|
|
||||||
{
|
|
||||||
set<string> keywords;
|
|
||||||
return getBehavior(key_value_pairs, keywords);
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/rulebase_config.h"
|
|
||||||
|
|
||||||
#include "telemetry.h"
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
set<string> BasicRuleConfig::assets_ids{};
|
|
||||||
set<string> BasicRuleConfig::assets_ids_aggregation{};
|
|
||||||
|
|
||||||
void
|
|
||||||
BasicRuleConfig::load(cereal::JSONInputArchive &ar)
|
|
||||||
{
|
|
||||||
parseJSONKey<vector<RulePractice>>("practices", practices, ar);
|
|
||||||
parseJSONKey<vector<RuleTrigger>>("triggers", triggers, ar);
|
|
||||||
parseJSONKey<vector<RuleParameter>>("parameters", parameters, ar);
|
|
||||||
parseJSONKey<uint8_t>("priority", priority, ar);
|
|
||||||
parseJSONKey<string>("ruleId", rule_id, ar);
|
|
||||||
parseJSONKey<string>("ruleName", rule_name, ar);
|
|
||||||
parseJSONKey<string>("assetId", asset_id, ar);
|
|
||||||
parseJSONKey<string>("assetName", asset_name, ar);
|
|
||||||
parseJSONKey<string>("zoneId", zone_id, ar);
|
|
||||||
parseJSONKey<string>("zoneName", zone_name, ar);
|
|
||||||
|
|
||||||
assets_ids_aggregation.insert(asset_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
BasicRuleConfig::updateCountMetric()
|
|
||||||
{
|
|
||||||
BasicRuleConfig::assets_ids = BasicRuleConfig::assets_ids_aggregation;
|
|
||||||
AssetCountEvent(AssetType::ALL, BasicRuleConfig::assets_ids.size()).notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
BasicRuleConfig::isPracticeActive(const string &practice_id) const
|
|
||||||
{
|
|
||||||
for (auto practice: practices) {
|
|
||||||
if (practice.getId() == practice_id) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
BasicRuleConfig::isTriggerActive(const string &trigger_id) const
|
|
||||||
{
|
|
||||||
for (auto trigger: triggers) {
|
|
||||||
if (trigger.getId() == trigger_id) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
BasicRuleConfig::isParameterActive(const string ¶meter_id) const
|
|
||||||
{
|
|
||||||
for (auto param: parameters) {
|
|
||||||
if (param.getId() == parameter_id) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -1,243 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "generic_rulebase/triggers_config.h"
|
|
||||||
#include "generic_rulebase/generic_rulebase_utils.h"
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
WebTriggerConf::WebTriggerConf() : response_title(""), response_body(""), response_code(0) {}
|
|
||||||
WebTriggerConf::WebTriggerConf(const string &title, const string &body, uint code)
|
|
||||||
:
|
|
||||||
response_title(title),
|
|
||||||
response_body(body),
|
|
||||||
response_code(code)
|
|
||||||
{}
|
|
||||||
|
|
||||||
WebTriggerConf WebTriggerConf::default_trigger_conf = WebTriggerConf(
|
|
||||||
"Attack blocked by web application protection", // title
|
|
||||||
"Check Point's <b>Application Security</b> has detected an attack and blocked it.", // body
|
|
||||||
403
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
WebTriggerConf::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
parseJSONKey<string>("details level", details_level, archive_in);
|
|
||||||
if (details_level == "Redirect") {
|
|
||||||
parseJSONKey<string>("redirect URL", redirect_url, archive_in);
|
|
||||||
parseJSONKey<bool>("xEventId", add_event_id_to_header, archive_in);
|
|
||||||
parseJSONKey<bool>("eventIdInHeader", add_event_id_to_header, archive_in);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
parseJSONKey<uint>("response code", response_code, archive_in);
|
|
||||||
if (response_code < 100 || response_code > 599) {
|
|
||||||
throw cereal::Exception(
|
|
||||||
"illegal web trigger response code: " +
|
|
||||||
to_string(response_code) +
|
|
||||||
" is out of range (100-599)"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (details_level == "Response Code") return;
|
|
||||||
|
|
||||||
parseJSONKey<string>("response body", response_body, archive_in);
|
|
||||||
parseJSONKey<string>("response title", response_title, archive_in);
|
|
||||||
} catch (const exception &e) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to parse the web trigger configuration: '" << e.what() << "'";
|
|
||||||
archive_in.setNextName(nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
WebTriggerConf::operator==(const WebTriggerConf &other) const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
response_code == other.response_code &&
|
|
||||||
response_title == other.response_title &&
|
|
||||||
response_body == other.response_body;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogTriggerConf::LogTriggerConf(string trigger_name, bool log_detect, bool log_prevent) : name(trigger_name)
|
|
||||||
{
|
|
||||||
if (log_detect) should_log_on_detect.setAll();
|
|
||||||
if (log_prevent) should_log_on_prevent.setAll();
|
|
||||||
active_streams.setFlag(ReportIS::StreamType::JSON_FOG);
|
|
||||||
active_streams.setFlag(ReportIS::StreamType::JSON_LOG_FILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReportIS::Severity
|
|
||||||
LogTriggerConf::getSeverity(bool is_action_drop_or_prevent) const
|
|
||||||
{
|
|
||||||
return is_action_drop_or_prevent ? ReportIS::Severity::MEDIUM : ReportIS::Severity::LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReportIS::Priority
|
|
||||||
LogTriggerConf::getPriority(bool is_action_drop_or_prevent) const
|
|
||||||
{
|
|
||||||
return is_action_drop_or_prevent ? ReportIS::Priority::HIGH : ReportIS::Priority::MEDIUM;
|
|
||||||
}
|
|
||||||
|
|
||||||
Flags<ReportIS::StreamType>
|
|
||||||
LogTriggerConf::getStreams(SecurityType security_type, bool is_action_drop_or_prevent) const
|
|
||||||
{
|
|
||||||
if (is_action_drop_or_prevent && should_log_on_prevent.isSet(security_type)) return active_streams;
|
|
||||||
if (!is_action_drop_or_prevent && should_log_on_detect.isSet(security_type)) return active_streams;
|
|
||||||
|
|
||||||
return Flags<ReportIS::StreamType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
Flags<ReportIS::Enreachments>
|
|
||||||
LogTriggerConf::getEnrechments(SecurityType security_type) const
|
|
||||||
{
|
|
||||||
Flags<ReportIS::Enreachments> enreachments;
|
|
||||||
|
|
||||||
if (log_geo_location.isSet(security_type)) enreachments.setFlag(ReportIS::Enreachments::GEOLOCATION);
|
|
||||||
if (should_format_output) enreachments.setFlag(ReportIS::Enreachments::BEAUTIFY_OUTPUT);
|
|
||||||
|
|
||||||
return enreachments;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename EnumClass>
|
|
||||||
static void
|
|
||||||
setTriggersFlag(const string &key, cereal::JSONInputArchive &ar, EnumClass flag, Flags<EnumClass> &flags)
|
|
||||||
{
|
|
||||||
bool value = false;
|
|
||||||
parseJSONKey<bool>(key, value, ar);
|
|
||||||
if (value) flags.setFlag(flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
setLogConfiguration(
|
|
||||||
const ReportIS::StreamType &log_type,
|
|
||||||
const string &log_server_url = "",
|
|
||||||
const string &protocol = ""
|
|
||||||
)
|
|
||||||
{
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "log server url:" << log_server_url;
|
|
||||||
if (log_server_url != "" && protocol != "") {
|
|
||||||
Singleton::Consume<I_Logging>::by<LogTriggerConf>()->addStream(log_type, log_server_url, protocol);
|
|
||||||
} else {
|
|
||||||
Singleton::Consume<I_Logging>::by<LogTriggerConf>()->addStream(log_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static string
|
|
||||||
parseProtocolWithDefault(
|
|
||||||
const std::string &default_value,
|
|
||||||
const std::string &key_name,
|
|
||||||
cereal::JSONInputArchive &archive_in
|
|
||||||
)
|
|
||||||
{
|
|
||||||
string value;
|
|
||||||
try {
|
|
||||||
archive_in(cereal::make_nvp(key_name, value));
|
|
||||||
} catch (const cereal::Exception &e) {
|
|
||||||
return default_value;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LogTriggerConf::load(cereal::JSONInputArchive& archive_in)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
parseJSONKey<string>("triggerName", name, archive_in);
|
|
||||||
parseJSONKey<string>("verbosity", verbosity, archive_in);
|
|
||||||
parseJSONKey<string>("urlForSyslog", url_for_syslog, archive_in);
|
|
||||||
parseJSONKey<string>("urlForCef", url_for_cef, archive_in);
|
|
||||||
parseJSONKey<string>("syslogProtocol", syslog_protocol, archive_in);
|
|
||||||
syslog_protocol = parseProtocolWithDefault("UDP", "syslogProtocol", archive_in);
|
|
||||||
cef_protocol = parseProtocolWithDefault("UDP", "cefProtocol", archive_in);
|
|
||||||
|
|
||||||
setTriggersFlag("webBody", archive_in, WebLogFields::webBody, log_web_fields);
|
|
||||||
setTriggersFlag("webHeaders", archive_in, WebLogFields::webHeaders, log_web_fields);
|
|
||||||
setTriggersFlag("webRequests", archive_in, WebLogFields::webRequests, log_web_fields);
|
|
||||||
setTriggersFlag("webUrlPath", archive_in, WebLogFields::webUrlPath, log_web_fields);
|
|
||||||
setTriggersFlag("webUrlQuery", archive_in, WebLogFields::webUrlQuery, log_web_fields);
|
|
||||||
setTriggersFlag("logToAgent", archive_in, ReportIS::StreamType::JSON_LOG_FILE, active_streams);
|
|
||||||
setTriggersFlag("logToCloud", archive_in, ReportIS::StreamType::JSON_FOG, active_streams);
|
|
||||||
setTriggersFlag("logToK8sService", archive_in, ReportIS::StreamType::JSON_K8S_SVC, active_streams);
|
|
||||||
setTriggersFlag("logToSyslog", archive_in, ReportIS::StreamType::SYSLOG, active_streams);
|
|
||||||
setTriggersFlag("logToCef", archive_in, ReportIS::StreamType::CEF, active_streams);
|
|
||||||
setTriggersFlag("acAllow", archive_in, SecurityType::AccessControl, should_log_on_detect);
|
|
||||||
setTriggersFlag("acDrop", archive_in, SecurityType::AccessControl, should_log_on_prevent);
|
|
||||||
setTriggersFlag("tpDetect", archive_in, SecurityType::ThreatPrevention, should_log_on_detect);
|
|
||||||
setTriggersFlag("tpPrevent", archive_in, SecurityType::ThreatPrevention, should_log_on_prevent);
|
|
||||||
setTriggersFlag("complianceWarnings", archive_in, SecurityType::Compliance, should_log_on_detect);
|
|
||||||
setTriggersFlag("complianceViolations", archive_in, SecurityType::Compliance, should_log_on_prevent);
|
|
||||||
setTriggersFlag("acLogGeoLocation", archive_in, SecurityType::AccessControl, log_geo_location);
|
|
||||||
setTriggersFlag("tpLogGeoLocation", archive_in, SecurityType::ThreatPrevention, log_geo_location);
|
|
||||||
setTriggersFlag("complianceLogGeoLocation", archive_in, SecurityType::Compliance, log_geo_location);
|
|
||||||
|
|
||||||
bool extend_logging = false;
|
|
||||||
parseJSONKey<bool>("extendLogging", extend_logging, archive_in);
|
|
||||||
if (extend_logging) {
|
|
||||||
setTriggersFlag("responseCode", archive_in, WebLogFields::responseCode, log_web_fields);
|
|
||||||
setTriggersFlag("responseBody", archive_in, WebLogFields::responseBody, log_web_fields);
|
|
||||||
|
|
||||||
string severity;
|
|
||||||
static const map<string, extendLoggingSeverity> extend_logging_severity_strings = {
|
|
||||||
{"High", extendLoggingSeverity::High},
|
|
||||||
{"Critical", extendLoggingSeverity::Critical}
|
|
||||||
};
|
|
||||||
parseJSONKey<string>("extendLoggingMinSeverity", severity, archive_in);
|
|
||||||
auto extended_severity = extend_logging_severity_strings.find(severity);
|
|
||||||
if (extended_severity != extend_logging_severity_strings.end()) {
|
|
||||||
extend_logging_severity = extended_severity->second;
|
|
||||||
} else {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG)
|
|
||||||
<< "Failed to parse the extendLoggingMinSeverityfield: '"
|
|
||||||
<< severity
|
|
||||||
<< "'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ReportIS::StreamType log_stream : makeRange<ReportIS::StreamType>()) {
|
|
||||||
if (!active_streams.isSet(log_stream)) continue;
|
|
||||||
switch (log_stream) {
|
|
||||||
case ReportIS::StreamType::JSON_DEBUG:
|
|
||||||
setLogConfiguration(ReportIS::StreamType::JSON_DEBUG);
|
|
||||||
break;
|
|
||||||
case ReportIS::StreamType::JSON_FOG:
|
|
||||||
setLogConfiguration(ReportIS::StreamType::JSON_FOG);
|
|
||||||
break;
|
|
||||||
case ReportIS::StreamType::JSON_LOG_FILE:
|
|
||||||
setLogConfiguration(ReportIS::StreamType::JSON_LOG_FILE);
|
|
||||||
break;
|
|
||||||
case ReportIS::StreamType::JSON_K8S_SVC:
|
|
||||||
setLogConfiguration(ReportIS::StreamType::JSON_K8S_SVC);
|
|
||||||
break;
|
|
||||||
case ReportIS::StreamType::SYSLOG:
|
|
||||||
setLogConfiguration(ReportIS::StreamType::SYSLOG, getUrlForSyslog(), syslog_protocol);
|
|
||||||
break;
|
|
||||||
case ReportIS::StreamType::CEF:
|
|
||||||
setLogConfiguration(ReportIS::StreamType::CEF, getUrlForCef(), cef_protocol);
|
|
||||||
break;
|
|
||||||
case ReportIS::StreamType::NONE: break;
|
|
||||||
case ReportIS::StreamType::COUNT: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parseJSONKey<bool>("formatLoggingOutput", should_format_output, archive_in);
|
|
||||||
} catch (const exception &e) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to parse the log trigger configuration: '" << e.what() << "'";
|
|
||||||
archive_in.setNextName(nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,179 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/zone.h"
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
static const unordered_map<string, Zone::Direction> string_to_direction = {
|
|
||||||
{ "to", Zone::Direction::To },
|
|
||||||
{ "from", Zone::Direction::From },
|
|
||||||
{ "bidirectional", Zone::Direction::Bidirectional }
|
|
||||||
};
|
|
||||||
|
|
||||||
class AdjacentZone
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void
|
|
||||||
load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
string direction_as_string;
|
|
||||||
archive_in(cereal::make_nvp("direction", direction_as_string));
|
|
||||||
archive_in(cereal::make_nvp("zoneId", id));
|
|
||||||
auto maybe_direction = string_to_direction.find(direction_as_string);
|
|
||||||
if (maybe_direction == string_to_direction.end()) {
|
|
||||||
reportConfigurationError(
|
|
||||||
"Illegal direction provided for adjacency. Provided direction in configuration: " +
|
|
||||||
direction_as_string
|
|
||||||
);
|
|
||||||
}
|
|
||||||
dir = maybe_direction->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
pair<Zone::Direction, GenericConfigId> getValue() const { return make_pair(dir, id); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Zone::Direction dir;
|
|
||||||
GenericConfigId id;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TagsValues
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static const string req_attrs_ctx_key;
|
|
||||||
|
|
||||||
TagsValues() {}
|
|
||||||
|
|
||||||
template <typename Archive>
|
|
||||||
void
|
|
||||||
serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
I_Environment *env = Singleton::Consume<I_Environment>::by<Zone>();
|
|
||||||
auto req_attrs = env->get<set<string>>(req_attrs_ctx_key);
|
|
||||||
if (!req_attrs.ok()) return;
|
|
||||||
|
|
||||||
for (const string &req_attr : *req_attrs) {
|
|
||||||
try {
|
|
||||||
string data;
|
|
||||||
ar(cereal::make_nvp(req_attr, data));
|
|
||||||
dbgDebug(D_RULEBASE_CONFIG)
|
|
||||||
<< "Found value for requested attribute. Tag: "
|
|
||||||
<< req_attr
|
|
||||||
<< ", Value: "
|
|
||||||
<< data;
|
|
||||||
|
|
||||||
tags_set[req_attr].insert(data);
|
|
||||||
} catch (const exception &e) {
|
|
||||||
dbgDebug(D_RULEBASE_CONFIG) << "Could not find values for requested attribute. Tag: " << req_attr;
|
|
||||||
ar.setNextName(nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
matchValueByKey(const string &requested_key, const unordered_set<string> &possible_values) const
|
|
||||||
{
|
|
||||||
auto values = tags_set.find(requested_key);
|
|
||||||
if (values == tags_set.end()) return false;
|
|
||||||
|
|
||||||
for (const string &val : possible_values) {
|
|
||||||
if (values->second.count(val)) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
insert(const TagsValues &other)
|
|
||||||
{
|
|
||||||
for (auto &single_tags_value : other.getData()) {
|
|
||||||
tags_set[single_tags_value.first].insert(single_tags_value.second.begin(), single_tags_value.second.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const unordered_map<string, set<string>> & getData() const { return tags_set; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
unordered_map<string, set<string>> tags_set;
|
|
||||||
};
|
|
||||||
|
|
||||||
const string TagsValues::req_attrs_ctx_key = "requested attributes key";
|
|
||||||
|
|
||||||
void
|
|
||||||
Zone::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
archive_in(cereal::make_nvp("id", zone_id));
|
|
||||||
archive_in(cereal::make_nvp("name", zone_name));
|
|
||||||
vector<AdjacentZone> adjacency;
|
|
||||||
try {
|
|
||||||
archive_in(cereal::make_nvp("adjacentZones", adjacency));
|
|
||||||
} catch (const cereal::Exception &) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG)
|
|
||||||
<< "List of adjacentZones does not exist for current object. Zone id: "
|
|
||||||
<< zone_id
|
|
||||||
<< ", Zone name: "
|
|
||||||
<< zone_name;
|
|
||||||
|
|
||||||
archive_in.setNextName(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const AdjacentZone &zone : adjacency) {
|
|
||||||
adjacent_zones.push_back(zone.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
archive_in(cereal::make_nvp("match", match_query));
|
|
||||||
|
|
||||||
is_any =
|
|
||||||
match_query.getType() == MatchQuery::MatchType::Condition &&
|
|
||||||
match_query.getKey() == "any" &&
|
|
||||||
match_query.getValue().count("any") > 0;
|
|
||||||
|
|
||||||
set<string> keys = match_query.getAllKeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
const string
|
|
||||||
contextKeyToString(Context::MetaDataType type)
|
|
||||||
{
|
|
||||||
if (type == Context::MetaDataType::SubjectIpAddr || type == Context::MetaDataType::OtherIpAddr) return "ip";
|
|
||||||
return Context::convertToString(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Zone::contains(const Asset &asset)
|
|
||||||
{
|
|
||||||
QueryRequest request;
|
|
||||||
|
|
||||||
for (const auto &main_attr : asset.getAttrs()) {
|
|
||||||
request.addCondition(Condition::EQUALS, contextKeyToString(main_attr.first), main_attr.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedContext req_attrs_key;
|
|
||||||
req_attrs_key.registerValue<set<string>>(TagsValues::req_attrs_ctx_key, match_query.getAllKeys());
|
|
||||||
|
|
||||||
I_Intelligence_IS_V2 *intelligence = Singleton::Consume<I_Intelligence_IS_V2>::by<Zone>();
|
|
||||||
auto query_res = intelligence->queryIntelligence<TagsValues>(request);
|
|
||||||
if (!query_res.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to perform intelligence query. Error: " << query_res.getErr();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const AssetReply<TagsValues> &asset : query_res.unpack()) {
|
|
||||||
TagsValues tag_values = asset.mergeReplyData();
|
|
||||||
|
|
||||||
if (match_query.matchAttributes(tag_values.getData())) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "generic_rulebase/zones_config.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
#include "generic_rulebase/generic_rulebase_utils.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "ip_utilities.h"
|
|
||||||
#include "connkey.h"
|
|
||||||
#include "i_generic_rulebase.h"
|
|
||||||
|
|
||||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
void
|
|
||||||
ZonesConfig::load(cereal::JSONInputArchive &archive_in)
|
|
||||||
{
|
|
||||||
dbgFlow(D_RULEBASE_CONFIG) << "Saving active zones";
|
|
||||||
set<string> used_zones;
|
|
||||||
cereal::load(archive_in, used_zones);
|
|
||||||
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Loading all zones";
|
|
||||||
auto all_zones_maybe = getSetting<Zones>("rulebase", "zones");
|
|
||||||
if (!all_zones_maybe.ok()) {
|
|
||||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to load zones";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Creating cache of all zones by ID";
|
|
||||||
map<GenericConfigId, Zone> all_zones;
|
|
||||||
for (const auto &single_zone : all_zones_maybe.unpack().zones) {
|
|
||||||
if (used_zones.count(single_zone.getId()) > 0 && single_zone.isAnyZone()) {
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Found used zone of type \"Any\": saving all zones as active zones";
|
|
||||||
zones = all_zones_maybe.unpack().zones;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbgDebug(D_RULEBASE_CONFIG)
|
|
||||||
<< "Adding specific zone to cache. Zone ID: "
|
|
||||||
<< single_zone.getId()
|
|
||||||
<< ", name: "
|
|
||||||
<< single_zone.getName();
|
|
||||||
all_zones.emplace(single_zone.getId(), single_zone);
|
|
||||||
}
|
|
||||||
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG) << "Creating list of active zones";
|
|
||||||
map<GenericConfigId, Zone> active_zones_set;
|
|
||||||
for (const auto &single_used_zone_id : used_zones) {
|
|
||||||
const auto &found_zone = all_zones[single_used_zone_id];
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG)
|
|
||||||
<< "Adding zone to list of active zones. Zone ID: "
|
|
||||||
<< single_used_zone_id
|
|
||||||
<< ", zone name: "
|
|
||||||
<< found_zone.getName();
|
|
||||||
active_zones_set.emplace(found_zone.getId(), found_zone);
|
|
||||||
|
|
||||||
for (const auto &adjacent_zone : found_zone.getAdjacentZones()) {
|
|
||||||
const auto &adjacent_zone_obj = all_zones[adjacent_zone.second];
|
|
||||||
dbgTrace(D_RULEBASE_CONFIG)
|
|
||||||
<< "Adding adjacent zone to list of active zones. Zone ID: "
|
|
||||||
<< adjacent_zone_obj.getId()
|
|
||||||
<< ", zone name: "
|
|
||||||
<< adjacent_zone_obj.getName();
|
|
||||||
active_zones_set.emplace(adjacent_zone_obj.getId(), adjacent_zone_obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<GenericConfigId> implied_zones = {
|
|
||||||
"impliedAzure",
|
|
||||||
"impliedDNS",
|
|
||||||
"impliedSSH",
|
|
||||||
"impliedProxy",
|
|
||||||
"impliedFog"
|
|
||||||
};
|
|
||||||
|
|
||||||
GenericConfigId any_zone_id = "";
|
|
||||||
for (const auto &single_zone : all_zones_maybe.unpack().zones) {
|
|
||||||
if (single_zone.isAnyZone()) any_zone_id = single_zone.getId();
|
|
||||||
}
|
|
||||||
for (GenericConfigId &implied_id: implied_zones) {
|
|
||||||
if (all_zones.find(implied_id) != all_zones.end()) {
|
|
||||||
dbgDebug(D_RULEBASE_CONFIG) << "Adding implied zone to cache. Zone ID: " << implied_id;
|
|
||||||
active_zones_set.emplace(implied_id, all_zones[implied_id]);
|
|
||||||
if (any_zone_id != "" && active_zones_set.count(any_zone_id) == 0) {
|
|
||||||
active_zones_set.emplace(any_zone_id, all_zones[any_zone_id]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &single_id_zone_pair : active_zones_set) {
|
|
||||||
zones.push_back(single_id_zone_pair.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ZonesConfig::preload()
|
|
||||||
{
|
|
||||||
registerExpectedSetting<Zones>("rulebase", "zones");
|
|
||||||
registerExpectedSetting<ZonesConfig>("rulebase", "usedZones");
|
|
||||||
}
|
|
||||||
@@ -128,7 +128,7 @@ private:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
dbgAssert(false) << "Unsupported IP type";
|
dbgAssert(false) << AlertInfo(AlertTeam::CORE, "gradual deployment") << "Unsupported IP type";
|
||||||
}
|
}
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
include_directories(${CMAKE_SOURCE_DIR}/components/include)
|
|
||||||
link_directories(${BOOST_ROOT}/lib)
|
|
||||||
|
|
||||||
add_unit_test(
|
|
||||||
health_check_manager_ut
|
|
||||||
"health_check_manager_ut.cc"
|
|
||||||
"singleton;messaging;mainloop;health_check_manager;event_is;metric;-lboost_regex"
|
|
||||||
)
|
|
||||||
@@ -46,7 +46,10 @@ operator<<(ostream &os, const EventVerdict &event)
|
|||||||
case ngx_http_cp_verdict_e::TRAFFIC_VERDICT_WAIT: return os << "Wait";
|
case ngx_http_cp_verdict_e::TRAFFIC_VERDICT_WAIT: return os << "Wait";
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgAssert(false) << "Illegal Event Verdict value: " << static_cast<uint>(event.getVerdict());
|
dbgAssert(false)
|
||||||
|
<< AlertInfo(AlertTeam::CORE, "http manager")
|
||||||
|
<< "Illegal Event Verdict value: "
|
||||||
|
<< static_cast<uint>(event.getVerdict());
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,8 +324,11 @@ private:
|
|||||||
|
|
||||||
state.setApplicationVerdict(respond.first, respond.second.getVerdict());
|
state.setApplicationVerdict(respond.first, respond.second.getVerdict());
|
||||||
}
|
}
|
||||||
|
FilterVerdict aggregated_verdict = state.getCurrVerdict();
|
||||||
return state.getCurrVerdict();
|
if (aggregated_verdict.getVerdict() == ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP) {
|
||||||
|
SecurityAppsDropEvent(state.getCurrentDropVerdictCausers()).notify();
|
||||||
|
}
|
||||||
|
return aggregated_verdict;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ HttpManagerOpaque::getCurrVerdict() const
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dbgAssert(false)
|
dbgAssert(false)
|
||||||
|
<< AlertInfo(AlertTeam::CORE, "http manager")
|
||||||
<< "Received unknown verdict "
|
<< "Received unknown verdict "
|
||||||
<< static_cast<int>(app_verdic_pair.second);
|
<< static_cast<int>(app_verdic_pair.second);
|
||||||
}
|
}
|
||||||
@@ -77,6 +78,25 @@ HttpManagerOpaque::getCurrVerdict() const
|
|||||||
return accepted_apps == applications_verdicts.size() ? ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT : verdict;
|
return accepted_apps == applications_verdicts.size() ? ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT : verdict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<std::string>
|
||||||
|
HttpManagerOpaque::getCurrentDropVerdictCausers() const
|
||||||
|
{
|
||||||
|
std::set<std::string> causers;
|
||||||
|
if (manager_verdict == ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP) {
|
||||||
|
causers.insert(HTTP_MANAGER_NAME);
|
||||||
|
}
|
||||||
|
for (const auto &app_verdic_pair : applications_verdicts) {
|
||||||
|
bool was_dropped = app_verdic_pair.second == ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP;
|
||||||
|
dbgTrace(D_HTTP_MANAGER)
|
||||||
|
<< "The verdict from: " << app_verdic_pair.first
|
||||||
|
<< (was_dropped ? " is \"drop\"" : " is not \"drop\" ");
|
||||||
|
if (was_dropped) {
|
||||||
|
causers.insert(app_verdic_pair.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return causers;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HttpManagerOpaque::saveCurrentDataToCache(const Buffer &full_data)
|
HttpManagerOpaque::saveCurrentDataToCache(const Buffer &full_data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
#include "table_opaque.h"
|
#include "table_opaque.h"
|
||||||
#include "nginx_attachment_common.h"
|
#include "nginx_attachment_common.h"
|
||||||
|
|
||||||
|
static const std::string HTTP_MANAGER_NAME = "HTTP Manager";
|
||||||
|
|
||||||
class HttpManagerOpaque : public TableOpaqueSerialize<HttpManagerOpaque>
|
class HttpManagerOpaque : public TableOpaqueSerialize<HttpManagerOpaque>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -30,6 +32,7 @@ public:
|
|||||||
void setManagerVerdict(ngx_http_cp_verdict_e verdict) { manager_verdict = verdict; }
|
void setManagerVerdict(ngx_http_cp_verdict_e verdict) { manager_verdict = verdict; }
|
||||||
ngx_http_cp_verdict_e getManagerVerdict() const { return manager_verdict; }
|
ngx_http_cp_verdict_e getManagerVerdict() const { return manager_verdict; }
|
||||||
ngx_http_cp_verdict_e getCurrVerdict() const;
|
ngx_http_cp_verdict_e getCurrVerdict() const;
|
||||||
|
std::set<std::string> getCurrentDropVerdictCausers() const;
|
||||||
void saveCurrentDataToCache(const Buffer &full_data);
|
void saveCurrentDataToCache(const Buffer &full_data);
|
||||||
void setUserDefinedValue(const std::string &value) { user_defined_value = value; }
|
void setUserDefinedValue(const std::string &value) { user_defined_value = value; }
|
||||||
Maybe<std::string> getUserDefinedValue() const { return user_defined_value; }
|
Maybe<std::string> getUserDefinedValue() const { return user_defined_value; }
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public:
|
|||||||
~DetailsResolver();
|
~DetailsResolver();
|
||||||
|
|
||||||
void preload() override;
|
void preload() override;
|
||||||
|
void init() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "url_parser.h"
|
#include "url_parser.h"
|
||||||
#include "i_agent_details.h"
|
#include "i_agent_details.h"
|
||||||
#include "i_mainloop.h"
|
#include "i_mainloop.h"
|
||||||
|
#include "i_environment.h"
|
||||||
#include "singleton.h"
|
#include "singleton.h"
|
||||||
#include "component.h"
|
#include "component.h"
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ class Downloader
|
|||||||
Singleton::Consume<I_Encryptor>,
|
Singleton::Consume<I_Encryptor>,
|
||||||
Singleton::Consume<I_MainLoop>,
|
Singleton::Consume<I_MainLoop>,
|
||||||
Singleton::Consume<I_OrchestrationTools>,
|
Singleton::Consume<I_OrchestrationTools>,
|
||||||
|
Singleton::Consume<I_Environment>,
|
||||||
Singleton::Consume<I_UpdateCommunication>
|
Singleton::Consume<I_UpdateCommunication>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -29,12 +29,15 @@ public:
|
|||||||
|
|
||||||
virtual EnvType getEnvType() override;
|
virtual EnvType getEnvType() override;
|
||||||
virtual std::string getToken() override;
|
virtual std::string getToken() override;
|
||||||
|
virtual std::string getNameSpace() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string retrieveToken();
|
std::string retrieveToken();
|
||||||
|
std::string retrieveNamespace();
|
||||||
std::string readFileContent(const std::string &file_path);
|
std::string readFileContent(const std::string &file_path);
|
||||||
|
|
||||||
std::string token;
|
std::string token;
|
||||||
|
std::string agent_namespace;
|
||||||
EnvType env_type;
|
EnvType env_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ class ExternalSdkServer
|
|||||||
:
|
:
|
||||||
public Component,
|
public Component,
|
||||||
Singleton::Provide<I_ExternalSdkServer>,
|
Singleton::Provide<I_ExternalSdkServer>,
|
||||||
Singleton::Consume<I_RestApi>
|
Singleton::Consume<I_RestApi>,
|
||||||
|
Singleton::Consume<I_Messaging>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExternalSdkServer();
|
ExternalSdkServer();
|
||||||
|
|||||||
@@ -89,7 +89,9 @@ private:
|
|||||||
bool matchAttributesRegEx(const std::set<std::string> &values,
|
bool matchAttributesRegEx(const std::set<std::string> &values,
|
||||||
std::set<std::string> &matched_override_keywords) const;
|
std::set<std::string> &matched_override_keywords) const;
|
||||||
bool matchAttributesString(const std::set<std::string> &values) const;
|
bool matchAttributesString(const std::set<std::string> &values) const;
|
||||||
|
bool matchAttributesIp(const std::set<std::string> &values) const;
|
||||||
bool isRegEx() const;
|
bool isRegEx() const;
|
||||||
|
void sortAndMergeIpRangesValues();
|
||||||
|
|
||||||
MatchType type;
|
MatchType type;
|
||||||
Operators operator_type;
|
Operators operator_type;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "i_shell_cmd.h"
|
#include "i_shell_cmd.h"
|
||||||
#include "i_orchestration_status.h"
|
#include "i_orchestration_status.h"
|
||||||
#include "component.h"
|
#include "component.h"
|
||||||
|
#include "i_service_controller.h"
|
||||||
|
|
||||||
class HealthChecker
|
class HealthChecker
|
||||||
:
|
:
|
||||||
@@ -29,7 +30,8 @@ class HealthChecker
|
|||||||
Singleton::Consume<I_Socket>,
|
Singleton::Consume<I_Socket>,
|
||||||
Singleton::Consume<I_Health_Check_Manager>,
|
Singleton::Consume<I_Health_Check_Manager>,
|
||||||
Singleton::Consume<I_ShellCmd>,
|
Singleton::Consume<I_ShellCmd>,
|
||||||
Singleton::Consume<I_OrchestrationStatus>
|
Singleton::Consume<I_OrchestrationStatus>,
|
||||||
|
Singleton::Consume<I_ServiceController>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HealthChecker();
|
HealthChecker();
|
||||||
|
|||||||
@@ -50,9 +50,11 @@ public:
|
|||||||
position(mod_position)
|
position(mod_position)
|
||||||
{
|
{
|
||||||
dbgAssert(mod_type != ModificationType::APPEND || position == injection_pos_irrelevant)
|
dbgAssert(mod_type != ModificationType::APPEND || position == injection_pos_irrelevant)
|
||||||
|
<< AlertInfo(AlertTeam::CORE, "http manager")
|
||||||
<< "Injection position is not applicable to a modification of type \"Append\"";
|
<< "Injection position is not applicable to a modification of type \"Append\"";
|
||||||
|
|
||||||
dbgAssert(mod_type != ModificationType::INJECT || position >= 0)
|
dbgAssert(mod_type != ModificationType::INJECT || position >= 0)
|
||||||
|
<< AlertInfo(AlertTeam::CORE, "http manager")
|
||||||
<< "Invalid injection position: must be non-negative. Position: "
|
<< "Invalid injection position: must be non-negative. Position: "
|
||||||
<< position;
|
<< position;
|
||||||
}
|
}
|
||||||
@@ -166,6 +168,7 @@ private:
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
dbgAssert(false)
|
dbgAssert(false)
|
||||||
|
<< AlertInfo(AlertTeam::CORE, "http manager")
|
||||||
<< "Unknown type of ModificationType: "
|
<< "Unknown type of ModificationType: "
|
||||||
<< static_cast<int>(modification_type);
|
<< static_cast<int>(modification_type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ class HttpGeoFilter
|
|||||||
public Component,
|
public Component,
|
||||||
Singleton::Consume<I_MainLoop>,
|
Singleton::Consume<I_MainLoop>,
|
||||||
Singleton::Consume<I_GeoLocation>,
|
Singleton::Consume<I_GeoLocation>,
|
||||||
Singleton::Consume<I_GenericRulebase>
|
Singleton::Consume<I_GenericRulebase>,
|
||||||
|
Singleton::Consume<I_Environment>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HttpGeoFilter();
|
HttpGeoFilter();
|
||||||
|
|||||||
@@ -183,4 +183,16 @@ class WaitTransactionEvent : public Event<WaitTransactionEvent, EventVerdict>
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SecurityAppsDropEvent : public Event<SecurityAppsDropEvent>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SecurityAppsDropEvent(
|
||||||
|
const std::set<std::string> &apps_names)
|
||||||
|
:
|
||||||
|
apps_names(apps_names) {}
|
||||||
|
const std::set<std::string> & getAppsNames() const { return apps_names; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::set<std::string> apps_names;
|
||||||
|
};
|
||||||
#endif // __HTTP_INSPECTION_EVENTS_H__
|
#endif // __HTTP_INSPECTION_EVENTS_H__
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ public:
|
|||||||
static const std::string req_body;
|
static const std::string req_body;
|
||||||
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 CompressionType default_response_content_encoding;
|
static const CompressionType default_response_content_encoding;
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ public:
|
|||||||
virtual bool isGwNotVsx() = 0;
|
virtual bool isGwNotVsx() = 0;
|
||||||
virtual bool isVersionAboveR8110() = 0;
|
virtual bool isVersionAboveR8110() = 0;
|
||||||
virtual bool isReverseProxy() = 0;
|
virtual bool isReverseProxy() = 0;
|
||||||
|
virtual bool isCloudStorageEnabled() = 0;
|
||||||
virtual Maybe<std::tuple<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 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)
|
||||||
virtual bool compareCheckpointVersion(int cp_version, std::function<bool(int, int)> compare_operator) const = 0;
|
virtual bool compareCheckpointVersion(int cp_version, std::function<bool(int, int)> compare_operator) const = 0;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
class I_Downloader
|
class I_Downloader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual Maybe<std::string> downloadFileFromFog(
|
virtual Maybe<std::string> downloadFile(
|
||||||
const std::string &checksum,
|
const std::string &checksum,
|
||||||
Package::ChecksumTypes,
|
Package::ChecksumTypes,
|
||||||
const GetResourceFile &resourse_file
|
const GetResourceFile &resourse_file
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ public:
|
|||||||
const std::string &conf_path) const = 0;
|
const std::string &conf_path) const = 0;
|
||||||
virtual bool copyFile(const std::string &src_path, const std::string &dst_path) const = 0;
|
virtual bool copyFile(const std::string &src_path, const std::string &dst_path) const = 0;
|
||||||
virtual bool doesFileExist(const std::string &file_path) const = 0;
|
virtual bool doesFileExist(const std::string &file_path) const = 0;
|
||||||
virtual void getClusterId() const = 0;
|
virtual void setClusterId() const = 0;
|
||||||
virtual void fillKeyInJson(
|
virtual void fillKeyInJson(
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
const std::string &_key,
|
const std::string &_key,
|
||||||
|
|||||||
@@ -64,7 +64,9 @@ public:
|
|||||||
const std::string &service_id
|
const std::string &service_id
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
virtual std::map<std::string, PortNumber> getServiceToPortMap() = 0;
|
virtual std::map<std::string, std::vector<PortNumber>> getServiceToPortMap() = 0;
|
||||||
|
|
||||||
|
virtual bool getServicesPolicyStatus() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~I_ServiceController() {}
|
virtual ~I_ServiceController() {}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public:
|
|||||||
const std::string &policy_versions
|
const std::string &policy_versions
|
||||||
) const = 0;
|
) const = 0;
|
||||||
virtual Maybe<void> authenticateAgent() = 0;
|
virtual Maybe<void> authenticateAgent() = 0;
|
||||||
|
virtual void registerLocalAgentToFog() = 0;
|
||||||
virtual Maybe<void> getUpdate(CheckUpdateRequest &request) = 0;
|
virtual Maybe<void> getUpdate(CheckUpdateRequest &request) = 0;
|
||||||
virtual Maybe<std::string> downloadAttributeFile(
|
virtual Maybe<std::string> downloadAttributeFile(
|
||||||
const GetResourceFile &resourse_file,
|
const GetResourceFile &resourse_file,
|
||||||
|
|||||||
@@ -28,8 +28,9 @@
|
|||||||
|
|
||||||
// LCOV_EXCL_START Reason: temporary until we add relevant UT until 07/10
|
// LCOV_EXCL_START Reason: temporary until we add relevant UT until 07/10
|
||||||
bool operator<(const IpAddress &this_ip_addr, const IpAddress &other_ip_addr);
|
bool operator<(const IpAddress &this_ip_addr, const IpAddress &other_ip_addr);
|
||||||
|
|
||||||
bool operator==(const IpAddress &this_ip_addr, const IpAddress &other_ip_addr);
|
bool operator==(const IpAddress &this_ip_addr, const IpAddress &other_ip_addr);
|
||||||
|
bool operator<=(const IpAddress &this_ip_addr, const IpAddress &other_ip_addr);
|
||||||
|
bool operator<(const IPRange &range1, const IPRange &range2);
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
|
||||||
Maybe<std::pair<std::string, int>> extractAddressAndMaskSize(const std::string &cidr);
|
Maybe<std::pair<std::string, int>> extractAddressAndMaskSize(const std::string &cidr);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "i_environment.h"
|
#include "i_environment.h"
|
||||||
#include "i_tenant_manager.h"
|
#include "i_tenant_manager.h"
|
||||||
#include "i_package_handler.h"
|
#include "i_package_handler.h"
|
||||||
|
#include "i_proxy_configuration.h"
|
||||||
#include "i_env_details.h"
|
#include "i_env_details.h"
|
||||||
#include "component.h"
|
#include "component.h"
|
||||||
|
|
||||||
@@ -54,7 +55,8 @@ class OrchestrationComp
|
|||||||
Singleton::Consume<I_UpdateCommunication>,
|
Singleton::Consume<I_UpdateCommunication>,
|
||||||
Singleton::Consume<I_Downloader>,
|
Singleton::Consume<I_Downloader>,
|
||||||
Singleton::Consume<I_ManifestController>,
|
Singleton::Consume<I_ManifestController>,
|
||||||
Singleton::Consume<I_EnvDetails>
|
Singleton::Consume<I_EnvDetails>,
|
||||||
|
Singleton::Consume<I_ProxyConfiguration>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OrchestrationComp();
|
OrchestrationComp();
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public:
|
|||||||
~OrchestrationStatus();
|
~OrchestrationStatus();
|
||||||
|
|
||||||
void init() override;
|
void init() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
std::unique_ptr<Impl> pimpl;
|
std::unique_ptr<Impl> pimpl;
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public:
|
|||||||
case ResourceFileType::VIRTUAL_SETTINGS: return "virtualSettings";
|
case ResourceFileType::VIRTUAL_SETTINGS: return "virtualSettings";
|
||||||
case ResourceFileType::VIRTUAL_POLICY: return "virtualPolicy";
|
case ResourceFileType::VIRTUAL_POLICY: return "virtualPolicy";
|
||||||
default:
|
default:
|
||||||
dbgAssert(false) << "Unknown file type";
|
dbgAssert(false) << AlertInfo(AlertTeam::CORE, "update process") << "Unknown file type";
|
||||||
}
|
}
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ private:
|
|||||||
if (mapped_type.second == type) return mapped_type.first;
|
if (mapped_type.second == type) return mapped_type.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgAssert(false) << "Unsupported type " << static_cast<int>(type);
|
dbgAssert(false) << AlertInfo(AlertTeam::CORE, "packaging") << "Unsupported type " << static_cast<int>(type);
|
||||||
// Just satisfying the compiler, this return never reached
|
// Just satisfying the compiler, this return never reached
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "i_package_handler.h"
|
#include "i_package_handler.h"
|
||||||
#include "i_orchestration_tools.h"
|
#include "i_orchestration_tools.h"
|
||||||
#include "i_shell_cmd.h"
|
#include "i_shell_cmd.h"
|
||||||
|
#include "i_environment.h"
|
||||||
#include "component.h"
|
#include "component.h"
|
||||||
|
|
||||||
class PackageHandler
|
class PackageHandler
|
||||||
@@ -24,7 +25,8 @@ class PackageHandler
|
|||||||
public Component,
|
public Component,
|
||||||
Singleton::Provide<I_PackageHandler>,
|
Singleton::Provide<I_PackageHandler>,
|
||||||
Singleton::Consume<I_ShellCmd>,
|
Singleton::Consume<I_ShellCmd>,
|
||||||
Singleton::Consume<I_OrchestrationTools>
|
Singleton::Consume<I_OrchestrationTools>,
|
||||||
|
Singleton::Consume<I_Environment>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PackageHandler();
|
PackageHandler();
|
||||||
|
|||||||
@@ -7,24 +7,28 @@ static const std::string product_name = getenv("DOCKER_RPM_ENABLED") ? "CloudGua
|
|||||||
static const std::string default_cp_cert_file = "/etc/cp/cpCert.pem";
|
static const std::string default_cp_cert_file = "/etc/cp/cpCert.pem";
|
||||||
static const std::string default_cp_key_file = "/etc/cp/cpKey.key";
|
static const std::string default_cp_key_file = "/etc/cp/cpKey.key";
|
||||||
static const std::string default_rpm_conf_path = "/etc/cp/conf/rpmanager/";
|
static const std::string default_rpm_conf_path = "/etc/cp/conf/rpmanager/";
|
||||||
|
|
||||||
static const std::string default_certificate_path = "/etc/cp/rpmanager/certs";
|
static const std::string default_certificate_path = "/etc/cp/rpmanager/certs";
|
||||||
|
static const std::string default_manual_certs_path = "/etc/cp/rpmanager/manualCerts/";
|
||||||
|
static const std::string default_config_path = "/etc/cp/conf/rpmanager/servers";
|
||||||
|
static const std::string default_rpm_prepare_path = "/etc/cp/conf/rpmanager/prepare/servers";
|
||||||
|
|
||||||
|
static const std::string default_nginx_log_files_path = "/var/log/nginx/";
|
||||||
static const std::string default_additional_files_path = "/etc/cp/conf/rpmanager/include";
|
static const std::string default_additional_files_path = "/etc/cp/conf/rpmanager/include";
|
||||||
static const std::string default_server_config = "additional_server_config.conf";
|
static const std::string default_server_config = "additional_server_config.conf";
|
||||||
static const std::string default_location_config = "additional_location_config.conf";
|
static const std::string default_location_config = "additional_location_config.conf";
|
||||||
static const std::string default_trusted_ca_suffix = "_user_ca_bundle.crt";
|
static const std::string default_trusted_ca_suffix = "_user_ca_bundle.crt";
|
||||||
static const std::string default_nginx_log_files_path = "/var/log/nginx/";
|
|
||||||
static const std::string default_log_files_host_path = "/var/log/nano_agent/rpmanager/nginx_log/";
|
static const std::string default_log_files_host_path = "/var/log/nano_agent/rpmanager/nginx_log/";
|
||||||
static const std::string default_config_path = "/etc/cp/conf/rpmanager/servers";
|
|
||||||
static const std::string default_template_path = "/etc/cp/conf/rpmanager/nginx-template-clear";
|
static const std::string default_template_path = "/etc/cp/conf/rpmanager/nginx-template-clear";
|
||||||
static const std::string default_manual_certs_path = "/etc/cp/rpmanager/manualCerts/";
|
|
||||||
static const std::string default_server_certificate_path = "/etc/cp/rpmanager/certs/sslCertificate_";
|
static const std::string default_server_certificate_path = "/etc/cp/rpmanager/certs/sslCertificate_";
|
||||||
static const std::string default_server_certificate_key_path = "/etc/cp/rpmanager/certs/sslPrivateKey_";
|
static const std::string default_server_certificate_key_path = "/etc/cp/rpmanager/certs/sslPrivateKey_";
|
||||||
static const std::string default_container_name = "cp_nginx_gaia";
|
static const std::string default_container_name = "cp_nginx_gaia";
|
||||||
static const std::string default_docker_image = "cp_nginx_gaia";
|
static const std::string default_docker_image = "cp_nginx_gaia";
|
||||||
static const std::string default_nginx_config_file = "/etc/cp/conf/rpmanager/nginx.conf";
|
static const std::string default_nginx_config_file = "/etc/cp/conf/rpmanager/nginx.conf";
|
||||||
|
static const std::string default_prepare_nginx_config_file = "/etc/cp/conf/rpmanager/nginx_prepare.conf";
|
||||||
static const std::string default_global_conf_template = "/etc/cp/conf/rpmanager/nginx-conf-template";
|
static const std::string default_global_conf_template = "/etc/cp/conf/rpmanager/nginx-conf-template";
|
||||||
static const std::string default_nginx_config_include_file =
|
static const std::string default_nginx_config_include_file =
|
||||||
"/etc/cp/conf/rpmanager/servers/nginx_conf_include";
|
"/etc/cp/conf/rpmanager/servers/00_nginx_conf_include.conf";
|
||||||
static const std::string default_global_conf_include_template =
|
static const std::string default_global_conf_include_template =
|
||||||
"/etc/cp/conf/rpmanager/nginx-conf-include-template";
|
"/etc/cp/conf/rpmanager/nginx-conf-include-template";
|
||||||
static const std::string default_global_conf_include_template_no_responses =
|
static const std::string default_global_conf_include_template_no_responses =
|
||||||
|
|||||||
39
components/include/service_health_status.h
Normal file
39
components/include/service_health_status.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||||
|
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef __SERVICE_HEALTH_STATUS_H__
|
||||||
|
#define __SERVICE_HEALTH_STATUS_H__
|
||||||
|
|
||||||
|
#include "singleton.h"
|
||||||
|
#include "i_rest_api.h"
|
||||||
|
#include "i_environment.h"
|
||||||
|
#include "component.h"
|
||||||
|
|
||||||
|
class ServiceHealthStatus
|
||||||
|
:
|
||||||
|
public Component,
|
||||||
|
Singleton::Consume<I_RestApi>,
|
||||||
|
Singleton::Consume<I_Environment>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ServiceHealthStatus();
|
||||||
|
~ServiceHealthStatus();
|
||||||
|
|
||||||
|
void init() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Impl;
|
||||||
|
std::unique_ptr<Impl> pimpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __SERVICE_HEALTH_STATUS_H__
|
||||||
@@ -35,8 +35,10 @@ public:
|
|||||||
bool isOverSSL() const { return over_ssl; }
|
bool isOverSSL() const { return over_ssl; }
|
||||||
std::string getPort() const { return port; }
|
std::string getPort() const { return port; }
|
||||||
std::string getQuery() const { return query; }
|
std::string getQuery() const { return query; }
|
||||||
|
std::string getHost() const;
|
||||||
URLProtocol getProtocol() const { return protocol; }
|
URLProtocol getProtocol() const { return protocol; }
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
void setHost(const std::string &new_host);
|
||||||
void setQuery(const std::string &new_query);
|
void setQuery(const std::string &new_query);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -47,6 +49,7 @@ private:
|
|||||||
std::string base_url;
|
std::string base_url;
|
||||||
std::string port;
|
std::string port;
|
||||||
std::string query;
|
std::string query;
|
||||||
|
std::string host;
|
||||||
URLProtocol protocol;
|
URLProtocol protocol;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ private:
|
|||||||
const std::string::const_iterator &end,
|
const std::string::const_iterator &end,
|
||||||
const std::string &key) const;
|
const std::string &key) const;
|
||||||
Buffer extractKeyValueFromCookie(const std::string &cookie_value, const std::string &key) const;
|
Buffer extractKeyValueFromCookie(const std::string &cookie_value, const std::string &key) const;
|
||||||
Maybe<std::string> parseXForwardedFor(const std::string &str) const;
|
Maybe<std::string> parseXForwardedFor(const std::string &str, ExtractType type) const;
|
||||||
|
|
||||||
std::vector<UsersIdentifiersConfig> user_identifiers;
|
std::vector<UsersIdentifiersConfig> user_identifiers;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ class I_Messaging;
|
|||||||
class I_AgentDetails;
|
class I_AgentDetails;
|
||||||
class I_Encryptor;
|
class I_Encryptor;
|
||||||
|
|
||||||
|
const std::string WAAP_APPLICATION_NAME = "waap application";
|
||||||
|
|
||||||
class WaapComponent
|
class WaapComponent
|
||||||
:
|
:
|
||||||
public Component,
|
public Component,
|
||||||
|
|||||||
@@ -563,7 +563,10 @@ Packet::parsePacket(PktType type, IPType proto)
|
|||||||
return parseFromL3v6();
|
return parseFromL3v6();
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
dbgAssert(false) << "Unknown (neither IPv4, nor IPv6), or uninitialized packet type: " << proto;
|
dbgAssert(false)
|
||||||
|
<< AlertInfo(AlertTeam::CORE, "packet")
|
||||||
|
<< "Unknown (neither IPv4, nor IPv6), or uninitialized packet type: "
|
||||||
|
<< proto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ PendingKey::print(ostream &os) const
|
|||||||
size_t
|
size_t
|
||||||
PendingKey::hash() const
|
PendingKey::hash() const
|
||||||
{
|
{
|
||||||
dbgAssert(src.type != IPType::UNINITIALIZED) << "PendingKey::hash was called on an uninitialized object";
|
dbgAssert(src.type != IPType::UNINITIALIZED)
|
||||||
|
<< AlertInfo(AlertTeam::CORE, "pending key")
|
||||||
|
<< "PendingKey::hash was called on an uninitialized object";
|
||||||
size_t seed = 0;
|
size_t seed = 0;
|
||||||
hashCombine(seed, static_cast<u_char>(src.type));
|
hashCombine(seed, static_cast<u_char>(src.type));
|
||||||
hashCombine(seed, src.proto);
|
hashCombine(seed, src.proto);
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
link_directories(${BOOST_ROOT}/lib)
|
|
||||||
|
|
||||||
add_unit_test(report_messaging_ut "report_messaging_ut.cc" "report_messaging;report;messaging;singleton;-lboost_regex")
|
|
||||||
@@ -1 +1,5 @@
|
|||||||
|
include_directories(../waap/include)
|
||||||
|
include_directories(../waap/waap_clib)
|
||||||
|
include_directories(../../attachment-intakers/nginx_attachment)
|
||||||
|
|
||||||
add_library(http_geo_filter http_geo_filter.cc)
|
add_library(http_geo_filter http_geo_filter.cc)
|
||||||
|
|||||||
@@ -4,10 +4,16 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
#include "cidrs_data.h"
|
||||||
#include "generic_rulebase/generic_rulebase.h"
|
#include "generic_rulebase/generic_rulebase.h"
|
||||||
#include "generic_rulebase/parameters_config.h"
|
#include "generic_rulebase/parameters_config.h"
|
||||||
#include "generic_rulebase/triggers_config.h"
|
#include "generic_rulebase/triggers_config.h"
|
||||||
|
#include "user_identifiers_config.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "rest.h"
|
#include "rest.h"
|
||||||
@@ -21,9 +27,10 @@ USE_DEBUG_FLAG(D_GEO_FILTER);
|
|||||||
|
|
||||||
static const LogTriggerConf default_triger;
|
static const LogTriggerConf default_triger;
|
||||||
|
|
||||||
class HttpGeoFilter::Impl : public Listener<NewHttpTransactionEvent>
|
class HttpGeoFilter::Impl : public Listener<HttpRequestHeaderEvent>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void
|
void
|
||||||
init()
|
init()
|
||||||
{
|
{
|
||||||
@@ -55,32 +62,42 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
EventVerdict
|
EventVerdict
|
||||||
respond(const NewHttpTransactionEvent &event) override
|
respond(const HttpRequestHeaderEvent &event) override
|
||||||
{
|
{
|
||||||
dbgTrace(D_GEO_FILTER) << getListenerName() << " new transaction event";
|
dbgTrace(D_GEO_FILTER) << getListenerName() << " new transaction event";
|
||||||
|
|
||||||
if (!ParameterException::isGeoLocationExceptionExists() &&
|
if (!event.isLastHeader()) return EventVerdict(ngx_http_cp_verdict_e::TRAFFIC_VERDICT_INSPECT);
|
||||||
!getConfiguration<GeoConfig>("rulebase", "httpGeoFilter").ok()
|
std::set<std::string> ip_set;
|
||||||
) {
|
auto env = Singleton::Consume<I_Environment>::by<HttpGeoFilter>();
|
||||||
dbgTrace(D_GEO_FILTER) << "No geo location practice nor exception was found. Returning default verdict";
|
auto maybe_xff = env->get<std::string>(HttpTransactionData::xff_vals_ctx);
|
||||||
|
if (!maybe_xff.ok()) {
|
||||||
|
dbgTrace(D_GEO_FILTER) << "failed to get xff vals from env";
|
||||||
|
} else {
|
||||||
|
ip_set = split(maybe_xff.unpack(), ',');
|
||||||
|
}
|
||||||
|
dbgDebug(D_GEO_FILTER) << getListenerName() << " last header, start lookup";
|
||||||
|
|
||||||
|
if (ip_set.size() > 0) {
|
||||||
|
removeTrustedIpsFromXff(ip_set);
|
||||||
|
} else {
|
||||||
|
dbgDebug(D_GEO_FILTER) << "xff not found in headers";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto maybe_source_ip = env->get<IPAddr>(HttpTransactionData::client_ip_ctx);
|
||||||
|
if (!maybe_source_ip.ok()) {
|
||||||
|
dbgWarning(D_GEO_FILTER) << "failed to get source ip from env";
|
||||||
return EventVerdict(default_action);
|
return EventVerdict(default_action);
|
||||||
}
|
}
|
||||||
|
|
||||||
I_GeoLocation *i_geo_location = Singleton::Consume<I_GeoLocation>::by<HttpGeoFilter>();
|
auto source_ip = convertIpAddrToString(maybe_source_ip.unpack());
|
||||||
auto asset_location = i_geo_location->lookupLocation(event.getSourceIP());
|
ip_set.insert(source_ip);
|
||||||
if (!asset_location.ok()) {
|
|
||||||
dbgTrace(D_GEO_FILTER) << "Lookup location failed, Error: " << asset_location.getErr();
|
|
||||||
return EventVerdict(default_action);
|
|
||||||
}
|
|
||||||
|
|
||||||
EnumArray<I_GeoLocation::GeoLocationField, std::string> geo_location_data = asset_location.unpack();
|
ngx_http_cp_verdict_e exception_verdict = getExceptionVerdict(ip_set);
|
||||||
|
|
||||||
ngx_http_cp_verdict_e exception_verdict = getExceptionVerdict(event, geo_location_data);
|
|
||||||
if (exception_verdict != ngx_http_cp_verdict_e::TRAFFIC_VERDICT_IRRELEVANT) {
|
if (exception_verdict != ngx_http_cp_verdict_e::TRAFFIC_VERDICT_IRRELEVANT) {
|
||||||
return EventVerdict(exception_verdict);
|
return EventVerdict(exception_verdict);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_http_cp_verdict_e geo_lookup_verdict = getGeoLookupVerdict(event, geo_location_data);
|
ngx_http_cp_verdict_e geo_lookup_verdict = getGeoLookupVerdict(ip_set);
|
||||||
if (geo_lookup_verdict != ngx_http_cp_verdict_e::TRAFFIC_VERDICT_IRRELEVANT) {
|
if (geo_lookup_verdict != ngx_http_cp_verdict_e::TRAFFIC_VERDICT_IRRELEVANT) {
|
||||||
return EventVerdict(geo_lookup_verdict);
|
return EventVerdict(geo_lookup_verdict);
|
||||||
}
|
}
|
||||||
@@ -88,6 +105,73 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::set<std::string>
|
||||||
|
split(const std::string& s, char delim) {
|
||||||
|
std::set<std::string> elems;
|
||||||
|
std::stringstream ss(s);
|
||||||
|
std::string value;
|
||||||
|
while (std::getline(ss, value, delim)) {
|
||||||
|
elems.insert(trim(value));
|
||||||
|
}
|
||||||
|
return elems;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::string <rim(std::string &s) {
|
||||||
|
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
|
||||||
|
[] (char c) { return !std::isspace(c); }));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// trim from end
|
||||||
|
static inline std::string &rtrim(std::string &s) {
|
||||||
|
s.erase(std::find_if(s.rbegin(), s.rend(),
|
||||||
|
[] (char c) { return !std::isspace(c); }).base(), s.end());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// trim from both ends
|
||||||
|
static inline std::string &trim(std::string &s) {
|
||||||
|
return ltrim(rtrim(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
removeTrustedIpsFromXff(std::set<std::string> &xff_set)
|
||||||
|
{
|
||||||
|
auto identify_config = getConfiguration<UsersAllIdentifiersConfig>(
|
||||||
|
"rulebase",
|
||||||
|
"usersIdentifiers"
|
||||||
|
);
|
||||||
|
if (!identify_config.ok()) {
|
||||||
|
dbgDebug(D_GEO_FILTER) << "did not find users identifiers definition in policy";
|
||||||
|
} else {
|
||||||
|
auto trusted_ips = (*identify_config).getHeaderValuesFromConfig("x-forwarded-for");
|
||||||
|
for (auto it = xff_set.begin(); it != xff_set.end();) {
|
||||||
|
if (isIpTrusted(*it, trusted_ips)) {
|
||||||
|
dbgTrace(D_GEO_FILTER) << "xff value is in trusted ips: " << *it;
|
||||||
|
it = xff_set.erase(it);
|
||||||
|
} else {
|
||||||
|
dbgTrace(D_GEO_FILTER) << "xff value is not in trusted ips: " << *it;
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
isIpTrusted(const string &ip, const vector<string> &trusted_ips)
|
||||||
|
{
|
||||||
|
for (const auto &trusted_ip : trusted_ips) {
|
||||||
|
CIDRSData cidr_data(trusted_ip);
|
||||||
|
if (
|
||||||
|
ip == trusted_ip ||
|
||||||
|
(cidr_data.contains(ip))
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
convertIpAddrToString(const IPAddr &ip_to_convert)
|
convertIpAddrToString(const IPAddr &ip_to_convert)
|
||||||
{
|
{
|
||||||
@@ -117,54 +201,75 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngx_http_cp_verdict_e
|
ngx_http_cp_verdict_e
|
||||||
getGeoLookupVerdict(
|
getGeoLookupVerdict(const std::set<std::string> &sources)
|
||||||
const NewHttpTransactionEvent &event,
|
|
||||||
const EnumArray<I_GeoLocation::GeoLocationField, std::string> &geo_location_data)
|
|
||||||
{
|
{
|
||||||
auto maybe_geo_config = getConfiguration<GeoConfig>("rulebase", "httpGeoFilter");
|
auto maybe_geo_config = getConfiguration<GeoConfig>("rulebase", "httpGeoFilter");
|
||||||
if (!maybe_geo_config.ok()) {
|
if (!maybe_geo_config.ok()) {
|
||||||
dbgWarning(D_GEO_FILTER) << "Failed to load HTTP Geo Filter config. Error:" << maybe_geo_config.getErr();
|
dbgTrace(D_GEO_FILTER) << "Failed to load HTTP Geo Filter config. Error:" << maybe_geo_config.getErr();
|
||||||
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_IRRELEVANT;
|
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_IRRELEVANT;
|
||||||
}
|
}
|
||||||
GeoConfig geo_config = maybe_geo_config.unpack();
|
GeoConfig geo_config = maybe_geo_config.unpack();
|
||||||
string country_code = geo_location_data[I_GeoLocation::GeoLocationField::COUNTRY_CODE];
|
EnumArray<I_GeoLocation::GeoLocationField, std::string> geo_location_data;
|
||||||
|
I_GeoLocation *i_geo_location = Singleton::Consume<I_GeoLocation>::by<HttpGeoFilter>();
|
||||||
|
|
||||||
if (geo_config.isAllowedCountry(country_code)) {
|
for (const std::string& source : sources) {
|
||||||
dbgTrace(D_GEO_FILTER)
|
Maybe<IPAddr> maybe_source_ip = IPAddr::createIPAddr(source);
|
||||||
<< "geo verdict ACCEPT, practice id: "
|
if (!maybe_source_ip.ok()){
|
||||||
<< geo_config.getId()
|
dbgWarning(D_GEO_FILTER) <<
|
||||||
<< ", country code: "
|
"create ip address failed for source: " <<
|
||||||
<< country_code;
|
source <<
|
||||||
generateVerdictLog(
|
", Error: " <<
|
||||||
ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT,
|
maybe_source_ip.getErr();
|
||||||
event,
|
continue;
|
||||||
geo_config.getId(),
|
}
|
||||||
true,
|
auto asset_location = i_geo_location->lookupLocation(maybe_source_ip.unpack());
|
||||||
geo_location_data
|
if (!asset_location.ok()) {
|
||||||
);
|
dbgWarning(D_GEO_FILTER) <<
|
||||||
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT;
|
"Lookup location failed for source: " <<
|
||||||
}
|
source <<
|
||||||
if (geo_config.isBlockedCountry(country_code)) {
|
", Error: " <<
|
||||||
dbgTrace(D_GEO_FILTER)
|
asset_location.getErr();
|
||||||
<< "geo verdict DROP, practice id: "
|
continue;
|
||||||
<< geo_config.getId()
|
}
|
||||||
<< ", country code: "
|
|
||||||
<< country_code;
|
geo_location_data = asset_location.unpack();
|
||||||
generateVerdictLog(
|
|
||||||
ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP,
|
string country_code = geo_location_data[I_GeoLocation::GeoLocationField::COUNTRY_CODE];
|
||||||
event,
|
|
||||||
geo_config.getId(),
|
if (geo_config.isAllowedCountry(country_code)) {
|
||||||
true,
|
dbgTrace(D_GEO_FILTER)
|
||||||
geo_location_data
|
<< "geo verdict ACCEPT, practice id: "
|
||||||
);
|
<< geo_config.getId()
|
||||||
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP;
|
<< ", country code: "
|
||||||
|
<< country_code;
|
||||||
|
generateVerdictLog(
|
||||||
|
ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT,
|
||||||
|
geo_config.getId(),
|
||||||
|
true,
|
||||||
|
geo_location_data
|
||||||
|
);
|
||||||
|
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT;
|
||||||
|
}
|
||||||
|
if (geo_config.isBlockedCountry(country_code)) {
|
||||||
|
dbgTrace(D_GEO_FILTER)
|
||||||
|
<< "geo verdict DROP, practice id: "
|
||||||
|
<< geo_config.getId()
|
||||||
|
<< ", country code: "
|
||||||
|
<< country_code;
|
||||||
|
generateVerdictLog(
|
||||||
|
ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP,
|
||||||
|
geo_config.getId(),
|
||||||
|
true,
|
||||||
|
geo_location_data
|
||||||
|
);
|
||||||
|
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dbgTrace(D_GEO_FILTER)
|
dbgTrace(D_GEO_FILTER)
|
||||||
<< "No matched practice. Returned default action: "
|
<< "No matched practice. Returned default action: "
|
||||||
<< geo_config.getDefaultAction();
|
<< geo_config.getDefaultAction();
|
||||||
generateVerdictLog(
|
generateVerdictLog(
|
||||||
convertActionToVerdict(geo_config.getDefaultAction()),
|
convertActionToVerdict(geo_config.getDefaultAction()),
|
||||||
event,
|
|
||||||
geo_config.getId(),
|
geo_config.getId(),
|
||||||
true,
|
true,
|
||||||
geo_location_data,
|
geo_location_data,
|
||||||
@@ -176,7 +281,6 @@ private:
|
|||||||
Maybe<pair<ngx_http_cp_verdict_e, string>>
|
Maybe<pair<ngx_http_cp_verdict_e, string>>
|
||||||
getBehaviorsVerdict(
|
getBehaviorsVerdict(
|
||||||
const unordered_map<string, set<string>> &behaviors_map_to_search,
|
const unordered_map<string, set<string>> &behaviors_map_to_search,
|
||||||
const NewHttpTransactionEvent &event,
|
|
||||||
EnumArray<I_GeoLocation::GeoLocationField, std::string> geo_location_data)
|
EnumArray<I_GeoLocation::GeoLocationField, std::string> geo_location_data)
|
||||||
{
|
{
|
||||||
bool is_matched = false;
|
bool is_matched = false;
|
||||||
@@ -193,7 +297,6 @@ private:
|
|||||||
dbgTrace(D_GEO_FILTER) << "behavior verdict: DROP, exception id: " << behavior.getId();
|
dbgTrace(D_GEO_FILTER) << "behavior verdict: DROP, exception id: " << behavior.getId();
|
||||||
generateVerdictLog(
|
generateVerdictLog(
|
||||||
matched_verdict,
|
matched_verdict,
|
||||||
event,
|
|
||||||
behavior.getId(),
|
behavior.getId(),
|
||||||
false,
|
false,
|
||||||
geo_location_data
|
geo_location_data
|
||||||
@@ -218,63 +321,74 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngx_http_cp_verdict_e
|
ngx_http_cp_verdict_e
|
||||||
getExceptionVerdict(
|
getExceptionVerdict(const std::set<std::string> &sources) {
|
||||||
const NewHttpTransactionEvent &event,
|
|
||||||
EnumArray<I_GeoLocation::GeoLocationField, std::string> geo_location_data
|
|
||||||
){
|
|
||||||
string country_code = geo_location_data[I_GeoLocation::GeoLocationField::COUNTRY_CODE];
|
|
||||||
string country_name = geo_location_data[I_GeoLocation::GeoLocationField::COUNTRY_NAME];
|
|
||||||
string source_ip = convertIpAddrToString(event.getSourceIP());
|
|
||||||
|
|
||||||
pair<ngx_http_cp_verdict_e, string> curr_matched_behavior;
|
pair<ngx_http_cp_verdict_e, string> curr_matched_behavior;
|
||||||
ngx_http_cp_verdict_e verdict = ngx_http_cp_verdict_e::TRAFFIC_VERDICT_IRRELEVANT;
|
ngx_http_cp_verdict_e verdict = ngx_http_cp_verdict_e::TRAFFIC_VERDICT_IRRELEVANT;
|
||||||
|
I_GeoLocation *i_geo_location = Singleton::Consume<I_GeoLocation>::by<HttpGeoFilter>();
|
||||||
|
EnumArray<I_GeoLocation::GeoLocationField, std::string> geo_location_data;
|
||||||
|
|
||||||
dbgTrace(D_GEO_FILTER)
|
for (const std::string& source : sources) {
|
||||||
|
|
||||||
|
Maybe<IPAddr> maybe_source_ip = IPAddr::createIPAddr(source);
|
||||||
|
if (!maybe_source_ip.ok()){
|
||||||
|
dbgWarning(D_GEO_FILTER) <<
|
||||||
|
"create ip address failed for source: " <<
|
||||||
|
source <<
|
||||||
|
", Error: " <<
|
||||||
|
maybe_source_ip.getErr();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto asset_location = i_geo_location->lookupLocation(maybe_source_ip.unpack());
|
||||||
|
if (!asset_location.ok()) {
|
||||||
|
dbgWarning(D_GEO_FILTER) << "Lookup location failed for source: " <<
|
||||||
|
source <<
|
||||||
|
", Error: " <<
|
||||||
|
asset_location.getErr();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
geo_location_data = asset_location.unpack();
|
||||||
|
string country_code = geo_location_data[I_GeoLocation::GeoLocationField::COUNTRY_CODE];
|
||||||
|
string country_name = geo_location_data[I_GeoLocation::GeoLocationField::COUNTRY_NAME];
|
||||||
|
dbgTrace(D_GEO_FILTER)
|
||||||
<< "Get exception verdict. "
|
<< "Get exception verdict. "
|
||||||
<< "country code: "
|
<< "country code: "
|
||||||
<< country_code
|
<< country_code
|
||||||
<< ", country name: "
|
<< ", country name: "
|
||||||
<< country_name
|
<< country_name
|
||||||
<< ", source ip address: "
|
<< ", source ip address: "
|
||||||
<< source_ip;
|
<< source;
|
||||||
|
|
||||||
unordered_map<string, set<string>> exception_value_source_ip = {{"sourceIP", {source_ip}}};
|
unordered_map<string, set<string>> exception_value_country_code = {
|
||||||
auto matched_behavior_maybe = getBehaviorsVerdict(exception_value_source_ip, event, geo_location_data);
|
{"countryCode", {country_code}}
|
||||||
if (matched_behavior_maybe.ok()) {
|
};
|
||||||
curr_matched_behavior = matched_behavior_maybe.unpack();
|
auto matched_behavior_maybe = getBehaviorsVerdict(exception_value_country_code, geo_location_data);
|
||||||
verdict = curr_matched_behavior.first;
|
if (matched_behavior_maybe.ok()) {
|
||||||
if (verdict == ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP) {
|
curr_matched_behavior = matched_behavior_maybe.unpack();
|
||||||
return verdict;
|
verdict = curr_matched_behavior.first;
|
||||||
|
if (verdict == ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP) {
|
||||||
|
return verdict;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_map<string, set<string>> exception_value_country_name = {
|
||||||
|
{"countryName", {country_name}}
|
||||||
|
};
|
||||||
|
matched_behavior_maybe = getBehaviorsVerdict(exception_value_country_name, geo_location_data);
|
||||||
|
if (matched_behavior_maybe.ok()) {
|
||||||
|
curr_matched_behavior = matched_behavior_maybe.unpack();
|
||||||
|
verdict = curr_matched_behavior.first;
|
||||||
|
if (verdict == ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP) {
|
||||||
|
return verdict;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unordered_map<string, set<string>> exception_value_country_code = {
|
|
||||||
{"countryCode", {country_code}}
|
|
||||||
};
|
|
||||||
matched_behavior_maybe = getBehaviorsVerdict(exception_value_country_code, event, geo_location_data);
|
|
||||||
if (matched_behavior_maybe.ok()) {
|
|
||||||
curr_matched_behavior = matched_behavior_maybe.unpack();
|
|
||||||
verdict = curr_matched_behavior.first;
|
|
||||||
if (verdict == ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP) {
|
|
||||||
return verdict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unordered_map<string, set<string>> exception_value_country_name = {
|
|
||||||
{"countryName", {country_name}}
|
|
||||||
};
|
|
||||||
matched_behavior_maybe = getBehaviorsVerdict(exception_value_country_name, event, geo_location_data);
|
|
||||||
if (matched_behavior_maybe.ok()) {
|
|
||||||
curr_matched_behavior = matched_behavior_maybe.unpack();
|
|
||||||
verdict = curr_matched_behavior.first;
|
|
||||||
if (verdict == ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP) {
|
|
||||||
return verdict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (verdict == ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT) {
|
if (verdict == ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT) {
|
||||||
generateVerdictLog(
|
generateVerdictLog(
|
||||||
verdict,
|
verdict,
|
||||||
event,
|
|
||||||
curr_matched_behavior.second,
|
curr_matched_behavior.second,
|
||||||
false,
|
false,
|
||||||
geo_location_data
|
geo_location_data
|
||||||
@@ -286,7 +400,6 @@ private:
|
|||||||
void
|
void
|
||||||
generateVerdictLog(
|
generateVerdictLog(
|
||||||
const ngx_http_cp_verdict_e &verdict,
|
const ngx_http_cp_verdict_e &verdict,
|
||||||
const NewHttpTransactionEvent &event,
|
|
||||||
const string &matched_id,
|
const string &matched_id,
|
||||||
bool is_geo_filter,
|
bool is_geo_filter,
|
||||||
const EnumArray<I_GeoLocation::GeoLocationField, std::string> geo_location_data,
|
const EnumArray<I_GeoLocation::GeoLocationField, std::string> geo_location_data,
|
||||||
@@ -307,14 +420,27 @@ private:
|
|||||||
LogField(matched_on, matched_id),
|
LogField(matched_on, matched_id),
|
||||||
ReportIS::Tags::HTTP_GEO_FILTER
|
ReportIS::Tags::HTTP_GEO_FILTER
|
||||||
);
|
);
|
||||||
log
|
auto env = Singleton::Consume<I_Environment>::by<HttpGeoFilter>();
|
||||||
<< LogField("sourceIP", convertIpAddrToString(event.getSourceIP()))
|
auto source_ip = env->get<IPAddr>(HttpTransactionData::client_ip_ctx);
|
||||||
<< LogField("sourcePort", event.getSourcePort())
|
if (source_ip.ok()) log << LogField("sourceIP", convertIpAddrToString(source_ip.unpack()));
|
||||||
<< LogField("hostName", event.getDestinationHost())
|
|
||||||
<< LogField("httpMethod", event.getHttpMethod())
|
auto source_identifier = env->get<string>(HttpTransactionData::source_identifier);
|
||||||
<< LogField("securityAction", is_prevent ? "Prevent" : "Detect");
|
if (source_identifier.ok()) log << LogField("httpSourceId", source_identifier.unpack());
|
||||||
|
|
||||||
|
auto source_port = env->get<string>(HttpTransactionData::client_port_ctx);
|
||||||
|
if (source_port.ok()) log << LogField("sourcePort", source_port.unpack());
|
||||||
|
|
||||||
|
auto host_name = env->get<string>(HttpTransactionData::host_name_ctx);
|
||||||
|
if (host_name.ok()) log << LogField("hostName", host_name.unpack());
|
||||||
|
|
||||||
|
auto method = env->get<string>(HttpTransactionData::method_ctx);
|
||||||
|
if (method.ok()) log << LogField("httpMethod", method.unpack());
|
||||||
|
|
||||||
|
log << LogField("securityAction", is_prevent ? "Prevent" : "Detect");
|
||||||
|
|
||||||
if (is_default_action) log << LogField("isDefaultSecurityAction", true);
|
if (is_default_action) log << LogField("isDefaultSecurityAction", true);
|
||||||
|
auto xff = env->get<string>(HttpTransactionData::xff_vals_ctx);
|
||||||
|
if (xff.ok()) log << LogField("proxyIP", xff.unpack());
|
||||||
|
|
||||||
log
|
log
|
||||||
<< LogField("sourceCountryCode", geo_location_data[I_GeoLocation::GeoLocationField::COUNTRY_CODE])
|
<< LogField("sourceCountryCode", geo_location_data[I_GeoLocation::GeoLocationField::COUNTRY_CODE])
|
||||||
@@ -343,5 +469,6 @@ void
|
|||||||
HttpGeoFilter::preload()
|
HttpGeoFilter::preload()
|
||||||
{
|
{
|
||||||
registerExpectedConfiguration<GeoConfig>("rulebase", "httpGeoFilter");
|
registerExpectedConfiguration<GeoConfig>("rulebase", "httpGeoFilter");
|
||||||
|
registerExpectedConfiguration<UsersAllIdentifiersConfig>("rulebase", "usersIdentifiers");
|
||||||
registerConfigLoadCb([this]() { pimpl->loadDefaultAction(); });
|
registerConfigLoadCb([this]() { pimpl->loadDefaultAction(); });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,10 @@ CompoundProtection::Impl::getMatch(const set<PMPattern> &matched) const
|
|||||||
case Operation::ORDERED_AND: return getMatchOrderedAnd(matched);
|
case Operation::ORDERED_AND: return getMatchOrderedAnd(matched);
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgAssert(false) << "Unknown compound operation: " << static_cast<uint>(operation);
|
dbgAssert(false)
|
||||||
|
<< AlertInfo(AlertTeam::CORE, "ips")
|
||||||
|
<< "Unknown compound operation: "
|
||||||
|
<< static_cast<uint>(operation);
|
||||||
return MatchType::NO_MATCH;
|
return MatchType::NO_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,9 +50,13 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void readRules(cereal::JSONInputArchive &ar);
|
void readRules(cereal::JSONInputArchive &ar);
|
||||||
|
void readTriggerId(cereal::JSONInputArchive &ar);
|
||||||
|
void readExceptionId(cereal::JSONInputArchive &ar);
|
||||||
void readDefaultAction(cereal::JSONInputArchive &ar);
|
void readDefaultAction(cereal::JSONInputArchive &ar);
|
||||||
|
|
||||||
std::vector<Rule> rules;
|
std::vector<Rule> rules;
|
||||||
|
std::string trigger_id;
|
||||||
|
std::string exception_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __IPS_BASIC_POLICY_H__
|
#endif // __IPS_BASIC_POLICY_H__
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "log_generator.h"
|
#include "log_generator.h"
|
||||||
#include "parsed_context.h"
|
#include "parsed_context.h"
|
||||||
#include "pm_hook.h"
|
#include "pm_hook.h"
|
||||||
|
#include "i_generic_rulebase.h"
|
||||||
|
|
||||||
/// \namespace IPSSignatureSubTypes
|
/// \namespace IPSSignatureSubTypes
|
||||||
/// \brief Namespace containing subtypes for IPS signatures.
|
/// \brief Namespace containing subtypes for IPS signatures.
|
||||||
@@ -348,8 +349,16 @@ public:
|
|||||||
/// \brief Construct a SignatureAndAction object.
|
/// \brief Construct a SignatureAndAction object.
|
||||||
/// \param _signature The complete signature.
|
/// \param _signature The complete signature.
|
||||||
/// \param _action The signature action.
|
/// \param _action The signature action.
|
||||||
SignatureAndAction(std::shared_ptr<CompleteSignature> _signature, SignatureAction _action) :
|
SignatureAndAction(
|
||||||
signature(_signature), action(_action)
|
std::shared_ptr<CompleteSignature> _signature,
|
||||||
|
SignatureAction _action,
|
||||||
|
std::string _trigger_id,
|
||||||
|
std::string _exception_id)
|
||||||
|
:
|
||||||
|
signature(_signature),
|
||||||
|
action(_action),
|
||||||
|
trigger_id(_trigger_id),
|
||||||
|
exception_id(_exception_id)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// \brief Check if the signature is matched for prevention.
|
/// \brief Check if the signature is matched for prevention.
|
||||||
@@ -375,6 +384,11 @@ public:
|
|||||||
return signature->getContext();
|
return signature->getContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogTriggerConf getTrigger() const;
|
||||||
|
|
||||||
|
std::set<ParameterBehavior>
|
||||||
|
getBehavior(const std::unordered_map<std::string, std::set<std::string>> &exceptions_dict) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// \brief Get the action results for the IPS state.
|
/// \brief Get the action results for the IPS state.
|
||||||
/// \param ips_state The IPS entry.
|
/// \param ips_state The IPS entry.
|
||||||
@@ -382,6 +396,8 @@ private:
|
|||||||
|
|
||||||
std::shared_ptr<CompleteSignature> signature;
|
std::shared_ptr<CompleteSignature> signature;
|
||||||
SignatureAction action;
|
SignatureAction action;
|
||||||
|
std::string trigger_id;
|
||||||
|
std::string exception_id;
|
||||||
};
|
};
|
||||||
} // namespace IPSSignatureSubTypes
|
} // namespace IPSSignatureSubTypes
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
IPSSignatureSubTypes::SignatureAction action = IPSSignatureSubTypes::SignatureAction::IGNORE;
|
IPSSignatureSubTypes::SignatureAction action = IPSSignatureSubTypes::SignatureAction::IGNORE;
|
||||||
std::vector<std::string> file_names;
|
std::vector<std::string> file_names;
|
||||||
|
std::string trigger_id;
|
||||||
|
std::string exception_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __SNORT_BASIC_POLICY_H__
|
#endif // __SNORT_BASIC_POLICY_H__
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ void
|
|||||||
RuleSelector::load(cereal::JSONInputArchive &ar)
|
RuleSelector::load(cereal::JSONInputArchive &ar)
|
||||||
{
|
{
|
||||||
readRules(ar);
|
readRules(ar);
|
||||||
|
readTriggerId(ar);
|
||||||
|
readExceptionId(ar);
|
||||||
readDefaultAction(ar);
|
readDefaultAction(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +38,7 @@ RuleSelector::selectSignatures() const
|
|||||||
if (rule.isSignaturedMatched(*signature)) {
|
if (rule.isSignaturedMatched(*signature)) {
|
||||||
if (rule.getAction() != IPSSignatureSubTypes::SignatureAction::IGNORE) {
|
if (rule.getAction() != IPSSignatureSubTypes::SignatureAction::IGNORE) {
|
||||||
signature->setIndicators("Check Point", signatures_version);
|
signature->setIndicators("Check Point", signatures_version);
|
||||||
res.emplace_back(signature, rule.getAction());
|
res.emplace_back(signature, rule.getAction(), trigger_id, exception_id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -52,6 +54,28 @@ RuleSelector::readRules(cereal::JSONInputArchive &ar)
|
|||||||
ar(cereal::make_nvp("rules", rules));
|
ar(cereal::make_nvp("rules", rules));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RuleSelector::readTriggerId(cereal::JSONInputArchive &ar)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
ar(cereal::make_nvp("triggers", trigger_id));
|
||||||
|
} catch (const cereal::Exception &e) {
|
||||||
|
ar.setNextName(nullptr);
|
||||||
|
trigger_id = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RuleSelector::readExceptionId(cereal::JSONInputArchive &ar)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
ar(cereal::make_nvp("exceptions", exception_id));
|
||||||
|
} catch (const cereal::Exception &e) {
|
||||||
|
ar.setNextName(nullptr);
|
||||||
|
exception_id = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RuleSelector::readDefaultAction(cereal::JSONInputArchive &ar)
|
RuleSelector::readDefaultAction(cereal::JSONInputArchive &ar)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ IPSConfiguration::Context::Context(ContextType _type, uint history) : type(_type
|
|||||||
uint
|
uint
|
||||||
IPSConfiguration::Context::getHistorySize() const
|
IPSConfiguration::Context::getHistorySize() const
|
||||||
{
|
{
|
||||||
dbgAssert(type == ContextType::HISTORY) << "Try to access history size for non-history context";
|
dbgAssert(type == ContextType::HISTORY)
|
||||||
|
<< AlertInfo(AlertTeam::CORE, "ips")
|
||||||
|
<< "Try to access history size for non-history context";
|
||||||
return history_size;
|
return history_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +71,8 @@ uint
|
|||||||
IPSConfiguration::getHistorySize(const string &name) const
|
IPSConfiguration::getHistorySize(const string &name) const
|
||||||
{
|
{
|
||||||
auto context = context_config.find(name);
|
auto context = context_config.find(name);
|
||||||
dbgAssert(context != context_config.end()) << "Try to access history size for non-exiting context";
|
dbgAssert(context != context_config.end())
|
||||||
|
<< AlertInfo(AlertTeam::CORE, "ips")
|
||||||
|
<< "Try to access history size for non-exiting context";
|
||||||
return context->second.getHistorySize();
|
return context->second.getHistorySize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ static const map<string, IPSConfiguration::Context> default_conf_mapping = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const IPSConfiguration default_conf(default_conf_mapping);
|
static const IPSConfiguration default_conf(default_conf_mapping);
|
||||||
|
static const IPSSignatures default_ips_sigs;
|
||||||
|
static const SnortSignatures default_snort_sigs;
|
||||||
|
|
||||||
IPSEntry::IPSEntry() : TableOpaqueSerialize<IPSEntry>(this) {}
|
IPSEntry::IPSEntry() : TableOpaqueSerialize<IPSEntry>(this) {}
|
||||||
|
|
||||||
@@ -51,9 +53,9 @@ IPSEntry::respond(const ParsedContext &parsed)
|
|||||||
ctx.registerValue(name, buf);
|
ctx.registerValue(name, buf);
|
||||||
|
|
||||||
ctx.activate();
|
ctx.activate();
|
||||||
auto &signatures = getConfigurationWithDefault(IPSSignatures(), "IPS", "IpsProtections");
|
auto &signatures = getConfigurationWithDefault(default_ips_sigs, "IPS", "IpsProtections");
|
||||||
bool should_drop = signatures.isMatchedPrevent(parsed.getName(), buf);
|
bool should_drop = signatures.isMatchedPrevent(parsed.getName(), buf);
|
||||||
auto &snort_signatures = getConfigurationWithDefault(SnortSignatures(), "IPSSnortSigs", "SnortProtections");
|
auto &snort_signatures = getConfigurationWithDefault(default_snort_sigs, "IPSSnortSigs", "SnortProtections");
|
||||||
should_drop |= snort_signatures.isMatchedPrevent(parsed.getName(), buf);
|
should_drop |= snort_signatures.isMatchedPrevent(parsed.getName(), buf);
|
||||||
ctx.deactivate();
|
ctx.deactivate();
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ IPSSignatureMetaData::getSeverityString() const
|
|||||||
return "Critical";
|
return "Critical";
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgAssert(false) << "Illegal severity value: " << static_cast<uint>(severity);
|
dbgAssert(false) << AlertInfo(AlertTeam::CORE, "ips") << "Illegal severity value: " << static_cast<uint>(severity);
|
||||||
return "Critical";
|
return "Critical";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +116,10 @@ IPSSignatureMetaData::getPerformanceString() const
|
|||||||
return "Critical";
|
return "Critical";
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgAssert(false) << "Illegal performance value: " << static_cast<uint>(performance);
|
dbgAssert(false)
|
||||||
|
<< AlertInfo(AlertTeam::CORE, "ips")
|
||||||
|
<< "Illegal performance value: "
|
||||||
|
<< static_cast<uint>(performance);
|
||||||
return "Critical";
|
return "Critical";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,8 +283,7 @@ SignatureAndAction::getAction(const IPSEntry &ips_state) const
|
|||||||
exceptions_dict["sourceIdentifier"].insert(*env_source_identifier);
|
exceptions_dict["sourceIdentifier"].insert(*env_source_identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
I_GenericRulebase *i_rulebase = Singleton::Consume<I_GenericRulebase>::by<IPSComp>();
|
auto behaviors = getBehavior(exceptions_dict);
|
||||||
auto behaviors = i_rulebase->getBehavior(exceptions_dict);
|
|
||||||
|
|
||||||
set<BehaviorValue> override_actions;
|
set<BehaviorValue> override_actions;
|
||||||
vector<string> override_ids;
|
vector<string> override_ids;
|
||||||
@@ -315,6 +317,23 @@ static const auto url_query = LogTriggerConf::WebLogFields::webUrlQuery;
|
|||||||
static const auto res_body = LogTriggerConf::WebLogFields::responseBody;
|
static const auto res_body = LogTriggerConf::WebLogFields::responseBody;
|
||||||
static const auto res_code = LogTriggerConf::WebLogFields::responseCode;
|
static const auto res_code = LogTriggerConf::WebLogFields::responseCode;
|
||||||
|
|
||||||
|
LogTriggerConf
|
||||||
|
SignatureAndAction::getTrigger() const
|
||||||
|
{
|
||||||
|
if (trigger_id.empty()) return getConfigurationWithDefault(LogTriggerConf(), "rulebase", "log");
|
||||||
|
|
||||||
|
return Singleton::Consume<I_GenericRulebase>::by<IPSComp>()->getLogTriggerConf(trigger_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
set<ParameterBehavior>
|
||||||
|
SignatureAndAction::getBehavior(const unordered_map<string, set<string>> &exceptions_dict) const
|
||||||
|
{
|
||||||
|
I_GenericRulebase *i_rulebase = Singleton::Consume<I_GenericRulebase>::by<IPSComp>();
|
||||||
|
if (exception_id.empty()) return i_rulebase->getBehavior(exceptions_dict);
|
||||||
|
|
||||||
|
return i_rulebase->getParameterException(exception_id).getBehavior(exceptions_dict);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SignatureAndAction::matchSilent(const Buffer &sample) const
|
SignatureAndAction::matchSilent(const Buffer &sample) const
|
||||||
{
|
{
|
||||||
@@ -398,7 +417,7 @@ SignatureAndAction::isMatchedPrevent(const Buffer &context_buffer, const set<PMP
|
|||||||
|
|
||||||
dbgDebug(D_IPS) << "Signature matched - sending log";
|
dbgDebug(D_IPS) << "Signature matched - sending log";
|
||||||
|
|
||||||
auto &trigger = getConfigurationWithDefault(default_triger, "rulebase", "log");
|
auto trigger = getTrigger();
|
||||||
bool is_prevent = get<0>(override_action) == IPSSignatureSubTypes::SignatureAction::PREVENT;
|
bool is_prevent = get<0>(override_action) == IPSSignatureSubTypes::SignatureAction::PREVENT;
|
||||||
|
|
||||||
auto severity = signature->getSeverity() < IPSLevel::HIGH ? Severity::HIGH : Severity::CRITICAL;
|
auto severity = signature->getSeverity() < IPSLevel::HIGH ? Severity::HIGH : Severity::CRITICAL;
|
||||||
|
|||||||
@@ -596,6 +596,8 @@ TEST_F(ComponentTest, check_filtering_by_year)
|
|||||||
|
|
||||||
TEST_F(ComponentTest, log_fields)
|
TEST_F(ComponentTest, log_fields)
|
||||||
{
|
{
|
||||||
|
generic_rulebase.preload();
|
||||||
|
generic_rulebase.init();
|
||||||
string config =
|
string config =
|
||||||
"{"
|
"{"
|
||||||
"\"IPS\": {"
|
"\"IPS\": {"
|
||||||
@@ -632,6 +634,8 @@ TEST_F(ComponentTest, log_fields)
|
|||||||
"\"assetId\": \"1-1-1\","
|
"\"assetId\": \"1-1-1\","
|
||||||
"\"practiceId\": \"2-2-2\","
|
"\"practiceId\": \"2-2-2\","
|
||||||
"\"practiceName\": \"practice1\","
|
"\"practiceName\": \"practice1\","
|
||||||
|
"\"triggers\": \"5eaeefde6765c30010bae8b6\","
|
||||||
|
"\"exceptions\": \"\","
|
||||||
"\"defaultAction\": \"Detect\","
|
"\"defaultAction\": \"Detect\","
|
||||||
"\"rules\": ["
|
"\"rules\": ["
|
||||||
"{"
|
"{"
|
||||||
@@ -643,10 +647,36 @@ TEST_F(ComponentTest, log_fields)
|
|||||||
"]"
|
"]"
|
||||||
"}"
|
"}"
|
||||||
"]"
|
"]"
|
||||||
|
"},"
|
||||||
|
"\"rulebase\": {"
|
||||||
|
"\"log\": ["
|
||||||
|
"{"
|
||||||
|
"\"context\": \"triggerId(5eaeefde6765c30010bae8b6)\","
|
||||||
|
"\"triggerName\": \"Logging Trigger\","
|
||||||
|
"\"triggerType\": \"log\","
|
||||||
|
"\"urlForSyslog\": \"\","
|
||||||
|
"\"urlForCef\": \"128.1.1.1:333\","
|
||||||
|
"\"acAllow\": false,"
|
||||||
|
"\"acDrop\": true,"
|
||||||
|
"\"complianceViolations\": true,"
|
||||||
|
"\"complianceWarnings\": true,"
|
||||||
|
"\"logToAgent\": true,"
|
||||||
|
"\"logToCloud\": true,"
|
||||||
|
"\"logToSyslog\": false,"
|
||||||
|
"\"logToCef\": true,"
|
||||||
|
"\"tpDetect\": true,"
|
||||||
|
"\"tpPrevent\": true,"
|
||||||
|
"\"verbosity\": \"Standard\","
|
||||||
|
"\"webBody\": true,"
|
||||||
|
"\"webHeaders\": true,"
|
||||||
|
"\"webRequests\": true,"
|
||||||
|
"\"webUrlPath\": true,"
|
||||||
|
"\"webUrlQuery\": true"
|
||||||
|
"}"
|
||||||
|
"]"
|
||||||
"}"
|
"}"
|
||||||
"}";
|
"}";
|
||||||
loadPolicy(config);
|
loadPolicy(config);
|
||||||
setTrigger();
|
|
||||||
|
|
||||||
EXPECT_CALL(table, createStateRValueRemoved(_, _));
|
EXPECT_CALL(table, createStateRValueRemoved(_, _));
|
||||||
EXPECT_CALL(table, getState(_)).WillRepeatedly(Return(&entry));
|
EXPECT_CALL(table, getState(_)).WillRepeatedly(Return(&entry));
|
||||||
@@ -829,6 +859,8 @@ TEST_F(ComponentTest, prxeem_exception_bug)
|
|||||||
" \"practiceId\": \"2-2-2\","
|
" \"practiceId\": \"2-2-2\","
|
||||||
" \"practiceName\": \"practice1\","
|
" \"practiceName\": \"practice1\","
|
||||||
" \"defaultAction\": \"Prevent\","
|
" \"defaultAction\": \"Prevent\","
|
||||||
|
" \"triggers\": \"\","
|
||||||
|
" \"exceptions\": \"6c3867be-4da5-42c2-93dc-8f509a764004\","
|
||||||
" \"rules\": []"
|
" \"rules\": []"
|
||||||
" }"
|
" }"
|
||||||
" ]"
|
" ]"
|
||||||
@@ -847,6 +879,11 @@ TEST_F(ComponentTest, prxeem_exception_bug)
|
|||||||
" \"parameterId\": \"6c3867be-4da5-42c2-93dc-8f509a764003\","
|
" \"parameterId\": \"6c3867be-4da5-42c2-93dc-8f509a764003\","
|
||||||
" \"parameterType\": \"exceptions\","
|
" \"parameterType\": \"exceptions\","
|
||||||
" \"parameterName\": \"exception\""
|
" \"parameterName\": \"exception\""
|
||||||
|
" },"
|
||||||
|
" {"
|
||||||
|
" \"parameterId\": \"6c3867be-4da5-42c2-93dc-8f509a764004\","
|
||||||
|
" \"parameterType\": \"exceptions\","
|
||||||
|
" \"parameterName\": \"exception\""
|
||||||
" }"
|
" }"
|
||||||
" ],"
|
" ],"
|
||||||
" \"zoneId\": \"\","
|
" \"zoneId\": \"\","
|
||||||
@@ -855,7 +892,7 @@ TEST_F(ComponentTest, prxeem_exception_bug)
|
|||||||
" ],"
|
" ],"
|
||||||
" \"exception\": ["
|
" \"exception\": ["
|
||||||
" {"
|
" {"
|
||||||
" \"context\": \"parameterId(6c3867be-4da5-42c2-93dc-8f509a764003)\","
|
" \"context\": \"parameterId(6c3867be-4da5-42c2-93dc-8f509a764004)\","
|
||||||
" \"match\": {"
|
" \"match\": {"
|
||||||
" \"type\": \"operator\","
|
" \"type\": \"operator\","
|
||||||
" \"op\": \"and\","
|
" \"op\": \"and\","
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ TEST(configuration, basic_context)
|
|||||||
|
|
||||||
IPSConfiguration::Context ctx1(IPSConfiguration::ContextType::HISTORY, 254);
|
IPSConfiguration::Context ctx1(IPSConfiguration::ContextType::HISTORY, 254);
|
||||||
EXPECT_EQ(ctx1.getType(), IPSConfiguration::ContextType::HISTORY);
|
EXPECT_EQ(ctx1.getType(), IPSConfiguration::ContextType::HISTORY);
|
||||||
EXPECT_EQ(ctx1.getHistorySize(), 254);
|
EXPECT_EQ(ctx1.getHistorySize(), 254u);
|
||||||
|
|
||||||
IPSConfiguration::Context ctx2(IPSConfiguration::ContextType::NORMAL, 0);
|
IPSConfiguration::Context ctx2(IPSConfiguration::ContextType::NORMAL, 0);
|
||||||
EXPECT_EQ(ctx2.getType(), IPSConfiguration::ContextType::NORMAL);
|
EXPECT_EQ(ctx2.getType(), IPSConfiguration::ContextType::NORMAL);
|
||||||
@@ -42,7 +42,7 @@ TEST(configuration, read_configuration)
|
|||||||
|
|
||||||
auto body = conf.getContext("HTTP_REQUEST_BODY");
|
auto body = conf.getContext("HTTP_REQUEST_BODY");
|
||||||
EXPECT_EQ(body.getType(), IPSConfiguration::ContextType::HISTORY);
|
EXPECT_EQ(body.getType(), IPSConfiguration::ContextType::HISTORY);
|
||||||
EXPECT_EQ(conf.getHistorySize("HTTP_REQUEST_BODY"), 100);
|
EXPECT_EQ(conf.getHistorySize("HTTP_REQUEST_BODY"), 100u);
|
||||||
|
|
||||||
auto header = conf.getContext("HTTP_REQUEST_HEADER");
|
auto header = conf.getContext("HTTP_REQUEST_HEADER");
|
||||||
EXPECT_EQ(header.getType(), IPSConfiguration::ContextType::KEEP);
|
EXPECT_EQ(header.getType(), IPSConfiguration::ContextType::KEEP);
|
||||||
|
|||||||
@@ -137,8 +137,8 @@ private:
|
|||||||
TEST_F(EntryTest, basic_inherited_functions)
|
TEST_F(EntryTest, basic_inherited_functions)
|
||||||
{
|
{
|
||||||
EXPECT_EQ(IPSEntry::name(), "IPS");
|
EXPECT_EQ(IPSEntry::name(), "IPS");
|
||||||
EXPECT_EQ(IPSEntry::currVer(), 0);
|
EXPECT_EQ(IPSEntry::currVer(), 0u);
|
||||||
EXPECT_EQ(IPSEntry::minVer(), 0);
|
EXPECT_EQ(IPSEntry::minVer(), 0u);
|
||||||
EXPECT_NE(IPSEntry::prototype(), nullptr);
|
EXPECT_NE(IPSEntry::prototype(), nullptr);
|
||||||
EXPECT_EQ(entry.getListenerName(), IPSEntry::name());
|
EXPECT_EQ(entry.getListenerName(), IPSEntry::name());
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ TEST(resources, basic_resource)
|
|||||||
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(resource);
|
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(resource);
|
||||||
|
|
||||||
auto loaded_resources = getSettingWithDefault(IPSSignaturesResource(), "IPS", "protections");
|
auto loaded_resources = getSettingWithDefault(IPSSignaturesResource(), "IPS", "protections");
|
||||||
EXPECT_EQ(loaded_resources.getSignatures().size(), 2);
|
EXPECT_EQ(loaded_resources.getSignatures().size(), 2u);
|
||||||
auto version = getSettingWithDefault<string>("", "IPS", "VersionId");
|
auto version = getSettingWithDefault<string>("", "IPS", "VersionId");
|
||||||
EXPECT_EQ(version, "1234567");
|
EXPECT_EQ(version, "1234567");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,19 @@ using namespace std;
|
|||||||
void
|
void
|
||||||
SnortRuleSelector::load(cereal::JSONInputArchive &ar)
|
SnortRuleSelector::load(cereal::JSONInputArchive &ar)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
|
ar(cereal::make_nvp("triggers", trigger_id));
|
||||||
|
} catch (const cereal::Exception &e) {
|
||||||
|
ar.setNextName(nullptr);
|
||||||
|
trigger_id = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
ar(cereal::make_nvp("exceptions", exception_id));
|
||||||
|
} catch (const cereal::Exception &e) {
|
||||||
|
ar.setNextName(nullptr);
|
||||||
|
exception_id = "";
|
||||||
|
}
|
||||||
string mode;
|
string mode;
|
||||||
ar(cereal::make_nvp("mode", mode), cereal::make_nvp("files", file_names));
|
ar(cereal::make_nvp("mode", mode), cereal::make_nvp("files", file_names));
|
||||||
|
|
||||||
@@ -38,7 +51,7 @@ SnortRuleSelector::selectSignatures() const
|
|||||||
|
|
||||||
for (auto &file : file_names) {
|
for (auto &file : file_names) {
|
||||||
for (auto &signature : (*signatures).getSignatures(file)) {
|
for (auto &signature : (*signatures).getSignatures(file)) {
|
||||||
res.emplace_back(signature, action);
|
res.emplace_back(signature, action, trigger_id, exception_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -385,8 +385,29 @@ Layer7AccessControl::Impl::init()
|
|||||||
i_intelligence = Singleton::Consume<I_Intelligence_IS_V2>::by<Layer7AccessControl>();
|
i_intelligence = Singleton::Consume<I_Intelligence_IS_V2>::by<Layer7AccessControl>();
|
||||||
i_mainloop = Singleton::Consume<I_MainLoop>::by<Layer7AccessControl>();
|
i_mainloop = Singleton::Consume<I_MainLoop>::by<Layer7AccessControl>();
|
||||||
|
|
||||||
chrono::minutes expiration(
|
int cache_expiration_in_seconds = 30;
|
||||||
getProfileAgentSettingWithDefault<uint>(60u, "layer7AccessControl.crowdsec.cacheExpiration")
|
string cache_expiration_env = getenv("CROWDSEC_CACHE_EXPIRATION") ? getenv("CROWDSEC_CACHE_EXPIRATION") : "";
|
||||||
|
if (!cache_expiration_env.empty()) {
|
||||||
|
if (
|
||||||
|
all_of(cache_expiration_env.begin(), cache_expiration_env.end(), ::isdigit)
|
||||||
|
&& stoi(cache_expiration_env) > 0
|
||||||
|
) {
|
||||||
|
cache_expiration_in_seconds = stoi(cache_expiration_env);
|
||||||
|
dbgInfo(D_L7_ACCESS_CONTROL)
|
||||||
|
<< "Successfully read cache expiration value from env: "
|
||||||
|
<< cache_expiration_env;
|
||||||
|
} else {
|
||||||
|
dbgWarning(D_L7_ACCESS_CONTROL)
|
||||||
|
<< "An invalid cache expiration value was provided in env: "
|
||||||
|
<< cache_expiration_env;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chrono::seconds expiration(
|
||||||
|
getProfileAgentSettingWithDefault<uint>(
|
||||||
|
cache_expiration_in_seconds,
|
||||||
|
"layer7AccessControl.crowdsec.cacheExpiration"
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
ip_reputation_cache.startExpiration(
|
ip_reputation_cache.startExpiration(
|
||||||
|
|||||||
@@ -142,6 +142,13 @@ string disabled_settings =
|
|||||||
"}"
|
"}"
|
||||||
"],\n";
|
"],\n";
|
||||||
|
|
||||||
|
|
||||||
|
string local_intelligence =
|
||||||
|
"\"intelligence\":{"
|
||||||
|
" \"local intelligence server ip\":\"127.0.0.1\","
|
||||||
|
" \"local intelligence server primary port\":9090"
|
||||||
|
"}\n,";
|
||||||
|
|
||||||
string policy =
|
string policy =
|
||||||
"\"rulebase\": {"
|
"\"rulebase\": {"
|
||||||
"\"usersIdentifiers\": ["
|
"\"usersIdentifiers\": ["
|
||||||
@@ -240,7 +247,9 @@ Layer7AccessControlTest::verifyReport(
|
|||||||
string log = reportToStr(report);
|
string log = reportToStr(report);
|
||||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Report: " << log;
|
dbgTrace(D_L7_ACCESS_CONTROL) << "Report: " << log;
|
||||||
|
|
||||||
if (!source_identifier.empty()) EXPECT_THAT(log, HasSubstr("\"httpSourceId\": \"" + source_identifier + "\""));
|
if (!source_identifier.empty()) {
|
||||||
|
EXPECT_THAT(log, HasSubstr("\"httpSourceId\": \"" + source_identifier + "\""));
|
||||||
|
}
|
||||||
EXPECT_THAT(log, HasSubstr("\"securityAction\": \"" + security_action + "\""));
|
EXPECT_THAT(log, HasSubstr("\"securityAction\": \"" + security_action + "\""));
|
||||||
EXPECT_THAT(log, HasSubstr("\"eventName\": \"Access Control External Vendor Reputation\""));
|
EXPECT_THAT(log, HasSubstr("\"eventName\": \"Access Control External Vendor Reputation\""));
|
||||||
EXPECT_THAT(log, HasSubstr("\"httpHostName\": \"juice-shop.checkpoint.com\""));
|
EXPECT_THAT(log, HasSubstr("\"httpHostName\": \"juice-shop.checkpoint.com\""));
|
||||||
@@ -259,7 +268,7 @@ Layer7AccessControlTest::verifyReport(
|
|||||||
|
|
||||||
TEST_F(Layer7AccessControlTest, ReturnAcceptVerdict)
|
TEST_F(Layer7AccessControlTest, ReturnAcceptVerdict)
|
||||||
{
|
{
|
||||||
stringstream ss_conf(prevent_settings + policy);
|
stringstream ss_conf(prevent_settings + local_intelligence + policy);
|
||||||
Singleton::Consume<Config::I_Config>::from(config)->loadConfiguration(ss_conf);
|
Singleton::Consume<Config::I_Config>::from(config)->loadConfiguration(ss_conf);
|
||||||
|
|
||||||
string intelligence_response_ok = loadIntelligenceResponse("data/ok_intelligence_response.json");
|
string intelligence_response_ok = loadIntelligenceResponse("data/ok_intelligence_response.json");
|
||||||
@@ -305,7 +314,7 @@ TEST_F(Layer7AccessControlTest, ReturnAcceptVerdict)
|
|||||||
|
|
||||||
TEST_F(Layer7AccessControlTest, ReturnDropVerdictOnMaliciousReputation)
|
TEST_F(Layer7AccessControlTest, ReturnDropVerdictOnMaliciousReputation)
|
||||||
{
|
{
|
||||||
stringstream ss_conf(prevent_settings + policy);
|
stringstream ss_conf(prevent_settings + local_intelligence + policy);
|
||||||
Singleton::Consume<Config::I_Config>::from(config)->loadConfiguration(ss_conf);
|
Singleton::Consume<Config::I_Config>::from(config)->loadConfiguration(ss_conf);
|
||||||
|
|
||||||
string malicious_intelligence_response = loadIntelligenceResponse("data/malicious_intelligence_response.json");
|
string malicious_intelligence_response = loadIntelligenceResponse("data/malicious_intelligence_response.json");
|
||||||
@@ -351,7 +360,7 @@ TEST_F(Layer7AccessControlTest, ReturnDropVerdictOnMaliciousReputation)
|
|||||||
|
|
||||||
TEST_F(Layer7AccessControlTest, ReturnDropVerdictCacheBased)
|
TEST_F(Layer7AccessControlTest, ReturnDropVerdictCacheBased)
|
||||||
{
|
{
|
||||||
stringstream ss_conf(prevent_settings + policy);
|
stringstream ss_conf(prevent_settings + local_intelligence + policy);
|
||||||
Singleton::Consume<Config::I_Config>::from(config)->loadConfiguration(ss_conf);
|
Singleton::Consume<Config::I_Config>::from(config)->loadConfiguration(ss_conf);
|
||||||
|
|
||||||
string malicious_intelligence_response = loadIntelligenceResponse("data/malicious_intelligence_response.json");
|
string malicious_intelligence_response = loadIntelligenceResponse("data/malicious_intelligence_response.json");
|
||||||
@@ -403,7 +412,7 @@ TEST_F(Layer7AccessControlTest, ReturnDropVerdictCacheBased)
|
|||||||
|
|
||||||
TEST_F(Layer7AccessControlTest, AcceptOnDetect)
|
TEST_F(Layer7AccessControlTest, AcceptOnDetect)
|
||||||
{
|
{
|
||||||
stringstream ss_conf(detect_settings + policy);
|
stringstream ss_conf(detect_settings + local_intelligence + policy);
|
||||||
Singleton::Consume<Config::I_Config>::from(config)->loadConfiguration(ss_conf);
|
Singleton::Consume<Config::I_Config>::from(config)->loadConfiguration(ss_conf);
|
||||||
|
|
||||||
string malicious_intelligence_response = loadIntelligenceResponse("data/malicious_intelligence_response.json");
|
string malicious_intelligence_response = loadIntelligenceResponse("data/malicious_intelligence_response.json");
|
||||||
@@ -449,7 +458,7 @@ TEST_F(Layer7AccessControlTest, AcceptOnDetect)
|
|||||||
|
|
||||||
TEST_F(Layer7AccessControlTest, FallbackToSourceIPAndDrop)
|
TEST_F(Layer7AccessControlTest, FallbackToSourceIPAndDrop)
|
||||||
{
|
{
|
||||||
stringstream ss_conf(prevent_settings + policy);
|
stringstream ss_conf(prevent_settings + local_intelligence + policy);
|
||||||
Singleton::Consume<Config::I_Config>::from(config)->loadConfiguration(ss_conf);
|
Singleton::Consume<Config::I_Config>::from(config)->loadConfiguration(ss_conf);
|
||||||
|
|
||||||
string malicious_intelligence_response = loadIntelligenceResponse("data/malicious_intelligence_response.json");
|
string malicious_intelligence_response = loadIntelligenceResponse("data/malicious_intelligence_response.json");
|
||||||
|
|||||||
@@ -228,6 +228,11 @@ AccessControlPracticeSpec::load(cereal::JSONInputArchive &archive_in)
|
|||||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec";
|
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec";
|
||||||
|
|
||||||
parseAppsecJSONKey<string>("name", practice_name, archive_in);
|
parseAppsecJSONKey<string>("name", practice_name, archive_in);
|
||||||
|
parseAppsecJSONKey<string>("practiceMode", mode, archive_in, "inherited");
|
||||||
|
if (valid_modes.count(mode) == 0) {
|
||||||
|
dbgWarning(D_LOCAL_POLICY) << "AppSec Access control practice mode invalid: " << mode;
|
||||||
|
throw PolicyGenException("AppSec Access control practice mode invalid: " + mode);
|
||||||
|
}
|
||||||
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
||||||
parseMandatoryAppsecJSONKey<AccessControlRateLimit>("rateLimit", rate_limit, archive_in);
|
parseMandatoryAppsecJSONKey<AccessControlRateLimit>("rateLimit", rate_limit, archive_in);
|
||||||
}
|
}
|
||||||
@@ -255,4 +260,10 @@ AccessControlPracticeSpec::getName() const
|
|||||||
{
|
{
|
||||||
return practice_name;
|
return practice_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const string &
|
||||||
|
AccessControlPracticeSpec::getMode(const std::string &default_mode) const
|
||||||
|
{
|
||||||
|
return isModeInherited(mode) ? default_mode : mode;
|
||||||
|
}
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
|||||||
@@ -19,7 +19,14 @@ using namespace std;
|
|||||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||||
// LCOV_EXCL_START Reason: no test exist
|
// LCOV_EXCL_START Reason: no test exist
|
||||||
|
|
||||||
static const set<string> valid_modes = {"prevent-learn", "detect-learn", "prevent", "detect", "inactive"};
|
static const set<string> valid_modes = {
|
||||||
|
"prevent-learn",
|
||||||
|
"detect-learn",
|
||||||
|
"prevent",
|
||||||
|
"detect",
|
||||||
|
"inactive",
|
||||||
|
"as-top-level"
|
||||||
|
};
|
||||||
static const set<string> valid_confidences = {"medium", "high", "critical"};
|
static const set<string> valid_confidences = {"medium", "high", "critical"};
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -138,15 +145,11 @@ AppSecPracticeWebAttacks::load(cereal::JSONInputArchive &archive_in)
|
|||||||
dbgWarning(D_LOCAL_POLICY) << "AppSec practice override mode invalid: " << mode;
|
dbgWarning(D_LOCAL_POLICY) << "AppSec practice override mode invalid: " << mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getMode() == "Prevent") {
|
parseAppsecJSONKey<string>("minimum-confidence", minimum_confidence, archive_in, "critical");
|
||||||
parseAppsecJSONKey<string>("minimum-confidence", minimum_confidence, archive_in, "critical");
|
if (valid_confidences.count(minimum_confidence) == 0) {
|
||||||
if (valid_confidences.count(minimum_confidence) == 0) {
|
dbgWarning(D_LOCAL_POLICY)
|
||||||
dbgWarning(D_LOCAL_POLICY)
|
<< "AppSec practice override minimum confidence invalid: "
|
||||||
<< "AppSec practice override minimum confidence invalid: "
|
<< minimum_confidence;
|
||||||
<< minimum_confidence;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
minimum_confidence = "Transparent";
|
|
||||||
}
|
}
|
||||||
parseAppsecJSONKey<int>("max-body-size-kb", max_body_size_kb, archive_in, 1000000);
|
parseAppsecJSONKey<int>("max-body-size-kb", max_body_size_kb, archive_in, 1000000);
|
||||||
parseAppsecJSONKey<int>("max-header-size-bytes", max_header_size_bytes, archive_in, 102400);
|
parseAppsecJSONKey<int>("max-header-size-bytes", max_header_size_bytes, archive_in, 102400);
|
||||||
@@ -189,7 +192,10 @@ AppSecPracticeWebAttacks::getMode(const string &default_mode) const
|
|||||||
{
|
{
|
||||||
if (isModeInherited(mode) || (key_to_practices_val2.find(mode) == key_to_practices_val2.end())) {
|
if (isModeInherited(mode) || (key_to_practices_val2.find(mode) == key_to_practices_val2.end())) {
|
||||||
dbgError(D_LOCAL_POLICY) << "Couldn't find a value for key: " << mode << ". Returning " << default_mode;
|
dbgError(D_LOCAL_POLICY) << "Couldn't find a value for key: " << mode << ". Returning " << default_mode;
|
||||||
return default_mode;
|
if(key_to_practices_val2.find(default_mode) == key_to_practices_val2.end()) {
|
||||||
|
return default_mode;
|
||||||
|
}
|
||||||
|
return key_to_practices_val2.at(default_mode);
|
||||||
}
|
}
|
||||||
return key_to_practices_val2.at(mode);
|
return key_to_practices_val2.at(mode);
|
||||||
}
|
}
|
||||||
@@ -404,6 +410,7 @@ AppsecPracticeAntiBotSection::save(cereal::JSONOutputArchive &out_ar) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LCOV_EXCL_START Reason: no test exist
|
// LCOV_EXCL_START Reason: no test exist
|
||||||
|
// Used for V1Beta1
|
||||||
WebAppSection::WebAppSection(
|
WebAppSection::WebAppSection(
|
||||||
const string &_application_urls,
|
const string &_application_urls,
|
||||||
const string &_asset_id,
|
const string &_asset_id,
|
||||||
@@ -417,7 +424,7 @@ WebAppSection::WebAppSection(
|
|||||||
const LogTriggerSection &parsed_log_trigger,
|
const LogTriggerSection &parsed_log_trigger,
|
||||||
const string &default_mode,
|
const string &default_mode,
|
||||||
const AppSecTrustedSources &parsed_trusted_sources,
|
const AppSecTrustedSources &parsed_trusted_sources,
|
||||||
const vector<InnerException> &parsed_exceptions)
|
const std::map<std::string, std::vector<InnerException>> &exceptions)
|
||||||
:
|
:
|
||||||
application_urls(_application_urls),
|
application_urls(_application_urls),
|
||||||
asset_id(_asset_id),
|
asset_id(_asset_id),
|
||||||
@@ -427,21 +434,34 @@ WebAppSection::WebAppSection(
|
|||||||
practice_id(_practice_id),
|
practice_id(_practice_id),
|
||||||
practice_name(_practice_name),
|
practice_name(_practice_name),
|
||||||
context(_context),
|
context(_context),
|
||||||
web_attack_mitigation_severity(parsed_appsec_spec.getWebAttacks().getMinimumConfidence()),
|
|
||||||
web_attack_mitigation_mode(parsed_appsec_spec.getWebAttacks().getMode(default_mode)),
|
web_attack_mitigation_mode(parsed_appsec_spec.getWebAttacks().getMode(default_mode)),
|
||||||
csrf_protection_mode("Disabled"),
|
csrf_protection_mode("Disabled"),
|
||||||
open_redirect_mode("Disabled"),
|
open_redirect_mode("Disabled"),
|
||||||
error_disclosure_mode("Disabled"),
|
error_disclosure_mode("Disabled"),
|
||||||
|
schema_validation_mode("Disabled"),
|
||||||
|
schema_validation_enforce_level("fullSchema"),
|
||||||
practice_advanced_config(parsed_appsec_spec),
|
practice_advanced_config(parsed_appsec_spec),
|
||||||
anti_bots(parsed_appsec_spec.getAntiBot()),
|
anti_bots(parsed_appsec_spec.getAntiBot()),
|
||||||
trusted_sources({ parsed_trusted_sources })
|
trusted_sources({ parsed_trusted_sources })
|
||||||
{
|
{
|
||||||
|
auto mitigation_sevirity = parsed_appsec_spec.getWebAttacks().getMinimumConfidence();
|
||||||
|
if (key_to_mitigation_severity.find(mitigation_sevirity) == key_to_mitigation_severity.end()) {
|
||||||
|
dbgWarning(D_LOCAL_POLICY)
|
||||||
|
<< "web attack mitigation severity invalid: "
|
||||||
|
<< mitigation_sevirity;
|
||||||
|
throw PolicyGenException("web attack mitigation severity invalid: " + mitigation_sevirity);
|
||||||
|
} else {
|
||||||
|
web_attack_mitigation_severity = key_to_mitigation_severity.at(mitigation_sevirity);
|
||||||
|
}
|
||||||
web_attack_mitigation = web_attack_mitigation_mode != "Disabled";
|
web_attack_mitigation = web_attack_mitigation_mode != "Disabled";
|
||||||
|
web_attack_mitigation_severity =
|
||||||
|
web_attack_mitigation_mode != "Prevent" ? "Transparent" :
|
||||||
|
web_attack_mitigation_severity;
|
||||||
web_attack_mitigation_action =
|
web_attack_mitigation_action =
|
||||||
web_attack_mitigation_mode != "Prevent" ? "Transparent" :
|
web_attack_mitigation_mode != "Prevent" ? "Transparent" :
|
||||||
web_attack_mitigation_severity == "critical" ? "low" :
|
web_attack_mitigation_severity == "Critical" ? "Low" :
|
||||||
web_attack_mitigation_severity == "high" ? "balanced" :
|
web_attack_mitigation_severity == "High" ? "Balanced" :
|
||||||
web_attack_mitigation_severity == "medium" ? "high" :
|
web_attack_mitigation_severity == "Medium" ? "High" :
|
||||||
"Error";
|
"Error";
|
||||||
|
|
||||||
triggers.push_back(TriggersInWaapSection(parsed_log_trigger));
|
triggers.push_back(TriggersInWaapSection(parsed_log_trigger));
|
||||||
@@ -449,8 +469,11 @@ WebAppSection::WebAppSection(
|
|||||||
overrides.push_back(AppSecOverride(source_ident));
|
overrides.push_back(AppSecOverride(source_ident));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const InnerException &exception : parsed_exceptions) {
|
for (const auto &exception : exceptions) {
|
||||||
overrides.push_back(AppSecOverride(exception));
|
|
||||||
|
for (const auto &inner_exception : exception.second) {
|
||||||
|
overrides.push_back(AppSecOverride(inner_exception));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,6 +489,10 @@ WebAppSection::WebAppSection(
|
|||||||
const string &_context,
|
const string &_context,
|
||||||
const string &_web_attack_mitigation_severity,
|
const string &_web_attack_mitigation_severity,
|
||||||
const string &_web_attack_mitigation_mode,
|
const string &_web_attack_mitigation_mode,
|
||||||
|
const string &_bot_protection,
|
||||||
|
const string &_schema_validation_mode,
|
||||||
|
const string &_schema_validation_enforce_level,
|
||||||
|
const vector<string> &_schema_validation_oas,
|
||||||
const PracticeAdvancedConfig &_practice_advanced_config,
|
const PracticeAdvancedConfig &_practice_advanced_config,
|
||||||
const AppsecPracticeAntiBotSection &_anti_bots,
|
const AppsecPracticeAntiBotSection &_anti_bots,
|
||||||
const LogTriggerSection &parsed_log_trigger,
|
const LogTriggerSection &parsed_log_trigger,
|
||||||
@@ -480,18 +507,29 @@ WebAppSection::WebAppSection(
|
|||||||
practice_id(_practice_id),
|
practice_id(_practice_id),
|
||||||
practice_name(_practice_name),
|
practice_name(_practice_name),
|
||||||
context(_context),
|
context(_context),
|
||||||
web_attack_mitigation_severity(_web_attack_mitigation_severity),
|
|
||||||
web_attack_mitigation_mode(_web_attack_mitigation_mode),
|
web_attack_mitigation_mode(_web_attack_mitigation_mode),
|
||||||
|
bot_protection(_bot_protection),
|
||||||
|
schema_validation_mode(_schema_validation_mode),
|
||||||
|
schema_validation_enforce_level(_schema_validation_enforce_level),
|
||||||
|
schema_validation_oas(_schema_validation_oas),
|
||||||
practice_advanced_config(_practice_advanced_config),
|
practice_advanced_config(_practice_advanced_config),
|
||||||
anti_bots(_anti_bots),
|
anti_bots(_anti_bots),
|
||||||
trusted_sources({ parsed_trusted_sources })
|
trusted_sources({ parsed_trusted_sources })
|
||||||
{
|
{
|
||||||
|
if (key_to_mitigation_severity.find(_web_attack_mitigation_severity) == key_to_mitigation_severity.end()) {
|
||||||
|
dbgWarning(D_LOCAL_POLICY)
|
||||||
|
<< "web attack mitigation severity invalid: "
|
||||||
|
<< _web_attack_mitigation_severity;
|
||||||
|
throw PolicyGenException("web attack mitigation severity invalid: " + _web_attack_mitigation_severity);
|
||||||
|
} else {
|
||||||
|
web_attack_mitigation_severity = key_to_mitigation_severity.at(_web_attack_mitigation_severity);
|
||||||
|
}
|
||||||
web_attack_mitigation = web_attack_mitigation_mode != "Disabled";
|
web_attack_mitigation = web_attack_mitigation_mode != "Disabled";
|
||||||
web_attack_mitigation_action =
|
web_attack_mitigation_action =
|
||||||
web_attack_mitigation_mode != "Prevent" ? "Transparent" :
|
web_attack_mitigation_mode != "Prevent" ? "Transparent" :
|
||||||
web_attack_mitigation_severity == "critical" ? "low" :
|
web_attack_mitigation_severity == "Critical" ? "Low" :
|
||||||
web_attack_mitigation_severity == "high" ? "balanced" :
|
web_attack_mitigation_severity == "High" ? "Balanced" :
|
||||||
web_attack_mitigation_severity == "medium" ? "high" :
|
web_attack_mitigation_severity == "Medium" ? "High" :
|
||||||
"Error";
|
"Error";
|
||||||
|
|
||||||
csrf_protection_mode = protections.getCsrfProtectionMode(_web_attack_mitigation_mode);
|
csrf_protection_mode = protections.getCsrfProtectionMode(_web_attack_mitigation_mode);
|
||||||
@@ -502,6 +540,7 @@ WebAppSection::WebAppSection(
|
|||||||
for (const SourcesIdentifiers &source_ident : parsed_trusted_sources.getSourcesIdentifiers()) {
|
for (const SourcesIdentifiers &source_ident : parsed_trusted_sources.getSourcesIdentifiers()) {
|
||||||
overrides.push_back(AppSecOverride(source_ident));
|
overrides.push_back(AppSecOverride(source_ident));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
@@ -509,36 +548,35 @@ WebAppSection::WebAppSection(
|
|||||||
void
|
void
|
||||||
WebAppSection::save(cereal::JSONOutputArchive &out_ar) const
|
WebAppSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||||
{
|
{
|
||||||
string disabled_str = "Disabled";
|
|
||||||
string detect_str = "Detect";
|
|
||||||
vector<string> empty_list;
|
vector<string> empty_list;
|
||||||
out_ar(
|
out_ar(
|
||||||
cereal::make_nvp("context", context),
|
cereal::make_nvp("context", context),
|
||||||
cereal::make_nvp("webAttackMitigation", web_attack_mitigation),
|
cereal::make_nvp("webAttackMitigation", web_attack_mitigation),
|
||||||
cereal::make_nvp("webAttackMitigationSeverity", web_attack_mitigation_severity),
|
cereal::make_nvp("webAttackMitigationSeverity", web_attack_mitigation_severity),
|
||||||
cereal::make_nvp("webAttackMitigationAction", web_attack_mitigation_action),
|
cereal::make_nvp("webAttackMitigationAction", web_attack_mitigation_action),
|
||||||
cereal::make_nvp("webAttackMitigationMode", web_attack_mitigation_mode),
|
cereal::make_nvp("webAttackMitigationMode", web_attack_mitigation_mode),
|
||||||
cereal::make_nvp("practiceAdvancedConfig", practice_advanced_config),
|
cereal::make_nvp("practiceAdvancedConfig", practice_advanced_config),
|
||||||
cereal::make_nvp("csrfProtection", csrf_protection_mode),
|
cereal::make_nvp("csrfProtection", csrf_protection_mode),
|
||||||
cereal::make_nvp("openRedirect", open_redirect_mode),
|
cereal::make_nvp("openRedirect", open_redirect_mode),
|
||||||
cereal::make_nvp("errorDisclosure", error_disclosure_mode),
|
cereal::make_nvp("errorDisclosure", error_disclosure_mode),
|
||||||
cereal::make_nvp("practiceId", practice_id),
|
cereal::make_nvp("practiceId", practice_id),
|
||||||
cereal::make_nvp("practiceName", practice_name),
|
cereal::make_nvp("practiceName", practice_name),
|
||||||
cereal::make_nvp("assetId", asset_id),
|
cereal::make_nvp("assetId", asset_id),
|
||||||
cereal::make_nvp("assetName", asset_name),
|
cereal::make_nvp("assetName", asset_name),
|
||||||
cereal::make_nvp("ruleId", rule_id),
|
cereal::make_nvp("ruleId", rule_id),
|
||||||
cereal::make_nvp("ruleName", rule_name),
|
cereal::make_nvp("ruleName", rule_name),
|
||||||
cereal::make_nvp("schemaValidation", false),
|
cereal::make_nvp("schemaValidation", schema_validation_mode == "Prevent"),
|
||||||
cereal::make_nvp("schemaValidation_v2", disabled_str),
|
cereal::make_nvp("schemaValidation_v2", schema_validation_mode),
|
||||||
cereal::make_nvp("oas", empty_list),
|
cereal::make_nvp("oas", schema_validation_oas),
|
||||||
cereal::make_nvp("triggers", triggers),
|
cereal::make_nvp("schemaValidationEnforceLevel", schema_validation_enforce_level),
|
||||||
cereal::make_nvp("applicationUrls", application_urls),
|
cereal::make_nvp("triggers", triggers),
|
||||||
cereal::make_nvp("overrides", overrides),
|
cereal::make_nvp("applicationUrls", application_urls),
|
||||||
cereal::make_nvp("trustedSources", trusted_sources),
|
cereal::make_nvp("overrides", overrides),
|
||||||
cereal::make_nvp("waapParameters", empty_list),
|
cereal::make_nvp("trustedSources", trusted_sources),
|
||||||
cereal::make_nvp("botProtection", false),
|
cereal::make_nvp("waapParameters", empty_list),
|
||||||
cereal::make_nvp("antiBot", anti_bots),
|
cereal::make_nvp("botProtection", false),
|
||||||
cereal::make_nvp("botProtection_v2", detect_str)
|
cereal::make_nvp("antiBot", anti_bots),
|
||||||
|
cereal::make_nvp("botProtection_v2", bot_protection != "" ? bot_protection : string("Detect"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,9 @@ AppsecException::load(cereal::JSONInputArchive &archive_in)
|
|||||||
{
|
{
|
||||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec exception";
|
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec exception";
|
||||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||||
archive_in(CEREAL_NVP(exception_spec));
|
AppsecExceptionSpec single_exception_spec;
|
||||||
|
single_exception_spec.load(archive_in);
|
||||||
|
exception_spec.push_back(single_exception_spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -174,7 +176,7 @@ ExceptionMatch::ExceptionMatch(const AppsecExceptionSpec &parsed_exception)
|
|||||||
{
|
{
|
||||||
bool single_condition = parsed_exception.isOneCondition();
|
bool single_condition = parsed_exception.isOneCondition();
|
||||||
for (auto &attrib : attributes) {
|
for (auto &attrib : attributes) {
|
||||||
auto &attrib_name = attrib.first;
|
auto attrib_name = (attrib.first == "sourceIp" ? "sourceIP" : attrib.first);
|
||||||
auto &attrib_getter = attrib.second;
|
auto &attrib_getter = attrib.second;
|
||||||
auto exceptions_value = attrib_getter(parsed_exception);
|
auto exceptions_value = attrib_getter(parsed_exception);
|
||||||
if (exceptions_value.empty()) continue;
|
if (exceptions_value.empty()) continue;
|
||||||
|
|||||||
@@ -181,12 +181,14 @@ public:
|
|||||||
const AccessControlRateLimit &getRateLimit() const;
|
const AccessControlRateLimit &getRateLimit() const;
|
||||||
const std::string & getAppSecClassName() const;
|
const std::string & getAppSecClassName() const;
|
||||||
const std::string & getName() const;
|
const std::string & getName() const;
|
||||||
|
const std::string & getMode(const std::string &default_mode = "inactive") const;
|
||||||
void setName(const std::string &_name);
|
void setName(const std::string &_name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AccessControlRateLimit rate_limit;
|
AccessControlRateLimit rate_limit;
|
||||||
std::string appsec_class_name;
|
std::string appsec_class_name;
|
||||||
std::string practice_name;
|
std::string practice_name;
|
||||||
|
std::string mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ACCESS_CONTROL_PRACTICE_H__
|
#endif // __ACCESS_CONTROL_PRACTICE_H__
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ public:
|
|||||||
const LogTriggerSection &parsed_log_trigger,
|
const LogTriggerSection &parsed_log_trigger,
|
||||||
const std::string &default_mode,
|
const std::string &default_mode,
|
||||||
const AppSecTrustedSources &parsed_trusted_sources,
|
const AppSecTrustedSources &parsed_trusted_sources,
|
||||||
const std::vector<InnerException> &parsed_exceptions
|
const std::map<std::string, std::vector<InnerException>> &exceptions
|
||||||
);
|
);
|
||||||
|
|
||||||
// used for V1beta2
|
// used for V1beta2
|
||||||
@@ -290,6 +290,10 @@ public:
|
|||||||
const std::string &_context,
|
const std::string &_context,
|
||||||
const std::string &_web_attack_mitigation_severity,
|
const std::string &_web_attack_mitigation_severity,
|
||||||
const std::string &_web_attack_mitigation_mode,
|
const std::string &_web_attack_mitigation_mode,
|
||||||
|
const std::string &_bot_protection,
|
||||||
|
const std::string &schema_validation_mode,
|
||||||
|
const std::string &schema_validation_enforce_level,
|
||||||
|
const std::vector<std::string> &schema_validation_oas,
|
||||||
const PracticeAdvancedConfig &_practice_advanced_config,
|
const PracticeAdvancedConfig &_practice_advanced_config,
|
||||||
const AppsecPracticeAntiBotSection &_anti_bots,
|
const AppsecPracticeAntiBotSection &_anti_bots,
|
||||||
const LogTriggerSection &parsed_log_trigger,
|
const LogTriggerSection &parsed_log_trigger,
|
||||||
@@ -301,26 +305,30 @@ public:
|
|||||||
bool operator< (const WebAppSection &other) const;
|
bool operator< (const WebAppSection &other) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string application_urls;
|
bool web_attack_mitigation;
|
||||||
std::string asset_id;
|
std::string application_urls;
|
||||||
std::string asset_name;
|
std::string asset_id;
|
||||||
std::string rule_id;
|
std::string asset_name;
|
||||||
std::string rule_name;
|
std::string rule_id;
|
||||||
std::string practice_id;
|
std::string rule_name;
|
||||||
std::string practice_name;
|
std::string practice_id;
|
||||||
std::string context;
|
std::string practice_name;
|
||||||
std::string web_attack_mitigation_action;
|
std::string context;
|
||||||
std::string web_attack_mitigation_severity;
|
std::string web_attack_mitigation_action;
|
||||||
std::string web_attack_mitigation_mode;
|
std::string web_attack_mitigation_severity;
|
||||||
std::string csrf_protection_mode;
|
std::string web_attack_mitigation_mode;
|
||||||
std::string open_redirect_mode;
|
std::string csrf_protection_mode;
|
||||||
std::string error_disclosure_mode;
|
std::string open_redirect_mode;
|
||||||
bool web_attack_mitigation;
|
std::string error_disclosure_mode;
|
||||||
std::vector<TriggersInWaapSection> triggers;
|
std::string bot_protection;
|
||||||
PracticeAdvancedConfig practice_advanced_config;
|
std::string schema_validation_mode;
|
||||||
AppsecPracticeAntiBotSection anti_bots;
|
std::string schema_validation_enforce_level;
|
||||||
std::vector<AppSecTrustedSources> trusted_sources;
|
std::vector<std::string> schema_validation_oas;
|
||||||
std::vector<AppSecOverride> overrides;
|
PracticeAdvancedConfig practice_advanced_config;
|
||||||
|
AppsecPracticeAntiBotSection anti_bots;
|
||||||
|
std::vector<AppSecOverride> overrides;
|
||||||
|
std::vector<AppSecTrustedSources> trusted_sources;
|
||||||
|
std::vector<TriggersInWaapSection> triggers;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WebAPISection
|
class WebAPISection
|
||||||
@@ -408,7 +416,7 @@ class ParsedRule
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ParsedRule() {}
|
ParsedRule() {}
|
||||||
ParsedRule(const std::string &_host) : host(_host) {}
|
ParsedRule(const std::string &_host, const std::string &_mode) : host(_host), mode(_mode) {}
|
||||||
|
|
||||||
void load(cereal::JSONInputArchive &archive_in);
|
void load(cereal::JSONInputArchive &archive_in);
|
||||||
const std::vector<std::string> & getExceptions() const;
|
const std::vector<std::string> & getExceptions() const;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
bool isOneCondition() const;
|
bool isOneCondition() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int conditions_number;
|
int conditions_number = 0;
|
||||||
std::string action;
|
std::string action;
|
||||||
std::vector<std::string> country_code;
|
std::vector<std::string> country_code;
|
||||||
std::vector<std::string> country_name;
|
std::vector<std::string> country_name;
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ class DefaultBackend
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void load(cereal::JSONInputArchive &);
|
void load(cereal::JSONInputArchive &);
|
||||||
|
bool doesExist() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool is_exists = false;
|
bool is_exists = false;
|
||||||
@@ -90,6 +91,7 @@ public:
|
|||||||
void load(cereal::JSONInputArchive &archive_in);
|
void load(cereal::JSONInputArchive &archive_in);
|
||||||
|
|
||||||
const std::vector<IngressDefinedRule> & getRules() const;
|
const std::vector<IngressDefinedRule> & getRules() const;
|
||||||
|
bool doesDefaultBackendExist() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string ingress_class_name;
|
std::string ingress_class_name;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "maybe_res.h"
|
#include "maybe_res.h"
|
||||||
#include "i_orchestration_tools.h"
|
#include "i_orchestration_tools.h"
|
||||||
#include "i_shell_cmd.h"
|
#include "i_shell_cmd.h"
|
||||||
|
#include "i_encryptor.h"
|
||||||
#include "i_messaging.h"
|
#include "i_messaging.h"
|
||||||
#include "i_env_details.h"
|
#include "i_env_details.h"
|
||||||
#include "i_agent_details.h"
|
#include "i_agent_details.h"
|
||||||
@@ -40,6 +41,7 @@ class K8sPolicyUtils
|
|||||||
Singleton::Consume<I_Messaging>,
|
Singleton::Consume<I_Messaging>,
|
||||||
Singleton::Consume<I_ShellCmd>,
|
Singleton::Consume<I_ShellCmd>,
|
||||||
Singleton::Consume<I_EnvDetails>,
|
Singleton::Consume<I_EnvDetails>,
|
||||||
|
Singleton::Consume<I_Encryptor>,
|
||||||
Singleton::Consume<I_AgentDetails>
|
Singleton::Consume<I_AgentDetails>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -80,6 +82,8 @@ private:
|
|||||||
|
|
||||||
void createSnortFile(std::vector<NewAppSecPracticeSpec> &practices) const;
|
void createSnortFile(std::vector<NewAppSecPracticeSpec> &practices) const;
|
||||||
|
|
||||||
|
void createSchemaValidationOas(std::vector<NewAppSecPracticeSpec> &practices) const;
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
std::vector<T> extractV1Beta2ElementsFromCluster(
|
std::vector<T> extractV1Beta2ElementsFromCluster(
|
||||||
const std::string &crd_plural,
|
const std::string &crd_plural,
|
||||||
@@ -112,6 +116,7 @@ private:
|
|||||||
I_Messaging* messaging = nullptr;
|
I_Messaging* messaging = nullptr;
|
||||||
EnvType env_type;
|
EnvType env_type;
|
||||||
std::string token;
|
std::string token;
|
||||||
|
std::string agent_ns;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __K8S_POLICY_UTILS_H__
|
#endif // __K8S_POLICY_UTILS_H__
|
||||||
|
|||||||
@@ -49,6 +49,13 @@ static const std::unordered_map<std::string, TriggerType> string_to_trigger_type
|
|||||||
{ "WebUserResponse", TriggerType::WebUserResponse }
|
{ "WebUserResponse", TriggerType::WebUserResponse }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const std::unordered_map<std::string, std::string> key_to_mitigation_severity = {
|
||||||
|
{ "high", "High"},
|
||||||
|
{ "medium", "Medium"},
|
||||||
|
{ "critical", "Critical"},
|
||||||
|
{ "Transparent", "Transparent"}
|
||||||
|
};
|
||||||
|
|
||||||
static const std::unordered_map<std::string, std::string> key_to_practices_val = {
|
static const std::unordered_map<std::string, std::string> key_to_practices_val = {
|
||||||
{ "prevent-learn", "Prevent"},
|
{ "prevent-learn", "Prevent"},
|
||||||
{ "detect-learn", "Learn"},
|
{ "detect-learn", "Learn"},
|
||||||
@@ -57,6 +64,14 @@ static const std::unordered_map<std::string, std::string> key_to_practices_val =
|
|||||||
{ "inactive", "Inactive"}
|
{ "inactive", "Inactive"}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const std::unordered_map<std::string, std::string> key_to_practices_mode_val = {
|
||||||
|
{ "prevent-learn", "Prevent"},
|
||||||
|
{ "detect-learn", "Detect"},
|
||||||
|
{ "prevent", "Prevent"},
|
||||||
|
{ "detect", "Detect"},
|
||||||
|
{ "inactive", "Disabled"}
|
||||||
|
};
|
||||||
|
|
||||||
static const std::unordered_map<std::string, std::string> key_to_practices_val2 = {
|
static const std::unordered_map<std::string, std::string> key_to_practices_val2 = {
|
||||||
{ "prevent-learn", "Prevent"},
|
{ "prevent-learn", "Prevent"},
|
||||||
{ "detect-learn", "Learn"},
|
{ "detect-learn", "Learn"},
|
||||||
@@ -66,6 +81,8 @@ static const std::unordered_map<std::string, std::string> key_to_practices_val2
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const std::string default_appsec_url = "http://*:*";
|
static const std::string default_appsec_url = "http://*:*";
|
||||||
|
static const std::string default_appsec_name = "Any";
|
||||||
|
|
||||||
|
|
||||||
class PolicyGenException : public std::exception
|
class PolicyGenException : public std::exception
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class NewParsedRule
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NewParsedRule() {}
|
NewParsedRule() {}
|
||||||
NewParsedRule(const std::string &_host) : host(_host) {}
|
NewParsedRule(const std::string &_host, const std::string &_mode) : host(_host), mode(_mode) {}
|
||||||
|
|
||||||
void load(cereal::JSONInputArchive &archive_in);
|
void load(cereal::JSONInputArchive &archive_in);
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public:
|
|||||||
bool shouldBeautifyLogs() const;
|
bool shouldBeautifyLogs() const;
|
||||||
|
|
||||||
bool getCloud() const;
|
bool getCloud() const;
|
||||||
bool isK8SNeeded() const;
|
bool isContainerNeeded() const;
|
||||||
bool isCefNeeded() const;
|
bool isCefNeeded() const;
|
||||||
bool isSyslogNeeded() const;
|
bool isSyslogNeeded() const;
|
||||||
const std::string & getSyslogServerIpv4Address() const;
|
const std::string & getSyslogServerIpv4Address() const;
|
||||||
@@ -140,7 +140,7 @@ private:
|
|||||||
const NewLoggingService & getCefServiceData() const;
|
const NewLoggingService & getCefServiceData() const;
|
||||||
|
|
||||||
bool cloud = false;
|
bool cloud = false;
|
||||||
bool k8s_service = false;
|
bool container_service = false;
|
||||||
bool agent_local = true;
|
bool agent_local = true;
|
||||||
bool beautify_logs = true;
|
bool beautify_logs = true;
|
||||||
NewLoggingService syslog_service;
|
NewLoggingService syslog_service;
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "local_policy_common.h"
|
#include "local_policy_common.h"
|
||||||
|
#include "i_orchestration_tools.h"
|
||||||
|
#include "i_encryptor.h"
|
||||||
|
|
||||||
bool isModeInherited(const std::string &mode);
|
bool isModeInherited(const std::string &mode);
|
||||||
|
|
||||||
@@ -88,6 +90,8 @@ public:
|
|||||||
|
|
||||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||||
|
|
||||||
|
bool operator<(const IpsProtectionsSection &other) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string context;
|
std::string context;
|
||||||
std::string name;
|
std::string name;
|
||||||
@@ -105,7 +109,7 @@ public:
|
|||||||
// LCOV_EXCL_START Reason: no test exist
|
// LCOV_EXCL_START Reason: no test exist
|
||||||
IPSSection() {};
|
IPSSection() {};
|
||||||
|
|
||||||
IPSSection(const std::vector<IpsProtectionsSection> &_ips) : ips(_ips) {};
|
IPSSection(const std::vector<IpsProtectionsSection> &_ips);
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
|
||||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||||
@@ -138,6 +142,12 @@ public:
|
|||||||
const std::string & getMode(const std::string &default_mode = "inactive") const;
|
const std::string & getMode(const std::string &default_mode = "inactive") const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
const std::string & getRulesMode(
|
||||||
|
const std::string &mode,
|
||||||
|
const std::string &default_mode = "inactive"
|
||||||
|
) const;
|
||||||
|
|
||||||
std::string override_mode;
|
std::string override_mode;
|
||||||
std::string max_performance_impact;
|
std::string max_performance_impact;
|
||||||
std::string min_severity_level;
|
std::string min_severity_level;
|
||||||
@@ -487,15 +497,16 @@ private:
|
|||||||
SnortSection snort;
|
SnortSection snort;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NewSnortSignaturesAndOpenSchemaAPI
|
class NewSnortSignatures
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NewSnortSignaturesAndOpenSchemaAPI() : is_temporary(false) {};
|
NewSnortSignatures() : is_temporary(false) {};
|
||||||
|
|
||||||
void load(cereal::JSONInputArchive &archive_in);
|
void load(cereal::JSONInputArchive &archive_in);
|
||||||
|
|
||||||
void addFile(const std::string &file_name);
|
void addFile(const std::string &file_name);
|
||||||
const std::string & getOverrideMode(const std::string &default_mode = "inactive") const;
|
const std::string & getOverrideMode(const std::string &default_mode = "inactive") const;
|
||||||
|
const std::string & getEnforceLevel() const;
|
||||||
const std::vector<std::string> & getConfigMap() const;
|
const std::vector<std::string> & getConfigMap() const;
|
||||||
const std::vector<std::string> & getFiles() const;
|
const std::vector<std::string> & getFiles() const;
|
||||||
bool isTemporary() const;
|
bool isTemporary() const;
|
||||||
@@ -503,35 +514,48 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string override_mode;
|
std::string override_mode;
|
||||||
|
std::string enforcement_level;
|
||||||
std::vector<std::string> config_map;
|
std::vector<std::string> config_map;
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
bool is_temporary;
|
bool is_temporary;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NewAppSecWebBotsURI
|
class NewOpenApiSchema : Singleton::Consume<I_OrchestrationTools>, Singleton::Consume<I_Encryptor>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
NewOpenApiSchema() {};
|
||||||
|
|
||||||
void load(cereal::JSONInputArchive &archive_in);
|
void load(cereal::JSONInputArchive &archive_in);
|
||||||
|
|
||||||
const std::string & getURI() const;
|
void addOas(const std::string &file);
|
||||||
|
const std::string & getOverrideMode(const std::string &default_mode = "inactive") const;
|
||||||
|
const std::string & getEnforceLevel() const;
|
||||||
|
const std::vector<std::string> & getConfigMap() const;
|
||||||
|
const std::vector<std::string> & getFiles() const;
|
||||||
|
const std::vector<std::string> & getOas() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string uri;
|
std::string override_mode;
|
||||||
|
std::string enforcement_level;
|
||||||
|
std::vector<std::string> config_map;
|
||||||
|
std::vector<std::string> files;
|
||||||
|
std::vector<std::string> oas;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NewAppSecPracticeAntiBot
|
class NewAppSecPracticeAntiBot
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::vector<std::string> getIjectedUris() const;
|
const std::vector<std::string> & getIjectedUris() const;
|
||||||
std::vector<std::string> getValidatedUris() const;
|
const std::vector<std::string> & getValidatedUris() const;
|
||||||
|
const std::string & getMode(const std::string &default_mode = "inactive") const;
|
||||||
|
|
||||||
void load(cereal::JSONInputArchive &archive_in);
|
void load(cereal::JSONInputArchive &archive_in);
|
||||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string override_mode;
|
std::string override_mode;
|
||||||
std::vector<NewAppSecWebBotsURI> injected_uris;
|
std::vector<std::string> injected_uris;
|
||||||
std::vector<NewAppSecWebBotsURI> validated_uris;
|
std::vector<std::string> validated_uris;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NewAppSecWebAttackProtections
|
class NewAppSecWebAttackProtections
|
||||||
@@ -579,25 +603,27 @@ class NewAppSecPracticeSpec
|
|||||||
public:
|
public:
|
||||||
void load(cereal::JSONInputArchive &archive_in);
|
void load(cereal::JSONInputArchive &archive_in);
|
||||||
|
|
||||||
NewSnortSignaturesAndOpenSchemaAPI & getSnortSignatures();
|
NewSnortSignatures & getSnortSignatures();
|
||||||
const NewSnortSignaturesAndOpenSchemaAPI & getOpenSchemaValidation() const;
|
NewOpenApiSchema & getOpenSchemaValidation();
|
||||||
const NewAppSecPracticeWebAttacks & getWebAttacks() const;
|
const NewAppSecPracticeWebAttacks & getWebAttacks() const;
|
||||||
const NewAppSecPracticeAntiBot & getAntiBot() const;
|
const NewAppSecPracticeAntiBot & getAntiBot() const;
|
||||||
const NewIntrusionPrevention & getIntrusionPrevention() const;
|
const NewIntrusionPrevention & getIntrusionPrevention() const;
|
||||||
const NewFileSecurity & getFileSecurity() const;
|
const NewFileSecurity & getFileSecurity() const;
|
||||||
const std::string & getAppSecClassName() const;
|
const std::string & getAppSecClassName() const;
|
||||||
const std::string & getName() const;
|
const std::string & getName() const;
|
||||||
|
const std::string & getMode(const std::string &default_mode = "inactive") const;
|
||||||
void setName(const std::string &_name);
|
void setName(const std::string &_name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NewFileSecurity file_security;
|
NewFileSecurity file_security;
|
||||||
NewIntrusionPrevention intrusion_prevention;
|
NewIntrusionPrevention intrusion_prevention;
|
||||||
NewSnortSignaturesAndOpenSchemaAPI openapi_schema_validation;
|
NewOpenApiSchema openapi_schema_validation;
|
||||||
NewSnortSignaturesAndOpenSchemaAPI snort_signatures;
|
NewSnortSignatures snort_signatures;
|
||||||
NewAppSecPracticeWebAttacks web_attacks;
|
NewAppSecPracticeWebAttacks web_attacks;
|
||||||
NewAppSecPracticeAntiBot anti_bot;
|
NewAppSecPracticeAntiBot anti_bot;
|
||||||
std::string appsec_class_name;
|
std::string appsec_class_name;
|
||||||
std::string practice_name;
|
std::string practice_name;
|
||||||
|
std::string mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __NEW_PRACTICE_H__
|
#endif // __NEW_PRACTICE_H__
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ private:
|
|||||||
SecurityAppsWrapper security_apps;
|
SecurityAppsWrapper security_apps;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PolicyMakerUtils
|
class PolicyMakerUtils : Singleton::Consume<I_EnvDetails>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string proccesSingleAppsecPolicy(
|
std::string proccesSingleAppsecPolicy(
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
const std::string & getIdentifier() const;
|
const std::string & getIdentifier() const;
|
||||||
|
const std::string & getIdentifierValue() const;
|
||||||
|
|
||||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||||
|
|
||||||
@@ -145,6 +146,7 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
const std::string & getIdentifier() const;
|
const std::string & getIdentifier() const;
|
||||||
|
const std::string & getIdentifierValue() const;
|
||||||
|
|
||||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public:
|
|||||||
bool _logToAgent,
|
bool _logToAgent,
|
||||||
bool _logToCef,
|
bool _logToCef,
|
||||||
bool _logToCloud,
|
bool _logToCloud,
|
||||||
bool _logToK8sService,
|
bool _logTolocalTuning,
|
||||||
bool _logToSyslog,
|
bool _logToSyslog,
|
||||||
bool _responseBody,
|
bool _responseBody,
|
||||||
bool _tpDetect,
|
bool _tpDetect,
|
||||||
@@ -73,7 +73,7 @@ private:
|
|||||||
bool logToAgent;
|
bool logToAgent;
|
||||||
bool logToCef;
|
bool logToCef;
|
||||||
bool logToCloud;
|
bool logToCloud;
|
||||||
bool logToK8sService;
|
bool logTolocalTuning;
|
||||||
bool logToSyslog;
|
bool logToSyslog;
|
||||||
bool responseBody;
|
bool responseBody;
|
||||||
bool tpDetect;
|
bool tpDetect;
|
||||||
@@ -258,7 +258,7 @@ public:
|
|||||||
bool shouldBeautifyLogs() const;
|
bool shouldBeautifyLogs() const;
|
||||||
|
|
||||||
bool getCloud() const;
|
bool getCloud() const;
|
||||||
bool isK8SNeeded() const;
|
bool isContainerNeeded() const;
|
||||||
bool isCefNeeded() const;
|
bool isCefNeeded() const;
|
||||||
bool isSyslogNeeded() const;
|
bool isSyslogNeeded() const;
|
||||||
const std::string & getSyslogServerIpv4Address() const;
|
const std::string & getSyslogServerIpv4Address() const;
|
||||||
@@ -269,7 +269,7 @@ private:
|
|||||||
const LoggingService & getCefServiceData() const;
|
const LoggingService & getCefServiceData() const;
|
||||||
|
|
||||||
bool cloud = false;
|
bool cloud = false;
|
||||||
bool k8s_service = false;
|
bool container_service = false;
|
||||||
bool agent_local = true;
|
bool agent_local = true;
|
||||||
bool beautify_logs = true;
|
bool beautify_logs = true;
|
||||||
LoggingService syslog_service;
|
LoggingService syslog_service;
|
||||||
|
|||||||
@@ -86,6 +86,12 @@ DefaultBackend::load(cereal::JSONInputArchive &)
|
|||||||
is_exists = true;
|
is_exists = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
DefaultBackend::doesExist() const
|
||||||
|
{
|
||||||
|
return is_exists;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
IngressSpec::load(cereal::JSONInputArchive &archive_in)
|
IngressSpec::load(cereal::JSONInputArchive &archive_in)
|
||||||
{
|
{
|
||||||
@@ -101,6 +107,12 @@ IngressSpec::getRules() const
|
|||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
IngressSpec::doesDefaultBackendExist() const
|
||||||
|
{
|
||||||
|
return default_backend.doesExist();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SingleIngressData::load(cereal::JSONInputArchive &archive_in)
|
SingleIngressData::load(cereal::JSONInputArchive &archive_in)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,6 +35,14 @@ convertAnnotationKeysTostring(const AnnotationKeys &key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
getAppSecScopeType()
|
||||||
|
{
|
||||||
|
auto env_res = getenv("CRDS_SCOPE");
|
||||||
|
if (env_res != nullptr) return env_res;
|
||||||
|
return "cluster";
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
K8sPolicyUtils::init()
|
K8sPolicyUtils::init()
|
||||||
{
|
{
|
||||||
@@ -42,6 +50,7 @@ K8sPolicyUtils::init()
|
|||||||
env_type = env_details->getEnvType();
|
env_type = env_details->getEnvType();
|
||||||
if (env_type == EnvType::K8S) {
|
if (env_type == EnvType::K8S) {
|
||||||
token = env_details->getToken();
|
token = env_details->getToken();
|
||||||
|
agent_ns = getAppSecScopeType() == "namespaced" ? env_details->getNameSpace() + "/" : "";
|
||||||
messaging = Singleton::Consume<I_Messaging>::by<K8sPolicyUtils>();
|
messaging = Singleton::Consume<I_Messaging>::by<K8sPolicyUtils>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,10 +149,12 @@ extractElementsFromNewRule(
|
|||||||
const NewParsedRule &rule,
|
const NewParsedRule &rule,
|
||||||
map<AnnotationTypes, unordered_set<string>> &policy_elements_names)
|
map<AnnotationTypes, unordered_set<string>> &policy_elements_names)
|
||||||
{
|
{
|
||||||
policy_elements_names[AnnotationTypes::EXCEPTION].insert(
|
if (rule.getExceptions().size() > 0) {
|
||||||
rule.getExceptions().begin(),
|
policy_elements_names[AnnotationTypes::EXCEPTION].insert(
|
||||||
rule.getExceptions().end()
|
rule.getExceptions().begin(),
|
||||||
);
|
rule.getExceptions().end()
|
||||||
|
);
|
||||||
|
}
|
||||||
policy_elements_names[AnnotationTypes::THREAT_PREVENTION_PRACTICE].insert(
|
policy_elements_names[AnnotationTypes::THREAT_PREVENTION_PRACTICE].insert(
|
||||||
rule.getPractices().begin(),
|
rule.getPractices().begin(),
|
||||||
rule.getPractices().end()
|
rule.getPractices().end()
|
||||||
@@ -152,14 +163,24 @@ extractElementsFromNewRule(
|
|||||||
rule.getAccessControlPractices().begin(),
|
rule.getAccessControlPractices().begin(),
|
||||||
rule.getAccessControlPractices().end()
|
rule.getAccessControlPractices().end()
|
||||||
);
|
);
|
||||||
policy_elements_names[AnnotationTypes::TRIGGER].insert(
|
if (rule.getLogTriggers().size() > 0) {
|
||||||
rule.getLogTriggers().begin(),
|
policy_elements_names[AnnotationTypes::TRIGGER].insert(
|
||||||
rule.getLogTriggers().end()
|
rule.getLogTriggers().begin(),
|
||||||
);
|
rule.getLogTriggers().end()
|
||||||
policy_elements_names[AnnotationTypes::WEB_USER_RES].insert(rule.getCustomResponse());
|
);
|
||||||
policy_elements_names[AnnotationTypes::SOURCE_IDENTIFIERS].insert(rule.getSourceIdentifiers());
|
}
|
||||||
policy_elements_names[AnnotationTypes::TRUSTED_SOURCES].insert(rule.getTrustedSources());
|
if (rule.getCustomResponse() != "" ) {
|
||||||
policy_elements_names[AnnotationTypes::UPGRADE_SETTINGS].insert(rule.getUpgradeSettings());
|
policy_elements_names[AnnotationTypes::WEB_USER_RES].insert(rule.getCustomResponse());
|
||||||
|
}
|
||||||
|
if (rule.getSourceIdentifiers() != "" ) {
|
||||||
|
policy_elements_names[AnnotationTypes::SOURCE_IDENTIFIERS].insert(rule.getSourceIdentifiers());
|
||||||
|
}
|
||||||
|
if (rule.getTrustedSources() != "" ) {
|
||||||
|
policy_elements_names[AnnotationTypes::TRUSTED_SOURCES].insert(rule.getTrustedSources());
|
||||||
|
}
|
||||||
|
if (rule.getUpgradeSettings() != "" ) {
|
||||||
|
policy_elements_names[AnnotationTypes::UPGRADE_SETTINGS].insert(rule.getUpgradeSettings());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map<AnnotationTypes, unordered_set<string>>
|
map<AnnotationTypes, unordered_set<string>>
|
||||||
@@ -259,9 +280,11 @@ K8sPolicyUtils::extractV1Beta2ElementsFromCluster(
|
|||||||
dbgTrace(D_LOCAL_POLICY) << "Retrieve AppSec elements. type: " << crd_plural;
|
dbgTrace(D_LOCAL_POLICY) << "Retrieve AppSec elements. type: " << crd_plural;
|
||||||
vector<T> elements;
|
vector<T> elements;
|
||||||
for (const string &element_name : elements_names) {
|
for (const string &element_name : elements_names) {
|
||||||
|
string ns_suffix = getAppSecScopeType() == "namespaced" ? "ns" : "";
|
||||||
|
string ns = getAppSecScopeType() == "namespaced" ? "namespaces/" : "";
|
||||||
dbgTrace(D_LOCAL_POLICY) << "AppSec element name: " << element_name;
|
dbgTrace(D_LOCAL_POLICY) << "AppSec element name: " << element_name;
|
||||||
auto maybe_appsec_element = getObjectFromCluster<AppsecSpecParser<T>>(
|
auto maybe_appsec_element = getObjectFromCluster<AppsecSpecParser<T>>(
|
||||||
"/apis/openappsec.io/v1beta2/" + crd_plural + "/" + element_name
|
"/apis/openappsec.io/v1beta2/" + ns + agent_ns + crd_plural + ns_suffix + "/" + element_name
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!maybe_appsec_element.ok()) {
|
if (!maybe_appsec_element.ok()) {
|
||||||
@@ -362,8 +385,9 @@ K8sPolicyUtils::createSnortFile(vector<NewAppSecPracticeSpec> &practices) const
|
|||||||
practice.getSnortSignatures().setTemporary(true);
|
practice.getSnortSignatures().setTemporary(true);
|
||||||
for (const string &config_map : practice.getSnortSignatures().getConfigMap())
|
for (const string &config_map : practice.getSnortSignatures().getConfigMap())
|
||||||
{
|
{
|
||||||
|
string ns = agent_ns == "" ? "default/" : agent_ns;
|
||||||
auto maybe_configmap = getObjectFromCluster<ConfigMaps>(
|
auto maybe_configmap = getObjectFromCluster<ConfigMaps>(
|
||||||
"/api/v1/namespaces/default/configmaps/" + config_map
|
"/api/v1/namespaces/" + ns + "configmaps/" + config_map
|
||||||
);
|
);
|
||||||
if (!maybe_configmap.ok()) {
|
if (!maybe_configmap.ok()) {
|
||||||
dbgWarning(D_LOCAL_POLICY) << "Failed to get configMaps from the cluster.";
|
dbgWarning(D_LOCAL_POLICY) << "Failed to get configMaps from the cluster.";
|
||||||
@@ -381,6 +405,28 @@ K8sPolicyUtils::createSnortFile(vector<NewAppSecPracticeSpec> &practices) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
K8sPolicyUtils::createSchemaValidationOas(vector<NewAppSecPracticeSpec> &practices) const
|
||||||
|
{
|
||||||
|
for (NewAppSecPracticeSpec &practice : practices) {
|
||||||
|
vector<string> res;
|
||||||
|
for (const string &config_map : practice.getOpenSchemaValidation().getConfigMap())
|
||||||
|
{
|
||||||
|
string ns = agent_ns == "" ? "default/" : agent_ns;
|
||||||
|
auto maybe_configmap = getObjectFromCluster<ConfigMaps>(
|
||||||
|
"/api/v1/namespaces/" + ns + "configmaps/" + config_map
|
||||||
|
);
|
||||||
|
if (!maybe_configmap.ok()) {
|
||||||
|
dbgWarning(D_LOCAL_POLICY) << "Failed to get configMaps from the cluster.";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
string file_content = maybe_configmap.unpack().getFileContent();
|
||||||
|
string res = Singleton::Consume<I_Encryptor>::by<K8sPolicyUtils>()->base64Encode(file_content);
|
||||||
|
practice.getOpenSchemaValidation().addOas(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Maybe<V1beta2AppsecLinuxPolicy>
|
Maybe<V1beta2AppsecLinuxPolicy>
|
||||||
K8sPolicyUtils::createAppsecPolicyK8sFromV1beta2Crds(
|
K8sPolicyUtils::createAppsecPolicyK8sFromV1beta2Crds(
|
||||||
const AppsecSpecParser<NewAppsecPolicySpec> &appsec_policy_spec,
|
const AppsecSpecParser<NewAppsecPolicySpec> &appsec_policy_spec,
|
||||||
@@ -396,6 +442,7 @@ K8sPolicyUtils::createAppsecPolicyK8sFromV1beta2Crds(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (default_rule.getMode().empty() && !ingress_mode.empty()) {
|
if (default_rule.getMode().empty() && !ingress_mode.empty()) {
|
||||||
|
dbgTrace(D_LOCAL_POLICY) << "setting the policy default rule mode to the ingress mode: " << ingress_mode;
|
||||||
default_rule.setMode(ingress_mode);
|
default_rule.setMode(ingress_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,6 +458,7 @@ K8sPolicyUtils::createAppsecPolicyK8sFromV1beta2Crds(
|
|||||||
);
|
);
|
||||||
|
|
||||||
createSnortFile(threat_prevention_practices);
|
createSnortFile(threat_prevention_practices);
|
||||||
|
createSchemaValidationOas(threat_prevention_practices);
|
||||||
|
|
||||||
vector<AccessControlPracticeSpec> access_control_practices =
|
vector<AccessControlPracticeSpec> access_control_practices =
|
||||||
extractV1Beta2ElementsFromCluster<AccessControlPracticeSpec>(
|
extractV1Beta2ElementsFromCluster<AccessControlPracticeSpec>(
|
||||||
@@ -493,9 +541,12 @@ K8sPolicyUtils::createAppsecPolicyK8s(const string &policy_name, const string &i
|
|||||||
maybe_appsec_policy_spec.ok() ? "There is no v1beta1 policy" : maybe_appsec_policy_spec.getErr();
|
maybe_appsec_policy_spec.ok() ? "There is no v1beta1 policy" : maybe_appsec_policy_spec.getErr();
|
||||||
dbgWarning(D_LOCAL_POLICY
|
dbgWarning(D_LOCAL_POLICY
|
||||||
) << "Failed to retrieve Appsec policy with crds version: v1beta1, Trying version: v1beta2";
|
) << "Failed to retrieve Appsec policy with crds version: v1beta1, Trying version: v1beta2";
|
||||||
|
string ns_suffix = getAppSecScopeType() == "namespaced" ? "ns" : "";
|
||||||
|
string ns = getAppSecScopeType() == "namespaced" ? "namespaces/" : "";
|
||||||
auto maybe_v1beta2_appsec_policy_spec = getObjectFromCluster<AppsecSpecParser<NewAppsecPolicySpec>>(
|
auto maybe_v1beta2_appsec_policy_spec = getObjectFromCluster<AppsecSpecParser<NewAppsecPolicySpec>>(
|
||||||
"/apis/openappsec.io/v1beta2/policies/" + policy_name
|
"/apis/openappsec.io/v1beta2/" + ns + agent_ns + "policies" + ns_suffix + "/" + policy_name
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!maybe_v1beta2_appsec_policy_spec.ok()) {
|
if (!maybe_v1beta2_appsec_policy_spec.ok()) {
|
||||||
dbgWarning(D_LOCAL_POLICY)
|
dbgWarning(D_LOCAL_POLICY)
|
||||||
<< "Failed to retrieve AppSec policy. Error: " << maybe_v1beta2_appsec_policy_spec.getErr();
|
<< "Failed to retrieve AppSec policy. Error: " << maybe_v1beta2_appsec_policy_spec.getErr();
|
||||||
@@ -532,26 +583,38 @@ K8sPolicyUtils::createPolicy(
|
|||||||
map<AnnotationKeys, string> &annotations_values,
|
map<AnnotationKeys, string> &annotations_values,
|
||||||
const SingleIngressData &item) const
|
const SingleIngressData &item) const
|
||||||
{
|
{
|
||||||
|
if (policies.find(annotations_values[AnnotationKeys::PolicyKey]) == policies.end()) {
|
||||||
|
policies[annotations_values[AnnotationKeys::PolicyKey]] = appsec_policy;
|
||||||
|
}
|
||||||
|
auto default_mode = appsec_policy.getAppsecPolicySpec().getDefaultRule().getMode();
|
||||||
|
if (item.getSpec().doesDefaultBackendExist()) {
|
||||||
|
dbgTrace(D_LOCAL_POLICY)
|
||||||
|
<< "Inserting Any host rule to the specific asset set";
|
||||||
|
K ingress_rule = K("*", default_mode);
|
||||||
|
policies[annotations_values[AnnotationKeys::PolicyKey]].addSpecificRule(ingress_rule);
|
||||||
|
}
|
||||||
|
|
||||||
for (const IngressDefinedRule &rule : item.getSpec().getRules()) {
|
for (const IngressDefinedRule &rule : item.getSpec().getRules()) {
|
||||||
string url = rule.getHost();
|
string host = rule.getHost();
|
||||||
for (const IngressRulePath &uri : rule.getPathsWrapper().getRulePaths()) {
|
for (const IngressRulePath &uri : rule.getPathsWrapper().getRulePaths()) {
|
||||||
if (!appsec_policy.getAppsecPolicySpec().isAssetHostExist(url + uri.getPath())) {
|
if (uri.getPath() != "/") {
|
||||||
|
host = host + uri.getPath();
|
||||||
|
}
|
||||||
|
if (!appsec_policy.getAppsecPolicySpec().isAssetHostExist(host)) {
|
||||||
dbgTrace(D_LOCAL_POLICY)
|
dbgTrace(D_LOCAL_POLICY)
|
||||||
<< "Inserting Host data to the specific asset set:"
|
<< "Inserting Host data to the specific asset set:"
|
||||||
<< "URL: '"
|
<< "URL: '"
|
||||||
<< url
|
<< rule.getHost()
|
||||||
<< "' uri: '"
|
<< "' uri: '"
|
||||||
<< uri.getPath()
|
<< uri.getPath()
|
||||||
<< "'";
|
<< "'";
|
||||||
K ingress_rule = K(url + uri.getPath());
|
K ingress_rule = K(host, default_mode);
|
||||||
appsec_policy.addSpecificRule(ingress_rule);
|
policies[annotations_values[AnnotationKeys::PolicyKey]].addSpecificRule(ingress_rule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
policies[annotations_values[AnnotationKeys::PolicyKey]] = appsec_policy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::tuple<map<string, AppsecLinuxPolicy>, map<string, V1beta2AppsecLinuxPolicy>>
|
std::tuple<map<string, AppsecLinuxPolicy>, map<string, V1beta2AppsecLinuxPolicy>>
|
||||||
K8sPolicyUtils::createAppsecPoliciesFromIngresses()
|
K8sPolicyUtils::createAppsecPoliciesFromIngresses()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ NewAppsecPolicySpec::load(cereal::JSONInputArchive &archive_in)
|
|||||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec policy spec";
|
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec policy spec";
|
||||||
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
||||||
parseAppsecJSONKey<NewParsedRule>("default", default_rule, archive_in);
|
parseAppsecJSONKey<NewParsedRule>("default", default_rule, archive_in);
|
||||||
|
default_rule.setHost("*");
|
||||||
parseAppsecJSONKey<vector<NewParsedRule>>("specificRules", specific_rules, archive_in);
|
parseAppsecJSONKey<vector<NewParsedRule>>("specificRules", specific_rules, archive_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ NewAppsecTriggerAccessControlLogging::load(cereal::JSONInputArchive &archive_in)
|
|||||||
{
|
{
|
||||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger - Access Control Logging";
|
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger - Access Control Logging";
|
||||||
parseAppsecJSONKey<bool>("allowEvents", ac_allow_events, archive_in, false);
|
parseAppsecJSONKey<bool>("allowEvents", ac_allow_events, archive_in, false);
|
||||||
parseAppsecJSONKey<bool>("dropEvents", ac_drop_events, archive_in, false);
|
parseAppsecJSONKey<bool>("dropEvents", ac_drop_events, archive_in, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -36,8 +36,7 @@ NewAppsecTriggerAdditionalSuspiciousEventsLogging::load(cereal::JSONInputArchive
|
|||||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger - Additional Suspicious Events Logging";
|
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger - Additional Suspicious Events Logging";
|
||||||
parseAppsecJSONKey<bool>("enabled", enabled, archive_in, true);
|
parseAppsecJSONKey<bool>("enabled", enabled, archive_in, true);
|
||||||
parseAppsecJSONKey<bool>("responseBody", response_body, archive_in, false);
|
parseAppsecJSONKey<bool>("responseBody", response_body, archive_in, false);
|
||||||
//the old code didn't parse the responsecode so ask Noam what is the currenct default value for it
|
parseAppsecJSONKey<bool>("responseCode", response_code, archive_in, true);
|
||||||
parseAppsecJSONKey<bool>("responseCode", response_code, archive_in, false);
|
|
||||||
parseAppsecJSONKey<string>("minSeverity", minimum_severity, archive_in, "high");
|
parseAppsecJSONKey<string>("minSeverity", minimum_severity, archive_in, "high");
|
||||||
if (valid_severities.count(minimum_severity) == 0) {
|
if (valid_severities.count(minimum_severity) == 0) {
|
||||||
dbgWarning(D_LOCAL_POLICY)
|
dbgWarning(D_LOCAL_POLICY)
|
||||||
@@ -133,7 +132,7 @@ void
|
|||||||
NewLoggingService::load(cereal::JSONInputArchive &archive_in)
|
NewLoggingService::load(cereal::JSONInputArchive &archive_in)
|
||||||
{
|
{
|
||||||
parseAppsecJSONKey<string>("address", address, archive_in);
|
parseAppsecJSONKey<string>("address", address, archive_in);
|
||||||
parseAppsecJSONKey<string>("proto", proto, archive_in);
|
parseAppsecJSONKey<string>("proto", proto, archive_in, "tcp");
|
||||||
if (valid_protocols.count(proto) == 0) {
|
if (valid_protocols.count(proto) == 0) {
|
||||||
dbgWarning(D_LOCAL_POLICY) << "AppSec Logging Service - proto invalid: " << proto;
|
dbgWarning(D_LOCAL_POLICY) << "AppSec Logging Service - proto invalid: " << proto;
|
||||||
throw PolicyGenException("AppSec Logging Service - proto invalid: " + proto);
|
throw PolicyGenException("AppSec Logging Service - proto invalid: " + proto);
|
||||||
@@ -175,16 +174,26 @@ void
|
|||||||
NewAppsecTriggerLogDestination::load(cereal::JSONInputArchive &archive_in)
|
NewAppsecTriggerLogDestination::load(cereal::JSONInputArchive &archive_in)
|
||||||
{
|
{
|
||||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger LogDestination";
|
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Trigger LogDestination";
|
||||||
// TBD: support "file"
|
if (getConfigurationFlag("orchestration-mode") != "hybrid_mode") {
|
||||||
parseAppsecJSONKey<bool>("cloud", cloud, archive_in, false);
|
// TBD: support "file"
|
||||||
auto mode = Singleton::Consume<I_AgentDetails>::by<NewAppsecTriggerLogDestination>()->getOrchestrationMode();
|
parseAppsecJSONKey<bool>("cloud", cloud, archive_in, false);
|
||||||
auto env_type = Singleton::Consume<I_EnvDetails>::by<NewAppsecTriggerLogDestination>()->getEnvType();
|
} else {
|
||||||
bool k8s_service_default = (mode == OrchestrationMode::HYBRID && env_type == EnvType::K8S);
|
cloud = false;
|
||||||
parseAppsecJSONKey<bool>("k8s-service", k8s_service, archive_in, k8s_service_default);
|
}
|
||||||
|
bool local_tuning_default = false;
|
||||||
|
// check ENV VAR LOCAL_TUNING_ENABLED
|
||||||
|
char * tuning_enabled = getenv("LOCAL_TUNING_ENABLED");
|
||||||
|
if (tuning_enabled != NULL) {
|
||||||
|
for (unsigned int i = 0; i < strlen(tuning_enabled); i++) {
|
||||||
|
tuning_enabled[i] = tolower(tuning_enabled[i]);
|
||||||
|
}
|
||||||
|
local_tuning_default = string(tuning_enabled) == "true";
|
||||||
|
}
|
||||||
|
parseAppsecJSONKey<bool>("local-tuning", container_service, archive_in, local_tuning_default);
|
||||||
|
|
||||||
NewStdoutLogging stdout_log;
|
NewStdoutLogging stdout_log;
|
||||||
parseAppsecJSONKey<NewStdoutLogging>("stdout", stdout_log, archive_in);
|
parseAppsecJSONKey<NewStdoutLogging>("stdout", stdout_log, archive_in);
|
||||||
agent_local = !(stdout_log.getFormat().empty());
|
parseAppsecJSONKey<bool>("logToAgent", agent_local, archive_in, true);
|
||||||
beautify_logs = stdout_log.getFormat() == "json-formatted";
|
beautify_logs = stdout_log.getFormat() == "json-formatted";
|
||||||
parseAppsecJSONKey<NewLoggingService>("syslogService", syslog_service, archive_in);
|
parseAppsecJSONKey<NewLoggingService>("syslogService", syslog_service, archive_in);
|
||||||
parseAppsecJSONKey<NewLoggingService>("cefService", cef_service, archive_in);
|
parseAppsecJSONKey<NewLoggingService>("cefService", cef_service, archive_in);
|
||||||
@@ -221,9 +230,9 @@ NewAppsecTriggerLogDestination::getCloud() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
NewAppsecTriggerLogDestination::isK8SNeeded() const
|
NewAppsecTriggerLogDestination::isContainerNeeded() const
|
||||||
{
|
{
|
||||||
return k8s_service;
|
return container_service;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user