summaryrefslogtreecommitdiffstats
path: root/bus
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-09-06 21:12:11 +0000
committerHavoc Pennington <hp@redhat.com>2003-09-06 21:12:11 +0000
commit83e41dff82abe99e1a35e70ca0bb60672204ffcd (patch)
treeaddc05c0961d5f908ee98f5bac859cdcf107b6ce /bus
parent666fe95480c14d7cbf5143b1a4e1bf0558403d4d (diff)
2003-09-06 Havoc Pennington <hp@pobox.com>
* doc/dbus-specification.sgml: partial updates * bus/dbus-daemon-1.1.in: fix the config file docs for the zillionth time; hopefully I edited the right file this time. * bus/config-parser.c (append_rule_from_element): support send_type, send_path, receive_type, receive_path * bus/policy.c: add message type and path to the list of things that can be "firewalled"
Diffstat (limited to 'bus')
-rw-r--r--bus/config-parser.c119
-rw-r--r--bus/dbus-daemon-1.1.in61
-rw-r--r--bus/policy.c50
-rw-r--r--bus/policy.h6
4 files changed, 204 insertions, 32 deletions
diff --git a/bus/config-parser.c b/bus/config-parser.c
index 471c67d8..2a7d0752 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -808,6 +808,21 @@ start_busconfig_child (BusConfigParser *parser,
}
}
+static int
+message_type_from_string (const char *type_str)
+{
+ if (strcmp (type_str, "method_call") == 0)
+ return DBUS_MESSAGE_TYPE_METHOD_CALL;
+ if (strcmp (type_str, "method_return") == 0)
+ return DBUS_MESSAGE_TYPE_METHOD_RETURN;
+ else if (strcmp (type_str, "signal") == 0)
+ return DBUS_MESSAGE_TYPE_SIGNAL;
+ else if (strcmp (type_str, "error") == 0)
+ return DBUS_MESSAGE_TYPE_ERROR;
+ else
+ return DBUS_MESSAGE_TYPE_INVALID;
+}
+
static dbus_bool_t
append_rule_from_element (BusConfigParser *parser,
const char *element_name,
@@ -820,10 +835,14 @@ append_rule_from_element (BusConfigParser *parser,
const char *send_member;
const char *send_error;
const char *send_service;
+ const char *send_path;
+ const char *send_type;
const char *receive_interface;
const char *receive_member;
const char *receive_error;
const char *receive_service;
+ const char *receive_path;
+ const char *receive_type;
const char *own;
const char *user;
const char *group;
@@ -837,10 +856,14 @@ append_rule_from_element (BusConfigParser *parser,
"send_member", &send_member,
"send_error", &send_error,
"send_service", &send_service,
+ "send_path", &send_path,
+ "send_type", &send_type,
"receive_interface", &receive_interface,
"receive_member", &receive_member,
"receive_error", &receive_error,
"receive_service", &receive_service,
+ "receive_path", &receive_path,
+ "receive_type", &receive_type,
"own", &own,
"user", &user,
"group", &group,
@@ -848,7 +871,9 @@ append_rule_from_element (BusConfigParser *parser,
return FALSE;
if (!(send_interface || send_member || send_error || send_service ||
+ send_type || send_path ||
receive_interface || receive_member || receive_error || receive_service ||
+ receive_type || receive_path ||
own || user || group))
{
dbus_set_error (error, DBUS_ERROR_FAILED,
@@ -857,11 +882,11 @@ append_rule_from_element (BusConfigParser *parser,
return FALSE;
}
- if ((send_member && send_interface == NULL) ||
- (receive_member && receive_interface == NULL))
+ if ((send_member && (send_interface == NULL && send_path == NULL)) ||
+ (receive_member && (receive_interface == NULL && receive_path == NULL)))
{
dbus_set_error (error, DBUS_ERROR_FAILED,
- "On element <%s>, if you specify a member you must specify an interface",
+ "On element <%s>, if you specify a member you must specify an interface or a path. Keep in mind that not all messages have an interface field.",
element_name);
return FALSE;
}
@@ -869,12 +894,13 @@ append_rule_from_element (BusConfigParser *parser,
/* Allowed combinations of elements are:
*
* base, must be all send or all receive:
+ * nothing
* interface
* interface + member
* error
*
- * base send_ can combine with send_service,
- * base receive_ with receive_service
+ * base send_ can combine with send_service, send_path, send_type
+ * base receive_ with receive_service, receive_path, receive_type
*
* user, group, own must occur alone
*/
@@ -913,6 +939,22 @@ append_rule_from_element (BusConfigParser *parser,
(send_service && user) ||
(send_service && group)) ||
+ ((send_type && receive_interface) ||
+ (send_type && receive_member) ||
+ (send_type && receive_error) ||
+ (send_type && receive_service) ||
+ (send_type && own) ||
+ (send_type && user) ||
+ (send_type && group)) ||
+
+ ((send_path && receive_interface) ||
+ (send_path && receive_member) ||
+ (send_path && receive_error) ||
+ (send_path && receive_service) ||
+ (send_path && own) ||
+ (send_path && user) ||
+ (send_path && group)) ||
+
((receive_interface && receive_error) ||
(receive_interface && own) ||
(receive_interface && user) ||
@@ -938,7 +980,7 @@ append_rule_from_element (BusConfigParser *parser,
element_name);
return FALSE;
}
-
+
rule = NULL;
/* In BusPolicyRule, NULL represents wildcard.
@@ -946,11 +988,10 @@ append_rule_from_element (BusConfigParser *parser,
*/
#define IS_WILDCARD(str) ((str) && ((str)[0]) == '*' && ((str)[1]) == '\0')
- if (send_interface || send_member || send_error || send_service)
+ if (send_interface || send_member || send_error || send_service ||
+ send_path || send_type)
{
- rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow);
- if (rule == NULL)
- goto nomem;
+ int message_type;
if (IS_WILDCARD (send_interface))
send_interface = NULL;
@@ -960,11 +1001,36 @@ append_rule_from_element (BusConfigParser *parser,
send_error = NULL;
if (IS_WILDCARD (send_service))
send_service = NULL;
+ if (IS_WILDCARD (send_path))
+ send_path = NULL;
+ if (IS_WILDCARD (send_type))
+ send_type = NULL;
+
+ message_type = DBUS_MESSAGE_TYPE_INVALID;
+ if (send_type != NULL)
+ {
+ message_type = message_type_from_string (send_type);
+ if (message_type == DBUS_MESSAGE_TYPE_INVALID)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Bad message type \"%s\"",
+ send_type);
+ return FALSE;
+ }
+ }
+ rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow);
+ if (rule == NULL)
+ goto nomem;
+
+ rule->d.send.message_type = message_type;
+ rule->d.send.path = _dbus_strdup (send_path);
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_service);
+ if (send_path && rule->d.send.path == NULL)
+ goto nomem;
if (send_interface && rule->d.send.interface == NULL)
goto nomem;
if (send_member && rule->d.send.member == NULL)
@@ -974,11 +1040,10 @@ append_rule_from_element (BusConfigParser *parser,
if (send_service && rule->d.send.destination == NULL)
goto nomem;
}
- else if (receive_interface || receive_member || receive_error || receive_service)
+ else if (receive_interface || receive_member || receive_error || receive_service ||
+ receive_path || receive_type)
{
- rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, allow);
- if (rule == NULL)
- goto nomem;
+ int message_type;
if (IS_WILDCARD (receive_interface))
receive_interface = NULL;
@@ -988,11 +1053,37 @@ append_rule_from_element (BusConfigParser *parser,
receive_error = NULL;
if (IS_WILDCARD (receive_service))
receive_service = NULL;
+ if (IS_WILDCARD (receive_path))
+ receive_path = NULL;
+ if (IS_WILDCARD (receive_type))
+ receive_type = NULL;
+
+
+ message_type = DBUS_MESSAGE_TYPE_INVALID;
+ if (receive_type != NULL)
+ {
+ message_type = message_type_from_string (receive_type);
+ if (message_type == DBUS_MESSAGE_TYPE_INVALID)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Bad message type \"%s\"",
+ receive_type);
+ return FALSE;
+ }
+ }
+
+ rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, allow);
+ if (rule == NULL)
+ goto nomem;
+ rule->d.receive.message_type = message_type;
+ rule->d.receive.path = _dbus_strdup (receive_path);
rule->d.receive.interface = _dbus_strdup (receive_interface);
rule->d.receive.member = _dbus_strdup (receive_member);
rule->d.receive.error = _dbus_strdup (receive_error);
rule->d.receive.origin = _dbus_strdup (receive_service);
+ if (receive_path && rule->d.receive.path == NULL)
+ goto nomem;
if (receive_interface && rule->d.receive.interface == NULL)
goto nomem;
if (receive_member && rule->d.receive.member == NULL)
diff --git a/bus/dbus-daemon-1.1.in b/bus/dbus-daemon-1.1.in
index 73a88c90..ec915edd 100644
--- a/bus/dbus-daemon-1.1.in
+++ b/bus/dbus-daemon-1.1.in
@@ -333,11 +333,22 @@ in the config file.
A <deny> element appears below a <policy> element and prohibits
some action. The possible attributes of a <deny> element are:
.nf
- send="messagename"
+ send_interface="interface_name"
+ send_member="method_or_signal_name"
+ send_error="error_name"
+ send_service="service_name"
+ send_type="method_call|method_return|signal|error"
+ send_path="/path/name"
+
+ receive_interface="interface_name"
+ receive_member="method_or_signal_name"
+ receive_error="error_name"
+ receive_service="service_name"
+ receive_type="method_call|method_return|signal|error"
+ receive_path="/path/name"
+
receive="messagename"
own="servicename"
- send_to="servicename"
- receive_from="servicename"
user="username"
group="groupname"
.fi
@@ -345,11 +356,11 @@ some action. The possible attributes of a <deny> element are:
.PP
Examples:
.nf
- <deny send="org.freedesktop.System.Reboot"/>
- <deny receive="org.freedesktop.System.Reboot"/>
+ <deny send_interface="org.freedesktop.System" send_member="Reboot"/>
+ <deny receive_interface="org.freedesktop.System" receive_member="Reboot"/>
<deny own="org.freedesktop.System"/>
- <deny send_to="org.freedesktop.System"/>
- <deny receive_from="org.freedesktop.System"/>
+ <deny send_service="org.freedesktop.System"/>
+ <deny receive_service="org.freedesktop.System"/>
<deny user="john"/>
<deny group="enemies"/>
.fi
@@ -360,18 +371,22 @@ particular action. If it matches, the action is denied (unless later
rules in the config file allow it).
.PP
-send_to and receive_from mean that messages may not be sent to or
-received from the *owner* of the given service, not that they may not
-be sent *to that service name*. That is, if a connection owns services
-A, B, C, and sending to A is denied, sending to B or C will not work
-either.
+send_service and receive_service rules mean that messages may not be
+sent to or received from the *owner* of the given service, not that
+they may not be sent *to that service name*. That is, if a connection
+owns services A, B, C, and sending to A is denied, sending to B or C
+will not work either.
+
+.PP
+The other send_* and receive_* attributes are purely textual/by-value
+matches against the given field in the message header.
.PP
user and group denials mean that the given user or group may
not connect to the message bus.
.PP
-For "servicename" or "messagename" or "username" or "groupname"
+For "service_name", "username", "groupname", etc.
the character "*" can be substituted, meaning "any." Complex globs
like "foo.bar.*" aren't allowed for now because they'd be work to
implement and maybe encourage sloppy security anyway.
@@ -382,11 +397,21 @@ for a user or group; user/group denials can only be inside
context="default" or context="mandatory" policies.
.PP
-A single <deny> rule may specify both send and send_to, OR both
-receive and receive_from. In this case, the denial applies only if
-both attributes match the message being denied.
-e.g. <deny send="foo.bar" send_to="foo.blah"/> would deny
-messages of the given name AND to the given service.
+A single <deny> rule may specify combinations of attributes such as
+send_service and send_interface and send_type. In this case, the
+denial applies only if both attributes match the message being denied.
+e.g. <deny send_interface="foo.bar" send_service="foo.blah"/> would
+deny messages of the given interface AND to the given service.
+To get an OR effect you specify multiple <deny> rules.
+
+.PP
+You can't include both send_ and receive_ attributes on the same
+rule, since "whether the message can be sent" and "whether it can be
+received" are evaluated separately.
+
+.PP
+Be careful with send_interface/receive_interface, because the
+interface field in messages is optional.
.TP
.I "<allow>"
diff --git a/bus/policy.c b/bus/policy.c
index f7978c05..21d0b02e 100644
--- a/bus/policy.c
+++ b/bus/policy.c
@@ -52,7 +52,11 @@ bus_policy_rule_new (BusPolicyRuleType type,
rule->d.group.gid = DBUS_GID_UNSET;
break;
case BUS_POLICY_RULE_SEND:
+ rule->d.send.message_type = DBUS_MESSAGE_TYPE_INVALID;
+ break;
case BUS_POLICY_RULE_RECEIVE:
+ rule->d.receive.message_type = DBUS_MESSAGE_TYPE_INVALID;
+ break;
case BUS_POLICY_RULE_OWN:
break;
}
@@ -80,12 +84,14 @@ bus_policy_rule_unref (BusPolicyRule *rule)
switch (rule->type)
{
case BUS_POLICY_RULE_SEND:
+ dbus_free (rule->d.send.path);
dbus_free (rule->d.send.interface);
dbus_free (rule->d.send.member);
dbus_free (rule->d.send.error);
dbus_free (rule->d.send.destination);
break;
case BUS_POLICY_RULE_RECEIVE:
+ dbus_free (rule->d.receive.path);
dbus_free (rule->d.receive.interface);
dbus_free (rule->d.receive.member);
dbus_free (rule->d.receive.error);
@@ -717,6 +723,8 @@ bus_client_policy_optimize (BusClientPolicy *policy)
{
case BUS_POLICY_RULE_SEND:
remove_preceding =
+ rule->d.send.message_type == DBUS_MESSAGE_TYPE_INVALID &&
+ rule->d.send.path == NULL &&
rule->d.send.interface == NULL &&
rule->d.send.member == NULL &&
rule->d.send.error == NULL &&
@@ -724,6 +732,8 @@ bus_client_policy_optimize (BusClientPolicy *policy)
break;
case BUS_POLICY_RULE_RECEIVE:
remove_preceding =
+ rule->d.receive.message_type == DBUS_MESSAGE_TYPE_INVALID &&
+ rule->d.receive.path == NULL &&
rule->d.receive.interface == NULL &&
rule->d.receive.member == NULL &&
rule->d.receive.error == NULL &&
@@ -799,6 +809,26 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
continue;
}
+ if (rule->d.send.message_type != DBUS_MESSAGE_TYPE_INVALID)
+ {
+ if (dbus_message_get_type (message) != rule->d.send.message_type)
+ {
+ _dbus_verbose (" (policy) skipping rule for different message type\n");
+ continue;
+ }
+ }
+
+ if (rule->d.send.path != NULL)
+ {
+ if (dbus_message_get_path (message) != NULL &&
+ strcmp (dbus_message_get_path (message),
+ rule->d.send.path) != 0)
+ {
+ _dbus_verbose (" (policy) skipping rule for different path\n");
+ continue;
+ }
+ }
+
if (rule->d.send.interface != NULL)
{
if (dbus_message_get_interface (message) != NULL &&
@@ -911,6 +941,26 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
_dbus_verbose (" (policy) skipping non-receive rule\n");
continue;
}
+
+ if (rule->d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID)
+ {
+ if (dbus_message_get_type (message) != rule->d.receive.message_type)
+ {
+ _dbus_verbose (" (policy) skipping rule for different message type\n");
+ continue;
+ }
+ }
+
+ if (rule->d.receive.path != NULL)
+ {
+ if (dbus_message_get_path (message) != NULL &&
+ strcmp (dbus_message_get_path (message),
+ rule->d.receive.path) != 0)
+ {
+ _dbus_verbose (" (policy) skipping rule for different path\n");
+ continue;
+ }
+ }
if (rule->d.receive.interface != NULL)
{
diff --git a/bus/policy.h b/bus/policy.h
index 2aa69aaf..5824816c 100644
--- a/bus/policy.h
+++ b/bus/policy.h
@@ -54,7 +54,10 @@ struct BusPolicyRule
{
struct
{
+ /* message type can be DBUS_MESSAGE_TYPE_INVALID meaning "any" */
+ int message_type;
/* any of these can be NULL meaning "any" */
+ char *path;
char *interface;
char *member;
char *error;
@@ -63,7 +66,10 @@ struct BusPolicyRule
struct
{
+ /* message type can be DBUS_MESSAGE_TYPE_INVALID meaning "any" */
+ int message_type;
/* any of these can be NULL meaning "any" */
+ char *path;
char *interface;
char *member;
char *error;