Skip to content

Commit

Permalink
Merge 106c788 into 6a697e0
Browse files Browse the repository at this point in the history
  • Loading branch information
mlw committed Mar 5, 2024
2 parents 6a697e0 + 106c788 commit cb9e341
Show file tree
Hide file tree
Showing 41 changed files with 489 additions and 89 deletions.
1 change: 1 addition & 0 deletions Source/common/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ objc_library(
deps = [
":SNTCommonEnums",
":SNTRule",
":SNTRuleIdentifiers",
":SNTStoredEvent",
":SNTXPCBundleServiceInterface",
":SantaVnode",
Expand Down
1 change: 1 addition & 0 deletions Source/common/SNTCachedDecision.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
@property NSArray<MOLCertificate *> *certChain;
@property NSString *teamID;
@property NSString *signingID;
@property NSString *cdhash;
@property NSDictionary *entitlements;
@property BOOL entitlementsFiltered;

Expand Down
3 changes: 3 additions & 0 deletions Source/common/SNTCommonEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ typedef NS_ENUM(NSInteger, SNTAction) {
typedef NS_ENUM(NSInteger, SNTRuleType) {
SNTRuleTypeUnknown = 0,

SNTRuleTypeCDHash = 500,
SNTRuleTypeBinary = 1000,
SNTRuleTypeSigningID = 2000,
SNTRuleTypeCertificate = 3000,
Expand Down Expand Up @@ -84,6 +85,7 @@ typedef NS_ENUM(uint64_t, SNTEventState) {
SNTEventStateBlockTeamID = 1ULL << 20,
SNTEventStateBlockLongPath = 1ULL << 21,
SNTEventStateBlockSigningID = 1ULL << 22,
SNTEventStateBlockCDHash = 1ULL << 23,

// Bits 40-63 store allow decision types
SNTEventStateAllowUnknown = 1ULL << 40,
Expand All @@ -95,6 +97,7 @@ typedef NS_ENUM(uint64_t, SNTEventState) {
SNTEventStateAllowPendingTransitive = 1ULL << 46,
SNTEventStateAllowTeamID = 1ULL << 47,
SNTEventStateAllowSigningID = 1ULL << 48,
SNTEventStateAllowCDHash = 1ULL << 49,

// Block and Allow masks
SNTEventStateBlock = 0xFFFFFFULL << 16,
Expand Down
11 changes: 11 additions & 0 deletions Source/common/SNTRule.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#import "Source/common/SNTRule.h"

#include <CommonCrypto/CommonCrypto.h>
#include <Kernel/kern/cs_blobs.h>
#include <os/base.h>

#import "Source/common/SNTSyncConstants.h"
Expand Down Expand Up @@ -103,6 +104,14 @@ - (instancetype)initWithIdentifier:(NSString *)identifier
break;
}

case SNTRuleTypeCDHash: {
identifier = [[identifier lowercaseString] stringByTrimmingCharactersInSet:nonHex];
if (identifier.length != CS_CDHASH_LEN * 2) {
return nil;
}
break;
}

default: {
break;
}
Expand Down Expand Up @@ -173,6 +182,8 @@ - (instancetype)initWithDictionary:(NSDictionary *)dict {
type = SNTRuleTypeTeamID;
} else if ([ruleTypeString isEqual:kRuleTypeSigningID]) {
type = SNTRuleTypeSigningID;
} else if ([ruleTypeString isEqual:kRuleTypeCDHash]) {
type = SNTRuleTypeCDHash;
} else {
return nil;
}
Expand Down
2 changes: 2 additions & 0 deletions Source/common/SNTRuleIdentifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@
#import <Foundation/Foundation.h>

struct RuleIdentifiers {
NSString *cdhash;
NSString *binarySHA256;
NSString *signingID;
NSString *certificateSHA256;
NSString *teamID;
};

@interface SNTRuleIdentifiers : NSObject
@property(readonly) NSString *cdhash;
@property(readonly) NSString *binarySHA256;
@property(readonly) NSString *signingID;
@property(readonly) NSString *certificateSHA256;
Expand Down
4 changes: 3 additions & 1 deletion Source/common/SNTRuleIdentifiers.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ @implementation SNTRuleIdentifiers
- (instancetype)initWithRuleIdentifiers:(struct RuleIdentifiers)identifiers {
self = [super init];
if (self) {
_cdhash = identifiers.cdhash;
_binarySHA256 = identifiers.binarySHA256;
_signingID = identifiers.signingID;
_certificateSHA256 = identifiers.certificateSHA256;
Expand All @@ -28,7 +29,8 @@ - (instancetype)initWithRuleIdentifiers:(struct RuleIdentifiers)identifiers {
}

- (struct RuleIdentifiers)toStruct {
return (struct RuleIdentifiers){.binarySHA256 = self.binarySHA256,
return (struct RuleIdentifiers){.cdhash = self.cdhash,
.binarySHA256 = self.binarySHA256,
.signingID = self.signingID,
.certificateSHA256 = self.certificateSHA256,
.teamID = self.teamID};
Expand Down
5 changes: 5 additions & 0 deletions Source/common/SNTStoredEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@
///
@property NSString *signingID;

///
/// If the executed file was signed, this is the CDHash of the binary.
///
@property NSString *cdhash;

///
/// The user who executed the binary.
///
Expand Down
2 changes: 2 additions & 0 deletions Source/common/SNTStoredEvent.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ - (void)encodeWithCoder:(NSCoder *)coder {
ENCODE(self.signingChain, @"signingChain");
ENCODE(self.teamID, @"teamID");
ENCODE(self.signingID, @"signingID");
ENCODE(self.cdhash, @"cdhash");

ENCODE(self.executingUser, @"executingUser");
ENCODE(self.occurrenceDate, @"occurrenceDate");
Expand Down Expand Up @@ -97,6 +98,7 @@ - (instancetype)initWithCoder:(NSCoder *)decoder {
_signingChain = DECODEARRAY(MOLCertificate, @"signingChain");
_teamID = DECODE(NSString, @"teamID");
_signingID = DECODE(NSString, @"signingID");
_cdhash = DECODE(NSString, @"cdhash");

_executingUser = DECODE(NSString, @"executingUser");
_occurrenceDate = DECODE(NSDate, @"occurrenceDate");
Expand Down
5 changes: 5 additions & 0 deletions Source/common/SNTSyncConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ extern NSString *const kCompilerRuleCount;
extern NSString *const kTransitiveRuleCount;
extern NSString *const kTeamIDRuleCount;
extern NSString *const kSigningIDRuleCount;
extern NSString *const kCDHashRuleCount;
extern NSString *const kFullSyncInterval;
extern NSString *const kFCMToken;
extern NSString *const kFCMFullSyncInterval;
Expand All @@ -70,12 +71,14 @@ extern NSString *const kDecisionAllowCertificate;
extern NSString *const kDecisionAllowScope;
extern NSString *const kDecisionAllowTeamID;
extern NSString *const kDecisionAllowSigningID;
extern NSString *const kDecisionAllowCDHash;
extern NSString *const kDecisionBlockUnknown;
extern NSString *const kDecisionBlockBinary;
extern NSString *const kDecisionBlockCertificate;
extern NSString *const kDecisionBlockScope;
extern NSString *const kDecisionBlockTeamID;
extern NSString *const kDecisionBlockSigningID;
extern NSString *const kDecisionBlockCDHash;
extern NSString *const kDecisionUnknown;
extern NSString *const kDecisionBundleBinary;
extern NSString *const kLoggedInUsers;
Expand All @@ -101,6 +104,7 @@ extern NSString *const kCertValidFrom;
extern NSString *const kCertValidUntil;
extern NSString *const kTeamID;
extern NSString *const kSigningID;
extern NSString *const kCDHash;
extern NSString *const kQuarantineDataURL;
extern NSString *const kQuarantineRefererURL;
extern NSString *const kQuarantineTimestamp;
Expand All @@ -125,6 +129,7 @@ extern NSString *const kRuleTypeBinary;
extern NSString *const kRuleTypeCertificate;
extern NSString *const kRuleTypeTeamID;
extern NSString *const kRuleTypeSigningID;
extern NSString *const kRuleTypeCDHash;
extern NSString *const kRuleCustomMsg;
extern NSString *const kRuleCustomURL;
extern NSString *const kCursor;
Expand Down
5 changes: 5 additions & 0 deletions Source/common/SNTSyncConstants.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
NSString *const kTransitiveRuleCount = @"transitive_rule_count";
NSString *const kTeamIDRuleCount = @"teamid_rule_count";
NSString *const kSigningIDRuleCount = @"signingid_rule_count";
NSString *const kCDHashRuleCount = @"cdhash_rule_count";
NSString *const kFullSyncInterval = @"full_sync_interval";
NSString *const kFCMToken = @"fcm_token";
NSString *const kFCMFullSyncInterval = @"fcm_full_sync_interval";
Expand Down Expand Up @@ -71,12 +72,14 @@
NSString *const kDecisionAllowScope = @"ALLOW_SCOPE";
NSString *const kDecisionAllowTeamID = @"ALLOW_TEAMID";
NSString *const kDecisionAllowSigningID = @"ALLOW_SIGNINGID";
NSString *const kDecisionAllowCDHash = @"ALLOW_CDHASH";
NSString *const kDecisionBlockUnknown = @"BLOCK_UNKNOWN";
NSString *const kDecisionBlockBinary = @"BLOCK_BINARY";
NSString *const kDecisionBlockCertificate = @"BLOCK_CERTIFICATE";
NSString *const kDecisionBlockScope = @"BLOCK_SCOPE";
NSString *const kDecisionBlockTeamID = @"BLOCK_TEAMID";
NSString *const kDecisionBlockSigningID = @"BLOCK_SIGNINGID";
NSString *const kDecisionBlockCDHash = @"BLOCK_CDHASH";
NSString *const kDecisionUnknown = @"UNKNOWN";
NSString *const kDecisionBundleBinary = @"BUNDLE_BINARY";
NSString *const kLoggedInUsers = @"logged_in_users";
Expand All @@ -102,6 +105,7 @@
NSString *const kCertValidUntil = @"valid_until";
NSString *const kTeamID = @"team_id";
NSString *const kSigningID = @"signing_id";
NSString *const kCDHash = @"cdhash";
NSString *const kQuarantineDataURL = @"quarantine_data_url";
NSString *const kQuarantineRefererURL = @"quarantine_referer_url";
NSString *const kQuarantineTimestamp = @"quarantine_timestamp";
Expand All @@ -126,6 +130,7 @@
NSString *const kRuleTypeCertificate = @"CERTIFICATE";
NSString *const kRuleTypeTeamID = @"TEAMID";
NSString *const kRuleTypeSigningID = @"SIGNINGID";
NSString *const kRuleTypeCDHash = @"CDHASH";
NSString *const kRuleCustomMsg = @"custom_msg";
NSString *const kRuleCustomURL = @"custom_url";
NSString *const kCursor = @"cursor";
Expand Down
13 changes: 4 additions & 9 deletions Source/common/SNTXPCUnprivilegedControlInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#import <MOLCertificate/MOLCertificate.h>

#import "Source/common/SNTCommonEnums.h"
#import "Source/common/SNTRuleIdentifiers.h"
#import "Source/common/SantaVnode.h"

@class SNTRule;
Expand All @@ -29,6 +30,7 @@ struct RuleCounts {
int64_t transitive;
int64_t teamID;
int64_t signingID;
int64_t cdhash;
};

///
Expand All @@ -55,17 +57,10 @@ struct RuleCounts {

///
/// @param filePath A Path to the file, can be nil.
/// @param fileSHA256 The pre-calculated SHA256 hash for the file, can be nil. If nil the hash will
/// be calculated by this method from the filePath.
/// @param certificateSHA256 A SHA256 hash of the signing certificate, can be nil.
/// @note If fileInfo and signingCertificate are both passed in, the most specific rule will be
/// returned. Binary rules take precedence over cert rules.
/// @param identifiers The various identifiers to be used when making a decision.
///
- (void)decisionForFilePath:(NSString *)filePath
fileSHA256:(NSString *)fileSHA256
certificateSHA256:(NSString *)certificateSHA256
teamID:(NSString *)teamID
signingID:(NSString *)signingID
identifiers:(SNTRuleIdentifiers *)identifiers
reply:(void (^)(SNTEventState))reply;

///
Expand Down
1 change: 1 addition & 0 deletions Source/common/santa.proto
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ message Execution {
REASON_LONG_PATH = 9;
REASON_NOT_RUNNING = 10;
REASON_SIGNING_ID = 11;
REASON_CDHASH = 12;
}
optional Reason reason = 10;

Expand Down
43 changes: 32 additions & 11 deletions Source/santactl/Commands/SNTCommandFileInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#import "Source/common/SNTFileInfo.h"
#import "Source/common/SNTLogging.h"
#import "Source/common/SNTRule.h"
#import "Source/common/SNTRuleIdentifiers.h"
#import "Source/common/SNTStoredEvent.h"
#import "Source/common/SNTXPCBundleServiceInterface.h"
#import "Source/common/SNTXPCControlInterface.h"
Expand All @@ -45,6 +46,7 @@
static NSString *const kUniversalSigningChain = @"Universal Signing Chain";
static NSString *const kTeamID = @"Team ID";
static NSString *const kSigningID = @"Signing ID";
static NSString *const kCDHash = @"CDHash";

// signing chain keys
static NSString *const kCommonName = @"Common Name";
Expand Down Expand Up @@ -123,6 +125,7 @@ @interface SNTCommandFileInfo : SNTCommand <SNTCommandProtocol>
@property(readonly, copy, nonatomic) SNTAttributeBlock downloadAgent;
@property(readonly, copy, nonatomic) SNTAttributeBlock teamID;
@property(readonly, copy, nonatomic) SNTAttributeBlock signingID;
@property(readonly, copy, nonatomic) SNTAttributeBlock cdhash;
@property(readonly, copy, nonatomic) SNTAttributeBlock type;
@property(readonly, copy, nonatomic) SNTAttributeBlock pageZero;
@property(readonly, copy, nonatomic) SNTAttributeBlock codeSigned;
Expand Down Expand Up @@ -201,8 +204,8 @@ + (NSString *)longHelpText {
+ (NSArray<NSString *> *)fileInfoKeys {
return @[
kPath, kSHA256, kSHA1, kBundleName, kBundleVersion, kBundleVersionStr, kDownloadReferrerURL,
kDownloadURL, kDownloadTimestamp, kDownloadAgent, kTeamID, kSigningID, kType, kPageZero,
kCodeSigned, kRule, kSigningChain, kUniversalSigningChain
kDownloadURL, kDownloadTimestamp, kDownloadAgent, kTeamID, kSigningID, kCDHash, kType,
kPageZero, kCodeSigned, kRule, kSigningChain, kUniversalSigningChain
];
}

Expand Down Expand Up @@ -236,6 +239,7 @@ - (instancetype)initWithDaemonConnection:(MOLXPCConnection *)daemonConn {
kUniversalSigningChain : self.universalSigningChain,
kTeamID : self.teamID,
kSigningID : self.signingID,
kCDHash : self.cdhash,
};

_printQueue = dispatch_queue_create("com.google.santactl.print_queue", DISPATCH_QUEUE_SERIAL);
Expand Down Expand Up @@ -376,6 +380,8 @@ - (SNTAttributeBlock)rule {
NSError *err;
MOLCodesignChecker *csc = [fileInfo codesignCheckerWithError:&err];

NSString *cdhash =
[csc.signingInformation objectForKey:(__bridge NSString *)kSecCodeInfoUnique];
NSString *teamID =
[csc.signingInformation objectForKey:(__bridge NSString *)kSecCodeInfoTeamIdentifier];
NSString *identifier =
Expand All @@ -394,15 +400,21 @@ - (SNTAttributeBlock)rule {
}
}

[[cmd.daemonConn remoteObjectProxy] decisionForFilePath:fileInfo.path
fileSHA256:fileInfo.SHA256
certificateSHA256:err ? nil : csc.leafCertificate.SHA256
teamID:teamID
signingID:signingID
reply:^(SNTEventState s) {
state = s;
dispatch_semaphore_signal(sema);
}];
struct RuleIdentifiers identifiers = {
.cdhash = cdhash,
.binarySHA256 = fileInfo.SHA256,
.signingID = signingID,
.certificateSHA256 = err ? nil : csc.leafCertificate.SHA256,
.teamID = teamID,
};

[[cmd.daemonConn remoteObjectProxy]
decisionForFilePath:fileInfo.path
identifiers:[[SNTRuleIdentifiers alloc] initWithRuleIdentifiers:identifiers]
reply:^(SNTEventState s) {
state = s;
dispatch_semaphore_signal(sema);
}];
if (dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC))) {
cmd.daemonUnavailable = YES;
return kCommunicationErrorMsg;
Expand All @@ -420,6 +432,8 @@ - (SNTAttributeBlock)rule {
case SNTEventStateBlockTeamID: [output appendString:@" (TeamID)"]; break;
case SNTEventStateAllowSigningID:
case SNTEventStateBlockSigningID: [output appendString:@" (SigningID)"]; break;
case SNTEventStateAllowCDHash:
case SNTEventStateBlockCDHash: [output appendString:@" (CDHash)"]; break;
case SNTEventStateAllowScope:
case SNTEventStateBlockScope: [output appendString:@" (Scope)"]; break;
case SNTEventStateAllowCompiler: [output appendString:@" (Compiler)"]; break;
Expand Down Expand Up @@ -519,6 +533,13 @@ - (SNTAttributeBlock)signingID {
};
}

- (SNTAttributeBlock)cdhash {
return ^id(SNTCommandFileInfo *cmd, SNTFileInfo *fileInfo) {
MOLCodesignChecker *csc = [fileInfo codesignCheckerWithError:NULL];
return [csc.signingInformation objectForKey:(__bridge NSString *)kSecCodeInfoUnique];
};
}

#pragma mark -

// Entry point for the command.
Expand Down

0 comments on commit cb9e341

Please sign in to comment.