Compare commits

...

1 Commits

12 changed files with 200 additions and 13 deletions

View File

@@ -29,4 +29,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 1728b86e95e7cdb481dd91ab9c38af38e060a023
COCOAPODS: 1.2.0
COCOAPODS: 1.2.1

View File

@@ -168,6 +168,7 @@
C776A1071DEE160500A56616 /* SNTCommandSyncManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C776A1061DEE160500A56616 /* SNTCommandSyncManager.m */; };
C795ED901D80A5BE007CFF42 /* SNTPolicyProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = C795ED8F1D80A5BE007CFF42 /* SNTPolicyProcessor.m */; };
C795ED911D80B66B007CFF42 /* SNTPolicyProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = C795ED8F1D80A5BE007CFF42 /* SNTPolicyProcessor.m */; };
C7E3A30E1ECF7D400073689C /* SNTCommandLog.m in Sources */ = {isa = PBXBuildFile; fileRef = C7E3A30D1ECF7D400073689C /* SNTCommandLog.m */; };
C7FB56F61DBFB480004E14EF /* SNTXPCSyncdInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = C7FB56F51DBFB480004E14EF /* SNTXPCSyncdInterface.m */; };
C7FB56F71DBFB480004E14EF /* SNTXPCSyncdInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = C7FB56F51DBFB480004E14EF /* SNTXPCSyncdInterface.m */; };
C7FB57001DBFC213004E14EF /* SNTSyncdQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = C7FB56FF1DBFC213004E14EF /* SNTSyncdQueue.m */; };
@@ -400,6 +401,7 @@
C776A1061DEE160500A56616 /* SNTCommandSyncManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandSyncManager.m; sourceTree = "<group>"; };
C795ED8E1D80A5BE007CFF42 /* SNTPolicyProcessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTPolicyProcessor.h; sourceTree = "<group>"; };
C795ED8F1D80A5BE007CFF42 /* SNTPolicyProcessor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTPolicyProcessor.m; sourceTree = "<group>"; };
C7E3A30D1ECF7D400073689C /* SNTCommandLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandLog.m; sourceTree = "<group>"; };
C7FB56F41DBFB480004E14EF /* SNTXPCSyncdInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTXPCSyncdInterface.h; sourceTree = "<group>"; };
C7FB56F51DBFB480004E14EF /* SNTXPCSyncdInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTXPCSyncdInterface.m; sourceTree = "<group>"; };
C7FB56FE1DBFC213004E14EF /* SNTSyncdQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTSyncdQueue.h; sourceTree = "<group>"; };
@@ -751,6 +753,7 @@
C76614EB1D142D3C00D150C1 /* SNTCommandCheckCache.m */,
0DCD5FBE1909D64A006B445C /* SNTCommandFileInfo.m */,
0DE4C8A518FF3B1700466D04 /* SNTCommandFlushCache.m */,
C7E3A30D1ECF7D400073689C /* SNTCommandLog.m */,
409232791A51B65D00A04527 /* SNTCommandRule.m */,
0D827E6619DF3C74006EC811 /* SNTCommandStatus.m */,
0DB390981AB1E11400614002 /* SNTCommandVersion.m */,
@@ -1150,7 +1153,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
8EF1E72D9F742F663ABE8DCD /* [CP] Check Pods Manifest.lock */ = {
@@ -1165,7 +1168,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
999D3C0A9B06CC3DFFB45CEA /* [CP] Copy Pods Resources */ = {
@@ -1210,7 +1213,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
D5EF20F46A8F8B36E63D1709 /* [CP] Check Pods Manifest.lock */ = {
@@ -1225,7 +1228,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
F1D2415B87633FA13FC7AA29 /* [CP] Copy Pods Resources */ = {
@@ -1338,6 +1341,7 @@
0D827E6719DF3C74006EC811 /* SNTCommandStatus.m in Sources */,
0D0A1EC6191AB9B000B8450F /* SNTCommandSyncPostflight.m in Sources */,
0D35BDAC18FD7CFD00921A21 /* SNTCommandController.m in Sources */,
C7E3A30E1ECF7D400073689C /* SNTCommandLog.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -40,12 +40,24 @@ enum SantaDriverMethods {
kSantaUserClientClearCache,
kSantaUserClientCacheCount,
kSantaUserClientCheckCache,
kSantaUserClientSetFileopLoggingFilter,
// Any methods supported by the driver should be added above this line to
// ensure this remains the count of methods.
kSantaUserClientNMethods,
};
typedef enum {
kFilterLogNone = 0,
kFilterLogAll = ~0U,
kFileopLogWrite = 1,
kFileopLogRename = 1 << 2,
kFileopLogExchange = 1 << 3,
kFileopLogLink = 1 << 4,
kFileopLogDelete = 1 << 5,
} fileop_log_filter_t;
typedef enum {
QUEUETYPE_DECISION,
QUEUETYPE_LOG

View File

@@ -35,6 +35,7 @@
- (void)cacheCount:(void (^)(int64_t))reply;
- (void)flushCache:(void (^)(BOOL))reply;
- (void)checkCacheForVnodeID:(uint64_t)vnodeID withReply:(void (^)(santa_action_t))reply;
- (void)setFileopLoggingFilter:(fileop_log_filter_t)filter withReply:(void (^)())reply;
///
/// Database ops

View File

@@ -374,6 +374,12 @@ bool SantaDecisionManager::PostToLogQueue(santa_message_t *message) {
return kr;
}
void SantaDecisionManager::SetFileopLoggingFilter(uint32_t filter) {
// All 32 bits should be set at once. Threads reading this value only do so once per run, so no
// extra serialization techniques are required.
fileop_log_filter_ = filter;
}
#pragma mark Invocation Tracking & PID comparison
void SantaDecisionManager::IncrementListenerInvocations() {
@@ -466,26 +472,38 @@ void SantaDecisionManager::FileOpCallback(
switch (action) {
case KAUTH_FILEOP_CLOSE:
message->action = ACTION_NOTIFY_WRITE;
if (fileop_log_filter_ & kFileopLogWrite) {
message->action = ACTION_NOTIFY_WRITE;
}
break;
case KAUTH_FILEOP_RENAME:
message->action = ACTION_NOTIFY_RENAME;
if (fileop_log_filter_ & kFileopLogRename) {
message->action = ACTION_NOTIFY_RENAME;
}
break;
case KAUTH_FILEOP_LINK:
message->action = ACTION_NOTIFY_LINK;
if (fileop_log_filter_ & kFileopLogLink) {
message->action = ACTION_NOTIFY_LINK;
}
break;
case KAUTH_FILEOP_EXCHANGE:
message->action = ACTION_NOTIFY_EXCHANGE;
if (fileop_log_filter_ & kFileopLogExchange) {
message->action = ACTION_NOTIFY_EXCHANGE;
}
break;
case KAUTH_FILEOP_DELETE:
message->action = ACTION_NOTIFY_DELETE;
if (fileop_log_filter_ & kFileopLogDelete) {
message->action = ACTION_NOTIFY_DELETE;
}
break;
default:
delete message;
return;
}
PostToLogQueue(message);
if (message->action != ACTION_UNSET) {
PostToLogQueue(message);
}
delete message;
}
}

View File

@@ -101,6 +101,9 @@ class SantaDecisionManager : public OSObject {
/// Clears the cache.
void ClearCache();
/// Sets the logging filter bitmask.
void SetFileopLoggingFilter(uint32_t filter);
/// Increments the count of active callbacks pending.
void IncrementListenerInvocations();
@@ -267,6 +270,8 @@ class SantaDecisionManager : public OSObject {
kauth_listener_t fileop_listener_;
struct timespec ts_;
uint32_t fileop_log_filter_ = kFilterLogAll;
};
/**

View File

@@ -180,6 +180,18 @@ IOReturn SantaDriverClient::check_cache(
return kIOReturnSuccess;
}
IOReturn SantaDriverClient::set_fileop_logging_filter(
OSObject *target, void *reference, IOExternalMethodArguments *arguments) {
SantaDriverClient *me = OSDynamicCast(SantaDriverClient, target);
if (!me) return kIOReturnBadArgument;
uint32_t input = (uint32_t)*arguments->scalarInput;
me->decisionManager->SetFileopLoggingFilter(input);
return kIOReturnSuccess;
}
#pragma mark Method Resolution
IOReturn SantaDriverClient::externalMethod(
@@ -197,7 +209,8 @@ IOReturn SantaDriverClient::externalMethod(
{ &SantaDriverClient::deny_binary, 1, 0, 0, 0 },
{ &SantaDriverClient::clear_cache, 0, 0, 0, 0 },
{ &SantaDriverClient::cache_count, 0, 0, 1, 0 },
{ &SantaDriverClient::check_cache, 1, 0, 1, 0 }
{ &SantaDriverClient::check_cache, 1, 0, 1, 0 },
{ &SantaDriverClient::set_fileop_logging_filter, 1, 0, 0, 0 }
};
if (selector > static_cast<UInt32>(kSantaUserClientNMethods)) {

View File

@@ -100,6 +100,10 @@ class com_google_SantaDriverClient : public IOUserClient {
static IOReturn check_cache(
OSObject *target, void *reference, IOExternalMethodArguments *arguments);
/// The daemon calls this to enable or disable portions of the fileop logging.
static IOReturn set_fileop_logging_filter(
OSObject *target, void *reference, IOExternalMethodArguments *arguments);
private:
com_google_SantaDriver *myProvider;
SantaDecisionManager *decisionManager;

View File

@@ -0,0 +1,115 @@
/// Copyright 2017 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 "SNTCommandController.h"
#import "SNTKernelCommon.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
@interface SNTCommandLog : NSObject<SNTCommand>
@end
@implementation SNTCommandLog
REGISTER_COMMAND_NAME(@"log")
+ (BOOL)requiresRoot {
return YES;
}
+ (BOOL)requiresDaemonConn {
return YES;
}
+ (NSString *)shortHelpText {
return @"Sets log types";
}
+ (NSString *)longHelpText {
return (@"Usage: santactl log [options]\n"
@" One of:\n"
@" --enable: [all, write, rename, exchange, link, delete]\n"
@" --disable: [all, write, rename, exchange, link, delete]\n");
}
+ (void)printErrorUsageAndExit:(NSString *)error {
printf("%s\n\n", [error UTF8String]);
printf("%s\n", [[self longHelpText] UTF8String]);
exit(1);
}
+ (void)runWithArguments:(NSArray *)arguments daemonConnection:(SNTXPCConnection *)daemonConn {
NSArray *flags;
BOOL enable = NO;
// Parse arguments
for (NSUInteger i = 0; i < arguments.count; ++i) {
NSString *arg = arguments[i];
if ([arg caseInsensitiveCompare:@"--enable"] == NSOrderedSame) {
if (++i > arguments.count - 1) {
[self printErrorUsageAndExit:@"--enable requires an argument"];
}
enable = YES;
flags = [arguments subarrayWithRange:NSMakeRange(i, arguments.count - 1)];
break;
} else if ([arg caseInsensitiveCompare:@"--disable"] == NSOrderedSame) {
if (++i > arguments.count - 1) {
[self printErrorUsageAndExit:@"--disable requires an argument"];
}
flags = [arguments subarrayWithRange:NSMakeRange(i, arguments.count - 1)];
break;
} else {
[self printErrorUsageAndExit:[@"Unknown argument: " stringByAppendingString:arg]];
}
}
NSDictionary *flagMap = @{
@"all" : @(kFilterLogAll),
@"write" : @(kFileopLogWrite),
@"rename" : @(kFileopLogRename),
@"exchange" : @(kFileopLogExchange),
@"link" : @(kFileopLogLink),
@"delete" : @(kFileopLogDelete)
};
fileop_log_filter_t filter = enable ? kFilterLogNone : kFilterLogAll;
for (NSString *f in flags) {
if (![flagMap.allKeys containsObject:f]) {
[self printErrorUsageAndExit:[NSString stringWithFormat:@"Invalid flag: %@", f]];
}
if ([f isEqualToString:@"all"] && flags.count > 1) {
[self printErrorUsageAndExit:@"Use all by itself"];
}
if (enable) {
filter |= [flagMap[f] unsignedIntValue];
} else {
filter ^= [flagMap[f] unsignedIntValue];
}
}
[[daemonConn remoteObjectProxy] setFileopLoggingFilter:filter withReply:^{
printf("Success, set filter to: 0x%08x Enabled log types: ", filter);
for (NSString *f in flagMap.allKeys) {
if (filter & [flagMap[f] unsignedIntValue] && ![f isEqualToString:@"all"]) {
printf("%s ", f.UTF8String);
}
}
printf("\n");
exit(0);
}];
}
@end

View File

@@ -66,6 +66,11 @@ double watchdogRAMPeak = 0;
reply([self.driverManager checkCache:vnodeID]);
}
- (void)setFileopLoggingFilter:(fileop_log_filter_t)filter withReply:(void (^)())reply {
[self.driverManager setFileopLoggingFilter:filter];
reply();
}
#pragma mark Database ops
- (void)databaseRuleCounts:(void (^)(int64_t binary, int64_t certificate))reply {

View File

@@ -60,6 +60,11 @@
///
/// Check the kernel cache for a VnodeID
///
-(santa_action_t)checkCache:(uint64_t)vnodeID;
- (santa_action_t)checkCache:(uint64_t)vnodeID;
///
/// Sets the type of logs to filter before the driver sends them to the daemon.
///
- (void)setFileopLoggingFilter:(fileop_log_filter_t)filter;
@end

View File

@@ -198,4 +198,9 @@ static const int MAX_DELAY = 15;
return (santa_action_t)vnode_action;
}
- (void)setFileopLoggingFilter:(fileop_log_filter_t)filter {
uint64_t f = (uint64_t)filter;
IOConnectCallScalarMethod(_connection, kSantaUserClientSetFileopLoggingFilter, &f, 1, 0, 0);
}
@end