我想启动许多需要root权限的NSTasks,我发现我应该使用Apple的授权工具包,我找到了专门为此设计的STPrivilegedTask。
问题是,当我启动STPrivilegedTask时,它每次都会询问我的root密码。有没有办法输入第一个特权任务的root密码,然后对于其他任务,应用程序将记住root密码,这样用户就不必一次又一次地输入密码?
答案 0 :(得分:1)
根据您的使用情况,您可能会高兴地将authorizationRef
中STPrivilegedTask -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
来电执行所需的命令。
使用STPrivilegedTask
或AuthorizationExecuteWithPrivileges
启动工具时,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);
}
}