mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-09 04:58:02 +02:00
dbus-daemon: add send_destination_prefix support
This extends dbus-daemon with support for send_destination_prefix attribute in XML policies. It allows having policy rules for sending to bus names generated within namespaces defined by a prefix. The similar behaviour can be emulated by owning an additional name, not used for addressing messages, as described in https://lists.freedesktop.org/archives/dbus/2017-May/017188.html However, introducing send_destination_prefix creates possibility of communicating intentions in a more direct way, which is easier to understand. Signed-off-by: Adrian Szyndela <adrian.s@samsung.com> Change-Id: I0016ad93f1c16b7742fef5f45ebaf01b55694d3c
This commit is contained in:
parent
3486e0f48d
commit
055ff9e64a
5 changed files with 111 additions and 6 deletions
|
|
@ -1298,6 +1298,7 @@ append_rule_from_element (BusConfigParser *parser,
|
||||||
const char *send_member;
|
const char *send_member;
|
||||||
const char *send_error;
|
const char *send_error;
|
||||||
const char *send_destination;
|
const char *send_destination;
|
||||||
|
const char *send_destination_prefix;
|
||||||
const char *send_path;
|
const char *send_path;
|
||||||
const char *send_type;
|
const char *send_type;
|
||||||
const char *send_requested_reply;
|
const char *send_requested_reply;
|
||||||
|
|
@ -1341,6 +1342,7 @@ append_rule_from_element (BusConfigParser *parser,
|
||||||
"send_member", &send_member,
|
"send_member", &send_member,
|
||||||
"send_error", &send_error,
|
"send_error", &send_error,
|
||||||
"send_destination", &send_destination,
|
"send_destination", &send_destination,
|
||||||
|
"send_destination_prefix", &send_destination_prefix,
|
||||||
"send_path", &send_path,
|
"send_path", &send_path,
|
||||||
"send_type", &send_type,
|
"send_type", &send_type,
|
||||||
"send_broadcast", &send_broadcast,
|
"send_broadcast", &send_broadcast,
|
||||||
|
|
@ -1364,6 +1366,7 @@ append_rule_from_element (BusConfigParser *parser,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
any_send_attribute = (send_destination != NULL ||
|
any_send_attribute = (send_destination != NULL ||
|
||||||
|
send_destination_prefix != NULL ||
|
||||||
send_broadcast != NULL ||
|
send_broadcast != NULL ||
|
||||||
send_path != NULL ||
|
send_path != NULL ||
|
||||||
send_type != NULL ||
|
send_type != NULL ||
|
||||||
|
|
@ -1417,7 +1420,8 @@ append_rule_from_element (BusConfigParser *parser,
|
||||||
* interface + member
|
* interface + member
|
||||||
* error
|
* error
|
||||||
*
|
*
|
||||||
* base send_ can combine with send_destination, send_path, send_type, send_requested_reply, send_broadcast, eavesdrop
|
* base send_ can combine with send_destination, send_destination_prefix, send_path, send_type, send_requested_reply, send_broadcast, eavesdrop
|
||||||
|
* send_destination must not occur with send_destination_prefix
|
||||||
* base receive_ with receive_sender, receive_path, receive_type, receive_requested_reply, eavesdrop
|
* base receive_ with receive_sender, receive_path, receive_type, receive_requested_reply, eavesdrop
|
||||||
*
|
*
|
||||||
* user, group, own, own_prefix must occur alone
|
* user, group, own, own_prefix must occur alone
|
||||||
|
|
@ -1456,6 +1460,16 @@ append_rule_from_element (BusConfigParser *parser,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((send_destination != NULL) + (send_destination_prefix != NULL) > 1)
|
||||||
|
{
|
||||||
|
dbus_set_error (error, DBUS_ERROR_FAILED,
|
||||||
|
"Invalid combination of attributes on element <%s>: "
|
||||||
|
"send_destination cannot be combined with "
|
||||||
|
"send_destination_prefix",
|
||||||
|
element_name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if ((receive_member != NULL || receive_interface != NULL) &&
|
if ((receive_member != NULL || receive_interface != NULL) &&
|
||||||
receive_error != NULL)
|
receive_error != NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -1589,7 +1603,16 @@ append_rule_from_element (BusConfigParser *parser,
|
||||||
rule->d.send.interface = _dbus_strdup (send_interface);
|
rule->d.send.interface = _dbus_strdup (send_interface);
|
||||||
rule->d.send.member = _dbus_strdup (send_member);
|
rule->d.send.member = _dbus_strdup (send_member);
|
||||||
rule->d.send.error = _dbus_strdup (send_error);
|
rule->d.send.error = _dbus_strdup (send_error);
|
||||||
rule->d.send.destination = _dbus_strdup (send_destination);
|
if (send_destination)
|
||||||
|
{
|
||||||
|
rule->d.send.destination = _dbus_strdup (send_destination);
|
||||||
|
rule->d.send.destination_is_prefix = 0;
|
||||||
|
}
|
||||||
|
else if (send_destination_prefix)
|
||||||
|
{
|
||||||
|
rule->d.send.destination = _dbus_strdup (send_destination_prefix);
|
||||||
|
rule->d.send.destination_is_prefix = 1;
|
||||||
|
}
|
||||||
rule->d.send.max_fds = max_fds;
|
rule->d.send.max_fds = max_fds;
|
||||||
rule->d.send.min_fds = min_fds;
|
rule->d.send.min_fds = min_fds;
|
||||||
|
|
||||||
|
|
@ -1601,7 +1624,7 @@ append_rule_from_element (BusConfigParser *parser,
|
||||||
goto nomem;
|
goto nomem;
|
||||||
if (send_error && rule->d.send.error == NULL)
|
if (send_error && rule->d.send.error == NULL)
|
||||||
goto nomem;
|
goto nomem;
|
||||||
if (send_destination && rule->d.send.destination == NULL)
|
if ((send_destination || send_destination_prefix) && rule->d.send.destination == NULL)
|
||||||
goto nomem;
|
goto nomem;
|
||||||
}
|
}
|
||||||
else if (any_receive_attribute)
|
else if (any_receive_attribute)
|
||||||
|
|
|
||||||
|
|
@ -1446,6 +1446,46 @@ bus_connection_get_n_match_rules (DBusConnection *connection)
|
||||||
return d->n_match_rules;
|
return d->n_match_rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the connection owns any name with a given prefix,
|
||||||
|
* regardless of whether the type of ownership is primary or queued.
|
||||||
|
*
|
||||||
|
* @note A name matches to a prefix if it is equal to the prefix,
|
||||||
|
* or if it starts with the prefix followed by a dot. This is the same
|
||||||
|
* rule as the 'own_prefix' checking rule.
|
||||||
|
*
|
||||||
|
* @param connection the connection
|
||||||
|
* @param name_prefix the prefix
|
||||||
|
* @returns #TRUE if the connection owns at least one name with the prefix,
|
||||||
|
* regardless of the type of ownership
|
||||||
|
*/
|
||||||
|
dbus_bool_t
|
||||||
|
bus_connection_is_name_owner_by_prefix (DBusConnection *connection,
|
||||||
|
const char *name_prefix)
|
||||||
|
{
|
||||||
|
BusConnectionData *d;
|
||||||
|
DBusList *link;
|
||||||
|
|
||||||
|
d = BUS_CONNECTION_DATA (connection);
|
||||||
|
_dbus_assert (d != NULL);
|
||||||
|
|
||||||
|
link = _dbus_list_get_first_link (&d->services_owned);
|
||||||
|
while (link != NULL)
|
||||||
|
{
|
||||||
|
BusService *service = link->data;
|
||||||
|
DBusString str;
|
||||||
|
|
||||||
|
_dbus_string_init_const (&str, bus_service_get_name (service));
|
||||||
|
|
||||||
|
if (_dbus_string_starts_with_words_c_str (&str, name_prefix, '.'))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
link = _dbus_list_get_next_link (&d->services_owned, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bus_connection_add_owned_service_link (DBusConnection *connection,
|
bus_connection_add_owned_service_link (DBusConnection *connection,
|
||||||
DBusList *link)
|
DBusList *link)
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,10 @@ void bus_connection_send_oom_error (DBusConnection *connection,
|
||||||
void bus_connection_request_headers (DBusConnection *connection,
|
void bus_connection_request_headers (DBusConnection *connection,
|
||||||
BusExtraHeaders headers);
|
BusExtraHeaders headers);
|
||||||
|
|
||||||
|
/* called by policy.c */
|
||||||
|
dbus_bool_t bus_connection_is_name_owner_by_prefix (DBusConnection *connection,
|
||||||
|
const char *name_prefix);
|
||||||
|
|
||||||
/* called by signals.c */
|
/* called by signals.c */
|
||||||
dbus_bool_t bus_connection_add_match_rule (DBusConnection *connection,
|
dbus_bool_t bus_connection_add_match_rule (DBusConnection *connection,
|
||||||
BusMatchRule *rule);
|
BusMatchRule *rule);
|
||||||
|
|
|
||||||
43
bus/policy.c
43
bus/policy.c
|
|
@ -1018,7 +1018,7 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rule->d.send.destination != NULL)
|
if (rule->d.send.destination != NULL && !rule->d.send.destination_is_prefix)
|
||||||
{
|
{
|
||||||
/* receiver can be NULL for messages that are sent to the
|
/* receiver can be NULL for messages that are sent to the
|
||||||
* message bus itself, we check the strings in that case as
|
* message bus itself, we check the strings in that case as
|
||||||
|
|
@ -1044,9 +1044,9 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
|
||||||
{
|
{
|
||||||
DBusString str;
|
DBusString str;
|
||||||
BusService *service;
|
BusService *service;
|
||||||
|
|
||||||
_dbus_string_init_const (&str, rule->d.send.destination);
|
_dbus_string_init_const (&str, rule->d.send.destination);
|
||||||
|
|
||||||
service = bus_registry_lookup (registry, &str);
|
service = bus_registry_lookup (registry, &str);
|
||||||
if (service == NULL)
|
if (service == NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -1064,6 +1064,43 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rule->d.send.destination != NULL && rule->d.send.destination_is_prefix)
|
||||||
|
{
|
||||||
|
/* receiver can be NULL - the same as in !send.destination_is_prefix */
|
||||||
|
if (receiver == NULL)
|
||||||
|
{
|
||||||
|
const char *destination = dbus_message_get_destination (message);
|
||||||
|
DBusString dest_name;
|
||||||
|
|
||||||
|
if (destination == NULL)
|
||||||
|
{
|
||||||
|
_dbus_verbose (" (policy) skipping rule because message has no dest\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dbus_string_init_const (&dest_name, destination);
|
||||||
|
|
||||||
|
if (!_dbus_string_starts_with_words_c_str (&dest_name,
|
||||||
|
rule->d.send.destination,
|
||||||
|
'.'))
|
||||||
|
{
|
||||||
|
_dbus_verbose (" (policy) skipping rule because message dest doesn't start with %s\n",
|
||||||
|
rule->d.send.destination);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!bus_connection_is_name_owner_by_prefix (receiver,
|
||||||
|
rule->d.send.destination))
|
||||||
|
{
|
||||||
|
_dbus_verbose (" (policy) skipping rule because no dest with prefix %s is owned by receiver\n",
|
||||||
|
rule->d.send.destination);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rule->d.send.min_fds > 0 ||
|
if (rule->d.send.min_fds > 0 ||
|
||||||
rule->d.send.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
|
rule->d.send.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ struct BusPolicyRule
|
||||||
unsigned int requested_reply : 1;
|
unsigned int requested_reply : 1;
|
||||||
unsigned int log : 1;
|
unsigned int log : 1;
|
||||||
unsigned int broadcast : 2; /**< really a BusPolicyTristate */
|
unsigned int broadcast : 2; /**< really a BusPolicyTristate */
|
||||||
|
unsigned int destination_is_prefix : 1;
|
||||||
} send;
|
} send;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue