I’m writing a chatbot that (besides other features) allows the admin to send custom message to instant message apps via a DBus call. The chatbot creates a service org.cdpa.cdpachan
on the system bus, exposes the interface org.cdpa.bot_send_message
and the method send_message
. I’m able to get any user to register the service name with the configuration file /usr/share/dbus-1/system.d/org.cdpa.cdpachan.conf
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> <policy context="default"> <allow own="org.cdpa.cdpachan"/> <allow send_destination="org.cdpa.bot_send_message"/> </policy> </busconfig>
But sending DBus method calls to my chatbot fails even when every user is allowed to send a message to it. And the error message isn’t very helpful.
❯ dbus-send --system --print-reply --dest=org.cdpa.cdpachan /org/cdpa/cdpachan org.cdpa.bot_send_message.send_message string:"foobar" Error org.freedesktop.DBus.Error.AccessDenied: Rejected send message, 1 matched rules; type="method_call", sender=":1.45410" (uid=1000 pid=741940 comm="dbus-send --system --print-reply --dest=org.cdpa.c") interface="org.cdpa.bot_send_message" member="send_message" error name="(unset)" requested_reply="0" destination="org.cdpa.cdpachan" (uid=1000 pid=741936 comm="./main ")
Why is this happning? How can I solve it? A minimal mock service looks like this (using sdbus-c++
)
#include <string> #include <iostream> #include <sdbus-c++/sdbus-c++.h> sdbus::IObject* g_message_sender{}; bool on_send_message(const std::string& msg) { std::cout << "Someone asked me to send a message!!!" << std::endl; g_message_sender->emitSignal("message_sent").onInterface("org.cdpa.bot_send_message").withArguments(true); return true; } int main() { const std::string service_name = "org.cdpa.cdpachan"; auto connection = sdbus::createSystemBusConnection(service_name); const std::string object_path = "/org/cdpa/cdpachan"; auto message_sender = sdbus::createObject(*connection, object_path); g_message_sender = message_sender.get(); const std::string interface_name = "org.cdpa.bot_send_message"; message_sender->registerMethod("send_message").onInterface(interface_name).implementedAs(&on_send_message); message_sender->registerSignal("message_sent").onInterface(interface_name).withParameters<bool>(); message_sender->finishRegistration(); connection->enterEventLoop(); }
Thanks
Edit: Note: If I make my chatbot live on the session bus. Then there’s no issue at all. But that doesn’t fit my use case.
Advertisement
Answer
<allow send_destination="org.cdpa.bot_send_message"/>
this looks like your interface name. You probably want something like:
<allow send_destination="org.cdpa.cdpachan" send_interface="org.cdpa.bot_send_message"/>