"Взаимодействие с пользователем не разрешено" при попытке подписать приложение OSX с использованием кода

Наша автоматизированная сборка работает на Jenkins. Сама сборка выполняется на подчиненных, причем подчиненные выполняются через SSH.

Я получаю ошибку:

00:03:25.113 [codesign-app] build/App.app: User interaction is not allowed.

Я испробовал каждое предложение, которое я видел до сих пор в других сообщениях здесь:

  • Использование безопасности unlock-keychain непосредственно перед подписью для разблокировки цепочки для ключей.
  • Перемещение подписывающего ключа в собственную цепочку для ключей.
  • Перемещение подписывающего ключа в связку ключей входа.
  • Перемещение ключа подписи в системную связку ключей.
  • Ручная настройка списков цепочек для ключей только для цепочки для ключей, которая содержит ключ.

Во всех случаях я получаю одну и ту же ошибку.

В попытке диагностировать проблему, я попытался выполнить команду "security unlock-keychain" на моем локальном терминале и обнаружил, что она на самом деле не разблокирует цепочку для ключей - если я смотрю в Keychain Access, символ блокировки все еще там. Это тот случай, когда я передаю пароль в командной строке или разрешаю ему запрашивать его. Разблокировка той же цепочки для ключей с помощью графического интерфейса предложит мне ввести пароль, а затем разблокировать его. Кроме того, если я запускаю "security lock-keychain", я вижу блокировку ключа сразу после запуска команды. Это заставляет меня думать, что unlock-keychain на самом деле не работает. Я испытываю такое же поведение на Lion (который мы используем для сборщиков) и Mavericks (на котором я разрабатываю).

Затем я попытался добавить -v ко всем командам безопасности:

list-keychains "-d" "system" "-s" "/Users/tester/.secret/App.keychain"
Listing keychains to see if it was added: ((
        "/Library/Keychains/System.keychain"
))
unlock-keychain "-p" "**PASSWORD**" "/Users/tester/.secret/App.keychain"
build/App.app: User interaction is not allowed.

Из этого может показаться, что списки-брелки - это то, что не работает. Может быть, ни работа.:/

Здесь есть похожий вопрос. Решение интересное - установите "SessionCreate" в true в launchctl. Но я не опираюсь на мастер - мой процесс сборки запускается из SSH на подчиненной сборочной машине. Может быть, есть способ командной строки сделать то, что делает launchctl, когда вы запускаете "SessionCreate"?

16 ответов

Решение

Ну, я думаю, что смогу ответить на свой вопрос сегодня, потому что после двух с половиной дней, кажется, что одна из вещей, которые я попробовал, сработала. Я просто собираюсь отступить от этого сейчас и надеюсь, что он продолжает работать.

По сути, похоже, что сводится к -d system на самом деле не работает. Поэтому многие ответы на другие вопросы здесь, вероятно, следует обновить, чтобы отразить это.

security -v list-keychains -s "$KEYCHAIN" "$HOME/Library/Keychains/login.keychain"
security list-keychains # so we can verify that it was added if it fails again
security -v unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
codesign --sign "$SIGNER_IDENTITY" --force --signature-size 9600 \
         --resource-rules src/AppResourceRules.plist --timestamp --verbose \
         "$APP"

Я тоже боролся с этим. Ничего не помогало, пока я не попробовал предложение на http://devnet.jetbrains.com/thread/311971. Спасибо Ашиш Агравал!

Войдите в свой пользователь сборки через графический интерфейс и откройте Keychain Access. Выберите подписывающий закрытый ключ, щелкните правой кнопкой мыши, выберите "Информация", перейдите на вкладку "Контроль доступа" и выберите "Разрешить всем приложениям доступ к этому элементу".

вкладка контроля доступа

Использование безопасности для создания цепочки для ключей для /usr/bin/codesign

Импортировать сертификат и заставить его работать с кодовым знаком программно - не значит использовать логин или системные цепочки для ключей или молиться богу кодового знака. Вам просто нужно установить правильные разрешения. Я рекомендую создать новый брелок специально для целей кодирования.

В эти дни, чтобы получить codesign не дать errSecInternalComponent вам нужно получить правильный список разделов (ACL). Я пройдусь по ступеням:

Создать брелок

security create-keychain -p "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_NAME}"

на этом этапе цепочка для ключей разблокирована, но не появится в Keychain Access,

Добавить новый брелок в список поиска

security list-keychains -s "${KEYCHAIN_NAME}" "${OLD_KEYCHAIN_NAMES[@]}"

Добавьте новый брелок в список. Если вы сначала не получите оригинальный список из list-keychains у тебя больше не будет login.keychain в вашем списке поиска.

Разблокировать брелок

security unlock-keychain -p "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_NAME}"

Это избыточно, если вы создали цепочку для ключей выше, но если цепочка для ключей уже существует, это необходимо.

Удалить значения по умолчанию из брелка

security set-keychain-settings "${TESTING_KEYCHAIN}"

Не указав никаких аргументов, вы установите неограниченное время автоблокировки и удалите автоблокировку в спящем режиме.

Импортируйте свои сертификаты подписи из.p12

security import "${DIST_CER}" -P "${CERTIFICATE_PASSWORD}" -k "${KEYCHAIN_NAME}" -T /usr/bin/codesign

Импортировать сертификаты и т codesign доступ через -T вариант.

Установите ACL на связку ключей

security set-key-partition-list -S apple-tool:,apple: -s -k "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_NAME}"

Это требование, которое многие люди пропускают. Вы можете увидеть, что делает macOS, используя dump-keychain. Что в случае кодирования требует apple: а также apple-tool:, -s относится к подписанию сертификатов.

Gitlab-Runner, Дженкинс и тому подобное

Для любого бегуна типа CI или системы сборки очень важно убедиться, что процесс запущен из launchd правильно. Убедитесь, что ваш лист содержит <SessionCreate> </true>,

Неправильное сопоставление владельца цепочки для ключей с процессом сборки и обеспечение того, что сеанс безопасности будет создан, приведет к разным головным болям. Диагностически говоря, вы можете представить list-keychains и посмотрите, соответствует ли результат вашим ожиданиям.

Это из launchd.plist человек-страница:

SessionCreate <boolean>

Этот ключ указывает, что задание должно порождаться в новом сеансе аудита безопасности, а не в сеансе по умолчанию для контекста. См Auditon(2) для деталей.

UserName <string>

Этот необязательный ключ указывает, что пользователь должен запускать задание как. Этот ключ применим только для служб, которые загружаются в привилегированный системный домен.

GroupName <string>

Этот необязательный ключ определяет группу для запуска задания. Этот ключ применим только для служб, которые загружаются в привилегированный системный домен. Если имя пользователя установлено, а имя группы нет, то группа будет установлена ​​в качестве основной группы пользователя.

Наконец код

Вы можете посмотреть хэш сертификатов подписи используя find-identity

security find-identity -p codesigning -v

Codesign рамки, dylib и др.

/usr/bin/codesign --verbose=4 -f -s "$SIGNER_HASH" "$SIGNABLE"

Создайте комплект приложений

/usr/bin/codesign --verbose=4 -f -s "$SIGNER_HASH" --entitlements entitlements.xcent "$SIGNABLE"

Заключительные замечания - если вы посмотрите, как Xcode это делает, они устанавливают CODESIGN_ALLOCATE использовать тот, который содержится в Xcode, а не в /usr/bin,

export CODESIGN_ALLOCATE="$( xcrun --find codesign_allocate )"

Путь поиска установлен в ${PLATFORM_PATH}:${TOOLCHAIN_PATH}:${PATH} где путь PLATFORM - это каталог / usr / bin для заданного целевого SDK, а TOOLCHAIN_PATH - это / usr / bin для инструментов узла Xcode.

Ни один из других ответов не работал для меня.

Что в конечном итоге спасло меня, был этот пост

Подводя итог, это может быть вызвано тайм-аутом по умолчанию в 5 минут, который вызовет эту ошибку после долгой сборки.

Чинить:

security set-keychain-settings -t 3600 -l ~/Library/Keychains/login.keychain

Попробуй позвонить security unlock-keychain а также codesign как однострочная команда. Это помогло мне. Что-то вроде:

security unlock-keychain -p <password> /Users/<user>/Library/Keychains/login.keychain && codesign --force --verify --verbose --sign "<certificate id>" <app name>

Поместите свои ключи в Системную цепочку для ключей

Так что это команда, которая работает. -A чтобы запретить Mac запрашивать пароль. Импорт в system.keychain не требует графического интерфейса.

sudo security import <cert.p12> -k "/Library/Keychains/System.keychain" -P <passphrase> -A

Мой брелок был заблокирован. Он сопротивлялся моим успехам, чтобы изменить этот факт...

Keychain Access -> Keychain First Aid -> Repairи так вуаля!

Разблокировка брелка не достаточно. Вы также должны установить доступ к закрытому ключу "Разрешить всем приложениям доступ к этому элементу". И чтобы сделать это из командной строки, необходимо повторно импортировать ключ. Итак, чтобы принять вещи за раз:

Разблокируйте брелок для входа, если он заблокирован. Это не должно быть заблокировано, но в любом случае вот как вы это делаете:

security -v unlock-keychain -p "$KEYCHAIN_PASSWORD" "~/Library/Keychains/login.keychain"

Если по какой-либо причине на вашей машине сборки заблокирована цепочка для ключей входа в систему, и вы не хотите показывать этот пароль в сценарии, вам следует использовать другую цепочку для ключей. Вы можете создать его на месте и использовать в предыдущей и следующей командах. Чтобы создать его на месте:

security create-keychain -p 'temporaryPassword' MyKeychain.keychain
security list-keychains -d user -s login.keychain MyKeychain.keychain

Затем импортируйте свои сертификаты и связанные закрытые ключи в цепочку ключей входа в систему, используя параметр -A. Обратите внимание, что вам не нужно sudo для всего этого...

security import <cert.p12> -k "~/Library/Keychains/login.keychain" -P <passphrase> -A

Параметр -A задает для вашего личного ключа значение "Разрешить всем приложениям доступ к этому элементу".

Таким образом, используя все это, вы сможете создать сценарий, который установит необходимый сертификат для создания релиза ipa и подпишет его без запроса. Вы можете сохранить файл.p12 в своем репозитории, чтобы любой компьютер мог собрать ваш ipa без необходимости ручной настройки.

Помимо разблокировки цепочки для ключей (как упомянуто в других ответах), вам необходимо разрешить доступ всех приложений к токену аутентификации XCode в цепочке для ключей:

  • Выберите брелок для входа
  • Выберите категорию "Все товары"
  • Поиск по ключевому слову "xcode"
  • Выберите "Разрешить всем приложениям доступ к этому элементу" для всех токенов Xcode
  • Не забудьте добавить шаг разблокировки брелка (из предыдущих ответов)

Поэтому я попробовал каждый ответ здесь, и что-то не совсем складывалось. Наконец, я понял, когда я перезагружал свой CI-сервис, он работал под другим пользователем, чем я ожидал. Переход на пользователя, который фактически имел доступ к ключу в своей цепочке входа, исправил все. Это может быть не частой проблемой, но я хотел документировать мою конкретную причину этой ошибки, на случай, если это случится с другими.

Импортируйте свои ключи в Системную цепочку для ключей. Вы можете использовать эту команду:

sudo security import YourKey.p12 -k /Library/Keychains/System.keychain -P PasswordToYourKey -T /usr/bin/codesign

Для меня ничего не работает, кажется, придется переустановить XCode снова и снова. Дженкинс продолжает повторять одну и ту же ошибку. Вы сэкономите много времени, если просто переместите установку XCode в корзину и переустановите. Убедитесь, что вы запускаете команду codeign из командной строки как минимум один раз.

Даже после того, как вы получите ту же ошибку, попробуйте установить 'Unlock Keychain?' свойства в Jenkins и укажите путь к своему login.keychain в /Users/$‹USER‹/Library/Keychains/login.keychain

Я надеюсь, что Бог будет с тобой после этого.

В моем случае это было вызвано созданием цепочки для ключей с таймаутом по умолчанию, равным 300 с, и длинной компиляцией xcode, продолжительностью более 300 с. Обходной путь, для меня, должен был вызвать:

security set-keychain-settings -t <longer timeout in seconds> <keychain>

сразу после создания временной цепочки для ключей.

Попробовав ряд вышеперечисленных решений. Я понял, что одним из факторов, с которыми я столкнулся, было то, что я начинал сборку с помощью консоли ION. Когда я вернулся к созданию сборки из приложения Terminal, все работало просто отлично.

Я просмотрел все эти предложения и все еще имел проблемы с использованием Fastlane's gym в работе Дженкинс. У меня был установлен сертификат и разблокирована цепочка для ключей, и я смог выполнить кодирование на ведомом устройстве, когда я вручную выполнил команду codeign в командной строке.

В качестве обходного пути, если Jenkins подключается к ведомому устройству, используя JNLP вместо SSH, вы сможете кодировать.

Для меня это происходит, когда вручную добавляется вторая цепочка для ключей, и она заблокирована. По какой-то причине codesign пытается получить доступ к заблокированной цепочке для ключей и терпит неудачу, даже если сертификаты находятся в цепочке для ключей входа (и разблокирована). Разблокировка второго решает проблему. Просто не имеет смысла для меня.

Другие вопросы по тегам