summaryrefslogtreecommitdiff
path: root/bus
diff options
context:
space:
mode:
authorSimon McVittie <smcv@collabora.com>2019-05-30 14:49:09 +0000
committerSimon McVittie <smcv@collabora.com>2019-05-30 14:49:09 +0000
commit463ecfb4fde5d7d30ce860f33dea596aa44d299e (patch)
treeaf28fd3c482a2df63446da88bb8734a18f418a7a /bus
parentedece0274b37472d7da6db37e8afd9100d18564b (diff)
parentdcbab02613d38db4aad5a23ce7ac2505540078d1 (diff)
downloaddbus-463ecfb4fde5d7d30ce860f33dea596aa44d299e.tar.gz
Merge branch 'send_destination_prefix' into 'master'
Send destination prefix See merge request dbus/dbus!85
Diffstat (limited to 'bus')
-rw-r--r--bus/config-parser.c29
-rw-r--r--bus/connection.c40
-rw-r--r--bus/connection.h4
-rw-r--r--bus/policy.c55
-rw-r--r--bus/policy.h1
5 files changed, 114 insertions, 15 deletions
diff --git a/bus/config-parser.c b/bus/config-parser.c
index 4e62c342..a47b8a58 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -1298,6 +1298,7 @@ append_rule_from_element (BusConfigParser *parser,
const char *send_member;
const char *send_error;
const char *send_destination;
+ const char *send_destination_prefix;
const char *send_path;
const char *send_type;
const char *send_requested_reply;
@@ -1341,6 +1342,7 @@ append_rule_from_element (BusConfigParser *parser,
"send_member", &send_member,
"send_error", &send_error,
"send_destination", &send_destination,
+ "send_destination_prefix", &send_destination_prefix,
"send_path", &send_path,
"send_type", &send_type,
"send_broadcast", &send_broadcast,
@@ -1364,6 +1366,7 @@ append_rule_from_element (BusConfigParser *parser,
return FALSE;
any_send_attribute = (send_destination != NULL ||
+ send_destination_prefix != NULL ||
send_broadcast != NULL ||
send_path != NULL ||
send_type != NULL ||
@@ -1417,7 +1420,8 @@ append_rule_from_element (BusConfigParser *parser,
* interface + member
* 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
*
* user, group, own, own_prefix must occur alone
@@ -1456,6 +1460,16 @@ append_rule_from_element (BusConfigParser *parser,
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) &&
receive_error != NULL)
{
@@ -1589,7 +1603,16 @@ append_rule_from_element (BusConfigParser *parser,
rule->d.send.interface = _dbus_strdup (send_interface);
rule->d.send.member = _dbus_strdup (send_member);
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.min_fds = min_fds;
@@ -1601,7 +1624,7 @@ append_rule_from_element (BusConfigParser *parser,
goto nomem;
if (send_error && rule->d.send.error == NULL)
goto nomem;
- if (send_destination && rule->d.send.destination == NULL)
+ if ((send_destination || send_destination_prefix) && rule->d.send.destination == NULL)
goto nomem;
}
else if (any_receive_attribute)
diff --git a/bus/connection.c b/bus/connection.c
index 3af980d0..5943841d 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -1446,6 +1446,46 @@ bus_connection_get_n_match_rules (DBusConnection *connection)
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
bus_connection_add_owned_service_link (DBusConnection *connection,
DBusList *link)
diff --git a/bus/connection.h b/bus/connection.h
index 949a2231..912638c0 100644
--- a/bus/connection.h
+++ b/bus/connection.h
@@ -82,6 +82,10 @@ void bus_connection_send_oom_error (DBusConnection *connection,
void bus_connection_request_headers (DBusConnection *connection,
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 */
dbus_bool_t bus_connection_add_match_rule (DBusConnection *connection,
BusMatchRule *rule);
diff --git a/bus/policy.c b/bus/policy.c
index c87bfecf..feb1156e 100644
--- a/bus/policy.c
+++ b/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
* 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;
BusService *service;
-
+
_dbus_string_init_const (&str, rule->d.send.destination);
-
+
service = bus_registry_lookup (registry, &str);
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 ||
rule->d.send.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
{
@@ -1341,15 +1378,9 @@ bus_rules_check_can_own (DBusList *rules,
}
else if (rule->d.own.prefix)
{
- const char *data;
- char next_char;
- if (!_dbus_string_starts_with_c_str (service_name,
- rule->d.own.service_name))
- continue;
-
- data = _dbus_string_get_const_data (service_name);
- next_char = data[strlen (rule->d.own.service_name)];
- if (next_char != '\0' && next_char != '.')
+ if (!_dbus_string_starts_with_words_c_str (service_name,
+ rule->d.own.service_name,
+ '.'))
continue;
}
diff --git a/bus/policy.h b/bus/policy.h
index 308eaf86..df59d090 100644
--- a/bus/policy.h
+++ b/bus/policy.h
@@ -76,6 +76,7 @@ struct BusPolicyRule
unsigned int requested_reply : 1;
unsigned int log : 1;
unsigned int broadcast : 2; /**< really a BusPolicyTristate */
+ unsigned int destination_is_prefix : 1;
} send;
struct