STPrivilegedTask要求为每个任务提供密码

时间:2015-07-27 13:06:43

标签: macos helper

我想启动许多需要root权限的NSTasks,我发现我应该使用Apple的授权工具包,我找到了专门为此设计的STPrivilegedTask。

问题是,当我启动STPrivilegedTask时,它每次都会询问我的root密码。有没有办法输入第一个特权任务的root密码,然后对于其他任务,应用程序将记住root密码,这样用户就不必一次又一次地输入密码?

2 个答案:

答案 0 :(得分:1)

根据您的使用情况,您可能会高兴地将authorizationRefSTPrivilegedTask -launch的初始化替换为类似......

// create authorization reference
static AuthorizationRef authorizationRef = NULL;
@synchronized(self) {
    if (!authorizationRef) {
        err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
        if (err != errAuthorizationSuccess) { return err; }
    }
}

...然后删除AuthorizationFree

// free the auth ref
AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);

这将允许您在没有five minutes的密码提示的情况下启动任务。

如果您需要更多控制权,请在Command Line Tool中创建一个Xcode,使用正常的NSTask来电执行所需的命令。

使用STPrivilegedTaskAuthorizationExecuteWithPrivileges启动工具时,NSTask命令将以管理员权限(euid = 0)运行。

SMJobBless是启动工具的方法 - 特别是如果您需要定期执行特权操作,而不提示输入密码。

much harder使用AuthorizationExecuteWithPrivileges正确执行此操作。

有关SMJobBless

的说明

SMJobBless提示输入密码&安装助手。

当您与帮助者交谈时,将没有密码提示。

Apple's own example对此非常复杂,但那里有other examples

有些网页建议只允许您的应用与您的帮助者交谈。 Apple并没有在任何地方说出这一点。安装帮助程序后,我非常确定anyone can talk to it

您可以自己强制执行代码签名要求(this document)的PROPERTY LISTS部分,但我找不到任何可以做到这一点的示例。

几年前我使用AuthorizationExecuteWithPrivileges来安装launchd守护程序,但我还没有和SMJobBless纠缠在一起。

答案 1 :(得分:0)

您好我找到了解决此问题的方法。在这里我列出了所有步骤,希望能帮助有人面对同样的问题:

应用程序启动的第一步,检查我们的应用程序是否具有管理权限。

 // run a terminal command for admin privileges available or not
NSString* csPluginDirectoryPath = [NSString stringWithFormat:@"%@/supportFiles",[CommonMethods getResourceFolderPath]];
NSString* tapPathCommand = [NSString stringWithFormat:@"chown root %@/tap.kext", csPluginDirectoryPath];

//if app has not admin privileges then it return error text
// if application has admin privileges it will return empty message
NSString* csErrorMessage = [self ExecuteSudoTerminalCommand:tapPathCommand];

if(csErrorMessage && [csErrorMessage length] > 2)
{
// go for admin privileges 
[self launchHelperTool];
}

-(NSString*) ExecuteSudoTerminalCommand:(NSString*) terminalCommands
{
    NSString* resultOfScript = @"";
    NSString* csScript = [NSString stringWithFormat:@"do shell script \"%@\"",terminalCommands];
    NSDictionary* errors = [NSDictionary dictionary];
    NSAppleScript* appleScript = [[NSAppleScript alloc] initWithSource:csScript];
    NSAppleEventDescriptor* descriptor = [appleScript executeAndReturnError:&errors];

    if(descriptor == nil)
    {
        resultOfScript = [errors objectForKey:@"NSAppleScriptErrorMessage"];

    }
    else
        resultOfScript = [descriptor stringValue];

    return resultOfScript;
}

-(void) launchHelperTool
{
    helperToolPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Chameleon VPN"];

    NSBundle *thisBundle = [NSBundle mainBundle];
    NSString* commonDictionaryPath = [[thisBundle bundleURL] absoluteString];
    commonDictionaryPath = [commonDictionaryPath substringToIndex:commonDictionaryPath.length - 1];

    commonDictionaryPath = [commonDictionaryPath stringByReplacingOccurrencesOfString:@"file:/" withString:@""];

    NSArray *args = [NSArray arrayWithObjects:helperToolPath, commonDictionaryPath, nil];
    NSTask *task = [NSTask launchedTaskWithLaunchPath:helperToolPath arguments:args];
    [task waitUntilExit];

    int status = [task terminationStatus];
    if (status == 0)
    {
        NSLog(@"Task succeeded.");
    }
    else
    {
        NSLog(@"Task failed.");
        exit(0);
    }
}