First release of open-appsec source code

This commit is contained in:
roybarda
2022-10-26 19:33:19 +03:00
parent 3883109caf
commit a883352f79
1353 changed files with 276290 additions and 1 deletions

View File

@@ -0,0 +1,3 @@
add_library(report tag_and_enum_management.cc report.cc)
add_subdirectory(report_ut)

296
core/report/report.cc Normal file
View File

@@ -0,0 +1,296 @@
// 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 "report/report.h"
#include <sstream>
#include <algorithm>
#include "i_encryptor.h"
using namespace std;
USE_DEBUG_FLAG(D_INFRA);
class SyslogReport
{
public:
SyslogReport() = default;
void
push(const string &in)
{
if (!is_init) {
is_init = true;
} else {
data << " ";
}
data << in;
}
string
toString()
{
return data.str();
}
private:
bool is_init = false;
stringstream data;
};
class CefReport
{
public:
CefReport() = default;
void
pushMandatory(const string &in)
{
data << in << "|";
mandetory_fields_count++;
}
void
pushExtension(const string &in)
{
static uint mandetory_fields_before_extension = 7;
if (mandetory_fields_count < mandetory_fields_before_extension) {
dbgWarning(D_INFRA)
<< "Cennot build CEF log, There must be "
<< mandetory_fields_before_extension
<< " before adding extension fields";
return;
}
if (!is_init) {
is_init = true;
} else {
data << " ";
}
data << in;
}
string
toString()
{
return data.str();
}
private:
bool is_init = false;
uint mandetory_fields_count = 0;
stringstream data;
};
const string LogField::Details::cp_xor = "ChkPoint";
const string LogField::Details::cp_xor_label = "{XORANDB64}:";
string
LogField::Details::obfuscateChkPoint(const string &orig)
{
string res;
res.reserve(orig.size());
for (size_t i = 0; i < orig.size(); i++) {
auto j = i % cp_xor.size();
res += orig[i] ^ cp_xor[j];
}
return cp_xor_label + Singleton::Consume<I_Encryptor>::by<Debug>()->base64Encode(res);
}
void
Report::serialize(cereal::JSONOutputArchive &ar) const
{
auto i_time = Singleton::Consume<I_TimeGet>::by<Report>();
string time_stamp = i_time->getWalltimeStr(time);
if (time_stamp.size() > 7 && time_stamp[time_stamp.size() - 7] == '.') {
time_stamp.erase(time_stamp.size() - 3); // downscale micro-sec resollution to milli-sec
}
ar( cereal::make_nvp("eventTime", time_stamp),
cereal::make_nvp("eventName", title),
cereal::make_nvp("eventSeverity", TagAndEnumManagement::convertToString(severity)),
cereal::make_nvp("eventPriority", TagAndEnumManagement::convertToString(priority)),
cereal::make_nvp("eventType", TagAndEnumManagement::convertToString(type)),
cereal::make_nvp("eventLevel", TagAndEnumManagement::convertToString(level)),
cereal::make_nvp("eventLogLevel", TagAndEnumManagement::convertToString(log_level)),
cereal::make_nvp("eventAudience", TagAndEnumManagement::convertToString(audience)),
cereal::make_nvp("eventAudienceTeam", TagAndEnumManagement::convertToString(audience_team)),
cereal::make_nvp("eventFrequency", frequency),
cereal::make_nvp("eventTags", TagAndEnumManagement::convertToString(tags))
);
origin.serialize(ar);
event_data.serialize(ar);
}
string
Report::getSyslog() const
{
static int counter = 0;
SyslogReport report;
auto i_time = Singleton::Consume<I_TimeGet>::by<Report>();
string time_stamp = i_time->getWalltimeStr(time);
if (time_stamp.size() > 7 && time_stamp[time_stamp.size() - 7] == '.') {
time_stamp.erase(time_stamp.size() - 3); // downscale micro-sec resoloution to milli-sec
}
time_stamp += "Z";
string origin_syslog = origin.getSyslog();
string event_data_syslog = event_data.getSyslog();
string agent_id = "cpnano-agent-" + Singleton::Consume<I_AgentDetails>::by<Report>()->getAgentId();
auto service_name = Singleton::Consume<I_Environment>::by<Report>()->get<string>("Service Name");
if (service_name.ok()) {
string tmp = service_name.unpack();
tmp.erase(remove_if(tmp.begin(), tmp.end(), [](const char &t) { return t == ' '; }), tmp.end());
service_name = tmp;
} else {
service_name = "UnnamedNanoService";
}
// Facility (Value 16), Severity (Value 5) and Version (Value 1) 16*8+5= 133
report.push("<133>1");
report.push(time_stamp); // Timestamp
report.push(agent_id); // Hostname
report.push(*service_name); // App-name
report.push("-"); // Process-Id (Null)
report.push(to_string(counter++)); // Message-ID
report.push("-"); // Strcutred-data (Null)
// Message payload
report.push("title='" + title + "'");
if (!origin_syslog.empty()) {
report.push(origin_syslog);
}
if (!event_data_syslog.empty()) {
report.push(event_data_syslog);
}
return report.toString();
}
string
Report::getCef() const
{
CefReport report;
auto service_name = Singleton::Consume<I_Environment>::by<Report>()->get<string>("Service Name");
if (service_name.ok()) {
string tmp = service_name.unpack();
tmp.erase(remove(tmp.begin(), tmp.end(), ' '), tmp.end());
service_name = tmp;
} else {
service_name = "UnnamedNanoService";
}
string version = "";
report.pushMandatory("CEF:0");
report.pushMandatory("Check Point");
report.pushMandatory(*service_name);
report.pushMandatory(version);
report.pushMandatory(TagAndEnumManagement::convertToString(type));
report.pushMandatory(title);
report.pushMandatory(TagAndEnumManagement::convertToString(priority));
string origin_cef = origin.getCef();
string event_data_cef = event_data.getCef();
if (!origin_cef.empty()) {
report.pushExtension(origin_cef);
}
if (!event_data_cef.empty()) {
report.pushExtension(event_data_cef);
}
return report.toString();
}
Report &
Report::operator<<(const LogField &log)
{
event_data.addFields(log);
return *this;
}
void
Report::addToOrigin(const LogField &field)
{
origin.addFields(field);
}
void
Report::setTenantID()
{
if (Singleton::exists<I_Environment>()) {
auto tenant_id = Singleton::Consume<I_Environment>::by<Report>()->get<string>("ActiveTenantId");
if (tenant_id.ok()) origin.addFields(LogField("eventTenantId", *tenant_id));
}
}
void
Report::setTraceID()
{
string trace_id;
if (Singleton::exists<I_Environment>()) {
trace_id = Singleton::Consume<I_Environment>::by<Report>()->getCurrentTrace();
}
origin.addFields(LogField("eventTraceId", trace_id));
}
void
Report::setSpanID()
{
string span_id;
if (Singleton::exists<I_Environment>()) {
span_id = Singleton::Consume<I_Environment>::by<Report>()->getCurrentSpan();
}
origin.addFields(LogField("eventSpanId", span_id));
}
void
Report::setEngineVersion()
{
string engine_version;
if (Singleton::exists<I_Environment>()) {
auto version = Singleton::Consume<I_Environment>::by<Report>()->get<string>("Service Version");
if (version.ok()) engine_version = *version;
}
origin.addFields(LogField("issuingEngineVersion", engine_version));
}
void
Report::setServiceName()
{
string service_name = "Unnamed Nano Service";
if (Singleton::exists<I_Environment>()) {
auto name = Singleton::Consume<I_Environment>::by<Report>()->get<string>("Service Name");
if (name.ok()) service_name = *name;
}
origin.addFields(LogField("serviceName", service_name));
}
void
Report::setInstanceAwareness()
{
if (Singleton::exists<I_InstanceAwareness>()) {
auto instance_awareness = Singleton::Consume<I_InstanceAwareness>::by<Report>();
auto uid = instance_awareness->getUniqueID();
auto family_id = instance_awareness->getFamilyID();
if (uid.ok()) origin.addFields(LogField("serviceId", uid.unpack()));
if (family_id.ok()) origin.addFields(LogField("serviceFamilyId", family_id.unpack()));
}
}

View File

@@ -0,0 +1,5 @@
add_unit_test(
report_ut
"report_ut.cc"
"report;config;encryptor;environment;metric;event_is;-lboost_regex;-lcrypto"
)

View File

@@ -0,0 +1,698 @@
#include "report/report.h"
#include "tag_and_enum_management.h"
#include <sstream>
#include <set>
#include "cptest.h"
#include "encryptor.h"
#include "config.h"
#include "config_component.h"
#include "mock/mock_time_get.h"
#include "mock/mock_environment.h"
#include "mock/mock_agent_details.h"
#include "mock/mock_instance_awareness.h"
using namespace testing;
using namespace std;
using namespace ReportIS;
class ReportTest : public Test
{
public:
ReportTest()
{
EXPECT_CALL(mock_timer, getWalltimeStr(_)).WillRepeatedly(Return("0:0:0.123456"));
EXPECT_CALL(mock_timer, getWalltime()).WillRepeatedly(Return(chrono::seconds(0)));
EXPECT_CALL(mock_env, getCurrentTrace()).WillRepeatedly(Return(""));
EXPECT_CALL(mock_env, getCurrentSpan()).WillRepeatedly(Return(""));
EXPECT_CALL(mock_env, getActiveContexts()).WillRepeatedly(ReturnRef(empty));
EXPECT_CALL(mock_agent_details, getAgentId()).WillRepeatedly(Return("001"));
EXPECT_CALL(mock_instance_awareness, getUniqueID()).WillRepeatedly(Return(Maybe<string>(string(""))));
EXPECT_CALL(mock_instance_awareness, getFamilyID()).WillRepeatedly(Return(Maybe<string>(string(""))));
}
string
toString(ostream& str)
{
ostringstream ss;
ss << str.rdbuf();
return ss.str();
}
template <typename T>
string
toJson(const T &obj)
{
stringstream ss;
{
cereal::JSONOutputArchive ar(ss);
obj.serialize(ar);
}
return ss.str();
}
StrictMock<MockEnvironment> mock_env;
StrictMock<MockAgentDetails> mock_agent_details;
void registerServiceName(const string &name) { ctx.registerValue("Service Name", name); }
void activateObfuscation() { ctx.registerValue<bool>("Obfuscate log field", true); }
private:
StrictMock<MockTimeGet> mock_timer;
StrictMock<MockInstanceAwareness> mock_instance_awareness;
Encryptor encryptor;
ConfigComponent config;
Context ctx;
std::pair<std::vector<Context *>, bool> empty{{&ctx}, true};
};
TEST_F(ReportTest, TagManagementTest)
{
stringstream os;
TagAndEnumManagement::print(Tags::NEW_APPROVE_TRANSACTION, os);
EXPECT_EQ(toString(os), "New Approve Transaction");
set<Tags> tagSet;
tagSet.insert(Tags::NEW_APPROVE_TRANSACTION);
tagSet.insert(Tags::POLICY_INSTALLATION);
set<string> stringSet;
stringSet.insert("New Approve Transaction");
stringSet.insert("Policy Installation");
EXPECT_EQ(TagAndEnumManagement::convertToString(tagSet), stringSet);
}
TEST(TagTest, TagStringTest)
{
set<string> tags_string;
for (Tags tag : makeRange<Tags>()) {
tags_string = TagAndEnumManagement::convertToString({tag});
ASSERT_EQ(tags_string.size(), 1);
Maybe<Tags> tag_from_string = TagAndEnumManagement::convertStringToTag(*tags_string.begin());
ASSERT_TRUE(tag_from_string.ok());
EXPECT_EQ(tag_from_string.unpack(), tag);
}
}
TEST_F(ReportTest, StringConvertion)
{
EXPECT_EQ(TagAndEnumManagement::convertToString(Severity::CRITICAL), "Critical");
EXPECT_EQ(TagAndEnumManagement::convertToString(Severity::HIGH), "High");
EXPECT_EQ(TagAndEnumManagement::convertToString(Severity::MEDIUM), "Medium");
EXPECT_EQ(TagAndEnumManagement::convertToString(Severity::LOW), "Low");
EXPECT_EQ(TagAndEnumManagement::convertToString(Severity::INFO), "Info");
EXPECT_EQ(TagAndEnumManagement::convertToString(Type::EVENT), "Event Driven");
EXPECT_EQ(TagAndEnumManagement::convertToString(Type::PERIODIC), "Periodic");
EXPECT_EQ(TagAndEnumManagement::convertToString(Type::CODE), "Code Related");
EXPECT_EQ(TagAndEnumManagement::convertToString(Level::LOG), "Log");
EXPECT_EQ(TagAndEnumManagement::convertToString(Level::INCIDENT), "Incident");
EXPECT_EQ(TagAndEnumManagement::convertToString(Level::INSIGHT), "Insight");
EXPECT_EQ(TagAndEnumManagement::convertToString(Level::ACTION), "Action Item");
EXPECT_EQ(TagAndEnumManagement::convertToString(Level::CUSTOM), "Custom");
EXPECT_EQ(TagAndEnumManagement::convertToString(LogLevel::TRACE), "trace");
EXPECT_EQ(TagAndEnumManagement::convertToString(LogLevel::DEBUG), "debug");
EXPECT_EQ(TagAndEnumManagement::convertToString(LogLevel::INFO), "info");
EXPECT_EQ(TagAndEnumManagement::convertToString(LogLevel::WARNING), "warning");
EXPECT_EQ(TagAndEnumManagement::convertToString(LogLevel::ERROR), "error");
EXPECT_EQ(TagAndEnumManagement::convertToString(Audience::SECURITY), "Security");
EXPECT_EQ(TagAndEnumManagement::convertToString(Audience::INTERNAL), "Internal");
EXPECT_EQ(
TagAndEnumManagement::convertToString(Notification::POLICY_UPDATE),
"c0516360-a0b1-4246-af4c-2b6c586958e0"
);
EXPECT_EQ(
TagAndEnumManagement::convertToString(IssuingEngine::AGENT_CORE),
"Agent Core"
);
}
TEST_F(ReportTest, TypedField)
{
EXPECT_EQ(
toJson(LogField("Integer", 5)),
"{\n"
" \"Integer\": 5\n"
"}"
);
EXPECT_EQ(
toJson(LogField("String", "Another string")),
"{\n"
" \"String\": \"Another string\"\n"
"}"
);
}
TEST_F(ReportTest, TypedFieldXorAndB64)
{
EXPECT_EQ(
toJson(LogField("String", "Another string", LogFieldOption::XORANDB64)),
"{\n"
" \"String\": \"Another string\"\n"
"}"
);
activateObfuscation();
EXPECT_EQ(
toJson(LogField("String", "Another string", LogFieldOption::XORANDB64)),
"{\n"
" \"String\": \"{XORANDB64}:AgYEJAcMHFQwHBk5AQ4=\"\n"
"}"
);
EXPECT_EQ(
toJson(LogField("Integer", 5, LogFieldOption::XORANDB64)),
"{\n"
" \"Integer\": 5\n"
"}"
);
}
TEST_F(ReportTest, TypedFieldValidation)
{
I_Environment::ActiveContexts active_context;
EXPECT_CALL(mock_env, getActiveContexts()).WillRepeatedly(ReturnRef(active_context));
cptestPrepareToDie();
EXPECT_DEATH(
LogField("Integer", 5).addFields(LogField("Integer", 5)),
"Trying to add a log field to a 'type'ed field"
);
}
TEST_F(ReportTest, StringTypesToEnum)
{
EXPECT_TRUE(TagAndEnumManagement::convertStringToSeverity("Critical") == ReportIS::Severity::CRITICAL);
EXPECT_TRUE(TagAndEnumManagement::convertStringToSeverity("High") == ReportIS::Severity::HIGH);
EXPECT_TRUE(TagAndEnumManagement::convertStringToSeverity("Medium") == ReportIS::Severity::MEDIUM);
EXPECT_TRUE(TagAndEnumManagement::convertStringToSeverity("Low") == ReportIS::Severity::LOW);
EXPECT_TRUE(TagAndEnumManagement::convertStringToSeverity("Info") == ReportIS::Severity::INFO);
EXPECT_TRUE(TagAndEnumManagement::convertStringToPriority("Urgent") == ReportIS::Priority::URGENT);
EXPECT_TRUE(TagAndEnumManagement::convertStringToPriority("High") == ReportIS::Priority::HIGH);
EXPECT_TRUE(TagAndEnumManagement::convertStringToPriority("Medium") == ReportIS::Priority::MEDIUM);
EXPECT_TRUE(TagAndEnumManagement::convertStringToPriority("Low") == ReportIS::Priority::LOW);
EXPECT_TRUE(TagAndEnumManagement::convertStringToAudience("Security") == ReportIS::Audience::SECURITY);
EXPECT_TRUE(TagAndEnumManagement::convertStringToAudience("Internal") == ReportIS::Audience::INTERNAL);
EXPECT_TRUE(TagAndEnumManagement::convertStringToLevel("Action Item") == ReportIS::Level::ACTION);
EXPECT_TRUE(TagAndEnumManagement::convertStringToLevel("Custom") == ReportIS::Level::CUSTOM);
EXPECT_TRUE(TagAndEnumManagement::convertStringToLevel("Incident") == ReportIS::Level::INCIDENT);
EXPECT_TRUE(TagAndEnumManagement::convertStringToLevel("Insight") == ReportIS::Level::INSIGHT);
EXPECT_TRUE(TagAndEnumManagement::convertStringToLevel("Log") == ReportIS::Level::LOG);
EXPECT_TRUE(TagAndEnumManagement::convertStringToLogLevel("Trace") == ReportIS::LogLevel::TRACE);
EXPECT_TRUE(TagAndEnumManagement::convertStringToLogLevel("Debug") == ReportIS::LogLevel::DEBUG);
EXPECT_TRUE(TagAndEnumManagement::convertStringToLogLevel("Info") == ReportIS::LogLevel::INFO);
EXPECT_TRUE(TagAndEnumManagement::convertStringToLogLevel("Warning") == ReportIS::LogLevel::WARNING);
EXPECT_TRUE(TagAndEnumManagement::convertStringToLogLevel("Error") == ReportIS::LogLevel::ERROR);
}
TEST_F(ReportTest, AggrField)
{
EXPECT_EQ(
toJson(LogField("AggField")),
"{\n"
" \"AggField\": {}\n"
"}"
);
EXPECT_EQ(
toJson(LogField("AggField", LogField("key1", "val1"))),
"{\n"
" \"AggField\": {\n"
" \"key1\": \"val1\"\n"
" }\n"
"}"
);
auto field = LogField("AggField");
field.addFields(LogField("key1", "val1"));
field.addFields(LogField("key2", "val2"));
field.addFields(LogField("key3", "val3"));
EXPECT_EQ(
toJson(field),
"{\n"
" \"AggField\": {\n"
" \"key1\": \"val1\",\n"
" \"key2\": \"val2\",\n"
" \"key3\": \"val3\"\n"
" }\n"
"}"
);
}
TEST_F(ReportTest, Report)
{
Tags tag1 = Tags::POLICY_INSTALLATION;
Tags tag2 = Tags::ACCESS_CONTROL;
LogField origin("agent", "Secret");
::Report report(
"Log Test",
chrono::microseconds(90000),
Type::EVENT,
Level::LOG,
LogLevel::INFO,
Audience::INTERNAL,
AudienceTeam::AGENT_CORE,
Severity::INFO,
Priority::LOW,
chrono::seconds(3600),
origin,
tag1,
tag2,
Notification::POLICY_UPDATE,
IssuingEngine::AGENT_CORE
);
EXPECT_EQ(
toJson(report),
"{\n"
" \"eventTime\": \"0:0:0.123\",\n"
" \"eventName\": \"Log Test\",\n"
" \"eventSeverity\": \"Info\",\n"
" \"eventPriority\": \"Low\",\n"
" \"eventType\": \"Event Driven\",\n"
" \"eventLevel\": \"Log\",\n"
" \"eventLogLevel\": \"info\",\n"
" \"eventAudience\": \"Internal\",\n"
" \"eventAudienceTeam\": \"Agent Core\",\n"
" \"eventFrequency\": 3600,\n"
" \"eventTags\": [\n"
" \"Access Control\",\n"
" \"Policy Installation\"\n"
" ],\n"
" \"eventSource\": {\n"
" \"agent\": \"Secret\",\n"
" \"issuingEngine\": \"Agent Core\",\n"
" \"eventTraceId\": \"\",\n"
" \"eventSpanId\": \"\",\n"
" \"issuingEngineVersion\": \"\",\n"
" \"serviceName\": \"Unnamed Nano Service\",\n"
" \"serviceId\": \"\",\n"
" \"serviceFamilyId\": \"\"\n"
" },\n"
" \"eventData\": {\n"
" \"notificationId\": \"c0516360-a0b1-4246-af4c-2b6c586958e0\"\n"
" }\n"
"}"
);
}
TEST_F(ReportTest, ReportWithoutIssuingEngine)
{
Tags tag1 = Tags::POLICY_INSTALLATION;
Tags tag2 = Tags::ACCESS_CONTROL;
LogField origin("agent", "Secret");
::Report report(
"Log Test",
chrono::microseconds(90000),
Type::EVENT,
Level::LOG,
LogLevel::INFO,
Audience::INTERNAL,
AudienceTeam::AGENT_CORE,
Severity::INFO,
Priority::LOW,
chrono::seconds(3600),
origin,
tag1,
tag2,
Notification::POLICY_UPDATE
);
EXPECT_EQ(
toJson(report),
"{\n"
" \"eventTime\": \"0:0:0.123\",\n"
" \"eventName\": \"Log Test\",\n"
" \"eventSeverity\": \"Info\",\n"
" \"eventPriority\": \"Low\",\n"
" \"eventType\": \"Event Driven\",\n"
" \"eventLevel\": \"Log\",\n"
" \"eventLogLevel\": \"info\",\n"
" \"eventAudience\": \"Internal\",\n"
" \"eventAudienceTeam\": \"Agent Core\",\n"
" \"eventFrequency\": 3600,\n"
" \"eventTags\": [\n"
" \"Access Control\",\n"
" \"Policy Installation\"\n"
" ],\n"
" \"eventSource\": {\n"
" \"agent\": \"Secret\",\n"
" \"eventTraceId\": \"\",\n"
" \"eventSpanId\": \"\",\n"
" \"issuingEngineVersion\": \"\",\n"
" \"serviceName\": \"Unnamed Nano Service\",\n"
" \"serviceId\": \"\",\n"
" \"serviceFamilyId\": \"\"\n"
" },\n"
" \"eventData\": {\n"
" \"notificationId\": \"c0516360-a0b1-4246-af4c-2b6c586958e0\"\n"
" }\n"
"}"
);
}
TEST_F(ReportTest, ReportWithoutNotification)
{
Tags tag1 = Tags::POLICY_INSTALLATION;
Tags tag2 = Tags::ACCESS_CONTROL;
LogField origin("agent", "Secret");
::Report report(
"Log Test",
chrono::microseconds(90000),
Type::EVENT,
Level::LOG,
LogLevel::INFO,
Audience::INTERNAL,
AudienceTeam::AGENT_CORE,
Severity::INFO,
Priority::LOW,
chrono::seconds(3600),
origin,
tag1,
tag2,
IssuingEngine::AGENT_CORE
);
EXPECT_EQ(
toJson(report),
"{\n"
" \"eventTime\": \"0:0:0.123\",\n"
" \"eventName\": \"Log Test\",\n"
" \"eventSeverity\": \"Info\",\n"
" \"eventPriority\": \"Low\",\n"
" \"eventType\": \"Event Driven\",\n"
" \"eventLevel\": \"Log\",\n"
" \"eventLogLevel\": \"info\",\n"
" \"eventAudience\": \"Internal\",\n"
" \"eventAudienceTeam\": \"Agent Core\",\n"
" \"eventFrequency\": 3600,\n"
" \"eventTags\": [\n"
" \"Access Control\",\n"
" \"Policy Installation\"\n"
" ],\n"
" \"eventSource\": {\n"
" \"agent\": \"Secret\",\n"
" \"issuingEngine\": \"Agent Core\",\n"
" \"eventTraceId\": \"\",\n"
" \"eventSpanId\": \"\",\n"
" \"issuingEngineVersion\": \"\",\n"
" \"serviceName\": \"Unnamed Nano Service\",\n"
" \"serviceId\": \"\",\n"
" \"serviceFamilyId\": \"\"\n"
" },\n"
" \"eventData\": {}\n"
"}"
);
}
TEST_F(ReportTest, AddOrigin)
{
Tags tag1 = Tags::POLICY_INSTALLATION;
Tags tag2 = Tags::ACCESS_CONTROL;
LogField origin("agent", "Secret");
LogField another_origin("Bond", "James");
::Report report(
"Log Test",
chrono::microseconds(90000),
Type::EVENT,
Level::LOG,
LogLevel::INFO,
Audience::INTERNAL,
AudienceTeam::AGENT_CORE,
Severity::INFO,
Priority::LOW,
chrono::seconds(0),
origin,
tag1,
tag2,
Notification::POLICY_UPDATE,
IssuingEngine::AGENT_CORE
);
report.addToOrigin(another_origin);
EXPECT_EQ(
toJson(report),
"{\n"
" \"eventTime\": \"0:0:0.123\",\n"
" \"eventName\": \"Log Test\",\n"
" \"eventSeverity\": \"Info\",\n"
" \"eventPriority\": \"Low\",\n"
" \"eventType\": \"Event Driven\",\n"
" \"eventLevel\": \"Log\",\n"
" \"eventLogLevel\": \"info\",\n"
" \"eventAudience\": \"Internal\",\n"
" \"eventAudienceTeam\": \"Agent Core\",\n"
" \"eventFrequency\": 0,\n"
" \"eventTags\": [\n"
" \"Access Control\",\n"
" \"Policy Installation\"\n"
" ],\n"
" \"eventSource\": {\n"
" \"agent\": \"Secret\",\n"
" \"issuingEngine\": \"Agent Core\",\n"
" \"eventTraceId\": \"\",\n"
" \"eventSpanId\": \"\",\n"
" \"issuingEngineVersion\": \"\",\n"
" \"serviceName\": \"Unnamed Nano Service\",\n"
" \"serviceId\": \"\",\n"
" \"serviceFamilyId\": \"\",\n"
" \"Bond\": \"James\"\n"
" },\n"
" \"eventData\": {\n"
" \"notificationId\": \"c0516360-a0b1-4246-af4c-2b6c586958e0\"\n"
" }\n"
"}"
);
}
TEST_F(ReportTest, TagSet)
{
Tags tag1 = Tags::POLICY_INSTALLATION;
Tags tag2 = Tags::ACCESS_CONTROL;
Tags tag3 = Tags::FW;
set<Tags> tag_set = { tag1, tag3 };
LogField origin("agent", "Secret");
::Report report(
"Log Test",
chrono::microseconds(90000),
Type::EVENT,
Level::LOG,
LogLevel::INFO,
Audience::INTERNAL,
AudienceTeam::AGENT_CORE,
Severity::INFO,
Priority::LOW,
chrono::seconds(0),
origin,
tag_set,
tag2,
Notification::POLICY_UPDATE,
IssuingEngine::AGENT_CORE
);
EXPECT_EQ(
toJson(report),
"{\n"
" \"eventTime\": \"0:0:0.123\",\n"
" \"eventName\": \"Log Test\",\n"
" \"eventSeverity\": \"Info\",\n"
" \"eventPriority\": \"Low\",\n"
" \"eventType\": \"Event Driven\",\n"
" \"eventLevel\": \"Log\",\n"
" \"eventLogLevel\": \"info\",\n"
" \"eventAudience\": \"Internal\",\n"
" \"eventAudienceTeam\": \"Agent Core\",\n"
" \"eventFrequency\": 0,\n"
" \"eventTags\": [\n"
" \"Access Control\",\n"
" \"Firewall Information\",\n"
" \"Policy Installation\"\n"
" ],\n"
" \"eventSource\": {\n"
" \"agent\": \"Secret\",\n"
" \"issuingEngine\": \"Agent Core\",\n"
" \"eventTraceId\": \"\",\n"
" \"eventSpanId\": \"\",\n"
" \"issuingEngineVersion\": \"\",\n"
" \"serviceName\": \"Unnamed Nano Service\",\n"
" \"serviceId\": \"\",\n"
" \"serviceFamilyId\": \"\"\n"
" },\n"
" \"eventData\": {\n"
" \"notificationId\": \"c0516360-a0b1-4246-af4c-2b6c586958e0\"\n"
" }\n"
"}"
);
}
TEST_F(ReportTest, testSyslogWithoutServiceName)
{
Tags tag1 = Tags::POLICY_INSTALLATION;
Tags tag2 = Tags::ACCESS_CONTROL;
Tags tag3 = Tags::FW;
set<Tags> tag_set = { tag1, tag3 };
LogField origin("agent", "Secret");
::Report report(
"Log Test",
chrono::microseconds(90000),
Type::EVENT,
Level::LOG,
LogLevel::INFO,
Audience::INTERNAL,
AudienceTeam::AGENT_CORE,
Severity::INFO,
Priority::LOW,
chrono::seconds(0),
origin,
tag_set,
tag2
);
EXPECT_EQ(
report.getSyslog(),
"<133>1 0:0:0.123Z cpnano-agent-001 UnnamedNanoService - 0 - "
"title='Log Test' agent='Secret' eventTraceId='' eventSpanId='' "
"issuingEngineVersion='' serviceName='Unnamed Nano Service' serviceId='' serviceFamilyId=''"
);
}
TEST_F(ReportTest, testSyslog)
{
Tags tag1 = Tags::POLICY_INSTALLATION;
Tags tag2 = Tags::ACCESS_CONTROL;
Tags tag3 = Tags::FW;
set<Tags> tag_set = { tag1, tag3 };
LogField origin("agent", "Secret");
registerServiceName("Access Control App");
::Report report(
"Log Test",
chrono::microseconds(90000),
Type::EVENT,
Level::LOG,
LogLevel::INFO,
Audience::INTERNAL,
AudienceTeam::AGENT_CORE,
Severity::INFO,
Priority::LOW,
chrono::seconds(0),
origin,
tag_set,
tag2
);
vector<vector<string>> f1 = { { "a", "b"}, {"1", "2"} };
report << LogField("ArrayOfArraies", f1);
string result =
string("<133>1 0:0:0.123Z cpnano-agent-001 AccessControlApp - 1 - "
"title='Log Test' agent='Secret'") +
" eventTraceId='' eventSpanId='' issuingEngineVersion=''" +
" serviceName='Access Control App' serviceId='' serviceFamilyId=''" +
string(" ArrayOfArraies='[ [ a, b ], [ 1, 2 ] ]'");
EXPECT_EQ(report.getSyslog(), result);
}
TEST_F(ReportTest, testCef)
{
Tags tag1 = Tags::POLICY_INSTALLATION;
Tags tag2 = Tags::ACCESS_CONTROL;
Tags tag3 = Tags::FW;
set<Tags> tag_set = { tag1, tag3 };
LogField origin("agent", "Secret");
LogField another_origin("Bond", 1);
registerServiceName("Access Control App");
::Report report(
"Log Test",
chrono::microseconds(90000),
Type::EVENT,
Level::LOG,
LogLevel::INFO,
Audience::INTERNAL,
AudienceTeam::AGENT_CORE,
Severity::INFO,
Priority::LOW,
chrono::seconds(0),
origin,
tag_set,
tag2
);
report.addToOrigin(another_origin);
EXPECT_EQ(
report.getCef(),
"CEF:0|Check Point|AccessControlApp||Event Driven|Log Test|Low|"
"agent=Secret eventTraceId= eventSpanId= issuingEngineVersion="
" serviceName=Access Control App serviceId= serviceFamilyId= Bond=1"
);
}
TEST_F(ReportTest, DataAccess)
{
Tags tag = Tags::FW;
LogField origin("agent", "Secret");
::Report report(
"Log Test",
chrono::microseconds(90000),
Type::EVENT,
Level::LOG,
LogLevel::INFO,
Audience::INTERNAL,
AudienceTeam::AGENT_CORE,
Severity::INFO,
Priority::LOW,
chrono::seconds(0),
origin,
tag
);
report << LogField("basic1", "ggg");
LogField aggr1("aggr1");
aggr1.addFields(LogField("basic2", "hhh"));
aggr1.addFields(LogField("basic3", 7));
report << aggr1;
auto res1 = report.getStringData("basic1");
EXPECT_EQ(*res1, "ggg");
auto res2 = report.getStringData("basic2");
EXPECT_FALSE(res2.ok());
auto res3 = report.getStringData("aggr1", "basic2");
EXPECT_EQ(*res3, "hhh");
auto res4 = report.getStringData("aggr1", "basic3");
EXPECT_EQ(*res4, "7");
auto res5 = report.getStringData("aggr1", "basic3", "no_field");
EXPECT_FALSE(res5.ok());
auto res6 = report.getStringData("aggr1");
EXPECT_FALSE(res6.ok());
}

View File

@@ -0,0 +1,318 @@
// 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 "tag_and_enum_management.h"
#include "debug.h"
using namespace std;
using namespace ReportIS;
#include <unordered_map>
Maybe<ReportIS::Severity>
TagAndEnumManagement::convertStringToSeverity(const string &severity)
{
if (severity == "Critical") return ReportIS::Severity::CRITICAL;
if (severity == "High") return ReportIS::Severity::HIGH;
if (severity == "Medium") return ReportIS::Severity::MEDIUM;
if (severity == "Low") return ReportIS::Severity::LOW;
if (severity == "Info") return ReportIS::Severity::INFO;
return genError("illegal severity: " + severity);
}
Maybe<ReportIS::Priority>
TagAndEnumManagement::convertStringToPriority(const string &priority)
{
if (priority == "Urgent") return ReportIS::Priority::URGENT;
if (priority == "High") return ReportIS::Priority::HIGH;
if (priority == "Medium") return ReportIS::Priority::MEDIUM;
if (priority == "Low") return ReportIS::Priority::LOW;
return genError("illegal priority: " + priority);
}
Maybe<ReportIS::Audience>
TagAndEnumManagement::convertStringToAudience(const string &audience)
{
if (audience == "Security") return ReportIS::Audience::SECURITY;
if (audience == "Internal") return ReportIS::Audience::INTERNAL;
return genError("illegal audience: " + audience);
}
Maybe<ReportIS::Level>
TagAndEnumManagement::convertStringToLevel(const string &level)
{
if (level == "Action Item") return ReportIS::Level::ACTION;
if (level == "Custom") return ReportIS::Level::CUSTOM;
if (level == "Incident") return ReportIS::Level::INCIDENT;
if (level == "Insight") return ReportIS::Level::INSIGHT;
if (level == "Log") return ReportIS::Level::LOG;
return genError("illegal level: " + level);
}
Maybe<ReportIS::LogLevel>
TagAndEnumManagement::convertStringToLogLevel(const string &log_level)
{
if (log_level == "Trace") return ReportIS::LogLevel::TRACE;
if (log_level == "Debug") return ReportIS::LogLevel::DEBUG;
if (log_level == "Info") return ReportIS::LogLevel::INFO;
if (log_level == "Warning") return ReportIS::LogLevel::WARNING;
if (log_level == "Error") return ReportIS::LogLevel::ERROR;
return genError("illegal log level: " + log_level);
}
Maybe<ReportIS::Tags>
TagAndEnumManagement::convertStringToTag(const string &tag)
{
static const unordered_map<string, ReportIS::Tags> strings_to_tags = {
{"Threat Prevention", ReportIS::Tags::THREAT_PREVENTION},
{"Remote Code Execution", ReportIS::Tags::REMOTE_CODE_EXECUTION},
{"Elevation Of Privileges", ReportIS::Tags::ELEVATION_OF_PRIVILEGES},
{"New Connection", ReportIS::Tags::NEW_CONNECTION},
{"Policy Installation", ReportIS::Tags::POLICY_INSTALLATION},
{"Access Control", ReportIS::Tags::ACCESS_CONTROL},
{"Data Leak", ReportIS::Tags::DATA_LEAK},
{"New Approve Transaction", ReportIS::Tags::NEW_APPROVE_TRANSACTION},
{"Firewall Information", ReportIS::Tags::FW},
{"Web Application & API Protection", ReportIS::Tags::WAF},
{"IPS", ReportIS::Tags::IPS},
{"URL Filtering", ReportIS::Tags::URLF},
{"Informational", ReportIS::Tags::INFORMATIONAL},
{"Orchestration", ReportIS::Tags::ORCHESTRATOR},
{"Compliance", ReportIS::Tags::COMPLIANCE},
{"IoT", ReportIS::Tags::IOT},
{"SDWAN", ReportIS::Tags::SDWAN},
{"CP_SDWAN", ReportIS::Tags::CP_SDWAN},
{"SDWAN_DATA_SHARING", ReportIS::Tags::SDWAN_DATA_SHARING},
{"SDWAN_POLICY_ERROR", ReportIS::Tags::SDWAN_POLICY_ERROR},
{"CPView Monitoring", ReportIS::Tags::CPVIEW_METRICS},
{"Reverse Proxy", ReportIS::Tags::REVERSE_PROXY},
{"Http Geo Filter", ReportIS::Tags::HTTP_GEO_FILTER},
{"File Upload", ReportIS::Tags::FILE_UPLOAD}
};
auto report_is_tag = strings_to_tags.find(tag);
if (report_is_tag != strings_to_tags.end()) return report_is_tag->second;
return genError("illegal tag: " + tag);
}
void
TagAndEnumManagement::print(Tags tag, ostream& os)
{
os << tags_translation_arr[tag];
}
set<string>
TagAndEnumManagement::convertToString(const set<Tags> &tags)
{
set<string> result;
for (auto &tag : tags) {
result.insert(tags_translation_arr[tag]);
}
return result;
}
string
TagAndEnumManagement::convertToString(const AudienceTeam &audience_team)
{
return audience_team_translation[audience_team];
}
string
TagAndEnumManagement::convertToString(const StreamType &stream_type)
{
switch (stream_type) {
case StreamType::JSON_DEBUG: return "JSON Debug stream";
case StreamType::JSON_FOG: return "JSON FOG stream";
case StreamType::JSON_LOG_FILE: return "JSON File stream";
case StreamType::SYSLOG: return "Syslog stream";
case StreamType::CEF: return "CEF stream";
case StreamType::NONE: break;
case StreamType::COUNT: break;
}
dbgAssert(false) << "Unknown log stream type. Type: " << static_cast<int>(stream_type);
return "";
}
string
TagAndEnumManagement::convertToString(const Severity &severity)
{
switch (severity) {
case Severity::CRITICAL: return "Critical";
case Severity::HIGH: return "High";
case Severity::MEDIUM: return "Medium";
case Severity::LOW: return "Low";
case Severity::INFO: return "Info";
}
dbgAssert(false) << "Reached an impossible severity value of: " << static_cast<int>(severity);
return "";
}
string
TagAndEnumManagement::convertToString(const Type &type)
{
switch (type) {
case Type::EVENT: return "Event Driven";
case Type::PERIODIC: return "Periodic";
case Type::CODE: return "Code Related";
}
dbgAssert(false) << "Reached an impossible type value of: " << static_cast<int>(type);
return "";
}
string
TagAndEnumManagement::convertToString(const Level &level)
{
switch (level) {
case Level::LOG: return "Log";
case Level::INCIDENT: return "Incident";
case Level::INSIGHT: return "Insight";
case Level::ACTION: return "Action Item";
case Level::CUSTOM: return "Custom";
}
dbgAssert(false) << "Reached an impossible type value of: " << static_cast<int>(level);
return "";
}
string
TagAndEnumManagement::convertToString(const LogLevel &log_level)
{
switch (log_level) {
case LogLevel::TRACE: return "trace";
case LogLevel::DEBUG: return "debug";
case LogLevel::INFO: return "info";
case LogLevel::WARNING: return "warning";
case LogLevel::ERROR: return "error";
}
dbgAssert(false) << "Reached an impossible type value of: " << static_cast<int>(log_level);
return "";
}
string
TagAndEnumManagement::convertToString(const Audience &audience)
{
switch (audience) {
case Audience::SECURITY: return "Security";
case Audience::INTERNAL: return "Internal";
}
dbgAssert(false) << "Reached an impossible audience value of: " << static_cast<int>(audience);
return "";
}
string
TagAndEnumManagement::convertToString(const Priority &priority)
{
switch (priority) {
case Priority::URGENT: return "Urgent";
case Priority::HIGH: return "High";
case Priority::MEDIUM: return "Medium";
case Priority::LOW: return "Low";
}
dbgAssert(false) << "Reached impossible priority value of: " << static_cast<int>(priority);
return "";
}
string
TagAndEnumManagement::convertToString(const Notification &notification)
{
switch (notification) {
case Notification::POLICY_UPDATE: return "c0516360-a0b1-4246-af4c-2b6c586958e0";
case Notification::FIRST_REQUEST_FOR_ASSET: return "a53a7091-5d7a-4881-9e64-0fa3a1fc5a93";
case Notification::UPSTREAM_STATUS: return "46e5af4e-db29-444a-8f6b-2a6bd8f2e131";
case Notification::IOT_POLICY_UPDATE: return "92b57541-77ec-4dc4-8d46-dd9de71a602d";
case Notification::SYNC_LEARNING: return "b9b9ab04-2e2a-4cd1-b7e5-2c956861fb69";
case Notification::SDWAN_POLICY_UPDATE: return "2b18f5a0-5503-4c6b-967f-aa71dbced1aa";
case Notification::SDWAN_POLICY_UPDATE_ERROR: return "8d2db6ea-30b7-11ec-8d3d-0242ac130003";
case Notification::SDWAN_POLICY_UPDATE_LOG: return "f3a4fa06-2d91-41bc-84cd-7e9eaa9f4ce3";
case Notification::SDWAN_POLICY_UPDATE_ERROR_LOG: return "5529d385-44ed-46d6-b8d0-1b8a99b4fbea";
}
dbgAssert(false) << "Reached impossible notification value of: " << static_cast<int>(notification);
return "";
}
string
TagAndEnumManagement::convertToString(const IssuingEngine &issuing_engine)
{
switch (issuing_engine) {
case IssuingEngine::AGENT_CORE: return "Agent Core";
case IssuingEngine::IOT_NEXT: return "iotNext";
case IssuingEngine::SDWAN: return "sdwanGwSharing";
}
dbgAssert(false) << "Reached impossible engine value of: " << static_cast<int>(issuing_engine);
return "";
}
EnumArray<Tags, Tags> TagAndEnumManagement::tags_hierarchy {
Tags::THREAT_PREVENTION,
Tags::THREAT_PREVENTION,
Tags::THREAT_PREVENTION,
Tags::NEW_CONNECTION,
Tags::POLICY_INSTALLATION,
Tags::ACCESS_CONTROL,
Tags::ACCESS_CONTROL,
Tags::ACCESS_CONTROL,
Tags::FW,
Tags::WAF,
Tags::IPS,
Tags::URLF,
Tags::INFORMATIONAL,
Tags::ORCHESTRATOR,
Tags::COMPLIANCE,
Tags::REVERSE_PROXY
};
EnumArray<Tags, string> TagAndEnumManagement::tags_translation_arr {
"Threat Prevention",
"Remote Code Execution",
"Elevation Of Privileges",
"New Connection",
"Policy Installation",
"Access Control",
"Data Leak",
"New Approve Transaction",
"Firewall Information",
"Web Application & API Protection",
"IPS",
"URL Filtering",
"Informational",
"Orchestration",
"Compliance",
"IoT",
"SDWAN",
"CP_SDWAN",
"SDWAN_DATA_SHARING",
"SDWAN_POLICY_ERROR",
"CPView Monitoring",
"Reverse Proxy",
"Http Geo Filter",
"File Upload"
};
EnumArray<AudienceTeam, string> TagAndEnumManagement::audience_team_translation {
"Agent Core",
"iotNext",
"WAAP",
"Agent Intelligence",
"cpviewMonitoring",
"Signature Developers"
};