Wie kann ich dem ssh-agent mitteilen, dass er sich beenden soll?
Helmut Waitzmann
nn.throttle at xoxy.net
So Dez 14 02:48:24 CET 2014
Mathias Bauer <mbauer at mailbox.org> writes:
> Hallo Helmut,
>
> * Helmut Waitzmann schrieb am Fr, 12. Dez 2014, um 20:18 (+0100):
>
> hier läuft
> $ gpg-agent --version
> gpg-agent (GnuPG) 2.0.19
>
Bei mir ist es
$ gpg-agent --version
gpg-agent (GnuPG) 2.0.14
libgcrypt 1.4.5
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
> Ein TERM beendet den Agenten; bei drei TERMs oder einem INT
> geschieht das sofort (ohne Rücksicht auf Verluste). Die
> Prozessnummer ist Teil von GPG_AGENT_INFO:
> /path/to/socket/S.gpg-agent:12345:1
>
> Mit einigen (POSIX-)Shell-Kommandos erhält man:
>
> P="${GPG_AGENT_INFO#*:}"
> P="${P%:*}"
Ah ja, also 3 Teile, getrennt mit je einem â:â. Vermutet habe ich das
auch, konnte aber in der Dokumentation keinen Hinweis finden, ob es
immer (d.h. auch in Zukunft) genau 3 Teile sind, und auch nicht, was
geschieht, wenn im Socketnamen ein Doppelpunkt enthalten ist.
Mein ssh-agent weigert sich, das Socket anzulegen, wenn ich ihm das
Option â--use-standard-socketâ mitgebe und GNUPGHOME einen â:â enthält.
Soweit also keine Gefahr für mehr als 2 â:â in GPG_AGENT_INFO. Nur das
Handbuch schweigt halt dazu.
>
>> âVerlässlichâ heiÃt: Auch im Fall, dass der Agent abgestürzt
>> ist und bereits ein anderer, unbeteiligter Prozess gestartet
>> wurde, der zufällig seine Prozessnummer erhalten hat, muss
>> sichergestellt werden können, dass dann nicht fälschlicherweise
>> dem anderen Prozess ein TERMâSignal geschickt wird.
>
> Kurz: Steckt hinter P wirklich der Agent? Das ist jetzt nicht
> mehr ganz so lustig:
>
> if [ -n "$P" ] && \
> [ -d "/proc/$P" ] && \
> [ "x$(/bin/readlink "/proc/$P/exe")" = x/usr/bin/gpg-agent ]
> then
> kill -TERM "$P"
> sleep 2
> kill -0 "$P" >/dev/null 2>&1 && kill -INT "$P"
> sleep 1
> kill -0 "$P" >/dev/null 2>&1 && kill -KILL "$P"
> fi
>
> Erklärung: *Wenn* es (a) ein P gibt und (b) einen Prozess dazu
> und (c) dessen auführbare Datei mit dem Pfad zum Agent-Programm
> übereinstimmt, *dann* beende den Agent freundlich und warte.
> Wenn er danach immer noch da ist, beende ihn "unfreundlich".
>
> Diese Prüfung ist zwar immer noch offen für Race conditions, aber
> doch etwas sicherer.
Ja, danke, verstanden.
Ich hatte gehofft, dass da vielleicht der gpg-connect-agent helfen
könnte, den gpg-agent zu finden, oder â noch besser â ihm zu sagen, er
solle sich beenden. Schade, das das nicht geht.
> Behandlung von GPG_AGENT_INFO, Agent mit --write-env-file
> starten,...
> Natürlich kannst Du auch einfach mit
>
> killall -v -TERM gpg-agent
>
> alle Agenten grob beenden. Aber das empfehle ich nicht pauschal.
Mir ist da auch nicht wohl dabei.
> Das ganze Vorgehen ist abhängig davon, wie Deine Sessions
> gestartet werden, ob Konsole und/oder X, ob mehrere parallel,
> etc.
Einen gpg-agent möchte ich bei jedem Einloggen zur Verfügung haben,
egal, ob auf der Konsole oder mit X11.
Ich hätte nichts dagegen, wenn es machbar wäre, auf jedem Rechner, der
das gemeinsame NFSâHOMEâVerzeichnis nutzt, nur einen gpg-agent für alle
Sessions zu nutzen. Das hätte den Vorteil, dass ich diesen einen
gpg-agent nicht beenden muss: Er soll ja sowieso für alle weitere
Sessions (egal, ob augenblickliche oder zukünftige) verwendet werden.
Das bedeutet aber, dass ich beim Einloggen nicht einfach einen gpg-agent
starten kann, denn es könnte ja bereits einer laufen. Deswegen kann
dann der Fall eintreten (wenn doch noch kein gpg-agent läuft), dass gpg2
selber einen startet. Weil ich dabei aber keine Möglichkeit habe,
"${GPG_AGENT_INFO}" an andere bereits laufende Prozesse (etwa ein
Mailerprogramm) weiterzugeben, müsste das Socket des von gpg2
gestarteten gpg-agents dann immer an derselben Stelle im Dateisystem zu
finden sein, ich müsste also in gpg-agents Konfigurationsdatei
âuse-standard-socketâ vermerken. Das aber ist laut Dokumentation nicht
erlaubt, wenn "${GNUPGHOME-"${HOME}/.gnupg"}" vom NFS kommt.
Also bleibt wohl nur die Vorgehensweise âfür jedes LoginâSession einen
eigenen gpg-agentâ: Weil dabei bei jedem Login in jedem Fall ein
gpg-agent gestartet wird, kann die von ihm herausgegebene
Umgebungsvariable GPG_AGENT_INFO einfach an alle weiteren Prozesse des
Sessions vererbt werden und es entsteht auch nicht das Problem, dass
gpg2 selber einen gpg-agent startet.
Ah, da tauchen noch ein paar Fragen auf:
Ich habe durch Ausprobieren festgestellt: Die mit dem Option
â--write-env-fileâ vom Agent erzeugte UmgebungsvariablenâDatei wird
weder geleert noch entfernt, wenn sich der Agent nach Empfang eines
TERMâSignals beendet. Das Socket aber wird entfernt.
Kann ich daran, ob das in "${GPG_AGENT_INFO%:*:*}" genannte Socket
vorhanden ist, sehen, ob ein gpg-agent läuft? Dann könnte ich das als
weiteres notwendiges Kriterium nutzen, ehe ich beim Ausloggen ein
TERMâSignal in Richtung gpg-agent schicke. Aber auch hier gäbe es
dasselbe RaceâCondition wie oben.
Wird die vom Agent mit Option â--write-env-fileâ erzeugte
UmgebungsvariablenâDatei von gpg2, gpg-connect-agent oder gpg-agent
gelesen oder ist sie nur eine Alternative zu
$ eval "$(gpg-agent --daemon)"
?
> Ich hoffe, die obigen Schritte helfen Dir erst einmal weiter.
Ja, das tun sie. Vielen Dank.
GrüÃe,
Helmut
Mehr Informationen über die Mailingliste Gnupg-de