diff options
41 files changed, 1048 insertions, 178 deletions
@@ -237,6 +237,5 @@ rules are: The reviewer group that can approve patches: Havoc Pennington, Michael Meeks, Alex Larsson, Zack Rusin, Joe Shaw, Mikael Hallendal, Richard Hult, Owen Fraser-Green, Olivier Andrieu, Colin Walters, Thiago -Macieira, John Palmieri. - +Macieira, John Palmieri, Scott James Remnant. diff --git a/bus/activation.c b/bus/activation.c index 18630958..a273c4ad 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -679,7 +679,7 @@ populate_environment (BusActivation *activation) DBusString value; int i; char **environment; - dbus_bool_t retval; + dbus_bool_t retval = FALSE; environment = _dbus_get_environment (); @@ -54,6 +54,9 @@ struct BusContext BusMatchmaker *matchmaker; BusLimits limits; unsigned int fork : 1; + unsigned int syslog : 1; + unsigned int keep_umask : 1; + unsigned int allow_anonymous : 1; }; static dbus_int32_t server_data_slot = -1; @@ -188,6 +191,9 @@ new_connection_callback (DBusServer *server, dbus_connection_set_max_message_size (new_connection, context->limits.max_message_size); + dbus_connection_set_allow_anonymous (new_connection, + context->allow_anonymous); + /* on OOM, we won't have ref'd the connection so it will die. */ } @@ -384,6 +390,9 @@ process_config_first_time_only (BusContext *context, } context->fork = bus_config_parser_get_fork (parser); + context->syslog = bus_config_parser_get_syslog (parser); + context->keep_umask = bus_config_parser_get_keep_umask (parser); + context->allow_anonymous = bus_config_parser_get_allow_anonymous (parser); _DBUS_ASSERT_ERROR_IS_CLEAR (error); retval = TRUE; @@ -708,7 +717,8 @@ bus_context_new (const DBusString *config_file, if (!_dbus_become_daemon (context->pidfile ? &u : NULL, print_pid_pipe, - error)) + error, + context->keep_umask)) { _DBUS_ASSERT_ERROR_IS_SET (error); goto failed; @@ -736,6 +746,11 @@ bus_context_new (const DBusString *config_file, if (print_pid_pipe && _dbus_pipe_is_valid (print_pid_pipe) && !_dbus_pipe_is_stdout_or_stderr (print_pid_pipe)) _dbus_pipe_close (print_pid_pipe, NULL); + + if (!bus_selinux_full_init ()) + { + _dbus_warn ("SELinux initialization failed\n"); + } if (!process_config_postinit (context, parser, error)) { @@ -766,11 +781,6 @@ bus_context_new (const DBusString *config_file, #endif } - if (!bus_selinux_full_init ()) - { - _dbus_warn ("SELinux initialization failed\n"); - } - dbus_server_free_data_slot (&server_data_slot); return context; @@ -826,7 +836,10 @@ bus_context_reload_config (BusContext *context, } ret = TRUE; + bus_context_log_info (context, "Reloaded configuration"); failed: + if (!ret) + bus_context_log_info (context, "Unable to reload configuration: %s", error->message); if (parser != NULL) bus_config_parser_unref (parser); return ret; @@ -1107,6 +1120,32 @@ bus_context_get_reply_timeout (BusContext *context) return context->limits.reply_timeout; } +void +bus_context_log_info (BusContext *context, const char *msg, ...) +{ + va_list args; + + va_start (args, msg); + + if (context->syslog) + _dbus_log_info (msg, args); + + va_end (args); +} + +void +bus_context_log_security (BusContext *context, const char *msg, ...) +{ + va_list args; + + va_start (args, msg); + + if (context->syslog) + _dbus_log_security (msg, args); + + va_end (args); +} + /* * addressed_recipient is the recipient specified in the message. * @@ -1129,20 +1168,44 @@ bus_context_check_security_policy (BusContext *context, DBusMessage *message, DBusError *error) { + const char *dest; BusClientPolicy *sender_policy; BusClientPolicy *recipient_policy; + dbus_int32_t toggles; + dbus_bool_t log; int type; dbus_bool_t requested_reply; + const char *sender_name; + const char *sender_loginfo; + const char *proposed_recipient_loginfo; type = dbus_message_get_type (message); + dest = dbus_message_get_destination (message); /* dispatch.c was supposed to ensure these invariants */ - _dbus_assert (dbus_message_get_destination (message) != NULL || + _dbus_assert (dest != NULL || type == DBUS_MESSAGE_TYPE_SIGNAL || (sender == NULL && !bus_connection_is_active (proposed_recipient))); _dbus_assert (type == DBUS_MESSAGE_TYPE_SIGNAL || addressed_recipient != NULL || - strcmp (dbus_message_get_destination (message), DBUS_SERVICE_DBUS) == 0); + strcmp (dest, DBUS_SERVICE_DBUS) == 0); + + /* Used in logging below */ + if (sender != NULL) + { + sender_name = bus_connection_get_name (sender); + sender_loginfo = bus_connection_get_loginfo (sender); + } + else + { + sender_name = NULL; + sender_loginfo = "(bus)"; + } + + if (proposed_recipient != NULL) + proposed_recipient_loginfo = bus_connection_get_loginfo (proposed_recipient); + else + proposed_recipient_loginfo = "bus"; switch (type) { @@ -1166,10 +1229,6 @@ bus_context_check_security_policy (BusContext *context, if (sender != NULL) { - const char *dest; - - dest = dbus_message_get_destination (message); - /* First verify the SELinux access controls. If allowed then * go on with the standard checks. */ @@ -1185,8 +1244,9 @@ bus_context_check_security_policy (BusContext *context, dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, "An SELinux policy prevents this sender " "from sending this message to this recipient " - "(rejected message had interface \"%s\" " + "(rejected message had sender \"%s\" interface \"%s\" " "member \"%s\" error name \"%s\" destination \"%s\")", + sender_name ? sender_name : "(unset)", dbus_message_get_interface (message) ? dbus_message_get_interface (message) : "(unset)", dbus_message_get_member (message) ? @@ -1299,57 +1359,112 @@ bus_context_check_security_policy (BusContext *context, (proposed_recipient != NULL && sender == NULL && recipient_policy == NULL) || (proposed_recipient == NULL && recipient_policy == NULL)); + log = FALSE; if (sender_policy && !bus_client_policy_check_can_send (sender_policy, context->registry, requested_reply, proposed_recipient, - message)) + message, &toggles, &log)) { - const char *dest; - - dest = dbus_message_get_destination (message); - dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, - "A security policy in place prevents this sender " - "from sending this message to this recipient, " - "see message bus configuration file (rejected message " - "had interface \"%s\" member \"%s\" error name \"%s\" destination \"%s\")", + const char *msg = "Rejected send message, %d matched rules; " + "type=\"%s\", sender=\"%s\" (%s) interface=\"%s\" member=\"%s\" error name=\"%s\" requested_reply=%d destination=\"%s\" (%s))"; + + dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, msg, + toggles, + dbus_message_type_to_string (dbus_message_get_type (message)), + sender_name ? sender_name : "(unset)", + sender_loginfo, dbus_message_get_interface (message) ? dbus_message_get_interface (message) : "(unset)", dbus_message_get_member (message) ? dbus_message_get_member (message) : "(unset)", dbus_message_get_error_name (message) ? dbus_message_get_error_name (message) : "(unset)", - dest ? dest : DBUS_SERVICE_DBUS); + requested_reply, + dest ? dest : DBUS_SERVICE_DBUS, + proposed_recipient_loginfo); + /* Needs to be duplicated to avoid calling malloc and having to handle OOM */ + if (addressed_recipient == proposed_recipient) + bus_context_log_security (context, msg, + toggles, + dbus_message_type_to_string (dbus_message_get_type (message)), + sender_name ? sender_name : "(unset)", + sender_loginfo, + dbus_message_get_interface (message) ? + dbus_message_get_interface (message) : "(unset)", + dbus_message_get_member (message) ? + dbus_message_get_member (message) : "(unset)", + dbus_message_get_error_name (message) ? + dbus_message_get_error_name (message) : "(unset)", + requested_reply, + dest ? dest : DBUS_SERVICE_DBUS, + proposed_recipient_loginfo); _dbus_verbose ("security policy disallowing message due to sender policy\n"); return FALSE; } + if (log) + bus_context_log_security (context, + "Would reject message, %d matched rules; " + "type=\"%s\", sender=\"%s\" (%s) interface=\"%s\" member=\"%s\" error name=\"%s\" requested_reply=%d destination=\"%s\" (%s))", + toggles, + dbus_message_type_to_string (dbus_message_get_type (message)), + sender_name ? sender_name : "(unset)", + sender_loginfo, + dbus_message_get_interface (message) ? + dbus_message_get_interface (message) : "(unset)", + dbus_message_get_member (message) ? + dbus_message_get_member (message) : "(unset)", + dbus_message_get_error_name (message) ? + dbus_message_get_error_name (message) : "(unset)", + requested_reply, + dest ? dest : DBUS_SERVICE_DBUS, + proposed_recipient_loginfo); + if (recipient_policy && !bus_client_policy_check_can_receive (recipient_policy, context->registry, requested_reply, sender, addressed_recipient, proposed_recipient, - message)) + message, &toggles)) { - const char *dest; - - dest = dbus_message_get_destination (message); - dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, - "A security policy in place prevents this recipient " - "from receiving this message from this sender, " - "see message bus configuration file (rejected message " - "had interface \"%s\" member \"%s\" error name \"%s\" destination \"%s\" reply serial %u requested_reply=%d)", + const char *msg = "Rejected receive message, %d matched rules; " + "type=\"%s\" sender=\"%s\" (%s) interface=\"%s\" member=\"%s\" error name=\"%s\" reply serial=%u requested_reply=%d destination=\"%s\" (%s))"; + + dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, msg, + toggles, + dbus_message_type_to_string (dbus_message_get_type (message)), + sender_name ? sender_name : "(unset)", + sender_loginfo, dbus_message_get_interface (message) ? dbus_message_get_interface (message) : "(unset)", dbus_message_get_member (message) ? dbus_message_get_member (message) : "(unset)", dbus_message_get_error_name (message) ? dbus_message_get_error_name (message) : "(unset)", - dest ? dest : DBUS_SERVICE_DBUS, dbus_message_get_reply_serial (message), - requested_reply); + requested_reply, + dest ? dest : DBUS_SERVICE_DBUS, + proposed_recipient_loginfo); + /* Needs to be duplicated to avoid calling malloc and having to handle OOM */ + if (addressed_recipient == proposed_recipient) + bus_context_log_security (context, msg, + toggles, + dbus_message_type_to_string (dbus_message_get_type (message)), + sender_name ? sender_name : "(unset)", + sender_loginfo, + dbus_message_get_interface (message) ? + dbus_message_get_interface (message) : "(unset)", + dbus_message_get_member (message) ? + dbus_message_get_member (message) : "(unset)", + dbus_message_get_error_name (message) ? + dbus_message_get_error_name (message) : "(unset)", + dbus_message_get_reply_serial (message), + requested_reply, + dest ? dest : DBUS_SERVICE_DBUS, + proposed_recipient_loginfo); _dbus_verbose ("security policy disallowing message due to recipient policy\n"); return FALSE; } @@ -1359,9 +1474,6 @@ bus_context_check_security_policy (BusContext *context, dbus_connection_get_outgoing_size (proposed_recipient) > context->limits.max_outgoing_bytes) { - const char *dest; - - dest = dbus_message_get_destination (message); dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED, "The destination service \"%s\" has a full message queue", dest ? dest : (proposed_recipient ? @@ -107,6 +107,12 @@ int bus_context_get_max_services_per_connection (BusContext int bus_context_get_max_match_rules_per_connection (BusContext *context); int bus_context_get_max_replies_per_connection (BusContext *context); int bus_context_get_reply_timeout (BusContext *context); +void bus_context_log_info (BusContext *context, + const char *msg, + ...); +void bus_context_log_security (BusContext *context, + const char *msg, + ...); dbus_bool_t bus_context_check_security_policy (BusContext *context, BusTransaction *transaction, DBusConnection *sender, diff --git a/bus/config-parser-common.c b/bus/config-parser-common.c index 6e4bb701..4965c192 100644 --- a/bus/config-parser-common.c +++ b/bus/config-parser-common.c @@ -114,6 +114,18 @@ bus_config_parser_element_name_to_type (const char *name) { return ELEMENT_ASSOCIATE; } + else if (strcmp (name, "keep_umask") == 0) + { + return ELEMENT_KEEP_UMASK; + } + else if (strcmp (name, "syslog") == 0) + { + return ELEMENT_SYSLOG; + } + else if (strcmp (name, "allow_anonymous") == 0) + { + return ELEMENT_ALLOW_ANONYMOUS; + } return ELEMENT_NONE; } @@ -162,6 +174,12 @@ bus_config_parser_element_type_to_name (ElementType type) return "selinux"; case ELEMENT_ASSOCIATE: return "associate"; + case ELEMENT_KEEP_UMASK: + return "keep_umask"; + case ELEMENT_SYSLOG: + return "syslog"; + case ELEMENT_ALLOW_ANONYMOUS: + return "allow_anonymous"; } _dbus_assert_not_reached ("bad element type"); diff --git a/bus/config-parser-common.h b/bus/config-parser-common.h index 3718c958..2c296433 100644 --- a/bus/config-parser-common.h +++ b/bus/config-parser-common.h @@ -47,7 +47,10 @@ typedef enum ELEMENT_SELINUX, ELEMENT_ASSOCIATE, ELEMENT_STANDARD_SESSION_SERVICEDIRS, - ELEMENT_STANDARD_SYSTEM_SERVICEDIRS + ELEMENT_STANDARD_SYSTEM_SERVICEDIRS, + ELEMENT_KEEP_UMASK, + ELEMENT_SYSLOG, + ELEMENT_ALLOW_ANONYMOUS } ElementType; ElementType bus_config_parser_element_name_to_type (const char *element_name); diff --git a/bus/config-parser.c b/bus/config-parser.c index f9e0b7d7..34d8684a 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -111,7 +111,13 @@ struct BusConfigParser unsigned int fork : 1; /**< TRUE to fork into daemon mode */ + unsigned int keep_umask : 1; /**< TRUE to keep original umask when forking */ + + unsigned int syslog : 1; /**< TRUE to enable syslog */ + unsigned int is_toplevel : 1; /**< FALSE if we are a sub-config-file inside another one */ + + unsigned int allow_anonymous : 1; /**< TRUE to allow anonymous connections */ }; static Element* @@ -306,6 +312,9 @@ merge_included (BusConfigParser *parser, if (included->fork) parser->fork = TRUE; + if (included->keep_umask) + parser->keep_umask = TRUE; + if (included->pidfile != NULL) { dbus_free (parser->pidfile); @@ -698,6 +707,36 @@ start_busconfig_child (BusConfigParser *parser, return TRUE; } + else if (element_type == ELEMENT_KEEP_UMASK) + { + if (!check_no_attributes (parser, "keep_umask", attribute_names, attribute_values, error)) + return FALSE; + + if (push_element (parser, ELEMENT_KEEP_UMASK) == NULL) + { + BUS_SET_OOM (error); + return FALSE; + } + + parser->keep_umask = TRUE; + + return TRUE; + } + else if (element_type == ELEMENT_SYSLOG) + { + if (!check_no_attributes (parser, "syslog", attribute_names, attribute_values, error)) + return FALSE; + + if (push_element (parser, ELEMENT_SYSLOG) == NULL) + { + BUS_SET_OOM (error); + return FALSE; + } + + parser->syslog = TRUE; + + return TRUE; + } else if (element_type == ELEMENT_PIDFILE) { if (!check_no_attributes (parser, "pidfile", attribute_names, attribute_values, error)) @@ -815,6 +854,20 @@ start_busconfig_child (BusConfigParser *parser, return TRUE; } + else if (element_type == ELEMENT_ALLOW_ANONYMOUS) + { + if (!check_no_attributes (parser, "allow_anonymous", attribute_names, attribute_values, error)) + return FALSE; + + if (push_element (parser, ELEMENT_ALLOW_ANONYMOUS) == NULL) + { + BUS_SET_OOM (error); + return FALSE; + } + + parser->allow_anonymous = TRUE; + return TRUE; + } else if (element_type == ELEMENT_SERVICEDIR) { if (!check_no_attributes (parser, "servicedir", attribute_names, attribute_values, error)) @@ -1073,6 +1126,7 @@ append_rule_from_element (BusConfigParser *parser, dbus_bool_t allow, DBusError *error) { + const char *log; const char *send_interface; const char *send_member; const char *send_error; @@ -1116,6 +1170,7 @@ append_rule_from_element (BusConfigParser *parser, "own", &own, "user", &user, "group", &group, + "log", &log, NULL)) return FALSE; @@ -1320,6 +1375,9 @@ append_rule_from_element (BusConfigParser *parser, if (eavesdrop) rule->d.send.eavesdrop = (strcmp (eavesdrop, "true") == 0); + if (log) + rule->d.send.log = (strcmp (log, "true") == 0); + if (send_requested_reply) rule->d.send.requested_reply = (strcmp (send_requested_reply, "true") == 0); @@ -1947,10 +2005,13 @@ bus_config_parser_end_element (BusConfigParser *parser, case ELEMENT_ALLOW: case ELEMENT_DENY: case ELEMENT_FORK: + case ELEMENT_KEEP_UMASK: + case ELEMENT_SYSLOG: case ELEMENT_SELINUX: case ELEMENT_ASSOCIATE: case ELEMENT_STANDARD_SESSION_SERVICEDIRS: case ELEMENT_STANDARD_SYSTEM_SERVICEDIRS: + case ELEMENT_ALLOW_ANONYMOUS: break; } @@ -2232,8 +2293,11 @@ bus_config_parser_content (BusConfigParser *parser, case ELEMENT_ALLOW: case ELEMENT_DENY: case ELEMENT_FORK: + case ELEMENT_KEEP_UMASK: + case ELEMENT_SYSLOG: case ELEMENT_STANDARD_SESSION_SERVICEDIRS: case ELEMENT_STANDARD_SYSTEM_SERVICEDIRS: + case ELEMENT_ALLOW_ANONYMOUS: case ELEMENT_SELINUX: case ELEMENT_ASSOCIATE: if (all_whitespace (content)) @@ -2554,6 +2618,24 @@ bus_config_parser_get_fork (BusConfigParser *parser) return parser->fork; } +dbus_bool_t +bus_config_parser_get_keep_umask (BusConfigParser *parser) +{ + return parser->keep_umask; +} + +dbus_bool_t +bus_config_parser_get_syslog (BusConfigParser *parser) +{ + return parser->syslog; +} + +dbus_bool_t +bus_config_parser_get_allow_anonymous (BusConfigParser *parser) +{ + return parser->allow_anonymous; +} + const char * bus_config_parser_get_pidfile (BusConfigParser *parser) { @@ -2947,6 +3029,9 @@ config_parsers_equal (const BusConfigParser *a, if (! bools_equal (a->fork, b->fork)) return FALSE; + if (! bools_equal (a->keep_umask, b->keep_umask)) + return FALSE; + if (! bools_equal (a->is_toplevel, b->is_toplevel)) return FALSE; diff --git a/bus/config-parser.h b/bus/config-parser.h index ec0dfed1..bb3a30f4 100644 --- a/bus/config-parser.h +++ b/bus/config-parser.h @@ -65,6 +65,9 @@ const char* bus_config_parser_get_type (BusConfigParser *parser); DBusList** bus_config_parser_get_addresses (BusConfigParser *parser); DBusList** bus_config_parser_get_mechanisms (BusConfigParser *parser); dbus_bool_t bus_config_parser_get_fork (BusConfigParser *parser); +dbus_bool_t bus_config_parser_get_allow_anonymous (BusConfigParser *parser); +dbus_bool_t bus_config_parser_get_syslog (BusConfigParser *parser); +dbus_bool_t bus_config_parser_get_keep_umask (BusConfigParser *parser); const char* bus_config_parser_get_pidfile (BusConfigParser *parser); const char* bus_config_parser_get_servicehelper (BusConfigParser *parser); DBusList** bus_config_parser_get_service_dirs (BusConfigParser *parser); diff --git a/bus/connection.c b/bus/connection.c index ed1b1391..9159c898 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -32,6 +32,9 @@ #include <dbus/dbus-hash.h> #include <dbus/dbus-timeout.h> +/* Trim executed commands to this length; we want to keep logs readable */ +#define MAX_LOG_COMMAND_LEN 50 + static void bus_connection_remove_transactions (DBusConnection *connection); typedef struct @@ -76,6 +79,7 @@ typedef struct DBusPreallocatedSend *oom_preallocated; BusClientPolicy *policy; + char *cached_loginfo_string; BusSELinuxID *selinux_id; long connection_tv_sec; /**< Time when we connected (seconds component) */ @@ -406,6 +410,8 @@ free_connection_data (void *data) if (d->selinux_id) bus_selinux_id_unref (d->selinux_id); + dbus_free (d->cached_loginfo_string); + dbus_free (d->name); dbus_free (d); @@ -537,13 +543,72 @@ bus_connections_unref (BusConnections *connections) } } +/* Used for logging */ +static dbus_bool_t +cache_peer_loginfo_string (BusConnectionData *d, + DBusConnection *connection) +{ + DBusString loginfo_buf; + unsigned long uid; + unsigned long pid; + char *windows_sid; + dbus_bool_t prev_added; + + if (!_dbus_string_init (&loginfo_buf)) + return FALSE; + + prev_added = FALSE; + if (dbus_connection_get_unix_user (connection, &uid)) + { + if (!_dbus_string_append_printf (&loginfo_buf, "uid=%ld", uid)) + goto oom; + else + prev_added = TRUE; + } + + if (dbus_connection_get_unix_process_id (connection, &pid)) + { + if (prev_added) + { + if (!_dbus_string_append_byte (&loginfo_buf, ' ')) + goto oom; + } + if (!_dbus_string_append_printf (&loginfo_buf, "pid=%ld comm=\"", pid)) + goto oom; + /* Ignore errors here; we may not have permissions to read the + * proc file. */ + _dbus_command_for_pid (pid, &loginfo_buf, MAX_LOG_COMMAND_LEN, NULL); + if (!_dbus_string_append_byte (&loginfo_buf, '"')) + goto oom; + } + + if (dbus_connection_get_windows_user (connection, &windows_sid)) + { + if (!_dbus_string_append_printf (&loginfo_buf, "sid=\"%s\" ", windows_sid)) + goto oom; + dbus_free (windows_sid); + } + + if (!_dbus_string_steal_data (&loginfo_buf, &(d->cached_loginfo_string))) + goto oom; + + _dbus_string_free (&loginfo_buf); + + return TRUE; +oom: + _dbus_string_free (&loginfo_buf); + return FALSE; +} + dbus_bool_t bus_connections_setup_connection (BusConnections *connections, DBusConnection *connection) { + BusConnectionData *d; dbus_bool_t retval; DBusError error; + d = dbus_new0 (BusConnectionData, 1); @@ -583,7 +648,7 @@ bus_connections_setup_connection (BusConnections *connections, dbus_error_free (&error); goto out; } - + if (!dbus_connection_set_watch_functions (connection, add_connection_watch, remove_connection_watch, @@ -842,6 +907,18 @@ bus_connection_is_in_unix_group (DBusConnection *connection, return FALSE; } +const char * +bus_connection_get_loginfo (DBusConnection *connection) +{ + BusConnectionData *d; + + d = BUS_CONNECTION_DATA (connection); + + if (!bus_connection_is_active (connection)) + return "inactive"; + return d->cached_loginfo_string; +} + BusClientPolicy* bus_connection_get_policy (DBusConnection *connection) { @@ -1302,16 +1379,15 @@ bus_connection_complete (DBusConnection *connection, { if (!adjust_connections_for_uid (d->connections, uid, 1)) - { - BUS_SET_OOM (error); - dbus_free (d->name); - d->name = NULL; - bus_client_policy_unref (d->policy); - d->policy = NULL; - return FALSE; - } + goto fail; } - + + /* Create and cache a string which holds information about the + * peer process; used for logging purposes. + */ + if (!cache_peer_loginfo_string (d, connection)) + goto fail; + /* Now the connection is active, move it between lists */ _dbus_list_unlink (&d->connections->incomplete, d->link_in_connection_list); @@ -1329,6 +1405,14 @@ bus_connection_complete (DBusConnection *connection, _dbus_assert (bus_connection_is_active (connection)); return TRUE; +fail: + BUS_SET_OOM (error); + dbus_free (d->name); + d->name = NULL; + if (d->policy) + bus_client_policy_unref (d->policy); + d->policy = NULL; + return FALSE; } const char * diff --git a/bus/connection.h b/bus/connection.h index 5099bcf9..4f352169 100644 --- a/bus/connection.h +++ b/bus/connection.h @@ -50,6 +50,7 @@ BusConnections* bus_connection_get_connections (DBusConnection BusRegistry* bus_connection_get_registry (DBusConnection *connection); BusActivation* bus_connection_get_activation (DBusConnection *connection); BusMatchmaker* bus_connection_get_matchmaker (DBusConnection *connection); +const char * bus_connection_get_loginfo (DBusConnection *connection); BusSELinuxID* bus_connection_get_selinux_id (DBusConnection *connection); dbus_bool_t bus_connections_check_limits (BusConnections *connections, DBusConnection *requesting_completion, diff --git a/bus/dbus-daemon.1.in b/bus/dbus-daemon.1.in index 5599afe6..4b55ac29 100644 --- a/bus/dbus-daemon.1.in +++ b/bus/dbus-daemon.1.in @@ -1,6 +1,6 @@ .\" .\" dbus-daemon manual page. -.\" Copyright (C) 2003 Red Hat, Inc. +.\" Copyright (C) 2003,2008 Red Hat, Inc. .\" .TH dbus-daemon 1 .SH NAME @@ -214,6 +214,13 @@ into the background, etc.). This is generally used rather than the \-\-fork command line option. .TP +.I "<keep_umask>" + +.PP +If present, the bus daemon keeps its original umask when forking. +This may be useful to avoid affecting the behavior of child processes. + +.TP .I "<listen>" .PP @@ -410,15 +417,27 @@ they are analogous to a firewall in that they allow expected traffic and prevent unexpected traffic. .PP -The <policy> element has one of three attributes: +Currently, the system bus has a default-deny policy for sending method calls +and owning bus names. Everything else, in particular reply messages, receive +checks, and signals has a default allow policy. + +.PP +In general, it is best to keep system services as small, targeted programs which +run in their own process and provide a single bus name. Then, all that is needed +is an <allow> rule for the "own" permission to let the process claim the bus +name, and a "send_destination" rule to allow traffic from some or all uids to +your service. + +.PP +The <policy> element has one of four attributes: .nf context="(default|mandatory)" + at_console="(true|false)" user="username or userid" group="group name or gid" .fi .PP - Policies are applied to a connection as follows: .nf - all context="default" policies are applied @@ -426,6 +445,8 @@ Policies are applied to a connection as follows: in undefined order - all user="connection's auth user" policies are applied in undefined order + - all at_console="true" policies are applied + - all at_console="false" policies are applied - all context="mandatory" policies are applied .fi @@ -474,9 +495,7 @@ The possible attributes of these elements are: .PP Examples: .nf - <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_destination="org.freedesktop.Service" send_interface="org.freedesktop.System" send_member="Reboot"/> <deny send_destination="org.freedesktop.System"/> <deny receive_sender="org.freedesktop.System"/> <deny user="john"/> @@ -566,7 +585,11 @@ received" are evaluated separately. .PP Be careful with send_interface/receive_interface, because the -interface field in messages is optional. +interface field in messages is optional. In particular, do NOT +specify <deny send_interface="org.foo.Bar"/>! This will cause +no-interface messages to be blocked for all services, which is +almost certainly not what you intended. Always use rules of +the form: <deny send_interface="org.foo.Bar" send_destination="org.foo.Service"/> .TP .I "<selinux>" diff --git a/bus/driver.c b/bus/driver.c index 05ecd56c..c97bff5d 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -1411,7 +1411,7 @@ bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection, BusService *serv; DBusConnection *conn; DBusMessage *reply; - char *data = NULL; + void *data = NULL; dbus_uint32_t data_size; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -44,7 +44,6 @@ static void close_reload_pipe (void); static void signal_handler (int sig) { - DBusString str; switch (sig) { @@ -52,16 +51,20 @@ signal_handler (int sig) case SIGIO: /* explicit fall-through */ #endif /* DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX */ +#ifdef SIGHUP case SIGHUP: - _dbus_string_init_const (&str, "foo"); - if ((reload_pipe[RELOAD_WRITE_END] > 0) && - !_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1)) - { - _dbus_warn ("Unable to write to reload pipe.\n"); - close_reload_pipe (); - } + { + DBusString str; + _dbus_string_init_const (&str, "foo"); + if ((reload_pipe[RELOAD_WRITE_END] > 0) && + !_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1)) + { + _dbus_warn ("Unable to write to reload pipe.\n"); + close_reload_pipe (); + } + } break; - +#endif case SIGTERM: _dbus_loop_quit (bus_context_get_loop (context)); break; @@ -458,7 +461,9 @@ main (int argc, char **argv) setup_reload_pipe (bus_context_get_loop (context)); +#ifdef SIGHUP _dbus_set_signal_handler (SIGHUP, signal_handler); +#endif _dbus_set_signal_handler (SIGTERM, signal_handler); #ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX _dbus_set_signal_handler (SIGIO, signal_handler); diff --git a/bus/policy.c b/bus/policy.c index caa544e7..ef31800f 100644 --- a/bus/policy.c +++ b/bus/policy.c @@ -866,7 +866,9 @@ bus_client_policy_check_can_send (BusClientPolicy *policy, BusRegistry *registry, dbus_bool_t requested_reply, DBusConnection *receiver, - DBusMessage *message) + DBusMessage *message, + dbus_int32_t *toggles, + dbus_bool_t *log) { DBusList *link; dbus_bool_t allowed; @@ -876,6 +878,7 @@ bus_client_policy_check_can_send (BusClientPolicy *policy, */ _dbus_verbose (" (policy) checking send rules\n"); + *toggles = 0; allowed = FALSE; link = _dbus_list_get_first_link (&policy->rules); @@ -1026,6 +1029,8 @@ bus_client_policy_check_can_send (BusClientPolicy *policy, /* Use this rule */ allowed = rule->allow; + *log = rule->d.send.log; + (*toggles)++; _dbus_verbose (" (policy) used rule, allow now = %d\n", allowed); @@ -1044,7 +1049,8 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy, DBusConnection *sender, DBusConnection *addressed_recipient, DBusConnection *proposed_recipient, - DBusMessage *message) + DBusMessage *message, + dbus_int32_t *toggles) { DBusList *link; dbus_bool_t allowed; @@ -1059,6 +1065,7 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy, */ _dbus_verbose (" (policy) checking receive rules, eavesdropping = %d\n", eavesdropping); + *toggles = 0; allowed = FALSE; link = _dbus_list_get_first_link (&policy->rules); @@ -1223,6 +1230,7 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy, /* Use this rule */ allowed = rule->allow; + (*toggles)++; _dbus_verbose (" (policy) used rule, allow now = %d\n", allowed); diff --git a/bus/policy.h b/bus/policy.h index adb9a059..a75e0dd9 100644 --- a/bus/policy.h +++ b/bus/policy.h @@ -65,6 +65,7 @@ struct BusPolicyRule char *destination; unsigned int eavesdrop : 1; unsigned int requested_reply : 1; + unsigned int log : 1; } send; struct @@ -141,14 +142,17 @@ dbus_bool_t bus_client_policy_check_can_send (BusClientPolicy *policy, BusRegistry *registry, dbus_bool_t requested_reply, DBusConnection *receiver, - DBusMessage *message); + DBusMessage *message, + dbus_int32_t *toggles, + dbus_bool_t *log); dbus_bool_t bus_client_policy_check_can_receive (BusClientPolicy *policy, BusRegistry *registry, dbus_bool_t requested_reply, DBusConnection *sender, DBusConnection *addressed_recipient, DBusConnection *proposed_recipient, - DBusMessage *message); + DBusMessage *message, + dbus_int32_t *toggles); dbus_bool_t bus_client_policy_check_can_own (BusClientPolicy *policy, DBusConnection *connection, const DBusString *service_name); diff --git a/bus/session.conf.in b/bus/session.conf.in index b2dee5b3..794eb8da 100644 --- a/bus/session.conf.in +++ b/bus/session.conf.in @@ -8,6 +8,10 @@ <!-- Our well-known bus type, don't change this --> <type>session</type> + <!-- If we fork, keep the user's original umask to avoid affecting + the behavior of child processes. --> + <keep_umask/> + <listen>unix:tmpdir=@DBUS_SESSION_SOCKET_DIR@</listen> <standard_session_servicedirs /> diff --git a/bus/system.conf.in b/bus/system.conf.in index 6a71926e..92f4cc42 100644 --- a/bus/system.conf.in +++ b/bus/system.conf.in @@ -29,6 +29,9 @@ <!-- Write a pid file --> <pidfile>@DBUS_SYSTEM_PID_FILE@</pidfile> + <!-- Enable logging to syslog --> + <syslog/> + <!-- Only allow socket-credentials-based authentication --> <auth>EXTERNAL</auth> @@ -39,21 +42,29 @@ <listen>@DBUS_SYSTEM_BUS_DEFAULT_ADDRESS@</listen> <policy context="default"> - <!-- Deny everything then punch holes --> - <deny send_interface="*"/> - <deny receive_interface="*"/> - <deny own="*"/> - <!-- But allow all users to connect --> + <!-- All users can connect to system bus --> <allow user="*"/> + + <!-- Holes must be punched in service configuration files for + name ownership and sending method calls --> + <deny own="*"/> + <deny send_type="method_call"/> + + <!-- Signals and reply messages (method returns, errors) are allowed + by default --> + <allow send_type="signal"/> + <allow send_requested_reply="true" send_type="method_return"/> + <allow send_requested_reply="true" send_type="error"/> + + <!-- All messages may be received by default --> + <allow receive_type="method_call"/> + <allow receive_type="method_return"/> + <allow receive_type="error"/> + <allow receive_type="signal"/> + <!-- Allow anyone to talk to the message bus --> - <!-- FIXME I think currently these allow rules are always implicit - even if they aren't in here --> <allow send_destination="org.freedesktop.DBus"/> - <allow receive_sender="org.freedesktop.DBus"/> - <!-- valid replies are always allowed --> - <allow send_requested_reply="true"/> - <allow receive_requested_reply="true"/> - <!-- disallow changing the activation environment of system services --> + <!-- But disallow some specific bus services --> <deny send_destination="org.freedesktop.DBus" send_interface="org.freedesktop.DBus" send_member="UpdateActivationEnvironment"/> diff --git a/configure.in b/configure.in index 8c05b11c..9d825c7d 100644 --- a/configure.in +++ b/configure.in @@ -8,7 +8,7 @@ m4_define([dbus_version], [dbus_major_version.dbus_minor_version.dbus_micro_version]) AC_INIT(dbus, [dbus_version]) -AC_CANONICAL_TARGET +AC_CANONICAL_HOST AM_INIT_AUTOMAKE([1.9 tar-ustar]) AM_CONFIG_HEADER(config.h) @@ -175,6 +175,12 @@ ld_supports_flag() { fi } +if test x$USE_MAINTAINER_MODE = xyes; then + if cc_supports_flag "-Werror"; then + CFLAGS="$CFLAGS -Werror" + fi +fi + if test "x$GCC" = "xyes"; then changequote(,)dnl case " $CFLAGS " in @@ -221,11 +227,6 @@ if test "x$GCC" = "xyes"; then esac case " $CFLAGS " in - *[\ \ ]-Wsign-compare[\ \ ]*) ;; - *) CFLAGS="$CFLAGS -Wsign-compare" ;; - esac - - case " $CFLAGS " in *[\ \ ]-Wdeclaration-after-statement[\ \ ]*) ;; *) if cc_supports_flag -Wdeclaration-after-statement; then CFLAGS="$CFLAGS -Wdeclaration-after-statement" @@ -264,6 +265,41 @@ if test "x$GCC" = "xyes"; then fi ;; esac + + ### Disabled warnings, and compiler flag overrides + + # Let's just ignore unused for now + case " $CFLAGS " in + *[\ \ ]-Wno-unused[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wno-unused" ;; + esac + + # This group is for warnings we currently don't pass. + # We would like to, however. Please fix. + + # http://bugs.freedesktop.org/show_bug.cgi?id=17433 + case " $CFLAGS " in + *[\ \ ]-Wno-sign-compare[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wno-sign-compare" ;; + esac + case " $CFLAGS " in + *[\ \ ]-Wno-pointer-sign[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wno-pointer-sign" ;; + esac + + # http://bugs.freedesktop.org/show_bug.cgi?id=19195 + case " $CFLAGS " in + *[\ \ ]-Wno-format[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wno-format" ;; + esac + + # This one is special - it's not a warning override. + # http://bugs.freedesktop.org/show_bug.cgi?id=10599 + case " $CFLAGS " in + *[\ \ ]-fno-strict-aliasing[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -fno-strict-aliasing" ;; + esac + ### End disabled warnings if test "x$enable_ansi" = "xyes"; then case " $CFLAGS " in @@ -284,7 +320,7 @@ if test "x$GCC" = "xyes"; then case " $CFLAGS " in *[\ \ ]-pedantic[\ \ ]*) ;; *) CFLAGS="$CFLAGS -pedantic" ;; - esac + esac fi if test x$enable_gcov = xyes; then case " $CFLAGS " in @@ -321,7 +357,7 @@ AC_MSG_RESULT($ac_gcsections) # Add -D_POSIX_PTHREAD_SEMANTICS if on Solaris # -case $target_os in +case $host_os in solaris*) CFLAGS="$CFLAGS -D_POSIX_PTHREAD_SEMANTICS" ;; esac @@ -775,6 +811,7 @@ AC_CHECK_FUNCS(getpeerucred getpeereid) #### Abstract sockets +if ! test x$enable_abstract_sockets = xno; then AC_LANG_PUSH(C) AC_CACHE_CHECK([abstract socket namespace], ac_cv_have_abstract_sockets, @@ -818,6 +855,7 @@ AC_CACHE_CHECK([abstract socket namespace], [ac_cv_have_abstract_sockets=no] )]) AC_LANG_POP(C) +fi if test x$enable_abstract_sockets = xyes; then if test x$ac_cv_have_abstract_sockets = xno; then @@ -851,30 +889,27 @@ AC_CHECK_LIB(expat, XML_ParserCreate_MM, dbus_use_libxml=false dbus_use_expat=false if test x$with_xml = xexpat; then - dbus_use_expat=true if ! $have_expat ; then AC_MSG_ERROR([Explicitly requested expat but expat not found]) fi + dbus_use_expat=true elif test x$with_xml = xlibxml; then - dbus_use_libxml=true PKG_CHECK_MODULES(LIBXML, libxml-2.0 >= 2.6.0, have_libxml=true, have_libxml=false) - if ! $have_libxml ; then AC_MSG_ERROR([Explicitly requested libxml but libxml not found]) fi + dbus_use_libxml=true else ### expat is the default because libxml can't currently survive ### our brutal OOM-handling unit test setup. ### http://bugzilla.gnome.org/show_bug.cgi?id=109368 - if $have_expat ; then - with_xml=expat - dbus_use_expat=true - elif $have_libxml ; then - with_xml=libxml - dbus_use_libxml=true - else - AC_MSG_ERROR([No XML library found, check config.log for failed attempts]) + if test x$have_expat = xfalse; then + AC_MSG_ERROR([Could not find expat.h, check config.log for failed attempts]) fi + ### By default, only use Expat since it's tested and known to work. If you're a + ### general-purpose OS vendor, please don't enable libxml. For embedded use + ### if your OS is built around libxml, that's another case. + dbus_use_expat=true fi AM_CONDITIONAL(DBUS_USE_EXPAT, $dbus_use_expat) @@ -957,7 +992,7 @@ AM_CONDITIONAL(DBUS_BUS_ENABLE_INOTIFY, test x$have_inotify = xyes) if test x$enable_dnotify = xno ; then have_dnotify=no; else - if test x$have_inotify = xno -a x$target_os = xlinux-gnu -o x$target_os = xlinux; then + if test x$have_inotify = xno -a x$host_os = xlinux-gnu -o x$host_os = xlinux; then have_dnotify=yes; else have_dnotify=no; @@ -995,7 +1030,7 @@ dnl console owner file if test x$enable_console_owner_file = xno ; then have_console_owner_file=no; else - case $target_os in + case $host_os in solaris*) have_console_owner_file=yes; AC_DEFINE(HAVE_CONSOLE_OWNER_FILE,1,[Have console owner file]) diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index a960a991..ae07adf0 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -448,7 +448,7 @@ _dbus_connection_queue_received_message_link (DBusConnection *connection, DBusList *link) { DBusPendingCall *pending; - dbus_int32_t reply_serial; + dbus_uint32_t reply_serial; DBusMessage *message; _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport)); @@ -459,7 +459,7 @@ _dbus_connection_queue_received_message_link (DBusConnection *connection, /* If this is a reply we're waiting on, remove timeout for it */ reply_serial = dbus_message_get_reply_serial (message); - if (reply_serial != -1) + if (reply_serial != 0) { pending = _dbus_hash_table_lookup_int (connection->pending_replies, reply_serial); diff --git a/dbus/dbus-credentials.h b/dbus/dbus-credentials.h index d4c8d160..8eed2bd2 100644 --- a/dbus/dbus-credentials.h +++ b/dbus/dbus-credentials.h @@ -47,6 +47,9 @@ dbus_bool_t _dbus_credentials_add_unix_uid (DBusCredentials dbus_uid_t uid); dbus_bool_t _dbus_credentials_add_windows_sid (DBusCredentials *credentials, const char *windows_sid); +dbus_bool_t _dbus_credentials_add_adt_audit_data (DBusCredentials *credentials, + void *audit_data, + dbus_int32_t size); dbus_bool_t _dbus_credentials_include (DBusCredentials *credentials, DBusCredentialType type); dbus_pid_t _dbus_credentials_get_unix_pid (DBusCredentials *credentials); diff --git a/dbus/dbus-marshal-basic.c b/dbus/dbus-marshal-basic.c index 0a33ff15..38fbe2d6 100644 --- a/dbus/dbus-marshal-basic.c +++ b/dbus/dbus-marshal-basic.c @@ -508,59 +508,74 @@ _dbus_marshal_read_basic (const DBusString *str, int *new_pos) { const char *str_data; - DBusBasicValue *vp; _dbus_assert (dbus_type_is_basic (type)); str_data = _dbus_string_get_const_data (str); - vp = value; + /* Below we volatile types to avoid aliasing issues; + * see http://bugs.freedesktop.org/show_bug.cgi?id=20137 + */ + switch (type) { case DBUS_TYPE_BYTE: - vp->byt = _dbus_string_get_byte (str, pos); + { + volatile unsigned char *vp = value; + *vp = (unsigned char) _dbus_string_get_byte (str, pos); (pos)++; + } break; case DBUS_TYPE_INT16: case DBUS_TYPE_UINT16: + { + volatile dbus_uint16_t *vp = value; pos = _DBUS_ALIGN_VALUE (pos, 2); - vp->u16 = *(dbus_uint16_t *)(str_data + pos); + *vp = *(dbus_uint16_t *)(str_data + pos); if (byte_order != DBUS_COMPILER_BYTE_ORDER) - vp->u16 = DBUS_UINT16_SWAP_LE_BE (vp->u16); + *vp = DBUS_UINT16_SWAP_LE_BE (*vp); pos += 2; + } break; case DBUS_TYPE_INT32: case DBUS_TYPE_UINT32: case DBUS_TYPE_BOOLEAN: + { + volatile dbus_uint32_t *vp = value; pos = _DBUS_ALIGN_VALUE (pos, 4); - vp->u32 = *(dbus_uint32_t *)(str_data + pos); + *vp = *(dbus_uint32_t *)(str_data + pos); if (byte_order != DBUS_COMPILER_BYTE_ORDER) - vp->u32 = DBUS_UINT32_SWAP_LE_BE (vp->u32); + *vp = DBUS_UINT32_SWAP_LE_BE (*vp); pos += 4; + } break; case DBUS_TYPE_INT64: case DBUS_TYPE_UINT64: case DBUS_TYPE_DOUBLE: + { + volatile dbus_uint64_t *vp = value; pos = _DBUS_ALIGN_VALUE (pos, 8); #ifdef DBUS_HAVE_INT64 if (byte_order != DBUS_COMPILER_BYTE_ORDER) - vp->u64 = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos)); + *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos)); else - vp->u64 = *(dbus_uint64_t*)(str_data + pos); + *vp = *(dbus_uint64_t*)(str_data + pos); #else - vp->u64 = *(DBus8ByteStruct*) (str_data + pos); + *vp = *(DBus8ByteStruct*) (str_data + pos); swap_8_octets (vp, byte_order); #endif pos += 8; + } break; case DBUS_TYPE_STRING: case DBUS_TYPE_OBJECT_PATH: { int len; + volatile char **vp = value; len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos); - vp->str = (char*) str_data + pos; + *vp = (char*) str_data + pos; pos += len + 1; /* length plus nul */ } @@ -568,11 +583,12 @@ _dbus_marshal_read_basic (const DBusString *str, case DBUS_TYPE_SIGNATURE: { int len; + volatile char **vp = value; len = _dbus_string_get_byte (str, pos); pos += 1; - vp->str = (char*) str_data + pos; + *vp = (char*) str_data + pos; pos += len + 1; /* length plus nul */ } @@ -1333,7 +1349,7 @@ _dbus_verbose_bytes (const unsigned char *data, if (aligned != data) { - _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned); + _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned); while (aligned != data) { _dbus_verbose (" "); diff --git a/dbus/dbus-marshal-recursive.c b/dbus/dbus-marshal-recursive.c index 6c2902e2..76ee344f 100644 --- a/dbus/dbus-marshal-recursive.c +++ b/dbus/dbus-marshal-recursive.c @@ -1654,7 +1654,7 @@ writer_recurse_init_and_check (DBusTypeWriter *writer, _dbus_type_to_string (expected), _dbus_string_get_const_data (writer->type_str), writer->type_pos); else - _dbus_warn_check_failed ("Writing an element of type %s, but no value is expected here\n", + _dbus_warn_check_failed ("Writing an element of type %s, but no value is expected here\n" "The overall signature expected here was '%s' and we are on byte %d of that signature.\n", _dbus_type_to_string (sub->container_type), _dbus_string_get_const_data (writer->type_str), writer->type_pos); diff --git a/dbus/dbus-marshal-validate-util.c b/dbus/dbus-marshal-validate-util.c index f2901d74..ac901c38 100644 --- a/dbus/dbus-marshal-validate-util.c +++ b/dbus/dbus-marshal-validate-util.c @@ -227,7 +227,8 @@ _dbus_marshal_validate_test (void) "not a valid signature", "123", ".", - "(" + "(", + "a{(ii)i}" /* https://bugs.freedesktop.org/show_bug.cgi?id=17803 */ }; /* Signature with reason */ diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c index e63a463b..ee955485 100644 --- a/dbus/dbus-marshal-validate.c +++ b/dbus/dbus-marshal-validate.c @@ -246,13 +246,15 @@ _dbus_validate_signature_with_reason (const DBusString *type_str, } } - if (last == DBUS_DICT_ENTRY_BEGIN_CHAR && - !dbus_type_is_basic (*p)) + if (last == DBUS_DICT_ENTRY_BEGIN_CHAR) { - result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE; - goto out; + if (!(_dbus_type_is_valid (*p) && dbus_type_is_basic (*p))) + { + result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE; + goto out; + } } - + last = *p; ++p; } @@ -369,12 +371,30 @@ validate_body_helper (DBusTypeReader *reader, /* p may now be == end */ _dbus_assert (p <= end); - + if (current_type == DBUS_TYPE_ARRAY) { int array_elem_type = _dbus_type_reader_get_element_type (reader); + + if (!_dbus_type_is_valid (array_elem_type)) + { + return DBUS_INVALID_UNKNOWN_TYPECODE; + } + alignment = _dbus_type_get_alignment (array_elem_type); - p = _DBUS_ALIGN_ADDRESS (p, alignment); + + a = _DBUS_ALIGN_ADDRESS (p, alignment); + + /* a may now be == end */ + if (a > end) + return DBUS_INVALID_NOT_ENOUGH_DATA; + + while (p != a) + { + if (*p != '\0') + return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL; + ++p; + } } if (claimed_len > (unsigned long) (end - p)) @@ -405,6 +425,7 @@ validate_body_helper (DBusTypeReader *reader, DBusTypeReader sub; DBusValidity validity; const unsigned char *array_end; + int array_elem_type; if (claimed_len > DBUS_MAXIMUM_ARRAY_LENGTH) return DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM; @@ -417,16 +438,46 @@ validate_body_helper (DBusTypeReader *reader, array_end = p + claimed_len; - while (p < array_end) + array_elem_type = _dbus_type_reader_get_element_type (reader); + + /* avoid recursive call to validate_body_helper if this is an array + * of fixed-size elements + */ + if (dbus_type_is_fixed (array_elem_type)) + { + /* bools need to be handled differently, because they can + * have an invalid value + */ + if (array_elem_type == DBUS_TYPE_BOOLEAN) + { + dbus_uint32_t v; + alignment = _dbus_type_get_alignment (array_elem_type); + + while (p < array_end) + { + v = _dbus_unpack_uint32 (byte_order, p); + + if (!(v == 0 || v == 1)) + return DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE; + + p += alignment; + } + } + + else + { + p = array_end; + } + } + + else { - /* FIXME we are calling a function per array element! very bad - * need if (dbus_type_is_fixed(elem_type)) here to just skip - * big blocks of ints/bytes/etc. - */ - - validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p); - if (validity != DBUS_VALID) - return validity; + while (p < array_end) + { + validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p); + if (validity != DBUS_VALID) + return validity; + } } if (p != array_end) diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index cd447985..e2c4771e 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -1726,7 +1726,7 @@ _dbus_message_iter_init_common (DBusMessage *message, * * The easiest way to iterate is like this: * @code - * dbus_message_iter_init (&iter); + * dbus_message_iter_init (message, &iter); * while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) * dbus_message_iter_next (&iter); * @endcode diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c index 35ccba6c..f4e3b587 100644 --- a/dbus/dbus-spawn.c +++ b/dbus/dbus-spawn.c @@ -36,6 +36,8 @@ #include <errno.h> #endif +extern char **environ; + /** * @addtogroup DBusInternalsUtils * @{ @@ -914,8 +916,6 @@ do_exec (int child_err_report_fd, if (envp == NULL) { - extern char **environ; - _dbus_assert (environ != NULL); envp = environ; diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 1e45649f..29d234a4 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -79,8 +79,8 @@ #define O_BINARY 0 #endif -#ifndef _AI_ADDRCONFIG -#define _AI_ADDRCONFIG 0 +#ifndef AI_ADDRCONFIG +#define AI_ADDRCONFIG 0 #endif #ifndef HAVE_SOCKLEN_T @@ -758,6 +758,7 @@ _dbus_connect_tcp_socket (const char *host, const char *family, DBusError *error) { + int saved_errno = 0; int fd = -1, res; struct addrinfo hints; struct addrinfo *ai, *tmp; @@ -783,7 +784,7 @@ _dbus_connect_tcp_socket (const char *host, else { dbus_set_error (error, - _dbus_error_from_errno (errno), + DBUS_ERROR_BAD_ADDRESS, "Unknown address family %s", family); return -1; } @@ -814,6 +815,7 @@ _dbus_connect_tcp_socket (const char *host, if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) { + saved_errno = errno; _dbus_close(fd, NULL); fd = -1; tmp = tmp->ai_next; @@ -827,9 +829,9 @@ _dbus_connect_tcp_socket (const char *host, if (fd == -1) { dbus_set_error (error, - _dbus_error_from_errno (errno), + _dbus_error_from_errno (saved_errno), "Failed to connect to socket \"%s:%s\" %s", - host, port, _dbus_strerror(errno)); + host, port, _dbus_strerror(saved_errno)); return -1; } @@ -867,6 +869,7 @@ _dbus_listen_tcp_socket (const char *host, int **fds_p, DBusError *error) { + int saved_errno; int nlisten_fd = 0, *listen_fd = NULL, res, i; struct addrinfo hints; struct addrinfo *ai, *tmp; @@ -885,7 +888,7 @@ _dbus_listen_tcp_socket (const char *host, else { dbus_set_error (error, - _dbus_error_from_errno (errno), + DBUS_ERROR_BAD_ADDRESS, "Unknown address family %s", family); return -1; } @@ -917,8 +920,9 @@ _dbus_listen_tcp_socket (const char *host, if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) { + saved_errno = errno; _dbus_close(fd, NULL); - if (errno == EADDRINUSE) + if (saved_errno == EADDRINUSE) { /* Depending on kernel policy, it may or may not be neccessary to bind to both IPv4 & 6 addresses @@ -926,28 +930,30 @@ _dbus_listen_tcp_socket (const char *host, tmp = tmp->ai_next; continue; } - dbus_set_error (error, _dbus_error_from_errno (errno), + dbus_set_error (error, _dbus_error_from_errno (saved_errno), "Failed to bind socket \"%s:%s\": %s", - host ? host : "*", port, _dbus_strerror (errno)); + host ? host : "*", port, _dbus_strerror (saved_errno)); goto failed; } if (listen (fd, 30 /* backlog */) < 0) { + saved_errno = errno; _dbus_close (fd, NULL); - dbus_set_error (error, _dbus_error_from_errno (errno), + dbus_set_error (error, _dbus_error_from_errno (saved_errno), "Failed to listen on socket \"%s:%s\": %s", - host ? host : "*", port, _dbus_strerror (errno)); + host ? host : "*", port, _dbus_strerror (saved_errno)); goto failed; } newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1)); if (!newlisten_fd) { + saved_errno = errno; _dbus_close (fd, NULL); - dbus_set_error (error, _dbus_error_from_errno (errno), + dbus_set_error (error, _dbus_error_from_errno (saved_errno), "Failed to allocate file handle array: %s", - _dbus_strerror (errno)); + _dbus_strerror (saved_errno)); goto failed; } listen_fd = newlisten_fd; @@ -1493,7 +1499,11 @@ fill_user_info (DBusUserInfo *info, /* retrieve maximum needed size for buf */ buflen = sysconf (_SC_GETPW_R_SIZE_MAX); - if (buflen <= 0) + /* sysconf actually returns a long, but everything else expects size_t, + * so just recast here. + * https://bugs.freedesktop.org/show_bug.cgi?id=17061 + */ + if ((long) buflen <= 0) buflen = 1024; result = -1; @@ -2224,6 +2234,15 @@ _dbus_string_save_to_file (const DBusString *str, total += bytes_written; } + if (fsync(fd)) + { + dbus_set_error (error, _dbus_error_from_errno (errno), + "Could not synchronize file %s: %s", + tmp_filename_c, _dbus_strerror (errno)); + + goto out; + } + if (!_dbus_close (fd, NULL)) { dbus_set_error (error, _dbus_error_from_errno (errno), @@ -2767,7 +2786,6 @@ _dbus_full_duplex_pipe (int *fd1, #endif } - /** * Measure the length of the given format string and arguments, * not including the terminating nul. diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c index 55eb9346..df9f7116 100644 --- a/dbus/dbus-sysdeps-util-unix.c +++ b/dbus/dbus-sysdeps-util-unix.c @@ -43,6 +43,8 @@ #include <sys/socket.h> #include <dirent.h> #include <sys/un.h> +#include <syslog.h> +#include <syslog.h> #ifdef HAVE_LIBAUDIT #include <sys/prctl.h> #include <sys/capability.h> @@ -69,12 +71,14 @@ * @param pidfile #NULL, or pidfile to create * @param print_pid_pipe pipe to print daemon's pid to, or -1 for none * @param error return location for errors + * @param keep_umask #TRUE to keep the original umask * @returns #FALSE on failure */ dbus_bool_t _dbus_become_daemon (const DBusString *pidfile, DBusPipe *print_pid_pipe, - DBusError *error) + DBusError *error, + dbus_bool_t keep_umask) { const char *s; pid_t child_pid; @@ -121,9 +125,12 @@ _dbus_become_daemon (const DBusString *pidfile, _dbus_verbose ("keeping stderr open due to DBUS_DEBUG_OUTPUT\n"); } - /* Get a predictable umask */ - _dbus_verbose ("setting umask\n"); - umask (022); + if (!keep_umask) + { + /* Get a predictable umask */ + _dbus_verbose ("setting umask\n"); + umask (022); + } _dbus_verbose ("calling setsid()\n"); if (setsid () == -1) @@ -451,6 +458,38 @@ _dbus_change_to_daemon_user (const char *user, return FALSE; } +void +_dbus_init_system_log (void) +{ + openlog ("dbus", LOG_PID, LOG_DAEMON); +} + +/** + * Log an informative message. Intended for use primarily by + * the system bus. + * + * @param msg a printf-style format string + * @param args arguments for the format string + */ +void +_dbus_log_info (const char *msg, va_list args) +{ + vsyslog (LOG_DAEMON|LOG_NOTICE, msg, args); +} + +/** + * Log a security-related message. Intended for use primarily by + * the system bus. + * + * @param msg a printf-style format string + * @param args arguments for the format string + */ +void +_dbus_log_security (const char *msg, va_list args) +{ + vsyslog (LOG_AUTH|LOG_NOTICE, msg, args); +} + /** Installs a UNIX signal handler * * @param sig the signal to handle @@ -836,7 +875,11 @@ fill_group_info (DBusGroupInfo *info, /* retrieve maximum needed size for buf */ buflen = sysconf (_SC_GETGR_R_SIZE_MAX); - if (buflen <= 0) + /* sysconf actually returns a long, but everything else expects size_t, + * so just recast here. + * https://bugs.freedesktop.org/show_bug.cgi?id=17061 + */ + if ((long) buflen <= 0) buflen = 1024; result = -1; @@ -1096,3 +1139,99 @@ _dbus_string_get_dirname (const DBusString *filename, } /** @} */ /* DBusString stuff */ +static void +string_squash_nonprintable (DBusString *str) +{ + char *buf; + int i, len; + + buf = _dbus_string_get_data (str); + len = _dbus_string_get_length (str); + + for (i = 0; i < len; i++) + if (buf[i] == '\0') + buf[i] = ' '; + else if (buf[i] < 0x20 || buf[i] > 127) + buf[i] = '?'; +} + +/** + * Get a printable string describing the command used to execute + * the process with pid. This string should only be used for + * informative purposes such as logging; it may not be trusted. + * + * The command is guaranteed to be printable ASCII and no longer + * than max_len. + * + * @param pid Process id + * @param str Append command to this string + * @param max_len Maximum length of returned command + * @param error return location for errors + * @returns #FALSE on error + */ +dbus_bool_t +_dbus_command_for_pid (unsigned long pid, + DBusString *str, + int max_len, + DBusError *error) +{ + /* This is all Linux-specific for now */ + DBusString path; + DBusString cmdline; + int fd; + + if (!_dbus_string_init (&path)) + { + _DBUS_SET_OOM (error); + return FALSE; + } + + if (!_dbus_string_init (&cmdline)) + { + _DBUS_SET_OOM (error); + _dbus_string_free (&path); + return FALSE; + } + + if (!_dbus_string_append_printf (&path, "/proc/%ld/cmdline", pid)) + goto oom; + + fd = open (_dbus_string_get_const_data (&path), O_RDONLY); + if (fd < 0) + { + dbus_set_error (error, + _dbus_error_from_errno (errno), + "Failed to open \"%s\": %s", + _dbus_string_get_const_data (&path), + _dbus_strerror (errno)); + goto fail; + } + + if (!_dbus_read (fd, &cmdline, max_len)) + { + dbus_set_error (error, + _dbus_error_from_errno (errno), + "Failed to read from \"%s\": %s", + _dbus_string_get_const_data (&path), + _dbus_strerror (errno)); + goto fail; + } + + if (!_dbus_close (fd, error)) + goto fail; + + string_squash_nonprintable (&cmdline); + + if (!_dbus_string_copy (&cmdline, 0, str, _dbus_string_get_length (str))) + goto oom; + + _dbus_string_free (&cmdline); + _dbus_string_free (&path); + return TRUE; +oom: + _DBUS_SET_OOM (error); +fail: + _dbus_string_free (&cmdline); + _dbus_string_free (&path); + return FALSE; +}
\ No newline at end of file diff --git a/dbus/dbus-sysdeps-util-win.c b/dbus/dbus-sysdeps-util-win.c index 8608ad0e..6358531b 100644 --- a/dbus/dbus-sysdeps-util-win.c +++ b/dbus/dbus-sysdeps-util-win.c @@ -70,12 +70,14 @@ errno_t strcpy_s(char *dest, size_t size, char *src) * @param pidfile #NULL, or pidfile to create * @param print_pid_fd file descriptor to print daemon's pid to, or -1 for none * @param error return location for errors + * @param keep_umask #TRUE to keep the original umask * @returns #FALSE on failure */ dbus_bool_t _dbus_become_daemon (const DBusString *pidfile, DBusPipe *print_pid_pipe, - DBusError *error) + DBusError *error, + dbus_bool_t keep_umask) { return TRUE; } diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index d740f875..00a1a3de 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -51,6 +51,8 @@ _DBUS_DEFINE_GLOBAL_LOCK (win_fds); _DBUS_DEFINE_GLOBAL_LOCK (sid_atom_cache); _DBUS_DEFINE_GLOBAL_LOCK (system_users); +extern char **environ; + /** * @defgroup DBusSysdeps Internal system-dependent API * @ingroup DBusInternals @@ -191,7 +193,6 @@ _dbus_clearenv (void) if (clearenv () != 0) rc = FALSE; #else - extern char **environ; if (environ != NULL) environ[0] = NULL; @@ -210,7 +211,6 @@ char ** _dbus_get_environment (void) { int i, length; - extern char **environ; char **environment; _dbus_assert (environ != NULL); diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 80236f05..b766f3f9 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -400,7 +400,8 @@ void _dbus_print_backtrace (void); dbus_bool_t _dbus_become_daemon (const DBusString *pidfile, DBusPipe *print_pid_pipe, - DBusError *error); + DBusError *error, + dbus_bool_t keep_umask); dbus_bool_t _dbus_verify_daemon_user (const char *user); dbus_bool_t _dbus_change_to_daemon_user (const char *user, @@ -411,6 +412,11 @@ dbus_bool_t _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile, dbus_pid_t pid_to_write, DBusError *error); +dbus_bool_t _dbus_command_for_pid (unsigned long pid, + DBusString *str, + int max_len, + DBusError *error); + /** A UNIX signal handler */ typedef void (* DBusSignalHandler) (int sig); @@ -420,6 +426,10 @@ void _dbus_set_signal_handler (int sig, dbus_bool_t _dbus_user_at_console (const char *username, DBusError *error); +void _dbus_init_system_log (void); +void _dbus_log_info (const char *msg, va_list args); +void _dbus_log_security (const char *msg, va_list args); + /* Define DBUS_VA_COPY() to do the right thing for copying va_list variables. * config.h may have already defined DBUS_VA_COPY as va_copy or __va_copy. */ diff --git a/doc/busconfig.dtd b/doc/busconfig.dtd index 84593fe0..0cc519b4 100644 --- a/doc/busconfig.dtd +++ b/doc/busconfig.dtd @@ -1,6 +1,7 @@ <!ELEMENT busconfig (user | type | fork | + keep_umask | listen | pidfile | includedir | @@ -21,6 +22,7 @@ <!ELEMENT type (#PCDATA)> <!ELEMENT pidfile (#PCDATA)> <!ELEMENT fork EMPTY> +<!ELEMENT keep_umask EMPTY> <!ELEMENT include (#PCDATA)> <!ATTLIST include diff --git a/test/name-test/Makefile.am b/test/name-test/Makefile.am index 17e05bec..10a2536d 100644 --- a/test/name-test/Makefile.am +++ b/test/name-test/Makefile.am @@ -5,12 +5,12 @@ INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) $(DBUS_TEST_C ## TESTS if DBUS_BUILD_TESTS TESTS_ENVIRONMENT=DBUS_TOP_BUILDDIR=@abs_top_builddir@ DBUS_TOP_SRCDIR=@abs_top_srcdir@ -TESTS=run-test.sh +TESTS=run-test.sh run-test-systemserver.sh else TESTS= endif -EXTRA_DIST=run-test.sh +EXTRA_DIST=run-test.sh run-test-systemserver.sh test-wait-for-echo.py if DBUS_BUILD_TESTS diff --git a/test/name-test/run-test-systemserver.sh b/test/name-test/run-test-systemserver.sh new file mode 100755 index 00000000..34dd6487 --- /dev/null +++ b/test/name-test/run-test-systemserver.sh @@ -0,0 +1,50 @@ +#! /bin/sh +die() +{ + if ! test -z "$DBUS_SESSION_BUS_PID" ; then + echo "killing message bus "$DBUS_SESSION_BUS_PID >&2 + kill -9 $DBUS_SESSION_BUS_PID + fi + echo $SCRIPTNAME: $* >&2 + + exit 1 +} + +SCRIPTNAME=$0 +MODE=$1 + +## so the tests can complain if you fail to use the script to launch them +DBUS_TEST_NAME_RUN_TEST_SCRIPT=1 +export DBUS_TEST_NAME_RUN_TEST_SCRIPT + +SOURCE_CONFIG_FILE=$DBUS_TOP_SRCDIR/test/name-test/tmp-session-like-system.conf +export SOURCE_CONFIG_FILE +# Rerun ourselves with tmp session bus if we're not already +if test -z "$DBUS_TEST_NAME_IN_SYS_RUN_TEST"; then + DBUS_TEST_NAME_IN_SYS_RUN_TEST=1 + export DBUS_TEST_NAME_IN_SYS_RUN_TEST + exec $DBUS_TOP_SRCDIR/tools/run-with-tmp-session-bus.sh $SCRIPTNAME $MODE +fi + +if test -n "$DBUS_TEST_MONITOR"; then + dbus-monitor --session & +fi + +echo "running test-expected-echo-fail" +${DBUS_TOP_BUILDDIR}/libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/tools/dbus-send --print-reply --dest=org.freedesktop.DBus.TestSuiteEchoService /org/freedesktop/TestSuite org.freedesktop.TestSuite.Echo string:hi >echo-error-output.tmp 2>&1 +if ! grep -q 'DBus.Error' echo-error-output.tmp; then + echo "Didn't get expected failure; output was:" + echo "=====" + cat echo-error-output.tmp + echo "=====" + exit 1 +fi + +echo "running test echo signal" +if ! python ./test-wait-for-echo.py; then + echo "Failed test-wait-for-echo" + exit 1 +fi + + +exit 0 diff --git a/test/name-test/test-wait-for-echo.py b/test/name-test/test-wait-for-echo.py new file mode 100755 index 00000000..bd09e459 --- /dev/null +++ b/test/name-test/test-wait-for-echo.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python + +import os,sys + +try: + import gobject + import dbus + import dbus.mainloop.glib +except: + print "Failed import, aborting test" + sys.exit(0) + +dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) +loop = gobject.MainLoop() + +exitcode = 0 + +def handle_noreceipt(): + print "Failed to get signal" + global exitcode + exitcode = 1 + loop.quit() + +gobject.timeout_add(7000, handle_noreceipt) + +bus = dbus.SessionBus() + +def sighandler(*args, **kwargs): + print "got signal" + loop.quit() + +bus.add_signal_receiver(sighandler, dbus_interface='org.freedesktop.TestSuite', signal_name='Foo') + +o = bus.get_object('org.freedesktop.DBus.TestSuiteEchoService', '/org/freedesktop/TestSuite') +i = dbus.Interface(o, 'org.freedesktop.TestSuite') +def nullhandler(*args, **kwargs): + pass +i.EmitFoo(reply_handler=nullhandler, error_handler=nullhandler) + +loop.run() +sys.exit(exitcode) diff --git a/test/name-test/tmp-session-like-system.conf b/test/name-test/tmp-session-like-system.conf new file mode 100644 index 00000000..29ab115f --- /dev/null +++ b/test/name-test/tmp-session-like-system.conf @@ -0,0 +1,91 @@ +<!-- This configuration file controls the per-user-login-session message bus. + Add a session-local.conf and edit that rather than changing this + file directly. --> + +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <!-- Our well-known bus type, don't change this --> + <type>session</type> + + <!-- If we fork, keep the user's original umask to avoid affecting + the behavior of child processes. --> + <keep_umask/> + + <syslog/> + + <listen>unix:tmpdir=/tmp</listen> + + <standard_session_servicedirs /> + + <!-- intended to match system bus --> + <policy context="default"> + <!-- All users can connect to system bus --> + <allow user="*"/> + + <!-- Holes must be punched in service configuration files for + name ownership and sending method calls --> + <deny own="*"/> + <deny send_type="method_call"/> + + <!-- Signals and reply messages (method returns, errors) are allowed + by default --> + <allow send_type="signal"/> + <allow send_requested_reply="true" send_type="method_return"/> + <allow send_requested_reply="true" send_type="error"/> + + <!-- All messages may be received by default --> + <allow receive_type="method_call"/> + <allow receive_type="method_return"/> + <allow receive_type="error"/> + <allow receive_type="signal"/> + + <!-- Allow anyone to talk to the message bus --> + <allow send_destination="org.freedesktop.DBus"/> + <!-- But disallow some specific bus services --> + <deny send_destination="org.freedesktop.DBus" + send_interface="org.freedesktop.DBus" + send_member="UpdateActivationEnvironment"/> + + <!-- Specific to the test suite --> + <allow own="org.freedesktop.DBus.TestSuiteEchoService"/> + <allow send_destination="org.freedesktop.DBus.TestSuiteEchoService" + send_interface="org.freedesktop.DBus.Introspectable"/> + <allow send_destination="org.freedesktop.DBus.TestSuiteEchoService" + send_interface="org.freedesktop.TestSuite" + send_member="EmitFoo"/> + </policy> + + <policy context="default"> + <allow own="org.freedesktop.DBus.TestSuiteEchoService"/> + <allow send_destination="org.freedesktop.DBus.TestSuiteEchoService" + send_interface="org.freedesktop.DBus.Introspectable"/> + <allow send_destination="org.freedesktop.DBus.TestSuiteEchoService" + send_interface="org.freedesktop.TestSuite" + send_member="EmitFoo"/> + </policy> + + <!-- For the session bus, override the default relatively-low limits + with essentially infinite limits, since the bus is just running + as the user anyway, using up bus resources is not something we need + to worry about. In some cases, we do set the limits lower than + "all available memory" if exceeding the limit is almost certainly a bug, + having the bus enforce a limit is nicer than a huge memory leak. But the + intent is that these limits should never be hit. --> + + <!-- the memory limits are 1G instead of say 4G because they can't exceed 32-bit signed int max --> + <limit name="max_incoming_bytes">1000000000</limit> + <limit name="max_outgoing_bytes">1000000000</limit> + <limit name="max_message_size">1000000000</limit> + <limit name="service_start_timeout">120000</limit> + <limit name="auth_timeout">240000</limit> + <limit name="max_completed_connections">100000</limit> + <limit name="max_incomplete_connections">10000</limit> + <limit name="max_connections_per_user">100000</limit> + <limit name="max_pending_service_starts">10000</limit> + <limit name="max_names_per_connection">50000</limit> + <limit name="max_match_rules_per_connection">50000</limit> + <limit name="max_replies_per_connection">50000</limit> + <limit name="reply_timeout">300000</limit> + +</busconfig> diff --git a/tools/dbus-launch-x11.c b/tools/dbus-launch-x11.c index 442e9ba2..b1824181 100644 --- a/tools/dbus-launch-x11.c +++ b/tools/dbus-launch-x11.c @@ -361,9 +361,9 @@ set_address_in_x11(char *address, pid_t pid) } /* Create our window */ - wid = XCreateSimpleWindow (xdisplay, RootWindow (xdisplay, 0), -20, -20, 10, 10, - 0, WhitePixel (xdisplay, 0), - BlackPixel (xdisplay, 0)); + wid = XCreateWindow (xdisplay, RootWindow (xdisplay, 0), -20, -20, 10, 10, + 0, CopyFromParent, InputOnly, CopyFromParent, + 0, NULL); verbose ("Created window %d\n", wid); /* Save the property in the window */ diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c index 216f7435..139d0aaf 100644 --- a/tools/dbus-launch.c +++ b/tools/dbus-launch.c @@ -402,7 +402,9 @@ signal_handler (int sig) { switch (sig) { +#ifdef SIGHUP case SIGHUP: +#endif case SIGTERM: got_sighup = TRUE; break; diff --git a/tools/dbus-print-message.c b/tools/dbus-print-message.c index d5fced34..ea15769f 100644 --- a/tools/dbus-print-message.c +++ b/tools/dbus-print-message.c @@ -263,7 +263,8 @@ print_message (DBusMessage *message, dbus_bool_t literal) { case DBUS_MESSAGE_TYPE_METHOD_CALL: case DBUS_MESSAGE_TYPE_SIGNAL: - printf (" path=%s; interface=%s; member=%s\n", + printf (" serial=%u path=%s; interface=%s; member=%s\n", + dbus_message_get_serial (message), dbus_message_get_path (message), dbus_message_get_interface (message), dbus_message_get_member (message)); diff --git a/tools/dbus-send.c b/tools/dbus-send.c index 407c0497..81a9c372 100644 --- a/tools/dbus-send.c +++ b/tools/dbus-send.c @@ -33,7 +33,7 @@ static const char *appname; static void usage (int ecode) { - fprintf (stderr, "Usage: %s [--help] [--system | --session] [--dest=NAME] [--type=TYPE] [--print-reply=(literal)] [--reply-timeout=MSEC] <destination object path> <message name> [contents ...]\n", appname); + fprintf (stderr, "Usage: %s [--help] [--system | --session | --address=ADDRESS] [--dest=NAME] [--type=TYPE] [--print-reply=(literal)] [--reply-timeout=MSEC] <destination object path> <message name> [contents ...]\n", appname); exit (ecode); } @@ -222,6 +222,8 @@ main (int argc, char *argv[]) const char *path = NULL; int message_type = DBUS_MESSAGE_TYPE_SIGNAL; const char *type_str = NULL; + const char *address = NULL; + int session_or_system = FALSE; appname = argv[0]; @@ -237,9 +239,29 @@ main (int argc, char *argv[]) char *arg = argv[i]; if (strcmp (arg, "--system") == 0) - type = DBUS_BUS_SYSTEM; + { + type = DBUS_BUS_SYSTEM; + session_or_system = TRUE; + } else if (strcmp (arg, "--session") == 0) - type = DBUS_BUS_SESSION; + { + type = DBUS_BUS_SESSION; + session_or_system = TRUE; + } + else if (strstr (arg, "--address") == arg) + { + address = strchr (arg, '='); + + if (address == NULL) + { + fprintf (stderr, "\"--address=\" requires an ADDRESS\n"); + usage (1); + } + else + { + address = address + 1; + } + } else if (strncmp (arg, "--print-reply", 13) == 0) { print_reply = TRUE; @@ -271,6 +293,13 @@ main (int argc, char *argv[]) if (name == NULL) usage (1); + if (session_or_system && + (address != NULL)) + { + fprintf (stderr, "\"--address\" may not be used with \"--system\" or \"--session\"\n"); + usage (1); + } + if (type_str != NULL) { message_type = dbus_message_type_from_string (type_str); @@ -284,11 +313,21 @@ main (int argc, char *argv[]) } dbus_error_init (&error); - connection = dbus_bus_get (type, &error); + + if (address != NULL) + { + connection = dbus_connection_open (address, &error); + } + else + { + connection = dbus_bus_get (type, &error); + } + if (connection == NULL) { - fprintf (stderr, "Failed to open connection to %s message bus: %s\n", - (type == DBUS_BUS_SYSTEM) ? "system" : "session", + fprintf (stderr, "Failed to open connection to \"%s\" message bus: %s\n", + (address != NULL) ? address : + ((type == DBUS_BUS_SYSTEM) ? "system" : "session"), error.message); dbus_error_free (&error); exit (1); diff --git a/tools/run-with-tmp-session-bus.sh b/tools/run-with-tmp-session-bus.sh index f95ee62e..982184a2 100755 --- a/tools/run-with-tmp-session-bus.sh +++ b/tools/run-with-tmp-session-bus.sh @@ -26,8 +26,11 @@ SERVICE_DIR="$DBUS_TOP_BUILDDIR/test/data/valid-service-files" ESCAPED_SERVICE_DIR=`echo $SERVICE_DIR | sed -e 's/\//\\\\\\//g'` echo "escaped service dir is: $ESCAPED_SERVICE_DIR" >&2 +if test -z "$SOURCE_CONFIG_FILE"; then + SOURCE_CONFIG_FILE="$DBUS_TOP_BUILDDIR/bus/session.conf"; +fi ## create a configuration file based on the standard session.conf -cat $DBUS_TOP_BUILDDIR/bus/session.conf | \ +cat $SOURCE_CONFIG_FILE | \ sed -e 's/<standard_session_servicedirs.*$/<servicedir>'$ESCAPED_SERVICE_DIR'<\/servicedir>/g' | \ sed -e 's/<include.*$//g' \ > $CONFIG_FILE |