Compare commits

...

762 Commits

Author SHA1 Message Date
Tom Burgin
2d98173c51 fix cache invalidation on macOS Mojave (#298) 2018-09-21 15:22:34 -04:00
Tom Burgin
5e3f13be70 intentional fall-through (#297)
* intentional fall-through

* russell's idea
2018-09-20 18:40:23 -04:00
Tom Burgin
90b894b88a santad: add critical system binaries (#296)
* santad: add critical system binaries

* review updates

* use a getter
2018-09-20 17:17:12 -04:00
nguyen-phillip
6dc7387881 Add transitive whitelisting to Santa (#224)
Add transitive whitelisting.

Binaries may be identified with WHITELIST_COMPILER rules.  Any executable they output will then be marked locally with a transitive whitelist rule and allowed to run if the TransitiveWhitelistingEnabled config key is true.
2018-07-20 11:47:04 -04:00
Tom Burgin
b14b017d72 santa-driver: add IOMatchCategory (#292) 2018-07-18 11:33:09 -04:00
Tom Burgin
d0ede18bf4 MOLCertificate --> 1.9 (#290) 2018-07-06 12:56:15 -04:00
Alessandro Gario
6d223aea03 Various fixes (documentation, and an additional check on the JSON received from the syncserver) (#288)
* santa-driver: Fix documentation warnings
* SantaCache: Fix documentation warnings
* santactl: Always make sure that the syncserver JSON is a dictionary
2018-07-06 09:42:22 -04:00
Alessandro Gario
f7986b0a05 Update MOLXPCConnection; add support for unprivileged XPC interfaces (#287)
* Update MOLXPCConnection; add support for unprivileged XPC interfaces

* Code review changes
2018-07-05 17:20:49 -04:00
Alessandro Gario
629e70287c Add CMake support, implement fuzzers (#284)
The new CMake project allows the user to select which SDK version
to use. The Xcode path is also configurable to support non-standard
installation paths and/or systems with multiple versions installed.

Code signing can now be configured via command line, using the
CODESIGN_IDENTITY environment variable.

New fuzzing targets (libFuzzer)
 - SantaCache
 - santactl
 - santad

New make targets:
 - tests: Runs the tests
 - fuzz: Runs the fuzzer
 - redist: Regenerates the redistributable folder
 - install: Installs Santa
2018-06-29 14:15:16 -04:00
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
Tom Burgin
5ee6531627 santad / santactl: validate all architectures within universal binaries (#249) 2018-04-24 16:11:49 -04:00
Tom Burgin
1cf8ee09e1 sync-state: Mitigate com.apple.ManagedClient flapping (#248)
* sync-state: Mitigate com.apple.ManagedClient flapping

* 10 min
2018-04-09 13:34:33 -04:00
Tom Burgin
4a2cf9d722 santad: event logger (#246)
* kext symbols

* santad: Create FileLog and Syslog options

* review updates

* review updates

* be a good citizen and let go of things you do not need
2018-04-03 13:15:12 -04:00
Tom Burgin
6a6a32c1cf santactl: Update to MOLFCMClient v1.7 (#245) 2018-03-13 13:07:44 -04:00
Tom Burgin
ce03611b52 santabs: Serialize calls to -[SNTBundleService createConnection] (#244) 2018-03-12 17:04:53 -04:00
Tom Burgin
bbe9f83878 Import fixes (#243)
* All: use common import style for cocoapods <PodName/PodName.h>

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

* delete it
2018-03-07 17:35:02 -05:00
Tom Burgin
9f6ccf092a code cleanup (#241) 2018-02-26 10:51:44 -05:00
Tom Burgin
d4ba4b082f codesign check: verify all architectures (#239)
* fileinfo rule: don't use certs that have codesigning errors

* pods: MOLCodesignChecker --> 1.8
2018-02-22 14:41:47 -05:00
Tom Burgin
cce43829eb use MOLFCMClient v1.5 (#238) 2018-02-16 14:35:52 -05:00
johnl
c1bfbac2fe Various small fixes to README.md (#237)
* Various small fixes to README.md

* Apply changes
2018-02-13 11:06:28 -05:00
Tom Burgin
fc87cde668 config: use KVO (#234)
* config: atomically update config

* config: add an explanation for sleep usage

* config: use mobileconfig in the getters

* config: cleanup file watcher

* config: spell

* config: clear or reload sync state on sync base url change

* config: Use KVO and Dependent Keys

* config: remove debug log

* config: review updates

* config: update rule sync getter and setter names

* config: get logical
2018-02-07 13:59:00 -05:00
Tom Burgin
400c413029 config: add option to disable mode change notifications (#235)
* config: add option to disable mode change notifications

* config: don't do extra work

* config: handle none, default and custom

* config: cleaner
2018-02-02 12:01:51 -05:00
Tom Burgin
0e6eb45732 santa-driver: add an acknowledge feature to allow timeouts (#220)
* santa-driver: Add an acknowledge feature to allow timeouts for lost requests

* project: cocoapods 1.3.1 update

* review updates
2018-01-26 11:33:54 -05:00
Tom Burgin
7ca2028c19 santabs: don't try to lookup nil bundle paths (#233) 2018-01-26 11:33:04 -05:00
Tom Burgin
08144b54a7 docs: updated configuration details (#232)
* docs: updated configuration details

* config: add example mobileconfig
2018-01-24 21:07:48 -05:00
Russell Hancox
103137498b santa-driver: Deny execs with names over MAXPATHLEN with appropriate errno (#231) 2018-01-24 14:02:05 -05:00
Tom Burgin
8e57e3709d SNTConfigurator: use mobileconfigs (#222)
* SNTConfigurator: use mobileconfigs

* use proper key groups

* remove state

* review updates

* review updates

* SNTConfigurator: Revert any out-of-band changes to the sync state file.

* SNTConfigurator move the file watcher to santad only
2018-01-08 12:56:24 -05:00
nguyen-phillip
bd6bd66946 santactl: Added -h and --help as synonyms for help (#225) 2017-12-05 14:16:04 -08:00
nguyen-phillip
6973dd0ec2 log the events generated by bundle hashing with action=BUNDLE (#207)
* log the events generated by bundle hashing with action=BUNDLE

* change EventLog to eventLog in SNTDaemonControlController init signature
2017-12-04 10:03:04 -08:00
Tom Burgin
2e8b08cd9e keep style fixes (#221) 2017-11-28 11:48:12 -05:00
Russell Hancox
edc8f43f42 Style fixes 2017-11-15 20:35:53 -05:00
Russell Hancox
133814cd73 santa-driver: Prevent possible infinite loop if decision requests fail to be retrieved
When enqueue'ing on the decision data queue, if the queue is full the new message will overwrite the oldest. In this scenario it's possible for that overwritten request to get stuck in an infinite loop - as far as the driver is concerned there's a request pending that the driver should be picking up and responding to but the daemon has never actually received the request. The only way out of this loop is for the file being executed to be written to. This change adds an expiration to pending requests (of 5s) so that if this scenario were to happen the pending request would be removed, breaking out of the inner decision loop to the outer loop where the request is sent to the daemon.

This change also removes a pointless dequeue in the log queue, it was intended to try and help reduce the queue size to get logs flowing again but it doesn't really help.
2017-11-15 20:35:53 -05:00
Russell Hancox
57213ee31b [santactl] Ensure reachability is released properly 2017-10-26 15:45:28 -04:00
Tom Burgin
b4fa2a394b Update .gitignore (#211)
Track files in the santa-driver dir
2017-10-16 15:20:43 -04:00
Tom Burgin
0c39342d53 santad: SNTPolicyProcessor fix nil scope check (#208)
Fixes `santactl rule --check` returning `Whitelisted (Scope)` incorrectly
2017-10-06 13:07:48 -04:00
Tom Burgin
1c95e8e25c santad: Stop ignoring CSInfoPlistFailed (#204)
It is too broad a check for the few false positive events we have seen.
2017-09-14 12:45:07 -04:00
nguyen-phillip
ff5a92772b sync: start reachability handler to retry to upload blocked event when initial upload fails (#202)
* sync: start reachability handler to retry to upload blocked event when initial upload fails

* fix indentation

* store related bundle events when server connection fails

* revert SNTBundleEventAction to BOOL

* go back to using SNTBundleEventAction in reply; make sure to send reply to avoid leaks

* fix indentation

* fix indentation
2017-09-14 12:44:32 -04:00
nguyen-phillip
bc2a17f70f santactl: added filtering to fileinfo command via --filter flag (#201)
* implemented simple filtering with fileinfo command

* Use regex filters instead of substring matching

* remove unnecessary match variable

* Update SNTCommandFileInfo.m
2017-09-14 11:21:08 -04:00
nguyen-phillip
f2e909e578 Minor refactor to merge similar methods into one: (#200)
* Merged similar methods into one:

* SNTSyncdQueue addBundleEvents: and addEvent: became addEvents:isFromBundle:
* SNTSyncdQueue backoffForBundleHash: and backoffForEvent: became backoffForPrimaryHash:
* SNTCommandSyncManager postBundleEventsToSyncServer: and postEventToSyncServer: became postEventsToSyncServer:isFromBundle:

* fix style issue

* simplify condition
2017-09-08 09:18:13 -04:00
nguyen-phillip
c3385a808c Bundle Notifications (#197)
* stub code for bundle notifications with new rules info

* get bundle rule count info from each rule, rather than initial FCM message

* Replace string literals with constants

* only update pendingNotifications for whitelist rules

* use pre-existing string constants as dictionary keys

* Remove processed entries from the notifications dictionary after we're done with them.

* fix indentation

* replace kRuleBundleHash with kFileBundleHash

* enforce serial access to the whitelistNotifications dictionary

* clarify comment

* fix queue spelling and better comments
2017-09-05 15:35:35 -04:00
Tom Burgin
8d480331ff Add Read the Docs to README (#196)
* Update README.md

* Update README.md
2017-08-18 13:29:43 -04:00
nguyen-phillip
5216f0989c santactl: Recursive fileinfo command (#191)
* temporarily gutted SNTCommandFileInfo. Added SNTCommand base class for all
of the SNTCommand* classes to inherit from.  Changed commands so that they
are consistently instantiated before being run, with a common init method.

* Put most of SNTCommandFileInfo functionality back in

* follow symlinks

* added -r and --recursive flags and updated help text

* moved humanReadableFileType to SNTFileInfo

* added back JSON output

* Fixed bundle info. Grab directory color from ENV variable.

* fixed indentation, moved stuff around

* Added SNTCommandFileInfo * back as parameter to property getters so that rule getter
doesn't have to be a special case any more.

* fixed code review issues

* added SNTCommand.h and SNTCommand.m to project

* added SNTCommand.m to build phases

* removed trailing spaces

* fixed tests for SNTCommandFileInfo and added a few more

* fix end-of-line comment spacing to conform to style guide

* Use NSBundle instead of NSWorkspace to determine if path is a bundle.

* added autorelease pool inside recursive search loop to fix bug where file listing
would abruptly stop after so many files with mach header related keys.

* removed directory headers. don't separate entries with newline when printing single key. format output based on max key length.

* an attempt at speeding things up.  also halfway fixed broken cert-index key.

* speedups via caching MOLCodeSignChecker & not using NSMutableString append*

* fix json ouput with cert-index, single key output, & cache SHA values

* reverted back to NSMutableString for building up output, since it seems slightly better
or at least no worse than using an NSMutableArray

* Don't print empty JSON objects

* fixed non-thread-safe JSON commas

* made the print dispatch group a property so it doesn't have to be passed around

* Fixed certIndex indexing bug & better error checking when parsing --cert-index argument

* prevent unsigned int overflow

* fixed logic tests broken by objc_setAssociatedObject with nil SNTFileInfo argument

* send error output to the serial print queue

* NSBundle bundleWithPath: returns an object even for non-bundle directories, so need to also check that there's a valid bundle identifier.

* Added TODO comment and fixed formatting issues

* added cached codeSignChecker property to SNTFileInfo

* rewrote SNTFileInfo's codesignChecker method to include an error reference parameter & removed @synchronized

* Removed caching of SHA values from SNTFileInfo

* use property getter/setter to access codesignCheckerError

* Change nil NSError ** arguments to NULL

* Don't try to create a new codesignChecker if there was previously an error

* Fix NSDirectoryEnumerator memory usage & don't retain self in rule getter.

The NSStrings grabbed from the directory enumerator needed a chance to be freed.

* fixed colon alignment
2017-08-18 09:56:37 -04:00
Tom Burgin
4238553a2e Docs: Start of Santa Docs (#192)
* Docs: Start of Santa Docs

* Docs: /exec()/execve()/

* Docs: /sync-server/sync server/

* Docs: review updates
2017-08-17 16:01:59 -04:00
nguyen-phillip
79662d0dcf santad/SNTEventLog: log original path of translocated apps (#194)
* log original path of translocated apps

* made handle a local variable & fixed capitalization

* Removed superfluous CFError
2017-08-17 11:09:46 -04:00
Russell Hancox
ff095bc53d KernelTests: Fix cache performance test
It was previously calculating CPU use rather than walltime which isn't really what we want to measure.
2017-08-16 16:13:45 -04:00
Russell Hancox
eefd70b2de santa-driver: Fix race condition by adding CAS op to SantaCache
Change the signature of the set method in SantaCache so that it takes an
optional previous-value parameter (and a bool indicating that this value
has been provided). If previous-value is provided, set becomes a
compare-and-swap. Also provide 2 overloads for a cleaner interface, one
with and without the previous-value parameter.
2017-08-16 16:13:45 -04:00
Russell Hancox
9b3eab67a2 santa-driver: Determine root FSID more safely
Only calculate root FSID during daemon connection. If daemon is running
there must be a root filesystem. Also check return values just in case.

Check vnode_id has been determined in VnodeCallback and SantaDriverClient
methods so that it doesn't need to be checked anywhere else.
2017-08-16 12:07:44 -04:00
Russell Hancox
54def2deb7 santa-driver: Reverse ClearCache() non_root_only default parameter 2017-08-16 12:07:44 -04:00
Russell Hancox
cd12744726 santad/santactl/santa-driver: Make status command return size of both caches 2017-08-16 12:07:44 -04:00
Russell Hancox
616fd9570f santa-driver: Split cache for root/non-root volume
Split the kernel-land cache into 2 separate caches, one for the root
volume and one for secondary volumes. When an unmount happens, clear
the non-root cache to ensure no overlap with filesystem IDs.
2017-08-16 12:07:44 -04:00
Russell Hancox
0544011ee0 [santad] Remove broken check and obsolete TODOs (#190) 2017-08-03 15:14:02 -04:00
nguyen-phillip
51920c7045 santad: modified execution log format to show path & args at end (#189)
Fixed problem where extremely long path/args obscured other log info.
2017-08-02 14:27:39 -04:00
Russell Hancox
6f417a1775 common: Remove EventDetailBundleURL key (#187)
The changes to bundle scanning mean this key isn't really necessary anymore - if a server supports bundles it tells the client during preflight, this in turn causes bundle hashes to be generated and these are used in place of the file hash when generating a detail URL. Keying bundles off the ID and version was never really a good idea anyway.
2017-08-01 12:16:37 -04:00
Russell Hancox
51034a24c6 SNTXPCConnection: Prevent crash if caller releases instance during resume (#183) 2017-07-18 16:50:32 -04:00
Tom Burgin
f631f219b0 santactl/sync: fixed exception when file_name is None / NSNull (#180)
* santactl/sync: fixed exception when file_name is None / NSNull

* review updates
2017-07-06 11:52:49 -04:00
Tom Burgin
aacae020b8 logs: add DAAppearanceTime to the DISKAPPEAR logs (#179)
* logs: add DAAppearanceTime to the DISKAPPEAR logs

* review updates

* discussion updates
2017-07-02 16:27:40 -04:00
Tom Burgin
7c426e0eec santactl/sync: upload file bundle executable relative path for bundle events (#178) 2017-06-28 11:55:21 -04:00
Tom Burgin
363826502f santabs: de-dupe generated events before upload (#177)
* santabs: de-dupe generated events before upload and remove locks

* review updates

* error updates
2017-06-22 17:46:04 -04:00
Russell Hancox
1cfadae068 SantaGUI: Don't show pop-up notifications for empty filenames (#176) 2017-06-12 11:28:32 -07:00
Tom Burgin
d3b3d722b4 santabs: use the ancestor bundle when searching for binaries (#175)
* santabs: use the ancestor bundle when searching for binaries

* review updates

* bundle tests
2017-06-09 17:04:23 -04:00
Tom Burgin
a82428958b santactl/rule: Add the ability to check the status of arbitrary sha256 hashes without on-disk artifacts. (#172) 2017-05-30 13:07:47 -04:00
Tom Burgin
b185632bda santad/SantaGUI: Add needsBundleHash property to SNTStoredEvent && (#170)
santactl/sync:sync server enables/disables client bundle support
2017-05-30 13:04:08 -04:00
Tom Burgin
e7a0c3d25b santactl/sync: Sync Server to set FCM interval and deadline (#168)
* santactl/sync: Sync Server to set FCM interval and deadline

* rename default constants

* review updates
2017-05-22 11:50:37 -04:00
Tom Burgin
ab33de2c15 project/config: Move /var/log/santa.log to /var/db/santa/santa.log (#173) 2017-05-22 11:10:10 -04:00
Tom Burgin
a1031cdc27 protect wakeup() from being called with 0 (#167)
* don't call wakeup on 0

* project: "share" the santabs target

* Project: Update CocoaPods to 1.2.1

* Project: pod deintegrate - pod install
2017-04-14 16:13:45 -04:00
Tom Burgin
e3ab3ca506 Update SNTCommandSyncEventUpload.m (#162) 2017-04-13 16:58:25 -04:00
Matthew Suozzo
b4cd1ccbee santa-driver: Fix a typo 2017-04-13 14:27:05 -04:00
Matthew Suozzo
14573a5714 santa-driver: Refactor cache expiration calculation 2017-04-12 22:35:08 -04:00
Tom Burgin
96150a9668 Bundle Events (#145)
* santabs: Create Santa Bundle Service

* common: SNTXPCConnection add initClientWithServiceName:

* santad: add logic for blocked bundles

* SantaGUI: add ui elements and xpc connections to / from santabs

* santactl/sync: add api features for syncing bundle events

* santactl/bundleinfo: add bundleinfo command for debug builds

* common: prefer bundle hash over file hash for event urls

* common: remove syncBackoff property - this is now handled in santactl sync

* common: add properties to support the bundle event api

* common: find a bundle from a nested binary

* review updates

* sane bundle hash time outs

* post rebase updates

* post review updates
2017-04-07 15:31:56 -04:00
Russell Hancox
c10c1303ed SantaGUI: Add preprocessor flag to import Cocoa for SNTBlockMessage 2017-04-05 14:19:50 -04:00
Tom Burgin
7852e69685 SantaCache fix 0 init (#158) 2017-03-22 09:38:27 -04:00
Russell Hancox
094880af50 Project: Add DevelopmentTeam configuration (#157)
This is a generated xcconfig in the Rakefile which gets included by the project
to set the DEVELOPMENT_TEAM key to keep Xcode 8 happy. The development team is
figured based on the available “Mac Developer” certificate.

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

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

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

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

This reverts commit a2d6338400.

* santactl/sync: use hostname for reachability

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

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

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

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

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

* Don't display rule count in notifications. Get FCM broadcast topic from sync server.
2016-12-06 16:04:34 -05:00
Tom Burgin
dacff76694 run santactl as a sync daemon (#129)
* run santactl as a sync daemon
2016-11-16 14:41:12 -05:00
Russell Hancox
c134169ea1 santad: Drop AUTOINCREMENT on event table (#130) 2016-11-01 11:14:51 -04:00
Russell Hancox
e252945047 santactl/fileinfo: Send resolved path to santad for processing (#128) 2016-10-26 16:04:27 -04:00
Russell Hancox
f8cfcaab20 Package/Conf: Fix typo in uninstall.sh (#126) 2016-10-25 15:05:36 -04:00
Tom Burgin
528237a239 santactl status: check non-boxed vars when building json output (#125) 2016-10-24 12:14:56 -04:00
Russell Hancox
91aefe25c4 santad: Fix printer-proxy workaround (#120) 2016-10-13 15:30:08 -04:00
Russell Hancox
a8c11097d9 Project: Use NSSet instead of NSDictionary for uniqueness in collections (#119) 2016-10-13 15:20:19 -04:00
Russell Hancox
92ba4a3ae9 santactl/sync: Debug log when clean sync requested (#118) 2016-10-13 15:20:12 -04:00
Russell Hancox
7c5d382010 santactl/sync: Fix bundle searching, make concurrent. (#115)
* santactl/sync: Fix bundle searching, make concurrent.
2016-10-13 15:14:35 -04:00
Russell Hancox
f8fbaefd86 Tests: Fix XPC connection tests (#116)
Also disable LTO in debug builds.
2016-10-13 12:43:26 -04:00
Russell Hancox
181b37296a santactl/sync Tests: Use constants (#117) 2016-10-13 12:43:14 -04:00
Tom Burgin
2ab61cfa12 SNTCommandFileInfo: Fixed retain cycle. Added locking for a NSMutableArray when accessed on multiple threads (#114) 2016-10-13 11:38:33 -04:00
Tom Burgin
1b0e9b14ef Global json bool shared between class and instance methods. https://github.com/google/santa/issues/112 (#113) 2016-10-12 14:35:27 -04:00
Russell Hancox
2aacc9266f Revert changes for building with Xcode 8 (#111)
* Partial Revert of "Project: Update project files for Xcode 8 (#105)"

Building with Xcode 8 (and specifically the 10.12 SDK) breaks logging on
10.12 and on top of that some tests don't pass while working perfectly
fine on 10.11. For now, we'll just continue building with 7.3.1.

* README: Add note about building with Xcode 7.3.1
2016-10-10 14:24:14 -04:00
Russell Hancox
d648d477bb santa-driver: Fix deadlocking on Sierra (#107)
1. Don't RemoveFromCache for advisory access by santad itself.
2. wakeup sleeping threads when removing from cache
3. Move the vnode type check earlier in the process for the vnode scope
2016-09-28 16:36:23 -04:00
Russell Hancox
6f91c1a1d3 Project: Update project files for Xcode 8 (#105) 2016-09-28 16:11:22 -04:00
Russell Hancox
aa1aca24b7 Common: Don't crash if ClientMode key is not an integer. (#106)
NSString has longLongValue but not longValue, so switch to that then cast down. Check that the receiver responds to longLongValue before calling it just in case someone tries to set it to an NSData or something.
2016-09-26 11:53:51 -04:00
Tom Burgin
6a0867172f Mocking for MOLCodesignChecker initWithBinaryPath:error: (#104) 2016-09-23 15:40:37 -04:00
Russell Hancox
f025a4b2fb santad: In required rule protection, handle case where there are multiple rules for the required certs (#101) 2016-09-22 16:17:59 -04:00
Russell Hancox
8871f36a92 santa-driver: FetchDecision - use a loop rather than recursing. (#100) 2016-09-22 15:58:53 -04:00
Russell Hancox
f17490edad santad: Handle UTF-8 in process args. (#99)
While appendFormat with %s is slightly faster (~1üs) it doesn't handle UTF-8 properly.
2016-09-22 15:38:00 -04:00
Russell Hancox
b360e782c6 santad: Start ignoring errSecCSInfoPlistFailed (-67030) (#98) 2016-09-22 15:36:35 -04:00
Russell Hancox
8d94324dd6 santad: Update SNTFileWatcher to fix broken dispatch source. (#97)
I'm not certain if this is a Sierra change or just that it was more rare before but changing a cancel handler on a dispatch source no longer seems to have any effect. This meant the file descriptor for the currently-active source was being closed instead of the one for the source that was just cancelled. It wasn't actually necessary to get the file handle from the source, we can just rely on capturing it in the block, which works just as well.
2016-09-22 15:36:26 -04:00
Russell Hancox
2818609412 santactl/sync: Fix bundle event upload (#96) 2016-09-20 12:37:12 -04:00
Russell Hancox
270a2e69d4 Project: Add bundler caching to travis build (#95) 2016-09-19 07:19:15 -04:00
Russell Hancox
d1d9762e29 santa-driver: Don't filter advisory vnode_write notifications (#94) 2016-09-15 10:17:18 -04:00
Russell Hancox
1666e8b127 Move some NSMutableDictionary uses to NSCache, log client connection (#93)
* santa-driver: Log when client connects (we already log disconnect)
* santad: Move a couple of NSMutableDictionary uses over to NSCache, add type info.
2016-09-14 17:09:04 -04:00
Tom Burgin
08dfad208b Move decision making to SNTPolicyProcessor (#91)
Move SNTEventState to a mixed bit field enum
SNTCommandFileInfo now handles all rule states
2016-09-14 12:34:42 -04:00
Russell Hancox
b5921f95f3 santa-driver: Remove the static wrappers in SantaDriverClient (#90)
SantaDriverClient was implemented to have static functions that call instance
methods passing appropriate arguments. While this works and is 'technically correct' (best kind),
it's a bit messy and hard to read.
2016-09-12 10:14:38 -04:00
Russell Hancox
2063bc3db3 Update pods, check length of EventDetailBundleURL, add text above URL in TTY (#89)
* SantaGUI: Check EventDetailBundleURL length rather than just existence

* santad: Add title above detail URL in TTY

* Project: Update pods
2016-09-09 16:11:40 -04:00
Tom Burgin
4380016d52 Compile SNTCommandController and SNTCommandFileInfo in the LogicTests target (#86) 2016-09-07 10:56:15 -04:00
Tom Burgin
5e3ceabe46 SNTCommandFileInfo Tests (#85) 2016-09-06 14:21:37 -04:00
Tom Burgin
8e7936275b Merge pull request #84 from russellhancox/fix-70
santactl/rule: Handle bad path properly (dir, non-file)
2016-09-06 13:31:57 -04:00
Russell Hancox
4b967239fa santactl/rule: Handle bad path properly (dir, non-file)
Fixes #70
2016-09-06 13:29:05 -04:00
Tom Burgin
92945c384c Merge pull request #83 from russellhancox/fix-82
Package: Ensure /usr/local/bin exists before making symlinks in it.
2016-09-06 13:10:44 -04:00
Russell Hancox
79d93c4ecf Package: Ensure /usr/local/bin exists before making symlinks in it.
Fixes #82
2016-09-06 13:03:49 -04:00
Allister Banks
76b6f25b0c uninstall.sh typo
typo
2016-09-01 11:20:44 -04:00
Allister Banks
aadce4890a Add uninstall script (#77)
Leaves configs, performs no checks about current state but should be
relatively idempotent (can't unload/rm stuff that's not there)
2016-08-30 11:41:20 -04:00
Tom Burgin
0e95a98fc2 santactl fileinfo sha1 & sha256 simultaneous hashing (#67) 2016-08-23 15:40:01 -04:00
Tom Burgin
9483437e8f Merge pull request #66 from russellhancox/master
santad: Database access optimizations
2016-08-23 14:29:40 -04:00
Russell Hancox
59542f8aef santad: Drop binrules/certrules views in rules database. 2016-08-23 12:48:41 -04:00
Russell Hancox
e29f7332f5 santad: Avoid creating multiple SNT*Table objects, as initializing them can be slow. 2016-08-23 12:48:41 -04:00
Russell Hancox
f8640feafe Project: Include xcodebuild clean in rake clean 2016-08-22 14:49:18 -04:00
Russell Hancox
e94e9e2be4 Project: Clean up CocoaPods project cruft 2016-08-22 14:46:56 -04:00
Tom Burgin
4053aac365 Merge pull request #65 from russellhancox/master
santactl/fileinfo: Recognize bundle/plugin mach-o files.
2016-08-22 14:07:43 -04:00
Russell Hancox
a5fa6c7aef santactl/fileinfo: Recognize bundle/plugin mach-o files. 2016-08-22 14:05:22 -04:00
Russell Hancox
97263894d1 santactl/sync: Send existing client mode in preflight request 2016-08-19 15:10:50 -04:00
Russell Hancox
1885580958 Project: pod update 2016-08-19 15:10:50 -04:00
Tom Burgin
1167b470bb santactl/fileinfo: Fix arg parsing, better cert printing
* arg parse fixes

* More parse fixes
2016-08-19 14:53:33 -04:00
Russell Hancox
7600506d6d santad: Include client mode in execution logs. 2016-08-18 14:44:40 -04:00
Russell Hancox
86bad866a0 santad: Unify CERT vs CERTIFICATE in logs. 2016-08-18 14:13:36 -04:00
Russell Hancox
2f1a15cf7e SantaGUI: Fix bundle version URLs 2016-08-18 14:11:42 -04:00
Tom Burgin
52b0e1870f Squashed binary and cert rule fetching down to one call. (#62) 2016-08-17 17:06:51 -04:00
Tom Burgin
9b181c1e0d santactl fileinfo updates (#61)
* Added --json output option. Added --key output option.
* Added multi-file processing
* Added threading
* \r to cleanup during really quick runs
2016-08-17 15:55:03 -04:00
Tom Burgin
100f2dc45e Merge pull request #60 from russellhancox/master
Performance improvements, GUI bundle handling
2016-08-12 16:42:00 -04:00
Russell Hancox
b247c3d477 santa-driver: Try to prevent logspam when dropping log queue messages
Both PostTo*Queue methods use mutexes, so access to the failed_*_queue_requests_ variables don't need to be atomic.
2016-08-12 16:08:23 -04:00
Russell Hancox
76ee82b258 santad: Limit log queue to 15 threads
To counteract the increased likelihood of dropped messages, double the maximum
log queue size.
2016-08-12 15:04:21 -04:00
Russell Hancox
e8fcd29669 santa-driver: If a request for a given vnode is pending, don't repeat request. 2016-08-12 15:04:21 -04:00
Russell Hancox
8dd16ecea4 santa-driver: Remove references to vnode_id_str
These should have been culled when moving to SantaCache but were missed.
2016-08-12 15:04:21 -04:00
Russell Hancox
e9c0bcd877 SantaGUI: Handle bundles having version instead of short version string 2016-08-12 15:04:21 -04:00
Allister Banks
75ed4b52a6 revise readme (#57)
* overall readme revise

admin-specific vs. security/performance features split up, add details
about path-based functionality, PAGEZERO feature, failsafe cert
whitelisting, explicitly say default mode is MONITOR

* process feedback

sticking with talking about binary launches while kext is loaded,
integrated all other feedback
2016-08-10 15:53:55 -04:00
Tom Burgin
71635c00df Merge pull request #58 from russellhancox/master
Performance improvements
2016-08-10 15:53:00 -04:00
Russell Hancox
1810af5483 SantaGUI: Change Dismiss button to Ignore 2016-08-10 15:18:22 -04:00
Russell Hancox
b07835dfd5 santad: Cache user/group id->name lookups. 2016-08-10 15:18:22 -04:00
Russell Hancox
4c33aa2aae santad: Improve loggedInUsers:sessions: 2016-08-09 16:51:23 -04:00
Russell Hancox
3c255640cb santad: Speed up TTY message creation 2016-08-09 16:51:23 -04:00
Russell Hancox
3d08ba9ebc santa-driver: Use msleep/wakeup instead of IOSleep.
This brings the average cache-miss decision making time down by 66%. Previously the minimum decision time was 10ms, now it's <1ms.
2016-08-09 16:51:23 -04:00
Russell Hancox
f64482500e santa-driver: Add debug logging of decision times to GetFromDaemon 2016-08-09 16:51:20 -04:00
Russell Hancox
215902f192 SantaCache: Extract entry value before unlocking bucket. 2016-07-19 16:28:35 -04:00
Russell Hancox
3e9c3a069d Project: Pod update 2016-07-19 14:51:01 -04:00
Russell Hancox
841fb48479 santa-driver: Only send file mod notifications to queue if client is connected. 2016-07-14 13:45:13 -04:00
Russell Hancox
df8e41925f SNTFileInfo: Check NSURLQuarantinePropertiesKey is usable 2016-07-13 17:29:53 -04:00
Russell Hancox
6b0994a990 santad: Avoid properties in critical path 2016-07-13 12:44:48 -04:00
Russell Hancox
7dd616e891 santa-driver: Switch SantaCache from an array to a linked list 2016-07-12 14:54:43 -04:00
Russell Hancox
c672edbe4d Whitespace clean-up 2016-07-12 14:51:10 -04:00
Russell Hancox
687ecc7097 santad: Close more file descriptors on exec 2016-07-11 16:23:38 -04:00
Russell Hancox
b8882b4826 santactl/fileinfo: Wait longer for daemon response. 2016-07-11 15:59:30 -04:00
Russell Hancox
51de0b38a4 santad: Change watchdog thread interval to 30s 2016-07-11 15:59:30 -04:00
Russell Hancox
e0309c0482 SantaGUI: In keyPathsForValuesAffectingValueForKey, return an empty set rather than nil 2016-07-11 15:53:04 -04:00
Russell Hancox
5dbe86869d santad: Move event storage out of the high priority decision queue
As event storage needs to happen before attempting upload, use the same serial queue.
2016-07-01 17:56:52 -04:00
Russell Hancox
14a11279c7 Project: Remove activesupport from travis settings.
It no longer appears to be needed for CocoaPods and causes errors.
2016-07-01 17:56:52 -04:00
Russell Hancox
df0ce42377 Merge pull request #54 from georgekola/gk-avoid-string-copy
Avoid two string copies
2016-07-01 17:09:54 -04:00
George Kola
4c03411405 Avoid two string copies 2016-07-01 14:07:23 -07:00
Russell Hancox
f020e18238 Project: Update to MOLCertificate 1.5 2016-07-01 13:02:07 -04:00
Russell Hancox
629bd4aff9 santad: argsForPid: Don't replace last NULL but still count up to it 2016-07-01 12:48:50 -04:00
Russell Hancox
f20825a66c Project: Increase optimization level for Pods 2016-06-30 14:36:16 -04:00
Russell Hancox
f098ca0d02 santad: Update argsForPid to append to a given string. 2016-06-30 09:41:26 -04:00
Russell Hancox
1f96f74f4d Merge pull request #52 from georgekola/gk-pread
Correctly use pread
2016-06-29 14:27:22 -04:00
George Kola
7a3a98c27a Correctly use pread
pread can return less than the chunk size (e.g. signal caught in the
middle) and hence we need to handle it. This change also cleans up the
hash function and makes it more performant.
2016-06-29 11:21:56 -07:00
Russell Hancox
1130448cb9 Merge pull request #53 from georgekola/gk-cacheCalls
Cache method call
2016-06-29 08:20:59 -04:00
George Kola
d388e99c0e Cache method call
Minor optimization. Cache objc method call in local variable to avoid a
second call
2016-06-28 21:26:35 -07:00
Russell Hancox
2baea9a6b4 Project: Xcode recommended updates. 2016-06-28 17:34:58 -04:00
Russell Hancox
0629625a9a santad: Move log queue down to BACKGROUND priority. 2016-06-28 17:21:07 -04:00
Russell Hancox
a2d0acc761 santad: sanitizeString: Use cached length value, use lengthOfBytesUsingEncoding: instead of length. 2016-06-28 17:02:37 -04:00
Russell Hancox
28a6bce90f santad: sanitizeString: Only allocate buffer if necessary. 2016-06-28 16:35:50 -04:00
Russell Hancox
9058192ffe santad: Use memcpy instead of strncpy where appropriate 2016-06-28 16:23:06 -04:00
Russell Hancox
465b358271 SantaCache: Initialize count_ to 0. 2016-06-28 15:01:57 -04:00
Russell Hancox
7de585fe1d santad: Replace sanitizeString with simple loop.
This is ~70% faster on average and is faster in all cases compared to the regex and the previous method.
2016-06-28 14:54:31 -04:00
Russell Hancox
8479730c95 SNTFileInfo: Catch potential NULL-pointer deref in isScript and isXARArchive. 2016-06-28 14:54:21 -04:00
Russell Hancox
7102e2df4c SNTFileInfo: More speed-ups in hashing, use RDAHEAD, don't use NOCACHE, catch EINTR. 2016-06-28 14:52:28 -04:00
Russell Hancox
c3bd99ff93 santad: Use serial queues instead of NSLock 2016-06-28 14:51:27 -04:00
Russell Hancox
c560405a46 SNTFileInfo: Speed up hashing - increase chunksize, read directly, use fcntl
- Use fcntl to disable cache and issue an advisory read
- Increase default chunk size from 4KB to 256KB
- Use pread to read from file descriptor, rather than make NSData objects

This is ~15% faster.
2016-06-27 17:38:41 -04:00
Russell Hancox
0c0fb28ccc santad: Make argsForPid more reliable and 33% faster 2016-06-27 15:55:18 -04:00
Russell Hancox
a33fce942c santad: Use regex to sanitize incoming strings, which is ~6x faster. 2016-06-27 13:11:15 -04:00
Russell Hancox
369cd40ee5 santad: Also optimize file logging by using NSMutableString 2016-06-27 12:51:29 -04:00
Russell Hancox
577b431a41 santad: Put locks around NSMutableDictionary in SNTEventLog and SNTExecutionController. 2016-06-27 12:48:36 -04:00
Russell Hancox
75cf8acd33 Project: Enable more compiler optimizations.
Specifically, switch from -Os to -Ofast and enable link-time optimization.
2016-06-27 10:08:38 -04:00
Russell Hancox
d70983962b Merge pull request #50 from georgekola/gk-optimize-log1
Optimize logging by using one pre-allocated NSMutableString
2016-06-27 10:05:46 -04:00
Russell Hancox
ff440984b0 Merge pull request #51 from georgekola/gk-optimize-fprintf
Using fwrite as we know the length of string
2016-06-27 09:48:53 -04:00
George Kola
c631155be7 Using fwrite as we know the length of string
It is better to use fwrite as it is generally faster and we are not
using any fprintf feature
2016-06-25 18:50:03 -07:00
George Kola
6038930755 Optimize logging by using one pre-allocated NSMutableString 2016-06-25 18:47:05 -07:00
Tom Burgin
9edc119c62 Merge pull request #49 from russellhancox/kernel-hashtable
santa-driver: Re-implement caching to avoid OSDictionary.
2016-06-20 13:16:09 -04:00
Russell Hancox
269a94bf03 SantaCache: Updates from PR:
+ Added check that per_bucket is >=1 and reduced max from 126 to 64.
+ Added note about cache reset above set method
+ Moved modulo into the hash function
2016-06-20 13:14:50 -04:00
Russell Hancox
7f3e4d7468 santa-driver: Re-implement caching to avoid OSDictionary.
OSDictionary is not well-suited to our needs and locking is quite expensive.
This commit:

  + Replaces all uses of OSDictionary with a new SantaCache class, which
    is a size-limited array hash table with per-bucket locking. It works with
    uint64_t keys, which is perfect for our needs.
  + Adds a unit test for SantaCache.
  + Removes SantaCachedDecision and SantaPIDAndPPID, which only existed
    because OSDictionary can only store OSObject subclasses.
  + Removes a lot of locking logic from SantaDecisionManager as the
    locking is now handled inside SantaCache and is therefore and is
    much more granular.
  + Removes the timed cache expiration for ALLOW decisions. This was
    originally to ensure executions were logged regularly but as we're
    logging all executions nowadays this is longer particularly useful.

SantaCache's configured load factor and hashing function may need tweaking
over-time but this is already a little faster and uses less memory
than what existed before.
2016-06-17 16:39:39 -04:00
Russell Hancox
eb89891cdd Merge pull request #48 from tburgin/tom
Add checkcache command to santactl
2016-06-17 16:17:38 -04:00
Tom Burgin
038b068370 u_int64_t --> uint64_t. CacheCheck --> RemoveFromCache. 2016-06-17 15:53:54 -04:00
Tom Burgin
d2017a59de Get back file status from the kernel cache 2016-06-17 12:45:51 -04:00
Tom Burgin
3435b56a84 Add checkcache command to santactl. It will check to see if the vnode id of a file is in the kernel cache 2016-06-17 12:03:26 -04:00
Russell Hancox
a812558d2d santad: Remove hashes from file write logs 2016-06-16 17:31:40 -04:00
Russell Hancox
aefd85455e Project: s/OS X/macOS/g 2016-06-16 17:31:40 -04:00
Russell Hancox
e42f1347b7 santad: Use IORegistryEntryFromPath instead of IORegistryEntryCopyFromPath.
The latter was only introduced in 10.11. Fixes #47
2016-06-16 17:31:40 -04:00
Russell Hancox
c7442a03d1 santa-driver: Use KAUTH_VNODE_WRITE_DATA instead of KAUTH_FILEOP_CLOSE to catch writes
It turns out that the KAUTH_FILEOP_CLOSE action is not used when the kernel automatically closes file descriptors for exiting processes. Some things, like dd, don't close their file descriptors and let the kernel do it for them which we were previously missing.
2016-06-16 17:31:40 -04:00
Russell Hancox
1eda8bdd9d KernelTests: Add test for overwritten file that was auto-closed 2016-06-16 17:31:37 -04:00
Russell Hancox
c4d0628bdb santad: Increase detail in TTY messages. 2016-06-13 12:38:55 -04:00
Russell Hancox
d51ae66242 santactl: Only resume in CommandContoller when its required, otherwise leave it to individual command 2016-06-10 12:48:54 -04:00
Russell Hancox
121dde6b8b KernelTests: Add cache speed test and secondary client rejection test 2016-06-10 12:48:54 -04:00
Russell Hancox
98081b067d Merge pull request #45 from clburlison/patch-1
Update style guide links
2016-06-09 16:53:54 -04:00
Clayton Burlison
8cc9345b42 Update style guide links 2016-06-09 15:52:48 -05:00
Russell Hancox
f7528365b0 Project: Have rake dist make the correct folder name from the version tag 2016-06-07 12:05:17 -04:00
Russell Hancox
7baa1a345e SNTFileWatcher: Don't call handler on main thread, sleep between handler invocations 2016-06-07 11:40:12 -04:00
Russell Hancox
acf7f4fd52 SantaGUI: Don't reload config file if attributes change (as it will trigger an attribute change) 2016-06-07 11:38:48 -04:00
Russell Hancox
f43e8680b8 santad: Improve SNTFileWatcher, update config file permissions if they change 2016-06-06 16:15:28 -04:00
Russell Hancox
545a6c1b36 santad: Ensure config file reloading is handled on main thread 2016-06-06 11:31:36 -04:00
Russell Hancox
f01fd8c850 Project: Try and fix CocoaPods on Travis 2016-06-03 14:12:03 -04:00
Russell Hancox
c9ec69b0b5 Tests: Fix OCMock misuse in testPreflightDatabaseCounts.
The block expects int64_t, not NSNumber. For some reason this didn't fail in Xcode but does from the command-line. Using OCMOCK_VALUE works properly.
2016-06-03 12:43:03 -04:00
Russell Hancox
3640e2c5f0 santad: Add a workaround for PrinterProxy 2016-06-03 11:32:55 -04:00
Russell Hancox
b3659cb456 santad: Don't spawn an event upload if one for this hash happened in the last 10 minutes 2016-06-01 17:20:16 -04:00
Russell Hancox
76284a2916 santad: Log disk mount/unmount events 2016-06-01 17:20:16 -04:00
Russell Hancox
40b1e011bd SantaGUI/santad: Add option to send bundled binaries to a different detail URL 2016-06-01 17:13:11 -04:00
Russell Hancox
e0bebecd59 santactl/sync: Switch bundle binary uploading
Only upload bundle related events when the server asks for it. Do the search inside a bundle for longer
2016-06-01 17:13:11 -04:00
Russell Hancox
8ac0cf6831 santad: Catch exceptions writing to TTY 2016-06-01 17:13:10 -04:00
Russell Hancox
992163206d Project: Switch to MOLAuthenticatingURLSession Pod. 2016-06-01 17:13:10 -04:00
Russell Hancox
86dd5d8078 santactl/sync: Refactor to reduce repetition, support XSRF tokens and add tests.
Move common request generating and performing code into a common
superclass.
Add code to handle XSSI in JSON responses and support XSRF
tokens via headers.
Adds tests, finally.
Changes preflight hostname to be long instead of short
2016-06-01 17:13:02 -04:00
Russell Hancox
932aa9d052 santad: For single-event syncs, use syslog logging 2016-05-25 17:52:53 -04:00
Russell Hancox
5f7f5204ec santad: Flush cache when switching into lockdown mode 2016-05-25 11:04:53 -04:00
Russell Hancox
a154d23637 SantaGUI: Add customizable notifications when client switches modes. 2016-05-25 11:04:35 -04:00
Russell Hancox
ac2bb9d362 SNTBlockMessage: Move HTML stripping to separate method 2016-05-24 16:32:25 -04:00
Russell Hancox
b918958bfa santactl/fileinfo: Don't fail if santad isn't running, colorize rule output on a TTY. 2016-05-19 19:08:52 -04:00
Russell Hancox
215df4ffa6 santactl: Always try to get daemonConn but only log and exit if it's marked as required 2016-05-19 19:08:52 -04:00
Russell Hancox
bb28bc5875 SNTXPCConnection: Ensure validation completes before returning remoteObjectProxy 2016-05-19 19:08:52 -04:00
Russell Hancox
a82bc3f712 SNTXPCConnection: Don't track accepted connections, it isn't useful. 2016-05-19 19:08:52 -04:00
Russell Hancox
b3a507014b Project: Update to CocoaPods 1.0 2016-05-19 19:08:52 -04:00
Russell Hancox
49c5e35a14 santad: Improve TTY message output.
Bold Santa title, replace <br/> with \n, add link to EventDetailURL
2016-05-19 19:08:03 -04:00
Russell Hancox
869ed33bd4 santactl/fileinfo: Show when code signature is adhoc 2016-05-03 14:15:27 -04:00
Russell Hancox
0c4a9be482 santad: Write message to TTY when blocking execution
Sometimes the GUI isn't running. Sometimes the user is using SSH. Either way, printing a message to the TTY of the parent of the just denied process is user-friendly.
2016-04-28 16:07:36 -04:00
Russell Hancox
4410ec575a santactl/fileinfo: Include rule state info 2016-04-28 16:07:24 -04:00
Russell Hancox
e3b92fc948 santactl/sync: Upload rule counts in preflight 2016-04-28 16:07:04 -04:00
Russell Hancox
4ca4692a67 santactl/flushcache: Disable flushcache in release builds.
It really isn't a useful command outside of development and its existence
seems to confuse people.
2016-04-28 15:00:10 -04:00
Russell Hancox
c1284d3c23 Project: Re-organize file structure, again 2016-04-28 14:11:50 -04:00
Russell Hancox
c8c0eadf72 santactl/fileinfo: Make file type output more accurate for executables 2016-04-28 10:54:54 -04:00
Russell Hancox
f4bbc8abc7 santactl/sync: Log successful stages as debug 2016-04-27 14:41:50 -04:00
Russell Hancox
a0f6ea57f8 SantaGUI: If SilencedNotifications key doesn't exist, create it 2016-04-27 14:19:25 -04:00
Russell Hancox
88d21a07ac santad, santactl/sync: Include Bundle Path in event upload data. 2016-04-26 17:35:29 -04:00
Russell Hancox
88e3a606a0 SNTFileInfo: Use CFBundleDisplayName if available 2016-04-26 17:34:29 -04:00
Russell Hancox
fff693c3f0 santad: Close the FMResultSet left after locking db to prevent spurious messages. 2016-04-26 17:33:43 -04:00
Russell Hancox
1e8d792d39 santa-driver: Flush vnode-pid map periodically. 2016-04-15 17:10:14 -04:00
Russell Hancox
dfb149ac6a santa-driver: Try to get uid/gid from credential if available 2016-04-15 17:05:50 -04:00
Russell Hancox
b5cfc92261 santactl/sync: Check that singleevent took an argument 2016-04-11 17:52:03 -04:00
Russell Hancox
079f3e3868 santactl/sync: Re-organize 'main' to bail earlier if config is invalid 2016-04-11 17:51:47 -04:00
Russell Hancox
15a6d58785 santactl/sync: Add long help, document --clean flag 2016-04-11 17:51:08 -04:00
Russell Hancox
a404498f8a santactl help: If command doesn't have long help, use short help. 2016-04-11 17:40:58 -04:00
Russell Hancox
0d133e2df6 Project: Enable code coverage for "All" test target 2016-04-11 17:40:00 -04:00
Russell Hancox
488b28bfd5 SantaGUI: Log to syslog 2016-04-11 15:15:03 -04:00
Russell Hancox
0fceb7b2e1 SantaGUI: Post notifications to main thread using dispatch_async 2016-04-11 15:14:52 -04:00
Russell Hancox
a79d1a98e7 santactl/fileinfo: Only print "Signing Chain" header if certificates array isn't empty 2016-04-08 16:21:15 -04:00
Russell Hancox
43434fd445 santactl/fileinfo: Don't crash on <512b files 2016-04-08 16:20:49 -04:00
Russell Hancox
492e523884 Project: Move enums in SNTCommonEnums to NS_ENUM, part 2 2016-04-08 15:41:26 -04:00
Russell Hancox
3d1fdb7a2b Project: Move enums in SNTCommonEnums to NS_ENUM, part 1 2016-04-08 15:17:32 -04:00
Russell Hancox
95a4bf0ec7 santad: Ensure launchd/santad rules are whitelisted on every startup
If they weren't already and the database is not new, log an error.
2016-04-08 15:16:12 -04:00
Russell Hancox
0d4f261e14 santad: Have SNTRuleTable return NSError when failing to add rules so user can see why 2016-04-08 15:07:43 -04:00
Russell Hancox
e96288b41b santad: Exclusive-lock rules.db when opening 2016-04-08 12:11:08 -04:00
Russell Hancox
deda1abcf7 SantaGUI: Detect value type for silenced notifications to prevent crashes from bad plist 2016-04-08 10:32:48 -04:00
Russell Hancox
ee79d75483 santad: Set ThrottleInterval to 1s. 2016-04-07 17:03:49 -04:00
Russell Hancox
0e9e445ddf SantaGUI: Reconnect when listener loses a client.
Also move WEAKIFY/STRONGIFY macros into their own header.
2016-04-07 17:03:09 -04:00
Russell Hancox
e64720bcd9 Project: Tell Travis to use xcode7 2016-04-07 15:33:10 -04:00
Russell Hancox
6e27590b57 SantaGUI: Add 'dismiss for a day' checkbox.
Fixes #39.
2016-04-07 14:40:33 -04:00
Russell Hancox
916c3c7a2a SNTXPCConnection: Re-add forced establishment of clients, better tests.
Previously SNTXPCConnection had two-way validation which, due to the method of
implementation, forced a client to connect to a server straight away. Once that
was removed, it meant invalidationHandlers aren't called if either end dies
before the connection is established.

This also puts back the acceptedHandler, which can be used to know when the
connection has finished being established (particularly useful on the server
side), updates the __weak stuff to use WEAKIFY/STRONGIFY macros (and now
actually switch them back to strong within each block) and make the
tests a lot better by using in-process anonymousListener's rather than
lots of mocking.
2016-04-06 23:25:55 -04:00
Russell Hancox
8a5fde8ceb LogicTests: Stop instrumenting program flow, it causes 100s of log lines during tests 2016-04-06 17:30:08 -04:00
Russell Hancox
f5bd9bde7f SantaGUI: Use ultralight system font for title of message window 2016-04-06 15:23:18 -04:00
Russell Hancox
b987f61924 SantaGUI: Fix centering constraint for publisher label 2016-04-06 15:22:21 -04:00
Russell Hancox
482b51a2f9 santactl/sync: Fix userAgent not being set 2016-04-05 14:52:48 -04:00
Russell Hancox
93f2078eda SantaGUI: Fix some constraint bugs in MessageWindow 2016-04-04 18:15:20 -04:00
Russell Hancox
158ae11e61 Tests: Remove old stuff from XPCConnectionTest 2016-04-01 17:53:37 -04:00
Russell Hancox
d282388266 santactl/sync: Release certificate after use 2016-04-01 17:31:24 -04:00
Russell Hancox
6ecdfcba38 santactl/sync: If unable to find client identity, let default handling occur. 2016-04-01 09:54:15 -04:00
Russell Hancox
88dc8a547e README: Add video of block event, as an example 2016-03-31 13:51:35 -04:00
Russell Hancox
58e24b3c11 santagui: Remove old comment, don't activateIgnoringOtherApps twice. 2016-03-31 09:27:38 -04:00
Russell Hancox
5f1b3a2284 santad: Initialize ppath to (null) before calling proc_pidpath 2016-03-30 16:12:52 -04:00
Russell Hancox
31be2584f2 Conf: Use facility instead of sender for santad/santactl logs 2016-03-29 18:00:30 -04:00
Russell Hancox
a2311e5128 santad: Attempt to load santa-driver before connecting to it 2016-03-29 14:08:29 -04:00
Russell Hancox
e94d42187b santactl/sync: Don't log successful stages
Currently a standard succesful sync will print 4 success lines, one for
each stage that was run, followed by a line that the entire sync was
successful. As each stage will also log if it did anything, these
success messages aren't useful. Instead, just log if they failed.
2016-03-25 16:44:06 -04:00
Russell Hancox
2b99cc3f62 Logging: strncmp for binaryName 2016-03-25 14:20:46 -04:00
Russell Hancox
cb7f782893 santad: Fix typo in cert protection error 2016-03-23 17:45:08 -04:00
Russell Hancox
d5a0f8a74b Logging: Remove extraneous ; 2016-03-23 16:46:38 -04:00
Russell Hancox
2ebd71df24 santactl/sync: Fix single-event upload with extra arguments 2016-03-23 16:46:21 -04:00
Russell Hancox
479203f47c santa-driver: Style and type cleanups, inlining some small functions 2016-03-22 15:38:48 -04:00
Russell Hancox
022b9209d9 LogicTests: Delete resources that aren't used anymore. 2016-03-22 15:36:56 -04:00
Russell Hancox
771c2c868f SantaGUI: Increase contrast of user-defined block window messages. 2016-03-21 18:00:02 -04:00
Russell Hancox
5285a728b1 santa-driver: Don't record fileop events from santad 2016-03-21 16:15:20 -04:00
Russell Hancox
41e6583920 SantaGUI: Improve accessiblity of message dialog
+ VoiceOver: add more useful label descriptions
+ VoiceOver: skip some fields
+ Color: increase contrast
2016-03-21 13:49:50 -04:00
Russell Hancox
cbb60b3a05 SantaGUI: Have daemon reply when setting notification listener so GUI can ensure it connected 2016-03-17 17:55:31 -04:00
Russell Hancox
cf1d1e3557 santa-driver: Better handle secondary volumes 2016-03-15 15:10:41 -04:00
Russell Hancox
8f05ee7d79 santa-driver: Rename some action types 2016-03-15 12:53:44 -04:00
Russell Hancox
641bd07c0b Project: New icon 2016-03-14 16:38:07 -04:00
Russell Hancox
7d9dc0a853 Tests: Fix kernel tests 2016-03-14 16:13:28 -04:00
Russell Hancox
e0a46be1b7 santactl/fileinfo: When resolving path, store bundle ref if possible. 2016-03-14 12:55:20 -04:00
Russell Hancox
fd82c67b56 santactl/fileinfo: Add disk image file type 2016-03-14 12:55:20 -04:00
Russell Hancox
f0a83b6f19 santactl/fileinfo: Add simultaneous hashing. 2016-03-14 12:52:25 -04:00
Russell Hancox
736b45bb46 SNTXPCConnection: Remove client validation of server
Now that santad<->SantaGUI work more like the client/server they are,
having an SNTXPCConnection 'client' validate its server is no longer necessary.
Having the validation in the 'server' only simplifies the code.
2016-03-11 17:06:43 -05:00
Russell Hancox
8eae9b7cb7 santad/SantaGUI: Refactor GUI<>santad connection logic and add queuing.
Instead of having santad create a listener for SantaGUI to connect to
and then reverse the client-server relationship, have SantaGUI create an
anonymous listener that it sends to santad using the control interface.

Also add a queue for notifications so that blocks that occur while
SantaGUI isn't running will show up once it starts.
2016-03-11 14:58:12 -05:00
Russell Hancox
0aa2d2c613 santactl/fileinfo: Print useful info when codesign validation fails 2016-03-10 18:23:21 -05:00
Russell Hancox
ad43db10f2 Tests: Attempt to fix FileWatcher tests 2016-03-10 17:17:02 -05:00
Russell Hancox
606f507422 Project: Update CocoaPods 2016-03-10 16:34:08 -05:00
Russell Hancox
36b7778883 LogicTests: Fix SNTXPCConnection test 2016-03-10 15:53:40 -05:00
Russell Hancox
7b032a6a73 Project: Travis, build in local dir instead of DerivedData 2016-03-10 15:53:27 -05:00
Russell Hancox
0e00237e44 Project: Add clang-format file, apply most of the fixes it suggested 2016-03-10 15:53:06 -05:00
Russell Hancox
e9ec9a7d7f santad: Log quarantine URL if one exists.
Fixes #34
2016-03-10 13:24:31 -05:00
Russell Hancox
6834507f3a XPC: Allow multiple XPC clients to a server 2016-03-10 12:21:49 -05:00
Russell Hancox
90e99255b1 santa-driver/santad: Split decision making and logging onto 2 data queues
This resolves an issue where the data queue can be overwhelmed by logging requests and fail to respond to decisions for an extended period of time.
2016-03-10 12:21:17 -05:00
Russell Hancox
b6487000a3 SNTFileInfo: Use NSBundle to find executable path in bundles.
Fixes #37
2016-03-10 12:19:52 -05:00
Russell Hancox
18ce2f72ed Config: Fix config reloading 2016-03-10 12:18:05 -05:00
Russell Hancox
8a2d04bf69 santactl/rule: Fix print error 2016-03-09 15:41:27 -05:00
Russell Hancox
a210ffecec Logging: Create one ASL client per-thread. 2016-03-07 17:31:31 -05:00
Russell Hancox
aff96e8144 Config: Warn if SyncBaseURL is an invalid URL 2016-03-07 12:36:00 -05:00
Russell Hancox
3d4c639bb4 santactl/sync: Fix logic when auto-detecting certificates.
Now, instead of assuming an identity can be found that the server asked
for, look for a chain of certs resulting in an identity that matches the
server's request.
2016-03-07 12:32:32 -05:00
Russell Hancox
d507e79505 santad: Fix quarantine data collection.
This previously didn't work for root (santactl fileinfo was fine)
because quarantine data is per-user.
2016-03-07 12:30:36 -05:00
Russell Hancox
d3e242ff42 Project: Update Travis settings 2016-02-05 19:37:11 -05:00
Russell Hancox
df7616403d SantaGUI: Show entire SHA-256 in fixed-width font 2016-01-14 16:51:29 -05:00
Russell Hancox
962b15517a SantaGUI: Add a transparent button to be the first responder, so tabbing the dialog works. 2015-12-28 17:24:29 -05:00
Russell Hancox
d295f2391f santactl/sync: In --debug log the full NSError for failed requests 2015-12-15 12:36:07 -05:00
Russell Hancox
c042222eea santad: Add user/group info to file changelogs also 2015-12-14 22:32:59 -05:00
Russell Hancox
63f6596bc2 santactl: Rename binaryinfo -> fileinfo. 2015-12-14 18:09:40 -05:00
Russell Hancox
d8a8aba0ea SNTFileInfo: Move machoType method to binaryinfo command, add XAR archive detection. 2015-12-14 17:25:32 -05:00
Russell Hancox
d9d9682029 santactl/sync: Let related-binary search take up to 5s 2015-12-14 16:37:19 -05:00
Russell Hancox
4a27a8ac70 Rakefile: Use Xcode to figure out where built products went, to avoid relying on particular Xcode settings. 2015-12-14 16:36:11 -05:00
Russell Hancox
32857ff304 Project: Apply latest Xcode recommendations 2015-12-14 16:35:34 -05:00
Russell Hancox
375bfd3862 santa-driver: Put locks around vnode_pid_map, use an OSObject subclass to store PID/PPID.
Put a R/W lock around vnode_pid_map_ to prevent use-after-free.
Create SantaPIDAndPPID to use instead of creating and then scanning strings.
Also rename SantaMessage -> SantaCachedDecision, as that's what it is.
2015-12-14 16:34:38 -05:00
Russell Hancox
9430c41b8a santad: Include user and group names in execution logs 2015-12-11 12:58:09 -05:00
Russell Hancox
9b342e146a santactl/sync: Include code sign info with related executables and encode to dict. 2015-12-10 17:37:22 -05:00
Russell Hancox
e5685f2959 santad: Don't try to add empty argument to array when processing execution arguments 2015-12-10 17:02:11 -05:00
Russell Hancox
4150feece2 santactl/sync: When uploading events for bundles, look for other bundled executables.
Many application bundles have related helper tools, which will individually need to be whitelisted unless they're covered by a certificate. To help make user's lives easier, when an event is triggered for a binary inside a bundle look for other executables in the same bundle and upload an event for those too (with an obvious tag) so that the server can let the user vote to whitelist all the binaries together.
2015-12-10 17:01:49 -05:00
Russell Hancox
6879ec5deb santa-driver: in DecisionManager free locks before anything else 2015-12-10 16:56:13 -05:00
Russell Hancox
28ad00ffad SantaGUI: Split block messages into unknown and banned.
This is so that a message can be configured for banned executables without having to provide a custom message for every single one.
2015-12-10 12:13:52 -05:00
Russell Hancox
bf51049fbf santa-driver: Save pid/ppid from VFS context when decision making for use when logging
Previously the execution logging from fileop didn't work when using posix_spawn as proc_selfpid/proc_selfppid still refer to the process calling posix_spawn. We can get the correct pid/ppid from the vfs_context in the vnode scope but we can't log executions from there as the arguments end up being wrong. Instead, save the vnode_id->pid/ppid mapping in the vnode scope and use that in the fileop scope for logging.
2015-12-10 12:12:38 -05:00
Russell Hancox
36189e9122 santad: Update SNTFileInfo to always get strings from bundle Info.plist data.
Also perform a one-time update of any events created before this change.
2015-12-04 13:09:56 -05:00
Russell Hancox
4c747463ac santad: Separate execution requests and logging into separate queues with appropriate priorities. 2015-12-04 12:39:26 -05:00
Russell Hancox
b4b1fbb9e6 santad: Run watchdog thread loop once before sleeping 2015-10-31 14:01:44 -04:00
Russell Hancox
209eaff3c6 SNTFileInfo: Embed SHA hashing loop in an autoreleasepool to avoid temporary RAM spikes 2015-10-31 13:45:47 -04:00
Russell Hancox
c3f70703fd santactl/status: Expose peak CPU/RAM use from santad. 2015-10-29 16:20:57 -04:00
Russell Hancox
f2967e7b94 santad: Switch watchdog CPU counter from rusage to task_info, capture peak CPU/RAM use. 2015-10-29 16:20:25 -04:00
Russell Hancox
77c46b5c43 SNTFileInfo: switch from NSData to NSFileHandle.
This seems to work much better than NSData with either mapped (SIGBUS when file is deleted) or uncached (ballooning memory use) reading.
2015-10-29 16:17:12 -04:00
Russell Hancox
5fda5bc081 santactl/binaryinfo: Only print bundle lines if bundle info is present 2015-10-29 12:35:27 -04:00
Russell Hancox
33a7b38c6a SNTFileInfo: check for NULL ptrs when parsing for embedded plist 2015-10-27 18:35:11 -04:00
Russell Hancox
2a7c0bd58c SNTFileInfo: Go back to using mmap, uncached read balloons memory use 2015-10-27 18:08:16 -04:00
Russell Hancox
86e4d0db0f santactl: Use yyyy instead of YYYY in NSDateFormatter 2015-10-27 17:58:23 -04:00
Russell Hancox
1310fea64d santa-driver: Only try to use/release proc_t if proc_find found it. 2015-10-22 11:29:49 -04:00
Russell Hancox
382f5a5bb9 Merge pull request #30 from stephanemoore/patch-1
Fix application deadlock.
2015-10-22 08:39:54 -04:00
Stephane Moore
ff3303e312 Fix application deadlock.
Fix application deadlock by asynchronously dispatching to the main queue in -[SNTAppDelegate createConnection].
2015-10-21 17:45:59 -07:00
Russell Hancox
6ce0ef62e9 SantaGUI: Ensure connection is only made on main thread 2015-10-15 18:31:07 -04:00
Russell Hancox
2a03341fb6 santad: Add configuration option for turning off PAGEZERO protection. 2015-10-15 18:10:00 -04:00
Russell Hancox
77a55dde56 santad: Catch errors archiving/unarchiving SNTStoredEvent, delete events that fail 2015-10-15 18:09:46 -04:00
Russell Hancox
1a71cdff4a santad/santactl: Report back if rule adding/removing failed rather than assuming success. 2015-10-15 12:15:38 -04:00
Russell Hancox
63f65c51c3 SNTFileInfo: Use NSURL method for getting quarantine data, don't try to use <10.10 2015-10-15 12:14:53 -04:00
Russell Hancox
75de2526c1 santactl/binaryinfo: Only print quarantine fields if they're not empty 2015-10-14 23:37:16 -04:00
Russell Hancox
6fc4b7b120 santactl/binaryinfo: Increase key padding +1 2015-10-14 23:31:50 -04:00
Russell Hancox
7b8068139b santad, santactl/sync: Collect and upload quarantine data with events. 2015-10-14 23:02:20 -04:00
Russell Hancox
ced7de884f santactl/binaryinfo: Add quarantine data to output, add print method to simplify changes. 2015-10-14 20:12:04 -04:00
Russell Hancox
bc51c9f25b SNTFileInfo: Add com.apple.quarantine data accessors for downloaded files. 2015-10-14 20:11:32 -04:00
Russell Hancox
c412e8b9a7 SNTFileInfo: Fix embedded plist parsing, extract into separate method 2015-10-14 20:07:50 -04:00
Russell Hancox
4e0ff224b6 Project: Remove SNTCertificate/SNTCodesignChecker, use new CocoaPod versions 2015-10-12 17:23:42 -04:00
Russell Hancox
61c817c9cb Tests: Fix SNTRuleTable tests 2015-10-09 15:14:15 -04:00
Russell Hancox
2ed384f677 santactl/sync: Only update client mode at end of sync 2015-10-09 13:12:25 -04:00
Russell Hancox
7a851cb080 santad: Typo in comment 2015-10-08 19:54:23 -04:00
Russell Hancox
13aa889633 SNTFileInfo: Add fileSize method, use it in SNTEventLog 2015-10-08 17:57:02 -04:00
Russell Hancox
5c3fba5f41 santad: Prevent user/server from accidentally deleting rules that would kill the system. 2015-10-08 17:45:39 -04:00
Russell Hancox
145d9216bf Project: Don't bother with "xcodebuild clean" for Rakefile clean rule 2015-10-08 17:43:59 -04:00
Russell Hancox
84f46de940 Driver/Daemon: Collect process name in-kernel for file events, parent name for exec requests. For file events log process name and path, if possible. 2015-10-05 17:09:33 -04:00
Russell Hancox
cb9a5b6fbe santactl: Add --json option to both status and version commands. 2015-10-05 14:15:10 -04:00
Russell Hancox
d9718faba4 SNTFileInfo: Return non-embedded dict if locating embedded fails 2015-10-05 14:13:40 -04:00
Russell Hancox
5472ff41f0 santactl/status: Show timezone as UTF offset rather than name 2015-10-05 13:00:55 -04:00
Russell Hancox
4f94c3b310 santactl/status: Use fixed format for sync date output but still include TZ. 2015-10-03 19:57:19 -04:00
Russell Hancox
420f1efa50 santad: For file write events, print process name as well as pid. 2015-10-03 18:16:06 -04:00
Russell Hancox
5d2ce17817 santactl/status: When printing last sync date, use local timezone and locale settings 2015-10-03 18:15:41 -04:00
Russell Hancox
053cb823a1 santa-driver: Change C++ std to C++11
This is mostly just to quiet the warning about override not being set on getMetaClass, which is part of the OSDeclareDefaultStructors macro.
2015-10-03 18:15:11 -04:00
Russell Hancox
18a7992372 Config: Add more protected keys, only protect if a server is set 2015-10-02 16:35:30 -04:00
Russell Hancox
9e935f5bfb GUI: Include CFBundleName as first item in UI, if available. 2015-10-01 18:53:58 -04:00
Russell Hancox
9f49e24dc5 santad: Update file changes logging to use a configurable regex 2015-10-01 17:57:07 -04:00
Russell Hancox
dbf60f16bc santactl/sync: Fix typo causing clean sync on every run 2015-09-30 16:00:39 -04:00
Russell Hancox
0f3a228788 santactl/rule: Make help text a little clearer 2015-09-28 17:46:30 -04:00
Russell Hancox
d905f5b095 santactl/rule: Add ability to add certificate rules. Re-write argument parsing. 2015-09-28 17:20:34 -04:00
Russell Hancox
1c310486c7 santactl/status, santad: Show watchdog events in status output 2015-09-28 16:41:33 -04:00
Russell Hancox
4b01c6da91 santactl/status: Report some sync statuses. 2015-09-28 16:14:45 -04:00
Russell Hancox
5782378616 santactl/sync, santad: Add clean sync and last success options, use to initiate clean sync when database is re-created 2015-09-28 16:11:17 -04:00
Russell Hancox
64c97ebfba santad: If database open fails, delete and re-create. 2015-09-28 16:09:05 -04:00
Russell Hancox
5fd4d56b00 santactl/sync: Add ability to sync blacklist regex 2015-09-28 16:08:11 -04:00
Russell Hancox
e658b5167e Project: Update README a little 2015-09-24 18:15:03 -04:00
Russell Hancox
cea698d720 SNTCertificate: Add serialNumber and isCa properties. 2015-09-21 17:48:47 -04:00
Russell Hancox
c07f41c312 santad: Stop closing stdout/stderr 2015-09-21 15:59:32 -04:00
Russell Hancox
a837aa0334 santactl/status: Use dispatch group instead of sleeping 2015-09-21 15:59:20 -04:00
Russell Hancox
0050724e22 SNTXPCConnection: Use semaphore instead of variable & sleep. 2015-09-21 15:58:54 -04:00
Russell Hancox
adac4ac75c SantaGUI: windowWillClose and orderOut are being marked nonnull 2015-09-21 15:51:36 -04:00
Russell Hancox
718f37024a SNTConfigurator: Use NSPropertyListImmutable instead of kCFPropertyListImmutable 2015-09-21 15:51:03 -04:00
Russell Hancox
fcb3008539 Rakefile: Handle xcpretty missing better 2015-09-21 15:50:22 -04:00
Russell Hancox
8faf3eec53 santactl/sync: Validate incoming rules better 2015-09-16 15:59:50 -04:00
Russell Hancox
2bc3df3255 santad: Stop using mmap while reading files, it can be forced to crash by truncating the file. 2015-09-16 15:52:49 -04:00
Russell Hancox
5b0e550c85 santad: Add BlacklistRegex option, log a useful explanation when decision is made by scope 2015-09-16 14:19:33 -04:00
Russell Hancox
e52211abf2 santa-driver: Release proc_t acquired with proc_find. 2015-09-15 17:23:07 -04:00
Russell Hancox
9b6f231b34 santa-driver: Check for daemon earlier in FetchDecision 2015-09-14 18:20:33 -04:00
Russell Hancox
b71223705f santa-driver: If daemon fails to provide a response, print the path of the files it failed on 2015-09-14 18:19:56 -04:00
Russell Hancox
863fbe69bb santa-driver: Simplify AddToCache's locking 2015-09-14 18:19:28 -04:00
Russell Hancox
2d46279961 santa-driver: Use 0 as the client_pid when not connected 2015-09-14 18:18:51 -04:00
Russell Hancox
0d0207d77f santa-driver: lck_attr and lck_grp_attr need freeing 2015-09-14 18:18:20 -04:00
Russell Hancox
00bbade34f santa-driver: ClientConnected() should check if process is exiting/dying. 2015-09-14 18:08:57 -04:00
Russell Hancox
682f741ddc santad: Separate uid/gid fields in log. 2015-09-11 11:35:14 -04:00
Russell Hancox
3d2744c9e3 santactl/sync: Use lib compression for both preflight and event upload phases 2015-09-09 17:13:38 -04:00
Russell Hancox
cc286dcf16 santad: Fix event storage 2015-09-09 17:13:21 -04:00
Russell Hancox
27c6e2a7bd santa-driver: Don't send file mod messages unless daemon is connected 2015-09-09 14:22:31 -04:00
Russell Hancox
72c7a67ad5 Logging: Limit kernel messages to those actually sent by the kernel 2015-09-09 13:34:30 -04:00
Russell Hancox
8fe5e4e238 Logging: Update logMessage to use asl directly, adding a facility 2015-09-09 11:56:53 -04:00
Russell Hancox
02f23d0c62 santad: Add LogFileChanges option, remove LogAllEvents, fix key protection 2015-09-09 11:56:31 -04:00
Russell Hancox
ff6f4d4152 Common: Update SNTRule and SNTStoredEvent isEqual/hash/description methods. 2015-09-08 16:35:50 -04:00
Russell Hancox
2242f46792 Conf: Don't roll logs too regularly 2015-09-08 16:34:38 -04:00
Russell Hancox
642b5609b2 Tests: Fix tests after adding file write logging 2015-09-08 16:34:21 -04:00
Russell Hancox
98878f3e7c Kernel/santad: Add file write logging and exec argv's.
This necessitated a large refactoring of a bunch of code, hence being a large commit. This moves all event logging into a separate class, moves logging of executions to be from FileOp events rather than Vnode events (so we can get the argv after the execve call has finished) and implements the logging of cached execs.
2015-09-08 16:33:59 -04:00
Russell Hancox
3eb28deccf santa-driver: Verify input args are not nullptr's. 2015-09-08 14:41:34 -04:00
Russell Hancox
761a852156 santad: Always request sizeof(santa_message_t) regardless of previous message size 2015-09-08 14:40:50 -04:00
Russell Hancox
f4ddb11c1f santad: Force database permissions on startup 2015-09-08 14:33:25 -04:00
Russell Hancox
75158c11ea santa-driver: Don't create santa_message_t structs on the stack.
Also rename userId field to uid and add gid field to match
2015-08-31 15:21:25 -04:00
Russell Hancox
fe96706b0c KernelTests: Always unload kext and cleanup tmp after running 2015-08-27 18:03:40 -04:00
Russell Hancox
b87482e824 santad: Move page zero check to after binary/cert rule checks so 'bad' binaries can be whitelisted and notifications will be generated when they're blocked 2015-08-27 15:25:13 -04:00
Russell Hancox
a9ba99dc79 SNTFileInfo: Re-write mach header parsing 2015-08-27 15:25:12 -04:00
Russell Hancox
8884e92a1a Tests: Add test for missing/bad pagezero 2015-08-27 15:25:12 -04:00
Russell Hancox
6385514257 santad: Block 32-bit binaries with missing/invalid page zero 2015-08-27 15:25:12 -04:00
Russell Hancox
d3ad47022b Conf: Change log time format to ISO8601Z.3 2015-08-27 15:25:01 -04:00
Russell Hancox
138d4b507d SantaGUI: Fix fast-user-switching support. 2015-08-18 17:00:38 -04:00
Russell Hancox
3c0b195bcf Update travis.yml to add Cocoapod caching 2015-08-07 17:27:15 -04:00
Russell Hancox
d941a71bb5 Package: Forcibly make santactl symlink 2015-08-05 16:19:37 -04:00
Russell Hancox
08697d9daf KernelTests: Fix lots-of-executions test 2015-08-05 15:59:41 -04:00
Russell Hancox
8959871988 Rakefile: Clean before dist 2015-08-05 15:59:34 -04:00
Russell Hancox
bb43a04992 SNTFileInfo: Always try to get embedded info.plist before bundle plist 2015-08-05 12:01:05 -04:00
Russell Hancox
5f93dc7991 Project: Stop trying to be smart with logging destinations 2015-08-04 18:13:04 -04:00
Russell Hancox
9be8eb223c KernelTests: Stop blocking ps while tests are running, block ed instead. 2015-08-04 17:13:35 -04:00
Russell Hancox
e8b6c47e0f KernelTests: Remove timeout, chdir to tmp dir before executing, add lots-of-binaries test 2015-08-04 17:13:20 -04:00
Russell Hancox
697d442afb Project: Update Mac OS X -> OS X. 2015-08-04 13:54:55 -04:00
Russell Hancox
5dbd261b5a GUI: Allow selection of all fields and add ppid to end of parent name. 2015-08-04 13:53:47 -04:00
Russell Hancox
9bc94ca658 GUI: Add defaultBlockMessage configuration 2015-08-04 13:52:44 -04:00
Russell Hancox
4404b5f849 santactl/sync: Default to ephemeralSessionConfiguration to avoid caching 2015-08-03 18:03:51 -04:00
Russell Hancox
6a4b73b8a9 santa-driver: Before posting request to santa, ensure it exists in the cache already 2015-08-03 18:02:57 -04:00
Russell Hancox
b6146224b3 santa-driver: Make "cache too large" log info instead of debug 2015-08-03 18:02:34 -04:00
Russell Hancox
e3593c1b0c santad: fclose stderr for santactl sync too 2015-07-22 16:35:25 -04:00
Russell Hancox
90a2f10da6 santactl/rule: Print usage when args are bad, catch missing long arguments.
Fixes #20
2015-07-22 13:48:43 -04:00
Russell Hancox
60bab1c004 Rakefile: Don't miss santad/santactl dSYMs 2015-07-21 15:22:14 -04:00
Russell Hancox
0898940d0b santad: Pass santa_message_t straight to SNTExecutionController 2015-07-21 14:52:53 -04:00
Russell Hancox
38b65b0ca4 santad: Move uid->username lookup to where it's actually used 2015-07-21 14:52:53 -04:00
Russell Hancox
d36ce5eefc KernelTests: Update comments, add extra write-to-cached-file check 2015-07-21 14:52:48 -04:00
Russell Hancox
ff99ab9cfe santad: loggedInUsers:sessions: style clean-up 2015-07-21 14:22:42 -04:00
Russell Hancox
64995367c3 santad: Simplify eventStateForDecision:type: 2015-07-21 14:22:42 -04:00
Russell Hancox
c67f0ffc11 santad: Don't initiate event upload if syncing isn't enabled 2015-07-21 14:22:42 -04:00
Russell Hancox
d5403ae112 santa-driver: Move vnode-id and vnode-id-str fetching to avoid duplication 2015-07-21 14:22:42 -04:00
Russell Hancox
d21d64cbfe santad: Don't print log format every startup 2015-07-21 14:22:42 -04:00
Russell Hancox
347ee3c4f5 Merge pull request #19 from samsymons/podfile-fix
Fix an installation error with CocoaPods.
2015-07-21 14:20:41 -04:00
Sam Symons
77ed1cca29 Fix an installation error with CocoaPods.
In the later versions of CocoaPods, the `project` method was replaced
with `pods_project`. This was preventing the post_install hooks from
being run.
2015-07-21 10:41:03 -07:00
Russell Hancox
cfac7dbb37 Logging: Fix syslog logging and file rotation 2015-07-17 17:43:04 -04:00
Russell Hancox
f27d72f3f9 Tests: Update tests for new error argument to SNTFileInfo 2015-07-17 12:59:48 -04:00
Russell Hancox
3cd93b287e santa-driver: Simplify kauth callbacks, moving most of the logic to methods on SDM 2015-07-16 22:33:24 -04:00
Russell Hancox
5e5605881b santa-driver: remove client_proc, use ClientConnected() instead 2015-07-16 22:32:17 -04:00
Russell Hancox
a9b48610df santa-driver: Clear data queue if client crashes. Restore dataqueue lock, the docs lied. 2015-07-16 22:31:31 -04:00
Russell Hancox
3cca09a48c santa-driver: Remove request loops in GetFromDaemon
For large binaries it poses a risk of being overrun and as santad is working pretty reliably it's almost certainly not necessary anymore.
2015-07-15 18:55:05 -04:00
Russell Hancox
3134448eac santad: Close password database after getpwuid 2015-07-15 18:25:26 -04:00
Russell Hancox
663bdf945b KernelTest: Update for EACCES -> EPERM change 2015-07-15 18:24:13 -04:00
Russell Hancox
e94d1175e7 santad: If file can't be hashed, log an error and allow execution. 2015-07-13 11:20:39 -04:00
Russell Hancox
e20b761965 santa-driver: Change rejection errno to EPERM 2015-07-01 18:55:04 -04:00
Russell Hancox
90c64812d0 santad: close stdout before running santactl sync 2015-07-01 17:22:40 -04:00
Russell Hancox
08d368fc49 santad: Rename watchdog thread with reverse-dns name 2015-06-26 16:29:46 -04:00
Russell Hancox
39385f0bff santad: Put an autoreleasepool inside the watchdog thread. 2015-06-26 13:12:46 -04:00
Russell Hancox
8bc3418ce1 santad: Watchdog: only log memory use if it increased since last check. Increase threshold to 250MB 2015-06-25 17:58:17 -04:00
Russell Hancox
a145700398 Rakefile: Properly unload/load GUI during build. 2015-06-25 17:52:59 -04:00
Russell Hancox
409535e617 santactl: Style, indenting. 2015-06-25 11:04:57 -04:00
Russell Hancox
f625016efe santactl/sync: When rejecting a redirect, cancel the task to avoid hanging the task until timeout 2015-06-24 17:32:35 -04:00
Russell Hancox
f4c94ab1d7 santactl/sync: Failed log upload should not fail whole sync 2015-06-24 17:21:54 -04:00
Russell Hancox
8234706dd3 santad: Vacuum event database after removing multiple events. 2015-06-24 11:58:38 -04:00
Russell Hancox
1a31dc870f Merge branch 'whitelistscope'
* whitelistscope:
  Common: Rename kWhitelistDirsKey/WhitelistDirs to kWhitelistRegexKey/WhitelistRegex
  santad: NSRegularExpression doesn't work with XPC.
  santactl/sync: Sync whitelist regex
  santad: In a rule vs scope, rule wins.
  santad: Move whitelisted dirs feature to using regex instead of array. Faster and more flexible.
  santactl: Update help/error wordings
  santad: Add whitelisted directory support
2015-06-23 18:31:03 -04:00
Russell Hancox
a1712858c5 Common: Rename kWhitelistDirsKey/WhitelistDirs to kWhitelistRegexKey/WhitelistRegex 2015-06-23 18:30:42 -04:00
Russell Hancox
0059e768b9 Common: Add __NSString__ attribute to logMessage to catch format string bugs. Fix some warnings that found. 2015-06-23 18:10:46 -04:00
Russell Hancox
4fe1550bd2 santad: NSRegularExpression doesn't work with XPC. 2015-06-23 18:09:35 -04:00
Russell Hancox
0c182c8a7f santactl/sync: Sync whitelist regex 2015-06-23 17:33:43 -04:00
Russell Hancox
bcdf746def santad: In a rule vs scope, rule wins. 2015-06-23 17:33:08 -04:00
Russell Hancox
bc13ac3a98 santad: Move whitelisted dirs feature to using regex instead of array. Faster and more flexible. 2015-06-23 17:22:18 -04:00
Russell Hancox
a894e018cd santactl: Update help/error wordings 2015-06-23 17:21:17 -04:00
Russell Hancox
cbecfd444d santad: Add whitelisted directory support 2015-06-23 17:21:17 -04:00
Russell Hancox
357e5ef963 santactl/sync: NSString doesn't have an unsignedIntegerValue method 2015-06-23 17:14:47 -04:00
Russell Hancox
60594c9f03 santad/santactl-sync: Accept backoff interval from server, disable event uploads if back off is used, re-enable on next sync. 2015-06-23 15:54:30 -04:00
Russell Hancox
44b5bae8da santad: Add sync execution timer to santad 2015-06-23 15:52:39 -04:00
Russell Hancox
2e856196c5 santad: Move SIGCHLD SIG_IGN setting to main(), it doesn't need to be set repeatedly. 2015-06-23 15:36:59 -04:00
Russell Hancox
8672187c02 SantaGUI: Add keepalive to launchagent plist 2015-06-23 11:20:20 -04:00
Russell Hancox
cf251c45b8 Project: Update package Makefile for santad/santactl move 2015-06-22 15:57:10 -04:00
Russell Hancox
385c03096d Project: Missed santactl/santad move in Rakefile dist command 2015-06-22 15:35:03 -04:00
Russell Hancox
f323f5e3de santad: Up watchdog interval to 60s and CPU threshold to 20%.
Whilst during normal operation santad doesn't use more than 5% CPU, it does spike if lots
of processes start, such as during bootup. This change helps to reduce the noise.
2015-06-22 15:28:02 -04:00
Russell Hancox
9562ee86cd Project: Add missing copy to a few properties previously missed 2015-06-19 17:32:45 -04:00
Russell Hancox
adfb4bc861 SNTFileInfo: Better caching of properties 2015-06-19 17:31:48 -04:00
Russell Hancox
957232ca40 santactl: Fix event counting bug in status command 2015-06-16 18:02:41 -04:00
Russell Hancox
44c9d9aead santad: Add watchdog thread to print warnings if CPU/RAM usage seem high. 2015-06-15 16:31:55 -04:00
Russell Hancox
f95245cedd 10.11 Prep: Move santad,santactl from /usr/libexec,/usr/sbin to within santa-driver.kext 2015-06-15 16:18:51 -04:00
Russell Hancox
3c034adf48 GUI: Prevent reconnection loop when XPC connection dies 2015-06-10 16:46:32 -04:00
Russell Hancox
abd3c5a06d GUI: Restore constraint move Dismiss button when event detail URL is not set 2015-06-10 16:45:16 -04:00
Russell Hancox
ca4951a475 SNTFileWatcher: Update test file location 2015-06-09 13:50:43 -04:00
Russell Hancox
e751a3d307 SNTFileWatcher: Only get the fileSystemRepresentation once, to avoid high memory use when file doesn't exist 2015-06-09 13:10:29 -04:00
Russell Hancox
2a8bdfd714 santad: Use _exit instead of exit after fork. Oops. 2015-06-01 17:12:12 -04:00
Russell Hancox
be9dca3ee2 GUI: Add close button to About window. 2015-05-21 16:12:48 -04:00
Russell Hancox
32707fb501 santa-driver: Fix rare panic in CacheCheck where lock upgrade fails.
lck_rw_lock_shared_to_exclusive can return false if a previous reader upgraded. The result is the lock being unlocked and the panic is caused when unlocking a lock that isn't locked.
2015-05-20 11:13:19 -04:00
Russell Hancox
d72547e187 Project: Simplify package download URL generation in pkg Makefile 2015-05-18 18:36:30 -04:00
Russell Hancox
9150ddffb1 Project: Fix broken curl command in pkg Makefile 2015-05-18 17:52:33 -04:00
Russell Hancox
d5c1d66c2f KernelTests: Update tests for dataqueue usage changes 2015-05-18 16:39:27 -04:00
Russell Hancox
536b8969ed santactl/sync: LogUpload - logsToUpload is part of the same class, use self. 2015-05-18 16:31:43 -04:00
Russell Hancox
0db3b6d955 santactl/sync: Split out Log Upload request generation and Rule Download rule parsing from main request methods. 2015-05-18 14:33:21 -04:00
Russell Hancox
78bb9a1bd6 common: Correct comment on default loglevels 2015-05-18 13:06:31 -04:00
Russell Hancox
567e0b6431 santad: If exiting because of a failed dequeue, log the return code at ERROR level. 2015-05-18 13:06:31 -04:00
Russell Hancox
f2f27c5675 santa-driver: Up ACTION_REQUEST_SHUTDOWN from 60->90 2015-05-18 13:06:31 -04:00
Russell Hancox
5a7ac2287b santa-driver: Stop defining MAX_PATH_LEN, use MAXPATHLEN instead.
I can't recall why I did this.
2015-05-18 13:06:31 -04:00
Russell Hancox
f82da21b75 santactl/sync: Bug from 8cd9898, call completion handler even if no rules are downloaded. 2015-05-15 10:38:26 -04:00
Russell Hancox
969a5ef94e santactl/sync: Don't release SecAsn1Coder until we're done with its data. 2015-05-14 17:35:06 -04:00
Russell Hancox
fd7ad07193 santactl/sync: Handle DER decoding failures more gracefully. 2015-05-14 17:01:49 -04:00
Russell Hancox
3f5400b264 santa-driver: Split FetchDecision, notify daemon of missed executions, reorganize some methods. 2015-05-14 17:01:49 -04:00
Russell Hancox
466b5ed491 santa-driver: Make SantaDecisionManager::AddToCache default the microsecs parameter to the current uptime 2015-05-14 17:01:48 -04:00
Russell Hancox
25f1b71f10 santa-driver: Move dataqueue to SantaDecisionManager rather than
recreating it on every connect.
2015-05-14 17:01:48 -04:00
Russell Hancox
d1295f97b9 santa-driver: Rename owning_pid/proc to client_pid/proc. Minor style
cleanup
2015-05-14 17:01:48 -04:00
Russell Hancox
f5eb274aa0 santa-driver: remove unnecessary dataqueue lock 2015-05-14 17:01:48 -04:00
Russell Hancox
58b9dab74f santa-driver: SDM should call super::init 2015-05-14 17:01:48 -04:00
Russell Hancox
9f6b6d10dc santa-driver: Make room in santa_message_t->path for the terminator so we don't miss a character. 2015-05-14 17:01:47 -04:00
Russell Hancox
57f6e516c2 santa-driver: Mark all overriden methods with 'override' 2015-05-14 17:01:42 -04:00
Russell Hancox
8cd9898cf3 santactl/sync: Don't send empty rules array to daemon. 2015-05-11 16:27:02 -04:00
Russell Hancox
d53b04213a santa-driver: Remove empty spacing at end of line 2015-05-08 14:58:16 -04:00
Russell Hancox
ac99bd1070 santad: Add tests for SNTRuleTable 2015-05-08 14:57:53 -04:00
Russell Hancox
30df44df96 santad: Correctly delete corrupt events. Add test for this. 2015-05-08 14:57:37 -04:00
Russell Hancox
fc55b86f30 santad: Switch to uint32_t for table version numbers 2015-05-08 14:56:20 -04:00
Russell Hancox
59ffb67554 santad: Reject addRules requests with empty/nil array. Also switch to NSUInteger for rule counts. 2015-05-08 14:55:28 -04:00
Russell Hancox
d46b156b85 santa-driver: vnode_getattr sometimes panics if a vfs_context isn't available (when used with osxfuse for instance). 2015-05-07 18:24:29 -04:00
Russell Hancox
6492e70599 santactl: Instead of rejecting authentication challenges and trying again, cancel the whole request. 2015-05-07 17:56:47 -04:00
Russell Hancox
bc5d0f8685 santa-driver: Don't allow StopListener to return until both kauth scopes are done 2015-05-06 14:57:33 -04:00
Russell Hancox
838da16da1 santad: Delete events that fail to unarchive 2015-05-06 14:44:09 -04:00
Russell Hancox
6e242bf98d SantaGUI: Change Line to custom NSBox 2015-05-05 17:44:06 -04:00
Russell Hancox
be1e66c29d Project: Enable more warnings and then fix them. 2015-05-01 17:40:39 -04:00
Russell Hancox
57866308e3 santad: Consider scripts that are part of installer packages as in-scope. 2015-04-30 18:37:04 -04:00
Russell Hancox
63bc8fca2d santad: Don't post GUI notification for SILENT_BLACKLIST rules. 2015-04-30 18:36:43 -04:00
Russell Hancox
408712f00f santad: Don't log when client mode is not set in defaultDecision, as that can't actually happen. 2015-04-30 18:36:20 -04:00
Russell Hancox
8cb6046f94 GUI: Add parent process name, only show part of the shasum, resize window. 2015-04-30 18:24:54 -04:00
Russell Hancox
297fb4cb68 Add parent process name collection and upload 2015-04-30 18:21:13 -04:00
Russell Hancox
1501d413f0 Project: Add install.sh script and package Makefile
Adds an install.sh script that can be run from the distribution tarball
and a Luggage package makefile
2015-04-30 14:12:02 -04:00
Russell Hancox
e747ace0f3 santactl/binaryinfo: Add bundle details to file info 2015-04-30 12:34:31 -04:00
Russell Hancox
6b96f36b2b SantaGUI: Re-create AboutWindowController each time it's needed so that More Info button state is correct 2015-04-22 15:59:04 -04:00
Russell Hancox
f16fa691b5 santactl: include zlib.h instead of import 2015-04-21 16:43:09 -04:00
Russell Hancox
4fd5e1139f Project: Style clean-ups 2015-04-21 14:29:30 -04:00
Russell Hancox
0b33079833 Merge pull request #16 from marczak/readme-up
Updated README to clarify intentions and expectations
2015-04-21 09:14:50 -07:00
Edward Marczak
6069ed5801 Update README.md 2015-04-21 12:14:05 -04:00
Edward Marczak
c2a9061ea2 Updated README to clarify expectations. 2015-04-21 11:24:58 -04:00
Russell Hancox
ee963d62a4 Project: Update README to mention dyld issue 2015-04-21 10:02:32 -04:00
Russell Hancox
c12adbc8e6 Project: Update schemes to make Xcode be quiet. 2015-04-20 18:35:10 -04:00
Russell Hancox
e6b20bcce6 Project: update Podfile.lock 2015-04-20 18:07:33 -04:00
Russell Hancox
10333bba01 santa-driver: Change file-write cache check, use FileOp scope for most writes and use hasdirtyblks to catch flushed but still-open files. 2015-04-20 18:07:22 -04:00
Russell Hancox
437764e6fc Conf: Undo adding Username/Groupname to santasync launchd, it doesn't work properly 2015-04-13 16:41:47 -04:00
Russell Hancox
460dd6aa8b Project: Stop using xctool, use xcpretty to make xcodebuild output nice instead. 2015-04-10 16:37:24 -04:00
Russell Hancox
0a511468e3 Conf: Run scheduled santactl/sync runs as nobody 2015-04-10 16:06:56 -04:00
Russell Hancox
96517573e7 santactl/sync: rename SyncStatus->SyncState, add cleanSync option that can be requested by client or server. 2015-04-10 12:39:22 -04:00
Russell Hancox
c996921c22 GUI: Move window centering to the fadeIn method so it's only called when the window is displayed 2015-04-10 10:07:53 -04:00
Russell Hancox
8365e00a50 Sync: Decision should be uploaded as a string, not an int. Rename serial_no to serial_num 2015-04-09 10:02:21 -04:00
Russell Hancox
a629e6cff1 Clean-up: NSString length is quicker than isEqual 2015-04-09 10:01:44 -04:00
Russell Hancox
cbb786c6d1 Kext: Check fSharedMemory and fDataQueue before trying to release them in terminate() 2015-04-09 10:01:04 -04:00
Russell Hancox
49b169ec36 SNTFileWatcher: unset source event handler correctly 2015-04-08 14:22:24 -04:00
Russell Hancox
41d1d7e3de SNTFileWatcher: fix some dispatch bugs, move eventHandler property to
class extension, add tests.
2015-04-08 12:29:41 -04:00
Russell Hancox
323a38dc21 Project: Clean-up block style, order of public/private in C++ headers 2015-04-08 12:29:22 -04:00
Russell Hancox
c37f1eb006 SNTConfigurator: remove auto-reloading code, move to file watching
class.
2015-04-08 12:28:58 -04:00
Russell Hancox
b7b2b5b630 santactl/status: Add daemon status, currently just the mode. 2015-04-01 16:15:35 -04:00
Russell Hancox
2486cfdcff santactl/sync: Update logging 2015-04-01 16:15:14 -04:00
Russell Hancox
4231781178 Project: Update CocoaPods 2015-03-31 18:13:37 -04:00
Russell Hancox
7ba886ed18 SNTConfigurator: Fix broken MachineOwner parsing, part 2 2015-03-31 17:29:11 -04:00
Russell Hancox
8096701fbd SNTConfigurator: Fix broken MachineID/MachineOwner parsing 2015-03-31 17:26:02 -04:00
Russell Hancox
16531d18c8 santa-driver: Kill daemon if PostToQueue is failing too much. 2015-03-31 16:14:32 -04:00
Russell Hancox
ef0cc2fffd santactl/sync: Put constant API strings in a separate file 2015-03-31 15:56:47 -04:00
Russell Hancox
f2dc7fb4b0 SNTConfigurator: Only reject and re-save client mode in santad. 2015-03-31 15:49:49 -04:00
Russell Hancox
707e9a11d4 SantaGUI: Let background move window, part 2. 2015-03-31 12:20:43 -04:00
Russell Hancox
aef3d57dcf SantaGUI: Ensure configuration is loaded before first message arrives, let window be moved, close window properly when opening event URL 2015-03-30 18:45:06 -04:00
Russell Hancox
cfb38068f8 santa-driver: DisconnectClient should return straight away if client is not properly connected 2015-03-30 18:37:36 -04:00
Russell Hancox
ca19d9fde7 SNTConfigurator: Do initial file monitoring async 2015-03-30 18:37:18 -04:00
Russell Hancox
e19aab36bd SantaGUI: Close window when opening web pages 2015-03-27 16:56:13 -04:00
Russell Hancox
111540f0a8 LogicTests: Update some Stub calls to Expect 2015-03-27 15:39:13 -04:00
Russell Hancox
88897477b6 santad: Now that SNTConfigurator auto-reloads, stop tracking clientMode separately. Also reload logAllDecisions if req'd. 2015-03-27 15:38:55 -04:00
Russell Hancox
a9d6e42d5a SNTConfigurator: Have configuration auto-reload if file on disk changes 2015-03-27 15:38:10 -04:00
Russell Hancox
8b5720b291 santad: Update comments in DriverManager 2015-03-27 15:37:08 -04:00
Russell Hancox
2d9f392efc santa-driver: Ensure fSDM and fDataQueue are NULL'd ASAP. 2015-03-27 15:36:24 -04:00
Russell Hancox
76844eb77d santa-driver: lock data queue mutex when retaining/releasing queue 2015-03-27 15:35:50 -04:00
Russell Hancox
2db996f8e0 SantaGUI: Add configurable About Window and Event Detail buttons 2015-03-27 15:35:16 -04:00
Russell Hancox
6c27ac60a1 SNTConfigurator: if MachineID hasn't been overridden get one from IOKit 2015-03-26 15:08:26 -04:00
Russell Hancox
d4c4b26c3b santactl/sync: Fix MachineOwnerPlist* config methods, don't crash if machine owner missing 2015-03-26 08:24:53 -04:00
Russell Hancox
50614f589c santactl/sync: Update Rule download API 2015-03-25 17:17:41 -04:00
Russell Hancox
0292d4e956 GUI: Handle missing custom message in event notifications 2015-03-16 17:29:27 -04:00
Russell Hancox
4e1e4cde3b santactl/sync: Fix broken Log Upload, re-add gzip compression 2015-03-16 17:05:49 -04:00
Russell Hancox
c86f0e7c80 Project: unload kext using bundle ID 2015-03-16 15:09:38 -04:00
Russell Hancox
77b8edda79 Project: enable 'deep' static analysis for all builds except for LogicTests and KernelTests 2015-03-16 15:04:18 -04:00
Russell Hancox
f3d098c521 Project: Add LogicTests scheme that can be used for logic tests without building all binaries 2015-03-16 15:03:46 -04:00
Russell Hancox
0afe465ac5 santactl: Rename machineIDOverride to machineID 2015-03-13 18:18:09 -04:00
Russell Hancox
472558a03c santad: Add LogAllEvents option 2015-03-13 18:17:09 -04:00
Russell Hancox
dfef7d8567 SantaGUI: Fix broken predicate for pending notifications 2015-03-13 17:33:18 -04:00
Russell Hancox
925903e07d SantaGUI: Move publisher certs button, make publisher info autosize width 2015-03-13 17:29:31 -04:00
Russell Hancox
a43c0ee295 SantaGUI: swap publisher/sha256 fields in message window 2015-03-13 16:57:25 -04:00
Russell Hancox
1e82b5abc6 Missed some newlines in printf statements 2015-03-13 16:56:38 -04:00
Russell Hancox
7502dbdec6 Project: Enable NDEBUG for FMDB in release builds. 2015-03-13 15:35:21 -04:00
Russell Hancox
217ad25531 santactl: move more commands from LOG* to printf 2015-03-13 12:48:49 -04:00
Russell Hancox
7c3b533679 santactl: Update help strings 2015-03-13 12:47:28 -04:00
Russell Hancox
2c4ba45988 santa-driver: Move from IO*Lock to lck_* 2015-03-12 14:34:52 -04:00
Russell Hancox
26ee0a68d1 santactl: Separate out version info from status, move user-only commands from LOG* to printf 2015-03-12 14:31:49 -04:00
Russell Hancox
27eb2e9cff santactl: Remove old todo about establishing connection 2015-03-11 21:42:15 -04:00
Russell Hancox
9431d954b5 SNTXPCConnection: invalidate connection if verification doesn't complete 2015-03-11 21:41:53 -04:00
Russell Hancox
1a2d8b55f8 SNTSystemInfo: NSHost is awful, use gethostname() instead 2015-03-11 21:24:56 -04:00
Russell Hancox
d27a26ca50 santad: Make driver-waiting an exponential backoff up to 16s 2015-03-11 19:14:41 -04:00
Russell Hancox
56d4a6b9fb santa-driver: Change when we consider the client connected to avoid getting into a state where events are being held but no memory descriptor is in place yet. 2015-03-10 17:40:03 -04:00
Russell Hancox
28a94cd56a santa-driver: each error state is already logged, don't log again 2015-03-10 17:39:29 -04:00
Russell Hancox
4344fc3d7d santa-driver: Remove process listener, it doesn't do anything useful and stops Hopper from working 2015-03-09 18:38:22 -04:00
Russell Hancox
40431d835e SNTStoredEvent: pid and ppid need to be encoded/decoded to be included in database/uploads 2015-03-09 12:19:26 -04:00
Russell Hancox
942804c478 santa-driver: Fix typo 2015-03-09 11:44:09 -04:00
Russell Hancox
d109aae6ef santad/santactl: include pid and ppid in event upload 2015-03-09 09:52:56 -04:00
Russell Hancox
b89040c37a santactl/sync: Add ability to refuse redirects 2015-03-06 17:41:31 -05:00
Russell Hancox
63aefb4654 santa-driver: increase max queue events to 256 2015-03-06 12:00:48 -05:00
Russell Hancox
1c92e968e3 SNTAuthenticatingURLSession: remove unnecessary import 2015-03-06 12:00:33 -05:00
Russell Hancox
c1b7f9ae63 SNTAuthenticatingURLSession: fix potential crash where client identity
is released before NSURLCredential is created
2015-03-05 13:58:31 -05:00
Russell Hancox
0507bc83d2 SNTCertificate: comment updats 2015-03-05 12:04:19 -05:00
Russell Hancox
7028c24425 Add missing copyright header from SNTDERDecoder.m 2015-03-05 12:03:55 -05:00
Russell Hancox
6ede057521 Update README.md 2015-02-04 10:26:12 -05:00
Russell Hancox
6f2ccca60a Tests: Add to SNTDERDecoderTest and SNTCertificateTest 2015-02-03 22:48:04 -05:00
Russell Hancox
a59d2aa8a9 Merge branch 'kext-listener-move' 2015-02-03 18:58:46 -05:00
Russell Hancox
d88fa4ecfe santad: sleep for less time when waiting for driver 2015-02-03 18:56:25 -05:00
Russell Hancox
4df93bfe6c Project: Fix version info 2015-02-03 18:56:08 -05:00
Russell Hancox
08ca3c9d95 Driver: Move SantaDecisionManager ownership to IOService level, start listeners ASAP but allow and log until daemon connects. Remove useless close method in SantaDriverClient. 2015-02-03 18:55:24 -05:00
Russell Hancox
3423026a43 santad: move scope check after bin/cert rule checks 2015-02-02 18:25:28 -05:00
Russell Hancox
e574621911 santactl/binaryinfo: Only show index in signing chain once 2015-02-02 18:17:46 -05:00
Russell Hancox
f1a3246eb9 santactl/sync: Minor style cleanup 2015-02-02 18:15:32 -05:00
Russell Hancox
eeda832fae santactl/sync: Factor out dictionary conversion 2015-02-02 18:12:07 -05:00
Russell Hancox
40af338af2 santad: Correctly log when file allowed due to scope 2015-02-02 17:35:45 -05:00
Russell Hancox
8a4b2a8480 SNTXPCConnection: add invalidate to header 2015-02-02 17:32:29 -05:00
Russell Hancox
912f3aa0e1 SantaGUI: kill daemon connection on user-switch, re-create on switch back. 2015-02-02 17:32:09 -05:00
Russell Hancox
e7cb5703f2 Tidy up event UI 2015-02-02 17:05:16 -05:00
Russell Hancox
6fb81471e0 Fix SNTEventTableTest 2015-02-02 17:04:56 -05:00
Russell Hancox
54ffbf40d6 Ensure kernel cache is flushed if rules are added which are not whitelisting 2015-02-02 17:04:37 -05:00
Russell Hancox
101c9d2b1f Event Table: rename a method, simplify event decoding, lowercase all table fields 2015-02-02 17:04:06 -05:00
Russell Hancox
ce9af3d019 santactl/sync: Simplify cert signing chain in event upload. 2015-02-02 17:02:55 -05:00
Russell Hancox
d11b137f9b santactl/sync: Don't attempt to apply rules until all have been downloaded 2015-02-02 17:02:08 -05:00
Russell Hancox
9d1117b0c7 SNTExecutionController: Change logging separator from comma to pipe. Also use logDecision when out of scope 2015-02-02 17:00:30 -05:00
Russell Hancox
ee9a7f635a Move from Certificate SHA-1 to SHA-256 2015-02-02 16:59:04 -05:00
Russell Hancox
63c6e4f852 santactl binaryinfo: Add Cert SHA-256 2015-02-02 13:21:34 -05:00
Russell Hancox
af63d036de Finish SNTExecutionControllerTest: testOutOfScope 2015-02-02 13:21:09 -05:00
Russell Hancox
b728ea3077 Rename SNTBinaryInfo -> SNTFileInfo, add more tests 2015-01-31 17:54:29 -05:00
Russell Hancox
a98bd00492 Unify path-standardizing into SNTBinaryInfo 2015-01-30 18:56:43 -05:00
Russell Hancox
6aeae5f1b6 santactl rule: print if rule is being deleted 2015-01-30 18:45:12 -05:00
Russell Hancox
7a03183cf0 Update Copyright years 2015-01-30 18:41:12 -05:00
Russell Hancox
6b743015a0 santactl rule: Correctly show rule SHA-256 2015-01-30 18:31:30 -05:00
Russell Hancox
b095625972 Remove SNTNotificationMessage, use SNTStoredEvent for that purpose instead. 2015-01-30 18:31:17 -05:00
Russell Hancox
98adf9c2c1 Update SNTRule and SNTStoredEvent encoding/decoding 2015-01-30 18:29:45 -05:00
Russell Hancox
c447eb959b More comment fixes 2015-01-30 17:28:32 -05:00
Russell Hancox
801d2b241a CommonEnums: Add ALLOW_SCOPE and BLOCK_SCOPE 2015-01-30 17:28:21 -05:00
Russell Hancox
42684387c5 Kernel: Rename RESPONSE_VALID macro to CHECKBW_RESPONSE_VALID 2015-01-30 17:28:04 -05:00
Russell Hancox
a66255aa8f Events: store event in archived form in database, store & upload entire signing chain rather than just leaf, rename eventsPendingCount, add unit tests. 2015-01-30 17:27:34 -05:00
Russell Hancox
30d335658c More missed SHA-1 references 2015-01-29 19:55:03 -05:00
Russell Hancox
20a7d6074f Missed a few SHA-1 references 2015-01-29 12:33:57 -05:00
Russell Hancox
f8273555a4 santactl: Binaryinfo detects bundles 2015-01-28 23:28:41 -05:00
Russell Hancox
a607136a0d Add logging of out-of-scope files 2015-01-28 23:20:16 -05:00
Russell Hancox
4b166f4485 Update Pods 2015-01-28 22:33:42 -05:00
Russell Hancox
f1f2913529 Update kernel tests for switch to userland hashing 2015-01-28 22:33:17 -05:00
Russell Hancox
1117b28d8d Change RuleDownload JSON to refer to shasum for rule instead of sha1 2015-01-28 22:20:55 -05:00
Russell Hancox
72811e5546 SNTXPCConnection: break loop when rejecting 2015-01-28 22:01:50 -05:00
Russell Hancox
3fefa7676f Add xctool support to Rakefile 2015-01-28 21:59:51 -05:00
Russell Hancox
75883af800 Fix some tests 2015-01-28 21:29:08 -05:00
Russell Hancox
22e5ffa1f1 SNTEventTable, rename from indexes to id 2015-01-28 21:28:59 -05:00
Russell Hancox
8b671ea2cd Remove DebugLogging config option, change to --debug flag instead. 2015-01-28 21:28:40 -05:00
Russell Hancox
ecbd92646d Update all docstrings to triple-slash doxygen style 2015-01-28 21:28:17 -05:00
Russell Hancox
b946598f7b Remove unused method from SNTEventTable 2015-01-28 19:13:00 -05:00
Russell Hancox
b30696b8a3 Fix alignment in SNTCommandSync.m 2015-01-28 19:13:00 -05:00
Russell Hancox
ae74a61a7e Add SHA-256 output to santactl binaryinfo command 2015-01-28 19:13:00 -05:00
Russell Hancox
2ae9229a6b Remove SHA-1 import in kernel 2015-01-28 19:12:59 -05:00
Russell Hancox
95a334dbaf Remove bundle icon from notification window 2015-01-28 19:12:59 -05:00
Russell Hancox
6335a02404 Move to SHA-256 hashing 2015-01-28 19:12:59 -05:00
Russell Hancox
5c9cceec35 common: Add SHA-256 to binaryinfo 2015-01-28 19:12:06 -05:00
Russell Hancox
71b08307a3 Driver: Move SHA-1 calculation to userland 2015-01-28 19:12:06 -05:00
Russell Hancox
180c8f2226 SNTCertificate: add SHA-256 hashing 2015-01-23 16:46:09 -05:00
Russell Hancox
2305ec578c More comment string updates 2015-01-23 16:45:54 -05:00
Russell Hancox
2f735dc716 Grr. Tabs. 2015-01-20 19:06:31 -05:00
Russell Hancox
afca026c12 SNTConfigurator: NSPropertyListSerialization argument should be NULL instead of nil 2015-01-20 19:05:32 -05:00
Russell Hancox
1447fd8789 SNTConfigurator: Make configFilePath configurable, try to enforce permissions on config file, use NSPropertyListSerialization instead of CFPropertyListCreateWithData 2015-01-20 18:59:45 -05:00
Russell Hancox
ccd871cfdd santactl: Simplify protocol and daemonConn handling 2015-01-20 18:58:40 -05:00
Russell Hancox
407466cd5f Update SNTXPCConnection's wait-during-resume and utilize it in SNTCommandController 2015-01-20 18:58:08 -05:00
Russell Hancox
ba9340d30d Some doxygen comment cleanups 2015-01-20 18:57:14 -05:00
Russell Hancox
a7715e3ce2 santad: Fix long-standing bug where santad won't finish shutting down when kext goes away 2015-01-14 18:37:46 -05:00
Russell Hancox
1a8cd79bf9 SNTXPCConnection: sleep for up to 5s during resume in clients to avoid sending messages during validation 2015-01-14 11:43:31 -05:00
Russell Hancox
a560c84cdc SNTBinaryInfo: Add downloadURLs method 2015-01-13 18:27:02 -05:00
Russell Hancox
4e0cfeb16d Driver: add missing debug log when process listener stops 2015-01-13 16:32:08 -05:00
Russell Hancox
195ba4d918 santactl status: don't block infinitely if daemonConn is nil 2015-01-13 16:16:03 -05:00
Russell Hancox
7458896a2a Driver: send down ppid to daemon 2015-01-13 16:08:29 -05:00
Russell Hancox
a78f2b37ee Driver: style and comment cleanup 2015-01-13 16:07:03 -05:00
Russell Hancox
d3c0d409ab Project: Remove references to unused imports 2015-01-13 16:05:09 -05:00
Russell Hancox
71833da8f4 Driver: Change back from using vn_rdwr to VNOP_READ 2015-01-13 16:01:45 -05:00
Russell Hancox
10892691e8 Merge pull request #12 from dutchcoders/add-remove-rules-using-cli
santactl: can add and remove rule(s) now
2015-01-12 18:56:20 -05:00
Russell Hancox
5139fe692c Project: Update deployment target to 10.9, santactl sync has never worked on 10.8 2015-01-09 16:46:58 -05:00
Russell Hancox
7cdfda187e Tests: Update to OCMock3 macro syntax 2015-01-09 16:36:43 -05:00
Russell Hancox
d4538b4f7c Project: simplify version numbering by basing the version number on the latest git tag number. Mark debug builds with git commit id. 2015-01-07 18:42:17 -05:00
Remco
c885dbdd4f moving exit within the block, because of race condition 2015-01-06 22:06:56 +01:00
Remco
1bfe8feeb1 customMsg wasn't set to parameter value 2015-01-06 22:06:18 +01:00
Remco
caaa7e60c3 disallow rule management when syncbaseurl is set 2015-01-06 22:05:51 +01:00
Remco
21bf445f46 fixed typo in help text 2015-01-06 22:05:36 +01:00
Russell Hancox
685641bb5d Merge branch 'master' of github.com:google/santa 2015-01-05 23:31:46 -05:00
Russell Hancox
53c00ef61e Move Style section, rename 2015-01-05 23:31:14 -05:00
Russell Hancox
8ec7f28f94 Update CONTRIBUTING, link to style guides 2015-01-05 23:29:52 -05:00
Russell Hancox
09d71f8790 Merge pull request #13 from russellhancox/master
Style cleanups and fix for santactl memory leak
2015-01-05 23:26:14 -05:00
Russell Hancox
e8f298aa38 santactl: Fix memory leaks in SNTAuthenticatingURLSession, inline extractIdentityAndTrust function 2015-01-05 23:19:24 -05:00
Russell Hancox
172a260cdc Style cleanups 2015-01-05 23:18:12 -05:00
Russell Hancox
d47770804e Merge branch 'master' of github.com:google/santa 2015-01-05 22:04:07 -05:00
Russell Hancox
b4b899cf37 Merge pull request #11 from dutchcoders/add-help-command
added help command to usage
2015-01-05 14:41:49 -05:00
Russell Hancox
df59825c57 Merge pull request #10 from dutchcoders/working-on-client-certificates
Work on client certificates
2015-01-05 14:40:50 -05:00
Remco
e959e42282 add help command to usage 2014-12-29 17:24:47 +01:00
Remco
86cd6aa133 enhancement(santactl): can add and remove rule(s) now. 2014-12-29 17:20:56 +01:00
Remco
de61869b01 corrected typo 2014-12-24 09:25:00 +01:00
Remco
c9a6b59a43 Print error when config couldn't be loaded and use empty configuration. 2014-12-24 09:21:03 +01:00
Remco
76ae6adced updated some styling issues 2014-12-24 09:19:03 +01:00
Remco
6b177933e2 fixed remarks 2014-12-23 20:51:00 +01:00
Remco
06c95e9121 fixed issue with ignored cert issuer cn and cert common name config 2014-12-22 15:41:22 +01:00
Remco
dbbdfb1965 added support for using custom pkcs#12 file with password 2014-12-22 15:37:25 +01:00
Remco
2d927175e0 Improved error logging. 2014-12-22 15:23:25 +01:00
Remco
642b69bde2 Removing hard coded disabling of client certificates. 2014-12-22 15:22:17 +01:00
Remco
16ca9b85ab exit when configuration file couldn't be opened
* when the configuration file couldn't be opened it failed silently and
used empty configuration. Now it prints an error and quits with
errorcode 1.
* LOGE not used because of circular reference
2014-12-22 12:31:23 +01:00
Remco
cbf16d140b return error when certificate file could not be loaded. 2014-12-21 15:20:43 +01:00
Russell Hancox
bf84a86450 Merge pull request #8 from dutchcoders/add-contenttype-header
added content-type application/json to json requests
2014-12-19 21:01:06 -05:00
Remco
1503f8658d added content-type application/json to json requests 2014-12-20 02:29:02 +01:00
Russell Hancox
c8bcf3ba2c Driver: Get ref to node before trying to read file 2014-12-19 12:41:30 -05:00
Russell Hancox
9d1c850b91 Driver: Use kernel page_size global 2014-12-19 12:40:53 -05:00
Russell Hancox
fe90353c75 Driver: invalidate cache on vnode delete 2014-12-19 12:39:28 -05:00
Russell Hancox
2d1941dcff Merge pull request #7 from dutchcoders/fix-rule-sync
santad: fix segfault while adding rules
2014-12-19 11:12:50 -05:00
Remco
546b2f1383 switched to @() boxing syntax instead of NSNumber literals 2014-12-19 17:10:49 +01:00
Remco
4509cd5c0b fixed segfault while adding rules 2014-12-19 12:45:35 +01:00
Russell Hancox
9a423f1b06 Proj: Add Travis-CI integration 2014-12-16 23:20:11 -05:00
280 changed files with 22067 additions and 7514 deletions

22
.clang-format Normal file
View File

@@ -0,0 +1,22 @@
BasedOnStyle: Google
Language: Cpp
Standard: Cpp11
# Disable ColumnLimit because it causes some very weird line breaks.
# For ObjC the limit is 100
# For Cpp the limit is 80
ColumnLimit: 0
# Allow short case statements to be on a single line
AllowShortCaseLabelsOnASingleLine: true
# Ban short loops and functions on a single line
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
# Allow spaces in NSArray/NSDictionary literals @[ and @{
SpacesInContainerLiterals: true
# For pointers, always put the * next to the variable name.
DerivePointerAlignment: false
PointerAlignment: Right

6
.gitignore vendored
View File

@@ -1,8 +1,12 @@
.DS_Store
Build
Dist
santa-*
!santa-driver
!*.md
Pods
Santa.xcodeproj/xcuserdata
Santa.xcodeproj/project.xcworkspace
Santa.xcworkspace/xcuserdata
Santa.xcworkspace/xcshareddata
Source/DevelopmentTeam.xcconfig
default.profraw

14
.travis.yml Normal file
View File

@@ -0,0 +1,14 @@
---
language: objective-c
cache:
- bundler
- cocoapods
sudo: false
osx_image: xcode9.3
before_install:
- gem install cocoapods xcpretty
- pod setup >/dev/null
script:
- xcodebuild -workspace Santa.xcworkspace -scheme All -derivedDataPath build build test CODE_SIGN_IDENTITY='' | xcpretty -sc && exit ${PIPESTATUS[0]}

133
CMakeLists.txt Normal file
View File

@@ -0,0 +1,133 @@
cmake_minimum_required(VERSION 3.10.0)
execute_process(
COMMAND git fetch --tags --all
COMMAND git describe --tags --always --abbrev=0
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE SANTA_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND xcode-select -p
OUTPUT_VARIABLE DEFAULT_XCODE_ROOT_FOLDER
)
string(STRIP "${DEFAULT_XCODE_ROOT_FOLDER}" DEFAULT_XCODE_ROOT_FOLDER)
add_custom_target(tests)
function(AddTestTarget target_name run_as_root)
if(run_as_root)
add_custom_target(
"${target_name}_runner"
COMMAND sudo $<TARGET_FILE:${target_name}>
COMMENT "Running ${target_name}_runner as root"
)
else()
add_custom_target(
"${target_name}_runner"
COMMAND $<TARGET_FILE:${target_name}>
)
endif()
add_dependencies(tests "${target_name}_runner")
endfunction()
add_custom_target(fuzz)
function(AddFuzzTarget target_name max_len max_total_time run_as_root)
add_custom_command(TARGET "${target_name}" POST_BUILD
COMMAND codesign --force --verify --verbose --sign "${CODESIGN_IDENTITY}" $<TARGET_FILE:${target_name}>
COMMENT "Signing ${target_name} with the following identity: ${CODESIGN_IDENTITY}"
)
if(${run_as_root})
set(sudo_command "sudo")
else()
set(sudo_command "")
endif()
add_custom_target(
"${target_name}_runner"
COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/${target_name}_corpus"
COMMAND ${sudo_command} $<TARGET_FILE:${target_name}> -max_len=${max_len} -max_total_time=${max_total_time} "${CMAKE_CURRENT_BINARY_DIR}/${target_name}_corpus" "${CMAKE_CURRENT_SOURCE_DIR}/${target_name}_seed_corpus"
COMMENT "Running fuzzer: ${target_name}"
)
add_dependencies("${target_name}_runner" "${target_name}")
add_dependencies(fuzz "${target_name}_runner")
endfunction()
function(main)
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif()
if(NOT DEFINED CODESIGN_IDENTITY)
if ("$ENV{CODESIGN_IDENTITY}" STREQUAL "")
message(FATAL_ERROR "Please define CODESIGN_IDENTITY - You can either use an environment variable or pass it to CMake with -DCODESIGN_IDENTITY=identity. If you are using sudo, make sure to keep the variable defined")
endif()
set(CODESIGN_IDENTITY "$ENV{CODESIGN_IDENTITY}")
endif()
if(NOT MACOSX_VERSION_MIN)
set(MACOSX_VERSION_MIN 10.9)
endif()
if(NOT MACOSX_SDK_VERSION)
set(sdk_version_name "Latest")
else()
set(sdk_version_name "${MACOSX_SDK_VERSION}")
endif()
if(NOT XCODE_ROOT_FOLDER)
set(XCODE_ROOT_FOLDER "${DEFAULT_XCODE_ROOT_FOLDER}")
endif()
message(STATUS "MACOSX_VERSION_MIN: ${MACOSX_VERSION_MIN}")
message(STATUS "MACOSX_SDK_VERSION: ${sdk_version_name}")
message(STATUS "XCODE_ROOT_FOLDER: ${XCODE_ROOT_FOLDER}")
message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
message(STATUS "SANTA_VERSION: ${SANTA_VERSION}")
add_subdirectory(CocoaPods)
add_subdirectory(Source/santad)
add_subdirectory(Source/santactl)
add_subdirectory(Source/santabs)
add_subdirectory(Source/SantaGUI)
add_subdirectory(Source/santa-driver)
add_subdirectory(Fuzzing)
add_subdirectory(Tests)
set(redist_folder_path "${CMAKE_BINARY_DIR}/redist")
add_custom_command(
OUTPUT "${redist_folder_path}/conf/install.sh"
# Copy the binaries
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_BINARY_DIR}/Source/SantaGUI/Santa.app" "${redist_folder_path}/binaries/Santa.app"
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_BINARY_DIR}/Source/santa-driver/santa-driver.kext" "${redist_folder_path}/binaries/santa-driver.kext"
# Copy the configuration files
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_SOURCE_DIR}/Conf" "${redist_folder_path}/conf"
COMMAND "${CMAKE_COMMAND}" -E remove_directory "${redist_folder_path}/conf/Package"
COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/Docs/deployment/com.google.santa.example.mobileconfig" "${redist_folder_path}/conf"
COMMENT "Generating redistributable package"
)
add_custom_target(redist DEPENDS "${redist_folder_path}/conf/install.sh")
add_dependencies(redist santad santa-driver santactl santabs Santa)
install(FILES Conf/com.google.santad.plist DESTINATION /Library/LaunchDaemons)
install(FILES Conf/com.google.santagui.plist DESTINATION /Library/LaunchAgents)
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E echo To finalize the installation, run the following commands)")
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E echo sudo /sbin/kextload /Library/Extensions/santa-driver.kext)")
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E echo sudo /bin/launchctl load /Library/LaunchDaemons/com.google.santad.plist)")
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E echo sudo /bin/launchctl asuser `/usr/bin/stat -f '%u' /dev/console` /bin/launchctl load /Library/LaunchAgents/com.google.santagui.plist)")
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E echo Configuration guide available on ReadTheDocs - https://santa.readthedocs.io/en/latest/deployment/configuration/)")
endfunction()
main()

View File

@@ -25,6 +25,12 @@ tests beforehand, which you can do with the following commands:
rake tests:logic
rake tests:kernel # only necessary if you're changing the kext code
```
### Code Style
All code submissions should try to match the surrounding code. Wherever possible,
code should adhere to either the
[Google Objective-C Style Guide](https://google.github.io/styleguide/objcguide.xml)
or the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html).
### The small print
Contributions made by corporations are covered by a different agreement than

195
CocoaPods/CMakeLists.txt Normal file
View File

@@ -0,0 +1,195 @@
cmake_minimum_required(VERSION 3.10.0)
project(CocoaPods)
function(main)
add_custom_command(
OUTPUT "${CMAKE_SOURCE_DIR}/Pods/Manifest.lock"
COMMAND pod repo update && pod install
DEPENDS "${CMAKE_SOURCE_DIR}/Podfile"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
COMMENT "Fetching CocoaPods dependencies"
VERBATIM
)
add_custom_target("${PROJECT_NAME}"
DEPENDS "${CMAKE_SOURCE_DIR}/Pods/Manifest.lock"
)
ImportCocoaPodsLibrary(
FMDB
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabase.h"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMResultSet.h"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabasePool.h"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabaseQueue.h"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDB.h"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabaseAdditions.h"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabaseQueue.m"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabaseAdditions.m"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabase.m"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabasePool.m"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMResultSet.m"
)
target_link_libraries(FMDB PUBLIC sqlite3 "-framework Cocoa")
ImportCocoaPodsLibrary(
MOLCertificate
"${CMAKE_SOURCE_DIR}/Pods/MOLCertificate/Source/MOLCertificate"
"${CMAKE_SOURCE_DIR}/Pods/MOLCertificate/Source/MOLCertificate/MOLCertificate.m"
"${CMAKE_SOURCE_DIR}/Pods/MOLCertificate/Source/MOLCertificate/MOLCertificate.h"
)
target_link_libraries(MOLCertificate PUBLIC "-framework Security" "-framework Cocoa")
ImportCocoaPodsLibrary(
MOLCodesignChecker
"${CMAKE_SOURCE_DIR}/Pods/MOLCodesignChecker/Source/MOLCodesignChecker"
"${CMAKE_SOURCE_DIR}/Pods/MOLCodesignChecker/Source/MOLCodesignChecker/MOLCodesignChecker.h"
"${CMAKE_SOURCE_DIR}/Pods/MOLCodesignChecker/Source/MOLCodesignChecker/MOLCodesignChecker.m"
)
target_link_libraries(MOLCodesignChecker PUBLIC "-framework Security" "-framework Cocoa")
ImportCocoaPodsLibrary(
MOLAuthenticatingURLSession
"${CMAKE_SOURCE_DIR}/Pods/MOLAuthenticatingURLSession/Source/MOLAuthenticatingURLSession"
"${CMAKE_SOURCE_DIR}/Pods/MOLAuthenticatingURLSession/Source/MOLAuthenticatingURLSession/MOLAuthenticatingURLSession.m"
"${CMAKE_SOURCE_DIR}/Pods/MOLAuthenticatingURLSession/Source/MOLAuthenticatingURLSession/MOLDERDecoder.m"
"${CMAKE_SOURCE_DIR}/Pods/MOLAuthenticatingURLSession/Source/MOLAuthenticatingURLSession/MOLDERDecoder.h"
"${CMAKE_SOURCE_DIR}/Pods/MOLAuthenticatingURLSession/Source/MOLAuthenticatingURLSession/MOLAuthenticatingURLSession.h"
)
target_link_libraries(MOLAuthenticatingURLSession PUBLIC "-framework Security" MOLCertificate "-framework Cocoa")
ImportCocoaPodsLibrary(
MOLFCMClient
"${CMAKE_SOURCE_DIR}/Pods/MOLFCMClient/MOLFCMClient"
"${CMAKE_SOURCE_DIR}/Pods/MOLFCMClient/Source/MOLFCMClient/MOLFCMClient.m"
"${CMAKE_SOURCE_DIR}/Pods/MOLFCMClient/Source/MOLFCMClient/MOLFCMClient.h"
)
target_link_libraries(MOLFCMClient PUBLIC MOLCertificate MOLAuthenticatingURLSession "-framework Cocoa")
target_compile_options(MOLFCMClient PRIVATE -fobjc-weak)
ImportCocoaPodsLibrary(
MOLXPCConnection
"${CMAKE_SOURCE_DIR}/Pods/MOLXPCConnection/Source/MOLXPCConnection"
"${CMAKE_SOURCE_DIR}/Pods/MOLXPCConnection/Source/MOLXPCConnection/MOLXPCConnection.h"
"${CMAKE_SOURCE_DIR}/Pods/MOLXPCConnection/Source/MOLXPCConnection/MOLXPCConnection.m"
)
target_link_libraries(MOLXPCConnection PUBLIC "-framework Cocoa")
ImportCocoaPodsLibrary(
OCMock
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMExceptionReturnValueProvider.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMBlockCaller.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMExpectationRecorder.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMockObject.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMArgAction.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMMacroState.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMRealObjectForwarder.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMInvocationStub.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCPartialMockObject.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMock.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMStubRecorder.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMRecorder.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMInvocationExpectation.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMFunctions.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMIndirectReturnValueProvider.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCProtocolMockObject.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMBlockArgCaller.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMReturnValueProvider.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMBoxedReturnValueProvider.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCClassMockObject.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSObject+OCMAdditions.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMInvocationMatcher.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMPassByRefSetter.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMArg.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMObserverRecorder.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMNotificationPoster.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMVerifier.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMConstraint.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMLocation.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSInvocation+OCMAdditions.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSValue+OCMAdditions.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCObserverMockObject.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMRealObjectForwarder.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMMacroState.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMArgAction.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMockObject.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMExpectationRecorder.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMBlockCaller.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMExceptionReturnValueProvider.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMIndirectReturnValueProvider.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMFunctions.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMStubRecorder.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMRecorder.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMInvocationExpectation.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCPartialMockObject.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMInvocationStub.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMPassByRefSetter.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMInvocationMatcher.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSObject+OCMAdditions.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCClassMockObject.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMBoxedReturnValueProvider.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMBlockArgCaller.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMReturnValueProvider.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCProtocolMockObject.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMFunctionsPrivate.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSInvocation+OCMAdditions.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCObserverMockObject.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSValue+OCMAdditions.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMLocation.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMConstraint.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMVerifier.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMNotificationPoster.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMObserverRecorder.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMArg.h"
)
target_link_libraries(OCMock PUBLIC "-framework Cocoa")
target_compile_options(OCMock PRIVATE -fno-objc-arc)
endfunction()
function(ImportCocoaPodsLibrary library_name source_directory)
set_source_files_properties(${ARGN} PROPERTIES GENERATED True)
add_library("${library_name}" STATIC ${ARGN})
add_dependencies("${library_name}" "${PROJECT_NAME}")
target_include_directories("${library_name}" PUBLIC
"${source_directory}"
"${CMAKE_SOURCE_DIR}/Pods/Headers/Public"
)
target_compile_options("${library_name}" PUBLIC
-Wno-deprecated -fmodules -fcxx-modules -fobjc-arc
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options("${library_name}" PRIVATE -g3)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options("${library_name}" PRIVATE -O0)
else()
target_compile_options("${library_name}" PRIVATE -O3)
endif()
endfunction()
main()

95
Conf/Package/Makefile Normal file
View File

@@ -0,0 +1,95 @@
#
# Package Makefile for Santa
# Requires TheLuggage (github.com/unixorn/luggage) to be installed
#
# Will generate a package based on the latest release. You can replace
# the PACKAGE_VERSION variable with a specific variable instead if you wish.
#
LUGGAGE:=/usr/local/share/luggage/luggage.make
include ${LUGGAGE}
TITLE:=santa
REVERSE_DOMAIN:=com.google
# Get latest Release version using the GitHub API. Each release is bound to a
# git tag, which should always be a semantic version number. The most recent
# release is always first in the API result.
PACKAGE_VERSION:=$(shell curl -fs https://api.github.com/repos/google/santa/releases |\
python -c 'import json, sys; print json.load(sys.stdin)[0]["tag_name"]' 2>/dev/null)
# Get the download URL for the latest Release. Each release should have a
# tarball named santa-$version.tar.bz2 containing all of the files associated
# with that release. The tarball layout is:
#
# santa-$version.tar.bz2
# +--santa-$version
# |-- binaries
# | |-- santa-driver.kext
# | |-- Santa.app
# |-- conf
# | |-- install.sh
# | |-- com.google.santad.plist
# | |-- com.google.santagui.plist
# | +-- com.google.santa.asl.conf
# | +-- com.google.santa.newsyslog.conf
# +--dsym
# |-- santa-driver.kext.dSYM
# |-- Santa.app.dSYM
# |-- santad.dSYM
# +-- santactl.dSYM
PACKAGE_DOWNLOAD_URL:="https://github.com/google/santa/releases/download/${PACKAGE_VERSION}/santa-${PACKAGE_VERSION}.tar.bz2"
PAYLOAD:=pack-Library-Extensions-santa-driver.kext \
pack-applications-Santa.app \
pack-Library-LaunchDaemons-com.google.santad.plist \
pack-Library-LaunchAgents-com.google.santagui.plist \
pack-etc-asl-com.google.santa.asl.conf \
pack-etc-newsyslog.d-com.google.santa.newsyslog.conf \
pack-script-preinstall \
pack-script-postinstall
santa-driver.kext: download
Santa.app: download
com.google.santad.plist: download
com.google.santagui.plist: download
com.google.santa.asl.conf: download
com.google.santa.newsyslog.conf: download
download:
$(if $(PACKAGE_VERSION),, $(error GitHub API returned unexpected result. Wait a while and try again))
@curl -fL ${PACKAGE_DOWNLOAD_URL} | tar xvj --strip=2
@rm -rf *.dSYM
pack-etc-asl-com.google.santa.asl.conf: com.google.santa.asl.conf l_private_etc
@sudo mkdir -p ${WORK_D}/private/etc/asl
@sudo chown root:wheel ${WORK_D}/private/etc/asl
@sudo chmod 755 ${WORK_D}/private/etc/asl
@sudo install -m 644 -o root -g wheel com.google.santa.asl.conf ${WORK_D}/private/etc/asl
pack-etc-newsyslog.d-com.google.santa.newsyslog.conf: com.google.santa.newsyslog.conf l_private_etc
@sudo mkdir -p ${WORK_D}/private/etc/newsyslog.d
@sudo chown root:wheel ${WORK_D}/private/etc/newsyslog.d
@sudo chmod 755 ${WORK_D}/private/etc/newsyslog.d
@sudo install -m 644 -o root -g wheel com.google.santa.newsyslog.conf ${WORK_D}/private/etc/newsyslog.d
pack-Library-Extensions-santa-driver.kext: santa-driver.kext l_Library
@sudo mkdir -p ${WORK_D}/Library/Extensions
@sudo ${DITTO} --noqtn santa-driver.kext ${WORK_D}/Library/Extensions/santa-driver.kext
@sudo chown -R root:wheel ${WORK_D}/Library/Extensions/santa-driver.kext
@sudo chmod -R 755 ${WORK_D}/Library/Extensions/santa-driver.kext
clean: myclean
myclean:
@rm -rf *.dSYM
@rm -rf Santa.app
@rm -rf santa-driver.kext
@rm -f config.plist
@rm -f com.google.santa.asl.conf
@rm -f com.google.santa.newsyslog.conf
@rm -f com.google.santad.plist
@rm -f com.google.santagui.plist
@rm -f install.sh
@rm -f uninstall.sh

28
Conf/Package/postinstall Normal file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
# Load the kernel extension, santad, sync client
# If a user is logged in, also load the GUI agent.
# If the target volume is not /, do nothing
[[ $3 != "/" ]] && exit 0
# Restart syslogd to pick up ASL configuration change
/usr/bin/killall -HUP syslogd
/sbin/kextload /Library/Extensions/santa-driver.kext
sleep 1
/bin/launchctl load -w /Library/LaunchDaemons/com.google.santad.plist
sleep 1
# Create hopefully useful symlink for santactl
mkdir -p /usr/local/bin
/bin/ln -sf /Library/Extensions/santa-driver.kext/Contents/MacOS/santactl /usr/local/bin/santactl
user=$(/usr/bin/stat -f '%u' /dev/console)
[[ -z "$user" ]] && exit 0
/bin/launchctl asuser ${user} /bin/launchctl load /Library/LaunchAgents/com.google.santagui.plist
exit 0

26
Conf/Package/preinstall Normal file
View File

@@ -0,0 +1,26 @@
#!/bin/bash
# Unload the kernel extension, santad, sync client
# If a user is logged in, also unload the GUI agent.
# If the target volume is not /, do nothing
[[ $3 != "/" ]] && exit 0
/bin/launchctl remove com.google.santad
sleep 1
/sbin/kextunload -b com.google.santa-driver >/dev/null 2>&1
# Remove cruft from old Santa versions
/bin/rm /usr/libexec/santad
/bin/rm /usr/sbin/santactl
/bin/launchctl remove com.google.santasync
/bin/rm /Library/LaunchDaemons/com.google.santasync.plist
sleep 1
user=$(/usr/bin/stat -f '%u' /dev/console)
[[ -n "$user" ]] && /bin/launchctl asuser ${user} /bin/launchctl remove com.google.santagui
exit 0

View File

@@ -1,4 +1,6 @@
# Copy this file to /etc/asl to log all messages from santa-driver to the log file
? [S= Message santa-driver:] claim only
? [S= Message santa-driver:] file /var/log/santa.log format="[$((Time)(utc.3))] $Message"
> /var/log/santa.log mode=0644 rotate=seq compress file_max=5M all_max=100M
> /var/db/santa/santa.log format="[$((Time)(ISO8601Z.3))] $Message" mode=0644 rotate=seq compress file_max=25M all_max=100M uid=0 gid=0
? [= Sender kernel] [S= Message santa-driver:] claim
? [= Sender kernel] [S= Message santa-driver:] file /var/db/santa/santa.log
? [= Facility com.google.santa] claim
? [= Facility com.google.santa] file /var/db/santa/santa.log

View File

@@ -0,0 +1,2 @@
# logfilename [owner:group] mode count size(KiB) when flags [/pid_file] # [sig_num]
/var/db/santa/santa.log root:wheel 644 10 25000 * NZ

View File

@@ -6,19 +6,14 @@
<string>com.google.santad</string>
<key>ProgramArguments</key>
<array>
<string>/usr/libexec/santad</string>
<string>/Library/Extensions/santa-driver.kext/Contents/MacOS/santad</string>
<string>--syslog</string>
</array>
<key>MachServices</key>
<dict>
<key>SantaXPCNotifications</key>
<true/>
<key>SantaXPCControl</key>
<true/>
<key>SantaXPCControl</key>
<true/>
</dict>
<key>StandardOutPath</key>
<string>/var/log/santa.log</string>
<key>StandardErrorPath</key>
<string>/var/log/santa.log</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>

View File

@@ -7,8 +7,11 @@
<key>ProgramArguments</key>
<array>
<string>/Applications/Santa.app/Contents/MacOS/Santa</string>
<string>--syslog</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.google.santasync</string>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/santactl</string>
<string>sync</string>
</array>
<key>StandardErrorPath</key>
<string>/var/log/santa.log</string>
<key>ProcessType</key>
<string>Background</string>
<key>StartInterval</key>
<integer>600</integer>
</dict>
</plist>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- Minimal Configuration -->
<key>ClientMode</key>
<integer>1</integer>
<!-- For documentation of other keys, see the following URL:
https://github.com/google/santa/wiki/Configuration-Keys -->
</dict>
</plist>

66
Conf/install.sh Executable file
View File

@@ -0,0 +1,66 @@
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
if [[ -d "binaries" ]]; then
SOURCE="."
elif [[ -d "../binaries" ]]; then
SOURCE=".."
else
echo "Can't find binaries, run install.sh from inside the conf directory" 1>&2
exit 1
fi
# Determine if anyone is logged into the GUI
GUI_USER=$(/usr/bin/stat -f '%u' /dev/console)
# Unload santad and scheduled sync job.
/bin/launchctl remove com.google.santad >/dev/null 2>&1
# Unload kext.
/sbin/kextunload -b com.google.santa-driver >/dev/null 2>&1
# Unload GUI agent if someone is logged in.
[[ -n "$GUI_USER" ]] && \
/bin/launchctl asuser ${GUI_USER} /bin/launchctl remove /Library/LaunchAgents/com.google.santagui.plist
# Cleanup cruft from old versions
/bin/launchctl remove com.google.santasync >/dev/null 2>&1
/bin/rm /Library/LaunchDaemons/com.google.santasync.plist >/dev/null 2>&1
/bin/rm /usr/libexec/santad >/dev/null 2>&1
/bin/rm /usr/sbin/santactl >/dev/null 2>&1
# Copy new files.
/bin/cp -r ${SOURCE}/binaries/santa-driver.kext /Library/Extensions
/bin/cp -r ${SOURCE}/binaries/Santa.app /Applications
mkdir -p /usr/local/bin
/bin/ln -s /Library/Extensions/santa-driver.kext/Contents/MacOS/santactl /usr/local/bin
if [ ! -d /var/db/santa ] ; then
mkdir /var/db/santa
fi
cp ${SOURCE}/conf/com.google.santa.example.mobileconfig /var/db/santa
/bin/cp ${SOURCE}/conf/com.google.santad.plist /Library/LaunchDaemons
/bin/cp ${SOURCE}/conf/com.google.santagui.plist /Library/LaunchAgents
/bin/cp ${SOURCE}/conf/com.google.santa.asl.conf /etc/asl/
/bin/cp ${SOURCE}/conf/com.google.santa.newsyslog.conf /etc/newsyslog.d/
# Reload syslogd to pick up ASL configuration change.
/usr/bin/killall -HUP syslogd
# Load kext.
/sbin/kextload /Library/Extensions/santa-driver.kext
# Load santad and scheduled sync jobs.
/bin/launchctl load /Library/LaunchDaemons/com.google.santad.plist
# Load GUI agent if someone is logged in.
[[ -n "$GUI_USER" ]] && \
/bin/launchctl asuser ${GUI_USER} /bin/launchctl load /Library/LaunchAgents/com.google.santagui.plist
exit 0

37
Conf/uninstall.sh Executable file
View File

@@ -0,0 +1,37 @@
#!/bin/bash
# Uninstalls Santa from the boot volume, clearing up everything but logs/configs.
# Unloads the kernel extension, services, and deletes component files.
# If a user is logged in, also unloads the GUI agent.
[ "$EUID" != 0 ] && printf "%s\n" "This requires running as root/sudo." && exit 1
if [[ -d "binaries" ]]; then
SOURCE="."
elif [[ -d "../binaries" ]]; then
SOURCE=".."
else
echo "Can't find binaries, run install.sh from inside the conf directory" 1>&2
exit 1
fi
/bin/launchctl remove com.google.santad
sleep 1
/sbin/kextunload -b com.google.santa-driver >/dev/null 2>&1
user=$(/usr/bin/stat -f '%u' /dev/console)
[[ -n "$user" ]] && /bin/launchctl asuser ${user} /bin/launchctl remove com.google.santagui
# and to clean out the log config, although it won't write after wiping the binary
/usr/bin/killall -HUP syslogd
# delete artifacts on-disk
/bin/rm -rf /Applications/Santa.app
/bin/rm -rf /Library/Extensions/santa-driver.kext
/bin/rm -f /Library/LaunchAgents/com.google.santagui.plist
/bin/rm -f /Library/LaunchDaemons/com.google.santad.plist
/bin/rm -f /private/etc/asl/com.google.santa.asl.conf
/bin/rm -f /private/etc/newsyslog.d/com.google.santa.newsyslog.conf
/bin/rm -f /usr/local/bin/santactl # just a symlink
#uncomment to remove the config file and all databases, log files
#/bin/rm -rf /var/db/santa
#/bin/rm -f /var/log/santa*
exit 0

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadContent</key>
<dict>
<key>com.google.santa</key>
<dict>
<key>Forced</key>
<array>
<dict>
<key>mcx_preference_settings</key>
<dict>
<key>BannedBlockMessage</key>
<string>This application has been banned</string>
<key>ClientMode</key>
<integer>1</integer>
<key>EnablePageZeroProtection</key>
<false/>
<key>EventDetailText</key>
<string>Open sync server</string>
<key>EventDetailURL</key>
<string>https://sync-server-hostname/blockables/%file_sha%</string>
<key>FileChangesRegex</key>
<string>^/(?!(?:private/tmp|Library/(?:Caches|Managed Installs/Logs|(?:Managed )?Preferences))/)</string>
<key>MachineIDKey</key>
<string>MachineUUID</string>
<key>MachineIDPlist</key>
<string>/Library/Preferences/com.company.machine-mapping.plist</string>
<key>MachineOwnerKey</key>
<string>Owner</string>
<key>MachineOwnerPlist</key>
<string>/Library/Preferences/com.company.machine-mapping.plist</string>
<key>ModeNotificationLockdown</key>
<string>Entering Lockdown mode</string>
<key>ModeNotificationMonitor</key>
<string>Entering Monitor mode&lt;br/&gt;Please be careful!</string>
<key>MoreInfoURL</key>
<string>https://sync-server-hostname/moreinfo</string>
<key>SyncBaseURL</key>
<string>https://sync-server-hostname/api/santa/</string>
<key>UnknownBlockMessage</key>
<string>This application has been blocked from executing.</string>
</dict>
</dict>
</array>
</dict>
</dict>
<key>PayloadEnabled</key>
<true/>
<key>PayloadIdentifier</key>
<string>0342c558-a101-4a08-a0b9-40cc00039ea5</string>
<key>PayloadType</key>
<string>com.apple.ManagedClient.preferences</string>
<key>PayloadUUID</key>
<string>0342c558-a101-4a08-a0b9-40cc00039ea5</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDescription</key>
<string>com.google.santa</string>
<key>PayloadDisplayName</key>
<string>com.google.santa</string>
<key>PayloadIdentifier</key>
<string>com.google.santa</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadRemovalDisallowed</key>
<true/>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>9020fb2d-cab3-420f-9268-acca4868bdd0</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

View File

@@ -0,0 +1,179 @@
# Important
Santa v0.9.21 has moved to using an Apple [Configuration Profile](https://developer.apple.com/library/content/featuredarticles/iPhoneConfigurationProfileRef/Introduction/Introduction.html) to manage the local configuration. The old config file (`/var/db/santa/config.plist`) is no longer used.
# Configuration
Two configuration methods can be used to control Santa: a local configuration profile and a sync server controlled configuration. There are certain options that can only be controlled with a local configuration profile and others that can only be controlled with a sync server controlled configuration. Additionally, there are options that can be controlled by both.
## Local Configuration Profile
| Key | Value Type | Description |
| ----------------------------- | ---------- | ---------------------------------------- |
| ClientMode* | Integer | 1 = MONITOR, 2 = LOCKDOWN, defaults to MONITOR |
| FileChangesRegex* | String | The regex of paths to log file changes. Regexes are specified in ICU format. |
| WhitelistRegex* | String | A regex to whitelist if the binary or certificate scopes did not allow execution. Regexes are specified in ICU format. |
| BlacklistRegex* | String | A regex to blacklist if the binary or certificate scopes did not block an execution. Regexes are specified in ICU format. |
| EnablePageZeroProtection | Bool | Enable `__PAGEZERO` protection, defaults to YES. If this flag is set to YES, 32-bit binaries that are missing the `__PAGEZERO` segment will be blocked even in MONITOR mode, **unless** the binary is whitelisted by an explicit rule. |
| MoreInfoURL | String | The URL to open when the user clicks "More Info..." when opening Santa.app. If unset, the button will not be displayed. |
| EventDetailURL | String | See the [EventDetailURL](#eventdetailurl) section below. |
| EventDetailText | String | Related to the above property, this string represents the text to show on the button. |
| UnknownBlockMessage | String | In Lockdown mode this is the message shown to the user when an unknown binary is blocked. If this message is not configured a reasonable default is provided. |
| BannedBlockMessage | String | This is the message shown to the user when a binary is blocked because of a rule if that rule doesn't provide a custom message. If this is not configured a reasonable default is provided. |
| ModeNotificationMonitor | String | The notification text to display when the client goes into Monitor mode. Defaults to "Switching into Monitor mode". |
| ModeNotificationLockdown | String | The notification text to display when the client goes into Lockdown mode. Defaults to "Switching into Lockdown mode". |
| SyncBaseURL* | String | The base URL of the sync server. |
| ClientAuthCertificateFile | String | If set, this contains the location of a PKCS#12 certificate to be used for sync authentication. |
| ClientAuthCertificatePassword | String | Contains the password for the PKCS#12 certificate. |
| ClientAuthCertificateCN | String | If set, this is the Common Name of a certificate in the System keychain to be used for sync authentication. The corresponding private key must also be in the keychain. |
| ClientAuthCertificateIssuerCN | String | If set, this is the Issuer Name of a certificate in the System keychain to be used for sync authentication. The corresponding private key must also be in the keychain. |
| ServerAuthRootsData | Data | If set, this is valid PEM containing one or more certificates to be used to evaluate the server's SSL chain, overriding the list of trusted CAs distributed with the OS. |
| ServerAuthRootsFile | String | The same as the above but is a path to a file on disk containing the PEM data. |
| MachineOwner | String | The machine owner. |
| MachineID | String | The machine ID. |
| MachineOwnerPlist | String | The path to a plist that contains the MachineOwnerKey / value pair. |
| 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
##### EventDetailURL
When the user gets a block notification, a button can be displayed which will take them to a web page with more information about that event.
This property contains a kind of format string to be turned into the URL to send them to. The following sequences will be replaced in the final URL:
| Key | Description |
| ------------ | ---------------------------------------- |
| %file_sha% | SHA-256 of the file that was blocked |
| %machine_id% | ID of the machine |
| %username% | The executing user |
| %bundle_id% | Bundle ID of the binary, if applicable |
| %bundle_ver% | Bundle version of the binary, if applicable |
For example: `https://sync-server-hostname/%machine_id%/%file_sha%`
##### Example Configuration Profile
Here is an example of a configuration profile that could be set. It was generated with Tim Sutton's great [mcxToProfile](https://github.com/timsutton/mcxToProfile) tool. A copy is also available [here](com.google.santa.example.mobileconfig).
A few key points to when creating your configuration profile:
* `com.google.santa` needs to be the key inside `PayloadContent`
* The `PayloadScope` needs to be `System`
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadContent</key>
<dict>
<key>com.google.santa</key>
<dict>
<key>Forced</key>
<array>
<dict>
<key>mcx_preference_settings</key>
<dict>
<key>BannedBlockMessage</key>
<string>This application has been banned</string>
<key>ClientMode</key>
<integer>1</integer>
<key>EnablePageZeroProtection</key>
<false/>
<key>EventDetailText</key>
<string>Open sync server</string>
<key>EventDetailURL</key>
<string>https://sync-server-hostname/blockables/%file_sha%</string>
<key>FileChangesRegex</key>
<string>^/(?!(?:private/tmp|Library/(?:Caches|Managed Installs/Logs|(?:Managed )?Preferences))/)</string>
<key>MachineIDKey</key>
<string>MachineUUID</string>
<key>MachineIDPlist</key>
<string>/Library/Preferences/com.company.machine-mapping.plist</string>
<key>MachineOwnerKey</key>
<string>Owner</string>
<key>MachineOwnerPlist</key>
<string>/Library/Preferences/com.company.machine-mapping.plist</string>
<key>ModeNotificationLockdown</key>
<string>Entering Lockdown mode</string>
<key>ModeNotificationMonitor</key>
<string>Entering Monitor mode&lt;br/&gt;Please be careful!</string>
<key>MoreInfoURL</key>
<string>https://sync-server-hostname/moreinfo</string>
<key>SyncBaseURL</key>
<string>https://sync-server-hostname/api/santa/</string>
<key>UnknownBlockMessage</key>
<string>This application has been blocked from executing.</string>
</dict>
</dict>
</array>
</dict>
</dict>
<key>PayloadEnabled</key>
<true/>
<key>PayloadIdentifier</key>
<string>0342c558-a101-4a08-a0b9-40cc00039ea5</string>
<key>PayloadType</key>
<string>com.apple.ManagedClient.preferences</string>
<key>PayloadUUID</key>
<string>0342c558-a101-4a08-a0b9-40cc00039ea5</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDescription</key>
<string>com.google.santa</string>
<key>PayloadDisplayName</key>
<string>com.google.santa</string>
<key>PayloadIdentifier</key>
<string>com.google.santa</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadRemovalDisallowed</key>
<true/>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>9020fb2d-cab3-420f-9268-acca4868bdd0</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
```
Configuration profiles have a `.mobileconfig` file extension. There are many ways to install configuration profiles:
* Double click them in Finder
* Use the `/usr/bin/profiles` tool
* Use an MDM
## Sync server Provided Configuration
| Key | Value Type | Description |
| ------------------------------ | ---------- | ---------------------------------------- |
| client_mode | String | MONITOR or LOCKDOWN, defaults to MONITOR. |
| clean_sync** | Bool | If set to `True` Santa will clear all local rules and download a fresh copy from the sync-server. Defaults to `False`. |
| batch_size | Integer | The number of rules to download or events to upload per request. Multiple requests will be made if there is more work than can fit in single request. Defaults to 50. |
| upload_logs_url** | String | If set, the endpoint to send Santa's current logs. No default. |
| whitelist_regex | String | Same as the "Local Configuration" WhitelistRegex. No default. |
| blacklist_regex | String | Same as the "Local Configuration" BlacklistRegex. No default. |
| fcm_token* | String | The FCM token used by Santa to listen for FCM messages. Unique for every machine. No default. |
| fcm_full_sync_interval* | Integer | The full sync interval if a fcm_token is set. Defaults to 14400 secs (4 hours). |
| fcm_global_rule_sync_deadline* | Integer | The max time to wait before performing a rule sync when a global rule sync FCM message is received. This allows syncing to be staggered for global events to avoid spikes in server load. Defaults to 600 secs (10 min). |
| bundles_enabled* | Bool | If set to `True` the bundle scanning feature is enabled. Defaults to `False`. |
*Held only in memory. Not persistent upon process restart.
**Performed once per preflight run (if set).

BIN
Docs/details/block.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

141
Docs/details/events.md Normal file
View File

@@ -0,0 +1,141 @@
# Events
Events are a defined set of data, core to how Santa interacts with a sync server. Events are generated when there is a blocked `execve()` while in Lockdown or Monitor mode. Events are also generated in Monitor mode for an `execve()` that was allowed to run, but would have been blocked in Lockdown mode. This allows an admin to roll out Santa to their macOS fleet in Monitor mode but still collect meaningful data. The events collected while in Monitor mode can be used to build a reasonably comprehensive whitelist of signing certificates and binaries before switching the fleet to Lockdown mode.
##### Event Data
Events begin their life as an [SNTStoredEvent](https://github.com/google/santa/blob/master/Source/common/SNTStoredEvent.h) object. The SNTStoredEvent class is just a simple storage class that has properties for all the relevant bits of information. More importantly the class implements the [NSSecureCoding](https://developer.apple.com/documentation/foundation/nssecurecoding?language=objc) protocol. This allows the objects to be encoded and decoded for storage in the events sqlite3 database on disk and sent over XPC to another process.
Events are temporarily stored in a database until they are uploaded. The format is subject the change; accessing the events database directly will most likely break in future releases. If direct access to the events database is required, raise a [issue on the Santa GitHub](https://github.com/google/santa/issues).
###### JSON
Before an event is uploaded to a sync server, the event data is copied into a JSON blob. Here is an example of Firefox being blocked and sent for upload:
```json
{
"events": [
{
"file_path": "/var/folders/l5/pd9rhsp54s79_9_qcy746_tw00b_4p/T/AppTranslocation/254C1357-7461-457B-B734-A0FDAF0F26D9/d/Firefox.app/Contents/MacOS",
"file_bundle_version": "5417.6.28",
"parent_name": "launchd",
"logged_in_users": [
"bur"
],
"quarantine_timestamp": 0,
"signing_chain": [
{
"cn": "Developer ID Application: Mozilla Corporation (43AQ936H96)",
"valid_until": 1652123338,
"org": "Mozilla Corporation",
"valid_from": 1494270538,
"ou": "43AQ936H96",
"sha256": "96f18e09d65445985c7df5df74ef152a0bc42e8934175a626180d9700c343e7b"
},
{
"cn": "Developer ID Certification Authority",
"valid_until": 1801519935,
"org": "Apple Inc.",
"valid_from": 1328134335,
"ou": "Apple Certification Authority",
"sha256": "7afc9d01a62f03a2de9637936d4afe68090d2de18d03f29c88cfb0b1ba63587f"
},
{
"cn": "Apple Root CA",
"valid_until": 2054670036,
"org": "Apple Inc.",
"valid_from": 1146001236,
"ou": "Apple Certification Authority",
"sha256": "b0b1730ecbc7ff4505142c49f1295e6eda6bcaed7e2c68c5be91b5a11001f024"
}
],
"file_bundle_name": "Firefox",
"executing_user": "bur",
"ppid": 1,
"file_bundle_path": "/var/folders/l5/pd9rhsp54s79_9_qcy746_tw00b_4p/T/AppTranslocation/254C1357-7461-457B-B734-A0FDAF0F26D9/d/Firefox.app",
"file_name": "firefox",
"execution_time": 1501691337.059514,
"file_sha256": "dd78f456a0929faf5dcbb6d952992d900bfdf025e1e77af60f0b029f0b85bf09",
"decision": "BLOCK_BINARY",
"file_bundle_id": "org.mozilla.firefox",
"file_bundle_version_string": "54.0.1",
"pid": 49368,
"current_sessions": [
"bur@console",
"bur@ttys000",
"bur@ttys001",
"bur@ttys002",
"bur@ttys003",
"bur@ttys004"
]
}
]
}
```
##### Event Lifecycle
1. santad generates a new event
2. santad compares, or adds if not present, the event's SHA-256 file hash to an in-memory cache with a timeout of 10 min. If an event with an matching hash is present in cache, the event is dropped.
3. santad saves the event to `/var/db/santa/events.db` with a unique ID assigned as the key.
4. santad sends an XPC message to the santactl daemon. The message contains the event with instructions to upload the event immediately. This is non-blocking and is performed on a background thread.
##### Bundle Events
Bundle events are a special type of event that are generated when a sync server supports receiving the associated bundle events, instead of just the original event. For example: `/Applications/Keynote.app/Contents/MacOS/Keynote` is blocked and an event representing the binary is uploaded. A whitelist rule is created for that one binary. Great, you can now run `/Applications/Keynote.app/Contents/MacOS/Keynote`, but what about all the other supporting binaries contained in the bundle? You would have to wait until they are executed until an event would be generated. It is very common for a bundle to contain multiple binaries, as shown here with Keynote.app. Waiting to get a block is not a very good user experience.
```sh
⇒ santactl bundleinfo /Applications/Keynote.app
Hashing time: 1047 ms
9 events found
BundleHash: b475667ab1ab6eddea48bfc2bed76fcef89b8f85ed456c8068351292f7cb4806
BundleID: com.apple.iWork.Keynote
SHA-256: be3aa404ee79c2af863132b93b0eedfdbc34c6e35d4fda2ade6dd637692ead84
Path: /Applications/Keynote.app/Contents/XPCServices/com.apple.iWork.MovieCompatibilityConverter.xpc/Contents/MacOS/com.apple.iWork.MovieCompatibilityConverter
BundleID: com.apple.iWork.Keynote
SHA-256: 3b2582fd5e7652b653276b3980c248dc973e8082e9d0678c96a08d7d1a8366ba
Path: /Applications/Keynote.app/Contents/XPCServices/com.apple.iWork.PICTConverter.xpc/Contents/MacOS/com.apple.iWork.PICTConverter
BundleID: com.apple.iWork.Keynote
SHA-256: f1bf3be05d511d7c7f651cf7b130d4977f8d28d0bfcd7c5de4144b95eaab7ad7
Path: /Applications/Keynote.app/Contents/XPCServices/com.apple.iWork.ExternalResourceAccessor.xpc/Contents/XPCServices/com.apple.iWork.TCMovieExtractor.xpc/Contents/MacOS/com.apple.iWork.TCMovieExtractor
BundleID: com.apple.iWork.Keynote
SHA-256: b59bc8548c91088a40d9023abb5d22fa8731b4aa17693fcb5b98c795607d219a
Path: /Applications/Keynote.app/Contents/XPCServices/com.apple.iWork.BitmapTracer.xpc/Contents/MacOS/com.apple.iWork.BitmapTracer
BundleID: com.apple.iWork.Keynote
SHA-256: 08cb407f541d867f1a63dc3ae44eeedd5181ca06c61df6ef62b5dc7192951a4b
Path: /Applications/Keynote.app/Contents/XPCServices/com.apple.iWork.TCUtilities32.xpc/Contents/MacOS/com.apple.iWork.TCUtilities32
BundleID: com.apple.iWork.Keynote
SHA-256: b965ae7be992d1ce818262752d0cf44297a88324a593c67278d78ca4d16fcc39
Path: /Applications/Keynote.app/Contents/XPCServices/com.apple.iWork.ExternalResourceAccessor.xpc/Contents/XPCServices/com.apple.iWork.TCMovieExtractor.xpc/Contents/XPCServices/com.apple.iWork.TCMovieExtractor.TCUtilities32.xpc/Contents/MacOS/com.apple.iWork.TCMovieExtractor.TCUtilities32
BundleID: com.apple.iWork.Keynote
SHA-256: 59668dc27314f0f6f5daa5f02b564c176f64836c88e2dfe166e90548f47336f1
Path: /Applications/Keynote.app/Contents/MacOS/Keynote
BundleID: com.apple.iWork.Keynote
SHA-256: 7ce324f919b14e14d327004b09f83ca81345fd4438c87ead4b699f89e9485595
Path: /Applications/Keynote.app/Contents/XPCServices/com.apple.iWork.ExternalResourceAccessor.xpc/Contents/XPCServices/com.apple.iWork.ExternalResourceValidator.xpc/Contents/MacOS/com.apple.iWork.ExternalResourceValidator
BundleID: com.apple.iWork.Keynote
SHA-256: 6b47f551565d886388eeec5e876b6de9cdd71ef36d43b0762e6ebf02bdd8515d
Path: /Applications/Keynote.app/Contents/XPCServices/com.apple.iWork.ExternalResourceAccessor.xpc/Contents/MacOS/com.apple.iWork.ExternalResourceAccessor
```
Bundle events provide a mechanism to generate and upload events for all the executable Mach-O binaries within a bundle. To enable bundle event generation a configuration must be set in the preflight sync stage on the sync server. Once set the sync server can use bundle events to drive a better user experience.
Bundle events can be differentiated by the existence of these fields:
| Field | Value |
| ------------------------ | ---------------------------------------- |
| decision | BUNDLE_BINARY |
| file_bundle_hash | Super Hash of all binary hashes |
| file_bundle_hash_millis | The time in milliseconds it took to find all of the binaries, hash and produce a super hash |
| file_bundle_binary_count | Number of binaries within the bundle |
To avoid redundant uploads of a bundle event Santa will wait for the sync server to ask for them. The server will respond to event uploads with a request like this:
| Field | Value |
| ---------------------------- | ---------------------------------------- |
| event_upload_bundle_binaries | An array of bundle hashes that the sync server needs to be uploaded |
When santactl receives this type of request, it sends an XPC reply to santad to save all the bundle events to the events.db. It then attempts to upload all the bundle events, purging the successes from the events.db. Any failures will be uploaded during the next full sync.

43
Docs/details/ipc.md Normal file
View File

@@ -0,0 +1,43 @@
# Interprocess Communication (IPC)
Most IPC within Santa is done by way of Apple's [XPC](https://developer.apple.com/documentation/xpc?language=objc). Santa wraps [NSXPCConnection](https://developer.apple.com/documentation/foundation/nsxpcconnection?language=objc) to provide client multiplexing, signature validation of connecting clients and forced connection establishment. This is called SNTXPCConnection.
Communication between santad and santa-driver (KEXT) is done with a [IOUserClient](https://developer.apple.com/documentation/kernel/iouserclient?language=objc) subclass and IOKit/IOKitLib.h functions.
##### Who starts who?
The santad and Santa (GUI) processes are both started and kept alive by launchd as a LaunchDaemon and a LaunchAgent, respectively. This means santad runs as root and Santa (GUI) runs as the console user.
There can be multiple Santa (GUI) processes running, one per user logged into the GUI (assuming fast-user switching is enabled). While multiple processes might be running, only the one for the user currently logged-in will be connected to santad and receiving notifications.
When using a sync server, the santactl process is started by santad. Before the new process starts, all privileges are dropped. santactl runs as _nobody_.
The santabs process is started by launchd via an XPC service connection from santad. XPC services inherit their initiator's privileges meaning santabs runs as root, which is necessary to ensure it has permission to read all files.
| Process | Parent Process | Running User |
| -------- | -------------- | ------------ |
| santad | launchd | root |
| Santa | launchd | user |
| santactl | santad | nobody |
| santabs | launchd | root |
##### Who communicates with who?
In short, santad has two-way communication with every other process. In addition, Santa and santabs have two-way communication between each other. For other combinations, there is no direct communication.
![Santa IPC](santa_ipc.png)
##### SNTXPCConnection and two way communication
`SNTXPCConnection` enforces a server / client model for XPC connections. This allows for strong signature validation and forced connection establishment. The only problem with this model is the lack of two-way communication. For example, process A can call methods on process B and retrieve a response, but process B cannot call methods on process A.
To accomplish two-way communication, the following approach can be used:
1. Process A creates a server with an anonymous `NSXPCListener`.
2. Process A sends the anonymous `NSXPCListenerEndpoint` to process B over an already established `SNTXPCConnection`.
3. Process B can now communicate directly with process A.
This is a powerful notion. It enables forced connection establishment between both processes, which is critical when reliability is a concern.

30
Docs/details/logs.md Normal file
View File

@@ -0,0 +1,30 @@
# Logs
Santa currently logs to `/var/db/santa/santa.log` by default. All executions and disk mounts are logged here. File operations can also be configured to be logged. See the `FileChangesRegex` key in the [configuration.md](../deployment/configuration.md) document.
To view the logs:
```sh
tail -F /var/db/santa/santa.log
```
The `-F` will continue watching the path even when the current file fills up and rolls over.
##### macOS Unified Logging System (ULS)
Currently all of the most recent releases of Santa are built with the macOS 10.11 SDK. This allows Santa to continue to log to Apple System Logger (ASL) instead of ULS. However, on macOS 10.12+ all of the Kernel logs are sent to ULS. See the KEXT Logging section below for more details.
If you are building Santa yourself and using the macOS 10.12+ SDKs, Santa's logs will be sent to ULS.
Work is currently underway to bypass ASL and ULS altogether, allowing Santa to continue logging to `/var/db/santa/santa.log`. This change will also allow us to add alternative logging formats, like Protocol Buffer or JSON.
##### KEXT Logging
Streaming logs from the santa-driver KEXT does not work properly. Logs are generated but they will likely be garbled or show inaccurate data.
Instead, `show` can be used to view the santa-driver KEXT logs:
```sh
/usr/bin/log show --info --debug --predicate 'senderImagePath == "/Library/Extensions/santa-driver.kext/Contents/MacOS/santa-driver"'
```

53
Docs/details/mode.md Normal file
View File

@@ -0,0 +1,53 @@
# Mode
Santa can run in one of two modes, Lockdown or Monitor. To check the current status run the following command:
```sh
⇒ santactl status
>>> Daemon Info
Mode | Monitor
File Logging | Yes
Watchdog CPU Events | 0 (Peak: 13.59%)
Watchdog RAM Events | 0 (Peak: 31.49MB)
>>> Kernel Info
Root cache count | 107
Non-root cache count | 0
>>> Database Info
Binary Rules | 5
Certificate Rules | 2
Events Pending Upload | 0
>>> Sync Info
Sync Server | https://sync-server-hostname.com
Clean Sync Required | No
Last Successful Full Sync | 2017/08/02 21:44:17 -0400
Last Successful Rule Sync | 2017/08/02 21:44:17 -0400
Push Notifications | Connected
Bundle Scanning | Yes
```
##### Monitor mode
The default mode. Running Santa in Monitor Mode will stop any binaries matching blacklist rules, but will not stop unknown binaries from running. This is a flexible state, allowing virtually zero user interruption but still gives protection against known blacklisted binaries. In addition execution events that would have been blocked in Lockdown mode are generated and can be collected and analyzed by a sync server.
##### Lockdown mode
Running Santa in Lockdown Mode will stop all blacklisted binaries and additionally will prevent all unknown binaries from running. This means that if the binary has no rules or scopes that apply, then it will be blocked.
##### Changing Modes
There are two ways to change the running mode: changing the configuration profile and with a sync server configuration.
###### Change modes with the configuration profile
Set the `ClientMode` in your configuration profile to the integer value `1` for MONITOR or `2` for LOCKDOWN.
```xml
<key>ClientMode</key>
<integer>1</integer>
```
Install your new configuration profile, it will overwrite any old `com.google.santa` profiles you may have already install. See the [configuration](../deployment/configuration.md) document for more details.
###### Change modes with a sync server
The mode is set in the preflight sync stage. Use the key `client_mode` and a value of `MONITOR` or `LOCKDOWN`.

BIN
Docs/details/push.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

104
Docs/details/rules.md Normal file
View File

@@ -0,0 +1,104 @@
# Rules
Rules provide the primary evaluation mechanism for whitelisting and blacklisting binaries with Santa on macOS. There are two types of rules: binary and certificate.
##### Binary Rules
Binary rules use the SHA-256 hash of the entire binary as an identifier. This is the most specific rule in Santa. Even a small change in the binary will alter the SHA-256 hash, invalidating the rule.
##### Certificate Rules
Certificate rules are formed from the SHA-256 fingerprint of an X.509 leaf signing certificate. This is a powerful rule type that has a much broader reach than an individual binary rule . A signing certificate can sign any number of binaries. Whitelisting or blacklisting just a few key signing certificates can cover the bulk of an average user's binaries. The leaf signing certificate is the only part of the chain that is evaluated. Though the whole chain is available for viewing.
```sh
⇒ santactl fileinfo /Applications/Dropbox.app --key "Signing Chain"
Signing Chain:
1. SHA-256 : 2a0417257348a20f96c9de0486b44fcc7eaeaeb7625b207591b8109698c02dd2
SHA-1 : 86ec91f726ba9caa09665b2109c49117f0b93134
Common Name : Developer ID Application: Dropbox, Inc.
Organization : Dropbox, Inc.
Organizational Unit : G7HH3F8CAK
Valid From : 2012/06/19 16:10:30 -0400
Valid Until : 2017/06/20 16:10:30 -0400
2. SHA-256 : 7afc9d01a62f03a2de9637936d4afe68090d2de18d03f29c88cfb0b1ba63587f
SHA-1 : 3b166c3b7dc4b751c9fe2afab9135641e388e186
Common Name : Developer ID Certification Authority
Organization : Apple Inc.
Organizational Unit : Apple Certification Authority
Valid From : 2012/02/01 17:12:15 -0500
Valid Until : 2027/02/01 17:12:15 -0500
3. SHA-256 : b0b1730ecbc7ff4505142c49f1295e6eda6bcaed7e2c68c5be91b5a11001f024
SHA-1 : 611e5b662c593a08ff58d14ae22452d198df6c60
Common Name : Apple Root CA
Organization : Apple Inc.
Organizational Unit : Apple Certification Authority
Valid From : 2006/04/25 17:40:36 -0400
Valid Until : 2035/02/09 16:40:36 -0500
```
If you wanted to whitelist or blacklist all software signed with this perticular Dropbox signing certificate you would use the leaf SHA-256 fingerprint.
`2a0417257348a20f96c9de0486b44fcc7eaeaeb7625b207591b8109698c02dd2`
Santa does not evaluate the `Valid From` or `Valid Until` fields, nor does it check the Certificate Revocation List (CRL) or the Online Certificate Status Protocol (OCSP) for revoked certificates. Adding rules for the certificate chain's intermediates or roots has no effect on binaries signing by a leaf. Santa ignores the chain and is only concerned with the leaf certificate's SHA-256 hash.
##### Rule Evaluation
When a process is trying to `execve()` santad retrieves information on the binary, including a hash of the entire file and the signing chain (if any). The hash and signing leaf certificate are then passed through the [SNTPolicyProcessor](https://github.com/google/santa/blob/master/Source/santad/SNTPolicyProcessor.h). Rules are evaluated from most specific to least specific. First binary (either whitelist or blacklist), then certificate (either whitelist or blacklist). If no rules are found that apply, scopes are then searched. See the [scopes.md](scopes.md) document for more information on scopes.
You can use the `santactl fileinfo` command to check the status of any given binary on the filesystem.
###### Whitelisted with a Binary Rule
```sh
⇒ santactl fileinfo /Applications/Hex\ Fiend.app --key Rule
Whitelisted (Binary)
```
###### Whitelisted with a Certificate Rule
```sh
⇒ santactl fileinfo /Applications/Safari.app --key Rule
Whitelisted (Certificate)
```
###### Blacklisted with a Binary Rule
```sh
⇒ santactl fileinfo /usr/bin/yes --key Rule
Blacklisted (Binary)
```
###### Blacklisted with a Certificate Rule
```sh
⇒ santactl fileinfo /Applications/Malware.app --key Rule
Blacklisted (Certificate)
```
You can also check arbitrary SHA-256 binary and certificate hashes for rules. The rule verb needs to be run with root privileges.
For checking the SHA-256 hash of `/usr/bin/yes`:
```sh
sudo santactl rule --check --sha256 $(santactl fileinfo --key SHA-256 /usr/bin/yes)
Blacklisted (Binary)
```
For checking the SHA-256 hash of `/usr/bin/yes ` signing certificate:
```sh
⇒ sudo santactl rule --check --certificate --sha256 $(santactl fileinfo --cert-index 1 --key SHA-256 /usr/bin/yes)
Whitelisted (Certificate)
```
##### Built-in rules
To avoid blocking any Apple system binaries or Santa binaries, santad will create 2 immutable certificate rules at startup:
* The signing certificate santad is signed with
* The signing certificate launchd is signed with
By creating these two rules at startup, Santa should never block critical Apple system binaries or other Santa components.

View File

@@ -0,0 +1,94 @@
# santa-driver
santa-driver is a macOS [kernel extension](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/KEXTConcept/KEXTConceptIntro/introduction.html) (KEXT) that makes use of the [Kernel Authorization](https://developer.apple.com/library/content/technotes/tn2127/_index.html) (Kauth) KPI. This allows santa-driver to listen for events and either deny or defer the decision of those events. The santa-driver acts as an intermediary layer between Kauth and santad, with some caching to lower the overhead of decision making.
##### Kauth
santa-driver utilizes two Kauth scopes `KAUTH_SCOPE_VNODE` and `KAUTH_SCOPE_FILEOP `. It registers itself with the Kauth API by calling `kauth_listen_scope()` for each scope. This function takes three arguments:
* `const char *scope`
* `kauth_scope_callback_t _callback`_
* `void *contex`
It returns a `kauth_listener_t` that is stored for later use, in Santa's case to stop listening.
###### KAUTH_SCOPE_VNODE
Here is how santa-driver starts listening for `KAUTH_SCOPE_VNODE` events.
```c++
vnode_listener_ = kauth_listen_scope(
KAUTH_SCOPE_VNODE, vnode_scope_callback, reinterpret_cast<void *>(this));
```
The function `vnode_scope_callback` is called for every vnode event. There are many types of vnode events, they complete list can be viewed in the kauth.h. There are many types of vnode events, the complete list can be viewed in kauth.h. Santa is only concerned with regular files generating `KAUTH_VNODE_EXECUTE` [1] and `KAUTH_VNODE_WRITE_DATA` events. All non-regular files and unnecessary vnode events are filtered out.
Here is how santa-driver stops listening for `KAUTH_SCOPE_VNODE` events:
```c++
kauth_unlisten_scope(vnode_listener_);
```
[1] `KAUTH_VNODE_EXECUTE` events that do not have the `KAUTH_VNODE_ACCESS` advisory bit set.
###### KAUTH_SCOPE_FILEOP
Santa also listens for file operations, this is mainly used for logging [1] and cache invalidation.
* `KAUTH_FILEOP_DELETE`, `KAUTH_FILEOP_RENAME`, `KAUTH_FILEOP_EXCHANGE` and `KAUTH_FILEOP_LINK` are logged
* `KAUTH_FILEOP_EXEC` is used to log `execve()`s. Since the `KAUTH_VNODE_EXECUTE` is used to allow or deny an `execve()` the process arguments have not been setup yet. Since `KAUTH_FILEOP_EXEC` is triggered after an `execve()` it is used to log the `execve()`.
[1] `KAUTH_FILEOP_CLOSE` is used to invalidate that file's representation in the cache. If a file has changed it needs to be re-evalauted. This is particularly necessary for files that were added to the cache with an action of allow.
##### Driver Interface
santa-driver implements an [IOUserClient](https://developer.apple.com/documentation/kernel/iouserclient?language=objc) subclass and santad interacts with it through IOKit/IOKitLib.h functions.
[//]: # "TODO(bur, rah) Flesh out the details"
##### Cache
To aid in performance, santa-driver utilizes a caching system to hold the state of all observed `execve()` events.
###### Key
The key is a `uint64_t`. The top 32 bits hold the filesystem ID, while the bottom 32 bits hold the file unique ID. Together we call this the vnode_id.
```c++
uint64_t vnode_id = (((uint64_t)fsid << 32) | fileid);
```
###### Value
The value is a `uint64_t` containing the action necessary, along with the decision timestamp. The action is stored in the top 8 bits. The decision timestamp is stored in the remaining 56 bits.
```c++
santa_action_t action = (santa_action_t)(cache_val >> 56);
uint64_t decision_time = (cache_val & ~(0xFF00000000000000));
```
The possible actions are:
| Actions | Expiry Time | Description |
| ----------------------- | ---------------- | ---------------------------------------- |
| `ACTION_REQUEST_BINARY` | None | Awaiting an allow or deny decision from santad. |
| `ACTION_RESPOND_ALLOW` | None | Allow the `execve()` |
| `ACTION_RESPOND_DENY` | 500 milliseconds | Deny the `execve()`, but re-evalaute after 500 milliseconds. If someone is trying to run a banned binary continually every millisecond for example, only 2 evaluation requests to santad for would occur per second. This mitigates a denial of service type attack on santad. |
###### Invalidation
Besides the expiry time for individual entries, the entire cache will be cleared if any of the following events takes place:
* Addition of a blacklist rule
* Addition of a blacklist regex scope
* Cache fills up. This defaults to `5000` entries for the root volume and `500` for all other mounted volumes.
To view the current kernel cache count see the "Kernel info" section of `santactl status`:
```sh
⇒ santactl status
>>> Kernel Info
Root cache count | 107
Non-root cache count | 0
```

11
Docs/details/santa-gui.md Normal file
View File

@@ -0,0 +1,11 @@
# Santa GUI
The Santa GUI process is pretty simple. It's only job is the display user GUI notifications. There are two types of notifications it can display:
A notification when an `execve()` is blocked.
![Block](block.png)
Notifications when specific rules arrive (when using FCM for push notifications).
![Notification](push.png)

BIN
Docs/details/santa_ipc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

44
Docs/details/santabs.md Normal file
View File

@@ -0,0 +1,44 @@
# santabs
The santabs process is an XPC service for the santa-driver.kext bundle, meaning only binaries within that bundle can launch santabs. It will be launched with the same privileges as its calling process. Currently, santad is the only caller of santabs, so santabs runs as root.
##### Events
The santabs process is quite simple and only does one thing: it generates non-execution events for the contents of a bundle.
When there is an `execve()` that is blocked within a bundle, a few actions take place:
1. The highest ancestor bundle in the tree is found
* So `/Applications/DVD Player.app/Contents/MacOS/DVD Player` would be `/Applications/DVD Player.app`
* Or `/Applications/Safari.app/Contents/PlugIns/CacheDeleteExtension.appex/Contents/MacOS/CacheDeleteExtension` would be `/Applications/Safari.app`
2. The ancestor bundle is then searched for Mach-O executables
* For Safari that would currently be 4 binaries
* ```sh
Hashing time: 53 ms
4 events found
BundleHash: 718773556ca5ea798f984fde2fe1a5994f175900b26d2964c9358a0f469a4ac6
BundleID: com.apple.Safari
SHA-256: ea872e83a518ce442ed050c4408a448d915e2bae90ef8455ce7805448d864a3e
Path: /Applications/Safari.app/Contents/PlugIns/CacheDeleteExtension.appex/Contents/MacOS/CacheDeleteExtension
BundleID: com.apple.Safari
SHA-256: 1a43283857b1822164f82af274c476204748c0a2894dbcaa11ed17f78e0273cc
Path: /Applications/Safari.app/Contents/MacOS/Safari
BundleID: com.apple.Safari
SHA-256: ab0ac54dd90144931b681d1e84e198c6510be44ac5339437bc004e60777af7ba
Path: /Applications/Safari.app/Contents/Resources/appdiagnose
BundleID: com.apple.Safari
SHA-256: f49c5aa3a7373127d0b4945782b1fa375dd3707d66808fd66b7c0756430defa8
Path: /Applications/Safari.app/Contents/XPCServices/com.apple.Safari.BrowserDataImportingService.xpc/Contents/MacOS/com.apple.Safari.BrowserDataImportingService
```
3. Events are created for each binary and the bundle hash is calculated
4. These events are sent to the sync server for processing
##### Bundle Hash
The found events are sorted by their file SHA-256 hash. The hashes are concatenated and then SHA-256 hashed. This is now a strong indicator on what Mach-O executables were within the bundle at the time of scan. This can then be verified by the sync server when deciding to generate rules.

425
Docs/details/santactl.md Normal file
View File

@@ -0,0 +1,425 @@
# santactl
This may be the most complex part of Santa. It does two types of work:
1. It contains all of the code and functionality for syncing with a sync-server.
2. It can be used to view the state and configuration of Santa as a whole. It can also inspect individual files. When running without a sync server it also a supported method of managing the rules database.
The details of santactl's syncing functionality are covered in the syncing.md document. This document will cover the status work that santactl performs.
##### status
To view the status of Santa run `santactl status`
```sh
⇒ santactl status
>>> Daemon Info
Mode | Monitor
File Logging | Yes
Watchdog CPU Events | 0 (Peak: 2.19%)
Watchdog RAM Events | 0 (Peak: 29.45MB)
>>> Kernel Info
Kernel cache count | 123
>>> Database Info
Binary Rules | 321
Certificate Rules | 123
Events Pending Upload | 0
>>> Sync Info
Sync Server | https://sync-server.com/santa/
Clean Sync Required | No
Last Successful Full Sync | 2017/08/10 15:05:32 -0400
Last Successful Rule Sync | 2017/08/10 15:29:21 -0400
Push Notifications | Connected
Bundle Scanning | Yes
```
The status command also has the ability to print JSON output `santactl status --json`
```sh
⇒ santactl status --json
{
"kernel" : {
"cache_count" : 123
},
"daemon" : {
"watchdog_ram_events" : 0,
"watchdog_ram_peak" : 29.44921875,
"watchdog_cpu_events" : 0,
"file_logging" : true,
"mode" : "Monitor",
"watchdog_cpu_peak" : 2.188006666666666
},
"database" : {
"events_pending_upload" : 0,
"certificate_rules" : 123,
"binary_rules" : 321
},
"sync" : {
"last_successful_rule" : "2017\/08\/10 15:29:21 -0400",
"push_notifications" : "Connected",
"bundle_scanning" : true,
"clean_required" : false,
"server" : "https:\/\//sync-server.com\/santa\/",
"last_successful_full" : "2017\/08\/10 15:05:32 -0400"
}
}
```
##### version
To view all of the component versions `santactl version`
```sh
⇒ santactl version
santa-driver | 0.9.19
santad | 0.9.19
santactl | 0.9.19
SantaGUI | 0.9.19
```
Again, a JSON version is available `santactl version --json`
```sh
⇒ santactl version --json
{
"santa-driver" : "0.9.19",
"santad" : "0.9.19",
"SantaGUI" : "0.9.19",
"santactl" : "0.9.19"
}
```
##### fileinfo
The fileinfo verb is very powerful and can be used to tease out just about anything you wish to know about a file, with respect to the domain of Santa.
Here is an example of using `santactl fileinfo ` to inspect the main executable within `/Applications/Hex Fiend.app`.
```sh
⇒ santactl fileinfo /Applications/Hex\ Fiend.app
Path : /Applications/Hex Fiend.app/Contents/MacOS/Hex Fiend
SHA-256 : efaf88db065beae61615f6f176c11c751555d2bad3c5da6cdad71635896014f1
SHA-1 : 5585e6fb94eace1bd37da9a0a2f928e992d7c60c
Bundle Name : Hex Fiend
Bundle Version : 170205
Bundle Version Str : 2.5
Download Referrer URL: http://ridiculousfish.com/hexfiend/
Download URL : http://ridiculousfish.com/hexfiend/files/Hex_Fiend_2.5.dmg
Download Timestamp : 2017/06/29 12:52:16 -0400
Download Agent : com.google.Chrome
Type : Executable (x86-64)
Code-signed : Yes
Rule : Whitelisted (Unknown)
Signing Chain:
1. SHA-256 : ba1be5d2d60a43658a0c6ebf61b577e428439b53ef2e0b96ba90285e2c82a1b2
SHA-1 : 8fdbf6d6c22a97c472fb4961b7733ab0d8830ff7
Common Name : Developer ID Application: Kevin Wojniak
Organization : Kevin Wojniak
Organizational Unit : QK92QP33YN
Valid From : 2012/10/30 01:07:40 -0400
Valid Until : 2017/10/31 01:07:40 -0400
2. SHA-256 : 7afc9d01a62f03a2de9637936d4afe68090d2de18d03f29c88cfb0b1ba63587f
SHA-1 : 3b166c3b7dc4b751c9fe2afab9135641e388e186
Common Name : Developer ID Certification Authority
Organization : Apple Inc.
Organizational Unit : Apple Certification Authority
Valid From : 2012/02/01 17:12:15 -0500
Valid Until : 2027/02/01 17:12:15 -0500
3. SHA-256 : b0b1730ecbc7ff4505142c49f1295e6eda6bcaed7e2c68c5be91b5a11001f024
SHA-1 : 611e5b662c593a08ff58d14ae22452d198df6c60
Common Name : Apple Root CA
Organization : Apple Inc.
Organizational Unit : Apple Certification Authority
Valid From : 2006/04/25 17:40:36 -0400
Valid Until : 2035/02/09 16:40:36 -0500
```
Any of the desired information can be targeted with the `--key` flag
```sh
⇒ santactl fileinfo /Applications/Hex\ Fiend.app --key SHA-256
efaf88db065beae61615f6f176c11c751555d2bad3c5da6cdad71635896014f1
```
Multiple `--key` flags are allowed
```sh
⇒ santactl fileinfo /Applications/Hex\ Fiend.app --key SHA-256 --key Rule
efaf88db065beae61615f6f176c11c751555d2bad3c5da6cdad71635896014f1
Whitelisted (Unknown)
```
The `--json` flag can also be used at any point
```sh
⇒ santactl fileinfo /Applications/Hex\ Fiend.app --key SHA-256 --key Rule --json
{
"SHA-256" : "efaf88db065beae61615f6f176c11c751555d2bad3c5da6cdad71635896014f1",
"Rule" : "Whitelisted (Unknown)"
}
```
Multiple files are also supported as input
```sh
⇒ santactl fileinfo /bin/* --key SHA-256 --key Rule --json
[
{
"SHA-256" : "5d8e161c21fc1a43374c4cf21be05360dbe2ecea0165fd4725ae7a958f2a0b02",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "295fbc2356e8605e804f95cb6d6f992335e247dbf11767fe8781e2a7f889978a",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "9f9b36ec79b9fcaf649e17f2f94c544dd408c2ab630e73d7c62a7a43f1bc7b1d",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "08a09d2d9bade16872acdf5da1c4e9d29582ed985480a9e73fd389e98293c40d",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "48e4b938b363201ec11d06a13d8080c1bd77187d286780259b9304c96edc5324",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "7dff6291a29fdaf97dad64c0671dc5d1ecc42189bc5daf8ca08e2a3ae06aff95",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "7cbba457df4c02d6a7fb93046fea0e869732c65a2225bee6f2e8ec290d38c57b",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "39e894d1705656451f592884a56bcc76e7ffbb9ed2a8b81d5f2878e1c0e68dbe",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "8555ed4622410aa7b4379041acabf80fe452a90efe3be2697406935ff0d6822e",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "cee3e29089f8919ee904328904a7492995cfa398b027857fbf8b3e601397b308",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "da2cfa9fc2cabd41907f9d0931cea79000a19520fe0b3d73fc40537408730e40",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "73aee02c4761e5501b1fdfa51ccd316bf735017a5cc0a09d5bcc46f4e7112be9",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "3a1c4ca5a038b42b1fbfca6f9bec25d307a8af40afbe9c48b307372fe8167a2f",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "9dc8e1c5b6ec49602dd968eb88286e330220233f7cfa6e73fd37fc983a365084",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "78fd9b8749c2a216ca76ff4541754d4cf5a5e2e8c00710a85c3fdab171486f92",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "c4daaf12bd42adee60549872126e15186c75d89e760f078bfa6a45a861f6400f",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "9dba1cbb01bce47a9610a40cbcbc27704a754e31a889503eb0670c3a25f7ad72",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "a5ae86cd413589d9661fc604349fb153c0d6f5dfa3d9e95e01b8bc5e09bc1da1",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "a5ae86cd413589d9661fc604349fb153c0d6f5dfa3d9e95e01b8bc5e09bc1da1",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "c4c5517ff40a33006028853a19734d8cda8e2942cb9ba27b8310e07f18677487",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "a944b104742db59204b45f1dae657bd6a845ff2374e1ade3cf9f09cc428154cf",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "09e143cf3b6c4dcc98676cc45543613b83b6527b502d4dacb42b3f6c7036ef5a",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "47cea771e93aff464f1060a6a1a2c3855401e6cd22c3971b2b76fae92e8c33b4",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "5682f15628ae15e5c29aa37f19ec421bbe4aca47734864b6363b73a16f891888",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "83c29a2445d84daf51eebd51668753fb39600a136efc20aba7298a812b44974c",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "83929910d3cd2c401636337fadc747a9a8ea6c174bfd80f1e96b99d877ddfa6e",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "cccd818698aa802b116586a773643d0b951067dea8284304acaae62ac97b362b",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "2bf2d10a7529a88d340ce0255da52dbef9873ccb44e46d23af03abf70b8e54ca",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "956f2dc7ba31663dd3a9b70e84e6a2491980165426b90cacd10db4bd010c3353",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "da1a3ae959751b211928f175f6c8987408a976be44690022c92d45ef5a8cb6e5",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "1e51209ae4549a72432ad504341c0731a282b33ba99c5f7f4e2abc9993e09b0a",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "7dff6291a29fdaf97dad64c0671dc5d1ecc42189bc5daf8ca08e2a3ae06aff95",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "5d8e161c21fc1a43374c4cf21be05360dbe2ecea0165fd4725ae7a958f2a0b02",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "83929910d3cd2c401636337fadc747a9a8ea6c174bfd80f1e96b99d877ddfa6e",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "17372eafbe9e920d5715a9cffa59f881ef4ed949785c1e2adf9c067d550dbde6",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "b1834d55b76c65d57cef1219a30331452301e84b6e315f2a17e5b5b295ce1648",
"Rule" : "Whitelisted (Certificate)"
}
]
```
Recursive lookups of an application or directory is a soon to be added feature
```sh
⇒ santactl fileinfo --recursive /Applications/Santa.app --key SHA-256 --key Rule --key Type --json
[
{
"SHA-256" : "c149c10c83abaf6b602401106f098b68d47a1a433ab02455cef2ca8057cf4a82",
"Type" : "Unknown",
"Rule" : "Whitelisted (Scope)"
},
{
"SHA-256" : "c339c3e5e04c732ae493dbc4a26d18fccc8bb48cea0cc0762ccd8754ef318a0b",
"Type" : "Unknown",
"Rule" : "Whitelisted (Scope)"
},
{
"SHA-256" : "6ee757ab65d7c93e8b6a467b44cd2f0d10b6db7da8b6200e778c3ca279ea5619",
"Type" : "Executable (x86-64)",
"Rule" : "Whitelisted (Certificate)"
},
{
"SHA-256" : "82502191c9484b04d685374f9879a0066069c49b8acae7a04b01d38d07e8eca0",
"Type" : "Unknown",
"Rule" : "Whitelisted (Scope)"
},
{
"SHA-256" : "9814019f865a540d3635012a75db932eaefc9a62468750f2294350690430aadf",
"Type" : "Unknown",
"Rule" : "Whitelisted (Scope)"
},
{
"SHA-256" : "05a9c9dbbf0a7a30f083e3dccd8db3d96845e0644930977b4e284c65083b89ac",
"Type" : "Unknown",
"Rule" : "Whitelisted (Scope)"
},
{
"SHA-256" : "e1db8fdffc5017684f962c51fad059dcaa06ab5d551186aa85711f80b727d23d",
"Type" : "Unknown",
"Rule" : "Whitelisted (Scope)"
}
]
```
##### rule
The rule command is covered in the [rules.md](rules.md) document.
##### sync
The sync command is covered in the [syncing.md](syncing.md) document.
##### Debug Commands
There are a few commands that are not included in the release versions of Santa. They are mainly used during development and only accessible with a debug build of Santa.
##### bundleinfo
This prints info about all of the executable Mach-O files within a bundle. It also prints the calculated bundle hash for that particular bundle. A bundle hash is a notion used by Santa to represent a set of binaries.
```sh
⇒ santactl bundleinfo /Applications/Hex\ Fiend.app
Hashing time: 12 ms
4 events found
BundleHash: 33da3e2d5e2ccbdb9d34fb9753c2c18805e6325853d2fb4eb947915c90113efc
BundleID: com.ridiculousfish.HexFiend
SHA-256: e592a7c65f803675c0b7d55ab7d2a1a2696c9f097a99dc28a4083d7387e53d95
Path: /Applications/Hex Fiend.app/Contents/Library/LaunchServices/com.ridiculousfish.HexFiend.PrivilegedHelper
BundleID: com.ridiculousfish.HexFiend
SHA-256: ce23d39a1a8ff2b42baad5a0204b24b57590bb7ff74c9552b3ba10d9c1517279
Path: /Applications/Hex Fiend.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate
BundleID: com.ridiculousfish.HexFiend
SHA-256: efaf88db065beae61615f6f176c11c751555d2bad3c5da6cdad71635896014f1
Path: /Applications/Hex Fiend.app/Contents/MacOS/Hex Fiend
BundleID: com.ridiculousfish.HexFiend
SHA-256: 148d6ae55176b619e5eb9f5000922b3ca4c126206fc5782f925d112027f9db3c
Path: /Applications/Hex Fiend.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/fileop
```
See the [santabs.md](santabs.md) document for more information on bundles and bundle hashes.
##### checkcache
This is used to check if a particular file is apart of santa-driver's kernel cache. Mainly for debugging purposes.
```sh
⇒ santactl checkcache /usr/bin/yes
File does not exist in cache
⇒ /usr/bin/yes
y
y
y
y
y
^C
⇒ santactl checkcache /usr/bin/yes
File exists in [whitelist] kernel cache
```
##### flushcache
This can be used to flush santa-driver's kernel cache, as shown here.
```sh
⇒ santactl checkcache /usr/bin/yes
File exists in [whitelist] kernel cache
⇒ sudo santactl flushcache
Cache flush requested
⇒ santactl checkcache /usr/bin/yes
File does not exist in cache
```

23
Docs/details/santad.md Normal file
View File

@@ -0,0 +1,23 @@
# santad
The santad process does the heavy lifting when it comes to making decisions about binary executions. It also handles brokering all of the XPC connections between the various components of Santa. It does all of this with performance being at the forefront.
##### A note on performance
On an idling machine, santad and the other components of Santa consume virtually no CPU and a minimal amount of memory (5-50MB). When lots of processes `execve()` at the same time, the CPU and memory usage can spike. All of the `execve()` decisions are made on high priority threads to ensure decisions are posted back to the kernel as soon as possible. A watchdog thread will log warnings when sustained high CPU (>20%) and memory (>250MB) usage by santad is detected.
##### On Launch
The very first thing santad does once it has been launched is to load and connect to santa-driver. Only one connection may be active at any given time.
At this point, santa-driver is loaded and running in the kernel, but is allowing all executions and not sending any messages to santad. Before santad tells santa-driver it is ready to receive messages, it needs to setup a few more things:
* The rule and event databases are initialized
* Connections to Santa (GUI) and santactl sync daemon are established.
* The config file is processed.
santad is now ready to start processing decision and logging messages from santa-driver. The listeners are started and santad sits in a run loop awaiting messages from santa-driver.
##### Running
Messages are read from a shared memory queue (`IODataQueueMemory` ) on a single thread. A callback is invoked for each message. The callback then dispatches all the work of processing a decision message to a concurrent high priority queue. The log messages are dispatched to a low priority queue for processing.

27
Docs/details/scopes.md Normal file
View File

@@ -0,0 +1,27 @@
# Scopes
In addition to rules, Santa can whitelist or blacklist based on scopes. Currently, only a few scopes are implemented. They fall into one of two categories: a whitelist scope or blacklist scope. Scopes are evaluated after rules, with blacklist evaluation preceding whitelist.
Scopes are a broader way of whitelisting or blacklisting `execve()`s.
For configuration of scopes see [configuration.md](../deployment/configuration.md).
##### Blacklist Scopes
| Scope | Configurable |
| -------------------- | ------------ |
| Blacklist Path Regex | Yes |
| Missing __PAGEZERO | Yes |
##### Whitelist Scopes
| Scope | Configurable |
| -------------------- | ------------ |
| Whitelist Path Regex | Yes |
| Not a Mach-O | No |
As seen above, Santa will whitelist any non Mach-O binary under a whitelist scope. However, a blacklist regex or binary SHA-256 rule can be used to block non Mach-O `execve()`s since they are evaluated before the whitelist scopes.
##### Regex Caveats
The paths covered by the whitelist and blacklist regex patterns are not tracked. If an `execve()` is allowed initially, then moved into a blacklist directory, Santa has no knowledge of that move. Since santa-driver caches decisions, the recently moved file will continue to be allowed to `execve()` even though it is now within a blacklisted regex path. The cache holds "allow" decisions until invalidated and "deny" decisions for 500 milliseconds. Going from a blacklist path to a whitelist path is not largely affected.

View File

@@ -0,0 +1,108 @@
# Building
Santa makes use of [rake](https://ruby.github.io/rake/) for building and testing Santa. All of the [releases](https://github.com/google/santa/releases) are made using this same process. Santa's releases are codesigned with Google's KEXT signing certificate. This allows Santa to be loaded with SIP fully enabled.
#### Cloning
Clone the source and change into the directory.
```sh
git clone https://github.com/google/santa
cd santa
```
The above command will default to using the `master` branch. If you wanted to build, run or test a specific version of Santa use this command.
```sh
git checkout <version, i.e. 0.9.19>
```
#### Building
Build a debug version of Santa. This keeps all the debug symbols, adds additional logs and does not optimize the compiled output. For speed sensitive tests make sure to benchmark a release version too.
```sh
rake build:debug
```
Build a release version of Santa.
```sh
rake build:release
```
Both of these just output the binaries that makeup Santa in the default Xcode build location. To actually run what was built, see the next section.
#### Running
On macOS 10.11+ System Integrity Protection (SIP) prevents loading of kernel extensions that are not signed by an Apple KEXT signing certificate. To be able to load and test a non-release version of Santa, SIP will have to be configured to allow non-Apple KEXT signing certificates.
__This is only to be done a machine that is actively developing, unloading and loading kernel extensions.__
1. Boot into Recovery Mode: Reboot and hold down `command+r`
2. From the utilities menu select `Terminal`
3. Disable the KEXT feature of SIP: `csrutil enable --without kext`
4. Reboot
You should now be able to load and run a non-release version of Santa.
Build and run a debug version of Santa.
```sh
rake reload:debug
```
Build and run a release version of Santa.
```sh
rake reload:release
```
#### Debugging
Xcode and lldb can be used to debug Santa, just like any other project. Instead of clicking the play button to launch and attach to a process, you can attach to an already running, or soon to by running, component of Santa. To do this select the Debug menu and choose `Attach to Process by PID or Name… `. Below are the four components of Santa and who to debug the process as.
Note: santa-driver (the kernel extension) cannot be debugged by attaching with Xcode.
Note: Xcode can attach to santad without interruption, however any breakpoints in the decision making codepath can deadlock the machine. Using lldb directly to attach to santad will deadlock the machine.
| process | user |
| -------- | ---- |
| santad | root |
| Santa* | me |
| santactl | me |
| santabs | root |
Xcode will then wait for the process to start. Issue this command to restart all the Santa processes in debug mode.
*The Santa (GUI) process is the only component of Santa that can be launched and debugged from Xcode directly. All the other components are launched with privileges and/or are scoped to an XPC service that launchd scopes to a hosting bundle. Thus the need for the `Attach to Process by PID or Name…` technique. See the [ipc](../details/ipc.md) document for for details.
```sh
rake reload:debug
```
Now the process is attached in Xcode and you can debug your day away.
#### Tests
Run all the logic / unit tests
```sh
rake tests:logic
```
Run all of santa-driver kernel extension tests
```sh
rake tests:kernel
```
#### Releases
Creates a release build of Santa with a version based of the newest tag. Also saves the dsym files for each component of Santa. This makes debugging and interpreting future crashes or kernel panics much easier.
```sh
rake dist
```

46
Docs/index.md Normal file
View File

@@ -0,0 +1,46 @@
# Welcome to the Santa Docs
Santa is a binary whitelisting / blacklisting system for macOS. Here you will find the documentation for understanding how Santa works, how to deploy it and how to contribute.
#### Introduction
The following documents give an overview of how Santa accomplishes binary whitelisting / blacklisting at the enterprise scale.
- [Binary Whitelisting](introduction/binary-whitelisting-overview.md): How Santa makes allow or deny decisions for any `execve()` taking place.
- [Syncing](introduction/syncing-overview.md): How configuration and whitelist / blacklist rules are applied from a sync server.
#### Deployment
* [Configuration](deployment/configuration.md): The local and sync server configuration options.
#### Development
* [Building Santa](development/building.md): How to build and load Santa for testing on a development machine.
* [Contributing](../CONTRIBUTING.md): How to contribute a bug fix or new feature to Santa.
#### Details
For those who want even more details on how Santa works under the hood, this section is for you.
###### Binaries
There are five main components that make up Santa whose core functionality is described in snippets below. For additional detail on each component, visit their respective pages. These quick descriptions do not encompass all the jobs performed by each component, but do provide a quick look at the basic functionality utilized to achieve the goal of binary whitelisting / blacklisting.
* [santa-driver](details/santa-driver.md): A macOS kernel extension that participates in `execve()` decisions.
* [santad](details/santad.md): A user-land root daemon that makes decisions on behalf of santa-driver requests.
* [santactl](details/santactl.md): A user-land anonymous daemon that communicates with a sync server for configurations and policies. santactl can also be used by a user to manually configure Santa when using the local configuration.
* [santa-gui](details/santa-gui.md): A user-land GUI daemon that displays notifications when an `execve()` is blocked.
* [santabs](details/santabs.md): A user-land root daemon that finds Mach-O binaries within a bundle and creates events for them.
###### Concepts
Additional documentation on the concepts that support the operation of the main components:
* [mode](details/mode.md): An operating mode, either Monitor or Lockdown.
* [events](details/events.md): Represents an `execve()` that was blocked, or would have been blocked, depending on the mode.
* [rules](details/rules.md): Represents allow or deny decisions for a given `execve()`. Can either be a binary's SHA-256 hash or a leaf code-signing certificate's SHA-256 hash.
* [scopes](details/scopes.md): The level at which an `execve()` was allowed or denied from taking place.
* [syncing](introduction/syncing-overview.md): How Santa communicates with a TLS server for configuration, rules and event uploading.
* [ipc](details/ipc.md): How all the components of Santa communicate.
duction/syncing-overview.
* [logs](details/logs.md): What and where Santa logs.

View File

@@ -0,0 +1,31 @@
# Binary Whitelisting Overview
#### Background
The decision flow starts in the kernel. The macOS kernel is extensible by way of a kernel extension (KEXT). macOS makes available kernel programming interfaces (KPIs) to be used by a KEXT. Santa utilizes the Kernel Authorization (Kauth) KPI. This is a very powerful and verbose interface that gives Santa the ability to listen in on most vnode and file systems operations and to take actions, directly or indirectly, on the operations being performed. Still, there are some limitations to Kauth which are pointed out in the santa-driver document. For more information on the santa-driver KEXT see the [santa-driver.md](../details/santa-driver.md) document.
#### Flow of an execve()
This is a high level overview of the binary whitelisting / blacklisting decision process. For a more detailed account of each part, see the respective documentation. This flow does not cover the logging component of Santa, see the [logs.md](../details/logs.md) documentation for more info.
###### Kernel Space
0. santa-driver registers itself as a `KAUTH_SCOPE_VNODE` listener. This flow follows how santa-driver handles `KAUTH_VNODE_EXECUTE` events.
1. A santa-driver Kauth callback function is executed by the kernel when a process is trying to `execve()`. In most cases, the `execve()` takes place right after a process calls `fork()` to start a new process. This function is running on a kernel thread representing the new process. Information on where to find the executable is provided. This information is known as the `vnode_id`.
2. santa-driver then checks if its cache has an allow or deny entry for the `vnode_id`. If so it returns that decision to the Kauth KPI.
* If Kauth receives a deny, it will stop the `execve()` from taking place.
* If Kauth receives an allow, it will defer the decision. If there are other Kauth listeners, they also have a chance deny or defer.
3. If there is no entry for the `vnode_id` in the cache a few actions occur:
* santa-driver hands off the decision making to santad.
* A new entry is created in the cache for the `vnode_id` with a special value of `ACTION_REQUEST_BINARY`. This is used as a placeholder until the decision from santad comes back. If another process tries to `execve()` the same `vnode_id`, santa-driver will have that thread wait for the in-flight decision from santad. All subsequent `execve()`s for the same `vnode_id` will use the decision in the cache as explained in #2, until the cache is invalidated. See the [santa-driver.md](../details/santa-driver.md) document for more details on the cache invalidation.
* If the executing file is written to while any of the threads are waiting for a response the `ACTION_REQUEST_BINARY` entry is removed, forcing the decision-making process to be restarted.
###### User Space
1. santad is listening for decision requests from santa-driver.
* More information is collected about the executable that lives at the `vnode_id`. Since this codepath has a sleeping kernel thread waiting for a decision, extra care is taken to be as performant as possible.
2. santad uses the information it has gathered to make a decision to allow or deny the `execve()`. There are more details on how these decisions are made in the [rules.md](../details/rules.md) and [scopes.md](../details/scopes.md) documents.
3. The decision is posted back to santa-driver.
4. If there was a deny decision, a message is sent to Santa GUI to display a user popup notification.

View File

@@ -0,0 +1,27 @@
# Syncing Overview
#### Background
Santa can be run and configured without a sync server. Doing so will enable an admin to configure rules with the `santactl rule` command. Using a sync server will enable an admin to configures rules and multiple other settings from the sync server itself. Santa was designed from the start with a sync server in mind. This allows an admin to easily configure and sync rules across a fleet of macOS systems. This document explains the syncing process.
#### Flow of a full sync
This is a high level overview of the syncing process. For a more a more detailed account of each part, see the respective documentation. The santaclt binary can be run in one of two modes, daemon and non-daemon. The non-daemon mode does one full sync and exits. This is the typical way a user will interact with Santa, mainly to force a full sync. The daemon mode is used by santad to schedule full syncs, listen for push notifications and upload events.
0. When the santad process starts up, it looks for a `SyncBaseURL` key/value in the config. If one exists it will `fork()` and `execve()` `santactl sync —-daemon`. Before the new process calls `execve()`, all privileges are dropped. All privileged actions are then restricted to the XPC interface made available to santactl by santad. Since this santactl process is running as a daemon it too exports an XPC interface so santad can interact with the process efficiently and securely. To ensure syncing reliability santad will restart the santactl daemon if it is killed or crashes.
1. The santactl daemon process now schedules a full sync for 15 sec in the future. The 15 sec is used to let santad settle before santactl starts sending rules from the sync server to process.
2. The full sync starts. There are a number of stages to a full sync:
1. preflight: The sync server can set various settings for Santa.
2. logupload (optional): The sync server can request that the Santa logs be uploaded to an endpoint.
3. eventupload (optional): If Santa has generated events, it will upload them to the sync-server.
4. ruledownload: Download rules from the sync server.
5. postflight: Updates timestamps for successful syncs.
3. After the full sync completes a new full sync will be scheduled, by default this will be 10min. However there are a few ways to manipulate this:
1. The sync server can send down a configuration in the preflight to override the 10min interval. It can be anything greater than 10min.
2. Firebase Cloud Messaging (FCM) can be used. The sync server can send down a configuration in the preflight to have the santactl daemon to start listening for FCM messages. If a connection to FCM is made, the full sync interval drops to a default of 4 hours. This can be further configured by a preflight configuration. The FCM connection allows the sync-sever to talk directly with Santa. This way we can reduce polling the sync server dramatically.
4. Full syncs will continue to take place at their configured interval. If configured FCM messages will continue to be digested and acted upon.
#### santactl XPC interface
When running as a daemon, the santactl process makes available an XPC interface for use by santad. This allows santad to send blocked binary or bundle events directly to santactl for immediate upload to the sync-server, enabling a smoother user experience. The binary that was blocked on macOS is immediately available for viewing or handling on the sync-server.

3
Docs/theme/Santa.css Normal file
View File

@@ -0,0 +1,3 @@
.wy-side-nav-search {
background-color: rgb(253, 67, 69);
}

25
Fuzzing/CMakeLists.txt Normal file
View File

@@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.10.0)
set(LIBFUZZER_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libFuzzer/bin/libFuzzer.a")
function(ImportLibFuzzer)
add_custom_command(
OUTPUT "${LIBFUZZER_PATH}"
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/libFuzzer/build.sh"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/libFuzzer/build.sh"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/libFuzzer"
COMMENT "Building libFuzzer..."
)
add_custom_target(libfuzzer_builder DEPENDS "${LIBFUZZER_PATH}")
endfunction()
function(main)
ImportLibFuzzer()
add_subdirectory(santacache)
add_subdirectory(santad)
add_subdirectory(santactl)
endfunction()
main()

4
Fuzzing/libFuzzer/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
bin
llvm-*.src
llvm-*.src.tar.xz

109
Fuzzing/libFuzzer/build.sh Executable file
View File

@@ -0,0 +1,109 @@
#!/usr/bin/env bash
LLVM_VERSION='5.0.1'
LLVM_COMPILERRT_TARBALL_NAME="llvm-${LLVM_VERSION}.src.tar.xz"
LLVM_COMPILERRT_SRC_FOLDER_NAME=`echo "${LLVM_COMPILERRT_TARBALL_NAME}" | cut -d '.' -f 1-4`
LLVM_COMPILERRT_TARBALL_URL="http://releases.llvm.org/${LLVM_VERSION}/${LLVM_COMPILERRT_TARBALL_NAME}"
LIBFUZZER_FOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
LOG_FILE=`mktemp`
main() {
echo "libFuzzer build script"
echo " > Checking dependencies..."
checkDependencies || return 1
echo " > Entering libFuzzer folder..."
cd "${LIBFUZZER_FOLDER}" > /dev/null 2>&1
if [ $? -ne 0 ] ; then
echo "Failed to enter the libFuzzer folder: ${LIBFUZZER_FOLDER}"
return 1
fi
if [ ! -f "${LLVM_COMPILERRT_TARBALL_NAME}" ] ; then
echo " > Downloading the LLVM tarball..."
curl "${LLVM_COMPILERRT_TARBALL_URL}" -o "${LLVM_COMPILERRT_TARBALL_NAME}" > "${LOG_FILE}" 2>&1
if [ $? -ne 0 ] ; then
dumpLogFile "Failed to download the LLVM tarball"
return 1
fi
else
echo " > An existing LLVM tarball was found"
fi
if [ -d "${LLVM_COMPILERRT_SRC_FOLDER_NAME}" ] ; then
echo " > Deleting existing LLVM folder..."
rm -rf "${LLVM_COMPILERRT_SRC_FOLDER_NAME}" > "${LOG_FILE}" 2>&1
if [ $? -ne 0 ] ; then
dumpLogFile "Failed to delete the existing source folder"
return 1
fi
fi
echo " > Extracting the LLVM tarball..."
tar xf "${LLVM_COMPILERRT_TARBALL_NAME}" > "${LOG_FILE}" 2>&1
if [ $? -ne 0 ] ; then
rm "${LLVM_COMPILERRT_TARBALL_NAME}" "${LLVM_COMPILERRT_SRC_FOLDER_NAME}"
dumpLogFile "Failed to extract the LLVM tarball"
return 1
fi
if [ -d "bin" ] ; then
echo " > Deleting existing bin folder..."
rm -rf "bin" > "${LOG_FILE}" 2>&1
if [ $? -ne 0 ] ; then
dumpLogFile "Failed to delete the existing bin folder"
return 1
fi
fi
mkdir "bin" > "${LOG_FILE}" 2>&1
if [ $? -ne 0 ] ; then
dumpLogFile "Failed to create the bin folder"
return 1
fi
echo " > Building libFuzzer..."
( cd "bin" && "../${LLVM_COMPILERRT_SRC_FOLDER_NAME}/lib/Fuzzer/build.sh" ) > "${LOG_FILE}" 2>&1
if [ $? -ne 0 ] ; then
dumpLogFile "Failed to build the library"
return 1
fi
printf "\nFinished building libFuzzer\n"
rm "${LOG_FILE}"
return 0
}
checkDependencies() {
executable_list=( "clang++" "curl" "tar" )
for executable in "${executable_list[@]}" ; do
which "${executable}" > /dev/null 2>&1
if [ $? -ne 0 ] ; then
echo "The following program was not found: ${executable}"
return 1
fi
done
return 0
}
dumpLogFile() {
if [ $# -eq 1 ] ; then
local message="$1"
else
local message="An error has occurred"
fi
printf "${message}\n"
printf "Log file follows\n===\n"
cat "${LOG_FILE}"
printf "\n===\n"
rm "${LOG_FILE}"
}
main $@
exit $?

3
Fuzzing/santacache/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
santacache.dSYM
santacache

View File

@@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.10.0)
project(santacache_fuzzer)
set(CMAKE_CXX_STANDARD 11)
function(main)
set(PROJECT_SOURCEFILES
src/main.cpp
)
add_executable("${PROJECT_NAME}" EXCLUDE_FROM_ALL ${PROJECT_SOURCEFILES})
add_dependencies("${PROJECT_NAME}" libfuzzer_builder)
target_link_libraries("${PROJECT_NAME}" PRIVATE "${LIBFUZZER_PATH}")
target_include_directories("${PROJECT_NAME}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/common"
"${CMAKE_SOURCE_DIR}/Source/santa-driver"
)
target_compile_options("${PROJECT_NAME}" PRIVATE
-g -O0 -Wno-deprecated-declarations
-fsanitize-coverage=trace-pc-guard
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
target_link_libraries("${PROJECT_NAME}" PRIVATE
-fsanitize=address -fno-omit-frame-pointer
-mno-omit-leaf-frame-pointer
)
AddFuzzTarget("${PROJECT_NAME}" 16 60 false)
endfunction()
main()

Binary file not shown.

View File

@@ -0,0 +1,41 @@
/// 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.
#include <SantaCache.h>
#include <iostream>
#include <cstdint>
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
static SantaCache<uint64_t, uint64_t> decision_cache(5000, 2);
std::uint64_t fields[2] = {};
if (size > 16) {
std::cout << "Invalid size! Start with -max_len=16\n";
return 1;
}
std::memcpy(fields, data, size);
decision_cache.set(fields[0], fields[1]);
auto returned_value = decision_cache.get(fields[0]);
if (returned_value != fields[1]) {
std::cout << fields[0] << ", " << fields[1] << " -> " << returned_value << "\n";
return 1;
}
return 0;
}

View File

@@ -0,0 +1,61 @@
cmake_minimum_required(VERSION 3.10.0)
project(santactl_fuzzer)
set(CMAKE_CXX_STANDARD 11)
function(main)
set(PROJECT_SOURCEFILES
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncRuleDownload.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncConstants.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncStage.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncState.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTRule.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTLogging.m"
src/main.mm
)
add_executable("${PROJECT_NAME}" EXCLUDE_FROM_ALL ${PROJECT_SOURCEFILES})
target_compile_options("${PROJECT_NAME}" PRIVATE
-fobjc-arc -Wno-everything -fmodules -fcxx-modules
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
target_compile_definitions("${PROJECT_NAME}" PRIVATE
COCOAPODS=1
)
target_include_directories("${PROJECT_NAME}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync"
"${CMAKE_SOURCE_DIR}/Source/common"
"${CMAKE_SOURCE_DIR}/Source/santad"
)
target_link_libraries("${PROJECT_NAME}" PRIVATE
MOLCertificate MOLCodesignChecker
MOLAuthenticatingURLSession FMDB MOLFCMClient
)
#
# Add libfuzzer
#
add_dependencies("${PROJECT_NAME}" libfuzzer_builder)
target_link_libraries("${PROJECT_NAME}" PRIVATE "${LIBFUZZER_PATH}")
target_compile_options("${PROJECT_NAME}" PRIVATE
-g -O0 -Wno-deprecated-declarations
-fsanitize-coverage=trace-pc-guard
)
target_link_libraries("${PROJECT_NAME}" PRIVATE
-fsanitize=address -fno-omit-frame-pointer
-mno-omit-leaf-frame-pointer
)
AddFuzzTarget("${PROJECT_NAME}" 428 60 false)
endfunction()
main()

View File

@@ -0,0 +1,16 @@
{
"rules": [
{
"rule_type": "BINARY",
"policy": "BLACKLIST",
"sha256": "2dc104631939b4bdf5d6bccab76e166e37fe5e1605340cf68dab919df58b8eda",
"custom_msg": "blacklist firefox"
},
{
"rule_type": "CERTIFICATE",
"policy": "BLACKLIST",
"sha256": "e7726cf87cba9e25139465df5bd1557c8a8feed5c7dd338342d8da0959b63c8d",
"custom_msg": "blacklist dash app certificate"
}
]
}

View File

@@ -0,0 +1,62 @@
/// 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.
#include <iostream>
#include <cstdint>
#include <vector>
#include <SNTCommandSyncRuleDownload.h>
#include <SNTCommandSyncState.h>
#include <SNTCommandSyncConstants.h>
#include <SNTRule.h>
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
NSData *buffer = [NSData dataWithBytes:static_cast<const void *>(data) length:size];
if (!buffer) {
return 0;
}
NSError *error;
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:buffer options:0 error:&error];
if (!response) {
return 0;
}
if (![response isKindOfClass:[NSDictionary class]]) {
return 0;
}
if (![response objectForKey:kRules]) {
return 0;
}
SNTCommandSyncState *state = [[SNTCommandSyncState alloc] init];
if (!state) {
return 0;
}
SNTCommandSyncRuleDownload *obj = [[SNTCommandSyncRuleDownload alloc] initWithState:state];
if (!obj) {
return 0;
}
for (NSDictionary *ruleDict in response[kRules]) {
SNTRule *rule = [obj ruleFromDictionary:ruleDict];
if (rule) {
std::cerr << "Rule: " << [[rule description] UTF8String] << "\n";
}
}
return 0;
}

View File

@@ -0,0 +1,109 @@
cmake_minimum_required(VERSION 3.10.0)
project(santad_fuzzer)
set(CMAKE_CXX_STANDARD 11)
function(main)
GenerateFuzzTarget(src/databaseRuleAddRules.mm 45 60 true)
GenerateFuzzTarget(src/checkCacheForVnodeID.mm 16 60 true)
GenerateFuzzTarget(src/databaseRemoveEventsWithIDs.mm 80 60 true)
endfunction()
function(GenerateFuzzTarget source_file data_size timeout run_as_root)
# Generate one new project for each source file in the 'src' folder. Copy
# the project source files and settings from santactl
set(PROJECT_SANTACTLSOURCEFILES
"${CMAKE_SOURCE_DIR}/Source/santactl/SNTCommand.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/SNTCommand.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/SNTCommandController.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/SNTCommandController.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Resources/santactl-Info.plist"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandBundleInfo.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandCheckCache.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandFileInfo.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandFlushCache.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandRule.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandStatus.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandVersion.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/NSData+Zlib.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/NSData+Zlib.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSync.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncConstants.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncConstants.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncEventUpload.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncEventUpload.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncLogUpload.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncLogUpload.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncManager.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncManager.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncPostflight.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncPostflight.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncPreflight.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncPreflight.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncRuleDownload.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncRuleDownload.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncStage.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncStage.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncState.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncState.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTConfigurator.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTFileInfo.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTRule.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTStoredEvent.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTSystemInfo.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCControlInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCSyncdInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTLogging.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTDropRootPrivs.m"
)
get_filename_component(target_name "${source_file}" NAME_WE)
set(target_name "santad_${target_name}_fuzzer")
add_executable("${target_name}" EXCLUDE_FROM_ALL ${source_file} ${PROJECT_SANTACTLSOURCEFILES})
target_compile_options("${target_name}" PRIVATE
-fobjc-arc -Wno-everything -fmodules -fcxx-modules
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
target_compile_definitions("${target_name}" PRIVATE
COCOAPODS=1
)
target_include_directories("${target_name}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/santactl"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync"
"${CMAKE_SOURCE_DIR}/Source/santad"
"${CMAKE_SOURCE_DIR}/Source/common"
)
target_link_libraries("${target_name}" PRIVATE
MOLCertificate MOLCodesignChecker
MOLAuthenticatingURLSession FMDB MOLFCMClient
MOLXPCConnection
)
#
# Add libfuzzer
#
add_dependencies("${target_name}" libfuzzer_builder)
target_link_libraries("${target_name}" PRIVATE "${LIBFUZZER_PATH}")
target_compile_options("${target_name}" PRIVATE
-g -O0 -Wno-deprecated-declarations
-fsanitize-coverage=trace-pc-guard
)
target_link_libraries("${target_name}" PRIVATE
-fsanitize=address -fno-omit-frame-pointer
-mno-omit-leaf-frame-pointer
)
AddFuzzTarget("${target_name}" ${data_size} ${timeout} ${run_as_root})
endfunction()
main()

View File

@@ -0,0 +1 @@
К'.p▒└G╗М┐║ЙSЮ╝и▌РУерЭxt1iАЫШ9ы*H╩4R"═©$-├Уww╙+Р╝╘[┼иу╧oС┬ОwRpЗя≤х°е

View File

@@ -0,0 +1,55 @@
/// 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.
#include <iostream>
#include <cstdint>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCommandController.h"
#import "SNTRule.h"
#import "SNTXPCControlInterface.h"
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
if (size > 16) {
std::cerr << "Invalid buffer size of " << size
<< " (should be <= 16)" << std::endl;
return 1;
}
santa_vnode_id_t vnodeID = {};
std::memcpy(&vnodeID, data, size);
MOLXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
daemonConn.invalidationHandler = ^{
printf("An error occurred communicating with the daemon, is it running?\n");
exit(1);
};
[daemonConn resume];
[[daemonConn remoteObjectProxy] checkCacheForVnodeID:vnodeID
withReply:^(santa_action_t action) {
if (action == ACTION_RESPOND_ALLOW) {
std::cerr << "File exists in [whitelist] kernel cache" << std::endl;;
} else if (action == ACTION_RESPOND_DENY) {
std::cerr << "File exists in [blacklist] kernel cache" << std::endl;;
} else if (action == ACTION_UNSET) {
std::cerr << "File does not exist in cache" << std::endl;;
}
}];
return 0;
}

View File

@@ -0,0 +1,51 @@
/// 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.
#include <iostream>
#include <cstdint>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCommandController.h"
#import "SNTRule.h"
#import "SNTXPCControlInterface.h"
#pragma pack(push, 1)
#pragma pack(pop)
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
auto *eventId = reinterpret_cast<const std::uint64_t *>(data);
std::size_t eventIdCount = size / sizeof(std::uint64_t);
if (eventIdCount == 0) {
return 0;
}
MOLXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
daemonConn.invalidationHandler = ^{
printf("An error occurred communicating with the daemon, is it running?\n");
exit(1);
};
[daemonConn resume];
NSMutableSet *eventIds = [NSMutableSet setWithCapacity:eventIdCount];
for (std::size_t i = 0; i < eventIdCount; i++) {
auto id = [NSNumber numberWithInteger:eventId[i]];
[eventIds addObject:id];
}
[[daemonConn remoteObjectProxy] databaseRemoveEventsWithIDs:[eventIds allObjects]];
return 0;
}

View File

@@ -0,0 +1,73 @@
/// 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.
#include <iostream>
#include <cstdint>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCommandController.h"
#import "SNTRule.h"
#import "SNTXPCControlInterface.h"
#pragma pack(push, 1)
struct InputData {
std::uint32_t cleanSlate;
std::uint32_t state;
std::uint32_t type;
char hash[33];
};
#pragma pack(pop)
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
if (size > sizeof(InputData)) {
std::cerr << "Invalid buffer size of " << size
<< " (should be <= " << sizeof(InputData)
<< ")" << std::endl;
return 1;
}
InputData input_data = {};
std::memcpy(&input_data, data, size);
SNTRule *newRule = [[SNTRule alloc] init];
newRule.state = (SNTRuleState) input_data.state;
newRule.type = (SNTRuleType) input_data.type;
newRule.shasum = @(input_data.hash);
newRule.customMsg = @"";
MOLXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
daemonConn.invalidationHandler = ^{
printf("An error occurred communicating with the daemon, is it running?\n");
exit(1);
};
[daemonConn resume];
[[daemonConn remoteObjectProxy] databaseRuleAddRules:@[newRule]
cleanSlate:NO
reply:^(NSError *error) {
if (!error) {
if (newRule.state == SNTRuleStateRemove) {
printf("Removed rule for SHA-256: %s.\n", [newRule.shasum UTF8String]);
} else {
printf("Added rule for SHA-256: %s.\n", [newRule.shasum UTF8String]);
}
}
}];
return 0;
}

51
Podfile
View File

@@ -1,12 +1,59 @@
platform :osx, "10.8"
platform :osx, "10.9"
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
target :santactl do
pod 'FMDB'
pod 'MOLAuthenticatingURLSession'
pod 'MOLCertificate'
pod 'MOLCodesignChecker'
pod 'MOLFCMClient', '~> 1.3'
pod 'MOLXPCConnection'
end
target :LogicTests do
pod 'OCMock'
pod 'FMDB'
pod 'MOLAuthenticatingURLSession'
pod 'MOLCertificate'
pod 'MOLCodesignChecker'
pod 'MOLXPCConnection'
pod 'OCMock'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
if config.name != 'Release' then
break
end
# This is necessary to get FMDB to not NSLog stuff.
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ''
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] <<= "NDEBUG=1"
# Enable more compiler optimizations.
config.build_settings['GCC_OPTIMIZATION_LEVEL'] = 'fast'
config.build_settings['LLVM_LTO'] = 'YES'
end
end
end

View File

@@ -1,17 +1,46 @@
PODS:
- FMDB (2.4):
- FMDB/standard (= 2.4)
- FMDB/common (2.4)
- FMDB/standard (2.4):
- FMDB/common
- OCMock (3.1.1)
- FMDB (2.7.2):
- FMDB/standard (= 2.7.2)
- FMDB/standard (2.7.2)
- MOLAuthenticatingURLSession (2.4):
- MOLCertificate (~> 1.8)
- MOLCertificate (1.9)
- MOLCodesignChecker (1.10):
- MOLCertificate (~> 1.8)
- MOLFCMClient (1.8):
- MOLAuthenticatingURLSession (~> 2.4)
- MOLXPCConnection (1.2):
- MOLCodesignChecker (~> 1.9)
- OCMock (3.4.2)
DEPENDENCIES:
- FMDB
- MOLAuthenticatingURLSession
- MOLCertificate
- MOLCodesignChecker
- MOLFCMClient (~> 1.3)
- MOLXPCConnection
- OCMock
SPEC CHECKSUMS:
FMDB: 0b2fa25e5264ef177973c0cb8c02c711107979aa
OCMock: f6cb8c162ab9d5620dddf411282c7b2c0ee78854
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- FMDB
- MOLAuthenticatingURLSession
- MOLCertificate
- MOLCodesignChecker
- MOLFCMClient
- MOLXPCConnection
- OCMock
COCOAPODS: 0.35.0
SPEC CHECKSUMS:
FMDB: 6198a90e7b6900cfc046e6bc0ef6ebb7be9236aa
MOLAuthenticatingURLSession: c238aa1c9a7b1077eb39a6f40204bfe76a7d204e
MOLCertificate: e9e88a396c57032cab847f51a46e20c730cd752a
MOLCodesignChecker: b0d5db9d2f9bd94e0fd093891a5d40e5ad77cbc0
MOLFCMClient: 2bfbacd45cc11e1ca3c077e97b80401c4e4a54f1
MOLXPCConnection: c27af5cb1c43b18319698b0e568a8ddc2fc1e306
OCMock: ebe9ee1dca7fbed0ff9193ac0b3e2d8862ea56f6
PODFILE CHECKSUM: ddca043a7ace9ec600c108621c56d13a50d17236
COCOAPODS: 1.5.3

148
README.md
View File

@@ -1,34 +1,73 @@
Santa
[![Build Status](https://travis-ci.org/google/santa.png?branch=master)](https://travis-ci.org/google/santa)
[![Documentation Status](https://readthedocs.org/projects/santa/badge/?version=latest)](https://santa.readthedocs.io/en/latest/?badge=latest)
=====
Santa is a binary whitelisting/blacklisting system for Mac OS X. It consists of
<p align="center">
<a href="#santa--">
<img src="./Source/SantaGUI/Resources/Images.xcassets/AppIcon.appiconset/santa-hat-icon-128.png" alt="Santa Icon" />
</a>
</p>
Santa is a binary whitelisting/blacklisting system for macOS. It consists of
a kernel extension that monitors for executions, a userland daemon that makes
execution decisions based on the contents of a SQLite database, a GUI agent that
notifies the user in case of a block decision and a command-line utility for
managing the system and synchronizing the database with a server.
Santa is not yet a 1.0. We're writing more tests, fixing bugs, working on TODOs
Santa is not yet at 1.0. We're writing more tests, fixing bugs, working on TODOs
and finishing up a security audit.
Santa is named because it keeps track of binaries that are naughty and nice.
It is named Santa because it keeps track of binaries that are naughty or nice.
Santa is a project of Google's Macintosh Operations Team.
Features
Docs
========
The Santa docs are stored in the [Docs](https://github.com/google/santa/blob/master/Docs) directory. A Read the Docs instance is available here: https://santa.readthedocs.io.
Admin-Related Features
========
* Multiple modes: MONITOR and LOCKDOWN. In MONITOR mode all binaries except
those marked as blacklisted will be allowed to run, whilst being logged and
recorded in the database. In LOCKDOWN mode, only whitelisted binaries are
* Multiple modes: In the default MONITOR mode, all binaries except
those marked as blacklisted will be allowed to run, whilst being logged and recorded in the events database. In LOCKDOWN mode, only whitelisted binaries are
allowed to run.
* Codesign listing: Binaries can be whitelisted/blacklisted by their signing
certificate, so you can trust/block all binaries by a given publisher. The
binary will only be whitelisted by certificate if its signature validates
correctly. However, a decision for a binary will override a decision for a
certificate; i.e. you can whitelist a certificate while blacklisting a binary
signed by that certificate or vice-versa.
* Event logging: When the kext is loaded, all binary launches are logged.
When in either mode, all unknown or denied binaries are stored in the database to enable later aggregation.
* Certificate-based rules, with override levels: Instead of relying on a binary's hash (or 'fingerprint'), executables can be whitelisted/blacklisted by their signing
certificate. You can therefore trust/block all binaries by a given publisher that were signed with that cert across version updates. A
binary can only be whitelisted by its certificate if its signature validates
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 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.
Intentions and Expectations
===========================
No single system or process will stop *all* attacks, or provide 100% security.
Santa is written with the intention of helping protect users from themselves.
People often download malware and trust it, giving the malware credentials, or
allowing unknown software to exfiltrate more data about your system. As a
centrally managed component, Santa can help stop the spread of malware among a
large fleet of machines. Independently, Santa can aid in analyzing what is
running on your computer.
Santa is part of a defense-in-depth strategy, and you should continue to protect
hosts in whatever other ways you see fit.
Get Help
========
If you have questions or otherwise need help getting started, the
[santa-dev](https://groups.google.com/forum/#!forum/santa-dev) group is a
great place. Please consult the [wiki](https://github.com/google/santa/wiki) and [issues](https://github.com/google/santa/issues) as well.
Security and Performance-Related Features
============
* In-kernel caching: whitelisted binaries are cached in the kernel so the
processing required to make a request is only done if the binary
isn't already cached.
@@ -38,41 +77,32 @@ daemon, the GUI agent and the command-line utility) communicate with each other
using XPC and check that their signing certificates are identical before any
communication is accepted.
* Event logging: all executions processed by the userland agent are logged and
all unknown or denied binaries are also stored in the database for upload to a
server.
* Kext uses only KPIs: the kernel extension only uses provided kernel
programming interfaces to do its job. This means that the kext code should
continue to work across OS versions.
Known Issues
============
Santa is not yet at 1.0 and we have some known issues to be aware of:
Santa is not yet a 1.0 and we have some known issues to be aware of:
* Potential race-condition: we currently have a single TODO in the kext code to
investigate a potential race condition where a binary is executed and then very
quickly modified between the kext getting the SHA-1 and the decision being made.
* Santa only blocks execution (execve and variants), it doesn't protect against
dynamic libraries loaded with dlopen, libraries on disk that have been replaced, or
libraries loaded using `DYLD_INSERT_LIBRARIES`. As of version 0.9.1 we *do* address [__PAGEZERO missing issues](b87482e) that were exploited in some versions of macOS. We are working on also protecting against similar avenues of attack.
* Kext communication security: the kext will only accept a connection from a
single client at a time and said client must be running as root. We haven't yet
found a good way to ensure the kext only accepts connections from a valid client,
short of hardcoding the SHA-1 in the kext. This shouldn't present a huge problem
as the daemon is loaded on boot-up by launchd, so any later attempts to connect
will be blocked.
found a good way to ensure the kext only accepts connections from a valid client.
* Database protection: the SQLite database is installed with permissions so that
only the root user can read/write it. We're considering approaches to secure
this further.
* Sync client: the command-line client includes a command to synchronize with a
management server, including the uploading of events that have occurred on the
machine and to download 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!)
* 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. 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,
@@ -81,11 +111,20 @@ of temporary generated scripts, which we can't possibly whitelist and not doing
so would cause problems. We're happy to revisit this (or at least make it an
option) if it would be useful to others.
* Documentation: There currently isn't any.
* Documentation: This is currently limited.
* Tests: There aren't enough of them.
Building
Screenshots
===========
A tool like Santa doesn't really lend itself to screenshots, so here's a video instead.
<p align="center">
<img src="https://zippy.gfycat.com/MadFatalAmphiuma.gif" alt="Santa Block Video" />
</p>
Building with Xcode
========
```sh
@@ -103,14 +142,35 @@ rake build:debug
Note: the Xcode project is setup to use any installed "Mac Developer" certificate
and for security-reasons parts of Santa will not operate properly if not signed.
For more details on building see the [building.md](https://github.com/google/santa/blob/master/Docs/development/building.md) document.
Building with CMake
========
### General steps
1. Install Xcode and the command line tools
2. Install CMake using homebrew
3. Clone the santa source code repository
4. Set the signing key
5. Create a build folder and configure the project
6. Run make
Example
git clone https://github.com/google/santa.git
mkdir build
cd build
export CODESIGN_IDENTITY=XXX
cmake ../santa
make -j `sysctl -n hw.ncpu`
The CODESIGN_IDENTITY parameter can also be passed directly to CMake: cmake -DCODESIGN_IDENTITY=XXX /path/to/source/code
Kext Signing
============
10.9 requires a special Developer ID certificate to sign kernel extensions and
if the kext is not signed with one of these special certificates a warning will
be shown when loading the kext for the first time. In 10.10 this is a hard error
and the kext will not load at all unless the machine is booted with a debug
boot-arg.
Kernel extensions on macOS 10.9 and later must be signed using an Apple-provided
Developer ID certificate with a kernel extension flag. Without it, the only way
to load an extension is to enable kext-dev-mode or disable SIP, depending on the
OS version.
There are two possible solutions for this, for distribution purposes:
@@ -125,17 +185,11 @@ and distribute a new version of the pre-signed kext.
Apple will only grant this for broad distribution within an organization, they
won't issue them just for testing purposes.
If you just want to locally test changes to the kext code, you should enable
kext-dev mode, instructions for which can be found on the Apple developer site.
Contributing
============
Patches to this project are very much welcome. Please see the [CONTRIBUTING](https://github.com/google/santa/blob/master/CONTRIBUTING.md)
file.
Disclaimer
==========
This is **not** an official Google product.

159
Rakefile
View File

@@ -1,68 +1,72 @@
require 'timeout'
require 'openssl'
WORKSPACE = 'Santa.xcworkspace'
DEFAULT_SCHEME = 'All'
OUTPUT_PATH = 'Build'
DIST_PATH = 'Dist'
BINARIES = ['Santa.app', 'santa-driver.kext', 'santad', 'santactl']
PLISTS = ['Source/SantaGUI/Resources/Santa-Info.plist',
'Source/santad/Resources/santad-Info.plist',
'Source/santa-driver/Resources/santa-driver-Info.plist',
'Source/santactl/Resources/santactl-Info.plist']
XCODE_DEFAULTS = "-workspace #{WORKSPACE} -scheme #{DEFAULT_SCHEME} -derivedDataPath #{OUTPUT_PATH} -parallelizeTargets"
WORKSPACE = 'Santa.xcworkspace'
DEFAULT_SCHEME = 'All'
OUTPUT_PATH = 'Build'
BINARIES = ['Santa.app', 'santa-driver.kext']
DSYMS = ['Santa.app.dSYM', 'santa-driver.kext.dSYM', 'santad.dSYM', 'santactl.dSYM']
XCPRETTY_DEFAULTS = '-sc'
XCODEBUILD_DEFAULTS = "-workspace #{WORKSPACE} -derivedDataPath #{OUTPUT_PATH} -parallelizeTargets"
DEVTEAM_FILE = 'Source/DevelopmentTeam.xcconfig'
DEVTEAM_CERT_CN = 'Mac Developer'
$DISABLE_XCPRETTY = false
task :default do
system("rake -sT")
end
def run_and_output_on_fail(cmd)
output=`#{cmd} 2>&1`
if not $?.success?
raise output
def xcodebuild(opts)
command = "xcodebuild #{XCODEBUILD_DEFAULTS} #{opts}"
if not $DISABLE_XCPRETTY
command << " | xcpretty #{XCPRETTY_DEFAULTS} && exit ${PIPESTATUS[0]}"
end
if system command
puts "\e[32mPass\e[0m"
else
raise "\e[31mFail\e[0m"
end
end
def run_and_output_with_color(cmd)
output=`#{cmd} 2>&1`
has_output = false
output.scan(/((Test Suite|Test Case|Executed).*)$/) do |match|
has_output = true
out = match[0]
if out.include?("passed")
puts "\e[32m#{out}\e[0m"
elsif out.include?("failed")
puts "\e[31m#{out}\e[0m"
else
puts out
def xcodebuilddir
if not $xcode_build_dir
output = `xcodebuild #{XCODEBUILD_DEFAULTS} -scheme All -showBuildSettings`
if match = output.match(/BUILD_DIR = (.*)/)
$xcode_build_dir = match.captures.first
puts "Found Xcode build dir #{$xcode_build_dir}"
end
end
if not has_output
raise output
end
$xcode_build_dir
end
task :init do
unless File.exists?(WORKSPACE) and File.exists?('Pods')
puts "Workspace is missing, running 'pod install'"
puts "Pods missing, running 'pod install'"
system "pod install" or raise "CocoaPods is not installed. Install with 'sudo gem install cocoapods'"
end
unless system 'xcpretty -v >/dev/null 2>&1'
puts "xcpretty is not installed. Install with 'sudo gem install xcpretty'"
$DISABLE_XCPRETTY = true
end
cert_pem = `security find-certificate -p -c '#{DEVTEAM_CERT_CN}'`
cert = OpenSSL::X509::Certificate.new cert_pem
team_id = cert.subject.to_a.find {|f| f[0] == "OU"}[1]
File.open(DEVTEAM_FILE, 'w') { |f|
f.puts("// This file is auto-generated. Do not edit manually")
f.puts("DEVELOPMENT_TEAM = #{team_id}")
}
end
task :remove_existing do
system 'sudo rm -rf /santa-driver.kext'
system 'sudo rm -rf /Library/Extensions/santa-driver.kext'
system 'sudo rm -rf /Applications/Santa.app'
system 'sudo rm /usr/libexec/santad'
system 'sudo rm /usr/sbin/santactl'
end
desc "Clean"
task :clean => :init do
puts "Cleaning"
run_and_output_on_fail("xcodebuild #{XCODE_DEFAULTS} clean")
FileUtils.rm_rf(OUTPUT_PATH)
FileUtils.rm_rf(DIST_PATH)
xcodebuild("-scheme All clean")
end
# Build
@@ -80,7 +84,7 @@ namespace :build do
task :build, [:configuration] => :init do |t, args|
config = args[:configuration]
puts "Building with configuration: #{config}"
run_and_output_on_fail("xcodebuild #{XCODE_DEFAULTS} -configuration #{config} build")
xcodebuild("-scheme All -configuration #{config} build")
end
end
@@ -100,16 +104,15 @@ namespace :install do
task :install, [:configuration] do |t, args|
config = args[:configuration]
system 'sudo cp conf/com.google.santad.plist /Library/LaunchDaemons'
system 'sudo cp conf/com.google.santasync.plist /Library/LaunchDaemons'
system 'sudo cp conf/com.google.santagui.plist /Library/LaunchAgents'
system 'sudo cp conf/com.google.santa.asl.conf /etc/asl'
system 'sudo cp conf/com.google.santa.newsyslog.conf /etc/newsyslog.d/'
system '/usr/bin/killall -HUP syslogd'
Rake::Task['build:build'].invoke(config)
puts "Installing with configuration: #{config}"
Rake::Task['remove_existing'].invoke()
system "sudo cp -r #{OUTPUT_PATH}/Products/#{config}/santa-driver.kext /"
system "sudo cp -r #{OUTPUT_PATH}/Products/#{config}/Santa.app /Applications"
system "sudo cp #{OUTPUT_PATH}/Products/#{config}/santad /usr/libexec"
system "sudo cp #{OUTPUT_PATH}/Products/#{config}/santactl /usr/sbin"
system "sudo cp -r #{xcodebuilddir}/#{config}/santa-driver.kext /Library/Extensions"
system "sudo cp -r #{xcodebuilddir}/#{config}/Santa.app /Applications"
end
end
@@ -117,22 +120,29 @@ end
task :dist do
desc "Create distribution folder"
Rake::Task['clean'].invoke()
Rake::Task['build:build'].invoke("Release")
FileUtils.rm_rf(DIST_PATH)
dist_path = "santa-#{`defaults read #{xcodebuilddir}/Release/santa-driver.kext/Contents/Info.plist CFBundleVersion`.strip}"
FileUtils.mkdir_p("#{DIST_PATH}/binaries")
FileUtils.mkdir_p("#{DIST_PATH}/conf")
FileUtils.mkdir_p("#{DIST_PATH}/dsym")
FileUtils.rm_rf(dist_path)
FileUtils.mkdir_p("#{dist_path}/binaries")
FileUtils.mkdir_p("#{dist_path}/conf")
FileUtils.mkdir_p("#{dist_path}/dsym")
BINARIES.each do |x|
FileUtils.cp_r("#{OUTPUT_PATH}/Products/Release/#{x}", "#{DIST_PATH}/binaries")
FileUtils.cp_r("#{OUTPUT_PATH}/Products/Release/#{x}.dSYM", "#{DIST_PATH}/dsym")
FileUtils.cp_r("#{xcodebuilddir}/Release/#{x}", "#{dist_path}/binaries")
end
Dir.glob("Conf/*") {|x| FileUtils.cp(x, "#{DIST_PATH}/conf")}
DSYMS.each do |x|
FileUtils.cp_r("#{xcodebuilddir}/Release/#{x}", "#{dist_path}/dsym")
end
puts "Distribution folder created"
Dir.glob("Conf/*") {|x| File.directory?(x) or FileUtils.cp(x, "#{dist_path}/conf")}
puts "Distribution folder #{dist_path} created"
end
# Tests
@@ -140,24 +150,13 @@ namespace :tests do
desc "Tests: Logic"
task :logic => [:init] do
puts "Running logic tests"
run_and_output_with_color("xcodebuild #{XCODE_DEFAULTS} test")
xcodebuild("-scheme LogicTests test")
end
desc "Tests: Kernel"
task :kernel do
Rake::Task['unload'].invoke()
Rake::Task['install:debug'].invoke()
Rake::Task['load_kext'].invoke
timeout = 30
puts "Running kernel tests with a #{timeout} second timeout"
begin
Timeout::timeout(timeout) {
system "sudo #{OUTPUT_PATH}/Products/Debug/KernelTests"
}
rescue Timeout::Error
puts "ERROR: tests ran for longer than #{timeout} seconds and were killed."
end
Rake::Task['unload_kext'].execute
Rake::Task['build:debug'].invoke()
system "sudo #{xcodebuilddir}/Debug/KernelTests"
end
end
@@ -169,12 +168,12 @@ end
task :unload_kext do
puts "Unloading kernel extension"
system "sudo kextunload /santa-driver.kext 2>/dev/null"
system "sudo kextunload -b com.google.santa-driver 2>/dev/null"
end
task :unload_gui do
puts "Unloading GUI agent"
system "sudo killall Santa 2>/dev/null"
system "launchctl unload /Library/LaunchAgents/com.google.santagui.plist 2>/dev/null"
end
desc "Unload"
@@ -187,12 +186,12 @@ end
task :load_kext do
puts "Loading kernel extension"
system "sudo kextload /santa-driver.kext"
system "sudo kextload /Library/Extensions/santa-driver.kext"
end
task :load_gui do
puts "Loading GUI agent"
system "open /Applications/Santa.app"
system "launchctl load /Library/LaunchAgents/com.google.santagui.plist 2>/dev/null"
end
desc "Load"
@@ -213,23 +212,3 @@ namespace :reload do
Rake::Task['load'].invoke()
end
end
# Versioning
desc "Update version, version should be of the form rake version[\\d{1,4}.\\d{1,2}(?:.\\d{1,2})?]"
task :version, :version do |t, args|
response = args[:version]
unless response =~ /^\d{1,4}\.\d{1,2}(?:\.\d{1,2})?$/
raise "Version number must be of form: xxxx.xx[.xx]. E.g: rake version[1.0.2], rake version[1.7]"
end
system "sed -i -e 's/MODULE_VERSION = .*;/MODULE_VERSION = #{response};/g' Santa.xcodeproj/project.pbxproj"
PLISTS.each do |plist|
system "defaults write $PWD/#{plist} CFBundleVersion #{response}"
system "defaults write $PWD/#{plist} CFBundleShortVersionString #{response}"
system "plutil -convert xml1 $PWD/#{plist}"
end
puts "Updated version to #{response}"
end

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0510"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -23,10 +23,12 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
codeCoverageEnabled = "YES"
enableAddressSanitizer = "YES">
<Testables>
<TestableReference
skipped = "NO">
@@ -39,24 +41,37 @@
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D91BCDC174E8AE600131A7D"
BuildableName = "All"
BlueprintName = "All"
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0600"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -23,10 +23,11 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
@@ -38,17 +39,23 @@
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
debugAsWhichUser = "root"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D0016A1192BCD3C005E7FCD"
@@ -61,12 +68,13 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D0016A1192BCD3C005E7FCD"

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D260DAB18B68E12002A0B55"
BuildableName = "LogicTests.xctest"
BlueprintName = "LogicTests"
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D260DAB18B68E12002A0B55"
BuildableName = "LogicTests.xctest"
BlueprintName = "LogicTests"
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D260DAB18B68E12002A0B55"
BuildableName = "LogicTests.xctest"
BlueprintName = "LogicTests"
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D260DAB18B68E12002A0B55"
BuildableName = "LogicTests.xctest"
BlueprintName = "LogicTests"
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D260DAB18B68E12002A0B55"
BuildableName = "LogicTests.xctest"
BlueprintName = "LogicTests"
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0510"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -23,10 +23,11 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
@@ -38,17 +39,22 @@
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D385DB5180DE4A900418BC6"
@@ -61,12 +67,13 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D385DB5180DE4A900418BC6"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0510"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -23,30 +23,44 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D91BCB3174E8A7E00131A7D"
BuildableName = "santa-driver.kext"
BlueprintName = "santa-driver"
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C78227531E1C3C58006EB2D6"
BuildableName = "santabs.xpc"
BlueprintName = "santabs"
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C78227531E1C3C58006EB2D6"
BuildableName = "santabs.xpc"
BlueprintName = "santabs"
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C78227531E1C3C58006EB2D6"
BuildableName = "santabs.xpc"
BlueprintName = "santabs"
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0510"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -23,10 +23,11 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
@@ -38,17 +39,22 @@
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D35BD9D18FD71CE00921A21"
@@ -61,12 +67,13 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D35BD9D18FD71CE00921A21"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0510"
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -23,10 +23,11 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
@@ -38,17 +39,23 @@
ReferencedContainer = "container:Santa.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
debugAsWhichUser = "root"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D9A7F3C1759330400035EB5"
@@ -61,12 +68,13 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0D9A7F3C1759330400035EB5"

View File

@@ -0,0 +1,139 @@
cmake_minimum_required(VERSION 3.10.0)
project(Santa)
function(CompileXib output_file_path_variable input_file_path)
get_filename_component(input_file_name "${input_file_path}" NAME_WE)
set(output_file_path "${CMAKE_CURRENT_BINARY_DIR}/${input_file_name}.nib")
add_custom_command(
OUTPUT "${output_file_path}"
COMMAND ibtool --compile "${output_file_path}" "${input_file_path}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Compiling: ${input_file_path}"
)
set("${output_file_path_variable}" "${output_file_path}" PARENT_SCOPE)
endfunction()
# It is important to only use absolute file paths with actool
function(CompileAssets asset_file_list_variable)
set(asset_file_list
"${CMAKE_CURRENT_BINARY_DIR}/AppIcon.icns"
"${CMAKE_CURRENT_BINARY_DIR}/Assets.car"
)
add_custom_command(
OUTPUT ${asset_file_list}
COMMAND xcrun actool --output-format=human-readable-text --notices --warnings --errors --platform macosx --minimum-deployment-target ${MACOSX_VERSION_MIN} --target-device mac --app-icon AppIcon --output-partial-info-plist "${CMAKE_CURRENT_BINARY_DIR}/Assets.plist" --compile "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/Resources/Images.xcassets"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Packaging resources"
)
set("${asset_file_list_variable}" ${asset_file_list} PARENT_SCOPE)
endfunction()
function(main)
# Include all files to make IDEs happy
set(PROJECT_SOURCEFILES
SNTAboutWindowController.h
SNTAboutWindowController.m
SNTAccessibleTextField.h
SNTAccessibleTextField.m
SNTAppDelegate.h
SNTAppDelegate.m
SNTMessageWindow.h
SNTMessageWindow.m
SNTMessageWindowController.h
SNTMessageWindowController.m
SNTNotificationManager.h
SNTNotificationManager.m
main.m
# The "common" folder contains some of the files required to build this target
"${CMAKE_SOURCE_DIR}/Source/common/SNTConfigurator.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCControlInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCUnprivilegedControlInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTBlockMessage.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTRule.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTStoredEvent.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTSystemInfo.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCBundleServiceInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCNotifierInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTLogging.m"
)
set(PROJECT_XIBFILES
"${CMAKE_CURRENT_SOURCE_DIR}/Resources/AboutWindow.xib"
"${CMAKE_CURRENT_SOURCE_DIR}/Resources/MessageWindow.xib"
)
foreach(xib_file ${PROJECT_XIBFILES})
CompileXib(output_nib_file_path "${xib_file}")
list(APPEND PROJECT_RESOURCES "${output_nib_file_path}")
list(APPEND PROJECT_SOURCEFILES "${output_nib_file_path}")
endforeach()
CompileAssets(asset_file_list)
foreach(asset_file ${asset_file_list})
list(APPEND PROJECT_RESOURCES "${asset_file}")
list(APPEND PROJECT_SOURCEFILES "${asset_file}")
endforeach()
add_executable("${PROJECT_NAME}" MACOSX_BUNDLE ${PROJECT_SOURCEFILES})
target_link_libraries("${PROJECT_NAME}" PRIVATE -ObjC)
set_target_properties("${PROJECT_NAME}" PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER "com.google.SantaGUI"
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Resources/SantaGUI-Info.plist"
RESOURCE "${PROJECT_RESOURCES}"
)
target_link_libraries("${PROJECT_NAME}" PRIVATE
MOLCertificate MOLCodesignChecker MOLXPCConnection
"-framework Cocoa"
)
target_compile_options("${PROJECT_NAME}" PRIVATE
-fobjc-arc -Wno-everything -fmodules
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
target_compile_options("${PROJECT_NAME}" PRIVATE -g3)
endif()
target_compile_definitions("${PROJECT_NAME}" PRIVATE
COCOAPODS=1
SANTAGUI=1
)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions("${PROJECT_NAME}" PRIVATE DEBUG=1)
else()
target_compile_definitions("${PROJECT_NAME}" PRIVATE NDEBUG=1)
endif()
target_include_directories("${PROJECT_NAME}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/SantaGUI"
"${CMAKE_SOURCE_DIR}/Source/common"
"${CMAKE_SOURCE_DIR}/Source/santad"
)
add_custom_command(TARGET "${PROJECT_NAME}" POST_BUILD
COMMAND codesign --force --verify --verbose --sign "${CODESIGN_IDENTITY}" "${CMAKE_BINARY_DIR}/Source/SantaGUI/Santa.app"
COMMENT "Signing ${PROJECT_NAME} with the following identity: ${CODESIGN_IDENTITY}"
)
# Ignore errors about the missing RESOURCE destination missing; this is a cmake bug
install(TARGETS "${PROJECT_NAME}" BUNDLE DESTINATION "/Applications")
endfunction()
main()

View File

@@ -1,21 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6250" systemVersion="13F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6250"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="SNTAboutWindowController">
<connections>
<outlet property="moreInfoButton" destination="SRu-Kf-vu5" id="Vj2-9Q-05d"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Santa" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES"/>
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="200"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1578"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="480" height="200"/>
<autoresizingMask key="autoresizingMask"/>
@@ -36,32 +37,51 @@
<rect key="frame" x="18" y="65" width="444" height="60"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="center" id="CcT-ul-1eA">
<font key="font" metaFont="system"/>
<string key="title">Santa is a binary whitelisting system for Mac OS X.
<string key="title">Santa is an application whitelisting system for macOS.
There are no user-configurable settings.</string>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Udo-BY-n7e">
<rect key="frame" x="196" y="21" width="88" height="32"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SRu-Kf-vu5">
<rect key="frame" x="130" y="21" width="111" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="76" id="2Xc-ax-2bV"/>
<constraint firstAttribute="width" constant="99" id="JHv-2J-QSe"/>
</constraints>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="uSw-o1-lWW">
<buttonCell key="cell" type="push" title="More Info..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6fe-ju-aET">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="openMoreInfoURL:" target="-2" id="dps-TN-rkS"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Udo-BY-n7e">
<rect key="frame" x="240" y="21" width="111" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="99" id="2Xc-ax-2bV"/>
</constraints>
<buttonCell key="cell" type="push" title="Dismiss" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="uSw-o1-lWW">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
</buttonCell>
<connections>
<action selector="orderOut:" target="-1" id="6oW-zI-zn5"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="Udo-BY-n7e" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" priority="900" constant="191" id="1T4-DB-Dz8"/>
<constraint firstItem="SRu-Kf-vu5" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="136" id="Ake-nU-qhW"/>
<constraint firstItem="BnL-ZS-kXw" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="Fj1-SG-mzF"/>
<constraint firstAttribute="bottom" secondItem="Udo-BY-n7e" secondAttribute="bottom" constant="28" id="bpF-hC-haN"/>
<constraint firstItem="BnL-ZS-kXw" firstAttribute="centerX" secondItem="Udo-BY-n7e" secondAttribute="centerX" constant="0.5" id="csK-2p-W94"/>
<constraint firstAttribute="bottom" secondItem="SRu-Kf-vu5" secondAttribute="bottom" constant="28" id="fCB-02-SEt"/>
<constraint firstItem="BnL-ZS-kXw" firstAttribute="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="kez-S0-6Gg"/>
<constraint firstItem="Udo-BY-n7e" firstAttribute="leading" secondItem="SRu-Kf-vu5" secondAttribute="trailing" constant="11" id="sYO-yY-w9w"/>
</constraints>
</view>
<connections>

View File

@@ -31,25 +31,25 @@
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"idiom" : "mac",
"filename" : "santa-hat-icon-256.png",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "256x256",
"idiom" : "mac",
"filename" : "santa-hat-icon-256.png",
"scale" : "1x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "santa-hat-icon-512.png",
"size" : "256x256",
"scale" : "2x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "santa-hat-icon-512.png",
"size" : "512x512",
"scale" : "1x"
},
{
@@ -62,4 +62,4 @@
"version" : 1,
"author" : "xcode"
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,141 +1,298 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6250" systemVersion="14B25" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6250"/>
<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">
<connections>
<outlet property="applicationNameLabel" destination="qgf-Jf-cJr" id="1JX-X8-03v"/>
<outlet property="bundleHashLabel" destination="xP7-jE-NF8" id="i8B-Gs-2E3"/>
<outlet property="bundleHashTitle" destination="MhO-U0-MLR" id="KT0-bK-fpV"/>
<outlet property="foundFileCountLabel" destination="LHV-gV-vyf" id="Sr0-T2-xGx"/>
<outlet property="hashingIndicator" destination="VyY-Yg-JOe" id="Yq4-tZ-9ep"/>
<outlet property="openEventButton" destination="7ua-5a-uSd" id="9s4-ZA-Vlo"/>
<outlet property="window" destination="9Bq-yh-54f" id="Uhs-WF-TV9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="none" id="9Bq-yh-54f" customClass="SNTMessageWindow">
<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="550" height="275"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1577"/>
<rect key="contentRect" x="167" y="107" width="540" height="479"/>
<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="550" height="275"/>
<rect key="frame" x="0.0" y="0.0" width="540" height="479"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="t8c-Fx-e5h">
<rect key="frame" x="234" y="210" width="83" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="KoG-v6-GfK"/>
<constraint firstAttribute="width" constant="79" id="oS3-CE-1vv"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Santa" id="7YA-iB-Zma">
<font key="font" size="34" name="HelveticaNeue-UltraLight"/>
<color key="textColor" red="0.18696189413265307" green="0.18696189413265307" blue="0.18696189413265307" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cD5-Su-lXR">
<rect key="frame" x="23" y="168" width="504" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="500" id="q9O-xW-hnS"/>
</constraints>
<textFieldCell key="cell" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="center" title="A message to the user goes here..." allowsEditingTextAttributes="YES" id="5tH-bG-UJA">
<font key="font" metaFont="system"/>
<color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.attributedCustomMessage" id="NH1-gV-Cor">
<dictionary key="options">
<string key="NSNullPlaceholder">The following application has been blocked from executing because its trustworthiness cannot be determined.</string>
</dictionary>
</binding>
</connections>
</textField>
<imageView horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="GYD-v8-fqH">
<rect key="frame" x="31" y="91" width="32" height="32"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSBonjour" id="jKM-qY-7mp"/>
<connections>
<binding destination="-2" name="value" keyPath="self.bundleIcon" id="X4L-aD-P21">
<dictionary key="options">
<bool key="NSConditionallySetsEnabled" value="NO"/>
</dictionary>
</binding>
</connections>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="d9e-Wv-Y5H">
<rect key="frame" x="111" y="126" width="34" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Path" id="KgY-X1-ESG">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="pc8-G9-4pJ">
<rect key="frame" x="154" y="126" width="350" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="346" id="BYY-2q-Lmb"/>
</constraints>
<textFieldCell key="cell" selectable="YES" sendsActionOnEndEditing="YES" alignment="left" title="Binary Path" id="E7T-9h-ofr">
<font key="font" metaFont="system"/>
<color key="textColor" white="0.0" alpha="0.5" colorSpace="deviceWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.event.path" id="4Nh-Ue-aCb"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="KEB-eH-x2Y">
<rect key="frame" x="96" y="99" width="46" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="SHA-1" id="eKN-Ic-5zy">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="PXc-xv-A28">
<rect key="frame" x="155" y="99" width="88" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" title="Binary SHA-1" id="X4W-9e-eIu">
<font key="font" metaFont="system"/>
<color key="textColor" white="0.0" alpha="0.5" colorSpace="deviceWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.event.SHA1" id="KuE-WW-9av"/>
</connections>
</textField>
<textField verticalHuggingPriority="750" verticalCompressionResistancePriority="499" translatesAutoresizingMaskIntoConstraints="NO" id="lvJ-Rk-UT5">
<rect key="frame" x="78" y="72" width="66" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Publisher" id="yL9-yD-JXX">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="Show code signing certificate chain" translatesAutoresizingMaskIntoConstraints="NO" id="cJf-k6-OxS">
<rect key="frame" x="322" y="75" width="10" height="10"/>
<constraints>
<constraint firstAttribute="height" constant="10" id="c3b-iv-bWa"/>
<constraint firstAttribute="width" constant="10" id="fXl-na-Lwx"/>
</constraints>
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="NSFollowLinkFreestandingTemplate" imagePosition="overlaps" alignment="center" refusesFirstResponder="YES" imageScaling="proportionallyDown" inset="2" id="R72-Qy-Xbb">
<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"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</buttonCell>
<connections>
<outlet property="nextKeyView" destination="7ua-5a-uSd" id="vl5-A8-O0H"/>
</connections>
</button>
<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>
<constraint firstAttribute="width" constant="450" id="XgJ-EV-tBa"/>
</constraints>
<textFieldCell key="cell" selectable="YES" refusesFirstResponder="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="center" title="A message to the user goes here..." allowsEditingTextAttributes="YES" id="5tH-bG-UJA">
<font key="font" metaFont="system"/>
<color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.attributedCustomMessage" id="376-sj-4Q1"/>
<outlet property="nextKeyView" destination="7ua-5a-uSd" id="VC7-bE-uHc"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="d9e-Wv-Y5H" userLabel="Label: Path">
<rect key="frame" x="8" y="297" width="142" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="138" id="Kqd-nX-7df"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Filename" id="KgY-X1-ESG">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="YNz-ka-cBi" userLabel="Label: Path">
<rect key="frame" x="8" y="272" width="142" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="138" id="3wU-P0-gAC"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Path" id="adC-be-Beh">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</textFieldCell>
</textField>
<textField toolTip="Binary Name" verticalHuggingPriority="900" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pc8-G9-4pJ" customClass="SNTAccessibleTextField">
<rect key="frame" x="187" y="297" width="315" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="311" id="xVR-j3-dLw"/>
</constraints>
<textFieldCell key="cell" selectable="YES" sendsActionOnEndEditing="YES" alignment="left" title="Binary Name" id="E7T-9h-ofr">
<font key="font" metaFont="system"/>
<color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.event.filePath.lastPathComponent" id="bOu-gv-1Vh"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lvJ-Rk-UT5" userLabel="Label: Publisher">
<rect key="frame" x="8" y="247" width="142" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Publisher" id="yL9-yD-JXX">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</textFieldCell>
</textField>
<textField toolTip="Publisher" verticalHuggingPriority="900" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="C3G-wL-u7w" userLabel="Publisher" customClass="SNTAccessibleTextField">
<rect key="frame" x="187" y="247" width="315" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="311" id="Dem-wH-KHm"/>
</constraints>
<textFieldCell key="cell" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Code signing information" placeholderString="" id="ztA-La-XgT">
<font key="font" metaFont="system"/>
<color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.publisherInfo" id="CEI-Cu-7pC">
<dictionary key="options">
<string key="NSNullPlaceholder">Not code-signed</string>
</dictionary>
</binding>
</connections>
</textField>
<button toolTip="Show code signing certificate chain" translatesAutoresizingMaskIntoConstraints="NO" id="cJf-k6-OxS" userLabel="Publisher Certs Button">
<rect key="frame" x="62" y="248" width="15" height="15"/>
<constraints>
<constraint firstAttribute="width" constant="15" id="QTm-Iv-m5p"/>
<constraint firstAttribute="height" constant="15" id="YwG-0s-jop"/>
</constraints>
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="NSInfo" imagePosition="overlaps" alignment="center" refusesFirstResponder="YES" imageScaling="proportionallyDown" inset="2" id="R72-Qy-Xbb">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</buttonCell>
<connections>
<action selector="showCertInfo:" target="-2" id="dB0-a3-X31"/>
<binding destination="-2" name="hidden" keyPath="self.binaryCert" id="xpJ-jl-aUN">
<binding destination="-2" name="hidden" keyPath="self.publisherInfo" id="fFR-f3-Oiw">
<dictionary key="options">
<string key="NSValueTransformerName">NSIsNil</string>
</dictionary>
</binding>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="BbV-3h-mmL">
<rect key="frame" x="220" y="23" width="110" height="25"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="KEB-eH-x2Y" userLabel="Label: Identifier">
<rect key="frame" x="8" y="222" width="142" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Identifier" id="eKN-Ic-5zy">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</textFieldCell>
</textField>
<textField toolTip="SHA-256" verticalHuggingPriority="900" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PXc-xv-A28">
<rect key="frame" x="187" y="222" width="219" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="110" id="HdL-6x-X4f"/>
<constraint firstAttribute="height" constant="22" id="YYm-GI-ojT"/>
<constraint firstAttribute="width" constant="215" id="4hh-R2-86s"/>
</constraints>
<buttonCell key="cell" type="roundTextured" title="OK" bezelStyle="texturedRounded" alignment="center" refusesFirstResponder="YES" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="XR6-Xa-gP4">
<textFieldCell key="cell" lineBreakMode="charWrapping" selectable="YES" sendsActionOnEndEditing="YES" title="SHA-256" id="X4W-9e-eIu">
<font key="font" metaFont="fixedUser" size="11"/>
<color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.event.fileSHA256" id="9KB-0b-qLV"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MhO-U0-MLR" userLabel="Label: Bundle Identifier">
<rect key="frame" x="8" y="197" width="142" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Bundle Identifier" id="LEe-u0-52o">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</textFieldCell>
<connections>
<binding destination="-2" name="hidden" keyPath="self.event.needsBundleHash" id="2kb-3z-Kyn">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eQb-0a-76J" userLabel="Label: Parent">
<rect key="frame" x="8" y="157" width="142" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Parent" id="gze-4A-1w5">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</textFieldCell>
</textField>
<textField toolTip="Parent Process" verticalHuggingPriority="900" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="f1p-GL-O3o" userLabel="Parent" customClass="SNTAccessibleTextField">
<rect key="frame" x="187" y="157" width="294" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="290" id="h3Y-mO-38F"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" title="Parent Name" id="ieo-WK-aDD">
<font key="font" metaFont="system"/>
<color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="displayPatternValue1" keyPath="self.event.parentName" id="Lce-TO-q9V">
<dictionary key="options">
<string key="NSDisplayPattern">%{value1}@ (%{value2}@)</string>
</dictionary>
</binding>
<binding destination="-2" name="displayPatternValue2" keyPath="self.event.ppid" previousBinding="Lce-TO-q9V" id="ofI-kH-F2d">
<dictionary key="options">
<string key="NSDisplayPattern">%{value1}@ (%{value2}@)</string>
</dictionary>
</binding>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oFj-ol-xpL" userLabel="Label: User">
<rect key="frame" x="8" y="132" width="142" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="User" id="1ut-uT-hQD">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" horizontalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="7ua-5a-uSd">
<rect key="frame" x="154" y="33" width="112" height="25"/>
<constraints>
<constraint firstAttribute="width" priority="900" constant="112" id="Pec-Pa-4aZ"/>
</constraints>
<buttonCell key="cell" type="roundTextured" title="Open Event..." bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="X1b-TF-1TL">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</buttonCell>
<connections>
<action selector="openEventDetails:" target="-2" id="VhL-ql-rCV"/>
<outlet property="nextKeyView" destination="BbV-3h-mmL" id="Xkz-va-iGc"/>
</connections>
</button>
<textField toolTip="Binary Path" verticalHuggingPriority="900" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bDE-Tl-UHg" customClass="SNTAccessibleTextField">
<rect key="frame" x="187" y="272" width="315" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="311" id="p1W-f9-KBX"/>
</constraints>
<textFieldCell key="cell" selectable="YES" sendsActionOnEndEditing="YES" alignment="left" title="Binary Path" id="H1b-Ui-CYo">
<font key="font" metaFont="system"/>
<color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.event.filePath" id="Sry-KY-HDb"/>
</connections>
</textField>
<button translatesAutoresizingMaskIntoConstraints="NO" id="5D8-GP-a4l">
<rect key="frame" x="113" y="80" width="315" height="29"/>
<constraints>
<constraint firstAttribute="height" constant="25" id="KvD-X6-CsO"/>
</constraints>
<buttonCell key="cell" type="check" title="Prevent future notifications for this application for a day" bezelStyle="regularSquare" imagePosition="left" alignment="center" inset="2" id="R5Y-Uc-rEP">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
</buttonCell>
<connections>
<binding destination="-2" name="value" keyPath="self.silenceFutureNotifications" id="tEb-2A-sht"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="BbV-3h-mmL" userLabel="Dismiss Button">
<rect key="frame" x="278" y="33" width="110" height="25"/>
<constraints>
<constraint firstAttribute="width" constant="110" id="6Uh-Bd-N64"/>
<constraint firstAttribute="height" constant="22" id="GH6-nw-6rD"/>
</constraints>
<buttonCell key="cell" type="roundTextured" title="Ignore" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="XR6-Xa-gP4">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
@@ -143,60 +300,203 @@ DQ
</string>
<modifierMask key="keyEquivalentModifierMask" shift="YES"/>
</buttonCell>
<accessibility description="Dismiss Dialog"/>
<connections>
<action selector="closeWindow:" target="-2" id="qQq-gh-8lw"/>
<outlet property="nextKeyView" destination="7ua-5a-uSd" id="4KL-Z2-1op"/>
</connections>
</button>
<textField horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="C3G-wL-u7w">
<rect key="frame" x="154" y="72" width="159" height="17"/>
<textField toolTip="Executing User" verticalHuggingPriority="900" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="h6f-PY-cc0" customClass="SNTAccessibleTextField">
<rect key="frame" x="187" y="132" width="294" height="17"/>
<constraints>
<constraint firstAttribute="height" constant="17" id="re0-7U-qcL"/>
<constraint firstAttribute="width" constant="290" id="on6-pj-m2k"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Code signing information" placeholderString="" id="ztA-La-XgT">
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" title="Executing User" id="HRT-Be-ePf">
<font key="font" metaFont="system"/>
<color key="textColor" white="0.0" alpha="0.5" colorSpace="deviceWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.binaryCert" id="eFt-oy-SXL">
<binding destination="-2" name="value" keyPath="self.event.executingUser" id="IcM-Lt-xTT">
<dictionary key="options">
<string key="NSNullPlaceholder">Not code-signed</string>
<string key="NSNullPlaceholder">Unknown</string>
</dictionary>
</binding>
</connections>
</textField>
<progressIndicator wantsLayer="YES" canDrawConcurrently="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="1" bezeled="NO" controlSize="small" style="bar" translatesAutoresizingMaskIntoConstraints="NO" id="VyY-Yg-JOe">
<rect key="frame" x="187" y="199" width="217" height="12"/>
<constraints>
<constraint firstAttribute="width" constant="217" id="M22-Dv-KIP"/>
</constraints>
</progressIndicator>
<textField toolTip="Bundle SHA-256" verticalHuggingPriority="900" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xP7-jE-NF8">
<rect key="frame" x="187" y="197" width="219" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="215" id="s7W-o9-2nN"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="charWrapping" selectable="YES" sendsActionOnEndEditing="YES" title="Calculating..." id="yJa-yL-X9a">
<font key="font" metaFont="fixedUser" size="11"/>
<color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.event.fileBundleHash" id="CnT-q6-bot"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LHV-gV-vyf">
<rect key="frame" x="187" y="182" width="219" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="215" id="LUu-Vd-peN"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="1000 related binaries" id="AVM-vB-hB8">
<font key="font" metaFont="fixedUser" size="11"/>
<color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<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"/>
</constraints>
<color key="borderColor" white="0.0" alpha="0.17999999999999999" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<font key="titleFont" metaFont="system"/>
</box>
<textField toolTip="Application Name" verticalHuggingPriority="900" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qgf-Jf-cJr" customClass="SNTAccessibleTextField">
<rect key="frame" x="187" y="322" width="315" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="311" id="Pav-ZA-iAu"/>
</constraints>
<textFieldCell key="cell" selectable="YES" sendsActionOnEndEditing="YES" alignment="left" title="Application Name" id="3UG-ca-d1k">
<font key="font" metaFont="systemBold"/>
<color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.event.fileBundleName" id="enC-Cl-UWt">
<dictionary key="options">
<string key="NSNullPlaceholder">Unknown</string>
</dictionary>
</binding>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pDa-fA-vnC" userLabel="Label: Application">
<rect key="frame" x="8" y="322" width="142" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="138" id="8mA-zi-Ev7"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Application" id="Hy7-WF-6xW">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="accessibilityElement" value="NO"/>
</userDefinedRuntimeAttributes>
</textFieldCell>
<connections>
<binding destination="-2" name="hidden" keyPath="self.event.fileBundleName" id="r2Q-hh-Uy5">
<dictionary key="options">
<string key="NSValueTransformerName">NSIsNil</string>
</dictionary>
</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="d9e-Wv-Y5H" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="113" id="3oY-g4-wHW"/>
<constraint firstItem="BbV-3h-mmL" firstAttribute="top" secondItem="PXc-xv-A28" secondAttribute="bottom" priority="800" constant="52" id="42Z-62-hKo"/>
<constraint firstItem="cD5-Su-lXR" firstAttribute="top" secondItem="t8c-Fx-e5h" secondAttribute="bottom" constant="25" id="4Hn-vu-fva"/>
<constraint firstItem="C3G-wL-u7w" firstAttribute="top" secondItem="PXc-xv-A28" secondAttribute="bottom" constant="10" id="7Pr-bA-HgG"/>
<constraint firstItem="PXc-xv-A28" firstAttribute="top" secondItem="pc8-G9-4pJ" secondAttribute="bottom" constant="10" id="8LX-e8-bKv"/>
<constraint firstItem="pc8-G9-4pJ" firstAttribute="top" secondItem="d9e-Wv-Y5H" secondAttribute="top" id="94E-d6-Jrg"/>
<constraint firstItem="pc8-G9-4pJ" firstAttribute="leading" secondItem="d9e-Wv-Y5H" secondAttribute="trailing" constant="13" id="A6N-gA-dt5"/>
<constraint firstItem="KEB-eH-x2Y" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="98" id="CYj-Gm-XZp"/>
<constraint firstItem="PXc-xv-A28" firstAttribute="leading" secondItem="KEB-eH-x2Y" secondAttribute="trailing" constant="17" id="IGi-bx-nBP"/>
<constraint firstItem="lvJ-Rk-UT5" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="80" id="O3p-RO-0ZJ"/>
<constraint firstItem="C3G-wL-u7w" firstAttribute="centerY" secondItem="cJf-k6-OxS" secondAttribute="centerY" constant="-1" id="R0U-iV-5Fx"/>
<constraint firstAttribute="centerX" secondItem="t8c-Fx-e5h" secondAttribute="centerX" id="SHu-BF-01V"/>
<constraint firstAttribute="centerX" secondItem="BbV-3h-mmL" secondAttribute="centerX" id="UAx-Xk-9DE"/>
<constraint firstItem="KEB-eH-x2Y" firstAttribute="top" secondItem="PXc-xv-A28" secondAttribute="top" id="YiW-o8-HZ2"/>
<constraint firstItem="BbV-3h-mmL" firstAttribute="top" secondItem="C3G-wL-u7w" secondAttribute="bottom" constant="25" id="Zxm-Pa-Ryj"/>
<constraint firstItem="lvJ-Rk-UT5" firstAttribute="top" secondItem="C3G-wL-u7w" secondAttribute="top" id="adm-oT-FAf"/>
<constraint firstAttribute="bottom" secondItem="BbV-3h-mmL" secondAttribute="bottom" constant="25" id="awW-Dh-Xl4"/>
<constraint firstItem="GYD-v8-fqH" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="31" id="btT-jY-NXw"/>
<constraint firstItem="GYD-v8-fqH" firstAttribute="centerY" secondItem="KEB-eH-x2Y" secondAttribute="centerY" id="cOS-EE-Mw8"/>
<constraint firstItem="C3G-wL-u7w" firstAttribute="leading" secondItem="lvJ-Rk-UT5" secondAttribute="trailing" constant="14" id="ewf-Pg-nRK"/>
<constraint firstAttribute="centerX" secondItem="cD5-Su-lXR" secondAttribute="centerX" id="goV-ub-zwi"/>
<constraint firstItem="t8c-Fx-e5h" firstAttribute="top" secondItem="Iwq-Lx-rLv" secondAttribute="top" constant="25" id="mY6-FP-uEK"/>
<constraint firstItem="pc8-G9-4pJ" firstAttribute="top" secondItem="cD5-Su-lXR" secondAttribute="bottom" constant="25" id="pfg-1u-Yfj"/>
<constraint firstItem="cJf-k6-OxS" firstAttribute="leading" secondItem="C3G-wL-u7w" secondAttribute="trailing" constant="11" id="sMW-KK-A28"/>
<constraint firstItem="oFj-ol-xpL" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="10" id="0AD-PS-5V1"/>
<constraint firstItem="f1p-GL-O3o" firstAttribute="centerY" secondItem="eQb-0a-76J" secondAttribute="centerY" id="2Aq-1E-Ybz"/>
<constraint firstItem="BbV-3h-mmL" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" priority="500" constant="193" id="2uo-Cm-Tfp"/>
<constraint firstItem="h6f-PY-cc0" firstAttribute="top" secondItem="f1p-GL-O3o" secondAttribute="bottom" constant="8" id="496-VQ-Fx5"/>
<constraint firstItem="xP7-jE-NF8" firstAttribute="leading" secondItem="4Li-ul-zIi" secondAttribute="trailing" constant="20" id="5Mr-By-PAU"/>
<constraint firstItem="pDa-fA-vnC" firstAttribute="centerY" secondItem="qgf-Jf-cJr" secondAttribute="centerY" id="AKX-pe-hEX"/>
<constraint firstItem="C3G-wL-u7w" firstAttribute="leading" secondItem="4Li-ul-zIi" secondAttribute="trailing" constant="20" id="ALv-0v-szi"/>
<constraint firstItem="d9e-Wv-Y5H" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="10" id="FPe-Rd-G4n"/>
<constraint firstItem="cJf-k6-OxS" firstAttribute="centerY" secondItem="C3G-wL-u7w" secondAttribute="centerY" id="FdL-ZZ-Vbe"/>
<constraint firstItem="t8c-Fx-e5h" firstAttribute="top" secondItem="Iwq-Lx-rLv" secondAttribute="top" constant="30" id="FuB-GX-0jg"/>
<constraint firstItem="oFj-ol-xpL" firstAttribute="bottom" secondItem="4Li-ul-zIi" secondAttribute="bottom" id="G0I-O2-S91"/>
<constraint firstItem="lvJ-Rk-UT5" firstAttribute="leading" secondItem="cJf-k6-OxS" secondAttribute="trailing" constant="-67" id="GD2-Ka-deo"/>
<constraint firstItem="BbV-3h-mmL" firstAttribute="top" secondItem="5D8-GP-a4l" secondAttribute="bottom" priority="900" constant="25" id="GT2-tO-2td"/>
<constraint firstItem="h6f-PY-cc0" firstAttribute="centerY" secondItem="oFj-ol-xpL" secondAttribute="centerY" id="GXI-pT-FM1"/>
<constraint firstItem="4Li-ul-zIi" firstAttribute="top" secondItem="pDa-fA-vnC" secondAttribute="top" id="Gd4-Nr-n5G"/>
<constraint firstItem="xP7-jE-NF8" firstAttribute="top" secondItem="PXc-xv-A28" secondAttribute="bottom" constant="8" id="HUT-MI-jsR"/>
<constraint firstItem="qgf-Jf-cJr" firstAttribute="leading" secondItem="4Li-ul-zIi" secondAttribute="trailing" constant="20" id="Ht4-Lg-U5N"/>
<constraint firstItem="LHV-gV-vyf" firstAttribute="leading" secondItem="4Li-ul-zIi" secondAttribute="trailing" constant="20" id="IA0-dy-2be"/>
<constraint firstItem="oFj-ol-xpL" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="10" id="IwX-ja-ZIs"/>
<constraint firstItem="d9e-Wv-Y5H" firstAttribute="top" secondItem="4Li-ul-zIi" secondAttribute="top" priority="500" id="JY4-N1-j8e"/>
<constraint firstItem="YNz-ka-cBi" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="10" id="KmX-kX-VCN"/>
<constraint firstItem="5D8-GP-a4l" firstAttribute="centerX" secondItem="Iwq-Lx-rLv" secondAttribute="centerX" id="LkH-F4-Ncm"/>
<constraint firstItem="pc8-G9-4pJ" firstAttribute="top" secondItem="cD5-Su-lXR" secondAttribute="bottom" priority="950" constant="55" id="Nsl-zf-poH"/>
<constraint firstItem="YNz-ka-cBi" firstAttribute="centerY" secondItem="bDE-Tl-UHg" secondAttribute="centerY" id="ObQ-RA-S5V"/>
<constraint firstItem="pc8-G9-4pJ" firstAttribute="leading" secondItem="4Li-ul-zIi" secondAttribute="trailing" constant="20" id="SCl-Ky-VmT"/>
<constraint firstItem="d9e-Wv-Y5H" firstAttribute="centerY" secondItem="pc8-G9-4pJ" secondAttribute="centerY" id="SLv-F7-w5k"/>
<constraint firstItem="4Li-ul-zIi" firstAttribute="leading" secondItem="KEB-eH-x2Y" secondAttribute="trailing" constant="20" id="Seb-c0-MUL"/>
<constraint firstAttribute="centerX" secondItem="cD5-Su-lXR" secondAttribute="centerX" id="V0a-Py-iEc"/>
<constraint firstItem="LHV-gV-vyf" firstAttribute="top" secondItem="VyY-Yg-JOe" secondAttribute="bottom" id="Vjr-NX-j8V"/>
<constraint firstItem="MhO-U0-MLR" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="10" id="Vly-VE-BwU"/>
<constraint firstItem="oFj-ol-xpL" firstAttribute="leading" secondItem="lvJ-Rk-UT5" secondAttribute="leading" priority="999" id="Z6G-l9-G4a"/>
<constraint firstItem="C3G-wL-u7w" firstAttribute="top" secondItem="bDE-Tl-UHg" secondAttribute="bottom" constant="8" id="ZoS-xV-2WA"/>
<constraint firstItem="lvJ-Rk-UT5" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="10" id="aMJ-Wb-vRS"/>
<constraint firstItem="KEB-eH-x2Y" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="10" id="aOk-S0-0n2"/>
<constraint firstItem="4Li-ul-zIi" firstAttribute="leading" secondItem="eQb-0a-76J" secondAttribute="trailing" constant="20" id="b0B-3w-grH"/>
<constraint firstItem="KEB-eH-x2Y" firstAttribute="centerY" secondItem="PXc-xv-A28" secondAttribute="centerY" id="cHe-pZ-0Oq"/>
<constraint firstItem="cD5-Su-lXR" firstAttribute="top" secondItem="t8c-Fx-e5h" secondAttribute="bottom" constant="22" id="dYg-zP-wh2"/>
<constraint firstItem="h6f-PY-cc0" firstAttribute="leading" secondItem="4Li-ul-zIi" secondAttribute="trailing" constant="20" id="eSz-lz-Fdh"/>
<constraint firstItem="qgf-Jf-cJr" firstAttribute="top" secondItem="cD5-Su-lXR" secondAttribute="bottom" constant="30" id="esg-lX-BAT"/>
<constraint firstItem="f1p-GL-O3o" firstAttribute="leading" secondItem="4Li-ul-zIi" secondAttribute="trailing" constant="20" id="fGd-YS-phP"/>
<constraint firstAttribute="centerX" secondItem="t8c-Fx-e5h" secondAttribute="centerX" id="h3d-Kc-q88"/>
<constraint firstItem="f1p-GL-O3o" firstAttribute="top" secondItem="LHV-gV-vyf" secondAttribute="bottom" constant="8" id="h4h-K3-BTd"/>
<constraint firstItem="f1p-GL-O3o" firstAttribute="top" secondItem="PXc-xv-A28" secondAttribute="bottom" priority="700" constant="8" id="hXw-6Z-lb2"/>
<constraint firstItem="BbV-3h-mmL" firstAttribute="leading" secondItem="7ua-5a-uSd" secondAttribute="trailing" constant="12" id="ioO-NJ-Jqo"/>
<constraint firstItem="bDE-Tl-UHg" firstAttribute="leading" secondItem="4Li-ul-zIi" secondAttribute="trailing" constant="20" id="jdk-ak-soQ"/>
<constraint firstItem="C3G-wL-u7w" firstAttribute="centerY" secondItem="lvJ-Rk-UT5" secondAttribute="centerY" id="jfs-YI-7Ae"/>
<constraint firstItem="4Li-ul-zIi" firstAttribute="leading" secondItem="oFj-ol-xpL" secondAttribute="trailing" constant="20" id="kOG-Cj-hFG"/>
<constraint firstItem="4Li-ul-zIi" firstAttribute="leading" secondItem="MhO-U0-MLR" secondAttribute="trailing" constant="20" id="ke9-wW-5fr"/>
<constraint firstItem="pc8-G9-4pJ" firstAttribute="top" secondItem="qgf-Jf-cJr" secondAttribute="bottom" constant="8" id="lWU-tC-vWg"/>
<constraint firstItem="5D8-GP-a4l" firstAttribute="top" secondItem="h6f-PY-cc0" secondAttribute="bottom" constant="25" id="lYd-VZ-lBs"/>
<constraint firstItem="VyY-Yg-JOe" firstAttribute="leading" secondItem="4Li-ul-zIi" secondAttribute="trailing" constant="18" id="lei-uP-T8m"/>
<constraint firstItem="f1p-GL-O3o" firstAttribute="top" secondItem="xP7-jE-NF8" secondAttribute="bottom" priority="701" constant="8" id="oY4-e7-lsz"/>
<constraint firstItem="7ua-5a-uSd" firstAttribute="top" secondItem="5D8-GP-a4l" secondAttribute="bottom" priority="900" constant="25" id="pCX-eX-erN"/>
<constraint firstItem="xP7-jE-NF8" firstAttribute="centerY" secondItem="MhO-U0-MLR" secondAttribute="centerY" id="pdC-x8-Nao"/>
<constraint firstAttribute="centerX" secondItem="7ua-5a-uSd" secondAttribute="centerX" constant="60" id="phL-j9-rPq"/>
<constraint firstItem="bDE-Tl-UHg" firstAttribute="top" secondItem="pc8-G9-4pJ" secondAttribute="bottom" constant="8" id="pis-of-f93"/>
<constraint firstItem="4Li-ul-zIi" firstAttribute="leading" secondItem="lvJ-Rk-UT5" secondAttribute="trailing" constant="20" id="qKi-KT-jzJ"/>
<constraint firstItem="C3G-wL-u7w" firstAttribute="bottom" secondItem="PXc-xv-A28" secondAttribute="top" constant="-8" id="snd-8T-LjC"/>
<constraint firstItem="4Li-ul-zIi" firstAttribute="leading" secondItem="d9e-Wv-Y5H" secondAttribute="trailing" constant="20" id="stz-Vm-Kxo"/>
<constraint firstItem="PXc-xv-A28" firstAttribute="leading" secondItem="4Li-ul-zIi" secondAttribute="trailing" constant="20" id="tAa-1s-xVZ"/>
<constraint firstItem="eQb-0a-76J" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="10" id="u1y-6V-moc"/>
<constraint firstAttribute="bottom" secondItem="BbV-3h-mmL" secondAttribute="bottom" constant="35" id="ukF-FH-DE8"/>
<constraint firstItem="VyY-Yg-JOe" firstAttribute="centerY" secondItem="MhO-U0-MLR" secondAttribute="centerY" id="vB8-c5-pfO"/>
<constraint firstItem="4Li-ul-zIi" firstAttribute="leading" secondItem="YNz-ka-cBi" secondAttribute="trailing" constant="20" id="vfq-83-tKI"/>
<constraint firstItem="pDa-fA-vnC" firstAttribute="leading" secondItem="Iwq-Lx-rLv" secondAttribute="leading" constant="10" id="z6s-ga-iAk"/>
</constraints>
</view>
<connections>
<outlet property="initialFirstResponder" destination="kiB-jZ-69S" id="I96-dS-lq5"/>
</connections>
<point key="canvasLocation" x="274" y="326.5"/>
</window>
<userDefaultsController representsSharedInstance="YES" id="iXx-cu-WYe"/>
</objects>
<resources>
<image name="NSBonjour" width="32" height="32"/>
<image name="NSFollowLinkFreestandingTemplate" width="14" height="14"/>
<image name="NSInfo" width="32" height="32"/>
</resources>
</document>

View File

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

View File

@@ -2,31 +2,31 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.google.${PRODUCT_NAME:rfc1034identifier}GUI</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.7.1</string>
<key>CFBundleVersion</key>
<string>0.7.1</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>Google, Inc.</string>
<key>CFBundleIdentifier</key>
<string>com.google.SantaGUI</string>
<key>CFBundleName</key>
<string>Santa</string>
<key>CFBundleExecutable</key>
<string>Santa</string>
<key>CFBundleVersion</key>
<string>${SANTA_VERSION}</string>
<key>CFBundleShortVersionString</key>
<string>${SANTA_VERSION}</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_VERSION_MIN}</string>
<key>LSUIElement</key>
<true/>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>CFBundleIconFile</key>
<string>AppIcon</string>
<key>CFBundleIconName</key>
<string>AppIcon</string>
</dict>
</plist>

View File

@@ -1,4 +1,4 @@
/// Copyright 2014 Google Inc. All rights reserved.
/// 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.
@@ -12,6 +12,12 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <Cocoa/Cocoa.h>
@interface SNTAboutWindowController : NSWindowController
@property IBOutlet NSButton *moreInfoButton;
- (IBAction)openMoreInfoURL:(id)sender;
@end

View File

@@ -1,4 +1,4 @@
/// Copyright 2014 Google Inc. All rights reserved.
/// 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.
@@ -14,10 +14,24 @@
#import "SNTAboutWindowController.h"
#import "SNTConfigurator.h"
@implementation SNTAboutWindowController
- (instancetype)init {
return [super initWithWindowNibName:@"AboutWindow"];
}
- (void)loadWindow {
[super loadWindow];
if (![[SNTConfigurator configurator] moreInfoURL]) {
[self.moreInfoButton removeFromSuperview];
}
}
- (IBAction)openMoreInfoURL:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[[SNTConfigurator configurator] moreInfoURL]];
[self close];
}
@end

View File

@@ -0,0 +1,23 @@
/// Copyright 2016 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <Cocoa/Cocoa.h>
/**
An NSTextField subclass that provides an accessiblity label equal to:
(self.toolTip + self.stringValue) where available. It also sets the
accessibilityRoleDescription to "label".
*/
@interface SNTAccessibleTextField : NSTextField
@end

View File

@@ -1,4 +1,4 @@
/// Copyright 2014 Google Inc. All rights reserved.
/// Copyright 2016 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
@@ -12,21 +12,28 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
/// An instance of this class is passed to each stage of the sync process for storing data
/// that might be needed in later stages.
@interface SNTCommandSyncStatus : NSObject
#import "SNTAccessibleTextField.h"
/// The base API URL
@property NSURL *syncBaseURL;
@implementation SNTAccessibleTextField
/// Machine identifier and owner
@property NSString *machineID;
@property NSString *machineOwner;
- (BOOL)accessibilityIsIgnored {
return NO;
}
/// Batch size for uploading events, sent from server
@property int32_t eventBatchSize;
- (NSString *)accessibilityLabel {
if (self.toolTip && self.stringValue) {
return [NSString stringWithFormat:@"%@: %@", self.toolTip, self.stringValue];
} else if (self.stringValue) {
return self.stringValue;
} else if (self.toolTip) {
return self.toolTip;
} else {
return nil;
}
}
/// Log upload URL sent from server
@property NSURL *uploadLogURL;
- (NSString *)accessibilityRoleDescription {
return @"label";
}
@end

View File

@@ -1,4 +1,4 @@
/// Copyright 2014 Google Inc. All rights reserved.
/// 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.
@@ -12,6 +12,10 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <Cocoa/Cocoa.h>
///
/// Initiates and manages the connection to santad
///
@interface SNTAppDelegate : NSObject<NSApplicationDelegate>
@end

View File

@@ -1,4 +1,4 @@
/// Copyright 2014 Google Inc. All rights reserved.
/// 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.
@@ -14,14 +14,19 @@
#import "SNTAppDelegate.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTAboutWindowController.h"
#import "SNTConfigurator.h"
#import "SNTNotificationManager.h"
#import "SNTXPCConnection.h"
#import "SNTStrengthify.h"
#import "SNTXPCControlInterface.h"
@interface SNTAppDelegate ()
@property SNTAboutWindowController *aboutWindowController;
@property SNTNotificationManager *notificationManager;
@property SNTXPCConnection *listener;
@property MOLXPCConnection *daemonListener;
@property MOLXPCConnection *bundleListener;
@end
@implementation SNTAppDelegate
@@ -30,40 +35,114 @@
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[self setupMenu];
self.aboutWindowController = [[SNTAboutWindowController alloc] init];
self.notificationManager = [[SNTNotificationManager alloc] init];
[self createConnection];
NSNotificationCenter *workspaceNotifications = [[NSWorkspace sharedWorkspace] notificationCenter];
[workspaceNotifications addObserverForName:NSWorkspaceSessionDidResignActiveNotification
object:nil
queue:[NSOperationQueue currentQueue]
usingBlock:^(NSNotification *note) {
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];
[self createBundleConnection];
}
- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag {
self.aboutWindowController = [[SNTAboutWindowController alloc] init];
[self.aboutWindowController showWindow:self];
return NO;
}
#pragma mark Connection handling
- (void)createConnection {
__weak __typeof(self) weakSelf = self;
- (void)createDaemonConnection {
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
self.listener =
[[SNTXPCConnection alloc] initClientWithName:[SNTXPCNotifierInterface serviceId]
options:NSXPCConnectionPrivileged];
self.listener.exportedInterface = [SNTXPCNotifierInterface notifierInterface];
self.listener.exportedObject = self.notificationManager;
self.listener.rejectedHandler = ^{
[weakSelf performSelectorInBackground:@selector(attemptReconnection)
withObject:nil];
WEAKIFY(self);
// Create listener for return connection from daemon.
NSXPCListener *listener = [NSXPCListener anonymousListener];
self.daemonListener = [[MOLXPCConnection alloc] initServerWithListener:listener];
self.daemonListener.privilegedInterface = [SNTXPCNotifierInterface notifierInterface];
self.daemonListener.exportedObject = self.notificationManager;
self.daemonListener.acceptedHandler = ^{
dispatch_semaphore_signal(sema);
};
self.listener.invalidationHandler = self.listener.rejectedHandler;
[self.listener resume];
self.daemonListener.invalidationHandler = ^{
STRONGIFY(self);
[self attemptDaemonReconnection];
};
[self.daemonListener resume];
// Tell daemon to connect back to the above listener.
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))) {
[self attemptDaemonReconnection];
}
}
- (void)attemptReconnection {
// TODO(rah): Make this smarter.
sleep(10);
[self performSelectorOnMainThread:@selector(createConnection)
withObject:nil
waitUntilDone:NO];
- (void)attemptDaemonReconnection {
self.daemonListener.invalidationHandler = nil;
[self.daemonListener invalidate];
[self performSelectorInBackground:@selector(createDaemonConnection) withObject:nil];
}
- (void)createBundleConnection {
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
WEAKIFY(self);
// Create listener for return connection from the bundle service.
NSXPCListener *listener = [NSXPCListener anonymousListener];
self.bundleListener = [[MOLXPCConnection alloc] initServerWithListener:listener];
self.bundleListener.privilegedInterface = [SNTXPCNotifierInterface bundleNotifierInterface];
self.bundleListener.exportedObject = self.notificationManager;
self.bundleListener.acceptedHandler = ^{
dispatch_semaphore_signal(sema);
};
self.bundleListener.invalidationHandler = ^{
STRONGIFY(self);
[self attemptBundleReconnection];
};
[self.bundleListener resume];
// Tell santabs to connect back to the above listener.
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))) {
[self attemptBundleReconnection];
}
}
- (void)attemptBundleReconnection {
self.bundleListener.invalidationHandler = nil;
[self.bundleListener invalidate];
[self performSelectorInBackground:@selector(createBundleConnection) withObject:nil];
}
#pragma mark Menu Management

View File

@@ -1,4 +1,4 @@
/// Copyright 2014 Google Inc. All rights reserved.
/// 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.
@@ -12,13 +12,21 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
/// An NSPanel that can become key/main and can fade in/out.
#import <Cocoa/Cocoa.h>
///
/// An NSPanel that can become key/main and can fade in/out.
///
@interface SNTMessageWindow : NSPanel
/// Fade the window in
///
/// Fade the window in
///
- (IBAction)fadeIn:(id)sender;
/// Fade the window out
///
/// Fade the window out
///
- (IBAction)fadeOut:(id)sender;
@end

View File

@@ -1,4 +1,4 @@
/// Copyright 2014 Google Inc. All rights reserved.
/// 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.
@@ -26,11 +26,12 @@
- (IBAction)fadeIn:(id)sender {
[self setAlphaValue:0.f];
[self center];
[self makeKeyAndOrderFront:sender];
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.15f];
[[NSAnimationContext currentContext] setCompletionHandler:^{
[NSApp activateIgnoringOtherApps:YES];
[NSApp activateIgnoringOtherApps:YES];
}];
[[self animator] setAlphaValue:1.f];
[NSAnimationContext endGrouping];
@@ -42,9 +43,9 @@
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.15f];
[[NSAnimationContext currentContext] setCompletionHandler:^{
[weakSelf.windowController windowWillClose:nil];
[weakSelf orderOut:nil];
[weakSelf setAlphaValue:1.f];
[weakSelf.windowController windowWillClose:sender];
[weakSelf orderOut:sender];
[weakSelf setAlphaValue:1.f];
}];
[[self animator] setAlphaValue:0.f];
[NSAnimationContext endGrouping];

View File

@@ -1,4 +1,4 @@
/// Copyright 2014 Google Inc. All rights reserved.
/// 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.
@@ -12,34 +12,62 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
@class SNTNotificationMessage;
#import <Cocoa/Cocoa.h>
@class SNTStoredEvent;
@protocol SNTMessageWindowControllerDelegate
- (void)windowDidClose;
- (void)windowDidCloseSilenceHash:(NSString *)hash;
@end
/// Controller for a single message window.
///
/// Controller for a single message window.
///
@interface SNTMessageWindowController : NSWindowController
- (instancetype)initWithEvent:(SNTNotificationMessage *)event;
- (instancetype)initWithEvent:(SNTStoredEvent *)event andMessage:(NSString *)message;
- (IBAction)showWindow:(id)sender;
- (IBAction)closeWindow:(id)sender;
- (IBAction)showCertInfo:(id)sender;
/// The execution event that this window is for
@property SNTNotificationMessage *event;
/// Reference to the "Bundle Hash" label in the XIB. Used to remove if application
/// doesn't have a bundle hash.
@property(weak) IBOutlet NSTextField *bundleHashLabel;
/// The delegate to inform when the notification is dismissed
/// Reference to the "Bundle Identifier" label in the XIB. Used to remove if application
/// doesn't have a bundle hash.
@property(weak) IBOutlet NSTextField *bundleHashTitle;
///
/// Is displayed if calculating the bundle hash is taking a bit.
///
@property(weak) IBOutlet NSProgressIndicator *hashingIndicator;
///
/// Is displayed if calculating the bundle hash is taking a bit.
///
@property(weak) IBOutlet NSTextField *foundFileCountLabel;
///
/// Reference to the "Open Event" button in the XIB. Used to either remove the button
/// if it isn't needed or set its title if it is.
///
@property(weak) IBOutlet NSButton *openEventButton;
///
/// The execution event that this window is for
///
@property(readonly) SNTStoredEvent *event;
///
/// The root progress object. Child nodes are vended to santad to report on work being done.
///
@property NSProgress *progress;
///
/// The delegate to inform when the notification is dismissed
///
@property(weak) id<SNTMessageWindowControllerDelegate> delegate;
/// A 'friendly' string representing the certificate information
@property(readonly) IBOutlet NSString *binaryCert;
/// An optional message to display with this block.
@property(readonly) IBOutlet NSAttributedString *attributedCustomMessage;
/// If the binary is part of a bundle, this is the icon for that bundle
@property(readonly) IBOutlet NSImage *bundleIcon;
@end

View File

@@ -1,4 +1,4 @@
/// Copyright 2014 Google Inc. All rights reserved.
/// 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.
@@ -16,40 +16,120 @@
#import <SecurityInterface/SFCertificatePanel.h>
#import "SNTBinaryInfo.h"
#import "SNTCertificate.h"
#import <MOLCertificate/MOLCertificate.h>
#import "SNTBlockMessage.h"
#import "SNTConfigurator.h"
#import "SNTMessageWindow.h"
#import "SNTNotificationMessage.h"
#import "SNTStoredEvent.h"
@interface SNTMessageWindowController ()
/// The custom message to display for this event
@property(copy) NSString *customMessage;
/// A 'friendly' string representing the certificate information
@property(readonly, nonatomic) NSString *publisherInfo;
/// An optional message to display with this block.
@property(readonly, nonatomic) NSAttributedString *attributedCustomMessage;
/// Reference to the "Application Name" label in the XIB. Used to remove if application
/// doesn't have a CFBundleName.
@property(weak) IBOutlet NSTextField *applicationNameLabel;
/// Linked to checkbox in UI to prevent future notifications for this binary.
@property BOOL silenceFutureNotifications;
@end
@implementation SNTMessageWindowController
- (instancetype)initWithEvent:(SNTNotificationMessage *)event {
- (instancetype)initWithEvent:(SNTStoredEvent *)event andMessage:(NSString *)message {
self = [super initWithWindowNibName:@"MessageWindow"];
if (self) {
_event = event;
[self.window setMovableByWindowBackground:NO];
[self.window setLevel:NSPopUpMenuWindowLevel];
[self.window center];
_customMessage = message;
_progress = [NSProgress discreteProgressWithTotalUnitCount:1];
[_progress addObserver:self
forKeyPath:@"fractionCompleted"
options:NSKeyValueObservingOptionNew
context:NULL];
}
return self;
}
- (void)dealloc {
[_progress removeObserver:self forKeyPath:@"fractionCompleted"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqualToString:@"fractionCompleted"]) {
dispatch_async(dispatch_get_main_queue(), ^{
NSProgress *progress = object;
if (progress.fractionCompleted != 0.0) {
self.hashingIndicator.indeterminate = NO;
}
self.hashingIndicator.doubleValue = progress.fractionCompleted;
});
}
}
- (void)loadWindow {
[super loadWindow];
[self.window setLevel:NSPopUpMenuWindowLevel];
[self.window setMovableByWindowBackground:YES];
if (![[SNTConfigurator configurator] eventDetailURL]) {
[self.openEventButton removeFromSuperview];
} else {
NSString *eventDetailText = [[SNTConfigurator configurator] eventDetailText];
if (eventDetailText) {
[self.openEventButton setTitle:eventDetailText];
}
}
if (!self.event.needsBundleHash) {
[self.bundleHashLabel removeFromSuperview];
[self.hashingIndicator removeFromSuperview];
[self.foundFileCountLabel removeFromSuperview];
} else {
self.openEventButton.enabled = NO;
self.hashingIndicator.indeterminate = YES;
[self.hashingIndicator startAnimation:self];
self.bundleHashLabel.hidden = YES;
self.foundFileCountLabel.stringValue = @"";
}
if (!self.event.fileBundleName) {
[self.applicationNameLabel removeFromSuperview];
}
}
- (IBAction)showWindow:(id)sender {
[(SNTMessageWindow *)self.window fadeIn:sender];
}
- (IBAction)closeWindow:(id)sender {
[self.progress cancel];
[(SNTMessageWindow *)self.window fadeOut:sender];
}
- (void)windowWillClose:(NSNotification *)notification {
if (self.delegate) [self.delegate windowDidClose];
if (!self.delegate) return;
if (self.silenceFutureNotifications) {
[self.delegate windowDidCloseSilenceHash:self.event.fileSHA256];
} else {
[self.delegate windowDidCloseSilenceHash:nil];
}
}
- (IBAction)showCertInfo:(id)sender {
// SFCertificatePanel expects an NSArray of SecCertificateRef's
NSMutableArray *certArray = [NSMutableArray arrayWithCapacity:[self.event.certificates count]];
for (SNTCertificate *cert in self.event.certificates) {
NSMutableArray *certArray = [NSMutableArray arrayWithCapacity:[self.event.signingChain count]];
for (MOLCertificate *cert in self.event.signingChain) {
[certArray addObject:(id)cert.certRef];
}
@@ -61,21 +141,27 @@
showGroup:YES];
}
- (IBAction)openEventDetails:(id)sender {
NSURL *url = [SNTBlockMessage eventDetailURLForEvent:self.event];
[self closeWindow:sender];
[[NSWorkspace sharedWorkspace] openURL:url];
}
#pragma mark Generated properties
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
if (! [key isEqualToString:@"event"]) {
if (![key isEqualToString:@"event"]) {
return [NSSet setWithObject:@"event"];
} else {
return nil;
return [NSSet set];
}
}
- (NSString *)binaryCert {
SNTCertificate *leafCert = self.event.leafCertificate;
- (NSString *)publisherInfo {
MOLCertificate *leafCert = [self.event.signingChain firstObject];
if (leafCert.commonName && leafCert.orgName) {
return [NSString stringWithFormat:@"%@ - %@", leafCert.commonName, leafCert.orgName];
return [NSString stringWithFormat:@"%@ - %@", leafCert.orgName, leafCert.commonName];
} else if (leafCert.commonName) {
return leafCert.commonName;
} else if (leafCert.orgName) {
@@ -86,33 +172,8 @@
}
- (NSAttributedString *)attributedCustomMessage {
if (self.event.customMessage) {
NSString *htmlHeader = @"<html><head><style>"
@"body {"
@" font-family: 'Lucida Grande', 'Helvetica', sans-serif;"
@" font-size: 13px;"
@" color: #666;"
@" text-align: center;"
@"}"
@"</style></head><body>";
NSString *htmlFooter = @"</body></html>";
NSString *fullHtml = [NSString stringWithFormat:@"%@%@%@", htmlHeader,
self.event.customMessage, htmlFooter];
NSData *htmlData = [fullHtml dataUsingEncoding:NSUTF8StringEncoding];
NSAttributedString *returnStr = [[NSAttributedString alloc] initWithHTML:htmlData
documentAttributes:NULL];
return returnStr;
} else {
return nil;
}
}
- (NSImage *)bundleIcon {
SNTBinaryInfo *bi = [[SNTBinaryInfo alloc] initWithPath:self.event.path];
if (!bi || !bi.bundle) return nil;
return [[NSWorkspace sharedWorkspace] iconForFile:bi.bundlePath];
return [SNTBlockMessage attributedBlockMessageForEvent:self.event
customMessage:self.customMessage];
}
@end

View File

@@ -1,4 +1,4 @@
/// Copyright 2014 Google Inc. All rights reserved.
/// 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.
@@ -12,11 +12,15 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <Cocoa/Cocoa.h>
#import "SNTMessageWindowController.h"
#import "SNTXPCNotifierInterface.h"
/// Keeps track of pending notifications and ensures only one is presented to the user at a time.
@interface SNTNotificationManager : NSObject<SNTMessageWindowControllerDelegate, SNTNotifierXPC>
///
/// Keeps track of pending notifications and ensures only one is presented to the user at a time.
///
@interface SNTNotificationManager : NSObject<SNTMessageWindowControllerDelegate,
SNTNotifierXPC, SNTBundleNotifierXPC>
@end

View File

@@ -1,4 +1,4 @@
/// Copyright 2014 Google Inc. All rights reserved.
/// 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.
@@ -14,68 +14,266 @@
#import "SNTNotificationManager.h"
#import "SNTNotificationMessage.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTBlockMessage.h"
#import "SNTConfigurator.h"
#import "SNTLogging.h"
#import "SNTStoredEvent.h"
#import "SNTStrengthify.h"
#import "SNTXPCControlInterface.h"
@interface SNTNotificationManager ()
/// The currently displayed notification
/// The currently displayed notification
@property SNTMessageWindowController *currentWindowController;
/// The queue of pending notifications
/// The queue of pending notifications
@property(readonly) NSMutableArray *pendingNotifications;
/// The connection to the bundle service
@property MOLXPCConnection *bundleServiceConnection;
/// A semaphore to block bundle hashing until a connection is established
@property dispatch_semaphore_t bundleServiceSema;
// A serial queue for holding hashBundleBinaries requests
@property dispatch_queue_t hashBundleBinariesQueue;
@end
@implementation SNTNotificationManager
static NSString * const silencedNotificationsKey = @"SilencedNotifications";
- (instancetype)init {
self = [super init];
if (self) {
_pendingNotifications = [[NSMutableArray alloc] init];
_bundleServiceSema = dispatch_semaphore_create(0);
_hashBundleBinariesQueue = dispatch_queue_create("com.google.santagui.hashbundlebinaries",
DISPATCH_QUEUE_SERIAL);
}
return self;
}
- (void)windowDidClose {
- (void)windowDidCloseSilenceHash:(NSString *)hash {
if (hash) [self updateSilenceDate:[NSDate date] forHash:hash];
[self.pendingNotifications removeObject:self.currentWindowController];
self.currentWindowController = nil;
if ([self.pendingNotifications count]) {
self.currentWindowController = [self.pendingNotifications firstObject];
[self.currentWindowController showWindow:self];
if (self.currentWindowController.event.needsBundleHash) {
dispatch_async(self.hashBundleBinariesQueue, ^{
[self hashBundleBinariesForEvent:self.currentWindowController.event];
});
}
} else {
// Tear down the bundle service
self.bundleServiceSema = dispatch_semaphore_create(0);
[self.bundleServiceConnection invalidate];
self.bundleServiceConnection = nil;
[NSApp hide:self];
}
}
- (void)updateSilenceDate:(NSDate *)date forHash:(NSString *)hash {
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *d = [[ud objectForKey:silencedNotificationsKey] mutableCopy];
if (!d) d = [NSMutableDictionary dictionary];
if (date) {
d[hash] = date;
} else {
[d removeObjectForKey:hash];
}
[ud setObject:d forKey:silencedNotificationsKey];
}
#pragma mark SNTNotifierXPC protocol methods
- (void)postBlockNotification:(SNTNotificationMessage *)event {
- (void)postClientModeNotification:(SNTClientMode)clientmode {
NSUserNotification *un = [[NSUserNotification alloc] init];
un.title = @"Santa";
un.hasActionButton = NO;
NSString *customMsg;
switch (clientmode) {
case SNTClientModeMonitor:
un.informativeText = @"Switching into Monitor mode";
customMsg = [[SNTConfigurator configurator] modeNotificationMonitor];
if (!customMsg) break;
if (!customMsg.length) return;
un.informativeText = [SNTBlockMessage stringFromHTML:customMsg];
break;
case SNTClientModeLockdown:
un.informativeText = @"Switching into Lockdown mode";
customMsg = [[SNTConfigurator configurator] modeNotificationLockdown];
if (!customMsg) break;
if (!customMsg.length) return;
un.informativeText = [SNTBlockMessage stringFromHTML:customMsg];
break;
default:
return;
}
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:un];
}
- (void)postBlockNotification:(SNTStoredEvent *)event withCustomMessage:(NSString *)message {
// See if this binary is already in the list of pending notifications.
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"event.SHA1==%@", event.SHA1];
NSPredicate *predicate =
[NSPredicate predicateWithFormat:@"event.fileSHA256==%@", event.fileSHA256];
if ([[self.pendingNotifications filteredArrayUsingPredicate:predicate] count]) return;
// See if this binary is silenced.
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSDate *silenceDate = [ud objectForKey:silencedNotificationsKey][event.fileSHA256];
if ([silenceDate isKindOfClass:[NSDate class]]) {
NSDate *oneDayAgo = [NSDate dateWithTimeIntervalSinceNow:-86400];
if ([silenceDate compare:[NSDate date]] == NSOrderedDescending) {
LOGI(@"Notification silence: date is in the future, ignoring");
[self updateSilenceDate:nil forHash:event.fileSHA256];
} else if ([silenceDate compare:oneDayAgo] == NSOrderedAscending) {
LOGI(@"Notification silence: date is more than one day ago, ignoring");
[self updateSilenceDate:nil forHash:event.fileSHA256];
} else {
LOGI(@"Notification silence: dropping notification for %@", event.fileSHA256);
return;
}
}
if (!event) {
LOGI(@"Error: Missing event object in message received from daemon!");
return;
}
// Notifications arrive on a background thread but UI updates must happen on the main thread.
// This includes making windows.
[self performSelectorOnMainThread:@selector(postBlockNotificationMainThread:)
withObject:event
waitUntilDone:NO];
dispatch_async(dispatch_get_main_queue(), ^{
SNTMessageWindowController *pendingMsg =
[[SNTMessageWindowController alloc] initWithEvent:event andMessage:message];
pendingMsg.delegate = self;
[self.pendingNotifications addObject:pendingMsg];
// If a notification isn't currently being displayed, display the incoming one.
if (!self.currentWindowController) {
self.currentWindowController = pendingMsg;
[pendingMsg showWindow:nil];
if (self.currentWindowController.event.needsBundleHash) {
dispatch_async(self.hashBundleBinariesQueue, ^{
[self hashBundleBinariesForEvent:self.currentWindowController.event];
});
}
}
});
}
- (void)postBlockNotificationMainThread:(SNTNotificationMessage *)event {
// Create message window
SNTMessageWindowController *pendingMsg = [[SNTMessageWindowController alloc] initWithEvent:event];
pendingMsg.delegate = self;
[self.pendingNotifications addObject:pendingMsg];
- (void)postRuleSyncNotificationWithCustomMessage:(NSString *)message {
NSUserNotification *un = [[NSUserNotification alloc] init];
un.title = @"Santa";
un.hasActionButton = NO;
un.informativeText = message ?: @"Requested application can now be run";
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:un];
}
// If a notification isn't currently being displayed, display the incoming one.
if (!self.currentWindowController) {
self.currentWindowController = pendingMsg;
#pragma mark SNTBundleNotifierXPC protocol methods
[NSApp activateIgnoringOtherApps:YES];
// It's quite likely that we're currently on a background thread, and GUI code should always be
// on main thread. Open the window on the main thread so any code it runs is also.
[pendingMsg showWindow:nil];
- (void)updateCountsForEvent:(SNTStoredEvent *)event
binaryCount:(uint64_t)binaryCount
fileCount:(uint64_t)fileCount
hashedCount:(uint64_t)hashedCount {
if ([self.currentWindowController.event.idx isEqual:event.idx]) {
dispatch_async(dispatch_get_main_queue(), ^{
self.currentWindowController.foundFileCountLabel.stringValue =
[NSString stringWithFormat:@"%llu binaries / %llu %@",
binaryCount, hashedCount ?: fileCount, hashedCount ? @"hashed" : @"files"];
});
}
}
- (void)setBundleServiceListener:(NSXPCListenerEndpoint *)listener {
MOLXPCConnection *c = [[MOLXPCConnection alloc] initClientWithListener:listener];
c.remoteInterface = [SNTXPCBundleServiceInterface bundleServiceInterface];
[c resume];
self.bundleServiceConnection = c;
WEAKIFY(self);
self.bundleServiceConnection.invalidationHandler = ^{
STRONGIFY(self);
if (self.currentWindowController) {
[self updateBlockNotification:self.currentWindowController.event withBundleHash:nil];
}
self.bundleServiceConnection.invalidationHandler = nil;
[self.bundleServiceConnection invalidate];
};
dispatch_semaphore_signal(self.bundleServiceSema);
}
#pragma mark SNTBundleNotifierXPC helper methods
- (void)hashBundleBinariesForEvent:(SNTStoredEvent *)event {
self.currentWindowController.foundFileCountLabel.stringValue = @"Searching for files...";
// Wait a max of 6 secs for the bundle service. Should the bundle service fall over, it will
// reconnect within 5 secs. Otherwise abandon bundle hashing and display the blockable event.
if (dispatch_semaphore_wait(self.bundleServiceSema,
dispatch_time(DISPATCH_TIME_NOW, 6 * NSEC_PER_SEC))) {
[self updateBlockNotification:event withBundleHash:nil];
return;
}
// Let all future requests flow, until the connection is terminated and we go back to waiting.
dispatch_semaphore_signal(self.bundleServiceSema);
// NSProgress becomes current for this thread. XPC messages vend a child node to the receiver.
[self.currentWindowController.progress becomeCurrentWithPendingUnitCount:100];
// Start hashing. Progress is reported to the root NSProgress (currentWindowController.progress).
[[self.bundleServiceConnection remoteObjectProxy]
hashBundleBinariesForEvent:event
reply:^(NSString *bh, NSArray<SNTStoredEvent *> *events, NSNumber *ms) {
// Revert to displaying the blockable event if we fail to calculate the bundle hash
if (!bh) return [self updateBlockNotification:event withBundleHash:nil];
event.fileBundleHash = bh;
event.fileBundleBinaryCount = @(events.count);
event.fileBundleHashMilliseconds = ms;
event.fileBundleExecutableRelPath = [events.firstObject fileBundleExecutableRelPath];
for (SNTStoredEvent *se in events) {
se.fileBundleHash = bh;
se.fileBundleBinaryCount = @(events.count);
se.fileBundleHashMilliseconds = ms;
}
// Send the results to santad. It will decide if they need to be synced.
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];
}];
[self.currentWindowController.progress resignCurrent];
}
- (void)updateBlockNotification:(SNTStoredEvent *)event withBundleHash:(NSString *)bundleHash {
dispatch_async(dispatch_get_main_queue(), ^{
if ([self.currentWindowController.event.idx isEqual:event.idx]) {
if (bundleHash) {
[self.currentWindowController.bundleHashLabel setHidden:NO];
} else {
[self.currentWindowController.bundleHashLabel removeFromSuperview];
[self.currentWindowController.bundleHashTitle removeFromSuperview];
}
self.currentWindowController.event.fileBundleHash = bundleHash;
[self.currentWindowController.foundFileCountLabel removeFromSuperview];
[self.currentWindowController.hashingIndicator setHidden:YES];
[self.currentWindowController.openEventButton setEnabled:YES];
}
});
}
@end

View File

@@ -1,4 +1,4 @@
/// Copyright 2014 Google Inc. All rights reserved.
/// 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.
@@ -12,6 +12,8 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <Cocoa/Cocoa.h>
#import "SNTAppDelegate.h"
int main(int argc, const char *argv[]) {

View File

@@ -1,73 +0,0 @@
/// Copyright 2014 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.
/// SNTBinaryInfo represents a binary on disk, providing access to details about that binary such as
/// the SHA-1, the Info.plist and the Mach-O data.
@interface SNTBinaryInfo : NSObject
/// Designated initializer
- (instancetype)initWithPath:(NSString *)path;
/// Return SHA-1 hash of this binary
- (NSString *)SHA1;
/// Returns the type of Mach-O file:
/// Dynamic Library, Kernel Extension, Fat Binary, Thin Binary
- (NSString *)machoType;
/// Returns the architectures included in this binary (e.g. x86_64, ppc)
- (NSArray *)architectures;
/// Returns YES if this file is a Mach-O file
- (BOOL)isMachO;
/// Returns YES if this file contains multiple architectures
- (BOOL)isFat;
/// Returns YES if this file is an executable Mach-O file
- (BOOL)isExecutable;
/// Returns YES if this file is a dynamic library
- (BOOL)isDylib;
/// Returns YES if this file is a kernel extension
- (BOOL)isKext;
/// Returns YES if this file is a script (e.g. it begins #!)
- (BOOL)isScript;
/// Returns an NSBundle if this file is part of a bundle.
- (NSBundle *)bundle;
/// Returns the path to the bundle this file is a part of, if any.
- (NSString *)bundlePath;
/// Returns either the Info.plist in the bundle this file is part of, or an embedded plist if there
/// is one. In the odd case that a file has both an embedded Info.plist and is part of a bundle,
/// the Info.plist from the bundle will be returned.
- (NSDictionary *)infoPlist;
/// Returns the CFBundleIdentifier from this file's Info.plist
- (NSString *)bundleIdentifier;
/// Returns the CFBundleName from this file's Info.plist
- (NSString *)bundleName;
/// Returns the CFBundleVersion from this file's Info.plist
- (NSString *)bundleVersion;
/// Returns the CFBundleShortVersionString from this file's Info.plist
- (NSString *)bundleShortVersionString;
@end

View File

@@ -1,291 +0,0 @@
/// Copyright 2014 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 "SNTBinaryInfo.h"
#import <CommonCrypto/CommonDigest.h>
#include <mach-o/loader.h>
#include <mach-o/swap.h>
@interface SNTBinaryInfo ()
@property NSString *path;
@property NSData *fileData;
@property NSBundle *bundleRef;
@property NSDictionary *infoDict;
@end
@implementation SNTBinaryInfo
- (instancetype)initWithPath:(NSString *)path {
self = [super init];
if (self) {
_path = path;
_fileData = [NSData dataWithContentsOfFile:path options:NSDataReadingMappedIfSafe error:nil];
if (!_fileData) return nil;
}
return self;
}
- (NSString *)SHA1 {
unsigned char sha1[CC_SHA1_DIGEST_LENGTH];
CC_SHA1([self.fileData bytes], (unsigned int)[self.fileData length], sha1);
// Convert the binary SHA into hex
NSMutableString *buf = [[NSMutableString alloc] initWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) {
[buf appendFormat:@"%02x", (unsigned char)sha1[i]];
}
return buf;
}
- (NSString *)machoType {
if ([self isDylib]) { return @"Dynamic Library"; }
if ([self isKext]) { return @"Kernel Extension"; }
if ([self isFat]) { return @"Fat Binary"; }
if ([self isMachO]) { return @"Thin Binary"; }
if ([self isScript]) { return @"Script"; }
return @"Unknown (not executable?)";
}
- (NSArray *)architectures {
if (![self isMachO]) return nil;
if ([self isFat]) {
NSMutableArray *ret = [[NSMutableArray alloc] init];
// Retrieve just the fat_header, if possible.
NSData *head = [self safeSubdataWithRange:NSMakeRange(0, sizeof(struct fat_header))];
if (!head) return nil;
struct fat_header *fat_header = (struct fat_header *)[head bytes];
// Get number of architectures in the binary
uint32_t narch = NSSwapBigIntToHost(fat_header->nfat_arch);
// Retrieve just the fat_arch's, make a mutable copy and if necessary swap the bytes
NSData *archs = [self safeSubdataWithRange:NSMakeRange(sizeof(struct fat_header),
sizeof(struct fat_arch) * narch)];
if (!archs) return nil;
struct fat_arch *fat_archs = (struct fat_arch *)[archs bytes];
// For each arch, get the name of it's architecture
for (int i = 0; i < narch; ++i) {
[ret addObject:[self nameForCPUType:NSSwapBigIntToHost(fat_archs[i].cputype)]];
}
return ret;
} else {
struct mach_header *hdr = [self firstMachHeader];
return @[ [self nameForCPUType:hdr->cputype] ];
}
return nil;
}
- (BOOL)isDylib {
struct mach_header *mach_header = [self firstMachHeader];
if (!mach_header) return NO;
if (mach_header->filetype == MH_DYLIB ||
mach_header->filetype == MH_FVMLIB) {
return YES;
}
return NO;
}
- (BOOL)isKext {
struct mach_header *mach_header = [self firstMachHeader];
if (!mach_header) return NO;
if (mach_header->filetype == MH_KEXT_BUNDLE) {
return YES;
}
return NO;
}
- (BOOL)isMachO {
return ([self.fileData length] >= 160 &&
([self isMachHeader:(struct mach_header *)[self.fileData bytes]] || [self isFat]));
}
- (BOOL)isFat {
return ([self isFatHeader:(struct fat_header *)[self.fileData bytes]]);
}
- (BOOL)isScript {
if ([self.fileData length] < 1) return NO;
char magic[2];
[self.fileData getBytes:&magic length:2];
return (strncmp("#!", magic, 2) == 0);
}
- (BOOL)isExecutable {
struct mach_header *mach_header = [self firstMachHeader];
if (!mach_header) return NO;
if (mach_header->filetype == MH_OBJECT ||
mach_header->filetype == MH_EXECUTE ||
mach_header->filetype == MH_PRELOAD) {
return YES;
}
return NO;
}
# pragma mark Bundle Information
/**
* Try and determine the bundle that the represented executable is contained within, if any.
*
* Rationale: An NSBundle has a method executablePath for discovering the main binary within a
* bundle but provides no way to get an NSBundle object when only the executablePath is known. Also,
* a bundle can contain multiple binaries within the MacOS folder and we want any of these to count
* as being part of the bundle.
*
* This method relies on executable bundles being laid out as follows:
*
*@code
* Bundle.app/
* Contents/
* MacOS/
* executable
*@endcode
*
* If @c self.path is the full path to @c executable above, this method would return an
* NSBundle reference for Bundle.app.
*/
- (NSBundle *)bundle {
if (self.bundleRef) return self.bundleRef;
NSArray *pathComponents = [self.path pathComponents];
// Check that the full path is at least 4-levels deep:
// e.g: /Calendar.app/Contents/MacOS/Calendar
if ([pathComponents count] < 4) return nil;
pathComponents = [pathComponents subarrayWithRange:NSMakeRange(0, [pathComponents count] - 3)];
self.bundleRef = [NSBundle bundleWithPath:[NSString pathWithComponents:pathComponents]];
// Clear the bundle if it doesn't have a bundle ID
if (![self.bundleRef objectForInfoDictionaryKey:@"CFBundleIdentifier"]) self.bundleRef = nil;
return self.bundleRef;
}
- (NSString *)bundlePath {
return [self.bundle bundlePath];
}
- (NSDictionary *)infoPlist {
if (self.infoDict) return self.infoDict;
if ([self bundle]) {
self.infoDict = [[self bundle] infoDictionary];
return self.infoDict;
}
NSURL *url = [NSURL fileURLWithPath:self.path isDirectory:NO];
self.infoDict =
(__bridge_transfer NSDictionary*)CFBundleCopyInfoDictionaryForURL((__bridge CFURLRef) url);
return self.infoDict;
}
- (NSString *)bundleIdentifier {
return [[self infoPlist] objectForKey:@"CFBundleIdentifier"];
}
- (NSString *)bundleName {
return [[self infoPlist] objectForKey:@"CFBundleName"];
}
- (NSString *)bundleVersion {
return [[self infoPlist] objectForKey:@"CFBundleVersion"];
}
- (NSString *)bundleShortVersionString {
return [[self infoPlist] objectForKey:@"CFBundleShortVersionString"];
}
# pragma mark Internal Methods
/// Look through the file for the first mach_header. If the file is thin, this will be the
/// header at the beginning of the file. If the file is fat, it will be the first
/// architecture-specific header.
- (struct mach_header *)firstMachHeader {
if (![self isMachO]) return NULL;
struct mach_header *mach_header = (struct mach_header *)[self.fileData bytes];
struct fat_header *fat_header = (struct fat_header *)[self.fileData bytes];
if ([self isFatHeader:fat_header]) {
// Get the bytes for the fat_arch
NSData *archHdr = [self safeSubdataWithRange:NSMakeRange(sizeof(struct fat_header),
sizeof(struct fat_arch))];
if (!archHdr) return nil;
struct fat_arch *fat_arch = (struct fat_arch *)[archHdr bytes];
// Get bytes for first mach_header
NSData *machHdr = [self safeSubdataWithRange:NSMakeRange(NSSwapBigIntToHost(fat_arch->offset),
sizeof(struct mach_header))];
if (!machHdr) return nil;
mach_header = (struct mach_header *)[machHdr bytes];
}
if ([self isMachHeader:mach_header]) {
return mach_header;
}
return NULL;
}
- (BOOL)isMachHeader:(struct mach_header *)header {
return (header->magic == MH_MAGIC || header->magic == MH_MAGIC_64 ||
header->magic == MH_CIGAM || header->magic == MH_CIGAM_64);
}
- (BOOL)isFatHeader:(struct fat_header *)header {
return (header->magic == FAT_MAGIC || header->magic == FAT_CIGAM);
}
/// Wrap subdataWithRange: in a @try/@catch, returning nil on exception.
/// Useful for when the range is beyond the end of the file.
- (NSData *)safeSubdataWithRange:(NSRange)range {
@try {
return [self.fileData subdataWithRange:range];
}
@catch (NSException *exception) {
return nil;
}
}
- (NSString *)nameForCPUType:(cpu_type_t)cpuType {
switch (cpuType) {
case CPU_TYPE_X86:
return @"i386";
case CPU_TYPE_X86_64:
return @"x86-64";
case CPU_TYPE_POWERPC:
return @"ppc";
case CPU_TYPE_POWERPC64:
return @"ppc64";
default:
return @"unknown";
}
return nil;
}
@end

View File

@@ -0,0 +1,47 @@
/// Copyright 2016 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
#ifdef SANTAGUI
#import <Cocoa/Cocoa.h>
#else
#import <Foundation/Foundation.h>
#endif
@class SNTStoredEvent;
@interface SNTBlockMessage : NSObject
///
/// Return a message suitable for presenting to the user.
/// Uses either the configured message depending on the event type or a custom message
/// if the rule that blocked this file included one.
///
/// In SantaGUI this will return an NSAttributedString with links and formatting included
/// while for santad all HTML will be properly stripped.
///
+ (NSAttributedString *)attributedBlockMessageForEvent:(SNTStoredEvent *)event
customMessage:(NSString *)customMessage;
///
/// Return a URL generated from the EventDetailURL configuration key
/// after replacing templates in the URL with values from the event.
///
+ (NSURL *)eventDetailURLForEvent:(SNTStoredEvent *)event;
///
/// Strip HTML from a string, replacing <br /> with newline.
///
+ (NSString *)stringFromHTML:(NSString *)html;
@end

View File

@@ -0,0 +1,115 @@
/// Copyright 2016 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import "SNTBlockMessage.h"
#import "SNTConfigurator.h"
#import "SNTLogging.h"
#import "SNTStoredEvent.h"
@implementation SNTBlockMessage
+ (NSAttributedString *)attributedBlockMessageForEvent:(SNTStoredEvent *)event
customMessage:(NSString *)customMessage {
NSString *htmlHeader = @"<html><head><style>"
@"body {"
@" font-family: 'Lucida Grande', 'Helvetica', sans-serif;"
@" font-size: 13px;"
@" color: #666;"
@" text-align: center;"
@"}"
@"</style></head><body>";
NSString *htmlFooter = @"</body></html>";
NSString *message;
if (customMessage.length) {
message = customMessage;
} else if (event.decision == SNTEventStateBlockUnknown) {
message = [[SNTConfigurator configurator] unknownBlockMessage];
if (!message) {
message = @"The following application has been blocked from executing<br />"
@"because its trustworthiness cannot be determined.";
}
} else {
message = [[SNTConfigurator configurator] bannedBlockMessage];
if (!message) {
message = @"The following application has been blocked from executing<br />"
@"because it has been deemed malicious.";
}
}
NSString *fullHTML = [NSString stringWithFormat:@"%@%@%@", htmlHeader, message, htmlFooter];
#ifdef NSAppKitVersionNumber10_0
NSData *htmlData = [fullHTML dataUsingEncoding:NSUTF8StringEncoding];
return [[NSAttributedString alloc] initWithHTML:htmlData documentAttributes:NULL];
#else
NSString *strippedHTML = [self stringFromHTML:fullHTML];
if (!strippedHTML) {
return [[NSAttributedString alloc] initWithString:@"This binary has been blocked."];
}
return [[NSAttributedString alloc] initWithString:strippedHTML];
#endif
}
+ (NSString *)stringFromHTML:(NSString *)html {
NSError *error;
NSXMLDocument *xml = [[NSXMLDocument alloc] initWithXMLString:html options:0 error:&error];
if (!xml && error.code == NSXMLParserEmptyDocumentError) {
html = [NSString stringWithFormat:@"<html><body>%@</body></html>", html];
xml = [[NSXMLDocument alloc] initWithXMLString:html options:0 error:&error];
if (!xml) return html;
}
// Strip any HTML tags out of the message. Also remove any content inside <style> tags and
// replace <br> elements with a newline.
NSString *stripXslt = @"<?xml version='1.0' encoding='utf-8'?>"
@"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
@" xmlns:xhtml='http://www.w3.org/1999/xhtml'>"
@"<xsl:output method='text'/>"
@"<xsl:template match='br'><xsl:text>\n</xsl:text></xsl:template>"
@"<xsl:template match='style'/>"
@"</xsl:stylesheet>";
NSData *data = [xml objectByApplyingXSLTString:stripXslt arguments:NULL error:&error];
if (error || ![data isKindOfClass:[NSData class]]) {
return html;
}
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
+ (NSURL *)eventDetailURLForEvent:(SNTStoredEvent *)event {
SNTConfigurator *config = [SNTConfigurator configurator];
NSString *formatStr = config.eventDetailURL;
if (!formatStr.length) return nil;
if (event.fileSHA256) {
formatStr =
[formatStr stringByReplacingOccurrencesOfString:@"%file_sha%"
withString:event.fileBundleHash ?: event.fileSHA256];
}
if (event.executingUser) {
formatStr = [formatStr stringByReplacingOccurrencesOfString:@"%username%"
withString:event.executingUser];
}
if (config.machineID) {
formatStr = [formatStr stringByReplacingOccurrencesOfString:@"%machine_id%"
withString:config.machineID];
}
return [NSURL URLWithString:formatStr];
}
@end

View File

@@ -1,67 +0,0 @@
/// Copyright 2014 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.
/// SNTCertificate wraps a @c SecCertificateRef to provide Objective-C accessors to
/// commonly used certificate data. Accessors cache data for repeated access.
@interface SNTCertificate : NSObject<NSSecureCoding>
/// Initialize a SNTCertificate object with a valid SecCertificateRef. Designated initializer.
- (instancetype)initWithSecCertificateRef:(SecCertificateRef)certRef;
/// Initialize a SNTCertificate object with certificate data in DER format.
/// Returns nil if |certData| is invalid.
- (instancetype)initWithCertificateDataDER:(NSData *)certData;
/// Initialize a SNTCertificate object with certificate data in PEM format.
/// If multiple PEM certificates exist within the string, the first is used.
/// Returns nil if |certData| is invalid.
- (instancetype)initWithCertificateDataPEM:(NSString *)certData;
/// Returns an array of SNTCertificate's for all of the certificates in |pemData|.
+ (NSArray *)certificatesFromPEM:(NSString *)pemData;
/// Access the underlying certificate ref.
@property(readonly) SecCertificateRef certRef;
/// SHA-1 hash of the certificate data.
@property(readonly) NSString *SHA1;
/// Certificate data.
@property(readonly) NSData *certData;
/// Common Name e.g: "Software Signing"
@property(readonly) NSString *commonName;
/// Country Name e.g: "US"
@property(readonly) NSString *countryName;
/// Organizational Name e.g: "Apple Inc."
@property(readonly) NSString *orgName;
/// Organizational Unit Name e.g: "Apple Software"
@property(readonly) NSString *orgUnit;
/// Issuer details, same fields as above.
@property(readonly) NSString *issuerCommonName;
@property(readonly) NSString *issuerCountryName;
@property(readonly) NSString *issuerOrgName;
@property(readonly) NSString *issuerOrgUnit;
/// Validity Not Before
@property(readonly) NSDate *validFrom;
/// Validity Not After
@property(readonly) NSDate *validUntil;
@end

View File

@@ -1,336 +0,0 @@
/// Copyright 2014 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 "SNTCertificate.h"
#import <CommonCrypto/CommonDigest.h>
#import <Security/Security.h>
@interface SNTCertificate ()
/// A container for cached property values
@property NSMutableDictionary *memoizedData;
@end
@implementation SNTCertificate
static NSString *const kCertDataKey = @"certData";
#pragma mark Init/Dealloc
- (instancetype)initWithSecCertificateRef:(SecCertificateRef)certRef {
self = [super init];
if (self) {
_certRef = certRef;
CFRetain(_certRef);
}
return self;
}
- (instancetype)initWithCertificateDataDER:(NSData *)certData {
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);
if (cert) {
// Despite the header file claiming that SecCertificateCreateWithData will return NULL if
// |certData| doesn't contain a valid DER-encoded X509 cert, this isn't always true.
// radar://problem/16124651
// To workaround, check that the certificate serial number can be retrieved.
NSData *ser = CFBridgingRelease(SecCertificateCopySerialNumber(cert, NULL));
if (ser) {
self = [self initWithSecCertificateRef:cert];
} else {
self = nil;
}
CFRelease(cert); // was retained in initWithSecCertificateRef
} else {
self = nil;
}
return self;
}
- (instancetype)initWithCertificateDataPEM:(NSString *)certData {
// Find the PEM and extract the base64-encoded DER data from within
NSScanner *scanner = [NSScanner scannerWithString:certData];
NSString *base64der;
// Locate and parse DER data into |base64der|
[scanner scanUpToString:@"-----BEGIN CERTIFICATE-----" intoString:NULL];
if (!([scanner scanString:@"-----BEGIN CERTIFICATE-----" intoString:NULL] &&
[scanner scanUpToString:@"-----END CERTIFICATE-----" intoString:&base64der] &&
[scanner scanString:@"-----END CERTIFICATE-----" intoString:NULL])) {
return nil;
}
// base64-decode the DER
SecTransformRef transform = SecDecodeTransformCreate(kSecBase64Encoding, NULL);
if (!transform) return nil;
NSData *input = [base64der dataUsingEncoding:NSUTF8StringEncoding];
NSData *output = nil;
if (SecTransformSetAttribute(transform,
kSecTransformInputAttributeName,
(__bridge CFDataRef)input,
NULL)) {
output = CFBridgingRelease(SecTransformExecute(transform, NULL));
}
if (transform) CFRelease(transform);
return [self initWithCertificateDataDER:output];
}
+ (NSArray *)certificatesFromPEM:(NSString *)pemData {
NSScanner *scanner = [NSScanner scannerWithString:pemData];
NSMutableArray *certs = [[NSMutableArray alloc] init];
while (YES) {
NSString *curCert;
[scanner scanUpToString:@"-----BEGIN CERTIFICATE-----" intoString:NULL];
[scanner scanUpToString:@"-----END CERTIFICATE-----" intoString:&curCert];
// If there was no data, break.
if (!curCert) break;
curCert = [curCert stringByAppendingString:@"-----END CERTIFICATE-----"];
SNTCertificate *cert = [[SNTCertificate alloc] initWithCertificateDataPEM:curCert];
// If the data couldn't be turned into a valid SNTCertificate, continue.
if (!cert) continue;
[certs addObject:cert];
}
return certs;
}
- (instancetype)init {
[self doesNotRecognizeSelector:_cmd];
return nil;
}
- (void)dealloc {
if (_certRef) CFRelease(_certRef);
}
#pragma mark Equality & description
- (BOOL)isEqual:(SNTCertificate *)other {
if (self == other) return YES;
if (![other isKindOfClass:[SNTCertificate class]]) return NO;
return [self.certData isEqual:other.certData];
}
- (NSUInteger)hash {
return [self.certData hash];
}
- (NSString *)description {
return [NSString stringWithFormat:@"/O=%@/OU=%@/CN=%@",
self.orgName,
self.orgUnit,
self.commonName];
}
#pragma mark NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:self.certData forKey:kCertDataKey];
}
- (instancetype)initWithCoder:(NSCoder *)decoder {
NSData *certData = [decoder decodeObjectOfClass:[NSData class] forKey:kCertDataKey];
if ([certData length] == 0) return nil;
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);
self = [self initWithSecCertificateRef:cert];
if (cert) CFRelease(cert);
return self;
}
#pragma mark Private Accessors
/// For a given selector, caches the value that selector would return on subsequent invocations,
/// using the provided block to get the value on the first invocation.
/// Assumes the selector's value will never change.
- (id)memoizedSelector:(SEL)selector forBlock:(id (^)(void))block {
NSString *selName = NSStringFromSelector(selector);
if (!self.memoizedData) {
self.memoizedData = [NSMutableDictionary dictionary];
}
if (!self.memoizedData[selName]) {
id val = block();
if (val) {
self.memoizedData[selName] = val;
} else {
self.memoizedData[selName] = [NSNull null];
}
}
// Return the value if there is one, or nil if the value is NSNull
return self.memoizedData[selName] != [NSNull null] ? self.memoizedData[selName] : nil;
}
- (NSDictionary *)allCertificateValues {
return [self memoizedSelector:_cmd forBlock:^id{
return CFBridgingRelease(SecCertificateCopyValues(self.certRef, NULL, NULL));
}];
}
- (NSDictionary *)x509SubjectName {
return [self memoizedSelector:_cmd forBlock:^id{
return [self allCertificateValues][(__bridge NSString *)kSecOIDX509V1SubjectName];
}];
}
- (NSDictionary *)x509IssuerName {
return [self memoizedSelector:_cmd forBlock:^id{
return [self allCertificateValues][(__bridge NSString *)kSecOIDX509V1IssuerName];
}];
}
/// Retrieve the value with the specified label from the X509 dictionary provided
/// @param desiredLabel The label you want, e.g: kSecOIDOrganizationName.
/// @param dict The dictionary to look in (Subject or Issuer)
/// @returns An @c NSString, the value for the specified label.
- (NSString *)x509ValueForLabel:(NSString *)desiredLabel fromDictionary:(NSDictionary *)dict {
@try {
NSArray *valArray = dict[(__bridge NSString *)kSecPropertyKeyValue];
for (NSDictionary *curCertVal in valArray) {
NSString *valueLabel = curCertVal[(__bridge NSString *)kSecPropertyKeyLabel];
if ([valueLabel isEqual:desiredLabel]) {
return curCertVal[(__bridge NSString *)kSecPropertyKeyValue];
}
}
return nil;
}
@catch (NSException *exception) {
return nil;
}
}
/// Retrieve the specified date from the certificate's values and convert from a reference date
/// to an NSDate object.
/// @param key The identifier for the date: @c kSecOIDX509V1ValiditityNot{Before,After}
/// @return An @c NSDate representing the date and time the certificate is valid from or expires.
- (NSDate *)dateForX509Key:(NSString *)key {
NSDictionary *curCertVal = [self allCertificateValues][key];
NSNumber *value = curCertVal[(__bridge NSString *)kSecPropertyKeyValue];
NSTimeInterval interval = [value doubleValue];
if (interval) {
return [NSDate dateWithTimeIntervalSinceReferenceDate:interval];
}
return nil;
}
#pragma mark Public Accessors
- (NSString *)SHA1 {
return [self memoizedSelector:_cmd forBlock:^id{
NSMutableData *SHA1Buffer = [[NSMutableData alloc] initWithCapacity:CC_SHA1_DIGEST_LENGTH];
CC_SHA1([self.certData bytes], (CC_LONG)[self.certData length], [SHA1Buffer mutableBytes]);
const unsigned char *bytes = (const unsigned char *)[SHA1Buffer bytes];
return [NSString stringWithFormat:
@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], bytes[8],
bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15], bytes[16],
bytes[17], bytes[18], bytes[19]];
}];
}
- (NSData *)certData {
return CFBridgingRelease(SecCertificateCopyData(self.certRef));
}
- (NSString *)commonName {
return [self memoizedSelector:_cmd forBlock:^id{
CFStringRef commonName = NULL;
SecCertificateCopyCommonName(self.certRef, &commonName);
return CFBridgingRelease(commonName);
}];
}
- (NSString *)countryName {
return [self memoizedSelector:_cmd forBlock:^id{
return [self x509ValueForLabel:(__bridge NSString *)kSecOIDCountryName
fromDictionary:[self x509SubjectName]];
}];
}
- (NSString *)orgName {
return [self memoizedSelector:_cmd forBlock:^id{
return [self x509ValueForLabel:(__bridge NSString *)kSecOIDOrganizationName
fromDictionary:[self x509SubjectName]];
}];
}
- (NSString *)orgUnit {
return [self memoizedSelector:_cmd forBlock:^id{
return [self x509ValueForLabel:(__bridge NSString *)kSecOIDOrganizationalUnitName
fromDictionary:[self x509SubjectName]];
}];
}
- (NSDate *)validFrom {
return [self memoizedSelector:_cmd forBlock:^id{
return [self dateForX509Key:(__bridge NSString *)kSecOIDX509V1ValidityNotBefore];
}];
}
- (NSDate *)validUntil {
return [self memoizedSelector:_cmd forBlock:^id{
return [self dateForX509Key:(__bridge NSString *)kSecOIDX509V1ValidityNotAfter];
}];
}
- (NSString *)issuerCommonName {
return [self memoizedSelector:_cmd forBlock:^id{
return [self x509ValueForLabel:(__bridge NSString *)kSecOIDCommonName
fromDictionary:[self x509IssuerName]];
}];
}
- (NSString *)issuerCountryName {
return [self memoizedSelector:_cmd forBlock:^id{
return [self x509ValueForLabel:(__bridge NSString *)kSecOIDCountryName
fromDictionary:[self x509IssuerName]];
}];
}
- (NSString *)issuerOrgName {
return [self memoizedSelector:_cmd forBlock:^id{
return [self x509ValueForLabel:(__bridge NSString *)kSecOIDOrganizationName
fromDictionary:[self x509IssuerName]];
}];
}
- (NSString *)issuerOrgUnit {
return [self memoizedSelector:_cmd forBlock:^id{
return [self x509ValueForLabel:(__bridge NSString *)kSecOIDOrganizationalUnitName
fromDictionary:[self x509IssuerName]];
}];
}
@end

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