gpg代理说代理存在,但gpg说,代理不存在?

我在Debian 6.0.6框中用bash编写gpg脚本时遇到了一些问题。 我有一个脚本,执行一批操作,并希望确保gpg-agent在尝试继续之前可用。

由于gpg-agent在运行时不会执行任何操作并返回成功,所以确保代理存在就像下面这样简单:

 eval $(gpg-agent --daemon) 

gpg-agent开始,或将会报告:

 gpg-agent[21927]: a gpg-agent is already running - not starting a new one 

如果已经运行,则返回0(成功)。

当代理程序已经在另一个会话中运行时,会出现问题。 gpg-agent说它已经在运行了……但是gpg自我声称它不可用。

 $ gpg-agent --version gpg-agent (GnuPG) 2.0.19 libgcrypt 1.5.0 $ gpg --version gpg (GnuPG) 1.4.13 $ eval $(gpg-agent --daemon) gpg-agent[21927]: a gpg-agent is already running - not starting a new one $ gpg -d demo-file.asc gpg: gpg-agent is not available in this session 

这让我感到沮丧和困惑。 看起来, gpg-agent正在检测代理以不同的方式来gpg自己。 更糟糕的是, gpg没有办法问这个代理是否可用脚本方式,就像它默默地忽略不可用密钥的收件人,仍然返回成功,所以在开始批处理之前很难检测到这个问题。 我不想为了国际原因parsinggpg的输出。

您可以通过确保您没有运行gpg代理程序或已设置GPG_AGENT_INFO来重现此操作,然后在运行eval $(gpg-agent --daemon) 另一个 terminal中运行以上代码。 你会注意到gpg-agent说它已经在运行,但是gpg无法连接到代理。

想法?

更新gpg-agent通过在知名位置查找套接字文件来检测另一个代理,并通过写入来testing活性,

 socket(PF_FILE, SOCK_STREAM, 0) = 5 connect(5, {sa_family=AF_FILE, sun_path="/home/craig/.gnupg/S.gpg-agent"}, 32) = 0 fcntl(5, F_GETFL) = 0x2 (flags O_RDWR) fcntl(5, F_GETFL) = 0x2 (flags O_RDWR) select(6, [5], NULL, NULL, {0, 0}) = 1 (in [5], left {0, 0}) read(5, "OK Pleased to meet you, process "..., 1002) = 38 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f41a3e61000 write(2, "gpg-agent: gpg-agent running and"..., 43gpg-agent: gpg-agent running and available ) = 43 

而GnuPG似乎只看环境,忽略了众所周知的插槽位置。 common/simple-pwquery.c

 /* Try to open a connection to the agent, send all options and return the file descriptor for the connection. Return -1 in case of error. */ static int agent_open (int *rfd) { int rc; int fd; char *infostr, *p; struct sockaddr_un client_addr; size_t len; int prot; char line[200]; int nread; *rfd = -1; infostr = getenv ( "GPG_AGENT_INFO" ); if ( !infostr || !*infostr ) infostr = default_gpg_agent_info; if ( !infostr || !*infostr ) { #ifdef SPWQ_USE_LOGGING log_error (_("gpg-agent is not available in this session\n")); #endif return SPWQ_NO_AGENT; } /* blah blah blah truncated blah */ } 

我真的不想杀死代理,只是为了确保我可以重新启动它,而且用户的代理可能不会写一个环境文件的标准位置。 更糟糕的是,我甚至GPG_AGENT_INFO在环境中testingGPG_AGENT_INFO的存在,因为它可能引用了一个已经被replace的失效代理程序,而且gpggpg-agent都不提供命令行选项来ping代理程序如果没关系,就返回true。

  1. 您可以查看gpg-connect-agent /bye的退出码
  2. 您可以检查$ GPG_AGENT_INFO中给出的套接字是否存在。 这应该足够了,但是您也可以使用fuser或lsof来检查$ GPG_AGENT_INFO中给出的过程是否是打开套接字的过程。 如果你想要非常详尽,你也可以检查/ proc / $ PID / exe是否是/ usr / bin / gpg-agent(或其他)的链接。

到目前为止,我所拥有的最好的解决方法是下面的可怕混乱:

 if ! test -v GPG_AGENT_INFO; then if gpg-agent 2>/dev/null; then if test -e /tmp/.gpg-agent-$USER/env; then . /tmp/.gpg-agent-$USER/env elif test -e ~/.gpg-agent-info; then . ~/.gpg-agent-info else echo 'A gpg agent is running, but we cannot find its socket info because' echo 'the GPG_AGENT_INFO env var is not set and gpg agent info has not been' echo 'written to any expected location. Cannot continue. Please report this' echo 'issue for investigation.' exit 5 fi else mkdir /tmp/.gpg-agent-$USER chmod 700 /tmp/.gpg-agent-$USER gpg-agent --daemon --write-env-file /tmp/.gpg-agent-$USER/env . /tmp/.gpg-agent-$USER/env fi # The env file doesn't include an export statement export GPG_AGENT_INFO else if ! gpg-agent 2>/dev/null; then echo 'GPG_AGENT_INFO is set, but cannot connect to the agent.' echo 'Unsure how to proceed, so aborting execution. Please report this' echo 'issue for investigation.' exit 5 fi fi 

这将在环境中检查GPG_AGENT_INFO ,如果已设置,请确保gpg-agent正在运行。 (我还不确定这是如何与其他gpg代理实现,如GNOME的代理交互)。 如果代理信息已设置但代理未运行,则不知道如何处理和放弃。

如果代理信息未设置,则检查代理是否正在运行。 如果是这样,它会在几个知名位置查找env信息,如果找不到它,就放弃。

如果代理程序未运行且代理程序信息未设置,则启动代理程序,将env文件写入专用位置,然后继续。

如果说我对这个可怕的,用户敌对的,不可靠的黑客不满意的话,这是轻描淡写的。

gpg是一个安全/encryption工具,将会忽略争议并继续进行,这是非常令人惊讶的。 --use-agent应该是一个致命的错误,如果一个代理程序没有运行,至less可以select,就像用一个无效的接收程序指定-r应该是一个错误,而不是被忽略。 gpg发现其代理与gpg-agent命令不同的事实令人眼花缭乱。

正在运行的gpg代理的主要版本是2.您应该调用gpg2而不是gpg作为回答在这里: https ://unix.stackexchange.com/questions/231386/how-to-make-gpg-find-gpg-agent

在我的Ubuntu系统上, gpg-agentconfiguration为将其环境文件写入~/.gnupg/gpg-agent-info-$(hostname) (由/etc/X11/Xsession.d/90gpg-agent完成)。 如果你的系统没有这样做,你可以修改代理开始写一个环境文件的方式在一个知道的位置,稍后可以find。 例如:

 $ gpg-agent --daemon --write-env-file="$HOME/.gnupg/gpg-agent-info" $ source ~/.gnupg/gpg-agent-info