Sto lottando con alcuni problemi mentre scripting gpg con bash
su una scatola Debian 6.0.6. Ho uno script che esegue una serie di operazioni e vuole assicurarmi che un agente gpg sia disponibile prima che tenti di procedere.
Poiché gpg-agent non eseguirà alcuna azione e restituirà il successo se avviato quando è già in esecuzione, assicurarsi che l'agente sia presente è semplice come:
eval $(gpg-agent --daemon)
gpg-agent
iniziare o segnalerà:
gpg-agent[21927]: a gpg-agent is already running - not starting a new one
e restituisce 0 (successo) se già in esecuzione.
Il problema sorge quando un agente è già in esecuzione in un'altra sessione. gpg-agent
dice che è già in esecuzione ... ma gpg
se stesso afferma quindi che non è disponibile.
$ 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
Questo mi lascia frustrato e confuso. Sembra che gpg-agent
stia rilevando l'agente in un modo diverso di gpg se stesso. Peggio ancora, gpg
non offre alcun modo per chiedere se l'agente è disponibile in modo programmabile, in quanto gli piace ignorare silenziosamente i destinatari con chiavi inutilizzabili e restituire comunque il successo, quindi è molto difficile rilevare questo problema prima di iniziare il batch. Non voglio analizzare l'output di gpg per motivi i18n tra gli altri.
Puoi riprodurlo assicurandoti di non avere un agente gpg in esecuzione o di averlo GPG_AGENT_INFO
impostato, quindi in un terminale in esecuzione eval $(gpg-agent --daemon)
e in un altro terminale in esecuzione sopra. Noterai che gpg-agent dice che è già in esecuzione, ma gpg non riesce a connettersi all'agent.
Idee?
AGGIORNAMENTO : gpg-agent
rileva un altro agente cercando un file socket in una posizione ben nota e scrivendo su di esso per verificare la disponibilità, a questo scopo 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
mentre GnuPG sembra guardare solo all'ambiente, ignorando la nota posizione del socket. In 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 */
}
Non voglio davvero uccidere l'agente solo per assicurarmi di poterlo ricominciare, e non esiste un posto standard in cui l'agente dell'utente potrebbe scrivere un file di ambiente. Peggio ancora, non riesco nemmeno a test per la presenza di GPG_AGENT_INFO
nell'ambiente dal momento che potrebbe riferirsi ad uno stantio (morto) l'agente che è stato successivamente sostituito ... e né gpg
né gpg-agent
fornire un'opzione di riga di comando per eseguire il ping l'agente e restituisce true se si tratta di ok.