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