Skip to content

Commit

Permalink
Wire up TTYWriter instance to the file access client (#1129)
Browse files Browse the repository at this point in the history
  • Loading branch information
mlw authored Jul 26, 2023
1 parent 03fcd0c commit bcac65a
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 29 deletions.
2 changes: 2 additions & 0 deletions Source/santad/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ objc_library(
":SNTDecisionCache",
":SNTEndpointSecurityClient",
":SNTEndpointSecurityEventHandler",
":TTYWriter",
":WatchItemPolicy",
":WatchItems",
"//Source/common:Platform",
Expand Down Expand Up @@ -692,6 +693,7 @@ objc_library(
":SNTExecutionController",
":SNTNotificationQueue",
":SNTSyncdQueue",
":TTYWriter",
":WatchItems",
"//Source/common:PrefixTree",
"//Source/common:SNTCommonEnums",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "Source/santad/Logs/EndpointSecurity/Logger.h"
#include "Source/santad/Metrics.h"
#import "Source/santad/SNTDecisionCache.h"
#include "Source/santad/TTYWriter.h"

typedef void (^SNTFileAccessBlockCallback)(SNTFileAccessEvent *event);

Expand All @@ -39,7 +40,8 @@ typedef void (^SNTFileAccessBlockCallback)(SNTFileAccessEvent *event);
watchItems:(std::shared_ptr<santa::santad::data_layer::WatchItems>)watchItems
enricher:
(std::shared_ptr<santa::santad::event_providers::endpoint_security::Enricher>)enricher
decisionCache:(SNTDecisionCache *)decisionCache;
decisionCache:(SNTDecisionCache *)decisionCache
ttyWriter:(std::shared_ptr<santa::santad::TTYWriter>)ttyWriter;

@property SNTFileAccessBlockCallback fileAccessBlockCallback;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

using santa::common::StringToNSString;
using santa::santad::EventDisposition;
using santa::santad::TTYWriter;
using santa::santad::data_layer::WatchItemPathType;
using santa::santad::data_layer::WatchItemPolicy;
using santa::santad::data_layer::WatchItems;
Expand Down Expand Up @@ -118,6 +119,10 @@ bool ShouldLogDecision(FileAccessPolicyDecision decision) {
}
}

bool ShouldNotifyUserDecision(FileAccessPolicyDecision decision) {
return ShouldLogDecision(decision) && decision != FileAccessPolicyDecision::kAllowedAuditOnly;
}

es_auth_result_t CombinePolicyResults(es_auth_result_t result1, es_auth_result_t result2) {
// If either policy denied the operation, the operation is denied
return ((result1 == ES_AUTH_RESULT_DENY || result2 == ES_AUTH_RESULT_DENY)
Expand Down Expand Up @@ -207,6 +212,7 @@ @implementation SNTEndpointSecurityFileAccessAuthorizer {
std::shared_ptr<Enricher> _enricher;
std::shared_ptr<RateLimiter> _rateLimiter;
SantaCache<SantaVnode, NSString *> _certHashCache;
std::shared_ptr<TTYWriter> _ttyWriter;
}

- (instancetype)
Expand All @@ -217,16 +223,17 @@ @implementation SNTEndpointSecurityFileAccessAuthorizer {
watchItems:(std::shared_ptr<WatchItems>)watchItems
enricher:
(std::shared_ptr<santa::santad::event_providers::endpoint_security::Enricher>)enricher
decisionCache:(SNTDecisionCache *)decisionCache {
decisionCache:(SNTDecisionCache *)decisionCache
ttyWriter:(std::shared_ptr<santa::santad::TTYWriter>)ttyWriter {
self = [super initWithESAPI:std::move(esApi)
metrics:metrics
processor:santa::santad::Processor::kFileAccessAuthorizer];
if (self) {
_watchItems = std::move(watchItems);
_logger = std::move(logger);
_enricher = std::move(enricher);

_decisionCache = decisionCache;
_ttyWriter = std::move(ttyWriter);

_rateLimiter = RateLimiter::Create(metrics, santa::santad::Processor::kFileAccessAuthorizer,
kDefaultRateLimitQPS);
Expand Down Expand Up @@ -567,7 +574,6 @@ - (void)handleMessage:(santa::santad::event_providers::endpoint_security::Messag
}

- (void)enable {
// TODO(xyz): Expand to support ES_EVENT_TYPE_AUTH_CREATE, ES_EVENT_TYPE_AUTH_TRUNCATE
std::set<es_event_type_t> events = {
ES_EVENT_TYPE_AUTH_CLONE, ES_EVENT_TYPE_AUTH_CREATE, ES_EVENT_TYPE_AUTH_EXCHANGEDATA,
ES_EVENT_TYPE_AUTH_LINK, ES_EVENT_TYPE_AUTH_OPEN, ES_EVENT_TYPE_AUTH_RENAME,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
extern void PopulatePathTargets(const Message &msg, std::vector<PathTarget> &targets);
extern es_auth_result_t FileAccessPolicyDecisionToESAuthResult(FileAccessPolicyDecision decision);
extern bool ShouldLogDecision(FileAccessPolicyDecision decision);
extern bool ShouldNotifyUserDecision(FileAccessPolicyDecision decision);
extern es_auth_result_t CombinePolicyResults(es_auth_result_t result1, es_auth_result_t result2);

void SetExpectationsForFileAccessAuthorizerInit(
Expand Down Expand Up @@ -135,7 +136,8 @@ - (void)testGetCertificateHash {
logger:nullptr
watchItems:nullptr
enricher:nullptr
decisionCache:self.dcMock];
decisionCache:self.dcMock
ttyWriter:nullptr];

//
// Test 1 - Not in local cache or decision cache, and code sig lookup fails
Expand Down Expand Up @@ -229,14 +231,30 @@ - (void)testShouldLogDecision {
{FileAccessPolicyDecision::kAllowed, false},
{FileAccessPolicyDecision::kAllowedReadAccess, false},
{FileAccessPolicyDecision::kAllowedAuditOnly, true},
{(FileAccessPolicyDecision)5, false},
{(FileAccessPolicyDecision)123, false},
};

for (const auto &kv : policyDecisionToShouldLog) {
XCTAssertEqual(ShouldLogDecision(kv.first), kv.second);
}
}

- (void)testShouldNotifyUserDecision {
std::map<FileAccessPolicyDecision, bool> policyDecisionToShouldLog = {
{FileAccessPolicyDecision::kNoPolicy, false},
{FileAccessPolicyDecision::kDenied, true},
{FileAccessPolicyDecision::kDeniedInvalidSignature, true},
{FileAccessPolicyDecision::kAllowed, false},
{FileAccessPolicyDecision::kAllowedReadAccess, false},
{FileAccessPolicyDecision::kAllowedAuditOnly, false},
{(FileAccessPolicyDecision)123, false},
};

for (const auto &kv : policyDecisionToShouldLog) {
XCTAssertEqual(ShouldNotifyUserDecision(kv.first), kv.second);
}
}

- (void)testCombinePolicyResults {
// Ensure that the combined result is ES_AUTH_RESULT_DENY if both or either
// input result is ES_AUTH_RESULT_DENY.
Expand Down Expand Up @@ -269,7 +287,8 @@ - (void)testSpecialCaseForPolicyMessage {
logger:nullptr
watchItems:nullptr
enricher:nullptr
decisionCache:nil];
decisionCache:nil
ttyWriter:nullptr];

auto policy = std::make_shared<WatchItemPolicy>("foo_policy", "/foo");

Expand Down Expand Up @@ -397,7 +416,8 @@ - (void)testPolicyProcessMatchesESProcess {
logger:nullptr
watchItems:nullptr
enricher:nullptr
decisionCache:nil];
decisionCache:nil
ttyWriter:nullptr];

id accessClientMock = OCMPartialMock(accessClient);

Expand Down Expand Up @@ -515,7 +535,8 @@ - (void)testApplyPolicyToMessage {
logger:nullptr
watchItems:nullptr
enricher:nullptr
decisionCache:nil];
decisionCache:nil
ttyWriter:nullptr];

id accessClientMock = OCMPartialMock(accessClient);

Expand Down Expand Up @@ -678,7 +699,8 @@ - (void)testDisable {
logger:nullptr
watchItems:nullptr
enricher:nullptr
decisionCache:nil];
decisionCache:nil
ttyWriter:nullptr];

EXPECT_CALL(*mockESApi, UnsubscribeAll);
EXPECT_CALL(*mockESApi, UnmuteAllTargetPaths).WillOnce(testing::Return(true));
Expand Down
5 changes: 3 additions & 2 deletions Source/santad/Santad.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#import "Source/santad/SNTExecutionController.h"
#import "Source/santad/SNTNotificationQueue.h"
#import "Source/santad/SNTSyncdQueue.h"
#include "Source/santad/TTYWriter.h"

void SantadMain(
std::shared_ptr<
Expand All @@ -45,7 +46,7 @@ void SantadMain(
SNTCompilerController* compiler_controller,
SNTNotificationQueue* notifier_queue, SNTSyncdQueue* syncd_queue,
SNTExecutionController* exec_controller,
std::shared_ptr<santa::common::PrefixTree<santa::common::Unit>>
prefix_tree);
std::shared_ptr<santa::common::PrefixTree<santa::common::Unit>> prefix_tree,
std::shared_ptr<santa::santad::TTYWriter> tty_writer);

#endif
19 changes: 11 additions & 8 deletions Source/santad/Santad.mm
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@
#include "Source/santad/Logs/EndpointSecurity/Logger.h"
#include "Source/santad/SNTDaemonControlController.h"
#include "Source/santad/SNTDecisionCache.h"
#include "Source/santad/TTYWriter.h"

using santa::common::PrefixTree;
using santa::common::Unit;
using santa::santad::Metrics;
using santa::santad::TTYWriter;
using santa::santad::data_layer::WatchItems;
using santa::santad::event_providers::AuthResultCache;
using santa::santad::event_providers::FlushCacheMode;
Expand Down Expand Up @@ -79,7 +81,8 @@ void SantadMain(std::shared_ptr<EndpointSecurityAPI> esapi, std::shared_ptr<Logg
MOLXPCConnection *control_connection, SNTCompilerController *compiler_controller,
SNTNotificationQueue *notifier_queue, SNTSyncdQueue *syncd_queue,
SNTExecutionController *exec_controller,
std::shared_ptr<santa::common::PrefixTree<santa::common::Unit>> prefix_tree) {
std::shared_ptr<santa::common::PrefixTree<santa::common::Unit>> prefix_tree,
std::shared_ptr<TTYWriter> tty_writer) {
SNTConfigurator *configurator = [SNTConfigurator configurator];

SNTDaemonControlController *dc =
Expand Down Expand Up @@ -133,13 +136,13 @@ void SantadMain(std::shared_ptr<EndpointSecurityAPI> esapi, std::shared_ptr<Logg

if (@available(macOS 13.0, *)) {
SNTEndpointSecurityFileAccessAuthorizer *access_authorizer_client =
[[SNTEndpointSecurityFileAccessAuthorizer alloc]
initWithESAPI:esapi
metrics:metrics
logger:logger
watchItems:watch_items
enricher:enricher
decisionCache:[SNTDecisionCache sharedCache]];
[[SNTEndpointSecurityFileAccessAuthorizer alloc] initWithESAPI:esapi
metrics:metrics
logger:logger
watchItems:watch_items
enricher:enricher
decisionCache:[SNTDecisionCache sharedCache]
ttyWriter:tty_writer];
watch_items->RegisterClient(access_authorizer_client);

access_authorizer_client.fileAccessBlockCallback = ^(SNTFileAccessEvent *event) {
Expand Down
6 changes: 5 additions & 1 deletion Source/santad/SantadDeps.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#import "Source/santad/SNTExecutionController.h"
#import "Source/santad/SNTNotificationQueue.h"
#import "Source/santad/SNTSyncdQueue.h"
#include "Source/santad/TTYWriter.h"

namespace santa::santad {

Expand All @@ -56,7 +57,8 @@ class SantadDeps {
SNTNotificationQueue *notifier_queue, SNTSyncdQueue *syncd_queue,
SNTExecutionController *exec_controller,
std::shared_ptr<santa::common::PrefixTree<santa::common::Unit>>
prefix_tree);
prefix_tree,
std::shared_ptr<santa::santad::TTYWriter> tty_writer);

std::shared_ptr<santa::santad::event_providers::AuthResultCache>
AuthResultCache();
Expand All @@ -74,6 +76,7 @@ class SantadDeps {
SNTSyncdQueue *SyncdQueue();
SNTExecutionController *ExecController();
std::shared_ptr<santa::common::PrefixTree<santa::common::Unit>> PrefixTree();
std::shared_ptr<santa::santad::TTYWriter> TTYWriter();

private:
std::shared_ptr<
Expand All @@ -93,6 +96,7 @@ class SantadDeps {
SNTSyncdQueue *syncd_queue_;
SNTExecutionController *exec_controller_;
std::shared_ptr<santa::common::PrefixTree<santa::common::Unit>> prefix_tree_;
std::shared_ptr<santa::santad::TTYWriter> tty_writer_;
};

} // namespace santa::santad
Expand Down
20 changes: 13 additions & 7 deletions Source/santad/SantadDeps.mm
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
exit(EXIT_FAILURE);
}

std::shared_ptr<TTYWriter> tty_writer = TTYWriter::Create();
std::shared_ptr<::TTYWriter> tty_writer = TTYWriter::Create();
if (!tty_writer) {
LOGW(@"Unable to initialize TTY writer");
}
Expand Down Expand Up @@ -152,10 +152,10 @@
exit(EXIT_FAILURE);
}

return std::make_unique<SantadDeps>(esapi, std::move(logger), std::move(metrics),
std::move(watch_items), std::move(auth_result_cache),
control_connection, compiler_controller, notifier_queue,
syncd_queue, exec_controller, prefix_tree);
return std::make_unique<SantadDeps>(
esapi, std::move(logger), std::move(metrics), std::move(watch_items),
std::move(auth_result_cache), control_connection, compiler_controller, notifier_queue,
syncd_queue, exec_controller, prefix_tree, std::move(tty_writer));
}

SantadDeps::SantadDeps(
Expand All @@ -164,7 +164,8 @@
std::shared_ptr<santa::santad::event_providers::AuthResultCache> auth_result_cache,
MOLXPCConnection *control_connection, SNTCompilerController *compiler_controller,
SNTNotificationQueue *notifier_queue, SNTSyncdQueue *syncd_queue,
SNTExecutionController *exec_controller, std::shared_ptr<::PrefixTree<Unit>> prefix_tree)
SNTExecutionController *exec_controller, std::shared_ptr<::PrefixTree<Unit>> prefix_tree,
std::shared_ptr<::TTYWriter> tty_writer)
: esapi_(std::move(esapi)),
logger_(std::move(logger)),
metrics_(std::move(metrics)),
Expand All @@ -176,7 +177,8 @@
notifier_queue_(notifier_queue),
syncd_queue_(syncd_queue),
exec_controller_(exec_controller),
prefix_tree_(prefix_tree) {}
prefix_tree_(prefix_tree),
tty_writer_(std::move(tty_writer)) {}

std::shared_ptr<::AuthResultCache> SantadDeps::AuthResultCache() {
return auth_result_cache_;
Expand Down Expand Up @@ -225,4 +227,8 @@
return prefix_tree_;
}

std::shared_ptr<::TTYWriter> SantadDeps::TTYWriter() {
return tty_writer_;
}

} // namespace santa::santad
2 changes: 1 addition & 1 deletion Source/santad/main.mm
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ int main(int argc, char *argv[]) {
SantadMain(deps->ESAPI(), deps->Logger(), deps->Metrics(), deps->WatchItems(), deps->Enricher(),
deps->AuthResultCache(), deps->ControlConnection(), deps->CompilerController(),
deps->NotifierQueue(), deps->SyncdQueue(), deps->ExecController(),
deps->PrefixTree());
deps->PrefixTree(), deps->TTYWriter());
}

return 0;
Expand Down

0 comments on commit bcac65a

Please sign in to comment.