Xác thực và ủy quyền D-Bus


13

Tôi đang cố gắng thiết lập quyền truy cập từ xa vào D-Bus và tôi không hiểu cách xác thực và ủy quyền (không) hoạt động.

Tôi có một máy chủ D-Bus lắng nghe trên một ổ cắm trừu tượng.

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

Tôi chạy dbus-monitorđể xem những gì đang xảy ra. Trường hợp thử nghiệm của tôi là notify-send hello, hoạt động khi được thực thi từ máy cục bộ.

Từ một tài khoản khác trên cùng một máy, tôi không thể kết nối với xe buýt đó.

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

Sau khi duyệt đặc tả D-Bus , tôi đã sao chép ~/.dbus-keyrings/org_freedesktop_generalsang tài khoản khác, nhưng không được.

Tôi cố gắng chuyển các ổ cắm D-Bus trên TCP, lấy cảm hứng từ Schedar 's truy cập D-Bus từ xa sử dụng socat .

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

Tôi có thể kết nối với ổ cắm TCP từ tài khoản của mình.

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

Nhưng không phải từ tài khoản khác, dbus-monitorcũng không phải với notify-send. Thông báo lỗi tương tự dbus-monitornhư trên với ổ cắm trừu tượng; notify-sendbây giờ phát ra một dấu vết:

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 tiết lộ rằng phiên bản notify-sendnày không cố đọc tệp cookie, vì vậy tôi hiểu tại sao nó không thể kết nối.

Tôi cũng đã thử SSH vào một máy khác và chuyển tiếp kết nối TCP.

ssh -R 8004:localhost:8004 remotehost

Đáng ngạc nhiên, dbus-monitorhoạt động mà không có một tập tin cookie! Tôi có thể xem lưu lượng D-Bus từ máy chủ từ xa. Tôi thấy một thông báo về việc nghe lén trong dbus-monitortrường hợp địa phương của tôi .

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"

Nếu tôi chạy notify-sendtrên máy cục bộ, dbus-monitortrên máy chủ từ xa sẽ thấy thông báo. Nó chắc chắn đã đạt đến một mức độ truy cập cần phải xác thực.

notify-sendphàn nàn về việc không tìm thấy một cookie. Sau khi sao chép tệp cookie, notify-sendhoạt động từ máy từ xa.

Máy cục bộ chạy Debian wheezy. Máy từ xa chạy FreeBSD 10.1.

Tôi không hiểu cách thức xác thực và ủy quyền của D-Bus.

  1. Tại sao tôi có thể nghe lén, theo như tôi có thể nói, không có thông tin xác thực từ máy từ xa? Tôi sẽ phơi bày điều gì khi chuyển tiếp D-Bus sang kết nối TCP? Tại sao ủy quyền cho dbus-monitornotify-sendkhác nhau?
  2. Tại sao tôi không thể nghe lén từ một tài khoản khác trên cùng một máy, cho dù qua ổ cắm trừu tượng hay qua kết nối TCP?
  3. Tôi nhận thấy rằng tệp cookie thay đổi cứ sau vài phút (tôi đã không biết liệu nó có đều đặn hay không). Tại sao?

(Tôi biết rằng tôi có thể khởi chạy một trình nền D-Bus nghe trên TCP. Đó không phải là mục đích của câu hỏi của tôi, tôi muốn hiểu tại sao những gì tôi đã làm và không hoạt động.)

Câu trả lời:


7

D-Bus không sử dụng tệp cookie ma thuật ở đây; nó chuyển thông tin đăng nhập qua ổ cắm tên miền UNIX ( SCM_CREDENTIALS).

Tệp cookie ma thuật chỉ là một trong một số cơ chế xác thực D-Bus. D-Bus triển khai giao diện SASL -compliant (xem RFC4422 ) để hỗ trợ một loạt các cơ chế xác thực. Một trong những cơ chế này được gọi là auth "EXTERNAL" và điều đó có nghĩa là chính kênh vận chuyển nên được sử dụng để đảm bảo xác thực. Ít nhất là trong trường hợp D-Bus qua các socket UNIX, đây dường như là cơ chế xác thực đầu tiên được thử.

Từ thông số D-Bus:

Thông tin đặc biệt thông qua byte nul

Ngay sau khi kết nối với máy chủ, máy khách phải gửi một byte nul duy nhất. Byte này có thể đi kèm với thông tin thông tin đăng nhập trên một số hệ điều hành sử dụng sendmsg () với SCM_CREDS hoặc SCM_CREDENTIALS để truyền thông tin xác thực qua ổ cắm tên miền UNIX. Tuy nhiên, byte nul phải được gửi ngay cả trên các loại ổ cắm khác và ngay cả trên các hệ điều hành không yêu cầu byte được gửi để truyền thông tin đăng nhập. Giao thức văn bản được mô tả trong tài liệu này bắt đầu sau một byte nul duy nhất. Nếu byte đầu tiên nhận được từ máy khách không phải là byte thứ cấp, máy chủ có thể ngắt kết nối máy khách đó.

Một byte nul trong bất kỳ bối cảnh nào khác với byte ban đầu là một lỗi; giao thức chỉ có ASCII.

Thông tin đăng nhập được gửi cùng với byte nul có thể được sử dụng với cơ chế SASL EXTERNAL.

Nếu bạn truy cập một thể hiện của dbus-daemon, bạn có thể thấy rằng khi bạn kết nối với nó, nó sẽ kiểm tra thông tin đăng nhập của người dùng kết nối:

$ 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

Vì vậy, để trả lời câu hỏi của bạn:

  1. Trình nền D-Bus đang sử dụng ID người dùng được xác minh hạt nhân của bạn để xác minh danh tính của bạn. Bằng cách sử dụng socatkết nối proxy, bạn cho phép mọi người kết nối với trình nền D-Bus bằng UID của bạn.

  2. Nếu bạn cố gắng kết nối trực tiếp với ổ cắm từ một UID khác, daemon nhận ra rằng UID kết nối không phải là UID được cho là được phép kết nối. Tôi tin rằng mặc định là chỉ cho phép UID của daemon, nhưng chưa chính thức xác minh điều đó. Bạn có thể cho phép người dùng khác, mặc dù: xem các tập tin cấu hình trong /etc/dbus-1/, và cũng có thể man dbus-daemon.

  3. Đây là máy chủ D-Bus thay thế cookie cũ / hết hạn bằng cookie mới. Theo phần DBUS_COOKIE_SHA1 của thông số D-Bus, một cookie được lưu trữ cùng với thời gian tạo và máy chủ có nghĩa vụ xóa cookie mà nó quyết định quá cũ. Rõ ràng thời gian tồn tại "có thể khá ngắn".


Việc triển khai tham chiếu của D-Bus không sử dụng SCM_CREDENTIALScụ thể. Trên Linux, nó sử dụng SO_PEERCREDtùy chọn ổ cắm thay thế.
Vasiliy Faronov

@VasiliyFaronov Bạn nói đúng - thật thú vị! Hơn nữa, có vẻ như việc sử dụng SCM_CREDENTIALSsẽ ngăn chặn một proxy đơn giản như vậy, vì nó yêu cầu người gửi phải chủ động trình bày thông tin đăng nhập của mình, trong khi SO_PEERCREDchỉ kiểm tra xem ai đã thực hiện kết nối. Tôi tự hỏi tại sao họ lại đưa ra lựa chọn này.
Jander

Rõ ràng là vì nó không yêu cầu sự hợp tác của đồng nghiệp, nên vì vậy, đây là một phần mềm mỏng manh hơn (từ các bình luận trong dbus-sysdeps-unix.c).
Vasiliy Faronov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.