mirror of
https://github.com/google/santa.git
synced 2026-02-08 21:05:15 -05:00
159 lines
5.5 KiB
Objective-C
159 lines
5.5 KiB
Objective-C
/// 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.
|
|
|
|
#include <pwd.h>
|
|
#include <sys/types.h>
|
|
|
|
#import "SNTApplication.h"
|
|
|
|
#include "SNTCommonEnums.h"
|
|
#include "SNTLogging.h"
|
|
|
|
#import "SNTConfigurator.h"
|
|
#import "SNTDaemonControlController.h"
|
|
#import "SNTDatabaseController.h"
|
|
#import "SNTDriverManager.h"
|
|
#import "SNTEventTable.h"
|
|
#import "SNTExecutionController.h"
|
|
#import "SNTRuleTable.h"
|
|
#import "SNTXPCConnection.h"
|
|
#import "SNTXPCControlInterface.h"
|
|
#import "SNTXPCNotifierInterface.h"
|
|
|
|
@interface SNTApplication ()
|
|
@property SNTDriverManager *driverManager;
|
|
@property SNTEventTable *eventTable;
|
|
@property SNTExecutionController *execController;
|
|
@property SNTRuleTable *ruleTable;
|
|
@property SNTXPCConnection *controlConnection;
|
|
@property SNTXPCConnection *notifierConnection;
|
|
@end
|
|
|
|
@implementation SNTApplication
|
|
|
|
- (instancetype)init {
|
|
self = [super init];
|
|
if (self) {
|
|
// Locate and connect to driver
|
|
_driverManager = [[SNTDriverManager alloc] init];
|
|
|
|
if (!_driverManager) {
|
|
LOGE(@"Failed to connect to driver, exiting.");
|
|
|
|
// TODO(rah): Consider trying to load the extension from within santad.
|
|
return nil;
|
|
}
|
|
|
|
// Initialize tables
|
|
_ruleTable = [SNTDatabaseController ruleTable];
|
|
if (! _ruleTable) {
|
|
LOGE(@"Failed to initialize rule table.");
|
|
return nil;
|
|
}
|
|
|
|
_eventTable = [SNTDatabaseController eventTable];
|
|
if (! _eventTable) {
|
|
LOGE(@"Failed to initialize event table.");
|
|
return nil;
|
|
}
|
|
|
|
// Establish XPC listener for GUI agent connections
|
|
_notifierConnection =
|
|
[[SNTXPCConnection alloc] initServerWithName:[SNTXPCNotifierInterface serviceId]];
|
|
_notifierConnection.remoteInterface = [SNTXPCNotifierInterface notifierInterface];
|
|
[_notifierConnection resume];
|
|
|
|
// Establish XPC listener for santactl connections
|
|
_controlConnection =
|
|
[[SNTXPCConnection alloc] initServerWithName:[SNTXPCControlInterface serviceId]];
|
|
_controlConnection.exportedInterface = [SNTXPCControlInterface controlInterface];
|
|
_controlConnection.exportedObject =
|
|
[[SNTDaemonControlController alloc] initWithDriverManager:_driverManager];
|
|
[_controlConnection resume];
|
|
|
|
// Get client mode and begin observing for updates
|
|
SNTConfigurator *configurator = [SNTConfigurator configurator];
|
|
santa_clientmode_t clientMode = [configurator clientMode];
|
|
[configurator addObserver:self
|
|
forKeyPath:@"clientMode"
|
|
options:NSKeyValueObservingOptionNew
|
|
context:NULL];
|
|
|
|
// Initialize the binary checker object
|
|
_execController = [[SNTExecutionController alloc] initWithDriverManager:_driverManager
|
|
ruleTable:_ruleTable
|
|
eventTable:_eventTable
|
|
operatingMode:clientMode
|
|
notifierConnection:_notifierConnection];
|
|
if (!_execController) return nil;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)observeValueForKeyPath:(NSString *)keyPath
|
|
ofObject:(id)object
|
|
change:(NSDictionary *)change
|
|
context:(void *)context {
|
|
if ([keyPath isEqual:@"clientMode"]) {
|
|
self.execController.operatingMode = [change[NSKeyValueChangeNewKey] intValue];
|
|
}
|
|
}
|
|
|
|
- (int)run {
|
|
LOGI(@"Connected to driver, activating.");
|
|
|
|
dispatch_queue_t q = dispatch_queue_create("com.google.santad.driver_queue",
|
|
DISPATCH_QUEUE_CONCURRENT);
|
|
|
|
[self.driverManager listenWithBlock:^BOOL(santa_message_t message) {
|
|
@autoreleasepool {
|
|
switch (message.action) {
|
|
case ACTION_REQUEST_SHUTDOWN: {
|
|
LOGI(@"Driver requested a shutdown");
|
|
// Sleep before exiting to give driver chance to ready itself
|
|
sleep(10);
|
|
return NO;
|
|
}
|
|
case ACTION_REQUEST_CHECKBW: {
|
|
// Validate the binary aynchronously on a concurrent queue so we don't
|
|
// hold up other execution requests in the background.
|
|
dispatch_async(q, ^{
|
|
struct passwd *user = getpwuid(message.userId);
|
|
NSString *userName;
|
|
if (user) {
|
|
userName = @(user->pw_name);
|
|
}
|
|
|
|
[self.execController validateBinaryWithSHA1:@(message.sha1)
|
|
path:@(message.path)
|
|
userName:userName
|
|
pid:@(message.pid)
|
|
vnodeId:message.vnode_id];
|
|
});
|
|
return YES;
|
|
}
|
|
default: {
|
|
LOGE(@"Received request without an action");
|
|
return NO;
|
|
}
|
|
}
|
|
}
|
|
}];
|
|
|
|
return 0;
|
|
}
|
|
|
|
@end
|