mirror of
https://github.com/openappsec/openappsec.git
synced 2025-09-30 11:44:29 +03:00
First release of open-appsec source code
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
include_directories(details_resolver_handlers)
|
||||
|
||||
add_library(details_resolver details_resolver.cc details_resolving_handler.cc)
|
@@ -0,0 +1,288 @@
|
||||
// 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 "details_resolver.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "details_resolving_handler.h"
|
||||
#include "i_orchestration_tools.h"
|
||||
#include "maybe_res.h"
|
||||
#include "version.h"
|
||||
#include "config.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_ORCHESTRATOR);
|
||||
|
||||
class DetailsResolver::Impl
|
||||
:
|
||||
Singleton::Provide<I_DetailsResolver>::From<DetailsResolver>
|
||||
{
|
||||
public:
|
||||
Maybe<string> getHostname() override;
|
||||
Maybe<string> getPlatform() override;
|
||||
Maybe<string> getArch() override;
|
||||
|
||||
map<string, string> getResolvedDetails() override;
|
||||
|
||||
string getAgentVersion() override;
|
||||
bool isKernelVersion3OrHigher() override;
|
||||
bool isGwNotVsx() override;
|
||||
bool isVersionEqualOrAboveR8110() override;
|
||||
bool isReverseProxy() override;
|
||||
Maybe<tuple<string, string, string>> parseNginxMetadata() override;
|
||||
#if defined(gaia) || defined(smb)
|
||||
bool compareCheckpointVersion(int cp_version, std::function<bool(int, int)> compare_operator) const override;
|
||||
#endif // gaia || smb
|
||||
|
||||
private:
|
||||
#if defined(gaia) || defined(smb)
|
||||
int getCheckpointVersion() const;
|
||||
#endif // gaia || smb
|
||||
|
||||
DetailsResolvingHanlder handler;
|
||||
};
|
||||
|
||||
map<string, string>
|
||||
DetailsResolver::Impl::getResolvedDetails()
|
||||
{
|
||||
return handler.getResolvedDetails();
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
DetailsResolver::Impl::getHostname()
|
||||
{
|
||||
#if defined(arm32_musl) || defined(openwrt)
|
||||
auto host_name = DetailsResolvingHanlder::getCommandOutput("uname -a | awk '{print $(2)}'");
|
||||
#else // not arm32_musl || openwrt
|
||||
auto host_name = DetailsResolvingHanlder::getCommandOutput("hostname");
|
||||
#endif // defined(arm32_musl) || defined(openwrt)
|
||||
if (!host_name.ok()) return genError("Failed to load host name, Error: " + host_name.getErr());
|
||||
return host_name;
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
DetailsResolver::Impl::getPlatform()
|
||||
{
|
||||
#if defined(gaia)
|
||||
return string("gaia");
|
||||
#elif defined(arm32_rpi)
|
||||
return string("glibc");
|
||||
#elif defined(arm32_musl)
|
||||
return string("musl");
|
||||
#elif defined(smb_mrv_v1)
|
||||
return string("smb_mrv_v1");
|
||||
#elif defined(smb_sve_v2)
|
||||
return string("smb_sve_v2");
|
||||
#elif defined(smb_thx_v3)
|
||||
return string("smb_thx_v3");
|
||||
#elif defined(openwrt)
|
||||
return string("uclibc");
|
||||
#elif defined(arm64_linaro)
|
||||
return string("arm64_linaro");
|
||||
#elif defined(alpine)
|
||||
return string("alpine");
|
||||
#elif defined(arm64_trustbox)
|
||||
return string("arm64_trustbox");
|
||||
#elif defined(linux)
|
||||
return string("linux");
|
||||
#else
|
||||
return genError("Failed to load platform details");
|
||||
#endif
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
DetailsResolver::Impl::getArch()
|
||||
{
|
||||
#if defined(arm32_rpi) || defined(arm32_musl) || defined(openwrt)
|
||||
auto architecture = DetailsResolvingHanlder::getCommandOutput("uname -a | awk '{print $(NF -1) }'");
|
||||
#else // not arm32_rpi || arm32_musl || openwrt
|
||||
auto architecture = DetailsResolvingHanlder::getCommandOutput("arch");
|
||||
#endif // defined(arm32_rpi) || defined(arm32_musl) || defined(openwrt)
|
||||
if (!architecture.ok()) return genError("Failed to load platform architecture, Error: " + architecture.getErr());
|
||||
return architecture;
|
||||
}
|
||||
|
||||
string
|
||||
DetailsResolver::Impl::getAgentVersion()
|
||||
{
|
||||
return Version::getFullVersion();
|
||||
}
|
||||
|
||||
bool
|
||||
DetailsResolver::Impl::isReverseProxy()
|
||||
{
|
||||
#if defined(gaia) || defined(smb)
|
||||
auto is_reverse_proxy = DetailsResolvingHanlder::getCommandOutput("cpprod_util CPPROD_IsConfigured CPwaap");
|
||||
if (is_reverse_proxy.ok()) {
|
||||
return is_reverse_proxy.unpack().front() == '1';
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
DetailsResolver::Impl::isKernelVersion3OrHigher()
|
||||
{
|
||||
static const string cmd =
|
||||
"clish -c 'show version os kernel' | awk '{print $4}' "
|
||||
"| cut -d '.' -f 1 | awk -F: '{ if ( $1 >= 3 ) {print 1} else {print 0}}'";
|
||||
|
||||
auto is_gogo = DetailsResolvingHanlder::getCommandOutput(cmd);
|
||||
if (is_gogo.ok()) {
|
||||
return is_gogo.unpack().front() == '1';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
DetailsResolver::Impl::isGwNotVsx()
|
||||
{
|
||||
static const string is_gw_cmd = "cpprod_util FwIsFirewallModule";
|
||||
static const string is_vsx_cmd = "cpprod_util FWisVSX";
|
||||
auto is_gw = DetailsResolvingHanlder::getCommandOutput(is_gw_cmd);
|
||||
auto is_vsx = DetailsResolvingHanlder::getCommandOutput(is_vsx_cmd);
|
||||
if (is_gw.ok() && is_vsx.ok()) {
|
||||
return is_gw.unpack().front() == '1' && is_vsx.unpack().front() == '0';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(gaia) || defined(smb)
|
||||
bool
|
||||
DetailsResolver::Impl::compareCheckpointVersion(int cp_version, std::function<bool(int, int)> compare_operator) const
|
||||
{
|
||||
int curr_version = getCheckpointVersion();
|
||||
return compare_operator(curr_version, cp_version);
|
||||
}
|
||||
|
||||
int
|
||||
DetailsResolver::Impl::getCheckpointVersion() const
|
||||
{
|
||||
#ifdef gaia
|
||||
static const string cmd =
|
||||
"echo $CPDIR | awk -F'-' '{print $NF}' | cut -c 2- |"
|
||||
" awk -F'.' '{ if( NF == 1 ) {print $1\"00\"} else {print $1$2} }'";
|
||||
#else // smb
|
||||
static const string cmd = "sqlcmd 'select major,minor from cpver' |"
|
||||
"awk '{if ($1 == \"major\") v += (substr($3,2) * 100);"
|
||||
" if ($1 == \"minor\") v += $3; } END { print v}'";
|
||||
|
||||
#endif // gaia
|
||||
auto version_out = DetailsResolvingHanlder::getCommandOutput(cmd);
|
||||
int cp_version = 0;
|
||||
if (version_out.ok()) {
|
||||
stringstream version_stream(version_out.unpack());
|
||||
version_stream >> cp_version;
|
||||
}
|
||||
return cp_version;
|
||||
}
|
||||
#endif // gaia || smb
|
||||
|
||||
bool
|
||||
DetailsResolver::Impl::isVersionEqualOrAboveR8110()
|
||||
{
|
||||
#if defined(gaia) || defined(smb)
|
||||
return compareCheckpointVersion(8110, std::greater_equal<int>());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
Maybe<tuple<string, string, string>>
|
||||
DetailsResolver::Impl::parseNginxMetadata()
|
||||
{
|
||||
auto output_path = getConfigurationWithDefault<string>(
|
||||
"/tmp/nginx_meta_data.txt",
|
||||
"orchestration",
|
||||
"Nginx metadata temp file"
|
||||
);
|
||||
const string srcipt_exe_cmd =
|
||||
getFilesystemPathConfig() +
|
||||
"/scripts/cp-nano-makefile-generator.sh -f -o " +
|
||||
output_path;
|
||||
|
||||
dbgTrace(D_ORCHESTRATOR) << "Details resolver, srcipt exe cmd: " << srcipt_exe_cmd;
|
||||
auto is_nginx_exist = DetailsResolvingHanlder::getCommandOutput("which nginx");
|
||||
if (!is_nginx_exist.ok() || is_nginx_exist.unpack().size() == 0) {
|
||||
return genError("Nginx isn't installed");
|
||||
}
|
||||
|
||||
auto script_output = DetailsResolvingHanlder::getCommandOutput(srcipt_exe_cmd);
|
||||
if (!script_output.ok()) {
|
||||
return genError("Failed to generate nginx metadata, Error: " + script_output.getErr());
|
||||
}
|
||||
|
||||
I_OrchestrationTools *orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<DetailsResolver>();
|
||||
if (!orchestration_tools->doesFileExist(output_path)) {
|
||||
return genError("Failed to access nginx metadata file.");
|
||||
}
|
||||
|
||||
vector<string> lines;
|
||||
try {
|
||||
ifstream input_stream(output_path);
|
||||
if (!input_stream) {
|
||||
return genError("Cannot open the file with nginx metadata, File: " + output_path);
|
||||
}
|
||||
|
||||
string line;
|
||||
while (getline(input_stream, line)) {
|
||||
lines.push_back(line);
|
||||
}
|
||||
input_stream.close();
|
||||
|
||||
orchestration_tools->removeFile(output_path);
|
||||
} catch (const ifstream::failure &exception) {
|
||||
dbgWarning(D_ORCHESTRATOR)
|
||||
<< "Cannot read the file with required nginx metadata."
|
||||
<< " File: " << output_path
|
||||
<< " Error: " << exception.what();
|
||||
}
|
||||
|
||||
if (lines.size() == 0) return genError("Failed to read nginx metadata file");
|
||||
string nginx_version;
|
||||
string config_opt;
|
||||
string cc_opt;
|
||||
|
||||
for(string &line : lines) {
|
||||
if (line.size() == 0) continue;
|
||||
if (line.find("RELEASE_VERSION") != string::npos) continue;
|
||||
if (line.find("--with-cc=") != string::npos) continue;
|
||||
if (line.find("NGINX_VERSION") != string::npos) {
|
||||
auto eq_index = line.find("=");
|
||||
nginx_version = "nginx-" + line.substr(eq_index + 1);
|
||||
continue;
|
||||
}
|
||||
if (line.find("EXTRA_CC_OPT") != string::npos) {
|
||||
auto eq_index = line.find("=");
|
||||
cc_opt = line.substr(eq_index + 1);
|
||||
continue;
|
||||
}
|
||||
if (line.find("CONFIGURE_OPT") != string::npos) continue;
|
||||
if (line.back() == '\\') line.pop_back();
|
||||
config_opt += line;
|
||||
}
|
||||
return make_tuple(config_opt, cc_opt, nginx_version);
|
||||
}
|
||||
|
||||
DetailsResolver::DetailsResolver() : Component("DetailsResolver"), pimpl(make_unique<Impl>()) {}
|
||||
|
||||
DetailsResolver::~DetailsResolver() {}
|
||||
|
||||
void
|
||||
DetailsResolver::preload()
|
||||
{
|
||||
registerExpectedConfiguration<uint32_t>("orchestration", "Details resolver time out");
|
||||
}
|
@@ -0,0 +1,183 @@
|
||||
// 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 __CHECKPOINT_PRODUCT_HANDLERS_H__
|
||||
#define __CHECKPOINT_PRODUCT_HANDLERS_H__
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#if defined(gaia) || defined(smb)
|
||||
Maybe<string>
|
||||
checkHasSDWan(const string &command_output)
|
||||
{
|
||||
if (command_output.front() == '1') return string("true");
|
||||
|
||||
return genError("Current host does not have SDWAN capability");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getMgmtObjType(const string &command_output)
|
||||
{
|
||||
if (!command_output.empty()) {
|
||||
if (command_output[0] == '1') return string("management");
|
||||
if (command_output[0] == '0') return string("gateway");
|
||||
}
|
||||
|
||||
return genError("Object type was not found");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
chopHeadAndTail(const string &str, const string &prefix, const string &suffix)
|
||||
{
|
||||
if (str.size() < prefix.size() + suffix.size()) return genError("String too short");
|
||||
if (str.compare(0, prefix.size(), prefix)) return genError("Prefix mismatch");
|
||||
if (str.compare(str.size() - suffix.size(), suffix.size(), suffix)) return genError("Suffix mismatch");
|
||||
|
||||
return str.substr(prefix.size(), str.size() - prefix.size() - suffix.size());
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getMgmtObjAttr(shared_ptr<istream> file_stream, const string &attr)
|
||||
{
|
||||
string line;
|
||||
while (getline(*file_stream, line)) {
|
||||
size_t attr_pos = line.find(attr);
|
||||
if (attr_pos == string::npos) continue;
|
||||
line = line.substr(attr_pos + attr.size());
|
||||
return chopHeadAndTail(line, "(", ")");
|
||||
}
|
||||
return genError("Object attribute was not found. Attr: " + attr);
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getMgmtObjUid(shared_ptr<istream> file_stream)
|
||||
{
|
||||
return getMgmtObjAttr(file_stream, "uuid ");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getMgmtObjName(shared_ptr<istream> file_stream)
|
||||
{
|
||||
return getMgmtObjAttr(file_stream, "name ");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getMgmtParentObjAttr(shared_ptr<istream> file_stream, const string &parent_obj, const string &attr)
|
||||
{
|
||||
string line;
|
||||
bool found_parent_obj = false;
|
||||
while (getline(*file_stream, line)) {
|
||||
size_t parent_obj_pos = line.find(parent_obj);
|
||||
if (parent_obj_pos != string::npos) found_parent_obj = true;
|
||||
if (!found_parent_obj) continue;
|
||||
|
||||
size_t attr_pos = line.find(attr);
|
||||
if (attr_pos == string::npos) continue;
|
||||
line = line.substr(attr_pos + attr.size());
|
||||
return line;
|
||||
}
|
||||
return genError("Parent object attribute was not found. Attr: " + attr);
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getMgmtParentObjUid(shared_ptr<istream> file_stream)
|
||||
{
|
||||
auto maybe_unparsed_uid = getMgmtParentObjAttr(file_stream, "cluster_object", "Uid ");
|
||||
if (!maybe_unparsed_uid.ok()) {
|
||||
return maybe_unparsed_uid;
|
||||
}
|
||||
const string &unparsed_uid = maybe_unparsed_uid.unpack();
|
||||
auto maybe_uid = chopHeadAndTail(unparsed_uid, "(\"{", "}\")");
|
||||
if (!maybe_uid.ok()) {
|
||||
return maybe_uid;
|
||||
}
|
||||
string uid = maybe_uid.unpack();
|
||||
transform(uid.begin(), uid.end(), uid.begin(), ::tolower);
|
||||
return uid;
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getMgmtParentObjName(shared_ptr<istream> file_stream)
|
||||
{
|
||||
auto maybe_unparsed_name = getMgmtParentObjAttr(file_stream, "cluster_object", "Name ");
|
||||
if (!maybe_unparsed_name.ok()) {
|
||||
return maybe_unparsed_name;
|
||||
}
|
||||
const string &unparsed_name = maybe_unparsed_name.unpack();
|
||||
return chopHeadAndTail(unparsed_name, "(", ")");
|
||||
}
|
||||
#endif // gaia || smb
|
||||
|
||||
Maybe<string>
|
||||
getOsRelease(shared_ptr<istream> file_stream)
|
||||
{
|
||||
string line;
|
||||
while (getline(*file_stream, line)) {
|
||||
if (line.find("Check Point") != string::npos) return line;
|
||||
|
||||
static const string prety_name_attr = "PRETTY_NAME=";
|
||||
size_t pretty_name_idx = line.find(prety_name_attr);
|
||||
if (pretty_name_idx == string::npos) continue;
|
||||
line = line.substr(pretty_name_idx + prety_name_attr.size());
|
||||
if (line.front() == '"') line.erase(0, 1);
|
||||
if (line.back() == '"') line.pop_back();
|
||||
return line;
|
||||
}
|
||||
|
||||
return genError("Os release was not found");
|
||||
}
|
||||
|
||||
#if defined(alpine)
|
||||
string &
|
||||
ltrim(string &s)
|
||||
{
|
||||
auto it = find_if(
|
||||
s.begin(),
|
||||
s.end(),
|
||||
[](char c) { return !isspace<char>(c, locale::classic()); }
|
||||
);
|
||||
s.erase(s.begin(), it);
|
||||
return s;
|
||||
}
|
||||
|
||||
string &
|
||||
rtrim(string &s)
|
||||
{
|
||||
auto it = find_if(
|
||||
s.rbegin(),
|
||||
s.rend(),
|
||||
[](char c) { return !isspace<char>(c, locale::classic()); }
|
||||
);
|
||||
s.erase(it.base(), s.end());
|
||||
return s;
|
||||
}
|
||||
|
||||
string &
|
||||
trim(string &s)
|
||||
{
|
||||
return ltrim(rtrim(s));
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getCPAlpineTag(shared_ptr<istream> file_stream)
|
||||
{
|
||||
string line;
|
||||
while (getline(*file_stream, line)) {
|
||||
if (trim(line) != "") return line;
|
||||
}
|
||||
return genError("Alpine tag was not found");
|
||||
}
|
||||
#endif // alpine
|
||||
|
||||
#endif // __CHECKPOINT_PRODUCT_HANDLERS_H__
|
@@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __DETAILS_RESOLVER_HANDLER_CC__
|
||||
#error details_resolver_handlers/details_resolver_impl.h should not be included directly.
|
||||
#endif // __DETAILS_RESOLVER_HANDLER_CC__
|
||||
|
||||
// use SHELL_CMD_HANDLER(key as string, shell command as string, ptr to Maybe<string> handler(const string&))
|
||||
// to return a string value for an attribute key based on a logic executed in a handler that receives
|
||||
// shell command execution output as its input
|
||||
#ifdef SHELL_CMD_HANDLER
|
||||
|
||||
#if defined(gaia) || defined(smb)
|
||||
SHELL_CMD_HANDLER("cpProductIntegrationMgmtObjectType", "cpprod_util CPPROD_IsMgmtMachine", getMgmtObjType)
|
||||
SHELL_CMD_HANDLER("hasSDWan", "[ -f $FWDIR/bin/sdwan_steering ] && echo '1' || echo '0'", checkHasSDWan)
|
||||
#endif //gaia
|
||||
|
||||
#endif // SHELL_CMD_HANDLER
|
||||
|
||||
|
||||
// use SHELL_CMD_OUTPUT(key as string, shell command as string) to return a shell command output as the value
|
||||
// for a given key
|
||||
#ifdef SHELL_CMD_OUTPUT
|
||||
SHELL_CMD_OUTPUT("kernel_version", "uname -r")
|
||||
SHELL_CMD_OUTPUT("helloWorld", "cat /tmp/agentHelloWorld 2>/dev/null")
|
||||
#endif // SHELL_CMD_OUTPUT
|
||||
|
||||
|
||||
// use FILE_CONTENT_HANDLER(key as string, path to file as string, ptr to Maybe<string> handler(ifstream&))
|
||||
// to return a string value for an attribute key based on a logic executed in a handler that receives file as input
|
||||
#ifdef FILE_CONTENT_HANDLER
|
||||
|
||||
#if defined(alpine)
|
||||
FILE_CONTENT_HANDLER("alpine_tag", "/usr/share/build/cp-alpine-tag", getCPAlpineTag)
|
||||
#endif // alpine
|
||||
#if defined(gaia) || defined(smb)
|
||||
FILE_CONTENT_HANDLER("os_release", "/etc/cp-release", getOsRelease)
|
||||
FILE_CONTENT_HANDLER(
|
||||
"cpProductIntegrationMgmtObjectUid",
|
||||
(getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myown.C",
|
||||
getMgmtObjUid
|
||||
)
|
||||
FILE_CONTENT_HANDLER(
|
||||
"cpProductIntegrationMgmtObjectName",
|
||||
(getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myown.C",
|
||||
getMgmtObjName
|
||||
)
|
||||
FILE_CONTENT_HANDLER(
|
||||
"cpProductIntegrationMgmtParentObjectUid",
|
||||
(getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myself_objects.C",
|
||||
getMgmtParentObjUid
|
||||
)
|
||||
FILE_CONTENT_HANDLER(
|
||||
"cpProductIntegrationMgmtParentObjectName",
|
||||
(getenv("FWDIR") ? string(getenv("FWDIR")) : "") + "/database/myself_objects.C",
|
||||
getMgmtParentObjName
|
||||
)
|
||||
#else // !(gaia || smb)
|
||||
FILE_CONTENT_HANDLER("os_release", "/etc/os-release", getOsRelease)
|
||||
#endif // gaia || smb
|
||||
|
||||
#endif // FILE_CONTENT_HANDLER
|
@@ -0,0 +1,128 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "details_resolving_handler.h"
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "maybe_res.h"
|
||||
#include "enum_array.h"
|
||||
#include "i_shell_cmd.h"
|
||||
#include "config.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_AGENT_DETAILS);
|
||||
|
||||
using ShellCommandHandler = function<Maybe<string>(const string &raw_otput)>;
|
||||
using FileContentHandler = function<Maybe<string>(shared_ptr<istream> file_otput)>;
|
||||
|
||||
#define __DETAILS_RESOLVER_HANDLER_CC__
|
||||
|
||||
#include "checkpoint_product_handlers.h"
|
||||
|
||||
class DetailsResolvingHanlder::Impl
|
||||
{
|
||||
public:
|
||||
map<string, string> getResolvedDetails() const;
|
||||
static Maybe<string> getCommandOutput(const string &cmd);
|
||||
|
||||
private:
|
||||
#define SHELL_CMD_OUTPUT(ATTRIBUTE, COMMAND) SHELL_CMD_HANDLER(ATTRIBUTE, COMMAND, [](const string &s) { return s; })
|
||||
#define SHELL_CMD_HANDLER(ATTRIBUTE, COMMAND, HANDLER) {ATTRIBUTE, {COMMAND, ShellCommandHandler(HANDLER)}},
|
||||
map<string, pair<string, ShellCommandHandler>> shell_command_handlers = {
|
||||
#include "details_resolver_impl.h"
|
||||
};
|
||||
#undef SHELL_CMD_OUTPUT
|
||||
#undef SHELL_CMD_HANDLER
|
||||
|
||||
#define FILE_CONTENT_HANDLER(ATTRIBUTE, FILE, HANDLER) {ATTRIBUTE, {FILE, FileContentHandler(HANDLER)}},
|
||||
map<string, pair<string, FileContentHandler>> file_content_handlers = {
|
||||
#include "details_resolver_impl.h"
|
||||
};
|
||||
#undef FILE_CONTENT_HANDLER
|
||||
};
|
||||
|
||||
map<string, string>
|
||||
DetailsResolvingHanlder::Impl::getResolvedDetails() const
|
||||
{
|
||||
map<string, string> resolved_details;
|
||||
for (auto shell_handler : shell_command_handlers) {
|
||||
const string &attr = shell_handler.first;
|
||||
const string &command = shell_handler.second.first;
|
||||
ShellCommandHandler handler = shell_handler.second.second;
|
||||
|
||||
Maybe<string> shell_command_output = getCommandOutput(command);
|
||||
if (!shell_command_output.ok()) continue;
|
||||
Maybe<string> handler_ret = handler(*shell_command_output);
|
||||
if (handler_ret.ok()) resolved_details[attr] = *handler_ret;
|
||||
}
|
||||
|
||||
for (auto file_handler : file_content_handlers) {
|
||||
const string &attr = file_handler.first;
|
||||
const string &path = file_handler.second.first;
|
||||
FileContentHandler handler = file_handler.second.second;
|
||||
|
||||
shared_ptr<ifstream> in_file = make_shared<ifstream>(path);
|
||||
if (!in_file->is_open()) {
|
||||
dbgWarning(D_AGENT_DETAILS) << "Could not open file for processing. Path: " << path;
|
||||
continue;
|
||||
}
|
||||
|
||||
dbgDebug(D_AGENT_DETAILS) << "Successfully opened file for processing. Path: " << path;
|
||||
if (in_file->peek() != ifstream::traits_type::eof()) {
|
||||
Maybe<string> handler_ret = handler(in_file);
|
||||
if (handler_ret.ok()) resolved_details[attr] = *handler_ret;
|
||||
}
|
||||
in_file->close();
|
||||
}
|
||||
|
||||
I_AgentDetailsReporter *reporter = Singleton::Consume<I_AgentDetailsReporter>::by<DetailsResolvingHanlder>();
|
||||
reporter->addAttr(resolved_details);
|
||||
|
||||
return resolved_details;
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
DetailsResolvingHanlder::Impl::getCommandOutput(const string &cmd)
|
||||
{
|
||||
I_ShellCmd *shell = Singleton::Consume<I_ShellCmd>::by<DetailsResolvingHanlder>();
|
||||
uint32_t timeout = getConfigurationWithDefault<uint32_t>(5000, "orchestration", "Details resolver time out");
|
||||
auto result = shell->getExecOutput(cmd, timeout);
|
||||
if (!result.ok()) return result;
|
||||
|
||||
auto unpacked_result = result.unpack();
|
||||
if (unpacked_result.back() == '\n') unpacked_result.pop_back();
|
||||
|
||||
return unpacked_result;
|
||||
}
|
||||
|
||||
DetailsResolvingHanlder::DetailsResolvingHanlder() : pimpl(make_unique<Impl>()) {}
|
||||
DetailsResolvingHanlder::~DetailsResolvingHanlder() {}
|
||||
|
||||
|
||||
map<string, string>
|
||||
DetailsResolvingHanlder::getResolvedDetails() const
|
||||
{
|
||||
return pimpl->getResolvedDetails();
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
DetailsResolvingHanlder::getCommandOutput(const string &cmd)
|
||||
{
|
||||
return DetailsResolvingHanlder::Impl::getCommandOutput(cmd);
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __DETAILS_RESOLVING_HANDLER_H__
|
||||
#define __DETAILS_RESOLVING_HANDLER_H__
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "i_shell_cmd.h"
|
||||
#include "i_agent_details_reporter.h"
|
||||
|
||||
class DetailsResolvingHanlder
|
||||
:
|
||||
Singleton::Consume<I_ShellCmd>,
|
||||
Singleton::Consume<I_AgentDetailsReporter>
|
||||
{
|
||||
public:
|
||||
DetailsResolvingHanlder();
|
||||
~DetailsResolvingHanlder();
|
||||
|
||||
std::map<std::string, std::string> getResolvedDetails() const;
|
||||
|
||||
static Maybe<std::string> getCommandOutput(const std::string &cmd);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> pimpl;
|
||||
};
|
||||
|
||||
#endif // __DETAILS_RESOLVING_HANDLER_H__
|
Reference in New Issue
Block a user