使用 gpg-agent 和 pinentry-curses 进行 git 标签

使用 gpg-agent 和 pinentry-curses 进行 git 标签

当使用 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 会以某种方式妨碍……某些东西,但在运行 archlinux-arm 的 raspberry pi 上,它的工作方式相同,但问题略有不同——运行命令后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

编辑:运行 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 时变量(也可以从 bash/zsh rc 文件完成):

export GPG_TTY=$(tty)

答案2

Pinentry ncurses 对话框的问题与 pinentry 尝试使用的 TTY 的所有权有关(例如,如果您最初以用户身份登录,然后按 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

相关内容