gpt4 book ai didi

cocoa - 获取管理员权限以使用 rm 从 Cocoa 应用程序删除文件

转载 作者:行者123 更新时间:2023-12-03 16:04:39 24 4
gpt4 key购买 nike

我正在制作一个删除日志文件的小应用程序。我正在使用运行 rm 和 srm(安全 rm)的 NSTask 实例来删除文件。

我希望能够删除以下位置的文件:

  • /库/日志
  • ~/库/日志

问题是用户帐户无权访问系统库文件夹中的某些文件,例如 Adob​​e 日志子文件夹等。例如,只有“系统”用户(组?)拥有 Adob​​e 日志文件夹及其内容的读/写权限,而当前用户甚至没有该文件夹的“获取信息”窗口中显示的权限条目.

我想要做什么:

  1. 获取管理员权限。
  2. 将密码存储在钥匙串(keychain)中,这样应用就不必每次都烦扰用户(存储密码是一个坏主意吗?可能吗?)
  3. 删除文件,无论文件权限如何。

我使用 NSTask 是因为它提供任务完成通知、从任务本身获取文本输出等。我需要使用其他东西吗?如果是这样,我如何在以管理员权限运行 rm 和 srm 时复制 NSTask 的完成通知和输出文件句柄?

我正在寻找最安全的方法来处理这种情况。即我不希望我的应用程序成为权限升级攻击的门户。

我查看了授权服务编程指南,但我不确定哪种情况适合。起初我认为 AuthorizationExecuteWithPrivileges 是个好主意,但在阅读了有关该主题的更多内容后,出于安全原因,似乎不建议使用此方法。

非常欢迎详细的答复。我确信你们中的一些人已经做过类似的事情并且有一些代码和知识可以分享。

提前致谢!

更新:

我现在可以弹出身份验证对话框并获取权限,如下所示:

OSStatus status;
AuthorizationRef authRef;
status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authRef);

AuthorizationRights authRights;
AuthorizationItem authItems[1];

authItems[0].name = kAuthorizationRightExecute;

authRights.count = sizeof(authItems) / sizeof(authItems[0]);
authRights.items = authItems;

AuthorizationFlags authFlags = kAuthorizationFlagDefaults | kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed;

status = AuthorizationCopyRights(authRef, &authRights, kAuthorizationEmptyEnvironment, authFlags, NULL);

从表面上看,“Factored Application”方法似乎是最合适的。问题是,对我来说,rm 已经像是一个外部辅助工具。我不确定我是否得到了文档中建议的 setuid 替代方案。我可以在 rm 上设置 setuid 位并使用我已经实现的 NSTask 方法运行它吗?这意味着我不需要创建自己的辅助工具。有人可以详细说明这个问题吗?

我还查看了 BetterAuthorizationSample,它被建议作为 setuid 位方法的更安全和最新的替代方法,但发现它对于简单的行为来说非常复杂。有什么提示吗?

预先感谢您的帮助!

最佳答案

也许有点晚了,但这可能对其他人将来的引用有用。大部分代码来自this person .

基本上,这与 Mac 上的授权有很大关系。您可以阅读更多相关信息 herehere .

使用rm工具的代码:

+ (BOOL)removeFileWithElevatedPrivilegesFromLocation:(NSString *)location
{
// Create authorization reference
OSStatus status;
AuthorizationRef authorizationRef;

// AuthorizationCreate and pass NULL as the initial
// AuthorizationRights set so that the AuthorizationRef gets created
// successfully, and then later call AuthorizationCopyRights to
// determine or extend the allowable rights.
// http://developer.apple.com/qa/qa2001/qa1172.html
status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
if (status != errAuthorizationSuccess)
{
NSLog(@"Error Creating Initial Authorization: %d", status);
return NO;
}

// kAuthorizationRightExecute == "system.privilege.admin"
AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0};
AuthorizationRights rights = {1, &right};
AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |
kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;

// Call AuthorizationCopyRights to determine or extend the allowable rights.
status = AuthorizationCopyRights(authorizationRef, &rights, NULL, flags, NULL);
if (status != errAuthorizationSuccess)
{
NSLog(@"Copy Rights Unsuccessful: %d", status);
return NO;
}

// use rm tool with -rf
char *tool = "/bin/rm";
char *args[] = {"-rf", (char *)[location UTF8String], NULL};
FILE *pipe = NULL;

status = AuthorizationExecuteWithPrivileges(authorizationRef, tool, kAuthorizationFlagDefaults, args, &pipe);
if (status != errAuthorizationSuccess)
{
NSLog(@"Error: %d", status);
return NO;
}

// The only way to guarantee that a credential acquired when you
// request a right is not shared with other authorization instances is
// to destroy the credential. To do so, call the AuthorizationFree
// function with the flag kAuthorizationFlagDestroyRights.
// http://developer.apple.com/documentation/Security/Conceptual/authorization_concepts/02authconcepts/chapter_2_section_7.html
status = AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights);
return YES;
}

关于cocoa - 获取管理员权限以使用 rm 从 Cocoa 应用程序删除文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3588779/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com