Tengo problemas con algunos problemas al crear scripts gpg bash
en un cuadro de Debian 6.0.6. Tengo un script que realiza un lote de operaciones y quiere asegurarse de que haya un agente gpg disponible antes de intentar continuar.
Dado que gpg-agent no realizará ninguna acción y devolverá el éxito si se inicia cuando ya se está ejecutando, garantizar que el agente esté presente es tan simple como:
eval $(gpg-agent --daemon)
gpg-agent
comenzará o informará:
gpg-agent[21927]: a gpg-agent is already running - not starting a new one
y devuelve 0 (éxito) si ya se está ejecutando.
El problema surge cuando un agente ya se está ejecutando en otra sesión. gpg-agent
dice que ya se está ejecutando ... pero gpg
luego afirma que no está 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
Esto me deja frustrado y confundido. Parece que gpg-agent
está detectando al agente de una manera diferente a gpg por sí mismo. Peor aún, gpg
no ofrece ninguna manera de preguntar si el agente está disponible de manera programable, por mucho que le guste ignorar silenciosamente a los destinatarios con claves inutilizables y aún así devolver el éxito, por lo que es muy difícil detectar este problema antes de comenzar el lote. No quiero entrar en el análisis de la salida de gpg por razones i18n entre otras.
Puede reproducir esto asegurándose de no tener un agente gpg ejecutándose o GPG_AGENT_INFO
configurado, luego en un terminal ejecutándose eval $(gpg-agent --daemon)
y en otro terminal ejecutando lo anterior. Notarás que gpg-agent dice que ya se está ejecutando, pero gpg no se conecta al agente.
Ideas?
ACTUALIZACIÓN : gpg-agent
detecta a otro agente buscando un archivo de socket en una ubicación conocida y escribiéndole para probar la vida, por esto 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
mientras que GnuPG parece mirar solo el entorno, ignorando la conocida ubicación del socket. En 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 */
}
Realmente no quiero matar al agente solo para asegurarme de que puedo iniciarlo nuevamente, y no hay un lugar estándar donde el agente del usuario pueda escribir un archivo de entorno. Peor aún, ni siquiera puedo probar la presencia GPG_AGENT_INFO
en el entorno, ya que eso podría referirse a un agente obsoleto (muerto) que desde entonces ha sido reemplazado ... y gpg
tampoco gpg-agent
proporcionar una opción de línea de comando para hacer ping al agente y devolver verdadero si es Okay.