00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "dbus/dbus-shared.h"
00025 #include "dbus-marshal-header.h"
00026 #include "dbus-marshal-recursive.h"
00027 #include "dbus-marshal-byteswap.h"
00028
00036
00037
00039 _DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE);
00041 _DBUS_STRING_DEFINE_STATIC(_dbus_local_interface_str, DBUS_INTERFACE_LOCAL);
00043 _DBUS_STRING_DEFINE_STATIC(_dbus_local_path_str, DBUS_PATH_LOCAL);
00044
00046 #define FIELDS_ARRAY_SIGNATURE_OFFSET 6
00047
00048 #define FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET 7
00049
00050
00052 #define BYTE_ORDER_OFFSET 0
00053
00054 #define TYPE_OFFSET 1
00055
00056 #define FLAGS_OFFSET 2
00057
00058 #define VERSION_OFFSET 3
00059
00060 #define BODY_LENGTH_OFFSET 4
00061
00062 #define SERIAL_OFFSET 8
00063
00064 #define FIELDS_ARRAY_LENGTH_OFFSET 12
00065
00066 #define FIRST_FIELD_OFFSET 16
00067
00068 typedef struct
00069 {
00070 unsigned char code;
00071 unsigned char type;
00072 } HeaderFieldType;
00073
00074 static const HeaderFieldType
00075 _dbus_header_field_types[DBUS_HEADER_FIELD_LAST+1] = {
00076 { DBUS_HEADER_FIELD_INVALID, DBUS_TYPE_INVALID },
00077 { DBUS_HEADER_FIELD_PATH, DBUS_TYPE_OBJECT_PATH },
00078 { DBUS_HEADER_FIELD_INTERFACE, DBUS_TYPE_STRING },
00079 { DBUS_HEADER_FIELD_MEMBER, DBUS_TYPE_STRING },
00080 { DBUS_HEADER_FIELD_ERROR_NAME, DBUS_TYPE_STRING },
00081 { DBUS_HEADER_FIELD_REPLY_SERIAL, DBUS_TYPE_UINT32 },
00082 { DBUS_HEADER_FIELD_DESTINATION, DBUS_TYPE_STRING },
00083 { DBUS_HEADER_FIELD_SENDER, DBUS_TYPE_STRING },
00084 { DBUS_HEADER_FIELD_SIGNATURE, DBUS_TYPE_SIGNATURE }
00085 };
00086
00088 #define EXPECTED_TYPE_OF_FIELD(field) (_dbus_header_field_types[field].type)
00089
00091 #define MAX_POSSIBLE_HEADER_PADDING 7
00092 static dbus_bool_t
00093 reserve_header_padding (DBusHeader *header)
00094 {
00095 _dbus_assert (header->padding <= MAX_POSSIBLE_HEADER_PADDING);
00096
00097 if (!_dbus_string_lengthen (&header->data,
00098 MAX_POSSIBLE_HEADER_PADDING - header->padding))
00099 return FALSE;
00100 header->padding = MAX_POSSIBLE_HEADER_PADDING;
00101 return TRUE;
00102 }
00103
00104 static void
00105 correct_header_padding (DBusHeader *header)
00106 {
00107 int unpadded_len;
00108
00109 _dbus_assert (header->padding == 7);
00110
00111 _dbus_string_shorten (&header->data, header->padding);
00112 unpadded_len = _dbus_string_get_length (&header->data);
00113
00114 if (!_dbus_string_align_length (&header->data, 8))
00115 _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated");
00116
00117 header->padding = _dbus_string_get_length (&header->data) - unpadded_len;
00118 }
00119
00121 #define HEADER_END_BEFORE_PADDING(header) \
00122 (_dbus_string_get_length (&(header)->data) - (header)->padding)
00123
00131 static void
00132 _dbus_header_cache_invalidate_all (DBusHeader *header)
00133 {
00134 int i;
00135
00136 i = 0;
00137 while (i <= DBUS_HEADER_FIELD_LAST)
00138 {
00139 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_UNKNOWN;
00140 ++i;
00141 }
00142 }
00143
00151 static void
00152 _dbus_header_cache_one (DBusHeader *header,
00153 int field_code,
00154 DBusTypeReader *variant_reader)
00155 {
00156 int variant_type;
00157
00158 variant_type = _dbus_type_reader_get_current_type (variant_reader);
00159
00160 header->fields[field_code].value_pos =
00161 _dbus_type_reader_get_value_pos (variant_reader);
00162
00163 #if 0
00164 _dbus_verbose ("cached value_pos %d for field %d\n",
00165 header->fields[field_code].value_pos, field_code)
00166 #endif
00167 }
00168
00174 static void
00175 _dbus_header_cache_revalidate (DBusHeader *header)
00176 {
00177 DBusTypeReader array;
00178 DBusTypeReader reader;
00179 int i;
00180
00181 i = 0;
00182 while (i <= DBUS_HEADER_FIELD_LAST)
00183 {
00184 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
00185 ++i;
00186 }
00187
00188 _dbus_type_reader_init (&reader,
00189 header->byte_order,
00190 &_dbus_header_signature_str,
00191 FIELDS_ARRAY_SIGNATURE_OFFSET,
00192 &header->data,
00193 FIELDS_ARRAY_LENGTH_OFFSET);
00194
00195 _dbus_type_reader_recurse (&reader, &array);
00196
00197 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
00198 {
00199 DBusTypeReader sub;
00200 DBusTypeReader variant;
00201 unsigned char field_code;
00202
00203 _dbus_type_reader_recurse (&array, &sub);
00204
00205 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
00206 _dbus_type_reader_read_basic (&sub, &field_code);
00207
00208
00209 if (field_code > DBUS_HEADER_FIELD_LAST)
00210 goto next_field;
00211
00212 _dbus_type_reader_next (&sub);
00213
00214 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_VARIANT);
00215 _dbus_type_reader_recurse (&sub, &variant);
00216
00217 _dbus_header_cache_one (header, field_code, &variant);
00218
00219 next_field:
00220 _dbus_type_reader_next (&array);
00221 }
00222 }
00223
00231 static dbus_bool_t
00232 _dbus_header_cache_check (DBusHeader *header,
00233 int field)
00234 {
00235 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00236
00237 if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
00238 _dbus_header_cache_revalidate (header);
00239
00240 if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT)
00241 return FALSE;
00242
00243 return TRUE;
00244 }
00245
00254 static dbus_bool_t
00255 _dbus_header_cache_known_nonexistent (DBusHeader *header,
00256 int field)
00257 {
00258 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00259
00260 return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
00261 }
00262
00271 static dbus_bool_t
00272 write_basic_field (DBusTypeWriter *writer,
00273 int field,
00274 int type,
00275 const void *value)
00276 {
00277 DBusTypeWriter sub;
00278 DBusTypeWriter variant;
00279 int start;
00280 int padding;
00281 unsigned char field_byte;
00282 DBusString contained_type;
00283 char buf[2];
00284
00285 start = writer->value_pos;
00286 padding = _dbus_string_get_length (writer->value_str) - start;
00287
00288 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
00289 NULL, 0, &sub))
00290 goto append_failed;
00291
00292 field_byte = field;
00293 if (!_dbus_type_writer_write_basic (&sub, DBUS_TYPE_BYTE,
00294 &field_byte))
00295 goto append_failed;
00296
00297 buf[0] = type;
00298 buf[1] = '\0';
00299 _dbus_string_init_const_len (&contained_type, buf, 1);
00300
00301 if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT,
00302 &contained_type, 0, &variant))
00303 goto append_failed;
00304
00305 if (!_dbus_type_writer_write_basic (&variant, type, value))
00306 goto append_failed;
00307
00308 if (!_dbus_type_writer_unrecurse (&sub, &variant))
00309 goto append_failed;
00310
00311 if (!_dbus_type_writer_unrecurse (writer, &sub))
00312 goto append_failed;
00313
00314 return TRUE;
00315
00316 append_failed:
00317 _dbus_string_delete (writer->value_str,
00318 start,
00319 _dbus_string_get_length (writer->value_str) - start - padding);
00320 return FALSE;
00321 }
00322
00332 static dbus_bool_t
00333 set_basic_field (DBusTypeReader *reader,
00334 int field,
00335 int type,
00336 const void *value,
00337 const DBusTypeReader *realign_root)
00338 {
00339 DBusTypeReader sub;
00340 DBusTypeReader variant;
00341
00342 _dbus_type_reader_recurse (reader, &sub);
00343
00344 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
00345 #ifndef DBUS_DISABLE_ASSERT
00346 {
00347 unsigned char v_BYTE;
00348 _dbus_type_reader_read_basic (&sub, &v_BYTE);
00349 _dbus_assert (((int) v_BYTE) == field);
00350 }
00351 #endif
00352
00353 if (!_dbus_type_reader_next (&sub))
00354 _dbus_assert_not_reached ("no variant field?");
00355
00356 _dbus_type_reader_recurse (&sub, &variant);
00357 _dbus_assert (_dbus_type_reader_get_current_type (&variant) == type);
00358
00359 if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
00360 return FALSE;
00361
00362 return TRUE;
00363 }
00364
00371 int
00372 _dbus_header_get_message_type (DBusHeader *header)
00373 {
00374 int type;
00375
00376 type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
00377 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
00378
00379 return type;
00380 }
00381
00389 void
00390 _dbus_header_set_serial (DBusHeader *header,
00391 dbus_uint32_t serial)
00392 {
00393
00394
00395
00396
00397 _dbus_assert (_dbus_header_get_serial (header) == 0 ||
00398 serial == 0);
00399
00400 _dbus_marshal_set_uint32 (&header->data,
00401 SERIAL_OFFSET,
00402 serial,
00403 header->byte_order);
00404 }
00405
00412 dbus_uint32_t
00413 _dbus_header_get_serial (DBusHeader *header)
00414 {
00415 return _dbus_marshal_read_uint32 (&header->data,
00416 SERIAL_OFFSET,
00417 header->byte_order,
00418 NULL);
00419 }
00420
00429 void
00430 _dbus_header_reinit (DBusHeader *header,
00431 int byte_order)
00432 {
00433 _dbus_string_set_length (&header->data, 0);
00434
00435 header->byte_order = byte_order;
00436 header->padding = 0;
00437
00438 _dbus_header_cache_invalidate_all (header);
00439 }
00440
00449 dbus_bool_t
00450 _dbus_header_init (DBusHeader *header,
00451 int byte_order)
00452 {
00453 if (!_dbus_string_init_preallocated (&header->data, 32))
00454 return FALSE;
00455
00456 _dbus_header_reinit (header, byte_order);
00457
00458 return TRUE;
00459 }
00460
00466 void
00467 _dbus_header_free (DBusHeader *header)
00468 {
00469 _dbus_string_free (&header->data);
00470 }
00471
00480 dbus_bool_t
00481 _dbus_header_copy (const DBusHeader *header,
00482 DBusHeader *dest)
00483 {
00484 *dest = *header;
00485
00486 if (!_dbus_string_init_preallocated (&dest->data,
00487 _dbus_string_get_length (&header->data)))
00488 return FALSE;
00489
00490 if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
00491 {
00492 _dbus_string_free (&dest->data);
00493 return FALSE;
00494 }
00495
00496
00497 _dbus_header_set_serial (dest, 0);
00498
00499 return TRUE;
00500 }
00501
00517 dbus_bool_t
00518 _dbus_header_create (DBusHeader *header,
00519 int message_type,
00520 const char *destination,
00521 const char *path,
00522 const char *interface,
00523 const char *member,
00524 const char *error_name)
00525 {
00526 unsigned char v_BYTE;
00527 dbus_uint32_t v_UINT32;
00528 DBusTypeWriter writer;
00529 DBusTypeWriter array;
00530
00531 _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) ||
00532 (error_name) ||
00533 !(interface || member || error_name));
00534 _dbus_assert (_dbus_string_get_length (&header->data) == 0);
00535
00536 if (!reserve_header_padding (header))
00537 return FALSE;
00538
00539 _dbus_type_writer_init_values_only (&writer, header->byte_order,
00540 &_dbus_header_signature_str, 0,
00541 &header->data,
00542 HEADER_END_BEFORE_PADDING (header));
00543
00544 v_BYTE = header->byte_order;
00545 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
00546 &v_BYTE))
00547 goto oom;
00548
00549 v_BYTE = message_type;
00550 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
00551 &v_BYTE))
00552 goto oom;
00553
00554 v_BYTE = 0;
00555 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
00556 &v_BYTE))
00557 goto oom;
00558
00559 v_BYTE = DBUS_MAJOR_PROTOCOL_VERSION;
00560 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
00561 &v_BYTE))
00562 goto oom;
00563
00564 v_UINT32 = 0;
00565 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
00566 &v_UINT32))
00567 goto oom;
00568
00569 v_UINT32 = 0;
00570 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
00571 &v_UINT32))
00572 goto oom;
00573
00574 if (!_dbus_type_writer_recurse (&writer, DBUS_TYPE_ARRAY,
00575 &_dbus_header_signature_str,
00576 FIELDS_ARRAY_SIGNATURE_OFFSET,
00577 &array))
00578 goto oom;
00579
00580
00581
00582 if (path != NULL)
00583 {
00584 if (!write_basic_field (&array,
00585 DBUS_HEADER_FIELD_PATH,
00586 DBUS_TYPE_OBJECT_PATH,
00587 &path))
00588 goto oom;
00589 }
00590
00591 if (destination != NULL)
00592 {
00593 if (!write_basic_field (&array,
00594 DBUS_HEADER_FIELD_DESTINATION,
00595 DBUS_TYPE_STRING,
00596 &destination))
00597 goto oom;
00598 }
00599
00600 if (interface != NULL)
00601 {
00602 if (!write_basic_field (&array,
00603 DBUS_HEADER_FIELD_INTERFACE,
00604 DBUS_TYPE_STRING,
00605 &interface))
00606 goto oom;
00607 }
00608
00609 if (member != NULL)
00610 {
00611 if (!write_basic_field (&array,
00612 DBUS_HEADER_FIELD_MEMBER,
00613 DBUS_TYPE_STRING,
00614 &member))
00615 goto oom;
00616 }
00617
00618 if (error_name != NULL)
00619 {
00620 if (!write_basic_field (&array,
00621 DBUS_HEADER_FIELD_ERROR_NAME,
00622 DBUS_TYPE_STRING,
00623 &error_name))
00624 goto oom;
00625 }
00626
00627 if (!_dbus_type_writer_unrecurse (&writer, &array))
00628 goto oom;
00629
00630 correct_header_padding (header);
00631
00632 return TRUE;
00633
00634 oom:
00635 _dbus_string_delete (&header->data, 0,
00636 _dbus_string_get_length (&header->data) - header->padding);
00637 correct_header_padding (header);
00638
00639 return FALSE;
00640 }
00641
00659 dbus_bool_t
00660 _dbus_header_have_message_untrusted (int max_message_length,
00661 DBusValidity *validity,
00662 int *byte_order,
00663 int *fields_array_len,
00664 int *header_len,
00665 int *body_len,
00666 const DBusString *str,
00667 int start,
00668 int len)
00669
00670 {
00671 dbus_uint32_t header_len_unsigned;
00672 dbus_uint32_t fields_array_len_unsigned;
00673 dbus_uint32_t body_len_unsigned;
00674
00675 _dbus_assert (start >= 0);
00676 _dbus_assert (start < _DBUS_INT32_MAX / 2);
00677 _dbus_assert (len >= 0);
00678
00679 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
00680
00681 *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET);
00682
00683 if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN)
00684 {
00685 *validity = DBUS_INVALID_BAD_BYTE_ORDER;
00686 return FALSE;
00687 }
00688
00689 _dbus_assert (FIELDS_ARRAY_LENGTH_OFFSET + 4 <= len);
00690 fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET,
00691 *byte_order, NULL);
00692
00693 if (fields_array_len_unsigned > (unsigned) max_message_length)
00694 {
00695 *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
00696 return FALSE;
00697 }
00698
00699 _dbus_assert (BODY_LENGTH_OFFSET + 4 < len);
00700 body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET,
00701 *byte_order, NULL);
00702
00703 if (body_len_unsigned > (unsigned) max_message_length)
00704 {
00705 *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
00706 return FALSE;
00707 }
00708
00709 header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned;
00710 header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
00711
00712
00713
00714
00715 _dbus_assert (max_message_length < _DBUS_INT32_MAX / 2);
00716 if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length)
00717 {
00718 *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
00719 return FALSE;
00720 }
00721
00722 _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT32_MAX);
00723 _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT32_MAX);
00724 _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT32_MAX);
00725
00726 *body_len = body_len_unsigned;
00727 *fields_array_len = fields_array_len_unsigned;
00728 *header_len = header_len_unsigned;
00729
00730 *validity = DBUS_VALID;
00731
00732 _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n",
00733 len, body_len_unsigned, header_len_unsigned,
00734 body_len_unsigned + header_len_unsigned);
00735
00736 return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
00737 }
00738
00739 static DBusValidity
00740 check_mandatory_fields (DBusHeader *header)
00741 {
00742 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0)
00743
00744 switch (_dbus_header_get_message_type (header))
00745 {
00746 case DBUS_MESSAGE_TYPE_SIGNAL:
00747 REQUIRE_FIELD (INTERFACE);
00748
00749 case DBUS_MESSAGE_TYPE_METHOD_CALL:
00750 REQUIRE_FIELD (PATH);
00751 REQUIRE_FIELD (MEMBER);
00752 break;
00753 case DBUS_MESSAGE_TYPE_ERROR:
00754 REQUIRE_FIELD (ERROR_NAME);
00755 REQUIRE_FIELD (REPLY_SERIAL);
00756 break;
00757 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
00758 REQUIRE_FIELD (REPLY_SERIAL);
00759 break;
00760 default:
00761
00762 break;
00763 }
00764
00765 return DBUS_VALID;
00766 }
00767
00768 static DBusValidity
00769 load_and_validate_field (DBusHeader *header,
00770 int field,
00771 DBusTypeReader *variant_reader)
00772 {
00773 int type;
00774 int expected_type;
00775 const DBusString *value_str;
00776 int value_pos;
00777 int str_data_pos;
00778 dbus_uint32_t v_UINT32;
00779 int bad_string_code;
00780 dbus_bool_t (* string_validation_func) (const DBusString *str,
00781 int start, int len);
00782
00783
00784 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00785 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);
00786
00787
00788 type = _dbus_type_reader_get_current_type (variant_reader);
00789
00790 _dbus_assert (_dbus_header_field_types[field].code == field);
00791
00792 expected_type = EXPECTED_TYPE_OF_FIELD (field);
00793 if (type != expected_type)
00794 {
00795 _dbus_verbose ("Field %d should have type %d but has %d\n",
00796 field, expected_type, type);
00797 return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
00798 }
00799
00800
00801 if (header->fields[field].value_pos >= 0)
00802 {
00803 _dbus_verbose ("Header field %d seen a second time\n", field);
00804 return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
00805 }
00806
00807
00808 _dbus_verbose ("initially caching field %d\n", field);
00809 _dbus_header_cache_one (header, field, variant_reader);
00810
00811 string_validation_func = NULL;
00812
00813
00814 v_UINT32 = 0;
00815 value_str = NULL;
00816 value_pos = -1;
00817 str_data_pos = -1;
00818 bad_string_code = DBUS_VALID;
00819
00820 if (expected_type == DBUS_TYPE_UINT32)
00821 {
00822 _dbus_header_get_field_basic (header, field, expected_type,
00823 &v_UINT32);
00824 }
00825 else if (expected_type == DBUS_TYPE_STRING ||
00826 expected_type == DBUS_TYPE_OBJECT_PATH ||
00827 expected_type == DBUS_TYPE_SIGNATURE)
00828 {
00829 _dbus_header_get_field_raw (header, field,
00830 &value_str, &value_pos);
00831 str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
00832 }
00833 else
00834 {
00835 _dbus_assert_not_reached ("none of the known fields should have this type");
00836 }
00837
00838 switch (field)
00839 {
00840 case DBUS_HEADER_FIELD_DESTINATION:
00841 string_validation_func = _dbus_validate_bus_name;
00842 bad_string_code = DBUS_INVALID_BAD_DESTINATION;
00843 break;
00844 case DBUS_HEADER_FIELD_INTERFACE:
00845 string_validation_func = _dbus_validate_interface;
00846 bad_string_code = DBUS_INVALID_BAD_INTERFACE;
00847
00848 if (_dbus_string_equal_substring (&_dbus_local_interface_str,
00849 0,
00850 _dbus_string_get_length (&_dbus_local_interface_str),
00851 value_str, str_data_pos))
00852 {
00853 _dbus_verbose ("Message is on the local interface\n");
00854 return DBUS_INVALID_USES_LOCAL_INTERFACE;
00855 }
00856 break;
00857
00858 case DBUS_HEADER_FIELD_MEMBER:
00859 string_validation_func = _dbus_validate_member;
00860 bad_string_code = DBUS_INVALID_BAD_MEMBER;
00861 break;
00862
00863 case DBUS_HEADER_FIELD_ERROR_NAME:
00864 string_validation_func = _dbus_validate_error_name;
00865 bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
00866 break;
00867
00868 case DBUS_HEADER_FIELD_SENDER:
00869 string_validation_func = _dbus_validate_bus_name;
00870 bad_string_code = DBUS_INVALID_BAD_SENDER;
00871 break;
00872
00873 case DBUS_HEADER_FIELD_PATH:
00874
00875 string_validation_func = NULL;
00876
00877 if (_dbus_string_equal_substring (&_dbus_local_path_str,
00878 0,
00879 _dbus_string_get_length (&_dbus_local_path_str),
00880 value_str, str_data_pos))
00881 {
00882 _dbus_verbose ("Message is from the local path\n");
00883 return DBUS_INVALID_USES_LOCAL_PATH;
00884 }
00885 break;
00886
00887 case DBUS_HEADER_FIELD_REPLY_SERIAL:
00888
00889 if (v_UINT32 == 0)
00890 {
00891 return DBUS_INVALID_BAD_SERIAL;
00892 }
00893 break;
00894
00895 case DBUS_HEADER_FIELD_SIGNATURE:
00896
00897 string_validation_func = NULL;
00898 break;
00899
00900 default:
00901 _dbus_assert_not_reached ("unknown field shouldn't be seen here");
00902 break;
00903 }
00904
00905 if (string_validation_func)
00906 {
00907 dbus_uint32_t len;
00908
00909 _dbus_assert (bad_string_code != DBUS_VALID);
00910
00911 len = _dbus_marshal_read_uint32 (value_str, value_pos,
00912 header->byte_order, NULL);
00913
00914 #if 0
00915 _dbus_verbose ("Validating string header field; code %d if fails\n",
00916 bad_string_code);
00917 #endif
00918 if (!(*string_validation_func) (value_str, str_data_pos, len))
00919 return bad_string_code;
00920 }
00921
00922 return DBUS_VALID;
00923 }
00924
00951 dbus_bool_t
00952 _dbus_header_load (DBusHeader *header,
00953 DBusValidationMode mode,
00954 DBusValidity *validity,
00955 int byte_order,
00956 int fields_array_len,
00957 int header_len,
00958 int body_len,
00959 const DBusString *str,
00960 int start,
00961 int len)
00962 {
00963 int leftover;
00964 DBusValidity v;
00965 DBusTypeReader reader;
00966 DBusTypeReader array_reader;
00967 unsigned char v_byte;
00968 dbus_uint32_t v_uint32;
00969 dbus_uint32_t serial;
00970 int padding_start;
00971 int padding_len;
00972 int i;
00973
00974 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
00975 _dbus_assert (header_len <= len);
00976 _dbus_assert (_dbus_string_get_length (&header->data) == 0);
00977
00978 if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
00979 {
00980 _dbus_verbose ("Failed to copy buffer into new header\n");
00981 *validity = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
00982 return FALSE;
00983 }
00984
00985 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
00986 {
00987 leftover = len - header_len - body_len - start;
00988 }
00989 else
00990 {
00991 v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
00992 byte_order,
00993 &leftover,
00994 str, start, len);
00995
00996 if (v != DBUS_VALID)
00997 {
00998 *validity = v;
00999 goto invalid;
01000 }
01001 }
01002
01003 _dbus_assert (leftover < len);
01004
01005 padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len);
01006 padding_start = start + FIRST_FIELD_OFFSET + fields_array_len;
01007 _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8));
01008 _dbus_assert (start + header_len == padding_start + padding_len);
01009
01010 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
01011 {
01012 if (!_dbus_string_validate_nul (str, padding_start, padding_len))
01013 {
01014 *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
01015 goto invalid;
01016 }
01017 }
01018
01019 header->padding = padding_len;
01020
01021 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
01022 {
01023 *validity = DBUS_VALID;
01024 return TRUE;
01025 }
01026
01027
01028
01029
01030
01031 _dbus_type_reader_init (&reader,
01032 byte_order,
01033 &_dbus_header_signature_str, 0,
01034 str, start);
01035
01036
01037 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
01038 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BYTE_ORDER_OFFSET);
01039 _dbus_type_reader_read_basic (&reader, &v_byte);
01040 _dbus_type_reader_next (&reader);
01041
01042 _dbus_assert (v_byte == byte_order);
01043 header->byte_order = byte_order;
01044
01045
01046 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
01047 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == TYPE_OFFSET);
01048 _dbus_type_reader_read_basic (&reader, &v_byte);
01049 _dbus_type_reader_next (&reader);
01050
01051
01052
01053
01054 if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
01055 {
01056 *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
01057 goto invalid;
01058 }
01059
01060
01061 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
01062 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FLAGS_OFFSET);
01063 _dbus_type_reader_read_basic (&reader, &v_byte);
01064 _dbus_type_reader_next (&reader);
01065
01066
01067
01068
01069 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
01070 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == VERSION_OFFSET);
01071 _dbus_type_reader_read_basic (&reader, &v_byte);
01072 _dbus_type_reader_next (&reader);
01073
01074 if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
01075 {
01076 *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
01077 goto invalid;
01078 }
01079
01080
01081 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32);
01082 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BODY_LENGTH_OFFSET);
01083 _dbus_type_reader_read_basic (&reader, &v_uint32);
01084 _dbus_type_reader_next (&reader);
01085
01086 _dbus_assert (body_len == (signed) v_uint32);
01087
01088
01089 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32);
01090 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == SERIAL_OFFSET);
01091 _dbus_type_reader_read_basic (&reader, &serial);
01092 _dbus_type_reader_next (&reader);
01093
01094 if (serial == 0)
01095 {
01096 *validity = DBUS_INVALID_BAD_SERIAL;
01097 goto invalid;
01098 }
01099
01100 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_ARRAY);
01101 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FIELDS_ARRAY_LENGTH_OFFSET);
01102
01103 _dbus_type_reader_recurse (&reader, &array_reader);
01104 while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
01105 {
01106 DBusTypeReader struct_reader;
01107 DBusTypeReader variant_reader;
01108 unsigned char field_code;
01109
01110 _dbus_assert (_dbus_type_reader_get_current_type (&array_reader) == DBUS_TYPE_STRUCT);
01111
01112 _dbus_type_reader_recurse (&array_reader, &struct_reader);
01113
01114 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_BYTE);
01115 _dbus_type_reader_read_basic (&struct_reader, &field_code);
01116 _dbus_type_reader_next (&struct_reader);
01117
01118 if (field_code == DBUS_HEADER_FIELD_INVALID)
01119 {
01120 _dbus_verbose ("invalid header field code\n");
01121 *validity = DBUS_INVALID_HEADER_FIELD_CODE;
01122 goto invalid;
01123 }
01124
01125 if (field_code > DBUS_HEADER_FIELD_LAST)
01126 {
01127 _dbus_verbose ("unknown header field code %d, skipping\n",
01128 field_code);
01129 goto next_field;
01130 }
01131
01132 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_VARIANT);
01133 _dbus_type_reader_recurse (&struct_reader, &variant_reader);
01134
01135 v = load_and_validate_field (header, field_code, &variant_reader);
01136 if (v != DBUS_VALID)
01137 {
01138 _dbus_verbose ("Field %d was invalid\n", field_code);
01139 *validity = v;
01140 goto invalid;
01141 }
01142
01143 next_field:
01144 _dbus_type_reader_next (&array_reader);
01145 }
01146
01147
01148 i = 0;
01149 while (i <= DBUS_HEADER_FIELD_LAST)
01150 {
01151 if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
01152 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
01153 ++i;
01154 }
01155
01156 v = check_mandatory_fields (header);
01157 if (v != DBUS_VALID)
01158 {
01159 _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
01160 *validity = v;
01161 goto invalid;
01162 }
01163
01164 *validity = DBUS_VALID;
01165 return TRUE;
01166
01167 invalid:
01168 _dbus_string_set_length (&header->data, 0);
01169 return FALSE;
01170 }
01171
01178 void
01179 _dbus_header_update_lengths (DBusHeader *header,
01180 int body_len)
01181 {
01182 _dbus_marshal_set_uint32 (&header->data,
01183 BODY_LENGTH_OFFSET,
01184 body_len,
01185 header->byte_order);
01186 }
01187
01188 static dbus_bool_t
01189 find_field_for_modification (DBusHeader *header,
01190 int field,
01191 DBusTypeReader *reader,
01192 DBusTypeReader *realign_root)
01193 {
01194 dbus_bool_t retval;
01195
01196 retval = FALSE;
01197
01198 _dbus_type_reader_init (realign_root,
01199 header->byte_order,
01200 &_dbus_header_signature_str,
01201 FIELDS_ARRAY_SIGNATURE_OFFSET,
01202 &header->data,
01203 FIELDS_ARRAY_LENGTH_OFFSET);
01204
01205 _dbus_type_reader_recurse (realign_root, reader);
01206
01207 while (_dbus_type_reader_get_current_type (reader) != DBUS_TYPE_INVALID)
01208 {
01209 DBusTypeReader sub;
01210 unsigned char field_code;
01211
01212 _dbus_type_reader_recurse (reader, &sub);
01213
01214 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
01215 _dbus_type_reader_read_basic (&sub, &field_code);
01216
01217 if (field_code == (unsigned) field)
01218 {
01219 _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_STRUCT);
01220 retval = TRUE;
01221 goto done;
01222 }
01223
01224 _dbus_type_reader_next (reader);
01225 }
01226
01227 done:
01228 return retval;
01229 }
01230
01242 dbus_bool_t
01243 _dbus_header_set_field_basic (DBusHeader *header,
01244 int field,
01245 int type,
01246 const void *value)
01247 {
01248 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
01249
01250 if (!reserve_header_padding (header))
01251 return FALSE;
01252
01253
01254 if (_dbus_header_cache_check (header, field))
01255 {
01256 DBusTypeReader reader;
01257 DBusTypeReader realign_root;
01258
01259 if (!find_field_for_modification (header, field,
01260 &reader, &realign_root))
01261 _dbus_assert_not_reached ("field was marked present in cache but wasn't found");
01262
01263 if (!set_basic_field (&reader, field, type, value, &realign_root))
01264 return FALSE;
01265 }
01266 else
01267 {
01268 DBusTypeWriter writer;
01269 DBusTypeWriter array;
01270
01271 _dbus_type_writer_init_values_only (&writer,
01272 header->byte_order,
01273 &_dbus_header_signature_str,
01274 FIELDS_ARRAY_SIGNATURE_OFFSET,
01275 &header->data,
01276 FIELDS_ARRAY_LENGTH_OFFSET);
01277
01278
01279
01280
01281 if (!_dbus_type_writer_append_array (&writer,
01282 &_dbus_header_signature_str,
01283 FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET,
01284 &array))
01285 _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
01286
01287 _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET);
01288 _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET);
01289 _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header));
01290
01291 if (!write_basic_field (&array,
01292 field, type, value))
01293 return FALSE;
01294
01295 if (!_dbus_type_writer_unrecurse (&writer, &array))
01296 _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
01297 }
01298
01299 correct_header_padding (header);
01300
01301
01302
01303
01304
01305 _dbus_header_cache_invalidate_all (header);
01306
01307 return TRUE;
01308 }
01309
01320 dbus_bool_t
01321 _dbus_header_get_field_basic (DBusHeader *header,
01322 int field,
01323 int type,
01324 void *value)
01325 {
01326 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);
01327 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
01328 _dbus_assert (_dbus_header_field_types[field].code == field);
01329
01330
01331
01332
01333 _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
01334
01335 if (!_dbus_header_cache_check (header, field))
01336 return FALSE;
01337
01338 _dbus_assert (header->fields[field].value_pos >= 0);
01339
01340 _dbus_marshal_read_basic (&header->data,
01341 header->fields[field].value_pos,
01342 type, value, header->byte_order,
01343 NULL);
01344
01345 return TRUE;
01346 }
01347
01361 dbus_bool_t
01362 _dbus_header_get_field_raw (DBusHeader *header,
01363 int field,
01364 const DBusString **str,
01365 int *pos)
01366 {
01367 if (!_dbus_header_cache_check (header, field))
01368 return FALSE;
01369
01370 if (str)
01371 *str = &header->data;
01372 if (pos)
01373 *pos = header->fields[field].value_pos;
01374
01375 return TRUE;
01376 }
01377
01385 dbus_bool_t
01386 _dbus_header_delete_field (DBusHeader *header,
01387 int field)
01388 {
01389 DBusTypeReader reader;
01390 DBusTypeReader realign_root;
01391
01392 if (_dbus_header_cache_known_nonexistent (header, field))
01393 return TRUE;
01394
01395
01396
01397
01398 if (!find_field_for_modification (header, field,
01399 &reader, &realign_root))
01400 return TRUE;
01401
01402 if (!reserve_header_padding (header))
01403 return FALSE;
01404
01405 if (!_dbus_type_reader_delete (&reader,
01406 &realign_root))
01407 return FALSE;
01408
01409 correct_header_padding (header);
01410
01411 _dbus_header_cache_invalidate_all (header);
01412
01413 _dbus_assert (!_dbus_header_cache_check (header, field));
01414
01415 return TRUE;
01416 }
01417
01426 void
01427 _dbus_header_toggle_flag (DBusHeader *header,
01428 dbus_uint32_t flag,
01429 dbus_bool_t value)
01430 {
01431 unsigned char *flags_p;
01432
01433 flags_p = _dbus_string_get_data_len (&header->data, FLAGS_OFFSET, 1);
01434
01435 if (value)
01436 *flags_p |= flag;
01437 else
01438 *flags_p &= ~flag;
01439 }
01440
01448 dbus_bool_t
01449 _dbus_header_get_flag (DBusHeader *header,
01450 dbus_uint32_t flag)
01451 {
01452 const unsigned char *flags_p;
01453
01454 flags_p = _dbus_string_get_const_data_len (&header->data, FLAGS_OFFSET, 1);
01455
01456 return (*flags_p & flag) != 0;
01457 }
01458
01465 void
01466 _dbus_header_byteswap (DBusHeader *header,
01467 int new_order)
01468 {
01469 if (header->byte_order == new_order)
01470 return;
01471
01472 _dbus_marshal_byteswap (&_dbus_header_signature_str,
01473 0, header->byte_order,
01474 new_order,
01475 &header->data, 0);
01476
01477 header->byte_order = new_order;
01478 }
01479
01482 #ifdef DBUS_BUILD_TESTS
01483 #include "dbus-test.h"
01484 #include <stdio.h>
01485
01486 dbus_bool_t
01487 _dbus_marshal_header_test (void)
01488 {
01489
01490 return TRUE;
01491 }
01492
01493 #endif