Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a USB device blocking popup. #728

Merged
merged 13 commits into from
Feb 28, 2022
Merged
10 changes: 10 additions & 0 deletions Source/common/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,23 @@ objc_library(
],
)

objc_library(
name = "SNTDeviceEvent",
srcs = ["SNTDeviceEvent.m"],
hdrs = ["SNTDeviceEvent.h"],
deps = [
":SNTCommonEnums",
],
)

objc_library(
name = "SNTBlockMessage_SantaGUI",
srcs = ["SNTBlockMessage.m"],
hdrs = ["SNTBlockMessage.h"],
defines = ["SANTAGUI"],
deps = [
":SNTConfigurator",
":SNTDeviceEvent",
":SNTLogging",
":SNTStoredEvent",
],
Expand Down
9 changes: 7 additions & 2 deletions Source/common/SNTBlockMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,17 @@

///
/// 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 *)formatMessage:(NSString *)message;

///
/// Uses either the configured message depending on the event type or a custom message
/// if the rule that blocked this file included one, formatted using
/// +[SNTBlockMessage formatMessage].
///
+ (NSAttributedString *)attributedBlockMessageForEvent:(SNTStoredEvent *)event
customMessage:(NSString *)customMessage;

Expand Down
33 changes: 18 additions & 15 deletions Source/common/SNTBlockMessage.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@

@implementation SNTBlockMessage

+ (NSAttributedString *)attributedBlockMessageForEvent:(SNTStoredEvent *)event
customMessage:(NSString *)customMessage {
+ (NSAttributedString *)formatMessage:(NSString *)message {
NSString *htmlHeader =
@"<html><head><style>"
@"body {"
Expand All @@ -48,6 +47,22 @@ + (NSAttributedString *)attributedBlockMessageForEvent:(SNTStoredEvent *)event

NSString *htmlFooter = @"</body></html>";

NSString *fullHTML = [NSString stringWithFormat:@"%@%@%@", htmlHeader, message, htmlFooter];

#ifdef SANTAGUI
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
}

+ (NSAttributedString *)attributedBlockMessageForEvent:(SNTStoredEvent *)event
customMessage:(NSString *)customMessage {
NSString *message;
if (customMessage.length) {
message = customMessage;
Expand All @@ -64,19 +79,7 @@ + (NSAttributedString *)attributedBlockMessageForEvent:(SNTStoredEvent *)event
@"because it has been deemed malicious.";
}
}

NSString *fullHTML = [NSString stringWithFormat:@"%@%@%@", htmlHeader, message, htmlFooter];

#ifdef SANTAGUI
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
return [SNTBlockMessage formatMessage:message];
}

+ (NSString *)stringFromHTML:(NSString *)html {
Expand Down
14 changes: 14 additions & 0 deletions Source/common/SNTConfigurator.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,20 @@
///
@property(readonly, nonatomic) NSString *bannedBlockMessage;

///
/// This is the message shown to the user when a USB storage device's mount is denied
/// from the BlockUSB configuration setting. If not configured, a reasonable
/// default is provided.
///
@property(readonly, nonatomic) NSString *bannedUSBBlockMessage;

///
/// This is the message shown to the user when a USB storage device's mount is forcibly
/// remounted to a different set of permissions from the BlockUSB and RemountUSBMode
/// configuration settings. If not configured, a reasonable default is provided.
///
@property(readonly, nonatomic) NSString *remountUSBBlockMessage;

///
/// The notification text to display when the client goes into MONITOR mode.
/// Defaults to "Switching into Monitor mode"
Expand Down
13 changes: 13 additions & 0 deletions Source/common/SNTConfigurator.m
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ @implementation SNTConfigurator
static NSString *const kEventDetailTextKey = @"EventDetailText";
static NSString *const kUnknownBlockMessage = @"UnknownBlockMessage";
static NSString *const kBannedBlockMessage = @"BannedBlockMessage";
static NSString *const kBannedUSBBlockMessage = @"BannedUSBBlockMessage";
static NSString *const kRemountUSBBlockMessage = @"RemountUSBBlockMessage";

static NSString *const kModeNotificationMonitor = @"ModeNotificationMonitor";
static NSString *const kModeNotificationLockdown = @"ModeNotificationLockdown";

Expand Down Expand Up @@ -163,6 +166,8 @@ - (instancetype)init {
kEventDetailTextKey : string,
kUnknownBlockMessage : string,
kBannedBlockMessage : string,
kBannedUSBBlockMessage : string,
kRemountUSBBlockMessage : string,
kModeNotificationMonitor : string,
kModeNotificationLockdown : string,
kSyncBaseURLKey : string,
Expand Down Expand Up @@ -563,6 +568,14 @@ - (NSString *)bannedBlockMessage {
return self.configState[kBannedBlockMessage];
}

- (NSString *)bannedUSBBlockMessage {
return self.configState[kBannedUSBBlockMessage];
tnek marked this conversation as resolved.
Show resolved Hide resolved
}

- (NSString *)remountUSBBlockMessage {
return self.configState[kRemountUSBBlockMessage];
tnek marked this conversation as resolved.
Show resolved Hide resolved
}

- (NSString *)modeNotificationMonitor {
return self.configState[kModeNotificationMonitor];
}
Expand Down
25 changes: 25 additions & 0 deletions Source/common/SNTDeviceEvent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/// Copyright 2022 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.

#import <Foundation/Foundation.h>

@interface SNTDeviceEvent : NSObject <NSSecureCoding>

@property NSString *mntonname;
@property NSString *mntfromname;
@property NSArray<NSString *> *remountArgs;

- (NSString *)readableRemountArgs;

@end
54 changes: 54 additions & 0 deletions Source/common/SNTDeviceEvent.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#import "Source/common/SNTDeviceEvent.h"

@implementation SNTDeviceEvent
tnek marked this conversation as resolved.
Show resolved Hide resolved

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-literal-conversion"

#define ENCODE(obj, key) \
if (obj) [coder encodeObject:obj forKey:key]
#define DECODE(cls, key) [decoder decodeObjectOfClass:[cls class] forKey:key]
#define DECODEARRAY(cls, key) \
[decoder decodeObjectOfClasses:[NSSet setWithObjects:[NSArray class], [cls class], nil] \
forKey:key]

+ (BOOL)supportsSecureCoding {
return YES;
}

- (void)encodeWithCoder:(NSCoder *)coder {
ENCODE(self.mntonname, @"mntonname");
ENCODE(self.mntfromname, @"mntfromname");
ENCODE(self.remountArgs, @"remountArgs");
}

- (instancetype)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (self) {
_mntonname = DECODE(NSString, @"mntonname");
_mntfromname = DECODE(NSString, @"mntfromname");
_remountArgs = DECODEARRAY(NSString, @"remountArgs");
}
return self;
}
- (NSString *)description {
return [NSString stringWithFormat:@"SNTDeviceEvent '%@' -> '%@' (with permissions: [%@]",
self.mntfromname, self.mntonname,
[self.remountArgs componentsJoinedByString:@", "]];
}

- (NSString *)readableRemountArgs {
NSMutableArray<NSString *> *readable = [NSMutableArray array];
for (NSString *arg in self.remountArgs) {
if ([arg isEqualToString:@"rdonly"]) {
[readable addObject:@"read-only"];
} else if ([arg isEqualToString:@"noexec"]) {
[readable addObject:@"block executables"];
} else {
[readable addObject:arg];
}
}
return [readable componentsJoinedByString:@", "];
}

@end
2 changes: 2 additions & 0 deletions Source/common/SNTXPCNotifierInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
#import "Source/common/SNTXPCBundleServiceInterface.h"

@class SNTStoredEvent;
@class SNTDeviceEvent;

/// Protocol implemented by SantaGUI and utilized by santad
@protocol SNTNotifierXPC
- (void)postBlockNotification:(SNTStoredEvent *)event withCustomMessage:(NSString *)message;
- (void)postUSBBlockNotification:(SNTDeviceEvent *)event withCustomMessage:(NSString *)message;
- (void)postClientModeNotification:(SNTClientMode)clientmode;
- (void)postRuleSyncNotificationWithCustomMessage:(NSString *)message;
- (void)updateCountsForEvent:(SNTStoredEvent *)event
Expand Down
5 changes: 5 additions & 0 deletions Source/santa/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ objc_library(
"SNTAccessibleTextField.m",
"SNTAppDelegate.h",
"SNTAppDelegate.m",
"SNTBinaryMessageWindowController.h",
"SNTBinaryMessageWindowController.m",
"SNTDeviceMessageWindowController.h",
"SNTDeviceMessageWindowController.m",
"SNTMessageWindow.h",
"SNTMessageWindow.m",
"SNTMessageWindowController.h",
Expand All @@ -25,6 +29,7 @@ objc_library(
],
data = [
"Resources/AboutWindow.xib",
"Resources/DeviceMessageWindow.xib",
"Resources/MessageWindow.xib",
],
sdk_frameworks = [
Expand Down
10 changes: 5 additions & 5 deletions Source/santa/Resources/AboutWindow.xib
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="19455" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="19455"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
Expand All @@ -17,7 +17,7 @@
<window title="Santa" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="F0z-JX-Cv5">
<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="3840" height="1577"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="480" height="200"/>
<autoresizingMask key="autoresizingMask"/>
Expand Down Expand Up @@ -47,7 +47,7 @@ There are no user-configurable settings.</string>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SRu-Kf-vu5">
<rect key="frame" x="130" y="21" width="111" height="32"/>
<rect key="frame" x="129" y="21" width="113" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="99" id="JHv-2J-QSe"/>
</constraints>
Expand All @@ -60,7 +60,7 @@ There are no user-configurable settings.</string>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Udo-BY-n7e">
<rect key="frame" x="240" y="21" width="111" height="32"/>
<rect key="frame" x="239" y="21" width="113" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="99" id="2Xc-ax-2bV"/>
</constraints>
Expand Down
Loading