Je rencontre des problèmes lors de l'écriture de scripts gpg bash
sur une boîte Debian 6.0.6. J'ai un script qui fait un lot d'opérations et veut m'assurer qu'un gpg-agent est disponible avant d'essayer de continuer.
Étant donné que gpg-agent ne prendra aucune action et retournera le succès s'il est lancé lorsqu'il est déjà en cours d'exécution, s'assurer que l'agent est présent est aussi simple que:
eval $(gpg-agent --daemon)
gpg-agent
commencer ou fera rapport:
gpg-agent[21927]: a gpg-agent is already running - not starting a new one
et retourner 0 (succès) s'il est déjà en cours d'exécution.
Le problème survient lorsqu'un agent est déjà en cours d'exécution dans une autre session. gpg-agent
dit qu'il fonctionne déjà ... mais gpg
son auto prétend alors qu'il n'est pas disponible.
$ 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
Cela me laisse frustré et confus. Il semble que la gpg-agent
détection de l'agent soit différente de celle de gpg. Pire, gpg
n'offre aucun moyen de demander si l'agent est disponible de manière scriptable, tout comme il aime ignorer silencieusement les destinataires avec des clés inutilisables et toujours retourner le succès, il est donc très difficile de détecter ce problème avant de commencer le lot. Je ne veux pas entrer dans l'analyse de la sortie de gpg pour des raisons i18n entre autres.
Vous pouvez reproduire cela en vous assurant que vous n'avez pas d'agent gpg en cours d'exécution ou que vous ne l'avez pas GPG_AGENT_INFO
défini, puis dans un terminal en cours d'exécution eval $(gpg-agent --daemon)
et dans un autre terminal exécutant ce qui précède. Vous remarquerez que gpg-agent indique qu'il est déjà en cours d'exécution, mais gpg ne parvient pas à se connecter à l'agent.
Des idées?
MISE À JOUR : gpg-agent
détecte un autre agent en recherchant un fichier socket dans un emplacement bien connu et en y écrivant pour tester la validité, par ceci 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
tandis que GnuPG semble ne regarder que l'environnement, ignorant l'emplacement bien connu des sockets. Dans 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 */
}
Je ne veux pas vraiment tuer l'agent juste pour m'assurer de pouvoir le redémarrer, et il n'y a pas d'endroit standard où l'agent de l'utilisateur pourrait écrire un fichier d'environnement. Pire, je ne peux même pas tester la présence de GPG_AGENT_INFO
dans l'environnement car cela pourrait faire référence à un agent périmé (mort) qui a depuis été remplacé ... et ni gpg
ni gpg-agent
fournir une option de ligne de commande pour envoyer un ping à l'agent et retourner vrai si c'est D'accord.