Uwierzytelnianie i autoryzacja D-Bus


13

Próbuję skonfigurować zdalny dostęp do D-Bus i nie rozumiem, jak działa (nie) uwierzytelnianie i autoryzacja.

Mam serwer D-Bus nasłuchujący na abstrakcyjnym gnieździe.

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

Pobiegam dbus-monitoroglądać co się dzieje. Mój przypadek testowy to notify-send hello, który działa po uruchomieniu z komputera lokalnego.

Z innego konta na tym samym komputerze nie mogę się połączyć z tą magistralą.

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

Po przejrzeniu specyfikacji D-Bus skopiowałem ~/.dbus-keyrings/org_freedesktop_generalna inne konto, ale to nie pomaga.

Próbowałem spedycja gniazdo D-Bus przez TCP, inspirowany schedar „s Wejście D-Bus zdalnie przy użyciu socat .

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

Mogę połączyć się z gniazdem TCP z mojego konta.

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

Ale nie z drugiego konta, ani z, dbus-monitorani z notify-send. Ten sam komunikat o błędzie dbus-monitorjak powyżej z gniazdem abstrakcyjnym; notify-sendteraz emituje ślad:

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 ujawnia, że ​​ta wersja notify-sendnie próbuje odczytać pliku cookie, więc rozumiem, dlaczego nie mógł się połączyć.

Próbowałem także SSHing na innym komputerze i przekazywanie połączenia TCP.

ssh -R 8004:localhost:8004 remotehost

Zaskakujące, dbus-monitordziała bez pliku cookie! Mogę obserwować ruch D-Bus ze zdalnego hosta. Widzę powiadomienie o podsłuchiwaniu w mojej lokalnej dbus-monitorinstancji.

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"

Jeśli uruchomię notify-sendna komputerze lokalnym, dbus-monitorna hoście zdalnym zobaczy powiadomienie. Zdecydowanie osiągnął poziom dostępu, który powinien wymagać uwierzytelnienia.

notify-sendskarżył się na brak pliku cookie. Po skopiowaniu pliku cookie notify-senddziała ze zdalnego komputera.

Na lokalnej maszynie działa wheezy Debiana. Na zdalnym komputerze działa FreeBSD 10.1.

Nie rozumiem, jak działa uwierzytelnianie i autoryzacja D-Bus.

  1. Dlaczego mogę podsłuchiwać, o ile mogę, bez poświadczeń ze zdalnego komputera? Co ujawniam, gdy przesyłam D-Bus do połączenia TCP? Dlaczego są zezwolenia na dbus-monitori notify-sendróżne?
  2. Dlaczego nie mogę podsłuchiwać z innego konta na tym samym komputerze, czy to przez gniazdo abstrakcyjne, czy przez połączenie TCP?
  3. Zauważyłem, że plik cookie zmienia się co kilka minut (nie wiedziałem, czy to w regularnych odstępach czasu, czy nie). Dlaczego?

(Wiem, że mogę uruchomić demona D-Bus, który nasłuchuje na TCP. Nie jest to celem mojego pytania, chcę zrozumieć, dlaczego to, co zrobiłem, a co nie działało).

Odpowiedzi:


7

D-Bus nie używa tutaj magicznego pliku cookie; przekazuje dane uwierzytelniające przez gniazdo domeny UNIX ( SCM_CREDENTIALS).

Magiczny plik cookie to tylko jeden z kilku mechanizmów uwierzytelniania D-Bus. D-Bus implementuje interfejs zgodny z SASL (patrz RFC4422 ) w celu obsługi szerokiej gamy mechanizmów uwierzytelniania. Jeden z tych mechanizmów nazywa się „ZEWNĘTRZNYM” uwierzytelnianiem i oznacza, że ​​sam kanał transportowy powinien być używany do zagwarantowania uwierzytelnienia. Przynajmniej w przypadku D-Bus przez gniazda UNIX wydaje się, że jest to pierwszy sprawdzany mechanizm uwierzytelniania.

Ze specyfikacji D-Bus:

Specjalne bajty przekazujące nul bajt

Natychmiast po połączeniu z serwerem klient musi wysłać pojedynczy bajt nul. Bajtowi temu mogą towarzyszyć informacje dotyczące poświadczeń w niektórych systemach operacyjnych, które używają sendmsg () z SCM_CREDS lub SCM_CREDENTIALS do przekazywania poświadczeń przez gniazda domeny UNIX. Jednak bajt nul musi być wysłany nawet na inne rodzaje gniazd, a nawet w systemach operacyjnych, które nie wymagają wysłania bajtu w celu przesłania referencji. Protokół tekstowy opisany w tym dokumencie rozpoczyna się po pojedynczym pustym bajcie. Jeśli pierwszy bajt otrzymany od klienta nie jest bajtem pustym, serwer może odłączyć tego klienta.

Nul bajt w dowolnym kontekście innym niż bajt początkowy jest błędem; protokół jest tylko ASCII.

Poświadczenia wysłane razem z bajtem nul mogą być używane z mechanizmem SASL EXTERNAL.

Jeśli wykryjesz wystąpienie dbus-daemon, możesz zobaczyć, że po połączeniu się z nim sprawdza on poświadczenia łączącego się użytkownika:

$ 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

Aby odpowiedzieć na twoje pytania:

  1. Demon D-Bus używa twojego ID użytkownika zweryfikowanego pod kątem jądra, aby zweryfikować twoją tożsamość. Korzystając socatz połączeń z serwerem proxy, pozwalasz każdemu połączyć się z demonem D-Bus za pomocą Twojego identyfikatora UID.

  2. Jeśli spróbujesz połączyć się bezpośrednio z gniazdem z innego identyfikatora UID, demon rozpozna, że ​​łączący identyfikator UID nie jest identyfikatorem UID, który powinien mieć możliwość połączenia. Uważam, że domyślnie dozwolone jest tylko własne UID demona, ale formalnie tego nie zweryfikowałem. Możesz jednak zezwolić innym użytkownikom: zobacz pliki konfiguracyjne w /etc/dbus-1/, a także man dbus-daemon.

  3. Jest to serwer D-Bus zastępujący stare / wygasłe pliki cookie nowymi. Zgodnie z sekcją DBUS_COOKIE_SHA1 specyfikacji D-Bus plik cookie jest przechowywany wraz z czasem jego utworzenia, a serwer powinien usunąć pliki cookie, które według niego są za stare. Najwyraźniej czas życia „może być dość krótki”.


Referencyjna implementacja D-Bus nie korzysta SCM_CREDENTIALSkonkretnie. W systemie Linux SO_PEERCREDzamiast tego używa opcji gniazda.
Wasilij Faronow

@VasiliyFaronov Masz rację - jakie ciekawe! Ponadto wygląda na to, że użycie SCM_CREDENTIALSuniemożliwiłoby tak prosty serwer proxy, ponieważ wymaga od nadawcy aktywnego przedstawienia swoich danych uwierzytelniających, a SO_PEERCREDjedynie sprawdzenia, kto nawiązał połączenie. Zastanawiam się, dlaczego dokonali tego wyboru.
Jander

Najwyraźniej dlatego, że „nie wymaga współpracy peera”, więc „jest to o wiele mniej kruche” (na podstawie komentarzy dbus-sysdeps-unix.c).
Vasiliy Faronov
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.