mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 20:40:47 +00:00
Prohibit remote processes from calling private methods of an application.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@22418 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
ba9a35db0e
commit
f986f0483d
2 changed files with 88 additions and 58 deletions
|
@ -5,6 +5,8 @@
|
||||||
userinfo dictionry really are there.
|
userinfo dictionry really are there.
|
||||||
* Source/NSApplication.m: Code more defensively setting up
|
* Source/NSApplication.m: Code more defensively setting up
|
||||||
notification info.
|
notification info.
|
||||||
|
* Source/GSServicesManager.m: Improve handling of incoming messages,
|
||||||
|
prohibit remote processes from calling private methods.
|
||||||
* Source/NSWindow.m:
|
* Source/NSWindow.m:
|
||||||
* Source/NSWindowController.m:
|
* Source/NSWindowController.m:
|
||||||
* Source/NSDataLinkManager.m:
|
* Source/NSDataLinkManager.m:
|
||||||
|
|
|
@ -275,31 +275,33 @@ NSRegisterServicesProvider(id provider, NSString *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selectively forwards those messages which are known to be safe.
|
* Selectively forwards those messages which are thought to be safe,
|
||||||
|
* and perform any special operations we need for workspace management
|
||||||
|
* etc.
|
||||||
*/
|
*/
|
||||||
- (void) forwardInvocation: (NSInvocation*)anInvocation
|
- (void) forwardInvocation: (NSInvocation*)anInvocation
|
||||||
{
|
{
|
||||||
SEL aSel = [anInvocation selector];
|
SEL aSel = [anInvocation selector];
|
||||||
NSString *selName = NSStringFromSelector(aSel);
|
NSString *selName = NSStringFromSelector(aSel);
|
||||||
|
id target = nil;
|
||||||
|
id delegate;
|
||||||
|
|
||||||
if ([selName isEqualToString: @"terminate:"])
|
/*
|
||||||
|
* We never permit remote processes to call private methods in this
|
||||||
|
* application.
|
||||||
|
*/
|
||||||
|
if ([selName hasPrefix: @"_"] == YES)
|
||||||
{
|
{
|
||||||
NSNotificationCenter *c;
|
[NSException raise: NSGenericException
|
||||||
|
format: @"method name '%@' private in '%@'",
|
||||||
/*
|
selName, [manager port]];
|
||||||
* Send a power off notification before asking app to terminate.
|
|
||||||
*/
|
|
||||||
c = [[NSWorkspace sharedWorkspace] notificationCenter];
|
|
||||||
[c _postLocal: NSWorkspaceWillPowerOffNotification userInfo: nil];
|
|
||||||
|
|
||||||
[anInvocation invokeWithTarget: NSApp];
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else if ([selName hasSuffix: @":userData:error:"])
|
|
||||||
|
if ([selName hasSuffix: @":userData:error:"] == YES)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The selector matches the correct form for a services request,
|
* The selector matches the correct form for a services request,
|
||||||
* so send the message to the services provider.
|
* so we send the message to the services provider.
|
||||||
*/
|
*/
|
||||||
if ([servicesProvider respondsToSelector: aSel] == YES)
|
if ([servicesProvider respondsToSelector: aSel] == YES)
|
||||||
{
|
{
|
||||||
|
@ -315,59 +317,85 @@ NSRegisterServicesProvider(id provider, NSString *name)
|
||||||
[anInvocation getArgument: (void*)&pb atIndex: 2];
|
[anInvocation getArgument: (void*)&pb atIndex: 2];
|
||||||
pb = [NSPasteboard pasteboardWithName: [pb name]];
|
pb = [NSPasteboard pasteboardWithName: [pb name]];
|
||||||
[anInvocation setArgument: (void*)&pb atIndex: 2];
|
[anInvocation setArgument: (void*)&pb atIndex: 2];
|
||||||
|
|
||||||
[anInvocation invokeWithTarget: servicesProvider];
|
[anInvocation invokeWithTarget: servicesProvider];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
[NSException raise: NSGenericException
|
||||||
|
format: @"service request '%@' not implemented in '%@'",
|
||||||
|
selName, [manager port]];
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate = [[NSApplication sharedApplication] delegate];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We assume that messages of the form 'application:...' are all
|
||||||
|
* safe and do mnot need to be listed in GSPermittedMessages.
|
||||||
|
* They can be handled either by the application delegate or by
|
||||||
|
* the shared GSServicesManager instance.
|
||||||
|
*/
|
||||||
|
if ([selName hasPrefix: @"application:"] == YES)
|
||||||
|
{
|
||||||
|
if ([delegate respondsToSelector: aSel] == YES)
|
||||||
|
{
|
||||||
|
target = delegate;
|
||||||
|
}
|
||||||
|
else if ([manager respondsToSelector: aSel] == YES)
|
||||||
|
{
|
||||||
|
target = manager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == nil)
|
||||||
|
{
|
||||||
|
NSArray *messages;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unless the message was of a format assumed to be safe,
|
||||||
|
* we must check it against the GSPermittedMessages array
|
||||||
|
* to see if the app allows it to be sent from a remote
|
||||||
|
* process.
|
||||||
|
*/
|
||||||
|
messages = [[NSUserDefaults standardUserDefaults] arrayForKey:
|
||||||
|
@"GSPermittedMessages"];
|
||||||
|
if (messages != nil && [messages containsObject: selName] == NO)
|
||||||
|
{
|
||||||
|
[NSException raise: NSGenericException
|
||||||
|
format: @"method '%@' not in GSPermittedMessages in '%@'",
|
||||||
|
selName, [manager port]];
|
||||||
|
}
|
||||||
|
if ([delegate respondsToSelector: aSel] == YES)
|
||||||
|
{
|
||||||
|
target = delegate;
|
||||||
|
}
|
||||||
|
else if ([NSApp respondsToSelector: aSel] == YES)
|
||||||
|
{
|
||||||
|
target = NSApp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == nil)
|
||||||
|
{
|
||||||
|
[NSException raise: NSGenericException
|
||||||
|
format: @"method '%@' not implemented in '%@'",
|
||||||
|
selName, [manager port]];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
id delegate = [[NSApplication sharedApplication] delegate];
|
if ([selName isEqualToString: @"terminate:"])
|
||||||
|
|
||||||
if ([selName isEqualToString: @"activateIgnoringOtherApps:"])
|
|
||||||
{
|
{
|
||||||
[anInvocation invokeWithTarget: NSApp];
|
NSNotificationCenter *c;
|
||||||
return;
|
|
||||||
|
/*
|
||||||
|
* We handle the terminate: message as a special case, sending
|
||||||
|
* a power off notification before allowing it to be processed
|
||||||
|
* as normal.
|
||||||
|
*/
|
||||||
|
c = [[NSWorkspace sharedWorkspace] notificationCenter];
|
||||||
|
[c _postLocal: NSWorkspaceWillPowerOffNotification userInfo: nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([selName hasPrefix: @"application:"] == YES)
|
[anInvocation invokeWithTarget: target];
|
||||||
{
|
|
||||||
if ([delegate respondsToSelector: aSel] == YES)
|
|
||||||
{
|
|
||||||
[anInvocation invokeWithTarget: delegate];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ([manager respondsToSelector: aSel] == YES)
|
|
||||||
{
|
|
||||||
[anInvocation invokeWithTarget: manager];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ([delegate respondsToSelector: aSel] == YES)
|
|
||||||
{
|
|
||||||
NSArray *messages;
|
|
||||||
|
|
||||||
messages = [[NSUserDefaults standardUserDefaults] arrayForKey:
|
|
||||||
@"GSPermittedMessages"];
|
|
||||||
if (messages != nil)
|
|
||||||
{
|
|
||||||
if ([messages containsObject: selName] == YES)
|
|
||||||
{
|
|
||||||
[anInvocation invokeWithTarget: delegate];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
[anInvocation invokeWithTarget: delegate];
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
[NSException raise: NSGenericException
|
|
||||||
format: @"method %@ not implemented", selName];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue