From ebf45fc946d57831ab33c22cf0201792bf0adc17 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 21 Oct 2015 19:53:12 +0100 Subject: [PATCH 1/2] Add send_broadcast as an attribute of and elements only matches broadcasts, which are signals with a NULL destination. There was previously no way for the policy language to express "NULL destination", only "any destination". only matches non-broadcasts, which are non-signals or signals with a non-NULL destination. There was previously no way for the policy language to express "any non-NULL destination", only "any destination". Bug: https://bugs.freedesktop.org/show_bug.cgi?id=92853 Signed-off-by: Simon McVittie --- bus/config-parser.c | 33 +++++++++++++++++++++++++++++++-- bus/policy.c | 22 +++++++++++++++++++++- bus/policy.h | 8 ++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/bus/config-parser.c b/bus/config-parser.c index adba69e..02d3c8c 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -1182,6 +1182,7 @@ append_rule_from_element (BusConfigParser *parser, const char *send_destination; const char *send_path; const char *send_type; + const char *send_broadcast; const char *receive_interface; const char *receive_member; const char *receive_error; @@ -1208,6 +1209,7 @@ append_rule_from_element (BusConfigParser *parser, "send_destination", &send_destination, "send_path", &send_path, "send_type", &send_type, + "send_broadcast", &send_broadcast, "receive_interface", &receive_interface, "receive_member", &receive_member, "receive_error", &receive_error, @@ -1226,7 +1228,7 @@ append_rule_from_element (BusConfigParser *parser, return FALSE; if (!(send_interface || send_member || send_error || send_destination || - send_type || send_path || + send_type || send_path || send_broadcast || receive_interface || receive_member || receive_error || receive_sender || receive_type || receive_path || eavesdrop || send_requested_reply || receive_requested_reply || @@ -1319,6 +1321,15 @@ append_rule_from_element (BusConfigParser *parser, user || group)) || + (send_broadcast && (receive_interface || + receive_member || + receive_error || + receive_sender || + receive_requested_reply || + own || own_prefix || + user || + group)) || + (send_requested_reply && (receive_interface || receive_member || receive_error || @@ -1370,7 +1381,7 @@ append_rule_from_element (BusConfigParser *parser, #define IS_WILDCARD(str) ((str) && ((str)[0]) == '*' && ((str)[1]) == '\0') if (send_interface || send_member || send_error || send_destination || - send_path || send_type || send_requested_reply) + send_path || send_type || send_requested_reply || send_broadcast) { int message_type; @@ -1410,6 +1421,16 @@ append_rule_from_element (BusConfigParser *parser, return FALSE; } + if (send_broadcast && + !(strcmp (send_broadcast, "true") == 0 || + strcmp (send_broadcast, "false") == 0)) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Bad value \"%s\" for %s attribute, must be true or false", + send_broadcast, "send_broadcast"); + return FALSE; + } + if (send_requested_reply && !(strcmp (send_requested_reply, "true") == 0 || strcmp (send_requested_reply, "false") == 0)) @@ -1433,6 +1454,14 @@ append_rule_from_element (BusConfigParser *parser, if (send_requested_reply) rule->d.send.requested_reply = (strcmp (send_requested_reply, "true") == 0); + if (send_broadcast) + { + if (strcmp (send_broadcast, "true") == 0) + rule->d.send.broadcast = BUS_POLICY_TRISTATE_TRUE; + else + rule->d.send.broadcast = BUS_POLICY_TRISTATE_FALSE; + } + rule->d.send.message_type = message_type; rule->d.send.path = _dbus_strdup (send_path); rule->d.send.interface = _dbus_strdup (send_interface); diff --git a/bus/policy.c b/bus/policy.c index 082f385..99ad698 100644 --- a/bus/policy.c +++ b/bus/policy.c @@ -986,7 +986,27 @@ bus_client_policy_check_can_send (BusClientPolicy *policy, continue; } } - + + if (rule->d.send.broadcast != BUS_POLICY_TRISTATE_ANY) + { + if (dbus_message_get_destination (message) == NULL && + dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL) + { + /* it's a broadcast */ + if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_FALSE) + { + _dbus_verbose (" (policy) skipping rule because message is a broadcast\n"); + continue; + } + } + /* else it isn't a broadcast: there is some destination */ + else if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_TRUE) + { + _dbus_verbose (" (policy) skipping rule because message is not a broadcast\n"); + continue; + } + } + if (rule->d.send.destination != NULL) { /* receiver can be NULL for messages that are sent to the diff --git a/bus/policy.h b/bus/policy.h index d1d3e72..c5275a7 100644 --- a/bus/policy.h +++ b/bus/policy.h @@ -39,6 +39,13 @@ typedef enum BUS_POLICY_RULE_GROUP } BusPolicyRuleType; +typedef enum +{ + BUS_POLICY_TRISTATE_ANY = 0, + BUS_POLICY_TRISTATE_FALSE, + BUS_POLICY_TRISTATE_TRUE +} BusPolicyTristate; + /** determines whether the rule affects a connection, or some global item */ #define BUS_POLICY_RULE_IS_PER_CLIENT(rule) (!((rule)->type == BUS_POLICY_RULE_USER || \ (rule)->type == BUS_POLICY_RULE_GROUP)) @@ -66,6 +73,7 @@ struct BusPolicyRule unsigned int eavesdrop : 1; unsigned int requested_reply : 1; unsigned int log : 1; + unsigned int broadcast : 2; /**< really a BusPolicyTristate */ } send; struct -- 2.6.2