Compare commits

...

22 Commits

Author SHA1 Message Date
Russell Hancox
094880af50 Project: Add DevelopmentTeam configuration (#157)
This is a generated xcconfig in the Rakefile which gets included by the project
to set the DEVELOPMENT_TEAM key to keep Xcode 8 happy. The development team is
figured based on the available “Mac Developer” certificate.

Also update the way SantaCache declares a ‘zero’ value, update the
OCMock pod and add a few missing includes.
2017-03-20 16:34:59 -04:00
Tom Burgin
c3db518aca santactl/sync: use the new fcm-stream format (#156) 2017-03-20 14:42:29 -04:00
Tom Burgin
41ee0c5fdb Running without a config fixes (#154)
* common: capture fileSystemRepresentation in a local variable

* santactl/status: check for instant notification status only when there is a sync url

* s/FALSE/NO
2017-03-17 12:12:41 -04:00
Tom Burgin
ae178bc146 create default config if one does not exist (#153) 2017-03-10 17:17:52 -05:00
Tom Burgin
a2a660d483 config update and modules (#152)
* santactl/sync: https://github.com/google/santa/issues/150

* pch to modules
2017-03-09 13:02:02 -08:00
Tom Burgin
8684cc34f7 santactl/sync: use hostname for reachability (#149)
* Revert "SNTXPCConnection: make XPC debugging easier (#141)"

This reverts commit a2d6338400.

* santactl/sync: use hostname for reachability

* style update
2017-03-08 07:55:35 -08:00
Tom Burgin
0aba8b78ba disable bundle scans (#146)
* config: update to cocoapods-1.2.0 and molfcmclient 1.2

* santactl/sync: disable sync server bundle scan requests
2017-03-01 09:02:00 -08:00
Russell Hancox
5e735aa8d5 santad: Clear cache when regexes change. (#143)
When white/black-list regexes are changed clear the kernel cache so the regexes are able to take effect immediately. Fixes #142
2017-02-03 11:00:32 -05:00
Tom Burgin
a2d6338400 SNTXPCConnection: make XPC debugging easier (#141) 2017-01-31 15:36:09 -05:00
Russell Hancox
5e4b8350ab SNTXPCConnection: allow redefining invalidationHandler after connections are established (#140) 2017-01-23 11:10:13 -05:00
Tom Burgin
4a65b646df santactl status: add last successful rule sync date (#139)
* santactl status: add last successful rule sync date
2017-01-11 15:52:07 -05:00
Tom Burgin
24c715aae9 santactl sync: reachability and notification updates santad: syncd xpc updates (#138)
* santactl sync: post a notification for every matching rule and fcm message

* santactl sync: if full sync fails, retry when reachable

* santad: only allow one syncd connection at any given time
2017-01-10 16:14:15 -05:00
Tom Burgin
9ab85768bd Update Podfile.lock to use MOLFCMClient v1.1 (#136) 2017-01-03 11:10:15 -05:00
Tom Burgin
16458d96e7 Notification verbage update (#135) 2016-12-14 14:41:20 -05:00
Tom Burgin
b307dd17af Use machine ids as the targeted sync indicator (#134)
* Use machine ids as the targeted sync indicator

* remove unused constant
2016-12-12 16:53:24 -05:00
Tom Burgin
313552352c Display the binary name when a local rule is synced from a push notification (#133) 2016-12-07 17:40:11 -05:00
Tom Burgin
543ac7c649 push notifications with FCM (#132)
* push notifications with FCM

* Don't display rule count in notifications. Get FCM broadcast topic from sync server.
2016-12-06 16:04:34 -05:00
Tom Burgin
dacff76694 run santactl as a sync daemon (#129)
* run santactl as a sync daemon
2016-11-16 14:41:12 -05:00
Russell Hancox
c134169ea1 santad: Drop AUTOINCREMENT on event table (#130) 2016-11-01 11:14:51 -04:00
Russell Hancox
e252945047 santactl/fileinfo: Send resolved path to santad for processing (#128) 2016-10-26 16:04:27 -04:00
Russell Hancox
f8cfcaab20 Package/Conf: Fix typo in uninstall.sh (#126) 2016-10-25 15:05:36 -04:00
Tom Burgin
528237a239 santactl status: check non-boxed vars when building json output (#125) 2016-10-24 12:14:56 -04:00
94 changed files with 1301 additions and 641 deletions

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@ Santa.xcodeproj/xcuserdata
Santa.xcodeproj/project.xcworkspace
Santa.xcworkspace/xcuserdata
Santa.xcworkspace/xcshareddata
Source/DevelopmentTeam.xcconfig

View File

@@ -82,3 +82,4 @@ myclean:
@rm -f com.google.santad.plist
@rm -f com.google.santagui.plist
@rm -f install.sh
@rm -f uninstall.sh

View File

@@ -19,8 +19,8 @@ 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 /usr/local/santactl # just a symlink
/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
#/bin/rm -f /var/log/santa*
exit 0
exit 0

View File

@@ -18,6 +18,7 @@ target :santactl do
pod 'MOLAuthenticatingURLSession'
pod 'MOLCertificate'
pod 'MOLCodesignChecker'
pod 'MOLFCMClient', '~> 1.3'
end
target :LogicTests do

View File

@@ -2,27 +2,31 @@ PODS:
- FMDB (2.6.2):
- FMDB/standard (= 2.6.2)
- FMDB/standard (2.6.2)
- MOLAuthenticatingURLSession (2.1):
- MOLAuthenticatingURLSession (2.2):
- MOLCertificate (~> 1.5)
- MOLCertificate (1.5)
- MOLCodesignChecker (1.5):
- MOLCertificate (~> 1.3)
- OCMock (3.3.1)
- MOLFCMClient (1.3):
- MOLAuthenticatingURLSession (~> 2.1)
- OCMock (3.4)
DEPENDENCIES:
- FMDB
- MOLAuthenticatingURLSession
- MOLCertificate
- MOLCodesignChecker
- MOLFCMClient (~> 1.3)
- OCMock
SPEC CHECKSUMS:
FMDB: 854a0341b4726e53276f2a8996f06f1b80f9259a
MOLAuthenticatingURLSession: 2f0fd35f641bc857ee1b026021dbd759955adaa3
MOLAuthenticatingURLSession: 5a5e31eb73248c3e92c79b9a285f031194e8404c
MOLCertificate: c39cae866d24d36fbc78032affff83d401b5384a
MOLCodesignChecker: fc9c64147811d7b0d0739127003e0630dff9213a
OCMock: f3f61e6eaa16038c30caa5798c5e49d3307b6f22
MOLFCMClient: 13d8b42db9d750e772f09cc38fc453922fece09f
OCMock: 35ae71d6a8fcc1b59434d561d1520b9dd4f15765
PODFILE CHECKSUM: bc456d69693ca262c781dbbde40529a9474b84b5
PODFILE CHECKSUM: 1728b86e95e7cdb481dd91ab9c38af38e060a023
COCOAPODS: 1.0.1
COCOAPODS: 1.2.0

View File

@@ -1,3 +1,5 @@
require 'openssl'
WORKSPACE = 'Santa.xcworkspace'
DEFAULT_SCHEME = 'All'
OUTPUT_PATH = 'Build'
@@ -5,6 +7,8 @@ BINARIES = ['Santa.app', 'santa-driver.kext']
DSYMS = ['Santa.app.dSYM', 'santa-driver.kext.dSYM', 'santad.dSYM', 'santactl.dSYM']
XCPRETTY_DEFAULTS = '-sc'
XCODEBUILD_DEFAULTS = "-workspace #{WORKSPACE} -derivedDataPath #{OUTPUT_PATH} -parallelizeTargets"
DEVTEAM_FILE = 'Source/DevelopmentTeam.xcconfig'
DEVTEAM_CERT_CN = 'Mac Developer'
$DISABLE_XCPRETTY = false
task :default do
@@ -44,6 +48,13 @@ task :init do
puts "xcpretty is not installed. Install with 'sudo gem install xcpretty'"
$DISABLE_XCPRETTY = true
end
cert_pem = `security find-certificate -p -c '#{DEVTEAM_CERT_CN}'`
cert = OpenSSL::X509::Certificate.new cert_pem
team_id = cert.subject.to_a.find {|f| f[0] == "OU"}[1]
File.open(DEVTEAM_FILE, 'w') { |f|
f.puts("// This file is auto-generated. Do not edit manually")
f.puts("DEVELOPMENT_TEAM = #{team_id}")
}
end
task :remove_existing do

View File

@@ -26,9 +26,7 @@
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
0D0016A3192BCD3C005E7FCD /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D9A7F3E1759330500035EB5 /* Foundation.framework */; };
0D0016A6192BCD3C005E7FCD /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0D0016A5192BCD3C005E7FCD /* main.mm */; };
0D0016AE192BCD8C005E7FCD /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D3AFBF718FB4C870087BCEE /* IOKit.framework */; };
0D0A1EC3191998C900B8450F /* SNTCommandSyncRuleDownload.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D0A1EC2191998C900B8450F /* SNTCommandSyncRuleDownload.m */; };
0D0A1EC6191AB9B000B8450F /* SNTCommandSyncPostflight.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D0A1EC5191AB9B000B8450F /* SNTCommandSyncPostflight.m */; };
0D10BE861A0AABD600C0C944 /* SNTDropRootPrivs.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D10BE851A0AABD600C0C944 /* SNTDropRootPrivs.m */; };
@@ -46,15 +44,12 @@
0D28D53819D9F5910015C5EB /* SNTConfigurator.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D42D2B719D2042900955F08 /* SNTConfigurator.m */; };
0D2CD4611A81C7B100C9C910 /* dn.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0D2CD4601A81C7B100C9C910 /* dn.plist */; };
0D2E1E631CEFA6C30039B2C4 /* SantaCacheTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0D2E1E621CEFA6C30039B2C4 /* SantaCacheTest.mm */; };
0D35BD9F18FD71CE00921A21 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D9A7F3E1759330500035EB5 /* Foundation.framework */; };
0D35BDA218FD71CE00921A21 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D35BDA118FD71CE00921A21 /* main.m */; };
0D35BDAC18FD7CFD00921A21 /* SNTCommandController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D35BDAB18FD7CFD00921A21 /* SNTCommandController.m */; };
0D35BDB518FD84F600921A21 /* SNTCommandSync.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D35BDB418FD84F600921A21 /* SNTCommandSync.m */; };
0D35BDBD18FDA23600921A21 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D3AFBF718FB4C870087BCEE /* IOKit.framework */; };
0D35BDC418FDA5D100921A21 /* SNTXPCConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D6FDC9518C93A020044685C /* SNTXPCConnection.m */; };
0D377C2A17A071B7008453DB /* SNTEventTable.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D377C2917A071B7008453DB /* SNTEventTable.m */; };
0D37C10F18F6029A0069BC61 /* SNTDatabaseTable.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D37C10E18F6029A0069BC61 /* SNTDatabaseTable.m */; };
0D385DB8180DE4A900418BC6 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D385DB7180DE4A900418BC6 /* Cocoa.framework */; };
0D385DC4180DE4A900418BC6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D385DC3180DE4A900418BC6 /* main.m */; };
0D385DD0180DE4A900418BC6 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D385DCF180DE4A900418BC6 /* Images.xcassets */; };
0D385DF0180DE51600418BC6 /* MessageWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0D385DE9180DE51600418BC6 /* MessageWindow.xib */; };
@@ -67,8 +62,6 @@
0D3AFBEE18FB4C6C0087BCEE /* SNTApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DB8ACC0185662DC00FEF9C7 /* SNTApplication.m */; };
0D3AFBEF18FB4C6C0087BCEE /* SNTExecutionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DE6788C1784A8C2007A9E52 /* SNTExecutionController.m */; };
0D3AFBF018FB4C6C0087BCEE /* SNTDriverManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D7D01861774F93A005DBAB4 /* SNTDriverManager.m */; };
0D3AFBF618FB4C7E0087BCEE /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D385DB7180DE4A900418BC6 /* Cocoa.framework */; };
0D3AFBF818FB4C870087BCEE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D3AFBF718FB4C870087BCEE /* IOKit.framework */; };
0D416401191974F1006A356A /* SNTCommandSyncState.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D416400191974F1006A356A /* SNTCommandSyncState.m */; };
0D41640519197AD7006A356A /* SNTCommandSyncEventUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D41640419197AD7006A356A /* SNTCommandSyncEventUpload.m */; };
0D41DAD41A7C28C800A890FE /* SNTEventTableTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D41DAD31A7C28C800A890FE /* SNTEventTableTest.m */; };
@@ -77,7 +70,6 @@
0D42D2B919D2042900955F08 /* SNTConfigurator.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D42D2B719D2042900955F08 /* SNTConfigurator.m */; };
0D4644C5182AF81700098690 /* SantaDecisionManager.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0D4644C3182AF81700098690 /* SantaDecisionManager.cc */; };
0D4644C6182AF81700098690 /* SantaDecisionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D4644C4182AF81700098690 /* SantaDecisionManager.h */; };
0D4A5007176A4602004F63BF /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D4A5006176A4602004F63BF /* Security.framework */; };
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 */; };
@@ -85,7 +77,6 @@
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 */; };
0D6F12D819EC8822006B218E /* SecurityInterface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0DCD5F771909C659006B445C /* SecurityInterface.framework */; };
0D6FDC9618C93A020044685C /* SNTXPCConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D6FDC9518C93A020044685C /* SNTXPCConnection.m */; };
0D6FDC9718C93A020044685C /* SNTXPCConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D6FDC9518C93A020044685C /* SNTXPCConnection.m */; };
0D7D01871774F93A005DBAB4 /* SNTDriverManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D7D01861774F93A005DBAB4 /* SNTDriverManager.m */; };
@@ -94,10 +85,8 @@
0D8868091AC48A1100B86659 /* SNTSystemInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D42D2B419D1D98A00955F08 /* SNTSystemInfo.m */; };
0D88680A1AC48A1200B86659 /* SNTSystemInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D42D2B419D1D98A00955F08 /* SNTSystemInfo.m */; };
0D88680C1AC48A1400B86659 /* SNTSystemInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D42D2B419D1D98A00955F08 /* SNTSystemInfo.m */; };
0D88680D1AC48A5D00B86659 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D3AFBF718FB4C870087BCEE /* IOKit.framework */; };
0D89310E1C931979002E8D74 /* SNTXPCControlInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD605419115D17006B445C /* SNTXPCControlInterface.m */; };
0D89310F1C931986002E8D74 /* SNTRule.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DE50F671912716A007B2B0C /* SNTRule.m */; };
0D8C200C180F359A00CE2BF8 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D8C200B180F359A00CE2BF8 /* Security.framework */; };
0D8E18CD19107B56000F89B8 /* SNTDaemonControlController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D8E18CC19107B56000F89B8 /* SNTDaemonControlController.m */; };
0D9184B81CD2F32D0004E859 /* SNTCommandSyncStage.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D9184B71CD2F32D0004E859 /* SNTCommandSyncStage.m */; };
0D9184B91CD2F32D0004E859 /* SNTCommandSyncStage.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D9184B71CD2F32D0004E859 /* SNTCommandSyncStage.m */; };
@@ -105,7 +94,6 @@
0D9A7F341759144800035EB5 /* SantaDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D9A7F321759144800035EB5 /* SantaDriver.h */; };
0D9A7F371759148E00035EB5 /* SantaDriverClient.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0D9A7F351759148E00035EB5 /* SantaDriverClient.cc */; };
0D9A7F381759148E00035EB5 /* SantaDriverClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D9A7F361759148E00035EB5 /* SantaDriverClient.h */; };
0D9A7F3F1759330500035EB5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D9A7F3E1759330500035EB5 /* Foundation.framework */; };
0D9A7F421759330500035EB5 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D9A7F411759330500035EB5 /* main.m */; };
0DA73C9F1934F8100056D7C4 /* SNTLogging.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DA73C9E1934F8100056D7C4 /* SNTLogging.m */; };
0DA73CA11934F8100056D7C4 /* SNTLogging.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DA73C9E1934F8100056D7C4 /* SNTLogging.m */; };
@@ -138,12 +126,10 @@
0DCD605819115E57006B445C /* SNTXPCControlInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD605419115D17006B445C /* SNTXPCControlInterface.m */; };
0DCD605919115E5A006B445C /* SNTXPCNotifierInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD604E19115A06006B445C /* SNTXPCNotifierInterface.m */; };
0DCD605C19117A90006B445C /* SNTCommandSyncPreflight.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD605B19117A90006B445C /* SNTCommandSyncPreflight.m */; };
0DD0D487194F5187005F27EB /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D3AFBF718FB4C870087BCEE /* IOKit.framework */; };
0DD0D48F194F78F8005F27EB /* SNTFileInfoTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DD0D48E194F78F8005F27EB /* SNTFileInfoTest.m */; };
0DD0D491194F9947005F27EB /* SNTExecutionControllerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DD0D490194F9947005F27EB /* SNTExecutionControllerTest.m */; };
0DD0D492194F9BEF005F27EB /* SNTLogging.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DA73C9E1934F8100056D7C4 /* SNTLogging.m */; };
0DE2CE561CA05561002B649A /* SNTAccessibleTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DE2CE551CA05561002B649A /* SNTAccessibleTextField.m */; };
0DE4C8A118FEF28200466D04 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D8C200B180F359A00CE2BF8 /* Security.framework */; };
0DE4C8A618FF3B1700466D04 /* SNTCommandFlushCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DE4C8A518FF3B1700466D04 /* SNTCommandFlushCache.m */; };
0DE50F681912716A007B2B0C /* SNTRule.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DE50F671912716A007B2B0C /* SNTRule.m */; };
0DE50F691912B0CD007B2B0C /* SNTRule.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DE50F671912716A007B2B0C /* SNTRule.m */; };
@@ -168,21 +154,23 @@
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 */; };
1C299D1C789489996FF9E081 /* libPods-Santa.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 87D1CEAEDF1FA6819A855559 /* libPods-Santa.a */; };
29C490B1720D4FD576F93519 /* libPods-LogicTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 17D03B346587131C45A8DA67 /* libPods-LogicTests.a */; };
2BA4AE89AA2447E29DA2E85C /* libPods-santactl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BE53E1EAE84D54E7FCB22FD5 /* libPods-santactl.a */; };
34D8F6C53153950A66DBEF69 /* libPods-santad.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 60A9B66BB0F7404D1F61D518 /* libPods-santad.a */; };
4092327A1A51B66400A04527 /* SNTCommandRule.m in Sources */ = {isa = PBXBuildFile; fileRef = 409232791A51B65D00A04527 /* SNTCommandRule.m */; };
580046F725A5D0874B970A17 /* libPods-Santa.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B2B9044B79DD2E4DEC5D3B7A /* libPods-Santa.a */; };
79C1556E6EAC94038762EF36 /* libPods-santactl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 556108C12FC29E329D82D4CB /* libPods-santactl.a */; };
A60673DE57680AC450A3B0B2 /* libPods-santad.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9BE438428F17C09C6A9D0802 /* libPods-santad.a */; };
42805FED981952EC9F0E4272 /* libPods-santactl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC914D8DD0F5C0E21DA45150 /* libPods-santactl.a */; };
7E396F5897B914399A568D27 /* libPods-Santa.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8FE66FA803110026A2A57C59 /* libPods-Santa.a */; };
8E6BE2EABCDF090F0FCEA980 /* libPods-santad.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E57A355BC439804E082B9C0A /* libPods-santad.a */; };
C4F8326EEB58061C1A579F0D /* libPods-LogicTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3EAD1E725C5F299F58F754D7 /* libPods-LogicTests.a */; };
C714F8B11D8044D400700EDF /* SNTCommandFileInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD5FBE1909D64A006B445C /* SNTCommandFileInfo.m */; };
C714F8B21D8044FE00700EDF /* SNTCommandController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D35BDAB18FD7CFD00921A21 /* SNTCommandController.m */; };
C72E8D941D7F399900C86DD3 /* SNTCommandFileInfoTest.m in Sources */ = {isa = PBXBuildFile; fileRef = C72E8D931D7F399900C86DD3 /* SNTCommandFileInfoTest.m */; };
C73A4B9A1DC10753007B6789 /* SNTSyncdQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = C7FB56FF1DBFC213004E14EF /* SNTSyncdQueue.m */; };
C73A4B9B1DC10758007B6789 /* SNTXPCSyncdInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = C7FB56F51DBFB480004E14EF /* SNTXPCSyncdInterface.m */; };
C76614EC1D142D3C00D150C1 /* SNTCommandCheckCache.m in Sources */ = {isa = PBXBuildFile; fileRef = C76614EB1D142D3C00D150C1 /* SNTCommandCheckCache.m */; };
C776A1071DEE160500A56616 /* SNTCommandSyncManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C776A1061DEE160500A56616 /* SNTCommandSyncManager.m */; };
C795ED901D80A5BE007CFF42 /* SNTPolicyProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = C795ED8F1D80A5BE007CFF42 /* SNTPolicyProcessor.m */; };
C795ED911D80B66B007CFF42 /* SNTPolicyProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = C795ED8F1D80A5BE007CFF42 /* SNTPolicyProcessor.m */; };
EFD8E30D32F6128B9E833D64 /* libPods-LogicTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 873978BCE4B0DBD2A89C99D1 /* libPods-LogicTests.a */; };
C7FB56F61DBFB480004E14EF /* SNTXPCSyncdInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = C7FB56F51DBFB480004E14EF /* SNTXPCSyncdInterface.m */; };
C7FB56F71DBFB480004E14EF /* SNTXPCSyncdInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = C7FB56F51DBFB480004E14EF /* SNTXPCSyncdInterface.m */; };
C7FB57001DBFC213004E14EF /* SNTSyncdQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = C7FB56FF1DBFC213004E14EF /* SNTSyncdQueue.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -259,6 +247,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
07B44952FAAF4CA056FC4A62 /* Pods-santad.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-santad.debug.xcconfig"; path = "Pods/Target Support Files/Pods-santad/Pods-santad.debug.xcconfig"; sourceTree = "<group>"; };
0D0016A2192BCD3C005E7FCD /* KernelTests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = KernelTests; sourceTree = BUILT_PRODUCTS_DIR; };
0D0016A5192BCD3C005E7FCD /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
0D0A1EC1191998C900B8450F /* SNTCommandSyncRuleDownload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTCommandSyncRuleDownload.h; sourceTree = "<group>"; };
@@ -274,9 +263,9 @@
0D202D1D1CDD479400A88F16 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
0D202D1F1CE4E90E00A88F16 /* sync_preflight_basic.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = sync_preflight_basic.json; sourceTree = "<group>"; };
0D202D231CE5071600A88F16 /* SantaCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SantaCache.h; sourceTree = "<group>"; };
0D2429471E787655005C6FC9 /* DevelopmentTeam.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DevelopmentTeam.xcconfig; sourceTree = "<group>"; };
0D260DAC18B68E12002A0B55 /* LogicTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LogicTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
0D260DB118B68E12002A0B55 /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = "<group>"; };
0D260DB718B68E12002A0B55 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = "<group>"; };
0D28E5E119269B3600280F87 /* SNTLogging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SNTLogging.h; sourceTree = "<group>"; };
0D28E5E31926AFE400280F87 /* SNTKernelCommon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SNTKernelCommon.h; sourceTree = "<group>"; };
0D28E5E41926B55600280F87 /* santactl-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "santactl-Info.plist"; sourceTree = "<group>"; };
@@ -284,7 +273,6 @@
0D2E1E621CEFA6C30039B2C4 /* SantaCacheTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SantaCacheTest.mm; sourceTree = "<group>"; };
0D35BD9E18FD71CE00921A21 /* santactl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = santactl; sourceTree = BUILT_PRODUCTS_DIR; };
0D35BDA118FD71CE00921A21 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
0D35BDA418FD71CE00921A21 /* santactl-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "santactl-Prefix.pch"; sourceTree = "<group>"; };
0D35BDAA18FD7CFD00921A21 /* SNTCommandController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTCommandController.h; sourceTree = "<group>"; };
0D35BDAB18FD7CFD00921A21 /* SNTCommandController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandController.m; sourceTree = "<group>"; };
0D35BDB418FD84F600921A21 /* SNTCommandSync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandSync.m; sourceTree = "<group>"; };
@@ -297,7 +285,6 @@
0D385DB7180DE4A900418BC6 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
0D385DBF180DE4A900418BC6 /* SantaGUI-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SantaGUI-Info.plist"; sourceTree = "<group>"; };
0D385DC3180DE4A900418BC6 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
0D385DC5180DE4A900418BC6 /* Santa-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Santa-Prefix.pch"; sourceTree = "<group>"; };
0D385DCF180DE4A900418BC6 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
0D385DE9180DE51600418BC6 /* MessageWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessageWindow.xib; sourceTree = "<group>"; };
0D385DEA180DE51600418BC6 /* SNTAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTAppDelegate.h; sourceTree = "<group>"; };
@@ -351,7 +338,6 @@
0D9A7F3E1759330500035EB5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
0D9A7F411759330500035EB5 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = main.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
0DA73C9E1934F8100056D7C4 /* SNTLogging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTLogging.m; sourceTree = "<group>"; };
0DB2B92318085753001C01D9 /* santad-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "santad-Prefix.pch"; sourceTree = "<group>"; };
0DB390981AB1E11400614002 /* SNTCommandVersion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandVersion.m; sourceTree = "<group>"; };
0DB537861AFD36EB00487F92 /* SNTRuleTableTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTRuleTableTest.m; sourceTree = "<group>"; };
0DB77FD61CCE824A004DF060 /* SNTBlockMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTBlockMessage.h; sourceTree = "<group>"; };
@@ -400,27 +386,28 @@
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; };
17D03B346587131C45A8DA67 /* libPods-LogicTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LogicTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
2B9F8A80C0F8D34D98135F36 /* Pods-santactl.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-santactl.release.xcconfig"; path = "Pods/Target Support Files/Pods-santactl/Pods-santactl.release.xcconfig"; sourceTree = "<group>"; };
3EAD1E725C5F299F58F754D7 /* libPods-LogicTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LogicTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
409232791A51B65D00A04527 /* SNTCommandRule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandRule.m; sourceTree = "<group>"; };
4D9D2DDDCD92DBB948D38B11 /* 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>"; };
4E43227BA5B261FF33141AFC /* Pods-LogicTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LogicTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LogicTests/Pods-LogicTests.debug.xcconfig"; sourceTree = "<group>"; };
556108C12FC29E329D82D4CB /* libPods-santactl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-santactl.a"; sourceTree = BUILT_PRODUCTS_DIR; };
60A9B66BB0F7404D1F61D518 /* libPods-santad.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-santad.a"; sourceTree = BUILT_PRODUCTS_DIR; };
691189054F4E484D030CF831 /* Pods-santactl.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-santactl.debug.xcconfig"; path = "Pods/Target Support Files/Pods-santactl/Pods-santactl.debug.xcconfig"; sourceTree = "<group>"; };
7C9CC3CDF2609E78E6A9C601 /* Pods-santad.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-santad.release.xcconfig"; path = "Pods/Target Support Files/Pods-santad/Pods-santad.release.xcconfig"; sourceTree = "<group>"; };
821428941753678DB772D761 /* Pods-LogicTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LogicTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-LogicTests/Pods-LogicTests.release.xcconfig"; sourceTree = "<group>"; };
873978BCE4B0DBD2A89C99D1 /* libPods-LogicTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LogicTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
87D1CEAEDF1FA6819A855559 /* libPods-Santa.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Santa.a"; sourceTree = BUILT_PRODUCTS_DIR; };
95B378553DCD86290341B8E4 /* Pods-santad.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-santad.debug.xcconfig"; path = "Pods/Target Support Files/Pods-santad/Pods-santad.debug.xcconfig"; sourceTree = "<group>"; };
9BE438428F17C09C6A9D0802 /* libPods-santad.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-santad.a"; sourceTree = BUILT_PRODUCTS_DIR; };
B2B9044B79DD2E4DEC5D3B7A /* libPods-Santa.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Santa.a"; sourceTree = BUILT_PRODUCTS_DIR; };
BE53E1EAE84D54E7FCB22FD5 /* libPods-santactl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-santactl.a"; sourceTree = BUILT_PRODUCTS_DIR; };
5123AB484639A3640D62CB67 /* Pods-santactl.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-santactl.release.xcconfig"; path = "Pods/Target Support Files/Pods-santactl/Pods-santactl.release.xcconfig"; sourceTree = "<group>"; };
5B0D17672432F610DE7F14EA /* Pods-LogicTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LogicTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LogicTests/Pods-LogicTests.debug.xcconfig"; sourceTree = "<group>"; };
6519E416CC4D06EE85DDB34B /* 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>"; };
6A947802FC1698EC37A47F5C /* Pods-santactl.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-santactl.debug.xcconfig"; path = "Pods/Target Support Files/Pods-santactl/Pods-santactl.debug.xcconfig"; sourceTree = "<group>"; };
8FE66FA803110026A2A57C59 /* libPods-Santa.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Santa.a"; sourceTree = BUILT_PRODUCTS_DIR; };
A5C68436912C0F98A7DE3BFA /* Pods-LogicTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LogicTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-LogicTests/Pods-LogicTests.release.xcconfig"; sourceTree = "<group>"; };
C72E8D931D7F399900C86DD3 /* SNTCommandFileInfoTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandFileInfoTest.m; 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>"; };
C776A1061DEE160500A56616 /* SNTCommandSyncManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandSyncManager.m; sourceTree = "<group>"; };
C795ED8E1D80A5BE007CFF42 /* SNTPolicyProcessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTPolicyProcessor.h; sourceTree = "<group>"; };
C795ED8F1D80A5BE007CFF42 /* SNTPolicyProcessor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTPolicyProcessor.m; sourceTree = "<group>"; };
D227889DF327E7D3532FE00B /* Pods-Santa.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Santa.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Santa/Pods-Santa.debug.xcconfig"; sourceTree = "<group>"; };
C7FB56F41DBFB480004E14EF /* SNTXPCSyncdInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTXPCSyncdInterface.h; sourceTree = "<group>"; };
C7FB56F51DBFB480004E14EF /* SNTXPCSyncdInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTXPCSyncdInterface.m; sourceTree = "<group>"; };
C7FB56FE1DBFC213004E14EF /* SNTSyncdQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTSyncdQueue.h; sourceTree = "<group>"; };
C7FB56FF1DBFC213004E14EF /* SNTSyncdQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTSyncdQueue.m; sourceTree = "<group>"; };
DC914D8DD0F5C0E21DA45150 /* libPods-santactl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-santactl.a"; sourceTree = BUILT_PRODUCTS_DIR; };
E57A355BC439804E082B9C0A /* libPods-santad.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-santad.a"; sourceTree = BUILT_PRODUCTS_DIR; };
F1E491F3C201A2362E04FF81 /* Pods-santad.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-santad.release.xcconfig"; path = "Pods/Target Support Files/Pods-santad/Pods-santad.release.xcconfig"; sourceTree = "<group>"; };
F25BED2D82EB26743AD59464 /* Pods-Santa.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Santa.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Santa/Pods-Santa.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -428,8 +415,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0D0016AE192BCD8C005E7FCD /* IOKit.framework in Frameworks */,
0D0016A3192BCD3C005E7FCD /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -438,10 +423,7 @@
buildActionMask = 2147483647;
files = (
0D202D1E1CDD479400A88F16 /* libz.tbd in Frameworks */,
0D3AFBF618FB4C7E0087BCEE /* Cocoa.framework in Frameworks */,
0D3AFBF818FB4C870087BCEE /* IOKit.framework in Frameworks */,
29C490B1720D4FD576F93519 /* libPods-LogicTests.a in Frameworks */,
EFD8E30D32F6128B9E833D64 /* libPods-LogicTests.a in Frameworks */,
C4F8326EEB58061C1A579F0D /* libPods-LogicTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -450,11 +432,7 @@
buildActionMask = 2147483647;
files = (
0DF395661AB76ABC00CBC520 /* libz.dylib in Frameworks */,
0DE4C8A118FEF28200466D04 /* Security.framework in Frameworks */,
0D35BDBD18FDA23600921A21 /* IOKit.framework in Frameworks */,
0D35BD9F18FD71CE00921A21 /* Foundation.framework in Frameworks */,
2BA4AE89AA2447E29DA2E85C /* libPods-santactl.a in Frameworks */,
79C1556E6EAC94038762EF36 /* libPods-santactl.a in Frameworks */,
42805FED981952EC9F0E4272 /* libPods-santactl.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -462,12 +440,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0D88680D1AC48A5D00B86659 /* IOKit.framework in Frameworks */,
0D6F12D819EC8822006B218E /* SecurityInterface.framework in Frameworks */,
0D8C200C180F359A00CE2BF8 /* Security.framework in Frameworks */,
0D385DB8180DE4A900418BC6 /* Cocoa.framework in Frameworks */,
1C299D1C789489996FF9E081 /* libPods-Santa.a in Frameworks */,
580046F725A5D0874B970A17 /* libPods-Santa.a in Frameworks */,
7E396F5897B914399A568D27 /* libPods-Santa.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -475,11 +448,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0DD0D487194F5187005F27EB /* IOKit.framework in Frameworks */,
0D4A5007176A4602004F63BF /* Security.framework in Frameworks */,
0D9A7F3F1759330500035EB5 /* Foundation.framework in Frameworks */,
A60673DE57680AC450A3B0B2 /* libPods-santad.a in Frameworks */,
34D8F6C53153950A66DBEF69 /* libPods-santad.a in Frameworks */,
8E6BE2EABCDF090F0FCEA980 /* libPods-santad.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -532,7 +501,6 @@
0DEA5F771CF64C8B00704398 /* sync_ruledownload_batch1.json */,
0DEA5F781CF64C8B00704398 /* sync_ruledownload_batch2.json */,
0D260DB118B68E12002A0B55 /* Tests-Info.plist */,
0D260DB718B68E12002A0B55 /* Tests-Prefix.pch */,
);
path = Resources;
sourceTree = "<group>";
@@ -553,7 +521,6 @@
isa = PBXGroup;
children = (
0D28E5E41926B55600280F87 /* santactl-Info.plist */,
0D35BDA418FD71CE00921A21 /* santactl-Prefix.pch */,
);
path = Resources;
sourceTree = "<group>";
@@ -570,6 +537,8 @@
0D41640419197AD7006A356A /* SNTCommandSyncEventUpload.m */,
0DC5D86F192160180078A5C0 /* SNTCommandSyncLogUpload.h */,
0DC5D870192160180078A5C0 /* SNTCommandSyncLogUpload.m */,
C776A1051DEE160500A56616 /* SNTCommandSyncManager.h */,
C776A1061DEE160500A56616 /* SNTCommandSyncManager.m */,
0D0A1EC4191AB9B000B8450F /* SNTCommandSyncPostflight.h */,
0D0A1EC5191AB9B000B8450F /* SNTCommandSyncPostflight.m */,
0DCD605A19117A90006B445C /* SNTCommandSyncPreflight.h */,
@@ -610,7 +579,6 @@
children = (
0D385DCF180DE4A900418BC6 /* Images.xcassets */,
0D385DBF180DE4A900418BC6 /* SantaGUI-Info.plist */,
0D385DC5180DE4A900418BC6 /* Santa-Prefix.pch */,
0D1B476F19A53419008CADD3 /* AboutWindow.xib */,
0D385DE9180DE51600418BC6 /* MessageWindow.xib */,
);
@@ -621,7 +589,6 @@
isa = PBXGroup;
children = (
0DB8ACE41858D73000FEF9C7 /* santad-Info.plist */,
0DB2B92318085753001C01D9 /* santad-Prefix.pch */,
);
path = Resources;
sourceTree = "<group>";
@@ -641,8 +608,8 @@
0DB77FDC1CD262F5004DF060 /* Source */,
0D789F9F1940F26D0036F7C4 /* Tests */,
0D91BCB5174E8A7E00131A7D /* Products */,
57575205DAC12A357F9EF899 /* Pods */,
9A8F78FCF1FF5934C80FB9B4 /* Frameworks */,
32B59E26727EF7DC0FC6A1C2 /* Pods */,
8ADEC8FA6FDD43E921A3E0D6 /* Frameworks */,
);
sourceTree = "<group>";
};
@@ -671,10 +638,6 @@
0D91BCB8174E8A7E00131A7D /* Kernel.framework */,
0D9A7F3E1759330500035EB5 /* Foundation.framework */,
0D385DB7180DE4A900418BC6 /* Cocoa.framework */,
17D03B346587131C45A8DA67 /* libPods-LogicTests.a */,
87D1CEAEDF1FA6819A855559 /* libPods-Santa.a */,
BE53E1EAE84D54E7FCB22FD5 /* libPods-santactl.a */,
9BE438428F17C09C6A9D0802 /* libPods-santad.a */,
);
name = Frameworks;
path = ../..;
@@ -725,6 +688,8 @@
0DCD605419115D17006B445C /* SNTXPCControlInterface.m */,
0DC8C9E3180CC3BC00FCFB29 /* SNTXPCNotifierInterface.h */,
0DCD604E19115A06006B445C /* SNTXPCNotifierInterface.m */,
C7FB56F41DBFB480004E14EF /* SNTXPCSyncdInterface.h */,
C7FB56F51DBFB480004E14EF /* SNTXPCSyncdInterface.m */,
);
path = common;
sourceTree = "<group>";
@@ -752,6 +717,8 @@
0DE6788C1784A8C2007A9E52 /* SNTExecutionController.m */,
0DE5B5491C926E3300C00603 /* SNTNotificationQueue.h */,
0DE5B54A1C926E3300C00603 /* SNTNotificationQueue.m */,
C7FB56FE1DBFC213004E14EF /* SNTSyncdQueue.h */,
C7FB56FF1DBFC213004E14EF /* SNTSyncdQueue.m */,
0D3AF83118F87CEF0087BCEE /* Resources */,
);
path = santad;
@@ -800,32 +767,33 @@
0D9A7F401759330500035EB5 /* santad */,
0D35BDA018FD71CE00921A21 /* santactl */,
0D385DBD180DE4A900418BC6 /* SantaGUI */,
0D2429471E787655005C6FC9 /* DevelopmentTeam.xcconfig */,
);
path = Source;
sourceTree = "<group>";
};
57575205DAC12A357F9EF899 /* Pods */ = {
32B59E26727EF7DC0FC6A1C2 /* Pods */ = {
isa = PBXGroup;
children = (
4E43227BA5B261FF33141AFC /* Pods-LogicTests.debug.xcconfig */,
821428941753678DB772D761 /* Pods-LogicTests.release.xcconfig */,
D227889DF327E7D3532FE00B /* Pods-Santa.debug.xcconfig */,
4D9D2DDDCD92DBB948D38B11 /* Pods-Santa.release.xcconfig */,
691189054F4E484D030CF831 /* Pods-santactl.debug.xcconfig */,
2B9F8A80C0F8D34D98135F36 /* Pods-santactl.release.xcconfig */,
95B378553DCD86290341B8E4 /* Pods-santad.debug.xcconfig */,
7C9CC3CDF2609E78E6A9C601 /* Pods-santad.release.xcconfig */,
5B0D17672432F610DE7F14EA /* Pods-LogicTests.debug.xcconfig */,
A5C68436912C0F98A7DE3BFA /* Pods-LogicTests.release.xcconfig */,
F25BED2D82EB26743AD59464 /* Pods-Santa.debug.xcconfig */,
6519E416CC4D06EE85DDB34B /* Pods-Santa.release.xcconfig */,
6A947802FC1698EC37A47F5C /* Pods-santactl.debug.xcconfig */,
5123AB484639A3640D62CB67 /* Pods-santactl.release.xcconfig */,
07B44952FAAF4CA056FC4A62 /* Pods-santad.debug.xcconfig */,
F1E491F3C201A2362E04FF81 /* Pods-santad.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
9A8F78FCF1FF5934C80FB9B4 /* Frameworks */ = {
8ADEC8FA6FDD43E921A3E0D6 /* Frameworks */ = {
isa = PBXGroup;
children = (
873978BCE4B0DBD2A89C99D1 /* libPods-LogicTests.a */,
B2B9044B79DD2E4DEC5D3B7A /* libPods-Santa.a */,
556108C12FC29E329D82D4CB /* libPods-santactl.a */,
60A9B66BB0F7404D1F61D518 /* libPods-santad.a */,
3EAD1E725C5F299F58F754D7 /* libPods-LogicTests.a */,
8FE66FA803110026A2A57C59 /* libPods-Santa.a */,
DC914D8DD0F5C0E21DA45150 /* libPods-santactl.a */,
E57A355BC439804E082B9C0A /* libPods-santad.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -867,13 +835,13 @@
isa = PBXNativeTarget;
buildConfigurationList = 0D260DBC18B68E12002A0B55 /* Build configuration list for PBXNativeTarget "LogicTests" */;
buildPhases = (
376E230296F6EA7A4DA8BBF0 /* [CP] Check Pods Manifest.lock */,
C22A218D691E062A00781563 /* [CP] Check Pods Manifest.lock */,
0D673DAD18FC9017009C5B06 /* Delete existing coverage files */,
0D260DA818B68E12002A0B55 /* Sources */,
0D260DA918B68E12002A0B55 /* Frameworks */,
0D260DAA18B68E12002A0B55 /* Resources */,
1D12555F0F4EF323B11E40F9 /* [CP] Embed Pods Frameworks */,
0C5C7A6AB763BCE7F760FAFF /* [CP] Copy Pods Resources */,
9F946EAD2A73FDCBE3FA3454 /* [CP] Embed Pods Frameworks */,
43EC969A89E13A43B4161035 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -888,11 +856,11 @@
isa = PBXNativeTarget;
buildConfigurationList = 0D35BDA918FD71CE00921A21 /* Build configuration list for PBXNativeTarget "santactl" */;
buildPhases = (
5F1504EA0D172767F2BCAAEB /* [CP] Check Pods Manifest.lock */,
8EF1E72D9F742F663ABE8DCD /* [CP] Check Pods Manifest.lock */,
0DD98E671A5DD02000A754C6 /* Update Version Info */,
0D35BD9A18FD71CE00921A21 /* Sources */,
0D35BD9B18FD71CE00921A21 /* Frameworks */,
E50DD7319E04737B040B69EC /* [CP] Copy Pods Resources */,
3AA84DD536CCE6A50E24E85E /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -907,13 +875,13 @@
isa = PBXNativeTarget;
buildConfigurationList = 0D385DE3180DE4A900418BC6 /* Build configuration list for PBXNativeTarget "Santa" */;
buildPhases = (
373591F801D7B22635DAD7A0 /* [CP] Check Pods Manifest.lock */,
D5EF20F46A8F8B36E63D1709 /* [CP] Check Pods Manifest.lock */,
0DD98E681A5DD03E00A754C6 /* Update Version Info */,
0D385DB2180DE4A900418BC6 /* Sources */,
0D385DB3180DE4A900418BC6 /* Frameworks */,
0D385DB4180DE4A900418BC6 /* Resources */,
31CD7EDCDEBD95322ED67F63 /* [CP] Embed Pods Frameworks */,
B3EB60284D47F89140F5A033 /* [CP] Copy Pods Resources */,
50E59E61A01D3126C43D49BB /* [CP] Embed Pods Frameworks */,
F1D2415B87633FA13FC7AA29 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -950,11 +918,11 @@
isa = PBXNativeTarget;
buildConfigurationList = 0D9A7F471759330500035EB5 /* Build configuration list for PBXNativeTarget "santad" */;
buildPhases = (
A3D478EF1D48EA118AF176E9 /* [CP] Check Pods Manifest.lock */,
828CFA7B34B9061FAFA68503 /* [CP] Check Pods Manifest.lock */,
0DD98E661A5DCED300A754C6 /* Update Version Info */,
0D9A7F391759330400035EB5 /* Sources */,
0D9A7F3A1759330400035EB5 /* Frameworks */,
435B0E246EE25ACC763D684C /* [CP] Copy Pods Resources */,
999D3C0A9B06CC3DFFB45CEA /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -1032,21 +1000,6 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
0C5C7A6AB763BCE7F760FAFF /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LogicTests/Pods-LogicTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
0D45F4271A5DCB7A00BF4375 /* Update Version Info */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -1140,22 +1093,37 @@
shellPath = /bin/sh;
shellScript = "GIT_TAG=$(git describe --abbrev=0 --tags)\nsed -i '' \"s/TO.BE.FILLED/${GIT_TAG}/\" ${DERIVED_FILE_DIR}/santa-driver_info.c";
};
1D12555F0F4EF323B11E40F9 /* [CP] Embed Pods Frameworks */ = {
3AA84DD536CCE6A50E24E85E /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LogicTests/Pods-LogicTests-frameworks.sh\"\n";
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-santactl/Pods-santactl-resources.sh\"\n";
showEnvVarsInLog = 0;
};
31CD7EDCDEBD95322ED67F63 /* [CP] Embed Pods Frameworks */ = {
43EC969A89E13A43B4161035 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LogicTests/Pods-LogicTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
50E59E61A01D3126C43D49BB /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1170,7 +1138,7 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Santa/Pods-Santa-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
373591F801D7B22635DAD7A0 /* [CP] Check Pods Manifest.lock */ = {
828CFA7B34B9061FAFA68503 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1182,10 +1150,10 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
376E230296F6EA7A4DA8BBF0 /* [CP] Check Pods Manifest.lock */ = {
8EF1E72D9F742F663ABE8DCD /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1197,10 +1165,10 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
435B0E246EE25ACC763D684C /* [CP] Copy Pods Resources */ = {
999D3C0A9B06CC3DFFB45CEA /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1215,7 +1183,22 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-santad/Pods-santad-resources.sh\"\n";
showEnvVarsInLog = 0;
};
5F1504EA0D172767F2BCAAEB /* [CP] Check Pods Manifest.lock */ = {
9F946EAD2A73FDCBE3FA3454 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LogicTests/Pods-LogicTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
C22A218D691E062A00781563 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1227,10 +1210,10 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
A3D478EF1D48EA118AF176E9 /* [CP] Check Pods Manifest.lock */ = {
D5EF20F46A8F8B36E63D1709 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1242,10 +1225,10 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
B3EB60284D47F89140F5A033 /* [CP] Copy Pods Resources */ = {
F1D2415B87633FA13FC7AA29 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1260,21 +1243,6 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Santa/Pods-Santa-resources.sh\"\n";
showEnvVarsInLog = 0;
};
E50DD7319E04737B040B69EC /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-santactl/Pods-santactl-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -1295,6 +1263,7 @@
0D88680C1AC48A1400B86659 /* SNTSystemInfo.m in Sources */,
0D536EDC1B94E9230039A26D /* SNTEventLog.m in Sources */,
0DEA5F7D1CF64EB600704398 /* SNTCommandSyncRuleDownload.m in Sources */,
C73A4B9B1DC10758007B6789 /* SNTXPCSyncdInterface.m in Sources */,
0DB77FDB1CD14093004DF060 /* SNTBlockMessage.m in Sources */,
0D63DD5E1906FCB400D346C4 /* SNTDatabaseController.m in Sources */,
0D202D191CDD2EE500A88F16 /* SNTCommandSyncTest.m in Sources */,
@@ -1331,6 +1300,7 @@
0DCD605919115E5A006B445C /* SNTXPCNotifierInterface.m in Sources */,
0DE50F691912B0CD007B2B0C /* SNTRule.m in Sources */,
0D202D1B1CDD465400A88F16 /* SNTCommandSyncState.m in Sources */,
C73A4B9A1DC10753007B6789 /* SNTSyncdQueue.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1345,11 +1315,13 @@
0DCD605619115D17006B445C /* SNTXPCControlInterface.m in Sources */,
0DE50F6C19130358007B2B0C /* SNTStoredEvent.m in Sources */,
0D9184B81CD2F32D0004E859 /* SNTCommandSyncStage.m in Sources */,
C776A1071DEE160500A56616 /* SNTCommandSyncManager.m in Sources */,
0D35BDC418FDA5D100921A21 /* SNTXPCConnection.m in Sources */,
0DCD605C19117A90006B445C /* SNTCommandSyncPreflight.m in Sources */,
0D41640519197AD7006A356A /* SNTCommandSyncEventUpload.m in Sources */,
0D42D2B919D2042900955F08 /* SNTConfigurator.m in Sources */,
0DF395641AB76A7900CBC520 /* NSData+Zlib.m in Sources */,
C7FB56F71DBFB480004E14EF /* SNTXPCSyncdInterface.m in Sources */,
0D10BE871A0AABD600C0C944 /* SNTDropRootPrivs.m in Sources */,
0DE4C8A618FF3B1700466D04 /* SNTCommandFlushCache.m in Sources */,
4092327A1A51B66400A04527 /* SNTCommandRule.m in Sources */,
@@ -1412,10 +1384,12 @@
0D10BE861A0AABD600C0C944 /* SNTDropRootPrivs.m in Sources */,
0D63DD5C1906FCB400D346C4 /* SNTDatabaseController.m in Sources */,
0DCD604B19105433006B445C /* SNTStoredEvent.m in Sources */,
C7FB57001DBFC213004E14EF /* SNTSyncdQueue.m in Sources */,
0DB8ACC1185662DC00FEF9C7 /* SNTApplication.m in Sources */,
0D9A7F421759330500035EB5 /* main.m in Sources */,
0DA73C9F1934F8100056D7C4 /* SNTLogging.m in Sources */,
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 */,
@@ -1510,6 +1484,10 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INSTALL_PATH = "";
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-fcxx-modules",
);
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
WARNING_CFLAGS = "";
@@ -1540,6 +1518,10 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INSTALL_PATH = "";
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-fcxx-modules",
);
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
WARNING_CFLAGS = "";
@@ -1548,7 +1530,7 @@
};
0D260DBA18B68E12002A0B55 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 4E43227BA5B261FF33141AFC /* Pods-LogicTests.debug.xcconfig */;
baseConfigurationReference = 5B0D17672432F610DE7F14EA /* Pods-LogicTests.debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
@@ -1571,7 +1553,6 @@
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_GENERATE_TEST_COVERAGE_FILES = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Tests/LogicTests/Resources/Tests-Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@@ -1597,7 +1578,7 @@
};
0D260DBB18B68E12002A0B55 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 821428941753678DB772D761 /* Pods-LogicTests.release.xcconfig */;
baseConfigurationReference = A5C68436912C0F98A7DE3BFA /* Pods-LogicTests.release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
@@ -1620,7 +1601,6 @@
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_GENERATE_TEST_COVERAGE_FILES = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Tests/LogicTests/Resources/Tests-Prefix.pch";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
@@ -1641,10 +1621,9 @@
};
0D35BDA718FD71CE00921A21 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 691189054F4E484D030CF831 /* Pods-santactl.debug.xcconfig */;
baseConfigurationReference = 6A947802FC1698EC37A47F5C /* Pods-santactl.debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_STATIC_ANALYZER_MODE = deep;
CLANG_WARN_BOOL_CONVERSION = YES;
@@ -1660,7 +1639,6 @@
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Source/santactl/Resources/santactl-Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@@ -1681,10 +1659,9 @@
};
0D35BDA818FD71CE00921A21 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2B9F8A80C0F8D34D98135F36 /* Pods-santactl.release.xcconfig */;
baseConfigurationReference = 5123AB484639A3640D62CB67 /* Pods-santactl.release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_STATIC_ANALYZER_MODE = deep;
CLANG_WARN_BOOL_CONVERSION = YES;
@@ -1700,7 +1677,6 @@
ENABLE_NS_ASSERTIONS = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Source/santactl/Resources/santactl-Prefix.pch";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
@@ -1716,11 +1692,10 @@
};
0D385DE4180DE4A900418BC6 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D227889DF327E7D3532FE00B /* Pods-Santa.debug.xcconfig */;
baseConfigurationReference = F25BED2D82EB26743AD59464 /* Pods-Santa.debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_STATIC_ANALYZER_MODE = deep;
CLANG_WARN_BOOL_CONVERSION = YES;
@@ -1736,7 +1711,6 @@
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Source/SantaGUI/Resources/Santa-Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@@ -1757,11 +1731,10 @@
};
0D385DE5180DE4A900418BC6 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 4D9D2DDDCD92DBB948D38B11 /* Pods-Santa.release.xcconfig */;
baseConfigurationReference = 6519E416CC4D06EE85DDB34B /* Pods-Santa.release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_STATIC_ANALYZER_MODE = deep;
CLANG_WARN_BOOL_CONVERSION = YES;
@@ -1777,7 +1750,6 @@
ENABLE_NS_ASSERTIONS = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Source/SantaGUI/Resources/Santa-Prefix.pch";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
@@ -1793,11 +1765,13 @@
};
0D91BCAC174E8A6500131A7D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 0D2429471E787655005C6FC9 /* DevelopmentTeam.xcconfig */;
buildSettings = {
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_CXX0X_EXTENSIONS = YES;
CODE_SIGN_IDENTITY = "Mac Developer";
ENABLE_TESTABILITY = YES;
@@ -1819,11 +1793,13 @@
};
0D91BCAD174E8A6500131A7D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 0D2429471E787655005C6FC9 /* DevelopmentTeam.xcconfig */;
buildSettings = {
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_CXX0X_EXTENSIONS = YES;
CODE_SIGN_IDENTITY = "Mac Developer";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
@@ -1846,7 +1822,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_MODULES = NO;
CLANG_STATIC_ANALYZER_MODE = deep;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -1884,7 +1860,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_MODULES = NO;
CLANG_STATIC_ANALYZER_MODE = deep;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -1931,7 +1907,7 @@
};
0D9A7F481759330500035EB5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 95B378553DCD86290341B8E4 /* Pods-santad.debug.xcconfig */;
baseConfigurationReference = 07B44952FAAF4CA056FC4A62 /* Pods-santad.debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
@@ -1946,7 +1922,6 @@
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Source/santad/Resources/santad-Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@@ -1966,7 +1941,7 @@
};
0D9A7F491759330500035EB5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7C9CC3CDF2609E78E6A9C601 /* Pods-santad.release.xcconfig */;
baseConfigurationReference = F1E491F3C201A2362E04FF81 /* Pods-santad.release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
@@ -1980,7 +1955,6 @@
CREATE_INFOPLIST_SECTION_IN_BINARY = YES;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Source/santad/Resources/santad-Prefix.pch";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;

View File

@@ -1,3 +0,0 @@
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Cocoa;
@interface SNTAboutWindowController : NSWindowController
@property IBOutlet NSButton *moreInfoButton;

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Cocoa;
/**
An NSTextField subclass that provides an accessiblity label equal to:
(self.toolTip + self.stringValue) where available. It also sets the

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Cocoa;
///
/// Initiates and manages the connection to santad
///

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Cocoa;
///
/// An NSPanel that can become key/main and can fade in/out.
///

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Cocoa;
@class SNTStoredEvent;
@protocol SNTMessageWindowControllerDelegate

View File

@@ -14,7 +14,7 @@
#import "SNTMessageWindowController.h"
#import <SecurityInterface/SFCertificatePanel.h>
@import SecurityInterface.SFCertificatePanel;
#import "MOLCertificate.h"
#import "SNTBlockMessage.h"

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Cocoa;
#import "SNTMessageWindowController.h"
#import "SNTXPCNotifierInterface.h"

View File

@@ -135,4 +135,12 @@ static NSString * const silencedNotificationsKey = @"SilencedNotifications";
});
}
- (void)postRuleSyncNotificationWithCustomMessage:(NSString *)message {
NSUserNotification *un = [[NSUserNotification alloc] init];
un.title = @"Santa";
un.hasActionButton = NO;
un.informativeText = message ?: @"Requested application can now be run";
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:un];
}
@end

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Cocoa;
#import "SNTAppDelegate.h"
int main(int argc, const char *argv[]) {

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
@class SNTStoredEvent;
@interface SNTBlockMessage : NSObject

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
///
/// These enums are used in various places throughout the Santa client code.
/// The integer values are also stored in the database and so shouldn't be changed.

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommonEnums.h"
///
@@ -143,9 +145,14 @@ extern NSString *const kDefaultConfigFilePath;
@property(readonly, nonatomic) NSString *machineOwner;
///
/// The last date of successful sync.
/// The last date of a successful full sync.
///
@property(nonatomic) NSDate *syncLastSuccess;
@property(nonatomic) NSDate *fullSyncLastSuccess;
///
/// The last date of a successful rule sync.
///
@property(nonatomic) NSDate *ruleSyncLastSuccess;
///
/// If YES a clean sync is required.
@@ -157,6 +164,24 @@ extern NSString *const kDefaultConfigFilePath;
///
@property(readonly, nonatomic) NSString *machineID;
///
/// The number of seconds in-between full syncs while connected to FCM
///
/// @note The default value is 14400.
/// @note The minimum value is 600.
///
@property(readonly, nonatomic) NSInteger FCMFullSyncInterval;
///
/// The maximum number of seconds to wait before a rule sync when
/// receiving a global rule sync message. Each client will choose a random
/// number of seconds between 0 and FCMGlobalRuleLeeway.
///
/// @note The default value is 600.
/// @note The minimum value is 60.
///
@property(readonly, nonatomic) NSInteger FCMGlobalRuleLeeway;
#pragma mark Server Auth Settings
///

View File

@@ -52,7 +52,8 @@ static NSString *const kModeNotificationMonitor = @"ModeNotificationMonitor";
static NSString *const kModeNotificationLockdown = @"ModeNotificationLockdown";
static NSString *const kSyncBaseURLKey = @"SyncBaseURL";
static NSString *const kSyncLastSuccess = @"SyncLastSuccess";
static NSString *const kFullSyncLastSuccess = @"FullSyncLastSuccess";
static NSString *const kRuleSyncLastSuccess = @"RuleSyncLastSuccess";
static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
static NSString *const kClientAuthCertificateFileKey = @"ClientAuthCertificateFile";
static NSString *const kClientAuthCertificatePasswordKey = @"ClientAuthCertificatePassword";
@@ -70,6 +71,9 @@ static NSString *const kMachineOwnerPlistKeyKey = @"MachineOwnerKey";
static NSString *const kMachineIDPlistFileKey = @"MachineIDPlist";
static NSString *const kMachineIDPlistKeyKey = @"MachineIDKey";
static NSString *const kFCMFullSyncInterval = @"FCMFullSyncInterval";
static NSString *const kFCMGlobalRuleLeeway = @"FCMGlobalRuleLeeway";
- (instancetype)initWithFilePath:(NSString *)filePath {
self = [super init];
if (self) {
@@ -111,7 +115,7 @@ static NSString *const kMachineIDPlistKeyKey = @"MachineIDKey";
return (SNTClientMode)cm;
} else {
LOGE(@"Client mode was set to bad value: %ld. Resetting to MONITOR.", cm);
self.configData[kClientModeKey] = @(SNTClientModeMonitor);
self.clientMode = SNTClientModeMonitor;
return SNTClientModeMonitor;
}
}
@@ -259,12 +263,22 @@ static NSString *const kMachineIDPlistKeyKey = @"MachineIDKey";
return self.configData[kServerAuthRootsFileKey];
}
- (NSDate *)syncLastSuccess {
return self.configData[kSyncLastSuccess];
- (NSDate *)fullSyncLastSuccess {
return self.configData[kFullSyncLastSuccess];
}
- (void)setSyncLastSuccess:(NSDate *)syncLastSuccess {
self.configData[kSyncLastSuccess] = syncLastSuccess;
- (void)setFullSyncLastSuccess:(NSDate *)fullSyncLastSuccess {
self.configData[kFullSyncLastSuccess] = fullSyncLastSuccess;
[self saveConfigToDisk];
self.ruleSyncLastSuccess = fullSyncLastSuccess;
}
- (NSDate *)ruleSyncLastSuccess {
return self.configData[kRuleSyncLastSuccess];
}
- (void)setRuleSyncLastSuccess:(NSDate *)ruleSyncLastSuccess {
self.configData[kRuleSyncLastSuccess] = ruleSyncLastSuccess;
[self saveConfigToDisk];
}
@@ -315,9 +329,26 @@ static NSString *const kMachineIDPlistKeyKey = @"MachineIDKey";
return machineId;
}
- (NSInteger)FCMFullSyncInterval {
NSInteger interval = [self.configData[kFCMFullSyncInterval] integerValue];
return (interval < 600) ? 1440 : interval;
}
- (NSInteger)FCMGlobalRuleLeeway {
NSInteger leeway = [self.configData[kFCMGlobalRuleLeeway] integerValue];
return (leeway < 60) ? 600 : leeway;
}
- (void)reloadConfigData {
NSFileManager *fm = [NSFileManager defaultManager];
if (![fm fileExistsAtPath:self.configFilePath]) return;
if (![fm fileExistsAtPath:self.configFilePath]) {
// As soon as saveConfigToDisk is called, reloadConfigData will be called again because
// of the SNTFileWatchers on the config path. No need to use dictionaryWithCapacity: here.
self.configData = [NSMutableDictionary dictionary];
self.configData[kClientModeKey] = @(SNTClientModeMonitor);
[self saveConfigToDisk];
return;
};
NSError *error;
NSData *readData = [NSData dataWithContentsOfFile:self.configFilePath

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
///
/// Simple function to check and drop root privileges.
///

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
///
/// Represents a binary on disk, providing access to details about that binary
/// such as the SHA-1, SHA-256, Info.plist and the Mach-O data.

View File

@@ -12,6 +12,8 @@
/// 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

View File

@@ -18,7 +18,7 @@
@interface SNTFileWatcher ()
@property NSString *filePath;
@property(strong) void (^handler)(unsigned long);
@property(copy) void (^handler)(unsigned long);
@property dispatch_source_t source;
@end
@@ -52,7 +52,8 @@
dispatch_async(queue, ^{
int fd = -1;
while ((fd = open([self.filePath fileSystemRepresentation], O_EVTONLY | O_CLOEXEC)) < 0) {
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);

View File

@@ -34,6 +34,8 @@
#else // KERNEL
@import Foundation;
typedef enum : NSUInteger {
LOG_LEVEL_ERROR,
LOG_LEVEL_WARN,

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommonEnums.h"
///

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommonEnums.h"
///
@@ -20,7 +22,7 @@
@interface SNTStoredEvent : NSObject<NSSecureCoding>
///
/// An index for this event, empty unless the event came from the database.
/// An index for this event, randomly generated during initialization.
///
@property NSNumber *idx;

View File

@@ -57,6 +57,14 @@
ENCODE(self.quarantineAgentBundleID, @"quarantineAgentBundleID");
}
- (instancetype)init {
self = [super init];
if (self) {
_idx = @(arc4random());
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (self) {

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
///
/// Simple class for fetching system information
///

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
/**
A wrapper around NSXPCListener and NSXPCConnection to provide client multiplexing, signature
validation of connecting clients and forced connection establishment.

View File

@@ -113,8 +113,10 @@
// send a message to the listener to finish establishing the connection
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
self.currentConnection.remoteObjectInterface = self.validationInterface;
self.currentConnection.interruptionHandler = self.invalidationHandler;
self.currentConnection.invalidationHandler = self.invalidationHandler;
self.currentConnection.interruptionHandler = self.currentConnection.invalidationHandler = ^{
STRONGIFY(self);
if (self.invalidationHandler) self.invalidationHandler();
};
[self.currentConnection resume];
[[self.currentConnection remoteObjectProxy] connectWithReply:^{
STRONGIFY(self);

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <MOLCertificate/MOLCertificate.h>
#import "SNTCachedDecision.h"
@@ -41,9 +43,7 @@
- (void)databaseRuleAddRules:(NSArray *)rules
cleanSlate:(BOOL)cleanSlate
reply:(void (^)(NSError *error))reply;
- (void)databaseEventCount:(void (^)(int64_t count))reply;
- (void)databaseEventForSHA256:(NSString *)sha256 reply:(void (^)(SNTStoredEvent *))reply;
- (void)databaseEventsPending:(void (^)(NSArray *events))reply;
- (void)databaseRemoveEventsWithIDs:(NSArray *)ids;
- (void)databaseRuleForBinarySHA256:(NSString *)binarySHA256
@@ -74,8 +74,8 @@
- (void)setClientMode:(SNTClientMode)mode reply:(void (^)())reply;
- (void)xsrfToken:(void (^)(NSString *))reply;
- (void)setXsrfToken:(NSString *)token reply:(void (^)())reply;
- (void)setNextSyncInterval:(uint64_t)seconds reply:(void (^)())reply;
- (void)setSyncLastSuccess:(NSDate *)date reply:(void (^)())reply;
- (void)setRuleSyncLastSuccess:(NSDate *)date reply:(void (^)())reply;
- (void)setSyncCleanRequired:(BOOL)cleanReqd reply:(void (^)())reply;
- (void)setWhitelistPathRegex:(NSString *)pattern reply:(void (^)())reply;
- (void)setBlacklistPathRegex:(NSString *)pattern reply:(void (^)())reply;
@@ -85,6 +85,14 @@
///
- (void)setNotificationListener:(NSXPCListenerEndpoint *)listener;
///
/// Syncd Ops
///
- (void)setSyncdListener:(NSXPCListenerEndpoint *)listener;
- (void)setNextSyncInterval:(uint64_t)seconds reply:(void (^)())reply;
- (void)pushNotifications:(void (^)(BOOL))reply;
- (void)postRuleSyncNotificationWithCustomMessage:(NSString *)message reply:(void (^)())reply;
@end
@interface SNTXPCControlInterface : NSObject

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommonEnums.h"
@class SNTStoredEvent;
@@ -20,6 +22,7 @@
@protocol SNTNotifierXPC
- (void)postBlockNotification:(SNTStoredEvent *)event withCustomMessage:(NSString *)message;
- (void)postClientModeNotification:(SNTClientMode)clientmode;
- (void)postRuleSyncNotificationWithCustomMessage:(NSString *)message;
@end
@interface SNTXPCNotifierInterface : NSObject

View File

@@ -0,0 +1,36 @@
/// Copyright 2016 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;
#import "SNTCommonEnums.h"
@class SNTStoredEvent;
/// Protocol implemented by santactl and utilized by santad
@protocol SNTSyncdXPC
- (void)postEventToSyncServer:(SNTStoredEvent *)event;
- (void)rescheduleSyncSecondsFromNow:(uint64_t)seconds;
- (void)isFCMListening:(void (^)(BOOL))reply;
@end
@interface SNTXPCSyncdInterface : NSObject
///
/// Returns an initialized NSXPCInterface for the SNTSyncdXPC protocol.
/// Ensures any methods that accept custom classes as arguments are set-up before returning
///
+ (NSXPCInterface *)syncdInterface;
@end

View File

@@ -0,0 +1,23 @@
/// Copyright 2016 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 "SNTXPCSyncdInterface.h"
@implementation SNTXPCSyncdInterface
+ (NSXPCInterface *)syncdInterface {
return [NSXPCInterface interfaceWithProtocol:@protocol(SNTSyncdXPC)];
}
@end

View File

@@ -247,7 +247,7 @@ template<class T> class SantaCache {
/**
Holder for a 'zero' entry for the current type
*/
T zero_ = {};
const T zero_ = T(0);
/**
Special bucket used when automatically clearing due to size

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandController.h"
#import "SNTLogging.h"

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandController.h"
#import <MOLCertificate/MOLCertificate.h>
@@ -275,9 +277,9 @@ REGISTER_COMMAND_NAME(@"fileinfo")
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
if (!fi.csc) {
NSError *error;
fi.csc = [[MOLCodesignChecker alloc] initWithBinaryPath:fi.filePath error:&error];
fi.csc = [[MOLCodesignChecker alloc] initWithBinaryPath:fi.path(fi) error:&error];
}
[[fi.daemonConn remoteObjectProxy] decisionForFilePath:fi.filePath
[[fi.daemonConn remoteObjectProxy] decisionForFilePath:fi.path(fi)
fileSHA256:fi.propertyMap[kSHA256](fi)
signingCertificate:fi.csc.leafCertificate
reply:^(SNTEventState state) {

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandController.h"
#import "SNTLogging.h"

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandController.h"
#include "SNTLogging.h"

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandController.h"
#import "SNTConfigurator.h"
@@ -102,10 +104,22 @@ REGISTER_COMMAND_NAME(@"status")
NSString *syncURLStr = [[[SNTConfigurator configurator] syncBaseURL] absoluteString];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"yyyy/MM/dd HH:mm:ss Z";
NSDate *lastSyncSuccess = [[SNTConfigurator configurator] syncLastSuccess];
NSDate *lastSyncSuccess = [[SNTConfigurator configurator] fullSyncLastSuccess];
NSString *lastSyncSuccessStr = [dateFormatter stringFromDate:lastSyncSuccess] ?: @"Never";
NSDate *lastRuleSyncSuccess = [[SNTConfigurator configurator] ruleSyncLastSuccess];
NSString *lastRuleSyncSuccessStr =
[dateFormatter stringFromDate:lastRuleSyncSuccess] ?: lastSyncSuccessStr;
BOOL syncCleanReqd = [[SNTConfigurator configurator] syncCleanRequired];
__block BOOL pushNotifications = NO;
if ([[SNTConfigurator configurator] syncBaseURL]) {
dispatch_group_enter(group);
[[daemonConn remoteObjectProxy] pushNotifications:^(BOOL response) {
pushNotifications = response;
dispatch_group_leave(group);
}];
}
// Wait a maximum of 5s for stats collected from daemon to arrive.
if (dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 5))) {
fprintf(stderr, "Failed to retrieve some stats from daemon\n\n");
@@ -114,7 +128,7 @@ REGISTER_COMMAND_NAME(@"status")
if ([arguments containsObject:@"--json"]) {
NSDictionary *stats = @{
@"daemon" : @{
@"mode" : clientMode,
@"mode" : clientMode ?: @"null",
@"file_logging" : @(fileLogging),
@"watchdog_cpu_events" : @(cpuEvents),
@"watchdog_ram_events" : @(ramEvents),
@@ -130,9 +144,11 @@ REGISTER_COMMAND_NAME(@"status")
@"events_pending_upload" : @(eventCount),
},
@"sync" : @{
@"server" : syncURLStr,
@"server" : syncURLStr ?: @"null",
@"clean_required" : @(syncCleanReqd),
@"last_successful" : lastSyncSuccessStr
@"last_successful_full" : lastSyncSuccessStr ?: @"null",
@"last_successful_rule" : lastRuleSyncSuccessStr ?: @"null",
@"push_notifications" : pushNotifications ? @"Connected" : @"Disconnected"
},
};
NSData *statsData = [NSJSONSerialization dataWithJSONObject:stats
@@ -142,22 +158,25 @@ REGISTER_COMMAND_NAME(@"status")
printf("%s\n", [statsStr UTF8String]);
} else {
printf(">>> Daemon Info\n");
printf(" %-22s | %s\n", "Mode", [clientMode UTF8String]);
printf(" %-22s | %s\n", "File Logging", (fileLogging ? "Yes" : "No"));
printf(" %-22s | %lld (Peak: %.2f%%)\n", "Watchdog CPU Events", cpuEvents, cpuPeak);
printf(" %-22s | %lld (Peak: %.2fMB)\n", "Watchdog RAM Events", ramEvents, ramPeak);
printf(" %-25s | %s\n", "Mode", [clientMode UTF8String]);
printf(" %-25s | %s\n", "File Logging", (fileLogging ? "Yes" : "No"));
printf(" %-25s | %lld (Peak: %.2f%%)\n", "Watchdog CPU Events", cpuEvents, cpuPeak);
printf(" %-25s | %lld (Peak: %.2fMB)\n", "Watchdog RAM Events", ramEvents, ramPeak);
printf(">>> Kernel Info\n");
printf(" %-22s | %lld\n", "Kernel cache count", cacheCount);
printf(" %-25s | %lld\n", "Kernel cache count", cacheCount);
printf(">>> Database Info\n");
printf(" %-22s | %lld\n", "Binary Rules", binaryRuleCount);
printf(" %-22s | %lld\n", "Certificate Rules", certRuleCount);
printf(" %-22s | %lld\n", "Events Pending Upload", eventCount);
printf(" %-25s | %lld\n", "Binary Rules", binaryRuleCount);
printf(" %-25s | %lld\n", "Certificate Rules", certRuleCount);
printf(" %-25s | %lld\n", "Events Pending Upload", eventCount);
if (syncURLStr) {
printf(">>> Sync Info\n");
printf(" %-22s | %s\n", "Sync Server", [syncURLStr UTF8String]);
printf(" %-22s | %s\n", "Clean Sync Required", (syncCleanReqd ? "Yes" : "No"));
printf(" %-22s | %s\n", "Last Successful Sync", [lastSyncSuccessStr UTF8String]);
printf(" %-25s | %s\n", "Sync Server", [syncURLStr UTF8String]);
printf(" %-25s | %s\n", "Clean Sync Required", (syncCleanReqd ? "Yes" : "No"));
printf(" %-25s | %s\n", "Last Successful Full Sync", [lastSyncSuccessStr UTF8String]);
printf(" %-25s | %s\n", "Last Successful Rule Sync", [lastRuleSyncSuccessStr UTF8String]);
printf(" %-25s | %s\n", "Push Notifications",
(pushNotifications ? "Connected" : "Disconnected"));
}
}

View File

@@ -12,9 +12,11 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandController.h"
#include <IOKit/kext/KextManager.h>
@import IOKit.kext;
#import "SNTCommonEnums.h"
#import "SNTFileInfo.h"

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
/// Category on NSData providing the option of getting zlib or gzip compressed data.
@interface NSData (Zlib)

View File

@@ -12,16 +12,11 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandController.h"
#import <MOLAuthenticatingURLSession.h>
#import "SNTCommandSyncEventUpload.h"
#import "SNTCommandSyncLogUpload.h"
#import "SNTCommandSyncPostflight.h"
#import "SNTCommandSyncPreflight.h"
#import "SNTCommandSyncRuleDownload.h"
#import "SNTCommandSyncState.h"
#import "SNTCommandSyncManager.h"
#import "SNTConfigurator.h"
#import "SNTDropRootPrivs.h"
#import "SNTLogging.h"
@@ -29,19 +24,22 @@
#import "SNTXPCControlInterface.h"
@interface SNTCommandSync : NSObject<SNTCommand>
@property SNTCommandSyncState *syncState;
@property SNTXPCConnection *listener;
@property SNTCommandSyncManager *syncManager;
@end
@implementation SNTCommandSync
REGISTER_COMMAND_NAME(@"sync")
#pragma mark SNTCommand protocol methods
+ (BOOL)requiresRoot {
return NO;
}
+ (BOOL)requiresDaemonConn {
return YES;
return NO;
}
+ (NSString *)shortHelpText {
@@ -63,36 +61,11 @@ REGISTER_COMMAND_NAME(@"sync")
exit(1);
}
SNTConfigurator *config = [SNTConfigurator configurator];
SNTCommandSync *s = [[self alloc] init];
// Gather some data needed during some sync stages
s.syncState = [[SNTCommandSyncState alloc] init];
s.syncState.syncBaseURL = config.syncBaseURL;
if (s.syncState.syncBaseURL.absoluteString.length == 0) {
LOGE(@"Missing SyncBaseURL. Can't sync without it.");
exit(1);
} else if (![s.syncState.syncBaseURL.scheme isEqual:@"https"]) {
LOGW(@"SyncBaseURL is not over HTTPS!");
}
s.syncState.machineID = config.machineID;
if (s.syncState.machineID.length == 0) {
LOGE(@"Missing Machine ID. Can't sync without it.");
exit(1);
}
s.syncState.machineOwner = config.machineOwner;
if (s.syncState.machineOwner.length == 0) {
s.syncState.machineOwner = @"";
LOGW(@"Missing Machine Owner.");
}
[[daemonConn remoteObjectProxy] xsrfToken:^(NSString *token) {
s.syncState.xsrfToken = token;
}];
[daemonConn resume];
BOOL daemon = [arguments containsObject:@"--daemon"];
s.syncManager = [[SNTCommandSyncManager alloc] initWithDaemonConnection:daemonConn
isDaemon:daemon];
// Dropping root privileges to the 'nobody' user causes the default NSURLCache to throw
// sandbox errors, which are benign but annoying. This line disables the cache entirely.
@@ -100,138 +73,40 @@ REGISTER_COMMAND_NAME(@"sync")
diskCapacity:0
diskPath:nil]];
if (!s.syncManager.daemon) return [s.syncManager fullSync];
[s syncdWithDaemonConnection:daemonConn];
}
MOLAuthenticatingURLSession *authURLSession = [[MOLAuthenticatingURLSession alloc] init];
authURLSession.userAgent = @"santactl-sync/";
NSString *santactlVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
if (santactlVersion) {
authURLSession.userAgent = [authURLSession.userAgent stringByAppendingString:santactlVersion];
}
authURLSession.refusesRedirects = YES;
authURLSession.serverHostname = s.syncState.syncBaseURL.host;
authURLSession.loggingBlock = ^(NSString *line) {
LOGD(@"%@", line);
#pragma mark daemon methods
- (void)syncdWithDaemonConnection:(SNTXPCConnection *)daemonConn {
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
// Create listener for return connection from daemon.
NSXPCListener *listener = [NSXPCListener anonymousListener];
self.listener = [[SNTXPCConnection alloc] initServerWithListener:listener];
self.listener.exportedInterface = [SNTXPCSyncdInterface syncdInterface];
self.listener.exportedObject = self.syncManager;
self.listener.acceptedHandler = ^{
LOGD(@"santad <--> santactl connections established");
dispatch_semaphore_signal(sema);
};
// Configure server auth
if ([config syncServerAuthRootsFile]) {
authURLSession.serverRootsPemFile = [config syncServerAuthRootsFile];
} else if ([config syncServerAuthRootsData]) {
authURLSession.serverRootsPemData = [config syncServerAuthRootsData];
}
// Configure client auth
if ([config syncClientAuthCertificateFile]) {
authURLSession.clientCertFile = [config syncClientAuthCertificateFile];
authURLSession.clientCertPassword = [config syncClientAuthCertificatePassword];
} else if ([config syncClientAuthCertificateCn]) {
authURLSession.clientCertCommonName = [config syncClientAuthCertificateCn];
} else if ([config syncClientAuthCertificateIssuer]) {
authURLSession.clientCertIssuerCn = [config syncClientAuthCertificateIssuer];
}
s.syncState.session = [authURLSession session];
s.syncState.daemonConn = daemonConn;
if ([arguments containsObject:@"singleevent"]) {
NSUInteger idx = [arguments indexOfObject:@"singleevent"] + 1;
if (idx >= arguments.count) {
LOGI(@"singleevent takes an argument");
exit(1);
}
NSString *obj = arguments[idx];
if (obj.length != 64) {
LOGI(@"singleevent passed without SHA-256 as next argument");
exit(1);
}
return [s eventUploadSingleEvent:obj];
} else {
return [s preflight];
}
}
- (void)preflight {
SNTCommandSyncPreflight *p = [[SNTCommandSyncPreflight alloc] initWithState:self.syncState];
if ([p sync]) {
LOGD(@"Preflight complete");
if (self.syncState.uploadLogURL) {
return [self logUpload];
} else {
return [self eventUpload];
}
} else {
LOGE(@"Preflight failed, aborting run");
exit(1);
}
}
- (void)logUpload {
SNTCommandSyncLogUpload *p = [[SNTCommandSyncLogUpload alloc] initWithState:self.syncState];
if ([p sync]) {
LOGD(@"Log upload complete");
} else {
LOGE(@"Log upload failed, continuing anyway");
}
return [self eventUpload];
}
- (void)eventUpload {
SNTCommandSyncEventUpload *p = [[SNTCommandSyncEventUpload alloc] initWithState:self.syncState];
if ([p sync]) {
LOGD(@"Event upload complete");
return [self ruleDownload];
} else {
LOGE(@"Event upload failed, aborting run");
exit(1);
}
}
- (void)eventUploadSingleEvent:(NSString *)sha256 {
SNTCommandSyncEventUpload *p = [[SNTCommandSyncEventUpload alloc] initWithState:self.syncState];
if ([p syncSingleEventWithSHA256:sha256]) {
LOGD(@"Event upload complete");
self.listener.invalidationHandler = ^{
// If santad is unloaded kill santactl
LOGD(@"exiting");
exit(0);
} else {
LOGE(@"Event upload failed");
exit(1);
}
}
};
[self.listener resume];
- (void)ruleDownload {
SNTCommandSyncRuleDownload *p = [[SNTCommandSyncRuleDownload alloc] initWithState:self.syncState];
if ([p sync]) {
LOGD(@"Rule download complete");
if (self.syncState.bundleBinaryRequests.count) {
return [self eventUploadBundleBinaries];
}
return [self postflight];
} else {
LOGE(@"Rule download failed, aborting run");
exit(1);
}
}
// Tell daemon to connect back to the above listener.
[[daemonConn remoteObjectProxy] setSyncdListener:listener.endpoint];
- (void)eventUploadBundleBinaries {
SNTCommandSyncEventUpload *p = [[SNTCommandSyncEventUpload alloc] initWithState:self.syncState];
if ([p syncBundleEvents]) {
LOGD(@"Event upload for bundle binaries complete");
} else {
LOGW(@"Event upload for bundle binary search failed");
// Now wait for the connection to come in.
if (dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) {
[self performSelectorInBackground:@selector(syncdWithDaemonConnection:) withObject:daemonConn];
}
return [self postflight];
}
- (void)postflight {
SNTCommandSyncPostflight *p = [[SNTCommandSyncPostflight alloc] initWithState:self.syncState];
if ([p sync]) {
LOGD(@"Postflight complete");
LOGI(@"Sync completed successfully");
exit(0);
} else {
LOGE(@"Postflight failed");
exit(1);
}
[self.syncManager fullSyncSecondsFromNow:15];
}
@end

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
extern NSString *const kXSRFToken;
extern NSString *const kSerialNumber;
@@ -31,6 +33,7 @@ extern NSString *const kWhitelistRegex;
extern NSString *const kBlacklistRegex;
extern NSString *const kBinaryRuleCount;
extern NSString *const kCertificateRuleCount;
extern NSString *const kFCMToken;
extern NSString *const kEvents;
extern NSString *const kFileSHA256;
@@ -88,3 +91,8 @@ extern NSString *const kRuleCustomMsg;
extern NSString *const kCursor;
extern NSString *const kBackoffInterval;
extern NSString *const kFullSync;
extern NSString *const kRuleSync;
extern NSString *const kConfigSync;
extern NSString *const kLogSync;

View File

@@ -33,6 +33,7 @@ NSString *const kWhitelistRegex = @"whitelist_regex";
NSString *const kBlacklistRegex = @"blacklist_regex";
NSString *const kBinaryRuleCount = @"binary_rule_count";
NSString *const kCertificateRuleCount = @"certificate_rule_count";
NSString *const kFCMToken = @"fcm_token";
NSString *const kEvents = @"events";
NSString *const kFileSHA256 = @"file_sha256";
@@ -90,3 +91,8 @@ NSString *const kRuleCustomMsg = @"custom_msg";
NSString *const kCursor = @"cursor";
NSString *const kBackoffInterval = @"backoff";
NSString *const kFullSync = @"full_sync";
NSString *const kRuleSync = @"rule_sync";
NSString *const kConfigSync = @"config_sync";
NSString *const kLogSync = @"log_sync";

View File

@@ -12,12 +12,12 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandSyncStage.h"
@interface SNTCommandSyncEventUpload : SNTCommandSyncStage
- (BOOL)syncSingleEventWithSHA256:(NSString *)sha256;
- (BOOL)syncBundleEvents;
- (BOOL)uploadEvents:(NSArray *)events;
@end

View File

@@ -44,39 +44,6 @@
return (dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER) == 0);
}
- (BOOL)syncSingleEventWithSHA256:(NSString *)sha256 {
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[[self.daemonConn remoteObjectProxy] databaseEventForSHA256:sha256 reply:^(SNTStoredEvent *e) {
if (e) {
[self uploadEvents:@[ e ]];
}
dispatch_semaphore_signal(sema);
}];
return (dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER) == 0);
}
- (BOOL)syncBundleEvents {
NSMutableArray *newEvents = [NSMutableArray array];
for (NSString *bundlePath in [NSSet setWithArray:self.syncState.bundleBinaryRequests]) {
__block NSArray *relatedBinaries;
__block BOOL shouldCancel = NO;
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
relatedBinaries = [self findRelatedBinaries:bundlePath shouldCancel:&shouldCancel];
dispatch_semaphore_signal(sema);
});
// Give the search up to 5m to run
if (dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 300))) {
LOGD(@"Timed out while searching for related binaries at path %@", bundlePath);
shouldCancel = YES;
} else {
[newEvents addObjectsFromArray:relatedBinaries];
}
}
return [self uploadEvents:newEvents];
}
- (BOOL)uploadEvents:(NSArray *)events {
NSMutableArray *uploadEvents = [[NSMutableArray alloc] init];
@@ -90,9 +57,6 @@
NSDictionary *r = [self performRequest:[self requestWithDictionary:@{ kEvents: uploadEvents }]];
if (!r) return NO;
// Keep track of bundle search requests
self.syncState.bundleBinaryRequests = r[kEventUploadBundleBinaries];
LOGI(@"Uploaded %lu events", uploadEvents.count);
// Remove event IDs. For Bundle Events the ID is 0 so nothing happens.
@@ -172,73 +136,4 @@
#undef ADDKEY
}
/**
Find binaries within a bundle given the bundle's path. Will run until completion, however long
that might be. Search is done within the bundle concurrently, using up to 25 threads at once.
@param path, the path to begin searching underneath
@param shouldCancel, if YES, the search is cancelled part way through.
@return array of SNTStoredEvent's
*/
- (NSArray *)findRelatedBinaries:(NSString *)path shouldCancel:(BOOL *)shouldCancel {
// For storing the generated events, with a simple lock for writing.
NSMutableArray *relatedEvents = [NSMutableArray array];
NSLock *relatedEventsLock = [[NSLock alloc] init];
// Limit the number of threads that can process files at once to keep CPU usage down.
dispatch_semaphore_t sema = dispatch_semaphore_create(25);
// Group the processing into a single group so we can wait on the whole group at the end.
dispatch_group_t group = dispatch_group_create();
NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:path];
while (1) {
@autoreleasepool {
if (*shouldCancel) break;
NSString *file = [dirEnum nextObject];
if (!file) break;
if ([dirEnum fileAttributes][NSFileType] != NSFileTypeRegular) continue;
// Wait for a processing thread to become available
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_group_async(group,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),
^{
@autoreleasepool {
NSString *newFile = [path stringByAppendingPathComponent:file];
SNTFileInfo *fi = [[SNTFileInfo alloc] initWithPath:newFile];
if (!fi.isExecutable) {
dispatch_semaphore_signal(sema);
return;
}
SNTStoredEvent *se = [[SNTStoredEvent alloc] init];
se.filePath = fi.path;
se.fileSHA256 = fi.SHA256;
se.decision = SNTEventStateBundleBinary;
se.fileBundleID = fi.bundleIdentifier;
se.fileBundleName = fi.bundleName;
se.fileBundlePath = fi.bundlePath;
se.fileBundleVersion = fi.bundleVersion;
se.fileBundleVersionString = fi.bundleShortVersionString;
MOLCodesignChecker *cs = [[MOLCodesignChecker alloc] initWithBinaryPath:se.filePath];
se.signingChain = cs.certificates;
[relatedEventsLock lock];
[relatedEvents addObject:se];
[relatedEventsLock unlock];
dispatch_semaphore_signal(sema);
}
});
}
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
return relatedEvents;
}
@end

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandSyncStage.h"
@interface SNTCommandSyncLogUpload : SNTCommandSyncStage

View File

@@ -0,0 +1,55 @@
/// Copyright 2016 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;
#import "SNTXPCSyncdInterface.h"
@class SNTXPCConnection;
///
/// Handles push notifications and periodic syncing with a sync server.
///
@interface SNTCommandSyncManager : NSObject<SNTSyncdXPC>
@property(readonly, nonatomic) BOOL daemon;
///
/// Use the designated initializer initWithDaemonConnection:isDaemon:
///
- (instancetype)init NS_UNAVAILABLE;
///
/// Designated initializer.
///
/// @param daemonConn A connection to santad.
/// @param daemon Set to YES if periodic syncing should occur.
/// Set to NO if a single sync should be performed. NO is default.
///
- (instancetype)initWithDaemonConnection:(SNTXPCConnection *)daemonConn
isDaemon:(BOOL)daemon NS_DESIGNATED_INITIALIZER;
///
/// Perform a full sync immediately. Non-blocking.
/// If a full sync is already running new requests will be dropped.
///
- (void)fullSync;
///
/// Perform a full sync seconds from now. Non-blocking.
/// If a full sync is already running new requests will be dropped.
///
- (void)fullSyncSecondsFromNow:(uint64_t)seconds;
@end

View File

@@ -0,0 +1,463 @@
/// Copyright 2016 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 "SNTCommandSyncManager.h"
@import SystemConfiguration;
#import <MOLAuthenticatingURLSession.h>
#import <MOLFCMClient/MOLFCMClient.h>
#import "SNTConfigurator.h"
#import "SNTCommandSyncConstants.h"
#import "SNTCommandSyncEventUpload.h"
#import "SNTCommandSyncLogUpload.h"
#import "SNTCommandSyncPostflight.h"
#import "SNTCommandSyncPreflight.h"
#import "SNTCommandSyncRuleDownload.h"
#import "SNTCommandSyncState.h"
#import "SNTLogging.h"
#import "SNTStrengthify.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
#import "SNTXPCSyncdInterface.h"
// Syncing time constant
const uint64_t kFullSyncInterval = 600;
@interface SNTCommandSyncManager () {
SCNetworkReachabilityRef _reachability;
}
@property(nonatomic) dispatch_source_t fullSyncTimer;
@property(nonatomic) dispatch_source_t ruleSyncTimer;
@property(nonatomic) NSCache *dispatchLock;
@property(nonatomic) NSCache *ruleSyncCache;
@property MOLFCMClient *FCMClient;
@property(nonatomic) SNTXPCConnection *daemonConn;
@property BOOL targetedRuleSync;
@property(nonatomic) BOOL reachable;
@end
// Called when the network state changes
static void reachabilityHandler(
SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info) {
// Ensure state changes are processed in order.
dispatch_async(dispatch_get_main_queue(), ^{
SNTCommandSyncManager *commandSyncManager = (__bridge SNTCommandSyncManager *)info;
// Only call the setter when there is a change. This will filter out the redundant calls to this
// callback whenever the network interface states change.
if (commandSyncManager.reachable != (flags & kSCNetworkReachabilityFlagsReachable)) {
commandSyncManager.reachable = (flags & kSCNetworkReachabilityFlagsReachable);
}
});
}
@implementation SNTCommandSyncManager
#pragma mark init
- (instancetype)initWithDaemonConnection:(SNTXPCConnection *)daemonConn isDaemon:(BOOL)daemon {
self = [super init];
if (self) {
_daemonConn = daemonConn;
_daemon = daemon;
_fullSyncTimer = [self createSyncTimerWithBlock:^{
[self rescheduleTimerQueue:self.fullSyncTimer
secondsFromNow:[SNTConfigurator configurator].FCMFullSyncInterval];
if (![[SNTConfigurator configurator] syncBaseURL]) return;
[self lockAction:kFullSync];
[self preflight];
[self unlockAction:kFullSync];
}];
_ruleSyncTimer = [self createSyncTimerWithBlock:^{
dispatch_source_set_timer(self.ruleSyncTimer,
DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, 0);
if (![[SNTConfigurator configurator] syncBaseURL]) return;
[self lockAction:kRuleSync];
SNTCommandSyncState *syncState = [self createSyncState];
syncState.targetedRuleSync = self.targetedRuleSync;
syncState.ruleSyncCache = self.ruleSyncCache;
SNTCommandSyncRuleDownload *p = [[SNTCommandSyncRuleDownload alloc] initWithState:syncState];
if ([p sync]) {
LOGD(@"Rule download complete");
} else {
LOGE(@"Rule download failed");
}
self.targetedRuleSync = NO;
[self unlockAction:kRuleSync];
}];
_dispatchLock = [[NSCache alloc] init];
_ruleSyncCache = [[NSCache alloc] init];
}
return self;
}
#pragma mark SNTSyncdXPC protocol methods
- (void)postEventToSyncServer:(SNTStoredEvent *)event {
SNTCommandSyncEventUpload *p = [[SNTCommandSyncEventUpload alloc]
initWithState:[self createSyncState]];
if (event && [p uploadEvents:@[event]]) {
LOGD(@"Event upload complete");
} else {
LOGE(@"Event upload failed");
}
}
- (void)rescheduleSyncSecondsFromNow:(uint64_t)seconds {
[self rescheduleTimerQueue:self.fullSyncTimer secondsFromNow:seconds];
}
- (void)isFCMListening:(void (^)(BOOL))reply {
reply((self.FCMClient.FCMToken != nil));
}
#pragma mark push notification methods
- (void)listenForPushNotificationsWithSyncState:(SNTCommandSyncState *)syncState {
if ([self.FCMClient.FCMToken isEqualToString:syncState.FCMToken]) {
LOGD(@"Continue with the current FCMToken");
return;
}
LOGD(@"Start listening for push notifications");
WEAKIFY(self);
[self.FCMClient disconnect];
NSString *machineID = syncState.machineID;
self.FCMClient = [[MOLFCMClient alloc] initWithFCMToken:syncState.FCMToken
sessionConfiguration:syncState.session.configuration.copy
messageHandler:^(NSDictionary *message) {
if (!message || [message isEqual:@{}]) return;
STRONGIFY(self);
LOGD(@"%@", message);
[self.FCMClient acknowledgeMessage:message];
[self processFCMMessage:message withMachineID:machineID];
}];
self.FCMClient.connectionErrorHandler = ^(NSError *error) {
STRONGIFY(self);
LOGE(@"FCM connection error: %@", error);
[self.FCMClient disconnect];
self.FCMClient = nil;
[self rescheduleTimerQueue:self.fullSyncTimer secondsFromNow:kFullSyncInterval];
};
self.FCMClient.loggingBlock = ^(NSString *log) {
LOGD(@"%@", log);
};
[self.FCMClient connect];
}
- (void)processFCMMessage:(NSDictionary *)FCMmessage withMachineID:(NSString *)machineID {
NSData *messageData = [self extractMessageDataFrom:FCMmessage];
if (!messageData) {
LOGD(@"Push notification message is not in the expected format...dropping message");
return;
}
NSError *error;
NSDictionary *actionMessage = [NSJSONSerialization JSONObjectWithData:messageData
options:0
error:&error];
if (!actionMessage) {
LOGD(@"Unable to parse push notification message value: %@", error);
return;
}
// Store the file name and hash in a cache. When the rule is actually added, use the cache
// to build a user notification.
NSString *fileHash = actionMessage[@"file_hash"];
NSString *fileName = actionMessage[@"file_name"];
if (fileName && fileHash) {
[self.ruleSyncCache setObject:fileName forKey:fileHash];
}
NSString *action = actionMessage[@"action"];
if (action) {
LOGD(@"Push notification action: %@ received", action);
} else {
LOGD(@"Push notification message contains no action");
}
if ([action isEqualToString:kFullSync]) {
[self fullSync];
} else if ([action isEqualToString:kRuleSync]) {
NSString *targetMachineID = actionMessage[@"target_host_id"];
if (![targetMachineID isKindOfClass:[NSNull class]] &&
[targetMachineID.lowercaseString isEqualToString:machineID.lowercaseString]) {
self.targetedRuleSync = YES;
[self ruleSync];
} else {
uint32_t delaySeconds =
arc4random_uniform((u_int32_t)[SNTConfigurator configurator].FCMGlobalRuleLeeway);
LOGD(@"Staggering rule download, %u second delay for this machine", delaySeconds);
[self ruleSyncSecondsFromNow:delaySeconds];
}
} else if ([action isEqualToString:kConfigSync]) {
[self fullSync];
} else if ([action isEqualToString:kLogSync]) {
[self fullSync];
} else {
LOGD(@"Unrecognised action: %@", action);
}
}
- (NSData *)extractMessageDataFrom:(NSDictionary *)FCMmessage {
if (![FCMmessage[@"data"] isKindOfClass:[NSDictionary class]]) return nil;
if (![FCMmessage[@"data"][@"blob"] isKindOfClass:[NSString class]]) return nil;
return [FCMmessage[@"data"][@"blob"] dataUsingEncoding:NSUTF8StringEncoding];
}
#pragma mark sync timer control
- (void)fullSync {
[self fullSyncSecondsFromNow:0];
}
- (void)fullSyncSecondsFromNow:(uint64_t)seconds {
if (![self checkLockAction:kFullSync]) {
LOGD(@"%@ in progress, dropping reschedule request", kFullSync);
return;
}
[self rescheduleTimerQueue:self.fullSyncTimer secondsFromNow:seconds];
}
- (void)ruleSync {
[self ruleSyncSecondsFromNow:0];
}
- (void)ruleSyncSecondsFromNow:(uint64_t)seconds {
if (![self checkLockAction:kRuleSync]) {
LOGD(@"%@ in progress, dropping reschedule request", kRuleSync);
return;
}
[self rescheduleTimerQueue:self.ruleSyncTimer secondsFromNow:seconds];
}
- (void)rescheduleTimerQueue:(dispatch_source_t)timerQueue secondsFromNow:(uint64_t)seconds {
uint64_t interval = seconds * NSEC_PER_SEC;
uint64_t leeway = (seconds * 0.5) * NSEC_PER_SEC;
dispatch_source_set_timer(timerQueue, dispatch_walltime(NULL, interval), interval, leeway);
}
#pragma mark syncing chain
- (void)preflight {
SNTCommandSyncState *syncState = [self createSyncState];
SNTCommandSyncPreflight *p = [[SNTCommandSyncPreflight alloc] initWithState:syncState];
if ([p sync]) {
LOGD(@"Preflight complete");
// Clean up reachability if it was started for a non-network error
[self stopReachability];
// Start listening for push notifications with a full sync every kFullSyncFCMInterval or
// revert to full syncing every kFullSyncInterval.
if (syncState.daemon && syncState.FCMToken) {
[self listenForPushNotificationsWithSyncState:syncState];
} else if (syncState.daemon) {
LOGD(@"FCMToken not provided. Sync every %llu min.", kFullSyncInterval / 60);
[self.FCMClient disconnect];
self.FCMClient = nil;
[self rescheduleTimerQueue:self.fullSyncTimer secondsFromNow:kFullSyncInterval];
}
if (syncState.uploadLogURL) {
return [self logUploadWithSyncState:syncState];
} else {
return [self eventUploadWithSyncState:syncState];
}
} else {
if (!syncState.daemon) {
LOGE(@"Preflight failed, aborting run");
exit(1);
}
LOGE(@"Preflight failed, will try again once %@ is reachable",
[[SNTConfigurator configurator] syncBaseURL].absoluteString);
[self startReachability];
}
}
- (void)logUploadWithSyncState:(SNTCommandSyncState *)syncState {
SNTCommandSyncLogUpload *p = [[SNTCommandSyncLogUpload alloc] initWithState:syncState];
if ([p sync]) {
LOGD(@"Log upload complete");
} else {
LOGE(@"Log upload failed, continuing anyway");
}
return [self eventUploadWithSyncState:syncState];
}
- (void)eventUploadWithSyncState:(SNTCommandSyncState *)syncState {
SNTCommandSyncEventUpload *p = [[SNTCommandSyncEventUpload alloc] initWithState:syncState];
if ([p sync]) {
LOGD(@"Event upload complete");
return [self ruleDownloadWithSyncState:syncState];
} else {
LOGE(@"Event upload failed, aborting run");
if (!syncState.daemon) exit(1);
}
}
- (void)ruleDownloadWithSyncState:(SNTCommandSyncState *)syncState {
SNTCommandSyncRuleDownload *p = [[SNTCommandSyncRuleDownload alloc] initWithState:syncState];
if ([p sync]) {
LOGD(@"Rule download complete");
return [self postflightWithSyncState:syncState];
} else {
LOGE(@"Rule download failed, aborting run");
if (!syncState.daemon) exit(1);
}
}
- (void)postflightWithSyncState:(SNTCommandSyncState *)syncState {
SNTCommandSyncPostflight *p = [[SNTCommandSyncPostflight alloc] initWithState:syncState];
if ([p sync]) {
LOGD(@"Postflight complete");
LOGI(@"Sync completed successfully");
if (!syncState.daemon) exit(0);
} else {
LOGE(@"Postflight failed");
if (!syncState.daemon) exit(1);
}
}
#pragma mark internal helpers
- (dispatch_source_t)createSyncTimerWithBlock:(void (^)())block {
dispatch_source_t timerQueue = dispatch_source_create(
DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0));
dispatch_source_set_event_handler(timerQueue, block);
dispatch_resume(timerQueue);
return timerQueue;
}
- (SNTCommandSyncState *)createSyncState {
// Gather some data needed during some sync stages
SNTCommandSyncState *syncState = [[SNTCommandSyncState alloc] init];
SNTConfigurator *config = [SNTConfigurator configurator];
syncState.syncBaseURL = config.syncBaseURL;
if (syncState.syncBaseURL.absoluteString.length == 0) {
LOGE(@"Missing SyncBaseURL. Can't sync without it.");
if (!syncState.daemon) exit(1);
} else if (![syncState.syncBaseURL.scheme isEqual:@"https"]) {
LOGW(@"SyncBaseURL is not over HTTPS!");
}
syncState.machineID = config.machineID;
if (syncState.machineID.length == 0) {
LOGE(@"Missing Machine ID. Can't sync without it.");
if (!syncState.daemon) exit(1);
}
syncState.machineOwner = config.machineOwner;
if (syncState.machineOwner.length == 0) {
syncState.machineOwner = @"";
LOGW(@"Missing Machine Owner.");
}
[[self.daemonConn remoteObjectProxy] xsrfToken:^(NSString *token) {
syncState.xsrfToken = token;
}];
MOLAuthenticatingURLSession *authURLSession = [[MOLAuthenticatingURLSession alloc] init];
authURLSession.userAgent = @"santactl-sync/";
NSString *santactlVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
if (santactlVersion) {
authURLSession.userAgent = [authURLSession.userAgent stringByAppendingString:santactlVersion];
}
authURLSession.refusesRedirects = YES;
authURLSession.serverHostname = syncState.syncBaseURL.host;
authURLSession.loggingBlock = ^(NSString *line) {
LOGD(@"%@", line);
};
// Configure server auth
if ([config syncServerAuthRootsFile]) {
authURLSession.serverRootsPemFile = [config syncServerAuthRootsFile];
} else if ([config syncServerAuthRootsData]) {
authURLSession.serverRootsPemData = [config syncServerAuthRootsData];
}
// Configure client auth
if ([config syncClientAuthCertificateFile]) {
authURLSession.clientCertFile = [config syncClientAuthCertificateFile];
authURLSession.clientCertPassword = [config syncClientAuthCertificatePassword];
} else if ([config syncClientAuthCertificateCn]) {
authURLSession.clientCertCommonName = [config syncClientAuthCertificateCn];
} else if ([config syncClientAuthCertificateIssuer]) {
authURLSession.clientCertIssuerCn = [config syncClientAuthCertificateIssuer];
}
syncState.session = [authURLSession session];
syncState.daemonConn = self.daemonConn;
syncState.daemon = self.daemon;
return syncState;
}
- (void)lockAction:(NSString *)action {
[self.dispatchLock setObject:@YES forKey:action];
}
- (void)unlockAction:(NSString *)action {
[self.dispatchLock removeObjectForKey:action];
}
- (BOOL)checkLockAction:(NSString *)action {
return ([self.dispatchLock objectForKey:action] == nil);
}
#pragma mark reachability methods
- (void)setReachable:(BOOL)reachable {
_reachable = reachable;
if (reachable) {
[self stopReachability];
[self fullSync];
}
}
// Start listening for network state changes on a background thread
- (void)startReachability {
if (_reachability) return;
const char *nodename = [[SNTConfigurator configurator] syncBaseURL].host.UTF8String;
_reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, nodename);
SCNetworkReachabilityContext context = {
.info = (__bridge void *)self
};
if (SCNetworkReachabilitySetCallback(_reachability, reachabilityHandler, &context)) {
SCNetworkReachabilitySetDispatchQueue(
_reachability, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0));
} else {
[self stopReachability];
}
}
// Stop listening for network state changes
- (void)stopReachability {
if (_reachability) {
SCNetworkReachabilitySetDispatchQueue(_reachability, NULL);
if (_reachability) CFRelease(_reachability);
_reachability = NULL;
}
}
@end

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandSyncStage.h"
@interface SNTCommandSyncPostflight : SNTCommandSyncStage

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandSyncStage.h"
@interface SNTCommandSyncPreflight : SNTCommandSyncStage

View File

@@ -74,10 +74,9 @@
if (!resp) return NO;
self.syncState.eventBatchSize = [resp[kBatchSize] intValue];
if (self.syncState.eventBatchSize == 0) {
self.syncState.eventBatchSize = 50;
}
self.syncState.FCMToken = resp[kFCMToken];
self.syncState.eventBatchSize = [resp[kBatchSize] intValue] ?: 50;
self.syncState.uploadLogURL = [NSURL URLWithString:resp[kUploadLogsURL]];

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandSyncStage.h"
@interface SNTCommandSyncRuleDownload : SNTCommandSyncStage

View File

@@ -67,7 +67,26 @@
return NO;
}
sema = dispatch_semaphore_create(0);
[[self.daemonConn remoteObjectProxy] setRuleSyncLastSuccess:[NSDate date] reply:^{
dispatch_semaphore_signal(sema);
}];
dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC));
LOGI(@"Added %lu rules", self.syncState.downloadedRules.count);
if (self.syncState.targetedRuleSync) {
for (SNTRule *r in self.syncState.downloadedRules) {
NSString *fileName = [[self.syncState.ruleSyncCache objectForKey:r.shasum] copy];
[self.syncState.ruleSyncCache removeObjectForKey:r.shasum];
if (fileName) {
NSString *message = [NSString stringWithFormat:@"%@ can now be run", fileName];
[[self.daemonConn remoteObjectProxy]
postRuleSyncNotificationWithCustomMessage:message reply:^{}];
}
}
}
return YES;
}

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
@class SNTCommandSyncState;
@class SNTXPCConnection;

View File

@@ -26,6 +26,7 @@
@property(readwrite) NSURLSession *urlSession;
@property(readwrite) SNTCommandSyncState *syncState;
@property(readwrite) SNTXPCConnection *daemonConn;
@property BOOL xsrfFetched;
@end
@@ -170,9 +171,9 @@
}
- (BOOL)fetchXSRFToken {
__block BOOL success = NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ // only fetch token once per session
BOOL success = NO;
if (!self.xsrfFetched) { // only fetch token once per session
self.xsrfFetched = YES;
NSString *stageName = [@"xsrf" stringByAppendingFormat:@"/%@", self.syncState.machineID];
NSURL *u = [NSURL URLWithString:stageName relativeToURL:self.syncState.syncBaseURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:u];
@@ -188,7 +189,7 @@
} else {
LOGD(@"Failed to retrieve XSRF token");
}
});
};
return success;
}

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommonEnums.h"
@class SNTXPCConnection;
@@ -32,6 +34,9 @@
/// An XSRF token to send in the headers with each request.
@property NSString *xsrfToken;
/// A FCM token to subscribe to push notifications.
@property(copy) NSString *FCMToken;
/// Machine identifier and owner.
@property(copy) NSString *machineID;
@property(copy) NSString *machineOwner;
@@ -56,4 +61,13 @@
/// Rules downloaded from server.
@property NSMutableArray *downloadedRules;
/// Returns YES if the santactl session is running as a daemon, returns NO otherwise.
@property BOOL daemon;
/// Returns YES if the session is targeted for this machine, returns NO otherwise.
@property BOOL targetedRuleSync;
/// Reference to the sync manager's ruleSyncCache. Used to lookup binary names for notifications.
@property(weak) NSCache *ruleSyncCache;
@end

View File

@@ -1,3 +0,0 @@
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
@class SNTXPCConnection;
///

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommandController.h"
///

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
// This is imported in the header rather than implementation to save
// classes that use this one from also having to import FMDB stuff.
#import <FMDB/FMDB.h>

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTDatabaseTable.h"
@class SNTNotificationMessage;
@@ -44,15 +46,6 @@
///
- (NSUInteger)pendingEventsCount;
///
/// Retrieve an event from the database with a given SHA-256. If multiple events
/// exist for the same SHA-256, just the first is returned.
///
/// @param sha256 a SHA-256 of the binary to return an event for.
/// @return a single SNTStoredEvent.
///
- (SNTStoredEvent *)pendingEventForSHA256:(NSString *)sha256;
///
/// Delete a single event from the database using its index.
///

View File

@@ -15,7 +15,6 @@
#import "SNTEventTable.h"
#import "MOLCertificate.h"
#import "SNTLogging.h"
#import "SNTStoredEvent.h"
@implementation SNTEventTable
@@ -66,13 +65,26 @@
newVersion = 2;
}
if (version < 3) {
// Clean-up: Disable AUTOINCREMENT on idx column
[db executeUpdate:@"CREATE TABLE 'events_tmp' ("
@"'idx' INTEGER PRIMARY KEY,"
@"'filesha256' TEXT NOT NULL,"
@"'eventdata' BLOB);"];
[db executeUpdate:@"INSERT INTO events_tmp SELECT * FROM events"];
[db executeUpdate:@"DROP TABLE events"];
[db executeUpdate:@"ALTER TABLE events_tmp RENAME TO events"];
newVersion = 3;
}
return newVersion;
}
#pragma mark Loading / Storing
- (BOOL)addStoredEvent:(SNTStoredEvent *)event {
if (!event.fileSHA256 ||
if (!event.idx ||
!event.fileSHA256 ||
!event.filePath ||
!event.occurrenceDate ||
!event.decision) return NO;
@@ -86,8 +98,9 @@
__block BOOL success = NO;
[self inTransaction:^(FMDatabase *db, BOOL *rollback) {
success = [db executeUpdate:@"INSERT INTO 'events' (filesha256, eventdata) VALUES (?, ?)",
event.fileSHA256, eventData];
success = [db executeUpdate:@"INSERT INTO 'events' (idx, filesha256, eventdata)"
@"VALUES (?, ?, ?)",
event.idx, event.fileSHA256, eventData];
}];
return success;
@@ -103,26 +116,6 @@
return eventsPending;
}
- (SNTStoredEvent *)pendingEventForSHA256:(NSString *)sha256 {
__block SNTStoredEvent *storedEvent;
[self inDatabase:^(FMDatabase *db) {
FMResultSet *rs =
[db executeQuery:@"SELECT * FROM events WHERE filesha256=? LIMIT 1;", sha256];
if ([rs next]) {
storedEvent = [self eventFromResultSet:rs];
if (!storedEvent) {
[db executeUpdate:@"DELETE FROM events WHERE idx=?", [rs objectForColumnName:@"idx"]];
}
}
[rs close];
}];
return storedEvent;
}
- (NSArray *)pendingEvents {
NSMutableArray *pendingEvents = [[NSMutableArray alloc] init];
@@ -152,7 +145,7 @@
@try {
event = [NSKeyedUnarchiver unarchiveObjectWithData:eventData];
event.idx = @([rs intForColumn:@"idx"]);
event.idx = event.idx ?: @((uint32_t)[rs intForColumn:@"idx"]);
} @catch (NSException *exception) {
}

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommonEnums.h"
#import "SNTDatabaseTable.h"

View File

@@ -1,3 +0,0 @@
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
///
/// The main controller class for santad
///

View File

@@ -14,7 +14,8 @@
#import "SNTApplication.h"
#import <DiskArbitration/DiskArbitration.h>
@import DiskArbitration;
#include <sys/stat.h>
#include <sys/types.h>
@@ -23,6 +24,7 @@
#import "SNTDaemonControlController.h"
#import "SNTDatabaseController.h"
#import "SNTDriverManager.h"
#import "SNTDropRootPrivs.h"
#import "SNTEventLog.h"
#import "SNTEventTable.h"
#import "SNTExecutionController.h"
@@ -30,6 +32,7 @@
#import "SNTLogging.h"
#import "SNTNotificationQueue.h"
#import "SNTRuleTable.h"
#import "SNTSyncdQueue.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
@@ -68,11 +71,18 @@
}
SNTNotificationQueue *notQueue = [[SNTNotificationQueue alloc] init];
SNTSyncdQueue *syncdQueue = [[SNTSyncdQueue alloc] init];
// Establish XPC listener for santactl connections
// Restart santactl if it goes down
syncdQueue.invalidationHandler = ^{
[self startSyncd];
};
// Establish XPC listener for Santa and santactl connections
SNTDaemonControlController *dc = [[SNTDaemonControlController alloc] init];
dc.driverManager = _driverManager;
dc.notQueue = notQueue;
dc.syncdQueue = syncdQueue;
_controlConnection =
[[SNTXPCConnection alloc] initServerWithName:[SNTXPCControlInterface serviceId]];
@@ -81,6 +91,7 @@
[_controlConnection resume];
__block SNTClientMode origMode = [[SNTConfigurator configurator] clientMode];
__block NSURL *origSyncURL = [[SNTConfigurator configurator] syncBaseURL];
_configFileWatcher = [[SNTFileWatcher alloc] initWithFilePath:kDefaultConfigFilePath
handler:^(unsigned long data) {
if (data & DISPATCH_VNODE_ATTRIB) {
@@ -107,6 +118,14 @@
[self.driverManager flushCache];
}
}
// Start santactl if the syncBaseURL changed from nil --> somthing
NSURL *syncURL = [[SNTConfigurator configurator] syncBaseURL];
if (!origSyncURL && syncURL) {
origSyncURL = syncURL;
LOGI(@"SyncBaseURL added, starting santactl.");
[self startSyncd];
}
}
}];
@@ -117,13 +136,29 @@
ruleTable:ruleTable
eventTable:eventTable
notifierQueue:notQueue
syncdQueue:syncdQueue
eventLog:_eventLog];
// Start up santactl as a daemon if a sync server exists.
[self startSyncd];
if (!_execController) return nil;
}
return self;
}
- (void)startSyncd {
if (![[SNTConfigurator configurator] syncBaseURL]) return;
if (fork() == 0) {
// Ensure we have no privileges
if (!DropRootPrivileges()) {
_exit(EPERM);
}
_exit(execl(kSantaCtlPath, kSantaCtlPath, "sync", "--daemon", "--syslog", NULL));
}
}
- (void)start {
LOGI(@"Connected to driver, activating.");

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommonEnums.h"
///

View File

@@ -12,10 +12,13 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTXPCControlInterface.h"
@class SNTDriverManager;
@class SNTNotificationQueue;
@class SNTSyncdQueue;
///
/// SNTDaemonControlController handles all of the RPCs from santactl
@@ -24,5 +27,6 @@
@property SNTDriverManager *driverManager;
@property SNTNotificationQueue *notQueue;
@property SNTSyncdQueue *syncdQueue;
@end

View File

@@ -18,15 +18,16 @@
#import "SNTConfigurator.h"
#import "SNTDatabaseController.h"
#import "SNTDriverManager.h"
#import "SNTDropRootPrivs.h"
#import "SNTEventTable.h"
#import "SNTLogging.h"
#import "SNTNotificationQueue.h"
#import "SNTPolicyProcessor.h"
#import "SNTRule.h"
#import "SNTRuleTable.h"
#import "SNTSyncdQueue.h"
#import "SNTXPCConnection.h"
#import "SNTXPCNotifierInterface.h"
#import "SNTXPCSyncdInterface.h"
// Globals used by the santad watchdog thread
uint64_t watchdogCPUEvents = 0;
@@ -36,7 +37,6 @@ double watchdogRAMPeak = 0;
@interface SNTDaemonControlController ()
@property NSString *_syncXsrfToken;
@property dispatch_source_t syncTimer;
@property SNTPolicyProcessor *policyProcessor;
@end
@@ -45,46 +45,12 @@ double watchdogRAMPeak = 0;
- (instancetype)init {
self = [super init];
if (self) {
_syncTimer = [self createSyncTimer];
[self rescheduleSyncSecondsFromNow:30];
_policyProcessor = [[SNTPolicyProcessor alloc] initWithRuleTable:
[SNTDatabaseController ruleTable]];
}
return self;
}
- (dispatch_source_t)createSyncTimer {
dispatch_source_t syncTimerQ = dispatch_source_create(
DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0));
dispatch_source_set_event_handler(syncTimerQ, ^{
[self rescheduleSyncSecondsFromNow:600];
if (![[SNTConfigurator configurator] syncBaseURL]) return;
[[SNTConfigurator configurator] setSyncBackOff:NO];
if (fork() == 0) {
// Ensure we have no privileges
if (!DropRootPrivileges()) {
_exit(EPERM);
}
_exit(execl(kSantaCtlPath, kSantaCtlPath, "sync", "--syslog", NULL));
}
});
dispatch_resume(syncTimerQ);
return syncTimerQ;
}
- (void)rescheduleSyncSecondsFromNow:(uint64_t)seconds {
uint64_t interval = seconds * NSEC_PER_SEC;
uint64_t leeway = (seconds * 0.05) * NSEC_PER_SEC;
dispatch_source_set_timer(self.syncTimer, dispatch_walltime(NULL, interval), interval, leeway);
}
#pragma mark Kernel ops
- (void)cacheCount:(void (^)(int64_t))reply {
@@ -127,10 +93,6 @@ double watchdogRAMPeak = 0;
reply([[SNTDatabaseController eventTable] pendingEventsCount]);
}
- (void)databaseEventForSHA256:(NSString *)sha256 reply:(void (^)(SNTStoredEvent *))reply {
reply([[SNTDatabaseController eventTable] pendingEventForSHA256:sha256]);
}
- (void)databaseEventsPending:(void (^)(NSArray *events))reply {
reply([[SNTDatabaseController eventTable] pendingEvents]);
}
@@ -180,14 +142,13 @@ double watchdogRAMPeak = 0;
reply();
}
- (void)setNextSyncInterval:(uint64_t)seconds reply:(void (^)())reply {
[self rescheduleSyncSecondsFromNow:seconds];
[[SNTConfigurator configurator] setSyncBackOff:YES];
- (void)setSyncLastSuccess:(NSDate *)date reply:(void (^)())reply {
[[SNTConfigurator configurator] setFullSyncLastSuccess:date];
reply();
}
- (void)setSyncLastSuccess:(NSDate *)date reply:(void (^)())reply {
[[SNTConfigurator configurator] setSyncLastSuccess:date];
- (void)setRuleSyncLastSuccess:(NSDate *)date reply:(void (^)())reply {
[[SNTConfigurator configurator] setRuleSyncLastSuccess:date];
reply();
}
@@ -201,6 +162,8 @@ double watchdogRAMPeak = 0;
options:0
error:NULL];
[[SNTConfigurator configurator] setWhitelistPathRegex:re];
LOGI(@"Received new whitelist regex, flushing cache");
[self.driverManager flushCache];
reply();
}
@@ -209,6 +172,8 @@ double watchdogRAMPeak = 0;
options:0
error:NULL];
[[SNTConfigurator configurator] setBlacklistPathRegex:re];
LOGI(@"Received new blacklist regex, flushing cache");
[self.driverManager flushCache];
reply();
}
@@ -225,4 +190,41 @@ double watchdogRAMPeak = 0;
self.notQueue.notifierConnection = c;
}
#pragma mark syncd Ops
- (void)setSyncdListener:(NSXPCListenerEndpoint *)listener {
// Only allow one active syncd connection
if (self.syncdQueue.syncdConnection) return;
SNTXPCConnection *c = [[SNTXPCConnection alloc] initClientWithListener:listener];
c.remoteInterface = [SNTXPCSyncdInterface syncdInterface];
c.invalidationHandler = ^{
[self.syncdQueue stopSyncingEvents];
self.syncdQueue.syncdConnection = nil;
self.syncdQueue.invalidationHandler();
};
c.acceptedHandler = ^{
[self.syncdQueue startSyncingEvents];
};
[c resume];
self.syncdQueue.syncdConnection = c;
}
- (void)setNextSyncInterval:(uint64_t)seconds reply:(void (^)())reply {
[[self.syncdQueue.syncdConnection remoteObjectProxy] rescheduleSyncSecondsFromNow:seconds];
[[SNTConfigurator configurator] setSyncBackOff:YES];
reply();
}
- (void)pushNotifications:(void (^)(BOOL))reply {
[self.syncdQueue.syncdConnection.remoteObjectProxy isFCMListening:^(BOOL response) {
reply(response);
}];
}
- (void)postRuleSyncNotificationWithCustomMessage:(NSString *)message reply:(void (^)())reply {
[[self.notQueue.notifierConnection remoteObjectProxy]
postRuleSyncNotificationWithCustomMessage:message];
reply();
}
@end

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
// This is imported in the header rather than implementation to saves
// classes that use this one from also having to import FMDB stuff.
#import <FMDB/FMDB.h>

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#include "SNTKernelCommon.h"
@class SNTNotificationMessage;

View File

@@ -14,8 +14,9 @@
#import "SNTDriverManager.h"
#import <IOKit/IODataQueueClient.h>
#import <IOKit/Kext/KextManager.h>
@import IOKit.kext;
#include <mach/mach_port.h>
#import "SNTLogging.h"

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTKernelCommon.h"
@class SNTCachedDecision;

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommonEnums.h"
#include "SNTKernelCommon.h"
@@ -21,6 +23,7 @@
@class SNTEventTable;
@class SNTNotificationQueue;
@class SNTRuleTable;
@class SNTSyncdQueue;
///
/// SNTExecutionController is responsible for handling binary execution requests:
@@ -36,6 +39,7 @@
ruleTable:(SNTRuleTable *)ruleTable
eventTable:(SNTEventTable *)eventTable
notifierQueue:(SNTNotificationQueue *)notifierQueue
syncdQueue:(SNTSyncdQueue *)syncdQueue
eventLog:(SNTEventLog *)eventLog;
///

View File

@@ -36,6 +36,7 @@
#import "SNTRule.h"
#import "SNTRuleTable.h"
#import "SNTStoredEvent.h"
#import "SNTSyncdQueue.h"
@interface SNTExecutionController ()
@property SNTDriverManager *driverManager;
@@ -44,8 +45,8 @@
@property SNTNotificationQueue *notifierQueue;
@property SNTPolicyProcessor *policyProcessor;
@property SNTRuleTable *ruleTable;
@property SNTSyncdQueue *syncdQueue;
@property NSCache<NSString *, NSDate *> *uploadBackoff;
@property dispatch_queue_t eventQueue;
@end
@@ -57,6 +58,7 @@
ruleTable:(SNTRuleTable *)ruleTable
eventTable:(SNTEventTable *)eventTable
notifierQueue:(SNTNotificationQueue *)notifierQueue
syncdQueue:(SNTSyncdQueue *)syncdQueue
eventLog:(SNTEventLog *)eventLog {
self = [super init];
if (self) {
@@ -64,11 +66,10 @@
_ruleTable = ruleTable;
_eventTable = eventTable;
_notifierQueue = notifierQueue;
_syncdQueue = syncdQueue;
_eventLog = eventLog;
_policyProcessor = [[SNTPolicyProcessor alloc] initWithRuleTable:_ruleTable];
_uploadBackoff = [[NSCache alloc] init];
_uploadBackoff.countLimit = 128;
_eventQueue = dispatch_queue_create("com.google.santad.event_upload", DISPATCH_QUEUE_SERIAL);
// This establishes the XPC connection between libsecurity and syspolicyd.
@@ -245,7 +246,7 @@
}
/**
This runs `santactl sync` for the event that was just saved, so that the user
This sends the event that was just saved to santactl for immediate upload, so that the user
has something to vote in straight away.
This method is always called on a serial queue to keep this low-priority method
@@ -259,24 +260,7 @@
![[SNTConfigurator configurator] syncBaseURL] ||
[[SNTConfigurator configurator] syncBackOff]) return;
// The event upload is skipped if an event upload has been initiated for it in the
// last 10 minutes.
NSDate *backoff = [self.uploadBackoff objectForKey:event.fileSHA256];
NSDate *now = [NSDate date];
if (([now timeIntervalSince1970] - [backoff timeIntervalSince1970]) < 600) return;
[self.uploadBackoff setObject:now forKey:event.fileSHA256];
if (fork() == 0) {
// Ensure we have no privileges
if (!DropRootPrivileges()) {
_exit(EPERM);
}
_exit(execl(kSantaCtlPath, kSantaCtlPath, "sync", "--syslog",
"singleevent", [event.fileSHA256 UTF8String], NULL));
}
[self.syncdQueue addEvent:event];
}
- (void)printMessage:(NSString *)msg toTTYForPID:(pid_t)pid {

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
@class SNTStoredEvent;
@class SNTXPCConnection;

View File

@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import "SNTCommonEnums.h"
#import "SNTKernelCommon.h"

View File

@@ -0,0 +1,30 @@
/// Copyright 2016 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;
@class SNTStoredEvent;
@class SNTXPCConnection;
@interface SNTSyncdQueue : NSObject
@property(nonatomic) SNTXPCConnection *syncdConnection;
@property(copy) void (^invalidationHandler)();
@property(copy) void (^acceptedHandler)();
- (void)addEvent:(SNTStoredEvent *)event;
- (void)startSyncingEvents;
- (void)stopSyncingEvents;
@end

View File

@@ -0,0 +1,72 @@
/// Copyright 2016 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 "SNTSyncdQueue.h"
#import "SNTLogging.h"
#import "SNTStoredEvent.h"
#import "SNTXPCConnection.h"
#import "SNTXPCSyncdInterface.h"
@interface SNTSyncdQueue ()
@property NSCache<NSString *, NSDate *> *uploadBackoff;
@property dispatch_queue_t syncdQueue;
@property dispatch_semaphore_t sema;
@end
@implementation SNTSyncdQueue
- (instancetype)init {
self = [super init];
if (self) {
_uploadBackoff = [[NSCache alloc] init];
_uploadBackoff.countLimit = 128;
_syncdQueue = dispatch_queue_create("com.google.syncd_queue", DISPATCH_QUEUE_SERIAL);
_sema = dispatch_semaphore_create(0);
}
return self;
}
- (void)addEvent:(SNTStoredEvent *)event {
// The event upload is skipped if an event upload has been initiated for it in the
// last 10 minutes.
NSDate *backoff = [self.uploadBackoff objectForKey:event.fileSHA256];
NSDate *now = [NSDate date];
if (([now timeIntervalSince1970] - [backoff timeIntervalSince1970]) < 600) return;
[self.uploadBackoff setObject:now forKey:event.fileSHA256];
// Hold events for a few seconds to allow santad and santactl to establish connections.
// If the connections are not established in time drop the event from the queue.
// They will be uploaded during a full sync.
dispatch_async(self.syncdQueue, ^{
if (!dispatch_semaphore_wait(self.sema, dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC))) {
[self.syncdConnection.remoteObjectProxy postEventToSyncServer:event];
// Let em flow
dispatch_semaphore_signal(self.sema);
} else {
LOGI(@"Dropping event %@ from com.google.syncd_queue", event.fileSHA256);
}
});
}
- (void)startSyncingEvents {
dispatch_semaphore_signal(self.sema);
}
- (void)stopSyncingEvents {
self.sema = dispatch_semaphore_create(0);
}
@end

View File

@@ -12,8 +12,11 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#include "SNTLogging.h"
#include <mach/task.h>
#include <pthread/pthread.h>
#include <sys/resource.h>

View File

@@ -12,9 +12,10 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
@import IOKit;
#import <CommonCrypto/CommonDigest.h>
#import <Foundation/Foundation.h>
#import <IOKit/IODataQueueClient.h>
#include <cmath>
#include <ctime>

View File

@@ -1,3 +0,0 @@
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <XCTest/XCTest.h>
@import XCTest;
#import <OCMock/OCMock.h>

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <XCTest/XCTest.h>
@import XCTest;
#import <OCMock/OCMock.h>
@@ -344,28 +344,6 @@
XCTAssertEqual(requestCount, 2);
}
- (void)testEventUploadBundleSearch {
SNTCommandSyncEventUpload *sut = [[SNTCommandSyncEventUpload alloc] initWithState:self.syncState];
self.syncState.eventBatchSize = 128;
self.syncState.bundleBinaryRequests = @[ @"/Applications/Safari.app"];
sut = OCMPartialMock(sut);
[self stubRequestBody:nil response:nil error:nil validateBlock:^BOOL(NSURLRequest *req) {
NSDictionary *requestDict = [self dictFromRequest:req];
NSArray *events = requestDict[kEvents];
XCTAssertGreaterThanOrEqual(events.count, 3);
for (NSDictionary *event in events) {
XCTAssertEqualObjects(event[kDecision], kDecisionBundleBinary);
}
return YES;
}];
[sut syncBundleEvents];
}
#pragma mark - SNTCommandSyncRuleDownload Tests
- (void)testRuleDownload {

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <XCTest/XCTest.h>
@import XCTest;
#import "MOLCodesignChecker.h"
#import "SNTEventTable.h"
@@ -46,6 +46,7 @@
MOLCodesignChecker *csInfo = [[MOLCodesignChecker alloc] initWithBinaryPath:@"/usr/bin/false"];
SNTStoredEvent *event;
event = [[SNTStoredEvent alloc] init];
event.idx = @(arc4random());
event.filePath = @"/usr/bin/false";
event.fileSHA256 = [binInfo SHA256];
event.signingChain = [csInfo certificates];
@@ -67,7 +68,7 @@
SNTStoredEvent *event = [self createTestEvent];
[self.sut addStoredEvent:event];
SNTStoredEvent *storedEvent = [self.sut pendingEventForSHA256:event.fileSHA256];
SNTStoredEvent *storedEvent = [self.sut pendingEvents].firstObject;
XCTAssertNotNil(storedEvent);
XCTAssertEqualObjects(event.filePath, storedEvent.filePath);
XCTAssertEqualObjects(event.signingChain, storedEvent.signingChain);
@@ -81,8 +82,7 @@
[self.sut addStoredEvent:newEvent];
XCTAssertEqual(self.sut.pendingEventsCount, 1);
SNTStoredEvent *storedEvent = [self.sut pendingEventForSHA256:newEvent.fileSHA256];
[self.sut deleteEventWithId:storedEvent.idx];
[self.sut deleteEventWithId:newEvent.idx];
XCTAssertEqual(self.sut.pendingEventsCount, 0);
}

View File

@@ -12,8 +12,9 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import XCTest;
#import <OCMock/OCMock.h>
#import <XCTest/XCTest.h>
#import "SNTExecutionController.h"
@@ -66,6 +67,7 @@
ruleTable:self.mockRuleDatabase
eventTable:self.mockEventDatabase
notifierQueue:nil
syncdQueue:nil
eventLog:nil];
}

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <XCTest/XCTest.h>
@import XCTest;
#import "SNTFileInfo.h"

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <XCTest/XCTest.h>
@import XCTest;
#import "SNTFileWatcher.h"

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <XCTest/XCTest.h>
@import XCTest;
#import "SNTRule.h"
#import "SNTRuleTable.h"

View File

@@ -12,8 +12,9 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import XCTest;
#import <OCMock/OCMock.h>
#import <XCTest/XCTest.h>
#import "MOLCodesignChecker.h"
#import "SNTXPCConnection.h"