git-тег с gpg-agent и pinentry-curses

git-тег с gpg-agent и pinentry-curses

При использовании gpg-agent с git tag -u я сразу получаю следующую ошибку:

gpg: cancelled by user
gpg: skipped "[email protected]": bad passphrase
gpg: signing failed: bad passphrase
error: gpg failed to sign the data
error: unable to sign the tag

gpg-agent.conf:

pinentry-program /usr/bin/pinentry-curses

Когда я сначала разблокирую ключ (через gpg -e -s test.txt), то git tag -uкоманда подбирает ключ и подписывает тег, как и ожидалось.

Это на ubuntu 13.10, использующем i3 wm. Я бы заподозрил, что gnome-keyring как-то мешает... чему-то, но на raspberry pi, работающем archlinux-arm, это работает так же, но с немного другой проблемой — после запуска команды git tag -uона запрашивает пароль для разблокировки, но не появляется ни pinentry, ни приглашения. Через некоторое время (около 30 секунд) она дает сбой со следующим:

gpg: problem with the agent: Line passed to IPC too long
gpg: skipped "[email protected]": Operation cancelled
gpg: signing failed: Operation cancelled
error: gpg failed to sign the data
error: unable to sign the tag

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

Я предполагаю, что что-то странное с моим использованием pinentry-curses. Я уже обновил /usr/bin/pinentry, чтобы он указывал на /usr/bin/pinentry-curses, но проблема осталась.

Что я делаю не так и как заставить git работать с gpg/pinentry?

  • версия ubuntu gpg: 1.4.14
  • archlinux-arm gpg версия: gnupg-2.0.22-1

EDIT: запуск zsh. Вот соответствующий бит, полученный для агента gpg:

if [ $EUID -ne 0 ] ; then
    envfile="$HOME/.gnupg/gpg-agent.env"
    if [[ -e "$envfile" ]] && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then
        eval "$(cat "$envfile")"
    else
        eval "$(gpg-agent --daemon --write-env-file "$envfile")"
    fi
    export GPG_AGENT_INFO  # the env file does not contain the export statement
fi

когда я следую за $(tty) (например: /dev/pts/16), владельцем уже является user:tty.

решение1

Вам также необходимо будет экспортироватьGPG_TTYпеременная каждый раз при запуске нового TTY (также можно сделать из rc-файлов bash/zsh):

export GPG_TTY=$(tty)

решение2

Проблемы с диалоговым окном Pinentry ncurses связаны с правами собственности на TTY, который пытается использовать pinentry (например, если вы сначала входите как пользователь, а затем su).

Поместите следующий скрипт в/etc/profile.d/gpg-agent.shчтобы исправить это (вы можете захотеть опустить внешний оператор ifв многопользовательской системе или изменить условие на !=):

if [ "$(id -un)" = "root" ] ; then
    envfile="$HOME/.gnupg/gpg-agent.env"
    if [[ -e "$envfile" ]] && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then
        eval "$(cat "$envfile")"
    else
        eval "$(gpg-agent --daemon --enable-ssh-support --write-env-file "$envfile")"
    fi

    export GPG_AGENT_INFO    # the env file does not contain the export statement
    export SSH_AUTH_SOCK     # enable gpg-agent for ssh

    GPG_TTY=$(tty)
    chown $USER:tty $GPG_TTY # make pinentry-ncurses work
fi

Связанный контент