Skip to content

Commit

Permalink
Merge 5258fee into 3702af0
Browse files Browse the repository at this point in the history
  • Loading branch information
pmarkowsky committed Oct 21, 2021
2 parents 3702af0 + 5258fee commit d3898e1
Show file tree
Hide file tree
Showing 19 changed files with 529 additions and 4 deletions.
7 changes: 7 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ run_command(
cmd = """
sudo launchctl unload /Library/LaunchDaemons/com.google.santad.plist 2>/dev/null
sudo launchctl unload /Library/LaunchDaemons/com.google.santa.bundleservice.plist 2>/dev/null
sudo launchctl unload /Library/LaunchDaemons/com.google.santa.metricservice.plist 2>/dev/null
sudo kextunload -b com.google.santa-driver 2>/dev/null
launchctl unload /Library/LaunchAgents/com.google.santa.plist 2>/dev/null
""",
Expand All @@ -58,6 +59,7 @@ run_command(
cmd = """
sudo launchctl load /Library/LaunchDaemons/com.google.santad.plist
sudo launchctl load /Library/LaunchDaemons/com.google.santa.bundleservice.plist
sudo launchctl load /Library/LaunchDaemons/com.google.santa.metricservice.plist
launchctl load /Library/LaunchAgents/com.google.santa.plist
""",
)
Expand Down Expand Up @@ -94,6 +96,7 @@ genrule(
"Conf/install.sh",
"Conf/uninstall.sh",
"Conf/com.google.santa.bundleservice.plist",
"Conf/com.google.santa.metricservice.plist",
"Conf/com.google.santad.plist",
"Conf/com.google.santa.plist",
"Conf/com.google.santa.asl.conf",
Expand Down Expand Up @@ -142,6 +145,10 @@ genrule(
mkdir -p $(@D)/dsym
cp -LR $$(dirname $$(dirname $${SRC})) $(@D)/dsym/santabundleservice.dSYM
;;
*santametricservice.dSYM*Info.plist)
mkdir -p $(@D)/dsym
cp -LR $$(dirname $$(dirname $${SRC})) $(@D)/dsym/santametricservice.dSYM
;;
*Santa.app.dSYM*Info.plist)
mkdir -p $(@D)/dsym
cp -LR $$(dirname $$(dirname $${SRC})) $(@D)/dsym/Santa.app.dSYM
Expand Down
3 changes: 3 additions & 0 deletions Conf/Package/postinstall
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ mkdir -p /usr/local/bin
# Load com.google.santa.bundleservice
/bin/launchctl load -w /Library/LaunchDaemons/com.google.santa.bundleservice.plist

# Load com.google.santa.metricservice
/bin/launchctl load -w /Library/LaunchDaemons/com.google.santa.metricservice.plist

GUI_USER=$(/usr/bin/stat -f '%u' /dev/console)
[[ -z "${GUI_USER}" ]] && exit 0

Expand Down
1 change: 1 addition & 0 deletions Conf/Package/preinstall
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/bin/launchctl remove com.google.santad || true
/bin/launchctl remove com.google.santa.bundleservice || true
/bin/launchctl remove com.google.santa.metricservice || true

/bin/sleep 1

Expand Down
22 changes: 22 additions & 0 deletions Conf/com.google.santa.metricservice.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.google.santa.metricservice</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/Santa.app/Contents/MacOS/santametricservice</string>
<string>--syslog</string>
</array>
<key>MachServices</key>
<dict>
<key>com.google.santa.metricservice</key>
<true/>
</dict>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
7 changes: 7 additions & 0 deletions Conf/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ fi
# Unload bundle service
/bin/launchctl remove com.google.santa.bundleservice >/dev/null 2>&1

# Unload metric service
/bin/launchctl remove com.google.santa.metricservice >/dev/null 2>&1

# Unload kext.
/sbin/kextunload -b com.google.santa-driver >/dev/null 2>&1

Expand Down Expand Up @@ -58,6 +61,7 @@ GUI_USER=$(/usr/bin/stat -f '%u' /dev/console)

/bin/cp ${CONF}/com.google.santa.plist /Library/LaunchAgents
/bin/cp ${CONF}/com.google.santa.bundleservice.plist /Library/LaunchDaemons
/bin/cp ${CONF}/com.google.santa.metricservice.plist /Library/LaunchDaemons
/bin/cp ${CONF}/com.google.santad.plist /Library/LaunchDaemons
/bin/cp ${CONF}/com.google.santa.asl.conf /etc/asl/
/bin/cp ${CONF}/com.google.santa.newsyslog.conf /etc/newsyslog.d/
Expand All @@ -71,6 +75,9 @@ GUI_USER=$(/usr/bin/stat -f '%u' /dev/console)
# Load com.google.santa.bundleservice
/bin/launchctl load /Library/LaunchDaemons/com.google.santa.bundleservice.plist

# Load com.google.santa.metricservice
/bin/launchctl load /Library/LaunchDaemons/com.google.santa.metricservice.plist

# Load GUI agent if someone is logged in.
[[ -z "${GUI_USER}" ]] && exit 0

Expand Down
1 change: 1 addition & 0 deletions Conf/uninstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ user=$(/usr/bin/stat -f '%u' /dev/console)
/bin/rm -f /Library/LaunchAgents/com.google.santa.plist
/bin/rm -f /Library/LaunchDaemons/com.google.santad.plist
/bin/rm -f /Library/LaunchDaemons/com.google.santa.bundleservice.plist
/bin/rm -f /Library/LaunchDaemons/com.google.santa.metricservice.plist
/bin/rm -f /private/etc/asl/com.google.santa.asl.conf
/bin/rm -f /private/etc/newsyslog.d/com.google.santa.newsyslog.conf
/bin/rm -f /usr/local/bin/santactl # just a symlink
Expand Down
9 changes: 9 additions & 0 deletions Source/common/SNTMetricSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ typedef NS_ENUM(NSInteger, SNTMetricType) {
fieldNames:(NSArray<NSString *> *)fieldNames
helpText:(NSString *)text;

/**
* Returns a shared global instance with default root labels and metrics registerd.
*/
+ (instancetype)sharedInstance;


/**
* Add a root label to the MetricSet.
*/
- (void)addRootLabel:(NSString *)label value:(NSString *)value;

/**
Expand Down
11 changes: 11 additions & 0 deletions Source/common/SNTMetricSet.m
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,17 @@ @implementation SNTMetricSet {
NSMutableArray<void (^)(void)> *_callbacks;
}

+ (instancetype) sharedInstance {
static SNTMetricSet *sharedMetrics;
static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{
sharedMetrics = [[SNTMetricSet alloc] init];
});

return sharedMetrics;
}

- (instancetype)init {
self = [super init];
if (self) {
Expand Down
3 changes: 2 additions & 1 deletion Source/common/SNTXPCMetricServiceInterface.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ @implementation SNTXPCMetricServiceInterface
+ (NSXPCInterface *)metricServiceInterface {
NSXPCInterface *r = [NSXPCInterface interfaceWithProtocol:@protocol(SNTMetricServiceXPC)];

[r setClasses:[NSSet setWithObjects:[NSDictionary class], nil]
[r setClasses:[NSSet setWithObjects:[NSDictionary class], [NSArray class], [NSNumber class],
[NSString class], [NSDate class], nil]
forSelector:@selector(exportForMonitoring:)
argumentIndex:0
ofReply:NO];
Expand Down
1 change: 1 addition & 0 deletions Source/santa/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ macos_application(
additional_contents = {
"//Source/santactl": "MacOS",
"//Source/santabundleservice": "MacOS",
"//Source/santametricservice": "MacOS",
"//Source/santad:com.google.santa.daemon": "Library/SystemExtensions",
},
app_icons = glob(["Resources/Images.xcassets/**"]),
Expand Down
29 changes: 29 additions & 0 deletions Source/santad/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,33 @@ objc_library(
"//Source/common:SNTFileInfo",
"//Source/common:SNTKernelCommon",
"//Source/common:SNTLogging",
"//Source/common:SNTMetricSet",
"//Source/common:SNTPrefixTree",
"//Source/common:SNTRule",
"//Source/common:SNTStoredEvent",
"//Source/common:SNTXPCControlInterface",
"//Source/common:SNTXPCMetricServiceInterface",
"//Source/common:SNTXPCNotifierInterface",
"//Source/common:SNTXPCSyncdInterface",
"//Source/common:SantaCache",
"//Source/santad:SNTApplicationCoreMetrics",
"@FMDB",
"@MOLCodesignChecker",
"@MOLXPCConnection",
],
)

objc_library(
name = "SNTApplicationCoreMetrics",
srcs = ["SNTApplicationCoreMetrics.m"],
hdrs = ["SNTApplicationCoreMetrics.h"],
deps = [
"//Source/common:SNTCommonEnums",
"//Source/common:SNTConfigurator",
"//Source/common:SNTMetricSet",
],
)

objc_library(
name = "EndpointSecurityTestLib",
testonly = 1,
Expand Down Expand Up @@ -261,3 +275,18 @@ santa_unit_test(
"@OCMock",
],
)

santa_unit_test(
name = "SNTApplicationCoreMetricsTest",
srcs = [
"SNTApplicationCoreMetricsTest.m",
],
minimum_os_version = "10.15",
deps = [
":SNTApplicationCoreMetrics",
"//Source/common:SNTCommonEnums",
"//Source/common:SNTMetricSet",
"//Source/santametricservice/Formats:SNTMetricFormatTestHelper",
"@OCMock",
],
)
82 changes: 81 additions & 1 deletion Source/santad/SNTApplication.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,20 @@
/// limitations under the License.

#import "Source/santad/SNTApplication.h"
#import "Source/santad/SNTApplicationCoreMetrics.h"

#import <DiskArbitration/DiskArbitration.h>
#import <MOLXPCConnection/MOLXPCConnection.h>

#import "Source/common/SNTCommonEnums.h"
#import "Source/common/SNTConfigurator.h"
#import "Source/common/SNTMetricSet.h"
#import "Source/common/SNTDropRootPrivs.h"
#import "Source/common/SNTLogging.h"
#import "Source/common/SNTXPCControlInterface.h"
#import "Source/common/SNTXPCNotifierInterface.h"
#import "Source/common/SNTXPCUnprivilegedControlInterface.h"
#import "Source/common/SNTXPCMetricServiceInterface.h"
#import "Source/santad/DataLayer/SNTEventTable.h"
#import "Source/santad/DataLayer/SNTRuleTable.h"
#import "Source/santad/EventProviders/SNTCachingEndpointSecurityManager.h"
Expand All @@ -48,6 +51,8 @@ @interface SNTApplication ()
@property MOLXPCConnection *controlConnection;
@property SNTNotificationQueue *notQueue;
@property pid_t syncdPID;
@property MOLXPCConnection *metricsConnection;
@property dispatch_source_t metricsTimer;
@end

@implementation SNTApplication
Expand Down Expand Up @@ -129,13 +134,18 @@ - (instancetype)init {
forKeyPath:NSStringFromSelector(@selector(blockedPathRegex))
options:bits
context:NULL];
[configurator addObserver:self
forKeyPath:NSStringFromSelector(@selector(exportMetrics))
options:bits
context:NULL];

if (![configurator enableSystemExtension]) {
[configurator addObserver:self
forKeyPath:NSStringFromSelector(@selector(enableSystemExtension))
options:bits
context:NULL];
}

// Establish XPC listener for Santa and santactl connections
SNTDaemonControlController *dc =
[[SNTDaemonControlController alloc] initWithEventProvider:_eventProvider
Expand Down Expand Up @@ -166,6 +176,11 @@ - (instancetype)init {
[self startSyncd];

if (!_execController) return nil;

if ([configurator exportMetrics]) {
[self startMetricsPoll];
}

}

return self;
Expand Down Expand Up @@ -271,6 +286,60 @@ void diskDisappearedCallback(DADiskRef disk, void *context) {
[app.eventProvider flushCacheNonRootOnly:YES];
}

dispatch_source_t createDispatchTimer(uint64_t interval,
uint64_t leeway,
dispatch_queue_t queue,
dispatch_block_t block)
{
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
0, 0, queue);
if (timer) {
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway);
dispatch_source_set_event_handler(timer, block);
dispatch_resume(timer);
}
return timer;
}

/*
* Create a SNTMetricSet instance and start reporting essential metrics immediately to the metric service.
*/
- (void)startMetricsPoll {
LOGI(@"starting to export metrics every 30s");
void (^exportMetricsBlock)(void) = ^{
[[self.metricsConnection remoteObjectProxy] exportForMonitoring: [[SNTMetricSet sharedInstance] export]];
};

static dispatch_once_t registerMetrics;
dispatch_once(&registerMetrics, ^{
_metricsConnection = [SNTXPCMetricServiceInterface configuredConnection];
[_metricsConnection resume];

LOGD(@"registering core metrics");
SNTRegisterCoreMetrics();
exportMetricsBlock();
});

dispatch_source_t timer = createDispatchTimer(30ull * NSEC_PER_SEC,
1ull * NSEC_PER_SEC,
dispatch_get_main_queue(),
exportMetricsBlock);
if (!timer) {
LOGE(@"failed to created timer for exporting metrics");
return;
}
_metricsTimer = timer;
}

- (void)stopMetricsPoll {
if (!_metricsTimer) {
LOGE(@"stopMetricsPoll called while _metricsTimer is nil");
return;
}

dispatch_source_cancel(_metricsTimer);
}

- (void)startSyncd {
if (![[SNTConfigurator configurator] syncBaseURL]) return;
[self stopSyncd];
Expand Down Expand Up @@ -331,6 +400,17 @@ - (void)observeValueForKeyPath:(NSString *)keyPath
LOGI(@"The penultimate exit.");
exit(0);
}
} else if ([keyPath isEqualToString:NSStringFromSelector(@selector(exportMetrics))]){
BOOL new = [change[newKey] boolValue];
BOOL old = [change[oldKey] boolValue];

if (old == NO && new == YES) {
LOGI(@"metricsExport changed NO -> YES, starting to export metrics");
[self startMetricsPoll];
} else if (old == YES && new == NO) {
LOGI(@"metricsExport changed YES -> NO, stopping export of metrics");
[self stopMetricsPoll];
}
}
}

Expand Down
18 changes: 18 additions & 0 deletions Source/santad/SNTApplicationCoreMetrics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/// Copyright 2021 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with 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.

#import "Source/common/SNTMetricSet.h"

void SNTRegisterCoreMetrics();

Loading

0 comments on commit d3898e1

Please sign in to comment.