bash
Debian 6.0.6のボックスで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
使用できないキーを持つ受信者を黙って無視し、それでも成功を返すのと同じように、スクリプト可能な方法でエージェントが利用できるかどうかを尋ねる方法を提供しません。したがって、バッチを開始する前にこの問題を検出することは非常に困難です。とりわけi18nの理由でgpgの出力を解析したくありません。
これを再現するには、gpg-agentが実行されていないか、GPG_AGENT_INFO
設定されていないことを確認してeval $(gpg-agent --daemon)
から、 ある 端末で上記の端末を実行します。gpg-agentはすでに実行されていると表示しますが、gpgはエージェントへの接続に失敗します。
アイデア?
UPDATE:gpg-agent
よく知られている場所でソケットファイルを探し、それを書き込んで生存度をテストすることにより、別のエージェントを検出しますstrace
。
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
ことは、環境中に交換されているためだ古い(死んだ)エージェントを参照してください...とどちらも可能性があるためgpg
でもgpg-agent
エージェントにpingを実行している場合、それはの真を返すようにコマンドラインオプションを提供しますOK。