Skip to content

Commit

Permalink
improved rule exports
Browse files Browse the repository at this point in the history
strings now escaped #588
  • Loading branch information
objective-see committed Mar 6, 2024
1 parent ba066de commit e1f8840
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 26 deletions.
15 changes: 14 additions & 1 deletion LuLu/App/RulesMenuController.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ -(void)addRule
// show panel then write out rules
-(void)exportRules
{
//count
NSUInteger count = 0;

//rules
NSDictionary* rules = nil;

Expand Down Expand Up @@ -120,7 +123,11 @@ -(void)exportRules
continue;
}

//append
[json appendFormat:@"{%@},", [rule toJSON]];

//inc
count++;
}

//remove last ','
Expand Down Expand Up @@ -169,9 +176,15 @@ -(void)exportRules
//show alert
showAlert(NSAlertStyleWarning, @"ERROR: Failed to export rules", @"See log for (more) details", @[@"OK"]);
}
//happy
else
{
//show alert
showAlert(NSAlertStyleInformational, [NSString stringWithFormat:@"Exported %lu rules", (unsigned long)count], nil, @[@"OK"]);
}
}
}];

return;
}

Expand Down
Binary file added LuLu/App/instructions.psd
Binary file not shown.
2 changes: 1 addition & 1 deletion LuLu/Extension/XPCListener.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ -(id)init
if(@available(macOS 13.0, *)) {

//init requirement
// BB helper, v2.0+
// LuLu client, v2.0+
requirement = [NSString stringWithFormat:@"anchor apple generic and identifier \"%@\" and certificate leaf [subject.CN] = \"%@\" and info [CFBundleShortVersionString] >= \"2.0.0\"", APP_ID, SIGNING_AUTH];

//set requirement
Expand Down
79 changes: 56 additions & 23 deletions LuLu/Shared/Rule.m
Original file line number Diff line number Diff line change
Expand Up @@ -385,12 +385,12 @@ -(NSString*)description
// needed for conversion to JSON
-(NSMutableString*)toJSON
{
//dbg msg
os_log_debug(logHandle, "converting rule to JSON...");

//json
NSMutableString* json = nil;

//escaped
NSString* escaped = nil;

//init
json = [NSMutableString string];

Expand All @@ -402,14 +402,31 @@ -(NSMutableString*)toJSON
[json appendFormat:@"\"%@\" : \"%d\",", NSStringFromSelector(@selector(pid)), self.pid.intValue];
}

[json appendFormat:@"\"%@\" : \"%@\",", NSStringFromSelector(@selector(path)), self.path];
[json appendFormat:@"\"%@\" : \"%@\",", NSStringFromSelector(@selector(name)), self.name];
escaped = toEscapedJSON(self.path);
if(nil != escaped)
{
[json appendFormat:@"\"%@\" : %@,", NSStringFromSelector(@selector(path)), escaped];
}

escaped = toEscapedJSON(self.name);
if(nil != escaped)
{
[json appendFormat:@"\"%@\" : %@,", NSStringFromSelector(@selector(name)), escaped];
}

[json appendFormat:@"\"%@\" : \"%@\",", NSStringFromSelector(@selector(endpointAddr)), self.endpointAddr];
escaped = toEscapedJSON(self.endpointAddr);
if(nil != escaped)
{
[json appendFormat:@"\"%@\" : %@,", NSStringFromSelector(@selector(endpointAddr)), escaped];
}

if(nil != self.endpointHost)
{
[json appendFormat:@"\"%@\" : \"%@\",", NSStringFromSelector(@selector(endpointHost)), self.endpointHost];
escaped = toEscapedJSON(self.endpointHost);
if(nil != escaped)
{
[json appendFormat:@"\"%@\" : %@,", NSStringFromSelector(@selector(endpointHost)), escaped];
}
}

[json appendFormat:@"\"%@\" : \"%@\",", NSStringFromSelector(@selector(endpointPort)), self.endpointPort];
Expand All @@ -434,8 +451,12 @@ -(NSMutableString*)toJSON
//string?
if(YES == [value isKindOfClass:[NSString class]])
{
//append
[json appendFormat:@"\"%@\" : \"%@\",", key, value];
escaped = toEscapedJSON(value);
if(nil != escaped)
{
//append
[json appendFormat:@"\"%@\" : %@,", key, escaped];
}
}

//number?
Expand All @@ -454,7 +475,20 @@ -(NSMutableString*)toJSON
//add each item
for(id item in value)
{
[json appendFormat:@"\"%@\",", item];
//string?
if(YES == [item isKindOfClass:[NSString class]])
{
escaped = toEscapedJSON(item);
if(nil != escaped)
{
//append
[json appendFormat:@"%@,", escaped];
}
}
else
{
[json appendFormat:@"\"%@\",", item];
}
}

//remove last ','
Expand Down Expand Up @@ -511,7 +545,7 @@ -(id)initFromJSON:(NSDictionary*)info
if(YES != [self.key isKindOfClass:[NSString class]])
{
//err msg
os_log_error(logHandle, "ERROR: 'key' should be a string");
os_log_error(logHandle, "ERROR: 'key' should be a string, not %@", self.key.className);

self = nil;
goto bail;
Expand All @@ -521,19 +555,18 @@ -(id)initFromJSON:(NSDictionary*)info
if(YES != [self.uuid isKindOfClass:[NSString class]])
{
//err msg
os_log_error(logHandle, "ERROR: 'uuid' should be a string");
os_log_error(logHandle, "ERROR: 'uuid' should be a string, not %@", self.uuid.className);

self = nil;
goto bail;
}


self.pid = info[NSStringFromSelector(@selector(pid))];
if( (nil != self.pid) &&
(YES != [self.pid isKindOfClass:[NSNumber class]]) )
{
//err msg
os_log_error(logHandle, "ERROR: 'pid' should be a number");
os_log_error(logHandle, "ERROR: 'pid' should be a number, not %@", self.pid.className);

self = nil;
goto bail;
Expand All @@ -543,7 +576,7 @@ -(id)initFromJSON:(NSDictionary*)info
if(YES != [self.path isKindOfClass:[NSString class]])
{
//err msg
os_log_error(logHandle, "ERROR: 'path' should be a string");
os_log_error(logHandle, "ERROR: 'path' should be a string, not %@", self.path.className);

self = nil;
goto bail;
Expand All @@ -553,7 +586,7 @@ -(id)initFromJSON:(NSDictionary*)info
if(YES != [self.name isKindOfClass:[NSString class]])
{
//err msg
os_log_error(logHandle, "ERROR: 'name' should be a string");
os_log_error(logHandle, "ERROR: 'name' should be a string, not %@", self.name.className);

self = nil;
goto bail;
Expand All @@ -564,7 +597,7 @@ -(id)initFromJSON:(NSDictionary*)info
(YES != [self.csInfo isKindOfClass:[NSDictionary class]]) )
{
//err msg
os_log_error(logHandle, "ERROR: 'csInfo' should be a dictionary");
os_log_error(logHandle, "ERROR: 'csInfo' should be a dictionary, not %@", self.csInfo.className);

self = nil;
goto bail;
Expand All @@ -574,7 +607,7 @@ -(id)initFromJSON:(NSDictionary*)info
if(YES != [self.endpointAddr isKindOfClass:[NSString class]])
{
//err msg
os_log_error(logHandle, "ERROR: 'endpointAddr' should be a string");
os_log_error(logHandle, "ERROR: 'endpointAddr' should be a string, not %@", self.endpointAddr.className);

self = nil;
goto bail;
Expand All @@ -585,7 +618,7 @@ -(id)initFromJSON:(NSDictionary*)info
(YES != [self.endpointHost isKindOfClass:[NSString class]]) )
{
//err msg
os_log_error(logHandle, "ERROR: 'endpointHost' should be a string");
os_log_error(logHandle, "ERROR: 'endpointHost' should be a string, not %@", self.endpointHost.className);

self = nil;
goto bail;
Expand All @@ -595,7 +628,7 @@ -(id)initFromJSON:(NSDictionary*)info
if(YES != [self.endpointPort isKindOfClass:[NSString class]])
{
//err msg
os_log_error(logHandle, "ERROR: 'endpointPort' should be a string");
os_log_error(logHandle, "ERROR: 'endpointPort' should be a string, not %@", self.endpointPort.className);

self = nil;
goto bail;
Expand All @@ -607,7 +640,7 @@ -(id)initFromJSON:(NSDictionary*)info
if(YES != [self.type isKindOfClass:[NSNumber class]])
{
//err msg
os_log_error(logHandle, "ERROR: 'type' should be a number");
os_log_error(logHandle, "ERROR: 'type' should be a number, not %@", self.type.className);

self = nil;
goto bail;
Expand All @@ -617,7 +650,7 @@ -(id)initFromJSON:(NSDictionary*)info
if(YES != [self.scope isKindOfClass:[NSNumber class]])
{
//err msg
os_log_error(logHandle, "ERROR: 'scope' should be a number");
os_log_error(logHandle, "ERROR: 'scope' should be a number, not %@", self.scope.className);

self = nil;
goto bail;
Expand All @@ -627,7 +660,7 @@ -(id)initFromJSON:(NSDictionary*)info
if(YES != [self.action isKindOfClass:[NSNumber class]])
{
//err msg
os_log_error(logHandle, "ERROR: 'action' should be a number");
os_log_error(logHandle, "ERROR: 'action' should be a number, not %@", self.endpointPort.className);

self = nil;
goto bail;
Expand Down
3 changes: 3 additions & 0 deletions LuLu/Shared/utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,7 @@ void fadeOut(NSWindow* window, float duration);
//matches CS info?
BOOL matchesCSInfo(NSDictionary* csInfo_1, NSDictionary* csInfo_2);

//escape string
NSString* toEscapedJSON(NSString* input);

#endif
34 changes: 33 additions & 1 deletion LuLu/Shared/utilities.m
Original file line number Diff line number Diff line change
Expand Up @@ -1589,7 +1589,7 @@ BOOL matchesCSInfo(NSDictionary* csInfo_1, NSDictionary* csInfo_2)
if( ((nil != signingAuths_1) || (nil != signingAuths_2)) &&
(YES != [signingAuths_1 isEqualToArray:signingAuths_2]) )
{
//dbg msg
//err msg
os_log_error(logHandle, "ERROR: code signing mismatch (signing auths): %{public}@ / %{public}@", csInfo_1, csInfo_2);

//bail
Expand All @@ -1604,3 +1604,35 @@ BOOL matchesCSInfo(NSDictionary* csInfo_1, NSDictionary* csInfo_2)
return matches;

}

//escape string
NSString* toEscapedJSON(NSString* input)
{
NSData* data = nil;
NSError* error = nil;
NSString* output = nil;

@try {

data = [NSJSONSerialization dataWithJSONObject:input options:NSJSONWritingFragmentsAllowed error:&error];
if( (nil == data) ||
(nil != error) )
{
//err msg
os_log_error(logHandle, "ERROR: failed to convert/escape %{public}@ to JSON (error: %{public}@)", input, error);

goto bail;
}
}
@catch(NSException* exception)
{
//err msg
os_log_error(logHandle, "ERROR: failed to convert/escape %{public}@ to JSON (exception: %{public}@)", input, exception);
goto bail;
}

output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

bail:
return output;
}
1 change: 1 addition & 0 deletions Uninstaller/Uninstaller/Configure.m
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ -(BOOL)uninstall:(NSInteger)action
[xpcComms uninstall:!action reply:block];
}

//error
else
{
//err msg
Expand Down

0 comments on commit e1f8840

Please sign in to comment.