Jul 31st update

This commit is contained in:
Ned Wright
2024-07-31 17:15:35 +00:00
parent 705a5e6061
commit 384b59cc87
39 changed files with 1026 additions and 74 deletions

View File

@@ -0,0 +1,87 @@
#ifndef __EXTERNAL_AGENT_SDK_H__
#define __EXTERNAL_AGENT_SDK_H__
#ifdef __cplusplus
enum class SdkApiType
#else
enum SdkApiType
#endif
{
SendCodeEvent,
SendPeriodicEvent,
SendEventDrivenEvent,
SendGetConfigRequest,
#ifndef __cplusplus
};
#else //__cplusplus
COUNT
};
extern "C"
{
#endif // __cplusplus
enum DebugLevel { DebugTrace, DebugDebug, DebugInfo, DebugWarning, DebugError };
enum EventAudience { AudienceSecurity, AudienceInternal };
enum EventAudienceTeam { AudienceTeamAgentCore, AudienceTeamIot, AudienceTeamWaap, AudienceTeamAgentIntelligence };
enum EventSeverity { SeverityCritical, SeverityHigh, SeverityMedium, SeverityLow, SeverityInfo };
enum EventPriority { PriorityUrgent, PriorityHigh, PriorityMedium, PriorityLow };
enum SdkReturn {
SdkSuccess = 0,
SdkUninitialized = -1,
IlegalNumOfAdditionData = -2,
EmptyConfigRespond = -3,
InitCurlFailed = -4,
ExecuteCurlFailed = -5,
Non200Respond = -6,
AllocationFailure = -7
};
void initAgentSdk();
void finiAgentSdk();
// Get configuration using path. Output is allocated internally and requires caller to free
enum SdkReturn getAgentConfiguration(const char *configuration_path, char **config_value_output);
enum SdkReturn
sendPeriodicData(
const char *event_title,
const char *service_name,
enum EventAudienceTeam team,
const char **periodic_data,
int periodic_data_size
);
enum SdkReturn
sendEventDrivenLog(
const char *event_name,
enum EventAudience audience,
enum EventSeverity severity,
enum EventPriority priority,
const char *tag,
enum EventAudienceTeam team,
const char **event_data,
int event_data_size
);
enum SdkReturn
sendDebugMessage(
const char *file_name,
const char *function_name,
unsigned int line_number,
enum DebugLevel debug_level,
const char *trace_id,
const char *span_id,
const char *message,
enum EventAudienceTeam team,
const char **event_data,
int event_data_size
);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __EXTERNAL_AGENT_SDK_H__

View File

@@ -5,6 +5,7 @@
#include <string>
#include "flags.h"
#include "config.h"
#include "singleton.h"
#include "i_agent_details.h"
@@ -118,6 +119,29 @@ public:
return headers;
}
std::string
getCaPath() const
{
if (!ca_path.empty()) return ca_path;
return getConfigurationWithDefault(
getFilesystemPathConfig() + "/certs/fog.pem",
"message",
"Certificate chain file path"
);
}
const std::string &
getClientCertPath() const
{
return client_cert_path;
}
const std::string &
getClientKeyPath() const
{
return client_key_path;
}
void
insertHeader(const std::string &header_key, const std::string &header_val)
{
@@ -137,6 +161,24 @@ public:
is_proxy_set = true;
}
void
setCAPath (const std::string &_ca_path)
{
ca_path = _ca_path;
}
void
setDualAuthenticationSettings
(
const std::string &_client_cert_path,
const std::string &_client_key_path
)
{
client_cert_path = _client_cert_path;
client_key_path = _client_key_path;
is_dual_auth = true;
}
void
setExternalCertificate(const std::string &_external_certificate)
{
@@ -161,6 +203,12 @@ public:
return is_proxy_set;
}
bool
isDualAuth() const
{
return is_dual_auth;
}
bool
isToFog() const
{
@@ -175,18 +223,26 @@ public:
cereal::make_nvp("host_name", host_name),
cereal::make_nvp("port_num", port_num),
cereal::make_nvp("is_proxy_set", is_proxy_set),
cereal::make_nvp("is_dual_auth", is_dual_auth),
cereal::make_nvp("headers", headers),
cereal::make_nvp("conn_flags", conn_flags),
cereal::make_nvp("external_certificate", external_certificate),
cereal::make_nvp("should_buffer", should_buffer),
cereal::make_nvp("is_to_fog", is_to_fog)
cereal::make_nvp("is_to_fog", is_to_fog),
cereal::make_nvp("ca_path", ca_path),
cereal::make_nvp("client_cert_path", client_cert_path),
cereal::make_nvp("client_key_path", client_key_path)
);
}
private:
std::string host_name = "";
std::string ca_path = "";
std::string client_cert_path = "";
std::string client_key_path = "";
uint16_t port_num = 0;
bool is_proxy_set = false;
bool is_dual_auth = false;
std::map<std::string, std::string> headers;
Flags<MessageConnectionConfig> conn_flags;
MessageProxySettings proxy_settings;

View File

@@ -23,7 +23,7 @@ enum class StreamType {
JSON_DEBUG,
JSON_FOG,
JSON_LOG_FILE,
JSON_K8S_SVC,
JSON_CONTAINER_SVC,
SYSLOG,
CEF,

View File

@@ -383,6 +383,11 @@ private:
}
if (getProfileAgentSettingWithDefault<bool>(false, "agent.config.supportInvalidation")) return true;
if (getSetting<string>("intelligence", "local intelligence server ip").ok()) {
return getProfileAgentSettingWithDefault<bool>(true, "agent.config.useLocalIntelligence");
}
dbgTrace(D_INTELLIGENCE) << "Local intelligence not supported";
return false;

View File

@@ -22,21 +22,21 @@ const static string default_log_uri = "/api/v1/agents/events";
USE_DEBUG_FLAG(D_REPORT);
K8sSvcStream::K8sSvcStream()
ContainerSvcStream::ContainerSvcStream()
:
i_msg(Singleton::Consume<I_Messaging>::by<LoggingComp>())
{
}
K8sSvcStream::~K8sSvcStream()
ContainerSvcStream::~ContainerSvcStream()
{
}
void
K8sSvcStream::sendLog(const Report &log)
ContainerSvcStream::sendLog(const Report &log)
{
auto svc_host = getConfigurationWithDefault(default_host, "Logging", "K8sSvc Log host");
auto K8sSvc_log_uri = getConfigurationWithDefault(default_log_uri, "Logging", "K8sSvc Log URI");
auto svc_host = getConfigurationWithDefault(default_host, "Logging", "Container Log host");
auto svc_log_uri = getConfigurationWithDefault(default_log_uri, "Logging", "Container Log URI");
LogRest rest(log);
MessageMetadata rest_req_md(svc_host, 80);
@@ -45,7 +45,7 @@ K8sSvcStream::sendLog(const Report &log)
bool ok = i_msg->sendSyncMessageWithoutResponse(
HTTPMethod::POST,
K8sSvc_log_uri,
svc_log_uri,
rest,
MessageCategory::LOG,
rest_req_md
@@ -57,7 +57,7 @@ K8sSvcStream::sendLog(const Report &log)
}
void
K8sSvcStream::sendLog(const LogBulkRest &logs, bool persistence_only)
ContainerSvcStream::sendLog(const LogBulkRest &logs, bool persistence_only)
{
dbgFlow(D_REPORT) << "send bulk logs";
@@ -66,15 +66,15 @@ K8sSvcStream::sendLog(const LogBulkRest &logs, bool persistence_only)
return;
}
auto svc_host = getConfigurationWithDefault(default_host, "Logging", "K8sSvc Log host");
auto K8sSvc_log_uri = getConfigurationWithDefault(default_bulk_uri, "Logging", "K8sSvc Bulk Log URI");
auto svc_host = getConfigurationWithDefault(default_host, "Logging", "Container Log host");
auto svc_log_uri = getConfigurationWithDefault(default_bulk_uri, "Logging", "Container Bulk Log URI");
MessageMetadata rest_req_md(svc_host, 80);
rest_req_md.insertHeader("X-Tenant-Id", Singleton::Consume<I_AgentDetails>::by<LoggingComp>()->getTenantId());
rest_req_md.setConnectioFlag(MessageConnectionConfig::UNSECURE_CONN);
bool ok = i_msg->sendSyncMessageWithoutResponse(
HTTPMethod::POST,
K8sSvc_log_uri,
svc_log_uri,
logs,
MessageCategory::LOG,
rest_req_md

View File

@@ -80,11 +80,11 @@ private:
I_Messaging *i_msg = nullptr;
};
class K8sSvcStream : public Stream
class ContainerSvcStream : public Stream
{
public:
K8sSvcStream();
~K8sSvcStream();
ContainerSvcStream();
~ContainerSvcStream();
void sendLog(const Report &log) override;
void sendLog(const LogBulkRest &logs, bool persistance_only) override;

View File

@@ -270,7 +270,7 @@ private:
case StreamType::JSON_DEBUG: return make_shared<DebugStream>();
case StreamType::JSON_FOG: return make_shared<FogStream>();
case StreamType::JSON_LOG_FILE: return make_shared<LogFileStream>();
case StreamType::JSON_K8S_SVC: return make_shared<K8sSvcStream>();
case StreamType::JSON_CONTAINER_SVC: return make_shared<ContainerSvcStream>();
case StreamType::SYSLOG: return nullptr;
case StreamType::CEF: return nullptr;
case StreamType::NONE: return nullptr;
@@ -319,7 +319,9 @@ LoggingComp::preload()
registerExpectedConfiguration<string>("Logging", "Log file name");
registerExpectedConfiguration<string>("Logging", "Log file line separator");
registerExpectedConfiguration<string>("Logging", "Fog Log URI");
registerExpectedConfiguration<string>("Logging", "K8sSvc Log host");
registerExpectedConfiguration<string>("Logging", "Container Log host");
registerExpectedConfiguration<string>("Logging", "Container Log URI");
registerExpectedConfiguration<string>("Logging", "Container Bulk Log URI");
registerExpectedConfiguration<string>("Logging", "Syslog IP");
registerExpectedConfiguration<uint>("Logging", "Syslog port");
registerExpectedConfiguration<string>("Logging", "CEF IP");

View File

@@ -68,7 +68,7 @@ public:
return;
}
if (should_load_k8s_stream) {
Singleton::Consume<I_Logging>::by<fakeConfig>()->addStream(ReportIS::StreamType::JSON_K8S_SVC);
Singleton::Consume<I_Logging>::by<fakeConfig>()->addStream(ReportIS::StreamType::JSON_CONTAINER_SVC);
return;
}
Singleton::Consume<I_Logging>::by<fakeConfig>()->addStream(ReportIS::StreamType::JSON_DEBUG);

View File

@@ -90,6 +90,12 @@ public:
if (metadata_flags.isSet(MessageConnectionConfig::IGNORE_SSL_VALIDATION)) {
flags.setFlag(ConnectionFlags::IGNORE_SSL_VALIDATION);
}
ca_path = metadata.getCaPath();
if (metadata.isDualAuth()) {
client_cert_path = metadata.getClientCertPath();
client_key_path = metadata.getClientKeyPath();
is_dual_auth = true;
}
}
void
@@ -263,20 +269,33 @@ private:
SSL_CTX_set_verify(ssl_ctx.get(), SSL_VERIFY_PEER, nullptr);
auto defualt_cert_path = getFilesystemPathConfig() + "/certs/fog.pem";
auto cert_path = getConfigurationWithDefault(defualt_cert_path, "message", "Certificate chain file path");
const char *cert = cert_path.c_str();
if (is_dual_auth) {
dbgTrace(D_CONNECTION)
<< "Setting dual authentication."
<< "Client cert path: " << client_cert_path
<< ", client key path: " << client_key_path;
if (SSL_CTX_use_certificate_file(ssl_ctx.get(), client_cert_path.c_str(), SSL_FILETYPE_PEM) <= 0) {
string error = ERR_error_string(ERR_get_error(), nullptr);
return genError("Error in setting client cert: " + error);
}
if (SSL_CTX_use_PrivateKey_file(ssl_ctx.get(), client_key_path.c_str(), SSL_FILETYPE_PEM) <= 0) {
string error = ERR_error_string(ERR_get_error(), nullptr);
return genError("Error in setting client key: " + error);
}
}
dbgTrace(D_CONNECTION) << "Setting CA authentication";
auto details_ssl_dir = Singleton::Consume<I_AgentDetails>::by<Messaging>()->getOpenSSLDir();
auto openssl_dir = details_ssl_dir.ok() ? *details_ssl_dir : "/usr/lib/ssl/certs/";
auto configured_ssl_dir = getConfigurationWithDefault(openssl_dir, "message", "Trusted CA directory");
const char *ca_dir = configured_ssl_dir.empty() ? nullptr : configured_ssl_dir.c_str();
if (SSL_CTX_load_verify_locations(ssl_ctx.get(), cert, ca_dir) != 1) {
if (SSL_CTX_load_verify_locations(ssl_ctx.get(), ca_path.c_str(), ca_dir) != 1) {
return genError("Failed to load certificate locations");
}
dbgDebug(D_CONNECTION) << "SSL context set successfully. Certificate: " << cert << ", CA dir: " << ca_dir;
dbgDebug(D_CONNECTION) << "SSL context set successfully. Certificate: " << ca_path << ", CA dir: " << ca_dir;
return Maybe<void>();
}
@@ -457,7 +476,6 @@ private:
return BioConnectionStatus::SHOULD_NOT_RETRY;
}
Maybe<void>
connectToHost()
{
@@ -654,6 +672,10 @@ private:
Flags<ConnectionFlags> flags;
MessageProxySettings settings;
string ca_path = "";
string client_cert_path = "";
string client_key_path = "";
string connect_message;
string certificate;
@@ -666,6 +688,7 @@ private:
bool lock = false;
bool should_close_connection = false;
bool is_dual_auth = false;
};
Connection::Connection(const MessageConnectionKey &key, const MessageMetadata &metadata)

View File

@@ -89,6 +89,8 @@ TEST_F(TestConnectionComp, testSetAndGetConnection)
Flags<MessageConnectionConfig> conn_flags;
conn_flags.setFlag(MessageConnectionConfig::UNSECURE_CONN);
MessageMetadata conn_metadata("127.0.0.1", 8080, conn_flags);
conn_metadata.setCAPath("ca.pem");
conn_metadata.setDualAuthenticationSettings("ca_client.pem", "private_client.key");
auto maybe_connection = i_conn->establishConnection(conn_metadata, MessageCategory::LOG);
ASSERT_TRUE(maybe_connection.ok());

View File

@@ -253,9 +253,13 @@ operator==(const MessageMetadata &one, const MessageMetadata &two)
one.getConnectionFlags() == two.getConnectionFlags() &&
one.getProxySettings() == two.getProxySettings() &&
one.getExternalCertificate() == two.getExternalCertificate() &&
one.getCaPath() == two.getCaPath() &&
one.getClientCertPath() == two.getClientCertPath() &&
one.getClientKeyPath() == two.getClientKeyPath() &&
one.getHeaders() == two.getHeaders() &&
one.shouldBufferMessage() == two.shouldBufferMessage() &&
one.isProxySet() == two.isProxySet();
one.isProxySet() == two.isProxySet() &&
one.isDualAuth() == two.isDualAuth();
}
TEST_F(TestMessagingComp, testSetFogConnection)

View File

@@ -150,7 +150,7 @@ TagAndEnumManagement::convertToString(const StreamType &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::JSON_K8S_SVC: return "JSON K8S service stream";
case StreamType::JSON_CONTAINER_SVC: return "JSON K8S service stream";
case StreamType::SYSLOG: return "Syslog stream";
case StreamType::CEF: return "CEF stream";