diff options
author | Hyotaek, Shim <hyotaek.shim@samsung.com> | 2015-12-16 15:27:54 +0900 |
---|---|---|
committer | Hyotaek, Shim <hyotaek.shim@samsung.com> | 2015-12-16 15:34:20 +0900 |
commit | 197db0df78e0a9f82df4162885854f99ff749505 (patch) | |
tree | fdf19cf51dfee7142ccbf2eea6ff5a64c373e731 | |
parent | 771f5155c9a393a242329988d56661a51fc04e6c (diff) | |
download | dbus-accepted/tizen/wearable/20151217.022613.tar.gz dbus-accepted/tizen/wearable/20151217.022613.tar.bz2 dbus-accepted/tizen/wearable/20151217.022613.zip |
Revert "Add kdbus transport"submit/tizen_common/20151229.154718submit/tizen_common/20151229.144031submit/tizen/20151216.111722accepted/tizen/wearable/20151217.022613accepted/tizen/tv/20151217.022431accepted/tizen/mobile/20151217.022738
This reverts commit 771f5155c9a393a242329988d56661a51fc04e6c.
Change-Id: I73b6adc6b76b63e972f7228c88c18dabda81b006
35 files changed, 461 insertions, 11206 deletions
@@ -643,8 +643,6 @@ main (int argc, char **argv) _dbus_set_signal_handler (SIGHUP, signal_handler); #endif /* DBUS_UNIX */ - dbus_set_protocol_version (DBUS_MAJOR_PROTOCOL_VERSION); - _dbus_verbose ("We are on D-Bus...\n"); _dbus_loop_run (bus_context_get_loop (context)); diff --git a/configure.ac b/configure.ac index e381860e..ca2c47cf 100644 --- a/configure.ac +++ b/configure.ac @@ -158,7 +158,6 @@ AC_ARG_ENABLE(kqueue, AS_HELP_STRING([--enable-kqueue],[build with kqueue suppor AC_ARG_ENABLE(console-owner-file, AS_HELP_STRING([--enable-console-owner-file],[enable console owner file]),enable_console_owner_file=$enableval,enable_console_owner_file=auto) AC_ARG_ENABLE(launchd, AS_HELP_STRING([--enable-launchd],[build with launchd auto-launch support]),enable_launchd=$enableval,enable_launchd=auto) AC_ARG_ENABLE(systemd, AS_HELP_STRING([--enable-systemd],[build with systemd at_console support]),enable_systemd=$enableval,enable_systemd=auto) -AC_ARG_ENABLE(kdbus-transport, AS_HELP_STRING([--enable-kdbus-transport],[build with kdbus transport support]),enable_kdbus_transport=$enableval,enable_kdbus_transport=no) AC_ARG_WITH(init-scripts, AS_HELP_STRING([--with-init-scripts=[redhat]],[Style of init scripts to install])) AC_ARG_WITH(session-socket-dir, AS_HELP_STRING([--with-session-socket-dir=[dirname]],[Where to put sockets for the per-login-session message bus])) @@ -1239,12 +1238,6 @@ if test x$with_valgrind != xno; then AC_DEFINE([WITH_VALGRIND], [1], [Define to add Valgrind instrumentation]) fi -### kdbus support -if test x$enable_kdbus_transport = xyes; then - AC_DEFINE(ENABLE_KDBUS_TRANSPORT,1,[Enable kdbus transport support]) -fi -AM_CONDITIONAL([ENABLE_KDBUS_TRANSPORT], [test x$enable_kdbus_transport = xyes]) - # Determine maximum number of Unix fds which may be passed AS_CASE([$host_os], [*qnx*], @@ -1257,7 +1250,7 @@ AC_DEFINE_UNQUOTED([DBUS_DEFAULT_MESSAGE_UNIX_FDS], AC_SUBST([DEFAULT_MESSAGE_UNIX_FDS]) #### Set up final flags -LIBDBUS_LIBS="$THREAD_LIBS $NETWORK_libs $KDBUS_LIBS" +LIBDBUS_LIBS="$THREAD_LIBS $NETWORK_libs" AC_SUBST([LIBDBUS_LIBS]) ### X11 detection @@ -1533,20 +1526,7 @@ AC_DEFINE_UNQUOTED(DBUS_SYSTEM_SOCKET,"$DBUS_SYSTEM_SOCKET",[The name of the soc ## and also to connect to. If this ever changes, it'll need to be split into ## two variables, one for the listening address and one for the connecting ## address. -#AC_SUBST(DBUS_SYSTEM_BUS_DEFAULT_ADDRESS) -if ! test -z "$with_system_default_bus"; then - ## Now system bus can work on kdbus too. It is diffrent situation than - ## described above (daemon working with kdbus doesn't need to listen on - ## any socket), so variable was not splited into two. - DBUS_SYSTEM_BUS_DEFAULT_ADDRESS=$with_system_default_bus -else - kdbus_address_path="" - if test x$enable_kdbus_transport = xyes; then - kdbus_address_path="kernel:path=/sys/fs/kdbus/0-system/bus;" - fi - - DBUS_SYSTEM_BUS_DEFAULT_ADDRESS="${kdbus_address_path}unix:path=$DBUS_SYSTEM_SOCKET" -fi +DBUS_SYSTEM_BUS_DEFAULT_ADDRESS="unix:path=$DBUS_SYSTEM_SOCKET" AC_SUBST(DBUS_SYSTEM_BUS_DEFAULT_ADDRESS) AC_DEFINE_UNQUOTED(DBUS_SYSTEM_BUS_DEFAULT_ADDRESS, "$DBUS_SYSTEM_BUS_DEFAULT_ADDRESS",[The default D-Bus address of the system bus]) @@ -1885,7 +1865,6 @@ echo " Building Doxygen docs: ${enable_doxygen_docs} Building XML docs: ${enable_xml_docs} Building launchd support: ${have_launchd} - Building kdbus support: ${enable_kdbus_transport} Init scripts style: ${with_init_scripts} Abstract socket names: ${ac_cv_have_abstract_sockets} System bus socket: ${DBUS_SYSTEM_SOCKET} diff --git a/dbus/Makefile.am b/dbus/Makefile.am index fa712428..86d5d466 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -112,21 +112,6 @@ DBUS_SHARED_arch_sources = \ sd-daemon.c \ sd-daemon.h -DBUS_SHARED_arch_sources += \ - dbus-marshal-gvariant.c \ - dbus-marshal-gvariant.h \ - dbus-protocol-gvariant.h - -if ENABLE_KDBUS_TRANSPORT -DBUS_SHARED_arch_sources += \ - dbus-transport-kdbus.c \ - dbus-transport-kdbus.h \ - kdbus-common.c \ - kdbus-common.h \ - dbus-signals.c \ - dbus-signals.h -endif - DBUS_UTIL_arch_sources = \ dbus-sysdeps-util-unix.c \ dbus-userdb-util.c \ @@ -245,10 +230,7 @@ DBUS_SHARED_SOURCES= \ $(DBUS_SHARED_arch_sources) \ dbus-sysdeps.c \ dbus-sysdeps.h \ - dbus-valgrind-internal.h \ - dbus-asv-util.c \ - dbus-asv-util.h \ - dbus-string-util.c + dbus-valgrind-internal.h ### source code that is generic utility functionality used ### by the bus daemon or test apps, but is NOT included @@ -256,6 +238,8 @@ DBUS_SHARED_SOURCES= \ ### should be underscore-prefixed but don't really need ### to be unless they move to DBUS_SHARED_SOURCES later) DBUS_UTIL_SOURCES= \ + dbus-asv-util.c \ + dbus-asv-util.h \ dbus-auth-script.c \ dbus-auth-script.h \ dbus-auth-util.c \ diff --git a/dbus/dbus-asv-util.c b/dbus/dbus-asv-util.c index e4440f4c..583e41fa 100644 --- a/dbus/dbus-asv-util.c +++ b/dbus/dbus-asv-util.c @@ -258,57 +258,3 @@ _dbus_asv_add_string (DBusMessageIter *arr_iter, return TRUE; } - -/** - * Create a new entry in an a{sv} (map from string to variant) - * with an array of bytes value. - * - * If this function fails, the a{sv} must be abandoned, for instance - * with _dbus_asv_abandon(). - * - * @param arr_iter the iterator which is appending to the array - * @param key a UTF-8 key for the map - * @param value the value - * @returns #TRUE on success, or #FALSE if not enough memory - */ -dbus_bool_t -_dbus_asv_add_array_of_bytes (DBusMessageIter *arr_iter, - const char *key, - const void *value, - unsigned int value_len) -{ - DBusMessageIter entry_iter, var_iter, sub_array_iter; - - if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key, - DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING, - &var_iter)) - return FALSE; - - if (!dbus_message_iter_open_container (&var_iter, - DBUS_TYPE_ARRAY, - DBUS_TYPE_BYTE_AS_STRING, - &sub_array_iter)) - { - _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter); - return FALSE; - } - - if (!dbus_message_iter_append_fixed_array (&sub_array_iter, DBUS_TYPE_BYTE, - &value, value_len)) - { - dbus_message_iter_abandon_container (&var_iter, &sub_array_iter); - _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter); - return FALSE; - } - - if (!dbus_message_iter_close_container (&var_iter, &sub_array_iter)) - { - _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter); - return FALSE; - } - - if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter)) - return FALSE; - - return TRUE; -} diff --git a/dbus/dbus-asv-util.h b/dbus/dbus-asv-util.h index 4c270bef..0337260a 100644 --- a/dbus/dbus-asv-util.h +++ b/dbus/dbus-asv-util.h @@ -28,23 +28,19 @@ DBUS_BEGIN_DECLS -DBusMessage *_dbus_asv_new_method_return (DBusMessage *message, - DBusMessageIter *iter, - DBusMessageIter *arr_iter); -dbus_bool_t _dbus_asv_close (DBusMessageIter *iter, - DBusMessageIter *arr_iter); -void _dbus_asv_abandon (DBusMessageIter *iter, - DBusMessageIter *arr_iter); +DBusMessage *_dbus_asv_new_method_return (DBusMessage *message, + DBusMessageIter *iter, + DBusMessageIter *arr_iter); +dbus_bool_t _dbus_asv_close (DBusMessageIter *iter, + DBusMessageIter *arr_iter); +void _dbus_asv_abandon (DBusMessageIter *iter, + DBusMessageIter *arr_iter); -dbus_bool_t _dbus_asv_add_uint32 (DBusMessageIter *arr_iter, - const char *key, - dbus_uint32_t value); -dbus_bool_t _dbus_asv_add_string (DBusMessageIter *arr_iter, - const char *key, - const char *value); +dbus_bool_t _dbus_asv_add_uint32 (DBusMessageIter *arr_iter, + const char *key, + dbus_uint32_t value); +dbus_bool_t _dbus_asv_add_string (DBusMessageIter *arr_iter, + const char *key, + const char *value); -dbus_bool_t _dbus_asv_add_array_of_bytes (DBusMessageIter *arr_iter, - const char *key, - const void *value, - unsigned int value_len); #endif diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c index 20af83d2..6a07665f 100644 --- a/dbus/dbus-auth.c +++ b/dbus/dbus-auth.c @@ -2322,39 +2322,6 @@ _dbus_auth_client_new (void) } /** - * Creates a new auth conversation object for the client side. - * In fact it only initialize structures and sets authenticated state - * and leaves authentication to different transport-dependent - * mechanisms. - * - * @returns the new object or #NULL if no memory - */ -DBusAuth* -_dbus_auth_client_new_authenticated (void) -{ - DBusAuth *auth; - DBusString guid_str; - - if (!_dbus_string_init (&guid_str)) - return NULL; - - auth = _dbus_auth_new (sizeof (DBusAuthClient)); - if (auth == NULL) - { - _dbus_string_free (&guid_str); - return NULL; - } - - DBUS_AUTH_CLIENT (auth)->guid_from_server = guid_str; - - auth->side = auth_side_client; - auth->state = &common_state_authenticated; - auth->unix_fd_negotiated = TRUE; - - return auth; -} - -/** * Increments the refcount of an auth object. * * @param auth the auth conversation diff --git a/dbus/dbus-auth.h b/dbus/dbus-auth.h index 9959b991..ba1975f7 100644 --- a/dbus/dbus-auth.h +++ b/dbus/dbus-auth.h @@ -43,7 +43,6 @@ typedef enum DBusAuth* _dbus_auth_server_new (const DBusString *guid); DBusAuth* _dbus_auth_client_new (void); -DBusAuth* _dbus_auth_client_new_authenticated (void); DBusAuth* _dbus_auth_ref (DBusAuth *auth); void _dbus_auth_unref (DBusAuth *auth); dbus_bool_t _dbus_auth_set_mechanisms (DBusAuth *auth, diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h index 3553f7db..682b5bff 100644 --- a/dbus/dbus-connection-internal.h +++ b/dbus/dbus-connection-internal.h @@ -110,7 +110,6 @@ dbus_bool_t _dbus_connection_putback_message (DBusConnectio dbus_bool_t _dbus_connection_remove_message (DBusConnection *connection, DBusMessage *message); -int _dbus_connection_get_n_incoming (DBusConnection *connection); /* if DBUS_ENABLE_STATS */ void _dbus_connection_get_stats (DBusConnection *connection, diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 0c817aa2..618b956d 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -587,20 +587,8 @@ void _dbus_connection_queue_synthesized_message_link (DBusConnection *connection, DBusList *link) { - DBusMessage *msg, *rmsg; - HAVE_LOCK_CHECK (connection); - - msg = (DBusMessage *)link->data; - - rmsg = msg; - _dbus_transport_assure_protocol_version (connection->transport, &rmsg); - - if (rmsg != msg) { - _dbus_list_free_link(link); - link = _dbus_list_alloc_link (rmsg); - } - + _dbus_list_append_link (&connection->incoming_messages, link); connection->n_incoming += 1; @@ -2065,28 +2053,6 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con { dbus_uint32_t serial; - /* Finish preparing the message */ - if (dbus_message_get_serial (message) == 0) - { - serial = _dbus_connection_get_next_client_serial (connection); - dbus_message_set_serial (message, serial); - if (client_serial) - *client_serial = serial; - } - else - { - if (client_serial) - *client_serial = dbus_message_get_serial (message); - } - - _dbus_verbose ("Message %p serial is %u\n", - message, dbus_message_get_serial (message)); - - dbus_message_lock (message); - - /* This converts message if neccessary */ - _dbus_transport_assure_protocol_version (connection->transport, &message); - preallocated->queue_link->data = message; _dbus_list_prepend_link (&connection->outgoing_messages, preallocated->queue_link); @@ -2122,6 +2088,24 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con connection, connection->n_outgoing); + if (dbus_message_get_serial (message) == 0) + { + serial = _dbus_connection_get_next_client_serial (connection); + dbus_message_set_serial (message, serial); + if (client_serial) + *client_serial = serial; + } + else + { + if (client_serial) + *client_serial = dbus_message_get_serial (message); + } + + _dbus_verbose ("Message %p serial is %u\n", + message, dbus_message_get_serial (message)); + + dbus_message_lock (message); + /* Now we need to run an iteration to hopefully just write the messages * out immediately, and otherwise get them queued up */ @@ -2253,6 +2237,52 @@ _dbus_memory_pause_based_on_timeout (int timeout_milliseconds) _dbus_sleep_milliseconds (1000); } +static DBusMessage * +generate_local_error_message (dbus_uint32_t serial, + char *error_name, + char *error_msg) +{ + DBusMessage *message; + message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR); + if (!message) + goto out; + + if (!dbus_message_set_error_name (message, error_name)) + { + dbus_message_unref (message); + message = NULL; + goto out; + } + + dbus_message_set_no_reply (message, TRUE); + + if (!dbus_message_set_reply_serial (message, + serial)) + { + dbus_message_unref (message); + message = NULL; + goto out; + } + + if (error_msg != NULL) + { + DBusMessageIter iter; + + dbus_message_iter_init_append (message, &iter); + if (!dbus_message_iter_append_basic (&iter, + DBUS_TYPE_STRING, + &error_msg)) + { + dbus_message_unref (message); + message = NULL; + goto out; + } + } + + out: + return message; +} + /* * Peek the incoming queue to see if we got reply for a specific serial */ @@ -2495,9 +2525,9 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending) { DBusMessage *error_msg; - error_msg = _dbus_generate_local_error_message (client_serial, - DBUS_ERROR_DISCONNECTED, - "Connection was disconnected before a reply was received"); + error_msg = generate_local_error_message (client_serial, + DBUS_ERROR_DISCONNECTED, + "Connection was disconnected before a reply was received"); /* on OOM error_msg is set to NULL */ complete_pending_call_and_unlock (connection, pending, error_msg); @@ -5247,16 +5277,6 @@ dbus_connection_get_socket(DBusConnection *connection, return retval; } -/** - * - * Getter for number of messages in incoming queue. - * Useful for sending reply to self (see kdbus_do_iteration) - */ -int -_dbus_connection_get_n_incoming (DBusConnection *connection) -{ - return connection->n_incoming; -} /** * Gets the UNIX user ID of the connection if known. Returns #TRUE if diff --git a/dbus/dbus-marshal-gvariant.c b/dbus/dbus-marshal-gvariant.c deleted file mode 100644 index 52595ed9..00000000 --- a/dbus/dbus-marshal-gvariant.c +++ /dev/null @@ -1,1388 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* dbus-marshal-gvariant.c Marshalling routines for GVariant protocol - * - * Copyright (C) 2015 Samsung Electronics - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include <config.h> -#include "dbus-internals.h" -#include "dbus-marshal-gvariant.h" -#include "dbus-protocol-gvariant.h" -#include "dbus-marshal-basic.h" -#include "dbus-message-private.h" -#include "dbus-signature.h" -#include "dbus-connection-internal.h" -#include <endian.h> - -/** Static #DBusString containing the signature of a message header */ -_DBUS_STRING_DEFINE_STATIC(_dbus_header_gvariant_signature_str, DBUS_HEADER_GVARIANT_SIGNATURE); - -#define FIELD_ID_SIZE sizeof(dbus_uint64_t) - -const DBusString * -_dbus_get_gvariant_header_signature_str (void) -{ - return &_dbus_header_gvariant_signature_str; -} - -static dbus_bool_t -append_sized_value (DBusString *str, - size_t value, - size_t value_size) -{ - /* always write as little endian */ - int i; - for (i = 0; i < value_size; i++) - { - size_t move = 8 * i; - size_t mask = 0xFF << move; - if (!_dbus_string_append_byte(str, (value & mask) >> move)) - return FALSE; - } - return TRUE; -} - -#define MAX_OFFSET_SIZE 8 -#define MAX_VALUE_FOR_OFFSET_SIZE(o) ((1ULL<<(8*(o)))-1) - -/* taken from systemd */ -static size_t -bus_gvariant_determine_word_size(size_t sz, size_t extra) -{ - if (sz + extra <= 0xFF) - return 1; - else if (sz + extra*2 <= 0xFFFF) - return 2; - else if (sz + extra*4 <= 0xFFFFFFFF) - return 4; - else - return 8; -} - -/* taken from systemd */ -static size_t -bus_gvariant_read_word_le (const void *p, size_t sz) -{ - union { - uint16_t u16; - uint32_t u32; - uint64_t u64; - } x; - - // FIXME -// assert(p); - - if (sz == 1) - return *(uint8_t*) p; - - memcpy(&x, p, sz); - - if (sz == 2) - return le16toh(x.u16); - else if (sz == 4) - return le32toh(x.u32); - else if (sz == 8) - return le64toh(x.u64); - return 0; -} - -static const char * -get_header_const_array (DBusHeader *header) -{ - return _dbus_string_get_const_data (&header->data) + FIRST_GVARIANT_FIELD_OFFSET; -} - -static size_t -get_header_array_size (DBusHeader *header) -{ - return _dbus_string_get_length (&header->data) - FIRST_GVARIANT_FIELD_OFFSET - header->padding; -} - -static dbus_bool_t -append_offsets (DBusString *str, - size_t *fields_offsets, - size_t n_fields_offsets) -{ - int i; - size_t array_size = _dbus_string_get_length (str) - FIRST_GVARIANT_FIELD_OFFSET; - size_t offset_size = bus_gvariant_determine_word_size (array_size, n_fields_offsets); - - for (i = 0; i < n_fields_offsets; i++) - { - if (!append_sized_value (str, fields_offsets[i], offset_size)) - return FALSE; - } - return TRUE; -} - -static dbus_bool_t -append_field_string (DBusString *str, - dbus_uint64_t field, - const char *value, - char type, - size_t *fields_offsets, - size_t *n_fields_offsets) -{ - dbus_bool_t res = TRUE; - if (value != NULL) - { - res = res && _dbus_string_align_length(str, 8); - res = res && append_sized_value(str, field, FIELD_ID_SIZE); - res = res && _dbus_string_append_len(str, value, strlen(value)+1); - res = res && _dbus_string_append_byte(str, 0); /* variant value-signature separator */ - res = res && _dbus_string_append_byte(str, type); - fields_offsets[(*n_fields_offsets)++] = _dbus_string_get_length(str) - FIRST_GVARIANT_FIELD_OFFSET; - } - return res; -} - -static dbus_bool_t -append_field_uint64 (DBusString *str, - dbus_uint64_t field, - dbus_uint64_t value, - size_t *fields_offsets, - size_t *n_fields_offsets) -{ - dbus_bool_t res = TRUE; - res = res && _dbus_string_align_length(str, 8); - res = res && append_sized_value(str, field, FIELD_ID_SIZE); - res = res && append_sized_value(str, value, 8); - res = res && _dbus_string_append_byte(str, 0); /* variant value-signature separator */ - res = res && _dbus_string_append_byte(str, DBUS_TYPE_UINT64); - fields_offsets[(*n_fields_offsets)++] = _dbus_string_get_length(str) - FIRST_GVARIANT_FIELD_OFFSET; - return res; -} - -static dbus_bool_t -append_field_uint32 (DBusString *str, - dbus_uint64_t field, - dbus_uint32_t value, - size_t *fields_offsets, - size_t *n_fields_offsets) -{ - dbus_bool_t res = TRUE; - res = res && _dbus_string_align_length(str, 8); - res = res && append_sized_value(str, field, FIELD_ID_SIZE); - res = res && append_sized_value(str, value, 4); - res = res && _dbus_string_append_byte(str, 0); /* variant value-signature separator */ - res = res && _dbus_string_append_byte(str, DBUS_TYPE_UINT32); - - fields_offsets[(*n_fields_offsets)++] = _dbus_string_get_length(str) - FIRST_GVARIANT_FIELD_OFFSET; - return res; -} - -static void -_dbus_header_toggle_gvariant (DBusHeader *header, dbus_bool_t gvariant) -{ - header->protocol_version = gvariant ? DBUS_PROTOCOL_VERSION_GVARIANT : DBUS_MAJOR_PROTOCOL_VERSION; -} - -static const char * -get_next_field_address (const char *array_buffer, size_t offset) -{ - return array_buffer + _DBUS_ALIGN_VALUE(offset, 8); -} - -static dbus_uint64_t -get_field_after (const char *array_buffer, size_t offset) -{ - return *(dbus_uint64_t*)(get_next_field_address(array_buffer, offset)); -} - -static void -_dbus_header_fill_cache (DBusHeader *header, - size_t *fields_offsets, - size_t n_fields_offsets) -{ - const char *array_buffer = get_header_const_array (header); - int i; - - if (get_header_array_size (header) > 0) - { - header->fields[get_field_after (array_buffer, 0)].value_pos = FIELD_ID_SIZE + FIRST_GVARIANT_FIELD_OFFSET; - for (i=0; i < n_fields_offsets-1; i++) - { - dbus_uint64_t field = get_field_after (array_buffer, fields_offsets[i]); - header->fields[field].value_pos = _DBUS_ALIGN_VALUE(fields_offsets[i],8) + - FIELD_ID_SIZE + FIRST_GVARIANT_FIELD_OFFSET; - } - } -} - -static dbus_bool_t -correct_header_padding (DBusHeader *header) -{ - int unpadded_len = _dbus_string_get_length (&header->data); - if (!_dbus_string_align_length (&header->data, 8)) - return FALSE; - - header->padding = _dbus_string_get_length (&header->data) - unpadded_len; - return TRUE; -} - -dbus_bool_t -_dbus_header_gvariant_create (DBusHeader *header, - int byte_order, - int type, - const char *destination, - const char *path, - const char *interface, - const char *member, - const char *error_name) -{ - size_t fields_offsets[DBUS_HEADER_FIELD_LAST]; - size_t n_fields_offsets = 0; - dbus_bool_t res = TRUE; - - _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || - byte_order == DBUS_BIG_ENDIAN); - _dbus_assert (((interface || type != DBUS_MESSAGE_TYPE_SIGNAL) && member) || - (error_name) || - !(interface || member || error_name)); - _dbus_assert (_dbus_string_get_length (&header->data) == 0); - - _dbus_header_toggle_gvariant (header, TRUE); - - res = res && _dbus_string_append_byte (&header->data, byte_order); - res = res && _dbus_string_append_byte (&header->data, type); - res = res && _dbus_string_append_byte (&header->data, 0); /* flags */ - res = res && _dbus_string_append_byte (&header->data, DBUS_PROTOCOL_VERSION_GVARIANT); - res = res && append_sized_value (&header->data, 0, sizeof(dbus_uint32_t)); /* reserved */ - res = res && append_sized_value (&header->data, 0, sizeof(dbus_uint64_t)); /* cookie */ - /* array of fields */ - res = res && append_field_string (&header->data, DBUS_HEADER_FIELD_PATH, path, DBUS_TYPE_OBJECT_PATH, - fields_offsets, &n_fields_offsets); - res = res && append_field_string (&header->data, DBUS_HEADER_FIELD_DESTINATION, destination, DBUS_TYPE_STRING, - fields_offsets, &n_fields_offsets); - res = res && append_field_string (&header->data, DBUS_HEADER_FIELD_INTERFACE, interface, DBUS_TYPE_STRING, - fields_offsets, &n_fields_offsets); - res = res && append_field_string (&header->data, DBUS_HEADER_FIELD_MEMBER, member, DBUS_TYPE_STRING, - fields_offsets, &n_fields_offsets); - res = res && append_field_string (&header->data, DBUS_HEADER_FIELD_ERROR_NAME, error_name, DBUS_TYPE_STRING, - fields_offsets, &n_fields_offsets); - res = res && append_offsets (&header->data, fields_offsets, n_fields_offsets); - - _dbus_header_fill_cache (header, fields_offsets, n_fields_offsets); - res = res && correct_header_padding (header); - - return res; -} - -static dbus_bool_t -marshal_gvariant_string (DBusString *str, - int insert_at, - const char *value, - int *pos_after, - dbus_bool_t with_nul) -{ - DBusString value_str; - size_t value_len = strlen(value); - - if (with_nul) - value_len++; - - _dbus_string_init_const_len (&value_str, value, value_len); - if (!_dbus_string_copy_len (&value_str, 0, value_len, str, insert_at)) - { - return FALSE; - } - - if (pos_after) - *pos_after = insert_at + value_len; - - return TRUE; -} - -dbus_bool_t -_dbus_marshal_write_gvariant_basic (DBusString *str, - int insert_at, - int type, - const void *value, - int byte_order, - int *pos_after) -{ - const DBusBasicValue *vp; - _dbus_assert (dbus_type_is_basic (type)); - - vp = value; - - switch (type) - { - case DBUS_TYPE_STRING: - case DBUS_TYPE_OBJECT_PATH: - case DBUS_TYPE_SIGNATURE: - return marshal_gvariant_string (str, insert_at, vp->str, pos_after, TRUE); - case DBUS_TYPE_BOOLEAN: - if (pos_after) - (*pos_after)++; - return _dbus_string_insert_byte (str, insert_at, vp->u32 != FALSE); - default: - return _dbus_marshal_write_basic (str, insert_at, type, value, byte_order, pos_after); - } -} - -void -_dbus_marshal_read_gvariant_basic (const DBusString *str, - int pos, - int type, - void *value, - int byte_order, - int *new_pos) -{ - const char *str_data; - - _dbus_assert (dbus_type_is_basic (type)); - - str_data = _dbus_string_get_const_data (str); - switch (type) - { - case DBUS_TYPE_STRING: - case DBUS_TYPE_OBJECT_PATH: - case DBUS_TYPE_SIGNATURE: - { - volatile char **vp = value; - *vp = (char*) str_data + pos; - pos += strlen (str_data+pos)+1; - } - break; - case DBUS_TYPE_BOOLEAN: - { - volatile dbus_bool_t *vp = value; - *vp = (dbus_bool_t) _dbus_string_get_byte (str, pos); - (pos)++; - } - break; - default: - _dbus_marshal_read_basic (str, pos, type, value, byte_order, new_pos); - break; - } - - if (new_pos) - *new_pos = pos; -} - -static void -get_offsets (const char *buffer, size_t container_size, - size_t *fields_offsets, size_t *n_fields_offsets, - size_t *offset_size) -{ - *offset_size = bus_gvariant_determine_word_size (container_size, 0); - - if (0 < container_size && 0 < *offset_size) - { - size_t last_offset_position = container_size - (*offset_size); - size_t last_offset = bus_gvariant_read_word_le (buffer + last_offset_position, - (*offset_size)); - int i; - - *n_fields_offsets = (container_size - last_offset) / (*offset_size); - fields_offsets[(*n_fields_offsets)-1] = last_offset; - for (i = 0; i < (*n_fields_offsets)-1; i++) - { - fields_offsets[i] = bus_gvariant_read_word_le (buffer + last_offset + i*(*offset_size), - (*offset_size)); - } - } -} - -static int -find_field (int field, const char *array_buffer, size_t *fields_offsets, size_t n_fields_offsets, - size_t *field_offset) -{ - /* last_offset points to the offsets array, beyond the last element of the array container */ - size_t last_offset = fields_offsets[n_fields_offsets-1]; - int i = 0; - size_t next_offset = 0; - - while ( next_offset < last_offset && get_field_after (array_buffer, next_offset) != field) - { - next_offset = fields_offsets[i]; - i++; - } - if (next_offset < last_offset) - { - *field_offset = next_offset; - return i; - } - return -1; -} - -dbus_bool_t -_dbus_header_gvariant_delete_field (DBusHeader *header, - int field) -{ - size_t fields_offsets[DBUS_HEADER_FIELD_LAST]; - size_t n_fields_offsets = 0; - size_t offset_size = 0; - const char *array_buffer; - - _dbus_assert(field <= DBUS_HEADER_FIELD_LAST); - - array_buffer = get_header_const_array (header); - - get_offsets (array_buffer, - get_header_array_size (header), - fields_offsets, &n_fields_offsets, &offset_size ); - - if (0 < n_fields_offsets) - { - /* check if the field is already in the header */ - size_t field_offset; - int field_index = find_field (field, array_buffer, fields_offsets, n_fields_offsets, &field_offset); - - /* prepare for changing - remove array offsets and offsets */ - _dbus_string_shorten (&header->data, n_fields_offsets*offset_size + header->padding); - - if (field_index >= 0) - { - /* field exists */ - size_t field_len = 0; - size_t field_start = 0; - /* let's remove aligned block of the field, along with padding */ - if (field_index == 0) - { - field_len = _DBUS_ALIGN_VALUE (fields_offsets[0],8); - } - else - { - field_len = _DBUS_ALIGN_VALUE (fields_offsets[field_index],8) - - _DBUS_ALIGN_VALUE (fields_offsets[field_index-1],8); - } - - field_start = FIRST_GVARIANT_FIELD_OFFSET + _DBUS_ALIGN_VALUE (field_offset, 8); - - /* if this is the last field, then there is no padding at the end */ - if (field_start + field_len > _dbus_string_get_length (&header->data)) - { - field_len = _dbus_string_get_length (&header->data) - field_start; - } - - /* remove the field */ - _dbus_string_delete (&header->data, field_start, field_len); - header->fields[field].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT; - /* and update offsets */ - for (; field_index < n_fields_offsets-1; field_index++) - { - fields_offsets[field_index] = fields_offsets[field_index+1]-field_len; - } - n_fields_offsets--; - - /* remove padding from now-last field */ - _dbus_string_shorten (&header->data, - _dbus_string_get_length(&header->data) - - (FIRST_GVARIANT_FIELD_OFFSET + fields_offsets[n_fields_offsets-1])); - header->padding = 0; - } - } - - /* It seems impossible for append_offsets() and correct_header_padding() to fail, - because space for offsets was already allocated */ - if (!append_offsets(&header->data, fields_offsets, n_fields_offsets)) - return FALSE; - _dbus_header_fill_cache (header, fields_offsets, n_fields_offsets); - if (!correct_header_padding (header)) - return FALSE; - - return TRUE; -} - -dbus_bool_t -_dbus_header_set_field_basic_gvariant (DBusHeader *header, - int field, - int type, - const void *value) -{ - size_t fields_offsets[DBUS_HEADER_FIELD_LAST]; - size_t n_fields_offsets = 0; - dbus_bool_t result = TRUE; - const DBusBasicValue *vp = value; - size_t offset_size = 0; - const char *array_buffer; - - _dbus_assert(field != DBUS_HEADER_FIELD_INVALID); - _dbus_assert(field <= DBUS_HEADER_FIELD_LAST); - - array_buffer = get_header_const_array (header); - - result = result && _dbus_header_gvariant_delete_field (header, field); - - /* now, we are sure that there is no such field (anymore) - so, simply append */ - - get_offsets (array_buffer, - get_header_array_size (header), - fields_offsets, &n_fields_offsets, &offset_size ); - - /* prepare for changing - remove array offsets and padding */ - _dbus_string_shorten (&header->data, n_fields_offsets*offset_size + header->padding); - - switch (type) - { - case DBUS_TYPE_STRING: - case DBUS_TYPE_OBJECT_PATH: - case DBUS_TYPE_SIGNATURE: - result = result && append_field_string (&header->data, field, vp->str, type, - fields_offsets, &n_fields_offsets); - break; - case DBUS_TYPE_UINT32: - result = result && append_field_uint32 (&header->data, field, vp->u32, - fields_offsets, &n_fields_offsets); - break; - case DBUS_TYPE_UINT64: - append_field_uint64 (&header->data, field, vp->u64, - fields_offsets, &n_fields_offsets); - result = TRUE; - break; - default: - _dbus_assert_not_reached("Not a basic type"); - result = FALSE; - break; - } - - result = result && append_offsets(&header->data, fields_offsets, n_fields_offsets); - _dbus_header_fill_cache (header, fields_offsets, n_fields_offsets); - result = result && correct_header_padding (header); - - return result; -} - -dbus_bool_t -_dbus_header_get_field_basic_gvariant (DBusHeader *header, - int field, - int type, - void *value) -{ - size_t fields_offsets[DBUS_HEADER_FIELD_LAST]; - size_t n_fields_offsets = 0; - dbus_bool_t result = FALSE; - DBusBasicValue *vp = value; - size_t offset_size = 0; - const char *array_buffer; - - _dbus_assert(field != DBUS_HEADER_FIELD_INVALID); - _dbus_assert(field <= DBUS_HEADER_FIELD_LAST); - - array_buffer = get_header_const_array (header); - - get_offsets( array_buffer, - get_header_array_size (header), - fields_offsets, &n_fields_offsets, &offset_size ); - - if (0 < n_fields_offsets) - { - /* check if the field is already in the header */ - size_t field_offset; - int field_index = find_field (field, array_buffer, fields_offsets, n_fields_offsets, &field_offset); - if (0 <= field_index) - { - /* field found, get value */ - const void *field_begin = array_buffer + _DBUS_ALIGN_VALUE(field_offset,8) + FIELD_ID_SIZE; - dbus_uint32_t byte_order = _dbus_header_get_byte_order (header); - - switch (type) - { - case DBUS_TYPE_STRING: - case DBUS_TYPE_OBJECT_PATH: - case DBUS_TYPE_SIGNATURE: - { - vp->str = (char *)field_begin; - } - break; - case DBUS_TYPE_UINT32: - { - vp->u32 = *(const dbus_uint32_t *)field_begin; - if (byte_order != DBUS_COMPILER_BYTE_ORDER) - vp->u32 = DBUS_UINT32_SWAP_LE_BE (vp->u32); - } - break; - case DBUS_TYPE_UINT64: - { - vp->u64 = *(const dbus_uint64_t *)field_begin; - if (byte_order != DBUS_COMPILER_BYTE_ORDER) - vp->u64 = DBUS_UINT64_SWAP_LE_BE (vp->u64); - } - break; - default: - _dbus_assert_not_reached("Not a basic type"); - break; - } - - result = TRUE; - } - } - return result; -} - -void -_dbus_marshal_skip_gvariant_basic (const DBusString *str, - int type, - int byte_order, - int *pos) -{ - switch (type) - { - case DBUS_TYPE_STRING: - case DBUS_TYPE_OBJECT_PATH: - case DBUS_TYPE_SIGNATURE: - /* FIXME - this will require redesign... size should come from upper container */ - *pos += strlen (_dbus_string_get_const_data (str) + *pos) + 1; /* length plus nul */ - break; - case DBUS_TYPE_BOOLEAN: - (*pos)++; - break; - default: - _dbus_marshal_skip_basic (str, type, byte_order, pos); - break; - } -} - -dbus_bool_t -_dbus_header_load_gvariant (DBusHeader *header, - DBusTypeReader *reader, - DBusValidity *validity) -{ - size_t fields_offsets[DBUS_HEADER_FIELD_LAST]; - size_t n_fields_offsets = 0; - size_t offset_size = 0; - const char *array_buffer = get_header_const_array (header); - - get_offsets( array_buffer, - get_header_array_size (header), - fields_offsets, &n_fields_offsets, &offset_size ); - - _dbus_header_fill_cache (header, fields_offsets, n_fields_offsets); - return TRUE; -} - -dbus_bool_t -_dbus_gvariant_raw_get_lengths (const DBusString *str, - dbus_uint32_t *fields_array_len_unsigned, - dbus_uint32_t *body_len_unsigned, - DBusValidity *validity) -{ - size_t message_len = _dbus_string_get_length (str); - size_t body_offsets_size = bus_gvariant_determine_word_size (message_len, 0); - const char *message_ptr = _dbus_string_get_const_data (str); - /* so, the offset of end of fields is written at offset str->len - body_offsets_size */ - size_t end_of_fields = bus_gvariant_read_word_le (message_ptr + message_len - body_offsets_size, - body_offsets_size); - *fields_array_len_unsigned = end_of_fields - FIRST_GVARIANT_FIELD_OFFSET; - - *body_len_unsigned = message_len - _DBUS_ALIGN_VALUE (end_of_fields, 8); - return TRUE; -} - -DBusValidity -_dbus_validate_gvariant_body_with_reason (const DBusString *expected_signature, - int expected_signature_start, - int byte_order, - int *bytes_remaining, - const DBusString *value_str, - int value_pos, - int len) -{ - /* FIXME stub */ - if (bytes_remaining) - *bytes_remaining = 0; - return DBUS_VALID; -} - -dbus_bool_t -_dbus_message_gvariant_get_signature (DBusMessage *message, - const DBusString **type_str_p, - int *type_pos_p, - int *type_str_len) -{ - size_t body_len = _dbus_string_get_length (&message->body); - size_t message_len = _dbus_string_get_length (&message->header.data) + body_len; - size_t body_offsets_size = bus_gvariant_determine_word_size (message_len, 0); - const char *body_ptr = _dbus_string_get_const_data (&message->body); - const char *sig_end_ptr = body_ptr + body_len - body_offsets_size; - const char *sig_ptr = sig_end_ptr - 1; - - while (sig_ptr >= body_ptr && (*sig_ptr) != 0) - { - sig_ptr--; - } - - if (sig_ptr < body_ptr) - return FALSE; - - if (type_str_p != NULL) - *type_str_p = &message->body; - *type_pos_p = sig_ptr - body_ptr + 1; - *type_str_len = sig_end_ptr - sig_ptr - 1; - - return TRUE; -} - -dbus_bool_t -_dbus_message_append_body_offset (DBusMessage *message) -{ - size_t body_len = _dbus_string_get_length (&message->body); - size_t end_of_fields_offset = _dbus_string_get_length (&message->header.data) - message->header.padding; - size_t message_len = _dbus_string_get_length (&message->header.data) + body_len; - size_t body_offsets_size = bus_gvariant_determine_word_size (message_len, 1); - - return append_sized_value (&message->body, end_of_fields_offset, body_offsets_size); -} - -dbus_bool_t -_dbus_message_gvariant_add_signature (DBusMessage *message, - const DBusString *type_str) -{ - dbus_bool_t res = _dbus_string_append_byte (&message->body, 0); - res = res && _dbus_string_append_byte (&message->body, '('); - res = res && marshal_gvariant_string (&message->body, _dbus_string_get_length (&message->body), - _dbus_string_get_const_data (type_str), NULL, FALSE); - res = res && _dbus_string_append_byte (&message->body, ')'); - return res; -} - -dbus_bool_t -_dbus_message_gvariant_remove_body_offset (DBusMessage *message) -{ - size_t offset_size = bus_gvariant_determine_word_size (_dbus_string_get_length (&message->header.data) + - _dbus_string_get_length (&message->body), - 0); - _dbus_string_shorten (&message->body, offset_size); - return TRUE; -} - -dbus_bool_t -_dbus_message_finalize_gvariant (DBusMessage *message, dbus_bool_t remove_signature_from_header) -{ - DBusString str; - const DBusString *type_str; - int type_pos; - dbus_bool_t fieldSignaturePresent; - dbus_bool_t res = TRUE; - - _dbus_assert (!message->locked); - - if (message->header.protocol_version != DBUS_PROTOCOL_VERSION_GVARIANT) - return TRUE; - - fieldSignaturePresent = _dbus_header_get_field_raw (&message->header, - DBUS_HEADER_FIELD_SIGNATURE, - &type_str, - &type_pos); - if (fieldSignaturePresent) - { - /* if there is signature field, then we need to move this signature to body, - * and delete the field - */ - const char *sig_ptr = _dbus_string_get_const_data (type_str) + type_pos; - _dbus_string_init_const (&str, sig_ptr); - } - else - { - /* If there is no signature field, then the body is empty. - * However, we need to add signature anyway, because body is a variant. - */ - _dbus_string_init_const (&str, ""); - type_str = &str; - type_pos = 0; - /* Let's set the body also */ - _dbus_string_set_length (&message->body, 0); - _dbus_string_append_byte (&message->body, 0); - } - - res = res && _dbus_message_gvariant_add_signature (message, &str); - - if (res && fieldSignaturePresent && remove_signature_from_header) - res = res && _dbus_header_gvariant_delete_field (&message->header, DBUS_HEADER_FIELD_SIGNATURE); - - res = res && _dbus_message_append_body_offset (message); - - return res; -} - -/* returns length of the body inside the outermost variant - * that is, without offset and signature from the end of messages - */ -static size_t -_dbus_message_gvariant_get_body_length (DBusMessage *message) -{ - size_t body_len = _dbus_string_get_length (&message->body); - size_t message_len = body_len + _dbus_string_get_length (&message->header.data); - body_len -= bus_gvariant_determine_word_size (message_len , 0); - - while (body_len > 0 && _dbus_string_get_byte (&message->body, body_len) != 0) - body_len--; - - return body_len; -} - -static inline int -get_max (int a, int b) -{ - return (a>b) ? a : b; -} - -static int -update_size (int current_size, int size_of_element, int *alignment, int new_alignment) -{ - *alignment = get_max (*alignment, new_alignment); - current_size = _DBUS_ALIGN_VALUE (current_size, *alignment); - return current_size + size_of_element; -} - -static int -_dbus_reader_get_signature_fixed_size (const DBusString *signature, int *pos, int *alignment) -{ - int res = 0; - int depth = 0; - int current_alignment = 1; - dbus_bool_t variable = FALSE; - - char c = _dbus_string_get_byte (signature, *pos); - if (c == DBUS_STRUCT_BEGIN_CHAR || c == DBUS_DICT_ENTRY_BEGIN_CHAR) - { - depth = 1; - (*pos)++; - } - - do { - switch (_dbus_string_get_byte (signature, *pos)) - { - case DBUS_TYPE_BYTE: - case DBUS_TYPE_BOOLEAN: - res += 1; - break; - case DBUS_TYPE_INT16: - case DBUS_TYPE_UINT16: - res = update_size (res, 2, ¤t_alignment, 2); - break; - case DBUS_TYPE_INT32: - case DBUS_TYPE_UINT32: - case DBUS_TYPE_UNIX_FD: - res = update_size (res, 4, ¤t_alignment, 4); - break; - case DBUS_TYPE_INT64: - case DBUS_TYPE_UINT64: - case DBUS_TYPE_DOUBLE: - res = update_size (res, 8, ¤t_alignment, 8); - break; - case DBUS_STRUCT_END_CHAR: - case DBUS_DICT_ENTRY_END_CHAR: - depth--; - break; - case DBUS_STRUCT_BEGIN_CHAR: - case DBUS_DICT_ENTRY_BEGIN_CHAR: - { - int alignment_recursive; - int res_recursive = _dbus_reader_get_signature_fixed_size (signature, pos, &alignment_recursive); - if (res_recursive == 0) - variable = TRUE; /* variable size detected */ - - /* we need to update at least alignment */ - res = update_size (res, res_recursive, ¤t_alignment, alignment_recursive); - } - break; - case DBUS_TYPE_VARIANT: - current_alignment = 8; - variable = TRUE; - break; - case DBUS_TYPE_ARRAY: - { - int alignment_recursive; - int recursive_pos = *pos + 1; - int res_recursive = _dbus_reader_get_signature_fixed_size (signature, &recursive_pos, &alignment_recursive); - - variable = TRUE; /* variable size detected */ - - /* we need to update alignment */ - res = update_size (res, res_recursive, ¤t_alignment, alignment_recursive); - - /* and update position */ - *pos = recursive_pos - 1; - } - break; - default: - variable = TRUE; /* variable size detected */ - } - (*pos)++; - } while (depth > 0); - - /* we want to point it to the last character, to allow upper instance to skip it */ - (*pos)--; - - if (alignment != NULL) - *alignment = current_alignment; - - return variable ? 0 : res; -} - -int -_dbus_reader_get_type_fixed_size (DBusTypeReader *reader, int *alignment) -{ - int pos = reader->type_pos; - return _dbus_reader_get_signature_fixed_size (reader->type_str, &pos, alignment); -} - -int -_dbus_type_gvariant_get_fixed_size (const DBusString *type_str, int type_pos, int *alignment) -{ - return _dbus_reader_get_signature_fixed_size (type_str, &type_pos, alignment); -} - -/* This is for structs and dict entries. - * Counts variable elements inside a container. - * This is equal to number of offsets embedded into the container. - */ -int -_dbus_reader_count_offsets (const DBusTypeReader *reader) -{ - DBusTypeReader r; - int variables = 0; - dbus_bool_t prev_is_variable = FALSE; - int current_type; - int ending_char; - - /* if signature is not empty, it must be after initial parenthesis */ - /* empty signature has length 1 - only nul byte */ - _dbus_assert (reader->type_pos > 0); - - _dbus_type_reader_init_types_only (&r, - reader->type_str, - reader->type_pos); - r.gvariant = TRUE; - r.klass = reader->klass; - - /* Check what container we're in */ - switch (_dbus_string_get_byte (r.type_str, r.type_pos-1)) - { - case DBUS_STRUCT_BEGIN_CHAR: - ending_char = DBUS_STRUCT_END_CHAR; - break; - case DBUS_DICT_ENTRY_BEGIN_CHAR: - ending_char = DBUS_DICT_ENTRY_END_CHAR; - break; - default: - _dbus_assert_not_reached ("function must be called inside structs or dict entries"); - break; - } - r.finished = (_dbus_string_get_byte (r.type_str, r.type_pos) == ending_char); - - while ((current_type = _dbus_type_reader_get_current_type (&r)) != DBUS_TYPE_INVALID) - { - int size = _dbus_reader_get_type_fixed_size (&r, NULL); - if (prev_is_variable) - variables++; - prev_is_variable = (size == 0); - _dbus_type_signature_next (_dbus_string_get_const_data(r.type_str), &r.type_pos); - r.finished = (_dbus_string_get_byte (r.type_str, r.type_pos) == ending_char); - } - return variables; -} - -size_t -_dbus_reader_get_offset_of_end_of_variable (DBusTypeReader *reader) -{ - if (reader->is_variant) - { - /* variant has its end set to the separating 0 */ - return reader->value_end; - } - else - { - const char *buffer = _dbus_string_get_const_data (reader->value_str) + reader->value_start; - size_t container_size = reader->value_end - reader->value_start; - size_t offset_size = bus_gvariant_determine_word_size (container_size, 0); - int index_from_back = reader->offsets_from_back ? - reader->variable_index : - reader->n_offsets - 1 - reader->variable_index; - - if (0 < container_size && 0 <= index_from_back) - { - size_t required_offset_position = container_size - (index_from_back+1)*offset_size; - if (index_from_back < reader->n_offsets) - return reader->value_start + - bus_gvariant_read_word_le (buffer + required_offset_position, - offset_size); - else if (reader->offsets_from_back) - return reader->value_start + - container_size - (reader->n_offsets * offset_size); /* this is end of internal container */ - } - } - - return reader->value_start; -} - -int -_dbus_reader_count_array_elems (const DBusTypeReader *reader) -{ - const char *buffer = _dbus_string_get_const_data (reader->value_str) + reader->value_start; - size_t container_size = reader->value_end - reader->value_start; - size_t offset_size = bus_gvariant_determine_word_size (container_size, 0); - size_t last_offset = bus_gvariant_read_word_le (buffer + container_size - offset_size, offset_size); - return (container_size - last_offset) / offset_size; -} - -static dbus_bool_t -write_offset (DBusString *offsets, - size_t offset, - size_t offset_size, - int insert_at) -{ - DBusString str; - dbus_bool_t res = _dbus_string_init_preallocated (&str, offset_size); - res = res && append_sized_value (&str, offset, offset_size); - res = res && _dbus_string_copy_len (&str, 0, offset_size, offsets, insert_at); - _dbus_string_free (&str); - return res; -} - -static dbus_bool_t -prepend_offset (DBusString *offsets, - size_t offset, - size_t offset_size) -{ - return write_offset (offsets, offset, offset_size, 0); -} - -static dbus_bool_t -append_offset (DBusString *offsets, - size_t offset, - size_t offset_size) -{ - return write_offset (offsets, offset, offset_size, _dbus_string_get_length(offsets)); -} - -static dbus_bool_t -convert_offsets (DBusString *offsets, - size_t old_offsets_size, - size_t new_offsets_size) -{ - char *old_offsets = NULL; - size_t n_offsets = _dbus_string_get_length (offsets) / old_offsets_size; - dbus_bool_t result = _dbus_string_steal_data (offsets, &old_offsets); - int i; - - for (i = 0; i < n_offsets && result; i++) - { - size_t offset = bus_gvariant_read_word_le (old_offsets + i*old_offsets_size, old_offsets_size); - result = result && append_sized_value (offsets, offset, new_offsets_size); - } - - dbus_free (old_offsets); - - return result; -} - -static size_t -get_offsets_count (DBusString *offsets, size_t offsets_size) -{ - return _dbus_string_get_length (offsets) / offsets_size; -} - -static dbus_bool_t -check_offsets_for_adding (DBusTypeWriter *writer) -{ - size_t container_size = writer->value_pos - writer->value_start; - size_t n_offsets = get_offsets_count (writer->offsets, - writer->offsets_size); - size_t offsets_size = bus_gvariant_determine_word_size (container_size, n_offsets + 1); - if (offsets_size != writer->offsets_size) - { - if (!convert_offsets (writer->offsets, writer->offsets_size, offsets_size)) - return FALSE; - writer->offsets_size = offsets_size; - } - return TRUE; -} - -static dbus_bool_t -convert_offsets_in_body (DBusTypeWriter *writer, - size_t new_offsets_size) -{ - DBusString offsets; - size_t n_offsets; - int i; - dbus_bool_t result = _dbus_string_init (&offsets); - char *old_offsets; - - result = result && _dbus_string_move (writer->value_str, writer->value_pos, &offsets, 0); - n_offsets = _dbus_string_get_length (&offsets) / writer->offsets_size; - old_offsets = _dbus_string_get_data (&offsets); - - for (i = 0; i < n_offsets && result; i++) - { - size_t offset = bus_gvariant_read_word_le (old_offsets + i*writer->offsets_size, writer->offsets_size); - result = result && append_sized_value (writer->value_str, offset, new_offsets_size); - } - - _dbus_string_free (&offsets); - return result; -} - -static dbus_bool_t -check_offsets_in_body_for_adding (DBusTypeWriter *writer) -{ - size_t container_size = writer->value_pos - writer->value_start; - size_t n_offsets = (_dbus_string_get_length (writer->value_str) - writer->value_pos) / writer->offsets_size; - size_t offsets_size = bus_gvariant_determine_word_size (container_size, n_offsets + 1); - if (offsets_size != writer->offsets_size) - { - if (!convert_offsets_in_body (writer, offsets_size)) - return FALSE; - writer->offsets_size = offsets_size; - } - return TRUE; -} - -static dbus_bool_t -_dbus_writer_gvariant_add_offset_with_variability (DBusTypeWriter *writer, - dbus_bool_t fixed) -{ - writer->is_fixed = writer->is_fixed && fixed; - - if (writer->body_container || - DBUS_TYPE_STRUCT == writer->container_type || - DBUS_TYPE_DICT_ENTRY == writer->container_type) - { - if (writer->u.struct_or_dict.last_offset != 0) - { - if (writer->body_container) - { - check_offsets_in_body_for_adding (writer); - - write_offset (writer->value_str, - writer->u.struct_or_dict.last_offset, - writer->offsets_size, - writer->value_pos); - } - else - { - check_offsets_for_adding (writer); - - prepend_offset (writer->offsets, - writer->u.struct_or_dict.last_offset, - writer->offsets_size); - } - } - if (!fixed) - { - writer->u.struct_or_dict.last_offset = writer->value_pos - writer->value_start; - } - else - { - writer->u.struct_or_dict.last_offset = 0; - } - } - else if (DBUS_TYPE_ARRAY == writer->container_type) - { - if (writer->offsets_size > 0) - { - check_offsets_for_adding (writer); - - if (!append_offset (writer->offsets, - writer->value_pos - writer->value_start, - writer->offsets_size)) - return FALSE; - } - } - return TRUE; -} - -static dbus_bool_t -_dbus_writer_gvariant_add_offset (DBusTypeWriter *writer, - int type) -{ - return _dbus_writer_gvariant_add_offset_with_variability (writer, dbus_type_is_fixed (type)); -} - -/* this function gets only known alignments - other are 1 */ -static int -get_alignment (int type) -{ - switch (type) - { - case DBUS_TYPE_INT16: - case DBUS_TYPE_UINT16: - return 2; - case DBUS_TYPE_INT32: - case DBUS_TYPE_UINT32: - case DBUS_TYPE_UNIX_FD: - return 4; - case DBUS_TYPE_INT64: - case DBUS_TYPE_UINT64: - case DBUS_TYPE_DOUBLE: - case DBUS_TYPE_VARIANT: - return 8; - default: - break; - } - return 1; -} - -static dbus_bool_t -fix_struct_alignment_value (DBusTypeWriter *writer, int alignment) -{ - dbus_bool_t result = TRUE; - int old_alignment = writer->alignment; - if (old_alignment < alignment) - { - int diff = _DBUS_ALIGN_VALUE (writer->value_start, alignment) - writer->value_start; - result = _dbus_string_insert_bytes (writer->value_str, writer->value_start, diff, 0); - writer->value_start += diff; - writer->value_pos += diff; - writer->alignment = alignment; - } - return result; -} - -static dbus_bool_t -fix_struct_alignment (DBusTypeWriter *writer, int type) -{ - return fix_struct_alignment_value (writer, get_alignment (type)); -} - -dbus_bool_t -_dbus_type_writer_gvariant_write_basic_no_typecode (DBusTypeWriter *writer, - int type, - const void *value) -{ - dbus_bool_t result = TRUE; - - if (writer->container_type == DBUS_TYPE_STRUCT || writer->container_type == DBUS_TYPE_DICT_ENTRY) - result = fix_struct_alignment (writer, type); - - result = result && _dbus_marshal_write_gvariant_basic (writer->value_str, - writer->value_pos, - type, - value, - writer->byte_order, - &writer->value_pos); - - result = result && _dbus_writer_gvariant_add_offset (writer, type); - return result; -} - -static dbus_bool_t -write_offsets (DBusString *dest, size_t insert_at, DBusString *offsets) -{ - return _dbus_string_copy (offsets, 0, dest, insert_at); -} - -dbus_bool_t -_dbus_writer_unrecurse_gvariant_write (DBusTypeWriter *writer, - DBusTypeWriter *sub) -{ - dbus_bool_t result = TRUE; - - if (writer->alignment < sub->alignment) - writer->alignment = sub->alignment; - - switch (sub->container_type) { - case DBUS_TYPE_STRUCT: - case DBUS_TYPE_DICT_ENTRY: - { - int diff; - int sub_len; - - if (NULL != sub->offsets) - { - write_offsets (sub->value_str, sub->value_pos, sub->offsets); - - _dbus_string_free (sub->offsets); - dbus_free (sub->offsets); - } - - diff = _DBUS_ALIGN_VALUE (writer->value_pos, sub->alignment) - writer->value_pos; - - result = _dbus_string_insert_bytes (writer->value_str, writer->value_pos, diff, 0); - writer->value_pos += diff; - sub_len = _dbus_string_get_length (sub->value_str); - result = result && _dbus_string_copy_len (sub->value_str, 0, - sub_len, - writer->value_str, - writer->value_pos); - writer->value_pos += sub_len; - - _dbus_string_free (sub->value_str); - dbus_free (sub->value_str); - - break; - } - case DBUS_TYPE_VARIANT: - { - int sub_type_len; - - /* write separating nul byte */ - result = _dbus_string_insert_byte (sub->value_str, sub->value_pos, 0); - sub->value_pos += 1; - - /* write signature */ - sub_type_len = _dbus_string_get_length (sub->type_str); - result = result && _dbus_string_copy_len (sub->type_str, 0, - sub_type_len, - sub->value_str, - sub->value_pos); - sub->value_pos += sub_type_len; - - /* free type string allocated in writer_recurse_variant() */ - _dbus_string_free (sub->type_str); - dbus_free (sub->type_str); - - /* update parent's string pointer */ - writer->value_pos = sub->value_pos; - - break; - } - case DBUS_TYPE_ARRAY: - writer->value_pos = sub->value_pos; - if (NULL != sub->offsets) - { - write_offsets (sub->value_str, sub->value_pos, sub->offsets); - - writer->value_pos += _dbus_string_get_length (sub->offsets); - - _dbus_string_free (sub->offsets); - dbus_free (sub->offsets); - } - - break; - default: - _dbus_assert_not_reached("Invalid container type"); - } - - /* well, we don't know where in the type string beginning of current container is */ - result = result && _dbus_writer_gvariant_add_offset_with_variability (writer, sub->is_fixed); - - return result; -} - -void -_dbus_type_reader_gvariant_init (DBusTypeReader *reader, - DBusMessage *message) -{ - reader->gvariant = TRUE; - /* GVariant wraps contents into struct */ - if (_dbus_string_get_byte (reader->type_str, reader->type_pos) == DBUS_STRUCT_BEGIN_CHAR) - { - reader->type_pos++; - if (_dbus_string_get_byte (reader->type_str, reader->type_pos) == DBUS_STRUCT_END_CHAR) - reader->finished = TRUE; - } - - reader->value_end = _dbus_message_gvariant_get_body_length (message); - reader->n_offsets = _dbus_reader_count_offsets (reader); -} diff --git a/dbus/dbus-marshal-gvariant.h b/dbus/dbus-marshal-gvariant.h deleted file mode 100644 index 79d23a0a..00000000 --- a/dbus/dbus-marshal-gvariant.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* dbus-marshal-gvariant.h Managing GVariant marshaling/demarshaling of messages - * - * Copyright (C) 2015 Samsung Electronics - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef DBUS_MARSHAL_GVARIANT_H -#define DBUS_MARSHAL_GVARIANT_H - -#include <dbus/dbus-marshal-header.h> -#include <dbus/dbus-marshal-recursive.h> -#include <dbus/dbus-message.h> -#include <dbus/dbus-connection.h> - -const DBusString *_dbus_get_gvariant_header_signature_str (void); - -dbus_bool_t _dbus_header_gvariant_create (DBusHeader *header, - int byte_order, - int type, - const char *destination, - const char *path, - const char *interface, - const char *member, - const char *error_name); - -dbus_bool_t _dbus_type_writer_write_gvariant_basic (DBusTypeWriter *writer, - int type, - const void *value); - -dbus_bool_t _dbus_marshal_write_gvariant_basic (DBusString *str, - int insert_at, - int type, - const void *value, - int byte_order, - int *pos_after); - -dbus_bool_t _dbus_header_set_field_basic_gvariant (DBusHeader *header, - int field, - int type, - const void *value); - -dbus_bool_t _dbus_header_get_field_basic_gvariant (DBusHeader *header, - int field, - int type, - void *value); - -dbus_bool_t _dbus_header_gvariant_delete_field (DBusHeader *header, - int field); - -void _dbus_marshal_read_gvariant_basic (const DBusString *str, - int pos, - int type, - void *value, - int byte_order, - int *new_pos); - -void _dbus_marshal_skip_gvariant_basic (const DBusString *str, - int type, - int byte_order, - int *pos); - -dbus_bool_t _dbus_header_load_gvariant (DBusHeader *header, - DBusTypeReader *reader, - DBusValidity *validity); - -dbus_bool_t _dbus_gvariant_raw_get_lengths (const DBusString *str, - dbus_uint32_t *fields_array_len_unsigned, - dbus_uint32_t *body_len_unsigned, - DBusValidity *validity); - -DBusValidity _dbus_validate_gvariant_body_with_reason (const DBusString *expected_signature, - int expected_signature_start, - int byte_order, - int *bytes_remaining, - const DBusString *value_str, - int value_pos, - int len); - -dbus_bool_t _dbus_message_gvariant_get_signature (DBusMessage *message, - const DBusString **type_str_p, - int *type_pos_p, - int *type_str_len); - -dbus_bool_t _dbus_message_gvariant_add_signature (DBusMessage *message, - const DBusString *type_str); - -dbus_bool_t _dbus_message_append_body_offset (DBusMessage *message); -dbus_bool_t _dbus_message_gvariant_remove_body_offset (DBusMessage *message); - -dbus_bool_t _dbus_message_finalize_gvariant (DBusMessage *message, - dbus_bool_t remove_signature_from_header); - -size_t _dbus_reader_get_offset_of_end_of_variable (DBusTypeReader *reader); -int _dbus_reader_get_type_fixed_size (DBusTypeReader *reader, - int *alignment); - -int _dbus_type_gvariant_get_fixed_size (const DBusString *type_str, - int type_pos, - int *alignment); - -int _dbus_reader_count_offsets (const DBusTypeReader *reader); - -int _dbus_reader_count_array_elems (const DBusTypeReader *reader); - -dbus_bool_t _dbus_type_writer_gvariant_write_basic_no_typecode (DBusTypeWriter *writer, - int type, - const void *value); - -dbus_bool_t _dbus_writer_unrecurse_gvariant_write (DBusTypeWriter *writer, - DBusTypeWriter *sub); - -void _dbus_type_reader_gvariant_init (DBusTypeReader *reader, - DBusMessage *message); - -#endif /* DBUS_MARSHAL_GVARIANT_H */ diff --git a/dbus/dbus-marshal-header.c b/dbus/dbus-marshal-header.c index bd98a12d..48151c62 100644 --- a/dbus/dbus-marshal-header.c +++ b/dbus/dbus-marshal-header.c @@ -27,9 +27,6 @@ #include "dbus-marshal-recursive.h" #include "dbus-marshal-byteswap.h" -#include "dbus-protocol-gvariant.h" -#include "dbus-marshal-gvariant.h" - /** * @addtogroup DBusMarshal * @@ -126,12 +123,6 @@ correct_header_padding (DBusHeader *header) #define HEADER_END_BEFORE_PADDING(header) \ (_dbus_string_get_length (&(header)->data) - (header)->padding) -static dbus_bool_t -_dbus_header_is_gvariant (const DBusHeader *header) -{ - return (header->protocol_version == DBUS_PROTOCOL_VERSION_GVARIANT); -} - /** * Invalidates all fields in the cache. This may be used when the * cache is totally uninitialized (contains junk) so should not @@ -424,11 +415,6 @@ _dbus_header_set_serial (DBusHeader *header, SERIAL_OFFSET, serial, _dbus_header_get_byte_order (header)); - if (_dbus_header_is_gvariant (header)) - _dbus_marshal_set_uint32 (&header->data, - SERIAL_OFFSET+4, - 0, - _dbus_header_get_byte_order (header)); } /** @@ -527,7 +513,6 @@ _dbus_header_copy (const DBusHeader *header, * for use. #NULL may be specified for some or all of the fields to * avoid adding those fields. Some combinations of fields don't make * sense, and passing them in will trigger an assertion failure. - * This is used only for dbus1 messages. GVariant uses _dbus_header_gvariant_create. * * @param header the header * @param byte_order byte order of the header @@ -693,16 +678,13 @@ _dbus_header_have_message_untrusted (int max_message_length, int *body_len, const DBusString *str, int start, - int len, - dbus_bool_t *is_gvariant) + int len) { dbus_uint32_t header_len_unsigned; dbus_uint32_t fields_array_len_unsigned; dbus_uint32_t body_len_unsigned; - dbus_uint32_t protocol_version; - _dbus_assert (start >= 0); _dbus_assert (start < _DBUS_INT32_MAX / 2); _dbus_assert (len >= 0); @@ -717,32 +699,9 @@ _dbus_header_have_message_untrusted (int max_message_length, return FALSE; } - protocol_version = _dbus_string_get_byte (str, start + VERSION_OFFSET); - if (DBUS_MAJOR_PROTOCOL_VERSION == protocol_version) - { - _dbus_assert (FIELDS_ARRAY_LENGTH_OFFSET + 4 <= len); - fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET, - *byte_order, NULL); - - _dbus_assert (BODY_LENGTH_OFFSET + 4 < len); - body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET, - *byte_order, NULL); - - *is_gvariant = FALSE; - } - else if (DBUS_PROTOCOL_VERSION_GVARIANT == protocol_version) - { - if (!_dbus_gvariant_raw_get_lengths (str, &fields_array_len_unsigned, &body_len_unsigned, validity)) - { - return FALSE; - } - *is_gvariant = TRUE; - } - else - { - *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION; - return FALSE; - } + _dbus_assert (FIELDS_ARRAY_LENGTH_OFFSET + 4 <= len); + fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET, + *byte_order, NULL); if (fields_array_len_unsigned > (unsigned) max_message_length) { @@ -750,6 +709,10 @@ _dbus_header_have_message_untrusted (int max_message_length, return FALSE; } + _dbus_assert (BODY_LENGTH_OFFSET + 4 < len); + body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET, + *byte_order, NULL); + if (body_len_unsigned > (unsigned) max_message_length) { *validity = DBUS_INVALID_INSANE_BODY_LENGTH; @@ -977,86 +940,6 @@ load_and_validate_field (DBusHeader *header, return DBUS_VALID; } -static dbus_bool_t -_dbus_header_load_dbus1 (DBusHeader *header, - DBusTypeReader *reader, - DBusValidity *validity, - int body_len) -{ - dbus_uint32_t v_uint32; - dbus_uint32_t serial; - DBusTypeReader array_reader; - - /* BODY LENGTH */ - _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_UINT32); - _dbus_assert (_dbus_type_reader_get_value_pos (reader) == BODY_LENGTH_OFFSET); - _dbus_type_reader_read_basic (reader, &v_uint32); - _dbus_type_reader_next (reader); - - _dbus_assert (body_len == (signed) v_uint32); - - /* SERIAL */ - _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_UINT32); - _dbus_assert (_dbus_type_reader_get_value_pos (reader) == SERIAL_OFFSET); - _dbus_type_reader_read_basic (reader, &serial); - _dbus_type_reader_next (reader); - - if (serial == 0) - { - *validity = DBUS_INVALID_BAD_SERIAL; - return FALSE; - } - - _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_ARRAY); - _dbus_assert (_dbus_type_reader_get_value_pos (reader) == FIELDS_ARRAY_LENGTH_OFFSET); - - _dbus_type_reader_recurse (reader, &array_reader); - while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID) - { - DBusTypeReader struct_reader; - DBusTypeReader variant_reader; - unsigned char field_code; - DBusValidity v; - - _dbus_assert (_dbus_type_reader_get_current_type (&array_reader) == DBUS_TYPE_STRUCT); - - _dbus_type_reader_recurse (&array_reader, &struct_reader); - - _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_BYTE); - _dbus_type_reader_read_basic (&struct_reader, &field_code); - _dbus_type_reader_next (&struct_reader); - - if (field_code == DBUS_HEADER_FIELD_INVALID) - { - _dbus_verbose ("invalid header field code\n"); - *validity = DBUS_INVALID_HEADER_FIELD_CODE; - return FALSE; - } - - if (field_code > DBUS_HEADER_FIELD_LAST) - { - _dbus_verbose ("unknown header field code %d, skipping\n", - field_code); - goto next_field; - } - - _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_VARIANT); - _dbus_type_reader_recurse (&struct_reader, &variant_reader); - - v = load_and_validate_field (header, field_code, &variant_reader); - if (v != DBUS_VALID) - { - _dbus_verbose ("Field %d was invalid\n", field_code); - *validity = v; - return FALSE; - } - - next_field: - _dbus_type_reader_next (&array_reader); - } - return TRUE; -} - /** * Creates a message header from potentially-untrusted data. The * return value is #TRUE if there was enough memory and the data was @@ -1098,11 +981,13 @@ _dbus_header_load (DBusHeader *header, int leftover; DBusValidity v; DBusTypeReader reader; + DBusTypeReader array_reader; unsigned char v_byte; + dbus_uint32_t v_uint32; + dbus_uint32_t serial; int padding_start; int padding_len; int i; - const DBusString *signature; _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8)); _dbus_assert (header_len <= len); @@ -1114,14 +999,6 @@ _dbus_header_load (DBusHeader *header, *validity = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; return FALSE; } - if (_dbus_header_is_gvariant (header)) - { - signature = _dbus_get_gvariant_header_signature_str(); - } - else - { - signature = &_dbus_header_signature_str; - } if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY) { @@ -1129,20 +1006,10 @@ _dbus_header_load (DBusHeader *header, } else { - if (!_dbus_header_is_gvariant (header)) - { - v = _dbus_validate_body_with_reason (signature, 0, - byte_order, - &leftover, - str, start, len); - } - else - { - v = _dbus_validate_gvariant_body_with_reason (signature, 0, - byte_order, - &leftover, - str, start, len); - } + v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0, + byte_order, + &leftover, + str, start, len); if (v != DBUS_VALID) { @@ -1181,7 +1048,7 @@ _dbus_header_load (DBusHeader *header, _dbus_type_reader_init (&reader, byte_order, - signature, 0, + &_dbus_header_signature_str, 0, str, start); /* BYTE ORDER */ @@ -1223,25 +1090,75 @@ _dbus_header_load (DBusHeader *header, if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION) { - if (v_byte == DBUS_PROTOCOL_VERSION_GVARIANT) - { - reader.gvariant = TRUE; - } - else - { - *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION; - goto invalid; - } + *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION; + goto invalid; } - if (reader.gvariant) + + /* BODY LENGTH */ + _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32); + _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BODY_LENGTH_OFFSET); + _dbus_type_reader_read_basic (&reader, &v_uint32); + _dbus_type_reader_next (&reader); + + _dbus_assert (body_len == (signed) v_uint32); + + /* SERIAL */ + _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32); + _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == SERIAL_OFFSET); + _dbus_type_reader_read_basic (&reader, &serial); + _dbus_type_reader_next (&reader); + + if (serial == 0) { - if (!_dbus_header_load_gvariant (header, &reader, validity)) - goto invalid; + *validity = DBUS_INVALID_BAD_SERIAL; + goto invalid; } - else + + _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_ARRAY); + _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FIELDS_ARRAY_LENGTH_OFFSET); + + _dbus_type_reader_recurse (&reader, &array_reader); + while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID) { - if (!_dbus_header_load_dbus1 (header, &reader, validity, body_len)) - goto invalid; + DBusTypeReader struct_reader; + DBusTypeReader variant_reader; + unsigned char field_code; + + _dbus_assert (_dbus_type_reader_get_current_type (&array_reader) == DBUS_TYPE_STRUCT); + + _dbus_type_reader_recurse (&array_reader, &struct_reader); + + _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_BYTE); + _dbus_type_reader_read_basic (&struct_reader, &field_code); + _dbus_type_reader_next (&struct_reader); + + if (field_code == DBUS_HEADER_FIELD_INVALID) + { + _dbus_verbose ("invalid header field code\n"); + *validity = DBUS_INVALID_HEADER_FIELD_CODE; + goto invalid; + } + + if (field_code > DBUS_HEADER_FIELD_LAST) + { + _dbus_verbose ("unknown header field code %d, skipping\n", + field_code); + goto next_field; + } + + _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_VARIANT); + _dbus_type_reader_recurse (&struct_reader, &variant_reader); + + v = load_and_validate_field (header, field_code, &variant_reader); + if (v != DBUS_VALID) + { + _dbus_verbose ("Field %d was invalid\n", field_code); + *validity = v; + goto invalid; + } + + next_field: + _dbus_type_reader_next (&array_reader); } /* Anything we didn't fill in is now known not to exist */ @@ -1341,8 +1258,19 @@ find_field_for_modification (DBusHeader *header, return retval; } -static dbus_bool_t -_dbus_header_set_field_basic_dbus1 (DBusHeader *header, +/** + * Sets the value of a field with basic type. If the value is a string + * value, it isn't allowed to be #NULL. If the field doesn't exist, + * it will be created. + * + * @param header the header + * @param field the field to set + * @param type the type of the value + * @param value the value as for _dbus_marshal_set_basic() + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_header_set_field_basic (DBusHeader *header, int field, int type, const void *value) @@ -1410,29 +1338,17 @@ _dbus_header_set_field_basic_dbus1 (DBusHeader *header, } /** - * Sets the value of a field with basic type. If the value is a string - * value, it isn't allowed to be #NULL. If the field doesn't exist, - * it will be created. + * Gets the value of a field with basic type. If the field + * doesn't exist, returns #FALSE, otherwise returns #TRUE. * * @param header the header - * @param field the field to set + * @param field the field to get * @param type the type of the value - * @param value the value as for _dbus_marshal_set_basic() - * @returns #FALSE if no memory + * @param value the value as for _dbus_marshal_read_basic() + * @returns #FALSE if the field doesn't exist */ dbus_bool_t -_dbus_header_set_field_basic (DBusHeader *header, - int field, - int type, - const void *value) -{ - return _dbus_header_is_gvariant (header) ? - _dbus_header_set_field_basic_gvariant (header, field, type, value) : - _dbus_header_set_field_basic_dbus1 (header, field, type, value); -} - -static dbus_bool_t -_dbus_header_get_field_basic_dbus1 (DBusHeader *header, +_dbus_header_get_field_basic (DBusHeader *header, int field, int type, void *value) @@ -1458,26 +1374,6 @@ _dbus_header_get_field_basic_dbus1 (DBusHeader *header, return TRUE; } -/** - * Gets the value of a field with basic type. If the field - * doesn't exist, returns #FALSE, otherwise returns #TRUE. - * - * @param header the header - * @param field the field to get - * @param type the type of the value - * @param value the value as for _dbus_marshal_read_basic() - * @returns #FALSE if the field doesn't exist - */ -dbus_bool_t -_dbus_header_get_field_basic (DBusHeader *header, - int field, - int type, - void *value) -{ - return _dbus_header_is_gvariant (header) ? - _dbus_header_get_field_basic_gvariant (header, field, type, value) : - _dbus_header_get_field_basic_dbus1 (header, field, type, value); -} /** * Gets the raw marshaled data for a field. If the field doesn't diff --git a/dbus/dbus-marshal-header.h b/dbus/dbus-marshal-header.h index 4ff986c9..350fe5c4 100644 --- a/dbus/dbus-marshal-header.h +++ b/dbus/dbus-marshal-header.h @@ -57,7 +57,6 @@ struct DBusHeader dbus_uint32_t padding : 3; /**< bytes of alignment in header */ dbus_uint32_t byte_order : 8; /**< byte order of header */ - unsigned char protocol_version; }; dbus_bool_t _dbus_header_init (DBusHeader *header); @@ -109,8 +108,7 @@ dbus_bool_t _dbus_header_have_message_untrusted (int max_messag int *body_len, const DBusString *str, int start, - int len, - dbus_bool_t *is_gvariant); + int len); dbus_bool_t _dbus_header_load (DBusHeader *header, DBusValidationMode mode, DBusValidity *validity, diff --git a/dbus/dbus-marshal-recursive.c b/dbus/dbus-marshal-recursive.c index 8a5c90e1..4adfd2e9 100644 --- a/dbus/dbus-marshal-recursive.c +++ b/dbus/dbus-marshal-recursive.c @@ -2,7 +2,6 @@ /* dbus-marshal-recursive.c Marshalling routines for recursive types * * Copyright (C) 2004, 2005 Red Hat, Inc. - * Copyright (C) 2015 Samsung Electronics * * Licensed under the Academic Free License version 2.1 * @@ -27,7 +26,6 @@ #include "dbus-marshal-basic.h" #include "dbus-signature.h" #include "dbus-internals.h" -#include "dbus-marshal-gvariant.h" /** * @addtogroup DBusMarshal @@ -149,8 +147,7 @@ reader_init (DBusTypeReader *reader, const DBusString *type_str, int type_pos, const DBusString *value_str, - int value_pos, - dbus_bool_t gvariant) + int value_pos) { reader->byte_order = byte_order; reader->finished = FALSE; @@ -158,11 +155,6 @@ reader_init (DBusTypeReader *reader, reader->type_pos = type_pos; reader->value_str = value_str; reader->value_pos = value_pos; - reader->value_start = value_pos; - reader->gvariant = gvariant; - reader->variable_index = 0; - reader->offsets_from_back = TRUE; - reader->is_variant = FALSE; } static void @@ -175,8 +167,7 @@ base_reader_recurse (DBusTypeReader *sub, parent->type_str, parent->type_pos, parent->value_str, - parent->value_pos, - parent->gvariant); + parent->value_pos); } static void @@ -199,31 +190,8 @@ struct_or_dict_entry_reader_recurse (DBusTypeReader *sub, { struct_or_dict_entry_types_only_reader_recurse (sub, parent); - if (sub->gvariant) - { - /* GVARIANT */ - /* check if current type is fixed or variable */ - int alignment = 1; - int size = _dbus_reader_get_type_fixed_size (parent, &alignment); - sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, alignment); /* adjust alignment */ - sub->value_start = sub->value_pos; - sub->n_offsets = _dbus_reader_count_offsets (sub); - sub->offsets_from_back = TRUE; - - if (0 == size) - { - sub->value_end = _dbus_reader_get_offset_of_end_of_variable (parent); - } - else - { - sub->value_end = sub->value_pos + size; - } - } - else - { - /* struct and dict entry have 8 byte alignment */ - sub->value_pos = sub->value_start = _DBUS_ALIGN_VALUE (sub->value_pos, 8); - } + /* struct and dict entry have 8 byte alignment */ + sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8); } static void @@ -251,9 +219,6 @@ array_reader_get_array_len (const DBusTypeReader *reader) dbus_uint32_t array_len; int len_pos; - if (reader->gvariant) - return reader->value_end - reader->value_start; - len_pos = ARRAY_READER_LEN_POS (reader); _dbus_assert (_DBUS_ALIGN_VALUE (len_pos, 4) == (unsigned) len_pos); @@ -279,38 +244,20 @@ array_reader_recurse (DBusTypeReader *sub, array_types_only_reader_recurse (sub, parent); - if (sub->gvariant) - { - int size = _dbus_reader_get_type_fixed_size (sub, &alignment); - sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, alignment); - sub->value_start = sub->value_pos; - sub->offsets_from_back = FALSE; - sub->value_end = _dbus_reader_get_offset_of_end_of_variable (parent); - sub->variable_index = 0; - if (0 == size) - sub->n_offsets = _dbus_reader_count_array_elems (sub); - else - sub->n_offsets = 0; - sub->u.array.start_pos = sub->value_start; - sub->finished = (sub->value_end == sub->value_start); - } - else - { - sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4); + sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4); - len_pos = sub->value_pos; + len_pos = sub->value_pos; - sub->value_pos += 4; /* for the length */ + sub->value_pos += 4; /* for the length */ - alignment = element_type_get_alignment (sub->type_str, - sub->type_pos); + alignment = element_type_get_alignment (sub->type_str, + sub->type_pos); - sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, alignment); + sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, alignment); - sub->u.array.start_pos = sub->value_pos; - _dbus_assert ((sub->u.array.start_pos - (len_pos + 4)) < 8); /* only 3 bits in array_len_offset */ - sub->array_len_offset = sub->u.array.start_pos - (len_pos + 4); - } + sub->u.array.start_pos = sub->value_pos; + _dbus_assert ((sub->u.array.start_pos - (len_pos + 4)) < 8); /* only 3 bits in array_len_offset */ + sub->array_len_offset = sub->u.array.start_pos - (len_pos + 4); #if RECURSIVE_MARSHAL_READ_TRACE _dbus_verbose (" type reader %p array start = %d len_offset = %d array len = %d array element type = %s\n", @@ -332,46 +279,21 @@ variant_reader_recurse (DBusTypeReader *sub, base_reader_recurse (sub, parent); - if (sub->gvariant) - { - /* GVariant's Variant is values, then nul byte, then signature. - * Variant's alignment is 8. - */ - sub->value_pos = sub->value_start = _DBUS_ALIGN_VALUE (sub->value_pos, 8); /* adjust alignment */ - sub->value_end = _dbus_reader_get_offset_of_end_of_variable (parent); - - /* find beginning of signature in variant */ - sub->type_str = sub->value_str; - sub->type_pos = sub->value_end - 1; - - while (sub->type_pos > 0 && _dbus_string_get_byte (sub->type_str, sub->type_pos) != 0) - sub->type_pos--; - - if (_dbus_string_get_byte (sub->type_str, sub->type_pos) == 0) - sub->type_pos++; - - /* set the end of variant's value to the zero byte before signature */ - sub->value_end = sub->type_pos - 1; - sub->is_variant = TRUE; - } - else - { - /* Variant is 1 byte sig length (without nul), signature with nul, - * padding to 8-boundary, then values - */ - - sig_len = _dbus_string_get_byte (sub->value_str, sub->value_pos); + /* Variant is 1 byte sig length (without nul), signature with nul, + * padding to 8-boundary, then values + */ - sub->type_str = sub->value_str; - sub->type_pos = sub->value_pos + 1; + sig_len = _dbus_string_get_byte (sub->value_str, sub->value_pos); - sub->value_pos = sub->type_pos + sig_len + 1; + sub->type_str = sub->value_str; + sub->type_pos = sub->value_pos + 1; - contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (sub->type_str, - sub->type_pos)); + sub->value_pos = sub->type_pos + sig_len + 1; - sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, contained_alignment); - } + contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (sub->type_str, + sub->type_pos)); + + sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, contained_alignment); #if RECURSIVE_MARSHAL_READ_TRACE _dbus_verbose (" type reader %p variant containing '%s'\n", @@ -416,7 +338,7 @@ skip_one_complete_type (const DBusString *type_str, */ void _dbus_type_signature_next (const char *type_str, - int *type_pos) + int *type_pos) { const unsigned char *p; const unsigned char *start; @@ -521,7 +443,6 @@ base_reader_next (DBusTypeReader *reader, case DBUS_TYPE_STRUCT: case DBUS_TYPE_VARIANT: /* Scan forward over the entire container contents */ - /* FIXME for GVariant - use offsets */ { DBusTypeReader sub; @@ -568,8 +489,7 @@ base_reader_next (DBusTypeReader *reader, default: if (!reader->klass->types_only) - (reader->gvariant ? _dbus_marshal_skip_gvariant_basic : _dbus_marshal_skip_basic) ( - reader->value_str, + _dbus_marshal_skip_basic (reader->value_str, current_type, reader->byte_order, &reader->value_pos); @@ -579,40 +499,12 @@ base_reader_next (DBusTypeReader *reader, } static void -struct_or_dict_entry_reader_next (DBusTypeReader *reader, - int current_type) -{ - if (reader->gvariant) - { - int alignment; - int size = _dbus_reader_get_type_fixed_size (reader, &alignment); - if (0 == size) - { - /* variable size - use offsets*/ - reader->value_pos = _dbus_reader_get_offset_of_end_of_variable (reader); - reader->variable_index++; - } - else - { - /* just move, but consider alignment */ - reader->value_pos = _DBUS_ALIGN_VALUE(reader->value_pos, alignment) + size; - } - - skip_one_complete_type (reader->type_str, &reader->type_pos); - } - else - { - base_reader_next (reader, current_type); - } -} - -static void struct_reader_next (DBusTypeReader *reader, int current_type) { int t; - struct_or_dict_entry_reader_next (reader, current_type); + base_reader_next (reader, current_type); /* for STRUCT containers we return FALSE at the end of the struct, * for INVALID we return FALSE at the end of the signature. @@ -628,22 +520,12 @@ struct_reader_next (DBusTypeReader *reader, } static void -body_reader_next (DBusTypeReader *reader, - int current_type) -{ - if (reader->gvariant) - struct_reader_next (reader, current_type); - else - base_reader_next (reader, current_type); -} - -static void dict_entry_reader_next (DBusTypeReader *reader, int current_type) { int t; - struct_or_dict_entry_reader_next (reader, current_type); + base_reader_next (reader, current_type); /* for STRUCT containers we return FALSE at the end of the struct, * for INVALID we return FALSE at the end of the signature. @@ -677,26 +559,6 @@ array_reader_next (DBusTypeReader *reader, /* Skip one array element */ int end_pos; - if (reader->gvariant) - { - int alignment; - int size = _dbus_reader_get_type_fixed_size (reader, &alignment); - if (0 == size) - { - /* variable size - use offsets*/ - reader->value_pos = _dbus_reader_get_offset_of_end_of_variable (reader); - reader->variable_index++; - reader->finished = (reader->variable_index >= reader->n_offsets); - } - else - { - /* fixed size - move on; consider alignment */ - reader->value_pos = _DBUS_ALIGN_VALUE(reader->value_pos, alignment) + size; - reader->finished = (reader->value_pos >= reader->value_end); - } - return; - } - end_pos = reader->u.array.start_pos + array_reader_get_array_len (reader); #if RECURSIVE_MARSHAL_READ_TRACE @@ -769,33 +631,12 @@ array_reader_next (DBusTypeReader *reader, } } -static void -variant_reader_next (DBusTypeReader *reader, - int current_type) -{ - if (reader->gvariant) - { - if (!reader->klass->types_only) - reader->value_pos = reader->value_end; - - reader->type_pos += 1; - - reader->finished = TRUE; - - reader->variable_index++; - } - else - { - base_reader_next (reader, current_type); - } -} - static const DBusTypeReaderClass body_reader_class = { "body", 0, FALSE, NULL, /* body is always toplevel, so doesn't get recursed into */ NULL, - body_reader_next + base_reader_next }; static const DBusTypeReaderClass body_types_only_reader_class = { @@ -803,7 +644,7 @@ static const DBusTypeReaderClass body_types_only_reader_class = { TRUE, NULL, /* body is always toplevel, so doesn't get recursed into */ NULL, - body_reader_next + base_reader_next }; static const DBusTypeReaderClass struct_reader_class = { @@ -859,7 +700,7 @@ static const DBusTypeReaderClass variant_reader_class = { FALSE, variant_reader_recurse, NULL, - variant_reader_next + base_reader_next }; #ifndef DBUS_DISABLE_ASSERT @@ -898,7 +739,7 @@ _dbus_type_reader_init (DBusTypeReader *reader, reader->klass = &body_reader_class; reader_init (reader, byte_order, type_str, type_pos, - value_str, value_pos, FALSE); + value_str, value_pos); #if RECURSIVE_MARSHAL_READ_TRACE _dbus_verbose (" type reader %p init type_pos = %d value_pos = %d remaining sig '%s'\n", @@ -923,8 +764,7 @@ _dbus_type_reader_init_types_only (DBusTypeReader *reader, reader->klass = &body_types_only_reader_class; reader_init (reader, DBUS_COMPILER_BYTE_ORDER /* irrelevant */, - type_str, type_pos, NULL, _DBUS_INT_MAX /* crashes if we screw up */, - FALSE); + type_str, type_pos, NULL, _DBUS_INT_MAX /* crashes if we screw up */); #if RECURSIVE_MARSHAL_READ_TRACE _dbus_verbose (" type reader %p init types only type_pos = %d remaining sig '%s'\n", @@ -1035,8 +875,7 @@ _dbus_type_reader_read_basic (const DBusTypeReader *reader, t = _dbus_type_reader_get_current_type (reader); - (reader->gvariant ? _dbus_marshal_read_gvariant_basic : _dbus_marshal_read_basic) ( - reader->value_str, + _dbus_marshal_read_basic (reader->value_str, reader->value_pos, t, value, reader->byte_order, @@ -1660,14 +1499,9 @@ _dbus_type_writer_init (DBusTypeWriter *writer, writer->type_pos = type_pos; writer->value_str = value_str; writer->value_pos = value_pos; - writer->value_start = value_pos; writer->container_type = DBUS_TYPE_INVALID; writer->type_pos_is_expectation = FALSE; writer->enabled = TRUE; - writer->gvariant = FALSE; - writer->body_container = FALSE; - writer->is_fixed = TRUE; - writer->alignment = 1; #if RECURSIVE_MARSHAL_WRITE_TRACE _dbus_verbose ("writer %p init remaining sig '%s'\n", writer, @@ -1697,24 +1531,6 @@ _dbus_type_writer_init_types_delayed (DBusTypeWriter *writer, NULL, 0, value_str, value_pos); } -void -_dbus_type_writer_gvariant_init_types_delayed (DBusTypeWriter *writer, - int byte_order, - DBusString *value_str, - int value_pos, - dbus_bool_t gvariant) -{ - _dbus_type_writer_init (writer, byte_order, - NULL, 0, value_str, value_pos); - writer->gvariant = gvariant; - writer->body_container = TRUE; - writer->is_fixed = TRUE; - writer->alignment = 8; - writer->u.struct_or_dict.last_offset = 0; - writer->offsets_size = 1; - writer->offsets = NULL; -} - /** * Adds type string to the writer, if it had none. * @@ -1782,19 +1598,12 @@ _dbus_type_writer_write_basic_no_typecode (DBusTypeWriter *writer, const void *value) { if (writer->enabled) - { - if (writer->gvariant) - { - return _dbus_type_writer_gvariant_write_basic_no_typecode (writer, type, value); - } - else - return _dbus_marshal_write_basic (writer->value_str, - writer->value_pos, - type, - value, - writer->byte_order, - &writer->value_pos); - } + return _dbus_marshal_write_basic (writer->value_str, + writer->value_pos, + type, + value, + writer->byte_order, + &writer->value_pos); else return TRUE; } @@ -1833,7 +1642,6 @@ writer_recurse_init_and_check (DBusTypeWriter *writer, writer->value_pos); sub->container_type = container_type; - sub->gvariant = writer->gvariant; if (writer->type_pos_is_expectation || (sub->container_type == DBUS_TYPE_ARRAY || sub->container_type == DBUS_TYPE_VARIANT)) @@ -1984,28 +1792,12 @@ writer_recurse_struct_or_dict_entry (DBusTypeWriter *writer, if (writer->enabled) { - if (writer->gvariant) - { - sub->alignment = 1; - sub->value_str = dbus_new (DBusString, 1); - if (NULL == sub->value_str || !_dbus_string_init (sub->value_str)) - return FALSE; - sub->value_start = sub->value_pos = 0; - sub->u.struct_or_dict.last_offset = 0; - sub->offsets_size = 1; - sub->is_fixed = TRUE; - sub->offsets = dbus_new (DBusString, 1); - _dbus_string_init (sub->offsets); - } - else - { - if (!_dbus_string_insert_bytes (sub->value_str, - sub->value_pos, - _DBUS_ALIGN_VALUE (sub->value_pos, 8) - sub->value_pos, - '\0')) - _dbus_assert_not_reached ("should not have failed to insert alignment padding for struct"); - sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8); - } + if (!_dbus_string_insert_bytes (sub->value_str, + sub->value_pos, + _DBUS_ALIGN_VALUE (sub->value_pos, 8) - sub->value_pos, + '\0')) + _dbus_assert_not_reached ("should not have failed to insert alignment padding for struct"); + sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8); } return TRUE; @@ -2093,47 +1885,27 @@ writer_recurse_array (DBusTypeWriter *writer, if (writer->enabled) { - if (!writer->gvariant) - { - /* Write (or jump over, if is_array_append) the length */ - sub->u.array.len_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4); - - if (is_array_append) - { - sub->value_pos += 4; - } - else - { - if (!_dbus_type_writer_write_basic_no_typecode (sub, DBUS_TYPE_UINT32, &value)) - _dbus_assert_not_reached ("should not have failed to insert array len"); - } + /* Write (or jump over, if is_array_append) the length */ + sub->u.array.len_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4); - _dbus_assert (sub->u.array.len_pos == sub->value_pos - 4); + if (is_array_append) + { + sub->value_pos += 4; + } + else + { + if (!_dbus_type_writer_write_basic_no_typecode (sub, DBUS_TYPE_UINT32, + &value)) + _dbus_assert_not_reached ("should not have failed to insert array len"); } + _dbus_assert (sub->u.array.len_pos == sub->value_pos - 4); + /* Write alignment padding for array elements * Note that we write the padding *even for empty arrays* * to avoid wonky special cases */ - if (writer->gvariant) - { - int size = _dbus_type_gvariant_get_fixed_size (contained_type, contained_type_start, &alignment); - if (0 == size) - { - sub->offsets_size = 1; - sub->offsets = dbus_new (DBusString, 1); - _dbus_string_init (sub->offsets); - } - else - { - sub->offsets_size = 0; - sub->offsets = NULL; - } - } - else - { - alignment = element_type_get_alignment (contained_type, contained_type_start); - } + alignment = element_type_get_alignment (contained_type, contained_type_start); aligned = _DBUS_ALIGN_VALUE (sub->value_pos, alignment); if (aligned != sub->value_pos) @@ -2152,7 +1924,7 @@ writer_recurse_array (DBusTypeWriter *writer, sub->u.array.start_pos = sub->value_pos; - if (is_array_append && !writer->gvariant) + if (is_array_append) { dbus_uint32_t len; @@ -2165,12 +1937,6 @@ writer_recurse_array (DBusTypeWriter *writer, sub->value_pos += len; } - if (writer->gvariant) - { - sub->alignment = alignment; - sub->is_fixed = FALSE; - sub->value_start = sub->value_pos; - } } else { @@ -2179,7 +1945,7 @@ writer_recurse_array (DBusTypeWriter *writer, sub->u.array.start_pos = sub->value_pos; } - _dbus_assert (sub->gvariant || sub->u.array.len_pos < sub->u.array.start_pos); + _dbus_assert (sub->u.array.len_pos < sub->u.array.start_pos); _dbus_assert (is_array_append || sub->u.array.start_pos == sub->value_pos); #if RECURSIVE_MARSHAL_WRITE_TRACE @@ -2246,58 +2012,31 @@ writer_recurse_variant (DBusTypeWriter *writer, /* If we're enabled then continue ... */ - if (writer->gvariant) - { - /* GVariant case: - * contents, then nul byte, then signature without nul byte. - * The alignment is always 8. - * - * Signature is at the end of a variant. So, the easiest way is to write it down - * when unrecursing. So, we need to copy it to a new string. - */ - contained_alignment = 8; - sub->alignment = 8; - sub->type_str = dbus_new (DBusString, 1); /* to be deallocated on unrecurse */ - sub->type_pos = 0; - sub->is_fixed = FALSE; - _dbus_string_init_preallocated (sub->type_str, contained_type_len); - - if (!_dbus_string_copy_len (contained_type, contained_type_start, contained_type_len, - sub->type_str, sub->type_pos)) - _dbus_assert_not_reached ("should not have failed to insert variant type sig"); - } - else - { - /* dbus1 case: - * length, signature with nul byte, then contents - * alignment depends on contents. - */ - if (!_dbus_string_insert_byte (sub->value_str, - sub->value_pos, - contained_type_len)) - _dbus_assert_not_reached ("should not have failed to insert variant type sig len"); + if (!_dbus_string_insert_byte (sub->value_str, + sub->value_pos, + contained_type_len)) + _dbus_assert_not_reached ("should not have failed to insert variant type sig len"); - sub->value_pos += 1; + sub->value_pos += 1; - /* Here we switch over to the expected type sig we're about to write */ - sub->type_str = sub->value_str; - sub->type_pos = sub->value_pos; + /* Here we switch over to the expected type sig we're about to write */ + sub->type_str = sub->value_str; + sub->type_pos = sub->value_pos; - if (!_dbus_string_copy_len (contained_type, contained_type_start, contained_type_len, - sub->value_str, sub->value_pos)) - _dbus_assert_not_reached ("should not have failed to insert variant type sig"); + if (!_dbus_string_copy_len (contained_type, contained_type_start, contained_type_len, + sub->value_str, sub->value_pos)) + _dbus_assert_not_reached ("should not have failed to insert variant type sig"); - sub->value_pos += contained_type_len; + sub->value_pos += contained_type_len; - if (!_dbus_string_insert_byte (sub->value_str, - sub->value_pos, - DBUS_TYPE_INVALID)) - _dbus_assert_not_reached ("should not have failed to insert variant type nul termination"); + if (!_dbus_string_insert_byte (sub->value_str, + sub->value_pos, + DBUS_TYPE_INVALID)) + _dbus_assert_not_reached ("should not have failed to insert variant type nul termination"); - sub->value_pos += 1; + sub->value_pos += 1; - contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (contained_type, contained_type_start)); - } + contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (contained_type, contained_type_start)); if (!_dbus_string_insert_bytes (sub->value_str, sub->value_pos, @@ -2305,7 +2044,6 @@ writer_recurse_variant (DBusTypeWriter *writer, '\0')) _dbus_assert_not_reached ("should not have failed to insert alignment padding for variant body"); sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, contained_alignment); - sub->value_start = sub->value_pos; return TRUE; } @@ -2378,8 +2116,6 @@ _dbus_type_writer_recurse (DBusTypeWriter *writer, else contained_type_len = 0; - sub->body_container = FALSE; - return _dbus_type_writer_recurse_contained_len (writer, container_type, contained_type, contained_type_start, @@ -2428,10 +2164,32 @@ writer_get_array_len (DBusTypeWriter *writer) return writer->value_pos - writer->u.array.start_pos; } -static dbus_bool_t -_dbus_type_writer_unrecurse_write (DBusTypeWriter *writer, - DBusTypeWriter *sub) +/** + * Closes a container created by _dbus_type_writer_recurse() + * and writes any additional information to the values block. + * + * @param writer the writer + * @param sub the sub-writer created by _dbus_type_writer_recurse() + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_type_writer_unrecurse (DBusTypeWriter *writer, + DBusTypeWriter *sub) { + /* type_pos_is_expectation never gets unset once set, or we'd get all hosed */ + _dbus_assert (!writer->type_pos_is_expectation || + (writer->type_pos_is_expectation && sub->type_pos_is_expectation)); + +#if RECURSIVE_MARSHAL_WRITE_TRACE + _dbus_verbose (" type writer %p unrecurse type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n", + writer, writer->type_pos, writer->value_pos, writer->type_pos_is_expectation, + _dbus_type_to_string (writer->container_type)); + _dbus_verbose (" type writer %p unrecurse sub type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n", + sub, sub->type_pos, sub->value_pos, + sub->type_pos_is_expectation, + _dbus_type_to_string (sub->container_type)); +#endif + if (sub->container_type == DBUS_TYPE_STRUCT) { if (!write_or_verify_typecode (sub, DBUS_STRUCT_END_CHAR)) @@ -2442,7 +2200,7 @@ _dbus_type_writer_unrecurse_write (DBusTypeWriter *writer, if (!write_or_verify_typecode (sub, DBUS_DICT_ENTRY_END_CHAR)) return FALSE; } - else if (sub->container_type == DBUS_TYPE_ARRAY && !sub->gvariant) + else if (sub->container_type == DBUS_TYPE_ARRAY) { if (sub->u.array.len_pos >= 0) /* len_pos == -1 if we weren't enabled when we passed it */ { @@ -2466,46 +2224,6 @@ _dbus_type_writer_unrecurse_write (DBusTypeWriter *writer, } #endif } - return TRUE; -} - -/** - * Closes a container created by _dbus_type_writer_recurse() - * and writes any additional information to the values block. - * - * @param writer the writer - * @param sub the sub-writer created by _dbus_type_writer_recurse() - * @returns #FALSE if no memory - */ -dbus_bool_t -_dbus_type_writer_unrecurse (DBusTypeWriter *writer, - DBusTypeWriter *sub) -{ - /* type_pos_is_expectation never gets unset once set, or we'd get all hosed */ - _dbus_assert (!writer->type_pos_is_expectation || - (writer->type_pos_is_expectation && sub->type_pos_is_expectation)); - -#if RECURSIVE_MARSHAL_WRITE_TRACE - _dbus_verbose (" type writer %p unrecurse type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n", - writer, writer->type_pos, writer->value_pos, writer->type_pos_is_expectation, - _dbus_type_to_string (writer->container_type)); - _dbus_verbose (" type writer %p unrecurse sub type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n", - sub, sub->type_pos, sub->value_pos, - sub->type_pos_is_expectation, - _dbus_type_to_string (sub->container_type)); -#endif - - if (!_dbus_type_writer_unrecurse_write (writer, sub)) - return FALSE; - - if (writer->gvariant) - { - if (!_dbus_writer_unrecurse_gvariant_write (writer, sub)) - return FALSE; - } - else - writer->value_pos = sub->value_pos; - /* Now get type_pos right for the parent writer. Here are the cases: * @@ -2565,6 +2283,8 @@ _dbus_type_writer_unrecurse (DBusTypeWriter *writer, } } + writer->value_pos = sub->value_pos; + #if RECURSIVE_MARSHAL_WRITE_TRACE _dbus_verbose (" type writer %p unrecursed type_pos = %d value_pos = %d remaining sig '%s'\n", writer, writer->type_pos, writer->value_pos, diff --git a/dbus/dbus-marshal-recursive.h b/dbus/dbus-marshal-recursive.h index 0873c5b8..acbfd731 100644 --- a/dbus/dbus-marshal-recursive.h +++ b/dbus/dbus-marshal-recursive.h @@ -2,7 +2,6 @@ /* dbus-marshal-recursive.h Marshalling routines for recursive types * * Copyright (C) 2004, 2005 Red Hat, Inc. - * Copyright (C) 2015 Samsung Electronics * * Licensed under the Academic Free License version 2.1 * @@ -45,17 +44,10 @@ struct DBusTypeReader * where we don't have another way to tell */ dbus_uint32_t array_len_offset : 3; /**< bytes back from start_pos that len ends */ - dbus_uint32_t gvariant : 1; /**< TRUE if gvariant marshaling should be used */ - dbus_uint32_t offsets_from_back : 1; /**< for GVariant marshalling: direction of offsets */ - dbus_uint32_t is_variant : 1; /**< for GVariant marshalling: indicator of variant type */ const DBusString *type_str; /**< string containing signature of block */ int type_pos; /**< current position in signature */ const DBusString *value_str; /**< string containing values of block */ int value_pos; /**< current position in values */ - int variable_index; /**< index of value within variable values in the container */ - size_t value_start; /**< start of container */ - size_t value_end; /**< end of container */ - int n_offsets; /**< for GVariant marshalling: number of variable offsets */ const DBusTypeReaderClass *klass; /**< the vtable for the reader */ union @@ -79,18 +71,10 @@ struct DBusTypeWriter dbus_uint32_t enabled : 1; /**< whether to write values */ - dbus_uint32_t gvariant : 1; /**< TRUE if gvariant marshaling should be used */ - dbus_uint32_t body_container : 1; /**< TRUE if this writer is top-level */ - dbus_uint32_t is_fixed : 1; /**< TRUE if this writer wrote only fixed-size values so far */ - DBusString *type_str; /**< where to write typecodes (or read type expectations) */ int type_pos; /**< current pos in type_str */ DBusString *value_str; /**< where to write values */ int value_pos; /**< next position to write */ - size_t value_start; /**< start of the container */ - DBusString *offsets; /**< for GVariant marshalling: actual offsets */ - int alignment; /**< for GVariant marshalling: for enclosing containers */ - char offsets_size; /**< for GVariant marshalling: current size of offsets */ union { @@ -99,9 +83,6 @@ struct DBusTypeWriter int len_pos; /**< position of length of the array */ int element_type_pos; /**< position of array element type in type_str */ } array; - struct { - size_t last_offset; /**< for GVariant marshalling: position of end of last field */ - } struct_or_dict; } u; /**< class-specific data */ }; @@ -165,11 +146,6 @@ void _dbus_type_writer_init_types_delayed (DBusTypeWriter *write int byte_order, DBusString *value_str, int value_pos); -void _dbus_type_writer_gvariant_init_types_delayed (DBusTypeWriter *writer, - int byte_order, - DBusString *value_str, - int value_pos, - dbus_bool_t gvariant); void _dbus_type_writer_add_types (DBusTypeWriter *writer, DBusString *type_str, int type_pos); @@ -183,11 +159,6 @@ void _dbus_type_writer_init_values_only (DBusTypeWriter *write dbus_bool_t _dbus_type_writer_write_basic (DBusTypeWriter *writer, int type, const void *value); -dbus_bool_t _dbus_type_writer_write_basic_with_gvariant - (DBusTypeWriter *writer, - int type, - const void *value, - dbus_bool_t gvariant); dbus_bool_t _dbus_type_writer_write_fixed_multi (DBusTypeWriter *writer, int element_type, const void *value, diff --git a/dbus/dbus-message-internal.h b/dbus/dbus-message-internal.h index c4530e60..5d6594e3 100644 --- a/dbus/dbus-message-internal.h +++ b/dbus/dbus-message-internal.h @@ -96,23 +96,11 @@ long _dbus_message_loader_get_max_message_size (DBusMessageLoader void _dbus_message_loader_set_max_message_unix_fds(DBusMessageLoader *loader, long n); long _dbus_message_loader_get_max_message_unix_fds(DBusMessageLoader *loader); -void _dbus_message_loader_set_unique_sender_id (DBusMessageLoader *loader, - uint64_t id); -uint64_t _dbus_message_loader_get_unique_sender_id (DBusMessageLoader *loader); typedef struct DBusInitialFDs DBusInitialFDs; DBusInitialFDs *_dbus_check_fdleaks_enter (void); void _dbus_check_fdleaks_leave (DBusInitialFDs *fds); -DBusMessage * _dbus_message_remarshal(DBusMessage *message, dbus_bool_t gvariant); - -DBusMessage * _dbus_generate_local_error_message (dbus_uint32_t serial, - char *error_name, - char *error_msg); - -dbus_bool_t _dbus_message_assure_dbus1 (DBusMessage **message); -dbus_bool_t _dbus_message_assure_gvariant (DBusMessage **message); - DBUS_END_DECLS #endif /* DBUS_MESSAGE_INTERNAL_H */ diff --git a/dbus/dbus-message-private.h b/dbus/dbus-message-private.h index 674716ae..e1578abd 100644 --- a/dbus/dbus-message-private.h +++ b/dbus/dbus-message-private.h @@ -81,7 +81,6 @@ struct DBusMessageLoader unsigned n_unix_fds_allocated; /**< Number of file descriptors this array has space for */ unsigned n_unix_fds; /**< Number of valid file descriptors in array */ #endif - uint64_t unique_sender_id; }; @@ -130,8 +129,6 @@ struct DBusMessage long unix_fd_counter_delta; /**< Size we incremented the unix fd counter by */ #endif - DBusString *signature; /**< A placeholder for signature of received GVariant messages */ - DBusString *unique_sender; /**< A placeholder for sender name of received GVariant messages */ }; dbus_bool_t _dbus_message_iter_get_args_valist (DBusMessageIter *iter, diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 4952c17c..c6953d02 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -3,7 +3,6 @@ * * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc. * Copyright (C) 2002, 2003 CodeFactory AB - * Copyright (C) 2015 Samsung Electronics * * Licensed under the Academic Free License version 2.1 * @@ -38,8 +37,6 @@ #ifdef HAVE_UNIX_FD_PASSING #include "dbus-sysdeps-unix.h" #endif -#include "dbus-marshal-gvariant.h" -#include "dbus-protocol-gvariant.h" #include <string.h> @@ -47,8 +44,6 @@ (type == DBUS_TYPE_STRING || type == DBUS_TYPE_SIGNATURE || \ type == DBUS_TYPE_OBJECT_PATH) -unsigned char _dbus_default_protocol_version = DBUS_PROTOCOL_VERSION_GVARIANT; - static void dbus_message_finalize (DBusMessage *message); /** @@ -122,8 +117,6 @@ enum { /** typedef for internals of message iterator */ typedef struct DBusMessageRealIter DBusMessageRealIter; -#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) - /** * @brief Internals of DBusMessageIter * @@ -142,80 +135,19 @@ struct DBusMessageRealIter } u; /**< the type writer or reader that does all the work */ }; -static dbus_bool_t -_dbus_header_is_gvariant (const DBusHeader *header) -{ - return (header->protocol_version == DBUS_PROTOCOL_VERSION_GVARIANT); -} - -static dbus_bool_t -_dbus_message_is_gvariant (const DBusMessage *message) -{ - return _dbus_header_is_gvariant (&message->header); -} - -static void -_dbus_message_toggle_gvariant (DBusMessage *message, dbus_bool_t gvariant) -{ - message->header.protocol_version = gvariant ? DBUS_PROTOCOL_VERSION_GVARIANT : DBUS_MAJOR_PROTOCOL_VERSION; -} - static void -get_const_signature (DBusMessage *message, +get_const_signature (DBusHeader *header, const DBusString **type_str_p, int *type_pos_p) { - dbus_bool_t got_signature = FALSE; - if (_dbus_message_is_gvariant (message) && message->locked) + if (_dbus_header_get_field_raw (header, + DBUS_HEADER_FIELD_SIGNATURE, + type_str_p, + type_pos_p)) { - /* only locked GVariant messages have signatures in the body */ - /* - * in case of received GVariant message, there may be no signature field in a header, - * but in the body. However, it is not nul-terminated. - * So, we need to allocate space and put it into message. - * It could also happen before, so check message->signature for already existing. - * FIXME: That may kinda break oom-safety. - * For now - if oom, then return empty signature. - */ - if (message->signature == NULL) - { - int type_str_len; - got_signature = _dbus_message_gvariant_get_signature (message, - type_str_p, - type_pos_p, - &type_str_len); - if (got_signature) - { - message->signature = dbus_new (DBusString, 1); - got_signature = got_signature && - _dbus_string_init_preallocated (message->signature, type_str_len + 1); - - got_signature = got_signature && - _dbus_string_copy_len (*type_str_p, *type_pos_p, type_str_len, - message->signature, 0); - got_signature = got_signature && - _dbus_string_append_byte (message->signature, 0); - } - } - else - got_signature = TRUE; - - if (got_signature) - { - *type_str_p = message->signature; - *type_pos_p = 0; - } + *type_pos_p += 1; /* skip the signature length which is 1 byte */ } - else if (_dbus_header_get_field_raw (&message->header, - DBUS_HEADER_FIELD_SIGNATURE, - type_str_p, - type_pos_p)) - { - if (!_dbus_message_is_gvariant (message)) - *type_pos_p += 1; /* skip the signature length which is 1 byte */ - got_signature = TRUE; - } - if (!got_signature) + else { *type_str_p = &_dbus_empty_signature_str; *type_pos_p = 0; @@ -241,7 +173,7 @@ _dbus_message_byteswap (DBusMessage *message) _dbus_verbose ("Swapping message into compiler byte order\n"); - get_const_signature (message, &type_str, &type_pos); + get_const_signature (&message->header, &type_str, &type_pos); _dbus_marshal_byteswap (type_str, type_pos, byte_order, @@ -452,11 +384,8 @@ dbus_message_lock (DBusMessage *message) { if (!message->locked) { - if (!_dbus_message_is_gvariant (message)) - _dbus_header_update_lengths (&message->header, - _dbus_string_get_length (&message->body)); - else - _dbus_message_finalize_gvariant (message, TRUE); + _dbus_header_update_lengths (&message->header, + _dbus_string_get_length (&message->body)); /* must have a signature if you have a body */ _dbus_assert (_dbus_string_get_length (&message->body) == 0 || @@ -736,18 +665,6 @@ dbus_message_cache_or_finalize (DBusMessage *message) close_unix_fds(message->unix_fds, &message->n_unix_fds); #endif - if (NULL != message->signature) - { - _dbus_string_free (message->signature); - message->signature = NULL; - } - - if (NULL != message->unique_sender) - { - _dbus_string_free (message->unique_sender); - message->unique_sender = NULL; - } - was_cached = FALSE; if (!_DBUS_LOCK (message_cache)) @@ -1225,25 +1142,13 @@ dbus_bool_t dbus_message_set_reply_serial (DBusMessage *message, dbus_uint32_t reply_serial) { - int type = DBUS_TYPE_UINT32; - _dbus_return_val_if_fail (message != NULL, FALSE); _dbus_return_val_if_fail (!message->locked, FALSE); _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */ - if (_dbus_message_is_gvariant (message)) - { - dbus_uint64_t reply_serial_uint64 = reply_serial; - type = DBUS_TYPE_UINT64; - return _dbus_header_set_field_basic (&message->header, - DBUS_HEADER_FIELD_REPLY_SERIAL, - type, - &reply_serial_uint64); - } - return _dbus_header_set_field_basic (&message->header, DBUS_HEADER_FIELD_REPLY_SERIAL, - type, + DBUS_TYPE_UINT32, &reply_serial); } @@ -1257,28 +1162,14 @@ dbus_uint32_t dbus_message_get_reply_serial (DBusMessage *message) { dbus_uint32_t v_UINT32; - dbus_uint64_t v_UINT64; - int type = DBUS_TYPE_UINT32; - void *value = &v_UINT32; _dbus_return_val_if_fail (message != NULL, 0); - if (_dbus_message_is_gvariant (message)) - { - type = DBUS_TYPE_UINT64; - value = &v_UINT64; - } - if (_dbus_header_get_field_basic (&message->header, DBUS_HEADER_FIELD_REPLY_SERIAL, - type, - value)) - { - if (_dbus_message_is_gvariant (message)) - return v_UINT64; - else - return v_UINT32; - } + DBUS_TYPE_UINT32, + &v_UINT32)) + return v_UINT32; else return 0; } @@ -1309,7 +1200,7 @@ dbus_message_finalize (DBusMessage *message) } static DBusMessage* -dbus_message_new_empty_header (dbus_bool_t gvariant) +dbus_message_new_empty_header (void) { DBusMessage *message; dbus_bool_t from_cache; @@ -1354,8 +1245,6 @@ dbus_message_new_empty_header (dbus_bool_t gvariant) message->unix_fd_counter_delta = 0; #endif - _dbus_message_toggle_gvariant (message, gvariant); /* this works only if kdbus is enabled */ - if (!from_cache) _dbus_data_slot_list_init (&message->slot_list); @@ -1380,33 +1269,36 @@ dbus_message_new_empty_header (dbus_bool_t gvariant) } } - message->signature = NULL; - message->unique_sender = NULL; - return message; } -static DBusMessage* -_dbus_message_create_protocol_version (int message_type, - const char *destination, - const char *path, - const char *interface, - const char *member, - const char *error_name, - dbus_bool_t gvariant) +/** + * Constructs a new message of the given message type. + * Types include #DBUS_MESSAGE_TYPE_METHOD_CALL, + * #DBUS_MESSAGE_TYPE_SIGNAL, and so forth. + * + * Usually you want to use dbus_message_new_method_call(), + * dbus_message_new_method_return(), dbus_message_new_signal(), + * or dbus_message_new_error() instead. + * + * @param message_type type of message + * @returns new message or #NULL if no memory + */ +DBusMessage* +dbus_message_new (int message_type) { DBusMessage *message; - _dbus_assert (message_type != DBUS_MESSAGE_TYPE_INVALID); + _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL); - message = dbus_message_new_empty_header (gvariant); + message = dbus_message_new_empty_header (); if (message == NULL) return NULL; - if (!(_dbus_message_is_gvariant(message) ? _dbus_header_gvariant_create : _dbus_header_create) (&message->header, + if (!_dbus_header_create (&message->header, DBUS_COMPILER_BYTE_ORDER, message_type, - destination, path, interface, member, error_name)) + NULL, NULL, NULL, NULL, NULL)) { dbus_message_unref (message); return NULL; @@ -1415,42 +1307,6 @@ _dbus_message_create_protocol_version (int message_type, return message; } -static DBusMessage* -_dbus_message_create (int message_type, - const char *destination, - const char *path, - const char *interface, - const char *member, - const char *error_name) -{ - return _dbus_message_create_protocol_version(message_type, - destination, - path, - interface, - member, - error_name, - _dbus_default_protocol_version == DBUS_PROTOCOL_VERSION_GVARIANT); -} - -/** - * Constructs a new message of the given message type. - * Types include #DBUS_MESSAGE_TYPE_METHOD_CALL, - * #DBUS_MESSAGE_TYPE_SIGNAL, and so forth. - * - * Usually you want to use dbus_message_new_method_call(), - * dbus_message_new_method_return(), dbus_message_new_signal(), - * or dbus_message_new_error() instead. - * - * @param message_type type of message - * @returns new message or #NULL if no memory - */ -DBusMessage* -dbus_message_new (int message_type) -{ - return _dbus_message_create(message_type, - NULL, NULL, NULL, NULL, NULL); -} - /** * Constructs a new message to invoke a method on a remote * object. Returns #NULL if memory can't be allocated for the @@ -1478,6 +1334,8 @@ dbus_message_new_method_call (const char *destination, const char *iface, const char *method) { + DBusMessage *message; + _dbus_return_val_if_fail (path != NULL, NULL); _dbus_return_val_if_fail (method != NULL, NULL); _dbus_return_val_if_fail (destination == NULL || @@ -1487,8 +1345,20 @@ dbus_message_new_method_call (const char *destination, _dbus_check_is_valid_interface (iface), NULL); _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL); - return _dbus_message_create(DBUS_MESSAGE_TYPE_METHOD_CALL, - destination, path, iface, method, NULL); + message = dbus_message_new_empty_header (); + if (message == NULL) + return NULL; + + if (!_dbus_header_create (&message->header, + DBUS_COMPILER_BYTE_ORDER, + DBUS_MESSAGE_TYPE_METHOD_CALL, + destination, path, iface, method, NULL)) + { + dbus_message_unref (message); + return NULL; + } + + return message; } /** @@ -1510,11 +1380,19 @@ dbus_message_new_method_return (DBusMessage *method_call) /* sender is allowed to be null here in peer-to-peer case */ - message = _dbus_message_create (DBUS_MESSAGE_TYPE_METHOD_RETURN, - sender, NULL, NULL, NULL, NULL); + message = dbus_message_new_empty_header (); if (message == NULL) return NULL; + if (!_dbus_header_create (&message->header, + DBUS_COMPILER_BYTE_ORDER, + DBUS_MESSAGE_TYPE_METHOD_RETURN, + sender, NULL, NULL, NULL, NULL)) + { + dbus_message_unref (message); + return NULL; + } + dbus_message_set_no_reply (message, TRUE); if (!dbus_message_set_reply_serial (message, @@ -1555,11 +1433,19 @@ dbus_message_new_signal (const char *path, _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL); _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL); - message = _dbus_message_create (DBUS_MESSAGE_TYPE_SIGNAL, - NULL, path, iface, name, NULL); + message = dbus_message_new_empty_header (); if (message == NULL) return NULL; + if (!_dbus_header_create (&message->header, + DBUS_COMPILER_BYTE_ORDER, + DBUS_MESSAGE_TYPE_SIGNAL, + NULL, path, iface, name, NULL)) + { + dbus_message_unref (message); + return NULL; + } + dbus_message_set_no_reply (message, TRUE); return message; @@ -1598,11 +1484,19 @@ dbus_message_new_error (DBusMessage *reply_to, * when the message bus is dealing with an unregistered * connection. */ - message = _dbus_message_create (DBUS_MESSAGE_TYPE_ERROR, - sender, NULL, NULL, NULL, error_name); + message = dbus_message_new_empty_header (); if (message == NULL) return NULL; + if (!_dbus_header_create (&message->header, + DBUS_COMPILER_BYTE_ORDER, + DBUS_MESSAGE_TYPE_ERROR, + sender, NULL, NULL, NULL, error_name)) + { + dbus_message_unref (message); + return NULL; + } + dbus_message_set_no_reply (message, TRUE); if (!dbus_message_set_reply_serial (message, @@ -1705,7 +1599,6 @@ dbus_message_copy (const DBusMessage *message) #ifndef DBUS_DISABLE_CHECKS retval->generation = message->generation; #endif - _dbus_message_toggle_gvariant (retval, _dbus_message_is_gvariant (message)); if (!_dbus_header_copy (&message->header, &retval->header)) { @@ -2174,24 +2067,19 @@ dbus_message_iter_init (DBusMessage *message, const DBusString *type_str; int type_pos; - BUILD_BUG_ON (sizeof(DBusMessageIter) != sizeof(DBusMessageRealIter)); - _dbus_return_val_if_fail (message != NULL, FALSE); _dbus_return_val_if_fail (iter != NULL, FALSE); - get_const_signature (message, &type_str, &type_pos); + get_const_signature (&message->header, &type_str, &type_pos); _dbus_message_iter_init_common (message, real, DBUS_MESSAGE_ITER_TYPE_READER); _dbus_type_reader_init (&real->u.reader, - _dbus_header_get_byte_order (&message->header), - type_str, type_pos, - &message->body, - 0); - - if (_dbus_message_is_gvariant (message)) - _dbus_type_reader_gvariant_init (&real->u.reader, message); + _dbus_header_get_byte_order (&message->header), + type_str, type_pos, + &message->body, + 0); return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID; } @@ -2544,12 +2432,10 @@ dbus_message_iter_init_append (DBusMessage *message, * when a value is actually appended. That means that init() never fails * due to OOM. */ - _dbus_type_writer_gvariant_init_types_delayed ( - &real->u.writer, - _dbus_header_get_byte_order (&message->header), - &message->body, - _dbus_string_get_length (&message->body), - _dbus_message_is_gvariant (message)); + _dbus_type_writer_init_types_delayed (&real->u.writer, + _dbus_header_get_byte_order (&message->header), + &message->body, + _dbus_string_get_length (&message->body)); } /** @@ -2588,21 +2474,11 @@ _dbus_message_iter_open_signature (DBusMessageRealIter *real) if (current_sig) { int current_len; - int additional_size_for_len = 0; - if (!real->u.writer.gvariant) - { - current_len = _dbus_string_get_byte (current_sig, current_sig_pos); - current_sig_pos += 1; /* move on to sig data */ - additional_size_for_len = 4; - } - else - { - /* GVariant has no length field, simply string */ - current_len = strlen (_dbus_string_get_const_data (current_sig) + current_sig_pos); - } + current_len = _dbus_string_get_byte (current_sig, current_sig_pos); + current_sig_pos += 1; /* move on to sig data */ - if (!_dbus_string_init_preallocated (str, current_len + additional_size_for_len)) + if (!_dbus_string_init_preallocated (str, current_len + 4)) { dbus_free (str); return FALSE; @@ -3636,9 +3512,6 @@ dbus_message_get_sender (DBusMessage *message) _dbus_return_val_if_fail (message != NULL, NULL); - if (NULL != message->unique_sender) - return _dbus_string_get_const_data (message->unique_sender); - v = NULL; /* in case field doesn't exist */ _dbus_header_get_field_basic (&message->header, DBUS_HEADER_FIELD_SENDER, @@ -3673,7 +3546,7 @@ dbus_message_get_signature (DBusMessage *message) _dbus_return_val_if_fail (message != NULL, NULL); - get_const_signature (message, &type_str, &type_pos); + get_const_signature (&message->header, &type_str, &type_pos); return _dbus_string_get_const_data_len (type_str, type_pos, 0); } @@ -4274,33 +4147,18 @@ load_message (DBusMessageLoader *loader, /* 2. VALIDATE BODY */ if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY) { - if (_dbus_message_is_gvariant (message)) - { - validity = _dbus_validate_gvariant_body_with_reason (type_str, - type_pos, - byte_order, - NULL, - &loader->data, - header_len, - body_len); - } - else - { - - get_const_signature (message, &type_str, &type_pos); - - /* Because the bytes_remaining arg is NULL, this validates that the - * body is the right length - */ - - validity = _dbus_validate_body_with_reason (type_str, - type_pos, - byte_order, - NULL, - &loader->data, - header_len, - body_len); - } + get_const_signature (&message->header, &type_str, &type_pos); + + /* Because the bytes_remaining arg is NULL, this validates that the + * body is the right length + */ + validity = _dbus_validate_body_with_reason (type_str, + type_pos, + byte_order, + NULL, + &loader->data, + header_len, + body_len); if (validity != DBUS_VALID) { _dbus_verbose ("Failed to validate message body code %d\n", validity); @@ -4419,31 +4277,6 @@ load_message (DBusMessageLoader *loader, return FALSE; } -static dbus_bool_t -set_unique_sender (DBusMessage *message, uint64_t unique_sender_id) -{ - if (NULL == message->unique_sender) - { - message->unique_sender = dbus_new (DBusString, 1); - if (NULL == message->unique_sender) - return FALSE; - - if (!_dbus_string_init (message->unique_sender)) - return FALSE; - } - - _dbus_string_set_length (message->unique_sender, 0); - - if (!_dbus_string_append_printf (message->unique_sender, ":1.%llu", (unsigned long long)unique_sender_id)) - { - _dbus_string_free (message->unique_sender); - message->unique_sender = NULL; - return FALSE; - } - - return TRUE; -} - /** * Converts buffered data into messages, if we have enough data. If * we don't have enough data, does nothing. @@ -4466,7 +4299,6 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader) { DBusValidity validity; int byte_order, fields_array_len, header_len, body_len; - dbus_bool_t is_gvariant; if (_dbus_header_have_message_untrusted (loader->max_message_size, &validity, @@ -4475,14 +4307,13 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader) &header_len, &body_len, &loader->data, 0, - _dbus_string_get_length (&loader->data), - &is_gvariant)) + _dbus_string_get_length (&loader->data))) { DBusMessage *message; _dbus_assert (validity == DBUS_VALID); - message = dbus_message_new_empty_header (is_gvariant); + message = dbus_message_new_empty_header (); if (message == NULL) return FALSE; @@ -4497,12 +4328,6 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader) return loader->corrupted; } - if (_dbus_message_is_gvariant (message)) - { - set_unique_sender (message, _dbus_message_loader_get_unique_sender_id (loader)); - message->locked = TRUE; - } - _dbus_assert (loader->messages != NULL); _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL); } @@ -4673,17 +4498,6 @@ _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader) return loader->max_message_unix_fds; } -void _dbus_message_loader_set_unique_sender_id (DBusMessageLoader *loader, - uint64_t id) -{ - loader->unique_sender_id = id; -} - -uint64_t _dbus_message_loader_get_unique_sender_id (DBusMessageLoader *loader) -{ - return loader->unique_sender_id; -} - static DBusDataSlotAllocator slot_allocator = _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots)); @@ -4990,7 +4804,6 @@ dbus_message_demarshal_bytes_needed(const char *buf, int byte_order, fields_array_len, header_len, body_len; DBusValidity validity = DBUS_VALID; int have_message; - dbus_bool_t is_gvariant; if (!buf || len < DBUS_MINIMUM_HEADER_SIZE) return 0; @@ -5007,8 +4820,7 @@ dbus_message_demarshal_bytes_needed(const char *buf, &header_len, &body_len, &str, 0, - len, - &is_gvariant); + len); _dbus_string_free (&str); if (validity == DBUS_VALID) @@ -5023,224 +4835,6 @@ dbus_message_demarshal_bytes_needed(const char *buf, } } -static dbus_bool_t -_dbus_message_copy_recursive(DBusMessageIter *iter, DBusMessageIter *dest) -{ - dbus_bool_t res = TRUE; - int current_type; - - while ((current_type = dbus_message_iter_get_arg_type (iter)) != DBUS_TYPE_INVALID) { - if (dbus_type_is_basic(current_type)) { - DBusBasicValue value; - dbus_message_iter_get_basic (iter, &value); - dbus_message_iter_append_basic (dest, current_type, &value); - } - else { - DBusMessageIter sub; - DBusMessageIter dest_sub; - char *sig = NULL; - - dbus_message_iter_recurse (iter, &sub); - if (DBUS_TYPE_VARIANT == current_type) - sig = dbus_message_iter_get_signature (&sub); - else if (DBUS_TYPE_ARRAY == current_type) - sig = dbus_message_iter_get_signature (&sub); - - res = res && dbus_message_iter_open_container (dest, current_type, sig, &dest_sub); - dbus_free(sig); - res = res && _dbus_message_copy_recursive (&sub, &dest_sub); - res = res && dbus_message_iter_close_container (dest, &dest_sub); - - if (!res) { - return FALSE; - } - } - - dbus_message_iter_next (iter); - } - - return TRUE; -} - -DBusMessage * -_dbus_message_remarshal (DBusMessage *message, dbus_bool_t gvariant) -{ - DBusMessage *ret; - DBusMessageIter iter, ret_iter; - int i; - dbus_uint32_t serial; - const char *sender; - - _dbus_assert (message->locked); - - ret = _dbus_message_create_protocol_version (dbus_message_get_type(message), - dbus_message_get_destination(message), - dbus_message_get_path(message), - dbus_message_get_interface(message), - dbus_message_get_member(message), - dbus_message_get_error_name(message), - gvariant); - - dbus_message_iter_init (message, &iter); - dbus_message_iter_init_append (ret, &ret_iter); - if (!_dbus_message_copy_recursive(&iter, &ret_iter)) - return NULL; - -#ifdef HAVE_UNIX_FD_PASSING - ret->unix_fds = dbus_new(int, message->n_unix_fds); - if (ret->unix_fds == NULL && message->n_unix_fds > 0) - goto err; - - ret->n_unix_fds_allocated = message->n_unix_fds; - - for (i = 0; i < message->n_unix_fds; ++i) { - ret->unix_fds[i] = _dbus_dup(message->unix_fds[i], NULL); - - if (ret->unix_fds[i] < 0) - goto err; - } - - ret->n_unix_fds = message->n_unix_fds; -#endif - - /* Remarshal data in header: - byte order (already set) - type (already set) - flags - only those we understand - version (already set) - body length - serial - fields array (length) - fields: - path (already set) - interface (already set) - member (already set) - error name (already set) - reply serial - destination (already set) - sender - signature (set during copy, but an action needed for conversion to GVariant) - unix fds - */ - - /* FLAGS */ - _dbus_header_toggle_flag (&ret->header, DBUS_HEADER_FLAG_NO_REPLY_EXPECTED, - _dbus_header_get_flag (&message->header, DBUS_HEADER_FLAG_NO_REPLY_EXPECTED)); - - _dbus_header_toggle_flag (&ret->header, DBUS_HEADER_FLAG_NO_AUTO_START, - _dbus_header_get_flag (&message->header, DBUS_HEADER_FLAG_NO_AUTO_START)); - - /* SERIAL / COOKIE */ - serial = dbus_message_get_serial (message); - - if (0 != serial) - dbus_message_set_serial (ret, serial); - - /* Field: REPLY_SERIAL */ - serial = dbus_message_get_reply_serial (message); - - if (0 != serial && !dbus_message_set_reply_serial (ret, serial)) - goto err; - - /* Field: SENDER */ - sender = dbus_message_get_sender (message); - - if (NULL != sender && !dbus_message_set_sender (ret, sender)) - goto err; - - /* BODY LENGTH */ - if (!gvariant) - _dbus_header_update_lengths (&ret->header, - _dbus_string_get_length (&ret->body)); - /* For GVariant: */ - /* Field: SIGNATURE to body; add body offset - this is done with dbus_message_lock() */ - - return ret; - -err: - _dbus_header_free (&ret->header); - _dbus_string_free (&ret->body); - -#ifdef HAVE_UNIX_FD_PASSING - close_unix_fds(ret->unix_fds, &ret->n_unix_fds); - dbus_free(ret->unix_fds); -#endif - - return NULL; -} - -void -dbus_set_protocol_version (unsigned char version) -{ - _dbus_default_protocol_version = version; -} - -DBusMessage * -_dbus_generate_local_error_message (dbus_uint32_t serial, - char *error_name, - char *error_msg) -{ - DBusMessage *message; - message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR); - if (!message) - goto out; - - if (!dbus_message_set_error_name (message, error_name)) - { - dbus_message_unref (message); - message = NULL; - goto out; - } - - dbus_message_set_no_reply (message, TRUE); - - if (!dbus_message_set_reply_serial (message, - serial)) - { - dbus_message_unref (message); - message = NULL; - goto out; - } - - if (error_msg != NULL) - { - DBusMessageIter iter; - - dbus_message_iter_init_append (message, &iter); - if (!dbus_message_iter_append_basic (&iter, - DBUS_TYPE_STRING, - &error_msg)) - { - dbus_message_unref (message); - message = NULL; - goto out; - } - } - - out: - return message; -} - -dbus_bool_t -_dbus_message_assure_dbus1 (DBusMessage **message) -{ - if ((*message)->header.protocol_version != DBUS_MAJOR_PROTOCOL_VERSION) - { - *message = _dbus_message_remarshal (*message, FALSE); - } - return *message != NULL; -} - -dbus_bool_t -_dbus_message_assure_gvariant (DBusMessage **message) -{ - if ((*message)->header.protocol_version != DBUS_PROTOCOL_VERSION_GVARIANT) - { - *message = _dbus_message_remarshal (*message, TRUE); - } - return *message != NULL; -} - /** @} */ /* tests in dbus-message-util.c */ diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h index 007a2d8c..4fd44dab 100644 --- a/dbus/dbus-message.h +++ b/dbus/dbus-message.h @@ -2,7 +2,6 @@ /* dbus-message.h DBusMessage object * * Copyright (C) 2002, 2003, 2005 Red Hat Inc. - * Copyright (C) 2015 Samsung Electronics * * Licensed under the Academic Free License version 2.1 * @@ -50,72 +49,21 @@ typedef struct DBusMessageIter DBusMessageIter; * DBusMessageIter struct; contains no public fields. */ struct DBusMessageIter -{ /* layout on a standard 64-bit system */ - void *dummy1; /**< Don't use this */ /* message */ - dbus_uint32_t dummy3a : 21; /**< Don't use this */ - dbus_uint32_t dummy3b : 3; /**< Don't use this */ - dbus_uint32_t dummy3c : 8; /**< Don't use this */ - - /* padding before union */ - union { - struct - { - dbus_uint32_t dummy1a : 8; /**< Don't use this */ - dbus_uint32_t dummy1b : 1; /**< Don't use this */ - dbus_uint32_t dummy1c : 3; /**< Don't use this */ - dbus_uint32_t dummy1d : 1; /**< Don't use this */ - dbus_uint32_t dummy1e : 1; /**< Don't use this */ - dbus_uint32_t dummy1f : 1; /**< Don't use this */ - void *dummy2; /**< Don't use this */ - int dummy3; /**< Don't use this */ - void *dummy4; /**< Don't use this */ - int dummy5; /**< Don't use this */ - int dummy6; /**< Don't use this */ - size_t dummy7; /**< Don't use this */ - size_t dummy8; /**< Don't use this */ - int dummy9; /**< Don't use this */ - - void *dummy10; /**< Don't use this */ - union - { - struct { - int dummy11; /**< Don't use this */ - }; - } u; - } s1; - - struct - { - dbus_uint32_t dummy1a : 8; /**< Don't use this */ - dbus_uint32_t dummy1b : 8; /**< Don't use this */ - dbus_uint32_t dummy1c : 1; /**< Don't use this */ - dbus_uint32_t dummy1d : 1; /**< Don't use this */ - dbus_uint32_t dummy1e : 1; /**< Don't use this */ - dbus_uint32_t dummy1f : 1; /**< Don't use this */ - dbus_uint32_t dummy1g : 1; /**< Don't use this */ - - void *dummy2; /**< Don't use this */ - int dummy3; /**< Don't use this */ - void *dummy4; /**< Don't use this */ - int dummy5; /**< Don't use this */ - size_t dummy6; /**< Don't use this */ - void *dummy7; /**< Don't use this */ - int dummy8; /**< Don't use this */ - char dummy9; /**< Don't use this */ - - union - { - struct { - int dummy10; /**< Don't use this */ - int dummy11; /**< Don't use this */ - int dummy12; /**< Don't use this */ - }; - struct { - size_t dummy13; /**< Don't use this */ - }; - } u; - } s2; - } u; +{ + void *dummy1; /**< Don't use this */ + void *dummy2; /**< Don't use this */ + dbus_uint32_t dummy3; /**< Don't use this */ + int dummy4; /**< Don't use this */ + int dummy5; /**< Don't use this */ + int dummy6; /**< Don't use this */ + int dummy7; /**< Don't use this */ + int dummy8; /**< Don't use this */ + int dummy9; /**< Don't use this */ + int dummy10; /**< Don't use this */ + int dummy11; /**< Don't use this */ + int pad1; /**< Don't use this */ + int pad2; /**< Don't use this */ + void *pad3; /**< Don't use this */ }; DBUS_EXPORT @@ -354,9 +302,6 @@ DBUS_EXPORT int dbus_message_demarshal_bytes_needed (const char *str, int len); -DBUS_EXPORT -void dbus_set_protocol_version (unsigned char version); - /** @} */ DBUS_END_DECLS diff --git a/dbus/dbus-pending-call.c b/dbus/dbus-pending-call.c index ed96242e..be534105 100644 --- a/dbus/dbus-pending-call.c +++ b/dbus/dbus-pending-call.c @@ -367,9 +367,6 @@ _dbus_pending_call_set_timeout_error_unlocked (DBusPendingCall *pending, if (reply == NULL) return FALSE; - /* FIXME - lock may now fail */ - dbus_message_lock (reply); - reply_link = _dbus_list_alloc_link (reply); if (reply_link == NULL) { diff --git a/dbus/dbus-protocol-gvariant.h b/dbus/dbus-protocol-gvariant.h deleted file mode 100644 index c01f9235..00000000 --- a/dbus/dbus-protocol-gvariant.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* dbus-protocol.h D-Bus protocol constants - * - * Copyright (C) 2015 Samsung Electronics - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef DBUS_PROTOCOL_GVARIANT_H -#define DBUS_PROTOCOL_GVARIANT_H - -#define DBUS_PROTOCOL_VERSION_GVARIANT 2 - -/** Header format is defined as a signature: - * byte byte order - * byte message type ID - * byte flags - * byte protocol version - * uint64 cookie - * array of dict entries (uint64,variant) (field name, value) - * - * The length of the header can be computed as the - * fixed size of the initial data, plus the length of - * the array at the end, plus padding to an 8-boundary. - */ -#define DBUS_HEADER_GVARIANT_SIGNATURE \ - DBUS_TYPE_BYTE_AS_STRING \ - DBUS_TYPE_BYTE_AS_STRING \ - DBUS_TYPE_BYTE_AS_STRING \ - DBUS_TYPE_BYTE_AS_STRING \ - DBUS_TYPE_UINT64_AS_STRING \ - DBUS_TYPE_ARRAY_AS_STRING \ - DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING \ - DBUS_TYPE_BYTE_AS_STRING \ - DBUS_TYPE_VARIANT_AS_STRING \ - DBUS_DICT_ENTRY_END_CHAR_AS_STRING \ - DBUS_TYPE_VARIANT_AS_STRING - -#define FIRST_GVARIANT_FIELD_OFFSET 16 /* yyyyut is before a{tv}*/ - -#endif /* DBUS_PROTOCOL_GVARIANT_H */ diff --git a/dbus/dbus-shared.h b/dbus/dbus-shared.h index b16d35e7..5371d886 100644 --- a/dbus/dbus-shared.h +++ b/dbus/dbus-shared.h @@ -120,8 +120,6 @@ typedef enum #define DBUS_START_REPLY_SUCCESS 1 /**< Service was auto started */ #define DBUS_START_REPLY_ALREADY_RUNNING 2 /**< Service was already running */ -#define DBUS_ADDRESS_KDBUS "kernel:" - /** @} */ #ifdef __cplusplus diff --git a/dbus/dbus-signals.c b/dbus/dbus-signals.c deleted file mode 100644 index e0496b17..00000000 --- a/dbus/dbus-signals.c +++ /dev/null @@ -1,1633 +0,0 @@ -/* signals.c Bus signal connection implementation - * - * Copyright (C) 2003, 2005 Red Hat, Inc. - * Copyright 2014 Samsung Electronics - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "../config.h" -#include "dbus-signals.h" -#include <dbus/dbus-marshal-validate.h> -#include "dbus-internals.h" -#include "dbus-hash.h" -#include "dbus-list.h" -#include "kdbus-common.h" -#include <stdlib.h> -#include <limits.h> - -#define SET_OOM(error) dbus_set_error_const ((error), DBUS_ERROR_NO_MEMORY, "Memory allocation failure in transport, regarding match rules") - -struct MatchRule -{ - int refcount; /**< reference count */ - - DBusConnection *matches_go_to; /**< Owner of the rule */ - - unsigned int flags; /**< MatchFlags */ - - int message_type; - char *interface; - char *member; - char *sender; - char *destination; - char *path; - - unsigned int *arg_lens; - char **args; - int args_len; - - __u64 kdbus_cookie; -}; - -#define MATCH_ARG_FLAGS (MATCH_ARG_NAMESPACE |MATCH_ARG_IS_PATH) - -static MatchRule* -bus_match_rule_new (DBusConnection *matches_go_to) -{ - MatchRule *rule; - - rule = dbus_new0 (MatchRule, 1); - if (rule == NULL) - return NULL; - - rule->refcount = 1; - rule->matches_go_to = matches_go_to; - rule->kdbus_cookie = 0; - -#ifndef DBUS_ENABLE_EMBEDDED_TESTS - _dbus_assert (rule->matches_go_to != NULL); -#endif - - return rule; -} - -static MatchRule * -bus_match_rule_ref (MatchRule *rule) -{ - _dbus_assert (rule->refcount > 0); - - rule->refcount += 1; - - return rule; -} - -void -match_rule_unref (MatchRule *rule) -{ - _dbus_assert (rule->refcount > 0); - - rule->refcount -= 1; - if (rule->refcount == 0) - { - dbus_free (rule->interface); - dbus_free (rule->member); - dbus_free (rule->sender); - dbus_free (rule->destination); - dbus_free (rule->path); - dbus_free (rule->arg_lens); - - /* can't use dbus_free_string_array() since there - * are embedded NULL - */ - if (rule->args) - { - int i; - - i = 0; - while (i < rule->args_len) - { - if (rule->args[i]) - dbus_free (rule->args[i]); - ++i; - } - - dbus_free (rule->args); - } - - dbus_free (rule); - } -} - -#ifdef DBUS_ENABLE_VERBOSE_MODE -/* Note this function does not do escaping, so it's only - * good for debug spew at the moment - */ -char* -match_rule_to_string (MatchRule *rule) -{ - DBusString str; - char *ret; - - if (!_dbus_string_init (&str)) - { - char *s; - while ((s = _dbus_strdup ("nomem")) == NULL) - ; /* only OK for debug spew... */ - return s; - } - - if (rule->flags & MATCH_MESSAGE_TYPE) - { - if (!_dbus_string_append_printf (&str, "type='%s'", - dbus_message_type_to_string (rule->message_type))) - goto nomem; - } - - if (rule->flags & MATCH_INTERFACE) - { - if (_dbus_string_get_length (&str) > 0) - { - if (!_dbus_string_append (&str, ",")) - goto nomem; - } - - if (!_dbus_string_append_printf (&str, "interface='%s'", rule->interface)) - goto nomem; - } - - if (rule->flags & MATCH_MEMBER) - { - if (_dbus_string_get_length (&str) > 0) - { - if (!_dbus_string_append (&str, ",")) - goto nomem; - } - - if (!_dbus_string_append_printf (&str, "member='%s'", rule->member)) - goto nomem; - } - - if (rule->flags & MATCH_PATH) - { - if (_dbus_string_get_length (&str) > 0) - { - if (!_dbus_string_append (&str, ",")) - goto nomem; - } - - if (!_dbus_string_append_printf (&str, "path='%s'", rule->path)) - goto nomem; - } - - if (rule->flags & MATCH_PATH_NAMESPACE) - { - if (_dbus_string_get_length (&str) > 0) - { - if (!_dbus_string_append (&str, ",")) - goto nomem; - } - - if (!_dbus_string_append_printf (&str, "path_namespace='%s'", rule->path)) - goto nomem; - } - - if (rule->flags & MATCH_SENDER) - { - if (_dbus_string_get_length (&str) > 0) - { - if (!_dbus_string_append (&str, ",")) - goto nomem; - } - - if (!_dbus_string_append_printf (&str, "sender='%s'", rule->sender)) - goto nomem; - } - - if (rule->flags & MATCH_DESTINATION) - { - if (_dbus_string_get_length (&str) > 0) - { - if (!_dbus_string_append (&str, ",")) - goto nomem; - } - - if (!_dbus_string_append_printf (&str, "destination='%s'", rule->destination)) - goto nomem; - } - - if (rule->flags & MATCH_CLIENT_IS_EAVESDROPPING) - { - if (_dbus_string_get_length (&str) > 0) - { - if (!_dbus_string_append (&str, ",")) - goto nomem; - } - - if (!_dbus_string_append_printf (&str, "eavesdrop='%s'", - (rule->flags & MATCH_CLIENT_IS_EAVESDROPPING) ? - "true" : "false")) - goto nomem; - } - - if (rule->flags &MATCH_ARGS) - { - int i; - - _dbus_assert (rule->args != NULL); - - i = 0; - while (i < rule->args_len) - { - if (rule->args[i] != NULL) - { - dbus_bool_t is_path, is_namespace; - - if (_dbus_string_get_length (&str) > 0) - { - if (!_dbus_string_append (&str, ",")) - goto nomem; - } - - is_path = (rule->arg_lens[i] & MATCH_ARG_IS_PATH) != 0; - is_namespace = (rule->arg_lens[i] & MATCH_ARG_NAMESPACE) != 0; - - if (!_dbus_string_append_printf (&str, - "arg%d%s='%s'", - i, - is_path ? "path" : - is_namespace ? "namespace" : "", - rule->args[i])) - goto nomem; - } - - ++i; - } - } - - if (!_dbus_string_steal_data (&str, &ret)) - goto nomem; - - _dbus_string_free (&str); - return ret; - - nomem: - _dbus_string_free (&str); - { - char *s; - while ((s = _dbus_strdup ("nomem")) == NULL) - ; /* only OK for debug spew... */ - return s; - } -} -#endif /* DBUS_ENABLE_VERBOSE_MODE */ - -static dbus_bool_t -bus_match_rule_set_message_type (MatchRule *rule, - int type) -{ - rule->flags |=MATCH_MESSAGE_TYPE; - - rule->message_type = type; - - return TRUE; -} - -static dbus_bool_t -bus_match_rule_set_interface (MatchRule *rule, - const char *interface) -{ - char *new; - - _dbus_assert (interface != NULL); - - new = _dbus_strdup (interface); - if (new == NULL) - return FALSE; - - rule->flags |=MATCH_INTERFACE; - dbus_free (rule->interface); - rule->interface = new; - - return TRUE; -} - -static dbus_bool_t -bus_match_rule_set_member (MatchRule *rule, - const char *member) -{ - char *new; - - _dbus_assert (member != NULL); - - new = _dbus_strdup (member); - if (new == NULL) - return FALSE; - - rule->flags |=MATCH_MEMBER; - dbus_free (rule->member); - rule->member = new; - - return TRUE; -} - -static dbus_bool_t -bus_match_rule_set_sender (MatchRule *rule, - const char *sender) -{ - char *new; - - _dbus_assert (sender != NULL); - - new = _dbus_strdup (sender); - if (new == NULL) - return FALSE; - - rule->flags |=MATCH_SENDER; - dbus_free (rule->sender); - rule->sender = new; - - return TRUE; -} - -static dbus_bool_t -bus_match_rule_set_destination (MatchRule *rule, - const char *destination) -{ - char *new; - - _dbus_assert (destination != NULL); - - new = _dbus_strdup (destination); - if (new == NULL) - return FALSE; - - rule->flags |=MATCH_DESTINATION; - dbus_free (rule->destination); - rule->destination = new; - - return TRUE; -} - -static void -bus_match_rule_set_client_is_eavesdropping (MatchRule *rule, - dbus_bool_t is_eavesdropping) -{ - if (is_eavesdropping) - rule->flags |= MATCH_CLIENT_IS_EAVESDROPPING; - else - rule->flags &= ~(MATCH_CLIENT_IS_EAVESDROPPING); -} - -static dbus_bool_t -bus_match_rule_set_path (MatchRule *rule, - const char *path, - dbus_bool_t is_namespace) -{ - char *new; - - _dbus_assert (path != NULL); - - new = _dbus_strdup (path); - if (new == NULL) - return FALSE; - - rule->flags &= ~(MATCH_PATH | MATCH_PATH_NAMESPACE); - - if (is_namespace) - rule->flags |= MATCH_PATH_NAMESPACE; - else - rule->flags |= MATCH_PATH; - - dbus_free (rule->path); - rule->path = new; - - return TRUE; -} - -static dbus_bool_t -bus_match_rule_set_arg (MatchRule *rule, - int arg, - const DBusString *value, - dbus_bool_t is_path, - dbus_bool_t is_namespace) -{ - int length; - char *new; - - _dbus_assert (value != NULL); - - /* args_len is the number of args not including null termination - * in the char** - */ - if (arg >= rule->args_len) - { - unsigned int *new_arg_lens; - char **new_args; - int new_args_len; - int i; - - new_args_len = arg + 1; - - /* add another + 1 here for null termination */ - new_args = dbus_realloc (rule->args, - sizeof (char *) * (new_args_len + 1)); - if (new_args == NULL) - return FALSE; - - /* NULL the new slots */ - i = rule->args_len; - while (i <= new_args_len) /* <= for null termination */ - { - new_args[i] = NULL; - ++i; - } - - rule->args = new_args; - - /* and now add to the lengths */ - new_arg_lens = dbus_realloc (rule->arg_lens, - sizeof (int) * (new_args_len + 1)); - - if (new_arg_lens == NULL) - return FALSE; - - /* zero the new slots */ - i = rule->args_len; - while (i <= new_args_len) /* <= for null termination */ - { - new_arg_lens[i] = 0; - ++i; - } - - rule->arg_lens = new_arg_lens; - rule->args_len = new_args_len; - } - - length = _dbus_string_get_length (value); - if (!_dbus_string_copy_data (value, &new)) - return FALSE; - - rule->flags |=MATCH_ARGS; - - dbus_free (rule->args[arg]); - rule->arg_lens[arg] = length; - rule->args[arg] = new; - - if (is_path) - rule->arg_lens[arg] |=MATCH_ARG_IS_PATH; - - if (is_namespace) - rule->arg_lens[arg] |=MATCH_ARG_NAMESPACE; - - /* NULL termination didn't get busted */ - _dbus_assert (rule->args[rule->args_len] == NULL); - _dbus_assert (rule->arg_lens[rule->args_len] == 0); - - return TRUE; -} - -void -match_rule_set_cookie (MatchRule *rule, dbus_uint64_t cookie) -{ - rule->kdbus_cookie = cookie; -} - -dbus_uint64_t -match_rule_get_cookie (MatchRule *rule) -{ - return rule->kdbus_cookie; -} - -#define ISWHITE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r')) - -static dbus_bool_t -find_key (const DBusString *str, - int start, - DBusString *key, - int *value_pos, - DBusError *error) -{ - const char *p; - const char *s; - const char *key_start; - const char *key_end; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - s = _dbus_string_get_const_data (str); - - p = s + start; - - while (*p && ISWHITE (*p)) - ++p; - - key_start = p; - - while (*p && *p != '=' && !ISWHITE (*p)) - ++p; - - key_end = p; - - while (*p && ISWHITE (*p)) - ++p; - - if (key_start == key_end) - { - /* Empty match rules or trailing whitespace are OK */ - *value_pos = p - s; - return TRUE; - } - - if (*p != '=') - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Match rule has a key with no subsequent '=' character"); - return FALSE; - } - ++p; - - if (!_dbus_string_append_len (key, key_start, key_end - key_start)) - { - SET_OOM (error); - return FALSE; - } - - *value_pos = p - s; - - return TRUE; -} - -static dbus_bool_t -find_value (const DBusString *str, - int start, - const char *key, - DBusString *value, - int *value_end, - DBusError *error) -{ - const char *p; - const char *s; - char quote_char; - int orig_len; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - orig_len = _dbus_string_get_length (value); - - s = _dbus_string_get_const_data (str); - - p = s + start; - - quote_char = '\0'; - - while (*p) - { - if (quote_char == '\0') - { - switch (*p) - { - case '\0': - goto done; - - case '\'': - quote_char = '\''; - goto next; - - case ',': - ++p; - goto done; - - case '\\': - quote_char = '\\'; - goto next; - - default: - if (!_dbus_string_append_byte (value, *p)) - { - SET_OOM (error); - goto failed; - } - } - } - else if (quote_char == '\\') - { - /* \ only counts as an escape if escaping a quote mark */ - if (*p != '\'') - { - if (!_dbus_string_append_byte (value, '\\')) - { - SET_OOM (error); - goto failed; - } - } - - if (!_dbus_string_append_byte (value, *p)) - { - SET_OOM (error); - goto failed; - } - - quote_char = '\0'; - } - else - { - _dbus_assert (quote_char == '\''); - - if (*p == '\'') - { - quote_char = '\0'; - } - else - { - if (!_dbus_string_append_byte (value, *p)) - { - SET_OOM (error); - goto failed; - } - } - } - - next: - ++p; - } - - done: - - if (quote_char == '\\') - { - if (!_dbus_string_append_byte (value, '\\')) - { - SET_OOM (error); - goto failed; - } - } - else if (quote_char == '\'') - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Unbalanced quotation marks in match rule"); - goto failed; - } - else - _dbus_assert (quote_char == '\0'); - - /* Zero-length values are allowed */ - - *value_end = p - s; - - return TRUE; - - failed: - _DBUS_ASSERT_ERROR_IS_SET (error); - _dbus_string_set_length (value, orig_len); - return FALSE; -} - -/* duplicates aren't allowed so the real legitimate max is only 6 or - * so. Leaving extra so we don't have to bother to update it. - * FIXME this is sort of busted now with arg matching, but we let - * you match on up to 10 args for now - */ -#define MAX_RULE_TOKENS 16 - -/* this is slightly too high level to be termed a "token" - * but let's not be pedantic. - */ -typedef struct -{ - char *key; - char *value; -} RuleToken; - -static dbus_bool_t -tokenize_rule (const DBusString *rule_text, - RuleToken tokens[MAX_RULE_TOKENS], - DBusError *error) -{ - int i; - int pos; - DBusString key; - DBusString value; - dbus_bool_t retval; - - retval = FALSE; - - if (!_dbus_string_init (&key)) - { - SET_OOM (error); - return FALSE; - } - - if (!_dbus_string_init (&value)) - { - _dbus_string_free (&key); - SET_OOM (error); - return FALSE; - } - - i = 0; - pos = 0; - while (i < MAX_RULE_TOKENS && - pos < _dbus_string_get_length (rule_text)) - { - _dbus_assert (tokens[i].key == NULL); - _dbus_assert (tokens[i].value == NULL); - - if (!find_key (rule_text, pos, &key, &pos, error)) - goto out; - - if (_dbus_string_get_length (&key) == 0) - goto next; - - if (!_dbus_string_steal_data (&key, &tokens[i].key)) - { - SET_OOM (error); - goto out; - } - - if (!find_value (rule_text, pos, tokens[i].key, &value, &pos, error)) - goto out; - - if (!_dbus_string_steal_data (&value, &tokens[i].value)) - { - SET_OOM (error); - goto out; - } - - next: - ++i; - } - - retval = TRUE; - - out: - if (!retval) - { - i = 0; - while (tokens[i].key || tokens[i].value) - { - dbus_free (tokens[i].key); - dbus_free (tokens[i].value); - tokens[i].key = NULL; - tokens[i].value = NULL; - ++i; - } - } - - _dbus_string_free (&key); - _dbus_string_free (&value); - - return retval; -} - -static dbus_bool_t -bus_match_rule_parse_arg_match (MatchRule *rule, - const char *key, - const DBusString *value, - DBusError *error) -{ - dbus_bool_t is_path = FALSE; - dbus_bool_t is_namespace = FALSE; - DBusString key_str; - unsigned long arg; - int length; - int end; - - /* For now, arg0='foo' always implies that 'foo' is a - * DBUS_TYPE_STRING. Someday we could add an arg0type='int32' thing - * if we wanted, which would specify another type, in which case - * arg0='5' would have the 5 parsed as an int rather than string. - */ - - /* First we need to parse arg0 = 0, arg27 = 27 */ - - _dbus_string_init_const (&key_str, key); - length = _dbus_string_get_length (&key_str); - - if (_dbus_string_get_length (&key_str) < 4) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Key '%s' in match rule starts with 'arg' but lacks an arg number. Should be 'arg0' or 'arg7' for example.\n", key); - goto failed; - } - - if (!_dbus_string_parse_uint (&key_str, 3, &arg, &end)) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Key '%s' in match rule starts with 'arg' but could not parse arg number. Should be 'arg0' or 'arg7' for example.\n", key); - goto failed; - } - - if (end != length) - { - if ((end + strlen ("path")) == length && - _dbus_string_ends_with_c_str (&key_str, "path")) - { - is_path = TRUE; - } - else if (_dbus_string_equal_c_str (&key_str, "arg0namespace")) - { - int value_len = _dbus_string_get_length (value); - - is_namespace = TRUE; - - if (!_dbus_validate_bus_namespace (value, 0, value_len)) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "arg0namespace='%s' is not a valid prefix of a bus name", - _dbus_string_get_const_data (value)); - goto failed; - } - } - else - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Key '%s' in match rule contains junk after argument number (%u). Only 'arg%upath' (for example) or 'arg0namespace' are valid", key, arg, arg); - goto failed; - } - } - - /* If we didn't check this we could allocate a huge amount of RAM */ - if (arg > DBUS_MAXIMUM_MATCH_RULE_ARG_NUMBER) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Key '%s' in match rule has arg number %lu but the maximum is %d.\n", key, (unsigned long) arg, DBUS_MAXIMUM_MATCH_RULE_ARG_NUMBER); - goto failed; - } - - if ((rule->flags &MATCH_ARGS) && - rule->args_len > (int) arg && - rule->args[arg] != NULL) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Argument %d matched more than once in match rule\n", key); - goto failed; - } - - if (!bus_match_rule_set_arg (rule, arg, value, is_path, is_namespace)) - { - SET_OOM (error); - goto failed; - } - - return TRUE; - - failed: - _DBUS_ASSERT_ERROR_IS_SET (error); - return FALSE; -} - -/* - * The format is comma-separated with strings quoted with single quotes - * as for the shell (to escape a literal single quote, use '\''). - * - * type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='Foo', - * path='/bar/foo',destination=':452345.34' - * - */ -MatchRule* -match_rule_parse (DBusConnection *matches_go_to, - const DBusString *rule_text, - DBusError *error) -{ - MatchRule *rule; - RuleToken tokens[MAX_RULE_TOKENS+1]; /* NULL termination + 1 */ - int i; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - if (_dbus_string_get_length (rule_text) > DBUS_MAXIMUM_MATCH_RULE_LENGTH) - { - dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED, - "Match rule text is %d bytes, maximum is %d", - _dbus_string_get_length (rule_text), - DBUS_MAXIMUM_MATCH_RULE_LENGTH); - return NULL; - } - - memset (tokens, '\0', sizeof (tokens)); - - rule = bus_match_rule_new (matches_go_to); - if (rule == NULL) - { - SET_OOM (error); - goto failed; - } - - if (!tokenize_rule (rule_text, tokens, error)) - goto failed; - - i = 0; - while (tokens[i].key != NULL) - { - DBusString tmp_str; - int len; - const char *key = tokens[i].key; - const char *value = tokens[i].value; - - _dbus_string_init_const (&tmp_str, value); - len = _dbus_string_get_length (&tmp_str); - - if (strcmp (key, "type") == 0) - { - int t; - - if (rule->flags & MATCH_MESSAGE_TYPE) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Key %s specified twice in match rule\n", key); - goto failed; - } - - t = dbus_message_type_from_string (value); - - if (t == DBUS_MESSAGE_TYPE_INVALID) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Invalid message type (%s) in match rule\n", value); - goto failed; - } - - if (!bus_match_rule_set_message_type (rule, t)) - { - SET_OOM (error); - goto failed; - } - } - else if (strcmp (key, "sender") == 0) - { - if (rule->flags & MATCH_SENDER) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Key %s specified twice in match rule\n", key); - goto failed; - } - - if (!_dbus_validate_bus_name (&tmp_str, 0, len)) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Sender name '%s' is invalid\n", value); - goto failed; - } - - if (!bus_match_rule_set_sender (rule, value)) - { - SET_OOM (error); - goto failed; - } - } - else if (strcmp (key, "interface") == 0) - { - if (rule->flags & MATCH_INTERFACE) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Key %s specified twice in match rule\n", key); - goto failed; - } - - if (!_dbus_validate_interface (&tmp_str, 0, len)) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Interface name '%s' is invalid\n", value); - goto failed; - } - - if (!bus_match_rule_set_interface (rule, value)) - { - SET_OOM (error); - goto failed; - } - } - else if (strcmp (key, "member") == 0) - { - if (rule->flags & MATCH_MEMBER) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Key %s specified twice in match rule\n", key); - goto failed; - } - - if (!_dbus_validate_member (&tmp_str, 0, len)) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Member name '%s' is invalid\n", value); - goto failed; - } - - if (!bus_match_rule_set_member (rule, value)) - { - SET_OOM (error); - goto failed; - } - } - else if (strcmp (key, "path") == 0 || - strcmp (key, "path_namespace") == 0) - { - dbus_bool_t is_namespace = (strcmp (key, "path_namespace") == 0); - - if (rule->flags & (MATCH_PATH | MATCH_PATH_NAMESPACE)) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "path or path_namespace specified twice in match rule\n"); - goto failed; - } - - if (!_dbus_validate_path (&tmp_str, 0, len)) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Path '%s' is invalid\n", value); - goto failed; - } - - if (!bus_match_rule_set_path (rule, value, is_namespace)) - { - SET_OOM (error); - goto failed; - } - } - else if (strcmp (key, "destination") == 0) - { - if (rule->flags & MATCH_DESTINATION) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Key %s specified twice in match rule\n", key); - goto failed; - } - - if (!_dbus_validate_bus_name (&tmp_str, 0, len)) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Destination name '%s' is invalid\n", value); - goto failed; - } - - if (!bus_match_rule_set_destination (rule, value)) - { - SET_OOM (error); - goto failed; - } - } - else if (strcmp (key, "eavesdrop") == 0) - { - /* do not detect "eavesdrop" being used more than once in rule: - * 1) it's not possible, it's only in the flags - * 2) it might be used twice to disable eavesdropping when it's - * automatically added (eg dbus-monitor/bustle) */ - - /* we accept only "true|false" as possible values */ - if ((strcmp (value, "true") == 0)) - { - bus_match_rule_set_client_is_eavesdropping (rule, TRUE); - } - else if (strcmp (value, "false") == 0) - { - bus_match_rule_set_client_is_eavesdropping (rule, FALSE); - } - else - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "eavesdrop='%s' is invalid, " - "it should be 'true' or 'false'\n", - value); - goto failed; - } - } - else if (strncmp (key, "arg", 3) == 0) - { - if (!bus_match_rule_parse_arg_match (rule, key, &tmp_str, error)) - goto failed; - } - else - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Unknown key \"%s\" in match rule", - key); - goto failed; - } - - ++i; - } - - - goto out; - - failed: - _DBUS_ASSERT_ERROR_IS_SET (error); - if (rule) - { - match_rule_unref (rule); - rule = NULL; - } - - out: - - i = 0; - while (tokens[i].key || tokens[i].value) - { - _dbus_assert (i < MAX_RULE_TOKENS); - dbus_free (tokens[i].key); - dbus_free (tokens[i].value); - ++i; - } - - return rule; -} - -typedef struct RulePool RulePool; -struct RulePool -{ - /* Maps non-NULL interface names to non-NULL (DBusList **)s */ - DBusHashTable *rules_by_iface; - - /* List of MatchRules which don't specify an interface */ - DBusList *rules_without_iface; -}; - -struct Matchmaker -{ - int refcount; - - /* Pools of rules, grouped by the type of message they match. 0 - * (DBUS_MESSAGE_TYPE_INVALID) represents rules that do not specify a message - * type. - */ - RulePool rules_by_type[DBUS_NUM_MESSAGE_TYPES]; - - int last_cookie; -}; - -static void -rule_list_free (DBusList **rules) -{ - while (*rules != NULL) - { - MatchRule *rule; - - rule = (*rules)->data; - match_rule_unref (rule); - _dbus_list_remove_link (rules, *rules); - } -} - -static void -rule_list_ptr_free (DBusList **list) -{ - /* We have to cope with NULL because the hash table frees the "existing" - * value (which is NULL) when creating a new table entry... - */ - if (list != NULL) - { - rule_list_free (list); - dbus_free (list); - } -} - -Matchmaker* -matchmaker_new (void) -{ - Matchmaker *matchmaker; - int i; - - matchmaker = dbus_new0 (Matchmaker, 1); - if (matchmaker == NULL) - return NULL; - - matchmaker->refcount = 1; - matchmaker->last_cookie = 0; - - for (i = DBUS_MESSAGE_TYPE_INVALID; i < DBUS_NUM_MESSAGE_TYPES; i++) - { - RulePool *p = matchmaker->rules_by_type + i; - - p->rules_by_iface = _dbus_hash_table_new (DBUS_HASH_STRING, - dbus_free, (DBusFreeFunction) rule_list_ptr_free); - - if (p->rules_by_iface == NULL) - goto nomem; - } - - return matchmaker; - - nomem: - for (i = DBUS_MESSAGE_TYPE_INVALID; i < DBUS_NUM_MESSAGE_TYPES; i++) - { - RulePool *p = matchmaker->rules_by_type + i; - - if (p->rules_by_iface == NULL) - break; - else - _dbus_hash_table_unref (p->rules_by_iface); - } - dbus_free (matchmaker); - - return NULL; -} - -DBusList ** -matchmaker_get_rules (Matchmaker *matchmaker, - int message_type, - const char *interface, - dbus_bool_t create) -{ - RulePool *p; - - _dbus_assert (message_type >= 0); - _dbus_assert (message_type < DBUS_NUM_MESSAGE_TYPES); - - _dbus_verbose ("Looking up rules for message_type %d, interface %s\n", - message_type, - interface != NULL ? interface : "<null>"); - - p = matchmaker->rules_by_type + message_type; - - if (interface == NULL) - { - return &p->rules_without_iface; - } - else - { - DBusList **list; - - list = _dbus_hash_table_lookup_string (p->rules_by_iface, interface); - - if (list == NULL && create) - { - char *dupped_interface; - - list = dbus_new0 (DBusList *, 1); - if (list == NULL) - return NULL; - - dupped_interface = _dbus_strdup (interface); - if (dupped_interface == NULL) - { - dbus_free (list); - return NULL; - } - - _dbus_verbose ("Adding list for type %d, iface %s\n", message_type, - interface); - - if (!_dbus_hash_table_insert_string (p->rules_by_iface, - dupped_interface, list)) - { - dbus_free (list); - dbus_free (dupped_interface); - return NULL; - } - } - - return list; - } -} - -static void -bus_matchmaker_gc_rules (Matchmaker *matchmaker, - int message_type, - const char *interface, - DBusList **rules) -{ - RulePool *p; - - if (interface == NULL) - return; - - if (*rules != NULL) - return; - - _dbus_verbose ("GCing HT entry for message_type %u, interface %s\n", - message_type, interface); - - p = matchmaker->rules_by_type + message_type; - - _dbus_assert (_dbus_hash_table_lookup_string (p->rules_by_iface, interface) - == rules); - - _dbus_hash_table_remove_string (p->rules_by_iface, interface); -} - -/* The rule can't be modified after it's added. */ -dbus_bool_t -matchmaker_add_rule (Matchmaker *matchmaker, - MatchRule *rule) -{ - DBusList **rules; - - _dbus_verbose ("Adding rule with message_type %d, interface %s\n", - rule->message_type, - rule->interface != NULL ? rule->interface : "<null>"); - - rules = matchmaker_get_rules (matchmaker, rule->message_type, - rule->interface, TRUE); - - if (rules == NULL) - return FALSE; - - if (!_dbus_list_append (rules, rule)) - return FALSE; - - rule->kdbus_cookie = ++(matchmaker->last_cookie); - - bus_match_rule_ref (rule); - -#ifdef DBUS_ENABLE_VERBOSE_MODE - { - char *s = match_rule_to_string (rule); - - _dbus_verbose ("Added match rule %s to connection %p\n", - s, rule->matches_go_to); - dbus_free (s); - } -#endif - - return TRUE; -} - -DBusList* -matchmaker_get_rules_list (Matchmaker *matchmaker, - MatchRule *rule) -{ - DBusList** list; - - list = matchmaker_get_rules (matchmaker, rule->message_type, - rule->interface, FALSE); - - if(list) - return *list; - - return NULL; -} - -dbus_bool_t -match_rule_equal_lib (MatchRule *a, - MatchRule *b) -{ - if (a->flags != b->flags) - return FALSE; - - if (a->matches_go_to != b->matches_go_to) - return FALSE; - - if ((a->flags &MATCH_MESSAGE_TYPE) && - a->message_type != b->message_type) - return FALSE; - - if ((a->flags &MATCH_MEMBER) && - strcmp (a->member, b->member) != 0) - return FALSE; - - if ((a->flags &MATCH_PATH) && - strcmp (a->path, b->path) != 0) - return FALSE; - - if ((a->flags &MATCH_INTERFACE) && - strcmp (a->interface, b->interface) != 0) - return FALSE; - - if ((a->flags &MATCH_SENDER) && - strcmp (a->sender, b->sender) != 0) - return FALSE; - - if ((a->flags &MATCH_DESTINATION) && - strcmp (a->destination, b->destination) != 0) - return FALSE; - - /* we already compared the value of flags, and - *MATCH_CLIENT_IS_EAVESDROPPING does not have another struct member */ - - if (a->flags &MATCH_ARGS) - { - int i; - - if (a->args_len != b->args_len) - return FALSE; - - i = 0; - while (i < a->args_len) - { - int length; - - if ((a->args[i] != NULL) != (b->args[i] != NULL)) - return FALSE; - - if (a->arg_lens[i] != b->arg_lens[i]) - return FALSE; - - length = a->arg_lens[i] & ~MATCH_ARG_FLAGS; - - if (a->args[i] != NULL) - { - _dbus_assert (b->args[i] != NULL); - if (memcmp (a->args[i], b->args[i], length) != 0) - return FALSE; - } - - ++i; - } - } - - return TRUE; -} - -static void -bus_matchmaker_remove_rule_link (DBusList **rules, - DBusList *link) -{ - MatchRule *rule = link->data; - - _dbus_list_remove_link (rules, link); - -#ifdef DBUS_ENABLE_VERBOSE_MODE - { - char *s = match_rule_to_string (rule); - - _dbus_verbose ("Removed match rule %s for connection %p\n", - s, rule->matches_go_to); - dbus_free (s); - } -#endif - - match_rule_unref (rule); -} - -/* Remove a single rule which is equal to the given rule by value */ -dbus_bool_t -matchmaker_remove_rule_by_value (Matchmaker *matchmaker, - MatchRule *value, - DBusError *error) -{ - DBusList **rules; - DBusList *link = NULL; - - _dbus_verbose ("Removing rule by value with message_type %d, interface %s\n", - value->message_type, - value->interface != NULL ? value->interface : "<null>"); - - rules = matchmaker_get_rules (matchmaker, value->message_type, - value->interface, FALSE); - - if (rules != NULL) - { - /* we traverse backward because bus_connection_remove_match_rule() - * removes the most-recently-added rule - */ - link = _dbus_list_get_last_link (rules); - while (link != NULL) - { - MatchRule *rule; - DBusList *prev; - - rule = link->data; - prev = _dbus_list_get_prev_link (rules, link); - - if (match_rule_equal_lib (rule, value)) - { - bus_matchmaker_remove_rule_link (rules, link); - break; - } - - link = prev; - } - } - - if (link == NULL) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_NOT_FOUND, - "The given match rule wasn't found and can't be removed"); - return FALSE; - } - - bus_matchmaker_gc_rules (matchmaker, value->message_type, value->interface, - rules); - - return TRUE; -} - -static void -rule_list_remove (DBusList **rules) -{ - DBusList *link; - - link = _dbus_list_get_first_link (rules); - while (link != NULL) - { - DBusList *next; - - next = _dbus_list_get_next_link (rules, link); - bus_matchmaker_remove_rule_link (rules, link); - link = next; - } -} - -void -free_matchmaker (Matchmaker *matchmaker) -{ - int i; - - _dbus_verbose ("Removing all rules for connection\n"); - - for (i = DBUS_MESSAGE_TYPE_INVALID; i < DBUS_NUM_MESSAGE_TYPES; i++) - { - RulePool *p = matchmaker->rules_by_type + i; - DBusHashIter iter; - - rule_list_remove (&p->rules_without_iface); - - _dbus_hash_iter_init (p->rules_by_iface, &iter); - while (_dbus_hash_iter_next (&iter)) - { - DBusList **items = _dbus_hash_iter_get_value (&iter); - - rule_list_remove (items); - - if (*items == NULL) - _dbus_hash_iter_remove_entry (&iter); - } - } -} - -int -_match_rule_get_message_type (MatchRule *rule) -{ - if (rule->flags & MATCH_MESSAGE_TYPE) - return rule->message_type; - else - return DBUS_MESSAGE_TYPE_INVALID; -} - -const char * -_match_rule_get_interface (MatchRule *rule) -{ - if (rule->flags & MATCH_INTERFACE) - return rule->interface; - else - return NULL; -} - -const char * -_match_rule_get_member (MatchRule *rule) -{ - if (rule->flags & MATCH_MEMBER) - return rule->member; - else - return NULL; -} - -const char * -_match_rule_get_sender (MatchRule *rule) -{ - if (rule->flags & MATCH_SENDER) - return rule->sender; - else - return NULL; -} - -const char * -_match_rule_get_destination (MatchRule *rule) -{ - if (rule->flags & MATCH_DESTINATION) - return rule->destination; - else - return NULL; -} - -const char * -_match_rule_get_path (MatchRule *rule) -{ - if (rule->flags & MATCH_PATH) - return rule->path; - else - return NULL; -} - -const char * -_match_rule_get_path_namespace (MatchRule *rule) -{ - if (rule->flags & MATCH_PATH_NAMESPACE) - return rule->path; - else - return NULL; -} - -int -_match_rule_get_args_len (MatchRule *rule) -{ - return rule->args_len; -} - -const char * -_match_rule_get_args (MatchRule *rule, int i) -{ - return rule->args[i]; -} - -unsigned int -_match_rule_get_arg_lens (MatchRule *rule, int i) -{ - return rule->arg_lens[i]; -} diff --git a/dbus/dbus-signals.h b/dbus/dbus-signals.h deleted file mode 100644 index da3fd57f..00000000 --- a/dbus/dbus-signals.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * dbus-signals.h - * - * Created on: Feb 26, 2014 - * Author: r.pajak - */ - -#ifndef DBUS_SIGNALS_H_ -#define DBUS_SIGNALS_H_ - -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* signals.h Bus signal connection implementation - * - * Copyright (C) 2003 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include <dbus/dbus.h> -#include <dbus/dbus-string.h> -#include <dbus/dbus-sysdeps.h> -#include <dbus/dbus-transport.h> - -typedef struct Matchmaker Matchmaker; -typedef struct MatchRule MatchRule; - -#ifndef MATCH_ARG_NAMESPACE -#define MATCH_ARG_NAMESPACE 0x4000000u -#endif -#ifndef MATCH_ARG_IS_PATH -#define MATCH_ARG_IS_PATH 0x8000000u -#endif - -typedef enum -{ - MATCH_MESSAGE_TYPE = 1 << 0, - MATCH_INTERFACE = 1 << 1, - MATCH_MEMBER = 1 << 2, - MATCH_SENDER = 1 << 3, - MATCH_DESTINATION = 1 << 4, - MATCH_PATH = 1 << 5, - MATCH_ARGS = 1 << 6, - MATCH_PATH_NAMESPACE = 1 << 7, - MATCH_CLIENT_IS_EAVESDROPPING = 1 << 8 -} MatchFlags; - -void match_rule_unref (MatchRule *rule); -void match_rule_set_cookie (MatchRule *rule, dbus_uint64_t cookie); -dbus_uint64_t match_rule_get_cookie (MatchRule *rule); - -/* Calling this methods a client declares that it is creating a rule which - * needs to eavesdrop (e.g., dbus-monitor), any other created rules not - * setting themselves as eavesdropping won't receive any message not addressed - * to them, when eavedrop is enabled in the policy. On the other hand, when - * eavedrop is not enabled in policy, this method won't have any effect */ -//void bus_match_rule_set_client_is_eavesdropping (BusMatchRule *rule, -// dbus_bool_t is_eavesdropping); - -DBusList ** matchmaker_get_rules (Matchmaker *matchmaker, - int message_type, - const char *interface, - dbus_bool_t create); - -MatchRule* match_rule_parse (DBusConnection *matches_go_to, - const DBusString *rule_text, - DBusError *error); - -dbus_bool_t match_rule_equal_lib (MatchRule *a, MatchRule *b); - - -Matchmaker* matchmaker_new (void); - -dbus_bool_t matchmaker_add_rule (Matchmaker *matchmaker, - MatchRule *rule); -DBusList* matchmaker_get_rules_list (Matchmaker *matchmaker, - MatchRule *rule); -dbus_bool_t matchmaker_remove_rule_by_value (Matchmaker *matchmaker, - MatchRule *value, - DBusError *error); -void free_matchmaker (Matchmaker *matchmaker); - -dbus_bool_t match_rule_matches (DBusTransport *transport, - MatchRule *rule, - DBusMessage *message, - MatchFlags already_matched); - -#ifdef DBUS_ENABLE_VERBOSE_MODE -char* match_rule_to_string (MatchRule *rule); -#endif - -int _match_rule_get_message_type (MatchRule *rule); -const char * _match_rule_get_interface (MatchRule *rule); -const char * _match_rule_get_member (MatchRule *rule); -const char * _match_rule_get_sender (MatchRule *rule); -const char * _match_rule_get_destination (MatchRule *rule); -const char * _match_rule_get_path (MatchRule *rule); -const char * _match_rule_get_path_namespace (MatchRule *rule); -int _match_rule_get_args_len (MatchRule *rule); -const char * _match_rule_get_args (MatchRule *rule, int i); -unsigned int _match_rule_get_arg_lens (MatchRule *rule, int i); - -#endif /* DBUS_SIGNALS_H_ */ diff --git a/dbus/dbus-transport-kdbus.c b/dbus/dbus-transport-kdbus.c deleted file mode 100644 index cc819cbb..00000000 --- a/dbus/dbus-transport-kdbus.c +++ /dev/null @@ -1,4000 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* dbus-transport-kdbus.c kdbus subclasses of DBusTransport - * - * Copyright (C) 2002, 2003, 2004, 2006 Red Hat Inc - * Copyright (C) 2013 Samsung Electronics - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version and under the terms of the GNU - * Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#include "../config.h" -#include "dbus-transport.h" -#include "dbus-transport-kdbus.h" -#include "dbus-transport-protected.h" -#include "dbus-connection-internal.h" -#include "dbus-marshal-gvariant.h" -#include "dbus-asv-util.h" -#include "kdbus.h" -#include "dbus-watch.h" -#include "dbus-errors.h" -#include "dbus-bus.h" -#include "kdbus-common.h" -#include <linux/types.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/syscall.h> -#include <fcntl.h> - -#include <linux/version.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -# if defined(__arm__) || defined(__aarch64__) -# define __NR_memfd_create 385 -# elif defined(__i386__) -# define __NR_memfd_create 279 -# else -# error "Architecture not supported" -# endif -#else -# include <linux/memfd.h> -#endif - -int debug = -1; - -/* FIXME shouldn't it be in fcntl.h header file? copied from systemd's missing.h */ -#ifndef F_LINUX_SPECIFIC_BASE -#define F_LINUX_SPECIFIC_BASE 1024 -#endif - -#ifndef F_ADD_SEALS -#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9) -#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10) - -#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */ -#define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */ -#define F_SEAL_GROW 0x0004 /* prevent file from growing */ -#define F_SEAL_WRITE 0x0008 /* prevent writes */ -#endif - -#ifndef MFD_CLOEXEC -#define MFD_CLOEXEC 0x0001U -#endif - -#ifndef MFD_ALLOW_SEALING -#define MFD_ALLOW_SEALING 0x0002U -#endif - -/* ALIGN8 and KDBUS_FOREACH taken from systemd */ -#define ALIGN8(l) (((l) + 7) & ~7) -#define KDBUS_FOREACH(iter, first, _size) \ - for (iter = (first); \ - ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \ - ((uint8_t *)(iter) >= (uint8_t *)(first)); \ - iter = (void*)(((uint8_t *)iter) + ALIGN8((iter)->size))) -#define KDBUS_DEFAULT_TIMEOUT_NS 5000000000LU - -/** - * @defgroup DBusTransportKdbus DBusTransport implementations for kdbus - * @ingroup DBusInternals - * @brief Implementation details of DBusTransport on kdbus - * - * @{ - */ - -/** Default Size of the memory area for received non-memfd messages. */ -#define RECEIVE_POOL_SIZE_DEFAULT_SIZE (2 * 1024LU * 1024LU) -/** Name of environmental variable to define receive pool size*/ -#define RECEIVE_POOL_SIZE_ENV_VAR_NAME "KDBUS_MEMORY_POOL_SIZE" -/** Max size of pool size in megabytes*/ -#define RECEIVE_POOL_SIZE_MAX_MBYTES 64 -/** Min size of pool size in kilobytes*/ -#define RECEIVE_POOL_SIZE_MIN_KBYTES 16 - -/** Over this memfd is used to send (if it is not broadcast). */ -#define MEMFD_SIZE_THRESHOLD (512 * 1024LU) - -/** Define max bytes read or written in one iteration. -* This is to avoid blocking on reading or writing for too long. It is checked after each message is sent or received, -* so if message is bigger than MAX_BYTES_PER_ITERATION it will be handled in one iteration, but sending/writing -* will break after that message. -**/ -#define MAX_BYTES_PER_ITERATION 16384 - -#if (MEMFD_SIZE_THRESHOLD > KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE) - #error Memfd size threshold higher than max kdbus message payload vector size -#endif - -/** Enables verbosing more information about kdbus message. - * Works only if DBUS_VERBOSE=1 is used. - */ -#define KDBUS_MSG_DECODE_DEBUG 0 - -#define MSG_ITEM_BUILD_VEC(data, datasize) \ - item->type = KDBUS_ITEM_PAYLOAD_VEC; \ - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof (struct kdbus_vec); \ - item->vec.address = (unsigned long) data; \ - item->vec.size = datasize; - -/** - * Opaque object representing a transport. - */ -typedef struct DBusTransportKdbus DBusTransportKdbus; - -/** - * Implementation details of DBusTransportKdbus. All members are private. - */ -struct DBusTransportKdbus -{ - DBusTransport base; /**< Parent instance */ - kdbus_t *kdbus; - DBusWatch *read_watch; /**< Watch for readability. */ - DBusWatch *write_watch; /**< Watch for writability. */ - - int max_bytes_read_per_iteration; /**< To avoid blocking too long. */ - int max_bytes_written_per_iteration; /**< To avoid blocking too long. */ - - char* my_DBus_unique_name; /**< unique name in DBus string format - :1.x , where x is kdbus id*/ - char* activator; /**< well known name for activator */ - Matchmaker *matchmaker; /**< for match rules management */ - dbus_uint32_t client_serial; /**< serial number for messages synthesized by library*/ -}; - -static kdbus_t * -get_kdbus (DBusTransport *transport) -{ - return ((DBusTransportKdbus*)transport)->kdbus; -} - -/** - * Creates unique name string frong unique id. - * - * @param id unique id - * @returns allocated string with unique name - * - * Caller has to free allocated string with free. - */ -static char * -create_unique_name_from_unique_id (unsigned long long id) -{ - char *str = NULL; - if (asprintf (&str, ":1.%llu", id) == -1) - str = NULL; - return str; -} - -/** - * Puts locally generated message into received messages queue - * @param message message that will be added - * @param connection connection to which message will be added - * @returns TRUE on success, FALSE on memory allocation error - */ -static dbus_bool_t -add_message_to_received (DBusMessage *message, - DBusConnection *connection) -{ - DBusList *message_link; - - message_link = _dbus_list_alloc_link (message); - if (message_link == NULL) - { - dbus_message_unref (message); - return FALSE; - } - - dbus_message_lock (message); - - _dbus_connection_queue_synthesized_message_link (connection, message_link); - return TRUE; -} - -static int -reply_with_error_preset_sender (const char *error_type, - const char *template, - const char *object, - DBusMessage *message, - DBusConnection *connection, - const char *sender) -{ - DBusMessage *errMessage; - char* error_msg = ""; - - if (template) - { - error_msg = alloca (strlen (template) + strlen (object) + 1); - sprintf (error_msg, template, object); - } - else if (object) - error_msg = (char*)object; - - errMessage = _dbus_generate_local_error_message ( dbus_message_get_serial (message), - (char*)error_type, - error_msg); - - if (errMessage == NULL) - return -1; - - if (sender) - dbus_message_set_sender (errMessage, sender); - - if (add_message_to_received (errMessage, connection)) - return 0; - - return -1; -} - -/** - * Generates local error message as a reply to message given as parameter - * and adds generated error message to received messages queue. - * @param error_type type of error, preferably DBUS_ERROR_(...) - * @param template Template of error description. It can has formatting - * characters to print object string into it. Can be NULL. - * @param object String to print into error description. Can be NULL. - * If object is not NULL while template is NULL, the object string - * will be the only error description. - * @param message Message for which the error reply is generated. - * @param connection The connection. - * @returns 0 on success, otherwise -1 - */ -static int -reply_with_error (const char *error_type, - const char *template, - const char *object, - DBusMessage *message, - DBusConnection *connection) -{ - return reply_with_error_preset_sender (error_type, template, - object, message, connection, NULL); -} - -/** - * Generates reply to the message given as a parameter with one item in the reply body - * and adds generated reply message to received messages queue. - * @param message The message we are replying to. - * @param data_type Type of data sent in the reply.Use DBUS_TYPE_(...) - * @param pData Address of data sent in the reply. - * @param connection The connection - * @returns 0 on success, otherwise -1 - */ -static int -reply_1_data (DBusMessage *message, - int data_type, - void *pData, - DBusConnection *connection) -{ - DBusMessageIter args; - DBusMessage *reply; - - reply = dbus_message_new_method_return (message); - if (reply == NULL) - return -1; - - if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS)) - goto oom_free; - - dbus_message_iter_init_append (reply, &args); - if (!dbus_message_iter_append_basic (&args, data_type, pData)) - goto oom_free; - - if (!add_message_to_received (reply, connection)) - goto oom_free; - - return 0; - -oom_free: - dbus_message_unref (reply); - - return -1; -} - -static int -reply_ack (DBusMessage *message, - DBusConnection *connection) -{ - DBusMessage *reply; - int ret = -1; - - reply = dbus_message_new_method_return (message); - if (reply != NULL) - { - if (add_message_to_received (reply, connection)) - ret = 0; - else - dbus_message_unref (reply); - } - return ret; -} - -static int -reply_fixed_array (DBusMessage *message, - int element_type, - const void *data, - int n_elements, - DBusConnection *connection) -{ - DBusMessageIter args, array_iter; - DBusMessage *reply; - - reply = dbus_message_new_method_return (message); - if (reply == NULL) - return -1; - - if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS)) - goto oom_free; - - dbus_message_iter_init_append (reply, &args); - - if (!dbus_message_iter_open_container (&args, - DBUS_TYPE_ARRAY, - DBUS_TYPE_BYTE_AS_STRING, - &array_iter)) - goto oom_free; - - if (!dbus_message_iter_append_fixed_array (&array_iter, element_type, &data, n_elements)) - goto oom_array_iter; - - if (!dbus_message_iter_close_container (&args, &array_iter)) - goto oom_free; - - if (!add_message_to_received (reply, connection)) - goto oom_free; - - return 0; - -oom_array_iter: - dbus_message_iter_abandon_container (&args, &array_iter); - -oom_free: - dbus_message_unref (reply); - return -1; -} - -/** - * Retrieves file descriptor to memory pool from kdbus module and stores - * it in kdbus_transport->memfd. It is then used to send large message. - * Triggered when message payload is over MEMFD_SIZE_THRESHOLD - * @param kdbus_transport DBusTransportKdbus transport structure - * @returns 0 on success, otherwise -1 - */ -static int -kdbus_acquire_memfd (DBusTransportKdbus *kdbus_transport, - uint64_t fsize) -{ - int fd; - - /* FIXME add HAVE_MEMFD_CREATE */ - if ((fd = syscall (__NR_memfd_create, "kdbus", MFD_ALLOW_SEALING | MFD_CLOEXEC )) < 0) - { - _dbus_verbose ("memfd_create failed (%d): %m\n", fd); - } - - _dbus_verbose ("%s: memfd=%d\n", __FUNCTION__, fd); - return fd; -} - -/* - * Macros for SipHash algorithm - */ -#define ROTL(x,b) (uint64_t)( ((x) << (b)) | ( (x) >> (64 - (b))) ) - -#define U32TO8_LE(p, v) \ - (p)[0] = (unsigned char)((v) ); (p)[1] = (unsigned char)((v) >> 8); \ - (p)[2] = (unsigned char)((v) >> 16); (p)[3] = (unsigned char)((v) >> 24); - -#define U64TO8_LE(p, v) \ - U32TO8_LE((p), (uint32_t)((v) )); \ - U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); - -#define U8TO64_LE(p) \ - (((uint64_t)((p)[0]) ) | \ - ((uint64_t)((p)[1]) << 8) | \ - ((uint64_t)((p)[2]) << 16) | \ - ((uint64_t)((p)[3]) << 24) | \ - ((uint64_t)((p)[4]) << 32) | \ - ((uint64_t)((p)[5]) << 40) | \ - ((uint64_t)((p)[6]) << 48) | \ - ((uint64_t)((p)[7]) << 56)) - -#define SIPROUND \ - do { \ - v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \ - v2 += v3; v3=ROTL(v3,16); v3 ^= v2; \ - v0 += v3; v3=ROTL(v3,21); v3 ^= v0; \ - v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \ - } while (0) - - -/* - * Hash keys for bloom filters - */ -const unsigned char hash_keys[8][16] = -{ - {0xb9,0x66,0x0b,0xf0,0x46,0x70,0x47,0xc1,0x88,0x75,0xc4,0x9c,0x54,0xb9,0xbd,0x15}, - {0xaa,0xa1,0x54,0xa2,0xe0,0x71,0x4b,0x39,0xbf,0xe1,0xdd,0x2e,0x9f,0xc5,0x4a,0x3b}, - {0x63,0xfd,0xae,0xbe,0xcd,0x82,0x48,0x12,0xa1,0x6e,0x41,0x26,0xcb,0xfa,0xa0,0xc8}, - {0x23,0xbe,0x45,0x29,0x32,0xd2,0x46,0x2d,0x82,0x03,0x52,0x28,0xfe,0x37,0x17,0xf5}, - {0x56,0x3b,0xbf,0xee,0x5a,0x4f,0x43,0x39,0xaf,0xaa,0x94,0x08,0xdf,0xf0,0xfc,0x10}, - {0x31,0x80,0xc8,0x73,0xc7,0xea,0x46,0xd3,0xaa,0x25,0x75,0x0f,0x9e,0x4c,0x09,0x29}, - {0x7d,0xf7,0x18,0x4b,0x7b,0xa4,0x44,0xd5,0x85,0x3c,0x06,0xe0,0x65,0x53,0x96,0x6d}, - {0xf2,0x77,0xe9,0x6f,0x93,0xb5,0x4e,0x71,0x9a,0x0c,0x34,0x88,0x39,0x25,0xbf,0x35} -}; - -/* - * SipHash algorithm - */ -static void -_g_siphash24 (unsigned char out[8], - const void *_in, - size_t inlen, - const unsigned char k[16]) -{ - uint64_t v0 = 0x736f6d6570736575ULL; - uint64_t v1 = 0x646f72616e646f6dULL; - uint64_t v2 = 0x6c7967656e657261ULL; - uint64_t v3 = 0x7465646279746573ULL; - uint64_t b; - uint64_t k0 = U8TO64_LE (k); - uint64_t k1 = U8TO64_LE (k + 8); - uint64_t m; - const unsigned char *in = _in; - const unsigned char *end = in + inlen - (inlen % sizeof (uint64_t)); - const int left = inlen & 7; - b = ((uint64_t) inlen) << 56; - v3 ^= k1; - v2 ^= k0; - v1 ^= k1; - v0 ^= k0; - - for (; in != end; in += 8) - { - m = U8TO64_LE (in); - v3 ^= m; - SIPROUND; - SIPROUND; - v0 ^= m; - } - - switch (left) - { - case 7: b |= ((uint64_t) in[6]) << 48; - case 6: b |= ((uint64_t) in[5]) << 40; - case 5: b |= ((uint64_t) in[4]) << 32; - case 4: b |= ((uint64_t) in[3]) << 24; - case 3: b |= ((uint64_t) in[2]) << 16; - case 2: b |= ((uint64_t) in[1]) << 8; - case 1: b |= ((uint64_t) in[0]); break; - case 0: break; - } - - v3 ^= b; - SIPROUND; - SIPROUND; - v0 ^= b; - - v2 ^= 0xff; - SIPROUND; - SIPROUND; - SIPROUND; - SIPROUND; - b = v0 ^ v1 ^ v2 ^ v3; - U64TO8_LE (out, b); -} - -static void -bloom_add_data (uint64_t bloom_data [], - struct kdbus_bloom_parameter *bloom_params, - const void *data, - size_t n) -{ - unsigned char hash[8]; - uint64_t bit_num; - unsigned int bytes_num = 0; - unsigned int cnt_1, cnt_2; - unsigned int hash_index = 0; - - unsigned int c = 0; - uint64_t p = 0; - - bit_num = bloom_params->size * 8; - - if (bit_num > 1) - bytes_num = ((__builtin_clzll (bit_num) ^ 63U) + 7) / 8; - - for (cnt_1 = 0; cnt_1 < bloom_params->n_hash; cnt_1++) - { - for (cnt_2 = 0, hash_index = 0; cnt_2 < bytes_num; cnt_2++) - { - if (c <= 0) - { - _g_siphash24(hash, data, n, hash_keys[hash_index++]); - c += 8; - } - - p = (p << 8ULL) | (uint64_t) hash[8 - c]; - c--; - } - - p &= bit_num - 1; - bloom_data[p >> 6] |= 1ULL << (p & 63); - } -} - -static void -bloom_add_pair (uint64_t bloom_data [], - struct kdbus_bloom_parameter *bloom_params, - const char *parameter, - const char *value) -{ - char buf[1024]; - size_t size; - - size = strlen (parameter) + strlen (value) + 1; - if (size > 1024) - return; - - strcpy (stpcpy (stpcpy (buf, parameter), ":"), value); - bloom_add_data (bloom_data, bloom_params, buf, size); -} - -static void -bloom_add_prefixes (uint64_t bloom_data [], - struct kdbus_bloom_parameter *bloom_params, - const char *parameter, - const char *value, - char separator) -{ - char buf[1024]; - size_t size; - - size = strlen (parameter) + strlen (value) + 1; - if (size > 1024) - return; - - strcpy (stpcpy (stpcpy (buf, parameter), ":"), value); - - for (;;) - { - char *last_sep; - last_sep = strrchr (buf, separator); - if (!last_sep || last_sep == buf) - break; - - *last_sep = 0; - bloom_add_data (bloom_data, bloom_params, buf, last_sep-buf); - } -} - -static int -bus_message_setup_bloom (DBusMessage *msg, - struct kdbus_bloom_filter *bloom, - struct kdbus_bloom_parameter *bloom_params) -{ - void *data; - unsigned i; - const char *str; - DBusMessageIter args; - - _dbus_assert (msg); - _dbus_assert (bloom); - - data = bloom->data; - memset (data, 0, bloom_params->size); - bloom->generation = 0; - - bloom_add_pair (data, bloom_params, "message-type", - dbus_message_type_to_string (dbus_message_get_type (msg))); //Fixme in systemd type invalid returns NULL but in dbus it returns "invalid" - - str = dbus_message_get_interface (msg); - if (str) - bloom_add_pair (data, bloom_params, "interface", str); - str = dbus_message_get_member (msg); - if (str) - bloom_add_pair (data, bloom_params, "member", str); - str = dbus_message_get_path (msg); - if (str) - { - bloom_add_pair (data, bloom_params, "path", str); - bloom_add_pair (data, bloom_params, "path-slash-prefix", str); - bloom_add_prefixes (data, bloom_params, "path-slash-prefix", str, '/'); - } - - if (!dbus_message_iter_init (msg, &args)) - return 0; - - for (i = 0; i < 64; i++) - { - char type; - char buf[sizeof ("arg")-1 + 2 + sizeof ("-slash-prefix")]; - char *e; - - type = dbus_message_iter_get_arg_type (&args); - if (type != DBUS_TYPE_STRING && - type != DBUS_TYPE_OBJECT_PATH && - type != DBUS_TYPE_SIGNATURE) - break; - - dbus_message_iter_get_basic (&args, &str); - - e = stpcpy (buf, "arg"); - if (i < 10) - *(e++) = '0' + (char) i; - else { - *(e++) = '0' + (char) (i / 10); - *(e++) = '0' + (char) (i % 10); - } - - *e = 0; - bloom_add_pair (data, bloom_params, buf, str); - - strcpy (e, "-dot-prefix"); - bloom_add_prefixes (data, bloom_params, buf, str, '.'); - strcpy (e, "-slash-prefix"); - bloom_add_prefixes (data, bloom_params, buf, str, '/'); - - if (!dbus_message_iter_next (&args)) - break; - } - - return 0; -} - -/** - * Checks if a string is a unique name or well known name. - * - * @param name - the string to check - * @param id - return pointer for unique id - * @returns 1 if the name is unique id, returns 0 if well-known name and -1 on error - */ -static int -parse_name (const char *name, - uint64_t *id) -{ - char *endptr; - /* if name is unique name it must be converted to unique id */ - if (strncmp (name, ":1.", 3) == 0) - { - errno = 0; - *id = strtoull (&name[3], &endptr, 10); - if (*id == 0 || *endptr != '\0' || errno == ERANGE) - return -1; - else - return 1; - } - else - return 0; //well known name -} - -static int -prepare_mfd (int memfd, - const char *header, - uint64_t header_size, - const char *body, - uint64_t body_size) -{ - const char *data[] = { header, body }; - uint64_t count[] = { header_size, body_size }; - int64_t wr; - int p; - - _dbus_verbose ("sending data via memfd\n"); - for (p = 0; p < sizeof (data) / sizeof (data[0]); ++p) - { - while (count[p]) - { - wr = write (memfd, data[p], count[p]); - if (wr < 0) - { - _dbus_verbose ("writing to memfd failed: (%d) %m\n", errno); - return -1; - } - count[p] -= wr; - data[p] += wr; - } - } - - // seal data - kdbus module needs it - if (fcntl (memfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL) < 0) - { - _dbus_verbose ("memfd sealing failed: %d (%m)\n", errno); - return -1; - } - return 0; -} - -static int -send_message (DBusTransportKdbus *transport, - struct kdbus_msg *kdbus_msg, - dbus_bool_t sync, - const char *destination, - dbus_bool_t is_auto_start, - struct kdbus_msg **kdbus_msg_reply, - DBusError *error) -{ - int ret; - dbus_uint64_t flags = 0; - - if (sync) - flags |= KDBUS_SEND_SYNC_REPLY; - - ret = _kdbus_send (transport->kdbus, - flags, - kdbus_msg, - kdbus_msg_reply); - if (ret != 0) - { - _dbus_verbose ("kdbus error sending message: err %d (%s)\n", ret, _dbus_strerror (ret) ); - - switch (ret) - { - case ENXIO: /* no such id on the bus */ - case ESRCH: - dbus_set_error (error, - DBUS_ERROR_NAME_HAS_NO_OWNER, - "Name \"%s\" does not exist", - destination); - break; - - case EADDRNOTAVAIL: - case ECONNRESET: - /* when well known name is not available on the bus */ - if (is_auto_start) - dbus_set_error (error, - DBUS_ERROR_SERVICE_UNKNOWN, - "The name %s was not provided by any .service files", - destination); - else - dbus_set_error (error, - DBUS_ERROR_NAME_HAS_NO_OWNER, - "Name \"%s\" does not exist", - destination); - break; - - case EMLINK: - dbus_set_error (error, - DBUS_ERROR_LIMITS_EXCEEDED, - NULL, - "The maximum number of pending replies per connection has been reached"); - break; - - case ENOBUFS: - case EXFULL: - dbus_set_error (error, - DBUS_ERROR_LIMITS_EXCEEDED, - "No space in receiver's buffer", - destination); - break; - - default: - break; - } - - ret = -1; - } - return ret; -} - -static void -kdbus_close_message (DBusTransportKdbus *transport, struct kdbus_msg *msg) -{ - struct kdbus_item *item; - - KDBUS_ITEM_FOREACH (item, msg, items) - { - if (item->type == KDBUS_ITEM_PAYLOAD_MEMFD) - close (item->memfd.fd); - } - - _kdbus_free_mem (transport->kdbus, msg); -} - -static void -debug_c_str (const char *msg, const char *str, int len) -{ - int i; - fprintf (stderr, "%s\n", msg); - for (i = 0; i < len; i++) - { - fprintf (stderr, "%02x ", (unsigned char)str[i]); - if (i%16==15) fprintf (stderr, "\n"); - } - fprintf (stderr, "\n"); -} - -static void -debug_str (const char *msg, const DBusString *str) -{ - debug_c_str (msg, _dbus_string_get_const_data (str), _dbus_string_get_length (str)); -} - -static int -kdbus_write_msg_internal (DBusTransportKdbus *transport, - DBusMessage *message, - const char *destination, - dbus_bool_t check_sync_reply) -{ - struct kdbus_msg *msg = NULL; - struct kdbus_msg *msg_reply = NULL; - struct kdbus_item *item; - uint64_t dst_id = KDBUS_DST_ID_BROADCAST; - const DBusString *header; - const DBusString *body; - uint64_t ret_size = -1; - uint64_t body_size = 0; - uint64_t header_size = 0; - int memfd = -1; - const int *unix_fds; - unsigned fds_count; - DBusError error; - - dbus_uint64_t items_size; - dbus_uint64_t flags = 0; - dbus_uint64_t timeout_ns_or_cookie_reply = 0; - - dbus_error_init (&error); - - // determine destination and destination id - if (destination) - { - dst_id = KDBUS_DST_ID_NAME; - switch (parse_name (destination, &dst_id)) - { - case 0: /* well-known name - nothing to do */ - break; - case 1: /* unique name */ - destination = NULL; - break; - default: /* error */ - _dbus_verbose ("error: unique name is not valid: %s\n", destination); - return -1; - } - } - - _dbus_message_get_network_data (message, &header, &body); - header_size = _dbus_string_get_length (header); - body_size = _dbus_string_get_length (body); - ret_size = header_size + body_size; - - /* check whether we can and should use memfd */ - if ((dst_id != KDBUS_DST_ID_BROADCAST) && (ret_size > MEMFD_SIZE_THRESHOLD)) - memfd = kdbus_acquire_memfd (transport, ret_size); - - _dbus_message_get_unix_fds (message, &unix_fds, &fds_count); - - items_size = _kdbus_compute_msg_items_size (transport->kdbus, - destination, - dst_id, - body_size, - memfd >= 0, - fds_count); - - if (!dbus_message_get_auto_start (message)) - flags |= KDBUS_MSG_NO_AUTO_START; - - if (KDBUS_DST_ID_BROADCAST == dst_id) /* signals */ - flags |= KDBUS_MSG_SIGNAL; - else - { - if (dbus_message_get_no_reply (message)) /* method replies and errors */ - timeout_ns_or_cookie_reply = dbus_message_get_reply_serial (message); - else /* method calls */ - { - long tv_sec, tv_usec; - - _dbus_get_monotonic_time (&tv_sec, &tv_usec); - /* ms us ns */ - timeout_ns_or_cookie_reply = (dbus_uint64_t)tv_sec * 1000ULL * 1000ULL * 1000ULL - + tv_usec * 1000ULL - + KDBUS_DEFAULT_TIMEOUT_NS; - - flags |= KDBUS_MSG_EXPECT_REPLY; - } - } - - msg = _kdbus_new_msg (transport->kdbus, - items_size, - flags, - 0, - dst_id, - 0, - KDBUS_PAYLOAD_DBUS, - dbus_message_get_serial (message), - timeout_ns_or_cookie_reply); - if (NULL == msg) - return -1; - - /* build message contents */ - item = msg->items; - - if (memfd >= 0) - { - if (prepare_mfd (memfd, - _dbus_string_get_const_data (header), header_size, - _dbus_string_get_const_data (body), body_size) == -1) - { - ret_size = -1; - goto out; - } - - item = _kdbus_item_add_payload_memfd (item, - 0, - ret_size, - memfd); - } - else - { - const char* header_data = _dbus_string_get_const_data (header); - - _dbus_verbose ("sending data by vec\n"); - item = _kdbus_item_add_payload_vec (item, - header_size, - (dbus_uint64_t)header_data); - if (body_size > 0) - { - const char* body_data = _dbus_string_get_const_data (body); - - if (-1 != debug) - { - debug_str ("Header to send:", header); - debug_str ("Body to send:", body); - } - - while (body_size > 0) - { - dbus_uint64_t part_size = body_size; - - if (part_size > KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE) - part_size = KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE; - - _dbus_verbose ("attaching body part\n"); - item = _kdbus_item_add_payload_vec (item, - part_size, - (dbus_uint64_t)body_data); - body_data += part_size; - body_size -= part_size; - } - } - } - - if (fds_count) - item = _kdbus_item_add_fds (item, unix_fds, fds_count); - - if (NULL != destination) - item = _kdbus_item_add_string (item, - KDBUS_ITEM_DST_NAME, - destination, - strlen (destination) + 1); - else if (dst_id == KDBUS_DST_ID_BROADCAST) - { - struct kdbus_bloom_parameter *bloom = _kdbus_bloom (transport->kdbus); - struct kdbus_bloom_filter *filter = NULL; - item = _kdbus_item_add_bloom_filter (item, - bloom->size, - &filter); - bus_message_setup_bloom (message, filter, bloom); - } - - if (send_message (transport, - msg, - check_sync_reply, - dbus_message_get_destination (message), - dbus_message_get_auto_start (message), - &msg_reply, - &error) != 0) - { - int ret = -1; - if (dbus_error_is_set (&error)) - ret = reply_with_error (error.name, - NULL, - error.message, - message, - transport->base.connection); - if (-1 == ret) - ret_size = -1; - } - - if (check_sync_reply) - kdbus_close_message (transport, msg_reply); - - out: - if (msg) - _kdbus_free_msg (msg); - if (memfd >= 0) - close (memfd); - - return ret_size; -} - -/** - * Sends DBus message using kdbus. - * Handles broadcasts and unicast messages, and passing of Unix fds. - * Also can locally generate error replies on some error returned by kernel. - * - * TODO refactor to be more compact - maybe we can send header always as a payload vector - * and only message body as memfd if needed. - * - * @param transport Transport. - * @param message DBus message to be sent - * @param destination Destination of the message. - * @returns bytes sent or -1 if sending failed - */ -static int -kdbus_write_msg (DBusTransportKdbus *transport, - DBusMessage *message, - const char *destination) -{ - return kdbus_write_msg_internal (transport, message, destination, FALSE); -} - -static dbus_uint64_t -get_pool_size (void) -{ - dbus_uint64_t receive_pool_size = RECEIVE_POOL_SIZE_DEFAULT_SIZE; - const char *env_pool; - - env_pool = _dbus_getenv (RECEIVE_POOL_SIZE_ENV_VAR_NAME); - if (env_pool) - { - dbus_uint64_t size = 0; - unsigned int multiply = 1; - long int page_size; - - page_size = sysconf (_SC_PAGESIZE); - if (page_size == -1) - { - goto finish; - } - - errno = 0; - size = strtoul (env_pool, (char**)&env_pool, 10); - if ((errno == EINVAL) || size == 0) - { - size = 0; - goto finish; - } - - if (*env_pool == 'k') - { - multiply = 1024; - env_pool++; - } - else if (*env_pool == 'M') - { - multiply = 1024 * 1024; - env_pool++; - } - - if (*env_pool != '\0') - { - size = 0; - goto finish; - } - - receive_pool_size = size * multiply; - - if ((receive_pool_size > RECEIVE_POOL_SIZE_MAX_MBYTES * 1024 * 1024) || - (receive_pool_size < RECEIVE_POOL_SIZE_MIN_KBYTES * 1024) || - ((receive_pool_size & (page_size - 1)) != 0)) //pool size must be aligned to page size - size = 0; - - finish: - if (size == 0) - { - _dbus_warn ("%s value is invalid, default value %luB will be used.\n", RECEIVE_POOL_SIZE_ENV_VAR_NAME, - RECEIVE_POOL_SIZE_DEFAULT_SIZE); - _dbus_warn ("Correct value must be between %ukB and %uMB and must be aligned to page size: %ldB.\n", - RECEIVE_POOL_SIZE_MIN_KBYTES, RECEIVE_POOL_SIZE_MAX_MBYTES, page_size); - - receive_pool_size = RECEIVE_POOL_SIZE_DEFAULT_SIZE; - } - } - - _dbus_verbose ("Receive pool size set to %llu.\n", (unsigned long long)receive_pool_size); - return receive_pool_size; -} - -/** - * Performs kdbus hello - registration on the kdbus bus - * needed to send and receive messages on the bus, - * and configures transport. - * As a result unique id on he bus is obtained. - * - * @see KDBUS_HELLO_* flags in kdbus.h - * - * @param transport transport structure - * @param registration_flags aditional flags to modify registration process - * @returns #TRUE on success - */ -static dbus_bool_t -bus_register_kdbus (DBusTransportKdbus *transport, - dbus_uint32_t registration_flags, - DBusError *error) -{ - int ret; - dbus_uint64_t flags; - - flags = KDBUS_HELLO_ACCEPT_FD; - if (registration_flags & REGISTER_FLAG_MONITOR) - flags |= KDBUS_HELLO_MONITOR; - - ret = _kdbus_hello (transport->kdbus, - flags, - _KDBUS_ATTACH_ANY, - 0, - get_pool_size (), - transport->activator, - "libdbus-kdbus"); - if (ret != 0) - { - dbus_set_error (error, DBUS_ERROR_FAILED, "Hello failed: %d", -ret); - return FALSE; - } - - transport->my_DBus_unique_name = create_unique_name_from_unique_id (_kdbus_id (transport->kdbus)); - if (NULL == transport->my_DBus_unique_name) - { - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, "Hello post failed: %d", -ret); - return FALSE; - } - - _dbus_verbose ("-- Our peer ID is: %llu\n", (unsigned long long)_kdbus_id (transport->kdbus)); - - return TRUE; -} - -static dbus_bool_t -request_DBus_name (DBusTransport *transport, - DBusMessage *msg, - int *result, - DBusError *error) -{ - DBusString service_name_real; - const DBusString *service_name = &service_name_real; - char* name; - dbus_uint32_t flags; - - if (!dbus_message_get_args (msg, error, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_UINT32, &flags, - DBUS_TYPE_INVALID)) - return FALSE; - - _dbus_string_init_const (&service_name_real, name); - - if (!_dbus_validate_bus_name (service_name, 0, - _dbus_string_get_length (service_name))) - { - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Requested bus name \"%s\" is not valid", name); - - _dbus_verbose ("Attempt to acquire invalid service name\n"); - - return FALSE; - } - - if (_dbus_string_get_byte (service_name, 0) == ':') - { - /* Not allowed; only base services can start with ':' */ - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Cannot acquire a service starting with ':' such as \"%s\"", name); - - _dbus_verbose ("Attempt to acquire invalid base service name \"%s\"", name); - - return FALSE; - } - - if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS)) - { - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Connection is not allowed to own the service \"%s\"because " - "it is reserved for D-Bus' use only", DBUS_SERVICE_DBUS); - return FALSE; - } - - *result = request_kdbus_name (transport, name, flags); - if (*result == -EPERM) - { - dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, - "Kdbus don't allow %s to own the service \"%s\"", - ((DBusTransportKdbus*)transport)->my_DBus_unique_name, _dbus_string_get_const_data (service_name)); - return FALSE; - } - else if (*result < 0) - { - dbus_set_error (error, DBUS_ERROR_FAILED , "Name \"%s\" could not be acquired, %d, %m", name, errno); - return FALSE; - } - - return TRUE; -} - -static dbus_bool_t -release_DBus_name (DBusTransport *transport, - DBusMessage *msg, - int *result, - DBusError *error) -{ - const char *name; - DBusString service_name; - - if (!dbus_message_get_args (msg, error, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID)) - return FALSE; - - _dbus_string_init_const (&service_name, name); - - if (!_dbus_validate_bus_name (&service_name, 0, - _dbus_string_get_length (&service_name))) - { - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Given bus name \"%s\" is not valid", - _dbus_string_get_const_data (&service_name)); - - _dbus_verbose ("Attempt to release invalid service name\n"); - return FALSE; - } - - if (_dbus_string_get_byte (&service_name, 0) == ':') - { - /* Not allowed; the base service name cannot be created or released */ - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Cannot release a service starting with ':' such as \"%s\"", - _dbus_string_get_const_data (&service_name)); - - _dbus_verbose ("Attempt to release invalid base service name \"%s\"", - _dbus_string_get_const_data (&service_name)); - return FALSE; - } - - if (_dbus_string_equal_c_str (&service_name, DBUS_SERVICE_DBUS)) - { - /* Not allowed; the base service name cannot be created or released */ - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Cannot release the %s service because it is owned by the bus", - DBUS_SERVICE_DBUS); - - _dbus_verbose ("Attempt to release service name \"%s\"", - DBUS_SERVICE_DBUS); - return FALSE; - } - - *result = release_kdbus_name (transport, name); - if (*result < 0) - { - dbus_set_error (error, DBUS_ERROR_FAILED , "Name \"%s\" could not be released, %d, %m", name, errno); - return FALSE; - } - - return TRUE; -} - -static int -strcmp_existing (const char *str1, const char *str2) -{ - if (NULL == str1 || NULL == str2) - return 0; - return strcmp (str1, str2); -} - -static dbus_bool_t -kernel_match_needed (MatchRule *rule) -{ - int message_type; - - /* Allow only NameOwnerChanged member */ - if (strcmp_existing (_match_rule_get_member (rule), "NameOwnerChanged") != 0) - return FALSE; - - /* Allow only signals */ - message_type = _match_rule_get_message_type (rule); - if (message_type != DBUS_MESSAGE_TYPE_INVALID && message_type != DBUS_MESSAGE_TYPE_SIGNAL) - return FALSE; - - /* Check if from DBus */ - if (strcmp_existing (_match_rule_get_sender (rule), DBUS_SERVICE_DBUS) != 0) - return FALSE; - - if (strcmp_existing (_match_rule_get_interface (rule), DBUS_INTERFACE_DBUS) != 0) - return FALSE; - - if (strcmp_existing (_match_rule_get_path (rule), DBUS_PATH_DBUS) != 0) - return FALSE; - - return TRUE; -} - -static dbus_bool_t -is_bloom_needed (MatchRule *rule) -{ - int rule_int; - int i; - - if (_match_rule_get_message_type (rule) != DBUS_TYPE_INVALID - || _match_rule_get_interface (rule) != NULL - || _match_rule_get_member (rule) != NULL - || _match_rule_get_path (rule) != NULL - || _match_rule_get_path_namespace (rule) != NULL) - return TRUE; - - rule_int = _match_rule_get_args_len (rule); - for (i = 0; i < rule_int; i++) - { - if (_match_rule_get_args (rule, i) != NULL) - return TRUE; - } - - return FALSE; -} - -static dbus_uint64_t * -get_bloom (kdbus_t *kdbus, MatchRule *rule) -{ - dbus_uint64_t *bloom; - dbus_uint64_t bloom_size; - int rule_int; - const char *rule_string; - int i; - char argument_buf[sizeof ("arg")-1 + 2 + sizeof ("-slash-prefix") +1]; - - bloom_size = _kdbus_bloom (kdbus)->size; - bloom = dbus_malloc (bloom_size); - if (bloom == NULL) - return NULL; - - memset (bloom, 0, bloom_size); - - rule_int = _match_rule_get_message_type (rule); - if (rule_int != DBUS_MESSAGE_TYPE_INVALID) - { - bloom_add_pair (bloom, _kdbus_bloom (kdbus), "message-type", dbus_message_type_to_string (rule_int)); - _dbus_verbose ("Adding type %s \n", dbus_message_type_to_string (rule_int)); - } - - rule_string = _match_rule_get_interface (rule); - if (rule_string != NULL) - { - bloom_add_pair (bloom, _kdbus_bloom (kdbus), "interface", rule_string); - _dbus_verbose ("Adding interface %s \n", rule_string); - } - - rule_string = _match_rule_get_member (rule); - if (rule_string != NULL) - { - bloom_add_pair (bloom, _kdbus_bloom (kdbus), "member", rule_string); - _dbus_verbose ("Adding member %s \n", rule_string); - } - - rule_string = _match_rule_get_path (rule); - if (rule_string != NULL) - { - bloom_add_pair (bloom, _kdbus_bloom (kdbus), "path", rule_string); - _dbus_verbose ("Adding path %s \n", rule_string); - } - - rule_string = _match_rule_get_path_namespace (rule); - if (rule_string != NULL) - { - bloom_add_pair (bloom, _kdbus_bloom (kdbus), "path-slash-prefix", rule_string); - _dbus_verbose ("Adding path-slash-prefix %s \n", rule_string); - } - - rule_int = _match_rule_get_args_len (rule); - for (i = 0; i < rule_int; i++) - { - rule_string = _match_rule_get_args (rule, i); - if (rule_string != NULL) - { - unsigned int rule_arg_lens = _match_rule_get_arg_lens (rule, i); - if (rule_arg_lens & MATCH_ARG_IS_PATH) - { - sprintf (argument_buf, "arg%d-slash-prefix", i); - bloom_add_prefixes (bloom, _kdbus_bloom (kdbus), argument_buf, rule_string, '/'); - } - else if (rule_arg_lens & MATCH_ARG_NAMESPACE) - { - sprintf (argument_buf, "arg%d-dot-prefix", i); - bloom_add_prefixes (bloom, _kdbus_bloom (kdbus), argument_buf, rule_string, '.'); - } - else - { - sprintf (argument_buf, "arg%d", i); - bloom_add_pair (bloom, _kdbus_bloom (kdbus), argument_buf, rule_string); - } - } - } - - return bloom; -} - -/** - * Adds a match rule to match broadcast messages going through the message bus. - * Do no affect messages addressed directly. - * - * copied a lot from systemd bus_add_match_internal_kernel () - * - * TODO add error reporting - * - * @param transport transport - * @param match rule - */ -static dbus_bool_t -add_match_kdbus (DBusTransportKdbus *transport, - MatchRule *rule) -{ - struct kdbus_cmd_match *cmd; - struct kdbus_item *item; - int sender = -1; - int sender_size = 0; - __u64 bloom_size; - __u64 rule_cookie; - uint64_t src_id = KDBUS_MATCH_ID_ANY; - uint64_t items_size; - uint64_t *bloom; - dbus_bool_t need_bloom = FALSE; - - const char *rule_sender; - int ret; - - rule_cookie = match_rule_get_cookie (rule); - -/* - * First check if it is org.freedesktop.DBus's NameOwnerChanged or any - * org.freedesktop.DBus combination that includes this, - * because it must be converted to special kdbus rule (kdbus has separate rules - * for kdbus (kernel) generated broadcasts). - */ - if (kernel_match_needed (rule)) - { - ret = _kdbus_add_match_name_change (transport->kdbus, - 0, - rule_cookie, - KDBUS_MATCH_ID_ANY, - 0, - KDBUS_MATCH_ID_ANY, - 0); - if (0 != ret) - { - _dbus_verbose ("Failed adding match rule for name removal for daemon, error: %d, %s\n", - ret, _dbus_strerror (ret)); - return FALSE; - } - - ret = _kdbus_add_match_id_change (transport->kdbus, - 0, - rule_cookie, - KDBUS_MATCH_ID_ANY, - 0); - if (0 != ret) - { - _dbus_verbose ("Failed adding match rule for adding id for daemon, error: %d, %s\n", - ret, _dbus_strerror (ret)); - return FALSE; - } - - _dbus_verbose ("Added match rule for kernel correctly.\n"); - -/* - * In case all of sender, interface and path are NULL, the rule - * says simply about NameHasOwner signal from any object, any interface, any sender. - * So, we need to consider that. - * Otherwise, our job is finished here. - */ - if (_match_rule_get_sender (rule) != NULL - || _match_rule_get_interface (rule) != NULL - || _match_rule_get_path (rule) != NULL) - return TRUE; - } - -/* - * standard rule - registered in general way, for non-kernel broadcasts - * kdbus doesn't use it to check kdbus (kernel) generated broadcasts - */ - - items_size = 0; - - need_bloom = is_bloom_needed (rule); - if (need_bloom) - { - bloom_size = _kdbus_bloom (transport->kdbus)->size; - items_size += KDBUS_ITEM_SIZE (bloom_size); - bloom = get_bloom (transport->kdbus, rule); - if (NULL == bloom) - return FALSE; - } - - rule_sender = _match_rule_get_sender (rule); - if (rule_sender != NULL) - { - sender = parse_name (rule_sender, &src_id); - if (sender < 0) - return FALSE; - - if (sender > 0) /* unique_id */ - items_size += KDBUS_ITEM_SIZE (sizeof (uint64_t)); - else /* well-known name */ - { - sender_size = strlen (rule_sender) + 1; - items_size += KDBUS_ITEM_SIZE (sender_size); - } - } - - cmd = _kdbus_new_cmd_match (transport->kdbus, - items_size, - 0, - rule_cookie); - if (NULL == cmd) - ret = ENOMEM; - else - { - item = cmd->items; - if (0 == sender) /* well-known name */ - { - item = _kdbus_item_add_string (item, - KDBUS_ITEM_NAME, - rule_sender, - sender_size); - _dbus_verbose ("Adding sender %s \n", rule_sender); - } - else if (KDBUS_MATCH_ID_ANY != src_id) /* unique id */ - { - item = _kdbus_item_add_id (item, src_id); - _dbus_verbose ("Adding src_id %llu \n", (unsigned long long)src_id); - } - - if (need_bloom) - { - item = _kdbus_item_add_bloom_mask (item, bloom, bloom_size); - dbus_free (bloom); - } - - ret = _kdbus_add_match (transport->kdbus, cmd); - - _kdbus_free_cmd_match (cmd); - } - - if (0 != ret) - { - _dbus_verbose ("Failed adding match bus rule cookie %llu,\nerror: %d, %s\n", - rule_cookie, ret, _dbus_strerror (ret)); - return FALSE; - } - - _dbus_verbose ("Added match bus rule %llu\n", rule_cookie); - return TRUE; -} - -static int -capture_org_freedesktop_DBus_Hello (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - DBusMessageIter args; - dbus_uint32_t registration_flags = 0; - - dbus_message_iter_init (message, &args); - if (dbus_message_iter_get_arg_type (&args) == DBUS_TYPE_UINT32) - dbus_message_iter_get_basic (&args, ®istration_flags); - - if (!bus_register_kdbus (transport, registration_flags, error)) - goto out; - - if (!reply_1_data (message, DBUS_TYPE_STRING, &transport->my_DBus_unique_name, transport->base.connection)) - return 0; /* on success we can not free name */ - -out: - free (transport->my_DBus_unique_name); - return -1; -} - -static int -capture_org_freedesktop_DBus_RequestName (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - int result; - - if (!request_DBus_name (&transport->base, message, &result, error)) - return -1; - - return reply_1_data (message, DBUS_TYPE_UINT32, &result, - transport->base.connection); -} - -static int -capture_org_freedesktop_DBus_ReleaseName (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - int result; - - if (!release_DBus_name (&transport->base, message, &result, error)) - return -1; - - return reply_1_data (message, DBUS_TYPE_UINT32, &result, - transport->base.connection); -} - -static int -capture_org_freedesktop_DBus_AddMatch (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - const char *arg; - DBusString arg_str; - MatchRule *rule = NULL; - DBusConnection *connection = transport->base.connection; - - if (!dbus_message_get_args (message, error, - DBUS_TYPE_STRING, &arg, - DBUS_TYPE_INVALID)) - goto failed; - - _dbus_string_init_const (&arg_str, arg); - - rule = match_rule_parse (connection, &arg_str, error); - if (rule == NULL) - goto failed; - - if (!matchmaker_add_rule (transport->matchmaker, rule)) - { - dbus_set_error_const (error, DBUS_ERROR_NO_MEMORY, "No memory to store match rule"); - goto failed; - } - - if (!add_match_kdbus (transport, rule)) - { - dbus_set_error (error, _dbus_error_from_errno (errno), "Could not add match rule, %s", - _dbus_strerror_from_errno ()); - goto failed; - } - - match_rule_unref (rule); - return reply_ack (message, connection); - -failed: - if (rule) - match_rule_unref (rule); - _dbus_verbose ("Error during AddMatch in lib: %s, %s\n", error->name, error->message); - return -1; -} - -static int -capture_org_freedesktop_DBus_RemoveMatch (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - const char *arg; - DBusString arg_str; - MatchRule *rule = NULL; - DBusConnection *connection = transport->base.connection; - - if (!dbus_message_get_args (message, error, - DBUS_TYPE_STRING, &arg, - DBUS_TYPE_INVALID)) - goto failed_remove; - - _dbus_string_init_const (&arg_str, arg); - - rule = match_rule_parse (connection, &arg_str, error); - if (rule == NULL) - goto failed_remove; - - if (!kdbus_remove_match (&transport->base, matchmaker_get_rules_list (transport->matchmaker, rule), - transport->my_DBus_unique_name, rule, error)) - goto failed_remove; - - if (!matchmaker_remove_rule_by_value (transport->matchmaker, rule, error)) - goto failed_remove; - - match_rule_unref (rule); - return reply_ack (message, connection); - -failed_remove: - if (rule) - match_rule_unref (rule); - _dbus_verbose ("Error during RemoveMatch in lib: %s, %s\n", error->name, error->message); - return -1; -} - -static int -get_connection_info_by_name (DBusMessage *message, - DBusError *error, - struct nameInfo *info, - DBusTransport *transport, - const char *name, - dbus_bool_t getLabel) -{ - int ret; - if (!dbus_validate_bus_name (name, error)) - return -1; - - if ((ret = _kdbus_connection_info_by_name (get_kdbus (transport), name, getLabel, info)) != 0) - { - if (ESRCH == ret || ENXIO == ret) - dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER, - "Could not get owner of name '%s': no such name", name); - else - dbus_set_error (error, DBUS_ERROR_FAILED, - "Unable to query name %s, returned %d, errno = %d (%m).", - name, ret, errno); - return -1; - } - if (info->flags & KDBUS_HELLO_ACTIVATOR) - { - dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER, - "Could not get owner of name '%s'", name); - /* we return ESRCH - this is an indicator that name has an activator */ - return -ESRCH; - } - return 0; -} - -/* This local function handles common case for org.freedesktop.DBus method handlers: - * 1. gets string argument from incoming message; - * 2. gets connection info for such name. - * Note: if getLabel argument is set to TRUE, the caller must free info.sec_label. - */ -static int -get_connection_info_from_message_argument (DBusMessage *message, - DBusError *error, - struct nameInfo *info, - DBusTransport *transport, - dbus_bool_t getLabel) -{ - const char *arg; - - if (!dbus_message_get_args (message, error, - DBUS_TYPE_STRING, &arg, - DBUS_TYPE_INVALID)) - return -1; - - return get_connection_info_by_name (message, error, info, transport, arg, getLabel); -} - -static int -capture_org_freedesktop_DBus_GetConnectionCredentials (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - DBusMessage *reply = NULL; - DBusConnection *conn = transport->base.connection; - DBusMessageIter reply_iter; - DBusMessageIter array_iter; - struct nameInfo info; - - if (get_connection_info_from_message_argument (message, error, &info, &transport->base, TRUE) != 0) - return -1; - - reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter); - if (reply == NULL) - return -1; - - /* we can't represent > 32-bit pids; if your system needs them, please - * add ProcessID64 to the spec or something */ - if (info.processId <= _DBUS_UINT32_MAX) - { - if (!_dbus_asv_add_uint32 (&array_iter, "ProcessID", info.processId)) - goto oom; - } - /* we can't represent > 32-bit uids; if your system needs them, please - * add UnixUserID64 to the spec or something */ - if (info.userId <= _DBUS_UINT32_MAX) - { - if (!_dbus_asv_add_uint32 (&array_iter, "UnixUserID", info.userId)) - goto oom; - } - - if (info.sec_label != NULL) - { - dbus_bool_t res = _dbus_asv_add_array_of_bytes (&array_iter, "LinuxSecurityLabel", - info.sec_label, - strlen (info.sec_label)+1); - - dbus_free (info.sec_label); - - if (!res) - goto oom; - } - - if (!_dbus_asv_close (&reply_iter, &array_iter)) - goto oom; - - if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS)) - goto oom; - - if (!add_message_to_received (reply, conn)) - goto oom; - - return 0; - -oom: - _dbus_asv_abandon (&reply_iter, &array_iter); - dbus_message_unref (reply); - - return -1; -} - -static int -capture_org_freedesktop_DBus_GetConnectionSELinuxSecurityContext (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - struct nameInfo info; - - if (get_connection_info_from_message_argument (message, error, &info, &transport->base, TRUE) != 0) - return -1; - - if (info.sec_label != NULL) - { - int ret = reply_fixed_array (message, DBUS_TYPE_BYTE, - info.sec_label, - strlen (info.sec_label)+1, - transport->base.connection); - - dbus_free (info.sec_label); - return ret; - } - else - { - dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, "Operation not supported"); - } - - return -1; -} - -static int -capture_org_freedesktop_DBus_GetConnectionUnixProcessID (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - struct nameInfo info; - dbus_uint32_t processId; - - if (get_connection_info_from_message_argument (message, error, &info, &transport->base, FALSE) != 0 || - info.processId > _DBUS_UINT32_MAX) - return -1; - - processId = info.processId; - - return reply_1_data (message, DBUS_TYPE_UINT32, &processId, transport->base.connection); -} - -static int -capture_org_freedesktop_DBus_GetConnectionUnixUser (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - struct nameInfo info; - dbus_uint32_t userId; - - if (get_connection_info_from_message_argument (message, error, &info, &transport->base, FALSE) != 0 || - info.userId > _DBUS_UINT32_MAX) - return -1; - - userId = info.userId; - - return reply_1_data (message, DBUS_TYPE_UINT32, &userId, transport->base.connection); -} - -static int -capture_org_freedesktop_DBus_GetId (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - dbus_uint64_t bus_id_size = _kdbus_bus_id_size (); - char bus_id[bus_id_size*2+1]; - char *bus_id_ptr = bus_id; - char *bus_id_original = _kdbus_bus_id (transport->kdbus); - int i = 0; - for (; i < bus_id_size; i++) - sprintf (bus_id + 2*i, "%02x", bus_id_original[i]); - return reply_1_data (message, DBUS_TYPE_STRING, &bus_id_ptr, transport->base.connection); -} - -static int -capture_org_freedesktop_DBus_GetNameOwner (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - struct nameInfo info; - char *unique_name; - int ret; - const char *arg; - - if (!dbus_message_get_args (message, error, - DBUS_TYPE_STRING, &arg, - DBUS_TYPE_INVALID)) - return -1; - - if (strcmp (arg, DBUS_SERVICE_DBUS) == 0) - { - if (-1 == asprintf (&unique_name, "%s", DBUS_SERVICE_DBUS)) - return -1; - } - else - { - if (get_connection_info_by_name (message, error, &info, &transport->base, arg, FALSE) != 0) - return -1; - - unique_name = create_unique_name_from_unique_id (info.uniqueId); - if (NULL == unique_name) - return -1; - } - - ret = reply_1_data (message, DBUS_TYPE_STRING, &unique_name, transport->base.connection); - - free (unique_name); - - return ret; -} - -static int -reply_listNames (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error, - dbus_uint64_t flags) -{ - DBusMessage *reply = NULL; - dbus_uint64_t prev_id = 0; - - /* First, get the list from kdbus */ - - struct kdbus_info *name_list, *name; - dbus_uint64_t list_size; - int ret; - DBusMessageIter iter; - DBusMessageIter array_iter; - - ret = _kdbus_list (transport->kdbus, - flags, - &name_list, - &list_size); - if (ret != 0) - { - dbus_set_error (error, DBUS_ERROR_FAILED, "Error listing names"); - return -1; - } - - /* Compose the reply on the fly */ - reply = dbus_message_new_method_return (message); - if (reply == NULL) - goto oom; - - dbus_message_iter_init_append (reply, &iter); - if (!dbus_message_iter_open_container (&iter, - DBUS_TYPE_ARRAY, - DBUS_TYPE_STRING_AS_STRING, - &array_iter)) - goto oom_reply; - - KDBUS_FOREACH (name, name_list, list_size) - { - struct kdbus_item *item; - - if ((flags & KDBUS_LIST_UNIQUE) && name->id != prev_id) - { - dbus_bool_t res; - - char *unique_name = create_unique_name_from_unique_id (name->id); - - if (NULL == unique_name) - goto oom_iterator; - - res = dbus_message_iter_append_basic (&array_iter, - DBUS_TYPE_STRING, - &unique_name); - free (unique_name); - - if (!res) - goto oom_iterator; - } - - KDBUS_ITEM_FOREACH (item, name, items) - { - if (item->type == KDBUS_ITEM_OWNED_NAME) - { - DBusError local_error; - char *name_ptr = item->name.name; - - dbus_error_init ( &local_error ); - if (!dbus_validate_bus_name (name_ptr, &local_error)) - continue; - - if (flags & KDBUS_LIST_QUEUED) - name_ptr = create_unique_name_from_unique_id (name->id); - - if (NULL == name_ptr) - goto oom_iterator; - - if (!dbus_message_iter_append_basic (&array_iter, - DBUS_TYPE_STRING, - &name_ptr)) - goto oom_iterator; - - if (flags & KDBUS_LIST_QUEUED) - free (name_ptr); - } - } - } - - if (!dbus_message_iter_close_container (&iter, &array_iter)) - goto oom_reply; - - if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS)) - goto oom_reply; - - /* Finally, send the reply */ - if (!add_message_to_received (reply, transport->base.connection)) - goto oom_reply; - - return 0; - -oom_iterator: - dbus_message_iter_abandon_container (&iter, &array_iter); - -oom_reply: - dbus_message_unref (reply); -oom: - _kdbus_free_mem (transport->kdbus, name_list); - return -1; -} - -static int -capture_org_freedesktop_DBus_ListActivatableNames (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - return reply_listNames (transport, message, error, KDBUS_LIST_ACTIVATORS); -} - -static int -capture_org_freedesktop_DBus_ListNames (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - return reply_listNames (transport, message, error, KDBUS_LIST_UNIQUE | KDBUS_LIST_NAMES); -} - -static int -capture_org_freedesktop_DBus_ListQueuedOwners (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - struct nameInfo info; - - if (get_connection_info_from_message_argument (message, error, &info, &transport->base, FALSE) != 0) - return -1; - - return reply_listNames (transport, message, error, KDBUS_LIST_QUEUED); -} - -static int -capture_org_freedesktop_DBus_NameHasOwner (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - struct nameInfo info; - dbus_bool_t result = TRUE; - - if (get_connection_info_from_message_argument (message, error, &info, &transport->base, FALSE) != 0) - { - if (dbus_error_is_set (error) && dbus_error_has_name (error, DBUS_ERROR_NAME_HAS_NO_OWNER)) - { - result = FALSE; - dbus_error_free (error); - } - else - return -1; - } - - return reply_1_data (message, DBUS_TYPE_BOOLEAN, &result, transport->base.connection); -} - -static int -capture_org_freedesktop_DBus_ReloadConfig (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - DBusMessageIter iter; - DBusMessage *reply = NULL; - - dbus_message_iter_init (message, &iter); - if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT) - { - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Call to 'ReloadConfig' has wrong args"); - return -1; - } - - reply = dbus_message_new_method_return (message); - if (reply == NULL) - return -1; - - if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS)) - goto oom; - - if (!add_message_to_received (reply, transport->base.connection)) - goto oom; - - return 0; - -oom: - dbus_message_unref (reply); - return -1; -} - -static int -capture_org_freedesktop_DBus_StartServiceByName (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - struct nameInfo info; - char *name; - dbus_uint32_t flags; /* Spec says: not used, but we check the syntax anyway */ - int ret = 0; - dbus_bool_t dbus_service = FALSE; - - if (!dbus_message_get_args (message, error, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_UINT32, &flags, - DBUS_TYPE_INVALID)) - return -1; - - dbus_service = (strncmp (name, DBUS_SERVICE_DBUS, strlen (DBUS_SERVICE_DBUS) + 1) == 0); - - if (!dbus_service) - ret = get_connection_info_by_name (message, - error, - &info, - &transport->base, - name, - FALSE); - - if (dbus_service || 0 == ret) - { - dbus_uint32_t status = DBUS_START_REPLY_ALREADY_RUNNING; - return reply_1_data (message, DBUS_TYPE_UINT32, &status, transport->base.connection); - } - else if (-ESRCH == ret) /* there is an activator */ - { - DBusMessage *sub_message; - - /* if we are here, then we have error set - free place for possible real error */ - dbus_error_free (error); - - /* send method call to org.freedesktop.DBus.Peer.Ping */ - sub_message = dbus_message_new_method_call (name, "/", DBUS_INTERFACE_PEER, "Ping"); - if (sub_message == NULL) - return -1; - - /* The serial number here is set to -1. A message needs a valid serial number. - * We do not have access to connection's serial numbers counter, so we need to make up one. - * -1 is the last valid serial, so we hope that we'll never get there, especially with 64-bit - * kdbus cookies. - */ - dbus_message_set_serial (sub_message, -1); - - dbus_message_lock (sub_message); - - if (kdbus_write_msg_internal (transport, sub_message, name, FALSE) == -1) - return -1; - else - { - dbus_uint32_t status = DBUS_START_REPLY_SUCCESS; - return reply_1_data (message, DBUS_TYPE_UINT32, &status, transport->base.connection); - } - } - else - { - /* - * There was an error set in get_connection_info_by_name() - * We want to have another error return from StartServiceByName. - */ - dbus_error_free (error); - dbus_set_error (error, - DBUS_ERROR_SERVICE_UNKNOWN, - "The name %s was not provided by any .service files", - name); - } - - return -1; -} - -static int -capture_org_freedesktop_DBus_UpdateActivationEnvironment (DBusTransportKdbus *transport, - DBusMessage *message, - DBusError *error) -{ - dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, - "'%s' method not supported", dbus_message_get_member (message)); - return -1; -} - -typedef int (*CaptureHandler)(DBusTransportKdbus *, DBusMessage *, DBusError *); -struct CaptureHandlers { - const char *method_name; - CaptureHandler handler; -}; - -#define HANDLER_ELEMENT(x) {#x, capture_org_freedesktop_DBus_##x} - -/* This is to cut the code to parts, and keep it organized: - * an array of elements of type, as in example: - * { "RequestName", capture_org_freedesktop_DBus_RequestName } - * That is, a method of name RequestName will be handled by capture_org_freedesktop_DBus_RequestName (). - */ -static struct CaptureHandlers capture_handlers[] = -{ -// "Hello" is handled separately -// HANDLER_ELEMENT(Hello), - HANDLER_ELEMENT (RequestName), - HANDLER_ELEMENT (ReleaseName), - HANDLER_ELEMENT (AddMatch), - HANDLER_ELEMENT (RemoveMatch), - HANDLER_ELEMENT (GetConnectionCredentials), - HANDLER_ELEMENT (GetConnectionSELinuxSecurityContext), - HANDLER_ELEMENT (GetConnectionUnixProcessID), - HANDLER_ELEMENT (GetConnectionUnixUser), - HANDLER_ELEMENT (GetId), - HANDLER_ELEMENT (GetNameOwner), - HANDLER_ELEMENT (ListActivatableNames), - HANDLER_ELEMENT (ListNames), - HANDLER_ELEMENT (ListQueuedOwners), - HANDLER_ELEMENT (NameHasOwner), - HANDLER_ELEMENT (ReloadConfig), - HANDLER_ELEMENT (StartServiceByName), - HANDLER_ELEMENT (UpdateActivationEnvironment) -}; - -/** - * Looks over messages sent to org.freedesktop.DBus. Hello message, which performs - * registration on the bus, is captured as it must be locally converted into - * appropriate ioctl. AddMatch and RemoveMatch are captured to store match rules - * locally in case of false positive result of kdbus bloom filters, but after - * being read they are passed to org.freedesktop.DBus to register these rules - * in kdbus. - * All the rest org.freedesktop.DBus methods are left untouched - * and they are sent to dbus-daemon in the same way as every other messages. - * - * @param transport Transport - * @param message Message being sent. - * @returns 1 if message is not captured and should be passed to daemon - * 0 if message was handled locally and correctly (it includes proper return of error reply), - * -1 message to org.freedesktop.DBus was not handled correctly. - */ -static int -capture_org_freedesktop_DBus (DBusTransportKdbus *transport, - const char *destination, - DBusMessage *message) -{ - int ret = 1; - if (!strcmp (destination, DBUS_SERVICE_DBUS)) - { - if (!strcmp (dbus_message_get_interface (message), DBUS_INTERFACE_DBUS)) - { - DBusError error; - const char *member = dbus_message_get_member (message); - - dbus_error_init (&error); - - ret = -1; - if (!strcmp (member, "Hello")) - { - ret = capture_org_freedesktop_DBus_Hello (transport, message, &error); - } - else - { - int i = 0; - int handlers_size = sizeof (capture_handlers)/sizeof (capture_handlers[0]); - - while (i < handlers_size && strcmp (member, capture_handlers[i].method_name) != 0) - i++; - - if (i < handlers_size) - { - ret = capture_handlers[i].handler (transport, message, &error); - } - else - { - dbus_set_error (&error, DBUS_ERROR_UNKNOWN_METHOD, - "org.freedesktop.DBus does not understand message %s", member); - } - } - - if (ret != 0 && dbus_error_is_set (&error)) - { - ret = reply_with_error ((char*)error.name, NULL, error.message, message, - transport->base.connection); - dbus_error_free (&error); - } - } - } - - return ret; //send message to daemon -} - -#if KDBUS_MSG_DECODE_DEBUG == 1 -static const char -*msg_id (uint64_t id) -{ - char buf[64]; - const char* const_ptr; - - if (id == 0) - return "KERNEL"; - if (id == ~0ULL) - return "BROADCAST"; - - sprintf (buf, "%llu", (unsigned long long)id); - - const_ptr = buf; - return const_ptr; -} -#endif -struct kdbus_enum_table { - long long id; - const char *name; -}; -#define _STRINGIFY(x) #x -#define STRINGIFY(x) _STRINGIFY(x) -#define ELEMENTSOF(x) (sizeof (x)/sizeof ((x)[0])) -#define TABLE(what) static struct kdbus_enum_table kdbus_table_##what[] -#define ENUM(_id) { .id=_id, .name=STRINGIFY(_id) } -#define LOOKUP(what) \ - const char *enum_##what (long long id) { \ - size_t i; \ - for (i = 0; i < ELEMENTSOF(kdbus_table_##what); i++) \ - if (id == kdbus_table_##what[i].id) \ - return kdbus_table_##what[i].name; \ - return "UNKNOWN"; \ - } -const char *enum_MSG(long long id); -TABLE(MSG) = { - ENUM(_KDBUS_ITEM_NULL), - ENUM(KDBUS_ITEM_PAYLOAD_VEC), - ENUM(KDBUS_ITEM_PAYLOAD_OFF), - ENUM(KDBUS_ITEM_PAYLOAD_MEMFD), - ENUM(KDBUS_ITEM_FDS), - ENUM(KDBUS_ITEM_BLOOM_PARAMETER), - ENUM(KDBUS_ITEM_BLOOM_FILTER), - ENUM(KDBUS_ITEM_DST_NAME), - ENUM(KDBUS_ITEM_CREDS), - ENUM(KDBUS_ITEM_PID_COMM), - ENUM(KDBUS_ITEM_TID_COMM), - ENUM(KDBUS_ITEM_EXE), - ENUM(KDBUS_ITEM_CMDLINE), - ENUM(KDBUS_ITEM_CGROUP), - ENUM(KDBUS_ITEM_CAPS), - ENUM(KDBUS_ITEM_SECLABEL), - ENUM(KDBUS_ITEM_AUDIT), - ENUM(KDBUS_ITEM_CONN_DESCRIPTION), - ENUM(KDBUS_ITEM_NAME), - ENUM(KDBUS_ITEM_TIMESTAMP), - ENUM(KDBUS_ITEM_NAME_ADD), - ENUM(KDBUS_ITEM_NAME_REMOVE), - ENUM(KDBUS_ITEM_NAME_CHANGE), - ENUM(KDBUS_ITEM_ID_ADD), - ENUM(KDBUS_ITEM_ID_REMOVE), - ENUM(KDBUS_ITEM_REPLY_TIMEOUT), - ENUM(KDBUS_ITEM_REPLY_DEAD), -}; -LOOKUP(MSG); -const char *enum_PAYLOAD(long long id); -TABLE(PAYLOAD) = { - ENUM(KDBUS_PAYLOAD_KERNEL), - ENUM(KDBUS_PAYLOAD_DBUS), -}; -LOOKUP(PAYLOAD); - -static dbus_uint32_t -get_next_client_serial (DBusTransportKdbus *transport) -{ - dbus_uint32_t serial; - - serial = transport->client_serial++; - - if (transport->client_serial == 0) - transport->client_serial = 1; - - return serial; -} - -/** - * Calculates length of the kdbus message content (payload). - * - * @param msg kdbus message - * @return the length of the kdbus message's payload. - */ -static int -kdbus_message_size (const struct kdbus_msg* msg) -{ - const struct kdbus_item *item; - int ret_size = 0; - - KDBUS_ITEM_FOREACH(item, msg, items) - { - if (item->size < KDBUS_ITEM_HEADER_SIZE) - { - _dbus_verbose (" +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size); - return -1; - } - switch (item->type) - { - case KDBUS_ITEM_PAYLOAD_OFF: - ret_size += item->vec.size; - break; - case KDBUS_ITEM_PAYLOAD_MEMFD: - ret_size += item->memfd.size; - break; - default: - break; - } - } - - return ret_size; -} - -static int -generate_NameSignal (const char *signal, - const char *name, - DBusTransportKdbus *transport) -{ - DBusMessage *message; - - _dbus_verbose ("Generating %s for %s.\n", signal, name); - - message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, signal); - if (message == NULL) - return -1; - - if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) - goto error; - if (!dbus_message_set_destination (message, transport->my_DBus_unique_name)) - goto error; - if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) - goto error; - dbus_message_set_serial (message, get_next_client_serial (transport)); - - if (!add_message_to_received (message, transport->base.connection)) - return -1; - - return 0; - - error: - dbus_message_unref (message); - return -1; -} - -/* - * The NameOwnerChanged signals take three parameters with - * unique or well-known names, but only some forms actually - * exist: - * - * WELLKNOWN, "", UNIQUE → KDBUS_ITEM_NAME_ADD - * WELLKNOWN, UNIQUE, "" → KDBUS_ITEM_NAME_REMOVE - * WELLKNOWN, UNIQUE, UNIQUE → KDBUS_ITEM_NAME_CHANGE - * UNIQUE, "", UNIQUE → KDBUS_ITEM_ID_ADD - * UNIQUE, UNIQUE, "" → KDBUS_ITEM_ID_REMOVE - * - * For the latter two the two unique names must be identical. - */ -static int -kdbus_handle_name_owner_changed (__u64 type, - const char *bus_name, - __u64 old, - __u64 new, - DBusTransportKdbus *transport) -{ - DBusMessage *message = NULL; - DBusMessageIter args; - char tmp_str[128]; - const char *const_ptr; - - if ((message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) == NULL) - return -1; - - dbus_message_iter_init_append (message, &args); - - // for ID_ADD and ID_REMOVE this function takes NULL as bus_name - if (bus_name == NULL) - { - sprintf (tmp_str,":1.%llu", old != 0 ? old : new); - const_ptr = tmp_str; - } - else - const_ptr = bus_name; - - if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr)) - goto error; - - _dbus_verbose ("%s\n", const_ptr); - - - if ((old==0) && (new==0)) - { - /* kdbus generates its own set of events that can not be passed to - * client without translation. */ - const char *src = "org.freedesktop.DBus"; - const char *dst = "org.freedesktop.DBus"; - - if (type == KDBUS_ITEM_NAME_ADD || type == KDBUS_ITEM_ID_ADD) - src = ""; - else if (type == KDBUS_ITEM_NAME_REMOVE || type == KDBUS_ITEM_ID_REMOVE) - dst = ""; - - if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &src)) - goto error; - if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &dst)) - goto error; - - _dbus_verbose ("[NameOwnerChanged:%s, old=%lld, new=%lld\n", __func__, old, new); - } - else - { - // determine and append old_id - if (old != 0) - { - sprintf (tmp_str,":1.%llu", old); - const_ptr = tmp_str; - } - else - const_ptr = ""; - - if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr)) - goto error; - - _dbus_verbose ("%s\n", const_ptr); - // determine and append new_id - if (new != 0) - { - sprintf (tmp_str,":1.%llu", new); - const_ptr = tmp_str; - } - else - const_ptr = ""; - - if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr)) - goto error; - - _dbus_verbose ("%s\n", const_ptr); - } - - dbus_message_set_sender (message, DBUS_SERVICE_DBUS); - dbus_message_set_serial (message, get_next_client_serial (transport)); - - if (!add_message_to_received (message, transport->base.connection)) - return -1; - - return 0; - -error: - dbus_message_unref (message); - - return -1; -} - -static void -_handle_item_timestamp (const struct kdbus_item *item) -{ -#if KDBUS_MSG_DECODE_DEBUG == 1 - _dbus_verbose (" +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n", - enum_MSG(item->type), item->size, - (unsigned long long)item->timestamp.realtime_ns, - (unsigned long long)item->timestamp.monotonic_ns); -#endif -} - -static void -_handle_unexpected_item (const struct kdbus_item *item) -{ - _dbus_assert_not_reached ("unexpected item from kdbus"); -} - -static void -_handle_padding (const struct kdbus_msg *msg, - const struct kdbus_item *end_of_items) -{ -#if KDBUS_MSG_DECODE_DEBUG == 1 - if ((char *)end_of_items - ((char *)msg + msg->size) >= 8) - _dbus_verbose ("invalid padding at end of message\n"); -#endif -} - -static int -kdbus_decode_dbus_message (const struct kdbus_msg *msg, - char *data, - DBusTransportKdbus *kdbus_transport, - int *fds, - int *n_fds) -{ - const struct kdbus_item *item; - int ret_size = 0; - - *n_fds = 0; - - KDBUS_ITEM_FOREACH(item, msg, items) - { - if (item->size < KDBUS_ITEM_HEADER_SIZE) - { - _dbus_verbose (" +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size); - ret_size = -1; - break; - } - - switch (item->type) - { - case KDBUS_ITEM_PAYLOAD_OFF: - memcpy (data, (char *)msg+item->vec.offset, item->vec.size); - data += item->vec.size; - ret_size += item->vec.size; - - if (-1 != debug) - { - debug_c_str ("Message part arrived:", (char *)msg+item->vec.offset, item->vec.size); - } - - _dbus_verbose (" +%s (%llu bytes) off=%llu size=%llu\n", - enum_MSG(item->type), item->size, - (unsigned long long)item->vec.offset, - (unsigned long long)item->vec.size); - break; - - case KDBUS_ITEM_PAYLOAD_MEMFD: - { - char *buf; - uint64_t size; - - size = item->memfd.size; - _dbus_verbose ("memfd.size : %llu\n", (unsigned long long)size); - - buf = mmap (NULL, size, PROT_READ , MAP_SHARED, item->memfd.fd, 0); - if (buf == MAP_FAILED) - { - _dbus_verbose ("mmap () fd=%i failed:%m", item->memfd.fd); - return -1; - } - - memcpy (data, buf, size); - data += size; - ret_size += size; - - munmap (buf, size); - close (item->memfd.fd); - - _dbus_verbose (" +%s (%llu bytes) off=%llu size=%llu\n", - enum_MSG(item->type), item->size, - (unsigned long long)item->vec.offset, - (unsigned long long)item->vec.size); - } - break; - - case KDBUS_ITEM_FDS: - { - int i; - - *n_fds = (item->size - KDBUS_ITEM_HEADER_SIZE) / sizeof (int); - memcpy (fds, item->fds, *n_fds * sizeof (int)); - for (i = 0; i < *n_fds; i++) - _dbus_fd_set_close_on_exec (fds[i]); - } - break; - - case KDBUS_ITEM_CREDS: -#if KDBUS_MSG_DECODE_DEBUG == 1 - _dbus_verbose (" +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n", - enum_MSG(item->type), item->size, - item->creds.uid, item->creds.gid, - item->creds.pid, item->creds.tid, - item->creds.starttime); -#endif - break; - - case KDBUS_ITEM_PID_COMM: - case KDBUS_ITEM_TID_COMM: - case KDBUS_ITEM_EXE: - case KDBUS_ITEM_CGROUP: - case KDBUS_ITEM_SECLABEL: - case KDBUS_ITEM_DST_NAME: -#if KDBUS_MSG_DECODE_DEBUG == 1 - _dbus_verbose (" +%s (%llu bytes) '%s' (%zu)\n", - enum_MSG(item->type), item->size, item->str, strlen (item->str)); -#endif - break; - - case KDBUS_ITEM_CMDLINE: - case KDBUS_ITEM_NAME: -#if KDBUS_MSG_DECODE_DEBUG == 1 - { - __u64 size = item->size - KDBUS_ITEM_HEADER_SIZE; - const char *str = item->str; - int count = 0; - - _dbus_verbose (" +%s (%llu bytes) ", enum_MSG(item->type), item->size); - while (size) - { - _dbus_verbose ("'%s' ", str); - size -= strlen (str) + 1; - str += strlen (str) + 1; - count++; - } - - _dbus_verbose ("(%d string%s)\n", count, (count == 1) ? "" : "s"); - } -#endif - break; - - case KDBUS_ITEM_AUDIT: -#if KDBUS_MSG_DECODE_DEBUG == 1 - _dbus_verbose (" +%s (%llu bytes) loginuid=%llu sessionid=%llu\n", - enum_MSG(item->type), item->size, - (unsigned long long)item->data64[0], - (unsigned long long)item->data64[1]); -#endif - break; - - case KDBUS_ITEM_CAPS: -#if KDBUS_MSG_DECODE_DEBUG == 1 - { - int n; - const uint32_t *cap; - int i; - - _dbus_verbose (" +%s (%llu bytes) len=%llu bytes)\n", - enum_MSG(item->type), item->size, - (unsigned long long)item->size - KDBUS_ITEM_HEADER_SIZE); - - cap = item->data32; - n = (item->size - KDBUS_ITEM_HEADER_SIZE) / 4 / sizeof (uint32_t); - - _dbus_verbose (" CapInh="); - for (i = 0; i < n; i++) - _dbus_verbose ("%08x", cap[(0 * n) + (n - i - 1)]); - - _dbus_verbose (" CapPrm="); - for (i = 0; i < n; i++) - _dbus_verbose ("%08x", cap[(1 * n) + (n - i - 1)]); - - _dbus_verbose (" CapEff="); - for (i = 0; i < n; i++) - _dbus_verbose ("%08x", cap[(2 * n) + (n - i - 1)]); - - _dbus_verbose (" CapInh="); - for (i = 0; i < n; i++) - _dbus_verbose ("%08x", cap[(3 * n) + (n - i - 1)]); - _dbus_verbose ("\n"); - } -#endif - break; - - case KDBUS_ITEM_TIMESTAMP: - _handle_item_timestamp (item); - break; - - case KDBUS_ITEM_BLOOM_FILTER: - /* no handling */ - break; - - default: - _handle_unexpected_item (item); - break; - } - } - - _handle_padding (msg, item); - - return ret_size; -} - -static int -kdbus_decode_kernel_message (const struct kdbus_msg *msg, - DBusTransportKdbus *kdbus_transport) -{ - const struct kdbus_item *item; - int ret_size = 0; - - KDBUS_ITEM_FOREACH (item, msg, items) - { - if (item->size < KDBUS_ITEM_HEADER_SIZE) - { - _dbus_verbose (" +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size); - ret_size = -1; - break; - } - - switch (item->type) - { - case KDBUS_ITEM_REPLY_TIMEOUT: - case KDBUS_ITEM_REPLY_DEAD: - { - DBusMessage *message = NULL; - _dbus_verbose (" +%s (%llu bytes) cookie=%llu\n", - enum_MSG (item->type), item->size, msg->cookie_reply); - - message = _dbus_generate_local_error_message (msg->cookie_reply, - item->type == KDBUS_ITEM_REPLY_TIMEOUT ? DBUS_ERROR_NO_REPLY : DBUS_ERROR_NAME_HAS_NO_OWNER, NULL); - if (message == NULL) - { - ret_size = -1; - goto out; - } - - dbus_message_set_serial (message, get_next_client_serial (kdbus_transport)); - - if (!add_message_to_received (message, kdbus_transport->base.connection)) - ret_size = -1; - } - break; - - case KDBUS_ITEM_NAME_ADD: - case KDBUS_ITEM_NAME_REMOVE: - case KDBUS_ITEM_NAME_CHANGE: - { - int local_ret; - - _dbus_verbose (" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, old flags=0x%llx, new flags=0x%llx\n", - enum_MSG(item->type), (unsigned long long) item->size, - item->name_change.name, item->name_change.old_id.id, - item->name_change.new_id.id, item->name_change.old_id.flags, - item->name_change.new_id.flags); - - if (item->name_change.new_id.id == _kdbus_id (kdbus_transport->kdbus)) - ret_size = generate_NameSignal ("NameAcquired", item->name_change.name, kdbus_transport); - else if (item->name_change.old_id.id == _kdbus_id (kdbus_transport->kdbus)) - ret_size = generate_NameSignal ("NameLost", item->name_change.name, kdbus_transport); - - if (ret_size == -1) - goto out; - - if (item->name_change.new_id.flags & KDBUS_NAME_ACTIVATOR) - local_ret = kdbus_handle_name_owner_changed (item->type, - item->name_change.name, - item->name_change.old_id.id, 0, - kdbus_transport); - else if (item->name_change.old_id.flags & KDBUS_NAME_ACTIVATOR) - local_ret = kdbus_handle_name_owner_changed (item->type, - item->name_change.name, 0, - item->name_change.new_id.id, - kdbus_transport); - else - local_ret = kdbus_handle_name_owner_changed (item->type, - item->name_change.name, - item->name_change.old_id.id, - item->name_change.new_id.id, - kdbus_transport); - if (local_ret == -1) - goto out; - - ret_size += local_ret; - } - break; - - case KDBUS_ITEM_ID_ADD: - case KDBUS_ITEM_ID_REMOVE: - _dbus_verbose (" +%s (%llu bytes) id=%llu flags=%llu\n", - enum_MSG(item->type), (unsigned long long) item->size, - (unsigned long long) item->id_change.id, - (unsigned long long) item->id_change.flags); - - if (item->id_change.flags & KDBUS_HELLO_ACTIVATOR) - ret_size = kdbus_handle_name_owner_changed (item->type, NULL, 0, 0, - kdbus_transport); - else - ret_size = kdbus_handle_name_owner_changed (item->type, NULL, - item->type == KDBUS_ITEM_ID_ADD ? 0 : item->id_change.id, - item->type == KDBUS_ITEM_ID_ADD ? item->id_change.id : 0, - kdbus_transport); - - if (ret_size == -1) - goto out; - break; - - case KDBUS_ITEM_TIMESTAMP: - _handle_item_timestamp (item); - break; - - default: - _handle_unexpected_item (item); - break; - } - } - - _handle_padding (msg, item); - -out: - return ret_size; -} - -/** - * Decodes kdbus message in order to extract DBus message and puts it into received data buffer - * and file descriptor's buffer. Also captures kdbus error messages and kdbus kernel broadcasts - * and converts all of them into appropriate DBus messages. - * - * @param msg kdbus message - * @param data place to copy DBus message to - * @param kdbus_transport transport - * @param fds place to store file descriptors received - * @param n_fds place to store quantity of file descriptors received - * @return number of DBus message's bytes received or -1 on error - */ -static int -kdbus_decode_msg (const struct kdbus_msg *msg, - char *data, - DBusTransportKdbus *kdbus_transport, - int *fds, - int *n_fds) -{ - int ret_size = 0; - -#if KDBUS_MSG_DECODE_DEBUG == 1 - _dbus_verbose ("MESSAGE: %s (%llu bytes) flags=0x%llx, %s → %s, cookie=%llu, timeout=%llu\n", - enum_PAYLOAD(msg->payload_type), - (unsigned long long) msg->size, - (unsigned long long) msg->flags, - msg_id (msg->src_id), - msg_id (msg->dst_id), - (unsigned long long) msg->cookie, - (unsigned long long) msg->timeout_ns); -#endif - - switch (msg->payload_type) - { - case KDBUS_PAYLOAD_DBUS: - ret_size = kdbus_decode_dbus_message (msg, data, kdbus_transport, fds, n_fds); - break; - case KDBUS_PAYLOAD_KERNEL: - ret_size = kdbus_decode_kernel_message (msg, kdbus_transport); - break; - default: - _dbus_assert_not_reached ("unexpected payload type from kdbus"); - break; - } - - return ret_size; -} - -/** - * Reads message from kdbus and puts it into DBus buffers - * - * @param kdbus_transport transport - * @param buffer place to copy received message to - * @param fds place to store file descriptors received with the message - * @param n_fds place to store quantity of file descriptors received - * @return size of received message on success, -1 on error - */ -static int -kdbus_read_message (DBusTransportKdbus *kdbus_transport, - DBusString *buffer, - int *fds, - int *n_fds) -{ - int ret_size, buf_size; - struct kdbus_msg *msg; - char *data; - int start; - dbus_uint64_t flags = 0; - int ret; - - start = _dbus_string_get_length (buffer); - - if (kdbus_transport->activator != NULL) - flags |= KDBUS_RECV_PEEK; - - ret = _kdbus_recv (kdbus_transport->kdbus, flags, 0, &msg); - - if (0 != ret) - { - _dbus_verbose ("kdbus error receiving message: %d (%s)\n", ret, _dbus_strerror (ret)); - _dbus_string_set_length (buffer, start); - return -1; - } - - buf_size = kdbus_message_size (msg); - if (buf_size == -1) - { - _dbus_verbose ("kdbus error - too short message: %d (%m)\n", errno); - return -1; - } - - /* What is the maximum size of the locally generated message? - I just assume 2048 bytes */ - buf_size = MAX(buf_size, 2048); - - if (!_dbus_string_lengthen (buffer, buf_size)) - { - errno = ENOMEM; - return -1; - } - data = _dbus_string_get_data_len (buffer, start, buf_size); - - ret_size = kdbus_decode_msg (msg, data, kdbus_transport, fds, n_fds); - - if (ret_size == -1) /* error */ - { - _dbus_string_set_length (buffer, start); - return -1; - } - else if (buf_size != ret_size) /* case of locally generated message */ - { - _dbus_string_set_length (buffer, start + ret_size); - } - - _dbus_message_loader_set_unique_sender_id (kdbus_transport->base.loader, msg->src_id); - - if (kdbus_transport->activator != NULL) - return ret_size; - - ret = _kdbus_free_mem (kdbus_transport->kdbus, msg); - if (0 != ret) - { - _dbus_verbose ("kdbus error freeing message: %d (%s)\n", ret, _dbus_strerror (ret)); - return -1; - } - - return ret_size; -} - -/** - * Copy-paste from socket transport. Only renames done. - */ -static void -free_watches (DBusTransport *transport) -{ - DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport; - - _dbus_verbose ("start\n"); - - if (kdbus_transport->read_watch) - { - if (transport->connection) - _dbus_connection_remove_watch_unlocked (transport->connection, - kdbus_transport->read_watch); - _dbus_watch_invalidate (kdbus_transport->read_watch); - _dbus_watch_unref (kdbus_transport->read_watch); - kdbus_transport->read_watch = NULL; - } - - if (kdbus_transport->write_watch) - { - if (transport->connection) - _dbus_connection_remove_watch_unlocked (transport->connection, - kdbus_transport->write_watch); - _dbus_watch_invalidate (kdbus_transport->write_watch); - _dbus_watch_unref (kdbus_transport->write_watch); - kdbus_transport->write_watch = NULL; - } - - _dbus_verbose ("end\n"); -} - -/** - * Copy-paste from socket transport. Only done needed renames and removed - * lines related to encoded messages. - */ -static void -transport_finalize (DBusTransport *transport) -{ - DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus *)transport; - _dbus_verbose ("\n"); - - free_watches (transport); - - _dbus_transport_finalize_base (transport); - - _dbus_assert (kdbus_transport->read_watch == NULL); - _dbus_assert (kdbus_transport->write_watch == NULL); - - free_matchmaker (kdbus_transport->matchmaker); - - dbus_free (kdbus_transport->activator); - - _kdbus_free (kdbus_transport->kdbus); - - dbus_free (transport); -} - -/** - * Copy-paste from socket transport. Removed code related to authentication, - * socket_transport replaced by kdbus_transport. - */ -static void -check_write_watch (DBusTransport *transport) -{ - DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport; - dbus_bool_t needed; - - if (transport->connection == NULL) - return; - - if (transport->disconnected) - { - _dbus_assert (kdbus_transport->write_watch == NULL); - return; - } - - _dbus_transport_ref (transport); - - needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection); - - _dbus_verbose ("check_write_watch (): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n", - needed, transport->connection, kdbus_transport->write_watch, - _kdbus_fd (kdbus_transport->kdbus), - _dbus_connection_has_messages_to_send_unlocked (transport->connection)); - - _dbus_connection_toggle_watch_unlocked (transport->connection, - kdbus_transport->write_watch, - needed); - - _dbus_transport_unref (transport); -} - -/** - * Copy-paste from socket transport. Removed code related to authentication, - * socket_transport replaced by kdbus_transport. - */ -static void -check_read_watch (DBusTransport *transport) -{ - DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport; - dbus_bool_t need_read_watch; - - _dbus_verbose ("fd = %d\n",_kdbus_fd (kdbus_transport->kdbus)); - - if (transport->connection == NULL) - return; - - if (transport->disconnected) - { - _dbus_assert (kdbus_transport->read_watch == NULL); - return; - } - - _dbus_transport_ref (transport); - - need_read_watch = - (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) && - (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds); - - _dbus_verbose (" setting read watch enabled = %d\n", need_read_watch); - - _dbus_connection_toggle_watch_unlocked (transport->connection, - kdbus_transport->read_watch, - need_read_watch); - - _dbus_transport_unref (transport); -} - -/** - * Copy-paste from socket transport. - */ -static void -do_io_error (DBusTransport *transport) -{ - _dbus_transport_ref (transport); - _dbus_transport_disconnect (transport); - _dbus_transport_unref (transport); -} - -/** - * Based on do_writing from socket transport. - * Removed authentication code and code related to encoded messages - * and adapted to kdbus transport. - * In socket transport returns false on out-of-memory. Here this won't happen, - * so it always returns TRUE. - */ -static dbus_bool_t -do_writing (DBusTransport *transport) -{ - DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport; - int total = 0; - dbus_bool_t oom = FALSE; - - if (transport->disconnected) - { - _dbus_verbose ("Not connected, not writing anything\n"); - return TRUE; - } - - _dbus_verbose ("do_writing (), have_messages = %d, fd = %d\n", - _dbus_connection_has_messages_to_send_unlocked (transport->connection), _kdbus_fd (kdbus_transport->kdbus)); - - while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection)) - { - int bytes_written; - DBusMessage *message; - const DBusString *header; - const DBusString *body; - const char* pDestination; - - if (total > kdbus_transport->max_bytes_written_per_iteration) - { - _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n", - total, kdbus_transport->max_bytes_written_per_iteration); - goto out; - } - - message = _dbus_connection_get_message_to_send (transport->connection); - _dbus_assert (message != NULL); - pDestination = dbus_message_get_destination (message); - - if (pDestination) - { - int ret; - - ret = capture_org_freedesktop_DBus ((DBusTransportKdbus*)transport, pDestination, message); - if (ret < 0) //error - { - bytes_written = -1; - goto written; - } - else if (ret == 0) //hello message captured and handled correctly - { - _dbus_message_get_network_data (message, &header, &body); - bytes_written = _dbus_string_get_length (header) + _dbus_string_get_length (body); - goto written; - } - //else send as regular message - } - - bytes_written = kdbus_write_msg (kdbus_transport, message, pDestination); - - written: - if (bytes_written < 0) - { - if (errno == ENOMEM) - { - oom = TRUE; - goto out; - } - - /* EINTR already handled for us */ - - /* For some discussion of why we also ignore EPIPE here, see - * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html - */ - - if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ()) - goto out; - else - { - _dbus_verbose ("Error writing to remote app: %s\n", _dbus_strerror_from_errno ()); -// do_io_error (transport); - /*TODO the comment above may cause side effects, but must be removed here - to not disconnect the connection. If side-effects appears, reporting errors for upper functions - must be rearranged.*/ - goto out; - } - } - else - { -#if defined (DBUS_ENABLE_VERBOSE_MODE) || !defined (DBUS_DISABLE_ASSERT) - int total_bytes_to_write; - - _dbus_message_get_network_data (message, &header, &body); - total_bytes_to_write = _dbus_string_get_length (header) - + _dbus_string_get_length (body); - _dbus_verbose (" wrote %d bytes of %d\n", bytes_written, - total_bytes_to_write); - - _dbus_assert (bytes_written == total_bytes_to_write); -#endif - total += bytes_written; - - _dbus_connection_message_sent_unlocked (transport->connection, - message); - } - } - -out: - if (oom) - return FALSE; - else - return TRUE; -} - -/** - * Based on do_reading from socket transport. - * Removed authentication code and code related to encoded messages - * and adapted to kdbus transport. - * returns false on out-of-memory - */ -static dbus_bool_t -do_reading (DBusTransport *transport) -{ - DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport; - DBusString *buffer; - int bytes_read; - dbus_bool_t oom = FALSE; - int *fds, n_fds; - int total = 0; - - _dbus_verbose ("fd = %d\n",_kdbus_fd (kdbus_transport->kdbus)); - - again: - - /* See if we've exceeded max messages and need to disable reading */ - if (kdbus_transport->activator == NULL) - check_read_watch (transport); - - if (total > kdbus_transport->max_bytes_read_per_iteration) - { - _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n", - total, kdbus_transport->max_bytes_read_per_iteration); - goto out; - } - - _dbus_assert (kdbus_transport->read_watch != NULL || - transport->disconnected); - - if (transport->disconnected) - goto out; - - if (!dbus_watch_get_enabled (kdbus_transport->read_watch)) - return TRUE; - - if (!_dbus_message_loader_get_unix_fds (transport->loader, &fds, &n_fds)) - { - _dbus_verbose ("Out of memory reading file descriptors\n"); - oom = TRUE; - goto out; - } - _dbus_message_loader_get_buffer (transport->loader, &buffer); - - bytes_read = kdbus_read_message (kdbus_transport, buffer, fds, &n_fds); - - if (bytes_read >= 0 && n_fds > 0) - _dbus_verbose ("Read %i unix fds\n", n_fds); - - _dbus_message_loader_return_buffer (transport->loader, - buffer); - _dbus_message_loader_return_unix_fds (transport->loader, fds, bytes_read < 0 ? 0 : n_fds); - - if (bytes_read < 0) - { - /* EINTR already handled for us */ - - if (_dbus_get_is_errno_enomem ()) - { - _dbus_verbose ("Out of memory in read()/do_reading()\n"); - oom = TRUE; - goto out; - } - else if (_dbus_get_is_errno_eagain_or_ewouldblock ()) - goto out; - else - { - _dbus_verbose ("Error reading from remote app: %s\n", - _dbus_strerror_from_errno ()); - do_io_error (transport); - goto out; - } - } - else if (bytes_read > 0) - { - _dbus_verbose (" read %d bytes\n", bytes_read); - - total += bytes_read; - - if (!_dbus_transport_queue_messages (transport)) - { - oom = TRUE; - _dbus_verbose (" out of memory when queueing messages we just read in the transport\n"); - goto out; - } - - /* Try reading more data until we get EAGAIN and return, or - * exceed max bytes per iteration. If in blocking mode of - * course we'll block instead of returning. - */ - goto again; - } - /* 0 == bytes_read is for kernel messages */ - - out: - if (oom) - return FALSE; - return TRUE; -} - -/** - * Copy-paste from socket transport, with socket replaced by kdbus. - */ -static dbus_bool_t -unix_error_with_read_to_come (DBusTransport *itransport, - DBusWatch *watch, - unsigned int flags) -{ - DBusTransportKdbus *transport = (DBusTransportKdbus *) itransport; - - if (!((flags & DBUS_WATCH_HANGUP) || (flags & DBUS_WATCH_ERROR))) - return FALSE; - - /* If we have a read watch enabled ... - we -might have data incoming ... => handle the HANGUP there */ - if (watch != transport->read_watch && _dbus_watch_get_enabled (transport->read_watch)) - return FALSE; - - return TRUE; -} - -/** - * Copy-paste from socket transport. Removed authentication related code - * and renamed socket_transport to kdbus_transport. - */ -static dbus_bool_t -kdbus_handle_watch (DBusTransport *transport, - DBusWatch *watch, - unsigned int flags) -{ - DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport; - - _dbus_assert (watch == kdbus_transport->read_watch || - watch == kdbus_transport->write_watch); - _dbus_assert (watch != NULL); - - /* If we hit an error here on a write watch, don't disconnect the transport yet because data can - * still be in the buffer and do_reading may need several iteration to read - * it all (because of its max_bytes_read_per_iteration limit). - */ - if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags)) - { - _dbus_verbose ("Hang up or error on watch\n"); - _dbus_transport_disconnect (transport); - return TRUE; - } - - if (watch == kdbus_transport->read_watch && - (flags & DBUS_WATCH_READABLE)) - { - _dbus_verbose ("handling read watch %p flags = %x\n", - watch, flags); - - if (!do_reading (transport)) - { - _dbus_verbose ("no memory to read\n"); - return FALSE; - } - } - else if (watch == kdbus_transport->write_watch && - (flags & DBUS_WATCH_WRITABLE)) - { - _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n", - _dbus_connection_has_messages_to_send_unlocked (transport->connection)); - - if (!do_writing (transport)) - { - _dbus_verbose ("no memory to write\n"); - return FALSE; - } - - /* See if we still need the write watch */ - check_write_watch (transport); - } - - return TRUE; -} - -/** - * Copy-paste from socket transport, but socket_transport renamed to kdbus_transport - * and _dbus_close_socket replaced with close (). - */ -static void -kdbus_disconnect (DBusTransport *transport) -{ - DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport; - - _dbus_verbose ("\n"); - - free_watches (transport); - - _kdbus_close (kdbus_transport->kdbus); -} - -/** - * Copy-paste from socket transport. Renamed socket_transport to - * kdbus_transport and added setting authenticated to TRUE, because - * we do not perform authentication in kdbus, so we have mark is as already done - * to make everything work. - */ -static dbus_bool_t -kdbus_connection_set (DBusTransport *transport) -{ - DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport; - - _dbus_watch_set_handler (kdbus_transport->write_watch, - _dbus_connection_handle_watch, - transport->connection, NULL); - - _dbus_watch_set_handler (kdbus_transport->read_watch, - _dbus_connection_handle_watch, - transport->connection, NULL); - - if (!_dbus_connection_add_watch_unlocked (transport->connection, - kdbus_transport->write_watch)) - return FALSE; - - if (!_dbus_connection_add_watch_unlocked (transport->connection, - kdbus_transport->read_watch)) - { - _dbus_connection_remove_watch_unlocked (transport->connection, - kdbus_transport->write_watch); - return FALSE; - } - - check_read_watch (transport); - check_write_watch (transport); - - return TRUE; -} - -/** - * Copy-paste from socket_transport. - * Socket_transport renamed to kdbus_transport - * - * Original dbus copy-pasted @todo comment below. - * @todo We need to have a way to wake up the select sleep if - * a new iteration request comes in with a flag (read/write) that - * we're not currently serving. Otherwise a call that just reads - * could block a write call forever (if there are no incoming - * messages). - */ -static void -kdbus_do_iteration (DBusTransport *transport, - unsigned int flags, - int timeout_milliseconds) -{ - DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport; - DBusPollFD poll_fd; - int poll_res; - int poll_timeout; - - _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n", - flags & DBUS_ITERATION_DO_READING ? "read" : "", - flags & DBUS_ITERATION_DO_WRITING ? "write" : "", - timeout_milliseconds, - kdbus_transport->read_watch, - kdbus_transport->write_watch, - _kdbus_fd (kdbus_transport->kdbus)); - - poll_fd.fd = _kdbus_fd (kdbus_transport->kdbus); - poll_fd.events = 0; - - /* - * TODO test this. - * This fix is for reply_with_error function. - * When timeout is set to -1 in client application, - * error messages are inserted directly to incoming queue and - * application hangs on dbus_poll. - */ - if (_dbus_connection_get_n_incoming (transport->connection) > 0) - { - timeout_milliseconds = 0; - } - /* This is kind of a hack; if we have stuff to write, then try - * to avoid the poll. This is probably about a 5% speedup on an - * echo client/server. - * - * If both reading and writing were requested, we want to avoid this - * since it could have funky effects: - * - both ends spinning waiting for the other one to read - * data so they can finish writing - * - prioritizing all writing ahead of reading - */ - if ((flags & DBUS_ITERATION_DO_WRITING) && - !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) && - !transport->disconnected && - _dbus_connection_has_messages_to_send_unlocked (transport->connection)) - { - do_writing (transport); - - if (transport->disconnected || - !_dbus_connection_has_messages_to_send_unlocked (transport->connection)) - goto out; - } - - /* If we get here, we decided to do the poll() after all */ - _dbus_assert (kdbus_transport->read_watch); - if (flags & DBUS_ITERATION_DO_READING) - poll_fd.events |= _DBUS_POLLIN; - - _dbus_assert (kdbus_transport->write_watch); - if (flags & DBUS_ITERATION_DO_WRITING) - poll_fd.events |= _DBUS_POLLOUT; - - if (poll_fd.events) - { - if ( (flags & DBUS_ITERATION_BLOCK) && !(flags & DBUS_ITERATION_DO_WRITING)) - poll_timeout = timeout_milliseconds; - else - poll_timeout = 0; - - /* For blocking selects we drop the connection lock here - * to avoid blocking out connection access during a potentially - * indefinite blocking call. The io path is still protected - * by the io_path_cond condvar, so we won't reenter this. - */ - if (flags & DBUS_ITERATION_BLOCK) - { - _dbus_verbose ("unlock pre poll\n"); - _dbus_connection_unlock (transport->connection); - } - - again: - poll_res = _dbus_poll (&poll_fd, 1, poll_timeout); - - if (poll_res < 0 && _dbus_get_is_errno_eintr ()) - goto again; - - if (flags & DBUS_ITERATION_BLOCK) - { - _dbus_verbose ("lock post poll\n"); - _dbus_connection_lock (transport->connection); - } - - if (poll_res >= 0) - { - if (poll_res == 0) - poll_fd.revents = 0; /* some concern that posix does not guarantee this; - * valgrind flags it as an error. though it probably - * is guaranteed on linux at least. - */ - - if (poll_fd.revents & _DBUS_POLLERR) - do_io_error (transport); - else - { - dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0; - - _dbus_verbose ("in iteration, need_read=%d\n", - need_read); - - if (need_read && (flags & DBUS_ITERATION_DO_READING)) - do_reading (transport); - /* We always be able to write to kdbus */ - if (flags & DBUS_ITERATION_DO_WRITING) - do_writing (transport); - } - } - else - _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ()); - } - - out: - /* We need to install the write watch only if we did not - * successfully write everything. Note we need to be careful that we - * don't call check_write_watch *before* do_writing, since it's - * inefficient to add the write watch, and we can avoid it most of - * the time since we can write immediately. - * - * However, we MUST always call check_write_watch(); DBusConnection code - * relies on the fact that running an iteration will notice that - * messages are pending. - */ - check_write_watch (transport); - - _dbus_verbose (" ... leaving do_iteration()\n"); -} - -/** - * Copy-paste from socket transport. - */ -static void -kdbus_live_messages_changed (DBusTransport *transport) -{ - /* See if we should look for incoming messages again */ - check_read_watch (transport); -} - -/** - * Gets file descriptor of the kdbus bus. - * @param transport transport - * @param fd_p place to write fd to - * @returns always TRUE - */ -static dbus_bool_t -kdbus_get_kdbus_fd (DBusTransport *transport, - int *fd_p) -{ - DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport; - - *fd_p = _kdbus_fd (kdbus_transport->kdbus); - - return TRUE; -} - -static const DBusTransportVTable kdbus_vtable = { - transport_finalize, - kdbus_handle_watch, - kdbus_disconnect, - kdbus_connection_set, - kdbus_do_iteration, - kdbus_live_messages_changed, - kdbus_get_kdbus_fd -}; - -typedef unsigned long (*ConnectionInfoExtractField) (struct nameInfo *); - -static inline unsigned long -_extract_name_info_userId (struct nameInfo *nameInfo) -{ - return nameInfo->userId; -} - -static inline unsigned long -_extract_name_info_processId (struct nameInfo *nameInfo) -{ - return nameInfo->processId; -} - -static dbus_bool_t -_dbus_transport_kdbus_get_connection_info_ulong_field (DBusTransport *transport, - ConnectionInfoExtractField function, - unsigned long *val) -{ - struct nameInfo conn_info; - int ret; - - ret = _kdbus_connection_info_by_id (get_kdbus (transport), - _kdbus_id (get_kdbus (transport)), - FALSE, - &conn_info); - if (ret != 0) - return FALSE; - - *val = function (&conn_info); - return TRUE; -} - -static dbus_bool_t -_dbus_transport_kdbus_get_unix_user (DBusTransport *transport, - unsigned long *uid) -{ - return _dbus_transport_kdbus_get_connection_info_ulong_field (transport, - _extract_name_info_userId, - uid); -} - -static dbus_bool_t -_dbus_transport_kdbus_get_unix_process_id (DBusTransport *transport, - unsigned long *pid) -{ - return _dbus_transport_kdbus_get_connection_info_ulong_field (transport, - _extract_name_info_processId, - pid); -} - -/** - * Copy-paste from dbus_transport_socket with needed changes. - * - * Creates a new transport for the given kdbus file descriptor and address. - * The file descriptor must be nonblocking. - * - * @param fd the file descriptor. - * @param address the transport's address - * @returns the new transport, or #NULL if no memory. - */ -static DBusTransport* -new_kdbus_transport (kdbus_t *kdbus, - const DBusString *address, - const char *activator) -{ - DBusTransportKdbus *kdbus_transport; - - kdbus_transport = dbus_new0 (DBusTransportKdbus, 1); - if (kdbus_transport == NULL) - return NULL; - - kdbus_transport->kdbus = kdbus; - - kdbus_transport->write_watch = _dbus_watch_new (_kdbus_fd (kdbus), - DBUS_WATCH_WRITABLE, - FALSE, - NULL, NULL, NULL); - if (kdbus_transport->write_watch == NULL) - goto failed_2; - - kdbus_transport->read_watch = _dbus_watch_new (_kdbus_fd (kdbus), - DBUS_WATCH_READABLE, - FALSE, - NULL, NULL, NULL); - if (kdbus_transport->read_watch == NULL) - goto failed_3; - - if (!_dbus_transport_init_base_authenticated (&kdbus_transport->base, - &kdbus_vtable, - NULL, address)) - goto failed_4; - - _dbus_transport_set_get_unix_user_function (&kdbus_transport->base, - _dbus_transport_kdbus_get_unix_user); - _dbus_transport_set_get_unix_process_id_function (&kdbus_transport->base, - _dbus_transport_kdbus_get_unix_process_id); - _dbus_transport_set_assure_protocol_function (&kdbus_transport->base, - _dbus_message_assure_gvariant); - - /* These values should probably be tunable or something. */ - kdbus_transport->max_bytes_read_per_iteration = MAX_BYTES_PER_ITERATION; - kdbus_transport->max_bytes_written_per_iteration = MAX_BYTES_PER_ITERATION; - - if (activator!=NULL) - { - int size = strlen (activator); - if (size) - { - kdbus_transport->activator = dbus_new (char, size + 1 ); - if (kdbus_transport->activator != NULL) - strcpy (kdbus_transport->activator, activator); - else - goto failed_4; - } - } - else - kdbus_transport->activator = NULL; - - kdbus_transport->matchmaker = matchmaker_new (); - - kdbus_transport->client_serial = 1; - - return (DBusTransport*) kdbus_transport; - - failed_4: - _dbus_watch_invalidate (kdbus_transport->read_watch); - _dbus_watch_unref (kdbus_transport->read_watch); - failed_3: - _dbus_watch_invalidate (kdbus_transport->write_watch); - _dbus_watch_unref (kdbus_transport->write_watch); - failed_2: - dbus_free (kdbus_transport); - return NULL; -} - -/** - * Connects to kdbus, creates and sets-up transport. - * - * @param path the path to the bus. - * @param error address where an error can be returned. - * @returns a new transport, or #NULL on failure. - */ -static DBusTransport* -_dbus_transport_new_for_kdbus (const char *path, - const char *activator, - DBusError *error) -{ - int ret; - DBusTransport *transport; - DBusString address; - kdbus_t *kdbus; - - const char *dbgenv = getenv ("G_DBUS_DEBUG"); - if (dbgenv != NULL) - { - if (!strcmp (dbgenv, "message")) - debug = 1; - else if (!strcmp (dbgenv, "all")) - debug = 2; - } - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - if (!_dbus_string_init (&address)) - { - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - return NULL; - } - - if ((!_dbus_string_append (&address, DBUS_ADDRESS_KDBUS "path=")) || (!_dbus_string_append (&address, path))) - { - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - goto failed_0; - } - - kdbus = _kdbus_new (); - if (NULL == kdbus) - { - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - goto failed_0; - } - - ret = _kdbus_open (kdbus, path); - if (ret < 0) - { - dbus_set_error (error, - _dbus_error_from_errno (-ret), - "Failed to open file descriptor: %s: %s", - path, - _dbus_strerror (-ret)); - goto failed_0_with_kdbus; - } - - _dbus_verbose ("Successfully connected to kdbus bus %s\n", path); - - transport = new_kdbus_transport (kdbus, &address, activator); - if (transport == NULL) - { - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - goto failed_1; - } - - _dbus_string_free (&address); - - return transport; - -failed_1: - _kdbus_close (kdbus); -failed_0_with_kdbus: - _kdbus_free (kdbus); -failed_0: - _dbus_string_free (&address); - return NULL; -} - - -/** - * Opens kdbus transport if method from address entry is kdbus - * - * @param entry the address entry to open - * @param transport_p return location for the opened transport - * @param error place to store error - * @returns result of the attempt as a DBusTransportOpenResult enum - */ -DBusTransportOpenResult -_dbus_transport_open_kdbus (DBusAddressEntry *entry, - DBusTransport **transport_p, - DBusError *error) -{ - const char *method; - - method = dbus_address_entry_get_method (entry); - _dbus_assert (method != NULL); - - if (strcmp (method, "kernel") == 0) - { - const char *path = dbus_address_entry_get_value (entry, "path"); - const char *activator = dbus_address_entry_get_value (entry, "activator"); - - if (path == NULL) - { - _dbus_set_bad_address (error, "kdbus", "path", NULL); - return DBUS_TRANSPORT_OPEN_BAD_ADDRESS; - } - - *transport_p = _dbus_transport_new_for_kdbus (path, activator, error); - - if (*transport_p == NULL) - { - _DBUS_ASSERT_ERROR_IS_SET (error); - return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; - } - else - { - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - return DBUS_TRANSPORT_OPEN_OK; - } - } - else - { - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - return DBUS_TRANSPORT_OPEN_NOT_HANDLED; - } -} - -/** @} */ diff --git a/dbus/dbus-transport-kdbus.h b/dbus/dbus-transport-kdbus.h deleted file mode 100644 index 75818f15..00000000 --- a/dbus/dbus-transport-kdbus.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* dbus-transport-kdbus.h kdbus subclasses of DBusTransport - * - * Copyright (C) 2013-2015 Samsung Electronics - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#ifndef DBUS_TRANSPORT_KDBUS_H_ -#define DBUS_TRANSPORT_KDBUS_H_ - -#include "dbus-transport-protected.h" - -#define REGISTER_FLAG_MONITOR 1 << 0 - -DBusTransportOpenResult _dbus_transport_open_kdbus (DBusAddressEntry *entry, - DBusTransport **transport_p, - DBusError *error); - -#endif diff --git a/dbus/dbus-transport-protected.h b/dbus/dbus-transport-protected.h index f6a5d501..396f0ffd 100644 --- a/dbus/dbus-transport-protected.h +++ b/dbus/dbus-transport-protected.h @@ -71,11 +71,6 @@ struct DBusTransportVTable /**< Get socket file descriptor */ }; -typedef dbus_bool_t (*DBusTransportGetUnixUserFunction) (DBusTransport *transport, - unsigned long *uid); -typedef dbus_bool_t (*DBusTransportGetUnixPIDFunction) (DBusTransport *transport, - unsigned long *uid); -typedef dbus_bool_t (*DBusTransportAssureProtocolFunction) (DBusMessage **message); /** * Object representing a transport such as a socket. * A transport can shuttle messages from point A to point B, @@ -114,10 +109,6 @@ struct DBusTransport void *windows_user_data; /**< Data for windows_user_function */ DBusFreeFunction free_windows_user_data; /**< Function to free windows_user_data */ - - DBusTransportGetUnixUserFunction get_unix_user_function; /**< Function for getting Unix user ID */ - DBusTransportGetUnixPIDFunction get_unix_process_id_function; /**< Function for getting Unix process ID */ - DBusTransportAssureProtocolFunction assure_protocol_function; /**< Function for converting messages, if needed */ unsigned int disconnected : 1; /**< #TRUE if we are disconnected. */ unsigned int authenticated : 1; /**< Cache of auth state; use _dbus_transport_peek_is_authenticated() to query value */ @@ -132,18 +123,8 @@ dbus_bool_t _dbus_transport_init_base (DBusTransport *transport, const DBusTransportVTable *vtable, const DBusString *server_guid, const DBusString *address); -dbus_bool_t _dbus_transport_init_base_authenticated (DBusTransport *transport, - const DBusTransportVTable *vtable, - const DBusString *server_guid, - const DBusString *address); void _dbus_transport_finalize_base (DBusTransport *transport); -void _dbus_transport_set_get_unix_user_function (DBusTransport *transport, - DBusTransportGetUnixUserFunction function); -void _dbus_transport_set_get_unix_process_id_function (DBusTransport *transport, - DBusTransportGetUnixPIDFunction function); -void _dbus_transport_set_assure_protocol_function (DBusTransport *transport, - DBusTransportAssureProtocolFunction function); typedef enum { diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index eacc6b89..ecc31827 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -2,7 +2,6 @@ /* dbus-transport.c DBusTransport object (internal to D-Bus implementation) * * Copyright (C) 2002, 2003 Red Hat Inc. - * Copyright (C) 2013 Samsung Electronics * * Licensed under the Academic Free License version 2.1 * @@ -33,9 +32,6 @@ #include "dbus-credentials.h" #include "dbus-mainloop.h" #include "dbus-message.h" -#ifdef ENABLE_KDBUS_TRANSPORT -#include "dbus-transport-kdbus.h" -#endif #ifdef DBUS_ENABLE_EMBEDDED_TESTS #include "dbus-server-debug-pipe.h" #endif @@ -89,58 +85,6 @@ live_messages_notify (DBusCounter *counter, _dbus_transport_unref (transport); } -static dbus_bool_t -_dbus_transport_default_get_unix_user (DBusTransport *transport, - unsigned long *uid) -{ - DBusCredentials *auth_identity; - - *uid = _DBUS_INT32_MAX; /* better than some root or system user in - * case of bugs in the caller. Caller should - * never use this value on purpose, however. - */ - - if (!transport->authenticated) - return FALSE; - - auth_identity = _dbus_auth_get_identity (transport->auth); - - if (_dbus_credentials_include (auth_identity, - DBUS_CREDENTIAL_UNIX_USER_ID)) - { - *uid = _dbus_credentials_get_unix_uid (auth_identity); - return TRUE; - } - else - return FALSE; -} - -static dbus_bool_t -_dbus_transport_default_get_unix_process_id (DBusTransport *transport, - unsigned long *pid) -{ - DBusCredentials *auth_identity; - - *pid = DBUS_PID_UNSET; /* Caller should never use this value on purpose, - * but we set it to a safe number, INT_MAX, - * just to root out possible bugs in bad callers. - */ - - if (!transport->authenticated) - return FALSE; - - auth_identity = _dbus_auth_get_identity (transport->auth); - - if (_dbus_credentials_include (auth_identity, - DBUS_CREDENTIAL_UNIX_PROCESS_ID)) - { - *pid = _dbus_credentials_get_pid (auth_identity); - return TRUE; - } - else - return FALSE; -} - /** * Initializes the base class members of DBusTransport. Chained up to * by subclasses in their constructor. The server GUID is the @@ -152,15 +96,13 @@ _dbus_transport_default_get_unix_process_id (DBusTransport *transport, * @param vtable the subclass vtable. * @param server_guid non-#NULL if this transport is on the server side of a connection * @param address the address of the transport - * @param with_auth TRUE if authentication should be used * @returns #TRUE on success. */ -static dbus_bool_t -_dbus_transport_init_base_with_auth (DBusTransport *transport, - const DBusTransportVTable *vtable, - const DBusString *server_guid, - const DBusString *address, - dbus_bool_t with_auth) +dbus_bool_t +_dbus_transport_init_base (DBusTransport *transport, + const DBusTransportVTable *vtable, + const DBusString *server_guid, + const DBusString *address) { DBusMessageLoader *loader; DBusAuth *auth; @@ -175,13 +117,7 @@ _dbus_transport_init_base_with_auth (DBusTransport *transport, if (server_guid) auth = _dbus_auth_server_new (server_guid); else - { - if (with_auth) - auth = _dbus_auth_client_new (); - else - auth = _dbus_auth_client_new_authenticated (); - } - + auth = _dbus_auth_client_new (); if (auth == NULL) { _dbus_message_loader_unref (loader); @@ -267,68 +203,9 @@ _dbus_transport_init_base_with_auth (DBusTransport *transport, if (transport->address) _dbus_verbose ("Initialized transport on address %s\n", transport->address); - transport->get_unix_user_function = _dbus_transport_default_get_unix_user; - transport->get_unix_process_id_function = _dbus_transport_default_get_unix_process_id; - transport->assure_protocol_function = _dbus_message_assure_dbus1; - return TRUE; } -dbus_bool_t -_dbus_transport_assure_protocol_version (DBusTransport *transport, - DBusMessage **message) -{ - return transport->assure_protocol_function (message); -} - -/** - * Initializes the base class members of DBusTransport. Chained up to - * by subclasses in their constructor. The server GUID is the - * globally unique ID for the server creating this connection - * and will be #NULL for the client side of a connection. The GUID - * is in hex format. - * - * @param transport the transport being created. - * @param vtable the subclass vtable. - * @param server_guid non-#NULL if this transport is on the server side of a connection - * @param address the address of the transport - * @returns #TRUE on success. - */ -dbus_bool_t -_dbus_transport_init_base (DBusTransport *transport, - const DBusTransportVTable *vtable, - const DBusString *server_guid, - const DBusString *address) -{ - return _dbus_transport_init_base_with_auth (transport, vtable, server_guid, address, TRUE); -} - -/** - * Initializes the base class members of DBusTransport. Chained up to - * by subclasses in their constructor. The server GUID is the - * globally unique ID for the server creating this connection - * and will be #NULL for the client side of a connection. The GUID - * is in hex format. Differs from _dbus_transport_init_base in that - * it sets auth as authenticated. This way auth negotiation is skipped. - * - * @param transport the transport being created. - * @param vtable the subclass vtable. - * @param server_guid non-#NULL if this transport is on the server side of a connection - * @param address the address of the transport - * @returns #TRUE on success. - */ -dbus_bool_t -_dbus_transport_init_base_authenticated (DBusTransport *transport, - const DBusTransportVTable *vtable, - const DBusString *server_guid, - const DBusString *address) -{ - dbus_bool_t result = _dbus_transport_init_base_with_auth (transport, vtable, server_guid, address, FALSE); - if (result) - transport->authenticated = TRUE; - return result; -} - /** * Finalizes base class members of DBusTransport. * Chained up to from subclass finalizers. @@ -470,9 +347,6 @@ static const struct { DBusTransport **transport_p, DBusError *error); } open_funcs[] = { -#ifdef ENABLE_KDBUS_TRANSPORT - { _dbus_transport_open_kdbus }, -#endif { _dbus_transport_open_socket }, { _dbus_transport_open_platform_specific }, { _dbus_transport_open_autolaunch } @@ -1426,47 +1300,6 @@ _dbus_transport_get_max_received_unix_fds (DBusTransport *transport) } /** - * Sets a function used to get UNIX user ID of the connection. - * See dbus_connection_get_unix_user(). - * - * @param transport the transport - * @param function the getter function - */ -void -_dbus_transport_set_get_unix_user_function (DBusTransport *transport, - DBusTransportGetUnixUserFunction function) -{ - transport->get_unix_user_function = function; -} - -/** - * Sets a function used to get process ID of the connection. - * See dbus_connection_get_unix_process_id(). - * - * @param transport the transport - * @param function the getter function - */ -void -_dbus_transport_set_get_unix_process_id_function (DBusTransport *transport, - DBusTransportGetUnixPIDFunction function) -{ - transport->get_unix_process_id_function = function; -} - -/** - * Sets a function used to assure that messages have correct protocol version - * - * @param transport the transport - * @param function the getter function - */ -void -_dbus_transport_set_assure_protocol_function (DBusTransport *transport, - DBusTransportAssureProtocolFunction function) -{ - transport->assure_protocol_function = function; -} - -/** * See dbus_connection_get_unix_user(). * * @param transport the transport @@ -1477,9 +1310,26 @@ dbus_bool_t _dbus_transport_get_unix_user (DBusTransport *transport, unsigned long *uid) { - if (transport->get_unix_user_function == NULL) + DBusCredentials *auth_identity; + + *uid = _DBUS_INT32_MAX; /* better than some root or system user in + * case of bugs in the caller. Caller should + * never use this value on purpose, however. + */ + + if (!transport->authenticated) + return FALSE; + + auth_identity = _dbus_auth_get_identity (transport->auth); + + if (_dbus_credentials_include (auth_identity, + DBUS_CREDENTIAL_UNIX_USER_ID)) + { + *uid = _dbus_credentials_get_unix_uid (auth_identity); + return TRUE; + } + else return FALSE; - return (transport->get_unix_user_function) (transport, uid); } /** @@ -1493,9 +1343,26 @@ dbus_bool_t _dbus_transport_get_unix_process_id (DBusTransport *transport, unsigned long *pid) { - if (transport->get_unix_process_id_function == NULL) + DBusCredentials *auth_identity; + + *pid = DBUS_PID_UNSET; /* Caller should never use this value on purpose, + * but we set it to a safe number, INT_MAX, + * just to root out possible bugs in bad callers. + */ + + if (!transport->authenticated) + return FALSE; + + auth_identity = _dbus_auth_get_identity (transport->auth); + + if (_dbus_credentials_include (auth_identity, + DBUS_CREDENTIAL_UNIX_PROCESS_ID)) + { + *pid = _dbus_credentials_get_pid (auth_identity); + return TRUE; + } + else return FALSE; - return (transport->get_unix_process_id_function) (transport, pid); } /** diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h index 0c9458d1..80fa24ef 100644 --- a/dbus/dbus-transport.h +++ b/dbus/dbus-transport.h @@ -98,10 +98,6 @@ dbus_bool_t _dbus_transport_set_auth_mechanisms (DBusTransport void _dbus_transport_set_allow_anonymous (DBusTransport *transport, dbus_bool_t value); -dbus_bool_t _dbus_transport_assure_protocol_version (DBusTransport *transport, - DBusMessage **message); - - /* if DBUS_ENABLE_STATS */ void _dbus_transport_get_stats (DBusTransport *transport, dbus_uint32_t *queue_bytes, diff --git a/dbus/kdbus-common.c b/dbus/kdbus-common.c deleted file mode 100644 index facd45a2..00000000 --- a/dbus/kdbus-common.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* kdbus-common.c kdbus related utils for daemon and libdbus - * - * Copyright (C) 2013 Samsung Electronics - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version and under the terms of the GNU - * Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#include "kdbus.h" -#include "kdbus-common.h" -#include "dbus-transport-kdbus.h" -#include <string.h> -#include <stddef.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <dbus/dbus-internals.h> -#include <dbus/dbus-shared.h> -#include "dbus-signals.h" -#include <stdio.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/mman.h> - -struct kdbus_t -{ - int fd; /**< File descriptor */ - void *mmap_ptr; /**< Mapped memory where kdbus (kernel) writes - * messages incoming to us. - */ - size_t pool_size; /**< Size of mapped memory */ - __u64 id; /**< unique id of the connection */ - char bus_id[sizeof(((struct kdbus_cmd_hello *)(0))->id128)]; /**< id of the bus */ - struct kdbus_bloom_parameter bloom; /**< bloom parameters*/ -}; - -/** temporary accessors - to delete soon */ -int _kdbus_fd (kdbus_t *kdbus) { return kdbus->fd; } -void *_kdbus_mmap_ptr (kdbus_t *kdbus) { return kdbus->mmap_ptr; } -dbus_uint64_t _kdbus_id (kdbus_t *kdbus) { return kdbus->id; } -char *_kdbus_bus_id (kdbus_t *kdbus) { return kdbus->bus_id; } -dbus_uint64_t _kdbus_bus_id_size (void) { return sizeof(((struct kdbus_t *)(0))->bus_id); } -struct kdbus_bloom_parameter *_kdbus_bloom (kdbus_t *kdbus) { return &kdbus->bloom; } - - - -/* ALIGN8 and KDBUS_FOREACH taken from systemd */ -#define ALIGN8(l) (((l) + 7) & ~7) -#define KDBUS_FOREACH(iter, first, _size) \ - for (iter = (first); \ - ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \ - ((uint8_t *)(iter) >= (uint8_t *)(first)); \ - iter = (void*)(((uint8_t *)iter) + ALIGN8((iter)->size))) - -static int -safe_ioctl (int fd, - unsigned long request, - void *data) -{ - int ret; - - do { - ret = ioctl (fd, request, data); - } - while (-1 == ret && EINTR == errno); - - return ret; -} - -static int -free_by_offset (kdbus_t *kdbus, - __u64 offset) -{ - struct kdbus_cmd_free cmd; - - cmd.size = sizeof (cmd); - cmd.offset = offset; - cmd.flags = 0; - - if (safe_ioctl (kdbus->fd, KDBUS_CMD_FREE, &cmd )!= 0) - return errno; - - return 0; -} - -static void make_item_name(const char *name, struct kdbus_item *item) -{ - size_t len = strlen(name) + 1; - item->size = KDBUS_ITEM_HEADER_SIZE + len; - item->type = KDBUS_ITEM_NAME; - - memcpy(item->str, name, len); -} - -/** - * Adds an item in the current position of items array. - * - * @param item item to fill - * @param item_type type of the item - * @param string value of the item - * @param string_size size of the value - * @returns pointer to the next item - */ -struct kdbus_item * -_kdbus_item_add_string (struct kdbus_item *item, - dbus_uint64_t item_type, - const char *item_string, - dbus_uint64_t item_string_size) -{ - item->size = KDBUS_ITEM_HEADER_SIZE + item_string_size; - item->type = item_type; - memcpy (item->str, item_string, item_string_size); - return KDBUS_ITEM_NEXT (item); -} - -struct kdbus_item * -_kdbus_item_add_payload_memfd (struct kdbus_item *item, - dbus_uint64_t start, - dbus_uint64_t size, - int fd) -{ - item->type = KDBUS_ITEM_PAYLOAD_MEMFD; - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof (struct kdbus_memfd); - item->memfd.start = start; - item->memfd.size = size; - item->memfd.fd = fd; - return KDBUS_ITEM_NEXT (item); -} - -struct kdbus_item * -_kdbus_item_add_payload_vec (struct kdbus_item *item, - dbus_uint64_t size, - dbus_uint64_t address_or_offset) -{ - item->type = KDBUS_ITEM_PAYLOAD_VEC; - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof (struct kdbus_vec); - item->vec.size = size; - item->vec.address = address_or_offset; - return KDBUS_ITEM_NEXT (item); -} - -struct kdbus_item * -_kdbus_item_add_fds (struct kdbus_item *item, - const int *fds, - int fds_count) -{ - item->type = KDBUS_ITEM_FDS; - item->size = KDBUS_ITEM_HEADER_SIZE + fds_count * sizeof (int); - memcpy (item->fds, fds, fds_count * sizeof (int)); - return KDBUS_ITEM_NEXT (item); -} - -struct kdbus_item * -_kdbus_item_add_bloom_filter (struct kdbus_item *item, - dbus_uint64_t data_size, - struct kdbus_bloom_filter **out_ptr) -{ - item->type = KDBUS_ITEM_BLOOM_FILTER; - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof (struct kdbus_bloom_filter) + data_size; - *out_ptr = &item->bloom_filter; - return KDBUS_ITEM_NEXT (item); -} - -struct kdbus_item * -_kdbus_item_add_name_change (struct kdbus_item *item, - dbus_uint64_t old_id, - dbus_uint64_t old_id_flags, - dbus_uint64_t new_id, - dbus_uint64_t new_id_flags) -{ - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof (struct kdbus_notify_name_change); - item->type = KDBUS_ITEM_NAME_CHANGE; - item->name_change.old_id.id = old_id; - item->name_change.old_id.flags = old_id_flags; - item->name_change.new_id.id = new_id; - item->name_change.new_id.flags = new_id_flags; - return KDBUS_ITEM_NEXT (item); -} - -struct kdbus_item * -_kdbus_item_add_id_add (struct kdbus_item *item, - dbus_uint64_t id, - dbus_uint64_t id_flags) -{ - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof (struct kdbus_notify_id_change); - item->type = KDBUS_ITEM_ID_ADD; - item->id_change.id = id; - item->id_change.flags = id_flags; - return KDBUS_ITEM_NEXT (item); -} - -struct kdbus_item * -_kdbus_item_add_id (struct kdbus_item *item, - dbus_uint64_t id) -{ - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof (struct kdbus_notify_id_change); - item->type = KDBUS_ITEM_ID; - item->id = id; - return KDBUS_ITEM_NEXT (item); -} - -struct kdbus_item * -_kdbus_item_add_bloom_mask (struct kdbus_item *item, - dbus_uint64_t *bloom, - dbus_uint64_t bloom_size) -{ - item->size = KDBUS_ITEM_HEADER_SIZE + bloom_size; - item->type = KDBUS_ITEM_BLOOM_MASK; - memcpy (item->data, bloom, bloom_size); - return KDBUS_ITEM_NEXT (item); -} - -static inline void * -get_from_offset (kdbus_t *kdbus, - __u64 offset) -{ - return ((char *)kdbus->mmap_ptr) + offset; -} - -kdbus_t * -_kdbus_new () -{ - return dbus_new (kdbus_t, 1); -} - -void -_kdbus_free (kdbus_t *kdbus) -{ - dbus_free (kdbus); -} - -/** - * Opens a connection to the kdbus bus - * - * @param kdbus kdbus object - * @param path the path to kdbus bus - * @returns 0 on success, -errno on failure - */ -int -_kdbus_open (kdbus_t *kdbus, const char *path) -{ - int fd = open (path, O_RDWR|O_CLOEXEC|O_NONBLOCK); - if (-1 == fd) - return -errno; - - kdbus->fd = fd; - return 0; -} - -int -_kdbus_close (kdbus_t *kdbus) -{ - int ret; - int errclose = 0; - int errunmap = 0; - - do - { - ret = close (kdbus->fd); - } while (-1 == ret && EINTR == errno); - if (-1 == ret) - errclose = errno; - - ret = munmap (kdbus->mmap_ptr, kdbus->pool_size); - if (-1 == ret) - errunmap = errno; - - if (0 != errclose) - return -errclose; - if (0 != errunmap) - return -errunmap; - return 0; -} - -int -_kdbus_hello (kdbus_t *kdbus, - dbus_uint64_t flags, - dbus_uint64_t attach_flags_send, - dbus_uint64_t attach_flags_recv, - dbus_uint64_t pool_size, - const char *activator_name, - const char *connection_name) -{ - struct kdbus_cmd_hello *hello; - struct kdbus_item *item, *items; - __u64 hello_size; - size_t activator_name_size = 0; - size_t connection_name_size = 0; - __u64 offset; - __u64 items_size; - - hello_size = sizeof (struct kdbus_cmd_hello); - - if (NULL != activator_name) - { - activator_name_size = strlen (activator_name) + 1; - hello_size += KDBUS_ITEM_SIZE (activator_name_size); - } - - if (NULL != connection_name) - { - connection_name_size = strlen (connection_name) + 1; - hello_size += KDBUS_ITEM_SIZE (connection_name_size); - } - - hello = dbus_malloc (hello_size); - if (NULL == hello) - return -ENOMEM; - - hello->flags = flags; - hello->attach_flags_send = attach_flags_send; - hello->attach_flags_recv = attach_flags_recv; - hello->pool_size = pool_size; - - item = hello->items; - if (connection_name_size > 0) - item = _kdbus_item_add_string (item, - KDBUS_ITEM_CONN_DESCRIPTION, - connection_name, - connection_name_size); - if (activator_name_size > 0) - { - _kdbus_item_add_string (item, - KDBUS_ITEM_NAME, - activator_name, - activator_name_size); - hello->flags |= KDBUS_HELLO_ACTIVATOR; - } - - hello->size = hello_size; - - if (safe_ioctl (kdbus->fd, KDBUS_CMD_HELLO, hello) != 0) - { - dbus_free (hello); - return -errno; - } - - kdbus->id = hello->id; - memcpy (kdbus->bus_id, hello->id128, sizeof (kdbus->bus_id)); - - offset = hello->offset; - items_size = hello->items_size; - dbus_free (hello); - - kdbus->mmap_ptr = mmap (NULL, pool_size, PROT_READ, MAP_SHARED, kdbus->fd, 0); - if (MAP_FAILED == kdbus->mmap_ptr) - return -errno; - - kdbus->pool_size = pool_size; - - items = get_from_offset (kdbus, offset); - KDBUS_FOREACH (item, items, items_size) - { - if (KDBUS_ITEM_BLOOM_PARAMETER == item->type) - kdbus->bloom = item->bloom_parameter; - } - - return 0; -} - -int -_kdbus_send (kdbus_t *kdbus, - dbus_uint64_t flags, - struct kdbus_msg *msg, - struct kdbus_msg **msg_reply) -{ - struct kdbus_cmd_send cmd; - - cmd.size = sizeof(cmd); - cmd.msg_address = (__u64)msg; - cmd.flags = flags; - - if (-1 == safe_ioctl (kdbus->fd, KDBUS_CMD_SEND, &cmd)) - return errno; - - if (flags & KDBUS_SEND_SYNC_REPLY) - { - if (NULL != msg_reply) - *msg_reply = get_from_offset (kdbus, cmd.reply.offset); - else - free_by_offset (kdbus, cmd.reply.offset); - } - - return 0; -} - -int -_kdbus_recv (kdbus_t *kdbus, - dbus_uint64_t flags, - dbus_int64_t priority, - struct kdbus_msg **msg) -{ - struct kdbus_cmd_recv cmd; - - cmd.size = sizeof (cmd); - cmd.flags = flags; - cmd.priority = priority; - - if (-1 == safe_ioctl (kdbus->fd, KDBUS_CMD_RECV, &cmd)) - return errno; - - *msg = get_from_offset (kdbus, cmd.msg.offset); - - return 0; -} - -int -_kdbus_list (kdbus_t *kdbus, - dbus_uint64_t flags, - struct kdbus_info **name_list, - dbus_uint64_t *list_size) -{ - struct kdbus_cmd_list cmd; - - cmd.size = sizeof (cmd); - cmd.flags = flags; - - if (-1 == safe_ioctl (kdbus->fd, KDBUS_CMD_LIST, &cmd)) - return errno; - - *name_list = get_from_offset (kdbus, cmd.offset); - *list_size = cmd.list_size; - - return 0; -} - -struct kdbus_cmd_match * -_kdbus_new_cmd_match (kdbus_t *kdbus, - dbus_uint64_t items_size, - dbus_uint64_t flags, - dbus_uint64_t cookie) -{ - struct kdbus_cmd_match *cmd; - dbus_uint64_t cmd_size = sizeof (*cmd) + items_size; - cmd = dbus_malloc (cmd_size); - if (NULL == cmd) - return NULL; - - cmd->size = cmd_size; - cmd->flags = flags; - cmd->cookie = cookie; - - return cmd; -} - -void -_kdbus_free_cmd_match (struct kdbus_cmd_match *cmd) -{ - dbus_free (cmd); -} - -int -_kdbus_add_match_name_change (kdbus_t *kdbus, - dbus_uint64_t flags, - dbus_uint64_t cookie, - dbus_uint64_t old_id, - dbus_uint64_t old_id_flags, - dbus_uint64_t new_id, - dbus_uint64_t new_id_flags) -{ - struct kdbus_cmd_match *cmd; - struct kdbus_item *item; - int ret; - - cmd = _kdbus_new_cmd_match (kdbus, - KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_name_change)), - flags, - cookie); - if (NULL == cmd) - return ENOMEM; - - item = cmd->items; - _kdbus_item_add_name_change (item, - old_id, old_id_flags, - new_id, new_id_flags); - - ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd); - if (0 == ret) - { - item->type = KDBUS_ITEM_NAME_ADD; - ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd); - if (0 == ret) - { - item->type = KDBUS_ITEM_NAME_REMOVE; - ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd); - } - } - - if (0 != ret) - ret = errno; - - _kdbus_free_cmd_match (cmd); - return ret; -} - -int -_kdbus_add_match_id_change (kdbus_t *kdbus, - dbus_uint64_t flags, - dbus_uint64_t cookie, - dbus_uint64_t id, - dbus_uint64_t id_flags) -{ - struct kdbus_cmd_match *cmd; - struct kdbus_item *item; - int ret; - - cmd = _kdbus_new_cmd_match (kdbus, - KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_id_change)), - flags, - cookie); - if (NULL == cmd) - return ENOMEM; - - item = cmd->items; - _kdbus_item_add_id_add (item, id, id_flags); - - ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd); - if (0 == ret) - { - item->type = KDBUS_ITEM_ID_REMOVE; - ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd); - } - - if (0 != ret) - ret = errno; - - _kdbus_free_cmd_match (cmd); - return ret; -} - -int _kdbus_add_match (kdbus_t *kdbus, - struct kdbus_cmd_match *cmd) -{ - int ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd); - if (0 != ret) - return errno; - - return 0; -} - -/** - * Allocates and initializes kdbus message structure. - * @param kdbus kdbus object - * @param size_for_items size of items that will be attached to this message - * @param flags flags for message - * @returns initialized kdbus message or NULL if malloc failed - */ -struct kdbus_msg * -_kdbus_new_msg (kdbus_t *kdbus, - dbus_uint64_t size_for_items, - dbus_uint64_t flags, - dbus_int64_t priority, - dbus_uint64_t dst_id, - dbus_uint64_t src_id, - enum kdbus_payload_type payload_type, - dbus_uint64_t cookie, - dbus_uint64_t timeout_ns_or_cookie_reply) -{ - struct kdbus_msg *msg; - dbus_uint64_t msg_size = sizeof (struct kdbus_msg) + size_for_items; - - msg = dbus_malloc (msg_size); - if (NULL == msg) - return NULL; - - msg->size = msg_size; - msg->flags = flags; - msg->priority = priority; - msg->dst_id = dst_id; - msg->src_id = src_id; - msg->payload_type = payload_type; - msg->cookie = cookie; - msg->timeout_ns = timeout_ns_or_cookie_reply; - - return msg; -} - -void -_kdbus_free_msg (struct kdbus_msg *msg) -{ - dbus_free (msg); -} - -int -_kdbus_free_mem (kdbus_t *kdbus, void *mem) -{ - char *base_ptr = kdbus->mmap_ptr; - char *mem_ptr = (char *)mem; - - return free_by_offset (kdbus, mem_ptr - base_ptr); -} - -/** - * Computes size of items that will be attached to a message. - * - * @param kdbus kdbus object - * @param destination Well-known name or NULL. If NULL, dst_id must be supplied. - * @param dst_id Numeric id of recipient. Ignored if name is not NULL. - * @param body_size Size of message body (may be 0). - * @param use_memfd Flag to build memfd message. - * @param fds_count Number of file descriptors sent in the message. - * @returns size in bytes needed for the message object - */ -dbus_uint64_t -_kdbus_compute_msg_items_size (kdbus_t *kdbus, - const char *destination, - dbus_uint64_t dst_id, - dbus_uint64_t body_size, - dbus_bool_t use_memfd, - int fds_count) -{ - dbus_uint64_t items_size = 0; - - if (use_memfd) - { - items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_memfd)); - } - else - { - dbus_uint64_t vectors = (body_size + KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE - 1) - / KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE; - /* 1st vector -> for header */ - items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec)); - /* subsequent vectors -> parts of body */ - items_size += vectors * KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec)); - } - - if (fds_count > 0) - items_size += KDBUS_ITEM_SIZE (sizeof (int) * fds_count); - - if (destination) - items_size += KDBUS_ITEM_SIZE (strlen (destination) + 1); - else if (KDBUS_DST_ID_BROADCAST == dst_id) - items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_bloom_filter)) - + kdbus->bloom.size; - return items_size; -} - -/** - * - * Asks the bus to assign the given name to the connection. - * - * Use same flags as original dbus version with one exception below. - * Result flag #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER is currently - * never returned by kdbus, instead DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER - * is returned by kdbus. - * - * @param transport transport of the connection - * @param name the name to request - * @param flags flags - * @returns a DBus result code on success, -errno on error - */ -int -request_kdbus_name(DBusTransport *transport, - const char *name, - const __u64 flags) -{ - struct kdbus_cmd *cmd_name; - int fd; - size_t len = strlen(name) + 1; - - __u64 size = sizeof(*cmd_name) + KDBUS_ITEM_SIZE(len); - __u64 flags_kdbus = 0; - - if(!_dbus_transport_get_socket_fd (transport, &fd)) - return FALSE; - - cmd_name = alloca(size); - cmd_name->size = size; - - if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT) - flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT; - if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE)) - flags_kdbus |= KDBUS_NAME_QUEUE; - if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) - flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING; - - cmd_name->flags = flags_kdbus; - make_item_name(name, &(cmd_name->items[0])); - - _dbus_verbose("Request name - flags sent: 0x%llx !!!!!!!!!\n", cmd_name->flags); - - if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name) < 0) - { - _dbus_verbose ("error acquiring name '%s': %m, %d\n", name, errno); - if(errno == EEXIST) - return DBUS_REQUEST_NAME_REPLY_EXISTS; - if(errno == EALREADY) - return DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER; - return -errno; - } - else if ((cmd_name->return_flags & KDBUS_NAME_PRIMARY) - && !(cmd_name->return_flags & KDBUS_NAME_ACQUIRED)) - return DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER; - - _dbus_verbose("Request name - received flag: 0x%llx !!!!!!!!!\n", cmd_name->flags); - - if(cmd_name->return_flags & KDBUS_NAME_IN_QUEUE) - return DBUS_REQUEST_NAME_REPLY_IN_QUEUE; - - return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER; -} - -/** - * - * Releases well-known name - the connections resign from the name - * which can be then assigned to another connection or the connection - * is being removed from the queue for that name - * - * @param fd - file descriptor of the connection - * @param name the name to request - * @param id unique id of the connection for which the name is being released - * @returns a DBus result code on success, -errno on error - */ -int -release_kdbus_name(DBusTransport *transport, - const char *name) -{ - struct kdbus_cmd *cmd_name; - int fd; - - size_t len = strlen(name)+1; - __u64 size = sizeof(*cmd_name) + KDBUS_ITEM_SIZE(len); - - if(!_dbus_transport_get_socket_fd (transport, &fd)) - return FALSE; - - cmd_name = alloca(size); - cmd_name->size = size; - cmd_name->flags = 0; - make_item_name(name, &(cmd_name->items[0])); - - if (ioctl(fd, KDBUS_CMD_NAME_RELEASE, cmd_name)) - { - if((errno == ESRCH)) - return DBUS_RELEASE_NAME_REPLY_NON_EXISTENT; - else if (errno == EADDRINUSE) - return DBUS_RELEASE_NAME_REPLY_NOT_OWNER; - _dbus_verbose ("error releasing name '%s'. Error: %m, %d\n", name, errno); - return -errno; - } - - _dbus_verbose("Name '%s' released\n", name); - - return DBUS_RELEASE_NAME_REPLY_RELEASED; -} - -static int -decode_connection_info (struct kdbus_info *connection_info, - struct nameInfo *pInfo, - dbus_bool_t get_sec_label) -{ - struct kdbus_item *item; - - memset (pInfo, 0, sizeof(*pInfo)); - - pInfo->uniqueId = connection_info->id; - pInfo->flags = connection_info->flags; - - item = connection_info->items; - - while ((uint8_t *)item < ((uint8_t *)connection_info) + connection_info->size) - { - switch (item->type) - { - case KDBUS_ITEM_PIDS: - pInfo->processId = item->pids.pid; - break; - case KDBUS_ITEM_CREDS: - pInfo->userId = item->creds.uid; - break; - case KDBUS_ITEM_SECLABEL: - if (get_sec_label) - { - pInfo->sec_label_len = item->size - KDBUS_ITEM_HEADER_SIZE - 1; - if (0 != pInfo->sec_label_len) - { - pInfo->sec_label = dbus_malloc (pInfo->sec_label_len); - if (NULL == pInfo->sec_label) - return ENOMEM; - - memcpy (pInfo->sec_label, item->data, pInfo->sec_label_len); - } - } - break; - } - - item = KDBUS_ITEM_NEXT (item); - } - return 0; -} - -static int -process_connection_info_cmd (kdbus_t *kdbus, - struct kdbus_cmd_info *cmd, - struct nameInfo *pInfo, - dbus_bool_t get_sec_label) -{ - int ret; - struct kdbus_info *kdbus_info; - - if (NULL == cmd) - return -1; - - ret = safe_ioctl (kdbus->fd, KDBUS_CMD_CONN_INFO, cmd); - - if (ret < 0) - { - pInfo->uniqueId = 0; - return errno; - } - - kdbus_info = get_from_offset (kdbus, cmd->offset); - ret = decode_connection_info (kdbus_info, - pInfo, - get_sec_label); - if (ret != 0) - return ret; - - ret = free_by_offset (kdbus, cmd->offset); - if (ret != 0) - { - _dbus_verbose("kdbus error freeing pool: %d (%m)\n", errno); - if (get_sec_label) - { - free(pInfo->sec_label); - pInfo->sec_label = NULL; - } - } - - dbus_free (cmd); - - return ret; -} - -static struct kdbus_cmd_info * -prepare_connection_info_cmd (dbus_uint64_t id, - const char *name, - dbus_bool_t get_sec_label) -{ - struct kdbus_cmd_info *cmd; - dbus_uint64_t size = sizeof(*cmd); - if (NULL != name) - { - size += KDBUS_ITEM_SIZE (strlen (name) + 1); - } - cmd = dbus_malloc (size); - if (NULL == cmd) - return NULL; - - cmd->size = size; - cmd->id = id; - if (0 == id) - make_item_name (name, &(cmd->items[0])); - - cmd->attach_flags = KDBUS_ATTACH_CREDS | KDBUS_ATTACH_PIDS; - if (get_sec_label) - cmd->attach_flags |= KDBUS_ATTACH_SECLABEL; - - cmd->flags = 0; - - return cmd; -} - -/** - * Gets connection info for the given unique id. - * - * @param transport transport - * @param id unique id to query for - * @param get_sec_label #TRUE if sec_label field in pInfo should be filled - * @param pInfo nameInfo structure address to store info about the name - * @return 0 on success, errno if failed - * - * @note If you specify #TRUE in get_sec_label param, you must free - * pInfo.sec_label with dbus_free() after use. - */ -int -_kdbus_connection_info_by_id (kdbus_t *kdbus, - dbus_uint64_t id, - dbus_bool_t get_sec_label, - struct nameInfo *pInfo) -{ - struct kdbus_cmd_info *cmd = prepare_connection_info_cmd (id, NULL, get_sec_label); - - return process_connection_info_cmd (kdbus, cmd, pInfo, get_sec_label); -} - -/** - * Gets connection info for the given name - * - * @param transport transport - * @param name name to query for - * @param get_sec_label #TRUE if sec_label field in pInfo should be filled - * @param pInfo nameInfo structure address to store info about the name - * @return 0 on success, errno if failed - * - * @note If you specify #TRUE in get_sec_label param, you must free - * pInfo.sec_label with dbus_free() after use. - */ -int -_kdbus_connection_info_by_name (kdbus_t *kdbus, - const char *name, - dbus_bool_t get_sec_label, - struct nameInfo *pInfo) -{ - struct kdbus_cmd_info *cmd; - - /* if name starts with ":1." it is a unique name and should be send as number */ - if((name[0] == ':') && (name[1] == '1') && (name[2] == '.')) - { - return _kdbus_connection_info_by_id (kdbus, - strtoull(&name[3], NULL, 10), - get_sec_label, - pInfo); - } - - cmd = prepare_connection_info_cmd (0, name, get_sec_label); - - return process_connection_info_cmd (kdbus, cmd, pInfo, get_sec_label); -} - -/** - * Opposing to dbus, in kdbus removes all match rules with given - * cookie, which in this implementation is equal to uniqe id. - * - * @param transport transport - * @param id connection id for which rules are to be removed - * @param cookie cookie of the rules to be removed - */ -static dbus_bool_t -remove_match_kdbus (DBusTransport *transport, - __u64 cookie) -{ - struct kdbus_cmd_match cmd; - int fd; - - if(!_dbus_transport_get_socket_fd(transport, &fd)) - return FALSE; - - cmd.cookie = cookie; - cmd.size = sizeof(struct kdbus_cmd_match); - cmd.flags = 0; - - if(ioctl(fd, KDBUS_CMD_MATCH_REMOVE, &cmd)) - { - _dbus_verbose("Failed removing match rule %llu, error: %d, %m\n", cookie, errno); - return FALSE; - } - else - { - _dbus_verbose("Match rule %llu removed correctly.\n", cookie); - return TRUE; - } -} - -/* - * Removes match rule in kdbus on behalf of sender of the message - */ -dbus_bool_t -kdbus_remove_match (DBusTransport *transport, - DBusList *rules, - const char *sender, - MatchRule *rule_to_remove, - DBusError *error) -{ - __u64 cookie = 0; - DBusList *link = NULL; - - if (rules != NULL) - { - /* we traverse backward because bus_connection_remove_match_rule() - * removes the most-recently-added rule - */ - link = _dbus_list_get_last_link (&rules); - while (link != NULL) - { - MatchRule *rule; - DBusList *prev; - - rule = link->data; - prev = _dbus_list_get_prev_link (&rules, link); - - if (match_rule_equal_lib (rule, rule_to_remove)) - { - cookie = match_rule_get_cookie(rule); - break; - } - - link = prev; - } - } - - if(cookie == 0) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_NOT_FOUND, - "The given match rule wasn't found and can't be removed"); - return FALSE; - } - - if(!remove_match_kdbus (transport, cookie)) - { - dbus_set_error (error, _dbus_error_from_errno (errno), "Could not remove match rule"); - return FALSE; - } - - return TRUE; -} diff --git a/dbus/kdbus-common.h b/dbus/kdbus-common.h deleted file mode 100644 index cea606e0..00000000 --- a/dbus/kdbus-common.h +++ /dev/null @@ -1,197 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* kdbus-common.h kdbus related utils for daemon and libdbus - * - * Copyright (C) 2013 Samsung Electronics - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version and under the terms of the GNU - * Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef KDBUS_COMMON_H_ -#define KDBUS_COMMON_H_ - -#include <dbus/dbus-types.h> -#include <dbus/dbus-transport.h> -#include "dbus-signals.h" -#include "kdbus.h" - -#define KDBUS_ALIGN8(l) (((l) + 7) & ~7) - -#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) -#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8(KDBUS_ITEM_HEADER_SIZE + (s)) -#define KDBUS_ITEM_NEXT(item) \ - (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size)) -#define KDBUS_ITEM_FOREACH(item, head, first) \ - for (item = (head)->first; \ - (uint8_t *)(item) < (uint8_t *)(head) + (head)->size; \ - item = KDBUS_ITEM_NEXT(item)) - -#define KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE 0x00200000 /* maximum size of message header and items */ - -struct nameInfo -{ - __u64 uniqueId; - __u64 flags; - __u64 userId; - __u64 processId; - __u32 sec_label_len; - char *sec_label; -}; - -typedef struct kdbus_t kdbus_t; - -kdbus_t * _kdbus_new (void); -void _kdbus_free (kdbus_t *kdbus); - -int _kdbus_open (kdbus_t *kdbus, const char *path); -int _kdbus_close (kdbus_t *kdbus); - -int _kdbus_hello (kdbus_t *kdbus, - dbus_uint64_t flags, - dbus_uint64_t attach_flags_send, - dbus_uint64_t attach_flags_recv, - dbus_uint64_t pool_size, - const char *activator_name, - const char *connection_name); - -int _kdbus_send (kdbus_t *kdbus, - dbus_uint64_t flags, - struct kdbus_msg *msg, - struct kdbus_msg **msg_reply); - -int _kdbus_recv (kdbus_t *kdbus, - dbus_uint64_t flags, - dbus_int64_t priority, - struct kdbus_msg **msg); - -int _kdbus_list (kdbus_t *kdbus, - dbus_uint64_t flags, - struct kdbus_info **name_list, - dbus_uint64_t *list_size); - -int _kdbus_add_match_name_change (kdbus_t *kdbus, - dbus_uint64_t flags, - dbus_uint64_t cookie, - dbus_uint64_t old_id, - dbus_uint64_t old_id_flags, - dbus_uint64_t new_id, - dbus_uint64_t new_id_flags); - -int _kdbus_add_match_id_change (kdbus_t *kdbus, - dbus_uint64_t flags, - dbus_uint64_t cookie, - dbus_uint64_t id, - dbus_uint64_t id_flags); - -int _kdbus_add_match (kdbus_t *kdbus, - struct kdbus_cmd_match *cmd); - -int _kdbus_connection_info_by_name (kdbus_t *kdbus, - const char *name, - dbus_bool_t get_sec_label, - struct nameInfo *pInfo); - -int _kdbus_connection_info_by_id (kdbus_t *kdbus, - dbus_uint64_t id, - dbus_bool_t get_sec_label, - struct nameInfo *pInfo); - -dbus_uint64_t _kdbus_compute_msg_items_size (kdbus_t *kdbus, - const char *destination, - dbus_uint64_t dst_id, - dbus_uint64_t body_size, - dbus_bool_t use_memfd, - int fds_count); - -struct kdbus_msg * _kdbus_new_msg (kdbus_t *kdbus, - dbus_uint64_t size_for_items, - dbus_uint64_t flags, - dbus_int64_t priority, - dbus_uint64_t dst_id, - dbus_uint64_t src_id, - enum kdbus_payload_type payload_type, - dbus_uint64_t cookie, - dbus_uint64_t timeout_ns_or_cookie_reply); - -void _kdbus_free_msg (struct kdbus_msg *msg); - -struct kdbus_cmd_match *_kdbus_new_cmd_match (kdbus_t *kdbus, - dbus_uint64_t items_size, - dbus_uint64_t flags, - dbus_uint64_t cookie); - -void _kdbus_free_cmd_match (struct kdbus_cmd_match *cmd); - -int _kdbus_free_mem (kdbus_t *kdbus, void *mem); - -struct kdbus_item * _kdbus_item_add_string (struct kdbus_item *item, - dbus_uint64_t item_type, - const char *item_string, - dbus_uint64_t item_string_size); - -struct kdbus_item * _kdbus_item_add_payload_memfd (struct kdbus_item *item, - dbus_uint64_t start, - dbus_uint64_t size, - int fd); - -struct kdbus_item * _kdbus_item_add_payload_vec (struct kdbus_item *item, - dbus_uint64_t size, - dbus_uint64_t address_or_offset); - -struct kdbus_item * _kdbus_item_add_fds (struct kdbus_item *item, - const int *fds, - int fds_count); - -struct kdbus_item * _kdbus_item_add_bloom_filter (struct kdbus_item *item, - dbus_uint64_t data_size, - struct kdbus_bloom_filter **out_ptr); - -struct kdbus_item * _kdbus_item_add_name_change (struct kdbus_item *item, - dbus_uint64_t old_id, - dbus_uint64_t old_id_flags, - dbus_uint64_t new_id, - dbus_uint64_t new_id_flags); - -struct kdbus_item * _kdbus_item_add_id_add (struct kdbus_item *item, - dbus_uint64_t id, - dbus_uint64_t id_flags); - -struct kdbus_item * _kdbus_item_add_id (struct kdbus_item *item, - dbus_uint64_t id); - -struct kdbus_item * _kdbus_item_add_bloom_mask (struct kdbus_item *item, - dbus_uint64_t *bloom, - dbus_uint64_t bloom_size); - -int request_kdbus_name (DBusTransport* transport, const char *name, const __u64 flags); -int release_kdbus_name (DBusTransport* transport, const char *name); - -dbus_bool_t kdbus_remove_match (DBusTransport *transport, DBusList *rules, const char *sender, - MatchRule *rule_to_remove, DBusError *error); - -/** temporary accessors - to delete soon */ -int _kdbus_fd (kdbus_t *kdbus); -void *_kdbus_mmap_ptr (kdbus_t *kdbus); -dbus_uint64_t _kdbus_id (kdbus_t *kdbus); -char *_kdbus_bus_id (kdbus_t *kdbus); -dbus_uint64_t _kdbus_bus_id_size (void); -struct kdbus_bloom_parameter *_kdbus_bloom (kdbus_t *kdbus); - -#endif /* KDBUS_COMMON_H_ */ diff --git a/dbus/kdbus.h b/dbus/kdbus.h deleted file mode 100644 index 4fc44cb1..00000000 --- a/dbus/kdbus.h +++ /dev/null @@ -1,984 +0,0 @@ -/* - * kdbus is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - */ - -#ifndef _UAPI_KDBUS_H_ -#define _UAPI_KDBUS_H_ - -#include <linux/ioctl.h> -#include <linux/types.h> - -#define KDBUS_IOCTL_MAGIC 0x95 -#define KDBUS_SRC_ID_KERNEL (0) -#define KDBUS_DST_ID_NAME (0) -#define KDBUS_MATCH_ID_ANY (~0ULL) -#define KDBUS_DST_ID_BROADCAST (~0ULL) -#define KDBUS_FLAG_NEGOTIATE (1ULL << 63) - -/** - * struct kdbus_notify_id_change - name registry change message - * @id: New or former owner of the name - * @flags: flags field from KDBUS_HELLO_* - * - * Sent from kernel to userspace when the owner or activator of - * a well-known name changes. - * - * Attached to: - * KDBUS_ITEM_ID_ADD - * KDBUS_ITEM_ID_REMOVE - */ -struct kdbus_notify_id_change { - __u64 id; - __u64 flags; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_notify_name_change - name registry change message - * @old_id: ID and flags of former owner of a name - * @new_id: ID and flags of new owner of a name - * @name: Well-known name - * - * Sent from kernel to userspace when the owner or activator of - * a well-known name changes. - * - * Attached to: - * KDBUS_ITEM_NAME_ADD - * KDBUS_ITEM_NAME_REMOVE - * KDBUS_ITEM_NAME_CHANGE - */ -struct kdbus_notify_name_change { - struct kdbus_notify_id_change old_id; - struct kdbus_notify_id_change new_id; - char name[0]; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_creds - process credentials - * @uid: User ID - * @euid: Effective UID - * @suid: Saved UID - * @fsuid: Filesystem UID - * @gid: Group ID - * @egid: Effective GID - * @sgid: Saved GID - * @fsgid: Filesystem GID - * - * Attached to: - * KDBUS_ITEM_CREDS - */ -struct kdbus_creds { - __u64 uid; - __u64 euid; - __u64 suid; - __u64 fsuid; - __u64 gid; - __u64 egid; - __u64 sgid; - __u64 fsgid; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_pids - process identifiers - * @pid: Process ID - * @tid: Thread ID - * @ppid: Parent process ID - * - * The PID and TID of a process. - * - * Attached to: - * KDBUS_ITEM_PIDS - */ -struct kdbus_pids { - __u64 pid; - __u64 tid; - __u64 ppid; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_caps - process capabilities - * @last_cap: Highest currently known capability bit - * @caps: Variable number of 32-bit capabilities flags - * - * Contains a variable number of 32-bit capabilities flags. - * - * Attached to: - * KDBUS_ITEM_CAPS - */ -struct kdbus_caps { - __u32 last_cap; - __u32 caps[0]; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_audit - audit information - * @sessionid: The audit session ID - * @loginuid: The audit login uid - * - * Attached to: - * KDBUS_ITEM_AUDIT - */ -struct kdbus_audit { - __u32 sessionid; - __u32 loginuid; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_timestamp - * @seqnum: Global per-domain message sequence number - * @monotonic_ns: Monotonic timestamp, in nanoseconds - * @realtime_ns: Realtime timestamp, in nanoseconds - * - * Attached to: - * KDBUS_ITEM_TIMESTAMP - */ -struct kdbus_timestamp { - __u64 seqnum; - __u64 monotonic_ns; - __u64 realtime_ns; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_vec - I/O vector for kdbus payload items - * @size: The size of the vector - * @address: Memory address of data buffer - * @offset: Offset in the in-message payload memory, - * relative to the message head - * - * Attached to: - * KDBUS_ITEM_PAYLOAD_VEC, KDBUS_ITEM_PAYLOAD_OFF - */ -struct kdbus_vec { - __u64 size; - union { - __u64 address; - __u64 offset; - }; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_bloom_parameter - bus-wide bloom parameters - * @size: Size of the bit field in bytes (m / 8) - * @n_hash: Number of hash functions used (k) - */ -struct kdbus_bloom_parameter { - __u64 size; - __u64 n_hash; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_bloom_filter - bloom filter containing n elements - * @generation: Generation of the element set in the filter - * @data: Bit field, multiple of 8 bytes - */ -struct kdbus_bloom_filter { - __u64 generation; - __u64 data[0]; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_memfd - a kdbus memfd - * @start: The offset into the memfd where the segment starts - * @size: The size of the memfd segment - * @fd: The file descriptor number - * @__pad: Padding to ensure proper alignment and size - * - * Attached to: - * KDBUS_ITEM_PAYLOAD_MEMFD - */ -struct kdbus_memfd { - __u64 start; - __u64 size; - int fd; - __u32 __pad; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_name - a registered well-known name with its flags - * @flags: Flags from KDBUS_NAME_* - * @name: Well-known name - * - * Attached to: - * KDBUS_ITEM_OWNED_NAME - */ -struct kdbus_name { - __u64 flags; - char name[0]; -} __attribute__((__aligned__(8))); - -/** - * enum kdbus_policy_access_type - permissions of a policy record - * @_KDBUS_POLICY_ACCESS_NULL: Uninitialized/invalid - * @KDBUS_POLICY_ACCESS_USER: Grant access to a uid - * @KDBUS_POLICY_ACCESS_GROUP: Grant access to gid - * @KDBUS_POLICY_ACCESS_WORLD: World-accessible - */ -enum kdbus_policy_access_type { - _KDBUS_POLICY_ACCESS_NULL, - KDBUS_POLICY_ACCESS_USER, - KDBUS_POLICY_ACCESS_GROUP, - KDBUS_POLICY_ACCESS_WORLD, -}; - -/** - * enum kdbus_policy_access_flags - mode flags - * @KDBUS_POLICY_OWN: Allow to own a well-known name - * Implies KDBUS_POLICY_TALK and KDBUS_POLICY_SEE - * @KDBUS_POLICY_TALK: Allow communication to a well-known name - * Implies KDBUS_POLICY_SEE - * @KDBUS_POLICY_SEE: Allow to see a well-known name - */ -enum kdbus_policy_type { - KDBUS_POLICY_SEE = 0, - KDBUS_POLICY_TALK, - KDBUS_POLICY_OWN, -}; - -/** - * struct kdbus_policy_access - policy access item - * @type: One of KDBUS_POLICY_ACCESS_* types - * @access: Access to grant - * @id: For KDBUS_POLICY_ACCESS_USER, the uid - * For KDBUS_POLICY_ACCESS_GROUP, the gid - */ -struct kdbus_policy_access { - __u64 type; /* USER, GROUP, WORLD */ - __u64 access; /* OWN, TALK, SEE */ - __u64 id; /* uid, gid, 0 */ -} __attribute__((__aligned__(8))); - -/** - * enum kdbus_attach_flags - flags for metadata attachments - * @KDBUS_ATTACH_TIMESTAMP: Timestamp - * @KDBUS_ATTACH_CREDS: Credentials - * @KDBUS_ATTACH_PIDS: PIDs - * @KDBUS_ATTACH_AUXGROUPS: Auxiliary groups - * @KDBUS_ATTACH_NAMES: Well-known names - * @KDBUS_ATTACH_TID_COMM: The "comm" process identifier of the TID - * @KDBUS_ATTACH_PID_COMM: The "comm" process identifier of the PID - * @KDBUS_ATTACH_EXE: The path of the executable - * @KDBUS_ATTACH_CMDLINE: The process command line - * @KDBUS_ATTACH_CGROUP: The croup membership - * @KDBUS_ATTACH_CAPS: The process capabilities - * @KDBUS_ATTACH_SECLABEL: The security label - * @KDBUS_ATTACH_AUDIT: The audit IDs - * @KDBUS_ATTACH_CONN_DESCRIPTION: The human-readable connection name - * @_KDBUS_ATTACH_ALL: All of the above - * @_KDBUS_ATTACH_ANY: Wildcard match to enable any kind of - * metatdata. - */ -enum kdbus_attach_flags { - KDBUS_ATTACH_TIMESTAMP = 1ULL << 0, - KDBUS_ATTACH_CREDS = 1ULL << 1, - KDBUS_ATTACH_PIDS = 1ULL << 2, - KDBUS_ATTACH_AUXGROUPS = 1ULL << 3, - KDBUS_ATTACH_NAMES = 1ULL << 4, - KDBUS_ATTACH_TID_COMM = 1ULL << 5, - KDBUS_ATTACH_PID_COMM = 1ULL << 6, - KDBUS_ATTACH_EXE = 1ULL << 7, - KDBUS_ATTACH_CMDLINE = 1ULL << 8, - KDBUS_ATTACH_CGROUP = 1ULL << 9, - KDBUS_ATTACH_CAPS = 1ULL << 10, - KDBUS_ATTACH_SECLABEL = 1ULL << 11, - KDBUS_ATTACH_AUDIT = 1ULL << 12, - KDBUS_ATTACH_CONN_DESCRIPTION = 1ULL << 13, - _KDBUS_ATTACH_ALL = (1ULL << 14) - 1, - _KDBUS_ATTACH_ANY = ~0ULL -}; - -/** - * enum kdbus_item_type - item types to chain data in a list - * @_KDBUS_ITEM_NULL: Uninitialized/invalid - * @_KDBUS_ITEM_USER_BASE: Start of user items - * @KDBUS_ITEM_NEGOTIATE: Negotiate supported items - * @KDBUS_ITEM_PAYLOAD_VEC: Vector to data - * @KDBUS_ITEM_PAYLOAD_OFF: Data at returned offset to message head - * @KDBUS_ITEM_PAYLOAD_MEMFD: Data as sealed memfd - * @KDBUS_ITEM_FDS: Attached file descriptors - * @KDBUS_ITEM_CANCEL_FD: FD used to cancel a synchronous - * operation by writing to it from - * userspace - * @KDBUS_ITEM_BLOOM_PARAMETER: Bus-wide bloom parameters, used with - * KDBUS_CMD_BUS_MAKE, carries a - * struct kdbus_bloom_parameter - * @KDBUS_ITEM_BLOOM_FILTER: Bloom filter carried with a message, - * used to match against a bloom mask of a - * connection, carries a struct - * kdbus_bloom_filter - * @KDBUS_ITEM_BLOOM_MASK: Bloom mask used to match against a - * message'sbloom filter - * @KDBUS_ITEM_DST_NAME: Destination's well-known name - * @KDBUS_ITEM_MAKE_NAME: Name of domain, bus, endpoint - * @KDBUS_ITEM_ATTACH_FLAGS_SEND: Attach-flags, used for updating which - * metadata a connection opts in to send - * @KDBUS_ITEM_ATTACH_FLAGS_RECV: Attach-flags, used for updating which - * metadata a connection requests to - * receive for each reeceived message - * @KDBUS_ITEM_ID: Connection ID - * @KDBUS_ITEM_NAME: Well-know name with flags - * @_KDBUS_ITEM_ATTACH_BASE: Start of metadata attach items - * @KDBUS_ITEM_TIMESTAMP: Timestamp - * @KDBUS_ITEM_CREDS: Process credentials - * @KDBUS_ITEM_PIDS: Process identifiers - * @KDBUS_ITEM_AUXGROUPS: Auxiliary process groups - * @KDBUS_ITEM_OWNED_NAME: A name owned by the associated - * connection - * @KDBUS_ITEM_TID_COMM: Thread ID "comm" identifier - * (Don't trust this, see below.) - * @KDBUS_ITEM_PID_COMM: Process ID "comm" identifier - * (Don't trust this, see below.) - * @KDBUS_ITEM_EXE: The path of the executable - * (Don't trust this, see below.) - * @KDBUS_ITEM_CMDLINE: The process command line - * (Don't trust this, see below.) - * @KDBUS_ITEM_CGROUP: The croup membership - * @KDBUS_ITEM_CAPS: The process capabilities - * @KDBUS_ITEM_SECLABEL: The security label - * @KDBUS_ITEM_AUDIT: The audit IDs - * @KDBUS_ITEM_CONN_DESCRIPTION: The connection's human-readable name - * (debugging) - * @_KDBUS_ITEM_POLICY_BASE: Start of policy items - * @KDBUS_ITEM_POLICY_ACCESS: Policy access block - * @_KDBUS_ITEM_KERNEL_BASE: Start of kernel-generated message items - * @KDBUS_ITEM_NAME_ADD: Notification in kdbus_notify_name_change - * @KDBUS_ITEM_NAME_REMOVE: Notification in kdbus_notify_name_change - * @KDBUS_ITEM_NAME_CHANGE: Notification in kdbus_notify_name_change - * @KDBUS_ITEM_ID_ADD: Notification in kdbus_notify_id_change - * @KDBUS_ITEM_ID_REMOVE: Notification in kdbus_notify_id_change - * @KDBUS_ITEM_REPLY_TIMEOUT: Timeout has been reached - * @KDBUS_ITEM_REPLY_DEAD: Destination died - * - * N.B: The process and thread COMM fields, as well as the CMDLINE and - * EXE fields may be altered by unprivileged processes und should - * hence *not* used for security decisions. Peers should make use of - * these items only for informational purposes, such as generating log - * records. - */ -enum kdbus_item_type { - _KDBUS_ITEM_NULL, - _KDBUS_ITEM_USER_BASE, - KDBUS_ITEM_NEGOTIATE = _KDBUS_ITEM_USER_BASE, - KDBUS_ITEM_PAYLOAD_VEC, - KDBUS_ITEM_PAYLOAD_OFF, - KDBUS_ITEM_PAYLOAD_MEMFD, - KDBUS_ITEM_FDS, - KDBUS_ITEM_CANCEL_FD, - KDBUS_ITEM_BLOOM_PARAMETER, - KDBUS_ITEM_BLOOM_FILTER, - KDBUS_ITEM_BLOOM_MASK, - KDBUS_ITEM_DST_NAME, - KDBUS_ITEM_MAKE_NAME, - KDBUS_ITEM_ATTACH_FLAGS_SEND, - KDBUS_ITEM_ATTACH_FLAGS_RECV, - KDBUS_ITEM_ID, - KDBUS_ITEM_NAME, - KDBUS_ITEM_DST_ID, - - /* keep these item types in sync with KDBUS_ATTACH_* flags */ - _KDBUS_ITEM_ATTACH_BASE = 0x1000, - KDBUS_ITEM_TIMESTAMP = _KDBUS_ITEM_ATTACH_BASE, - KDBUS_ITEM_CREDS, - KDBUS_ITEM_PIDS, - KDBUS_ITEM_AUXGROUPS, - KDBUS_ITEM_OWNED_NAME, - KDBUS_ITEM_TID_COMM, - KDBUS_ITEM_PID_COMM, - KDBUS_ITEM_EXE, - KDBUS_ITEM_CMDLINE, - KDBUS_ITEM_CGROUP, - KDBUS_ITEM_CAPS, - KDBUS_ITEM_SECLABEL, - KDBUS_ITEM_AUDIT, - KDBUS_ITEM_CONN_DESCRIPTION, - - _KDBUS_ITEM_POLICY_BASE = 0x2000, - KDBUS_ITEM_POLICY_ACCESS = _KDBUS_ITEM_POLICY_BASE, - - _KDBUS_ITEM_KERNEL_BASE = 0x8000, - KDBUS_ITEM_NAME_ADD = _KDBUS_ITEM_KERNEL_BASE, - KDBUS_ITEM_NAME_REMOVE, - KDBUS_ITEM_NAME_CHANGE, - KDBUS_ITEM_ID_ADD, - KDBUS_ITEM_ID_REMOVE, - KDBUS_ITEM_REPLY_TIMEOUT, - KDBUS_ITEM_REPLY_DEAD, -}; - -/** - * struct kdbus_item - chain of data blocks - * @size: Overall data record size - * @type: Kdbus_item type of data - * @data: Generic bytes - * @data32: Generic 32 bit array - * @data64: Generic 64 bit array - * @str: Generic string - * @id: Connection ID - * @vec: KDBUS_ITEM_PAYLOAD_VEC - * @creds: KDBUS_ITEM_CREDS - * @audit: KDBUS_ITEM_AUDIT - * @timestamp: KDBUS_ITEM_TIMESTAMP - * @name: KDBUS_ITEM_NAME - * @bloom_parameter: KDBUS_ITEM_BLOOM_PARAMETER - * @bloom_filter: KDBUS_ITEM_BLOOM_FILTER - * @memfd: KDBUS_ITEM_PAYLOAD_MEMFD - * @name_change: KDBUS_ITEM_NAME_ADD - * KDBUS_ITEM_NAME_REMOVE - * KDBUS_ITEM_NAME_CHANGE - * @id_change: KDBUS_ITEM_ID_ADD - * KDBUS_ITEM_ID_REMOVE - * @policy: KDBUS_ITEM_POLICY_ACCESS - */ -struct kdbus_item { - __u64 size; - __u64 type; - union { - __u8 data[0]; - __u32 data32[0]; - __u64 data64[0]; - char str[0]; - - __u64 id; - struct kdbus_vec vec; - struct kdbus_creds creds; - struct kdbus_pids pids; - struct kdbus_audit audit; - struct kdbus_caps caps; - struct kdbus_timestamp timestamp; - struct kdbus_name name; - struct kdbus_bloom_parameter bloom_parameter; - struct kdbus_bloom_filter bloom_filter; - struct kdbus_memfd memfd; - int fds[0]; - struct kdbus_notify_name_change name_change; - struct kdbus_notify_id_change id_change; - struct kdbus_policy_access policy_access; - }; -} __attribute__((__aligned__(8))); - -/** - * enum kdbus_msg_flags - type of message - * @KDBUS_MSG_EXPECT_REPLY: Expect a reply message, used for - * method calls. The userspace-supplied - * cookie identifies the message and the - * respective reply carries the cookie - * in cookie_reply - * @KDBUS_MSG_NO_AUTO_START: Do not start a service if the addressed - * name is not currently active. This flag is - * not looked at by the kernel but only - * serves as hint for userspace implementations. - * @KDBUS_MSG_SIGNAL: Treat this message as signal - */ -enum kdbus_msg_flags { - KDBUS_MSG_EXPECT_REPLY = 1ULL << 0, - KDBUS_MSG_NO_AUTO_START = 1ULL << 1, - KDBUS_MSG_SIGNAL = 1ULL << 2, -}; - -/** - * enum kdbus_payload_type - type of payload carried by message - * @KDBUS_PAYLOAD_KERNEL: Kernel-generated simple message - * @KDBUS_PAYLOAD_DBUS: D-Bus marshalling "DBusDBus" - * - * Any payload-type is accepted. Common types will get added here once - * established. - */ -enum kdbus_payload_type { - KDBUS_PAYLOAD_KERNEL, - KDBUS_PAYLOAD_DBUS = 0x4442757344427573ULL, -}; - -/** - * struct kdbus_msg - the representation of a kdbus message - * @size: Total size of the message - * @flags: Message flags (KDBUS_MSG_*), userspace → kernel - * @priority: Message queue priority value - * @dst_id: 64-bit ID of the destination connection - * @src_id: 64-bit ID of the source connection - * @payload_type: Payload type (KDBUS_PAYLOAD_*) - * @cookie: Userspace-supplied cookie, for the connection - * to identify its messages - * @timeout_ns: The time to wait for a message reply from the peer. - * If there is no reply, and the send command is - * executed asynchronously, a kernel-generated message - * with an attached KDBUS_ITEM_REPLY_TIMEOUT item - * is sent to @src_id. For synchronously executed send - * command, the value denotes the maximum time the call - * blocks to wait for a reply. The timeout is expected in - * nanoseconds and as absolute CLOCK_MONOTONIC value. - * @cookie_reply: A reply to the requesting message with the same - * cookie. The requesting connection can match its - * request and the reply with this value - * @items: A list of kdbus_items containing the message payload - */ -struct kdbus_msg { - __u64 size; - __u64 flags; - __s64 priority; - __u64 dst_id; - __u64 src_id; - __u64 payload_type; - __u64 cookie; - union { - __u64 timeout_ns; - __u64 cookie_reply; - }; - struct kdbus_item items[0]; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_msg_info - returned message container - * @offset: Offset of kdbus_msg slice in pool - * @msg_size: Copy of the kdbus_msg.size field - * @return_flags: Command return flags, kernel → userspace - */ -struct kdbus_msg_info { - __u64 offset; - __u64 msg_size; - __u64 return_flags; -} __attribute__((__aligned__(8))); - -/** - * enum kdbus_send_flags - flags for sending messages - * @KDBUS_SEND_SYNC_REPLY: Wait for destination connection to - * reply to this message. The - * KDBUS_CMD_SEND ioctl() will block - * until the reply is received, and - * reply in struct kdbus_cmd_send will - * yield the offset in the sender's pool - * where the reply can be found. - * This flag is only valid if - * @KDBUS_MSG_EXPECT_REPLY is set as well. - */ -enum kdbus_send_flags { - KDBUS_SEND_SYNC_REPLY = 1ULL << 0, -}; - -/** - * struct kdbus_cmd_send - send message - * @size: Overall size of this structure - * @flags: Flags to change send behavior (KDBUS_SEND_*) - * @return_flags: Command return flags, kernel → userspace - * @msg_address: Storage address of the kdbus_msg to send - * @reply: Storage for message reply if KDBUS_SEND_SYNC_REPLY - * was given - * @items: Additional items for this command - */ -struct kdbus_cmd_send { - __u64 size; - __u64 flags; - __u64 return_flags; - __u64 msg_address; - struct kdbus_msg_info reply; - struct kdbus_item items[0]; -} __attribute__((__aligned__(8))); - -/** - * enum kdbus_recv_flags - flags for de-queuing messages - * @KDBUS_RECV_PEEK: Return the next queued message without - * actually de-queuing it, and without installing - * any file descriptors or other resources. It is - * usually used to determine the activating - * connection of a bus name. - * @KDBUS_RECV_DROP: Drop and free the next queued message and all - * its resources without actually receiving it. - * @KDBUS_RECV_USE_PRIORITY: Only de-queue messages with the specified or - * higher priority (lowest values); if not set, - * the priority value is ignored. - */ -enum kdbus_recv_flags { - KDBUS_RECV_PEEK = 1ULL << 0, - KDBUS_RECV_DROP = 1ULL << 1, - KDBUS_RECV_USE_PRIORITY = 1ULL << 2, -}; - -/** - * enum kdbus_recv_return_flags - return flags for message receive commands - * @KDBUS_RECV_RETURN_INCOMPLETE_FDS: One or more file descriptors could not - * be installed. These descriptors in - * KDBUS_ITEM_FDS will carry the value -1. - * @KDBUS_RECV_RETURN_DROPPED_MSGS: There have been dropped messages since - * the last time a message was received. - * The 'dropped_msgs' counter contains the - * number of messages dropped pool - * overflows or other missed broadcasts. - */ -enum kdbus_recv_return_flags { - KDBUS_RECV_RETURN_INCOMPLETE_FDS = 1ULL << 0, - KDBUS_RECV_RETURN_DROPPED_MSGS = 1ULL << 1, -}; - -/** - * struct kdbus_cmd_recv - struct to de-queue a buffered message - * @size: Overall size of this object - * @flags: KDBUS_RECV_* flags, userspace → kernel - * @return_flags: Command return flags, kernel → userspace - * @priority: Minimum priority of the messages to de-queue. Lowest - * values have the highest priority. - * @dropped_msgs: In case there were any dropped messages since the last - * time a message was received, this will be set to the - * number of lost messages and - * KDBUS_RECV_RETURN_DROPPED_MSGS will be set in - * 'return_flags'. This can only happen if the ioctl - * returns 0 or EAGAIN. - * @msg: Return storage for received message. - * @items: Additional items for this command. - * - * This struct is used with the KDBUS_CMD_RECV ioctl. - */ -struct kdbus_cmd_recv { - __u64 size; - __u64 flags; - __u64 return_flags; - __s64 priority; - __u64 dropped_msgs; - struct kdbus_msg_info msg; - struct kdbus_item items[0]; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_cmd_free - struct to free a slice of memory in the pool - * @size: Overall size of this structure - * @flags: Flags for the free command, userspace → kernel - * @return_flags: Command return flags, kernel → userspace - * @offset: The offset of the memory slice, as returned by other - * ioctls - * @items: Additional items to modify the behavior - * - * This struct is used with the KDBUS_CMD_FREE ioctl. - */ -struct kdbus_cmd_free { - __u64 size; - __u64 flags; - __u64 return_flags; - __u64 offset; - struct kdbus_item items[0]; -} __attribute__((__aligned__(8))); - -/** - * enum kdbus_hello_flags - flags for struct kdbus_cmd_hello - * @KDBUS_HELLO_ACCEPT_FD: The connection allows the reception of - * any passed file descriptors - * @KDBUS_HELLO_ACTIVATOR: Special-purpose connection which registers - * a well-know name for a process to be started - * when traffic arrives - * @KDBUS_HELLO_POLICY_HOLDER: Special-purpose connection which registers - * policy entries for a name. The provided name - * is not activated and not registered with the - * name database, it only allows unprivileged - * connections to acquire a name, talk or discover - * a service - * @KDBUS_HELLO_MONITOR: Special-purpose connection to monitor - * bus traffic - */ -enum kdbus_hello_flags { - KDBUS_HELLO_ACCEPT_FD = 1ULL << 0, - KDBUS_HELLO_ACTIVATOR = 1ULL << 1, - KDBUS_HELLO_POLICY_HOLDER = 1ULL << 2, - KDBUS_HELLO_MONITOR = 1ULL << 3, -}; - -/** - * struct kdbus_cmd_hello - struct to say hello to kdbus - * @size: The total size of the structure - * @flags: Connection flags (KDBUS_HELLO_*), userspace → kernel - * @return_flags: Command return flags, kernel → userspace - * @attach_flags_send: Mask of metadata to attach to each message sent - * off by this connection (KDBUS_ATTACH_*) - * @attach_flags_recv: Mask of metadata to attach to each message receieved - * by the new connection (KDBUS_ATTACH_*) - * @bus_flags: The flags field copied verbatim from the original - * KDBUS_CMD_BUS_MAKE ioctl. It's intended to be useful - * to do negotiation of features of the payload that is - * transferred (kernel → userspace) - * @id: The ID of this connection (kernel → userspace) - * @pool_size: Size of the connection's buffer where the received - * messages are placed - * @offset: Pool offset where items are returned to report - * additional information about the bus and the newly - * created connection. - * @items_size: Size of buffer returned in the pool slice at @offset. - * @id128: Unique 128-bit ID of the bus (kernel → userspace) - * @items: A list of items - * - * This struct is used with the KDBUS_CMD_HELLO ioctl. - */ -struct kdbus_cmd_hello { - __u64 size; - __u64 flags; - __u64 return_flags; - __u64 attach_flags_send; - __u64 attach_flags_recv; - __u64 bus_flags; - __u64 id; - __u64 pool_size; - __u64 offset; - __u64 items_size; - __u8 id128[16]; - struct kdbus_item items[0]; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_info - connection information - * @size: total size of the struct - * @id: 64bit object ID - * @flags: object creation flags - * @items: list of items - * - * Note that the user is responsible for freeing the allocated memory with - * the KDBUS_CMD_FREE ioctl. - */ -struct kdbus_info { - __u64 size; - __u64 id; - __u64 flags; - struct kdbus_item items[0]; -} __attribute__((__aligned__(8))); - -/** - * enum kdbus_list_flags - what to include into the returned list - * @KDBUS_LIST_UNIQUE: active connections - * @KDBUS_LIST_ACTIVATORS: activator connections - * @KDBUS_LIST_NAMES: known well-known names - * @KDBUS_LIST_QUEUED: queued-up names - */ -enum kdbus_list_flags { - KDBUS_LIST_UNIQUE = 1ULL << 0, - KDBUS_LIST_NAMES = 1ULL << 1, - KDBUS_LIST_ACTIVATORS = 1ULL << 2, - KDBUS_LIST_QUEUED = 1ULL << 3, -}; - -/** - * struct kdbus_cmd_list - list connections - * @size: overall size of this object - * @flags: flags for the query (KDBUS_LIST_*), userspace → kernel - * @return_flags: command return flags, kernel → userspace - * @offset: Offset in the caller's pool buffer where an array of - * kdbus_info objects is stored. - * The user must use KDBUS_CMD_FREE to free the - * allocated memory. - * @list_size: size of returned list in bytes - * @items: Items for the command. Reserved for future use. - * - * This structure is used with the KDBUS_CMD_LIST ioctl. - */ -struct kdbus_cmd_list { - __u64 size; - __u64 flags; - __u64 return_flags; - __u64 offset; - __u64 list_size; - struct kdbus_item items[0]; -} __attribute__((__aligned__(8))); - -/** - * struct kdbus_cmd_info - struct used for KDBUS_CMD_CONN_INFO ioctl - * @size: The total size of the struct - * @flags: Flags for this ioctl, userspace → kernel - * @return_flags: Command return flags, kernel → userspace - * @id: The 64-bit ID of the connection. If set to zero, passing - * @name is required. kdbus will look up the name to - * determine the ID in this case. - * @attach_flags: Set of attach flags to specify the set of information - * to receive, userspace → kernel - * @offset: Returned offset in the caller's pool buffer where the - * kdbus_info struct result is stored. The user must - * use KDBUS_CMD_FREE to free the allocated memory. - * @info_size: Output buffer to report size of data at @offset. - * @items: The optional item list, containing the - * well-known name to look up as a KDBUS_ITEM_NAME. - * Only needed in case @id is zero. - * - * On success, the KDBUS_CMD_CONN_INFO ioctl will return 0 and @offset will - * tell the user the offset in the connection pool buffer at which to find the - * result in a struct kdbus_info. - */ -struct kdbus_cmd_info { - __u64 size; - __u64 flags; - __u64 return_flags; - __u64 id; - __u64 attach_flags; - __u64 offset; - __u64 info_size; - struct kdbus_item items[0]; -} __attribute__((__aligned__(8))); - -/** - * enum kdbus_cmd_match_flags - flags to control the KDBUS_CMD_MATCH_ADD ioctl - * @KDBUS_MATCH_REPLACE: If entries with the supplied cookie already - * exists, remove them before installing the new - * matches. - */ -enum kdbus_cmd_match_flags { - KDBUS_MATCH_REPLACE = 1ULL << 0, -}; - -/** - * struct kdbus_cmd_match - struct to add or remove matches - * @size: The total size of the struct - * @flags: Flags for match command (KDBUS_MATCH_*), - * userspace → kernel - * @return_flags: Command return flags, kernel → userspace - * @cookie: Userspace supplied cookie. When removing, the cookie - * identifies the match to remove - * @items: A list of items for additional information - * - * This structure is used with the KDBUS_CMD_MATCH_ADD and - * KDBUS_CMD_MATCH_REMOVE ioctl. - */ -struct kdbus_cmd_match { - __u64 size; - __u64 flags; - __u64 return_flags; - __u64 cookie; - struct kdbus_item items[0]; -} __attribute__((__aligned__(8))); - -/** - * enum kdbus_make_flags - Flags for KDBUS_CMD_{BUS,ENDPOINT}_MAKE - * @KDBUS_MAKE_ACCESS_GROUP: Make the bus or endpoint node group-accessible - * @KDBUS_MAKE_ACCESS_WORLD: Make the bus or endpoint node world-accessible - */ -enum kdbus_make_flags { - KDBUS_MAKE_ACCESS_GROUP = 1ULL << 0, - KDBUS_MAKE_ACCESS_WORLD = 1ULL << 1, -}; - -/** - * enum kdbus_name_flags - flags for KDBUS_CMD_NAME_ACQUIRE - * @KDBUS_NAME_REPLACE_EXISTING: Try to replace name of other connections - * @KDBUS_NAME_ALLOW_REPLACEMENT: Allow the replacement of the name - * @KDBUS_NAME_QUEUE: Name should be queued if busy - * @KDBUS_NAME_IN_QUEUE: Name is queued - * @KDBUS_NAME_ACTIVATOR: Name is owned by a activator connection - * @KDBUS_NAME_PRIMARY: Primary owner of the name - * @KDBUS_NAME_ACQUIRED: Name was acquired/queued _now_ - */ -enum kdbus_name_flags { - KDBUS_NAME_REPLACE_EXISTING = 1ULL << 0, - KDBUS_NAME_ALLOW_REPLACEMENT = 1ULL << 1, - KDBUS_NAME_QUEUE = 1ULL << 2, - KDBUS_NAME_IN_QUEUE = 1ULL << 3, - KDBUS_NAME_ACTIVATOR = 1ULL << 4, - KDBUS_NAME_PRIMARY = 1ULL << 5, - KDBUS_NAME_ACQUIRED = 1ULL << 6, -}; - -/** - * struct kdbus_cmd - generic ioctl payload - * @size: Overall size of this structure - * @flags: Flags for this ioctl, userspace → kernel - * @return_flags: Ioctl return flags, kernel → userspace - * @items: Additional items to modify the behavior - * - * This is a generic ioctl payload object. It's used by all ioctls that only - * take flags and items as input. - */ -struct kdbus_cmd { - __u64 size; - __u64 flags; - __u64 return_flags; - struct kdbus_item items[0]; -} __attribute__((__aligned__(8))); - -/** - * Ioctl API - * - * KDBUS_CMD_BUS_MAKE: After opening the "control" node, this command - * creates a new bus with the specified - * name. The bus is immediately shut down and - * cleaned up when the opened file descriptor is - * closed. - * - * KDBUS_CMD_ENDPOINT_MAKE: Creates a new named special endpoint to talk to - * the bus. Such endpoints usually carry a more - * restrictive policy and grant restricted access - * to specific applications. - * KDBUS_CMD_ENDPOINT_UPDATE: Update the properties of a custom enpoint. Used - * to update the policy. - * - * KDBUS_CMD_HELLO: By opening the bus node, a connection is - * created. After a HELLO the opened connection - * becomes an active peer on the bus. - * KDBUS_CMD_UPDATE: Update the properties of a connection. Used to - * update the metadata subscription mask and - * policy. - * KDBUS_CMD_BYEBYE: Disconnect a connection. If there are no - * messages queued up in the connection's pool, - * the call succeeds, and the handle is rendered - * unusable. Otherwise, -EBUSY is returned without - * any further side-effects. - * KDBUS_CMD_FREE: Release the allocated memory in the receiver's - * pool. - * KDBUS_CMD_CONN_INFO: Retrieve credentials and properties of the - * initial creator of the connection. The data was - * stored at registration time and does not - * necessarily represent the connected process or - * the actual state of the process. - * KDBUS_CMD_BUS_CREATOR_INFO: Retrieve information of the creator of the bus - * a connection is attached to. - * - * KDBUS_CMD_SEND: Send a message and pass data from userspace to - * the kernel. - * KDBUS_CMD_RECV: Receive a message from the kernel which is - * placed in the receiver's pool. - * - * KDBUS_CMD_NAME_ACQUIRE: Request a well-known bus name to associate with - * the connection. Well-known names are used to - * address a peer on the bus. - * KDBUS_CMD_NAME_RELEASE: Release a well-known name the connection - * currently owns. - * KDBUS_CMD_LIST: Retrieve the list of all currently registered - * well-known and unique names. - * - * KDBUS_CMD_MATCH_ADD: Install a match which broadcast messages should - * be delivered to the connection. - * KDBUS_CMD_MATCH_REMOVE: Remove a current match for broadcast messages. - */ -enum kdbus_ioctl_type { - /* bus owner (00-0f) */ - KDBUS_CMD_BUS_MAKE = _IOW(KDBUS_IOCTL_MAGIC, 0x00, - struct kdbus_cmd), - - /* endpoint owner (10-1f) */ - KDBUS_CMD_ENDPOINT_MAKE = _IOW(KDBUS_IOCTL_MAGIC, 0x10, - struct kdbus_cmd), - KDBUS_CMD_ENDPOINT_UPDATE = _IOW(KDBUS_IOCTL_MAGIC, 0x11, - struct kdbus_cmd), - - /* connection owner (80-ff) */ - KDBUS_CMD_HELLO = _IOWR(KDBUS_IOCTL_MAGIC, 0x80, - struct kdbus_cmd_hello), - KDBUS_CMD_UPDATE = _IOW(KDBUS_IOCTL_MAGIC, 0x81, - struct kdbus_cmd), - KDBUS_CMD_BYEBYE = _IOW(KDBUS_IOCTL_MAGIC, 0x82, - struct kdbus_cmd), - KDBUS_CMD_FREE = _IOW(KDBUS_IOCTL_MAGIC, 0x83, - struct kdbus_cmd_free), - KDBUS_CMD_CONN_INFO = _IOR(KDBUS_IOCTL_MAGIC, 0x84, - struct kdbus_cmd_info), - KDBUS_CMD_BUS_CREATOR_INFO = _IOR(KDBUS_IOCTL_MAGIC, 0x85, - struct kdbus_cmd_info), - KDBUS_CMD_LIST = _IOR(KDBUS_IOCTL_MAGIC, 0x86, - struct kdbus_cmd_list), - - KDBUS_CMD_SEND = _IOW(KDBUS_IOCTL_MAGIC, 0x90, - struct kdbus_cmd_send), - KDBUS_CMD_RECV = _IOR(KDBUS_IOCTL_MAGIC, 0x91, - struct kdbus_cmd_recv), - - KDBUS_CMD_NAME_ACQUIRE = _IOW(KDBUS_IOCTL_MAGIC, 0xa0, - struct kdbus_cmd), - KDBUS_CMD_NAME_RELEASE = _IOW(KDBUS_IOCTL_MAGIC, 0xa1, - struct kdbus_cmd), - - KDBUS_CMD_MATCH_ADD = _IOW(KDBUS_IOCTL_MAGIC, 0xb0, - struct kdbus_cmd_match), - KDBUS_CMD_MATCH_REMOVE = _IOW(KDBUS_IOCTL_MAGIC, 0xb1, - struct kdbus_cmd_match), -}; - -#endif /* _UAPI_KDBUS_H_ */ diff --git a/packaging/dbus-x11.spec b/packaging/dbus-x11.spec index b63ee7f9..e77c13e4 100644 --- a/packaging/dbus-x11.spec +++ b/packaging/dbus-x11.spec @@ -1,5 +1,4 @@ %bcond_with x -%bcond_with kdbus Name: dbus-x11 %define _name dbus @@ -76,9 +75,6 @@ export V=1 %if %{with_systemd} --enable-systemd \ %endif -%if %{with kdbus} - --enable-kdbus-transport \ -%endif --with-console-auth-dir=/var/run/dbus/at_console/ \ --with-systemdsystemunitdir=%{_unitdir} \ --enable-smack diff --git a/packaging/dbus.spec b/packaging/dbus.spec index 2919332b..860d70c3 100644 --- a/packaging/dbus.spec +++ b/packaging/dbus.spec @@ -1,7 +1,5 @@ %define dbus_user_uid 81 -%bcond_with kdbus - Name: dbus Url: http://dbus.freedesktop.org/ Summary: D-Bus Message Bus System @@ -92,9 +90,6 @@ export V=1 %if %{with_systemd} --enable-systemd \ %endif -%if %{with kdbus} - --enable-kdbus-transport \ -%endif --with-console-auth-dir=/var/run/dbus/at_console/ \ --with-systemdsystemunitdir=%{_unitdir} \ --enable-smack \ diff --git a/packaging/libdbus.spec b/packaging/libdbus.spec index 0494b8cc..26604810 100644 --- a/packaging/libdbus.spec +++ b/packaging/libdbus.spec @@ -1,5 +1,3 @@ -%bcond_with kdbus - Name: libdbus Url: http://dbus.freedesktop.org/ Summary: Library package for D-Bus @@ -70,9 +68,6 @@ export V=1 --enable-inotify \ --with-console-auth-dir=/var/run/dbus/at_console/ \ --with-systemdsystemunitdir=%{_unitdir} \ -%if %{with kdbus} - --enable-kdbus-transport \ -%endif --enable-smack make %{?_smp_mflags} -C dbus libdbus-1.la |