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

时间:2015-01-26 11:19:57

标签: macos root lazarus access-rights smjobbless

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

在初始版本中,我使用了AuthorizationExecuteWithPrivileges()link),尽管并非完全用于此目的,但它确实非常有效并且非常一致。 但是,自OSX 10.7起,此函数已被折旧,因为它可能是一个安全问题,并且重定向的命令行语句也无法正常工作(将zip的输出重定向为dd的输入)。

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

经过大量阅读后,Apple似乎更喜欢使用名为SMJobBless()的辅助工具。遗憾的是,就Objective-C而言,我并不是很有经验,所提出的代码看起来非常简单,也没有很好的记录。

我想知道是否有人有经验或可以协助移植"这个方法Lazarus Pascal ......我全都赞成做对。 当然,也欢迎其他方法!

非常感谢任何帮助。

2 个答案:

答案 0 :(得分: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知识。

答案 1 :(得分:0)

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

您会在其中找到一个示例项目和大量信息。

重现此步骤的步骤相当广泛,因此这里有一个简短的回顾:

由于我没有NSXPCConnection的绑定,所以我一直在使用CFMessages将消息发送到帮助工具。

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}

我们别忘了设置回调函数来处理传入消息。

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