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