Compare commits

...

5 Commits

Author SHA1 Message Date
Tom Burgin
6a6a32c1cf santactl: Update to MOLFCMClient v1.7 (#245) 2018-03-13 13:07:44 -04:00
Tom Burgin
ce03611b52 santabs: Serialize calls to -[SNTBundleService createConnection] (#244) 2018-03-12 17:04:53 -04:00
Tom Burgin
bbe9f83878 Import fixes (#243)
* All: use common import style for cocoapods <PodName/PodName.h>

* All: Update Pods
2018-03-12 16:02:55 -04:00
Tom Burgin
40e6c6aa92 sync-state: perform sync-state operations on a serial q (#242)
* sync-state serial

* delete it
2018-03-07 17:35:02 -05:00
Tom Burgin
9f6ccf092a code cleanup (#241) 2018-02-26 10:51:44 -05:00
19 changed files with 180 additions and 465 deletions

View File

@@ -1,15 +1,15 @@
PODS:
- FMDB (2.6.2):
- FMDB/standard (= 2.6.2)
- FMDB/standard (2.6.2)
- MOLAuthenticatingURLSession (2.2):
- MOLCertificate (~> 1.5)
- MOLCertificate (1.7)
- MOLCodesignChecker (1.8):
- MOLCertificate (~> 1.7)
- MOLFCMClient (1.5):
- MOLAuthenticatingURLSession (~> 2.1)
- OCMock (3.4)
- FMDB (2.7.2):
- FMDB/standard (= 2.7.2)
- FMDB/standard (2.7.2)
- MOLAuthenticatingURLSession (2.4):
- MOLCertificate (~> 1.8)
- MOLCertificate (1.8)
- MOLCodesignChecker (1.9):
- MOLCertificate (~> 1.8)
- MOLFCMClient (1.7):
- MOLAuthenticatingURLSession (~> 2.4)
- OCMock (3.4.1)
DEPENDENCIES:
- FMDB
@@ -20,12 +20,12 @@ DEPENDENCIES:
- OCMock
SPEC CHECKSUMS:
FMDB: 854a0341b4726e53276f2a8996f06f1b80f9259a
MOLAuthenticatingURLSession: 5a5e31eb73248c3e92c79b9a285f031194e8404c
MOLCertificate: 1cdb264405631b4bbdcf4cde7627469290cf1187
MOLCodesignChecker: 93460b82eb41b671c1c8eff9fc904d0d3d149e16
MOLFCMClient: 88debb79f8c0454c3dd4f6514c2453e57a963c08
OCMock: 35ae71d6a8fcc1b59434d561d1520b9dd4f15765
FMDB: 6198a90e7b6900cfc046e6bc0ef6ebb7be9236aa
MOLAuthenticatingURLSession: c238aa1c9a7b1077eb39a6f40204bfe76a7d204e
MOLCertificate: c999513316d511c69f290fbf313dfe8dca4ad592
MOLCodesignChecker: 303c01755646a0045c97f9f0b0fe5945ead42130
MOLFCMClient: ee45348909351f232e2759c580329072ae7e02d4
OCMock: 2cd0716969bab32a2283ff3a46fd26a8c8b4c5e3
PODFILE CHECKSUM: acd378b3727c923d912e09812da344f7375c14fe

View File

@@ -148,9 +148,6 @@
0DEA5F7B1CF64C9200704398 /* sync_ruledownload_batch2.json in Resources */ = {isa = PBXBuildFile; fileRef = 0DEA5F781CF64C8B00704398 /* sync_ruledownload_batch2.json */; };
0DEA5F7D1CF64EB600704398 /* SNTCommandSyncRuleDownload.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D0A1EC2191998C900B8450F /* SNTCommandSyncRuleDownload.m */; };
0DEFB7C01ACB28B000B92AAE /* SNTCommandSyncConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEFB7BF1ACB28B000B92AAE /* SNTCommandSyncConstants.m */; };
0DEFB7C41ACDD80100B92AAE /* SNTFileWatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEFB7C31ACDD80100B92AAE /* SNTFileWatcher.m */; };
0DEFB7C61ACDE5F600B92AAE /* SNTFileWatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEFB7C31ACDD80100B92AAE /* SNTFileWatcher.m */; };
0DEFB7C81ACF0BFE00B92AAE /* SNTFileWatcherTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEFB7C71ACF0BFE00B92AAE /* SNTFileWatcherTest.m */; };
0DF395641AB76A7900CBC520 /* NSData+Zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DF395631AB76A7900CBC520 /* NSData+Zlib.m */; };
0DF395661AB76ABC00CBC520 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0DF395651AB76ABC00CBC520 /* libz.dylib */; };
168A4E09A2A5E0B7DF8A2F1A /* libPods-santad.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C11A10A5D6E112788769CF70 /* libPods-santad.a */; };
@@ -171,8 +168,6 @@
C76614EC1D142D3C00D150C1 /* SNTCommandCheckCache.m in Sources */ = {isa = PBXBuildFile; fileRef = C76614EB1D142D3C00D150C1 /* SNTCommandCheckCache.m */; };
C776A1071DEE160500A56616 /* SNTCommandSyncManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C776A1061DEE160500A56616 /* SNTCommandSyncManager.m */; };
C78227631E1C3C7D006EB2D6 /* santabs.xpc in CopyFiles */ = {isa = PBXBuildFile; fileRef = C78227541E1C3C58006EB2D6 /* santabs.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
C7943FE92028B855008D4F76 /* SNTFileWatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEFB7C31ACDD80100B92AAE /* SNTFileWatcher.m */; };
C7943FEA2028C4F7008D4F76 /* SNTFileWatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEFB7C31ACDD80100B92AAE /* SNTFileWatcher.m */; };
C795ED901D80A5BE007CFF42 /* SNTPolicyProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = C795ED8F1D80A5BE007CFF42 /* SNTPolicyProcessor.m */; };
C795ED911D80B66B007CFF42 /* SNTPolicyProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = C795ED8F1D80A5BE007CFF42 /* SNTPolicyProcessor.m */; };
C79A23581E23F7E80037AFA8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C79A23561E23F7E80037AFA8 /* main.m */; };
@@ -416,9 +411,6 @@
0DEA5F781CF64C8B00704398 /* sync_ruledownload_batch2.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = sync_ruledownload_batch2.json; sourceTree = "<group>"; };
0DEFB7BF1ACB28B000B92AAE /* SNTCommandSyncConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandSyncConstants.m; sourceTree = "<group>"; };
0DEFB7C11ACB28BC00B92AAE /* SNTCommandSyncConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SNTCommandSyncConstants.h; sourceTree = "<group>"; };
0DEFB7C21ACDD80100B92AAE /* SNTFileWatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTFileWatcher.h; sourceTree = "<group>"; };
0DEFB7C31ACDD80100B92AAE /* SNTFileWatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTFileWatcher.m; sourceTree = "<group>"; };
0DEFB7C71ACF0BFE00B92AAE /* SNTFileWatcherTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTFileWatcherTest.m; sourceTree = "<group>"; };
0DF395621AB76A7900CBC520 /* NSData+Zlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Zlib.h"; sourceTree = "<group>"; };
0DF395631AB76A7900CBC520 /* NSData+Zlib.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Zlib.m"; sourceTree = "<group>"; };
0DF395651AB76ABC00CBC520 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
@@ -540,7 +532,6 @@
0D41DAD31A7C28C800A890FE /* SNTEventTableTest.m */,
0DD0D490194F9947005F27EB /* SNTExecutionControllerTest.m */,
0DD0D48E194F78F8005F27EB /* SNTFileInfoTest.m */,
0DEFB7C71ACF0BFE00B92AAE /* SNTFileWatcherTest.m */,
0DB537861AFD36EB00487F92 /* SNTRuleTableTest.m */,
0D3AFBE618FB32CB0087BCEE /* SNTXPCConnectionTest.m */,
);
@@ -733,8 +724,6 @@
0D10BE851A0AABD600C0C944 /* SNTDropRootPrivs.m */,
0DCD6040190ACCB8006B445C /* SNTFileInfo.h */,
0DCD6041190ACCB8006B445C /* SNTFileInfo.m */,
0DEFB7C21ACDD80100B92AAE /* SNTFileWatcher.h */,
0DEFB7C31ACDD80100B92AAE /* SNTFileWatcher.m */,
0D28E5E31926AFE400280F87 /* SNTKernelCommon.h */,
0D28E5E119269B3600280F87 /* SNTLogging.h */,
0DA73C9E1934F8100056D7C4 /* SNTLogging.m */,
@@ -1466,10 +1455,8 @@
0DCD605819115E57006B445C /* SNTXPCControlInterface.m in Sources */,
0D202D1A1CDD464B00A88F16 /* SNTCommandSyncPreflight.m in Sources */,
0D10BE891A0AAF6700C0C944 /* SNTDropRootPrivs.m in Sources */,
0DEFB7C61ACDE5F600B92AAE /* SNTFileWatcher.m in Sources */,
C795ED911D80B66B007CFF42 /* SNTPolicyProcessor.m in Sources */,
C72E8D941D7F399900C86DD3 /* SNTCommandFileInfoTest.m in Sources */,
0DEFB7C81ACF0BFE00B92AAE /* SNTFileWatcherTest.m in Sources */,
0D28D53819D9F5910015C5EB /* SNTConfigurator.m in Sources */,
0DE5B54C1C92722300C00603 /* SNTNotificationQueue.m in Sources */,
0DEA5F651CF6057D00704398 /* SNTCommandSyncEventUpload.m in Sources */,
@@ -1516,7 +1503,6 @@
C76614EC1D142D3C00D150C1 /* SNTCommandCheckCache.m in Sources */,
0D416401191974F1006A356A /* SNTCommandSyncState.m in Sources */,
0DC5D871192160180078A5C0 /* SNTCommandSyncLogUpload.m in Sources */,
C7943FE92028B855008D4F76 /* SNTFileWatcher.m in Sources */,
0DB77FDA1CD14092004DF060 /* SNTBlockMessage.m in Sources */,
0D35BDA218FD71CE00921A21 /* main.m in Sources */,
0DCD6043190ACCB8006B445C /* SNTFileInfo.m in Sources */,
@@ -1535,7 +1521,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C7943FEA2028C4F7008D4F76 /* SNTFileWatcher.m in Sources */,
0DCA552718C95928002A7DAE /* SNTXPCConnection.m in Sources */,
0D385DF1180DE51600418BC6 /* SNTAppDelegate.m in Sources */,
0D88680A1AC48A1200B86659 /* SNTSystemInfo.m in Sources */,
@@ -1583,7 +1568,6 @@
0DE71A751B95F7F900518526 /* SNTCachedDecision.m in Sources */,
C7FB56F61DBFB480004E14EF /* SNTXPCSyncdInterface.m in Sources */,
0DCD6042190ACCB8006B445C /* SNTFileInfo.m in Sources */,
0DEFB7C41ACDD80100B92AAE /* SNTFileWatcher.m in Sources */,
0DC5D86D191AED220078A5C0 /* SNTRuleTable.m in Sources */,
0D7D01871774F93A005DBAB4 /* SNTDriverManager.m in Sources */,
0D8E18CD19107B56000F89B8 /* SNTDaemonControlController.m in Sources */,

View File

@@ -16,10 +16,10 @@
@import SecurityInterface.SFCertificatePanel;
#import "MOLCertificate.h"
#import <MOLCertificate/MOLCertificate.h>
#import "SNTBlockMessage.h"
#import "SNTConfigurator.h"
#import "SNTFileInfo.h"
#import "SNTMessageWindow.h"
#import "SNTStoredEvent.h"

View File

@@ -16,7 +16,6 @@
#include <sys/stat.h>
#import "SNTFileWatcher.h"
#import "SNTLogging.h"
#import "SNTStrengthify.h"
#import "SNTSystemInfo.h"
@@ -32,9 +31,6 @@
/// Holds the configurations from a sync server and mobileconfig.
@property NSMutableDictionary *syncState;
@property NSMutableDictionary *configState;
/// Watcher for the sync-state.plist.
@property(nonatomic) SNTFileWatcher *syncStateWatcher;
@end
@implementation SNTConfigurator
@@ -86,40 +82,45 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
- (instancetype)init {
self = [super init];
if (self) {
Class number = [NSNumber class];
Class re = [NSRegularExpression class];
Class date = [NSDate class];
Class string = [NSString class];
Class data = [NSData class];
_syncServerKeyTypes = @{
kClientModeKey : [NSNumber class],
kWhitelistRegexKey : [NSRegularExpression class],
kBlacklistRegexKey : [NSRegularExpression class],
kFullSyncLastSuccess : [NSDate class],
kRuleSyncLastSuccess : [NSDate class],
kSyncCleanRequired : [NSNumber class]
kClientModeKey : number,
kWhitelistRegexKey : re,
kBlacklistRegexKey : re,
kFullSyncLastSuccess : date,
kRuleSyncLastSuccess : date,
kSyncCleanRequired : number
};
_forcedConfigKeyTypes = @{
kClientModeKey : [NSNumber class],
kFileChangesRegexKey : [NSRegularExpression class],
kWhitelistRegexKey : [NSRegularExpression class],
kBlacklistRegexKey : [NSRegularExpression class],
kEnablePageZeroProtectionKey : [NSNumber class],
kMoreInfoURLKey : [NSString class],
kEventDetailURLKey : [NSString class],
kEventDetailTextKey : [NSString class],
kUnknownBlockMessage : [NSString class],
kBannedBlockMessage : [NSString class],
kModeNotificationMonitor : [NSString class],
kModeNotificationLockdown : [NSString class],
kSyncBaseURLKey : [NSString class],
kClientAuthCertificateFileKey : [NSString class],
kClientAuthCertificatePasswordKey : [NSString class],
kClientAuthCertificateCNKey : [NSString class],
kClientAuthCertificateIssuerKey : [NSString class],
kServerAuthRootsDataKey : [NSData class],
kServerAuthRootsFileKey : [NSString class],
kMachineOwnerKey : [NSString class],
kMachineIDKey : [NSString class],
kMachineOwnerPlistFileKey : [NSString class],
kMachineOwnerPlistKeyKey : [NSString class],
kMachineIDPlistFileKey : [NSString class],
kMachineIDPlistKeyKey : [NSString class],
kClientModeKey : number,
kFileChangesRegexKey : re,
kWhitelistRegexKey : re,
kBlacklistRegexKey : re,
kEnablePageZeroProtectionKey : number,
kMoreInfoURLKey : string,
kEventDetailURLKey : string,
kEventDetailTextKey : string,
kUnknownBlockMessage : string,
kBannedBlockMessage : string,
kModeNotificationMonitor : string,
kModeNotificationLockdown : string,
kSyncBaseURLKey : string,
kClientAuthCertificateFileKey : string,
kClientAuthCertificatePasswordKey : string,
kClientAuthCertificateCNKey : string,
kClientAuthCertificateIssuerKey : string,
kServerAuthRootsDataKey : data,
kServerAuthRootsFileKey : string,
kMachineOwnerKey : string,
kMachineIDKey : string,
kMachineOwnerPlistFileKey : string,
kMachineOwnerPlistKeyKey : string,
kMachineIDPlistFileKey : string,
kMachineIDPlistKeyKey : string,
};
_defaults = [NSUserDefaults standardUserDefaults];
[_defaults addSuiteNamed:@"com.google.santa"];
@@ -141,94 +142,129 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
return sharedConfigurator;
}
+ (NSSet *)syncAndConfigStateSet {
static NSSet *set;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
set = [[self syncStateSet] setByAddingObjectsFromSet:[self configStateSet]];
});
return set;
}
+ (NSSet *)syncStateSet {
static NSSet *set;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
set = [NSSet setWithObject:NSStringFromSelector(@selector(syncState))];
});
return set;
}
+ (NSSet *)configStateSet {
static NSSet *set;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
set = [NSSet setWithObject:NSStringFromSelector(@selector(configState))];
});
return set;
}
#pragma mark KVO Dependencies
+ (NSSet *)keyPathsForValuesAffectingClientMode {
return [NSSet setWithObjects:@"syncState", @"configState", nil];
return [self syncAndConfigStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingWhitelistPathRegex {
return [NSSet setWithObjects:@"syncState", @"configState", nil];
return [self syncAndConfigStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingBlacklistPathRegex {
return [NSSet setWithObjects:@"syncState", @"configState", nil];
return [self syncAndConfigStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingFileChangesRegex {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingSyncBaseURL {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingEnablePageZeroProtection {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingMoreInfoURL {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingEventDetailURL {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingEventDetailText {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingUnknownBlockMessage {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingBannedBlockMessage {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingModeNotificationMonitor {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingModeNotificationLockdown {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingSyncClientAuthCertificateFile {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingSyncClientAuthCertificatePassword {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingSyncClientAuthCertificateCn {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingSyncClientAuthCertificateIssuer {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingSyncServerAuthRootsData {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingSyncServerAuthRootsFile {
return [NSSet setWithObject:@"configState"];
}
+ (NSSet *)keyPathsForValuesAffectingFullSyncLastSuccess {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingMachineOwner {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingMachineID {
return [NSSet setWithObject:@"configState"];
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingFullSyncLastSuccess {
return [self syncStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingRuleSyncLastSuccess {
return [self syncStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingSyncCleanRequired {
return [self syncStateSet];
}
#pragma mark Public Interface
@@ -344,7 +380,7 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
}
- (void)setFullSyncLastSuccess:(NSDate *)fullSyncLastSuccess {
self.syncState[kFullSyncLastSuccess] = fullSyncLastSuccess;
[self updateSyncStateForKey:kFullSyncLastSuccess value:fullSyncLastSuccess];
self.ruleSyncLastSuccess = fullSyncLastSuccess;
}
@@ -353,8 +389,7 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
}
- (void)setRuleSyncLastSuccess:(NSDate *)ruleSyncLastSuccess {
self.syncState[kRuleSyncLastSuccess] = ruleSyncLastSuccess;
[self saveSyncStateToDisk];
[self updateSyncStateForKey:kRuleSyncLastSuccess value:ruleSyncLastSuccess];
}
- (BOOL)syncCleanRequired {
@@ -362,8 +397,7 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
}
- (void)setSyncCleanRequired:(BOOL)syncCleanRequired {
self.syncState[kSyncCleanRequired] = @(syncCleanRequired);
[self saveSyncStateToDisk];
[self updateSyncStateForKey:kSyncCleanRequired value:@(syncCleanRequired)];
}
- (NSString *)machineOwner {
@@ -400,12 +434,13 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
///
/// Update the syncState. Triggers a KVO event for all dependents.
///
- (BOOL)updateSyncStateForKey:(NSString *)key value:(id)value {
NSMutableDictionary *syncState = self.syncState.mutableCopy;
syncState[key] = value;
self.syncState = syncState;
[self saveSyncStateToDisk];
return YES;
- (void)updateSyncStateForKey:(NSString *)key value:(id)value {
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableDictionary *syncState = self.syncState.mutableCopy;
syncState[key] = value;
self.syncState = syncState;
[self saveSyncStateToDisk];
});
}
///
@@ -427,15 +462,6 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
continue;
}
}
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
WEAKIFY(self);
self.syncStateWatcher = [[SNTFileWatcher alloc] initWithFilePath:kSyncStateFilePath
handler:^(unsigned long data) {
STRONGIFY(self);
[self syncStateFileChanged:data];
}];
});
return syncState;
}
@@ -456,39 +482,6 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
ofItemAtPath:kSyncStateFilePath error:NULL];
}
///
/// Ensure permissions are 0644.
/// Revert any out-of-band changes.
///
- (void)syncStateFileChanged:(unsigned long)data {
if (data & DISPATCH_VNODE_ATTRIB) {
const char *cPath = [kSyncStateFilePath fileSystemRepresentation];
struct stat fileStat;
stat(cPath, &fileStat);
int mask = S_IRWXU | S_IRWXG | S_IRWXO;
int desired = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
if (fileStat.st_uid != 0 || fileStat.st_gid != 0 || (fileStat.st_mode & mask) != desired) {
LOGI(@"Sync state file permissions changed, fixing.");
chown(cPath, 0, 0);
chmod(cPath, desired);
}
} else {
NSDictionary *newSyncState = [self readSyncStateFromDisk];
for (NSString *key in self.syncState) {
if (((self.syncState[key] && !newSyncState[key]) ||
(!self.syncState[key] && newSyncState[key]) ||
(self.syncState[key] && ![self.syncState[key] isEqualTo:newSyncState[key]]))) {
// Ignore sync url and dates
if ([key isEqualToString:kRuleSyncLastSuccess] ||
[key isEqualToString:kFullSyncLastSuccess]) continue;
LOGE(@"Sync state file changed, replacing");
[self saveSyncStateToDisk];
return;
}
}
}
}
- (void)clearSyncState {
self.syncState = [NSMutableDictionary dictionary];
}

View File

@@ -1,35 +0,0 @@
/// Copyright 2015 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 Foundation;
///
/// Simple file watching class using dispatch sources. Will automatically
/// reload the watch if the file is deleted and continue watching for
/// events until deallocated.
///
@interface SNTFileWatcher : NSObject
///
/// Designated initializer
/// Initializes the watcher and begins watching for modifications.
///
/// @param filePath the file to watch.
/// @param handler the handler to call when changes happen. The argument to the block is the
/// type of change that happened as a bitmask to be compared with DISPATCH_VNODE_* constants.
///
- (nonnull instancetype)initWithFilePath:(nonnull NSString *)filePath
handler:(nonnull void (^)(unsigned long))handler;
@end

View File

@@ -1,94 +0,0 @@
/// Copyright 2015 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 "SNTFileWatcher.h"
#import "SNTStrengthify.h"
@interface SNTFileWatcher ()
@property NSString *filePath;
@property(copy) void (^handler)(unsigned long);
@property dispatch_source_t source;
@end
@implementation SNTFileWatcher
- (instancetype)init {
[self doesNotRecognizeSelector:_cmd];
return nil;
}
- (instancetype)initWithFilePath:(nonnull NSString *)filePath
handler:(nonnull void (^)(unsigned long))handler {
self = [super init];
if (self) {
_filePath = filePath;
_handler = handler;
[self startWatchingFile];
}
return self;
}
- (void)dealloc {
[self stopWatchingFile];
}
- (void)startWatchingFile {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
int mask = (DISPATCH_VNODE_DELETE | DISPATCH_VNODE_RENAME |
DISPATCH_VNODE_WRITE | DISPATCH_VNODE_EXTEND | DISPATCH_VNODE_ATTRIB);
dispatch_async(queue, ^{
int fd = -1;
const char *filePath = [self.filePath fileSystemRepresentation];
while ((fd = open(filePath, O_EVTONLY | O_CLOEXEC)) < 0) {
usleep(200000); // wait 200ms
}
self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fd, mask, queue);
WEAKIFY(self);
dispatch_source_set_event_handler(self.source, ^{
STRONGIFY(self);
unsigned long data = dispatch_source_get_data(self.source);
self.handler(data);
if (data & DISPATCH_VNODE_DELETE || data & DISPATCH_VNODE_RENAME) {
[self stopWatchingFile];
[self startWatchingFile];
}
sleep(2);
});
dispatch_source_set_registration_handler(self.source, ^{
STRONGIFY(self);
self.handler(0);
});
dispatch_source_set_cancel_handler(self.source, ^{
close(fd);
});
dispatch_resume(self.source);
});
}
- (void)stopWatchingFile {
if (!self.source) return;
dispatch_source_set_event_handler_f(self.source, NULL);
dispatch_source_cancel(self.source);
self.source = nil;
}
@end

View File

@@ -66,7 +66,7 @@ typedef enum {
ACTION_RESPOND_DENY = 21,
ACTION_RESPOND_TOOLONG = 22,
ACTION_RESPOND_ACK = 23,
// NOTIFY
ACTION_NOTIFY_EXEC = 30,
ACTION_NOTIFY_WRITE = 31,

View File

@@ -14,7 +14,7 @@
#import "SNTStoredEvent.h"
#import "MOLCertificate.h"
#import <MOLCertificate/MOLCertificate.h>
@implementation SNTStoredEvent

View File

@@ -14,7 +14,7 @@
#import "SNTXPCConnection.h"
#import "MOLCodesignChecker.h"
#import <MOLCodesignChecker/MOLCodesignChecker.h>
#import "SNTStrengthify.h"

View File

@@ -17,8 +17,8 @@
#import <CommonCrypto/CommonDigest.h>
#import <pthread/pthread.h>
#import "MOLCertificate.h"
#import "MOLCodesignChecker.h"
#import <MOLCodesignChecker/MOLCodesignChecker.h>
#import "SNTFileInfo.h"
#import "SNTStoredEvent.h"
#import "SNTXPCConnection.h"
@@ -72,18 +72,18 @@
}
- (void)attemptReconnection {
[self performSelectorInBackground:@selector(createConnection) withObject:nil];
[self performSelectorOnMainThread:@selector(createConnection) withObject:nil waitUntilDone:NO];
}
#pragma mark SNTBundleServiceXPC Methods
// Connect to the SantaGUI
- (void)setBundleNotificationListener:(NSXPCListenerEndpoint *)listener {
SNTXPCConnection *c = [[SNTXPCConnection alloc] initClientWithListener:listener];
c.remoteInterface = [SNTXPCNotifierInterface bundleNotifierInterface];
[c resume];
self.notifierConnection = c;
dispatch_async(self.queue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
SNTXPCConnection *c = [[SNTXPCConnection alloc] initClientWithListener:listener];
c.remoteInterface = [SNTXPCNotifierInterface bundleNotifierInterface];
[c resume];
self.notifierConnection = c;
[self createConnection];
});
}

View File

@@ -17,8 +17,9 @@
#import "SNTCommand.h"
#import "SNTCommandController.h"
#import "MOLCertificate.h"
#import "MOLCodesignChecker.h"
#import <MOLCertificate/MOLCertificate.h>
#import <MOLCodesignChecker/MOLCodesignChecker.h>
#import "SNTConfigurator.h"
#import "SNTDropRootPrivs.h"
#import "SNTFileInfo.h"

View File

@@ -14,7 +14,8 @@
#import "SNTEventTable.h"
#import "MOLCertificate.h"
#import <MOLCertificate/MOLCertificate.h>
#import "SNTStoredEvent.h"
@implementation SNTEventTable

View File

@@ -14,8 +14,9 @@
#import "SNTRuleTable.h"
#import "MOLCertificate.h"
#import "MOLCodesignChecker.h"
#import <MOLCertificate/MOLCertificate.h>
#import <MOLCodesignChecker/MOLCodesignChecker.h>
#import "SNTConfigurator.h"
#import "SNTLogging.h"
#import "SNTRule.h"

View File

@@ -80,22 +80,23 @@
// Listen for actionable config changes.
NSKeyValueObservingOptions bits = (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld);
[[SNTConfigurator configurator] addObserver:self
forKeyPath:@"clientMode"
options:bits
context:NULL];
[[SNTConfigurator configurator] addObserver:self
forKeyPath:@"syncBaseURL"
options:bits
context:NULL];
[[SNTConfigurator configurator] addObserver:self
forKeyPath:@"whitelistPathRegex"
options:bits
context:NULL];
[[SNTConfigurator configurator] addObserver:self
forKeyPath:@"blacklistPathRegex"
options:bits
context:NULL];
SNTConfigurator *configurator = [SNTConfigurator configurator];
[configurator addObserver:self
forKeyPath:NSStringFromSelector(@selector(clientMode))
options:bits
context:NULL];
[configurator addObserver:self
forKeyPath:NSStringFromSelector(@selector(syncBaseURL))
options:bits
context:NULL];
[configurator addObserver:self
forKeyPath:NSStringFromSelector(@selector(whitelistPathRegex))
options:bits
context:NULL];
[configurator addObserver:self
forKeyPath:NSStringFromSelector(@selector(blacklistPathRegex))
options:bits
context:NULL];
// Establish XPC listener for Santa and santactl connections
SNTDaemonControlController *dc =
@@ -270,23 +271,25 @@ void diskDisappearedCallback(DADiskRef disk, void *context) {
ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change
context:(void *)context {
if ([keyPath isEqualToString:@"clientMode"]) {
NSString *newKey = NSKeyValueChangeNewKey;
NSString *oldKey = NSKeyValueChangeOldKey;
if ([keyPath isEqualToString:NSStringFromSelector(@selector(clientMode))]) {
SNTClientMode new =
[change[@"new"] isKindOfClass:[NSNumber class]] ? [change[@"new"] longLongValue] : 0;
[change[newKey] isKindOfClass:[NSNumber class]] ? [change[newKey] longLongValue] : 0;
SNTClientMode old =
[change[@"old"] isKindOfClass:[NSNumber class]] ? [change[@"old"] longLongValue] : 0;
[change[oldKey] isKindOfClass:[NSNumber class]] ? [change[oldKey] longLongValue] : 0;
if (new != old) [self clientModeDidChange:new];
} else if ([keyPath isEqualToString:@"syncBaseURL"]) {
NSURL *new = [change[@"new"] isKindOfClass:[NSURL class]] ? change[@"new"] : nil;
NSURL *old = [change[@"old"] isKindOfClass:[NSURL class]] ? change[@"old"] : nil;
} else if ([keyPath isEqualToString:NSStringFromSelector(@selector(syncBaseURL))]) {
NSURL *new = [change[newKey] isKindOfClass:[NSURL class]] ? change[newKey] : nil;
NSURL *old = [change[oldKey] isKindOfClass:[NSURL class]] ? change[oldKey] : nil;
if (!new && !old) return;
if (![new.absoluteString isEqualToString:old.absoluteString]) [self syncBaseURLDidChange:new];
} else if ([keyPath isEqualToString:@"whitelistPathRegex"] ||
[keyPath isEqualToString:@"blacklistPathRegex"]) {
} else if ([keyPath isEqualToString:NSStringFromSelector(@selector(whitelistPathRegex))] ||
[keyPath isEqualToString:NSStringFromSelector(@selector(blacklistPathRegex))]) {
NSRegularExpression *new =
[change[@"new"] isKindOfClass:[NSRegularExpression class]] ? change[@"new"] : nil;
[change[newKey] isKindOfClass:[NSRegularExpression class]] ? change[newKey] : nil;
NSRegularExpression *old =
[change[@"old"] isKindOfClass:[NSRegularExpression class]] ? change[@"old"] : nil;
[change[oldKey] isKindOfClass:[NSRegularExpression class]] ? change[oldKey] : nil;
if (!new && !old) return;
if (![new.pattern isEqualToString:old.pattern]) {
LOGI(@"Changed [white|black]list regex, flushing cache");

View File

@@ -20,7 +20,8 @@
#include <pwd.h>
#include <sys/sysctl.h>
#import "MOLCertificate.h"
#import <MOLCertificate/MOLCertificate.h>
#import "SNTCachedDecision.h"
#import "SNTCommonEnums.h"
#import "SNTConfigurator.h"

View File

@@ -20,8 +20,8 @@
#include "SNTLogging.h"
#import "MOLCertificate.h"
#import "MOLCodesignChecker.h"
#import <MOLCodesignChecker/MOLCodesignChecker.h>
#import "SNTBlockMessage.h"
#import "SNTCachedDecision.h"
#import "SNTCommonEnums.h"

View File

@@ -17,7 +17,7 @@
#import "SNTCommonEnums.h"
#import "SNTKernelCommon.h"
#import <MOLCertificate.h>
#import <MOLCertificate/MOLCertificate.h>
@class SNTCachedDecision;
@class SNTFileInfo;

View File

@@ -133,7 +133,7 @@
///
- (NSString *)fileIsScopeWhitelisted:(SNTFileInfo *)fi {
if (!fi) return nil;
// Determine if file is within a whitelisted path
NSRegularExpression *re = [[SNTConfigurator configurator] whitelistPathRegex];
if ([re numberOfMatchesInString:fi.path options:0 range:NSMakeRange(0, fi.path.length)]) {
@@ -150,7 +150,7 @@
- (NSString *)fileIsScopeBlacklisted:(SNTFileInfo *)fi {
if (!fi) return nil;
NSRegularExpression *re = [[SNTConfigurator configurator] blacklistPathRegex];
if ([re numberOfMatchesInString:fi.path options:0 range:NSMakeRange(0, fi.path.length)]) {
return @"Blacklist Regex";

View File

@@ -1,140 +0,0 @@
/// Copyright 2015 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 XCTest;
#import "SNTFileWatcher.h"
@interface SNTFileWatcherTest : XCTestCase
@property NSFileManager *fm;
@property NSString *file;
@end
@implementation SNTFileWatcherTest
- (void)setUp {
[super setUp];
self.fm = [NSFileManager defaultManager];
self.file = [NSTemporaryDirectory() stringByAppendingString:@"SNTFileWatcherTest_File"];
[self createFile];
usleep(10000);
}
- (void)tearDown {
[self deleteFile];
usleep(10000);
[super tearDown];
}
- (void)createFile {
[self.fm createFileAtPath:self.file contents:nil attributes:nil];
}
- (void)deleteFile {
[self.fm removeItemAtPath:self.file error:NULL];
}
- (void)testPlainInit {
XCTAssertThrows([[SNTFileWatcher alloc] init]);
}
- (void)testInitFileExists {
__weak XCTestExpectation *exp = [self expectationWithDescription:@"Init: callback called"];
__unused SNTFileWatcher *sut = [[SNTFileWatcher alloc] initWithFilePath:self.file
handler:^(unsigned long data) {
[exp fulfill];
}];
[self waitForExpectationsWithTimeout:5.0 handler:nil];
}
- (void)testInitNewFile {
[self deleteFile];
__weak XCTestExpectation *exp = [self expectationWithDescription:@"Init: callback called"];
__unused SNTFileWatcher *sut = [[SNTFileWatcher alloc] initWithFilePath:self.file
handler:^(unsigned long data) {
[exp fulfill];
}];
[self createFile];
[self waitForExpectationsWithTimeout:5.0 handler:nil];
}
- (void)testFileChanged {
__block BOOL fulfilled = NO;
__weak XCTestExpectation *exp = [self expectationWithDescription:@"Changed: callback called"];
__unused SNTFileWatcher *sut = [[SNTFileWatcher alloc] initWithFilePath:self.file
handler:^(unsigned long data) {
NSString *d = [NSString stringWithContentsOfFile:self.file
encoding:NSUTF8StringEncoding
error:nil];
if (!fulfilled && [d isEqual:@"0x8BADF00D"]) {
fulfilled = YES;
[exp fulfill];
}
}];
sleep(1);
[[@"0x8BADF00D" dataUsingEncoding:NSUTF8StringEncoding] writeToFile:self.file atomically:NO];
[self waitForExpectationsWithTimeout:5.0 handler:nil];
}
- (void)testFileReplaced {
__block BOOL fulfilled = NO;
__weak XCTestExpectation *exp = [self expectationWithDescription:@"Replaced: callback called"];
__unused SNTFileWatcher *sut = [[SNTFileWatcher alloc] initWithFilePath:self.file
handler:^(unsigned long data) {
NSString *d = [NSString stringWithContentsOfFile:self.file
encoding:NSUTF8StringEncoding
error:nil];
if (!fulfilled && [d isEqual:@"0xFACEFEED"]) {
fulfilled = YES;
[exp fulfill];
}
}];
[[@"0xFACEFEED" dataUsingEncoding:NSUTF8StringEncoding] writeToFile:self.file atomically:YES];
[self waitForExpectationsWithTimeout:5.0 handler:nil];
}
- (void)testFileExtended {
int fd = open(self.file.fileSystemRepresentation, O_WRONLY);
write(fd, "0xDEAD", 6);
__block BOOL fulfilled = NO;
__weak XCTestExpectation *exp = [self expectationWithDescription:@"Extended: callback called"];
__unused SNTFileWatcher *sut = [[SNTFileWatcher alloc] initWithFilePath:self.file
handler:^(unsigned long data) {
int file = open(self.file.fileSystemRepresentation, O_RDONLY);
char fileData[10];
read(file, fileData, 10);
if (!fulfilled && strncmp(fileData, "0xDEADBEEF", 10) == 0) {
fulfilled = YES;
[exp fulfill];
}
}];
write(fd, "BEEF", 4);
close(fd);
[self waitForExpectationsWithTimeout:5.0 handler:nil];
}
@end