"因为它不受SIP保护" - OSX Mojave中的Apple事件错误

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

Pat*_*ita 9

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,则不提示用户.

结论:

如前所述,它并不完美.

  • 目标应用程序必须运行 - 否则它将返回-600
  • 一旦被拒绝,用户只能手动激活它 - 这不会感觉良好和流畅.
  • 它的线程安全,所以你不应该在主线程中调用它(除了手动激活的对话框)