diff options
author | Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> | 2011-07-11 17:03:00 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2011-07-11 17:03:20 +0100 |
commit | a940e7b1d1b6b832e2ec732a11f495240156fb31 (patch) | |
tree | 55ddc85e3f8b7b9cc4858ab9029ec4ffa96d4c93 | |
parent | 0ecd0a02b993685a456da58c5c03e2d3bab17d67 (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.c | 93 | ||||
-rw-r--r-- | bus/signals.h | 25 |
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); |