以编程方式确定 gpg-gent 是否会要求输入密码

以编程方式确定 gpg-gent 是否会要求输入密码

我已经gpg-agent使用缓存的密码运行了一个小时左右。我为offlineimapIMAP 同步实用程序加密了我的电子邮件帐户密码,并让脚本通过从 GPG 加密文件中解密密码来传递密码。

由于我offlineimap使用 systemd 运行,因为它是一个 cron 作业,因此它自然会弹出 pinentry 程序并要求输入密码。我想知道是否有一种方法可以通过编程确认是否gpg-agent需要密码,以便我可以查询信息,并在需要交互式密码输入时正常退出 systemd/cron 作业。

以前有人做过这个吗?

答案1

mbsync我也有类似的计划,定期使用和获取/同步电子邮件cron。密码由pass它使用 GnuPG 加密敏感数据。

较新的 GnuPG(我使用的是 v2.1.18)必须使用gpg-agent来请求解密私钥所需的密码。gpg-agent当我调用pass以获取我的电子邮件帐户的密码时,它将自动启动,并弹出松树入口询问密码的对话框。

我不想将gpg-agent密码缓存太久(例如 1 天甚至 1 年),也不想出现烦人的松树入口由 cron 作业触发的对话框gpg-agent应该很安静。

我认为cron 作业将在可以解密密码mbsync时同步我的电子邮件,而无需触发询问用户密码,否则,cron 作业将退出。gpgpassgpg-agent

我发现 GnuPG 有一个--pinentry-mode选项,其可能值如下:

  • default:使用代理的默认值,即ask
  • ask:强制使用 Pinentry。
  • cancel:模拟使用 Pinentry 的取消按钮。
  • error:返回 Pinentry 错误(“无 Pinentry”)。
  • loopback:将 Pinentry 查询重定向到调用者。请注意,与 Pinentry 不同,如果用户输入了错误的密码,系统不会再次提示用户。

因此,我可以通过传递--pinentry-mode cancel或来明确禁用 pinentry 使用--pinentry-mode error,然后尝试gpg对消息进行签名/解密。如果成功,则gpg-agent已经缓存了密码,并且不会弹出松树入口对话框;否则,签名/解密测试就失败了。

例如:

何时gpg-agent不缓存所需的密码:

$ echo "test" | \
  gpg2 --sign --batch --no-tty --pinentry-mode error \
       --local-user <[email protected]> -o /dev/null

# Return code: 2
# OUTPUT:
# gpg: signing failed: No pinentry
# gpg: signing failed: No pinentry

gpg-agent已经缓存密码时,相同的命令将会成功并返回状态代码 0。

如果我使用--pinentry-mode cancel,则gpg失败Operation cancelled

答案2

我不太确定,但我想知道有这样的选择是否合理,因为它很容易被滥用,例如:

#!/bin/sh
if gpg_ready_to_work_without_pinentry; then
    do_something_malicious_with_the_key;
fi

而且您没有机会检测到滥用。(事实上,我甚至不喜欢我的登录会话中的每个程序都可以访问我可能解锁的密钥,而没有办法检查它是否已解锁。我在搜索 gpg-agent 的选项时发现了您的问题,该选项在每次使用时都会弹出一个确认对话框,原因正是如此。)

相关内容