summaryrefslogtreecommitdiffstats
path: root/meta-app-framework/recipes-core/dbus-cynagora/dbus-cynagora/0002-Disable-message-dispatching-when-send-rule-result-is.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-app-framework/recipes-core/dbus-cynagora/dbus-cynagora/0002-Disable-message-dispatching-when-send-rule-result-is.patch')
-rw-r--r--meta-app-framework/recipes-core/dbus-cynagora/dbus-cynagora/0002-Disable-message-dispatching-when-send-rule-result-is.patch967
1 files changed, 0 insertions, 967 deletions
diff --git a/meta-app-framework/recipes-core/dbus-cynagora/dbus-cynagora/0002-Disable-message-dispatching-when-send-rule-result-is.patch b/meta-app-framework/recipes-core/dbus-cynagora/dbus-cynagora/0002-Disable-message-dispatching-when-send-rule-result-is.patch
deleted file mode 100644
index bac8cf97f..000000000
--- a/meta-app-framework/recipes-core/dbus-cynagora/dbus-cynagora/0002-Disable-message-dispatching-when-send-rule-result-is.patch
+++ /dev/null
@@ -1,967 +0,0 @@
-From c2f4ba585c777b731df6b6b8a165b6cc4dc5d639 Mon Sep 17 00:00:00 2001
-From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Date: Fri, 28 Nov 2014 12:07:39 +0100
-Subject: [PATCH 2/8] Disable message dispatching when send rule result is not
- known
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When unicast message is sent to addressed recipient and policy result
-is not available message dispatch from the sender is disabled.
-This also means that any further messages from the given connection are
-put into the incoming queue without being processed. If response is received
-message dispatching is resumed. This time answer is attached to the message
-which is now processed synchronously.
-Receive rule result unavailability is not yet handled - such messages are
-rejected. Also, if message is sent to non-addressed recipient and policy result
-is unknown, message is silently dropped.
-
-Cherry-picked from b1b87ad9f20b2052c28431b48e81073078a745ce
-by Jose Bollo.
-
-Updated for dbus 1.10.20 by Scott Murray and José Bollo
-
-Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-Signed-off-by: Scott Murray <scott.murray@konsulko.com>
----
- bus/activation.c | 76 +++++++++++--
- bus/check.c | 109 +++++++++++++++++--
- bus/check.h | 10 ++
- bus/cynara.c | 1 -
- bus/dispatch.c | 184 ++++++++++++++++++++++++++++----
- bus/dispatch.h | 2 +-
- bus/driver.c | 12 ++-
- dbus/dbus-connection-internal.h | 15 +++
- dbus/dbus-connection.c | 125 +++++++++++++++++++++-
- dbus/dbus-list.c | 29 +++++
- dbus/dbus-list.h | 3 +
- dbus/dbus-shared.h | 3 +-
- 12 files changed, 528 insertions(+), 41 deletions(-)
-
-diff --git a/bus/activation.c b/bus/activation.c
-index f9c6c62..8301b59 100644
---- a/bus/activation.c
-+++ b/bus/activation.c
-@@ -32,6 +32,7 @@
- #include "services.h"
- #include "test.h"
- #include "utils.h"
-+#include <dbus/dbus-connection-internal.h>
- #include <dbus/dbus-internals.h>
- #include <dbus/dbus-hash.h>
- #include <dbus/dbus-list.h>
-@@ -94,6 +95,8 @@ struct BusPendingActivationEntry
- DBusConnection *connection;
-
- dbus_bool_t auto_activation;
-+
-+ dbus_bool_t is_put_back;
- };
-
- typedef struct
-@@ -1241,20 +1244,23 @@ bus_activation_send_pending_auto_activation_messages (BusActivation *activation
- BusPendingActivationEntry *entry = link->data;
- DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
-
-- if (entry->auto_activation && (entry->connection == NULL || dbus_connection_get_is_connected (entry->connection)))
-+ if (entry->auto_activation && !entry->is_put_back &&
-+ (entry->connection == NULL || dbus_connection_get_is_connected (entry->connection)))
- {
- DBusConnection *addressed_recipient;
- DBusError error;
-+ BusResult res;
-
- dbus_error_init (&error);
-
- addressed_recipient = bus_service_get_primary_owners_connection (service);
-
- /* Resume dispatching where we left off in bus_dispatch() */
-- if (!bus_dispatch_matches (transaction,
-- entry->connection,
-- addressed_recipient,
-- entry->activation_message, &error))
-+ res = bus_dispatch_matches (transaction,
-+ entry->connection,
-+ addressed_recipient,
-+ entry->activation_message, &error);
-+ if (res == BUS_RESULT_FALSE)
- {
- /* If permission is denied, we just want to return the error
- * to the original method invoker; in particular, we don't
-@@ -1266,11 +1272,44 @@ bus_activation_send_pending_auto_activation_messages (BusActivation *activation
- bus_connection_send_oom_error (entry->connection,
- entry->activation_message);
- }
--
- dbus_error_free (&error);
- link = next;
- continue;
- }
-+ else if (res == BUS_RESULT_LATER)
-+ {
-+ DBusList *putback_message_link = link;
-+ DBusMessage *last_inserted_message = NULL;
-+
-+ /* NULL entry->connection implies sending pending ActivationRequest message to systemd */
-+ if (entry->connection == NULL)
-+ {
-+ _dbus_assert_not_reached ("bus_dispatch_matches returned BUS_RESULT_LATER unexpectedly when sender is NULL");
-+ link = next;
-+ continue;
-+ }
-+
-+ /**
-+ * Getting here means that policy check result is not yet available and dispatching
-+ * messages from entry->connection has been disabled.
-+ * Let's put back all messages for the given connection in the incoming queue and mark
-+ * this entry as put back so they are not handled twice.
-+ */
-+ while (putback_message_link != NULL)
-+ {
-+ BusPendingActivationEntry *putback_message = putback_message_link->data;
-+ if (putback_message->connection == entry->connection)
-+ {
-+ if (!_dbus_connection_putback_message (putback_message->connection, last_inserted_message,
-+ putback_message->activation_message, &error))
-+ goto error;
-+ last_inserted_message = putback_message->activation_message;
-+ putback_message->is_put_back = TRUE;
-+ }
-+
-+ putback_message_link = _dbus_list_get_next_link(&pending_activation->entries, putback_message_link);
-+ }
-+ }
- }
-
- link = next;
-@@ -1287,6 +1326,19 @@ bus_activation_send_pending_auto_activation_messages (BusActivation *activation
- return TRUE;
-
- error:
-+ /* remove all messages that have been put to connections' incoming queues */
-+ link = _dbus_list_get_first_link (&pending_activation->entries);
-+ while (link != NULL)
-+ {
-+ BusPendingActivationEntry *entry = link->data;
-+ if (entry->is_put_back)
-+ {
-+ _dbus_connection_remove_message(entry->connection, entry->activation_message);
-+ entry->is_put_back = FALSE;
-+ }
-+ link = _dbus_list_get_next_link(&pending_activation->entries, link);
-+ }
-+
- return FALSE;
- }
-
-@@ -2079,6 +2131,7 @@ bus_activation_activate_service (BusActivation *activation,
-
- if (service != NULL)
- {
-+ BusResult res;
- bus_context_log (activation->context,
- DBUS_SYSTEM_LOG_INFO, "Activating via systemd: service name='%s' unit='%s' requested by '%s' (%s)",
- service_name,
-@@ -2086,8 +2139,17 @@ bus_activation_activate_service (BusActivation *activation,
- bus_connection_get_name (connection),
- bus_connection_get_loginfo (connection));
- /* Wonderful, systemd is connected, let's just send the msg */
-- retval = bus_dispatch_matches (activation_transaction, NULL,
-+ res = bus_dispatch_matches (activation_transaction, NULL,
- systemd, message, error);
-+
-+ if (res == BUS_RESULT_TRUE)
-+ retval = TRUE;
-+ else
-+ {
-+ retval = FALSE;
-+ if (res == BUS_RESULT_LATER)
-+ _dbus_verbose("Unexpectedly need time to check message from bus driver to systemd - dropping the message.\n");
-+ }
- }
- else
- {
-diff --git a/bus/check.c b/bus/check.c
-index 5b72d31..4b8a699 100644
---- a/bus/check.c
-+++ b/bus/check.c
-@@ -55,6 +55,8 @@ typedef struct BusDeferredMessage
- BusCheckResponseFunc response_callback;
- } BusDeferredMessage;
-
-+static dbus_int32_t deferred_message_data_slot = -1;
-+
- BusCheck *
- bus_check_new (BusContext *context, DBusError *error)
- {
-@@ -67,11 +69,19 @@ bus_check_new (BusContext *context, DBusError *error)
- return NULL;
- }
-
-+ if (!dbus_message_allocate_data_slot(&deferred_message_data_slot))
-+ {
-+ dbus_free(check);
-+ BUS_SET_OOM(error);
-+ return NULL;
-+ }
-+
- check->refcount = 1;
- check->context = context;
- check->cynara = bus_cynara_new(check, error);
- if (dbus_error_is_set(error))
- {
-+ dbus_message_free_data_slot(&deferred_message_data_slot);
- dbus_free(check);
- return NULL;
- }
-@@ -98,6 +108,7 @@ bus_check_unref (BusCheck *check)
- if (check->refcount == 0)
- {
- bus_cynara_unref(check->cynara);
-+ dbus_message_free_data_slot(&deferred_message_data_slot);
- dbus_free(check);
- }
- }
-@@ -114,6 +125,45 @@ bus_check_get_cynara (BusCheck *check)
- return check->cynara;
- }
-
-+static void
-+bus_check_enable_dispatch_callback (BusDeferredMessage *deferred_message,
-+ BusResult result)
-+{
-+ _dbus_verbose("bus_check_enable_dispatch_callback called deferred_message=%p\n", deferred_message);
-+
-+ deferred_message->response = result;
-+ _dbus_connection_enable_dispatch(deferred_message->sender);
-+}
-+
-+static void
-+deferred_message_free_function(void *data)
-+{
-+ BusDeferredMessage *deferred_message = (BusDeferredMessage *)data;
-+ bus_deferred_message_unref(deferred_message);
-+}
-+
-+void
-+bus_deferred_message_disable_sender (BusDeferredMessage *deferred_message)
-+{
-+ _dbus_assert(deferred_message != NULL);
-+ _dbus_assert(deferred_message->sender != NULL);
-+
-+ if (dbus_message_get_data(deferred_message->message, deferred_message_data_slot) == NULL)
-+ {
-+ if (dbus_message_set_data(deferred_message->message, deferred_message_data_slot, deferred_message,
-+ deferred_message_free_function))
-+ bus_deferred_message_ref(deferred_message);
-+ }
-+
-+ _dbus_connection_disable_dispatch(deferred_message->sender);
-+ deferred_message->response_callback = bus_check_enable_dispatch_callback;
-+}
-+
-+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
-+BusResult (*bus_check_test_override) (DBusConnection *connection,
-+ const char *privilege);
-+#endif
-+
- BusResult
- bus_check_privilege (BusCheck *check,
- DBusMessage *message,
-@@ -124,6 +174,7 @@ bus_check_privilege (BusCheck *check,
- BusDeferredMessageStatus check_type,
- BusDeferredMessage **deferred_message)
- {
-+ BusDeferredMessage *previous_deferred_message;
- BusResult result = BUS_RESULT_FALSE;
- #ifdef DBUS_ENABLE_CYNARA
- BusCynara *cynara;
-@@ -137,16 +188,54 @@ bus_check_privilege (BusCheck *check,
- return BUS_RESULT_FALSE;
- }
-
-- /* ask policy checkers */
--#ifdef DBUS_ENABLE_CYNARA
-- cynara = bus_check_get_cynara(check);
-- result = bus_cynara_check_privilege(cynara, message, sender, addressed_recipient,
-- proposed_recipient, privilege, check_type, deferred_message);
-+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
-+ if (bus_check_test_override)
-+ return bus_check_test_override (connection, privilege);
- #endif
-
-- if (result == BUS_RESULT_LATER && deferred_message != NULL)
-+ previous_deferred_message = dbus_message_get_data(message, deferred_message_data_slot);
-+ /* check if message blocked at sender's queue is being processed */
-+ if (previous_deferred_message != NULL)
-+ {
-+ if ((check_type & BUS_DEFERRED_MESSAGE_CHECK_SEND) &&
-+ !(previous_deferred_message->status & BUS_DEFERRED_MESSAGE_CHECK_SEND))
-+ {
-+ /**
-+ * Message has been deferred due to receive or own rule which means that sending this message
-+ * is allowed - it must have been checked previously.
-+ * This might happen when client calls RequestName method which depending on security
-+ * policy might result in both "can_send" and "can_own" Cynara checks.
-+ */
-+ result = BUS_RESULT_TRUE;
-+ }
-+ else
-+ {
-+ result = previous_deferred_message->response;
-+ if (result == BUS_RESULT_LATER)
-+ {
-+ /* result is still not known - reuse deferred message object */
-+ if (deferred_message != NULL)
-+ *deferred_message = previous_deferred_message;
-+ }
-+ else
-+ {
-+ /* result is available - we can remove deferred message from the processed message */
-+ dbus_message_set_data(message, deferred_message_data_slot, NULL, NULL);
-+ }
-+ }
-+ }
-+ else
- {
-- (*deferred_message)->status |= check_type;
-+ /* ask policy checkers */
-+#ifdef DBUS_ENABLE_CYNARA
-+ cynara = bus_check_get_cynara(check);
-+ result = bus_cynara_check_privilege(cynara, message, sender, addressed_recipient,
-+ proposed_recipient, privilege, check_type, deferred_message);
-+#endif
-+ if (result == BUS_RESULT_LATER && deferred_message != NULL)
-+ {
-+ (*deferred_message)->status |= check_type;
-+ }
- }
- return result;
- }
-@@ -206,6 +295,12 @@ bus_deferred_message_unref (BusDeferredMessage *deferred_message)
- }
- }
-
-+BusDeferredMessageStatus
-+bus_deferred_message_get_status (BusDeferredMessage *deferred_message)
-+{
-+ return deferred_message->status;
-+}
-+
- void
- bus_deferred_message_response_received (BusDeferredMessage *deferred_message,
- BusResult result)
-diff --git a/bus/check.h b/bus/check.h
-index c3fcaf9..d177549 100644
---- a/bus/check.h
-+++ b/bus/check.h
-@@ -55,6 +55,7 @@ BusResult bus_check_privilege (BusCheck *check,
- BusDeferredMessageStatus check_type,
- BusDeferredMessage **deferred_message);
-
-+
- BusDeferredMessage *bus_deferred_message_new (DBusMessage *message,
- DBusConnection *sender,
- DBusConnection *addressed_recipient,
-@@ -65,4 +66,13 @@ BusDeferredMessage *bus_deferred_message_ref (BusDeferredMessage
- void bus_deferred_message_unref (BusDeferredMessage *deferred_message);
- void bus_deferred_message_response_received (BusDeferredMessage *deferred_message,
- BusResult result);
-+void bus_deferred_message_disable_sender (BusDeferredMessage *deferred_message);
-+
-+BusDeferredMessageStatus bus_deferred_message_get_status (BusDeferredMessage *deferred_message);
-+
-+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
-+extern BusResult (*bus_check_test_override) (DBusConnection *connection,
-+ const char *privilege);
-+#endif
-+
- #endif /* BUS_CHECK_H */
-diff --git a/bus/cynara.c b/bus/cynara.c
-index 57a4c45..77aed62 100644
---- a/bus/cynara.c
-+++ b/bus/cynara.c
-@@ -36,7 +36,6 @@
- #include <cynara-client-async.h>
- #endif
-
--
- #ifdef DBUS_ENABLE_CYNARA
- typedef struct BusCynara
- {
-diff --git a/bus/dispatch.c b/bus/dispatch.c
-index d3867f7..50a22a3 100644
---- a/bus/dispatch.c
-+++ b/bus/dispatch.c
-@@ -35,6 +35,7 @@
- #include "signals.h"
- #include "test.h"
- #include <dbus/dbus-internals.h>
-+#include <dbus/dbus-connection-internal.h>
- #include <dbus/dbus-misc.h>
- #include <string.h>
-
-@@ -122,7 +123,7 @@ send_one_message (DBusConnection *connection,
- return TRUE;
- }
-
--dbus_bool_t
-+BusResult
- bus_dispatch_matches (BusTransaction *transaction,
- DBusConnection *sender,
- DBusConnection *addressed_recipient,
-@@ -158,13 +159,29 @@ bus_dispatch_matches (BusTransaction *transaction,
- message, NULL, error,
- &deferred_message);
- if (res == BUS_RESULT_FALSE)
-- return FALSE;
-+ return BUS_RESULT_FALSE;
- else if (res == BUS_RESULT_LATER)
- {
-- dbus_set_error (error,
-- DBUS_ERROR_ACCESS_DENIED,
-- "Rejecting message because time is needed to check security policy");
-- return FALSE;
-+ BusDeferredMessageStatus status;
-+ status = bus_deferred_message_get_status(deferred_message);
-+
-+ if (status & BUS_DEFERRED_MESSAGE_CHECK_SEND)
-+ {
-+ /* send rule result not available - disable dispatching messages from the sender */
-+ bus_deferred_message_disable_sender(deferred_message);
-+ return BUS_RESULT_LATER;
-+ }
-+ else if (status & BUS_DEFERRED_MESSAGE_CHECK_RECEIVE)
-+ {
-+ dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
-+ "Rejecting message because time is needed to check security policy");
-+ return BUS_RESULT_FALSE;
-+ }
-+ else
-+ {
-+ _dbus_verbose("deferred message has no status field set to send or receive unexpectedly\n");
-+ return BUS_RESULT_FALSE;
-+ }
- }
-
- if (dbus_message_contains_unix_fds (message) &&
-@@ -175,14 +192,14 @@ bus_dispatch_matches (BusTransaction *transaction,
- DBUS_ERROR_NOT_SUPPORTED,
- "Tried to send message with Unix file descriptors"
- "to a client that doesn't support that.");
-- return FALSE;
-- }
-+ return BUS_RESULT_FALSE;
-+ }
-
- /* Dispatch the message */
- if (!bus_transaction_send (transaction, addressed_recipient, message))
- {
- BUS_SET_OOM (error);
-- return FALSE;
-+ return BUS_RESULT_FALSE;
- }
- }
-
-@@ -197,7 +214,7 @@ bus_dispatch_matches (BusTransaction *transaction,
- &recipients))
- {
- BUS_SET_OOM (error);
-- return FALSE;
-+ return BUS_RESULT_FALSE;
- }
-
- link = _dbus_list_get_first_link (&recipients);
-@@ -219,10 +236,10 @@ bus_dispatch_matches (BusTransaction *transaction,
- if (dbus_error_is_set (&tmp_error))
- {
- dbus_move_error (&tmp_error, error);
-- return FALSE;
-+ return BUS_RESULT_FALSE;
- }
- else
-- return TRUE;
-+ return BUS_RESULT_TRUE;
- }
-
- static DBusHandlerResult
-@@ -409,10 +426,12 @@ bus_dispatch (DBusConnection *connection,
- }
- else if (res == BUS_RESULT_LATER)
- {
-- dbus_set_error (&error,
-- DBUS_ERROR_ACCESS_DENIED,
-- "Rejecting message because time is needed to check security policy");
-- _dbus_verbose ("Security policy needs time to check policy. Dropping message\n");
-+ /* Disable dispatching messages from the sender,
-+ * roll back and dispatch the message once the policy result is available */
-+ bus_deferred_message_disable_sender(deferred_message);
-+ bus_transaction_cancel_and_free (transaction);
-+ transaction = NULL;
-+ result = DBUS_HANDLER_RESULT_LATER;
- goto out;
- }
-
-@@ -514,8 +533,14 @@ bus_dispatch (DBusConnection *connection,
- * addressed_recipient == NULL), and match it against other connections'
- * match rules.
- */
-- if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error))
-- goto out;
-+ if (BUS_RESULT_LATER == bus_dispatch_matches (transaction, connection, addressed_recipient,
-+ message, &error))
-+ {
-+ /* Roll back and dispatch the message once the policy result is available */
-+ bus_transaction_cancel_and_free (transaction);
-+ transaction = NULL;
-+ result = DBUS_HANDLER_RESULT_LATER;
-+ }
-
- out:
- if (dbus_error_is_set (&error))
-@@ -5060,9 +5085,132 @@ bus_dispatch_test_conf_fail (const DBusString *test_data_dir,
- }
- #endif
-
-+typedef struct {
-+ DBusTimeout *timeout;
-+ DBusConnection *connection;
-+ dbus_bool_t timedout;
-+ int check_counter;
-+} BusTestCheckData;
-+
-+static BusTestCheckData *cdata;
-+
-+static dbus_bool_t
-+bus_dispatch_test_check_timeout (void *data)
-+{
-+ _dbus_verbose ("timeout triggered - pretend that privilege check result is available\n");
-+
-+ /* should only happen once during the test */
-+ _dbus_assert (!cdata->timedout);
-+ cdata->timedout = TRUE;
-+ _dbus_connection_enable_dispatch (cdata->connection);
-+
-+ /* don't call this again */
-+ _dbus_loop_remove_timeout (bus_connection_get_loop (cdata->connection),
-+ cdata->timeout);
-+ dbus_connection_unref (cdata->connection);
-+ cdata->connection = NULL;
-+ return TRUE;
-+}
-+
-+static BusResult
-+bus_dispatch_test_check_override (DBusConnection *connection,
-+ const char *privilege)
-+{
-+ _dbus_verbose ("overriding privilege check %s #%d\n", privilege, cdata->check_counter);
-+ cdata->check_counter++;
-+ if (!cdata->timedout)
-+ {
-+ dbus_bool_t added;
-+
-+ /* Should be the first privilege check for the "Echo" method. */
-+ _dbus_assert (cdata->check_counter == 1);
-+ cdata->timeout = _dbus_timeout_new (1, bus_dispatch_test_check_timeout,
-+ NULL, NULL);
-+ _dbus_assert (cdata->timeout);
-+ added = _dbus_loop_add_timeout (bus_connection_get_loop (connection),
-+ cdata->timeout);
-+ _dbus_assert (added);
-+ cdata->connection = connection;
-+ dbus_connection_ref (connection);
-+ _dbus_connection_disable_dispatch (connection);
-+ return BUS_RESULT_LATER;
-+ }
-+ else
-+ {
-+ /* Should only be checked one more time, and this time succeeds. */
-+ _dbus_assert (cdata->check_counter == 2);
-+ return BUS_RESULT_TRUE;
-+ }
-+}
-+
-+static dbus_bool_t
-+bus_dispatch_test_check (const DBusString *test_data_dir)
-+{
-+ const char *filename = "valid-config-files/debug-check-some.conf";
-+ BusContext *context;
-+ DBusConnection *foo;
-+ DBusError error;
-+ dbus_bool_t result = TRUE;
-+ BusTestCheckData data;
-+
-+ /* save the config name for the activation helper */
-+ if (!setenv_TEST_LAUNCH_HELPER_CONFIG (test_data_dir, filename))
-+ _dbus_assert_not_reached ("no memory setting TEST_LAUNCH_HELPER_CONFIG");
-+
-+ dbus_error_init (&error);
-+
-+ context = bus_context_new_test (test_data_dir, filename);
-+ if (context == NULL)
-+ return FALSE;
-+
-+ foo = dbus_connection_open_private (TEST_DEBUG_PIPE, &error);
-+ if (foo == NULL)
-+ _dbus_assert_not_reached ("could not alloc connection");
-+
-+ if (!bus_setup_debug_client (foo))
-+ _dbus_assert_not_reached ("could not set up connection");
-+
-+ spin_connection_until_authenticated (context, foo);
-+
-+ if (!check_hello_message (context, foo))
-+ _dbus_assert_not_reached ("hello message failed");
-+
-+ if (!check_double_hello_message (context, foo))
-+ _dbus_assert_not_reached ("double hello message failed");
-+
-+ if (!check_add_match (context, foo, ""))
-+ _dbus_assert_not_reached ("AddMatch message failed");
-+
-+ /*
-+ * Cause bus_check_send_privilege() to return BUS_RESULT_LATER in the
-+ * first call, then BUS_RESULT_TRUE.
-+ */
-+ cdata = &data;
-+ memset (cdata, 0, sizeof(*cdata));
-+ bus_check_test_override = bus_dispatch_test_check_override;
-+
-+ result = check_existent_service_auto_start (context, foo);
-+
-+ _dbus_assert (cdata->check_counter == 2);
-+ _dbus_assert (cdata->timedout);
-+ _dbus_assert (cdata->timeout);
-+ _dbus_assert (!cdata->connection);
-+ _dbus_timeout_unref (cdata->timeout);
-+
-+ kill_client_connection_unchecked (foo);
-+
-+ bus_context_unref (context);
-+
-+ return result;
-+}
-+
- dbus_bool_t
- bus_dispatch_test (const DBusString *test_data_dir)
- {
-+ _dbus_verbose ("<check> tests\n");
-+ if (!bus_dispatch_test_check (test_data_dir))
-+ return FALSE;
-+
- /* run normal activation tests */
- _dbus_verbose ("Normal activation tests\n");
- if (!bus_dispatch_test_conf (test_data_dir,
-diff --git a/bus/dispatch.h b/bus/dispatch.h
-index fb5ba7a..afba6a2 100644
---- a/bus/dispatch.h
-+++ b/bus/dispatch.h
-@@ -29,7 +29,7 @@
-
- dbus_bool_t bus_dispatch_add_connection (DBusConnection *connection);
- void bus_dispatch_remove_connection (DBusConnection *connection);
--dbus_bool_t bus_dispatch_matches (BusTransaction *transaction,
-+BusResult bus_dispatch_matches (BusTransaction *transaction,
- DBusConnection *sender,
- DBusConnection *recipient,
- DBusMessage *message,
-diff --git a/bus/driver.c b/bus/driver.c
-index cd0a714..f414f64 100644
---- a/bus/driver.c
-+++ b/bus/driver.c
-@@ -218,6 +218,7 @@ bus_driver_send_service_owner_changed (const char *service_name,
- {
- DBusMessage *message;
- dbus_bool_t retval;
-+ BusResult res;
- const char *null_service;
-
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-@@ -253,7 +254,16 @@ bus_driver_send_service_owner_changed (const char *service_name,
- if (!bus_transaction_capture (transaction, NULL, NULL, message))
- goto oom;
-
-- retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
-+ res = bus_dispatch_matches (transaction, NULL, NULL, message, error);
-+ if (res == BUS_RESULT_TRUE)
-+ retval = TRUE;
-+ else
-+ {
-+ retval = FALSE;
-+ if (res == BUS_RESULT_LATER)
-+ /* should never happen */
-+ _dbus_assert_not_reached ("bus_dispatch_matches returned BUS_RESULT_LATER unexpectedly");
-+ }
- dbus_message_unref (message);
-
- return retval;
-diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h
-index 4835732..94b1c95 100644
---- a/dbus/dbus-connection-internal.h
-+++ b/dbus/dbus-connection-internal.h
-@@ -118,6 +118,21 @@ DBUS_PRIVATE_EXPORT
- dbus_bool_t _dbus_connection_get_linux_security_label (DBusConnection *connection,
- char **label_p);
-
-+DBUS_PRIVATE_EXPORT
-+void _dbus_connection_enable_dispatch (DBusConnection *connection);
-+DBUS_PRIVATE_EXPORT
-+void _dbus_connection_disable_dispatch (DBusConnection *connection);
-+
-+DBUS_PRIVATE_EXPORT
-+dbus_bool_t _dbus_connection_putback_message (DBusConnection *connection,
-+ DBusMessage *after_message,
-+ DBusMessage *message,
-+ DBusError *error);
-+
-+DBUS_PRIVATE_EXPORT
-+dbus_bool_t _dbus_connection_remove_message (DBusConnection *connection,
-+ DBusMessage *message);
-+
- /* if DBUS_ENABLE_STATS */
- DBUS_PRIVATE_EXPORT
- void _dbus_connection_get_stats (DBusConnection *connection,
-diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
-index c525b6d..958968c 100644
---- a/dbus/dbus-connection.c
-+++ b/dbus/dbus-connection.c
-@@ -311,7 +311,8 @@ struct DBusConnection
- */
- dbus_bool_t dispatch_acquired; /**< Someone has dispatch path (can drain incoming queue) */
- dbus_bool_t io_path_acquired; /**< Someone has transport io path (can use the transport to read/write messages) */
--
-+
-+ unsigned int dispatch_disabled : 1; /**< if true, then dispatching incoming messages is stopped until enabled again */
- unsigned int shareable : 1; /**< #TRUE if libdbus owns a reference to the connection and can return it from dbus_connection_open() more than once */
-
- unsigned int exit_on_disconnect : 1; /**< If #TRUE, exit after handling disconnect signal */
-@@ -439,6 +440,39 @@ _dbus_connection_wakeup_mainloop (DBusConnection *connection)
- (*connection->wakeup_main_function) (connection->wakeup_main_data);
- }
-
-+static void
-+_dbus_connection_set_dispatch(DBusConnection *connection,
-+ dbus_bool_t disabled)
-+{
-+ CONNECTION_LOCK (connection);
-+ if (connection->dispatch_disabled != disabled)
-+ {
-+ DBusDispatchStatus status;
-+
-+ connection->dispatch_disabled = disabled;
-+ status = _dbus_connection_get_dispatch_status_unlocked (connection);
-+ _dbus_connection_update_dispatch_status_and_unlock (connection, status);
-+ }
-+ else
-+ {
-+ CONNECTION_UNLOCK (connection);
-+ }
-+}
-+
-+
-+void
-+_dbus_connection_enable_dispatch (DBusConnection *connection)
-+{
-+ _dbus_connection_set_dispatch (connection, FALSE);
-+}
-+
-+void
-+ _dbus_connection_disable_dispatch (DBusConnection *connection)
-+{
-+ _dbus_connection_set_dispatch (connection, TRUE);
-+}
-+
-+
- #ifdef DBUS_ENABLE_EMBEDDED_TESTS
- /**
- * Gets the locks so we can examine them
-@@ -4069,6 +4103,82 @@ _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
- "_dbus_connection_putback_message_link_unlocked");
- }
-
-+dbus_bool_t
-+_dbus_connection_putback_message (DBusConnection *connection,
-+ DBusMessage *after_message,
-+ DBusMessage *message,
-+ DBusError *error)
-+{
-+ DBusDispatchStatus status;
-+ DBusList *message_link = _dbus_list_alloc_link (message);
-+ DBusList *after_link;
-+ if (message_link == NULL)
-+ {
-+ _DBUS_SET_OOM (error);
-+ return FALSE;
-+ }
-+ dbus_message_ref (message);
-+
-+ CONNECTION_LOCK (connection);
-+ _dbus_connection_acquire_dispatch (connection);
-+ HAVE_LOCK_CHECK (connection);
-+
-+ after_link = _dbus_list_find_first(&connection->incoming_messages, after_message);
-+ _dbus_list_insert_after_link (&connection->incoming_messages, after_link, message_link);
-+ connection->n_incoming += 1;
-+
-+ _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
-+ message_link->data,
-+ dbus_message_type_to_string (dbus_message_get_type (message_link->data)),
-+ dbus_message_get_interface (message_link->data) ?
-+ dbus_message_get_interface (message_link->data) :
-+ "no interface",
-+ dbus_message_get_member (message_link->data) ?
-+ dbus_message_get_member (message_link->data) :
-+ "no member",
-+ dbus_message_get_signature (message_link->data),
-+ connection, connection->n_incoming);
-+
-+ _dbus_message_trace_ref (message_link->data, -1, -1,
-+ "_dbus_connection_putback_message");
-+
-+ _dbus_connection_release_dispatch (connection);
-+
-+ status = _dbus_connection_get_dispatch_status_unlocked (connection);
-+ _dbus_connection_update_dispatch_status_and_unlock (connection, status);
-+
-+ return TRUE;
-+}
-+
-+dbus_bool_t
-+_dbus_connection_remove_message (DBusConnection *connection,
-+ DBusMessage *message)
-+{
-+ DBusDispatchStatus status;
-+ dbus_bool_t removed;
-+
-+ CONNECTION_LOCK (connection);
-+ _dbus_connection_acquire_dispatch (connection);
-+ HAVE_LOCK_CHECK (connection);
-+
-+ removed = _dbus_list_remove(&connection->incoming_messages, message);
-+
-+ if (removed)
-+ {
-+ connection->n_incoming -= 1;
-+ dbus_message_unref(message);
-+ _dbus_verbose ("Message %p removed from incoming queue\n", message);
-+ }
-+ else
-+ _dbus_verbose ("Message %p not found in the incoming queue\n", message);
-+
-+ _dbus_connection_release_dispatch (connection);
-+
-+ status = _dbus_connection_get_dispatch_status_unlocked (connection);
-+ _dbus_connection_update_dispatch_status_and_unlock (connection, status);
-+ return removed;
-+}
-+
- /**
- * Returns the first-received message from the incoming message queue,
- * removing it from the queue. The caller owns a reference to the
-@@ -4252,8 +4362,9 @@ static DBusDispatchStatus
- _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
- {
- HAVE_LOCK_CHECK (connection);
--
-- if (connection->n_incoming > 0)
-+ if (connection->dispatch_disabled && _dbus_connection_get_is_connected_unlocked(connection))
-+ return DBUS_DISPATCH_COMPLETE;
-+ else if (connection->n_incoming > 0)
- return DBUS_DISPATCH_DATA_REMAINS;
- else if (!_dbus_transport_queue_messages (connection->transport))
- return DBUS_DISPATCH_NEED_MEMORY;
-@@ -4716,6 +4827,8 @@ dbus_connection_dispatch (DBusConnection *connection)
-
- CONNECTION_LOCK (connection);
-
-+ if (result == DBUS_HANDLER_RESULT_LATER)
-+ goto out;
- if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
- {
- _dbus_verbose ("No memory\n");
-@@ -4838,9 +4951,11 @@ dbus_connection_dispatch (DBusConnection *connection)
- connection);
-
- out:
-- if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
-+ if (result == DBUS_HANDLER_RESULT_LATER ||
-+ result == DBUS_HANDLER_RESULT_NEED_MEMORY)
- {
-- _dbus_verbose ("out of memory\n");
-+ if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
-+ _dbus_verbose ("out of memory\n");
-
- /* Put message back, and we'll start over.
- * Yes this means handlers must be idempotent if they
-diff --git a/dbus/dbus-list.c b/dbus/dbus-list.c
-index 8e713c0..32ea871 100644
---- a/dbus/dbus-list.c
-+++ b/dbus/dbus-list.c
-@@ -458,6 +458,35 @@ _dbus_list_remove_last (DBusList **list,
- return FALSE;
- }
-
-+/**
-+ * Finds a value in the list. Returns the first link
-+ * with value equal to the given data pointer.
-+ * This is a linear-time operation.
-+ * Returns #NULL if no value found that matches.
-+ *
-+ * @param list address of the list head.
-+ * @param data the value to find.
-+ * @returns the link if found
-+ */
-+DBusList*
-+_dbus_list_find_first (DBusList **list,
-+ void *data)
-+{
-+ DBusList *link;
-+
-+ link = _dbus_list_get_first_link (list);
-+
-+ while (link != NULL)
-+ {
-+ if (link->data == data)
-+ return link;
-+
-+ link = _dbus_list_get_next_link (list, link);
-+ }
-+
-+ return NULL;
-+}
-+
- /**
- * Finds a value in the list. Returns the last link
- * with value equal to the given data pointer.
-diff --git a/dbus/dbus-list.h b/dbus/dbus-list.h
-index 9350a0d..fee9f1b 100644
---- a/dbus/dbus-list.h
-+++ b/dbus/dbus-list.h
-@@ -68,6 +68,9 @@ DBUS_PRIVATE_EXPORT
- void _dbus_list_remove_link (DBusList **list,
- DBusList *link);
- DBUS_PRIVATE_EXPORT
-+DBusList* _dbus_list_find_first (DBusList **list,
-+ void *data);
-+DBUS_PRIVATE_EXPORT
- DBusList* _dbus_list_find_last (DBusList **list,
- void *data);
- DBUS_PRIVATE_EXPORT
-diff --git a/dbus/dbus-shared.h b/dbus/dbus-shared.h
-index 7ab9103..e5bfbed 100644
---- a/dbus/dbus-shared.h
-+++ b/dbus/dbus-shared.h
-@@ -67,7 +67,8 @@ typedef enum
- {
- DBUS_HANDLER_RESULT_HANDLED, /**< Message has had its effect - no need to run more handlers. */
- DBUS_HANDLER_RESULT_NOT_YET_HANDLED, /**< Message has not had any effect - see if other handlers want it. */
-- DBUS_HANDLER_RESULT_NEED_MEMORY /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */
-+ DBUS_HANDLER_RESULT_NEED_MEMORY, /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */
-+ DBUS_HANDLER_RESULT_LATER /**< Message dispatch deferred due to pending policy check */
- } DBusHandlerResult;
-
- /* Bus names */
---
-2.21.1
-