Comment obtenir des curses pinentry pour commencer sur le bon tty?

13

J'utilise gpg-agentpour gérer les deux identités PGP e SSH. L'agent démarre avec un script comme celui-ci

gpg_agent_env="$XDG_CACHE_HOME/gpg-agent.env"

export GPG_TTY="$(tty)"

if ! ps -U "$USER" -o ucomm | grep -q gpg-agent; then
    eval "$({gpg-agent --daemon | tee $gpg_agent_env} 2> /dev/null)"
else
    source "$gpg_agent_env" 2> /dev/null
fi

qui provient chaque fois que je lance un shell interactif. Tout fonctionne bien avec cette configuration mais il y a un problème. Disons que je:

  1. ouvrir un terminal (lancement de l'agent en arrière-plan) et commencer à travailler
  2. après un certain temps, ouvrez un deuxième terminal
  3. effectuer une action nécessitant la saisie d'une phrase secrète dans le deuxième terminal

À ce stade gpg-agent, pinentry-cursesun mot de passe sera lancé, mais il le fera dans le premier terminal, ce qui entraînera un mélange de sa sortie avec tout ce qui était en cours d'exécution (généralement un éditeur de texte) sans aucun moyen de reprendre le programme ou d'arrêter le pinentry (il commence à utiliser 100% cpu et je dois le tuer).

Je dois faire quelque chose de mal ici. Quelqu'un a vécu cela?

Mise à jour:

J'ai compris que cela ne se produit que pour une invite à déverrouiller une clé SSH, qui ressemble à ceci , tandis que les invites pour les clés PGP s'ouvrent toujours sur le tty correct (c'est-à-dire actuel).

Rnhmjoj
la source
Avez-vous essayé de démarrer l'agent à partir de votre shell de connexion, vous n'avez donc que celui en cours d'exécution?
jasonwryan
@jasonwryan Je viens d'essayer: c'est la même chose pour les terminaux virtuels linux (agetty). Par ailleurs, dans la question avec le terminal, je voulais dire une fenêtre d'émulateur de terminal.
Rnhmjoj
1
C'est export GPG_TTY="$(tty)"ça qui l'a réparé pour moi
naisanza

Réponses:

11

La page de manuel gpg-agent explique sous l'option --enable-ssh-supportque le protocole d'agent ssh n'est pas en mesure de fournir le nom du tty à l'agent, il utilise par défaut le terminal d'origine dans lequel il a été démarré. Avant d'exécuter la commande ssh qui nécessite un phrase de passe dans un nouveau terminal que vous devez saisir

gpg-connect-agent updatestartuptty /bye

dans le nouveau terminal pour mettre à jour la vue de l'agent sur le tty ou l'affichage à utiliser.

meuh
la source
1
Cette réponse m'a aidé à figer complètement cette réalisation: les personnes responsables gpg2n'ont aucune idée de ce que c'est que d'avoir un flux de travail / style de vie centré sur la ligne de commande. D'une manière ou d'une autre, les personnes dont le concept fondamental d'une expérience utilisateur d'ordinateur typique commence et se termine dans les limites des fenêtres GUI ont pu prendre des décisions qui affectent un outil qui était auparavant confortablement utilisable sur la ligne de commande.
mtraceur
2
@mtraceur Pas vraiment, c'est ssh-agent en faute ici: en fait gpg2 affichera l'invite sur le bon tty lors du déverrouillage d'une clé PGP. Ce sont les responsables de ssh-agent qui n'ont peut-être jamais pensé à passer à un autre terminal.
Rnhmjoj
2
@Rnhmjoj Les gars de SSH auraient-ils dû prendre en charge un cas d'utilisation de commutation TTY qu'aucun outil de ligne de commande pour la plupart de l'histoire Unix / Linux ne voulait? Savez-vous comment le processus de réflexion sur la conception et les décisions concernant exactement quelle partie du flux de travail a été gérée par la commande et laquelle a été gérée par l'agent? Si vous l'êtes, peut-être pouvez-vous m'aider à voir quelque chose qui me manque, car je ne vois tout simplement pas clairement comment le besoin même pour l'agent de «changer» de TTY se poserait à moins que l'architecture ne soit décidée sans considérer utilisation et workflows typiques en ligne de commande.
mtraceur
1
@ArneBabenhauserheide La différence est que gpgvous ne pouvez jamais demander la phrase secrète sur le mauvais terminal, alors que vous gpg2le pouvez facilement. La gpgcommande demanderait toujours la phrase secrète sur le terminal à partir duquel vous avez exécuté la commande, car la création de la phrase secrète a été effectuée à partir de cet arbre de processus. Mais gpg2est codé de telle sorte qu'il ne peut pas garantir cela, car il doit demander à un processus d'agent de longue durée distinct de demander la phrase secrète, et cet agent peut avoir démarré à l'origine sur un autre terminal. gpg2et l'agent pouvait, mais n'était pas, codé pour contourner cela.
mtraceur
1
@ArneBabenhauserheide À moins que vous ne demandiez la différence entre l'agent SSH et gpg2? Parce que si oui, alors la différence est que SSH jamais nécessaire cette perversion d'autres outils ayant à dire de manière proactive son agent spécifique aux bornes de commutation en arrière - plan (pour autant que je sais - et si elle a fait alors je les mêmes critiques pour ce trop ). La gpg2conception n'a de sens que si elle est mise en œuvre par des personnes qui ne comprennent pas les aspects pertinents de la CLI sur le fonctionnement de Linux / Unix, et n'ont pas une bonne idée de ce qui rend les interfaces et les outils bons pour composer dans des combinaisons arbitraires.
mtraceur
5

Selon le bogue en amont contre openssh, la bonne façon d'ajouter ceci à votre ~/.ssh/config:

Match host * exec "gpg-connect-agent UPDATESTARTUPTTY /bye"

Jusqu'à présent, cela a parfaitement fonctionné pour moi.

smaslennikov
la source
1
Notez que GPG_TTYdoit être défini sur $(tty)pour que cela fonctionne.
Peter