10

Apparently, as of 10.7, AuthorizationExecuteWithPrivileges is deprecated. The general gist of the information I've gathered on this seems to suggest using ServiceManagement.framework's SMJobBless() function to have a helper application deployed.

My understanding of it though, is that this will need a developer certificate to be purchased from Apple to code sign both my application and the helper process - or this will not work. Is this correct?

I originally used AuthorizationExecuteWithPrivileges to ask a user for elevated privileges, since they are needed to access another running process. Without that, my app can't work as the unofficial plugin it's intended to. Is the code signing way really the only way to go from here? I'm trying to avoid purchasing a developer certificate due to the sheer cost of it.

Has anyone found any alternative ways to relaunch an application with elevated privileges, with user permission of course?

Tiago
  • 1,984
  • 1
  • 21
  • 43

2 Answers2

3

@CarlosP's answer with code to escape the path & arguments:

- (BOOL)runProcessAsAdministrator:(NSString*)scriptPath
                    withArguments:(NSArray*)arguments
                           output:(NSString**)output
                 errorDescription:(NSString**)errorDescription {

    //Check path.
    if (![scriptPath hasPrefix:@"/"]) {
        @throw [NSException exceptionWithName:
                    NSInvalidArgumentException reason:@"Absolute path required." userInfo:nil];
    }

    //Define script.
    static NSAppleScript* appleScript = nil;
    if (!appleScript) {
        appleScript = [[NSAppleScript alloc] initWithSource:
            @"on run commandWithArguments\n"
             "  activate\n"
             "  repeat with currentArgument in commandWithArguments\n"
             "      set contents of currentArgument to quoted form of currentArgument\n"
             "  end repeat\n"
             "  set AppleScript's text item delimiters to space\n"
             "  return do shell script (commandWithArguments as text) with administrator privileges\n"
             "end run"];
    }

    //Set command.
    NSAppleEventDescriptor* commandWithArguments = [NSAppleEventDescriptor listDescriptor];
    [commandWithArguments insertDescriptor:
        [NSAppleEventDescriptor descriptorWithString:scriptPath] atIndex:0];

    //Set arguments.
    for (NSString* currentArgument in arguments) {
        [commandWithArguments insertDescriptor:
            [NSAppleEventDescriptor descriptorWithString:currentArgument] atIndex:0];
    }

    //Create target & event.
    ProcessSerialNumber     processSerial   = {0, kCurrentProcess};
    NSAppleEventDescriptor* scriptTarget    =
        [NSAppleEventDescriptor descriptorWithDescriptorType:typeProcessSerialNumber bytes:&processSerial length:sizeof(ProcessSerialNumber)];
    NSAppleEventDescriptor* scriptEvent     =
        [NSAppleEventDescriptor appleEventWithEventClass:kCoreEventClass
                                                 eventID:kAEOpenApplication
                                        targetDescriptor:scriptTarget
                                                returnID:kAutoGenerateReturnID
                                           transactionID:kAnyTransactionID];
    [scriptEvent setParamDescriptor:commandWithArguments forKeyword:keyDirectObject];

    //Run script.
    NSDictionary*           errorInfo   = [NSDictionary dictionary];
    NSAppleEventDescriptor* eventResult = [appleScript executeAppleEvent:scriptEvent error:&errorInfo];

    //Success?
    if (!eventResult) {
        if (errorDescription)
            *errorDescription = [errorInfo objectForKey:NSAppleScriptErrorMessage];
        return NO;
    } else {
        if (output)
            *output = [eventResult stringValue];
        return YES;
    }

}

Update

In Yosemite, do shell script just calls a version of AuthorizationExecuteWithPrivileges embedded in StandardAdditions.osax.

It's conceivable that the with administrator privileges option for do shell script will go away when AuthorizationExecuteWithPrivileges does.

Personally, I would just continue calling AuthorizationExecuteWithPrivileges directly.

do shell script does have the advantage of reaping the process automatically. That requires a little extra work with AuthorizationExecuteWithPrivileges.

Community
  • 1
  • 1
  • Thanks @null, I wasn't completely sure about the feasibility in using this to relaunch the application with elevated privileges. It's not ideal, since it is a hacky applescript approach - but if it works it works. I'll try it out, fingers crossed. – Tiago Jul 28 '15 at 11:59
  • @loco Sorry, completely missed the "relaunching" part of your question. To do that, [you'll need a few tweaks](https://developer.apple.com/library/mac/technotes/tn2065/_index.html#//apple_ref/doc/uid/DTS10003093-CH1-SECTION5). So something like `do shell script (commandWithArguments as text) & " &> /dev/null &" with administrator privileges`. I'll trust that you've investigated all of the implications of launching a GUI application as root — I just played around with it for the first time today. –  Jul 29 '15 at 00:50
2

Is the code signing way really the only way to go from here?

To my knowledge, there is no secure alternative to AuthorizationExecuteWithPrivileges.

It still works fine under Yosemite. Haven't tried out El Capitan yet.

You can try to fail gracefully if the call goes away in the future.

I'm trying to avoid purchasing a developer certificate due to the sheer cost of it.

Well, if it helps, the code signing certificate will be valid for several years.

I'm pretty sure I've let my developer account lapse without any issues.

So it's basically $99 every five years.

  • I'm still looking to see if there are options that won't require codesigning/purchasing a license from Apple, but thanks for the pointer to an example on how to fail gracefully in a "worst case" scenario! Interesting to see how that is handled there! – Tiago Jul 11 '15 at 13:15
  • @loco You've probably seen this already, but [you can use Applescript](https://stackoverflow.com/questions/6841937/authorizationexecutewithprivileges-is-deprecated). If you go down this route, make sure you use `quoted form` to [sanitize the executable path & arguments](https://developer.apple.com/library/mac/technotes/tn2065/_index.html#//apple_ref/doc/uid/DTS10003093-CH1-SECTION3). –  Jul 23 '15 at 02:19