D-Bus
1.10.12
|
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 00173 char 00174 _dbus_header_get_byte_order (const DBusHeader *header) 00175 { 00176 _dbus_assert (_dbus_string_get_length (&header->data) > BYTE_ORDER_OFFSET); 00177 00178 return (char) _dbus_string_get_byte (&header->data, BYTE_ORDER_OFFSET); 00179 } 00180 00186 static void 00187 _dbus_header_cache_revalidate (DBusHeader *header) 00188 { 00189 DBusTypeReader array; 00190 DBusTypeReader reader; 00191 int i; 00192 00193 i = 0; 00194 while (i <= DBUS_HEADER_FIELD_LAST) 00195 { 00196 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT; 00197 ++i; 00198 } 00199 00200 _dbus_type_reader_init (&reader, 00201 _dbus_header_get_byte_order (header), 00202 &_dbus_header_signature_str, 00203 FIELDS_ARRAY_SIGNATURE_OFFSET, 00204 &header->data, 00205 FIELDS_ARRAY_LENGTH_OFFSET); 00206 00207 _dbus_type_reader_recurse (&reader, &array); 00208 00209 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID) 00210 { 00211 DBusTypeReader sub; 00212 DBusTypeReader variant; 00213 unsigned char field_code; 00214 00215 _dbus_type_reader_recurse (&array, &sub); 00216 00217 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE); 00218 _dbus_type_reader_read_basic (&sub, &field_code); 00219 00220 /* Unknown fields should be ignored */ 00221 if (field_code > DBUS_HEADER_FIELD_LAST) 00222 goto next_field; 00223 00224 _dbus_type_reader_next (&sub); 00225 00226 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_VARIANT); 00227 _dbus_type_reader_recurse (&sub, &variant); 00228 00229 _dbus_header_cache_one (header, field_code, &variant); 00230 00231 next_field: 00232 _dbus_type_reader_next (&array); 00233 } 00234 } 00235 00243 static dbus_bool_t 00244 _dbus_header_cache_check (DBusHeader *header, 00245 int field) 00246 { 00247 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 00248 00249 if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN) 00250 _dbus_header_cache_revalidate (header); 00251 00252 if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT) 00253 return FALSE; 00254 00255 return TRUE; 00256 } 00257 00266 static dbus_bool_t 00267 _dbus_header_cache_known_nonexistent (DBusHeader *header, 00268 int field) 00269 { 00270 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 00271 00272 return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT); 00273 } 00274 00284 static dbus_bool_t 00285 write_basic_field (DBusTypeWriter *writer, 00286 int field, 00287 int type, 00288 const void *value) 00289 { 00290 DBusTypeWriter sub; 00291 DBusTypeWriter variant; 00292 int start; 00293 int padding; 00294 unsigned char field_byte; 00295 DBusString contained_type; 00296 char buf[2]; 00297 00298 start = writer->value_pos; 00299 padding = _dbus_string_get_length (writer->value_str) - start; 00300 00301 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT, 00302 NULL, 0, &sub)) 00303 goto append_failed; 00304 00305 field_byte = field; 00306 if (!_dbus_type_writer_write_basic (&sub, DBUS_TYPE_BYTE, 00307 &field_byte)) 00308 goto append_failed; 00309 00310 buf[0] = type; 00311 buf[1] = '\0'; 00312 _dbus_string_init_const_len (&contained_type, buf, 1); 00313 00314 if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT, 00315 &contained_type, 0, &variant)) 00316 goto append_failed; 00317 00318 if (!_dbus_type_writer_write_basic (&variant, type, value)) 00319 goto append_failed; 00320 00321 if (!_dbus_type_writer_unrecurse (&sub, &variant)) 00322 goto append_failed; 00323 00324 if (!_dbus_type_writer_unrecurse (writer, &sub)) 00325 goto append_failed; 00326 00327 return TRUE; 00328 00329 append_failed: 00330 _dbus_string_delete (writer->value_str, 00331 start, 00332 _dbus_string_get_length (writer->value_str) - start - padding); 00333 return FALSE; 00334 } 00335 00346 static dbus_bool_t 00347 set_basic_field (DBusTypeReader *reader, 00348 int field, 00349 int type, 00350 const void *value, 00351 const DBusTypeReader *realign_root) 00352 { 00353 DBusTypeReader sub; 00354 DBusTypeReader variant; 00355 00356 _dbus_type_reader_recurse (reader, &sub); 00357 00358 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE); 00359 #ifndef DBUS_DISABLE_ASSERT 00360 { 00361 unsigned char v_BYTE; 00362 _dbus_type_reader_read_basic (&sub, &v_BYTE); 00363 _dbus_assert (((int) v_BYTE) == field); 00364 } 00365 #endif 00366 00367 if (!_dbus_type_reader_next (&sub)) 00368 _dbus_assert_not_reached ("no variant field?"); 00369 00370 _dbus_type_reader_recurse (&sub, &variant); 00371 _dbus_assert (_dbus_type_reader_get_current_type (&variant) == type); 00372 00373 if (!_dbus_type_reader_set_basic (&variant, value, realign_root)) 00374 return FALSE; 00375 00376 return TRUE; 00377 } 00378 00385 int 00386 _dbus_header_get_message_type (DBusHeader *header) 00387 { 00388 int type; 00389 00390 type = _dbus_string_get_byte (&header->data, TYPE_OFFSET); 00391 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID); 00392 00393 return type; 00394 } 00395 00403 void 00404 _dbus_header_set_serial (DBusHeader *header, 00405 dbus_uint32_t serial) 00406 { 00407 /* we use this function to set the serial on outgoing 00408 * messages, and to reset the serial in dbus_message_copy; 00409 * this assertion should catch a double-set on outgoing. 00410 */ 00411 _dbus_assert (_dbus_header_get_serial (header) == 0 || 00412 serial == 0); 00413 00414 _dbus_marshal_set_uint32 (&header->data, 00415 SERIAL_OFFSET, 00416 serial, 00417 _dbus_header_get_byte_order (header)); 00418 } 00419 00426 dbus_uint32_t 00427 _dbus_header_get_serial (DBusHeader *header) 00428 { 00429 return _dbus_marshal_read_uint32 (&header->data, 00430 SERIAL_OFFSET, 00431 _dbus_header_get_byte_order (header), 00432 NULL); 00433 } 00434 00442 void 00443 _dbus_header_reinit (DBusHeader *header) 00444 { 00445 _dbus_string_set_length (&header->data, 0); 00446 00447 header->padding = 0; 00448 00449 _dbus_header_cache_invalidate_all (header); 00450 } 00451 00459 dbus_bool_t 00460 _dbus_header_init (DBusHeader *header) 00461 { 00462 if (!_dbus_string_init_preallocated (&header->data, 32)) 00463 return FALSE; 00464 00465 _dbus_header_reinit (header); 00466 00467 return TRUE; 00468 } 00469 00475 void 00476 _dbus_header_free (DBusHeader *header) 00477 { 00478 _dbus_string_free (&header->data); 00479 } 00480 00489 dbus_bool_t 00490 _dbus_header_copy (const DBusHeader *header, 00491 DBusHeader *dest) 00492 { 00493 *dest = *header; 00494 00495 if (!_dbus_string_init_preallocated (&dest->data, 00496 _dbus_string_get_length (&header->data))) 00497 return FALSE; 00498 00499 if (!_dbus_string_copy (&header->data, 0, &dest->data, 0)) 00500 { 00501 _dbus_string_free (&dest->data); 00502 return FALSE; 00503 } 00504 00505 /* Reset the serial */ 00506 _dbus_header_set_serial (dest, 0); 00507 00508 return TRUE; 00509 } 00510 00527 dbus_bool_t 00528 _dbus_header_create (DBusHeader *header, 00529 int byte_order, 00530 int message_type, 00531 const char *destination, 00532 const char *path, 00533 const char *interface, 00534 const char *member, 00535 const char *error_name) 00536 { 00537 unsigned char v_BYTE; 00538 dbus_uint32_t v_UINT32; 00539 DBusTypeWriter writer; 00540 DBusTypeWriter array; 00541 00542 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || 00543 byte_order == DBUS_BIG_ENDIAN); 00544 _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) || 00545 (error_name) || 00546 !(interface || member || error_name)); 00547 _dbus_assert (_dbus_string_get_length (&header->data) == 0); 00548 00549 if (!reserve_header_padding (header)) 00550 return FALSE; 00551 00552 _dbus_type_writer_init_values_only (&writer, byte_order, 00553 &_dbus_header_signature_str, 0, 00554 &header->data, 00555 HEADER_END_BEFORE_PADDING (header)); 00556 00557 v_BYTE = byte_order; 00558 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, 00559 &v_BYTE)) 00560 goto oom; 00561 00562 v_BYTE = message_type; 00563 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, 00564 &v_BYTE)) 00565 goto oom; 00566 00567 v_BYTE = 0; /* flags */ 00568 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, 00569 &v_BYTE)) 00570 goto oom; 00571 00572 v_BYTE = DBUS_MAJOR_PROTOCOL_VERSION; 00573 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, 00574 &v_BYTE)) 00575 goto oom; 00576 00577 v_UINT32 = 0; /* body length */ 00578 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32, 00579 &v_UINT32)) 00580 goto oom; 00581 00582 v_UINT32 = 0; /* serial */ 00583 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32, 00584 &v_UINT32)) 00585 goto oom; 00586 00587 if (!_dbus_type_writer_recurse (&writer, DBUS_TYPE_ARRAY, 00588 &_dbus_header_signature_str, 00589 FIELDS_ARRAY_SIGNATURE_OFFSET, 00590 &array)) 00591 goto oom; 00592 00593 /* Marshal all the fields (Marshall Fields?) */ 00594 00595 if (path != NULL) 00596 { 00597 if (!write_basic_field (&array, 00598 DBUS_HEADER_FIELD_PATH, 00599 DBUS_TYPE_OBJECT_PATH, 00600 &path)) 00601 goto oom; 00602 } 00603 00604 if (destination != NULL) 00605 { 00606 if (!write_basic_field (&array, 00607 DBUS_HEADER_FIELD_DESTINATION, 00608 DBUS_TYPE_STRING, 00609 &destination)) 00610 goto oom; 00611 } 00612 00613 if (interface != NULL) 00614 { 00615 if (!write_basic_field (&array, 00616 DBUS_HEADER_FIELD_INTERFACE, 00617 DBUS_TYPE_STRING, 00618 &interface)) 00619 goto oom; 00620 } 00621 00622 if (member != NULL) 00623 { 00624 if (!write_basic_field (&array, 00625 DBUS_HEADER_FIELD_MEMBER, 00626 DBUS_TYPE_STRING, 00627 &member)) 00628 goto oom; 00629 } 00630 00631 if (error_name != NULL) 00632 { 00633 if (!write_basic_field (&array, 00634 DBUS_HEADER_FIELD_ERROR_NAME, 00635 DBUS_TYPE_STRING, 00636 &error_name)) 00637 goto oom; 00638 } 00639 00640 if (!_dbus_type_writer_unrecurse (&writer, &array)) 00641 goto oom; 00642 00643 correct_header_padding (header); 00644 00645 return TRUE; 00646 00647 oom: 00648 _dbus_string_delete (&header->data, 0, 00649 _dbus_string_get_length (&header->data) - header->padding); 00650 correct_header_padding (header); 00651 00652 return FALSE; 00653 } 00654 00672 dbus_bool_t 00673 _dbus_header_have_message_untrusted (int max_message_length, 00674 DBusValidity *validity, 00675 int *byte_order, 00676 int *fields_array_len, 00677 int *header_len, 00678 int *body_len, 00679 const DBusString *str, 00680 int start, 00681 int len) 00682 00683 { 00684 dbus_uint32_t header_len_unsigned; 00685 dbus_uint32_t fields_array_len_unsigned; 00686 dbus_uint32_t body_len_unsigned; 00687 00688 _dbus_assert (start >= 0); 00689 _dbus_assert (start < _DBUS_INT32_MAX / 2); 00690 _dbus_assert (len >= 0); 00691 00692 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8)); 00693 00694 *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET); 00695 00696 if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN) 00697 { 00698 *validity = DBUS_INVALID_BAD_BYTE_ORDER; 00699 return FALSE; 00700 } 00701 00702 _dbus_assert (FIELDS_ARRAY_LENGTH_OFFSET + 4 <= len); 00703 fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET, 00704 *byte_order, NULL); 00705 00706 if (fields_array_len_unsigned > (unsigned) max_message_length) 00707 { 00708 *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH; 00709 return FALSE; 00710 } 00711 00712 _dbus_assert (BODY_LENGTH_OFFSET + 4 < len); 00713 body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET, 00714 *byte_order, NULL); 00715 00716 if (body_len_unsigned > (unsigned) max_message_length) 00717 { 00718 *validity = DBUS_INVALID_INSANE_BODY_LENGTH; 00719 return FALSE; 00720 } 00721 00722 header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned; 00723 header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8); 00724 00725 /* overflow should be impossible since the lengths aren't allowed to 00726 * be huge. 00727 */ 00728 _dbus_assert (max_message_length < _DBUS_INT32_MAX / 2); 00729 if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length) 00730 { 00731 *validity = DBUS_INVALID_MESSAGE_TOO_LONG; 00732 return FALSE; 00733 } 00734 00735 _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT32_MAX); 00736 _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT32_MAX); 00737 _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT32_MAX); 00738 00739 *body_len = body_len_unsigned; 00740 *fields_array_len = fields_array_len_unsigned; 00741 *header_len = header_len_unsigned; 00742 00743 *validity = DBUS_VALID; 00744 00745 _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n", 00746 len, body_len_unsigned, header_len_unsigned, 00747 body_len_unsigned + header_len_unsigned); 00748 00749 return (body_len_unsigned + header_len_unsigned) <= (unsigned) len; 00750 } 00751 00752 static DBusValidity 00753 check_mandatory_fields (DBusHeader *header) 00754 { 00755 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0) 00756 00757 switch (_dbus_header_get_message_type (header)) 00758 { 00759 case DBUS_MESSAGE_TYPE_SIGNAL: 00760 REQUIRE_FIELD (INTERFACE); 00761 /* FALL THRU - signals also require the path and member */ 00762 case DBUS_MESSAGE_TYPE_METHOD_CALL: 00763 REQUIRE_FIELD (PATH); 00764 REQUIRE_FIELD (MEMBER); 00765 break; 00766 case DBUS_MESSAGE_TYPE_ERROR: 00767 REQUIRE_FIELD (ERROR_NAME); 00768 REQUIRE_FIELD (REPLY_SERIAL); 00769 break; 00770 case DBUS_MESSAGE_TYPE_METHOD_RETURN: 00771 REQUIRE_FIELD (REPLY_SERIAL); 00772 break; 00773 default: 00774 /* other message types allowed but ignored */ 00775 break; 00776 } 00777 00778 return DBUS_VALID; 00779 } 00780 00781 static DBusValidity 00782 load_and_validate_field (DBusHeader *header, 00783 int field, 00784 DBusTypeReader *variant_reader) 00785 { 00786 int type; 00787 int expected_type; 00788 const DBusString *value_str; 00789 int value_pos; 00790 int str_data_pos; 00791 dbus_uint32_t v_UINT32; 00792 int bad_string_code; 00793 dbus_bool_t (* string_validation_func) (const DBusString *str, 00794 int start, int len); 00795 00796 /* Supposed to have been checked already */ 00797 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 00798 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID); 00799 00800 /* Before we can cache a field, we need to know it has the right type */ 00801 type = _dbus_type_reader_get_current_type (variant_reader); 00802 00803 _dbus_assert (_dbus_header_field_types[field].code == field); 00804 00805 expected_type = EXPECTED_TYPE_OF_FIELD (field); 00806 if (type != expected_type) 00807 { 00808 _dbus_verbose ("Field %d should have type %d but has %d\n", 00809 field, expected_type, type); 00810 return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE; 00811 } 00812 00813 /* If the field was provided twice, we aren't happy */ 00814 if (header->fields[field].value_pos >= 0) 00815 { 00816 _dbus_verbose ("Header field %d seen a second time\n", field); 00817 return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE; 00818 } 00819 00820 /* Now we can cache and look at the field content */ 00821 _dbus_verbose ("initially caching field %d\n", field); 00822 _dbus_header_cache_one (header, field, variant_reader); 00823 00824 string_validation_func = NULL; 00825 00826 /* make compiler happy that all this is initialized */ 00827 v_UINT32 = 0; 00828 value_str = NULL; 00829 value_pos = -1; 00830 str_data_pos = -1; 00831 bad_string_code = DBUS_VALID; 00832 00833 if (expected_type == DBUS_TYPE_UINT32) 00834 { 00835 _dbus_header_get_field_basic (header, field, expected_type, 00836 &v_UINT32); 00837 } 00838 else if (expected_type == DBUS_TYPE_STRING || 00839 expected_type == DBUS_TYPE_OBJECT_PATH || 00840 expected_type == DBUS_TYPE_SIGNATURE) 00841 { 00842 _dbus_header_get_field_raw (header, field, 00843 &value_str, &value_pos); 00844 str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4; 00845 } 00846 else 00847 { 00848 _dbus_assert_not_reached ("none of the known fields should have this type"); 00849 } 00850 00851 switch (field) 00852 { 00853 case DBUS_HEADER_FIELD_DESTINATION: 00854 string_validation_func = _dbus_validate_bus_name; 00855 bad_string_code = DBUS_INVALID_BAD_DESTINATION; 00856 break; 00857 case DBUS_HEADER_FIELD_INTERFACE: 00858 string_validation_func = _dbus_validate_interface; 00859 bad_string_code = DBUS_INVALID_BAD_INTERFACE; 00860 00861 if (_dbus_string_equal_substring (&_dbus_local_interface_str, 00862 0, 00863 _dbus_string_get_length (&_dbus_local_interface_str), 00864 value_str, str_data_pos)) 00865 { 00866 _dbus_verbose ("Message is on the local interface\n"); 00867 return DBUS_INVALID_USES_LOCAL_INTERFACE; 00868 } 00869 break; 00870 00871 case DBUS_HEADER_FIELD_MEMBER: 00872 string_validation_func = _dbus_validate_member; 00873 bad_string_code = DBUS_INVALID_BAD_MEMBER; 00874 break; 00875 00876 case DBUS_HEADER_FIELD_ERROR_NAME: 00877 string_validation_func = _dbus_validate_error_name; 00878 bad_string_code = DBUS_INVALID_BAD_ERROR_NAME; 00879 break; 00880 00881 case DBUS_HEADER_FIELD_SENDER: 00882 string_validation_func = _dbus_validate_bus_name; 00883 bad_string_code = DBUS_INVALID_BAD_SENDER; 00884 break; 00885 00886 case DBUS_HEADER_FIELD_PATH: 00887 /* OBJECT_PATH was validated generically due to its type */ 00888 string_validation_func = NULL; 00889 00890 if (_dbus_string_equal_substring (&_dbus_local_path_str, 00891 0, 00892 _dbus_string_get_length (&_dbus_local_path_str), 00893 value_str, str_data_pos)) 00894 { 00895 _dbus_verbose ("Message is from the local path\n"); 00896 return DBUS_INVALID_USES_LOCAL_PATH; 00897 } 00898 break; 00899 00900 case DBUS_HEADER_FIELD_REPLY_SERIAL: 00901 /* Can't be 0 */ 00902 if (v_UINT32 == 0) 00903 { 00904 return DBUS_INVALID_BAD_SERIAL; 00905 } 00906 break; 00907 00908 case DBUS_HEADER_FIELD_UNIX_FDS: 00909 /* Every value makes sense */ 00910 break; 00911 00912 case DBUS_HEADER_FIELD_SIGNATURE: 00913 /* SIGNATURE validated generically due to its type */ 00914 string_validation_func = NULL; 00915 break; 00916 00917 default: 00918 _dbus_assert_not_reached ("unknown field shouldn't be seen here"); 00919 break; 00920 } 00921 00922 if (string_validation_func) 00923 { 00924 dbus_uint32_t len; 00925 00926 _dbus_assert (bad_string_code != DBUS_VALID); 00927 00928 len = _dbus_marshal_read_uint32 (value_str, value_pos, 00929 _dbus_header_get_byte_order (header), 00930 NULL); 00931 00932 #if 0 00933 _dbus_verbose ("Validating string header field; code %d if fails\n", 00934 bad_string_code); 00935 #endif 00936 if (!(*string_validation_func) (value_str, str_data_pos, len)) 00937 return bad_string_code; 00938 } 00939 00940 return DBUS_VALID; 00941 } 00942 00969 dbus_bool_t 00970 _dbus_header_load (DBusHeader *header, 00971 DBusValidationMode mode, 00972 DBusValidity *validity, 00973 int byte_order, 00974 int fields_array_len, 00975 int header_len, 00976 int body_len, 00977 const DBusString *str, 00978 int start, 00979 int len) 00980 { 00981 int leftover; 00982 DBusValidity v; 00983 DBusTypeReader reader; 00984 DBusTypeReader array_reader; 00985 unsigned char v_byte; 00986 dbus_uint32_t v_uint32; 00987 dbus_uint32_t serial; 00988 int padding_start; 00989 int padding_len; 00990 int i; 00991 00992 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8)); 00993 _dbus_assert (header_len <= len); 00994 _dbus_assert (_dbus_string_get_length (&header->data) == 0); 00995 00996 if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0)) 00997 { 00998 _dbus_verbose ("Failed to copy buffer into new header\n"); 00999 *validity = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; 01000 return FALSE; 01001 } 01002 01003 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY) 01004 { 01005 leftover = len - header_len - body_len - start; 01006 } 01007 else 01008 { 01009 v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0, 01010 byte_order, 01011 &leftover, 01012 str, start, len); 01013 01014 if (v != DBUS_VALID) 01015 { 01016 *validity = v; 01017 goto invalid; 01018 } 01019 } 01020 01021 _dbus_assert (leftover < len); 01022 01023 padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len); 01024 padding_start = start + FIRST_FIELD_OFFSET + fields_array_len; 01025 _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8)); 01026 _dbus_assert (start + header_len == padding_start + padding_len); 01027 01028 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY) 01029 { 01030 if (!_dbus_string_validate_nul (str, padding_start, padding_len)) 01031 { 01032 *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL; 01033 goto invalid; 01034 } 01035 } 01036 01037 header->padding = padding_len; 01038 01039 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY) 01040 { 01041 *validity = DBUS_VALID; 01042 return TRUE; 01043 } 01044 01045 /* We now know the data is well-formed, but we have to check that 01046 * it's valid. 01047 */ 01048 01049 _dbus_type_reader_init (&reader, 01050 byte_order, 01051 &_dbus_header_signature_str, 0, 01052 str, start); 01053 01054 /* BYTE ORDER */ 01055 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE); 01056 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BYTE_ORDER_OFFSET); 01057 _dbus_type_reader_read_basic (&reader, &v_byte); 01058 _dbus_type_reader_next (&reader); 01059 01060 _dbus_assert (v_byte == byte_order); 01061 01062 /* MESSAGE TYPE */ 01063 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE); 01064 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == TYPE_OFFSET); 01065 _dbus_type_reader_read_basic (&reader, &v_byte); 01066 _dbus_type_reader_next (&reader); 01067 01068 /* unknown message types are supposed to be ignored, so only validation here is 01069 * that it isn't invalid 01070 */ 01071 if (v_byte == DBUS_MESSAGE_TYPE_INVALID) 01072 { 01073 *validity = DBUS_INVALID_BAD_MESSAGE_TYPE; 01074 goto invalid; 01075 } 01076 01077 /* FLAGS */ 01078 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE); 01079 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FLAGS_OFFSET); 01080 _dbus_type_reader_read_basic (&reader, &v_byte); 01081 _dbus_type_reader_next (&reader); 01082 01083 /* unknown flags should be ignored */ 01084 01085 /* PROTOCOL VERSION */ 01086 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE); 01087 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == VERSION_OFFSET); 01088 _dbus_type_reader_read_basic (&reader, &v_byte); 01089 _dbus_type_reader_next (&reader); 01090 01091 if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION) 01092 { 01093 *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION; 01094 goto invalid; 01095 } 01096 01097 /* BODY LENGTH */ 01098 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32); 01099 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BODY_LENGTH_OFFSET); 01100 _dbus_type_reader_read_basic (&reader, &v_uint32); 01101 _dbus_type_reader_next (&reader); 01102 01103 _dbus_assert (body_len == (signed) v_uint32); 01104 01105 /* SERIAL */ 01106 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32); 01107 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == SERIAL_OFFSET); 01108 _dbus_type_reader_read_basic (&reader, &serial); 01109 _dbus_type_reader_next (&reader); 01110 01111 if (serial == 0) 01112 { 01113 *validity = DBUS_INVALID_BAD_SERIAL; 01114 goto invalid; 01115 } 01116 01117 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_ARRAY); 01118 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FIELDS_ARRAY_LENGTH_OFFSET); 01119 01120 _dbus_type_reader_recurse (&reader, &array_reader); 01121 while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID) 01122 { 01123 DBusTypeReader struct_reader; 01124 DBusTypeReader variant_reader; 01125 unsigned char field_code; 01126 01127 _dbus_assert (_dbus_type_reader_get_current_type (&array_reader) == DBUS_TYPE_STRUCT); 01128 01129 _dbus_type_reader_recurse (&array_reader, &struct_reader); 01130 01131 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_BYTE); 01132 _dbus_type_reader_read_basic (&struct_reader, &field_code); 01133 _dbus_type_reader_next (&struct_reader); 01134 01135 if (field_code == DBUS_HEADER_FIELD_INVALID) 01136 { 01137 _dbus_verbose ("invalid header field code\n"); 01138 *validity = DBUS_INVALID_HEADER_FIELD_CODE; 01139 goto invalid; 01140 } 01141 01142 if (field_code > DBUS_HEADER_FIELD_LAST) 01143 { 01144 _dbus_verbose ("unknown header field code %d, skipping\n", 01145 field_code); 01146 goto next_field; 01147 } 01148 01149 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_VARIANT); 01150 _dbus_type_reader_recurse (&struct_reader, &variant_reader); 01151 01152 v = load_and_validate_field (header, field_code, &variant_reader); 01153 if (v != DBUS_VALID) 01154 { 01155 _dbus_verbose ("Field %d was invalid\n", field_code); 01156 *validity = v; 01157 goto invalid; 01158 } 01159 01160 next_field: 01161 _dbus_type_reader_next (&array_reader); 01162 } 01163 01164 /* Anything we didn't fill in is now known not to exist */ 01165 i = 0; 01166 while (i <= DBUS_HEADER_FIELD_LAST) 01167 { 01168 if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN) 01169 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT; 01170 ++i; 01171 } 01172 01173 v = check_mandatory_fields (header); 01174 if (v != DBUS_VALID) 01175 { 01176 _dbus_verbose ("Mandatory fields were missing, code %d\n", v); 01177 *validity = v; 01178 goto invalid; 01179 } 01180 01181 *validity = DBUS_VALID; 01182 return TRUE; 01183 01184 invalid: 01185 _dbus_string_set_length (&header->data, 0); 01186 return FALSE; 01187 } 01188 01195 void 01196 _dbus_header_update_lengths (DBusHeader *header, 01197 int body_len) 01198 { 01199 _dbus_marshal_set_uint32 (&header->data, 01200 BODY_LENGTH_OFFSET, 01201 body_len, 01202 _dbus_header_get_byte_order (header)); 01203 } 01204 01218 static dbus_bool_t 01219 find_field_for_modification (DBusHeader *header, 01220 int field, 01221 DBusTypeReader *reader, 01222 DBusTypeReader *realign_root) 01223 { 01224 dbus_bool_t retval; 01225 01226 retval = FALSE; 01227 01228 _dbus_type_reader_init (realign_root, 01229 _dbus_header_get_byte_order (header), 01230 &_dbus_header_signature_str, 01231 FIELDS_ARRAY_SIGNATURE_OFFSET, 01232 &header->data, 01233 FIELDS_ARRAY_LENGTH_OFFSET); 01234 01235 _dbus_type_reader_recurse (realign_root, reader); 01236 01237 while (_dbus_type_reader_get_current_type (reader) != DBUS_TYPE_INVALID) 01238 { 01239 DBusTypeReader sub; 01240 unsigned char field_code; 01241 01242 _dbus_type_reader_recurse (reader, &sub); 01243 01244 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE); 01245 _dbus_type_reader_read_basic (&sub, &field_code); 01246 01247 if (field_code == (unsigned) field) 01248 { 01249 _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_STRUCT); 01250 retval = TRUE; 01251 goto done; 01252 } 01253 01254 _dbus_type_reader_next (reader); 01255 } 01256 01257 done: 01258 return retval; 01259 } 01260 01272 dbus_bool_t 01273 _dbus_header_set_field_basic (DBusHeader *header, 01274 int field, 01275 int type, 01276 const void *value) 01277 { 01278 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 01279 01280 if (!reserve_header_padding (header)) 01281 return FALSE; 01282 01283 /* If the field exists we set, otherwise we append */ 01284 if (_dbus_header_cache_check (header, field)) 01285 { 01286 DBusTypeReader reader; 01287 DBusTypeReader realign_root; 01288 01289 if (!find_field_for_modification (header, field, 01290 &reader, &realign_root)) 01291 _dbus_assert_not_reached ("field was marked present in cache but wasn't found"); 01292 01293 if (!set_basic_field (&reader, field, type, value, &realign_root)) 01294 return FALSE; 01295 } 01296 else 01297 { 01298 DBusTypeWriter writer; 01299 DBusTypeWriter array; 01300 01301 _dbus_type_writer_init_values_only (&writer, 01302 _dbus_header_get_byte_order (header), 01303 &_dbus_header_signature_str, 01304 FIELDS_ARRAY_SIGNATURE_OFFSET, 01305 &header->data, 01306 FIELDS_ARRAY_LENGTH_OFFSET); 01307 01308 /* recurse into array without creating a new length, and jump to 01309 * end of array. 01310 */ 01311 if (!_dbus_type_writer_append_array (&writer, 01312 &_dbus_header_signature_str, 01313 FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET, 01314 &array)) 01315 _dbus_assert_not_reached ("recurse into ARRAY should not have used memory"); 01316 01317 _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET); 01318 _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET); 01319 _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header)); 01320 01321 if (!write_basic_field (&array, 01322 field, type, value)) 01323 return FALSE; 01324 01325 if (!_dbus_type_writer_unrecurse (&writer, &array)) 01326 _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory"); 01327 } 01328 01329 correct_header_padding (header); 01330 01331 /* We could be smarter about this (only invalidate fields after the 01332 * one we modified, or even only if the one we modified changed 01333 * length). But this hack is a start. 01334 */ 01335 _dbus_header_cache_invalidate_all (header); 01336 01337 return TRUE; 01338 } 01339 01350 dbus_bool_t 01351 _dbus_header_get_field_basic (DBusHeader *header, 01352 int field, 01353 int type, 01354 void *value) 01355 { 01356 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID); 01357 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 01358 _dbus_assert (_dbus_header_field_types[field].code == field); 01359 /* in light of this you might ask why the type is passed in; 01360 * the only rationale I can think of is so the caller has 01361 * to specify its expectation and breaks if we change it 01362 */ 01363 _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field)); 01364 01365 if (!_dbus_header_cache_check (header, field)) 01366 return FALSE; 01367 01368 _dbus_assert (header->fields[field].value_pos >= 0); 01369 01370 _dbus_marshal_read_basic (&header->data, 01371 header->fields[field].value_pos, 01372 type, value, _dbus_header_get_byte_order (header), 01373 NULL); 01374 01375 return TRUE; 01376 } 01377 01391 dbus_bool_t 01392 _dbus_header_get_field_raw (DBusHeader *header, 01393 int field, 01394 const DBusString **str, 01395 int *pos) 01396 { 01397 if (!_dbus_header_cache_check (header, field)) 01398 return FALSE; 01399 01400 if (str) 01401 *str = &header->data; 01402 if (pos) 01403 *pos = header->fields[field].value_pos; 01404 01405 return TRUE; 01406 } 01407 01415 dbus_bool_t 01416 _dbus_header_delete_field (DBusHeader *header, 01417 int field) 01418 { 01419 DBusTypeReader reader; 01420 DBusTypeReader realign_root; 01421 01422 if (_dbus_header_cache_known_nonexistent (header, field)) 01423 return TRUE; /* nothing to do */ 01424 01425 /* Scan to the field we want, delete and realign, reappend 01426 * padding. Field may turn out not to exist. 01427 */ 01428 if (!find_field_for_modification (header, field, 01429 &reader, &realign_root)) 01430 return TRUE; /* nothing to do */ 01431 01432 if (!reserve_header_padding (header)) 01433 return FALSE; 01434 01435 if (!_dbus_type_reader_delete (&reader, 01436 &realign_root)) 01437 return FALSE; 01438 01439 correct_header_padding (header); 01440 01441 _dbus_header_cache_invalidate_all (header); 01442 01443 _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */ 01444 01445 return TRUE; 01446 } 01447 01456 void 01457 _dbus_header_toggle_flag (DBusHeader *header, 01458 dbus_uint32_t flag, 01459 dbus_bool_t value) 01460 { 01461 unsigned char *flags_p; 01462 01463 flags_p = _dbus_string_get_data_len (&header->data, FLAGS_OFFSET, 1); 01464 01465 if (value) 01466 *flags_p |= flag; 01467 else 01468 *flags_p &= ~flag; 01469 } 01470 01478 dbus_bool_t 01479 _dbus_header_get_flag (DBusHeader *header, 01480 dbus_uint32_t flag) 01481 { 01482 const unsigned char *flags_p; 01483 01484 flags_p = _dbus_string_get_const_data_len (&header->data, FLAGS_OFFSET, 1); 01485 01486 return (*flags_p & flag) != 0; 01487 } 01488 01495 void 01496 _dbus_header_byteswap (DBusHeader *header, 01497 int new_order) 01498 { 01499 char byte_order; 01500 01501 byte_order = _dbus_header_get_byte_order (header); 01502 01503 if (byte_order == new_order) 01504 return; 01505 01506 _dbus_marshal_byteswap (&_dbus_header_signature_str, 01507 0, byte_order, 01508 new_order, 01509 &header->data, 0); 01510 01511 _dbus_string_set_byte (&header->data, BYTE_ORDER_OFFSET, new_order); 01512 } 01513