Skip to content

Commit

Permalink
Merge 8f59867 into 160195a
Browse files Browse the repository at this point in the history
  • Loading branch information
kallsyms committed Mar 13, 2024
2 parents 160195a + 8f59867 commit 10a5df2
Show file tree
Hide file tree
Showing 27 changed files with 343 additions and 48 deletions.
1 change: 1 addition & 0 deletions Source/common/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ proto_library(
name = "santa_proto",
srcs = ["santa.proto"],
deps = [
"//Source/santad/ProcessTree:process_tree_proto",
"@com_google_protobuf//:any_proto",
"@com_google_protobuf//:timestamp_proto",
],
Expand Down
6 changes: 6 additions & 0 deletions Source/common/SNTConfigurator.h
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,12 @@
///
@property(readonly, nonatomic) NSArray<NSString *> *entitlementsTeamIDFilter;

///
/// List of enabled process annotations.
/// This property is not KVO compliant.
///
@property(readonly, nonatomic) NSArray<NSString *> *enabledProcessAnnotations;

///
/// Retrieve an initialized singleton configurator object using the default file path.
///
Expand Down
13 changes: 13 additions & 0 deletions Source/common/SNTConfigurator.m
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ @implementation SNTConfigurator
static NSString *const kMetricExportTimeout = @"MetricExportTimeout";
static NSString *const kMetricExtraLabels = @"MetricExtraLabels";

static NSString *const kEnabledProcessAnnotations = @"EnabledProcessAnnotations";

// The keys managed by a sync server or mobileconfig.
static NSString *const kClientModeKey = @"ClientMode";
static NSString *const kBlockUSBMountKey = @"BlockUSBMount";
Expand Down Expand Up @@ -275,6 +277,7 @@ - (instancetype)initWithSyncStateFile:(NSString *)syncStateFilePath
kOverrideFileAccessActionKey : string,
kEntitlementsPrefixFilterKey : array,
kEntitlementsTeamIDFilterKey : array,
kEnabledProcessAnnotations : array,
};

_syncStateFilePath = syncStateFilePath;
Expand Down Expand Up @@ -1105,6 +1108,16 @@ - (NSDictionary *)extraMetricLabels {
return self.configState[kMetricExtraLabels];
}

- (NSArray<NSString *> *)enabledProcessAnnotations {
NSArray<NSString *> *annotations = self.configState[kEnabledProcessAnnotations];
for (id annotation in annotations) {
if (![annotation isKindOfClass:[NSString class]]) {
return nil;
}
}
return annotations;
}

#pragma mark Private

///
Expand Down
5 changes: 5 additions & 0 deletions Source/common/santa.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ syntax = "proto3";

import "google/protobuf/any.proto";
import "google/protobuf/timestamp.proto";
import "Source/santad/ProcessTree/process_tree.proto";

option objc_class_prefix = "SNTPB";

Expand Down Expand Up @@ -173,6 +174,8 @@ message ProcessInfo {

// Time the process was started
optional google.protobuf.Timestamp start_time = 17;

optional process_tree.Annotations annotations = 18;
}

// Light variant of ProcessInfo message to help minimize on-disk/on-wire sizes
Expand Down Expand Up @@ -202,6 +205,8 @@ message ProcessInfoLight {

// File information for the executable backing this process
optional FileInfoLight executable = 10;

optional process_tree.Annotations annotations = 11;
}

// Certificate information
Expand Down
24 changes: 22 additions & 2 deletions Source/santad/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,20 @@ objc_library(
],
)

objc_library(
name = "SNTEndpointSecurityTreeAwareClient",
srcs = ["EventProviders/SNTEndpointSecurityTreeAwareClient.mm"],
hdrs = ["EventProviders/SNTEndpointSecurityTreeAwareClient.h"],
deps = [
":EndpointSecurityAPI",
":EndpointSecurityMessage",
":Metrics",
":SNTEndpointSecurityClient",
"//Source/santad/ProcessTree:SNTEndpointSecurityAdapter",
"//Source/santad/ProcessTree:process_tree",
],
)

objc_library(
name = "SNTEndpointSecurityRecorder",
srcs = ["EventProviders/SNTEndpointSecurityRecorder.mm"],
Expand All @@ -305,8 +319,8 @@ objc_library(
":EndpointSecurityMessage",
":Metrics",
":SNTCompilerController",
":SNTEndpointSecurityClient",
":SNTEndpointSecurityEventHandler",
":SNTEndpointSecurityTreeAwareClient",
"//Source/common:PrefixTree",
"//Source/common:SNTConfigurator",
"//Source/common:SNTLogging",
Expand Down Expand Up @@ -343,8 +357,8 @@ objc_library(
":EndpointSecurityMessage",
":Metrics",
":SNTCompilerController",
":SNTEndpointSecurityClient",
":SNTEndpointSecurityEventHandler",
":SNTEndpointSecurityTreeAwareClient",
":SNTExecutionController",
"//Source/common:BranchPrediction",
"//Source/common:SNTCommonEnums",
Expand Down Expand Up @@ -445,6 +459,8 @@ objc_library(
":EndpointSecurityEnrichedTypes",
"//Source/common:SNTLogging",
"//Source/common:SantaCache",
"//Source/santad/ProcessTree:SNTEndpointSecurityAdapter",
"//Source/santad/ProcessTree:process_tree",
],
)

Expand All @@ -453,6 +469,7 @@ objc_library(
hdrs = ["EventProviders/EndpointSecurity/EnrichedTypes.h"],
deps = [
":EndpointSecurityMessage",
"//Source/santad/ProcessTree:process_tree_cc_proto",
],
)

Expand Down Expand Up @@ -627,6 +644,7 @@ objc_library(
deps = [
":EndpointSecurityClient",
":WatchItemPolicy",
"//Source/santad/ProcessTree:process_tree",
],
)

Expand Down Expand Up @@ -724,6 +742,7 @@ objc_library(
"//Source/common:SNTXPCNotifierInterface",
"//Source/common:SNTXPCSyncServiceInterface",
"//Source/common:Unit",
"//Source/santad/ProcessTree:process_tree",
"@MOLXPCConnection",
],
)
Expand Down Expand Up @@ -755,6 +774,7 @@ objc_library(
"//Source/common:SNTXPCControlInterface",
"//Source/common:SNTXPCUnprivilegedControlInterface",
"//Source/common:Unit",
"//Source/santad/ProcessTree:process_tree",
"@MOLXPCConnection",
],
)
Expand Down
29 changes: 20 additions & 9 deletions Source/santad/EventProviders/EndpointSecurity/EnrichedTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <variant>

#include "Source/santad/EventProviders/EndpointSecurity/Message.h"
#include "Source/santad/ProcessTree/process_tree.pb.h"

namespace santa::santad::event_providers::endpoint_security {

Expand Down Expand Up @@ -71,25 +72,30 @@ class EnrichedProcess {
: effective_user_(std::nullopt),
effective_group_(std::nullopt),
real_user_(std::nullopt),
real_group_(std::nullopt) {}

EnrichedProcess(std::optional<std::shared_ptr<std::string>> &&effective_user,
std::optional<std::shared_ptr<std::string>> &&effective_group,
std::optional<std::shared_ptr<std::string>> &&real_user,
std::optional<std::shared_ptr<std::string>> &&real_group,
EnrichedFile &&executable)
real_group_(std::nullopt),
annotations_(std::nullopt) {}

EnrichedProcess(
std::optional<std::shared_ptr<std::string>> &&effective_user,
std::optional<std::shared_ptr<std::string>> &&effective_group,
std::optional<std::shared_ptr<std::string>> &&real_user,
std::optional<std::shared_ptr<std::string>> &&real_group,
EnrichedFile &&executable,
std::optional<santa::pb::v1::process_tree::Annotations> &&annotations)
: effective_user_(std::move(effective_user)),
effective_group_(std::move(effective_group)),
real_user_(std::move(real_user)),
real_group_(std::move(real_group)),
executable_(std::move(executable)) {}
executable_(std::move(executable)),
annotations_(std::move(annotations)) {}

EnrichedProcess(EnrichedProcess &&other)
: effective_user_(std::move(other.effective_user_)),
effective_group_(std::move(other.effective_group_)),
real_user_(std::move(other.real_user_)),
real_group_(std::move(other.real_group_)),
executable_(std::move(other.executable_)) {}
executable_(std::move(other.executable_)),
annotations_(std::move(other.annotations_)) {}

// Note: Move assignment could be safely implemented but not currently needed
EnrichedProcess &operator=(EnrichedProcess &&other) = delete;
Expand All @@ -110,13 +116,18 @@ class EnrichedProcess {
return real_group_;
}
const EnrichedFile &executable() const { return executable_; }
const std::optional<santa::pb::v1::process_tree::Annotations> &annotations()
const {
return annotations_;
}

private:
std::optional<std::shared_ptr<std::string>> effective_user_;
std::optional<std::shared_ptr<std::string>> effective_group_;
std::optional<std::shared_ptr<std::string>> real_user_;
std::optional<std::shared_ptr<std::string>> real_group_;
EnrichedFile executable_;
std::optional<santa::pb::v1::process_tree::Annotations> annotations_;
};

class EnrichedEventType {
Expand Down
3 changes: 2 additions & 1 deletion Source/santad/EventProviders/EndpointSecurity/Enricher.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ enum class EnrichOptions {

class Enricher {
public:
Enricher();
Enricher(std::shared_ptr<process_tree::ProcessTree> pt = nullptr);
virtual ~Enricher() = default;
virtual std::unique_ptr<EnrichedMessage> Enrich(Message &&msg);
virtual EnrichedProcess Enrich(
Expand All @@ -51,6 +51,7 @@ class Enricher {
username_cache_;
SantaCache<gid_t, std::optional<std::shared_ptr<std::string>>>
groupname_cache_;
std::shared_ptr<process_tree::ProcessTree> process_tree_;
};

} // namespace santa::santad::event_providers::endpoint_security
Expand Down
11 changes: 9 additions & 2 deletions Source/santad/EventProviders/EndpointSecurity/Enricher.mm
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@

#include "Source/common/SNTLogging.h"
#include "Source/santad/EventProviders/EndpointSecurity/EnrichedTypes.h"
#include "Source/santad/ProcessTree/SNTEndpointSecurityAdapter.h"
#include "Source/santad/ProcessTree/process_tree.h"
#include "Source/santad/ProcessTree/process_tree_macos.h"

namespace santa::santad::event_providers::endpoint_security {

Enricher::Enricher() : username_cache_(256), groupname_cache_(256) {}
Enricher::Enricher(std::shared_ptr<::santa::santad::process_tree::ProcessTree> pt)
: username_cache_(256), groupname_cache_(256), process_tree_(std::move(pt)) {}

std::unique_ptr<EnrichedMessage> Enricher::Enrich(Message &&es_msg) {
// TODO(mlw): Consider potential design patterns that could help reduce memory usage under load
Expand Down Expand Up @@ -89,7 +93,10 @@
UsernameForGID(audit_token_to_egid(es_proc.audit_token), options),
UsernameForUID(audit_token_to_ruid(es_proc.audit_token), options),
UsernameForGID(audit_token_to_rgid(es_proc.audit_token), options),
Enrich(*es_proc.executable, options));
Enrich(*es_proc.executable, options),
process_tree_ ? process_tree_->ExportAnnotations(
process_tree::PidFromAuditToken(es_proc.audit_token))
: std::nullopt);
}

EnrichedFile Enricher::Enrich(const es_file_t &es_file, EnrichOptions options) {
Expand Down
9 changes: 7 additions & 2 deletions Source/santad/EventProviders/EndpointSecurity/Message.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <memory>
#include <string>

#include "Source/santad/ProcessTree/process_tree.h"

namespace santa::santad::event_providers::endpoint_security {

class EndpointSecurityAPI;
Expand All @@ -37,21 +39,24 @@ class Message {
Message(const Message& other);
Message& operator=(const Message& other) = delete;

void SetProcessToken(process_tree::ProcessToken tok);

// Operators to access underlying es_message_t
const es_message_t* operator->() const { return es_msg_; }
const es_message_t& operator*() const { return *es_msg_; }

// Helper to get the API associated with this message.
// Used for things like es_exec_arg_count.
// We should ideally rework this to somehow present these functions as
// methods on the Message, however this would be a bit of a bigger lift.
// We should ideally rework this to somehow present these functions as methods
// on the Message, however this would be a bit of a bigger lift.
std::shared_ptr<EndpointSecurityAPI> ESAPI() const { return esapi_; }

std::string ParentProcessName() const;

private:
std::shared_ptr<EndpointSecurityAPI> esapi_;
const es_message_t* es_msg_;
std::optional<process_tree::ProcessToken> process_token_;

std::string GetProcessName(pid_t pid) const;
};
Expand Down
9 changes: 8 additions & 1 deletion Source/santad/EventProviders/EndpointSecurity/Message.mm
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
namespace santa::santad::event_providers::endpoint_security {

Message::Message(std::shared_ptr<EndpointSecurityAPI> esapi, const es_message_t *es_msg)
: esapi_(std::move(esapi)), es_msg_(es_msg) {
: esapi_(std::move(esapi)), es_msg_(es_msg), process_token_(std::nullopt) {
esapi_->RetainMessage(es_msg);
}

Expand All @@ -36,12 +36,19 @@
esapi_ = std::move(other.esapi_);
es_msg_ = other.es_msg_;
other.es_msg_ = nullptr;
process_token_ = std::move(other.process_token_);
other.process_token_ = std::nullopt;
}

Message::Message(const Message &other) {
esapi_ = other.esapi_;
es_msg_ = other.es_msg_;
esapi_->RetainMessage(es_msg_);
process_token_ = other.process_token_;
}

void Message::SetProcessToken(process_tree::ProcessToken tok) {
process_token_ = std::move(tok);
}

std::string Message::ParentProcessName() const {
Expand Down
12 changes: 12 additions & 0 deletions Source/santad/EventProviders/SNTEndpointSecurityClient.mm
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ - (BOOL)shouldHandleMessage:(const Message &)esMsg {
return YES;
}

- (bool)handleContextMessage:(Message &)esMsg {
return false;
}

- (void)establishClientOrDie {
if (self->_esClient.IsConnected()) {
// This is a programming error
Expand All @@ -143,6 +147,14 @@ - (void)establishClientOrDie {
self->_metrics->UpdateEventStats(self->_processor, esMsg.operator->());

es_event_type_t eventType = esMsg->event_type;

if ([self handleContextMessage:esMsg]) {
int64_t processingEnd = clock_gettime_nsec_np(CLOCK_MONOTONIC);
self->_metrics->SetEventMetrics(self->_processor, eventType, EventDisposition::kProcessed,
processingEnd - processingStart);
return;
}

if ([self shouldHandleMessage:esMsg]) {
[self handleMessage:std::move(esMsg)
recordEventMetrics:^(EventDisposition disposition) {
Expand Down
10 changes: 5 additions & 5 deletions Source/santad/EventProviders/SNTEndpointSecurityClientTest.mm
Original file line number Diff line number Diff line change
Expand Up @@ -417,11 +417,11 @@ - (void)testProcessEnrichedMessageHandler {
metrics:nullptr
processor:Processor::kUnknown];
{
auto enrichedMsg = std::make_unique<EnrichedMessage>(
EnrichedClose(Message(mockESApi, &esMsg),
EnrichedProcess(std::nullopt, std::nullopt, std::nullopt, std::nullopt,
EnrichedFile(std::nullopt, std::nullopt, std::nullopt)),
EnrichedFile(std::nullopt, std::nullopt, std::nullopt)));
auto enrichedMsg = std::make_unique<EnrichedMessage>(EnrichedClose(
Message(mockESApi, &esMsg),
EnrichedProcess(std::nullopt, std::nullopt, std::nullopt, std::nullopt,
EnrichedFile(std::nullopt, std::nullopt, std::nullopt), std::nullopt),
EnrichedFile(std::nullopt, std::nullopt, std::nullopt)));

[client processEnrichedMessage:std::move(enrichedMsg)
handler:^(std::unique_ptr<EnrichedMessage> msg) {
Expand Down
Loading

0 comments on commit 10a5df2

Please sign in to comment.