Pat*_*ita 6 security objective-c appleevents macos-mojave
我在OSX中有一个poperly沙盒应用程序,objective-c通过apple事件(例如Adobe InDesign)与第三方应用程序对话.
在OSX mojave中,一切都中断,因为Apple的新SIP(https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/Introduction/Introduction.html)不允许进行通信.
我还没有找到任何解决方案.任何帮助赞赏.
这是错误消息
__PRE__
这是对问题的一个非常好的总结:https: //www.felix-schwarz.org/blog/2018/06/apple-event-sandboxing-in-macos-mojave
Apple仍然需要对此进行研究,它并不完美,它不是用户友好的,它没有很好的文档记录.但这是一个有效的解决方案.
从OSX 10.14(Mojave)开始,如果用户允许您的应用程序与其他人通信,则必须询问OSX的系统完整性保护(SIP).
要使其工作,您需要在应用程序的.plist文件中添加一个条目:
key: NSAppleEventsUsageDescription
value: [Some description why you need to use AppleEvents]
Run Code Online (Sandbox Code Playgroud)
注意:您不能为更多应用程序使用更多条目.它的一个条目.所以明智地选择你的描述.此描述将显示在Apple的对话框中,要求用户接受.
如果您有像我这样的XPC服务,请将其放在MAIN应用程序中,而不是服务中.
现在在您的应用程序中 - 在使用Apple事件之前 - 检查当前状态(如果AppleEvents允许或不允许).我写了这个方法:
- (BOOL)checkSIPforAppIdentifier:(NSString*)identifier {
// First available from 10.14 Mojave
if (@available(macOS 10.14, *)) {
OSStatus status;
NSAppleEventDescriptor *targetAppEventDescriptor;
targetAppEventDescriptor = [NSAppleEventDescriptor descriptorWithBundleIdentifier:identifier];
status = AEDeterminePermissionToAutomateTarget(targetAppEventDescriptor.aeDesc, typeWildCard, typeWildCard, true);
switch (status) {
case -600: //procNotFound
NSLog(@"Not running app with id '%@'",identifier);
break;
case 0: // noErr
NSLog(@"SIP check successfull for app with id '%@'",identifier);
break;
case -1744: // errAEEventWouldRequireUserConsent
// This only appears if you send false for askUserIfNeeded
NSLog(@"User consent required for app with id '%@'",identifier);
break;
case -1743: //errAEEventNotPermitted
NSLog(@"User didn't allow usage for app with id '%@'",identifier);
// Here you should present a dialog with a tutorial on how to activate it manually
// This can be something like
// Go to system preferences > security > privacy
// Choose automation and active [APPNAME] for [APPNAME]
return NO;
default:
break;
}
}
return YES;
}
Run Code Online (Sandbox Code Playgroud)
这样叫:
[self checkSIPforAppIdentifier:@"com.apple.mail"];
Run Code Online (Sandbox Code Playgroud)
您可以在AppleEvents.h中找到详细信息 - 这是使用方法的副本:
AEDeterminePermissionToAutomateTarget()
讨论:确定当前应用程序是否能够将具有给定eventClass和eventID的AppleEvent发送到描述为targetAddressDesc的应用程序.
Mac OS 10.14及更高版本在将AppleEvents发送到其他应用程序时对应用程序施加了额外要求,以确保用户了解并同意允许此类控制或信息交换.通常,这涉及在应用程序第一次尝试将AppleEvent发送到另一个应用程序时以安全方式提示用户.
如果用户同意,则此应用程序可以将事件发送到目标.如果用户不同意,则将来尝试发送AppleEvents将导致返回errAEEventNotPermitted失败.允许在不提示用户的情况下发送某些AppleEvent.为typeClass和eventID传递typeWildCard,以确定是否允许将每个事件从此应用程序发送到目标.
应用程序可以在不向目标应用程序发送AppleEvent的情况下确定是否允许他们使用此功能将AppleEvents发送到目标.如果askUserIfNeeded为true,并且此应用程序还没有将AppleEvents发送给目标的权限,则会询问用户是否可以授予权限; 如果askUserIfNeeded为false且未授予权限,则将返回errAEEventWouldRequireUserConsent.
目标AEAddressDesc必须引用已在运行的应用程序.
结果
如果允许当前应用程序将给定的AppleEvent发送到目标,则将返回noErr.如果不允许当前应用程序发送事件,则将返回errAEEventNotPermitted.如果目标应用程序未运行,则将返回procNotFound.如果askUserIfNeeded为false,并且尚未允许此应用程序将AppleEvents发送到目标,则将返回errAEEventWouldRequireUserConsent.
Mac OS X线程:
从版本10.14开始,线程安全.不要在主线程上调用此函数,因为如果需要提示用户同意,则可能需要很长时间才能返回.
参数:
目标:
指向地址描述符的指针.在调用AEDeterminePermissionToAutomateTarget之前,您可以设置描述符以标识Apple事件的目标应用程序.目标地址描述符必须引用正在运行的应用程序.如果目标应用程序位于另一台计算机上,则必须在该计算机上为该用户启用Remote AppleEvents.
theAEEventClass:确定权限的Apple事件的事件类.
theAEEventID:用于确定权限的Apple事件的事件ID.
askUserIfNeeded:布尔值; 如果为true,并且此应用程序尚未具有将事件发送到目标应用程序的权限,则提示用户获取权限.如果为false,则不提示用户.
结论:
如前所述,它并不完美.