25 #include "dbus/dbus-shared.h" 26 #include "dbus-marshal-header.h" 27 #include "dbus-marshal-recursive.h" 28 #include "dbus-marshal-byteswap.h" 47 #define FIELDS_ARRAY_SIGNATURE_OFFSET 6 49 #define FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET 7 53 #define BYTE_ORDER_OFFSET 0 57 #define FLAGS_OFFSET 2 59 #define VERSION_OFFSET 3 61 #define BODY_LENGTH_OFFSET 4 63 #define SERIAL_OFFSET 8 65 #define FIELDS_ARRAY_LENGTH_OFFSET 12 67 #define FIRST_FIELD_OFFSET 16 88 ,{ DBUS_HEADER_FIELD_EXEC_SRC, DBUS_TYPE_STRING }
89 ,{ DBUS_HEADER_FIELD_EXEC_DST, DBUS_TYPE_STRING }
94 #define EXPECTED_TYPE_OF_FIELD(field) (_dbus_header_field_types[field].type) 97 #define MAX_POSSIBLE_HEADER_PADDING 7 118 unpadded_len = _dbus_string_get_length (&header->
data);
123 header->
padding = _dbus_string_get_length (&header->
data) - unpadded_len;
127 #define HEADER_END_BEFORE_PADDING(header) \ 128 (_dbus_string_get_length (&(header)->data) - (header)->padding) 138 _dbus_header_cache_invalidate_all (
DBusHeader *header)
166 _dbus_verbose (
"cached value_pos %d for field %d\n",
191 _dbus_header_cache_revalidate (
DBusHeader *header)
206 &_dbus_header_signature_str,
217 unsigned char field_code;
233 _dbus_header_cache_one (header, field_code, &variant);
253 if (header->
fields[field].
value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
254 _dbus_header_cache_revalidate (header);
256 if (header->
fields[field].
value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT)
271 _dbus_header_cache_known_nonexistent (
DBusHeader *header,
276 return (header->
fields[field].
value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
298 unsigned char field_byte;
303 padding = _dbus_string_get_length (writer->
value_str) - start;
319 &contained_type, 0, &variant))
336 _dbus_string_get_length (writer->
value_str) - start - padding);
363 #ifndef DBUS_DISABLE_ASSERT 365 unsigned char v_BYTE;
409 dbus_uint32_t serial)
453 _dbus_header_cache_invalidate_all (header);
500 _dbus_string_get_length (&header->
data)))
535 const char *destination,
537 const char *interface,
539 const char *error_name)
541 unsigned char v_BYTE;
542 dbus_uint32_t v_UINT32;
550 !(interface || member || error_name));
553 if (!reserve_header_padding (header))
557 &_dbus_header_signature_str, 0,
566 v_BYTE = message_type;
592 &_dbus_header_signature_str,
601 if (!write_basic_field (&array,
608 if (destination !=
NULL)
610 if (!write_basic_field (&array,
617 if (interface !=
NULL)
619 if (!write_basic_field (&array,
628 if (!write_basic_field (&array,
635 if (error_name !=
NULL)
637 if (!write_basic_field (&array,
647 correct_header_padding (header);
653 _dbus_string_get_length (&header->
data) - header->
padding);
654 correct_header_padding (header);
680 int *fields_array_len,
688 dbus_uint32_t header_len_unsigned;
689 dbus_uint32_t fields_array_len_unsigned;
690 dbus_uint32_t body_len_unsigned;
696 _dbus_assert (start == (
int) _DBUS_ALIGN_VALUE (start, 8));
702 *validity = DBUS_INVALID_BAD_BYTE_ORDER;
710 if (fields_array_len_unsigned > (
unsigned) max_message_length)
712 *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
720 if (body_len_unsigned > (
unsigned) max_message_length)
722 *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
727 header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
733 if (body_len_unsigned + header_len_unsigned > (
unsigned) max_message_length)
735 *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
740 _dbus_assert (fields_array_len_unsigned < (
unsigned) _DBUS_INT32_MAX);
741 _dbus_assert (header_len_unsigned < (
unsigned) _DBUS_INT32_MAX);
743 *body_len = body_len_unsigned;
744 *fields_array_len = fields_array_len_unsigned;
745 *header_len = header_len_unsigned;
749 _dbus_verbose (
"have %d bytes, need body %u + header %u = %u\n",
750 len, body_len_unsigned, header_len_unsigned,
751 body_len_unsigned + header_len_unsigned);
753 return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
759 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0) 764 REQUIRE_FIELD (INTERFACE);
767 REQUIRE_FIELD (PATH);
768 REQUIRE_FIELD (MEMBER);
771 REQUIRE_FIELD (ERROR_NAME);
772 REQUIRE_FIELD (REPLY_SERIAL);
775 REQUIRE_FIELD (REPLY_SERIAL);
795 dbus_uint32_t v_UINT32;
807 _dbus_assert (_dbus_header_field_types[field].code == field);
810 if (type != expected_type)
812 _dbus_verbose (
"Field %d should have type %d but has %d\n",
813 field, expected_type, type);
814 return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
820 _dbus_verbose (
"Header field %d seen a second time\n", field);
821 return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
825 _dbus_verbose (
"initially caching field %d\n", field);
826 _dbus_header_cache_one (header, field, variant_reader);
828 string_validation_func =
NULL;
847 &value_str, &value_pos);
848 str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
859 bad_string_code = DBUS_INVALID_BAD_DESTINATION;
863 bad_string_code = DBUS_INVALID_BAD_INTERFACE;
867 _dbus_string_get_length (&_dbus_local_interface_str),
868 value_str, str_data_pos))
870 _dbus_verbose (
"Message is on the local interface\n");
871 return DBUS_INVALID_USES_LOCAL_INTERFACE;
877 bad_string_code = DBUS_INVALID_BAD_MEMBER;
882 bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
887 bad_string_code = DBUS_INVALID_BAD_SENDER;
892 string_validation_func =
NULL;
896 _dbus_string_get_length (&_dbus_local_path_str),
897 value_str, str_data_pos))
899 _dbus_verbose (
"Message is from the local path\n");
900 return DBUS_INVALID_USES_LOCAL_PATH;
908 return DBUS_INVALID_BAD_SERIAL;
917 case DBUS_HEADER_FIELD_EXEC_SRC:
920 case DBUS_HEADER_FIELD_EXEC_DST:
927 string_validation_func =
NULL;
935 if (string_validation_func)
946 _dbus_verbose (
"Validating string header field; code %d if fails\n",
949 if (!(*string_validation_func) (value_str, str_data_pos, len))
950 return bad_string_code;
987 int fields_array_len,
998 unsigned char v_byte;
999 dbus_uint32_t v_uint32;
1000 dbus_uint32_t serial;
1005 _dbus_assert (start == (
int) _DBUS_ALIGN_VALUE (start, 8));
1011 _dbus_verbose (
"Failed to copy buffer into new header\n");
1016 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1018 leftover = len - header_len - body_len - start;
1038 _dbus_assert (start + header_len == (
int) _DBUS_ALIGN_VALUE (padding_start, 8));
1039 _dbus_assert (start + header_len == padding_start + padding_len);
1041 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1045 *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
1050 header->
padding = padding_len;
1052 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1064 &_dbus_header_signature_str, 0,
1086 *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1106 *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1126 *validity = DBUS_INVALID_BAD_SERIAL;
1138 unsigned char field_code;
1150 _dbus_verbose (
"invalid header field code\n");
1151 *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1157 _dbus_verbose (
"unknown header field code %d, skipping\n",
1165 v = load_and_validate_field (header, field_code, &variant_reader);
1168 _dbus_verbose (
"Field %d was invalid\n", field_code);
1186 v = check_mandatory_fields (header);
1189 _dbus_verbose (
"Mandatory fields were missing, code %d\n", v);
1232 find_field_for_modification (
DBusHeader *header,
1243 &_dbus_header_signature_str,
1253 unsigned char field_code;
1260 if (field_code == (
unsigned) field)
1293 if (!reserve_header_padding (header))
1297 if (_dbus_header_cache_check (header, field))
1302 if (!find_field_for_modification (header, field,
1303 &reader, &realign_root))
1306 if (!set_basic_field (&reader, field, type, value, &realign_root))
1316 &_dbus_header_signature_str,
1325 &_dbus_header_signature_str,
1334 if (!write_basic_field (&array,
1335 field, type, value))
1342 correct_header_padding (header);
1348 _dbus_header_cache_invalidate_all (header);
1371 _dbus_assert (_dbus_header_field_types[field].code == field);
1378 if (!_dbus_header_cache_check (header, field))
1410 if (!_dbus_header_cache_check (header, field))
1414 *str = &header->
data;
1435 if (_dbus_header_cache_known_nonexistent (header, field))
1441 if (!find_field_for_modification (header, field,
1442 &reader, &realign_root))
1445 if (!reserve_header_padding (header))
1452 correct_header_padding (header);
1454 _dbus_header_cache_invalidate_all (header);
1456 _dbus_assert (!_dbus_header_cache_check (header, field));
1474 unsigned char *flags_p;
1495 const unsigned char *flags_p;
1497 flags_p = _dbus_string_get_const_udata_len (&header->
data,
FLAGS_OFFSET, 1);
1499 return (*flags_p & flag) != 0;
1516 if (byte_order == new_order)
DBusValidity _dbus_validate_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)
Verifies that the range of value_str from value_pos to value_end is a legitimate value of type expect...
#define DBUS_HEADER_FIELD_INVALID
Not equal to any valid header field code.
#define NULL
A null pointer, defined appropriately for C or C++.
dbus_bool_t _dbus_header_load(DBusHeader *header, DBusValidationMode mode, DBusValidity *validity, int byte_order, int fields_array_len, int header_len, int body_len, const DBusString *str, int start, int len)
Creates a message header from potentially-untrusted data.
dbus_bool_t _dbus_header_copy(const DBusHeader *header, DBusHeader *dest)
Initializes dest with a copy of the given header.
void _dbus_marshal_set_uint32(DBusString *str, int pos, dbus_uint32_t value, int byte_order)
Sets the 4 bytes at the given offset to a marshaled unsigned integer, replacing anything found there ...
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
The type writer is an iterator for writing to a block of values.
void _dbus_type_reader_recurse(DBusTypeReader *reader, DBusTypeReader *sub)
Initialize a new reader pointing to the first type and corresponding value that's a child of the curr...
#define DBUS_HEADER_FIELD_SIGNATURE
Header field code for the type signature of a message.
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can't appear in a type string...
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
dbus_uint32_t _dbus_header_get_serial(DBusHeader *header)
See dbus_message_get_serial()
dbus_bool_t _dbus_header_get_flag(DBusHeader *header, dbus_uint32_t flag)
Gets a message flag bit, returning TRUE if the bit is set.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
dbus_bool_t _dbus_header_init(DBusHeader *header)
Initializes a header, but doesn't prepare it for use; to make the header valid, you have to call _dbu...
#define DBUS_HEADER_SIGNATURE
Header format is defined as a signature: byte byte order byte message type ID byte flags byte protoco...
#define DBUS_HEADER_FIELD_LAST
Value of the highest-numbered header field code, can be used to determine the size of an array indexe...
#define DBUS_TYPE_BYTE
Type code marking an 8-bit unsigned integer.
#define DBUS_INTERFACE_LOCAL
This is a special interface whose methods can only be invoked by the local implementation (messages f...
dbus_bool_t _dbus_validate_interface(const DBusString *str, int start, int len)
Checks that the given range of the string is a valid interface name in the D-Bus protocol.
dbus_bool_t _dbus_type_writer_write_basic(DBusTypeWriter *writer, int type, const void *value)
Writes out a basic type.
#define DBUS_MESSAGE_TYPE_ERROR
Message type of an error reply message, see dbus_message_get_type()
#define DBUS_MESSAGE_TYPE_METHOD_RETURN
Message type of a method return message, see dbus_message_get_type()
#define EXPECTED_TYPE_OF_FIELD(field)
Macro to look up the correct type for a field.
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
DBusValidationMode
This is used rather than a bool for high visibility.
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
#define DBUS_HEADER_FIELD_INTERFACE
Header field code for the interface containing a member (method or signal).
DBusValidity
This is primarily used in unit testing, so we can verify that each invalid message is invalid for the...
dbus_bool_t _dbus_validate_member(const DBusString *str, int start, int len)
Checks that the given range of the string is a valid member name in the D-Bus protocol.
DBusString * value_str
where to write values
#define VERSION_OFFSET
Offset to version from start of header.
#define DBUS_PATH_LOCAL
The object path used in local/in-process-generated messages.
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
#define FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET
Offset from start of _dbus_header_signature_str to the signature of an element of the fields array...
#define DBUS_MAJOR_PROTOCOL_VERSION
Protocol version.
dbus_bool_t _dbus_validate_error_name(const DBusString *str, int start, int len)
Checks that the given range of the string is a valid error name in the D-Bus protocol.
#define BYTE_ORDER_OFFSET
Offset to byte order from start of header.
dbus_bool_t _dbus_type_reader_delete(DBusTypeReader *reader, const DBusTypeReader *realign_root)
Recursively deletes any value pointed to by the reader, leaving the reader valid to continue reading...
#define TYPE_OFFSET
Offset to type from start of header.
void _dbus_type_writer_init_values_only(DBusTypeWriter *writer, int byte_order, const DBusString *type_str, int type_pos, DBusString *value_str, int value_pos)
Like _dbus_type_writer_init(), except the type string passed in should correspond to an existing sign...
dbus_bool_t _dbus_type_reader_set_basic(DBusTypeReader *reader, const void *value, const DBusTypeReader *realign_root)
Sets a new value for the basic type value pointed to by the reader, leaving the reader valid to conti...
int _dbus_header_get_message_type(DBusHeader *header)
Gets the type of the message.
#define DBUS_HEADER_FIELD_ERROR_NAME
Header field code for an error name (found in DBUS_MESSAGE_TYPE_ERROR messages).
#define BODY_LENGTH_OFFSET
Offset to body length from start of header.
dbus_bool_t _dbus_type_writer_unrecurse(DBusTypeWriter *writer, DBusTypeWriter *sub)
Closes a container created by _dbus_type_writer_recurse() and writes any additional information to th...
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
void _dbus_type_reader_read_basic(const DBusTypeReader *reader, void *value)
Reads a basic-typed value, as with _dbus_marshal_read_basic().
#define SERIAL_OFFSET
Offset to client serial from start of header.
dbus_bool_t _dbus_header_get_field_basic(DBusHeader *header, int field, int type, void *value)
Gets the value of a field with basic type.
can't determine validity due to OOM
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
dbus_bool_t _dbus_type_writer_append_array(DBusTypeWriter *writer, const DBusString *contained_type, int contained_type_start, DBusTypeWriter *sub)
Append to an existing array.
void _dbus_marshal_read_basic(const DBusString *str, int pos, int type, void *value, int byte_order, int *new_pos)
Demarshals a basic-typed value.
dbus_bool_t _dbus_type_reader_next(DBusTypeReader *reader)
Skip to the next value on this "level".
void _dbus_header_byteswap(DBusHeader *header, int new_order)
Swaps the header into the given order if required.
dbus_bool_t _dbus_header_have_message_untrusted(int max_message_length, DBusValidity *validity, int *byte_order, int *fields_array_len, int *header_len, int *body_len, const DBusString *str, int start, int len)
Given data long enough to contain the length of the message body and the fields array, check whether the data is long enough to contain the entire message (assuming the claimed lengths are accurate).
#define DBUS_MESSAGE_TYPE_METHOD_CALL
Message type of a method call message, see dbus_message_get_type()
#define DBUS_HEADER_FIELD_UNIX_FDS
Header field code for the number of unix file descriptors associated with this message.
#define DBUS_BIG_ENDIAN
Code marking MSB-first byte order in the wire protocol.
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
dbus_bool_t _dbus_validate_bus_name(const DBusString *str, int start, int len)
Checks that the given range of the string is a valid bus name in the D-Bus protocol.
dbus_bool_t _dbus_string_align_length(DBusString *str, int alignment)
Align the length of a string to a specific alignment (typically 4 or 8) by appending nul bytes to the...
#define DBUS_MESSAGE_TYPE_SIGNAL
Message type of a signal message, see dbus_message_get_type()
dbus_bool_t _dbus_string_equal_substring(const DBusString *a, int a_start, int a_len, const DBusString *b, int b_start)
Tests two sub-parts of two DBusString for equality.
#define FIRST_FIELD_OFFSET
Offset to first field in header.
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
#define HEADER_END_BEFORE_PADDING(header)
Compute the end of the header, ignoring padding.
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
void _dbus_header_reinit(DBusHeader *header)
Re-initializes a header that was previously initialized and never freed.
#define DBUS_HEADER_FIELD_DESTINATION
Header field code for the destination bus name of a message.
dbus_bool_t _dbus_header_delete_field(DBusHeader *header, int field)
Deletes a field, if it exists.
#define MAX_POSSIBLE_HEADER_PADDING
The most padding we could ever need for a header.
#define DBUS_MESSAGE_TYPE_INVALID
This value is never a valid message type, see dbus_message_get_type()
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
The type reader is an iterator for reading values from a block of values.
#define TRUE
Expands to "1".
dbus_bool_t _dbus_header_set_field_basic(DBusHeader *header, int field, int type, const void *value)
Sets the value of a field with basic type.
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
#define DBUS_HEADER_FIELD_MEMBER
Header field code for a member (method or signal).
#define DBUS_HEADER_FIELD_SENDER
Header field code for the sender of a message; usually initialized by the message bus...
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
dbus_bool_t _dbus_header_create(DBusHeader *header, int byte_order, int message_type, const char *destination, const char *path, const char *interface, const char *member, const char *error_name)
Fills in the primary fields of the header, so the header is ready for use.
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
int value_pos
next position to write
void _dbus_type_reader_init(DBusTypeReader *reader, int byte_order, const DBusString *type_str, int type_pos, const DBusString *value_str, int value_pos)
Initializes a type reader.
void _dbus_header_free(DBusHeader *header)
Frees a header.
#define FIELDS_ARRAY_LENGTH_OFFSET
Offset to fields array length from start of header.
void _dbus_header_set_serial(DBusHeader *header, dbus_uint32_t serial)
Sets the serial number of a header.
char _dbus_header_get_byte_order(const DBusHeader *header)
Returns the header's byte order.
_DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE)
Static DBusString containing the signature of a message header.
union DBusTypeWriter::@3 u
class-specific data
#define _DBUS_INT32_MAX
Maximum value of type "int32".
dbus_bool_t _dbus_string_validate_nul(const DBusString *str, int start, int len)
Checks that the given range of the string is all nul bytes.
dbus_bool_t _dbus_header_get_field_raw(DBusHeader *header, int field, const DBusString **str, int *pos)
Gets the raw marshaled data for a field.
int _dbus_type_reader_get_current_type(const DBusTypeReader *reader)
Gets the type of the value the reader is currently pointing to; or for a types-only reader gets the t...
#define FALSE
Expands to "0".
#define DBUS_HEADER_FIELD_PATH
Header field code for the path - the path is the object emitting a signal or the object receiving a m...
#define DBUS_HEADER_FIELD_REPLY_SERIAL
Header field code for a reply serial, used to match a DBUS_MESSAGE_TYPE_METHOD_RETURN message with th...
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
#define FLAGS_OFFSET
Offset to flags from start of header.
dbus_bool_t _dbus_string_copy_len(const DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_copy(), but can copy a segment from the middle of the source string.
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
dbus_bool_t _dbus_type_writer_recurse(DBusTypeWriter *writer, int container_type, const DBusString *contained_type, int contained_type_start, DBusTypeWriter *sub)
Opens a new container and writes out the initial information for that container.
#define FIELDS_ARRAY_SIGNATURE_OFFSET
Offset from start of _dbus_header_signature_str to the signature of the fields array.
void _dbus_header_toggle_flag(DBusHeader *header, dbus_uint32_t flag, dbus_bool_t value)
Toggles a message flag bit, turning on the bit if value = TRUE and flipping it off if value = FALSE...
void _dbus_header_update_lengths(DBusHeader *header, int body_len)
Fills in the correct body length.
void _dbus_marshal_byteswap(const DBusString *signature, int signature_start, int old_byte_order, int new_byte_order, DBusString *value_str, int value_pos)
Byteswaps the marshaled data in the given value_str.
int _dbus_type_reader_get_value_pos(const DBusTypeReader *reader)
Gets the current position in the value block.
#define DBUS_LITTLE_ENDIAN
Code marking LSB-first byte order in the wire protocol.
dbus_uint32_t _dbus_marshal_read_uint32(const DBusString *str, int pos, int byte_order, int *new_pos)
Convenience function to demarshal a 32 bit unsigned integer.