Autenticazione e autorizzazione D-Bus


13

Sto cercando di impostare l'accesso remoto a D-Bus e non capisco come funzionano (non) l'autenticazione e l'autorizzazione.

Ho un server D-Bus in ascolto su un socket astratto.

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

Corro dbus-monitorper vedere cosa sta succedendo. Il mio caso di test è notify-send hello, che funziona quando eseguito dal computer locale.

Da un altro account sullo stesso computer, non riesco a collegarmi a quel bus.

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

Dopo aver consultato le specifiche D-Bus , ho copiato ~/.dbus-keyrings/org_freedesktop_generall'altro account, ma non aiuta.

Ho provato a inoltrare la presa D-Bus su TCP, ispirato Schedar 's di accesso D-Bus remoto utilizzando socat .

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

Posso collegarmi al socket TCP dal mio account.

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

Ma non dall'altro account, né con dbus-monitorné con notify-send. Stesso messaggio di errore dbus-monitorcome sopra con il socket astratto; notify-sendora emette una traccia:

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 rivela che questa versione di notify-sendnon tenta di leggere il file cookie, quindi capisco perché non sia in grado di connettersi.

Ho anche provato SSHing su un'altra macchina e inoltrare la connessione TCP.

ssh -R 8004:localhost:8004 remotehost

Sorprendentemente, dbus-monitorfunziona senza un file cookie! Posso guardare il traffico D-Bus dall'host remoto. Vedo un avviso di intercettazione nella mia dbus-monitoristanza locale .

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"

Se corro notify-sendsul computer locale, dbus-monitorsull'host remoto viene visualizzata la notifica. Ha sicuramente raggiunto un livello di accesso che dovrebbe richiedere l'autenticazione.

notify-sendsi è lamentato di non aver trovato un cookie. Dopo aver copiato il file cookie, notify-sendfunziona dal computer remoto.

Il computer locale esegue Debian wheezy. La macchina remota esegue FreeBSD 10.1.

Non capisco come funzionano l'autenticazione e l'autorizzazione D-Bus.

  1. Perché posso intercettare, per quanto posso dire, senza credenziali dalla macchina remota? Cosa espongo quando inoltro D-Bus a una connessione TCP? Perché le autorizzazioni sono diverse dbus-monitore notify-senddiverse?
  2. Perché non posso intercettare da un altro account sulla stessa macchina, sia sul socket astratto che sulla connessione TCP?
  3. Ho notato che il file dei cookie cambia ogni pochi minuti (non ho capito se è a intervalli regolari o meno). Perché?

(So ​​di poter avviare un demone D-Bus in ascolto su TCP. Non è questo lo scopo della mia domanda, voglio capire perché quello che ho fatto e non ha funzionato.)

Risposte:


7

D-Bus non utilizza qui il file dei cookie magici; sta trasferendo le credenziali sul socket del dominio UNIX ( SCM_CREDENTIALS).

Il file cookie magico è solo uno dei numerosi meccanismi di autenticazione D-Bus. D-Bus implementa un'interfaccia conforme a SASL (vedi RFC4422 ) per supportare un'ampia gamma di meccanismi di autenticazione. Uno di questi meccanismi è chiamato auth "ESTERNO" e significa che il canale di trasporto stesso dovrebbe essere usato per garantire l'autenticazione. Almeno nel caso di D-Bus su socket UNIX, questo sembra essere il primo meccanismo di autenticazione che viene provato.

Dalle specifiche D-Bus:

Byte null speciale che passa credenziali

Immediatamente dopo la connessione al server, il client deve inviare un singolo byte nul. Questo byte può essere accompagnato da informazioni sulle credenziali su alcuni sistemi operativi che utilizzano sendmsg () con SCM_CREDS o SCM_CREDENTIALS per trasferire le credenziali sui socket di dominio UNIX. Tuttavia, il byte nul deve essere inviato anche su altri tipi di socket e persino su sistemi operativi che non richiedono l'invio di un byte per la trasmissione delle credenziali. Il protocollo di testo descritto in questo documento inizia dopo il singolo byte nul. Se il primo byte ricevuto dal client non è un byte nullo, il server potrebbe disconnettere quel client.

Un byte nul in qualsiasi contesto diverso dal byte iniziale è un errore; il protocollo è solo ASCII.

Le credenziali inviate insieme al byte nul possono essere utilizzate con il meccanismo SASL EXTERNAL.

Se si traccia un'istanza di dbus-daemon, si può vedere che quando ci si connette ad esso, controlla le credenziali dell'utente che si connette:

$ 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

Quindi, per rispondere alle tue domande:

  1. Il daemon D-Bus utilizza l'ID utente verificato dal kernel per verificare la tua identità. Usando socatle connessioni proxy, stai permettendo a chiunque di connettersi al demone D-Bus usando il tuo UID.

  2. Se si tenta di connettersi direttamente al socket da un altro UID, il daemon riconosce che l'UID di connessione non è un UID che dovrebbe essere autorizzato a connettersi. Credo che il valore predefinito sia che sia consentito solo l'UID del demone, ma non l'ho verificato formalmente. Tuttavia, puoi consentire ad altri utenti: vedi i file di configurazione in /etc/dbus-1/e anche man dbus-daemon.

  3. Questo è il server D-Bus che sostituisce i cookie vecchi / scaduti con quelli nuovi. Secondo la sezione DBUS_COOKIE_SHA1 delle specifiche D-Bus, un cookie viene memorizzato insieme al suo tempo di creazione e il server dovrebbe eliminare i cookie che ritiene troppo vecchi. Apparentemente la vita "può essere piuttosto breve".


L'implementazione di riferimento di D-Bus non utilizza in modo SCM_CREDENTIALSspecifico. Su Linux, invece utilizza l' SO_PEERCREDopzione socket.
Vasiliy Faronov,

@VasiliyFaronov Hai ragione, quanto è interessante! Inoltre, sembra che l'utilizzo SCM_CREDENTIALSavrebbe impedito un proxy così semplice, poiché richiede al mittente di presentare attivamente le proprie credenziali, mentre SO_PEERCREDcontrolla semplicemente chi ha effettuato la connessione. Mi chiedo perché abbiano fatto questa scelta.
Jander

Apparentemente perché "non richiede la collaborazione del pari", quindi "questo è molto meno fragile" (dai commenti in dbus-sysdeps-unix.c).
Vasiliy Faronov,
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.