From 8e4e4aa5fdb45b8581ff29f77c87fe4e892a207b Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 23 Jan 2015 19:25:35 +0000 Subject: [PATCH 4/6] dbus-monitor: add support for using BecomeMonitor to be a read-only monitor Move the dbus_connection_add_filter() call further up as a precaution, because it isn't safe for a monitor to not have a filter that swallows all messages. --- tools/Makefile.am | 11 +++--- tools/dbus-monitor.c | 95 ++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 84 insertions(+), 22 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index 05d1dcb..821ad5c 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -31,10 +31,13 @@ dbus_send_SOURCES= \ dbus-print-message.h \ dbus-send.c -dbus_monitor_SOURCES= \ - dbus-monitor.c \ - dbus-print-message.c \ - dbus-print-message.h +dbus_monitor_SOURCES= \ + dbus-monitor.c \ + dbus-print-message.c \ + dbus-print-message.h \ + tool-common.c \ + tool-common.h \ + $(NULL) if DBUS_WIN dbus_launch_SOURCES= \ diff --git a/tools/dbus-monitor.c b/tools/dbus-monitor.c index ff8390d..23e0c17 100644 --- a/tools/dbus-monitor.c +++ b/tools/dbus-monitor.c @@ -34,6 +34,7 @@ #include #include "dbus-print-message.h" +#include "tool-common.h" #define EAVESDROPPING_RULE "eavesdrop=true" @@ -78,13 +79,6 @@ gettimeofday (struct timeval *__p, } #endif -inline static void -oom (const char *doing) -{ - fprintf (stderr, "OOM while %s\n", doing); - exit (1); -} - static DBusHandlerResult monitor_filter_func (DBusConnection *connection, DBusMessage *message, @@ -96,10 +90,9 @@ monitor_filter_func (DBusConnection *connection, DBUS_INTERFACE_LOCAL, "Disconnected")) exit (0); - - /* Conceptually we want this to be - * DBUS_HANDLER_RESULT_NOT_YET_HANDLED, but this raises - * some problems. See bug 1719. + + /* Monitors must not allow libdbus to reply to messages, so we eat + * the message. See bug 1719. */ return DBUS_HANDLER_RESULT_HANDLED; } @@ -242,6 +235,66 @@ only_one_type (dbus_bool_t *seen_bus_type, } } +static dbus_bool_t +become_monitor (DBusConnection *connection, + int numFilters, + char **filters) +{ + DBusError error = DBUS_ERROR_INIT; + DBusMessage *m; + DBusMessage *r; + int i; + dbus_uint32_t zero = 0; + DBusMessageIter appender, array_appender; + + m = dbus_message_new_method_call (DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, DBUS_INTERFACE_MONITORING, "BecomeMonitor"); + + if (m == NULL) + tool_oom ("becoming a monitor"); + + dbus_message_iter_init_append (m, &appender); + + if (!dbus_message_iter_open_container (&appender, DBUS_TYPE_ARRAY, "s", + &array_appender)) + tool_oom ("opening string array"); + + for (i = 0; i < numFilters; i++) + { + if (!dbus_message_iter_append_basic (&array_appender, DBUS_TYPE_STRING, + &filters[i])) + tool_oom ("adding filter to array"); + } + + if (!dbus_message_iter_close_container (&appender, &array_appender) || + !dbus_message_iter_append_basic (&appender, DBUS_TYPE_UINT32, &zero)) + tool_oom ("finishing arguments"); + + r = dbus_connection_send_with_reply_and_block (connection, m, -1, &error); + + if (r != NULL) + { + dbus_message_unref (r); + } + else if (dbus_error_has_name (&error, DBUS_ERROR_UNKNOWN_INTERFACE)) + { + fprintf (stderr, "dbus-monitor: unable to enable new-style monitoring, " + "your dbus-daemon is too old. Falling back to eavesdropping.\n"); + dbus_error_free (&error); + } + else + { + fprintf (stderr, "dbus-monitor: unable to enable new-style monitoring: " + "%s: \"%s\". Falling back to eavesdropping.\n", + error.name, error.message); + dbus_error_free (&error); + } + + dbus_message_unref (m); + + return (r != NULL); +} + int main (int argc, char *argv[]) { @@ -312,10 +365,10 @@ main (int argc, char *argv[]) filters = (char **) realloc (filters, numFilters * sizeof (char *)); if (filters == NULL) - oom ("adding a new filter slot"); + tool_oom ("adding a new filter slot"); filters[j] = (char *) malloc (filter_len); if (filters[j] == NULL) - oom ("adding a new filter"); + tool_oom ("adding a new filter"); snprintf (filters[j], filter_len, "%s,%s", EAVESDROPPING_RULE, arg); j++; } @@ -365,7 +418,17 @@ main (int argc, char *argv[]) exit (1); } - if (numFilters) + if (!dbus_connection_add_filter (connection, filter_func, NULL, NULL)) + { + fprintf (stderr, "Couldn't add filter!\n"); + exit (1); + } + + if (become_monitor (connection, numFilters, filters)) + { + /* no more preparation needed */ + } + else if (numFilters) { size_t offset = 0; for (i = 0; i < j; i++) @@ -408,10 +471,6 @@ main (int argc, char *argv[]) } } - if (!dbus_connection_add_filter (connection, filter_func, NULL, NULL)) { - fprintf (stderr, "Couldn't add filter!\n"); - exit (1); - } while (dbus_connection_read_write_dispatch(connection, -1)) ; -- 2.1.4