1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-marshal-header.c Managing marshaling/demarshaling of message headers
4 * Copyright (C) 2005 Red Hat, Inc.
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "dbus/dbus-shared.h"
26 #include "dbus-marshal-header.h"
27 #include "dbus-marshal-recursive.h"
28 #include "dbus-marshal-byteswap.h"
31 * @addtogroup DBusMarshal
37 /* Not thread locked, but strictly const/read-only so should be OK
39 /** Static #DBusString containing the signature of a message header */
40 _DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE);
41 /** Static #DBusString containing the local interface */
42 _DBUS_STRING_DEFINE_STATIC(_dbus_local_interface_str, DBUS_INTERFACE_LOCAL);
43 /** Static #DBusString containing the local path */
44 _DBUS_STRING_DEFINE_STATIC(_dbus_local_path_str, DBUS_PATH_LOCAL);
46 /** Offset from start of _dbus_header_signature_str to the signature of the fields array */
47 #define FIELDS_ARRAY_SIGNATURE_OFFSET 6
48 /** Offset from start of _dbus_header_signature_str to the signature of an element of the fields array */
49 #define FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET 7
52 /** Offset to byte order from start of header */
53 #define BYTE_ORDER_OFFSET 0
54 /** Offset to type from start of header */
56 /** Offset to flags from start of header */
57 #define FLAGS_OFFSET 2
58 /** Offset to version from start of header */
59 #define VERSION_OFFSET 3
60 /** Offset to body length from start of header */
61 #define BODY_LENGTH_OFFSET 4
62 /** Offset to client serial from start of header */
63 #define SERIAL_OFFSET 8
64 /** Offset to fields array length from start of header */
65 #define FIELDS_ARRAY_LENGTH_OFFSET 12
66 /** Offset to first field in header */
67 #define FIRST_FIELD_OFFSET 16
71 unsigned char code; /**< the field code */
72 unsigned char type; /**< the value type */
75 static const HeaderFieldType
76 _dbus_header_field_types[DBUS_HEADER_FIELD_LAST+1] = {
77 { DBUS_HEADER_FIELD_INVALID, DBUS_TYPE_INVALID },
78 { DBUS_HEADER_FIELD_PATH, DBUS_TYPE_OBJECT_PATH },
79 { DBUS_HEADER_FIELD_INTERFACE, DBUS_TYPE_STRING },
80 { DBUS_HEADER_FIELD_MEMBER, DBUS_TYPE_STRING },
81 { DBUS_HEADER_FIELD_ERROR_NAME, DBUS_TYPE_STRING },
82 { DBUS_HEADER_FIELD_REPLY_SERIAL, DBUS_TYPE_UINT32 },
83 { DBUS_HEADER_FIELD_DESTINATION, DBUS_TYPE_STRING },
84 { DBUS_HEADER_FIELD_SENDER, DBUS_TYPE_STRING },
85 { DBUS_HEADER_FIELD_SIGNATURE, DBUS_TYPE_SIGNATURE },
86 { DBUS_HEADER_FIELD_UNIX_FDS, DBUS_TYPE_UINT32 }
89 /** Macro to look up the correct type for a field */
90 #define EXPECTED_TYPE_OF_FIELD(field) (_dbus_header_field_types[field].type)
92 /** The most padding we could ever need for a header */
93 #define MAX_POSSIBLE_HEADER_PADDING 7
95 reserve_header_padding (DBusHeader *header)
97 _dbus_assert (header->padding <= MAX_POSSIBLE_HEADER_PADDING);
99 if (!_dbus_string_lengthen (&header->data,
100 MAX_POSSIBLE_HEADER_PADDING - header->padding))
102 header->padding = MAX_POSSIBLE_HEADER_PADDING;
107 correct_header_padding (DBusHeader *header)
111 _dbus_assert (header->padding == 7);
113 _dbus_string_shorten (&header->data, header->padding);
114 unpadded_len = _dbus_string_get_length (&header->data);
116 if (!_dbus_string_align_length (&header->data, 8))
117 _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated");
119 header->padding = _dbus_string_get_length (&header->data) - unpadded_len;
122 /** Compute the end of the header, ignoring padding */
123 #define HEADER_END_BEFORE_PADDING(header) \
124 (_dbus_string_get_length (&(header)->data) - (header)->padding)
127 * Invalidates all fields in the cache. This may be used when the
128 * cache is totally uninitialized (contains junk) so should not
129 * look at what's in there now.
131 * @param header the header
134 _dbus_header_cache_invalidate_all (DBusHeader *header)
139 while (i <= DBUS_HEADER_FIELD_LAST)
141 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_UNKNOWN;
149 * @param header the header
150 * @param field_code the field
151 * @param variant_reader the reader for the variant in the field
154 _dbus_header_cache_one (DBusHeader *header,
156 DBusTypeReader *variant_reader)
158 header->fields[field_code].value_pos =
159 _dbus_type_reader_get_value_pos (variant_reader);
162 _dbus_verbose ("cached value_pos %d for field %d\n",
163 header->fields[field_code].value_pos, field_code)
168 * Returns the header's byte order.
170 * @param header the header
171 * @returns the byte order
174 _dbus_header_get_byte_order (const DBusHeader *header)
176 _dbus_assert (_dbus_string_get_length (&header->data) > BYTE_ORDER_OFFSET);
178 return (char) _dbus_string_get_byte (&header->data, BYTE_ORDER_OFFSET);
182 * Revalidates the fields cache
184 * @param header the header
187 _dbus_header_cache_revalidate (DBusHeader *header)
189 DBusTypeReader array;
190 DBusTypeReader reader;
194 while (i <= DBUS_HEADER_FIELD_LAST)
196 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
200 _dbus_type_reader_init (&reader,
201 _dbus_header_get_byte_order (header),
202 &_dbus_header_signature_str,
203 FIELDS_ARRAY_SIGNATURE_OFFSET,
205 FIELDS_ARRAY_LENGTH_OFFSET);
207 _dbus_type_reader_recurse (&reader, &array);
209 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
212 DBusTypeReader variant;
213 unsigned char field_code;
215 _dbus_type_reader_recurse (&array, &sub);
217 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
218 _dbus_type_reader_read_basic (&sub, &field_code);
220 /* Unknown fields should be ignored */
221 if (field_code > DBUS_HEADER_FIELD_LAST)
224 _dbus_type_reader_next (&sub);
226 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_VARIANT);
227 _dbus_type_reader_recurse (&sub, &variant);
229 _dbus_header_cache_one (header, field_code, &variant);
232 _dbus_type_reader_next (&array);
237 * Checks for a field, updating the cache if required.
239 * @param header the header
240 * @param field the field to check
241 * @returns #FALSE if the field doesn't exist
244 _dbus_header_cache_check (DBusHeader *header,
247 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
249 if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
250 _dbus_header_cache_revalidate (header);
252 if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT)
259 * Checks whether a field is known not to exist. It may exist
260 * even if it's not known to exist.
262 * @param header the header
263 * @param field the field to check
264 * @returns #FALSE if the field definitely doesn't exist
267 _dbus_header_cache_known_nonexistent (DBusHeader *header,
270 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
272 return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
276 * Writes a struct of { byte, variant } with the given basic type.
278 * @param writer the writer (should be ready to write a struct)
279 * @param type the type of the value
280 * @param value the value as for _dbus_marshal_set_basic()
281 * @returns #FALSE if no memory
284 write_basic_field (DBusTypeWriter *writer,
290 DBusTypeWriter variant;
293 unsigned char field_byte;
294 DBusString contained_type;
297 start = writer->value_pos;
298 padding = _dbus_string_get_length (writer->value_str) - start;
300 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
305 if (!_dbus_type_writer_write_basic (&sub, DBUS_TYPE_BYTE,
311 _dbus_string_init_const_len (&contained_type, buf, 1);
313 if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT,
314 &contained_type, 0, &variant))
317 if (!_dbus_type_writer_write_basic (&variant, type, value))
320 if (!_dbus_type_writer_unrecurse (&sub, &variant))
323 if (!_dbus_type_writer_unrecurse (writer, &sub))
329 _dbus_string_delete (writer->value_str,
331 _dbus_string_get_length (writer->value_str) - start - padding);
336 * Sets a struct of { byte, variant } with the given basic type.
338 * @param reader the reader (should be iterating over the array pointing at the field to set)
339 * @param type the type of the value
340 * @param value the value as for _dbus_marshal_set_basic()
341 * @param realign_root where to realign from
342 * @returns #FALSE if no memory
345 set_basic_field (DBusTypeReader *reader,
349 const DBusTypeReader *realign_root)
352 DBusTypeReader variant;
354 _dbus_type_reader_recurse (reader, &sub);
356 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
357 #ifndef DBUS_DISABLE_ASSERT
359 unsigned char v_BYTE;
360 _dbus_type_reader_read_basic (&sub, &v_BYTE);
361 _dbus_assert (((int) v_BYTE) == field);
365 if (!_dbus_type_reader_next (&sub))
366 _dbus_assert_not_reached ("no variant field?");
368 _dbus_type_reader_recurse (&sub, &variant);
369 _dbus_assert (_dbus_type_reader_get_current_type (&variant) == type);
371 if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
378 * Gets the type of the message.
380 * @param header the header
384 _dbus_header_get_message_type (DBusHeader *header)
388 type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
389 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
395 * Sets the serial number of a header. This can only be done once on
398 * @param header the header
399 * @param serial the serial
402 _dbus_header_set_serial (DBusHeader *header,
403 dbus_uint32_t serial)
405 /* we use this function to set the serial on outgoing
406 * messages, and to reset the serial in dbus_message_copy;
407 * this assertion should catch a double-set on outgoing.
409 _dbus_assert (_dbus_header_get_serial (header) == 0 ||
412 _dbus_marshal_set_uint32 (&header->data,
415 _dbus_header_get_byte_order (header));
419 * See dbus_message_get_serial()
421 * @param header the header
422 * @returns the client serial
425 _dbus_header_get_serial (DBusHeader *header)
427 return _dbus_marshal_read_uint32 (&header->data,
429 _dbus_header_get_byte_order (header),
434 * Re-initializes a header that was previously initialized and never
435 * freed. After this, to make the header valid you have to call
436 * _dbus_header_create().
438 * @param header header to re-initialize
441 _dbus_header_reinit (DBusHeader *header)
443 _dbus_string_set_length (&header->data, 0);
447 _dbus_header_cache_invalidate_all (header);
451 * Initializes a header, but doesn't prepare it for use;
452 * to make the header valid, you have to call _dbus_header_create().
454 * @param header header to initialize
455 * @param byte_order byte order of the header
456 * @returns #FALSE if not enough memory
459 _dbus_header_init (DBusHeader *header)
461 if (!_dbus_string_init_preallocated (&header->data, 32))
464 _dbus_header_reinit (header);
472 * @param header the header
475 _dbus_header_free (DBusHeader *header)
477 _dbus_string_free (&header->data);
481 * Initializes dest with a copy of the given header.
482 * Resets the message serial to 0 on the copy.
484 * @param header header to copy
485 * @param dest destination for copy
486 * @returns #FALSE if not enough memory
489 _dbus_header_copy (const DBusHeader *header,
494 if (!_dbus_string_init_preallocated (&dest->data,
495 _dbus_string_get_length (&header->data)))
498 if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
500 _dbus_string_free (&dest->data);
504 /* Reset the serial */
505 _dbus_header_set_serial (dest, 0);
511 * Fills in the primary fields of the header, so the header is ready
512 * for use. #NULL may be specified for some or all of the fields to
513 * avoid adding those fields. Some combinations of fields don't make
514 * sense, and passing them in will trigger an assertion failure.
516 * @param header the header
517 * @param message_type the message type
518 * @param destination destination field or #NULL
519 * @param path path field or #NULL
520 * @param interface interface field or #NULL
521 * @param member member field or #NULL
522 * @param error_name error name or #NULL
523 * @returns #FALSE if not enough memory
526 _dbus_header_create (DBusHeader *header,
529 const char *destination,
531 const char *interface,
533 const char *error_name)
535 unsigned char v_BYTE;
536 dbus_uint32_t v_UINT32;
537 DBusTypeWriter writer;
538 DBusTypeWriter array;
540 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
541 byte_order == DBUS_BIG_ENDIAN);
542 _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) ||
544 !(interface || member || error_name));
545 _dbus_assert (_dbus_string_get_length (&header->data) == 0);
547 if (!reserve_header_padding (header))
550 _dbus_type_writer_init_values_only (&writer, byte_order,
551 &_dbus_header_signature_str, 0,
553 HEADER_END_BEFORE_PADDING (header));
556 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
560 v_BYTE = message_type;
561 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
565 v_BYTE = 0; /* flags */
566 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
570 v_BYTE = DBUS_MAJOR_PROTOCOL_VERSION;
571 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
575 v_UINT32 = 0; /* body length */
576 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
580 v_UINT32 = 0; /* serial */
581 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
585 if (!_dbus_type_writer_recurse (&writer, DBUS_TYPE_ARRAY,
586 &_dbus_header_signature_str,
587 FIELDS_ARRAY_SIGNATURE_OFFSET,
591 /* Marshal all the fields (Marshall Fields?) */
595 if (!write_basic_field (&array,
596 DBUS_HEADER_FIELD_PATH,
597 DBUS_TYPE_OBJECT_PATH,
602 if (destination != NULL)
604 if (!write_basic_field (&array,
605 DBUS_HEADER_FIELD_DESTINATION,
611 if (interface != NULL)
613 if (!write_basic_field (&array,
614 DBUS_HEADER_FIELD_INTERFACE,
622 if (!write_basic_field (&array,
623 DBUS_HEADER_FIELD_MEMBER,
629 if (error_name != NULL)
631 if (!write_basic_field (&array,
632 DBUS_HEADER_FIELD_ERROR_NAME,
638 if (!_dbus_type_writer_unrecurse (&writer, &array))
641 correct_header_padding (header);
646 _dbus_string_delete (&header->data, 0,
647 _dbus_string_get_length (&header->data) - header->padding);
648 correct_header_padding (header);
654 * Given data long enough to contain the length of the message body
655 * and the fields array, check whether the data is long enough to
656 * contain the entire message (assuming the claimed lengths are
657 * accurate). Also checks that the lengths are in sanity parameters.
659 * @param max_message_length maximum length of a valid message
660 * @param validity return location for why the data is invalid if it is
661 * @param byte_order return location for byte order
662 * @param fields_array_len return location for claimed fields array length
663 * @param header_len return location for claimed header length
664 * @param body_len return location for claimed body length
665 * @param str the data
666 * @param start start of data, 8-aligned
667 * @param len length of data
668 * @returns #TRUE if the data is long enough for the claimed length, and the lengths were valid
671 _dbus_header_have_message_untrusted (int max_message_length,
672 DBusValidity *validity,
674 int *fields_array_len,
677 const DBusString *str,
682 dbus_uint32_t header_len_unsigned;
683 dbus_uint32_t fields_array_len_unsigned;
684 dbus_uint32_t body_len_unsigned;
686 _dbus_assert (start >= 0);
687 _dbus_assert (start < _DBUS_INT32_MAX / 2);
688 _dbus_assert (len >= 0);
690 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
692 *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET);
694 if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN)
696 *validity = DBUS_INVALID_BAD_BYTE_ORDER;
700 _dbus_assert (FIELDS_ARRAY_LENGTH_OFFSET + 4 <= len);
701 fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET,
704 if (fields_array_len_unsigned > (unsigned) max_message_length)
706 *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
710 _dbus_assert (BODY_LENGTH_OFFSET + 4 < len);
711 body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET,
714 if (body_len_unsigned > (unsigned) max_message_length)
716 *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
720 header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned;
721 header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
723 /* overflow should be impossible since the lengths aren't allowed to
726 _dbus_assert (max_message_length < _DBUS_INT32_MAX / 2);
727 if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length)
729 *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
733 _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT32_MAX);
734 _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT32_MAX);
735 _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT32_MAX);
737 *body_len = body_len_unsigned;
738 *fields_array_len = fields_array_len_unsigned;
739 *header_len = header_len_unsigned;
741 *validity = DBUS_VALID;
743 _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n",
744 len, body_len_unsigned, header_len_unsigned,
745 body_len_unsigned + header_len_unsigned);
747 return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
751 check_mandatory_fields (DBusHeader *header)
753 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0)
755 switch (_dbus_header_get_message_type (header))
757 case DBUS_MESSAGE_TYPE_SIGNAL:
758 REQUIRE_FIELD (INTERFACE);
759 /* FALL THRU - signals also require the path and member */
760 case DBUS_MESSAGE_TYPE_METHOD_CALL:
761 REQUIRE_FIELD (PATH);
762 REQUIRE_FIELD (MEMBER);
764 case DBUS_MESSAGE_TYPE_ERROR:
765 REQUIRE_FIELD (ERROR_NAME);
766 REQUIRE_FIELD (REPLY_SERIAL);
768 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
769 REQUIRE_FIELD (REPLY_SERIAL);
772 /* other message types allowed but ignored */
780 load_and_validate_field (DBusHeader *header,
782 DBusTypeReader *variant_reader)
786 const DBusString *value_str;
789 dbus_uint32_t v_UINT32;
791 dbus_bool_t (* string_validation_func) (const DBusString *str,
794 /* Supposed to have been checked already */
795 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
796 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);
798 /* Before we can cache a field, we need to know it has the right type */
799 type = _dbus_type_reader_get_current_type (variant_reader);
801 _dbus_assert (_dbus_header_field_types[field].code == field);
803 expected_type = EXPECTED_TYPE_OF_FIELD (field);
804 if (type != expected_type)
806 _dbus_verbose ("Field %d should have type %d but has %d\n",
807 field, expected_type, type);
808 return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
811 /* If the field was provided twice, we aren't happy */
812 if (header->fields[field].value_pos >= 0)
814 _dbus_verbose ("Header field %d seen a second time\n", field);
815 return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
818 /* Now we can cache and look at the field content */
819 _dbus_verbose ("initially caching field %d\n", field);
820 _dbus_header_cache_one (header, field, variant_reader);
822 string_validation_func = NULL;
824 /* make compiler happy that all this is initialized */
829 bad_string_code = DBUS_VALID;
831 if (expected_type == DBUS_TYPE_UINT32)
833 _dbus_header_get_field_basic (header, field, expected_type,
836 else if (expected_type == DBUS_TYPE_STRING ||
837 expected_type == DBUS_TYPE_OBJECT_PATH ||
838 expected_type == DBUS_TYPE_SIGNATURE)
840 _dbus_header_get_field_raw (header, field,
841 &value_str, &value_pos);
842 str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
846 _dbus_assert_not_reached ("none of the known fields should have this type");
851 case DBUS_HEADER_FIELD_DESTINATION:
852 string_validation_func = _dbus_validate_bus_name;
853 bad_string_code = DBUS_INVALID_BAD_DESTINATION;
855 case DBUS_HEADER_FIELD_INTERFACE:
856 string_validation_func = _dbus_validate_interface;
857 bad_string_code = DBUS_INVALID_BAD_INTERFACE;
859 if (_dbus_string_equal_substring (&_dbus_local_interface_str,
861 _dbus_string_get_length (&_dbus_local_interface_str),
862 value_str, str_data_pos))
864 _dbus_verbose ("Message is on the local interface\n");
865 return DBUS_INVALID_USES_LOCAL_INTERFACE;
869 case DBUS_HEADER_FIELD_MEMBER:
870 string_validation_func = _dbus_validate_member;
871 bad_string_code = DBUS_INVALID_BAD_MEMBER;
874 case DBUS_HEADER_FIELD_ERROR_NAME:
875 string_validation_func = _dbus_validate_error_name;
876 bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
879 case DBUS_HEADER_FIELD_SENDER:
880 string_validation_func = _dbus_validate_bus_name;
881 bad_string_code = DBUS_INVALID_BAD_SENDER;
884 case DBUS_HEADER_FIELD_PATH:
885 /* OBJECT_PATH was validated generically due to its type */
886 string_validation_func = NULL;
888 if (_dbus_string_equal_substring (&_dbus_local_path_str,
890 _dbus_string_get_length (&_dbus_local_path_str),
891 value_str, str_data_pos))
893 _dbus_verbose ("Message is from the local path\n");
894 return DBUS_INVALID_USES_LOCAL_PATH;
898 case DBUS_HEADER_FIELD_REPLY_SERIAL:
902 return DBUS_INVALID_BAD_SERIAL;
906 case DBUS_HEADER_FIELD_UNIX_FDS:
907 /* Every value makes sense */
910 case DBUS_HEADER_FIELD_SIGNATURE:
911 /* SIGNATURE validated generically due to its type */
912 string_validation_func = NULL;
916 _dbus_assert_not_reached ("unknown field shouldn't be seen here");
920 if (string_validation_func)
924 _dbus_assert (bad_string_code != DBUS_VALID);
926 len = _dbus_marshal_read_uint32 (value_str, value_pos,
927 _dbus_header_get_byte_order (header),
931 _dbus_verbose ("Validating string header field; code %d if fails\n",
934 if (!(*string_validation_func) (value_str, str_data_pos, len))
935 return bad_string_code;
942 * Creates a message header from potentially-untrusted data. The
943 * return value is #TRUE if there was enough memory and the data was
944 * valid. If it returns #TRUE, the header will be created. If it
945 * returns #FALSE and *validity == #DBUS_VALIDITY_UNKNOWN_OOM_ERROR,
946 * then there wasn't enough memory. If it returns #FALSE
947 * and *validity != #DBUS_VALIDITY_UNKNOWN_OOM_ERROR then the data was
950 * The byte_order, fields_array_len, and body_len args should be from
951 * _dbus_header_have_message_untrusted(). Validation performed in
952 * _dbus_header_have_message_untrusted() is assumed to have been
955 * @param header the header (must be initialized)
956 * @param mode whether to do validation
957 * @param validity return location for invalidity reason
958 * @param byte_order byte order from header
959 * @param fields_array_len claimed length of fields array
960 * @param body_len claimed length of body
961 * @param header_len claimed length of header
962 * @param str a string
963 * @param start start of header, 8-aligned
964 * @param len length of string to look at
965 * @returns #FALSE if no memory or data was invalid, #TRUE otherwise
968 _dbus_header_load (DBusHeader *header,
969 DBusValidationMode mode,
970 DBusValidity *validity,
972 int fields_array_len,
975 const DBusString *str,
981 DBusTypeReader reader;
982 DBusTypeReader array_reader;
983 unsigned char v_byte;
984 dbus_uint32_t v_uint32;
985 dbus_uint32_t serial;
990 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
991 _dbus_assert (header_len <= len);
992 _dbus_assert (_dbus_string_get_length (&header->data) == 0);
994 if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
996 _dbus_verbose ("Failed to copy buffer into new header\n");
997 *validity = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
1001 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1003 leftover = len - header_len - body_len - start;
1007 v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
1012 if (v != DBUS_VALID)
1019 _dbus_assert (leftover < len);
1021 padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len);
1022 padding_start = start + FIRST_FIELD_OFFSET + fields_array_len;
1023 _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8));
1024 _dbus_assert (start + header_len == padding_start + padding_len);
1026 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1028 if (!_dbus_string_validate_nul (str, padding_start, padding_len))
1030 *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
1035 header->padding = padding_len;
1037 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1039 *validity = DBUS_VALID;
1043 /* We now know the data is well-formed, but we have to check that
1047 _dbus_type_reader_init (&reader,
1049 &_dbus_header_signature_str, 0,
1053 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1054 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BYTE_ORDER_OFFSET);
1055 _dbus_type_reader_read_basic (&reader, &v_byte);
1056 _dbus_type_reader_next (&reader);
1058 _dbus_assert (v_byte == byte_order);
1061 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1062 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == TYPE_OFFSET);
1063 _dbus_type_reader_read_basic (&reader, &v_byte);
1064 _dbus_type_reader_next (&reader);
1066 /* unknown message types are supposed to be ignored, so only validation here is
1067 * that it isn't invalid
1069 if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
1071 *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1076 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1077 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FLAGS_OFFSET);
1078 _dbus_type_reader_read_basic (&reader, &v_byte);
1079 _dbus_type_reader_next (&reader);
1081 /* unknown flags should be ignored */
1083 /* PROTOCOL VERSION */
1084 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1085 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == VERSION_OFFSET);
1086 _dbus_type_reader_read_basic (&reader, &v_byte);
1087 _dbus_type_reader_next (&reader);
1089 if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
1091 *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1096 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32);
1097 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BODY_LENGTH_OFFSET);
1098 _dbus_type_reader_read_basic (&reader, &v_uint32);
1099 _dbus_type_reader_next (&reader);
1101 _dbus_assert (body_len == (signed) v_uint32);
1104 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32);
1105 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == SERIAL_OFFSET);
1106 _dbus_type_reader_read_basic (&reader, &serial);
1107 _dbus_type_reader_next (&reader);
1111 *validity = DBUS_INVALID_BAD_SERIAL;
1115 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_ARRAY);
1116 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FIELDS_ARRAY_LENGTH_OFFSET);
1118 _dbus_type_reader_recurse (&reader, &array_reader);
1119 while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
1121 DBusTypeReader struct_reader;
1122 DBusTypeReader variant_reader;
1123 unsigned char field_code;
1125 _dbus_assert (_dbus_type_reader_get_current_type (&array_reader) == DBUS_TYPE_STRUCT);
1127 _dbus_type_reader_recurse (&array_reader, &struct_reader);
1129 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_BYTE);
1130 _dbus_type_reader_read_basic (&struct_reader, &field_code);
1131 _dbus_type_reader_next (&struct_reader);
1133 if (field_code == DBUS_HEADER_FIELD_INVALID)
1135 _dbus_verbose ("invalid header field code\n");
1136 *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1140 if (field_code > DBUS_HEADER_FIELD_LAST)
1142 _dbus_verbose ("unknown header field code %d, skipping\n",
1147 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_VARIANT);
1148 _dbus_type_reader_recurse (&struct_reader, &variant_reader);
1150 v = load_and_validate_field (header, field_code, &variant_reader);
1151 if (v != DBUS_VALID)
1153 _dbus_verbose ("Field %d was invalid\n", field_code);
1159 _dbus_type_reader_next (&array_reader);
1162 /* Anything we didn't fill in is now known not to exist */
1164 while (i <= DBUS_HEADER_FIELD_LAST)
1166 if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
1167 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
1171 v = check_mandatory_fields (header);
1172 if (v != DBUS_VALID)
1174 _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
1179 *validity = DBUS_VALID;
1183 _dbus_string_set_length (&header->data, 0);
1188 * Fills in the correct body length.
1190 * @param header the header
1191 * @param body_len the length of the body
1194 _dbus_header_update_lengths (DBusHeader *header,
1197 _dbus_marshal_set_uint32 (&header->data,
1200 _dbus_header_get_byte_order (header));
1204 find_field_for_modification (DBusHeader *header,
1206 DBusTypeReader *reader,
1207 DBusTypeReader *realign_root)
1213 _dbus_type_reader_init (realign_root,
1214 _dbus_header_get_byte_order (header),
1215 &_dbus_header_signature_str,
1216 FIELDS_ARRAY_SIGNATURE_OFFSET,
1218 FIELDS_ARRAY_LENGTH_OFFSET);
1220 _dbus_type_reader_recurse (realign_root, reader);
1222 while (_dbus_type_reader_get_current_type (reader) != DBUS_TYPE_INVALID)
1225 unsigned char field_code;
1227 _dbus_type_reader_recurse (reader, &sub);
1229 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
1230 _dbus_type_reader_read_basic (&sub, &field_code);
1232 if (field_code == (unsigned) field)
1234 _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_STRUCT);
1239 _dbus_type_reader_next (reader);
1247 * Sets the value of a field with basic type. If the value is a string
1248 * value, it isn't allowed to be #NULL. If the field doesn't exist,
1249 * it will be created.
1251 * @param header the header
1252 * @param field the field to set
1253 * @param type the type of the value
1254 * @param value the value as for _dbus_marshal_set_basic()
1255 * @returns #FALSE if no memory
1258 _dbus_header_set_field_basic (DBusHeader *header,
1263 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
1265 if (!reserve_header_padding (header))
1268 /* If the field exists we set, otherwise we append */
1269 if (_dbus_header_cache_check (header, field))
1271 DBusTypeReader reader;
1272 DBusTypeReader realign_root;
1274 if (!find_field_for_modification (header, field,
1275 &reader, &realign_root))
1276 _dbus_assert_not_reached ("field was marked present in cache but wasn't found");
1278 if (!set_basic_field (&reader, field, type, value, &realign_root))
1283 DBusTypeWriter writer;
1284 DBusTypeWriter array;
1286 _dbus_type_writer_init_values_only (&writer,
1287 _dbus_header_get_byte_order (header),
1288 &_dbus_header_signature_str,
1289 FIELDS_ARRAY_SIGNATURE_OFFSET,
1291 FIELDS_ARRAY_LENGTH_OFFSET);
1293 /* recurse into array without creating a new length, and jump to
1296 if (!_dbus_type_writer_append_array (&writer,
1297 &_dbus_header_signature_str,
1298 FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET,
1300 _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
1302 _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET);
1303 _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET);
1304 _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header));
1306 if (!write_basic_field (&array,
1307 field, type, value))
1310 if (!_dbus_type_writer_unrecurse (&writer, &array))
1311 _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
1314 correct_header_padding (header);
1316 /* We could be smarter about this (only invalidate fields after the
1317 * one we modified, or even only if the one we modified changed
1318 * length). But this hack is a start.
1320 _dbus_header_cache_invalidate_all (header);
1326 * Gets the value of a field with basic type. If the field
1327 * doesn't exist, returns #FALSE, otherwise returns #TRUE.
1329 * @param header the header
1330 * @param field the field to get
1331 * @param type the type of the value
1332 * @param value the value as for _dbus_marshal_read_basic()
1333 * @returns #FALSE if the field doesn't exist
1336 _dbus_header_get_field_basic (DBusHeader *header,
1341 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);
1342 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
1343 _dbus_assert (_dbus_header_field_types[field].code == field);
1344 /* in light of this you might ask why the type is passed in;
1345 * the only rationale I can think of is so the caller has
1346 * to specify its expectation and breaks if we change it
1348 _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
1350 if (!_dbus_header_cache_check (header, field))
1353 _dbus_assert (header->fields[field].value_pos >= 0);
1355 _dbus_marshal_read_basic (&header->data,
1356 header->fields[field].value_pos,
1357 type, value, _dbus_header_get_byte_order (header),
1364 * Gets the raw marshaled data for a field. If the field doesn't
1365 * exist, returns #FALSE, otherwise returns #TRUE. Returns the start
1366 * of the marshaled data, i.e. usually the byte where the length
1367 * starts (for strings and arrays) or for basic types just the value
1370 * @param header the header
1371 * @param field the field to get
1372 * @param str return location for the data string
1373 * @param pos return location for start of field value
1374 * @returns #FALSE if the field doesn't exist
1377 _dbus_header_get_field_raw (DBusHeader *header,
1379 const DBusString **str,
1382 if (!_dbus_header_cache_check (header, field))
1386 *str = &header->data;
1388 *pos = header->fields[field].value_pos;
1394 * Deletes a field, if it exists.
1396 * @param header the header
1397 * @param field the field to delete
1398 * @returns #FALSE if no memory
1401 _dbus_header_delete_field (DBusHeader *header,
1404 DBusTypeReader reader;
1405 DBusTypeReader realign_root;
1407 if (_dbus_header_cache_known_nonexistent (header, field))
1408 return TRUE; /* nothing to do */
1410 /* Scan to the field we want, delete and realign, reappend
1411 * padding. Field may turn out not to exist.
1413 if (!find_field_for_modification (header, field,
1414 &reader, &realign_root))
1415 return TRUE; /* nothing to do */
1417 if (!reserve_header_padding (header))
1420 if (!_dbus_type_reader_delete (&reader,
1424 correct_header_padding (header);
1426 _dbus_header_cache_invalidate_all (header);
1428 _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */
1434 * Toggles a message flag bit, turning on the bit if value = TRUE and
1435 * flipping it off if value = FALSE.
1437 * @param header the header
1438 * @param flag the message flag to toggle
1439 * @param value toggle on or off
1442 _dbus_header_toggle_flag (DBusHeader *header,
1446 unsigned char *flags_p;
1448 flags_p = _dbus_string_get_data_len (&header->data, FLAGS_OFFSET, 1);
1457 * Gets a message flag bit, returning TRUE if the bit is set.
1459 * @param header the header
1460 * @param flag the message flag to get
1461 * @returns #TRUE if the flag is set
1464 _dbus_header_get_flag (DBusHeader *header,
1467 const unsigned char *flags_p;
1469 flags_p = _dbus_string_get_const_data_len (&header->data, FLAGS_OFFSET, 1);
1471 return (*flags_p & flag) != 0;
1475 * Swaps the header into the given order if required.
1477 * @param header the header
1478 * @param new_order the new byte order
1481 _dbus_header_byteswap (DBusHeader *header,
1486 byte_order = _dbus_header_get_byte_order (header);
1488 if (byte_order == new_order)
1491 _dbus_marshal_byteswap (&_dbus_header_signature_str,
1496 _dbus_string_set_byte (&header->data, BYTE_ORDER_OFFSET, new_order);
1501 #ifdef DBUS_BUILD_TESTS
1502 #include "dbus-test.h"
1506 _dbus_marshal_header_test (void)
1512 #endif /* DBUS_BUILD_TESTS */