D-Bus Authentifizierung und Autorisierung

13

Ich versuche, den Fernzugriff auf D-Bus einzurichten, und verstehe nicht, wie Authentifizierung und Autorisierung funktionieren (nicht).

Ich habe einen D-Bus-Server, der an einem abstrakten Socket lauscht.

$ echo $DBUS_SESSION_BUS_ADDRESS 
unix:abstract=/tmp/dbus-g5sxxvDlmz,guid=49bd93b893fe40d83604952155190c31

Ich renne dbus-monitor, um zu sehen, was los ist. Mein Testfall ist notify-send hello, was funktioniert, wenn es vom lokalen Rechner ausgeführt wird.

Von einem anderen Konto auf demselben Computer kann ich keine Verbindung zu diesem Bus herstellen.

otheraccount$ DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-g5sxxvDlmz,guid=49bd93b893fe40d83604952155190c31 dbus-monitor
Failed to open connection to session bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.
otheraccount$ DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-g5sxxvDlmz,guid=49bd93b893fe40d83604952155190c31 notify-send hello

Nach dem Durchsuchen der D-Bus-Spezifikation habe ich ~/.dbus-keyrings/org_freedesktop_generalauf das andere Konto kopiert , aber es hilft nicht.

Ich habe versucht, den D-Bus-Socket über TCP weiterzuleiten , inspiriert durch die Remote -Verwendung von socat für Access D-Bus von schedar .

socat TCP-LISTEN:8004,reuseaddr,fork,range=127.0.0.1/32 ABSTRACT-CONNECT:/tmp/dbus-g5sxxvDlmz

Ich kann von meinem Konto aus eine Verbindung zum TCP-Socket herstellen.

DBUS_SESSION_BUS_ADDRESS=tcp:host=127.0.0.1,port=8004 notify-send hello

Aber nicht von der anderen Seite, weder mit dbus-monitornoch mit notify-send. Gleiche Fehlermeldung dbus-monitorwie oben beim abstrakten Socket; notify-sendJetzt wird eine Spur ausgegeben:

otheraccount$ DBUS_SESSION_BUS_ADDRESS=tcp:host=127.0.0.1,port=8004 notify-send hello

** (notify-send:2952): WARNING **: The connection is closed

Stracing zeigt, dass diese Version von notify-sendnicht versucht, die Cookie-Datei zu lesen, so dass ich verstehe, warum es nicht in der Lage wäre, eine Verbindung herzustellen .

Ich habe auch versucht, SSH auf einen anderen Computer zu übertragen und die TCP-Verbindung weiterzuleiten.

ssh -R 8004:localhost:8004 remotehost

Funktioniert überraschenderweise dbus-monitorohne Cookie-Datei! Ich kann den D-Bus-Verkehr vom Remote-Host aus verfolgen. In meiner lokalen dbus-monitorInstanz wird ein Hinweis zum Abhören angezeigt.

remotehost$ DBUS_SESSION_BUS_ADDRESS=tcp:host=127.0.0.1,port=8004 dbus-monitor
signal sender=org.freedesktop.DBus -> dest=:1.58 serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired
   string ":1.58"
method call sender=:1.58 -> dest=org.freedesktop.DBus serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "eavesdrop=true"

Wenn ich notify-sendauf dem lokalen Computer ausgeführt werde, wird dbus-monitorauf dem Remote-Host die Benachrichtigung angezeigt. Es ist definitiv eine Zugriffsebene erreicht, die eine Authentifizierung erfordern sollte.

notify-sendbeschwerte sich darüber, dass kein Cookie gefunden wurde. Funktioniert nach dem Kopieren der Cookie-Datei auf notify-senddem Remote-Computer.

Auf der lokalen Maschine läuft Debian Wheezy. Auf der entfernten Maschine läuft FreeBSD 10.1.

Ich verstehe nicht, wie die D-Bus-Authentifizierung und -Autorisierung funktionieren.

  1. Warum kann ich, soweit ich das beurteilen kann, ohne Anmeldeinformationen von der Remote-Maschine abhören? Was kann ich tun, wenn ich D-Bus an eine TCP-Verbindung weiterleite? Warum sind Berechtigungen für dbus-monitorund notify-sendunterschiedlich?
  2. Warum kann ich nicht von einem anderen Konto auf demselben Computer abhören, ob über den abstrakten Socket oder über die TCP-Verbindung?
  3. Ich habe festgestellt, dass sich die Cookie-Datei alle paar Minuten ändert (ich habe nicht herausgefunden, ob sie in regelmäßigen Abständen stattfindet oder nicht). Warum?

(Ich weiß, dass ich einen D-Bus-Daemon starten kann, der auf TCP lauscht. Das ist nicht der Zweck meiner Frage, ich möchte verstehen, warum das, was ich getan und was nicht funktioniert hat.)

Gilles 'SO - hör auf böse zu sein'
quelle

Antworten:

7

D-Bus verwendet die Magic Cookie-Datei hier nicht. Es werden Anmeldeinformationen über die UNIX-Domäne socket ( SCM_CREDENTIALS) übergeben.

Die Magic Cookie-Datei ist nur einer von mehreren D-Bus-Authentifizierungsmechanismen. D-Bus implementiert eine SASL- kompatible Schnittstelle (siehe RFC4422 ), um eine Vielzahl von Authentifizierungsmechanismen zu unterstützen. Einer dieser Mechanismen heißt "EXTERNAL" auth. Dies bedeutet, dass der Transportkanal selbst verwendet werden sollte, um die Authentifizierung zu gewährleisten. Zumindest bei D-Bus über UNIX-Sockets scheint dies der erste Authentifizierungsmechanismus zu sein, der versucht wird.

Aus der D-Bus-Spezifikation:

Spezielle Anmeldeinformationen, die kein Byte übergeben

Unmittelbar nach dem Herstellen der Verbindung zum Server muss der Client ein einzelnes Nullbyte senden. Diesem Byte können Anmeldeinformationen für einige Betriebssysteme beigefügt sein, die sendmsg () mit SCM_CREDS oder SCM_CREDENTIALS verwenden, um Anmeldeinformationen über UNIX-Domänensockets zu übergeben. Das nul-Byte muss jedoch auch auf anderen Arten von Sockets und sogar auf Betriebssystemen gesendet werden, auf denen zum Übertragen von Anmeldeinformationen kein Byte gesendet werden muss. Das in diesem Dokument beschriebene Textprotokoll beginnt nach dem Einzelbyte. Wenn das erste vom Client empfangene Byte kein Nullbyte ist, trennt der Server möglicherweise die Verbindung zum Client.

Ein Null-Byte in einem anderen Kontext als dem Anfangs-Byte ist ein Fehler. Das Protokoll ist nur ASCII-fähig.

Die zusammen mit dem nul-Byte gesendeten Anmeldeinformationen können mit dem SASL-Mechanismus EXTERNAL verwendet werden.

Wenn Sie eine Instanz von stracen dbus-daemon, können Sie feststellen, dass beim Herstellen einer Verbindung die Anmeldeinformationen des Benutzers überprüft werden, der die Verbindung herstellt:

$ strace dbus-daemon --session --nofork
...
accept4(4, {sa_family=AF_LOCAL, NULL}, [2], SOCK_CLOEXEC) = 8
...
recvmsg(8, {msg_name(0)=NULL, msg_iov(1)=[{"\0", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
getsockopt(8, SOL_SOCKET, SO_PEERCRED, {pid=6694, uid=1000, gid=1000}, [12]) = 0

So beantworten Sie Ihre Fragen:

  1. Der D-Bus-Dämon verwendet Ihre vom Kernel überprüfte Benutzer-ID, um Ihre Identität zu überprüfen. Durch die Verwendung von socatzu Proxy-Verbindungen kann sich jeder mit Ihrer UID mit dem D-Bus-Dämon verbinden.

  2. Wenn Sie versuchen, eine direkte Verbindung von einer anderen UID zum Socket herzustellen, erkennt der Dämon, dass die verbindende UID keine UID ist, die eine Verbindung herstellen darf. Ich glaube, die Standardeinstellung ist, dass nur die eigene UID des Daemons zulässig ist, dies wurde jedoch nicht offiziell bestätigt. Sie können jedoch auch andere Benutzer zulassen: siehe die Konfigurationsdateien in /etc/dbus-1/und auch man dbus-daemon.

  3. Dies ist der D-Bus-Server, der alte / abgelaufene Cookies durch neue ersetzt. Gemäß dem Abschnitt DBUS_COOKIE_SHA1 der D-Bus-Spezifikation wird ein Cookie zusammen mit seiner Erstellungszeit gespeichert und der Server soll Cookies löschen, die er für zu alt hält. Anscheinend kann die Lebensdauer "ziemlich kurz sein".

Jander
quelle
Die Referenzimplementierung von D-Bus wird nicht SCM_CREDENTIALSspeziell verwendet. Unter Linux wird SO_PEERCREDstattdessen die Option socket verwendet.
Vasiliy Faronov
@ VasiliyFaronov Du hast Recht - wie interessant! Außerdem scheint die Verwendung SCM_CREDENTIALSeines solchen einfachen Proxys verhindert zu haben, da der Absender aktiv seine Anmeldeinformationen vorlegen muss, während SO_PEERCREDlediglich überprüft wird, wer die Verbindung hergestellt hat. Ich frage mich, warum sie diese Wahl getroffen haben.
Jander
Anscheinend, weil es "nicht die Kooperation des Kollegen erfordert", also "das ist viel weniger zerbrechlich" (aus Kommentaren in dbus-sysdeps-unix.c).
Vasiliy Faronov