Аутентифікація та авторизація D-Bus


13

Я намагаюся налаштувати віддалений доступ до D-Bus, і я не розумію, як аутентифікація та авторизація працюють (не) працюють.

У мене D-Bus-сервер прослуховує абстрактну розетку.

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

Я біжу dbus-monitorдивитись, що відбувається. Мій тестовий випадок notify-send hello, який працює при виконанні з локальної машини.

З іншого облікового запису на тій же машині я не можу підключитися до цієї шини.

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

Після перегляду специфікації D-Bus , я скопіював ~/.dbus-keyrings/org_freedesktop_generalна інший рахунок, але це не допомагає.

Я намагався пересиланням гніздо D-Bus через TCP, натхненний Шедар «s Access D-Bus дистанційно з використанням SOCAT .

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

Я можу підключитися до сокета TCP зі свого облікового запису.

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

Але не з іншого рахунку, ні з, dbus-monitorні з notify-send. Те саме повідомлення про помилку, dbus-monitorяк описано вище з абстрактним сокетом; notify-sendтепер випромінює слід:

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

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

Структування показує, що ця версія notify-sendне намагається прочитати файл cookie, тому я розумію, чому він не зміг би з'єднатися.

Я також спробував SSHing в іншу машину і переадресував TCP-з'єднання.

ssh -R 8004:localhost:8004 remotehost

Дивно, але dbus-monitorпрацює без файлу cookie! Я можу спостерігати за трафіком D-Bus від віддаленого хоста. Я бачу повідомлення про підслуховування в моєму місцевому dbus-monitorекземплярі.

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"

Якщо я працюю notify-sendна локальній машині, dbus-monitorна віддаленому хості бачиться повідомлення. Однозначно досягнуто рівня доступу, який повинен вимагати автентифікації.

notify-sendскаржився на те, що не знайшов печиво. Після копіювання файлу cookie notify-sendпрацює з віддаленої машини.

Місцева машина працює за допомогою хрипів Debian. Віддалена машина працює на FreeBSD 10.1.

Я не розумію, як працюють автентифікація та авторизація D-Bus.

  1. Чому я можу підслуховувати, наскільки я можу сказати, без даних для віддаленої машини? Що я відкриваю, коли пересилаю D-Bus на з'єднання TCP? Чому авторизація dbus-monitorі чим notify-sendвідрізняється?
  2. Чому я не можу підслуховувати інший обліковий запис на тій же машині, чи то через абстрактний сокет, так і через TCP-з'єднання?
  3. Я помітив, що файл файлів cookie змінюється кожні кілька хвилин (я не зрозумів, чи є він через рівні проміжки часу чи ні). Чому?

(Я знаю, що можу запустити демон-D-Bus, який слухає на TCP. Це не мета мого запитання. Я хочу зрозуміти, чому я це зробив і не працював.)

Відповіді:


7

D-Bus тут не використовує файл чарівного файлу cookie; він передає облікові дані через сокет домену UNIX ( SCM_CREDENTIALS).

Чарівний файл файлів cookie - це лише один із декількох механізмів аутентифікації D-Bus. D-Bus реалізує інтерфейс, сумісний із SASL (див. RFC4422 ) для підтримки широкого спектру механізмів аутентифікації. Один з цих механізмів називається "ЗОВНІШНИЙ" auth, і це означає, що саме транспортний канал повинен використовуватися для гарантії автентичності. Принаймні, у випадку з D-Bus через сокети UNIX, це, здається, є першим випробуваним механізмом аутентифікації.

Від специфікації D-Bus:

Спеціальні облікові дані, що передають нульовий байт

Відразу після підключення до сервера клієнт повинен надіслати єдиний нульовий байт. Цей байт може супроводжуватися інформацією про облікові дані в деяких операційних системах, які використовують sendmsg () з SCM_CREDS або SCM_CREDENTIALS для передачі облікових даних через сокети домену UNIX. Однак нульовий байт повинен бути надісланий навіть в інших типах сокета і навіть в операційних системах, яким не потрібен байт для надсилання для передачі облікових даних. Текстовий протокол, описаний у цьому документі, починається після єдиного нульового байта. Якщо перший байт, отриманий від клієнта, не є нульовим байтом, сервер може відключити цього клієнта.

Нуль-байт у будь-якому контексті, крім початкового байта, є помилкою; протокол призначений лише для ASCII.

Вхідні дані, надіслані разом з нульовим байтом, можуть використовуватися із механізмом SASL EXTERNAL.

Якщо ви напружите екземпляр dbus-daemon, ви можете побачити, що при підключенні до нього він перевіряє облікові дані користувача, що підключається:

$ 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

Отже, щоб відповісти на ваші запитання:

  1. Демон D-Bus використовує ваш ідентифікатор, підтверджений ядром, для підтвердження вашої особи. Використовуючи socatпідключення проксі, ви дозволяєте комусь підключатися до демона D-Bus за допомогою вашого UID.

  2. Якщо ви спробуєте підключитися безпосередньо до сокета з іншого UID, демон визнає, що UID, що підключається, не є UID, до якого слід дозволити з'єднання. Я вважаю, що типовим є те, що дозволений лише власний UID демона, але офіційно не підтвердив це. Ви можете дозволити іншим користувачам: див. Файли конфігурації в /etc/dbus-1/, а також man dbus-daemon.

  3. Це сервер D-Bus, який замінює старі / минулі файли cookie новими. Відповідно до розділу DBUS_COOKIE_SHA1 специфікації D-Bus, файл cookie зберігається разом із часом його створення, і сервер повинен видалити файли cookie, які він вважає занадто старими. Мабуть, термін експлуатації "може бути досить коротким".


Довідкова реалізація D-Bus спеціально не використовується SCM_CREDENTIALS. У Linux він SO_PEERCREDзамість цього використовує опцію socket.
Василь Фаронов

@VasiliyFaronov Ти маєш рацію - як цікаво! Крім того, схоже, що використання SCM_CREDENTIALSзавадило б такому простому проксі, оскільки він вимагає від відправника активно представляти свої облікові дані, тоді як SO_PEERCREDлише перевіряє, хто встановив з'єднання. Цікаво, чому вони зробили такий вибір.
Джендер

Мабуть, тому, що це "не вимагає співпраці з колегами", тому "це набагато менш тендітно" (з коментарів у dbus-sysdeps-unix.c).
Василь Фаронов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.