加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

xcode – 使用swift为Mac应用程序获得管理权限

发布时间:2020-12-14 17:57:41 所属栏目:百科 来源:网络整理
导读:我正在写一些需要经常运行具有root权限的命令的软件. 现在,我这样做是通过向用户询问一次密码,保存密码然后将该密码作为参数提供给NSAppleScript以及管理员权限. 这显然对用户来说是不安全的,因为有人可以访问他们的密码. 我一直在寻找更好的一周时间,但无法
我正在写一些需要经常运行具有root权限的命令的软件.

现在,我这样做是通过向用户询问一次密码,保存密码然后将该密码作为参数提供给NSAppleScript以及管理员权限.

这显然对用户来说是不安全的,因为有人可以访问他们的密码.

我一直在寻找更好的一周时间,但无法找到解决方案.

SMJobBless似乎允许您以更高的权限安装您的应用程序.

我已经关注了应用程序的示例,我从他们的SMJobBlessUtil脚本中收到错误.

这是错误:

SMJobBlessUtil.py: tool designated requirement (identifier "com.domain.AppName.SampleService" and anchor apple generic and certificate leaf[subject.CN] = "Mac Developer: firstName lastName (XXXXXXXXXX)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */) doesn't match entry in 'SMPrivilegedExecutables' (anchor apple generic and identifier "com.domain.AppName.SampleService" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.CN] = "Mac Developer: firstName lastName (XXXXXXXXXX)")

显然,出了点问题.这是各自的plists

服务信息plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleIdentifier</key>
    <string>com.domain.AppName.SampleService</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>SampleService</string>
    <key>CFBundleVersion</key>
    <string>6</string>
    <key>SMAuthorizedClients</key>
    <array>
        <string>anchor apple generic and identifier "com.domain.AppName" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = xxxxxxxxxx)</string>
    </array>
</dict>
</plist>

应用信息plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleDisplayName</key>
    <dict/>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleGetInfoString</key>
    <dict/>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>Away</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0.99</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>9</string>
    <key>LSApplicationCategoryType</key>
    <string>public.app-category.utilities</string>
    <key>LSMinimumSystemVersion</key>
    <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
    <key>LSUIElement</key>
    <true/>
    <key>NSHumanReadableCopyright</key>
    <string>Copyright ? 2016 firstName lastName. All rights reserved.</string>
    <key>NSMainStoryboardFile</key>
    <string>Main</string>
    <key>NSPrincipalClass</key>
    <string>NSApplication</string>
    <key>SMPrivilegedExecutables</key>
    <dict>
        <key>com.domain.AppName.SampleService</key>
        <string>anchor apple generic and identifier "com.domain.AppName.SampleService" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.CN] = "Mac Developer: firstName lastName (XXXXXXXXXX)"</string>
    </dict>
</dict>
</plist>

我看过at this stackoverflow post,还有很多人喜欢它.据我所知,我的钳子设置正确.我究竟做错了什么?

解决方法

这种方法的关键部分在ReadMe.txt的“如何工作”下的“PROPERTY LISTS”部分中描述:

[…] when you sign the helper tool with a Developer ID,Xcode automatically sets the helper tool’s designated requirement like this,and that’s what you should use for SMPrivilegedExecutables. Moreover,this is what the “setreq” command shown above does: extracts the designated requirement from the built tool and put it into the app’s Info.plist source code.

由于您未签署产品(至少不使用示例中描述的证书),因此此过程将始终失败.

如果您不在开发者计划中,则可以使用create a self-signed certificate进行签名.然而,这或多或少地违背了签署要求的目的.如果您不打算注册开发人员计划,您应该能够按如下方式缩短该流程:

>在您的应用程序的Info.plist中,将SMPrivilegedExecutables下的要求缩写为仅匹配帮助程序的标识符:

< string>标识符“com.domain.AppName.SampleService”< / string>

>在助手的Info.plist中,将SMAuthorizedClients下的要求缩写为仅匹配应用程序的标识符:

< string>标识符“com.domain.AppName”< / string>

>忽略ReadMe.txt的“构建和运行示例”指令,并简单地构建和运行项目.

我不能说我当然推荐这个;这些签署要求存在是有充分理由的.它至少比最终的替代方案更好,然而,它将使用NSAppleScript通过chmod和chown为一个帮助程序执行一个root setuid位.

附录详细阐述了这里的一些概念:

运行特权代码会带来许多潜在的安全漏洞;安全地验证用户只是第一步.将所有特权操作委派给一个单独的进程是另一个重要步骤,但仍然存在的主要问题是如何确保您的应用程序 – 用户实际授予的权限 – 是唯一能够利用特权访问权限的实体.

Apple的示例演示了使用代码签名来解决此问题.以防您不熟悉:代码签名涉及以加密方式标记您的最终产品,以便OS X可以验证您的程序是否未被受损版本替换.那些额外的“证书叶子”引用在原始示例的SMAuthorizedClients中,SMPrivilegedExecutables专门用于此;它们描述了您的应用和帮助者必须签署的证书,以便彼此交互.

为了帮助绘制图片,这里有一个粗略的概述:

>您的用户授予launchd授权以安装标记为com.domain.AppName.SampleService的帮助程序守护程序.
> launchd在应用程序的Info.plist中找到SMPrivilegedExecutables下的com.domain.AppName.SampleService条目;这描述了应该使用帮助程序的二进制文件签署的证书. (如果它们不匹配,那么理论上攻击者已经用自己的版本替换了你的帮助工具,以便以root身份运行它.)
>安装了有效的帮助工具后,您的应用程序会发出启动请求以在您的控制下生成帮助程序.此时,launchd会参考帮助工具的Info.plist中的SMAuthorizedClients部分,以确保应用程序实际上有权运行该工具.当然,它会验证您应用的签名,以确保它没有被篡改.

回到您的方案,您的产品目前的工作方式是取消签名步骤.你指示启动检查的唯一一件事是你的应用程序的Info.plist是否将其ID列为“com.domain.AppName”.由于没有什么可以阻止攻击者改变他们的Info.plist来说明这一点,所以你希望他们无法使用你的帮助工具在他们控制它之后做任何伤害.

其他附录概述了备选方案:

>正如我之前提到的,可以使用您在Keychain Access中自己创建的证书对代码进行签名.但是,由于此证书不会向权威机构(即Apple)注册,因此com.domain.AppName将不会更难以欺骗.
>实施您自己的加密解决方案,作为您的应用和帮助之间的通信的一部分.举个例子,你可以generate a pair of keys during installation of the helper,store them via Keychain Services so that your programs have access to them,and verify them against one another when using the helper in the future.
>注册Apple Developer program,以便按Apple的意图签署您的代码;这为您提供OS X的额外好处,而不是通过“未识别的开发人员”schtick吓跑您的用户.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读