From 83e41dff82abe99e1a35e70ca0bb60672204ffcd Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sat, 6 Sep 2003 21:12:11 +0000 Subject: 2003-09-06 Havoc Pennington * 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" --- ChangeLog | 13 +++ bus/config-parser.c | 119 +++++++++++++++++++++++---- bus/dbus-daemon-1.1.in | 61 ++++++++++---- bus/policy.c | 50 +++++++++++ bus/policy.h | 6 ++ doc/dbus-specification.sgml | 53 ++++++++---- test/data/valid-config-files/many-rules.conf | 57 +++++++++++++ 7 files changed, 309 insertions(+), 50 deletions(-) create mode 100644 test/data/valid-config-files/many-rules.conf diff --git a/ChangeLog b/ChangeLog index a9328da2..1e60a09e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2003-09-06 Havoc Pennington + + * 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" + 2003-09-06 Havoc Pennington * dbus/dbus-connection.c (dbus_connection_register_fallback): add this 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 element appears below a element and prohibits some action. The possible attributes of a 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 element are: .PP Examples: .nf - - + + - - + + .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 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. would deny -messages of the given name AND to the given service. +A single 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. would +deny messages of the given interface AND to the given service. +To get an OR effect you specify multiple 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 "" 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; diff --git a/doc/dbus-specification.sgml b/doc/dbus-specification.sgml index 031bb329..7800165b 100644 --- a/doc/dbus-specification.sgml +++ b/doc/dbus-specification.sgml @@ -3,8 +3,8 @@
D-BUS Specification - Version 0.7 - 26 March 2003 + Version 0.8 + 06 September 2003 Havoc @@ -65,10 +65,10 @@ D-BUS is easy to use because it works in terms of messages rather than byte streams, and - does not require users to understand any complex concepts such as a - new type system or elaborate APIs. Libraries implementing D-BUS - may choose to abstract messages as "method calls" (see - ). + automatically handles a lot of the hard IPC issues. Also, the D-BUS + library is designed to be wrapped in a way that lets users use their + framework's existing object/type system, rather than learning a new + one specifically for IPC. @@ -83,11 +83,10 @@ forwards messages among them. - Things that D-BUS can be used for is for example notification of - system changes (notification of when a camera is plugged in to a - computer, or a new version of some software has been installed), - or desktop interoperablity, for example a file monitoring - service or a configuration service. + Uses of D-BUS include notification of system changes (notification of when + a camera is plugged in to a computer, or a new version of some software + has been installed), or desktop interoperablity, for example a file + monitoring service or a configuration service. @@ -279,9 +278,27 @@ - name + path STRING - The name of the message, such as org.freedesktop.Peer.Ping + The object to send the message to; objects are identified by + a path, "/foo/bar" + + + ifce + STRING + The interface to invoke a method call on, or + that a signal is emitted from. e.g. "org.freedesktop.Introspectable" + + + mebr + STRING + The member, either the method name or signal name. + e.g. "Frobate" + + + ernm + STRING + The name of the error that occurred, for errors rply @@ -298,10 +315,10 @@ . - sndr + sdrs STRING - The name of the base service that sent this message. - The message bus fills in this field; the field is + Sender service. The name of the base service that sent + this message. The message bus fills in this field; the field is only meaningful in combination with the message bus. @@ -480,9 +497,9 @@ Valid names - Messages and services have names with type STRING, meaning that + Services have names with type STRING, meaning that they must be valid UTF-8. However, there are also some - additional restrictions that apply to message and service names + additional restrictions that apply to service names specifically: They must contain at least one '.' (period) character diff --git a/test/data/valid-config-files/many-rules.conf b/test/data/valid-config-files/many-rules.conf new file mode 100644 index 00000000..57ea5ec9 --- /dev/null +++ b/test/data/valid-config-files/many-rules.conf @@ -0,0 +1,57 @@ + + + mybususer + unix:path=/foo/bar + tcp:port=1234 + basic.d + /usr/share/foo + nonexistent.conf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5000 + 5000 + 300 + 5000 + 6000 + 50 + 80 + 64 + 64 + 256 + + -- cgit v1.2.1