从派生终端运行xcodebuild

59

我正在尝试为iPhone应用程序设置自动化构建服务器。我希望能够每晚创建adhoc测试版构建,以便测试人员可以跟进开发。

我已成功设置了xcode以执行adhoc构建,并且也可以通过命令行启动构建:

xcodebuild -configuration AdHoc -sdk iphoneos2.2 clean build

我的问题是,以下行不适用于forked终端(使用nohup或screen),并出现以下错误:

CodeSign error: Code Signing Identity 'iPhone Distribution: XXXXX' does not match any code-signing certificate in your keychain. Once added to the keychain, touch a file or clean the project to continue.

我已经检查了我的shell和nohup或screen中的环境变量,但没有找到线索。我猜想我的问题是forked终端无法访问钥匙串,但我不知道如何允许它访问。

感谢您的帮助。


你能否粘贴你用来启动终端的命令? - Nik Reiman
第一个终端被启动,打开Terminal.app。 第二个使用screen。 - Yann Biancheri
这个问题可以使用sudo解决吗? - adam
我刚刚尝试了使用各种sudo组合运行命令,但始终出现相同的CodeSign错误。 - Yann Biancheri
此问题可能仍会出现,无论是否解锁登录钥匙串。 唯一适用于我的方法是使用钥匙串访问应用程序,并将分发/ adhoc 证书+密钥复制到系统钥匙串中。 - brack
13个回答

91

我曾遇到过错误"User interaction is not allowed",并通过先解锁钥匙串来解决它。

security unlock-keychain /Users/yannooo/Library/Keychains/login.keychain

我也尝试将我的证书放入系统的钥匙串中,而且它确实起作用了。我的最终解决方案是使用 Keychain Access 应用程序将所有与 iPhone 相关的证书放入名为 iPhone.keychain 的专用钥匙串中。

security list-keychains -s /Users/yannooo/Library/Keychains/iPhone.keychain 
security unlock-keychain -p keychainpassword /Users/yannooo/Library/Keychains/iPhone.keychain 

3
这是我原本打算在评论中写的,但内容太长了无法放进去。据我所知,评论也无法进行格式调整。 - Yann Biancheri
这解决了我的“用户交互不允许”的问题。很棒的技巧。 - Jirapong
1
对我也起作用了,但是我必须将iPhone钥匙串设置为默认,因为xcodebuild似乎只使用默认的。这可能对某些人有帮助。 - pojo
1
以上方法对我也都不起作用,直到我手动将证书从“登录”钥匙串复制到“系统”钥匙串。这还消除了在代码中使用“security”解锁钥匙串的需要。 - brack
1
请注意,这还有另一个组件。访问控制列表。请参见下面的答案。 - markshiz
显示剩余4条评论

30
这涉及到两个(可能是三个!)组件。首先,必须解锁钥匙串。其次,在钥匙串中有一个访问控制列表,告诉哪些权限在解锁状态下授予应用程序。因此,即使您已成功解锁了钥匙串,如果没有将访问私钥和签名的能力授予 /usr/bin/codesign,那么仍然会收到此消息。最后,如果您使用的是Mac OS Sierra,则为密钥分配的默认分区ID不正确,以与codesign二进制文件兼容。
解决方案如下:
1)如果您可以访问Keychain Access GUI,则可以通过右键单击您的私钥,选择“Access Control”选项卡,然后选择“Allow all applications to access this item”单选按钮或“Always allow access by these applications”列表手动授权每个程序或 /usr/bin/codesign访问。
2)如果您遇到此错误,则很有可能正在尝试为非登录用户运行codesign。在这种情况下,您显然无法访问“Keychain Access”GUI。对于这些情况,您可以使用以下命令验证应用程序<null>缺少的sign授权,该授权显然适用于所有应用程序,或特别适用于/usr/bin/codesign
security dump-keychain -i login.keychain

但是,由于某种原因,您不能在交互模式下添加或修改访问控制属性——只能删除!实际上,您必须手动删除密钥并重新将其加入到密钥链中,指定 -T 标志。

security import login.keychain -P "<password>" -T /usr/bin/codesign

-T指定了

-T  Specify an application which may access the imported key (multiple -T options are allowed)

3) 如果你使用的是Mac OS Sierra系统,请修改分区ID以包括apple分区。据推测,这是由于codesign是由苹果公司分发的,因此被分配了该命名空间。

security set-key-partition-list -S apple-tool:,apple: -k "<password>" login.keychain

注意apple-tool分区是由security工具插入的,因此上述命令会保留该分区。有关此方面的更多信息,请参见:http://www.openradar.me/28524119


非常感谢!这解决了我的问题。我将/usr/bin/codesign添加到我的私钥中。 - bmauter
将 /usr/bin/codesign 添加到私钥中是解决我们代码签名问题的方法。这应该是被接受的答案。非常感谢! - Vertigo
“-T”不再以相同的方式工作。您还需要设置一个分区列表。https://dev59.com/oVkS5IYBdhLWcg3wb2Ts#40039594(嗨,马克!) - Heath Borders

13

另一种解决方案:

  • 打开钥匙串访问
  • 右键点击私钥
  • 选择“获取信息”
  • 选择“访问控制”选项卡
  • 点击“允许所有应用程序访问此项目”
  • 点击“保存更改”
  • 输入您的密码
  • 享受吧

这对我也有帮助,因为我在 TeamCity 构建中使用了新的证书/密钥。 - Taytay

9

您可以在构建过程中使用security list-keychains -s ${HOME}/Library/Keychains/login.keychain来显式地将您的登录钥匙串添加到搜索列表中吗?似乎从分叉的终端,构建过程看不到您的用户钥匙串。如果钥匙串搜索列表基于当前安全会话,这可能是有道理的 - 分叉的终端会像通过环回连接进行ssh一样保留登录会话。


不是针对我。如果我互动登录到构建帐户,则可以将keychains添加到我的搜索列表中。如果我以其他人的身份登录,则无法执行此操作。 - sehugg

7

针对遇到Jenkins类似问题的用户更新:

如果您设置了Mac以通过LaunchDaemons启动Jenkins,则需要确保添加以下内容:

<key>SessionCreate</key>
<true />

整个ci.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>Label</key>
 <string>Jenkins</string>
 <key>UserName</key>
 <string>user</string>
 <key>GroupName</key>
 <string>staff</string>
 <key>ProgramArguments</key>
 <array>
 <string>/usr/bin/java</string>
 <string>-Xmx512m</string>
 <string>-jar</string>
 <string>/path/to/jenkins/jenkins.war</string>
 </array>
 <key>RunAtLoad</key>
 <true/>
 <key>KeepAlive</key>
 <true/>
 <key>EnvironmentVariables</key>
   <dict>
     <key>JENKINS_HOME</key>
     <string>/path/to/jenkins/home</string>
   </dict>
 <key>SessionCreate</key>
 <true />
</dict>
</plist>

我一直遇到和上面许多人一样的问题。具体来说,当我从 Jenkins shell 脚本运行时,我也遇到了 "User interaction is not allowed" 的错误。但在 ssh shell 中运行脚本时,它可以正常工作。
大多数人注意到的区别是,如果您运行 "security list-keychain" 命令,则会得到:
$ security list-keychain
  "/Library/Keychains/System.keychain"
  "/Library/Keychains/System.keychain"

但是在ssh shell中运行时,我会得到以下错误提示:

$ security list-keychain
    "/Users/<i>user_account_name</i>/Library/Keychains/login.keychain"
    "/Library/Keychains/System.keychain"

大多数人会将所有的密钥/证书等存储在用户账户钥匙串中。正如一些人建议的那样,很容易创建一个与用户钥匙串不同的新钥匙串,并将其保留用于XCode签名。我最终将我的放在这里:/Library/Keychains/sysiphone.keychain。
我认为问题在于我的设置(可能也适用于你的设置),你正在运行在不同的安全性偏好域(系统 vs. 用户)。最后 - 这是我让我的sysiphone.keychain显示出来的方法:
$ sudo security list-keychains -d system -s "/Library/Keychains/sysiphone.keychain"
Password: *****
$ security list-keychains -d system
    "/Library/Keychains/sysiphone.keychain"

我开始在Jenkins中构建,神奇的事情发生了。哇...这对我来说浪费了大约4个小时。叹气。


这解决了我的TeamCity构建器问题。谢谢! - ddoughty
我最终把我的放在这里:/Library/Keychains/sysiphone.keychain。神奇!! - jiangjiefs

6
好的,这个问题对我来说有两个方面,第一个是解锁钥匙串;
security unlock-keychain login.keychain

第二个是(空)密码短语。

security import blahblahbackup.p12 -k login.keychain -T /usr/bin/codesign -P ""

更新:

我后来遇到了一个小问题,当脚本从网页脚本(或类似的东西)触发时。它只能看到 /Library/Keychains/System.chain。所以我找到了一个不太好的解决方法(可能会导致安全问题,但对我来说还可以);

  • 设置 pubkey ssh 登录(从想要调用构建脚本的用户到实际拥有证书并将运行 xcodebuild 的用户),在我的案例中,它是相同的用户。Apache 正在作为 someuser 工作,并且构建的所有内容都已设置在 someuser 上。
  • 我的 php 脚本(用于触发构建)正在调用 ~/build-script。我把它改成了这样:

    ssh someuser@localhost ~/build-script

所以它在真正的 tty 中工作,并且所有钥匙串都是可访问的,一切正常运行。


4
正如另一位发帖者所说,
security list-keychains -s  "~/Library/Keychains/login.keychain"

但我认为只有在GUI上下文中登录时才能访问login.keychain(我刚刚通过SSH和屏幕测试了一个系统,但我也恰好通过VNC登录了该系统)。
显然可以使用launchctl选择GUI上下文并运行程序,但我怀疑这仅适用于“已登录用户”。
如果尝试“security show-keychain-info keychain-file”,则会收到以下错误:

不允许用户交互

这是一个搜索更多信息的短语。 另一种解决方案是将证书放入您的系统钥匙串中!

1
你找到了“如何共享”登录或任何钥匙链的解决方案吗?我的意思是使用ssh或其他方式(而不是GUI)来使用Keychains。 - Sergey Kopanev
您可以使用以下命令来修复“用户交互不允许”的问题:security unlock-keychain -p "密码" /Users/用户名/Library/Keychains/login.keychain-db - undefined

2

我查看了安全命令,发现在分叉时分配给我的终端的钥匙串与启动安全命令时不同。如果我在终端中启动安全命令,则会显示:

$ security list-keychains
  "/Users/yannooo/Library/Keychains/login.keychain"
  "/Library/Keychains/System.keychain"

然而,当我使用screen时,输出结果如下:

$ security list-keychains
    "/Library/Keychains/System.keychain"
    "/Library/Keychains/System.keychain"

由于我的构建证书存储在登录钥匙串中,所以我遇到的代码签名错误看起来很正常。

有人知道如何将钥匙串分配给终端吗?我已经尝试过但没有成功。

security login-keychain -s /Users/yannooo/Library/Keychains/login.keychain

有什么想法吗?

使用钥匙串访问应用程序,手动将所需证书从“登录”钥匙串复制到“系统”钥匙串。 - brack
谢谢!对我来说它运行得很好。但是我有点担心它——这个方案正确吗?谢谢。 - Sergey Kopanev
当您只看到两个 System.keychains 时,您可能是以 root 而不是您的用户身份运行该命令。当我意外以 root 而不是我的用户身份运行 Bamboo 持续集成服务器并尝试构建和签署应用程序时,我遇到了这个确切的问题。 - Collin Allen

2
我正在使用Atlassian Bamboo 2.7和OS X 10.7.3 Lion,尝试了线程中找到的每种方法,但仍然出现“不允许用户交互”的错误。
问题在于,在远程终端会话中(作为“superuser”,例如Bamboo或另一个自动构建系统的情况下),需要解锁包含签名证书的钥匙串与您正常看到的不同(例如Yann在here中显示的)。当您不是超级用户时)。
对我最终有效的方法是执行以下操作:
  1. 按照here中的说明登录为系统管理员
  2. 创建仅签名的钥匙串(例如ios.keychain
  3. 将签名证书添加到其中(以及WWDRCA证书)
通过在终端上输入su并运行security list-keychains来验证它。您应该在列表中看到ios.keychain。(sudo security list-keychains不会显示相同的内容):
sh-3.2# security list-keychains
"/private/var/root/Library/Keychains/login.keychain"
"/Library/Keychains/ios.keychain"
"/Library/Keychains/System.keychain"

我发现在执行unlock-keychain命令之前,您仍然需要将ios.keychain添加到搜索范围中。在您的构建脚本中,请运行以下行:
KEYCHAIN=/Library/Keychains/ios.keychain
# the -s option adds $KEYCHAIN to the search scope, while the -d option adds $KEYCHAIN to the system domain; both are needed
security -v list-keychains -d system -s $KEYCHAIN 
security -v unlock-keychain -p bambooiphone $KEYCHAIN

2
如果你运行了security list-keychains命令,发现你的自定义钥匙串在列表中出现,但仍然无法使用,可能是因为你遇到了我所遇到的问题,即钥匙串按照搜索列表的顺序进行检查。由于我没有在SSH会话中解锁login.keychain,它就会在那里失败,而不会移动到列表中的下一个钥匙串,也就是我想要解锁的自定义钥匙串。

将搜索列表设置为一个使用security unlock-keychain解锁的自定义钥匙串可以解决这个问题。使用Yann的答案中的方法还可以从搜索列表中删除你的login.keychain。

如果要保留login.keychain:

security list-keychains -s ~/Library/Keychains/custom.keychain ~/Library/Keychains/login.keychain

这样,当您在机器上使用GUI会话时,仍然可以访问login.keychain项目,但代码签名将首先检查自定义钥匙串,如果您已解锁它,则成功。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接