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