mirror of
https://github.com/google/santa.git
synced 2026-04-24 03:00:12 -04:00
99 lines
4.0 KiB
Objective-C
99 lines
4.0 KiB
Objective-C
/// Copyright 2017 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 "Source/santad/SNTCompilerController.h"
|
|
|
|
#import "Source/common/SNTCachedDecision.h"
|
|
#import "Source/common/SNTCommonEnums.h"
|
|
#import "Source/common/SNTFileInfo.h"
|
|
#import "Source/common/SNTKernelCommon.h"
|
|
#import "Source/common/SNTLogging.h"
|
|
#import "Source/common/SNTRule.h"
|
|
#import "Source/santad/DataLayer/SNTRuleTable.h"
|
|
#import "Source/santad/EventProviders/SNTEventProvider.h"
|
|
#import "Source/santad/Logs/SNTEventLog.h"
|
|
#import "Source/santad/SNTDatabaseController.h"
|
|
|
|
@interface SNTCompilerController ()
|
|
@property id<SNTEventProvider> eventProvider;
|
|
@end
|
|
|
|
@implementation SNTCompilerController
|
|
|
|
- (instancetype)initWithEventProvider:(id<SNTEventProvider>)eventProvider {
|
|
self = [super init];
|
|
if (self) {
|
|
_eventProvider = eventProvider;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
// Adds a fake cached decision to SNTEventLog for pending files. If the file
|
|
// is executed before we can create a transitive rule for it, then we can at
|
|
// least log the pending decision info.
|
|
- (void)saveFakeDecision:(santa_message_t)message {
|
|
SNTCachedDecision *cd = [[SNTCachedDecision alloc] init];
|
|
cd.decision = SNTEventStateAllowPendingTransitive;
|
|
cd.vnodeId = message.vnode_id;
|
|
cd.sha256 = @"pending";
|
|
[[SNTEventLog logger] cacheDecision:cd];
|
|
}
|
|
|
|
- (void)removeFakeDecision:(santa_message_t)message {
|
|
[[SNTEventLog logger] forgetCachedDecisionForVnodeId:message.vnode_id];
|
|
}
|
|
|
|
// Assume that this method is called only when we already know that the writing process is a
|
|
// compiler. It checks if the closed file is executable, and if so, transitively allowlists it.
|
|
// The passed in message contains the pid of the writing process and path of closed file.
|
|
- (void)createTransitiveRule:(santa_message_t)message {
|
|
[self saveFakeDecision:message];
|
|
|
|
char *target = message.path;
|
|
|
|
// Check if this file is an executable.
|
|
SNTFileInfo *fi = [[SNTFileInfo alloc] initWithPath:@(target)];
|
|
if (fi.isExecutable) {
|
|
// Check if there is an existing (non-transitive) rule for this file. We leave existing rules
|
|
// alone, so that a allowlist or blocklist rule can't be overwritten by a transitive one.
|
|
SNTRuleTable *ruleTable = [SNTDatabaseController ruleTable];
|
|
SNTRule *prevRule = [ruleTable ruleForBinarySHA256:fi.SHA256 certificateSHA256:nil teamID:nil];
|
|
if (!prevRule || prevRule.state == SNTRuleStateAllowTransitive) {
|
|
// Construct a new transitive allowlist rule for the executable.
|
|
SNTRule *rule = [[SNTRule alloc] initWithIdentifier:fi.SHA256
|
|
state:SNTRuleStateAllowTransitive
|
|
type:SNTRuleTypeBinary
|
|
customMsg:@""];
|
|
|
|
// Add the new rule to the rules database.
|
|
NSError *err;
|
|
if (![ruleTable addRules:@[ rule ] cleanSlate:NO error:&err]) {
|
|
LOGE(@"unable to add new transitive rule to database: %@", err.localizedDescription);
|
|
} else {
|
|
[[SNTEventLog logger]
|
|
writeLog:[NSString
|
|
stringWithFormat:@"action=ALLOWLIST|pid=%d|pidversion=%d|path=%s|sha256=%@",
|
|
message.pid, message.pidversion, target, fi.SHA256]];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove the temporary allow rule in the kernel decision cache.
|
|
[self.eventProvider removeCacheEntryForVnodeID:message.vnode_id];
|
|
// Remove the "pending" decision info from SNTEventLog.
|
|
[self removeFakeDecision:message];
|
|
}
|
|
|
|
@end
|