• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

google / santa / 10309967616

08 Aug 2024 09:43PM UTC coverage: 62.69% (-0.4%) from 63.125%
10309967616

push

github

web-flow
sync: Fix Content-Type logic bug, add test (#1412)

5612 of 13404 branches covered (41.87%)

Branch coverage included in aggregate %.

12 of 12 new or added lines in 2 files covered. (100.0%)

170 existing lines in 8 files now uncovered.

18659 of 25312 relevant lines covered (73.72%)

6451.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

56.28
/Source/common/SNTBlockMessage.m
1
/// Copyright 2016 Google Inc. All rights reserved.
2
///
3
/// Licensed under the Apache License, Version 2.0 (the "License");
4
/// you may not use this file except in compliance with the License.
5
/// You may obtain a copy of the License at
6
///
7
///    http://www.apache.org/licenses/LICENSE-2.0
8
///
9
///    Unless required by applicable law or agreed to in writing, software
10
///    distributed under the License is distributed on an "AS IS" BASIS,
11
///    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
///    See the License for the specific language governing permissions and
13
///    limitations under the License.
14

15
#import "Source/common/SNTBlockMessage.h"
16

17
#import "Source/common/SNTConfigurator.h"
18
#import "Source/common/SNTFileAccessEvent.h"
19
#import "Source/common/SNTLogging.h"
20
#import "Source/common/SNTStoredEvent.h"
21
#import "Source/common/SNTSystemInfo.h"
22

23
static id ValueOrNull(id value) {
105✔
24
  return value ?: [NSNull null];
105✔
25
}
105✔
26

27
@implementation SNTBlockMessage
28

29
+ (NSAttributedString *)formatMessage:(NSString *)message {
1✔
30
  NSString *htmlHeader =
1✔
31
    @"<html><head><style>"
1✔
32
    @"body {"
1✔
33
    @"  font-family: 'Lucida Grande', 'Helvetica', sans-serif;"
1✔
34
    @"  font-size: 13px;"
1✔
35
    @"  color: %@;"
1✔
36
    @"  text-align: center;"
1✔
37
    @"}"
1✔
38

39
    // Supported in beta WebKit. Not sure if it is dynamic when used with NSAttributedString.
40
    @"@media (prefers-color-scheme: dark) {"
1✔
41
    @"  body {"
1✔
42
    @"    color: #ddd;"
1✔
43
    @"  }"
1✔
44
    @"}"
1✔
45
    @"</style></head><body>";
1✔
46

47
  // Support Dark Mode. Note, the returned NSAttributedString is static and does not update when
48
  // the OS switches modes.
49
  NSString *mode = [NSUserDefaults.standardUserDefaults stringForKey:@"AppleInterfaceStyle"];
1✔
50
  BOOL dark = [mode isEqualToString:@"Dark"];
1✔
51
  htmlHeader = [NSString stringWithFormat:htmlHeader, dark ? @"#ddd" : @"#333"];
1!
52

53
  NSString *htmlFooter = @"</body></html>";
1✔
54

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

57
#ifdef SANTAGUI
1✔
58
  NSData *htmlData = [fullHTML dataUsingEncoding:NSUTF8StringEncoding];
1✔
59
  NSDictionary *options = @{
1✔
60
    NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType,
1✔
61
    NSCharacterEncodingDocumentAttribute : @(NSUTF8StringEncoding),
1✔
62
  };
1✔
63
  return [[NSAttributedString alloc] initWithHTML:htmlData options:options documentAttributes:NULL];
1✔
64
#else
65
  NSString *strippedHTML = [self stringFromHTML:fullHTML];
×
66
  if (!strippedHTML) {
×
67
    return [[NSAttributedString alloc] initWithString:@"This binary has been blocked."];
×
68
  }
×
69
  return [[NSAttributedString alloc] initWithString:strippedHTML];
×
70
#endif
×
71
}
1✔
72

73
+ (NSAttributedString *)attributedBlockMessageForEvent:(SNTStoredEvent *)event
UNCOV
74
                                         customMessage:(NSString *)customMessage {
×
UNCOV
75
  NSString *message;
×
UNCOV
76
  if (customMessage.length) {
×
77
    message = customMessage;
×
UNCOV
78
  } else if (event.decision == SNTEventStateBlockUnknown) {
×
79
    message = [[SNTConfigurator configurator] unknownBlockMessage];
×
80
    if (!message) {
×
81
      message = @"The following application has been blocked from executing<br />"
×
82
                @"because its trustworthiness cannot be determined.";
×
83
    }
×
UNCOV
84
  } else {
×
UNCOV
85
    message = [[SNTConfigurator configurator] bannedBlockMessage];
×
UNCOV
86
    if (!message) {
×
UNCOV
87
      message = @"The following application has been blocked from executing<br />"
×
UNCOV
88
                @"because it has been deemed malicious.";
×
UNCOV
89
    }
×
UNCOV
90
  }
×
UNCOV
91
  return [SNTBlockMessage formatMessage:message];
×
UNCOV
92
}
×
93

94
+ (NSAttributedString *)attributedBlockMessageForFileAccessEvent:(SNTFileAccessEvent *)event
95
                                                   customMessage:(NSString *)customMessage {
×
96
  NSString *message = customMessage;
×
97
  if (!message.length) {
×
98
    message = [[SNTConfigurator configurator] fileAccessBlockMessage];
×
99
    if (!message.length) {
×
100
      message = @"Access to a file has been denied.";
×
101
    }
×
102
  }
×
103
  return [SNTBlockMessage formatMessage:message];
×
104
}
×
105

106
+ (NSString *)stringFromHTML:(NSString *)html {
×
107
  NSError *error;
×
108
  NSXMLDocument *xml = [[NSXMLDocument alloc] initWithXMLString:html options:0 error:&error];
×
109

110
  if (!xml && error.code == NSXMLParserEmptyDocumentError) {
×
111
    html = [NSString stringWithFormat:@"<html><body>%@</body></html>", html];
×
112
    xml = [[NSXMLDocument alloc] initWithXMLString:html options:0 error:&error];
×
113
    if (!xml) return html;
×
114
  }
×
115

116
  // Strip any HTML tags out of the message. Also remove any content inside <style> tags and
117
  // replace <br> elements with a newline.
118
  NSString *stripXslt =
×
119
    @"<?xml version='1.0' encoding='utf-8'?>"
×
120
    @"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
×
121
    @"                              xmlns:xhtml='http://www.w3.org/1999/xhtml'>"
×
122
    @"<xsl:output method='text'/>"
×
123
    @"<xsl:template match='br'><xsl:text>\n</xsl:text></xsl:template>"
×
124
    @"<xsl:template match='style'/>"
×
125
    @"</xsl:stylesheet>";
×
126
  NSData *data = [xml objectByApplyingXSLTString:stripXslt arguments:NULL error:&error];
×
127
  if (error || ![data isKindOfClass:[NSData class]]) {
×
128
    return html;
×
129
  }
×
130
  return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
×
131
}
×
132

133
+ (NSString *)replaceFormatString:(NSString *)str
134
                         withDict:(NSDictionary<NSString *, NSString *> *)replacements {
4✔
135
  __block NSString *formatStr = str;
4✔
136

137
  [replacements enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {
51✔
138
    if ((id)value != [NSNull null]) {
51✔
139
      formatStr = [formatStr stringByReplacingOccurrencesOfString:key withString:value];
46✔
140
    }
46✔
141
  }];
51✔
142

143
  return formatStr;
4✔
144
}
4✔
145

146
//
147
//   The following "format strings" will be replaced in the URL provided by
148
//   `+eventDetailURLForEvent:customURL:templateMapping:`.
149
//
150
//   %file_identifier%           - The SHA-256 of the binary being executed.
151
//   %bundle_or_file_identifier% - The hash of the bundle containing this file or the file itself,
152
//                                 if no bundle hash is present.
153
//   %file_bundle_id%            - The bundle id of the binary, if any.
154
//   %team_id%                   - The Team ID if present in the signature information.
155
//   %signing_id%                - The Signing ID if present in the signature information.
156
//   %cdhash%                    - If signed, the CDHash.
157
//   %username%                  - The executing user's name.
158
//   %machine_id%                - The configured machine ID for this host.
159
//   %hostname%                  - The machine's FQDN.
160
//   %uuid%                      - The machine's UUID.
161
//   %serial%                    - The machine's serial number.
162
//
163
+ (NSDictionary *)eventDetailTemplateMappingForEvent:(SNTStoredEvent *)event {
8✔
164
  SNTConfigurator *config = [SNTConfigurator configurator];
8✔
165
  return @{
8✔
166
    @"%file_sha%" : ValueOrNull(event.fileSHA256 ? event.fileBundleHash ?: event.fileSHA256 : nil),
8!
167
    @"%file_identifier%" : ValueOrNull(event.fileSHA256),
8✔
168
    @"%bundle_or_file_identifier%" :
5✔
169
      ValueOrNull(event.fileSHA256 ? event.fileBundleHash ?: event.fileSHA256 : nil),
8✔
170
    @"%username%" : ValueOrNull(event.executingUser),
5✔
171
    @"%file_bundle_id%" : ValueOrNull(event.fileBundleID),
2✔
172
    @"%team_id%" : ValueOrNull(event.teamID),
2✔
173
    @"%signing_id%" : ValueOrNull(event.signingID),
2✔
174
    @"%cdhash%" : ValueOrNull(event.cdhash),
2✔
175
    @"%machine_id%" : ValueOrNull(config.machineID),
2✔
176
    @"%hostname%" : ValueOrNull([SNTSystemInfo longHostname]),
2✔
177
    @"%uuid%" : ValueOrNull([SNTSystemInfo hardwareUUID]),
2✔
178
    @"%serial%" : ValueOrNull([SNTSystemInfo serialNumber]),
2✔
179
  };
2✔
180
}
5✔
181

182
//
183
//   Everything from `+eventDetailTemplateMappingForEvent:` with the following file access
184
//   specific templates.
185
//
186
//   %rule_version%    - The version of the rule that was violated.
187
//   %rule_name%       - The name of the rule that was violated.
188
//   %accessed_path%   - The path accessed by the binary.
189
//
190
+ (NSDictionary *)fileAccessEventDetailTemplateMappingForEvent:(SNTFileAccessEvent *)event {
3✔
191
  NSMutableDictionary *d = [self eventDetailTemplateMappingForEvent:event].mutableCopy;
3✔
192
  [d addEntriesFromDictionary:@{
3✔
193
    @"%rule_version%" : ValueOrNull(event.ruleVersion),
3✔
194
    @"%rule_name%" : ValueOrNull(event.ruleName),
3✔
195
    @"%accessed_path%" : ValueOrNull(event.accessedPath),
3✔
196
  }];
3✔
197
  return d;
3✔
198
}
3✔
199

200
// Returns either the generated URL for the passed in event, or an NSURL from the passed in custom
201
// URL string. If the custom URL string is the string "null", nil will be returned. If no custom
202
// URL is passed and there is no configured EventDetailURL template, nil will be returned.
203
// The "format strings" in `templateMapping` will be replaced in the URL, if they are present.
204
+ (NSURL *)eventDetailURLForEvent:(SNTStoredEvent *)event
205
                        customURL:(NSString *)url
206
                  templateMapping:(NSDictionary *)templateMapping {
8✔
207
  SNTConfigurator *config = [SNTConfigurator configurator];
8✔
208

209
  NSString *formatStr = url;
8✔
210
  if (!formatStr.length) {
8✔
211
    formatStr = config.eventDetailURL;
2✔
212
    if (!formatStr.length) {
2!
213
      return nil;
2✔
214
    }
2✔
215
  }
2✔
216

217
  if ([formatStr isEqualToString:@"null"]) {
6✔
218
    return nil;
2✔
219
  }
2✔
220

221
  formatStr = [SNTBlockMessage replaceFormatString:formatStr withDict:templateMapping];
4✔
222
  NSURL *u = [NSURL URLWithString:formatStr];
4✔
223
  if (!u) {
4!
224
    LOGW(@"Unable to generate event detail URL for string '%@'", formatStr);
×
225
  }
×
226

227
  return u;
4✔
228
}
6✔
229

230
+ (NSURL *)eventDetailURLForEvent:(SNTStoredEvent *)event customURL:(NSString *)url {
5✔
231
  return [self eventDetailURLForEvent:event
5✔
232
                            customURL:url
5✔
233
                      templateMapping:[self eventDetailTemplateMappingForEvent:event]];
5✔
234
}
5✔
235

236
+ (NSURL *)eventDetailURLForFileAccessEvent:(SNTFileAccessEvent *)event customURL:(NSString *)url {
3✔
237
  return [self eventDetailURLForEvent:event
3✔
238
                            customURL:url
3✔
239
                      templateMapping:[self fileAccessEventDetailTemplateMappingForEvent:event]];
3✔
240
}
3✔
241

242
@end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc