mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-05 15:47:59 +02:00
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>
This commit is contained in:
parent
0ecd0a02b9
commit
a940e7b1d1
2 changed files with 110 additions and 8 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue