1

我过去在 Lazarus Pascal 中创建了一个应用程序,它执行“dd”以将图像写入驱动器。为此,显然需要提升权限。

在我使用的初始版本AuthorizationExecuteWithPrivileges()链接)中,尽管并非完全用于此目的,但它确实运行良好且非常一致。但是,此功能自 OSX 10.7 以来已被贬值,因为它可能是一个安全问题,并且重定向的命令行语句也无法正常工作(重定向输出zip作为 的输入dd)。

在下一个版本中,我使用了 Lazarus Pascal Wiki(执行外部程序)中描述的方法,它基本上启动了一个与我的程序通信的 TProcess。使用sudo -S dd ...,会询问并输入用户密码以确保他/她具有适当的访问权限。显然,这是一种肮脏的黑客方法,它表明某些用户会遇到问题。

经过大量阅读后,Apple 似乎更喜欢使用名为SMJobBless()的辅助工具来完成此操作。不幸的是,当谈到 Objective-C 时,我不是很有经验,所提供的代码似乎充其量只是很少,也没有很好的文档记录。

我想知道是否有人有经验或可以协助将这种方法“移植”到Lazarus Pascal ......我都赞成做对。当然,替代方法也是最受欢迎的!

任何帮助将不胜感激。

4

2 回答 2

1

不幸的是,我在 Objective-C 方面不是很有经验

不要让这让您停止使用 Apple 提供的示例。如果您仔细查看 SMJobBlessAppController.m 中的代码,您会发现除了一行 Objective-C 代码之外,其余的只是 C。

Objective-C 行注册了辅助应用程序:-

if (![self blessHelperWithLabel:@"com.apple.bsd.SMJobBlessHelper" error:&error])

您将使用自己的 URI,而不是 com.apple.bsd.SMJobBlessHelper。

所有其他相关行都是纯 C 函数。打破这个,你留下: -

// Obtain rights 
AuthorizationCopyRights(self->_authRef, &authRights, kAuthorizationEmptyEnvironment, flags, NULL)


//Start the helper
SMJobBless(kSMDomainSystemLaunchd, (CFStringRef)label, self->_authRef, &cfError);

我省略了检查错误代码,但我希望这表明您需要处理的代码很少,并且需要很少的 Objective-C 知识。

于 2015-01-26T11:52:09.770 回答
0

由于我做了很多工作并认为这对其他人有帮助,因此这是我的最终工作解决方案。 https://www.tweaking4all.com/software-development/lazarus-development/macos-smjobbless-elevated-privileges-lazarus-pascal/

你会在那里找到一个示例项目和大量信息。

重现这一点的步骤非常广泛,所以这里有一个简短的回顾:

我一直在使用 CFMessages 向 Helper Tool 发送消息,因为我没有 NSXPCConnection 的绑定。

Helper Tool 必须基于 Lazarus Pascal 模板“程序”或“简单程序”,不能基于任何 TApplication 类,也不能创建任何踏板。对于 Helper Tool,需要创建一个 info.plist 和一个 launchd.plist,它们都必须嵌入到二进制文件中。

主(测试)应用程序可以是任何 Lazarus Pascal 应用程序,但也需要适当的 Info.plist,表明允许帮助工具以提升的权限启动。

Helper Tool 和应用程序包都需要使用有效的 Apple Developer ID 进行签名。

一些缺少的绑定需要到位:

const  kSMRightBlessPrivilegedHelper = 'com.apple.ServiceManagement.blesshelper';
function SMJobBless(domain:CFStringRef; executableLabel:CFStringRef; auth:AuthorizationRef; outError:CFErrorRef): boolean; external name '_SMJobBless'; mwpascal; 
var kSMDomainSystemLaunchd: CFStringRef; external name '_kSMDomainSystemLaunchd';

并且需要包括适当的框架:

{$linkframework ServiceManagement}
{$linkframework Security}
{$linkframework Foundation}
{$linkframework CoreFoundation}
{$calling mwpascal}

并且不要忘记设置回调函数来处理传入的消息。

我希望这对某人有用...... :-)

于 2019-03-19T12:13:21.560 回答