Skip to content

Commit

Permalink
Standardize entitlement dictionary formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
mlw committed Nov 8, 2023
1 parent 8980d8d commit 0cb1ca1
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 60 deletions.
4 changes: 2 additions & 2 deletions Source/common/santa.proto
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ message CertificateInfo {
}

message Entitlement {
string key = 1;
string value = 2;
string key = 1;
string value = 2;
}

// Information about a process execution event
Expand Down
53 changes: 40 additions & 13 deletions Source/santad/Logs/EndpointSecurity/Serializers/Protobuf.mm
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
namespace santa::santad::logs::endpoint_security::serializers {

static constexpr NSUInteger kMaxEncodeObjectEntries = 64;
static constexpr NSUInteger kMaxEncodeObjectLevels = 5;

std::shared_ptr<Protobuf> Protobuf::Create(std::shared_ptr<EndpointSecurityAPI> esapi,
SNTDecisionCache *decision_cache, bool json) {
Expand Down Expand Up @@ -451,11 +452,49 @@ static inline void EncodeCertificateInfo(::pbv1::CertificateInfo *pb_cert_info,
return FinalizeProto(santa_msg);
}

id StandardizedNestedObjects(id obj, int level) {
if (level-- == 0) {
return [obj description];
}

if ([obj isKindOfClass:[NSNumber class]] || [obj isKindOfClass:[NSString class]]) {
return obj;
} else if ([obj isKindOfClass:[NSArray class]]) {
NSMutableArray *arr = [NSMutableArray array];
for (id item in obj) {
[arr addObject:StandardizedNestedObjects(item, level)];
}
return arr;
} else if ([obj isKindOfClass:[NSDictionary class]]) {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (id key in obj) {
[dict setObject:StandardizedNestedObjects(obj[key], level) forKey:key];
}
return dict;
} else if ([obj isKindOfClass:[NSData class]]) {
return [obj base64EncodedStringWithOptions:0];
} else if ([obj isKindOfClass:[NSDate class]]) {
return [NSISO8601DateFormatter stringFromDate:obj
timeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]
formatOptions:NSISO8601DateFormatWithFractionalSeconds | NSISO8601DateFormatWithInternetDateTime];

} else {
NSLog(@"Got unknown... %d", level);
LOGW(@"Unexpected object encountered: %@", obj);
return [obj description];
}
}

void EncodeEntitlements(::pbv1::Execution *pb_exec, NSDictionary *entitlements) {
if (!entitlements) {
return;
}

// Since nested objects with varying types is hard for the API to serialize to
// JSON, first go through and standardize types to ensure better serialization
// as well as a consitent view of data.
entitlements = StandardizedNestedObjects(entitlements, kMaxEncodeObjectLevels);

__block int numObjectsToEncode = (int)std::min(kMaxEncodeObjectEntries, entitlements.count);

pb_exec->mutable_entitlements()->Reserve(numObjectsToEncode);
Expand All @@ -474,19 +513,7 @@ void EncodeEntitlements(::pbv1::Execution *pb_exec, NSDictionary *entitlements)
NSError *err;
NSData *jsonData;
@try {
id val = obj;

// Fixup some types with data that can be better represented in JSON
if ([obj isKindOfClass:[NSDate class]]) {
// Example format output: "November 6, 2023 at 10:25:20 AM EST"
val = [NSDateFormatter localizedStringFromDate:obj
dateStyle:NSDateFormatterLongStyle
timeStyle:NSDateFormatterLongStyle];
} else if ([obj isKindOfClass:[NSData class]]) {
val = [obj base64EncodedStringWithOptions:0];
}

jsonData = [NSJSONSerialization dataWithJSONObject:val
jsonData = [NSJSONSerialization dataWithJSONObject:obj
options:NSJSONWritingFragmentsAllowed
error:&err];
} @catch (NSException *e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,10 @@ void SerializeAndCheck(es_event_type_t eventType,
options:NSJSONReadingMutableContainers
error:&jsonError];
XCTAssertNil(jsonError, @"failed to parse got data as JSON");

XCTAssertNil(FindDelta(wantJSONDict, gotJSONDict));
// Note: Uncomment this line to help create testfile JSON when the assert above fails
// XCTAssertEqualObjects([NSString stringWithUTF8String:gotData.c_str()], wantData);
}

XCTBubbleMockVerifyAndClearExpectations(mockESApi.get());
Expand Down
18 changes: 9 additions & 9 deletions Source/santad/testdata/protobuf/v1/exec.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,40 +123,40 @@
"quarantine_url": "google.com",
"entitlements": [
{
"key": "key_with_arr_val",
"value": "[\"v1\",\"v2\",\"v3\"]"
"key": "key_with_arr_val_multitype",
"value": "[\"v1\",\"v2\",\"v3\",123,\"2023-11-07T17:00:02.000Z\"]"
},
{
"key": "key_with_data_val",
"value": "\"SGVsbG8gV29ybGQ=\""
},
{
"key": "key_with_arr_val_multitype",
"value": "\"(\\n v1,\\n v2,\\n v3,\\n 123,\\n \\\"2023-11-07 17:00:02 +0000\\\"\\n)\""
"key": "key_with_str_val",
"value": "\"bar\""
},
{
"key": "key_with_arr_val_nested",
"value": "[\"v1\",\"v2\",\"v3\",[\"nv1\",\"nv2\"]]"
},
{
"key": "key_with_dict_val",
"value": "{\"k1\":\"v1\",\"k2\":\"v2\"}"
"value": "{\"k2\":\"v2\",\"k1\":\"v1\"}"
},
{
"key": "key_with_date_val",
"value": "\"November 7, 2023 at 5:00:02 PM GMT\""
"value": "\"2023-11-07T17:00:02.000Z\""
},
{
"key": "key_with_dict_val_nested",
"value": "\"{\\n k1 = v1;\\n k2 = v2;\\n k3 = {\\n nk1 = nv1;\\n nk2 = \\\"2023-11-07 17:00:02 +0000\\\";\\n };\\n}\""
"value": "{\"k3\":{\"nk1\":\"nv1\",\"nk2\":\"2023-11-07T17:00:02.000Z\"},\"k2\":\"v2\",\"k1\":\"v1\"}"
},
{
"key": "key_with_num_val",
"value": "1234"
},
{
"key": "key_with_str_val",
"value": "\"bar\""
"key": "key_with_arr_val",
"value": "[\"v1\",\"v2\",\"v3\"]"
}
]
}
18 changes: 9 additions & 9 deletions Source/santad/testdata/protobuf/v2/exec.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,40 +151,40 @@
"quarantine_url": "google.com",
"entitlements": [
{
"key": "key_with_arr_val",
"value": "[\"v1\",\"v2\",\"v3\"]"
"key": "key_with_arr_val_multitype",
"value": "[\"v1\",\"v2\",\"v3\",123,\"2023-11-07T17:00:02.000Z\"]"
},
{
"key": "key_with_data_val",
"value": "\"SGVsbG8gV29ybGQ=\""
},
{
"key": "key_with_arr_val_multitype",
"value": "\"(\\n v1,\\n v2,\\n v3,\\n 123,\\n \\\"2023-11-07 17:00:02 +0000\\\"\\n)\""
"key": "key_with_str_val",
"value": "\"bar\""
},
{
"key": "key_with_arr_val_nested",
"value": "[\"v1\",\"v2\",\"v3\",[\"nv1\",\"nv2\"]]"
},
{
"key": "key_with_dict_val",
"value": "{\"k1\":\"v1\",\"k2\":\"v2\"}"
"value": "{\"k2\":\"v2\",\"k1\":\"v1\"}"
},
{
"key": "key_with_date_val",
"value": "\"November 7, 2023 at 5:00:02 PM GMT\""
"value": "\"2023-11-07T17:00:02.000Z\""
},
{
"key": "key_with_dict_val_nested",
"value": "\"{\\n k1 = v1;\\n k2 = v2;\\n k3 = {\\n nk1 = nv1;\\n nk2 = \\\"2023-11-07 17:00:02 +0000\\\";\\n };\\n}\""
"value": "{\"k3\":{\"nk1\":\"nv1\",\"nk2\":\"2023-11-07T17:00:02.000Z\"},\"k2\":\"v2\",\"k1\":\"v1\"}"
},
{
"key": "key_with_num_val",
"value": "1234"
},
{
"key": "key_with_str_val",
"value": "\"bar\""
"key": "key_with_arr_val",
"value": "[\"v1\",\"v2\",\"v3\"]"
}
]
}
18 changes: 9 additions & 9 deletions Source/santad/testdata/protobuf/v4/exec.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,40 +200,40 @@
"quarantine_url": "google.com",
"entitlements": [
{
"key": "key_with_arr_val",
"value": "[\"v1\",\"v2\",\"v3\"]"
"key": "key_with_arr_val_multitype",
"value": "[\"v1\",\"v2\",\"v3\",123,\"2023-11-07T17:00:02.000Z\"]"
},
{
"key": "key_with_data_val",
"value": "\"SGVsbG8gV29ybGQ=\""
},
{
"key": "key_with_arr_val_multitype",
"value": "\"(\\n v1,\\n v2,\\n v3,\\n 123,\\n \\\"2023-11-07 17:00:02 +0000\\\"\\n)\""
"key": "key_with_str_val",
"value": "\"bar\""
},
{
"key": "key_with_arr_val_nested",
"value": "[\"v1\",\"v2\",\"v3\",[\"nv1\",\"nv2\"]]"
},
{
"key": "key_with_dict_val",
"value": "{\"k1\":\"v1\",\"k2\":\"v2\"}"
"value": "{\"k2\":\"v2\",\"k1\":\"v1\"}"
},
{
"key": "key_with_date_val",
"value": "\"November 7, 2023 at 5:00:02 PM GMT\""
"value": "\"2023-11-07T17:00:02.000Z\""
},
{
"key": "key_with_dict_val_nested",
"value": "\"{\\n k1 = v1;\\n k2 = v2;\\n k3 = {\\n nk1 = nv1;\\n nk2 = \\\"2023-11-07 17:00:02 +0000\\\";\\n };\\n}\""
"value": "{\"k3\":{\"nk1\":\"nv1\",\"nk2\":\"2023-11-07T17:00:02.000Z\"},\"k2\":\"v2\",\"k1\":\"v1\"}"
},
{
"key": "key_with_num_val",
"value": "1234"
},
{
"key": "key_with_str_val",
"value": "\"bar\""
"key": "key_with_arr_val",
"value": "[\"v1\",\"v2\",\"v3\"]"
}
]
}
18 changes: 9 additions & 9 deletions Source/santad/testdata/protobuf/v5/exec.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,40 +200,40 @@
"quarantine_url": "google.com",
"entitlements": [
{
"key": "key_with_arr_val",
"value": "[\"v1\",\"v2\",\"v3\"]"
"key": "key_with_arr_val_multitype",
"value": "[\"v1\",\"v2\",\"v3\",123,\"2023-11-07T17:00:02.000Z\"]"
},
{
"key": "key_with_data_val",
"value": "\"SGVsbG8gV29ybGQ=\""
},
{
"key": "key_with_arr_val_multitype",
"value": "\"(\\n v1,\\n v2,\\n v3,\\n 123,\\n \\\"2023-11-07 17:00:02 +0000\\\"\\n)\""
"key": "key_with_str_val",
"value": "\"bar\""
},
{
"key": "key_with_arr_val_nested",
"value": "[\"v1\",\"v2\",\"v3\",[\"nv1\",\"nv2\"]]"
},
{
"key": "key_with_dict_val",
"value": "{\"k1\":\"v1\",\"k2\":\"v2\"}"
"value": "{\"k2\":\"v2\",\"k1\":\"v1\"}"
},
{
"key": "key_with_date_val",
"value": "\"November 7, 2023 at 5:00:02 PM GMT\""
"value": "\"2023-11-07T17:00:02.000Z\""
},
{
"key": "key_with_dict_val_nested",
"value": "\"{\\n k1 = v1;\\n k2 = v2;\\n k3 = {\\n nk1 = nv1;\\n nk2 = \\\"2023-11-07 17:00:02 +0000\\\";\\n };\\n}\""
"value": "{\"k3\":{\"nk1\":\"nv1\",\"nk2\":\"2023-11-07T17:00:02.000Z\"},\"k2\":\"v2\",\"k1\":\"v1\"}"
},
{
"key": "key_with_num_val",
"value": "1234"
},
{
"key": "key_with_str_val",
"value": "\"bar\""
"key": "key_with_arr_val",
"value": "[\"v1\",\"v2\",\"v3\"]"
}
]
}
18 changes: 9 additions & 9 deletions Source/santad/testdata/protobuf/v6/exec.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,40 +200,40 @@
"quarantine_url": "google.com",
"entitlements": [
{
"key": "key_with_arr_val",
"value": "[\"v1\",\"v2\",\"v3\"]"
"key": "key_with_arr_val_multitype",
"value": "[\"v1\",\"v2\",\"v3\",123,\"2023-11-07T17:00:02.000Z\"]"
},
{
"key": "key_with_data_val",
"value": "\"SGVsbG8gV29ybGQ=\""
},
{
"key": "key_with_arr_val_multitype",
"value": "\"(\\n v1,\\n v2,\\n v3,\\n 123,\\n \\\"2023-11-07 17:00:02 +0000\\\"\\n)\""
"key": "key_with_str_val",
"value": "\"bar\""
},
{
"key": "key_with_arr_val_nested",
"value": "[\"v1\",\"v2\",\"v3\",[\"nv1\",\"nv2\"]]"
},
{
"key": "key_with_dict_val",
"value": "{\"k1\":\"v1\",\"k2\":\"v2\"}"
"value": "{\"k2\":\"v2\",\"k1\":\"v1\"}"
},
{
"key": "key_with_date_val",
"value": "\"November 7, 2023 at 5:00:02 PM GMT\""
"value": "\"2023-11-07T17:00:02.000Z\""
},
{
"key": "key_with_dict_val_nested",
"value": "\"{\\n k1 = v1;\\n k2 = v2;\\n k3 = {\\n nk1 = nv1;\\n nk2 = \\\"2023-11-07 17:00:02 +0000\\\";\\n };\\n}\""
"value": "{\"k3\":{\"nk1\":\"nv1\",\"nk2\":\"2023-11-07T17:00:02.000Z\"},\"k2\":\"v2\",\"k1\":\"v1\"}"
},
{
"key": "key_with_num_val",
"value": "1234"
},
{
"key": "key_with_str_val",
"value": "\"bar\""
"key": "key_with_arr_val",
"value": "[\"v1\",\"v2\",\"v3\"]"
}
]
}

0 comments on commit 0cb1ca1

Please sign in to comment.