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