D-Bus 1.4.0
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-marshal-header.c Managing marshaling/demarshaling of message headers 00003 * 00004 * Copyright (C) 2005 Red Hat, Inc. 00005 * 00006 * Licensed under the Academic Free License version 2.1 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 /* Not thread locked, but strictly const/read-only so should be OK 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 /* Unknown fields should be ignored */ 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 /* we use this function to set the serial on outgoing 00392 * messages, and to reset the serial in dbus_message_copy; 00393 * this assertion should catch a double-set on outgoing. 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 /* Reset the serial */ 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; /* flags */ 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; /* body length */ 00563 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32, 00564 &v_UINT32)) 00565 goto oom; 00566 00567 v_UINT32 = 0; /* serial */ 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 /* Marshal all the fields (Marshall Fields?) */ 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 /* overflow should be impossible since the lengths aren't allowed to 00711 * be huge. 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 /* FALL THRU - signals also require the path and member */ 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 /* other message types allowed but ignored */ 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 /* Supposed to have been checked already */ 00782 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 00783 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID); 00784 00785 /* Before we can cache a field, we need to know it has the right type */ 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 /* If the field was provided twice, we aren't happy */ 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 /* Now we can cache and look at the field content */ 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 /* make compiler happy that all this is initialized */ 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 /* OBJECT_PATH was validated generically due to its type */ 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 /* Can't be 0 */ 00887 if (v_UINT32 == 0) 00888 { 00889 return DBUS_INVALID_BAD_SERIAL; 00890 } 00891 break; 00892 00893 case DBUS_HEADER_FIELD_UNIX_FDS: 00894 /* Every value makes sense */ 00895 break; 00896 00897 case DBUS_HEADER_FIELD_SIGNATURE: 00898 /* SIGNATURE validated generically due to its type */ 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 /* We now know the data is well-formed, but we have to check that 01030 * it's valid. 01031 */ 01032 01033 _dbus_type_reader_init (&reader, 01034 byte_order, 01035 &_dbus_header_signature_str, 0, 01036 str, start); 01037 01038 /* BYTE ORDER */ 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 /* MESSAGE TYPE */ 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 /* unknown message types are supposed to be ignored, so only validation here is 01054 * that it isn't invalid 01055 */ 01056 if (v_byte == DBUS_MESSAGE_TYPE_INVALID) 01057 { 01058 *validity = DBUS_INVALID_BAD_MESSAGE_TYPE; 01059 goto invalid; 01060 } 01061 01062 /* FLAGS */ 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 /* unknown flags should be ignored */ 01069 01070 /* PROTOCOL VERSION */ 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 /* BODY LENGTH */ 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 /* SERIAL */ 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 /* Anything we didn't fill in is now known not to exist */ 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 /* If the field exists we set, otherwise we append */ 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 /* recurse into array without creating a new length, and jump to 01281 * end of array. 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 /* We could be smarter about this (only invalidate fields after the 01304 * one we modified, or even only if the one we modified changed 01305 * length). But this hack is a start. 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 /* in light of this you might ask why the type is passed in; 01332 * the only rationale I can think of is so the caller has 01333 * to specify its expectation and breaks if we change it 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; /* nothing to do */ 01396 01397 /* Scan to the field we want, delete and realign, reappend 01398 * padding. Field may turn out not to exist. 01399 */ 01400 if (!find_field_for_modification (header, field, 01401 &reader, &realign_root)) 01402 return TRUE; /* nothing to do */ 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)); /* Expensive assertion ... */ 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 /* DBUS_BUILD_TESTS */