mirror of
https://github.com/google/santa.git
synced 2026-01-15 01:08:12 -05:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ee6531627 | ||
|
|
1cf8ee09e1 | ||
|
|
4a2cf9d722 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,3 +9,4 @@ Santa.xcodeproj/project.xcworkspace
|
||||
Santa.xcworkspace/xcuserdata
|
||||
Santa.xcworkspace/xcshareddata
|
||||
Source/DevelopmentTeam.xcconfig
|
||||
default.profraw
|
||||
|
||||
@@ -32,6 +32,7 @@ PACKAGE_VERSION:=$(shell curl -fs https://api.github.com/repos/google/santa/rele
|
||||
# | |-- com.google.santad.plist
|
||||
# | |-- com.google.santagui.plist
|
||||
# | +-- com.google.santa.asl.conf
|
||||
# | +-- com.google.santa.newsyslog.conf
|
||||
# +--dsym
|
||||
# |-- santa-driver.kext.dSYM
|
||||
# |-- Santa.app.dSYM
|
||||
@@ -44,6 +45,7 @@ PAYLOAD:=pack-Library-Extensions-santa-driver.kext \
|
||||
pack-Library-LaunchDaemons-com.google.santad.plist \
|
||||
pack-Library-LaunchAgents-com.google.santagui.plist \
|
||||
pack-etc-asl-com.google.santa.asl.conf \
|
||||
pack-etc-newsyslog.d-com.google.santa.newsyslog.conf \
|
||||
pack-script-preinstall \
|
||||
pack-script-postinstall
|
||||
|
||||
@@ -52,6 +54,7 @@ Santa.app: download
|
||||
com.google.santad.plist: download
|
||||
com.google.santagui.plist: download
|
||||
com.google.santa.asl.conf: download
|
||||
com.google.santa.newsyslog.conf: download
|
||||
|
||||
download:
|
||||
$(if $(PACKAGE_VERSION),, $(error GitHub API returned unexpected result. Wait a while and try again))
|
||||
@@ -65,6 +68,12 @@ pack-etc-asl-com.google.santa.asl.conf: com.google.santa.asl.conf l_private_etc
|
||||
@sudo chmod 755 ${WORK_D}/private/etc/asl
|
||||
@sudo install -m 644 -o root -g wheel com.google.santa.asl.conf ${WORK_D}/private/etc/asl
|
||||
|
||||
pack-etc-newsyslog.d-com.google.santa.newsyslog.conf: com.google.santa.newsyslog.conf l_private_etc
|
||||
@sudo mkdir -p ${WORK_D}/private/etc/newsyslog.d
|
||||
@sudo chown root:wheel ${WORK_D}/private/etc/newsyslog.d
|
||||
@sudo chmod 755 ${WORK_D}/private/etc/newsyslog.d
|
||||
@sudo install -m 644 -o root -g wheel com.google.santa.newsyslog.conf ${WORK_D}/private/etc/newsyslog.d
|
||||
|
||||
pack-Library-Extensions-santa-driver.kext: santa-driver.kext l_Library
|
||||
@sudo mkdir -p ${WORK_D}/Library/Extensions
|
||||
@sudo ${DITTO} --noqtn santa-driver.kext ${WORK_D}/Library/Extensions/santa-driver.kext
|
||||
@@ -79,6 +88,7 @@ myclean:
|
||||
@rm -rf santa-driver.kext
|
||||
@rm -f config.plist
|
||||
@rm -f com.google.santa.asl.conf
|
||||
@rm -f com.google.santa.newsyslog.conf
|
||||
@rm -f com.google.santad.plist
|
||||
@rm -f com.google.santagui.plist
|
||||
@rm -f install.sh
|
||||
|
||||
2
Conf/com.google.santa.newsyslog.conf
Normal file
2
Conf/com.google.santa.newsyslog.conf
Normal file
@@ -0,0 +1,2 @@
|
||||
# logfilename [owner:group] mode count size(KiB) when flags [/pid_file] # [sig_num]
|
||||
/var/db/santa/santa.log root:wheel 644 10 25000 * NZ
|
||||
@@ -42,6 +42,7 @@ mkdir -p /usr/local/bin
|
||||
/bin/cp ${SOURCE}/conf/com.google.santad.plist /Library/LaunchDaemons
|
||||
/bin/cp ${SOURCE}/conf/com.google.santagui.plist /Library/LaunchAgents
|
||||
/bin/cp ${SOURCE}/conf/com.google.santa.asl.conf /etc/asl/
|
||||
/bin/cp ${SOURCE}/conf/com.google.santa.newsyslog.conf /etc/newsyslog.d/
|
||||
|
||||
# Reload syslogd to pick up ASL configuration change.
|
||||
/usr/bin/killall -HUP syslogd
|
||||
|
||||
@@ -19,6 +19,7 @@ user=$(/usr/bin/stat -f '%u' /dev/console)
|
||||
/bin/rm -f /Library/LaunchAgents/com.google.santagui.plist
|
||||
/bin/rm -f /Library/LaunchDaemons/com.google.santad.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
|
||||
#uncomment to remove the config file and all databases, log files
|
||||
#/bin/rm -rf /var/db/santa
|
||||
|
||||
@@ -5,7 +5,7 @@ PODS:
|
||||
- MOLAuthenticatingURLSession (2.4):
|
||||
- MOLCertificate (~> 1.8)
|
||||
- MOLCertificate (1.8)
|
||||
- MOLCodesignChecker (1.9):
|
||||
- MOLCodesignChecker (1.10):
|
||||
- MOLCertificate (~> 1.8)
|
||||
- MOLFCMClient (1.7):
|
||||
- MOLAuthenticatingURLSession (~> 2.4)
|
||||
@@ -23,7 +23,7 @@ SPEC CHECKSUMS:
|
||||
FMDB: 6198a90e7b6900cfc046e6bc0ef6ebb7be9236aa
|
||||
MOLAuthenticatingURLSession: c238aa1c9a7b1077eb39a6f40204bfe76a7d204e
|
||||
MOLCertificate: c999513316d511c69f290fbf313dfe8dca4ad592
|
||||
MOLCodesignChecker: 303c01755646a0045c97f9f0b0fe5945ead42130
|
||||
MOLCodesignChecker: b0d5db9d2f9bd94e0fd093891a5d40e5ad77cbc0
|
||||
MOLFCMClient: ee45348909351f232e2759c580329072ae7e02d4
|
||||
OCMock: 2cd0716969bab32a2283ff3a46fd26a8c8b4c5e3
|
||||
|
||||
|
||||
1
Rakefile
1
Rakefile
@@ -106,6 +106,7 @@ namespace :install do
|
||||
system 'sudo cp conf/com.google.santad.plist /Library/LaunchDaemons'
|
||||
system 'sudo cp conf/com.google.santagui.plist /Library/LaunchAgents'
|
||||
system 'sudo cp conf/com.google.santa.asl.conf /etc/asl'
|
||||
system 'sudo cp conf/com.google.santa.newsyslog.conf /etc/newsyslog.d/'
|
||||
system '/usr/bin/killall -HUP syslogd'
|
||||
Rake::Task['build:build'].invoke(config)
|
||||
puts "Installing with configuration: #{config}"
|
||||
|
||||
@@ -72,8 +72,6 @@
|
||||
0D4644C6182AF81700098690 /* SantaDecisionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D4644C4182AF81700098690 /* SantaDecisionManager.h */; };
|
||||
0D536ED71B8E7A2E0039A26D /* bad_pagezero in Resources */ = {isa = PBXBuildFile; fileRef = 0D536ED51B8E7A2E0039A26D /* bad_pagezero */; };
|
||||
0D536ED81B8E7A2E0039A26D /* missing_pagezero in Resources */ = {isa = PBXBuildFile; fileRef = 0D536ED61B8E7A2E0039A26D /* missing_pagezero */; };
|
||||
0D536EDB1B94E9230039A26D /* SNTEventLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D536EDA1B94E9230039A26D /* SNTEventLog.m */; };
|
||||
0D536EDC1B94E9230039A26D /* SNTEventLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D536EDA1B94E9230039A26D /* SNTEventLog.m */; };
|
||||
0D63DD5C1906FCB400D346C4 /* SNTDatabaseController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D63DD5B1906FCB400D346C4 /* SNTDatabaseController.m */; };
|
||||
0D63DD5E1906FCB400D346C4 /* SNTDatabaseController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D63DD5B1906FCB400D346C4 /* SNTDatabaseController.m */; };
|
||||
0D668E8118D1121700E29A8B /* SNTMessageWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D668E8018D1121700E29A8B /* SNTMessageWindow.m */; };
|
||||
@@ -164,6 +162,12 @@
|
||||
C7479F051E53704E0054C1CF /* SNTXPCBundleServiceInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = C7C721B01E23FF300051FAA6 /* SNTXPCBundleServiceInterface.m */; };
|
||||
C7479F071E5374BF0054C1CF /* SNTXPCControlInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD605419115D17006B445C /* SNTXPCControlInterface.m */; };
|
||||
C7479F091E5374E50054C1CF /* SNTRule.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DE50F671912716A007B2B0C /* SNTRule.m */; };
|
||||
C748E8A3206964E1006CFD1B /* SNTEventLog.m in Sources */ = {isa = PBXBuildFile; fileRef = C748E8A2206964DE006CFD1B /* SNTEventLog.m */; };
|
||||
C748E8A4206964EE006CFD1B /* SNTEventLog.m in Sources */ = {isa = PBXBuildFile; fileRef = C748E8A2206964DE006CFD1B /* SNTEventLog.m */; };
|
||||
C748E8A720696595006CFD1B /* SNTFileEventLog.m in Sources */ = {isa = PBXBuildFile; fileRef = C748E8A620696595006CFD1B /* SNTFileEventLog.m */; };
|
||||
C748E8A820696595006CFD1B /* SNTFileEventLog.m in Sources */ = {isa = PBXBuildFile; fileRef = C748E8A620696595006CFD1B /* SNTFileEventLog.m */; };
|
||||
C748E8B020697F01006CFD1B /* SNTSyslogEventLog.m in Sources */ = {isa = PBXBuildFile; fileRef = C748E8AF20697F01006CFD1B /* SNTSyslogEventLog.m */; };
|
||||
C748E8B120697F01006CFD1B /* SNTSyslogEventLog.m in Sources */ = {isa = PBXBuildFile; fileRef = C748E8AF20697F01006CFD1B /* SNTSyslogEventLog.m */; };
|
||||
C74D6CC61EEB3B9B00BB5A33 /* BundleExample.app in Resources */ = {isa = PBXBuildFile; fileRef = C74D6CC51EEB3B9B00BB5A33 /* BundleExample.app */; };
|
||||
C76614EC1D142D3C00D150C1 /* SNTCommandCheckCache.m in Sources */ = {isa = PBXBuildFile; fileRef = C76614EB1D142D3C00D150C1 /* SNTCommandCheckCache.m */; };
|
||||
C776A1071DEE160500A56616 /* SNTCommandSyncManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C776A1061DEE160500A56616 /* SNTCommandSyncManager.m */; };
|
||||
@@ -341,8 +345,6 @@
|
||||
0D5058CF1CB70123008784BA /* SNTStrengthify.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SNTStrengthify.h; sourceTree = "<group>"; };
|
||||
0D536ED51B8E7A2E0039A26D /* bad_pagezero */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = bad_pagezero; sourceTree = "<group>"; };
|
||||
0D536ED61B8E7A2E0039A26D /* missing_pagezero */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = missing_pagezero; sourceTree = "<group>"; };
|
||||
0D536ED91B94E9230039A26D /* SNTEventLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTEventLog.h; sourceTree = "<group>"; };
|
||||
0D536EDA1B94E9230039A26D /* SNTEventLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTEventLog.m; sourceTree = "<group>"; };
|
||||
0D63DD5A1906FCB400D346C4 /* SNTDatabaseController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTDatabaseController.h; sourceTree = "<group>"; };
|
||||
0D63DD5B1906FCB400D346C4 /* SNTDatabaseController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTDatabaseController.m; sourceTree = "<group>"; };
|
||||
0D668E7F18D1121700E29A8B /* SNTMessageWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTMessageWindow.h; sourceTree = "<group>"; };
|
||||
@@ -429,6 +431,12 @@
|
||||
A6A91785C40257CC156B4F05 /* Pods-Santa.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Santa.release.xcconfig"; path = "Pods/Target Support Files/Pods-Santa/Pods-Santa.release.xcconfig"; sourceTree = "<group>"; };
|
||||
C11A10A5D6E112788769CF70 /* libPods-santad.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-santad.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C72E8D931D7F399900C86DD3 /* SNTCommandFileInfoTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandFileInfoTest.m; sourceTree = "<group>"; };
|
||||
C748E8A1206964DE006CFD1B /* SNTEventLog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SNTEventLog.h; sourceTree = "<group>"; };
|
||||
C748E8A2206964DE006CFD1B /* SNTEventLog.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SNTEventLog.m; sourceTree = "<group>"; };
|
||||
C748E8A520696594006CFD1B /* SNTFileEventLog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SNTFileEventLog.h; sourceTree = "<group>"; };
|
||||
C748E8A620696595006CFD1B /* SNTFileEventLog.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SNTFileEventLog.m; sourceTree = "<group>"; };
|
||||
C748E8AE20697F01006CFD1B /* SNTSyslogEventLog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SNTSyslogEventLog.h; sourceTree = "<group>"; };
|
||||
C748E8AF20697F01006CFD1B /* SNTSyslogEventLog.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SNTSyslogEventLog.m; sourceTree = "<group>"; };
|
||||
C74D6CC51EEB3B9B00BB5A33 /* BundleExample.app */ = {isa = PBXFileReference; lastKnownFileType = wrapper.application; path = BundleExample.app; sourceTree = "<group>"; };
|
||||
C76614EB1D142D3C00D150C1 /* SNTCommandCheckCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandCheckCache.m; sourceTree = "<group>"; };
|
||||
C776A1051DEE160500A56616 /* SNTCommandSyncManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTCommandSyncManager.h; sourceTree = "<group>"; };
|
||||
@@ -752,6 +760,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0DA73CA519363C9F0056D7C4 /* DataLayer */,
|
||||
C748E8A020696001006CFD1B /* Logs */,
|
||||
0D9A7F411759330500035EB5 /* main.m */,
|
||||
0DB8ACBF185662DC00FEF9C7 /* SNTApplication.h */,
|
||||
0DB8ACC0185662DC00FEF9C7 /* SNTApplication.m */,
|
||||
@@ -765,8 +774,6 @@
|
||||
C795ED8F1D80A5BE007CFF42 /* SNTPolicyProcessor.m */,
|
||||
0D7D01851774F93A005DBAB4 /* SNTDriverManager.h */,
|
||||
0D7D01861774F93A005DBAB4 /* SNTDriverManager.m */,
|
||||
0D536ED91B94E9230039A26D /* SNTEventLog.h */,
|
||||
0D536EDA1B94E9230039A26D /* SNTEventLog.m */,
|
||||
0DE6788B1784A8C2007A9E52 /* SNTExecutionController.h */,
|
||||
0DE6788C1784A8C2007A9E52 /* SNTExecutionController.m */,
|
||||
0DE5B5491C926E3300C00603 /* SNTNotificationQueue.h */,
|
||||
@@ -840,6 +847,19 @@
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C748E8A020696001006CFD1B /* Logs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C748E8A1206964DE006CFD1B /* SNTEventLog.h */,
|
||||
C748E8A2206964DE006CFD1B /* SNTEventLog.m */,
|
||||
C748E8AE20697F01006CFD1B /* SNTSyslogEventLog.h */,
|
||||
C748E8AF20697F01006CFD1B /* SNTSyslogEventLog.m */,
|
||||
C748E8A520696594006CFD1B /* SNTFileEventLog.h */,
|
||||
C748E8A620696595006CFD1B /* SNTFileEventLog.m */,
|
||||
);
|
||||
path = Logs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C79A23541E23F7E80037AFA8 /* santabs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1437,8 +1457,9 @@
|
||||
C7DA62F71E241938009BDF2C /* SNTXPCBundleServiceInterface.m in Sources */,
|
||||
C714F8B11D8044D400700EDF /* SNTCommandFileInfo.m in Sources */,
|
||||
0D88680C1AC48A1400B86659 /* SNTSystemInfo.m in Sources */,
|
||||
0D536EDC1B94E9230039A26D /* SNTEventLog.m in Sources */,
|
||||
0DEA5F7D1CF64EB600704398 /* SNTCommandSyncRuleDownload.m in Sources */,
|
||||
C748E8A4206964EE006CFD1B /* SNTEventLog.m in Sources */,
|
||||
C748E8B120697F01006CFD1B /* SNTSyslogEventLog.m in Sources */,
|
||||
C73A4B9B1DC10758007B6789 /* SNTXPCSyncdInterface.m in Sources */,
|
||||
0DB77FDB1CD14093004DF060 /* SNTBlockMessage.m in Sources */,
|
||||
0D63DD5E1906FCB400D346C4 /* SNTDatabaseController.m in Sources */,
|
||||
@@ -1457,6 +1478,7 @@
|
||||
0D10BE891A0AAF6700C0C944 /* SNTDropRootPrivs.m in Sources */,
|
||||
C795ED911D80B66B007CFF42 /* SNTPolicyProcessor.m in Sources */,
|
||||
C72E8D941D7F399900C86DD3 /* SNTCommandFileInfoTest.m in Sources */,
|
||||
C748E8A820696595006CFD1B /* SNTFileEventLog.m in Sources */,
|
||||
0D28D53819D9F5910015C5EB /* SNTConfigurator.m in Sources */,
|
||||
0DE5B54C1C92722300C00603 /* SNTNotificationQueue.m in Sources */,
|
||||
0DEA5F651CF6057D00704398 /* SNTCommandSyncEventUpload.m in Sources */,
|
||||
@@ -1558,6 +1580,7 @@
|
||||
0D8868091AC48A1100B86659 /* SNTSystemInfo.m in Sources */,
|
||||
0DE6788D1784A8C2007A9E52 /* SNTExecutionController.m in Sources */,
|
||||
0D10BE861A0AABD600C0C944 /* SNTDropRootPrivs.m in Sources */,
|
||||
C748E8B020697F01006CFD1B /* SNTSyslogEventLog.m in Sources */,
|
||||
0D63DD5C1906FCB400D346C4 /* SNTDatabaseController.m in Sources */,
|
||||
0DCD604B19105433006B445C /* SNTStoredEvent.m in Sources */,
|
||||
C7FB57001DBFC213004E14EF /* SNTSyncdQueue.m in Sources */,
|
||||
@@ -1576,10 +1599,11 @@
|
||||
0DE50F681912716A007B2B0C /* SNTRule.m in Sources */,
|
||||
0DB77FD81CCE824A004DF060 /* SNTBlockMessage.m in Sources */,
|
||||
0D37C10F18F6029A0069BC61 /* SNTDatabaseTable.m in Sources */,
|
||||
C748E8A720696595006CFD1B /* SNTFileEventLog.m in Sources */,
|
||||
C748E8A3206964E1006CFD1B /* SNTEventLog.m in Sources */,
|
||||
0D42D2B819D2042900955F08 /* SNTConfigurator.m in Sources */,
|
||||
0DCD605519115D17006B445C /* SNTXPCControlInterface.m in Sources */,
|
||||
C795ED901D80A5BE007CFF42 /* SNTPolicyProcessor.m in Sources */,
|
||||
0D536EDB1B94E9230039A26D /* SNTEventLog.m in Sources */,
|
||||
0DCD604F19115A06006B445C /* SNTXPCNotifierInterface.m in Sources */,
|
||||
0DE5B54B1C926E3300C00603 /* SNTNotificationQueue.m in Sources */,
|
||||
);
|
||||
@@ -2026,6 +2050,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ENABLE_CODE_COVERAGE = NO;
|
||||
CLANG_ENABLE_MODULES = NO;
|
||||
CLANG_STATIC_ANALYZER_MODE = deep;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
@@ -2064,6 +2089,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ENABLE_CODE_COVERAGE = NO;
|
||||
CLANG_ENABLE_MODULES = NO;
|
||||
CLANG_STATIC_ANALYZER_MODE = deep;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
|
||||
@@ -80,6 +80,12 @@ typedef NS_ENUM(NSInteger, SNTBundleEventAction) {
|
||||
SNTBundleEventActionSendEvents,
|
||||
};
|
||||
|
||||
// Indicates where to store event logs.
|
||||
typedef NS_ENUM(NSInteger, SNTEventLogType) {
|
||||
SNTEventLogTypeSyslog,
|
||||
SNTEventLogTypeFilelog,
|
||||
};
|
||||
|
||||
static const char *kKextPath = "/Library/Extensions/santa-driver.kext";
|
||||
static const char *kSantaDPath = "/Library/Extensions/santa-driver.kext/Contents/MacOS/santad";
|
||||
static const char *kSantaCtlPath = "/Library/Extensions/santa-driver.kext/Contents/MacOS/santactl";
|
||||
|
||||
@@ -79,6 +79,25 @@
|
||||
///
|
||||
@property(readonly, nonatomic) BOOL enablePageZeroProtection;
|
||||
|
||||
///
|
||||
/// Defines how event logs are stored. Options are:
|
||||
/// SNTEventLogTypeSyslog: Sent to ASL or ULS (if built with the 10.12 SDK or later).
|
||||
/// SNTEventLogTypeFilelog: Sent to a file on disk. Use eventLogPath to specify a path.
|
||||
/// Defaults to SNTEventLogTypeFilelog.
|
||||
/// For mobileconfigs use EventLogType as the key and syslog or filelog strings as the value.
|
||||
///
|
||||
/// @note: This property is KVO compliant, but should only be read once at santad startup.
|
||||
///
|
||||
@property(readonly, nonatomic) SNTEventLogType eventLogType;
|
||||
|
||||
///
|
||||
/// If eventLogType is set to Filelog, eventLogPath will provide the path to save logs.
|
||||
/// Defaults to /var/db/santa/santa.log.
|
||||
///
|
||||
/// @note: This property is KVO compliant, but should only be read once at santad startup.
|
||||
///
|
||||
@property(readonly, nonatomic) NSString *eventLogPath;
|
||||
|
||||
#pragma mark - GUI Settings
|
||||
|
||||
///
|
||||
|
||||
@@ -69,6 +69,9 @@ static NSString *const kEnablePageZeroProtectionKey = @"EnablePageZeroProtection
|
||||
|
||||
static NSString *const kFileChangesRegexKey = @"FileChangesRegex";
|
||||
|
||||
static NSString *const kEventLogType = @"EventLogType";
|
||||
static NSString *const kEventLogPath = @"EventLogPath";
|
||||
|
||||
// The keys managed by a sync server or mobileconfig.
|
||||
static NSString *const kClientModeKey = @"ClientMode";
|
||||
static NSString *const kWhitelistRegexKey = @"WhitelistRegex";
|
||||
@@ -121,6 +124,8 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
|
||||
kMachineOwnerPlistKeyKey : string,
|
||||
kMachineIDPlistFileKey : string,
|
||||
kMachineIDPlistKeyKey : string,
|
||||
kEventLogType : string,
|
||||
kEventLogPath : string,
|
||||
};
|
||||
_defaults = [NSUserDefaults standardUserDefaults];
|
||||
[_defaults addSuiteNamed:@"com.google.santa"];
|
||||
@@ -267,6 +272,14 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
|
||||
return [self syncStateSet];
|
||||
}
|
||||
|
||||
+ (NSSet *)keyPathsForValuesAffectingEventLogType {
|
||||
return [self configStateSet];
|
||||
}
|
||||
|
||||
+ (NSSet *)keyPathsForValuesAffectingEventLogPath {
|
||||
return [self configStateSet];
|
||||
}
|
||||
|
||||
#pragma mark Public Interface
|
||||
|
||||
- (SNTClientMode)clientMode {
|
||||
@@ -429,6 +442,15 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
|
||||
return machineId.length ? machineId : [SNTSystemInfo hardwareUUID];
|
||||
}
|
||||
|
||||
- (SNTEventLogType)eventLogType {
|
||||
NSString *s = [self.configState[kEventLogType] lowercaseString];
|
||||
return [s isEqualToString:@"syslog"] ? SNTEventLogTypeSyslog : SNTEventLogTypeFilelog;
|
||||
}
|
||||
|
||||
- (NSString *)eventLogPath {
|
||||
return self.configState[kEventLogPath] ?: @"/var/db/santa/santa.log";
|
||||
}
|
||||
|
||||
#pragma mark Private
|
||||
|
||||
///
|
||||
|
||||
@@ -212,6 +212,11 @@
|
||||
///
|
||||
- (NSUInteger)fileSize;
|
||||
|
||||
///
|
||||
/// @return The underlying file handle.
|
||||
///
|
||||
@property(readonly) NSFileHandle *fileHandle;
|
||||
|
||||
///
|
||||
/// @return Returns an instance of MOLCodeSignChecker initialized with the file's binary path.
|
||||
/// Both the MOLCodesignChecker and any resulting NSError are cached and returned on subsequent
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
#import <MOLCodesignChecker/MOLCodesignChecker.h>
|
||||
|
||||
#include <mach-o/arch.h>
|
||||
#include <mach-o/loader.h>
|
||||
#include <mach-o/swap.h>
|
||||
#include <pwd.h>
|
||||
@@ -287,7 +288,8 @@ extern NSString *const NSURLQuarantinePropertiesKey WEAK_IMPORT_ATTRIBUTE;
|
||||
- (BOOL)isMissingPageZero {
|
||||
// This method only checks i386 arch because the kernel enforces this for other archs
|
||||
// See bsd/kern/mach_loader.c, search for enforce_hard_pagezero.
|
||||
MachHeaderWithOffset *x86Header = self.machHeaders[[self nameForCPUType:CPU_TYPE_X86]];
|
||||
MachHeaderWithOffset *x86Header = self.machHeaders[[self nameForCPUType:CPU_TYPE_X86
|
||||
cpuSubType:CPU_SUBTYPE_I386_ALL]];
|
||||
if (!x86Header) return NO;
|
||||
|
||||
struct mach_header *mh = (struct mach_header *)[x86Header.data bytes];
|
||||
@@ -443,7 +445,7 @@ extern NSString *const NSURLQuarantinePropertiesKey WEAK_IMPORT_ATTRIBUTE;
|
||||
if (machHeader) {
|
||||
struct mach_header *mh = (struct mach_header *)[machHeader bytes];
|
||||
MachHeaderWithOffset *mhwo = [[MachHeaderWithOffset alloc] initWithData:machHeader offset:0];
|
||||
machHeaders[[self nameForCPUType:mh->cputype]] = mhwo;
|
||||
machHeaders[[self nameForCPUType:mh->cputype cpuSubType:mh->cpusubtype]] = mhwo;
|
||||
} else {
|
||||
NSRange range = NSMakeRange(0, sizeof(struct fat_header));
|
||||
NSData *fatHeader = [self safeSubdataWithRange:range];
|
||||
@@ -459,11 +461,12 @@ extern NSString *const NSURLQuarantinePropertiesKey WEAK_IMPORT_ATTRIBUTE;
|
||||
int offset = OSSwapBigToHostInt32(fat_arch[i].offset);
|
||||
int size = OSSwapBigToHostInt32(fat_arch[i].size);
|
||||
int cputype = OSSwapBigToHostInt(fat_arch[i].cputype);
|
||||
int cpusubtype = OSSwapBigToHostInt(fat_arch[i].cpusubtype);
|
||||
|
||||
range = NSMakeRange(offset, size);
|
||||
NSData *machHeader = [self parseSingleMachHeader:[self safeSubdataWithRange:range]];
|
||||
if (machHeader) {
|
||||
NSString *key = [self nameForCPUType:cputype];
|
||||
NSString *key = [self nameForCPUType:cputype cpuSubType:cpusubtype];
|
||||
MachHeaderWithOffset *mhwo = [[MachHeaderWithOffset alloc] initWithData:machHeader
|
||||
offset:offset];
|
||||
machHeaders[key] = mhwo;
|
||||
@@ -647,20 +650,15 @@ extern NSString *const NSURLQuarantinePropertiesKey WEAK_IMPORT_ATTRIBUTE;
|
||||
///
|
||||
/// Return a human-readable string for a cpu_type_t.
|
||||
///
|
||||
- (NSString *)nameForCPUType:(cpu_type_t)cpuType {
|
||||
switch (cpuType) {
|
||||
case CPU_TYPE_X86:
|
||||
return @"i386";
|
||||
case CPU_TYPE_X86_64:
|
||||
return @"x86-64";
|
||||
case CPU_TYPE_POWERPC:
|
||||
return @"ppc";
|
||||
case CPU_TYPE_POWERPC64:
|
||||
return @"ppc64";
|
||||
default:
|
||||
return @"unknown";
|
||||
- (NSString *)nameForCPUType:(cpu_type_t)cpuType cpuSubType:(cpu_subtype_t)cpuSubType {
|
||||
const NXArchInfo *archInfo = NXGetArchInfoFromCpuType(cpuType, cpuSubType);
|
||||
NSString *arch;
|
||||
if (archInfo && archInfo->name) {
|
||||
arch = @(archInfo->name);
|
||||
} else {
|
||||
arch = [NSString stringWithFormat:@"%i:%i", cpuType, cpuSubType];
|
||||
}
|
||||
return nil;
|
||||
return arch;
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
@@ -29,12 +29,12 @@ void syslogClientDestructor(void *arg) {
|
||||
|
||||
void logMessage(LogLevel level, FILE *destination, NSString *format, ...) {
|
||||
static BOOL useSyslog = NO;
|
||||
static const char *binaryName;
|
||||
static NSString *binaryName;
|
||||
static dispatch_once_t pred;
|
||||
static pthread_key_t syslogKey = 0;
|
||||
|
||||
dispatch_once(&pred, ^{
|
||||
binaryName = [[[NSProcessInfo processInfo] processName] UTF8String];
|
||||
binaryName = [[NSProcessInfo processInfo] processName];
|
||||
|
||||
// If debug logging is enabled, the process must be restarted.
|
||||
if ([[[NSProcessInfo processInfo] arguments] containsObject:@"--debug"]) {
|
||||
@@ -76,7 +76,7 @@ void logMessage(LogLevel level, FILE *destination, NSString *format, ...) {
|
||||
break;
|
||||
case LOG_LEVEL_INFO:
|
||||
levelName = "I";
|
||||
syslogLevel = ASL_LEVEL_INFO;
|
||||
syslogLevel = ASL_LEVEL_NOTICE; // Maps to ULS Default
|
||||
break;
|
||||
case LOG_LEVEL_DEBUG:
|
||||
levelName = "D";
|
||||
@@ -84,7 +84,7 @@ void logMessage(LogLevel level, FILE *destination, NSString *format, ...) {
|
||||
break;
|
||||
}
|
||||
|
||||
asl_log(client, NULL, syslogLevel, "%s %s: %s", levelName, binaryName, [s UTF8String]);
|
||||
asl_log(client, NULL, syslogLevel, "%s %s: %s", levelName, binaryName.UTF8String, s.UTF8String);
|
||||
} else {
|
||||
[s appendString:@"\n"];
|
||||
size_t len = [s lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
@@ -42,6 +42,7 @@ static NSString *const kPageZero = @"Page Zero";
|
||||
static NSString *const kCodeSigned = @"Code-signed";
|
||||
static NSString *const kRule = @"Rule";
|
||||
static NSString *const kSigningChain = @"Signing Chain";
|
||||
static NSString *const kUniversalSigningChain = @"Universal Signing Chain";
|
||||
|
||||
// signing chain keys
|
||||
static NSString *const kCommonName = @"Common Name";
|
||||
@@ -115,6 +116,7 @@ typedef id (^SNTAttributeBlock)(SNTCommandFileInfo *, SNTFileInfo *);
|
||||
@property(readonly, copy, nonatomic) SNTAttributeBlock codeSigned;
|
||||
@property(readonly, copy, nonatomic) SNTAttributeBlock rule;
|
||||
@property(readonly, copy, nonatomic) SNTAttributeBlock signingChain;
|
||||
@property(readonly, copy, nonatomic) SNTAttributeBlock universalSigningChain;
|
||||
|
||||
// Mapping between property string keys and SNTAttributeBlocks
|
||||
@property(nonatomic) NSDictionary<NSString *, SNTAttributeBlock> *propertyMap;
|
||||
@@ -182,7 +184,7 @@ REGISTER_COMMAND_NAME(@"fileinfo")
|
||||
+ (NSArray<NSString *> *)fileInfoKeys {
|
||||
return @[ kPath, kSHA256, kSHA1, kBundleName, kBundleVersion, kBundleVersionStr,
|
||||
kDownloadReferrerURL, kDownloadURL, kDownloadTimestamp, kDownloadAgent,
|
||||
kType, kPageZero, kCodeSigned, kRule, kSigningChain ];
|
||||
kType, kPageZero, kCodeSigned, kRule, kSigningChain, kUniversalSigningChain ];
|
||||
}
|
||||
|
||||
+ (NSArray<NSString *> *)signingChainKeys {
|
||||
@@ -210,7 +212,8 @@ REGISTER_COMMAND_NAME(@"fileinfo")
|
||||
kPageZero : self.pageZero,
|
||||
kCodeSigned : self.codeSigned,
|
||||
kRule : self.rule,
|
||||
kSigningChain : self.signingChain };
|
||||
kSigningChain : self.signingChain,
|
||||
kUniversalSigningChain : self.universalSigningChain };
|
||||
|
||||
_printQueue = dispatch_queue_create("com.google.santactl.print_queue", DISPATCH_QUEUE_SERIAL);
|
||||
}
|
||||
@@ -325,6 +328,10 @@ REGISTER_COMMAND_NAME(@"fileinfo")
|
||||
return @"Yes, but failed requirement validation";
|
||||
case errSecCSInfoPlistFailed:
|
||||
return @"Yes, but can't validate as Info.plist is missing";
|
||||
case errSecCSSignatureInvalid:
|
||||
if ([error.domain isEqualToString:@"com.google.molcodesignchecker"]) {
|
||||
return @"Yes, but signing is not consistent for all architectures";
|
||||
}
|
||||
default: {
|
||||
return [NSString stringWithFormat:@"Yes, but failed to validate (%ld)", error.code];
|
||||
}
|
||||
@@ -418,6 +425,46 @@ REGISTER_COMMAND_NAME(@"fileinfo")
|
||||
};
|
||||
}
|
||||
|
||||
- (SNTAttributeBlock)universalSigningChain {
|
||||
return ^id (SNTCommandFileInfo *cmd, SNTFileInfo *fileInfo) {
|
||||
MOLCodesignChecker *csc = [fileInfo codesignCheckerWithError:NULL];
|
||||
if (csc.certificates.count) return nil;
|
||||
if (!csc.universalSigningInformation) return nil;
|
||||
NSMutableArray *universal = [NSMutableArray array];
|
||||
for (NSDictionary *arch in csc.universalSigningInformation) {
|
||||
[universal addObject:@{ @"arch" : arch.allKeys.firstObject }];
|
||||
int flags = [arch.allValues.firstObject[(__bridge id)kSecCodeInfoFlags] intValue];
|
||||
if (flags & kSecCodeSignatureAdhoc) {
|
||||
[universal addObject:@{ @"ad-hoc" : @YES }];
|
||||
continue;
|
||||
}
|
||||
NSArray *certs = arch.allValues.firstObject[(__bridge id)kSecCodeInfoCertificates];
|
||||
NSArray *chain = [MOLCertificate certificatesFromArray:certs];
|
||||
if (!chain.count) {
|
||||
[universal addObject:@{ @"unsigned" : @YES }];
|
||||
continue;
|
||||
}
|
||||
for (MOLCertificate *c in chain) {
|
||||
[universal addObject:@{
|
||||
kSHA256 : c.SHA256 ?: @"null",
|
||||
kSHA1 : c.SHA1 ?: @"null",
|
||||
kCommonName : c.commonName ?: @"null",
|
||||
kOrganization : c.orgName ?: @"null",
|
||||
kOrganizationalUnit : c.orgUnit ?: @"null",
|
||||
kValidFrom : [cmd.dateFormatter stringFromDate:c.validFrom] ?: @"null",
|
||||
kValidUntil : [cmd.dateFormatter stringFromDate:c.validUntil] ?: @"null"
|
||||
}];
|
||||
}
|
||||
}
|
||||
NSMutableSet *set = [NSMutableSet set];
|
||||
for (NSDictionary *cert in universal) {
|
||||
if (cert[@"arch"]) continue;
|
||||
[set addObject:cert];
|
||||
}
|
||||
return (set.count > 1) ? universal : nil;
|
||||
};
|
||||
}
|
||||
|
||||
# pragma mark -
|
||||
|
||||
// Entry point for the command.
|
||||
@@ -591,8 +638,8 @@ REGISTER_COMMAND_NAME(@"fileinfo")
|
||||
} else {
|
||||
for (NSString *key in self.outputKeyList) {
|
||||
if (![outputDict objectForKey:key]) continue;
|
||||
if ([key isEqual:kSigningChain]) {
|
||||
[output appendString:[self stringForSigningChain:outputDict[key]]];
|
||||
if ([key isEqual:kSigningChain] || [key isEqual:kUniversalSigningChain]) {
|
||||
[output appendString:[self stringForSigningChain:outputDict[key] key:key]];
|
||||
} else {
|
||||
if (singleKey) {
|
||||
[output appendFormat:@"%@\n", outputDict[key]];
|
||||
@@ -729,14 +776,25 @@ REGISTER_COMMAND_NAME(@"fileinfo")
|
||||
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (NSString *)stringForSigningChain:(NSArray *)signingChain {
|
||||
- (NSString *)stringForSigningChain:(NSArray *)signingChain key:(NSString *)key {
|
||||
if (!signingChain) return @"";
|
||||
NSMutableString *result = [NSMutableString string];
|
||||
[result appendFormat:@"%@:\n", kSigningChain];
|
||||
[result appendFormat:@"%@:\n", key];
|
||||
int i = 1;
|
||||
NSArray<NSString *> *certKeys = [[self class] signingChainKeys];
|
||||
for (NSDictionary *cert in signingChain) {
|
||||
if ([cert isEqual:[NSNull null]]) continue;
|
||||
if (cert[@"arch"]) {
|
||||
[result appendFormat:@" %2@\n", [@"Architecture: " stringByAppendingString:cert[@"arch"]]];
|
||||
i = 1;
|
||||
continue;
|
||||
} else if (cert[@"ad-hoc"]) {
|
||||
[result appendFormat:@" %2d. %-20@\n", i, @"ad-hoc"];
|
||||
continue;
|
||||
} else if (cert[@"unsigned"]) {
|
||||
[result appendFormat:@" %2d. %-20@\n", i, @"unsigned"];
|
||||
continue;
|
||||
}
|
||||
if (i > 1) [result appendFormat:@"\n"];
|
||||
[result appendString:[self stringForCertificate:cert withKeys:certKeys index:i]];
|
||||
i += 1;
|
||||
@@ -750,10 +808,10 @@ REGISTER_COMMAND_NAME(@"fileinfo")
|
||||
BOOL firstKey = YES;
|
||||
for (NSString *key in keys) {
|
||||
if (firstKey) {
|
||||
[result appendFormat:@" %2d. %-20s: %@\n", index, key.UTF8String, cert[key]];
|
||||
[result appendFormat:@" %2d. %-20s: %@\n", index, key.UTF8String, cert[key]];
|
||||
firstKey = NO;
|
||||
} else {
|
||||
[result appendFormat:@" %-20s: %@\n", key.UTF8String, cert[key]];
|
||||
[result appendFormat:@" %-20s: %@\n", key.UTF8String, cert[key]];
|
||||
}
|
||||
}
|
||||
return result.copy;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// Copyright 2015 Google Inc. All rights reserved.
|
||||
/// Copyright 2018 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.
|
||||
@@ -23,15 +23,32 @@
|
||||
/// Logs execution and file write events to syslog
|
||||
///
|
||||
@interface SNTEventLog : NSObject
|
||||
|
||||
// Methods implemented by a concrete subclass.
|
||||
- (void)logDiskAppeared:(NSDictionary *)diskProperties;
|
||||
- (void)logDiskDisappeared:(NSDictionary *)diskProperties;
|
||||
|
||||
- (void)logFileModification:(santa_message_t)message;
|
||||
|
||||
- (void)saveDecisionDetails:(SNTCachedDecision *)cd;
|
||||
- (void)logDeniedExecution:(SNTCachedDecision *)cd withMessage:(santa_message_t)message;
|
||||
- (void)logAllowedExecution:(santa_message_t)message;
|
||||
|
||||
- (void)logBundleHashingEvents:(NSArray<SNTStoredEvent *> *)events;
|
||||
|
||||
// Getter and setter for cached decisions.
|
||||
- (SNTCachedDecision *)cachedDecisionForMessage:(santa_message_t)message;
|
||||
- (void)cacheDecision:(SNTCachedDecision *)cd;
|
||||
|
||||
// String formatter helpers.
|
||||
- (void)addArgsForPid:(pid_t)pid toString:(NSMutableString *)str;
|
||||
- (NSString *)diskImageForDevice:(NSString *)devPath;
|
||||
- (NSString *)nameForUID:(uid_t)uid;
|
||||
- (NSString *)nameForGID:(gid_t)gid;
|
||||
- (NSString *)sanitizeCString:(const char *)str ofLength:(NSUInteger)length;
|
||||
- (NSString *)sanitizeString:(NSString *)inStr;
|
||||
- (NSString *)serialForDevice:(NSString *)devPath;
|
||||
- (NSString *)originalPathForTranslocation:(santa_message_t)message;
|
||||
|
||||
// A cache for usernames and groups.
|
||||
@property(readonly, nonatomic) NSCache<NSNumber *, NSString *> *userNameMap;
|
||||
@property(readonly, nonatomic) NSCache<NSNumber *, NSString *> *groupNameMap;
|
||||
|
||||
// A UTC Date formatter.
|
||||
@property(readonly, nonatomic) NSDateFormatter *dateFormatter;
|
||||
@end
|
||||
@@ -1,4 +1,4 @@
|
||||
/// Copyright 2015 Google Inc. All rights reserved.
|
||||
/// Copyright 2018 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.
|
||||
@@ -16,29 +16,14 @@
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <grp.h>
|
||||
#include <libproc.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#import <MOLCertificate/MOLCertificate.h>
|
||||
|
||||
#import "SNTCachedDecision.h"
|
||||
#import "SNTCommonEnums.h"
|
||||
#import "SNTConfigurator.h"
|
||||
#import "SNTFileInfo.h"
|
||||
#import "SNTKernelCommon.h"
|
||||
#import "SNTLogging.h"
|
||||
#import "SNTStoredEvent.h"
|
||||
|
||||
@interface SNTEventLog ()
|
||||
@property NSMutableDictionary<NSNumber *, SNTCachedDecision *> *detailStore;
|
||||
@property dispatch_queue_t detailStoreQueue;
|
||||
|
||||
// Caches for uid->username and gid->groupname lookups.
|
||||
@property NSCache<NSNumber *, NSString *> *userNameMap;
|
||||
@property NSCache<NSNumber *, NSString *> *groupNameMap;
|
||||
|
||||
@property NSDateFormatter *dateFormatter;
|
||||
@end
|
||||
|
||||
@implementation SNTEventLog
|
||||
@@ -62,222 +47,47 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)saveDecisionDetails:(SNTCachedDecision *)cd {
|
||||
dispatch_sync(_detailStoreQueue, ^{
|
||||
_detailStore[@(cd.vnodeId)] = cd;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)logFileModification:(santa_message_t)message {
|
||||
NSString *action, *newpath;
|
||||
|
||||
NSString *path = @(message.path);
|
||||
|
||||
switch (message.action) {
|
||||
case ACTION_NOTIFY_DELETE: {
|
||||
action = @"DELETE";
|
||||
break;
|
||||
}
|
||||
case ACTION_NOTIFY_EXCHANGE: {
|
||||
action = @"EXCHANGE";
|
||||
newpath = @(message.newpath);
|
||||
break;
|
||||
}
|
||||
case ACTION_NOTIFY_LINK: {
|
||||
action = @"LINK";
|
||||
newpath = @(message.newpath);
|
||||
break;
|
||||
}
|
||||
case ACTION_NOTIFY_RENAME: {
|
||||
action = @"RENAME";
|
||||
newpath = @(message.newpath);
|
||||
break;
|
||||
}
|
||||
case ACTION_NOTIFY_WRITE: {
|
||||
action = @"WRITE";
|
||||
break;
|
||||
}
|
||||
default: action = @"UNKNOWN"; break;
|
||||
}
|
||||
|
||||
// init the string with 2k capacity to avoid reallocs
|
||||
NSMutableString *outStr = [NSMutableString stringWithCapacity:2048];
|
||||
[outStr appendFormat:@"action=%@|path=%@", action, [self sanitizeString:path]];
|
||||
if (newpath) {
|
||||
[outStr appendFormat:@"|newpath=%@", [self sanitizeString:newpath]];
|
||||
}
|
||||
char ppath[PATH_MAX] = "(null)";
|
||||
proc_pidpath(message.pid, ppath, PATH_MAX);
|
||||
|
||||
[outStr appendFormat:@"|pid=%d|ppid=%d|process=%s|processpath=%s|uid=%d|user=%@|gid=%d|group=%@",
|
||||
message.pid, message.ppid, message.pname, ppath,
|
||||
message.uid, [self nameForUID:message.uid],
|
||||
message.gid, [self nameForGID:message.gid]];
|
||||
LOGI(@"%@", outStr);
|
||||
}
|
||||
|
||||
- (void)logDeniedExecution:(SNTCachedDecision *)cd withMessage:(santa_message_t)message {
|
||||
[self logExecution:message withDecision:cd];
|
||||
}
|
||||
|
||||
- (void)logAllowedExecution:(santa_message_t)message {
|
||||
__block SNTCachedDecision *cd;
|
||||
dispatch_sync(_detailStoreQueue, ^{
|
||||
cd = _detailStore[@(message.vnode_id)];
|
||||
});
|
||||
[self logExecution:message withDecision:cd];
|
||||
}
|
||||
|
||||
- (void)logExecution:(santa_message_t)message withDecision:(SNTCachedDecision *)cd {
|
||||
NSString *d, *r;
|
||||
BOOL logArgs = NO;
|
||||
|
||||
switch (cd.decision) {
|
||||
case SNTEventStateAllowBinary:
|
||||
d = @"ALLOW";
|
||||
r = @"BINARY";
|
||||
logArgs = YES;
|
||||
break;
|
||||
case SNTEventStateAllowCertificate:
|
||||
d = @"ALLOW";
|
||||
r = @"CERT";
|
||||
logArgs = YES;
|
||||
break;
|
||||
case SNTEventStateAllowScope:
|
||||
d = @"ALLOW";
|
||||
r = @"SCOPE";
|
||||
logArgs = YES;
|
||||
break;
|
||||
case SNTEventStateAllowUnknown:
|
||||
d = @"ALLOW";
|
||||
r = @"UNKNOWN";
|
||||
logArgs = YES;
|
||||
break;
|
||||
case SNTEventStateBlockBinary:
|
||||
d = @"DENY";
|
||||
r = @"BINARY";
|
||||
break;
|
||||
case SNTEventStateBlockCertificate:
|
||||
d = @"DENY";
|
||||
r = @"CERT";
|
||||
break;
|
||||
case SNTEventStateBlockScope:
|
||||
d = @"DENY";
|
||||
r = @"SCOPE";
|
||||
break;
|
||||
case SNTEventStateBlockUnknown:
|
||||
d = @"DENY";
|
||||
r = @"UNKNOWN";
|
||||
break;
|
||||
default:
|
||||
d = @"ALLOW";
|
||||
r = @"NOTRUNNING";
|
||||
logArgs = YES;
|
||||
break;
|
||||
}
|
||||
|
||||
// init the string with 4k capacity to avoid reallocs
|
||||
NSMutableString *outLog = [[NSMutableString alloc] initWithCapacity:4096];
|
||||
[outLog appendFormat:@"action=EXEC|decision=%@|reason=%@", d, r];
|
||||
|
||||
if (cd.decisionExtra) {
|
||||
[outLog appendFormat:@"|explain=%@", cd.decisionExtra];
|
||||
}
|
||||
|
||||
[outLog appendFormat:@"|sha256=%@", cd.sha256];
|
||||
|
||||
if (cd.certSHA256) {
|
||||
[outLog appendFormat:@"|cert_sha256=%@|cert_cn=%@", cd.certSHA256,
|
||||
[self sanitizeString:cd.certCommonName]];
|
||||
}
|
||||
|
||||
if (cd.quarantineURL) {
|
||||
[outLog appendFormat:@"|quarantine_url=%@", [self sanitizeString:cd.quarantineURL]];
|
||||
}
|
||||
|
||||
NSString *mode;
|
||||
switch ([[SNTConfigurator configurator] clientMode]) {
|
||||
case SNTClientModeMonitor:
|
||||
mode = @"M"; break;
|
||||
case SNTClientModeLockdown:
|
||||
mode = @"L"; break;
|
||||
default:
|
||||
mode = @"U"; break;
|
||||
}
|
||||
|
||||
[outLog appendFormat:@"|pid=%d|ppid=%d|uid=%d|user=%@|gid=%d|group=%@|mode=%@|path=%@",
|
||||
message.pid, message.ppid,
|
||||
message.uid, [self nameForUID:message.uid],
|
||||
message.gid, [self nameForGID:message.gid],
|
||||
mode, [self sanitizeString:@(message.path)]];
|
||||
|
||||
// Check for app translocation by GateKeeper, and log original path if the case.
|
||||
NSString *originalPath = [self originalPathForTranslocation:message];
|
||||
if (originalPath) {
|
||||
[outLog appendFormat:@"|origpath=%@", [self sanitizeString:originalPath]];
|
||||
}
|
||||
|
||||
if (logArgs) {
|
||||
[self addArgsForPid:message.pid toString:outLog];
|
||||
}
|
||||
|
||||
LOGI(@"%@", outLog);
|
||||
}
|
||||
|
||||
- (void)logDiskAppeared:(NSDictionary *)diskProperties {
|
||||
NSString *dmgPath = @"";
|
||||
NSString *serial = @"";
|
||||
if ([diskProperties[@"DADeviceModel"] isEqual:@"Disk Image"]) {
|
||||
dmgPath = [self diskImageForDevice:diskProperties[@"DADevicePath"]];
|
||||
} else {
|
||||
serial = [self serialForDevice:diskProperties[@"DADevicePath"]];
|
||||
serial = [serial stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
}
|
||||
|
||||
NSString *model = [NSString stringWithFormat:@"%@ %@",
|
||||
diskProperties[@"DADeviceVendor"] ?: @"",
|
||||
diskProperties[@"DADeviceModel"] ?: @""];
|
||||
model = [model stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
|
||||
double appearance = [diskProperties[@"DAAppearanceTime"] doubleValue];
|
||||
NSString *appearanceDateString =
|
||||
[_dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSinceReferenceDate:appearance]];
|
||||
|
||||
NSString *log =
|
||||
@"action=DISKAPPEAR|mount=%@|volume=%@|bsdname=%@|fs=%@|"
|
||||
@"model=%@|serial=%@|bus=%@|dmgpath=%@|appearance=%@";
|
||||
LOGI(log,
|
||||
[diskProperties[@"DAVolumePath"] path] ?: @"",
|
||||
diskProperties[@"DAVolumeName"] ?: @"",
|
||||
diskProperties[@"DAMediaBSDName"] ?: @"",
|
||||
diskProperties[@"DAVolumeKind"] ?: @"",
|
||||
model ?: @"",
|
||||
serial,
|
||||
diskProperties[@"DADeviceProtocol"] ?: @"",
|
||||
dmgPath,
|
||||
appearanceDateString);
|
||||
[self doesNotRecognizeSelector:_cmd];
|
||||
}
|
||||
|
||||
- (void)logDiskDisappeared:(NSDictionary *)diskProperties {
|
||||
LOGI(@"action=DISKDISAPPEAR|mount=%@|volume=%@|bsdname=%@",
|
||||
[diskProperties[@"DAVolumePath"] path] ?: @"",
|
||||
diskProperties[@"DAVolumeName"] ?: @"",
|
||||
diskProperties[@"DAMediaBSDName"]);
|
||||
[self doesNotRecognizeSelector:_cmd];
|
||||
}
|
||||
|
||||
- (void)logFileModification:(santa_message_t)message {
|
||||
[self doesNotRecognizeSelector:_cmd];
|
||||
}
|
||||
|
||||
- (void)logDeniedExecution:(SNTCachedDecision *)cd withMessage:(santa_message_t)message {
|
||||
[self doesNotRecognizeSelector:_cmd];
|
||||
}
|
||||
|
||||
- (void)logAllowedExecution:(santa_message_t)message {
|
||||
[self doesNotRecognizeSelector:_cmd];
|
||||
}
|
||||
|
||||
- (void)logBundleHashingEvents:(NSArray<SNTStoredEvent *> *)events {
|
||||
for (SNTStoredEvent *event in events) {
|
||||
LOGI(@"action=BUNDLE|sha256=%@|bundlehash=%@|bundlename=%@|bundleid=%@|bundlepath=%@|path=%@",
|
||||
event.fileSHA256,
|
||||
event.fileBundleHash,
|
||||
event.fileBundleName,
|
||||
event.fileBundleID,
|
||||
event.fileBundlePath,
|
||||
event.filePath);
|
||||
}
|
||||
[self doesNotRecognizeSelector:_cmd];
|
||||
}
|
||||
|
||||
#pragma mark Helpers
|
||||
- (void)writeLog:(NSString *)log {
|
||||
[self doesNotRecognizeSelector:_cmd];
|
||||
}
|
||||
|
||||
- (void)cacheDecision:(SNTCachedDecision *)cd {
|
||||
dispatch_sync(self.detailStoreQueue, ^{
|
||||
self.detailStore[@(cd.vnodeId)] = cd;
|
||||
});
|
||||
}
|
||||
|
||||
- (SNTCachedDecision *)cachedDecisionForMessage:(santa_message_t)message {
|
||||
__block SNTCachedDecision *cd;
|
||||
dispatch_sync(self.detailStoreQueue, ^{
|
||||
cd = self.detailStore[@(message.vnode_id)];
|
||||
});
|
||||
return cd;
|
||||
}
|
||||
|
||||
/**
|
||||
Sanitizes a given string if necessary, otherwise returns the original.
|
||||
18
Source/santad/Logs/SNTFileEventLog.h
Normal file
18
Source/santad/Logs/SNTFileEventLog.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/// Copyright 2018 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 "SNTSyslogEventLog.h"
|
||||
|
||||
@interface SNTFileEventLog : SNTSyslogEventLog
|
||||
@end
|
||||
101
Source/santad/Logs/SNTFileEventLog.m
Normal file
101
Source/santad/Logs/SNTFileEventLog.m
Normal file
@@ -0,0 +1,101 @@
|
||||
/// Copyright 2018 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 "SNTFileEventLog.h"
|
||||
|
||||
#import "SNTConfigurator.h"
|
||||
#import "SNTLogging.h"
|
||||
#import "SNTStrengthify.h"
|
||||
|
||||
@interface SNTFileEventLog ()
|
||||
@property NSFileHandle *fh;
|
||||
@property(readonly, nonatomic) dispatch_queue_t q;
|
||||
@property dispatch_source_t source;
|
||||
@property(readonly, nonatomic) dispatch_source_t timer;
|
||||
@property(readonly, nonatomic) NSString *path;
|
||||
@property(readonly, nonatomic) NSMutableData *buffer;
|
||||
@end
|
||||
|
||||
@implementation SNTFileEventLog
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_q = dispatch_queue_create("com.google.santa.file_event_log", DISPATCH_QUEUE_SERIAL);
|
||||
_path = [[SNTConfigurator configurator] eventLogPath];
|
||||
_fh = [self fileHandleForPath:_path];
|
||||
[self watchLogFile];
|
||||
// 8k buffer to batch logs for writing.
|
||||
_buffer = [NSMutableData dataWithCapacity:8192];
|
||||
// To avoid long lulls in the log being updated, flush the buffer every second.
|
||||
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _q);
|
||||
dispatch_source_set_timer(_timer, dispatch_time(DISPATCH_TIME_NOW, 0), NSEC_PER_SEC * 1, 0);
|
||||
WEAKIFY(self);
|
||||
dispatch_source_set_event_handler(_timer, ^{
|
||||
STRONGIFY(self);
|
||||
[self flushBuffer];
|
||||
});
|
||||
dispatch_resume(_timer);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSFileHandle *)fileHandleForPath:(NSString *)path {
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
if (![fm fileExistsAtPath:path]) {
|
||||
[fm createFileAtPath:path contents:nil attributes:nil];
|
||||
}
|
||||
NSFileHandle *fh = [NSFileHandle fileHandleForWritingAtPath:path];
|
||||
[fh seekToEndOfFile];
|
||||
return fh;
|
||||
}
|
||||
|
||||
- (void)watchLogFile {
|
||||
if (self.source) {
|
||||
dispatch_source_set_event_handler_f(self.source, NULL);
|
||||
dispatch_source_cancel(self.source);
|
||||
}
|
||||
self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE,
|
||||
self.fh.fileDescriptor,
|
||||
DISPATCH_VNODE_DELETE | DISPATCH_VNODE_RENAME,
|
||||
self.q);
|
||||
WEAKIFY(self);
|
||||
dispatch_source_set_event_handler(self.source, ^{
|
||||
STRONGIFY(self);
|
||||
[self.fh closeFile];
|
||||
self.fh = [self fileHandleForPath:self.path];
|
||||
[self watchLogFile];
|
||||
});
|
||||
dispatch_resume(self.source);
|
||||
}
|
||||
|
||||
- (void)writeLog:(NSString *)log {
|
||||
dispatch_async(self.q, ^{
|
||||
NSString *dateString = [self.dateFormatter stringFromDate:[NSDate date]];
|
||||
NSString *outLog = [NSString stringWithFormat:@"[%@] I santad: %@\n", dateString, log];
|
||||
[self.buffer appendBytes:outLog.UTF8String
|
||||
length:[outLog lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
|
||||
// Avoid excessive calls to write() by batching logs.
|
||||
if (self.buffer.length >= 4096) {
|
||||
[self flushBuffer];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)flushBuffer {
|
||||
write(self.fh.fileDescriptor, self.buffer.bytes, self.buffer.length);
|
||||
[self.buffer setLength:0];
|
||||
}
|
||||
|
||||
@end
|
||||
18
Source/santad/Logs/SNTSyslogEventLog.h
Normal file
18
Source/santad/Logs/SNTSyslogEventLog.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/// Copyright 2018 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 "SNTEventLog.h"
|
||||
|
||||
@interface SNTSyslogEventLog : SNTEventLog
|
||||
@end
|
||||
242
Source/santad/Logs/SNTSyslogEventLog.m
Normal file
242
Source/santad/Logs/SNTSyslogEventLog.m
Normal file
@@ -0,0 +1,242 @@
|
||||
/// Copyright 2018 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 "SNTSyslogEventLog.h"
|
||||
|
||||
#import <libproc.h>
|
||||
|
||||
#import "SNTCachedDecision.h"
|
||||
#import "SNTConfigurator.h"
|
||||
#import "SNTLogging.h"
|
||||
#import "SNTStoredEvent.h"
|
||||
|
||||
@implementation SNTSyslogEventLog
|
||||
|
||||
- (void)logFileModification:(santa_message_t)message {
|
||||
NSString *action, *newpath;
|
||||
|
||||
NSString *path = @(message.path);
|
||||
|
||||
switch (message.action) {
|
||||
case ACTION_NOTIFY_DELETE: {
|
||||
action = @"DELETE";
|
||||
break;
|
||||
}
|
||||
case ACTION_NOTIFY_EXCHANGE: {
|
||||
action = @"EXCHANGE";
|
||||
newpath = @(message.newpath);
|
||||
break;
|
||||
}
|
||||
case ACTION_NOTIFY_LINK: {
|
||||
action = @"LINK";
|
||||
newpath = @(message.newpath);
|
||||
break;
|
||||
}
|
||||
case ACTION_NOTIFY_RENAME: {
|
||||
action = @"RENAME";
|
||||
newpath = @(message.newpath);
|
||||
break;
|
||||
}
|
||||
case ACTION_NOTIFY_WRITE: {
|
||||
action = @"WRITE";
|
||||
break;
|
||||
}
|
||||
default: action = @"UNKNOWN"; break;
|
||||
}
|
||||
|
||||
// init the string with 2k capacity to avoid reallocs
|
||||
NSMutableString *outStr = [NSMutableString stringWithCapacity:2048];
|
||||
[outStr appendFormat:@"action=%@|path=%@", action, [self sanitizeString:path]];
|
||||
if (newpath) {
|
||||
[outStr appendFormat:@"|newpath=%@", [self sanitizeString:newpath]];
|
||||
}
|
||||
char ppath[PATH_MAX] = "(null)";
|
||||
proc_pidpath(message.pid, ppath, PATH_MAX);
|
||||
|
||||
[outStr appendFormat:@"|pid=%d|ppid=%d|process=%s|processpath=%s|uid=%d|user=%@|gid=%d|group=%@",
|
||||
message.pid, message.ppid, message.pname, ppath,
|
||||
message.uid, [self nameForUID:message.uid],
|
||||
message.gid, [self nameForGID:message.gid]];
|
||||
|
||||
[self writeLog:outStr];
|
||||
}
|
||||
|
||||
- (void)logExecution:(santa_message_t)message withDecision:(SNTCachedDecision *)cd {
|
||||
NSString *d, *r;
|
||||
BOOL logArgs = NO;
|
||||
|
||||
switch (cd.decision) {
|
||||
case SNTEventStateAllowBinary:
|
||||
d = @"ALLOW";
|
||||
r = @"BINARY";
|
||||
logArgs = YES;
|
||||
break;
|
||||
case SNTEventStateAllowCertificate:
|
||||
d = @"ALLOW";
|
||||
r = @"CERT";
|
||||
logArgs = YES;
|
||||
break;
|
||||
case SNTEventStateAllowScope:
|
||||
d = @"ALLOW";
|
||||
r = @"SCOPE";
|
||||
logArgs = YES;
|
||||
break;
|
||||
case SNTEventStateAllowUnknown:
|
||||
d = @"ALLOW";
|
||||
r = @"UNKNOWN";
|
||||
logArgs = YES;
|
||||
break;
|
||||
case SNTEventStateBlockBinary:
|
||||
d = @"DENY";
|
||||
r = @"BINARY";
|
||||
break;
|
||||
case SNTEventStateBlockCertificate:
|
||||
d = @"DENY";
|
||||
r = @"CERT";
|
||||
break;
|
||||
case SNTEventStateBlockScope:
|
||||
d = @"DENY";
|
||||
r = @"SCOPE";
|
||||
break;
|
||||
case SNTEventStateBlockUnknown:
|
||||
d = @"DENY";
|
||||
r = @"UNKNOWN";
|
||||
break;
|
||||
default:
|
||||
d = @"ALLOW";
|
||||
r = @"NOTRUNNING";
|
||||
logArgs = YES;
|
||||
break;
|
||||
}
|
||||
|
||||
// init the string with 4k capacity to avoid reallocs
|
||||
NSMutableString *outLog = [[NSMutableString alloc] initWithCapacity:4096];
|
||||
[outLog appendFormat:@"action=EXEC|decision=%@|reason=%@", d, r];
|
||||
|
||||
if (cd.decisionExtra) {
|
||||
[outLog appendFormat:@"|explain=%@", cd.decisionExtra];
|
||||
}
|
||||
|
||||
[outLog appendFormat:@"|sha256=%@", cd.sha256];
|
||||
|
||||
if (cd.certSHA256) {
|
||||
[outLog appendFormat:@"|cert_sha256=%@|cert_cn=%@", cd.certSHA256,
|
||||
[self sanitizeString:cd.certCommonName]];
|
||||
}
|
||||
|
||||
if (cd.quarantineURL) {
|
||||
[outLog appendFormat:@"|quarantine_url=%@", [self sanitizeString:cd.quarantineURL]];
|
||||
}
|
||||
|
||||
NSString *mode;
|
||||
switch ([[SNTConfigurator configurator] clientMode]) {
|
||||
case SNTClientModeMonitor:
|
||||
mode = @"M"; break;
|
||||
case SNTClientModeLockdown:
|
||||
mode = @"L"; break;
|
||||
default:
|
||||
mode = @"U"; break;
|
||||
}
|
||||
|
||||
[outLog appendFormat:@"|pid=%d|ppid=%d|uid=%d|user=%@|gid=%d|group=%@|mode=%@|path=%@",
|
||||
message.pid, message.ppid,
|
||||
message.uid, [self nameForUID:message.uid],
|
||||
message.gid, [self nameForGID:message.gid],
|
||||
mode, [self sanitizeString:@(message.path)]];
|
||||
|
||||
// Check for app translocation by GateKeeper, and log original path if the case.
|
||||
NSString *originalPath = [self originalPathForTranslocation:message];
|
||||
if (originalPath) {
|
||||
[outLog appendFormat:@"|origpath=%@", [self sanitizeString:originalPath]];
|
||||
}
|
||||
|
||||
if (logArgs) {
|
||||
[self addArgsForPid:message.pid toString:outLog];
|
||||
}
|
||||
|
||||
[self writeLog:outLog];
|
||||
}
|
||||
|
||||
- (void)logDeniedExecution:(SNTCachedDecision *)cd withMessage:(santa_message_t)message {
|
||||
[self logExecution:message withDecision:cd];
|
||||
}
|
||||
|
||||
- (void)logAllowedExecution:(santa_message_t)message {
|
||||
SNTCachedDecision *cd = [self cachedDecisionForMessage:message];
|
||||
[self logExecution:message withDecision:cd];
|
||||
}
|
||||
|
||||
- (void)logDiskAppeared:(NSDictionary *)diskProperties {
|
||||
NSString *dmgPath = @"";
|
||||
NSString *serial = @"";
|
||||
if ([diskProperties[@"DADeviceModel"] isEqual:@"Disk Image"]) {
|
||||
dmgPath = [self diskImageForDevice:diskProperties[@"DADevicePath"]];
|
||||
} else {
|
||||
serial = [self serialForDevice:diskProperties[@"DADevicePath"]];
|
||||
serial = [serial stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
}
|
||||
|
||||
NSString *model = [NSString stringWithFormat:@"%@ %@",
|
||||
diskProperties[@"DADeviceVendor"] ?: @"",
|
||||
diskProperties[@"DADeviceModel"] ?: @""];
|
||||
model = [model stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
|
||||
double a = [diskProperties[@"DAAppearanceTime"] doubleValue];
|
||||
NSString *appearanceDateString =
|
||||
[self.dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSinceReferenceDate:a]];
|
||||
|
||||
NSString *format =
|
||||
@"action=DISKAPPEAR|mount=%@|volume=%@|bsdname=%@|fs=%@|"
|
||||
@"model=%@|serial=%@|bus=%@|dmgpath=%@|appearance=%@";
|
||||
NSString *outLog = [NSMutableString stringWithFormat:format,
|
||||
[diskProperties[@"DAVolumePath"] path] ?: @"",
|
||||
diskProperties[@"DAVolumeName"] ?: @"",
|
||||
diskProperties[@"DAMediaBSDName"] ?: @"",
|
||||
diskProperties[@"DAVolumeKind"] ?: @"",
|
||||
model ?: @"",
|
||||
serial,
|
||||
diskProperties[@"DADeviceProtocol"] ?: @"",
|
||||
dmgPath,
|
||||
appearanceDateString];
|
||||
[self writeLog:outLog];
|
||||
}
|
||||
|
||||
- (void)logDiskDisappeared:(NSDictionary *)diskProperties {
|
||||
NSString *format = @"action=DISKDISAPPEAR|mount=%@|volume=%@|bsdname=%@";
|
||||
NSString *outLog = [NSMutableString stringWithFormat:format,
|
||||
[diskProperties[@"DAVolumePath"] path] ?: @"",
|
||||
diskProperties[@"DAVolumeName"] ?: @"",
|
||||
diskProperties[@"DAMediaBSDName"]];
|
||||
[self writeLog:outLog];
|
||||
}
|
||||
|
||||
- (void)logBundleHashingEvents:(NSArray<SNTStoredEvent *> *)events {
|
||||
for (SNTStoredEvent *event in events) {
|
||||
NSString *format = @"action=DISKDISAPPEAR|mount=%@|volume=%@|bsdname=%@";
|
||||
NSString *outLog = [NSMutableString stringWithFormat:format,
|
||||
event.fileSHA256,
|
||||
event.fileBundleHash,
|
||||
event.fileBundleName,
|
||||
event.fileBundleID,
|
||||
event.fileBundlePath,
|
||||
event.filePath];
|
||||
[self writeLog:outLog];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)writeLog:(NSString *)log {
|
||||
LOGI(@"%@", log);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -22,13 +22,14 @@
|
||||
#import "SNTDatabaseController.h"
|
||||
#import "SNTDriverManager.h"
|
||||
#import "SNTDropRootPrivs.h"
|
||||
#import "SNTEventLog.h"
|
||||
#import "SNTEventTable.h"
|
||||
#import "SNTExecutionController.h"
|
||||
#import "SNTFileEventLog.h"
|
||||
#import "SNTLogging.h"
|
||||
#import "SNTNotificationQueue.h"
|
||||
#import "SNTRuleTable.h"
|
||||
#import "SNTSyncdQueue.h"
|
||||
#import "SNTSyslogEventLog.h"
|
||||
#import "SNTXPCConnection.h"
|
||||
#import "SNTXPCControlInterface.h"
|
||||
#import "SNTXPCNotifierInterface.h"
|
||||
@@ -68,7 +69,16 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
_eventLog = [[SNTEventLog alloc] init];
|
||||
// Choose an event logger.
|
||||
SNTConfigurator *configurator = [SNTConfigurator configurator];
|
||||
switch ([configurator eventLogType]) {
|
||||
case SNTEventLogTypeSyslog:
|
||||
_eventLog = [[SNTSyslogEventLog alloc] init];
|
||||
break;
|
||||
case SNTEventLogTypeFilelog:
|
||||
_eventLog = [[SNTFileEventLog alloc] init];
|
||||
break;
|
||||
}
|
||||
|
||||
self.notQueue = [[SNTNotificationQueue alloc] init];
|
||||
SNTSyncdQueue *syncdQueue = [[SNTSyncdQueue alloc] init];
|
||||
@@ -80,7 +90,6 @@
|
||||
|
||||
// Listen for actionable config changes.
|
||||
NSKeyValueObservingOptions bits = (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld);
|
||||
SNTConfigurator *configurator = [SNTConfigurator configurator];
|
||||
[configurator addObserver:self
|
||||
forKeyPath:NSStringFromSelector(@selector(clientMode))
|
||||
options:bits
|
||||
@@ -309,11 +318,17 @@ void diskDisappearedCallback(DADiskRef disk, void *context) {
|
||||
- (void)syncBaseURLDidChange:(NSURL *)syncBaseURL {
|
||||
if (syncBaseURL) {
|
||||
LOGI(@"Starting santactl with new SyncBaseURL: %@", syncBaseURL);
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:[SNTConfigurator configurator]
|
||||
selector:@selector(clearSyncState)
|
||||
object:nil];
|
||||
[self startSyncd];
|
||||
} else {
|
||||
LOGI(@"SyncBaseURL removed, killing santactl pid: %i", self.syncdPID);
|
||||
[self stopSyncd];
|
||||
[[SNTConfigurator configurator] clearSyncState];
|
||||
// Keep the syncState active for 10 min in case com.apple.ManagedClient is flapping.
|
||||
[[SNTConfigurator configurator] performSelector:@selector(clearSyncState)
|
||||
withObject:nil
|
||||
afterDelay:600];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -225,6 +225,7 @@ double watchdogRAMPeak = 0;
|
||||
bs.remoteInterface = [SNTXPCBundleServiceInterface bundleServiceInterface];
|
||||
[bs resume];
|
||||
[[bs remoteObjectProxy] setBundleNotificationListener:listener];
|
||||
[bs invalidate];
|
||||
}
|
||||
|
||||
#pragma mark syncd Ops
|
||||
|
||||
@@ -117,9 +117,11 @@ static size_t kLargeBinarySize = 30 * 1024 * 1024;
|
||||
|
||||
// Get codesigning info about the file.
|
||||
NSError *csError;
|
||||
MOLCodesignChecker *csInfo = [[MOLCodesignChecker alloc] initWithBinaryPath:binInfo.path
|
||||
error:&csError];
|
||||
// Ignore codesigning if there are any errors with the signature.
|
||||
MOLCodesignChecker *csInfo =
|
||||
[[MOLCodesignChecker alloc] initWithBinaryPath:binInfo.path
|
||||
fileDescriptor:binInfo.fileHandle.fileDescriptor
|
||||
error:&csError];
|
||||
// Ignore codesigning if there are any errors with the signature.
|
||||
if (csError) csInfo = nil;
|
||||
|
||||
// Actually make the decision.
|
||||
@@ -134,7 +136,7 @@ static size_t kLargeBinarySize = 30 * 1024 * 1024;
|
||||
(SNTEventStateAllow & cd.decision) ? ACTION_RESPOND_ALLOW : ACTION_RESPOND_DENY;
|
||||
|
||||
// Save decision details for logging the execution later.
|
||||
if (action == ACTION_RESPOND_ALLOW) [_eventLog saveDecisionDetails:cd];
|
||||
if (action == ACTION_RESPOND_ALLOW) [_eventLog cacheDecision:cd];
|
||||
|
||||
// Send the decision to the kernel.
|
||||
[_driverManager postToKernelAction:action forVnodeID:cd.vnodeId];
|
||||
|
||||
@@ -47,7 +47,10 @@
|
||||
|
||||
self.mockCodesignChecker = OCMClassMock([MOLCodesignChecker class]);
|
||||
OCMStub([self.mockCodesignChecker alloc]).andReturn(self.mockCodesignChecker);
|
||||
OCMStub([self.mockCodesignChecker initWithBinaryPath:OCMOCK_ANY error:[OCMArg setTo:NULL]])
|
||||
|
||||
OCMStub([self.mockCodesignChecker initWithBinaryPath:OCMOCK_ANY
|
||||
fileDescriptor:0
|
||||
error:[OCMArg setTo:NULL]])
|
||||
.andReturn(self.mockCodesignChecker);
|
||||
|
||||
self.mockConfigurator = OCMClassMock([SNTConfigurator class]);
|
||||
|
||||
Reference in New Issue
Block a user