From 45c9f8d9fb98920de8f297fd2dd80a360f8dfc80 Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Mon, 9 Nov 2015 05:17:15 +0100 Subject: [PATCH] Add tests for GetConnectionWindowsUser and GetConnectionProcessID to test-bus for windows. This patch includes the definition of methods GetConnectionWindowsUser and GetConnectionProcessID in org.freedesktop.DBus driver. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=92721 --- bus/dispatch.c | 306 ++++++++++++++++++++++++++++++++++++++++++++++++++- bus/driver.c | 127 +++++++++++++++++++++ dbus/dbus-protocol.h | 2 + 3 files changed, 431 insertions(+), 4 deletions(-) diff --git a/bus/dispatch.c b/bus/dispatch.c index 9ea1aaa..c029f58 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -1197,6 +1197,301 @@ check_double_hello_message (BusContext *context, return retval; } +#ifdef DBUS_WIN + +/* returns TRUE if the correct thing happens, + * but the correct thing may include OOM errors. + */ +static dbus_bool_t +check_get_connection_windows_user (BusContext *context, + DBusConnection *connection) +{ + DBusMessage *message; + dbus_uint32_t serial; + dbus_bool_t retval; + DBusError error; + const char *base_service_name; + char *sid; + + retval = FALSE; + dbus_error_init (&error); + message = NULL; + + _dbus_verbose ("check_get_connection_windows_user for %p\n", connection); + + message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionWindowsUser"); + + if (message == NULL) + return TRUE; + + base_service_name = dbus_bus_get_unique_name (connection); + + if (!dbus_message_append_args (message, + DBUS_TYPE_STRING, &base_service_name, + DBUS_TYPE_INVALID)) + { + dbus_message_unref (message); + return TRUE; + } + + if (!dbus_connection_send (connection, message, &serial)) + { + dbus_message_unref (message); + return TRUE; + } + + /* send our message */ + bus_test_run_clients_loop (SEND_PENDING (connection)); + + dbus_message_unref (message); + message = NULL; + + dbus_connection_ref (connection); /* because we may get disconnected */ + block_connection_until_message_from_bus (context, connection, "reply to GetConnectionWindowsUser"); + + if (!dbus_connection_get_is_connected (connection)) + { + _dbus_verbose ("connection was disconnected\n"); + + dbus_connection_unref (connection); + + return TRUE; + } + + dbus_connection_unref (connection); + + message = pop_message_waiting_for_memory (connection); + if (message == NULL) + { + _dbus_warn ("Did not receive a reply to %s %d on %p\n", + "GetConnectionWindowsUser", serial, connection); + goto out; + } + + verbose_message_received (connection, message); + + if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) + { + if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY)) + { + ; /* good, this is a valid response */ + } + else + { + warn_unexpected (connection, message, "not this error"); + + goto out; + } + } + else + { + if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) + { + ; /* good, expected */ + } + else + { + warn_unexpected (connection, message, + "method_return for GetConnectionWindowsUser"); + + goto out; + } + + retry_get_property: + + if (!dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &sid, + DBUS_TYPE_INVALID)) + { + if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) + { + _dbus_verbose ("no memory to get sid by GetConnectionWindowsUser\n"); + dbus_error_free (&error); + _dbus_wait_for_memory (); + goto retry_get_property; + } + else + { + _dbus_assert (dbus_error_is_set (&error)); + _dbus_warn ("Did not get the expected DBUS_TYPE_STRING from GetConnectionWindowsUser\n"); + goto out; + } + } + } + + if (!check_no_leftovers (context)) + goto out; + + retval = TRUE; + + out: + dbus_error_free (&error); + + if (message) + dbus_message_unref (message); + + return retval; +} + +/* returns TRUE if the correct thing happens, + * but the correct thing may include OOM errors. + */ +static dbus_bool_t +check_get_connection_process_id (BusContext *context, + DBusConnection *connection) +{ + DBusMessage *message; + dbus_uint32_t serial; + dbus_bool_t retval; + DBusError error; + const char *base_service_name; + dbus_uint32_t pid; + + retval = FALSE; + dbus_error_init (&error); + message = NULL; + + _dbus_verbose ("check_get_connection_process_id for %p\n", connection); + + message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionProcessID"); + + if (message == NULL) + return TRUE; + + base_service_name = dbus_bus_get_unique_name (connection); + + if (!dbus_message_append_args (message, + DBUS_TYPE_STRING, &base_service_name, + DBUS_TYPE_INVALID)) + { + dbus_message_unref (message); + return TRUE; + } + + if (!dbus_connection_send (connection, message, &serial)) + { + dbus_message_unref (message); + return TRUE; + } + + /* send our message */ + bus_test_run_clients_loop (SEND_PENDING (connection)); + + dbus_message_unref (message); + message = NULL; + + dbus_connection_ref (connection); /* because we may get disconnected */ + block_connection_until_message_from_bus (context, connection, "reply to GetConnectionProcessID"); + + if (!dbus_connection_get_is_connected (connection)) + { + _dbus_verbose ("connection was disconnected\n"); + + dbus_connection_unref (connection); + + return TRUE; + } + + dbus_connection_unref (connection); + + message = pop_message_waiting_for_memory (connection); + if (message == NULL) + { + _dbus_warn ("Did not receive a reply to %s %d on %p\n", + "GetConnectionProcessID", serial, connection); + goto out; + } + + verbose_message_received (connection, message); + + if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) + { + if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY)) + { + ; /* good, this is a valid response */ + } + else if (dbus_message_is_error (message, DBUS_ERROR_PROCESS_ID_UNKNOWN)) + { + _dbus_verbose ("Windows correctly does not support GetConnectionProcessID\n"); + } + else + { + _dbus_verbose ("does not support GetConnectionProcessID but perhaps that's OK?\n"); + } + } + else + { + if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) + { + ; /* good, expected */ + } + else + { + warn_unexpected (connection, message, + "method_return for GetConnectionWindowsProcessID"); + + goto out; + } + + retry_get_property: + + if (!dbus_message_get_args (message, &error, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_INVALID)) + { + if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) + { + _dbus_verbose ("no memory to get pid by GetConnectionProcessID\n"); + dbus_error_free (&error); + _dbus_wait_for_memory (); + goto retry_get_property; + } + else + { + _dbus_assert (dbus_error_is_set (&error)); + _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionProcessID\n"); + goto out; + } + } + else + { + /* test if returned pid is the same as our own pid + * + * @todo It would probably be good to restructure the tests + * in a way so our parent is the bus that we're testing + * cause then we can test that the pid returned matches + * getppid() + */ + if (pid != (dbus_uint32_t) _dbus_getpid ()) + { + _dbus_assert (dbus_error_is_set (&error)); + _dbus_warn ("Result from GetConnectionProcessID is not our own pid\n"); + goto out; + } + } + } + + if (!check_no_leftovers (context)) + goto out; + + retval = TRUE; + + out: + dbus_error_free (&error); + + if (message) + dbus_message_unref (message); + + return retval; +} +#else + /* returns TRUE if the correct thing happens, * but the correct thing may include OOM errors. */ @@ -1513,7 +1808,7 @@ check_get_connection_unix_process_id (BusContext *context, return retval; } - +#endif /* returns TRUE if the correct thing happens, * but the correct thing may include OOM errors. */ @@ -4835,9 +5130,12 @@ bus_dispatch_test_conf (const DBusString *test_data_dir, _dbus_assert_not_reached ("GetAllMatchRules message failed"); #endif -#ifdef DBUS_WIN_FIXME - _dbus_verbose("TODO: testing of GetConnectionUnixUser message skipped for now\n"); - _dbus_verbose("TODO: testing of GetConnectionUnixProcessID message skipped for now\n"); +#ifdef DBUS_WIN + if (!check_get_connection_windows_user (context, baz)) + _dbus_assert_not_reached ("GetConnectionWindowsUser message failed"); + + if (!check_get_connection_process_id (context, baz)) + _dbus_assert_not_reached ("GetConnectionProcessID message failed"); #else if (!check_get_connection_unix_user (context, baz)) _dbus_assert_not_reached ("GetConnectionUnixUser message failed"); diff --git a/bus/driver.c b/bus/driver.c index 852ac53..c6e7797 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -1434,6 +1434,121 @@ bus_driver_handle_list_queued_owners (DBusConnection *connection, return FALSE; } +#ifdef DBUS_WIN +static dbus_bool_t +bus_driver_handle_get_connection_windows_user (DBusConnection *connection, + BusTransaction *transaction, + DBusMessage *message, + DBusError *error) +{ + DBusConnection *conn; + DBusMessage *reply; + char *sid; + const char *service; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + reply = NULL; + + conn = bus_driver_get_conn_helper (connection, message, "UID", &service, + error); + + if (conn == NULL) + goto failed; + + reply = dbus_message_new_method_return (message); + if (reply == NULL) + goto oom; + + if (!dbus_connection_get_windows_user (conn, &sid)) + { + dbus_set_error (error, + DBUS_ERROR_FAILED, + "Could not determine SID for '%s'", service); + goto failed; + } + + if (! dbus_message_append_args (reply, + DBUS_TYPE_STRING, &sid, + DBUS_TYPE_INVALID)) + goto oom; + + if (! bus_transaction_send_from_driver (transaction, connection, reply)) + goto oom; + + dbus_message_unref (reply); + dbus_free (sid); + + return TRUE; + + oom: + BUS_SET_OOM (error); + + failed: + _DBUS_ASSERT_ERROR_IS_SET (error); + if (reply) + dbus_message_unref (reply); + return FALSE; +} + +static dbus_bool_t +bus_driver_handle_get_connection_process_id (DBusConnection *connection, + BusTransaction *transaction, + DBusMessage *message, + DBusError *error) +{ + DBusConnection *conn; + DBusMessage *reply; + unsigned long pid; + dbus_uint32_t pid32; + const char *service; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + reply = NULL; + + conn = bus_driver_get_conn_helper (connection, message, "PID", &service, + error); + + if (conn == NULL) + goto failed; + + reply = dbus_message_new_method_return (message); + if (reply == NULL) + goto oom; + + if (!dbus_connection_get_unix_process_id (conn, &pid)) + { + dbus_set_error (error, + DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN, + "Could not determine PID for '%s'", service); + goto failed; + } + + pid32 = pid; + if (! dbus_message_append_args (reply, + DBUS_TYPE_UINT32, &pid32, + DBUS_TYPE_INVALID)) + goto oom; + + if (! bus_transaction_send_from_driver (transaction, connection, reply)) + goto oom; + + dbus_message_unref (reply); + + return TRUE; + + oom: + BUS_SET_OOM (error); + + failed: + _DBUS_ASSERT_ERROR_IS_SET (error); + if (reply) + dbus_message_unref (reply); + return FALSE; +} +#else + static dbus_bool_t bus_driver_handle_get_connection_unix_user (DBusConnection *connection, BusTransaction *transaction, @@ -1547,6 +1662,7 @@ bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection, dbus_message_unref (reply); return FALSE; } +#endif static dbus_bool_t bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection, @@ -2111,6 +2227,16 @@ static const MessageHandler dbus_message_handlers[] = { DBUS_TYPE_STRING_AS_STRING, DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_list_queued_owners }, +#ifdef DBUS_WIN + { "GetConnectionWindowsUser", + DBUS_TYPE_STRING_AS_STRING, + DBUS_TYPE_UINT32_AS_STRING, + bus_driver_handle_get_connection_windows_user }, + { "GetConnectionProcessID", + DBUS_TYPE_STRING_AS_STRING, + DBUS_TYPE_UINT32_AS_STRING, + bus_driver_handle_get_connection_process_id }, +#else { "GetConnectionUnixUser", DBUS_TYPE_STRING_AS_STRING, DBUS_TYPE_UINT32_AS_STRING, @@ -2119,6 +2245,7 @@ static const MessageHandler dbus_message_handlers[] = { DBUS_TYPE_STRING_AS_STRING, DBUS_TYPE_UINT32_AS_STRING, bus_driver_handle_get_connection_unix_process_id }, +#endif { "GetAdtAuditSessionData", DBUS_TYPE_STRING_AS_STRING, DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING, diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h index 933c365..ff02fad 100644 --- a/dbus/dbus-protocol.h +++ b/dbus/dbus-protocol.h @@ -438,6 +438,8 @@ extern "C" { #define DBUS_ERROR_SPAWN_NO_MEMORY "org.freedesktop.DBus.Error.Spawn.NoMemory" /** Tried to get a UNIX process ID and it wasn't available. */ #define DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN "org.freedesktop.DBus.Error.UnixProcessIdUnknown" +/** Tried to get a process ID and it wasn't available. */ +#define DBUS_ERROR_PROCESS_ID_UNKNOWN "org.freedesktop.DBus.Error.ProcessIdUnknown" /** A type signature is not valid. */ #define DBUS_ERROR_INVALID_SIGNATURE "org.freedesktop.DBus.Error.InvalidSignature" /** A file contains invalid syntax or is otherwise broken. */ -- 1.8.4.5