summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCosimo Alfarano <cosimo.alfarano@collabora.co.uk>2011-07-11 17:03:00 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2011-07-11 17:03:20 +0100
commita940e7b1d1b6b832e2ec732a11f495240156fb31 (patch)
tree55ddc85e3f8b7b9cc4858ab9029ec4ffa96d4c93
parent0ecd0a02b993685a456da58c5c03e2d3bab17d67 (diff)
Do not allow eavedropping unless rule owner explicitely declare it
Adds "eavesdrop=true" as a match rule, meaning that the owner intend to eavedrop. Otherwise the owner will receive only broadcasted messages and the ones meant to be delivered to it. [plus a typo fix in an error message -smcv] Bug: https://bugs.freedesktop.org/show_bug.cgi?id=37890 Bug-NB: NB#269748 Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
-rw-r--r--bus/signals.c93
-rw-r--r--bus/signals.h25
2 files changed, 110 insertions, 8 deletions
diff --git a/bus/signals.c b/bus/signals.c
index 62881b57..28506d3f 100644
--- a/bus/signals.c
+++ b/bus/signals.c
@@ -215,6 +215,20 @@ match_rule_to_string (BusMatchRule *rule)
goto nomem;
}
+ if (rule->flags & BUS_MATCH_CLIENT_IS_EAVESDROPPING)
+ {
+ if (_dbus_string_get_length (&str) > 0)
+ {
+ if (!_dbus_string_append (&str, ","))
+ goto nomem;
+ }
+
+ if (!_dbus_string_append_printf (&str, "eavesdrop='%s'",
+ (rule->flags & BUS_MATCH_CLIENT_IS_EAVESDROPPING) ?
+ "true" : "false"))
+ goto nomem;
+ }
+
if (rule->flags & BUS_MATCH_ARGS)
{
int i;
@@ -354,6 +368,16 @@ bus_match_rule_set_destination (BusMatchRule *rule,
return TRUE;
}
+void
+bus_match_rule_set_client_is_eavesdropping (BusMatchRule *rule,
+ dbus_bool_t is_eavesdropping)
+{
+ if (is_eavesdropping)
+ rule->flags |= BUS_MATCH_CLIENT_IS_EAVESDROPPING;
+ else
+ rule->flags &= ~(BUS_MATCH_CLIENT_IS_EAVESDROPPING);
+}
+
dbus_bool_t
bus_match_rule_set_path (BusMatchRule *rule,
const char *path,
@@ -1030,6 +1054,31 @@ bus_match_rule_parse (DBusConnection *matches_go_to,
goto failed;
}
}
+ else if (strcmp (key, "eavesdrop") == 0)
+ {
+ /* do not detect "eavesdrop" being used more than once in rule:
+ * 1) it's not possible, it's only in the flags
+ * 2) it might be used twice to disable eavesdropping when it's
+ * automatically added (eg dbus-monitor/bustle) */
+
+ /* we accept only "true|false" as possible values */
+ if ((strcmp (value, "true") == 0))
+ {
+ bus_match_rule_set_client_is_eavesdropping (rule, TRUE);
+ }
+ else if (strcmp (value, "false") == 0)
+ {
+ bus_match_rule_set_client_is_eavesdropping (rule, FALSE);
+ }
+ else
+ {
+ dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
+ "eavesdrop='%s' is invalid, "
+ "it should be 'true' or 'false'\n",
+ value);
+ goto failed;
+ }
+ }
else if (strncmp (key, "arg", 3) == 0)
{
if (!bus_match_rule_parse_arg_match (rule, key, &tmp_str, error))
@@ -1352,6 +1401,9 @@ match_rule_equal (BusMatchRule *a,
strcmp (a->destination, b->destination) != 0)
return FALSE;
+ /* we already compared the value of flags, and
+ * BUS_MATCH_CLIENT_IS_EAVESDROPPING does not have another struct member */
+
if (a->flags & BUS_MATCH_ARGS)
{
int i;
@@ -1619,6 +1671,7 @@ match_rule_matches (BusMatchRule *rule,
DBusMessage *message,
BusMatchFlags already_matched)
{
+ dbus_bool_t wants_to_eavesdrop = FALSE;
int flags;
/* All features of the match rule are AND'd together,
@@ -1633,6 +1686,9 @@ match_rule_matches (BusMatchRule *rule,
/* Don't bother re-matching features we've already checked implicitly. */
flags = rule->flags & (~already_matched);
+ if (flags & BUS_MATCH_CLIENT_IS_EAVESDROPPING)
+ wants_to_eavesdrop = TRUE;
+
if (flags & BUS_MATCH_MESSAGE_TYPE)
{
_dbus_assert (rule->message_type != DBUS_MESSAGE_TYPE_INVALID);
@@ -1686,6 +1742,24 @@ match_rule_matches (BusMatchRule *rule,
}
}
+ /* Note: this part is relevant for eavesdropper rules:
+ * Two cases:
+ * 1) rule has a destination to be matched
+ * (flag BUS_MATCH_DESTINATION present). Rule will match if:
+ * - rule->destination matches the addressed_recipient
+ * AND
+ * - wants_to_eavesdrop=TRUE
+ *
+ * Note: (the case in which addressed_recipient is the actual rule owner
+ * is handled elsewere in dispatch.c:bus_dispatch_matches().
+ *
+ * 2) rule has no destination. Rule will match if:
+ * - message has no specified destination (ie broadcasts)
+ * (Note: this will rule out unicast method calls and unicast signals,
+ * fixing FDO#269748)
+ * OR
+ * - wants_to_eavesdrop=TRUE (destination-catch-all situation)
+ */
if (flags & BUS_MATCH_DESTINATION)
{
const char *destination;
@@ -1694,6 +1768,12 @@ match_rule_matches (BusMatchRule *rule,
destination = dbus_message_get_destination (message);
if (destination == NULL)
+ /* broadcast, but this rule specified a destination: no match */
+ return FALSE;
+
+ /* rule owner does not intend to eavesdrop: we'll deliver only msgs
+ * directed to it, NOT MATCHING */
+ if (!wants_to_eavesdrop)
return FALSE;
if (addressed_recipient == NULL)
@@ -1707,6 +1787,19 @@ match_rule_matches (BusMatchRule *rule,
if (!connection_is_primary_owner (addressed_recipient, rule->destination))
return FALSE;
}
+ } else { /* no destination in rule */
+ dbus_bool_t msg_is_broadcast;
+
+ _dbus_assert (rule->destination == NULL);
+
+ msg_is_broadcast = (dbus_message_get_destination (message) == NULL);
+
+ if (!wants_to_eavesdrop && !msg_is_broadcast)
+ return FALSE;
+
+ /* if we are here rule owner intends to eavesdrop
+ * OR
+ * message is being broadcasted */
}
if (flags & BUS_MATCH_PATH)
diff --git a/bus/signals.h b/bus/signals.h
index 5b086f04..a71d2e45 100644
--- a/bus/signals.h
+++ b/bus/signals.h
@@ -31,14 +31,15 @@
typedef enum
{
- BUS_MATCH_MESSAGE_TYPE = 1 << 0,
- BUS_MATCH_INTERFACE = 1 << 1,
- BUS_MATCH_MEMBER = 1 << 2,
- BUS_MATCH_SENDER = 1 << 3,
- BUS_MATCH_DESTINATION = 1 << 4,
- BUS_MATCH_PATH = 1 << 5,
- BUS_MATCH_ARGS = 1 << 6,
- BUS_MATCH_PATH_NAMESPACE = 1 << 7
+ BUS_MATCH_MESSAGE_TYPE = 1 << 0,
+ BUS_MATCH_INTERFACE = 1 << 1,
+ BUS_MATCH_MEMBER = 1 << 2,
+ BUS_MATCH_SENDER = 1 << 3,
+ BUS_MATCH_DESTINATION = 1 << 4,
+ BUS_MATCH_PATH = 1 << 5,
+ BUS_MATCH_ARGS = 1 << 6,
+ BUS_MATCH_PATH_NAMESPACE = 1 << 7,
+ BUS_MATCH_CLIENT_IS_EAVESDROPPING = 1 << 8
} BusMatchFlags;
BusMatchRule* bus_match_rule_new (DBusConnection *matches_go_to);
@@ -64,6 +65,14 @@ dbus_bool_t bus_match_rule_set_arg (BusMatchRule *rule,
dbus_bool_t is_path,
dbus_bool_t is_namespace);
+/* Calling this methods a client declares that it is creating a rule which
+ * needs to eavesdrop (e.g., dbus-monitor), any other created rules not
+ * setting themselves as eavesdropping won't receive any message not addressed
+ * to them, when eavedrop is enabled in the policy. On the other hand, when
+ * eavedrop is not enabled in policy, this method won't have any effect */
+void bus_match_rule_set_client_is_eavesdropping (BusMatchRule *rule,
+ dbus_bool_t is_eavesdropping);
+
BusMatchRule* bus_match_rule_parse (DBusConnection *matches_go_to,
const DBusString *rule_text,
DBusError *error);