1

我有一个需要管理员权限才能执行 cmd 的 Cocoa 应用程序,但在某些极端情况下,例如包含双引号的文件名,此代码不起作用。

 NSString *fileName = @"~/Documents/My\" File/";
 NSString *cmd = [NSString stringWithFormat:@"chown -R '%@' '%@';NSUserName(), fileName];
 NSString *cmd_execute = [NSString stringWithFormat:@"do shell script
 \"%@\" with administrator privileges",cmd_execute]; 
//This line is the problem, our %@ contains double quote, so cocoa 
//cannot interpret correctly.
4

1 回答 1

2

这是使用 NSAppleScript 将参数传递到 AppleScript 处理程序的正确方法:

// load/compile AppleScript
NSAppleScript *scpt = [[NSAppleScript alloc] initWithSource:
        @"on joinText(a, b)\n"
        @"  return a & b\n"
        @"end addTo"];

NSString *arg1 = @"Hello ";
NSString *arg2 = @"World!";

// pack positional parameters
NSAppleEventDescriptor *params = [NSAppleEventDescriptor listDescriptor];
[params insertDescriptor: [NSAppleEventDescriptor descriptorWithString: arg1] atIndex: 1];
[params insertDescriptor: [NSAppleEventDescriptor descriptorWithString: arg2] atIndex: 2];

// build Apple event to invoke user-defined handler in script
NSAppleEventDescriptor *eventDesc = [NSAppleEventDescriptor appleEventWithEventClass: 'ascr'
                                                            eventID: 'psbr'
                                                            targetDescriptor: [NSAppleEventDescriptor nullDescriptor]
                                                            returnID: 0
                                                            transactionID: 0];
[eventDesc setDescriptor: params forKeyword: '----'];
[eventDesc setDescriptor: [NSAppleEventDescriptor descriptorWithString: @"joinText"] forKeyword: 'snam'];

 // invoke handler
 NSDictionary *errorInfo = nil;
 NSAppleEventDescriptor *resultDesc = [scpt executeAppleEvent: eventDesc error: &errorInfo];
 if (resultDesc)
     NSLog(@"Result: %@\n", [resultDesc stringValue]);
 else
     NSLog(@"Error: %@\n", errorInfo);

这避免了即时编译和编译 AS 脚本的需要 - 正如您的原始 ObjC 代码所展示的那样,由于清理不足,这是在您的程序中引入错误和安全漏洞的丰富机会。

...

这是在 AppleScript 中组装 shell 脚本字符串的正确方法:

do shell script ("chown -R " & quoted form of username & " " & quoted form of filepath)

AppleScript 的do shell script命令不提供传递参数的安全机制(它在许多其他方面也存在缺陷),但 AS 字符串具有quoted form至少返回适合连接到 shell 脚本字符串的带引号和转义版本的文本的属性.

...

当然,通过do shell scriptAppleScript 调用 shell 只是为了chmod以升级的权限运行,这本身并不是一个小问题,尽管这主要是 Apple 的错,因为它没有提供简单的官方 API 来执行此操作(例如,通过添加“以管理员权限运行”选项到NSUserScriptTask)。

Apple 确实提供了一个示例项目SMJobBless,它展示了如何使用服务管理框架和 launchd 添加和运行特权进程。但这是一个足够复杂的解决方案,很多人会(有意或无意地)偷工减料或完全做错事,这反而违背了首先提供安全做事方式的意义。但是您需要与 Apple 合作。

于 2013-11-04T18:38:33.307 回答