gpg-agent dice che l'agente esiste, ma gpg dice che l'agente non esiste?


9

Sto lottando con alcuni problemi mentre scripting gpg con bashsu 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-agentdice che è già in esecuzione ... ma gpgse 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-agentstia rilevando l'agente in un modo diverso di gpg se stesso. Peggio ancora, gpgnon 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_INFOimpostato, 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-agentrileva 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_INFOnell'ambiente dal momento che potrebbe riferirsi ad uno stantio (morto) l'agente che è stato successivamente sostituito ... e né gpggpg-agentfornire un'opzione di riga di comando per eseguire il ping l'agente e restituisce true se si tratta di ok.


Ho anche chiesto sulla mailing list degli utenti di gpg; Collegherò al post una volta che appare negli archivi.
Craig Ringer,

Unix.SE Come configurare gpg per inserire la passphrase solo una volta per sessione ha risolto alcuni dei miei problemi - su un sistema a utente singolo.
Joel Purra,

Risposte:


6
  1. Puoi controllare il codice di uscita di gpg-connect-agent /bye
  2. Puoi verificare se esiste il socket indicato in $ GPG_AGENT_INFO. Dovrebbe bastare, ma puoi anche verificare con fuser o lsof se il processo indicato in $ GPG_AGENT_INFO è quello che ha aperto il socket. E se vuoi essere davvero completo, puoi anche verificare se / proc / $ PID / exe è un link a / usr / bin / gpg-agent (o qualsiasi altra cosa).

Sfortunatamente, nessuno di questi risolve il problema. (1) determina correttamente se gpg-agent è in esecuzione, ma non verifica allo stesso modo di gpgse stesso, quindi potrebbe avere successo quando gpg successivamente non riesce a connettersi all'agent. Lo stesso vale per (2) in quanto l'agente potrebbe essere in esecuzione, ma GPG_AGENT_INFO non è impostato nella sessione corrente e non esiste un modo apparente per chiedere al gpg-agentcomando GPG_AGENT_INFOdi un agente già in esecuzione.
Craig Ringer,


3

Finora la soluzione migliore che ho è il seguente disastro orribile:

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

Questo verificherà GPG_AGENT_INFOnell'ambiente e se è impostato, assicurati che gpg-agent sia effettivamente in esecuzione. (Non sono ancora sicuro di come interagisca con altre implementazioni di agenti gpg come l'agente di GNOME). Se le informazioni sull'agente sono impostate ma l'agente non è in esecuzione, non sa come far fronte e si arrende.

Se le informazioni sull'agente non sono impostate, controlla se l'agente è in esecuzione. Se lo è, cerca le informazioni env in un paio di posizioni ben note e se non riesce a trovarle, si arrende.

Se l'agente non è in esecuzione e le informazioni sull'agente non sono impostate, avvia un agente, scrive il file env in un percorso privato e procede.

Dire che non sono soddisfatto di questo hack orribile, ostile all'utente e inaffidabile è un eufemismo.

È molto sorprendente che gpg, uno strumento di sicurezza / crittografia, ignori gli argomenti e proceda. --use-agentdovrebbe essere un errore fatale se un agente non è in esecuzione, almeno facoltativamente, tanto quanto la specifica -rcon un destinatario non valido dovrebbe essere un errore anziché essere ignorato. Il fatto che gpgtrova il suo agente in un modo diverso dal gpg-agentcomando è sconcertante.


Come al solito può essere reso ancora più disordinato ... :-) Se GPG_AGENT_INFO non è impostato (o erroneamente) e conosci il PID (ad es. pgrep gpg-agentlsof -n -p $PID | grep S.gpg-agent$ | awk '{print $NF}'
By

1
@HaukeLaging ... se davvero gpg-agentnon si dice gnome-keyring-daemonal lavoro. perché non era già abbastanza orribile: S. Sono sorpreso che sia tutto un casino così incoerente.
Craig Ringer,

! test -v GPG_AGENT_INFO non funziona su Mac OS X. Dovrai [ -z ${GPG_AGENT_INFO+x} ]invece utilizzare qualcosa di simile .
Dan Loewenherz,

2

Sul mio sistema Ubuntu gpg-agentè configurato per scrivere il suo file di ambiente in ~/.gnupg/gpg-agent-info-$(hostname)(che è fatto da /etc/X11/Xsession.d/90gpg-agent). Se il sistema non lo fa, è possibile modificare il modo in cui l'agente viene avviato per scrivere un file di ambiente in una posizione ben nota che può essere successivamente reperita. Per esempio:

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

Sì, il problema è che sono strumenti di scripting che devono essere portatili; Non posso davvero fare affidamento su dettagli specifici della distro. gpg-agent non scriverà un file env se un agente è già in esecuzione e non riesco a determinare dove potrebbe essere già un file env. Se gpg-agent --write-env-file interrogherà l'agente attualmente in esecuzione e scriverà un file env, andrebbe bene, ma non lo è.
Craig Ringer,

1
NB:gpg-agent[2333]: WARNING: "--write-env-file" is an obsolete option - it has no effect
Kent Fredric,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.