From 2c0c2adb8cdb3dedac045dbd11749dd22f4c2bfe Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 15 Jan 2018 16:30:33 +0000 Subject: [PATCH 6/8] DBusMessage: Add a header field for the container instance In the bus daemon, don't pass through the container instance path: if there's any value here at all, we want to be able to guarantee that we sent it (in a later commit). Signed-off-by: Simon McVittie --- bus/dispatch.c | 3 ++- dbus/dbus-marshal-header.c | 8 +++++++- dbus/dbus-message-util.c | 5 +++++ dbus/dbus-message.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++ dbus/dbus-message.h | 6 ++++++ dbus/dbus-protocol.h | 6 +++++- 6 files changed, 76 insertions(+), 3 deletions(-) diff --git a/bus/dispatch.c b/bus/dispatch.c index b16ad2b3..c3914a86 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -290,7 +290,8 @@ bus_dispatch (DBusConnection *connection, /* Make sure the message does not have any header fields that we * don't understand (or validate), so that we can add header fields * in future and clients can assume that we have checked them. */ - if (!_dbus_message_remove_unknown_fields (message)) + if (!_dbus_message_remove_unknown_fields (message) || + !dbus_message_set_container_instance (message, NULL)) { BUS_SET_OOM (&error); goto out; diff --git a/dbus/dbus-marshal-header.c b/dbus/dbus-marshal-header.c index f9a33258..b2461749 100644 --- a/dbus/dbus-marshal-header.c +++ b/dbus/dbus-marshal-header.c @@ -83,7 +83,8 @@ _dbus_header_field_types[DBUS_HEADER_FIELD_LAST+1] = { { DBUS_HEADER_FIELD_DESTINATION, DBUS_TYPE_STRING }, { DBUS_HEADER_FIELD_SENDER, DBUS_TYPE_STRING }, { DBUS_HEADER_FIELD_SIGNATURE, DBUS_TYPE_SIGNATURE }, - { DBUS_HEADER_FIELD_UNIX_FDS, DBUS_TYPE_UINT32 } + { DBUS_HEADER_FIELD_UNIX_FDS, DBUS_TYPE_UINT32 }, + { DBUS_HEADER_FIELD_CONTAINER_INSTANCE, DBUS_TYPE_OBJECT_PATH } }; /** Macro to look up the correct type for a field */ @@ -919,6 +920,11 @@ load_and_validate_field (DBusHeader *header, string_validation_func = NULL; break; + case DBUS_HEADER_FIELD_CONTAINER_INSTANCE: + /* OBJECT_PATH was validated generically due to its type */ + string_validation_func = NULL; + break; + default: _dbus_assert_not_reached ("unknown field shouldn't be seen here"); break; diff --git a/dbus/dbus-message-util.c b/dbus/dbus-message-util.c index 2fefbe4f..6b4acf60 100644 --- a/dbus/dbus-message-util.c +++ b/dbus/dbus-message-util.c @@ -1294,6 +1294,11 @@ _dbus_message_test (const char *test_data_dir) _dbus_assert (strcmp (dbus_message_get_path (message), "/foo") == 0); + if (!dbus_message_set_container_instance (message, "/org/freedesktop/DBus/Containers1/c42")) + _dbus_test_fatal ("out of memory"); + _dbus_assert (strcmp (dbus_message_get_container_instance (message), + "/org/freedesktop/DBus/Containers1/c42") == 0); + if (!dbus_message_set_interface (message, "org.Foo")) _dbus_test_fatal ("out of memory"); _dbus_assert (strcmp (dbus_message_get_interface (message), diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 36066848..d9e5bb90 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -4069,6 +4069,57 @@ dbus_message_contains_unix_fds(DBusMessage *message) #endif } +/** + * Sets the container instance this message was sent from. + * + * The path must contain only valid characters for an object path + * as defined in the D-Bus specification. + * + * @param message the message + * @param object_path the path or #NULL to unset + * @returns #FALSE if not enough memory + */ +dbus_bool_t +dbus_message_set_container_instance (DBusMessage *message, + const char *object_path) +{ + _dbus_return_val_if_fail (message != NULL, FALSE); + _dbus_return_val_if_fail (!message->locked, FALSE); + _dbus_return_val_if_fail (object_path == NULL || + _dbus_check_is_valid_path (object_path), + FALSE); + + return set_or_delete_string_field (message, + DBUS_HEADER_FIELD_CONTAINER_INSTANCE, + DBUS_TYPE_OBJECT_PATH, + object_path); +} + +/** + * Gets the container instance this message was sent from, or #NULL + * if none. + * + * The returned string becomes invalid if the message is + * modified, since it points into the wire-marshaled message data. + * + * @param message the message + * @returns the path (should not be freed) or #NULL + */ +const char * +dbus_message_get_container_instance (DBusMessage *message) +{ + const char *v; + + _dbus_return_val_if_fail (message != NULL, NULL); + + v = NULL; /* in case field doesn't exist */ + _dbus_header_get_field_basic (&message->header, + DBUS_HEADER_FIELD_CONTAINER_INSTANCE, + DBUS_TYPE_OBJECT_PATH, + (void *) &v); + return v; +} + /** @} */ /** diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h index 8a9d57a0..9d590ceb 100644 --- a/dbus/dbus-message.h +++ b/dbus/dbus-message.h @@ -217,6 +217,12 @@ DBUS_EXPORT dbus_bool_t dbus_message_get_path_decomposed (DBusMessage *message, char ***path); +DBUS_EXPORT +const char *dbus_message_get_container_instance (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_set_container_instance (DBusMessage *message, + const char *object_path); + DBUS_EXPORT dbus_bool_t dbus_message_append_args (DBusMessage *message, int first_arg_type, diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h index 56be9832..61f6212d 100644 --- a/dbus/dbus-protocol.h +++ b/dbus/dbus-protocol.h @@ -300,6 +300,10 @@ extern "C" { * with this message. */ #define DBUS_HEADER_FIELD_UNIX_FDS 9 +/** + * Header field code for the container instance that sent this message. + */ +#define DBUS_HEADER_FIELD_CONTAINER_INSTANCE 10 /** @@ -308,7 +312,7 @@ extern "C" { * that unknown codes must be ignored, so check for that before * indexing the array. */ -#define DBUS_HEADER_FIELD_LAST DBUS_HEADER_FIELD_UNIX_FDS +#define DBUS_HEADER_FIELD_LAST DBUS_HEADER_FIELD_CONTAINER_INSTANCE /** Header format is defined as a signature: * byte byte order -- 2.15.1