Lazarus Pascal:使用 SMJobBless() 编写特权助手工具



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

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

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

在做了大量的阅读之后,苹果似乎更喜欢使用一个名为SMJobBless()的辅助工具来完成此操作。不幸的是,我在 Objective-C 方面不是很有经验,呈现的代码充其量似乎非常少,也没有很好的文档记录。

我想知道是否有人有经验或可以帮助将这种方法"移植"到拉撒路帕斯卡......我完全赞成做对。当然,也非常欢迎其他方法!

任何帮助将不胜感激。

不幸的是,我在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 知识。

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

你会发现一个示例项目和大量的信息。

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

我一直在使用 CFMessages 将消息发送到帮助程序工具,因为我没有 NSXPCConnection 的绑定。

辅助工具必须基于Lazarus Pascal模板"程序"或"简单程序",并且不能基于任何TApplication类,也不能创建任何踏板。对于帮助程序工具,需要创建一个 info.plist 和一个 launchd.plist,它们都必须嵌入到二进制文件中。

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

帮助程序工具和应用程序应用程序捆绑包都需要使用有效的 Apple 开发人员 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}

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

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

相关内容

最新更新