DBus 拒绝向系统总线上的自定义服务发送消息
DBus rejecting to send message to a custom service on the system bus
我正在编写一个聊天机器人(除其他功能外)允许管理员通过 DBus 调用将自定义消息发送到即时消息应用程序。聊天机器人在系统总线上创建一个服务 org.cdpa.cdpachan
,公开接口 org.cdpa.bot_send_message
和方法 send_message
。我可以让任何用户使用配置文件注册服务名称 /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>
但是即使允许每个用户向它发送消息,向我的聊天机器人发送 DBus 方法调用也会失败。而且错误消息不是很有帮助。
❯ 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 ")
为什么会这样?我该如何解决?最小的模拟服务如下所示(使用 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();
}
谢谢
编辑: 注意:如果我让我的聊天机器人在会话总线上运行。那么就完全没有问题了。但这不适合我的用例。
<allow send_destination="org.cdpa.bot_send_message"/>
这看起来像您的界面名称。你可能想要这样的东西:
<allow send_destination="org.cdpa.cdpachan"
send_interface="org.cdpa.bot_send_message"/>
我正在编写一个聊天机器人(除其他功能外)允许管理员通过 DBus 调用将自定义消息发送到即时消息应用程序。聊天机器人在系统总线上创建一个服务 org.cdpa.cdpachan
,公开接口 org.cdpa.bot_send_message
和方法 send_message
。我可以让任何用户使用配置文件注册服务名称 /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>
但是即使允许每个用户向它发送消息,向我的聊天机器人发送 DBus 方法调用也会失败。而且错误消息不是很有帮助。
❯ 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 ")
为什么会这样?我该如何解决?最小的模拟服务如下所示(使用 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();
}
谢谢
编辑: 注意:如果我让我的聊天机器人在会话总线上运行。那么就完全没有问题了。但这不适合我的用例。
<allow send_destination="org.cdpa.bot_send_message"/>
这看起来像您的界面名称。你可能想要这样的东西:
<allow send_destination="org.cdpa.cdpachan"
send_interface="org.cdpa.bot_send_message"/>