Compare commits

...

28 Commits

Author SHA1 Message Date
Russell Hancox
3c2a88144c santad: Wait for driver appearance using IOKit notifications. (#278)
Continue loading without driver, report status in santactl.
2018-06-12 16:15:41 -04:00
dgw
3651f18566 readme: s/precendence/precedence/ (#283) 2018-06-12 15:01:42 -04:00
Russell Hancox
472fea75b1 KernelTests: Simplify kernel tests (#282)
This change does 2 major things:

1) Makes the test runnable from within Xcode, unloading any running
santad and santa-driver, loading the just-built driver from the same folder and
then running each test.

2) Makes each test responsible for declaring what should happen to
incoming requests from the driver, instead of keeping all of that
code near the top of the file. This makes each test much clearer in what
should be happening.
2018-06-12 09:53:20 -04:00
Russell Hancox
e1b5438865 santa-driver: Re-factor some destruction methods (#281) 2018-06-11 12:54:29 -04:00
Russell Hancox
fbbf523333 santa-driver: Stop catching hasdirtyblks, the loader handles this (#280) 2018-06-06 18:56:00 -04:00
Russell Hancox
15fa53d744 santa-driver: Switch to a struct for vnode IDs, holding both the file… (#276)
santa-driver: Switch to a struct for vnode IDs, holding both the filesystem ID and vnode ID.

Also drop the separate caches for root/non-root as this doesn't offer any benefit anymore.
2018-06-05 06:43:49 -04:00
Russell Hancox
9595f80fde santad: Don't get code signature info for non Mach-O's. (#277) 2018-06-05 06:43:11 -04:00
Russell Hancox
61a67e45c1 SantaCache: Add command to print histogram of bucket distribution (#275)
* SantaCache: Add santactl command to print histogram of bucket distribution.

This currently only prints the distribution of the non-root cache. In the near future I'll unify the caches again which stops this being a problem.
2018-06-01 17:02:39 -04:00
Russell Hancox
143e690dab SantaCache: Add very basic distribution test (#273)
* SantaCache: Add very basic distribution test
2018-06-01 13:11:24 -04:00
Russell Hancox
ebd507f143 Project: Update cocoapods, again (#274) 2018-06-01 12:01:21 -04:00
Russell Hancox
f71bc0a8f7 santa-driver: Fix cache CAS operations, which haven't been working (#272)
* santa-driver: Fix cache CAS operations, which haven't really been working.
2018-06-01 11:38:25 -04:00
Russell Hancox
edc0c72464 SantaCache: Templatize key types (#271) 2018-05-30 15:50:23 -04:00
Tom Burgin
c3ce4f718b Update configuration.md (#270) 2018-05-30 11:06:45 -04:00
Tom Burgin
40ee482973 Update SNTSyslogEventLog.m (#269)
remove extra space
2018-05-29 16:39:18 -04:00
Mitchell Grenier
a5d2e6fdd2 Optional MachineID for Logs (#256)
* First draft, no UUID caching

* Cache UUID in SNTEventLog super class

* Add a configuration flag for UUID decoration

* Port from UUID to MachineID

* KVO complicance

* Remove extra newline I accidentally introduced
2018-05-29 16:16:21 -04:00
Tom Burgin
e9a835a642 log deny because of dirty vnode (#267)
* log dirty vnode blocks

* review update
2018-05-25 14:16:16 -04:00
Tom Burgin
ac7b95ceb6 santa-driver: do not invalidate cached decisions on KAUTH_VNODE_ACCESS (#266)
* santa-driver: do not invalidate cached decisions on KAUTH_VNODE_ACCESS

* downtown
2018-05-25 10:47:48 -04:00
Russell Hancox
055b2d8ede Update project for Xcode 9.1, add codesigning flags (#264)
* Project: Update project to Xcode 9.1 and handle all the new warnings that entails.

* Project: Add library-validation and kill flags to codesigning options
2018-05-22 10:13:59 -04:00
Russell Hancox
a75cd0a0f5 Update README.md (#263)
Update the sync client section to point at known open-source solutions, remove the Xcode 7.3.1 build requirement
2018-05-18 12:26:37 -04:00
Matthew Suozzo
2b1ddf9a4e Fix typo in sync help text (#259) 2018-05-09 21:53:51 -04:00
Tom Burgin
b70442e483 Project: Use MOLXPCConnection (#258)
* Project: Use MOLXPCConnection

* review fixes
2018-05-09 11:40:35 -04:00
Tom Burgin
798b0fab15 fileinfo: whitelist bundle extensions when performing an ancestor search (#257)
* fileinfo: whitelist bundle extensions when performing an ancestor search

* fix tests

* conform to russell's every whim
2018-05-07 13:57:58 -04:00
Russell Hancox
e8630132d7 Project: make building on case-sensitive volumes work (#255) 2018-04-27 12:58:54 -04:00
Russell Hancox
273ae5f21a santad: Missed an import (#254) 2018-04-27 10:51:53 -04:00
Tom Burgin
06b688fef4 Update .travis.yml (#253) 2018-04-26 17:23:32 -04:00
Russell Hancox
59cc038ab2 All: stop using @import for reasons. (#252) 2018-04-26 17:19:19 -04:00
Tom Burgin
ea5a6c3438 downstream --> upstream changes (#251) 2018-04-25 16:16:56 -04:00
Tom Burgin
e2adfdf3cf Add EventLog Docs (#250) 2018-04-24 16:33:53 -04:00
125 changed files with 1561 additions and 1489 deletions

View File

@@ -4,7 +4,7 @@ cache:
- bundler
- cocoapods
sudo: false
osx_image: xcode7
osx_image: xcode9.3
before_install:
- gem install cocoapods xcpretty

View File

@@ -20,7 +20,5 @@
<true />
<key>ProcessType</key>
<string>Interactive</string>
<key>ThrottleInterval</key>
<integer>1</integer>
</dict>
</plist>

View File

@@ -35,6 +35,9 @@ Two configuration methods can be used to control Santa: a local configuration pr
| MachineOwnerKey | String | The key to use on MachineOwnerPlist. |
| MachineIDPlist | String | The path to a plist that contains the MachineOwnerKey / value pair. |
| MachineIDKey | String | The key to use on MachineIDPlist. |
| EventLogType | String | Defines how event logs are stored. Options are 1) syslog: Sent to ASL or ULS (if built with the 10.12 SDK or later). 2) filelog: Sent to a file on disk. Use EventLogPath to specify a path. Defaults to filelog |
| EventLogPath | String | If EventLogType is set to filelog, EventLogPath will provide the path to save logs. Defaults to /var/db/santa/santa.log. If you change this value ensure you also update com.google.santa.newsyslog.conf with the new path. |
| EnableMachineIDDecoration | Bool | If YES, this appends the MachineID to the end of each log line. Defaults to NO. |
*overridable by the sync server: run `santactl status` to check the current running config

View File

@@ -5,16 +5,19 @@ inhibit_all_warnings!
target :Santa do
pod 'MOLCertificate'
pod 'MOLCodesignChecker'
pod 'MOLXPCConnection'
end
target :santad do
pod 'FMDB'
pod 'MOLCertificate'
pod 'MOLCodesignChecker'
pod 'MOLXPCConnection'
target :santabs do
pod 'FMDB'
pod 'MOLCertificate'
pod 'MOLCodesignChecker'
pod 'MOLXPCConnection'
end
end
@@ -24,6 +27,7 @@ target :santactl do
pod 'MOLCertificate'
pod 'MOLCodesignChecker'
pod 'MOLFCMClient', '~> 1.3'
pod 'MOLXPCConnection'
end
target :LogicTests do
@@ -31,6 +35,7 @@ target :LogicTests do
pod 'MOLAuthenticatingURLSession'
pod 'MOLCertificate'
pod 'MOLCodesignChecker'
pod 'MOLXPCConnection'
pod 'OCMock'
end

View File

@@ -9,6 +9,8 @@ PODS:
- MOLCertificate (~> 1.8)
- MOLFCMClient (1.7):
- MOLAuthenticatingURLSession (~> 2.4)
- MOLXPCConnection (1.1):
- MOLCodesignChecker (~> 1.9)
- OCMock (3.4.1)
DEPENDENCIES:
@@ -17,16 +19,28 @@ DEPENDENCIES:
- MOLCertificate
- MOLCodesignChecker
- MOLFCMClient (~> 1.3)
- MOLXPCConnection
- OCMock
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- FMDB
- MOLAuthenticatingURLSession
- MOLCertificate
- MOLCodesignChecker
- MOLFCMClient
- MOLXPCConnection
- OCMock
SPEC CHECKSUMS:
FMDB: 6198a90e7b6900cfc046e6bc0ef6ebb7be9236aa
MOLAuthenticatingURLSession: c238aa1c9a7b1077eb39a6f40204bfe76a7d204e
MOLCertificate: c999513316d511c69f290fbf313dfe8dca4ad592
MOLCodesignChecker: b0d5db9d2f9bd94e0fd093891a5d40e5ad77cbc0
MOLFCMClient: ee45348909351f232e2759c580329072ae7e02d4
MOLXPCConnection: de9d5535928f59766a768384e411077b83ec2f9c
OCMock: 2cd0716969bab32a2283ff3a46fd26a8c8b4c5e3
PODFILE CHECKSUM: acd378b3727c923d912e09812da344f7375c14fe
PODFILE CHECKSUM: ddca043a7ace9ec600c108621c56d13a50d17236
COCOAPODS: 1.4.0
COCOAPODS: 1.5.3

View File

@@ -43,7 +43,7 @@ correctly, but a rule for a binary's fingerprint will override a decision for a
certificate; i.e. you can whitelist a certificate while blacklisting a binary
signed with that certificate, or vice-versa.
* Path-based rules (via NSRegularExpression/ICU): This allows a similar feature to that found in Managed Client (the precursor to configuration profiles, which used the same implementation mechanism), Application Launch Restrictions via the mcxalr binary. This implementation carries the added benefit of being configurable via regex, and not relying on LaunchServices. As detailed in the wiki, when evaluating rules this holds the lowest precendence.
* Path-based rules (via NSRegularExpression/ICU): This allows a similar feature to that found in Managed Client (the precursor to configuration profiles, which used the same implementation mechanism), Application Launch Restrictions via the mcxalr binary. This implementation carries the added benefit of being configurable via regex, and not relying on LaunchServices. As detailed in the wiki, when evaluating rules this holds the lowest precedence.
* Failsafe cert rules: You cannot put in a deny rule that would block the certificate used to sign launchd, a.k.a. pid 1, and therefore all components used in macOS. The binaries in every OS update (and in some cases entire new versions) are therefore auto-whitelisted. This does not affect binaries from Apple's App Store, which use various certs that change regularly for common apps. Likewise, you cannot blacklist Santa itself, and Santa uses a distinct separate cert than other Google apps.
@@ -98,11 +98,11 @@ only the root user can read/write it. We're considering approaches to secure
this further.
* Sync client: The `santactl` command-line client includes a flag to synchronize with a management server, which uploads events that have occurred on the
machine and downloads new rules. We're still very heavily working on this
server (which is AppEngine-based and will be open-sourced in the future), so the
sync client code is unfinished. It does show the 'API' that we're expecting to
use so if you'd like to write your own management server, feel free to look at
how the client currently works (and suggest changes!)
machine and downloads new rules. There are several open-source servers you can sync with:
* [Upvote](https://github.com/google/upvote) - An AppEngine-based server that implements social voting to make managing a large fleet easier.
* [Moroz](https://github.com/groob/moroz) - A simple golang server that serves hardcoded rules from simple configuration files.
* [Zentral](https://github.com/zentralopensource/zentral/wiki) - A centralized service that pulls data from multiple sources and deploy configurations to multiple services.
* Scripts: Santa is currently written to ignore any execution that isn't a
binary. This is because after weighing the administration cost vs the benefit,
@@ -126,8 +126,6 @@ A tool like Santa doesn't really lend itself to screenshots, so here's a video i
Building
========
Firstly, make sure you're using Xcode 7.3.1 as currently we do not support
building with Xcode 8.
```sh
git clone https://github.com/google/santa

View File

@@ -155,20 +155,8 @@ namespace :tests do
desc "Tests: Kernel"
task :kernel do
Rake::Task['unload'].invoke()
Rake::Task['install:debug'].invoke()
Rake::Task['load_kext'].invoke
FileUtils.mkdir_p("/tmp/santa_kerneltests_tmp")
begin
puts "\033[?25l\033[12h" # hide cursor
puts "Running kernel tests"
system "cd /tmp/santa_kerneltests_tmp && sudo #{xcodebuilddir}/Debug/KernelTests"
rescue Exception
ensure
puts "\033[?25h\033[12l\n\n" # unhide cursor
FileUtils.rm_rf("/tmp/santa_kerneltests_tmp")
Rake::Task['unload_kext'].execute
end
Rake::Task['build:debug'].invoke()
system "sudo #{xcodebuilddir}/Debug/KernelTests"
end
end

View File

@@ -32,6 +32,7 @@
0D10BE861A0AABD600C0C944 /* SNTDropRootPrivs.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D10BE851A0AABD600C0C944 /* SNTDropRootPrivs.m */; };
0D10BE871A0AABD600C0C944 /* SNTDropRootPrivs.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D10BE851A0AABD600C0C944 /* SNTDropRootPrivs.m */; };
0D10BE891A0AAF6700C0C944 /* SNTDropRootPrivs.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D10BE851A0AABD600C0C944 /* SNTDropRootPrivs.m */; };
0D10D18420C19445008251ED /* SNTCommandCacheHistogram.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D10D18320C19445008251ED /* SNTCommandCacheHistogram.m */; };
0D1B477019A53419008CADD3 /* SNTAboutWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D1B476E19A53419008CADD3 /* SNTAboutWindowController.m */; };
0D1B477119A53419008CADD3 /* AboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0D1B476F19A53419008CADD3 /* AboutWindow.xib */; };
0D202D191CDD2EE500A88F16 /* SNTCommandSyncTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D202D181CDD2EE500A88F16 /* SNTCommandSyncTest.m */; };
@@ -47,7 +48,6 @@
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 */; };
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 */; };
0D385DC4180DE4A900418BC6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D385DC3180DE4A900418BC6 /* main.m */; };
@@ -56,7 +56,6 @@
0D385DF1180DE51600418BC6 /* SNTAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D385DEB180DE51600418BC6 /* SNTAppDelegate.m */; };
0D385DF2180DE51600418BC6 /* SNTMessageWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D385DED180DE51600418BC6 /* SNTMessageWindowController.m */; };
0D385DF3180DE51600418BC6 /* SNTNotificationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D385DEF180DE51600418BC6 /* SNTNotificationManager.m */; };
0D3AFBE718FB32CB0087BCEE /* SNTXPCConnectionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D3AFBE618FB32CB0087BCEE /* SNTXPCConnectionTest.m */; };
0D3AFBEB18FB48E70087BCEE /* SNTDatabaseTable.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D37C10E18F6029A0069BC61 /* SNTDatabaseTable.m */; };
0D3AFBEC18FB48E70087BCEE /* SNTEventTable.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D377C2917A071B7008453DB /* SNTEventTable.m */; };
0D3AFBEE18FB4C6C0087BCEE /* SNTApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DB8ACC0185662DC00FEF9C7 /* SNTApplication.m */; };
@@ -75,8 +74,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 */; };
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 */; };
0D827E6519DF392E006EC811 /* SNTConfigurator.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D42D2B719D2042900955F08 /* SNTConfigurator.m */; };
0D827E6719DF3C74006EC811 /* SNTCommandStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D827E6619DF3C74006EC811 /* SNTCommandStatus.m */; };
@@ -109,7 +106,6 @@
0DC5D871192160180078A5C0 /* SNTCommandSyncLogUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DC5D870192160180078A5C0 /* SNTCommandSyncLogUpload.m */; };
0DC765EA1B28D9EA00BAE651 /* santad in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0D9A7F3D1759330500035EB5 /* santad */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
0DC765EB1B28D9EA00BAE651 /* santactl in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0D35BD9E18FD71CE00921A21 /* santactl */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
0DCA552718C95928002A7DAE /* SNTXPCConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D6FDC9518C93A020044685C /* SNTXPCConnection.m */; };
0DCD5FBF1909D64A006B445C /* SNTCommandFileInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD5FBE1909D64A006B445C /* SNTCommandFileInfo.m */; };
0DCD6042190ACCB8006B445C /* SNTFileInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD6041190ACCB8006B445C /* SNTFileInfo.m */; };
0DCD6043190ACCB8006B445C /* SNTFileInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD6041190ACCB8006B445C /* SNTFileInfo.m */; };
@@ -179,12 +175,12 @@
C7C721AE1E23FCB50051FAA6 /* SNTBundleService.m in Sources */ = {isa = PBXBuildFile; fileRef = C7C721AD1E23FCB50051FAA6 /* SNTBundleService.m */; };
C7C721B11E23FF300051FAA6 /* SNTXPCBundleServiceInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = C7C721B01E23FF300051FAA6 /* SNTXPCBundleServiceInterface.m */; };
C7C721B21E23FF300051FAA6 /* SNTXPCBundleServiceInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = C7C721B01E23FF300051FAA6 /* SNTXPCBundleServiceInterface.m */; };
C7C721B31E2400310051FAA6 /* SNTXPCConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D6FDC9518C93A020044685C /* SNTXPCConnection.m */; };
C7C721B41E24042B0051FAA6 /* SNTStoredEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD604A19105433006B445C /* SNTStoredEvent.m */; };
C7C721B51E2408BE0051FAA6 /* SNTFileInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD6041190ACCB8006B445C /* SNTFileInfo.m */; };
C7C721B61E2408C30051FAA6 /* SNTLogging.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DA73C9E1934F8100056D7C4 /* SNTLogging.m */; };
C7DA62F71E241938009BDF2C /* SNTXPCBundleServiceInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = C7C721B01E23FF300051FAA6 /* SNTXPCBundleServiceInterface.m */; };
C7DA62F91E241A02009BDF2C /* SNTCommandBundleInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DA62F81E241A02009BDF2C /* SNTCommandBundleInfo.m */; };
C7EAF71820A0A20B00745126 /* DirectoryBundle in Resources */ = {isa = PBXBuildFile; fileRef = C7EAF71720A0A20B00745126 /* DirectoryBundle */; };
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 */; };
@@ -291,6 +287,7 @@
0D0A1EC5191AB9B000B8450F /* SNTCommandSyncPostflight.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandSyncPostflight.m; sourceTree = "<group>"; };
0D10BE851A0AABD600C0C944 /* SNTDropRootPrivs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTDropRootPrivs.m; sourceTree = "<group>"; };
0D10BE881A0AAC2100C0C944 /* SNTDropRootPrivs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SNTDropRootPrivs.h; sourceTree = "<group>"; };
0D10D18320C19445008251ED /* SNTCommandCacheHistogram.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SNTCommandCacheHistogram.m; sourceTree = "<group>"; };
0D1B476D19A53419008CADD3 /* SNTAboutWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTAboutWindowController.h; sourceTree = "<group>"; };
0D1B476E19A53419008CADD3 /* SNTAboutWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTAboutWindowController.m; sourceTree = "<group>"; };
0D1B476F19A53419008CADD3 /* AboutWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AboutWindow.xib; sourceTree = "<group>"; };
@@ -328,7 +325,6 @@
0D385DED180DE51600418BC6 /* SNTMessageWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTMessageWindowController.m; sourceTree = "<group>"; };
0D385DEE180DE51600418BC6 /* SNTNotificationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTNotificationManager.h; sourceTree = "<group>"; };
0D385DEF180DE51600418BC6 /* SNTNotificationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTNotificationManager.m; sourceTree = "<group>"; };
0D3AFBE618FB32CB0087BCEE /* SNTXPCConnectionTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTXPCConnectionTest.m; sourceTree = "<group>"; };
0D3AFBF718FB4C870087BCEE /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
0D4163FF191974F1006A356A /* SNTCommandSyncState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTCommandSyncState.h; sourceTree = "<group>"; };
0D416400191974F1006A356A /* SNTCommandSyncState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandSyncState.m; sourceTree = "<group>"; };
@@ -349,8 +345,6 @@
0D63DD5B1906FCB400D346C4 /* SNTDatabaseController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTDatabaseController.m; sourceTree = "<group>"; };
0D668E7F18D1121700E29A8B /* SNTMessageWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTMessageWindow.h; sourceTree = "<group>"; };
0D668E8018D1121700E29A8B /* SNTMessageWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTMessageWindow.m; sourceTree = "<group>"; };
0D6FDC9418C93A020044685C /* SNTXPCConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTXPCConnection.h; sourceTree = "<group>"; };
0D6FDC9518C93A020044685C /* SNTXPCConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTXPCConnection.m; sourceTree = "<group>"; };
0D7D01851774F93A005DBAB4 /* SNTDriverManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTDriverManager.h; sourceTree = "<group>"; };
0D7D01861774F93A005DBAB4 /* SNTDriverManager.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = SNTDriverManager.m; sourceTree = "<group>"; };
0D827E6619DF3C74006EC811 /* SNTCommandStatus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandStatus.m; sourceTree = "<group>"; };
@@ -451,6 +445,7 @@
C7C721AF1E23FF300051FAA6 /* SNTXPCBundleServiceInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTXPCBundleServiceInterface.h; sourceTree = "<group>"; };
C7C721B01E23FF300051FAA6 /* SNTXPCBundleServiceInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTXPCBundleServiceInterface.m; sourceTree = "<group>"; };
C7DA62F81E241A02009BDF2C /* SNTCommandBundleInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTCommandBundleInfo.m; sourceTree = "<group>"; };
C7EAF71720A0A20B00745126 /* DirectoryBundle */ = {isa = PBXFileReference; lastKnownFileType = folder; path = DirectoryBundle; 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>"; };
@@ -541,7 +536,6 @@
0DD0D490194F9947005F27EB /* SNTExecutionControllerTest.m */,
0DD0D48E194F78F8005F27EB /* SNTFileInfoTest.m */,
0DB537861AFD36EB00487F92 /* SNTRuleTableTest.m */,
0D3AFBE618FB32CB0087BCEE /* SNTXPCConnectionTest.m */,
);
path = LogicTests;
sourceTree = "<group>";
@@ -549,6 +543,7 @@
0D260DB018B68E12002A0B55 /* Resources */ = {
isa = PBXGroup;
children = (
C7EAF71720A0A20B00745126 /* DirectoryBundle */,
C74D6CC51EEB3B9B00BB5A33 /* BundleExample.app */,
0D536ED51B8E7A2E0039A26D /* bad_pagezero */,
0D2CD4601A81C7B100C9C910 /* dn.plist */,
@@ -744,8 +739,6 @@
0D42D2B419D1D98A00955F08 /* SNTSystemInfo.m */,
C7C721AF1E23FF300051FAA6 /* SNTXPCBundleServiceInterface.h */,
C7C721B01E23FF300051FAA6 /* SNTXPCBundleServiceInterface.m */,
0D6FDC9418C93A020044685C /* SNTXPCConnection.h */,
0D6FDC9518C93A020044685C /* SNTXPCConnection.m */,
0DCD605319115D17006B445C /* SNTXPCControlInterface.h */,
0DCD605419115D17006B445C /* SNTXPCControlInterface.m */,
0DC8C9E3180CC3BC00FCFB29 /* SNTXPCNotifierInterface.h */,
@@ -810,6 +803,7 @@
isa = PBXGroup;
children = (
C7DA62F81E241A02009BDF2C /* SNTCommandBundleInfo.m */,
0D10D18320C19445008251ED /* SNTCommandCacheHistogram.m */,
C76614EB1D142D3C00D150C1 /* SNTCommandCheckCache.m */,
0DCD5FBE1909D64A006B445C /* SNTCommandFileInfo.m */,
0DE4C8A518FF3B1700466D04 /* SNTCommandFlushCache.m */,
@@ -938,8 +932,6 @@
0D260DA818B68E12002A0B55 /* Sources */,
0D260DA918B68E12002A0B55 /* Frameworks */,
0D260DAA18B68E12002A0B55 /* Resources */,
D49A3AB950AFD99741E9AF89 /* [CP] Embed Pods Frameworks */,
23869BA352E2C86DEFE62819 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -958,7 +950,6 @@
0DD98E671A5DD02000A754C6 /* Update Version Info */,
0D35BD9A18FD71CE00921A21 /* Sources */,
0D35BD9B18FD71CE00921A21 /* Frameworks */,
2737FE8516A33567D3449943 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -978,8 +969,6 @@
0D385DB2180DE4A900418BC6 /* Sources */,
0D385DB3180DE4A900418BC6 /* Frameworks */,
0D385DB4180DE4A900418BC6 /* Resources */,
BA20035148DDEF5808B2C7EF /* [CP] Embed Pods Frameworks */,
DDE76075391100F3BCE3634E /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -1021,7 +1010,6 @@
0DD98E661A5DCED300A754C6 /* Update Version Info */,
0D9A7F391759330400035EB5 /* Sources */,
0D9A7F3A1759330400035EB5 /* Frameworks */,
531BBB5BA4BF953D628D29AB /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -1042,7 +1030,6 @@
C78227501E1C3C58006EB2D6 /* Sources */,
C78227511E1C3C58006EB2D6 /* Frameworks */,
C78227521E1C3C58006EB2D6 /* Resources */,
FCF4BDAA180BD63C32AC85DE /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -1059,7 +1046,7 @@
0D91BCA8174E8A6500131A7D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0730;
LastUpgradeCheck = 0910;
TargetAttributes = {
0D260DAB18B68E12002A0B55 = {
TestTargetID = 0D385DB5180DE4A900418BC6;
@@ -1107,6 +1094,7 @@
0D2CD4611A81C7B100C9C910 /* dn.plist in Resources */,
0DEA5F7B1CF64C9200704398 /* sync_ruledownload_batch2.json in Resources */,
0DEA5F6C1CF6254900704398 /* sync_preflight_lockdown.json in Resources */,
C7EAF71820A0A20B00745126 /* DirectoryBundle in Resources */,
0D536ED81B8E7A2E0039A26D /* missing_pagezero in Resources */,
0D202D201CE4E90E00A88F16 /* sync_preflight_basic.json in Resources */,
);
@@ -1261,51 +1249,6 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
23869BA352E2C86DEFE62819 /* [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;
};
2737FE8516A33567D3449943 /* [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;
};
531BBB5BA4BF953D628D29AB /* [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-santad/Pods-santad-resources.sh\"\n";
showEnvVarsInLog = 0;
};
9BF8830B1029605A497F13D5 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -1342,21 +1285,6 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
BA20035148DDEF5808B2C7EF /* [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-Santa/Pods-Santa-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
C7F95F971E23F9E7007A6BF5 /* Update bundle version */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -1392,51 +1320,6 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
D49A3AB950AFD99741E9AF89 /* [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;
};
DDE76075391100F3BCE3634E /* [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-Santa/Pods-Santa-resources.sh\"\n";
showEnvVarsInLog = 0;
};
FCF4BDAA180BD63C32AC85DE /* [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-santad-santabs/Pods-santad-santabs-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -1466,7 +1349,6 @@
0D202D191CDD2EE500A88F16 /* SNTCommandSyncTest.m in Sources */,
0D3AFBF018FB4C6C0087BCEE /* SNTDriverManager.m in Sources */,
0DCD6044190ACCB8006B445C /* SNTFileInfo.m in Sources */,
0D6FDC9718C93A020044685C /* SNTXPCConnection.m in Sources */,
0D3AFBEB18FB48E70087BCEE /* SNTDatabaseTable.m in Sources */,
0DD0D491194F9947005F27EB /* SNTExecutionControllerTest.m in Sources */,
0D3AFBEF18FB4C6C0087BCEE /* SNTExecutionController.m in Sources */,
@@ -1483,7 +1365,6 @@
0DE5B54C1C92722300C00603 /* SNTNotificationQueue.m in Sources */,
0DEA5F651CF6057D00704398 /* SNTCommandSyncEventUpload.m in Sources */,
0DB77FFB1CD7AC5A004DF060 /* SNTCommandSyncConstants.m in Sources */,
0D3AFBE718FB32CB0087BCEE /* SNTXPCConnectionTest.m in Sources */,
0D9184B91CD2F32D0004E859 /* SNTCommandSyncStage.m in Sources */,
0DCD605719115E54006B445C /* SNTDaemonControlController.m in Sources */,
0D2E1E631CEFA6C30039B2C4 /* SantaCacheTest.mm in Sources */,
@@ -1513,9 +1394,9 @@
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 */,
0D10D18420C19445008251ED /* SNTCommandCacheHistogram.m in Sources */,
0D42D2B919D2042900955F08 /* SNTConfigurator.m in Sources */,
0DF395641AB76A7900CBC520 /* NSData+Zlib.m in Sources */,
C7FB56F71DBFB480004E14EF /* SNTXPCSyncdInterface.m in Sources */,
@@ -1543,7 +1424,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0DCA552718C95928002A7DAE /* SNTXPCConnection.m in Sources */,
0D385DF1180DE51600418BC6 /* SNTAppDelegate.m in Sources */,
0D88680A1AC48A1200B86659 /* SNTSystemInfo.m in Sources */,
0D89310F1C931986002E8D74 /* SNTRule.m in Sources */,
@@ -1594,7 +1474,6 @@
0DC5D86D191AED220078A5C0 /* SNTRuleTable.m in Sources */,
0D7D01871774F93A005DBAB4 /* SNTDriverManager.m in Sources */,
0D8E18CD19107B56000F89B8 /* SNTDaemonControlController.m in Sources */,
0D6FDC9618C93A020044685C /* SNTXPCConnection.m in Sources */,
0D377C2A17A071B7008453DB /* SNTEventTable.m in Sources */,
0DE50F681912716A007B2B0C /* SNTRule.m in Sources */,
0DB77FD81CCE824A004DF060 /* SNTBlockMessage.m in Sources */,
@@ -1614,7 +1493,6 @@
buildActionMask = 2147483647;
files = (
C7C721B21E23FF300051FAA6 /* SNTXPCBundleServiceInterface.m in Sources */,
C7C721B31E2400310051FAA6 /* SNTXPCConnection.m in Sources */,
C7C721B61E2408C30051FAA6 /* SNTLogging.m in Sources */,
C7C721B41E24042B0051FAA6 /* SNTStoredEvent.m in Sources */,
C7C721B51E2408BE0051FAA6 /* SNTFileInfo.m in Sources */,
@@ -1706,6 +1584,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INSTALL_PATH = "";
OTHER_CODE_SIGN_FLAGS = "";
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-fcxx-modules",
@@ -1740,6 +1619,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INSTALL_PATH = "";
OTHER_CODE_SIGN_FLAGS = "";
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-fcxx-modules",
@@ -2000,11 +1880,34 @@
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_CXX0X_EXTENSIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Mac Developer";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = c99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LLVM_LTO = NO;
MACOSX_DEPLOYMENT_TARGET = 10.9;
ONLY_ACTIVE_ARCH = YES;
@@ -2028,13 +1931,37 @@
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_CXX0X_EXTENSIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Mac Developer";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = c99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = fast;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LLVM_LTO = YES;
MACOSX_DEPLOYMENT_TARGET = 10.9;
OTHER_CODE_SIGN_FLAGS = "-o library,kill";
PROVISIONING_PROFILE = "";
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = macosx;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -48,6 +48,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -45,6 +46,8 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
debugAsWhichUser = "root"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
@@ -55,6 +56,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -45,6 +46,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -36,6 +37,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -36,6 +37,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -45,6 +46,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -46,6 +47,7 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
debugAsWhichUser = "root"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

View File

@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="16F73" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<development version="6300" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13529"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
<capability name="system font weights other than Regular or Bold" minToolsVersion="7.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="SNTMessageWindowController">
@@ -22,13 +23,14 @@
<window title="Santa Blocked Execution" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="none" id="9Bq-yh-54f" customClass="SNTMessageWindow">
<windowStyleMask key="styleMask" utility="YES"/>
<rect key="contentRect" x="167" y="107" width="540" height="479"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<rect key="screenRect" x="0.0" y="0.0" width="3840" height="1578"/>
<view key="contentView" id="Iwq-Lx-rLv">
<rect key="frame" x="0.0" y="0.0" width="540" height="479"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kiB-jZ-69S">
<rect key="frame" x="16" y="451" width="37" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Hidden Button" alternateTitle="This button exists so neither of the other two buttons is pre-selected when the dialog opens." bezelStyle="rounded" alignment="center" borderStyle="border" focusRingType="none" transparent="YES" imageScaling="proportionallyDown" inset="2" id="XGa-Sl-F4t">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -40,20 +42,6 @@
<outlet property="nextKeyView" destination="7ua-5a-uSd" id="vl5-A8-O0H"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="t8c-Fx-e5h">
<rect key="frame" x="228" y="408" width="85" height="41"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" refusesFirstResponder="YES" sendsActionOnEndEditing="YES" title="Santa" id="7YA-iB-Zma">
<font key="font" metaFont="systemUltraLight" size="34"/>
<color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</textFieldCell>
<connections>
<outlet property="nextKeyView" destination="7ua-5a-uSd" id="z5y-RR-IEH"/>
</connections>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cD5-Su-lXR" customClass="SNTAccessibleTextField">
<rect key="frame" x="43" y="369" width="454" height="17"/>
<constraints>
@@ -370,7 +358,7 @@ DQ
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<box horizontalHuggingPriority="750" title="Line" boxType="custom" borderType="line" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="4Li-ul-zIi">
<box horizontalHuggingPriority="750" boxType="custom" borderType="line" title="Line" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="4Li-ul-zIi">
<rect key="frame" x="168" y="132" width="1" height="207"/>
<constraints>
<constraint firstAttribute="width" constant="1" id="0o1-Jh-epf"/>
@@ -418,6 +406,20 @@ DQ
</binding>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="t8c-Fx-e5h">
<rect key="frame" x="229" y="408" width="82" height="41"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" refusesFirstResponder="YES" sendsActionOnEndEditing="YES" title="Santa" id="7YA-iB-Zma">
<font key="font" metaFont="systemUltraLight" size="34"/>
<color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</textFieldCell>
<connections>
<outlet property="nextKeyView" destination="7ua-5a-uSd" id="z5y-RR-IEH"/>
</connections>
</textField>
</subviews>
<constraints>
<constraint firstItem="oFj-ol-xpL" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="10" id="0AD-PS-5V1"/>

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Cocoa;
#import <Cocoa/Cocoa.h>
@interface SNTAboutWindowController : NSWindowController

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Cocoa;
#import <Cocoa/Cocoa.h>
/**
An NSTextField subclass that provides an accessiblity label equal to:

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Cocoa;
#import <Cocoa/Cocoa.h>
///
/// Initiates and manages the connection to santad

View File

@@ -14,18 +14,19 @@
#import "SNTAppDelegate.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTAboutWindowController.h"
#import "SNTConfigurator.h"
#import "SNTNotificationManager.h"
#import "SNTStrengthify.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
@interface SNTAppDelegate ()
@property SNTAboutWindowController *aboutWindowController;
@property SNTNotificationManager *notificationManager;
@property SNTXPCConnection *daemonListener;
@property SNTXPCConnection *bundleListener;
@property MOLXPCConnection *daemonListener;
@property MOLXPCConnection *bundleListener;
@end
@implementation SNTAppDelegate
@@ -45,12 +46,17 @@
self.daemonListener.invalidationHandler = nil;
[self.daemonListener invalidate];
self.daemonListener = nil;
self.bundleListener.invalidationHandler = nil;
[self.bundleListener invalidate];
self.bundleListener = nil;
}];
[workspaceNotifications addObserverForName:NSWorkspaceSessionDidBecomeActiveNotification
object:nil
queue:[NSOperationQueue currentQueue]
usingBlock:^(NSNotification *note) {
[self attemptDaemonReconnection];
[self attemptBundleReconnection];
}];
[self createDaemonConnection];
@@ -72,7 +78,7 @@
// Create listener for return connection from daemon.
NSXPCListener *listener = [NSXPCListener anonymousListener];
self.daemonListener = [[SNTXPCConnection alloc] initServerWithListener:listener];
self.daemonListener = [[MOLXPCConnection alloc] initServerWithListener:listener];
self.daemonListener.exportedInterface = [SNTXPCNotifierInterface notifierInterface];
self.daemonListener.exportedObject = self.notificationManager;
self.daemonListener.acceptedHandler = ^{
@@ -85,9 +91,10 @@
[self.daemonListener resume];
// Tell daemon to connect back to the above listener.
SNTXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
MOLXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
[daemonConn resume];
[[daemonConn remoteObjectProxy] setNotificationListener:listener.endpoint];
[daemonConn invalidate];
// Now wait for the connection to come in.
if (dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) {
@@ -96,6 +103,8 @@
}
- (void)attemptDaemonReconnection {
self.daemonListener.invalidationHandler = nil;
[self.daemonListener invalidate];
[self performSelectorInBackground:@selector(createDaemonConnection) withObject:nil];
}
@@ -106,7 +115,7 @@
// Create listener for return connection from the bundle service.
NSXPCListener *listener = [NSXPCListener anonymousListener];
self.bundleListener = [[SNTXPCConnection alloc] initServerWithListener:listener];
self.bundleListener = [[MOLXPCConnection alloc] initServerWithListener:listener];
self.bundleListener.exportedInterface = [SNTXPCNotifierInterface bundleNotifierInterface];
self.bundleListener.exportedObject = self.notificationManager;
self.bundleListener.acceptedHandler = ^{
@@ -119,9 +128,10 @@
[self.bundleListener resume];
// Tell santabs to connect back to the above listener.
SNTXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
MOLXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
[daemonConn resume];
[[daemonConn remoteObjectProxy] setBundleNotificationListener:listener.endpoint];
[daemonConn invalidate];
// Now wait for the connection to come in.
if (dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) {
@@ -130,6 +140,8 @@
}
- (void)attemptBundleReconnection {
self.bundleListener.invalidationHandler = nil;
[self.bundleListener invalidate];
[self performSelectorInBackground:@selector(createBundleConnection) withObject:nil];
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -14,12 +14,13 @@
#import "SNTNotificationManager.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTBlockMessage.h"
#import "SNTConfigurator.h"
#import "SNTLogging.h"
#import "SNTStoredEvent.h"
#import "SNTStrengthify.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
@interface SNTNotificationManager ()
@@ -31,7 +32,7 @@
@property(readonly) NSMutableArray *pendingNotifications;
/// The connection to the bundle service
@property SNTXPCConnection *bundleServiceConnection;
@property MOLXPCConnection *bundleServiceConnection;
/// A semaphore to block bundle hashing until a connection is established
@property dispatch_semaphore_t bundleServiceSema;
@@ -192,7 +193,7 @@ static NSString * const silencedNotificationsKey = @"SilencedNotifications";
}
- (void)setBundleServiceListener:(NSXPCListenerEndpoint *)listener {
SNTXPCConnection *c = [[SNTXPCConnection alloc] initClientWithListener:listener];
MOLXPCConnection *c = [[MOLXPCConnection alloc] initClientWithListener:listener];
c.remoteInterface = [SNTXPCBundleServiceInterface bundleServiceInterface];
[c resume];
self.bundleServiceConnection = c;
@@ -203,6 +204,8 @@ static NSString * const silencedNotificationsKey = @"SilencedNotifications";
if (self.currentWindowController) {
[self updateBlockNotification:self.currentWindowController.event withBundleHash:nil];
}
self.bundleServiceConnection.invalidationHandler = nil;
[self.bundleServiceConnection invalidate];
};
dispatch_semaphore_signal(self.bundleServiceSema);
@@ -245,9 +248,10 @@ static NSString * const silencedNotificationsKey = @"SilencedNotifications";
}
// Send the results to santad. It will decide if they need to be synced.
SNTXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
MOLXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
[daemonConn resume];
[[daemonConn remoteObjectProxy] syncBundleEvent:event relatedEvents:events];
[daemonConn invalidate];
// Update the UI with the bundle hash. Also make the openEventButton available.
[self updateBlockNotification:event withBundleHash:bh];

View File

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

View File

@@ -13,9 +13,9 @@
/// limitations under the License.
#ifdef SANTAGUI
@import Cocoa;
#import <Cocoa/Cocoa.h>
#else
@import Foundation;
#import <Foundation/Foundation.h>
#endif
@class SNTStoredEvent;

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
///
/// These enums are used in various places throughout the Santa client code.

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import "SNTCommonEnums.h"
@@ -98,6 +98,13 @@
///
@property(readonly, nonatomic) NSString *eventLogPath;
///
/// Enabling this appends the Santa machine ID to the end of each log line. If nothing
/// has been overriden, this is the host's UUID.
/// Defaults to NO.
///
@property(readonly, nonatomic) BOOL enableMachineIDDecoration;
#pragma mark - GUI Settings
///

View File

@@ -72,6 +72,8 @@ static NSString *const kFileChangesRegexKey = @"FileChangesRegex";
static NSString *const kEventLogType = @"EventLogType";
static NSString *const kEventLogPath = @"EventLogPath";
static NSString *const kEnableMachineIDDecoration = @"EnableMachineIDDecoration";
// The keys managed by a sync server or mobileconfig.
static NSString *const kClientModeKey = @"ClientMode";
static NSString *const kWhitelistRegexKey = @"WhitelistRegex";
@@ -126,6 +128,7 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
kMachineIDPlistKeyKey : string,
kEventLogType : string,
kEventLogPath : string,
kEnableMachineIDDecoration : number,
};
_defaults = [NSUserDefaults standardUserDefaults];
[_defaults addSuiteNamed:@"com.google.santa"];
@@ -280,6 +283,10 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
return [self configStateSet];
}
+ (NSSet *)keyPathsForValuesAffectingEnableMachineIDDecoration {
return [self configStateSet];
}
#pragma mark Public Interface
- (SNTClientMode)clientMode {
@@ -451,6 +458,11 @@ static NSString *const kSyncCleanRequired = @"SyncCleanRequired";
return self.configState[kEventLogPath] ?: @"/var/db/santa/santa.log";
}
- (BOOL)enableMachineIDDecoration {
NSNumber *number = self.configState[kEnableMachineIDDecoration];
return number ? [number boolValue] : NO;
}
#pragma mark Private
///

View File

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

View File

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

View File

@@ -24,7 +24,7 @@
#include <sys/stat.h>
#include <sys/xattr.h>
#import <FMDB/FMDB.h>
#import <fmdb/FMDB.h>
// Simple class to hold the data of a mach_header and the offset within the file
// in which that header was found.
@@ -317,6 +317,26 @@ extern NSString *const NSURLQuarantinePropertiesKey WEAK_IMPORT_ATTRIBUTE;
#pragma mark Bundle Information
///
/// Directories with a "Contents/Info.plist" entry can be mistaken as a bundle. To be considered an
/// ancestor, the bundle must have a valid extension.
///
- (NSSet *)allowedAncestorExtensions {
static NSSet *set;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
set = [NSSet setWithArray:@[
@"app",
@"bundle",
@"framework",
@"kext",
@"xctest",
@"xpc",
]];
});
return set;
}
///
/// Try and determine the bundle that the represented executable is contained within, if any.
///
@@ -327,18 +347,21 @@ extern NSString *const NSURLQuarantinePropertiesKey WEAK_IMPORT_ATTRIBUTE;
///
/// This method walks up the path until a bundle is found, if any.
///
/// @param ancestor YES this will return the highest NSBundle found in the tree. No will return the
/// the lowest.
/// @param ancestor YES this will return the highest NSBundle, with a valid extension, found in the
/// tree. NO will return the the lowest NSBundle, without validating the extension.
///
-(NSBundle *)findBundleWithAncestor:(BOOL)ancestor {
- (NSBundle *)findBundleWithAncestor:(BOOL)ancestor {
NSBundle *bundle;
NSMutableArray *pathComponents = [[self.path pathComponents] mutableCopy];
// Ignore the root path "/", for some reason this is considered a bundle.
while (pathComponents.count > 1) {
NSBundle *bndl = [NSBundle bundleWithPath:[NSString pathWithComponents:pathComponents]];
if (bndl && [bndl objectForInfoDictionaryKey:@"CFBundleIdentifier"]) {
bundle = bndl;
if ([bndl objectForInfoDictionaryKey:@"CFBundleIdentifier"]) {
if (!ancestor ||
[[self allowedAncestorExtensions] containsObject:bndl.bundlePath.pathExtension]) {
bundle = bndl;
}
if (!ancestor) break;
}
[pathComponents removeLastObject];

View File

@@ -21,9 +21,6 @@
#ifndef SANTA__COMMON__KERNELCOMMON_H
#define SANTA__COMMON__KERNELCOMMON_H
// Defines the lengths of paths and Vnode IDs passed around.
#define MAX_VNODE_ID_STR 21 // digits in UINT64_MAX + 1 for NULL-terminator
// Defines the name of the userclient class and the driver bundle ID.
#define USERCLIENT_CLASS "com_google_SantaDriver"
#define USERCLIENT_ID "com.google.santa-driver"
@@ -41,6 +38,7 @@ enum SantaDriverMethods {
kSantaUserClientClearCache,
kSantaUserClientCacheCount,
kSantaUserClientCheckCache,
kSantaUserClientCacheBucketCount,
// Any methods supported by the driver should be added above this line to
// ensure this remains the count of methods.
@@ -82,10 +80,27 @@ typedef enum {
#define RESPONSE_VALID(x) \
(x == ACTION_RESPOND_ALLOW || x == ACTION_RESPOND_DENY)
// Struct to manage vnode IDs
typedef struct santa_vnode_id_t {
uint64_t fsid;
uint64_t fileid;
#ifdef __cplusplus
bool operator==(const santa_vnode_id_t& rhs) const {
return fsid == rhs.fsid && fileid == rhs.fileid;
}
// This _must not_ be used for anything security-sensitive. It exists solely to make
// the msleep/wakeup calls easier.
uint64_t unsafe_simple_id() const {
return (((uint64_t)fsid << 32) | fileid);
}
#endif
} santa_vnode_id_t;
// Message struct that is sent down the IODataQueue.
typedef struct {
santa_action_t action;
uint64_t vnode_id;
santa_vnode_id_t vnode_id;
uid_t uid;
gid_t gid;
pid_t pid;
@@ -99,4 +114,10 @@ typedef struct {
char pname[MAXPATHLEN];
} santa_message_t;
// Used for the kSantaUserClientCacheBucketCount request.
typedef struct {
uint16_t per_bucket[1024];
uint64_t start;
} santa_bucket_count_t;
#endif // SANTA__COMMON__KERNELCOMMON_H

View File

@@ -34,7 +34,7 @@
#else // KERNEL
@import Foundation;
#import <Foundation/Foundation.h>
typedef enum : NSUInteger {
LOG_LEVEL_ERROR,

View File

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

View File

@@ -32,6 +32,8 @@
#pragma mark NSSecureCoding
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-literal-conversion"
#define ENCODE(obj, key) if (obj) [coder encodeObject:obj forKey:key]
#define DECODE(cls, key) [decoder decodeObjectOfClass:[cls class] forKey:key]
@@ -59,6 +61,7 @@
#undef DECODE
#undef ENCODE
#pragma clang diagnostic pop
- (BOOL)isEqual:(id)other {
if (other == self) return YES;

View File

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

View File

@@ -18,6 +18,9 @@
@implementation SNTStoredEvent
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-literal-conversion"
#define ENCODE(obj, key) if (obj) [coder encodeObject:obj forKey:key]
#define DECODE(cls, key) [decoder decodeObjectOfClass:[cls class] forKey:key]
#define DECODEARRAY(cls, key) \
@@ -129,4 +132,6 @@
[NSString stringWithFormat:@"SNTStoredEvent[%@] with SHA-256: %@", self.idx, self.fileSHA256];
}
#pragma clang diagnostic pop
@end

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
///
/// Simple class for fetching system information

View File

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

View File

@@ -1,135 +0,0 @@
/// Copyright 2015 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
/**
A wrapper around NSXPCListener and NSXPCConnection to provide client multiplexing, signature
validation of connecting clients and forced connection establishment.
Example server started by @c launchd where the @c launchd job has a @c MachServices key:
@code
SNTXPCConnection *conn = [[SNTXPCConnection alloc] initServerWithName:@"MyServer"];
conn.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MyServerProtocol)];
conn.exportedObject = myObject;
[conn resume];
@endcode
Example client, connecting to above server:
@code
SNTXPCConnection *conn = [[SNTXPCConnection alloc] initClientWithName:"MyServer"
withOptions:0];
conn.remoteInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MyServerProtocol)];
conn.invalidationHandler = ^{ NSLog(@"Connection invalidated") };
[conn resume];
@endcode
The client can send a message to the server with:
@code
[conn.remoteObjectProxy selectorInRemoteInterface];
@endcode
One advantage of the way that SNTXPCConnection works over using NSXPCConnection directly is that
from the client-side once the resume method has finished, the connection is either valid or the
invalidation handler will be called. Ordinarily, the connection doesn't actually get made until
the first message is sent across it.
@note messages are always delivered on a background thread!
*/
@interface SNTXPCConnection : NSObject<NSXPCListenerDelegate>
/**
Initialize a new server with a given listener, provided by `[NSXPCListener anonymousListener]`.
*/
- (nullable instancetype)initServerWithListener:(nonnull NSXPCListener *)listener;
/**
Initializer for the 'server' side of the connection, started by launchd.
@param name MachService name, must match the MachServices key in the launchd.plist
*/
- (nullable instancetype)initServerWithName:(nonnull NSString *)name;
/**
Initialize a new client to a service exported by a LaunchDaemon.
@param name MachService name
@param privileged Use YES if the server is running as root.
*/
- (nullable instancetype)initClientWithName:(nonnull NSString *)name privileged:(BOOL)privileged;
/**
Initialize a new client to a service within a bundle.
@param name service name
*/
- (nullable instancetype)initClientWithServiceName:(nonnull NSString *)name;
/**
Initialize a new client with a listener endpoint sent from another process.
@param listener An NSXPCListenerEndpoint to connect to.
*/
- (nullable instancetype)initClientWithListener:(nonnull NSXPCListenerEndpoint *)listener;
/**
Call when the properties of the object have been set-up and you're ready for connections.
For clients, this call can take up to 2s to complete for connection to finish establishing though
in basically all cases it will actually complete in a few milliseconds.
*/
- (void)resume;
/**
Invalidate the connection(s). This must be done before the object can be released.
*/
- (void)invalidate;
/**
The interface the remote object should conform to. (client)
*/
@property(retain, nullable) NSXPCInterface *remoteInterface;
/**
A proxy to the object at the other end of the connection. (client)
@note If the connection to the server failed, this will be nil, so you can safely send messages
and rely on the invalidationHandler for handling the failure.
*/
@property(readonly, nonatomic, nullable) id remoteObjectProxy;
/**
The interface this object exports. (server)
*/
@property(retain, nullable) NSXPCInterface *exportedInterface;
/**
The object that responds to messages from the other end. (server)
*/
@property(retain, nullable) id exportedObject;
/**
A block to run when a/the connection is accepted and fully established.
*/
@property(copy, nullable) void (^acceptedHandler)(void);
/**
A block to run when a/the connection is invalidated/interrupted/rejected.
*/
@property(copy, nullable) void (^invalidationHandler)(void);
@end

View File

@@ -1,210 +0,0 @@
/// Copyright 2015 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import "SNTXPCConnection.h"
#import <MOLCodesignChecker/MOLCodesignChecker.h>
#import "SNTStrengthify.h"
/**
Protocol used during connection establishment, @see SNTXPCConnectionInterface
*/
@protocol SNTXPCConnectionProtocol
- (void)connectWithReply:(void (^)())reply;
@end
/**
Recipient object used during connection establishment. Each incoming connection
has one of these objects created which accept the message in the protocol
and call the block provided during creation before replying.
This allows the server to reset the connection's exported interface and
object to the correct values after the client has sent the establishment message.
*/
@interface SNTXPCConnectionInterface : NSObject<SNTXPCConnectionProtocol>
@property(strong) void (^block)(void);
@end
@implementation SNTXPCConnectionInterface
- (void)connectWithReply:(void (^)())reply {
if (self.block) self.block();
reply();
}
@end
@interface SNTXPCConnection ()
@property NSXPCInterface *validationInterface;
/// The XPC listener (server only).
@property NSXPCListener *listenerObject;
/// The current connection object (client only).
@property NSXPCConnection *currentConnection;
@end
@implementation SNTXPCConnection
#pragma mark Initializers
- (instancetype)initServerWithListener:(NSXPCListener *)listener {
self = [super init];
if (self) {
_listenerObject = listener;
_validationInterface =
[NSXPCInterface interfaceWithProtocol:@protocol(SNTXPCConnectionProtocol)];
}
return self;
}
- (instancetype)initServerWithName:(NSString *)name {
return [self initServerWithListener:[[NSXPCListener alloc] initWithMachServiceName:name]];
}
- (instancetype)initClientWithListener:(NSXPCListenerEndpoint *)listener {
self = [super init];
if (self) {
_currentConnection = [[NSXPCConnection alloc] initWithListenerEndpoint:listener];
if (!_currentConnection) return nil;
_validationInterface =
[NSXPCInterface interfaceWithProtocol:@protocol(SNTXPCConnectionProtocol)];
}
return self;
}
- (instancetype)initClientWithName:(NSString *)name privileged:(BOOL)privileged {
self = [super init];
if (self) {
NSXPCConnectionOptions options = (privileged ? NSXPCConnectionPrivileged : 0);
_currentConnection = [[NSXPCConnection alloc] initWithMachServiceName:name options:options];
if (!_currentConnection) return nil;
_validationInterface =
[NSXPCInterface interfaceWithProtocol:@protocol(SNTXPCConnectionProtocol)];
}
return self;
}
- (instancetype)initClientWithServiceName:(NSString *)name {
self = [super init];
if (self) {
_currentConnection = [[NSXPCConnection alloc] initWithServiceName:name];
if (!_currentConnection) return nil;
_validationInterface =
[NSXPCInterface interfaceWithProtocol:@protocol(SNTXPCConnectionProtocol)];
}
return self;
}
- (instancetype)init {
[self doesNotRecognizeSelector:_cmd];
return nil;
}
#pragma mark Connection set-up
- (void)resume {
if (self.listenerObject) {
self.listenerObject.delegate = self;
[self.listenerObject resume];
} else {
WEAKIFY(self);
// Set-up the connection with the remote interface set to the validation interface,
// 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.currentConnection.invalidationHandler = ^{
STRONGIFY(self);
if (self.invalidationHandler) self.invalidationHandler();
};
[self.currentConnection resume];
[[self.currentConnection remoteObjectProxy] connectWithReply:^{
STRONGIFY(self);
// The connection is now established
[self.currentConnection suspend];
self.currentConnection.remoteObjectInterface = self.remoteInterface;
[self.currentConnection resume];
dispatch_semaphore_signal(sema);
if (self.acceptedHandler) self.acceptedHandler();
}];
if (dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC))) {
// This is unusual - as we're not inside a block - but necessary in case the caller sets an
// invalidation handler that causes this instance to be released (which is a reasonable
// approach). If establishing a connection fails, the invalidation handler will be called
// and then shortly after this bit of code will run causing a crash.
STRONGIFY(self);
// Connection was not established in a reasonable time, invalidate.
self.currentConnection.remoteObjectInterface = nil; // ensure clients don't try to use it.
[self.currentConnection invalidate];
}
}
}
- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)connection {
pid_t pid = connection.processIdentifier;
MOLCodesignChecker *otherCS = [[MOLCodesignChecker alloc] initWithPID:pid];
if (![otherCS signingInformationMatches:[[MOLCodesignChecker alloc] initWithSelf]]) {
return NO;
}
// The client passed the code signature check, now we need to resume the listener and
// return YES so that the client can send the connectWithReply message. Once the client does
// we reset the connection's exportedInterface and exportedObject.
SNTXPCConnectionInterface *ci = [[SNTXPCConnectionInterface alloc] init];
WEAKIFY(self);
WEAKIFY(connection);
ci.block = ^{
STRONGIFY(self)
STRONGIFY(connection);
[connection suspend];
connection.invalidationHandler = connection.interruptionHandler = ^{
if (self.invalidationHandler) self.invalidationHandler();
};
connection.exportedInterface = self.exportedInterface;
connection.exportedObject = self.exportedObject;
[connection resume];
// The connection is now established.
if (self.acceptedHandler) self.acceptedHandler();
};
connection.exportedInterface = self.validationInterface;
connection.exportedObject = ci;
[connection resume];
return YES;
}
- (id)remoteObjectProxy {
if (self.currentConnection.remoteObjectInterface &&
self.currentConnection.remoteObjectInterface != self.validationInterface) {
return [self.currentConnection remoteObjectProxyWithErrorHandler:^(NSError *error) {
[self.currentConnection invalidate];
}];
}
return nil;
}
#pragma mark Connection tear-down
- (void)invalidate {
if (self.currentConnection) {
[self.currentConnection invalidate];
self.currentConnection = nil;
} else if (self.listenerObject) {
[self.listenerObject invalidate];
}
}
@end

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import <MOLCertificate/MOLCertificate.h>
@@ -23,7 +23,7 @@
@class SNTRule;
@class SNTStoredEvent;
@class SNTXPCConnection;
@class MOLXPCConnection;
///
/// Protocol implemented by santad and utilized by santactl
@@ -33,9 +33,11 @@
///
/// Kernel ops
///
- (void)cacheCounts:(void (^)(uint64_t rootCache, uint64_t nonRootCache))reply;
- (void)cacheCounts:(void (^)(uint64_t count))reply;
- (void)flushCache:(void (^)(BOOL))reply;
- (void)checkCacheForVnodeID:(uint64_t)vnodeID withReply:(void (^)(santa_action_t))reply;
- (void)cacheBucketCount:(void (^)(NSArray *))reply;
- (void)checkCacheForVnodeID:(santa_vnode_id_t)vnodeID withReply:(void (^)(santa_action_t))reply;
- (void)driverConnectionEstablished:(void (^)(BOOL))reply;
///
/// Database ops
@@ -72,19 +74,19 @@
///
- (void)watchdogInfo:(void (^)(uint64_t, uint64_t, double, double))reply;
- (void)clientMode:(void (^)(SNTClientMode))reply;
- (void)setClientMode:(SNTClientMode)mode reply:(void (^)())reply;
- (void)setClientMode:(SNTClientMode)mode reply:(void (^)(void))reply;
- (void)xsrfToken:(void (^)(NSString *))reply;
- (void)setXsrfToken:(NSString *)token reply:(void (^)())reply;
- (void)setXsrfToken:(NSString *)token reply:(void (^)(void))reply;
- (void)fullSyncLastSuccess:(void (^)(NSDate *))reply;
- (void)setFullSyncLastSuccess:(NSDate *)date reply:(void (^)())reply;
- (void)setFullSyncLastSuccess:(NSDate *)date reply:(void (^)(void))reply;
- (void)ruleSyncLastSuccess:(void (^)(NSDate *))reply;
- (void)setRuleSyncLastSuccess:(NSDate *)date reply:(void (^)())reply;
- (void)setRuleSyncLastSuccess:(NSDate *)date reply:(void (^)(void))reply;
- (void)syncCleanRequired:(void (^)(BOOL))reply;
- (void)setSyncCleanRequired:(BOOL)cleanReqd reply:(void (^)())reply;
- (void)setWhitelistPathRegex:(NSString *)pattern reply:(void (^)())reply;
- (void)setBlacklistPathRegex:(NSString *)pattern reply:(void (^)())reply;
- (void)setSyncCleanRequired:(BOOL)cleanReqd reply:(void (^)(void))reply;
- (void)setWhitelistPathRegex:(NSString *)pattern reply:(void (^)(void))reply;
- (void)setBlacklistPathRegex:(NSString *)pattern reply:(void (^)(void))reply;
- (void)bundlesEnabled:(void (^)(BOOL))reply;
- (void)setBundlesEnabled:(BOOL)bundlesEnabled reply:(void (^)())reply;
- (void)setBundlesEnabled:(BOOL)bundlesEnabled reply:(void (^)(void))reply;
///
/// GUI Ops
@@ -97,7 +99,7 @@
///
- (void)setSyncdListener:(NSXPCListenerEndpoint *)listener;
- (void)pushNotifications:(void (^)(BOOL))reply;
- (void)postRuleSyncNotificationWithCustomMessage:(NSString *)message reply:(void (^)())reply;
- (void)postRuleSyncNotificationWithCustomMessage:(NSString *)message reply:(void (^)(void))reply;
///
/// Bundle Ops
@@ -121,9 +123,9 @@
+ (NSXPCInterface *)controlInterface;
///
/// Retrieve a pre-configured SNTXPCConnection for communicating with santad.
/// Retrieve a pre-configured MOLXPCConnection for communicating with santad.
/// Connections just needs any handlers set and then can be resumed and used.
///
+ (SNTXPCConnection *)configuredConnection;
+ (MOLXPCConnection *)configuredConnection;
@end

View File

@@ -14,9 +14,10 @@
#import "SNTXPCControlInterface.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTRule.h"
#import "SNTStoredEvent.h"
#import "SNTXPCConnection.h"
@implementation SNTXPCControlInterface
@@ -50,8 +51,8 @@
return r;
}
+ (SNTXPCConnection *)configuredConnection {
SNTXPCConnection *c = [[SNTXPCConnection alloc] initClientWithName:[self serviceId]
+ (MOLXPCConnection *)configuredConnection {
MOLXPCConnection *c = [[MOLXPCConnection alloc] initClientWithName:[self serviceId]
privileged:YES];
c.remoteInterface = [self controlInterface];
return c;

View File

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

View File

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

View File

@@ -40,9 +40,21 @@
#define OSDecrementAtomic(addr) OSAtomicDecrement64((volatile int64_t *)addr)
#endif // KERNEL
/**
A type to specialize to help SantaCache with its hashing.
The default works for numeric types with a multiplicative hash
using a prime near to the golden ratio, per Knuth.
*/
template<typename T> uint64_t SantaCacheHasher(T const& t) {
return t * 11400714819323198549UL;
};
/**
A somewhat simple, concurrent linked-list hash table intended for use in IOKit kernel extensions.
Maps 64-bit unsigned integer keys to values.
The type used for keys must overload the == operator and a specialization of
SantaCacheHasher must exist for it.
Enforces a maximum size by clearing all entries if a new value
is added that would go over the maximum size declared at creation.
@@ -50,7 +62,7 @@
The number of buckets is calculated as `maximum_size` / `per_bucket`
rounded up to the next power of 2. Locking is done per-bucket.
*/
template<class T> class SantaCache {
template<typename KeyT, typename ValueT> class SantaCache {
public:
/**
Initialize a newly created cache.
@@ -65,8 +77,7 @@ template<class T> class SantaCache {
if (unlikely(per_bucket < 1)) per_bucket = 1;
if (unlikely(per_bucket > 64)) per_bucket = 64;
max_size_ = maximum_size;
bucket_count_ = 1 << (32 - __builtin_clz(
((uint32_t)max_size_ / per_bucket) - 1));
bucket_count_ = 1 << (32 - __builtin_clz(((uint32_t)max_size_ / per_bucket) - 1));
buckets_ = (struct bucket *)IOMalloc(bucket_count_ * sizeof(struct bucket));
bzero(buckets_, bucket_count_ * sizeof(struct bucket));
}
@@ -82,13 +93,13 @@ template<class T> class SantaCache {
/**
Get an element from the cache. Returns zero_ if item doesn't exist.
*/
T get(uint64_t key) {
ValueT get(KeyT key) {
struct bucket *bucket = &buckets_[hash(key)];
lock(bucket);
struct entry *entry = (struct entry *)((uintptr_t)bucket->head - 1);
while (entry != nullptr) {
if (entry->key == key) {
T val = entry->value;
ValueT val = entry->value;
unlock(bucket);
return val;
}
@@ -102,103 +113,39 @@ template<class T> class SantaCache {
Set an element in the cache.
@note If the cache is full when this is called, this will
empty the cache before inserting the new value.
empty the cache before inserting the new value.
@param key, The key
@param value, The value with parameterized type
@param previous_value, If the has_prev_value parameter is true the new
value will only be set if this parameter is equal to the provided value.
This allows set to become a CAS operation.
@param has_prev_value, Pass true if previous_value should be used.
@param key, The key.
@param value, The value with parameterized type.
@return the previous value (which may be zero_)
@return true if the value was set.
*/
T set(uint64_t key, T value, T previous_value, bool has_prev_value) {
struct bucket *bucket = &buckets_[hash(key)];
lock(bucket);
struct entry *entry = (struct entry *)((uintptr_t)bucket->head - 1);
struct entry *previous_entry = nullptr;
while (entry != nullptr) {
if (entry->key == key) {
T existing_value = entry->value;
if (has_prev_value && previous_value != existing_value) {
unlock(bucket);
return existing_value;
}
entry->value = value;
if (value == zero_) {
if (previous_entry != nullptr) {
previous_entry->next = entry->next;
} else {
bucket->head = (struct entry *)((uintptr_t)entry->next + 1);
}
IOFreeAligned(entry, sizeof(struct entry));
OSDecrementAtomic(&count_);
}
unlock(bucket);
return existing_value;
}
previous_entry = entry;
entry = entry->next;
}
// If value is zero_, we're clearing but there's nothing to clear
// so we don't need to do anything else. Alternatively, if has_prev_value
// is true and is not zero_ we don't want to set a value.
if (value == zero_ || (has_prev_value && previous_value != zero_)) {
unlock(bucket);
return zero_;
}
// Check that adding this new item won't take the cache
// over its maximum size.
if (count_ + 1 > max_size_) {
unlock(bucket);
lock(&clear_bucket_);
// Check again in case clear has already run while waiting for lock
if (count_ + 1 > max_size_) {
clear();
}
lock(bucket);
unlock(&clear_bucket_);
}
// Allocate a new entry, set the key and value, then put this new entry at
// the head of this bucket's linked list.
struct entry *new_entry = (struct entry *)IOMallocAligned(
sizeof(struct entry), 2);
new_entry->key = key;
new_entry->value = value;
new_entry->next = (struct entry *)((uintptr_t)bucket->head - 1);
bucket->head = (struct entry *)((uintptr_t)new_entry + 1);
OSIncrementAtomic(&count_);
unlock(bucket);
return zero_;
}
/**
Overload to allow setting without providing a previous value
*/
T set(uint64_t key, T value) {
bool set(KeyT key, ValueT value) {
return set(key, value, {}, false);
}
/**
Overload to allow setting while providing a previous value
Set an element in the cache.
@note If the cache is full when this is called, this will
empty the cache before inserting the new value.
@param key, The key.
@param value, The value with parameterized type.
@param previous_value, the new value will only be set if this
parameter is equal to the existing value in the cache.
This allows set to become a CAS operation.
@return true if the value was set
*/
T set(uint64_t key, T value, T previous_value) {
bool set(KeyT key, ValueT value, ValueT previous_value) {
return set(key, value, previous_value, true);
}
/**
An alias for `set(key, zero_)`
*/
inline void remove(uint64_t key) {
inline void remove(KeyT key) {
set(key, zero_);
}
@@ -238,10 +185,42 @@ template<class T> class SantaCache {
return count_;
}
/**
Fill in the per_bucket_counts array with the number of entries in each bucket.
The per_buckets_count array will contain the per-bucket counts, up to the number
in array_size. The start_bucket parameter will determine which bucket to start off
with and upon return will contain either 0 if no buckets are remaining or the next
bucket to begin with when called again.
*/
void bucket_counts(uint16_t *per_bucket_counts, uint16_t *array_size, uint64_t *start_bucket) {
if (per_bucket_counts == nullptr || array_size == nullptr || start_bucket == nullptr) return;
uint64_t start = *start_bucket;
uint16_t size = *array_size;
if (start + size > bucket_count_) size = bucket_count_ - start;
for (uint16_t i = 0; i < size; ++i) {
uint16_t count = 0;
struct bucket *bucket = &buckets_[start++];
lock(bucket);
struct entry *entry = (struct entry *)((uintptr_t)bucket->head - 1);
while (entry != nullptr) {
if (entry->value != zero_) ++count;
entry = entry->next;
}
unlock(bucket);
per_bucket_counts[i] = count;
}
*array_size = size;
*start_bucket = (start >= bucket_count_) ? 0 : start;
}
private:
struct entry {
uint64_t key;
T value;
KeyT key;
ValueT value;
struct entry *next;
};
@@ -251,6 +230,88 @@ template<class T> class SantaCache {
struct entry *head;
};
/**
Set an element in the cache.
@note If the cache is full when this is called, this will
empty the cache before inserting the new value.
@param key, The key
@param value, The value with parameterized type
@param previous_value, If has_prev_value is true, the new value will only
be set if this parameter is equal to the existing value in the cache.
This allows set to become a CAS operation.
@param has_prev_value, Pass true if previous_value should be used.
@return true if the entry was set, false if it was not
*/
bool set(KeyT key, ValueT value, ValueT previous_value, bool has_prev_value) {
struct bucket *bucket = &buckets_[hash(key)];
lock(bucket);
struct entry *entry = (struct entry *)((uintptr_t)bucket->head - 1);
struct entry *previous_entry = nullptr;
while (entry != nullptr) {
if (entry->key == key) {
ValueT existing_value = entry->value;
if (has_prev_value && previous_value != existing_value) {
unlock(bucket);
return false;
}
entry->value = value;
if (value == zero_) {
if (previous_entry != nullptr) {
previous_entry->next = entry->next;
} else {
bucket->head = (struct entry *)((uintptr_t)entry->next + 1);
}
IOFreeAligned(entry, sizeof(struct entry));
OSDecrementAtomic(&count_);
}
unlock(bucket);
return true;
}
previous_entry = entry;
entry = entry->next;
}
// If value is zero_, we're clearing but there's nothing to clear
// so we don't need to do anything else. Alternatively, if has_prev_value
// is true and is not zero_ we don't want to set a value.
if (value == zero_ || (has_prev_value && previous_value != zero_)) {
unlock(bucket);
return false;
}
// Check that adding this new item won't take the cache
// over its maximum size.
if (count_ + 1 > max_size_) {
unlock(bucket);
lock(&clear_bucket_);
// Check again in case clear has already run while waiting for lock
if (count_ + 1 > max_size_) {
clear();
}
lock(bucket);
unlock(&clear_bucket_);
}
// Allocate a new entry, set the key and value, then put this new entry at
// the head of this bucket's linked list.
struct entry *new_entry = (struct entry *)IOMallocAligned(sizeof(struct entry), 2);
new_entry->key = key;
new_entry->value = value;
new_entry->next = (struct entry *)((uintptr_t)bucket->head - 1);
bucket->head = (struct entry *)((uintptr_t)new_entry + 1);
OSIncrementAtomic(&count_);
unlock(bucket);
return true;
}
/**
Lock a bucket. Spins until the lock is acquired.
*/
@@ -277,7 +338,7 @@ template<class T> class SantaCache {
/**
Holder for a 'zero' entry for the current type
*/
const T zero_ = {};
const ValueT zero_ = {};
/**
Special bucket used when automatically clearing due to size
@@ -288,13 +349,9 @@ template<class T> class SantaCache {
/**
Hash a key to determine which bucket it belongs in.
Multiplicative hash using a prime near to the golden ratio, per Knuth.
This seems to have good bucket distribution generally and for the range of
values we expect to see.
*/
inline uint64_t hash(uint64_t input) const {
return (input * 11400714819323198549ul) % bucket_count_;
inline uint64_t hash(KeyT input) const {
return SantaCacheHasher<KeyT>(input) % bucket_count_;
}
};

View File

@@ -19,6 +19,10 @@ OSDefineMetaClassAndStructors(SantaDecisionManager, OSObject);
#pragma mark Object Lifecycle
template<> uint64_t SantaCacheHasher<santa_vnode_id_t>(santa_vnode_id_t const& s) {
return (SantaCacheHasher<uint64_t>(s.fsid) << 1) ^ SantaCacheHasher<uint64_t>(s.fileid);
}
bool SantaDecisionManager::init() {
if (!super::init()) return false;
@@ -29,9 +33,8 @@ bool SantaDecisionManager::init() {
decision_dataqueue_lock_ = lck_mtx_alloc_init(sdm_lock_grp_, sdm_lock_attr_);
log_dataqueue_lock_ = lck_mtx_alloc_init(sdm_lock_grp_, sdm_lock_attr_);
root_decision_cache_ = new SantaCache<uint64_t>(5000, 2);
non_root_decision_cache_ = new SantaCache<uint64_t>(500, 2);
vnode_pid_map_ = new SantaCache<uint64_t>(2000, 5);
decision_cache_ = new SantaCache<santa_vnode_id_t, uint64_t>(10000, 2);
vnode_pid_map_ = new SantaCache<santa_vnode_id_t, uint64_t>(2000, 5);
decision_dataqueue_ = IOSharedDataQueue::withEntries(
kMaxDecisionQueueEvents, sizeof(santa_message_t));
@@ -42,17 +45,12 @@ bool SantaDecisionManager::init() {
if (!log_dataqueue_) return kIOReturnNoMemory;
client_pid_ = 0;
root_fsid_ = 0;
ts_ = { .tv_sec = kRequestLoopSleepMilliseconds / 1000,
.tv_nsec = kRequestLoopSleepMilliseconds % 1000 * 1000000 };
return true;
}
void SantaDecisionManager::free() {
delete root_decision_cache_;
delete non_root_decision_cache_;
delete decision_cache_;
delete vnode_pid_map_;
if (decision_dataqueue_lock_) {
@@ -93,17 +91,6 @@ void SantaDecisionManager::ConnectClient(pid_t pid) {
client_pid_ = pid;
// Determine root fsid
vfs_context_t ctx = vfs_context_create(NULL);
if (ctx) {
vnode_t root = vfs_rootvnode();
if (root) {
root_fsid_ = GetVnodeIDForVnode(ctx, root) >> 32;
vnode_put(root);
}
vfs_context_rele(ctx);
}
// Any decisions made while the daemon wasn't
// connected should be cleared
ClearCache();
@@ -112,8 +99,8 @@ void SantaDecisionManager::ConnectClient(pid_t pid) {
failed_log_queue_requests_ = 0;
}
void SantaDecisionManager::DisconnectClient(bool itDied) {
if (client_pid_ < 1) return;
void SantaDecisionManager::DisconnectClient(bool itDied, pid_t pid) {
if (client_pid_ == 0 || (pid > 0 && pid != client_pid_)) return;
client_pid_ = 0;
// Ask santad to shutdown, in case it's running.
@@ -210,74 +197,58 @@ kern_return_t SantaDecisionManager::StopListener() {
#pragma mark Cache Management
/**
Return the correct cache for a given identifier.
@param identifier The identifier
@return SantaCache* The cache to use
*/
SantaCache<uint64_t>* SantaDecisionManager::CacheForIdentifier(
const uint64_t identifier) {
return (identifier >> 32 == root_fsid_) ?
root_decision_cache_ : non_root_decision_cache_;
}
void SantaDecisionManager::AddToCache(
uint64_t identifier, santa_action_t decision, uint64_t microsecs) {
// Decision is stored in upper 8 bits, timestamp in remaining 56.
uint64_t val = ((uint64_t)decision << 56) | (microsecs & 0xFFFFFFFFFFFFFF);
auto decision_cache = CacheForIdentifier(identifier);
santa_vnode_id_t identifier, santa_action_t decision, uint64_t microsecs) {
switch (decision) {
case ACTION_REQUEST_BINARY:
decision_cache->set(identifier, val, 0);
decision_cache_->set(identifier, (uint64_t)ACTION_REQUEST_BINARY << 56, 0);
break;
case ACTION_RESPOND_ACK:
decision_cache->set(identifier, val, ((uint64_t)ACTION_REQUEST_BINARY << 56));
decision_cache_->set(identifier, (uint64_t)ACTION_RESPOND_ACK << 56,
((uint64_t)ACTION_REQUEST_BINARY << 56));
break;
case ACTION_RESPOND_ALLOW:
case ACTION_RESPOND_DENY:
// TODO(bur): Avoid calling set() twice, finding and locking buckets is fast, but not free.
if (decision_cache->set(identifier, val, ((uint64_t)ACTION_REQUEST_BINARY << 56))) {
decision_cache->set(identifier, val, ((uint64_t)ACTION_RESPOND_ACK << 56));
case ACTION_RESPOND_DENY: {
// Decision is stored in upper 8 bits, timestamp in remaining 56.
uint64_t val = ((uint64_t)decision << 56) | (microsecs & 0xFFFFFFFFFFFFFF);
if (!decision_cache_->set(identifier, val, ((uint64_t)ACTION_REQUEST_BINARY << 56))) {
decision_cache_->set(identifier, val, ((uint64_t)ACTION_RESPOND_ACK << 56));
}
break;
}
default:
break;
}
wakeup((void *)identifier);
wakeup((void *)identifier.unsafe_simple_id());
}
void SantaDecisionManager::RemoveFromCache(uint64_t identifier) {
CacheForIdentifier(identifier)->remove(identifier);
if (unlikely(!identifier)) return;
wakeup((void *)identifier);
void SantaDecisionManager::RemoveFromCache(santa_vnode_id_t identifier) {
if (unlikely(identifier.fsid == 0 && identifier.fileid == 0)) return;
decision_cache_->remove(identifier);
wakeup((void *)identifier.unsafe_simple_id());
}
uint64_t SantaDecisionManager::RootCacheCount() const {
return root_decision_cache_->count();
uint64_t SantaDecisionManager::CacheCount() const {
return decision_cache_->count();
}
uint64_t SantaDecisionManager::NonRootCacheCount() const {
return non_root_decision_cache_->count();
void SantaDecisionManager::ClearCache() {
decision_cache_->clear();
}
void SantaDecisionManager::ClearCache(bool non_root_only) {
if (!non_root_only) root_decision_cache_->clear();
non_root_decision_cache_->clear();
void SantaDecisionManager::CacheBucketCount(
uint16_t *per_bucket_counts, uint16_t *array_size, uint64_t *start_bucket) {
decision_cache_->bucket_counts(per_bucket_counts, array_size, start_bucket);
}
#pragma mark Decision Fetching
santa_action_t SantaDecisionManager::GetFromCache(uint64_t identifier) {
santa_action_t SantaDecisionManager::GetFromCache(santa_vnode_id_t identifier) {
auto result = ACTION_UNSET;
uint64_t decision_time = 0;
auto decision_cache = CacheForIdentifier(identifier);
uint64_t cache_val = decision_cache->get(identifier);
uint64_t cache_val = decision_cache_->get(identifier);
if (cache_val == 0) return result;
// Decision is stored in upper 8 bits, timestamp in remaining 56.
@@ -288,7 +259,7 @@ santa_action_t SantaDecisionManager::GetFromCache(uint64_t identifier) {
if (result == ACTION_RESPOND_DENY) {
auto expiry_time = decision_time + (kMaxDenyCacheTimeMilliseconds * 1000);
if (expiry_time < GetCurrentUptime()) {
decision_cache->remove(identifier);
decision_cache_->remove(identifier);
return ACTION_UNSET;
}
}
@@ -298,7 +269,7 @@ santa_action_t SantaDecisionManager::GetFromCache(uint64_t identifier) {
}
santa_action_t SantaDecisionManager::GetFromDaemon(
santa_message_t *message, uint64_t identifier) {
santa_message_t *message, santa_vnode_id_t identifier) {
auto return_action = ACTION_UNSET;
#ifdef DEBUG
@@ -326,7 +297,7 @@ santa_action_t SantaDecisionManager::GetFromDaemon(
// request, indicated with ACTION_RESPOND_ACK.
auto cache_check_count = 0;
do {
msleep((void *)message->vnode_id, NULL, 0, "", &ts_);
msleep((void *)message->vnode_id.unsafe_simple_id(), NULL, 0, "", &ts_);
return_action = GetFromCache(identifier);
} while (ClientConnected() &&
((return_action == ACTION_REQUEST_BINARY && ++cache_check_count < kRequestCacheChecks)
@@ -353,7 +324,7 @@ santa_action_t SantaDecisionManager::GetFromDaemon(
santa_action_t SantaDecisionManager::FetchDecision(
const kauth_cred_t cred,
const vnode_t vp,
const uint64_t vnode_id) {
const santa_vnode_id_t vnode_id) {
while (true) {
if (!ClientConnected()) return ACTION_RESPOND_ALLOW;
@@ -368,7 +339,7 @@ santa_action_t SantaDecisionManager::FetchDecision(
} else if (return_action == ACTION_REQUEST_BINARY || return_action == ACTION_RESPOND_ACK) {
// This thread will now sleep for kRequestLoopSleepMilliseconds (1s) or
// until AddToCache is called, indicating a response has arrived.
msleep((void *)vnode_id, NULL, 0, "", &ts_);
msleep((void *)vnode_id.unsafe_simple_id(), NULL, 0, "", &ts_);
} else {
break;
}
@@ -403,7 +374,6 @@ bool SantaDecisionManager::PostToDecisionQueue(santa_message_t *message) {
LOGE("Failed to queue more than %d decision requests, killing daemon",
kMaxDecisionQueueFailures);
proc_signal(client_pid_, SIGKILL);
client_pid_ = 0;
}
}
lck_mtx_unlock(decision_dataqueue_lock_);
@@ -417,10 +387,6 @@ bool SantaDecisionManager::PostToLogQueue(santa_message_t *message) {
if (failed_log_queue_requests_++ == 0) {
LOGW("Dropping log queue messages");
}
// If enqueue failed, pop an item off the queue and try again.
uint32_t dataSize = 0;
log_dataqueue_->dequeue(0, &dataSize);
kr = log_dataqueue_->enqueue(message, sizeof(santa_message_t));
} else {
if (failed_log_queue_requests_ > 0) {
failed_log_queue_requests_--;
@@ -448,19 +414,11 @@ int SantaDecisionManager::VnodeCallback(const kauth_cred_t cred,
int *errno) {
// Get ID for the vnode
auto vnode_id = GetVnodeIDForVnode(ctx, vp);
if (!vnode_id) return KAUTH_RESULT_DEFER;
if (vnode_id.fsid == 0 && vnode_id.fileid == 0) return KAUTH_RESULT_DEFER;
// Fetch decision
auto returnedAction = FetchDecision(cred, vp, vnode_id);
// If file has dirty blocks, remove from cache and deny. This would usually
// be the case if a file has been written to and flushed but not yet
// closed.
if (vnode_hasdirtyblks(vp)) {
RemoveFromCache(vnode_id);
returnedAction = ACTION_RESPOND_DENY;
}
switch (returnedAction) {
case ACTION_RESPOND_ALLOW: {
auto proc = vfs_context_proc(ctx);
@@ -497,9 +455,7 @@ void SantaDecisionManager::FileOpCallback(
auto vnode_id = GetVnodeIDForVnode(context, vp);
vfs_context_rele(context);
if (action == KAUTH_FILEOP_CLOSE) {
RemoveFromCache(vnode_id);
} else if (action == KAUTH_FILEOP_EXEC) {
if (action == KAUTH_FILEOP_EXEC) {
auto message = NewMessage(nullptr);
message->vnode_id = vnode_id;
message->action = ACTION_NOTIFY_EXEC;
@@ -615,8 +571,12 @@ extern "C" int vnode_scope_callback(
reinterpret_cast<int *>(arg3));
sdm->DecrementListenerInvocations();
return result;
} else if (action & KAUTH_VNODE_WRITE_DATA) {
} else if (action & KAUTH_VNODE_WRITE_DATA || action & KAUTH_VNODE_APPEND_DATA) {
sdm->IncrementListenerInvocations();
if (!(action & KAUTH_VNODE_ACCESS)) {
auto vnode_id = sdm->GetVnodeIDForVnode(reinterpret_cast<vfs_context_t>(arg0), vp);
sdm->RemoveFromCache(vnode_id);
}
char path[MAXPATHLEN];
int pathlen = MAXPATHLEN;
vn_getpath(vp, path, &pathlen);

View File

@@ -64,7 +64,7 @@ class SantaDecisionManager : public OSObject {
void ConnectClient(pid_t pid);
/// Called by SantaDriverClient when a client disconnects
void DisconnectClient(bool itDied = false);
void DisconnectClient(bool itDied = false, pid_t pid = proc_selfpid());
/// Returns whether a client is currently connected or not.
bool ClientConnected() const;
@@ -86,7 +86,7 @@ class SantaDecisionManager : public OSObject {
kern_return_t StopListener();
/// Adds a decision to the cache, with a timestamp.
void AddToCache(uint64_t identifier,
void AddToCache(santa_vnode_id_t identifier,
const santa_action_t decision,
const uint64_t microsecs = GetCurrentUptime());
@@ -94,20 +94,30 @@ class SantaDecisionManager : public OSObject {
Fetches a response from the cache, first checking to see if the entry
has expired.
*/
santa_action_t GetFromCache(uint64_t identifier);
santa_action_t GetFromCache(santa_vnode_id_t identifier);
/// Checks to see if a given identifier is in the cache and removes it.
void RemoveFromCache(uint64_t identifier);
void RemoveFromCache(santa_vnode_id_t identifier);
/// Returns the number of entries in the cache.
uint64_t RootCacheCount() const;
uint64_t NonRootCacheCount() const;
uint64_t CacheCount() const;
/// Clears the cache.
void ClearCache();
/**
Clears the cache(s). If non_root_only is true, only the non-root cache
is cleared.
Fills out the per_bucket_counts array with the number of items in each bucket in the
non-root decision cache.
@param per_bucket_counts An array of uint16_t's to fill in with the number of items in each
bucket. The size of this array is expected to equal array_size.
@param array_size The size of the per_bucket_counts array on input. Upon return this will be
updated to the number of slots that were actually used.
@param start_bucket If non-zero this is the bucket in the cache to start from. Upon return this
will be the next numbered bucket to start from for subsequent requests.
*/
void ClearCache(bool non_root_only = false);
void CacheBucketCount(uint16_t *per_bucket_counts, uint16_t *array_size, uint64_t *start_bucket);
/// Increments the count of active callbacks pending.
void IncrementListenerInvocations();
@@ -115,6 +125,25 @@ class SantaDecisionManager : public OSObject {
/// Decrements the count of active callbacks pending.
void DecrementListenerInvocations();
/**
Fetches the vnode_id for a given vnode.
@param ctx The VFS context to use.
@param vp The Vnode to get the ID for
@return santa_vnode_id_t The Vnode ID.
*/
static inline santa_vnode_id_t GetVnodeIDForVnode(const vfs_context_t ctx, const vnode_t vp) {
struct vnode_attr vap;
VATTR_INIT(&vap);
VATTR_WANTED(&vap, va_fsid);
VATTR_WANTED(&vap, va_fileid);
vnode_getattr(vp, &vap, ctx);
return {
.fsid = vap.va_fsid,
.fileid = vap.va_fileid
};
}
/**
Vnode Callback
@@ -182,7 +211,7 @@ class SantaDecisionManager : public OSObject {
@param identifier The vnode ID string for this request
@return santa_action_t The response for this request
*/
santa_action_t GetFromDaemon(santa_message_t *message, uint64_t identifier);
santa_action_t GetFromDaemon(santa_message_t *message, santa_vnode_id_t identifier);
/**
Fetches an execution decision for a file, first using the cache and then
@@ -196,7 +225,7 @@ class SantaDecisionManager : public OSObject {
@return santa_action_t The response for this request
*/
santa_action_t FetchDecision(
const kauth_cred_t cred, const vnode_t vp, const uint64_t vnode_id);
const kauth_cred_t cred, const vnode_t vp, const santa_vnode_id_t vnode_id);
/**
Posts the requested message to the decision data queue.
@@ -214,23 +243,6 @@ class SantaDecisionManager : public OSObject {
*/
bool PostToLogQueue(santa_message_t *message);
/**
Fetches the vnode_id for a given vnode.
@param ctx The VFS context to use.
@param vp The Vnode to get the ID for
@return uint64_t The Vnode ID as a 64-bit unsigned int.
*/
static inline uint64_t GetVnodeIDForVnode(
const vfs_context_t ctx, const vnode_t vp) {
struct vnode_attr vap;
VATTR_INIT(&vap);
VATTR_WANTED(&vap, va_fsid);
VATTR_WANTED(&vap, va_fileid);
vnode_getattr(vp, &vap, ctx);
return (((uint64_t)vap.va_fsid << 32) | vap.va_fileid);
}
/**
Creates a new santa_message_t with some fields pre-filled.
@@ -267,21 +279,8 @@ class SantaDecisionManager : public OSObject {
return (uint64_t)((sec * 1000000) + usec);
}
SantaCache<uint64_t> *root_decision_cache_;
SantaCache<uint64_t> *non_root_decision_cache_;
SantaCache<uint64_t> *vnode_pid_map_;
/**
Return the correct cache for a given identifier.
@param identifier The identifier
@return SantaCache* The cache to use
*/
SantaCache<uint64_t>* CacheForIdentifier(const uint64_t identifier);
// This is the file system ID of the root filesystem,
// used to determine which cache to use for requests
uint32_t root_fsid_;
SantaCache<santa_vnode_id_t, uint64_t> *decision_cache_;
SantaCache<santa_vnode_id_t, uint64_t> *vnode_pid_map_;
lck_grp_t *sdm_lock_grp_;
lck_grp_attr_t *sdm_lock_grp_attr_;
@@ -302,7 +301,8 @@ class SantaDecisionManager : public OSObject {
kauth_listener_t vnode_listener_;
kauth_listener_t fileop_listener_;
struct timespec ts_;
struct timespec ts_= { .tv_sec = kRequestLoopSleepMilliseconds / 1000,
.tv_nsec = kRequestLoopSleepMilliseconds % 1000 * 1000000 };
};
/**

View File

@@ -37,34 +37,38 @@ bool SantaDriverClient::initWithTask(
bool SantaDriverClient::start(IOService *provider) {
myProvider = OSDynamicCast(com_google_SantaDriver, provider);
if (!myProvider) return false;
if (!super::start(provider)) return false;
decisionManager = myProvider->GetDecisionManager();
if (!decisionManager) return false;
decisionManager->retain();
return true;
return super::start(provider);
}
void SantaDriverClient::stop(IOService *provider) {
super::stop(provider);
myProvider = nullptr;
decisionManager->release();
decisionManager = nullptr;
super::stop(provider);
}
IOReturn SantaDriverClient::clientDied() {
LOGI("Client died.");
decisionManager->DisconnectClient(true);
return terminate(0) ? kIOReturnSuccess : kIOReturnError;
}
IOReturn SantaDriverClient::clientClose() {
decisionManager->DisconnectClient(true);
return terminate(kIOServiceSynchronous) ? kIOReturnSuccess : kIOReturnError;
LOGI("Client disconnected.");
decisionManager->DisconnectClient();
return terminate(0) ? kIOReturnSuccess : kIOReturnError;
}
bool SantaDriverClient::terminate(IOOptionBits options) {
decisionManager->DisconnectClient();
LOGI("Client disconnected.");
bool SantaDriverClient::didTerminate(IOService *provider, IOOptionBits options, bool *defer) {
decisionManager->DisconnectClient(false, 0);
if (myProvider && myProvider->isOpen(this)) myProvider->close(this);
return super::terminate(options);
return super::didTerminate(provider, options, defer);
}
#pragma mark Fetching memory and data queue notifications
@@ -133,9 +137,10 @@ IOReturn SantaDriverClient::allow_binary(
SantaDriverClient *me = OSDynamicCast(SantaDriverClient, target);
if (!me) return kIOReturnBadArgument;
const uint64_t vnode_id = static_cast<const uint64_t>(arguments->scalarInput[0]);
if (!vnode_id) return kIOReturnInvalid;
me->decisionManager->AddToCache(vnode_id, ACTION_RESPOND_ALLOW);
if (arguments->structureInputSize != sizeof(santa_vnode_id_t)) return kIOReturnInvalid;
santa_vnode_id_t *vnode_id = (santa_vnode_id_t *)arguments->structureInput;
if (vnode_id->fsid == 0 || vnode_id->fileid == 0) return kIOReturnInvalid;
me->decisionManager->AddToCache(*vnode_id, ACTION_RESPOND_ALLOW);
return kIOReturnSuccess;
}
@@ -145,9 +150,10 @@ IOReturn SantaDriverClient::deny_binary(
SantaDriverClient *me = OSDynamicCast(SantaDriverClient, target);
if (!me) return kIOReturnBadArgument;
const uint64_t vnode_id = static_cast<const uint64_t>(arguments->scalarInput[0]);
if (!vnode_id) return kIOReturnInvalid;
me->decisionManager->AddToCache(vnode_id, ACTION_RESPOND_DENY);
if (arguments->structureInputSize != sizeof(santa_vnode_id_t)) return kIOReturnInvalid;
santa_vnode_id_t *vnode_id = (santa_vnode_id_t *)arguments->structureInput;
if (vnode_id->fsid == 0 || vnode_id->fileid == 0) return kIOReturnInvalid;
me->decisionManager->AddToCache(*vnode_id, ACTION_RESPOND_DENY);
return kIOReturnSuccess;
}
@@ -157,9 +163,10 @@ IOReturn SantaDriverClient::acknowledge_binary(
SantaDriverClient *me = OSDynamicCast(SantaDriverClient, target);
if (!me) return kIOReturnBadArgument;
const uint64_t vnode_id = static_cast<const uint64_t>(arguments->scalarInput[0]);
if (!vnode_id) return kIOReturnInvalid;
me->decisionManager->AddToCache(vnode_id, ACTION_RESPOND_ACK, 0);
if (arguments->structureInputSize != sizeof(santa_vnode_id_t)) return kIOReturnInvalid;
santa_vnode_id_t *vnode_id = (santa_vnode_id_t *)arguments->structureInput;
if (vnode_id->fsid == 0 || vnode_id->fileid == 0) return kIOReturnInvalid;
me->decisionManager->AddToCache(*vnode_id, ACTION_RESPOND_ACK);
return kIOReturnSuccess;
}
@@ -169,8 +176,7 @@ IOReturn SantaDriverClient::clear_cache(
SantaDriverClient *me = OSDynamicCast(SantaDriverClient, target);
if (!me) return kIOReturnBadArgument;
const bool non_root_only = static_cast<const bool>(arguments->scalarInput[0]);
me->decisionManager->ClearCache(non_root_only);
me->decisionManager->ClearCache();
return kIOReturnSuccess;
}
@@ -180,8 +186,7 @@ IOReturn SantaDriverClient::cache_count(
SantaDriverClient *me = OSDynamicCast(SantaDriverClient, target);
if (!me) return kIOReturnBadArgument;
arguments->scalarOutput[0] = me->decisionManager->RootCacheCount();
arguments->scalarOutput[1] = me->decisionManager->NonRootCacheCount();
arguments->scalarOutput[0] = me->decisionManager->CacheCount();
return kIOReturnSuccess;
}
@@ -190,8 +195,27 @@ IOReturn SantaDriverClient::check_cache(
SantaDriverClient *me = OSDynamicCast(SantaDriverClient, target);
if (!me) return kIOReturnBadArgument;
const uint64_t input = static_cast<const uint64_t>(arguments->scalarInput[0]);
arguments->scalarOutput[0] = me->decisionManager->GetFromCache(input);
if (arguments->structureInputSize != sizeof(santa_vnode_id_t)) return kIOReturnInvalid;
santa_vnode_id_t *vnode_id = (santa_vnode_id_t *)arguments->structureInput;
if (vnode_id->fsid == 0 || vnode_id->fileid == 0) return kIOReturnInvalid;
arguments->scalarOutput[0] = me->decisionManager->GetFromCache(*vnode_id);
return kIOReturnSuccess;
}
IOReturn SantaDriverClient::cache_bucket_count(
OSObject *target, void *reference, IOExternalMethodArguments *arguments) {
SantaDriverClient *me = OSDynamicCast(SantaDriverClient, target);
if (!me) return kIOReturnBadArgument;
santa_bucket_count_t *counts = reinterpret_cast<santa_bucket_count_t *>(
arguments->structureOutput);
const santa_bucket_count_t *input = reinterpret_cast<const santa_bucket_count_t *>(
arguments->structureInput);
uint16_t s = sizeof(counts->per_bucket) / sizeof(uint16_t);
counts->start = input->start;
me->decisionManager->CacheBucketCount(counts->per_bucket, &s, &(counts->start));
return kIOReturnSuccess;
}
@@ -209,12 +233,14 @@ IOReturn SantaDriverClient::externalMethod(
static IOExternalMethodDispatch sMethods[kSantaUserClientNMethods] = {
// Function ptr, input scalar count, input struct size, output scalar count, output struct size
{ &SantaDriverClient::open, 0, 0, 0, 0 },
{ &SantaDriverClient::allow_binary, 1, 0, 0, 0 },
{ &SantaDriverClient::deny_binary, 1, 0, 0, 0 },
{ &SantaDriverClient::acknowledge_binary, 1, 0, 0, 0 },
{ &SantaDriverClient::clear_cache, 1, 0, 0, 0 },
{ &SantaDriverClient::cache_count, 0, 0, 2, 0 },
{ &SantaDriverClient::check_cache, 1, 0, 1, 0 }
{ &SantaDriverClient::allow_binary, 0, sizeof(santa_vnode_id_t), 0, 0 },
{ &SantaDriverClient::deny_binary, 0, sizeof(santa_vnode_id_t), 0, 0 },
{ &SantaDriverClient::acknowledge_binary, 0, sizeof(santa_vnode_id_t), 0, 0 },
{ &SantaDriverClient::clear_cache, 0, 0, 0, 0 },
{ &SantaDriverClient::cache_count, 0, 0, 1, 0 },
{ &SantaDriverClient::check_cache, 0, sizeof(santa_vnode_id_t), 1, 0 },
{ &SantaDriverClient::cache_bucket_count, 0, sizeof(santa_bucket_count_t),
0, sizeof(santa_bucket_count_t) },
};
if (selector > static_cast<UInt32>(kSantaUserClientNMethods)) {

View File

@@ -47,11 +47,14 @@ class com_google_SantaDriverClient : public IOUserClient {
/// Called when this class is stopping
void stop(IOService *provider) override;
/// Called when a client disconnects
/// Called when a client manually disconnects (via IOServiceClose)
IOReturn clientClose() override;
/// Called when the driver is shutting down
bool terminate(IOOptionBits options) override;
/// Called when a client dies
IOReturn clientDied() override;
/// Called during termination
bool didTerminate(IOService* provider, IOOptionBits options, bool* defer) override;
/// Called in clients with IOConnectSetNotificationPort
IOReturn registerNotificationPort(
@@ -105,6 +108,11 @@ class com_google_SantaDriverClient : public IOUserClient {
static IOReturn check_cache(
OSObject *target, void *reference, IOExternalMethodArguments *arguments);
/// The daemon calls this to find out how many items are in each cache bucket.
/// Input and output are both an instance of santa_bucket_count_t.
static IOReturn cache_bucket_count(
OSObject *target, void *reference, IOExternalMethodArguments *arguments);
private:
com_google_SantaDriver *myProvider;
SantaDecisionManager *decisionManager;

View File

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

View File

@@ -18,15 +18,15 @@
#import <pthread/pthread.h>
#import <MOLCodesignChecker/MOLCodesignChecker.h>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTFileInfo.h"
#import "SNTStoredEvent.h"
#import "SNTXPCConnection.h"
#import "SNTXPCNotifierInterface.h"
@interface SNTBundleService ()
@property SNTXPCConnection *notifierConnection;
@property SNTXPCConnection *listener;
@property MOLXPCConnection *notifierConnection;
@property MOLXPCConnection *listener;
@property(nonatomic) dispatch_queue_t queue;
@end
@@ -48,7 +48,7 @@
// Create listener for return connection from SantaGUI.
NSXPCListener *listener = [NSXPCListener anonymousListener];
self.listener = [[SNTXPCConnection alloc] initServerWithListener:listener];
self.listener = [[MOLXPCConnection alloc] initServerWithListener:listener];
self.listener.exportedInterface = [SNTXPCBundleServiceInterface bundleServiceInterface];
self.listener.exportedObject = self;
self.listener.acceptedHandler = ^{
@@ -80,7 +80,7 @@
// Connect to the SantaGUI
- (void)setBundleNotificationListener:(NSXPCListenerEndpoint *)listener {
dispatch_async(dispatch_get_main_queue(), ^{
SNTXPCConnection *c = [[SNTXPCConnection alloc] initClientWithListener:listener];
MOLXPCConnection *c = [[MOLXPCConnection alloc] initClientWithListener:listener];
c.remoteInterface = [SNTXPCNotifierInterface bundleNotifierInterface];
[c resume];
self.notifierConnection = c;

View File

@@ -12,15 +12,16 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTBundleService.h"
#import "SNTXPCBundleServiceInterface.h"
#import "SNTXPCConnection.h"
int main(int argc, const char *argv[]) {
SNTXPCConnection *c =
[[SNTXPCConnection alloc] initServerWithListener:[NSXPCListener serviceListener]];
MOLXPCConnection *c =
[[MOLXPCConnection alloc] initServerWithListener:[NSXPCListener serviceListener]];
c.exportedInterface = [SNTXPCBundleServiceInterface bundleServiceInterface];
c.exportedObject = [[SNTBundleService alloc] init];
[c resume];

View File

@@ -15,20 +15,21 @@
#import "SNTCommand.h"
#import "SNTCommandController.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTFileInfo.h"
#import "SNTLogging.h"
#import "SNTStoredEvent.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
#ifdef DEBUG
@interface SNTCommandBundleInfo : SNTCommand<SNTCommandProtocol>
@end
@implementation SNTCommandBundleInfo
#ifdef DEBUG
REGISTER_COMMAND_NAME(@"bundleinfo")
#endif
+ (BOOL)requiresRoot {
return NO;
@@ -77,3 +78,5 @@ REGISTER_COMMAND_NAME(@"bundleinfo")
}
@end
#endif

View File

@@ -0,0 +1,81 @@
/// Copyright 2018 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
#ifdef DEBUG
#import <Foundation/Foundation.h>
#import "SNTCommand.h"
#import "SNTCommandController.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTLogging.h"
#import "SNTXPCControlInterface.h"
@interface SNTCommandCacheHistogram : SNTCommand<SNTCommandProtocol>
@end
@implementation SNTCommandCacheHistogram
REGISTER_COMMAND_NAME(@"cachehistogram")
+ (BOOL)requiresRoot {
return YES;
}
+ (BOOL)requiresDaemonConn {
return YES;
}
+ (NSString *)shortHelpText {
return @"Print a cache distribution histogram.";
}
+ (NSString *)longHelpText {
return (@"Prints a histogram of each bucket of the in-kernel cache\n"
@" Use -g to get 'graphical' output\n"
@"Only available in DEBUG builds.");
}
- (void)runWithArguments:(NSArray *)arguments {
[[self.daemonConn remoteObjectProxy] cacheBucketCount:^(NSArray *counts) {
NSMutableDictionary<NSNumber *, NSNumber *> *d = [NSMutableDictionary dictionary];
[counts enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
d[obj] = @([d[obj] intValue] + 1);
}];
printf("There are %llu empty buckets\n", [d[@0] unsignedLongLongValue]);
for (NSNumber *key in [d.allKeys sortedArrayUsingSelector:@selector(compare:)]) {
if ([key isEqual:@0]) continue;
uint64_t k = [key unsignedLongLongValue];
uint64_t v = [d[key] unsignedLongLongValue];
if ([[[NSProcessInfo processInfo] arguments] containsObject:@"-g"]) {
printf("%4llu: ", k);
for (uint64_t y = 0; y < v; ++y) {
printf("#");
}
printf("\n");
} else {
printf("%4llu: %llu\n", k, v);
}
}
exit(0);
}];
}
@end
#endif

View File

@@ -12,25 +12,26 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import "SNTCommand.h"
#import "SNTCommandController.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTLogging.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
#include <sys/stat.h>
#ifdef DEBUG
@interface SNTCommandCheckCache : SNTCommand<SNTCommandProtocol>
@end
@implementation SNTCommandCheckCache
#ifdef DEBUG
REGISTER_COMMAND_NAME(@"checkcache")
#endif
+ (BOOL)requiresRoot {
return NO;
@@ -50,7 +51,7 @@ REGISTER_COMMAND_NAME(@"checkcache")
}
- (void)runWithArguments:(NSArray *)arguments {
uint64_t vnodeID = [self vnodeIDForFile:arguments.firstObject];
santa_vnode_id_t vnodeID = [self vnodeIDForFile:arguments.firstObject];
[[self.daemonConn remoteObjectProxy] checkCacheForVnodeID:vnodeID
withReply:^(santa_action_t action) {
if (action == ACTION_RESPOND_ALLOW) {
@@ -66,10 +67,13 @@ REGISTER_COMMAND_NAME(@"checkcache")
}];
}
- (uint64_t)vnodeIDForFile:(NSString *)path {
- (santa_vnode_id_t)vnodeIDForFile:(NSString *)path {
struct stat fstat = {};
stat(path.fileSystemRepresentation, &fstat);
return (((uint64_t)fstat.st_dev << 32) | fstat.st_ino);
santa_vnode_id_t ret = {.fsid = fstat.st_dev, .fileid = fstat.st_ino};
return ret;
}
@end
#endif

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import "SNTCommand.h"
#import "SNTCommandController.h"
@@ -20,12 +20,12 @@
#import <objc/runtime.h>
#import <MOLCertificate/MOLCertificate.h>
#import <MOLCodesignChecker/MOLCodesignChecker.h>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCachedDecision.h"
#import "SNTFileInfo.h"
#import "SNTLogging.h"
#import "SNTRule.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
// file info keys
@@ -192,7 +192,7 @@ REGISTER_COMMAND_NAME(@"fileinfo")
kValidUntil ];
}
- (instancetype)initWithDaemonConnection:(SNTXPCConnection *)daemonConn {
- (instancetype)initWithDaemonConnection:(MOLXPCConnection *)daemonConn {
self = [super initWithDaemonConnection:daemonConn];
if (self) {
_dateFormatter = [[NSDateFormatter alloc] init];

View File

@@ -12,13 +12,16 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#ifdef DEBUG
#import <Foundation/Foundation.h>
#import "SNTCommand.h"
#import "SNTCommandController.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTLogging.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
@interface SNTCommandFlushCache : SNTCommand<SNTCommandProtocol>
@@ -26,9 +29,7 @@
@implementation SNTCommandFlushCache
#ifdef DEBUG
REGISTER_COMMAND_NAME(@"flushcache")
#endif
+ (BOOL)requiresRoot {
return YES;
@@ -60,3 +61,5 @@ REGISTER_COMMAND_NAME(@"flushcache")
}
@end
#endif

View File

@@ -12,20 +12,20 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import "SNTCommand.h"
#import "SNTCommandController.h"
#import <MOLCertificate/MOLCertificate.h>
#import <MOLCodesignChecker/MOLCodesignChecker.h>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTConfigurator.h"
#import "SNTDropRootPrivs.h"
#import "SNTFileInfo.h"
#include "SNTLogging.h"
#import "SNTRule.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
@interface SNTCommandRule : SNTCommand<SNTCommandProtocol>
@@ -164,7 +164,7 @@ REGISTER_COMMAND_NAME(@"rule")
}];
}
- (void)printStateOfRule:(SNTRule *)rule daemonConnection:(SNTXPCConnection *)daemonConn {
- (void)printStateOfRule:(SNTRule *)rule daemonConnection:(MOLXPCConnection *)daemonConn {
NSString *fileSHA256 = (rule.type == SNTRuleTypeBinary) ? rule.shasum : nil;
NSString *certificateSHA256 = (rule.type == SNTRuleTypeCertificate) ? rule.shasum : nil;
dispatch_group_t group = dispatch_group_create();

View File

@@ -12,13 +12,14 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import "SNTCommand.h"
#import "SNTCommandController.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTConfigurator.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
@interface SNTCommandStatus : SNTCommand<SNTCommandProtocol>
@@ -49,10 +50,16 @@ REGISTER_COMMAND_NAME(@"status")
dispatch_group_t group = dispatch_group_create();
// Daemon status
__block BOOL driverConnected;
__block NSString *clientMode;
__block uint64_t cpuEvents, ramEvents;
__block double cpuPeak, ramPeak;
dispatch_group_enter(group);
[[self.daemonConn remoteObjectProxy] driverConnectionEstablished:^(BOOL connected) {
driverConnected = connected;
dispatch_group_leave(group);
}];
dispatch_group_enter(group);
[[self.daemonConn remoteObjectProxy] clientMode:^(SNTClientMode cm) {
switch (cm) {
case SNTClientModeMonitor:
@@ -80,11 +87,10 @@ REGISTER_COMMAND_NAME(@"status")
BOOL fileLogging = ([[SNTConfigurator configurator] fileChangesRegex] != nil);
// Kext status
__block uint64_t rootCacheCount = -1, nonRootCacheCount = -1;
__block uint64_t cacheCount = -1;
dispatch_group_enter(group);
[[self.daemonConn remoteObjectProxy] cacheCounts:^(uint64_t rootCache, uint64_t nonRootCache) {
rootCacheCount = rootCache;
nonRootCacheCount = nonRootCache;
[[self.daemonConn remoteObjectProxy] cacheCounts:^(uint64_t count) {
cacheCount = count;
dispatch_group_leave(group);
}];
@@ -159,6 +165,7 @@ REGISTER_COMMAND_NAME(@"status")
if ([arguments containsObject:@"--json"]) {
NSDictionary *stats = @{
@"daemon" : @{
@"driver_connected" : @(driverConnected),
@"mode" : clientMode ?: @"null",
@"file_logging" : @(fileLogging),
@"watchdog_cpu_events" : @(cpuEvents),
@@ -167,8 +174,7 @@ REGISTER_COMMAND_NAME(@"status")
@"watchdog_ram_peak" : @(ramPeak),
},
@"kernel" : @{
@"root_cache_count" : @(rootCacheCount),
@"non_root_cache_count": @(nonRootCacheCount),
@"cache_count" : @(cacheCount),
},
@"database" : @{
@"binary_rules" : @(binaryRuleCount),
@@ -191,13 +197,13 @@ REGISTER_COMMAND_NAME(@"status")
printf("%s\n", [statsStr UTF8String]);
} else {
printf(">>> Daemon Info\n");
printf(" %-25s | %s\n", "Driver Connected", driverConnected ? "Yes" : "No");
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(" %-25s | %lld\n", "Root cache count", rootCacheCount);
printf(" %-25s | %lld\n", "Non-root cache count", nonRootCacheCount);
printf(" %-25s | %lld\n", "Cache count", cacheCount);
printf(">>> Database Info\n");
printf(" %-25s | %lld\n", "Binary Rules", binaryRuleCount);
printf(" %-25s | %lld\n", "Certificate Rules", certRuleCount);

View File

@@ -12,16 +12,17 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
@import IOKit.kext;
#import <Foundation/Foundation.h>
#import <IOKit/kext/KextManager.h>
#import "SNTCommand.h"
#import "SNTCommandController.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCommonEnums.h"
#import "SNTFileInfo.h"
#import "SNTKernelCommon.h"
#import "SNTXPCConnection.h"
@interface SNTCommandVersion : SNTCommand<SNTCommandProtocol>
@end

View File

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

View File

@@ -12,20 +12,21 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import "SNTCommand.h"
#import "SNTCommandController.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCommandSyncManager.h"
#import "SNTConfigurator.h"
#import "SNTDropRootPrivs.h"
#import "SNTLogging.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
@interface SNTCommandSync : SNTCommand<SNTCommandProtocol>
@property SNTXPCConnection *listener;
@property MOLXPCConnection *listener;
@property SNTCommandSyncManager *syncManager;
@end
@@ -48,7 +49,7 @@ REGISTER_COMMAND_NAME(@"sync")
}
+ (NSString *)longHelpText {
return (@"If Santa is configured to synchronize with a a server, "
return (@"If Santa is configured to synchronize with a server, "
@"this is the command used for syncing.\n\n"
@"Options:\n"
@" --clean: Perform a clean sync, erasing all existing rules and requesting a"
@@ -84,12 +85,12 @@ REGISTER_COMMAND_NAME(@"sync")
#pragma mark daemon methods
- (void)syncdWithDaemonConnection:(SNTXPCConnection *)daemonConn {
- (void)syncdWithDaemonConnection:(MOLXPCConnection *)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 = [[MOLXPCConnection alloc] initServerWithListener:listener];
self.listener.exportedInterface = [SNTXPCSyncdInterface syncdInterface];
self.listener.exportedObject = self.syncManager;
self.listener.acceptedHandler = ^{
@@ -108,6 +109,8 @@ REGISTER_COMMAND_NAME(@"sync")
// Now wait for the connection to come in.
if (dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) {
self.listener.invalidationHandler = nil;
[self.listener invalidate];
[self performSelectorInBackground:@selector(syncdWithDaemonConnection:) withObject:daemonConn];
}

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
extern NSString *const kXSRFToken;

View File

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

View File

@@ -16,14 +16,14 @@
#include "SNTLogging.h"
#import "MOLCertificate.h"
#import "MOLCodesignChecker.h"
#import <MOLCertificate/MOLCertificate.h>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "NSData+Zlib.h"
#import "SNTCommandSyncConstants.h"
#import "SNTCommandSyncState.h"
#import "SNTFileInfo.h"
#import "SNTStoredEvent.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
@implementation SNTCommandSyncEventUpload
@@ -76,6 +76,8 @@
}
- (NSDictionary *)dictionaryForEvent:(SNTStoredEvent *)event {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-literal-conversion"
#define ADDKEY(dict, key, value) if (value) dict[key] = value
NSMutableDictionary *newEvent = [NSMutableDictionary dictionary];
@@ -144,6 +146,7 @@
return newEvent;
#undef ADDKEY
#pragma clang diagnostic pop
}
@end

View File

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

View File

@@ -12,11 +12,11 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import "SNTXPCSyncdInterface.h"
@class SNTXPCConnection;
@class MOLXPCConnection;
///
/// Handles push notifications and periodic syncing with a sync server.
@@ -37,7 +37,7 @@
/// @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
- (instancetype)initWithDaemonConnection:(MOLXPCConnection *)daemonConn
isDaemon:(BOOL)daemon NS_DESIGNATED_INITIALIZER;
///

View File

@@ -14,10 +14,11 @@
#import "SNTCommandSyncManager.h"
@import SystemConfiguration;
#import <SystemConfiguration/SystemConfiguration.h>
#import <MOLAuthenticatingURLSession.h>
#import <MOLAuthenticatingURLSession/MOLAuthenticatingURLSession.h>
#import <MOLFCMClient/MOLFCMClient.h>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTConfigurator.h"
#import "SNTCommandSyncConstants.h"
@@ -31,7 +32,6 @@
#import "SNTLogging.h"
#import "SNTStoredEvent.h"
#import "SNTStrengthify.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
#import "SNTXPCSyncdInterface.h"
@@ -63,7 +63,7 @@ static NSString *const kFCMTargetHostIDKey = @"target_host_id";
@property MOLFCMClient *FCMClient;
@property(nonatomic) SNTXPCConnection *daemonConn;
@property(nonatomic) MOLXPCConnection *daemonConn;
@property BOOL targetedRuleSync;
@@ -89,7 +89,7 @@ static void reachabilityHandler(
#pragma mark init
- (instancetype)initWithDaemonConnection:(SNTXPCConnection *)daemonConn isDaemon:(BOOL)daemon {
- (instancetype)initWithDaemonConnection:(MOLXPCConnection *)daemonConn isDaemon:(BOOL)daemon {
self = [super init];
if (self) {
_daemonConn = daemonConn;
@@ -420,7 +420,7 @@ static void reachabilityHandler(
#pragma mark internal helpers
- (dispatch_source_t)createSyncTimerWithBlock:(void (^)())block {
- (dispatch_source_t)createSyncTimerWithBlock:(void (^)(void))block {
dispatch_source_t timerQueue = dispatch_source_create(
DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0));

View File

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

View File

@@ -16,9 +16,10 @@
#include "SNTLogging.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCommandSyncConstants.h"
#import "SNTCommandSyncState.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
@implementation SNTCommandSyncPostflight
@@ -32,7 +33,7 @@
[self performRequest:[self requestWithDictionary:nil]];
dispatch_group_t group = dispatch_group_create();
void (^replyBlock)() = ^{
void (^replyBlock)(void) = ^{
dispatch_group_leave(group);
};

View File

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

View File

@@ -17,11 +17,12 @@
#include "SNTKernelCommon.h"
#include "SNTLogging.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCommandSyncConstants.h"
#import "SNTCommandSyncState.h"
#import "SNTConfigurator.h"
#import "SNTSystemInfo.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
@implementation SNTCommandSyncPreflight

View File

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

View File

@@ -14,10 +14,11 @@
#import "SNTCommandSyncRuleDownload.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCommandSyncConstants.h"
#import "SNTCommandSyncState.h"
#import "SNTRule.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
#include "SNTLogging.h"

View File

@@ -12,16 +12,16 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
@class SNTCommandSyncState;
@class SNTXPCConnection;
@class MOLXPCConnection;
@interface SNTCommandSyncStage : NSObject
@property(readonly, nonnull) NSURLSession *urlSession;
@property(readonly, nonnull) SNTCommandSyncState *syncState;
@property(readonly, nonnull) SNTXPCConnection *daemonConn;
@property(readonly, nonnull) MOLXPCConnection *daemonConn;
/**
Initialize this stage. Designated initializer.

View File

@@ -14,18 +14,19 @@
#import "SNTCommandSyncStage.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "NSData+Zlib.h"
#import "SNTCommandSyncConstants.h"
#import "SNTCommandSyncState.h"
#import "SNTLogging.h"
#import "SNTXPCControlInterface.h"
#import "SNTXPCConnection.h"
@interface SNTCommandSyncStage ()
@property(readwrite) NSURLSession *urlSession;
@property(readwrite) SNTCommandSyncState *syncState;
@property(readwrite) SNTXPCConnection *daemonConn;
@property(readwrite) MOLXPCConnection *daemonConn;
@property BOOL xsrfFetched;
@end

View File

@@ -12,12 +12,12 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import "SNTCommonEnums.h"
@class SNTCommandSyncManager;
@class SNTXPCConnection;
@class MOLXPCConnection;
/// An instance of this class is passed to each stage of the sync process for storing data
/// that might be needed in later stages.
@@ -27,7 +27,7 @@
@property NSURLSession *session;
/// Connection to the daemon control interface.
@property SNTXPCConnection *daemonConn;
@property MOLXPCConnection *daemonConn;
/// The base API URL.
@property NSURL *syncBaseURL;

View File

@@ -7,7 +7,7 @@
<key>NSHumanReadableCopyright</key>
<string>Google, Inc.</string>
<key>CFBundleIdentifier</key>
<string>com.google.${PRODUCT_NAME:rfc1034identifier}</string>
<string>com.google.santactl</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleShortVersionString</key>

View File

@@ -12,9 +12,9 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
@class SNTXPCConnection;
@class MOLXPCConnection;
@protocol SNTCommandProtocol
@@ -50,16 +50,16 @@
///
/// @note This method (or one of the methods it calls) is responsible for calling exit().
///
+ (void)runWithArguments:(NSArray *)arguments daemonConnection:(SNTXPCConnection *)daemonConn;
+ (void)runWithArguments:(NSArray *)arguments daemonConnection:(MOLXPCConnection *)daemonConn;
@end
@interface SNTCommand : NSObject<SNTCommandRunProtocol>
@property(nonatomic,readonly) SNTXPCConnection *daemonConn;
@property(nonatomic,readonly) MOLXPCConnection *daemonConn;
/// Designated initializer
- (instancetype)initWithDaemonConnection:(SNTXPCConnection *)daemonConn;
- (instancetype)initWithDaemonConnection:(MOLXPCConnection *)daemonConn;
- (void)runWithArguments:(NSArray *)arguments;

View File

@@ -16,12 +16,12 @@
@implementation SNTCommand
+ (void)runWithArguments:(NSArray *)arguments daemonConnection:(SNTXPCConnection *)daemonConn {
+ (void)runWithArguments:(NSArray *)arguments daemonConnection:(MOLXPCConnection *)daemonConn {
id cmd = [[self alloc] initWithDaemonConnection:daemonConn];
[cmd runWithArguments:arguments];
}
- (instancetype)initWithDaemonConnection:(SNTXPCConnection *)daemonConn {
- (instancetype)initWithDaemonConnection:(MOLXPCConnection *)daemonConn {
self = [super init];
if (self) {
_daemonConn = daemonConn;

View File

@@ -12,11 +12,11 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import "SNTCommand.h"
@class SNTXPCConnection;
@class MOLXPCConnection;
///
/// Responsible for maintaining the list of available commands by name, printing their help text

View File

@@ -14,7 +14,8 @@
#import "SNTCommandController.h"
#import "SNTXPCConnection.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTXPCControlInterface.h"
@implementation SNTCommandController
@@ -69,8 +70,8 @@ static NSMutableDictionary *registeredCommands;
return nil;
}
+ (SNTXPCConnection *)connectToDaemonRequired:(BOOL)required {
SNTXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
+ (MOLXPCConnection *)connectToDaemonRequired:(BOOL)required {
MOLXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
if (required) {
daemonConn.invalidationHandler = ^{
@@ -94,7 +95,7 @@ static NSMutableDictionary *registeredCommands;
exit(2);
}
SNTXPCConnection *daemonConn = [self connectToDaemonRequired:[command requiresDaemonConn]];
MOLXPCConnection *daemonConn = [self connectToDaemonRequired:[command requiresDaemonConn]];
[command runWithArguments:arguments daemonConnection:daemonConn];
// The command is responsible for quitting.

View File

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

View File

@@ -12,11 +12,11 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
// 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>
#import <fmdb/FMDB.h>
@interface SNTDatabaseTable : NSObject

View File

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

View File

@@ -54,7 +54,7 @@
}
NSData *eventData;
NSNumber *idx = [rs objectForColumnName:@"idx"];
NSNumber *idx = [rs objectForColumn:@"idx"];
@try {
eventData = [NSKeyedArchiver archivedDataWithRootObject:se];
[db executeUpdate:@"UPDATE events SET eventdata=? WHERE idx=?", eventData, idx];
@@ -141,7 +141,7 @@
if (obj) {
[pendingEvents addObject:obj];
} else {
[db executeUpdate:@"DELETE FROM events WHERE idx=?", [rs objectForColumnName:@"idx"]];
[db executeUpdate:@"DELETE FROM events WHERE idx=?", [rs objectForColumn:@"idx"]];
}
}

View File

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

View File

@@ -133,7 +133,8 @@
#pragma mark Adding
- (BOOL)addRules:(NSArray *)rules cleanSlate:(BOOL)cleanSlate error:(NSError **)error {
- (BOOL)addRules:(NSArray *)rules cleanSlate:(BOOL)cleanSlate
error:(NSError * __autoreleasing *)error {
if (!rules || rules.count < 1) {
[self fillError:error code:SNTRuleTableErrorEmptyRuleArray message:nil];
return NO;

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import "SNTKernelCommon.h"
@@ -40,7 +40,6 @@
- (NSString *)diskImageForDevice:(NSString *)devPath;
- (NSString *)nameForUID:(uid_t)uid;
- (NSString *)nameForGID:(gid_t)gid;
- (NSString *)sanitizeCString:(const char *)str ofLength:(NSUInteger)length;
- (NSString *)sanitizeString:(NSString *)inStr;
- (NSString *)serialForDevice:(NSString *)devPath;
- (NSString *)originalPathForTranslocation:(santa_message_t)message;
@@ -51,4 +50,5 @@
// A UTC Date formatter.
@property(readonly, nonatomic) NSDateFormatter *dateFormatter;
@property(readonly, nonatomic) NSString *machineID;
@end

View File

@@ -20,6 +20,7 @@
#include <sys/sysctl.h>
#import "SNTCachedDecision.h"
#import "SNTConfigurator.h"
@interface SNTEventLog ()
@property NSMutableDictionary<NSNumber *, SNTCachedDecision *> *detailStore;
@@ -43,6 +44,9 @@
_dateFormatter = [[NSDateFormatter alloc] init];
_dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
_dateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
// Grab the system UUID on init
_machineID = [[SNTConfigurator configurator] machineID];
}
return self;
}
@@ -77,14 +81,14 @@
- (void)cacheDecision:(SNTCachedDecision *)cd {
dispatch_sync(self.detailStoreQueue, ^{
self.detailStore[@(cd.vnodeId)] = cd;
self.detailStore[@(cd.vnodeId.fileid)] = cd;
});
}
- (SNTCachedDecision *)cachedDecisionForMessage:(santa_message_t)message {
__block SNTCachedDecision *cd;
dispatch_sync(self.detailStoreQueue, ^{
cd = self.detailStore[@(message.vnode_id)];
cd = self.detailStore[@(message.vnode_id.fileid)];
});
return cd;
}
@@ -114,6 +118,8 @@
char *buf = NULL;
BOOL shouldFree = NO;
if (length < 1) return @"";
// Loop through the string one character at a time, looking for the characters
// we want to remove.
for (const char *p = str; (c = *p) != 0; ++p) {
@@ -366,9 +372,12 @@
// SecTranslocateCreateOriginalPathForURL requires that our uid be the same as the user who
// launched the executable. So we temporarily drop from root down to this uid, then reset.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
pthread_setugid_np(message.uid, message.gid);
NSURL *origURL = CFBridgingRelease(CreateOriginalPathForURL(cfExecURL, NULL));
pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE);
#pragma clang diagnostic pop
return [origURL path]; // this will be nil if there was an error
}

View File

@@ -69,6 +69,10 @@
message.uid, [self nameForUID:message.uid],
message.gid, [self nameForGID:message.gid]];
if ([[SNTConfigurator configurator] enableMachineIDDecoration]) {
[outStr appendFormat:@"|machineid=%@", self.machineID];
}
[self writeLog:outStr];
}
@@ -165,6 +169,10 @@
[self addArgsForPid:message.pid toString:outLog];
}
if ([[SNTConfigurator configurator] enableMachineIDDecoration]) {
[outLog appendFormat:@"|machineid=%@", self.machineID];
}
[self writeLog:outLog];
}

View File

@@ -7,7 +7,7 @@
<key>NSHumanReadableCopyright</key>
<string>Google, Inc.</string>
<key>CFBundleIdentifier</key>
<string>com.google.${PRODUCT_NAME:rfc1034identifier}</string>
<string>com.google.santad</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleVersion</key>

View File

@@ -12,7 +12,7 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
///
/// The main controller class for santad

View File

@@ -14,7 +14,9 @@
#import "SNTApplication.h"
@import DiskArbitration;
#import <DiskArbitration/DiskArbitration.h>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCommonEnums.h"
#import "SNTConfigurator.h"
@@ -30,7 +32,6 @@
#import "SNTRuleTable.h"
#import "SNTSyncdQueue.h"
#import "SNTSyslogEventLog.h"
#import "SNTXPCConnection.h"
#import "SNTXPCControlInterface.h"
#import "SNTXPCNotifierInterface.h"
@@ -39,7 +40,7 @@
@property SNTDriverManager *driverManager;
@property SNTEventLog *eventLog;
@property SNTExecutionController *execController;
@property SNTXPCConnection *controlConnection;
@property MOLXPCConnection *controlConnection;
@property SNTNotificationQueue *notQueue;
@property pid_t syncdPID;
@end
@@ -115,7 +116,7 @@
eventLog:_eventLog];
_controlConnection =
[[SNTXPCConnection alloc] initServerWithName:[SNTXPCControlInterface serviceId]];
[[MOLXPCConnection alloc] initServerWithName:[SNTXPCControlInterface serviceId]];
_controlConnection.exportedInterface = [SNTXPCControlInterface controlInterface];
_controlConnection.exportedObject = dc;
[_controlConnection resume];
@@ -249,7 +250,7 @@ void diskDisappearedCallback(DADiskRef disk, void *context) {
if (![props[@"DAVolumeMountable"] boolValue]) return;
[app.eventLog logDiskDisappeared:props];
[app.driverManager flushCacheNonRootOnly:YES];
[app.driverManager flushCache];
}
- (void)startSyncd {
@@ -302,7 +303,7 @@ void diskDisappearedCallback(DADiskRef disk, void *context) {
if (!new && !old) return;
if (![new.pattern isEqualToString:old.pattern]) {
LOGI(@"Changed [white|black]list regex, flushing cache");
[self.driverManager flushCacheNonRootOnly:NO];
[self.driverManager flushCache];
}
}
}
@@ -310,7 +311,7 @@ void diskDisappearedCallback(DADiskRef disk, void *context) {
- (void)clientModeDidChange:(SNTClientMode)clientMode {
if (clientMode == SNTClientModeLockdown) {
LOGI(@"Changed client mode, flushing cache.");
[self.driverManager flushCacheNonRootOnly:NO];
[self.driverManager flushCache];
}
[[self.notQueue.notifierConnection remoteObjectProxy] postClientModeNotification:clientMode];
}

View File

@@ -12,16 +12,17 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@import Foundation;
#import <Foundation/Foundation.h>
#import "SNTCommonEnums.h"
#import "SNTKernelCommon.h"
///
/// Store information about executions from decision making for later logging.
///
@interface SNTCachedDecision : NSObject
@property uint64_t vnodeId;
@property santa_vnode_id_t vnodeId;
@property SNTEventState decision;
@property NSString *decisionExtra;
@property NSString *sha256;

View File

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

Some files were not shown because too many files have changed in this diff Show More