| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "dbus/message.h" | 5 #include "dbus/message.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/platform_file.h" |
| 12 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
| 13 #include "dbus/object_path.h" | 14 #include "dbus/object_path.h" |
| 14 #include "third_party/protobuf/src/google/protobuf/message_lite.h" | 15 #include "third_party/protobuf/src/google/protobuf/message_lite.h" |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 // Appends the header name and the value to |output|, if the value is | 19 // Appends the header name and the value to |output|, if the value is |
| 19 // not empty. | 20 // not empty. |
| 20 static void AppendStringHeader(const std::string& header_name, | 21 static void AppendStringHeader(const std::string& header_name, |
| 21 const std::string& header_value, | 22 const std::string& header_value, |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 break; | 193 break; |
| 193 } | 194 } |
| 194 case VARIANT: { | 195 case VARIANT: { |
| 195 MessageReader sub_reader(this); | 196 MessageReader sub_reader(this); |
| 196 if (!reader->PopVariant(&sub_reader)) | 197 if (!reader->PopVariant(&sub_reader)) |
| 197 return kBrokenMessage; | 198 return kBrokenMessage; |
| 198 output += indent + "variant "; | 199 output += indent + "variant "; |
| 199 output += ToStringInternal(indent + " ", &sub_reader); | 200 output += ToStringInternal(indent + " ", &sub_reader); |
| 200 break; | 201 break; |
| 201 } | 202 } |
| 203 case UNIX_FD: { |
| 204 CHECK(kDBusTypeUnixFdIsSupported); |
| 205 |
| 206 FileDescriptor file_descriptor; |
| 207 if (!reader->PopFileDescriptor(&file_descriptor)) |
| 208 return kBrokenMessage; |
| 209 output += indent + "fd#" + |
| 210 base::StringPrintf("%d", file_descriptor.value()) + "\n"; |
| 211 break; |
| 212 } |
| 202 default: | 213 default: |
| 203 LOG(FATAL) << "Unknown type: " << type; | 214 LOG(FATAL) << "Unknown type: " << type; |
| 204 } | 215 } |
| 205 } | 216 } |
| 206 return output; | 217 return output; |
| 207 } | 218 } |
| 208 | 219 |
| 209 // The returned string consists of message headers such as | 220 // The returned string consists of message headers such as |
| 210 // destination if any, followed by a blank line, and the message | 221 // destination if any, followed by a blank line, and the message |
| 211 // payload. For example, a MethodCall's ToString() will look like: | 222 // payload. For example, a MethodCall's ToString() will look like: |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 } | 681 } |
| 671 | 682 |
| 672 void MessageWriter::AppendVariantOfBasic(int dbus_type, const void* value) { | 683 void MessageWriter::AppendVariantOfBasic(int dbus_type, const void* value) { |
| 673 const std::string signature = base::StringPrintf("%c", dbus_type); | 684 const std::string signature = base::StringPrintf("%c", dbus_type); |
| 674 MessageWriter variant_writer(message_); | 685 MessageWriter variant_writer(message_); |
| 675 OpenVariant(signature, &variant_writer); | 686 OpenVariant(signature, &variant_writer); |
| 676 variant_writer.AppendBasic(dbus_type, value); | 687 variant_writer.AppendBasic(dbus_type, value); |
| 677 CloseContainer(&variant_writer); | 688 CloseContainer(&variant_writer); |
| 678 } | 689 } |
| 679 | 690 |
| 691 void MessageWriter::AppendFileDescriptor(const FileDescriptor& value) { |
| 692 CHECK(kDBusTypeUnixFdIsSupported); |
| 693 |
| 694 base::PlatformFileInfo info; |
| 695 int fd = value.value(); |
| 696 bool ok = base::GetPlatformFileInfo(fd, &info); |
| 697 if (!ok || info.is_directory) { |
| 698 // NB: sending a directory potentially enables sandbox escape |
| 699 LOG(FATAL) << "Attempt to pass invalid file descriptor"; |
| 700 } |
| 701 AppendBasic(DBUS_TYPE_UNIX_FD, &fd); |
| 702 } |
| 703 |
| 680 // | 704 // |
| 681 // MessageReader implementation. | 705 // MessageReader implementation. |
| 682 // | 706 // |
| 683 | 707 |
| 684 MessageReader::MessageReader(Message* message) | 708 MessageReader::MessageReader(Message* message) |
| 685 : message_(message) { | 709 : message_(message) { |
| 686 memset(&raw_message_iter_, 0, sizeof(raw_message_iter_)); | 710 memset(&raw_message_iter_, 0, sizeof(raw_message_iter_)); |
| 687 if (message) | 711 if (message) |
| 688 dbus_message_iter_init(message_->raw_message(), &raw_message_iter_); | 712 dbus_message_iter_init(message_->raw_message(), &raw_message_iter_); |
| 689 } | 713 } |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 929 return true; | 953 return true; |
| 930 } | 954 } |
| 931 | 955 |
| 932 bool MessageReader::PopVariantOfBasic(int dbus_type, void* value) { | 956 bool MessageReader::PopVariantOfBasic(int dbus_type, void* value) { |
| 933 dbus::MessageReader variant_reader(message_); | 957 dbus::MessageReader variant_reader(message_); |
| 934 if (!PopVariant(&variant_reader)) | 958 if (!PopVariant(&variant_reader)) |
| 935 return false; | 959 return false; |
| 936 return variant_reader.PopBasic(dbus_type, value); | 960 return variant_reader.PopBasic(dbus_type, value); |
| 937 } | 961 } |
| 938 | 962 |
| 963 bool MessageReader::PopFileDescriptor(FileDescriptor* value) { |
| 964 CHECK(kDBusTypeUnixFdIsSupported); |
| 965 |
| 966 int fd = -1; |
| 967 const bool success = PopBasic(DBUS_TYPE_UNIX_FD, &fd); |
| 968 if (!success) |
| 969 return false; |
| 970 |
| 971 base::PlatformFileInfo info; |
| 972 bool ok = base::GetPlatformFileInfo(fd, &info); |
| 973 if (!ok || info.is_directory) { |
| 974 base::ClosePlatformFile(fd); |
| 975 // NB: receiving a directory potentially enables sandbox escape |
| 976 LOG(FATAL) << "Attempt to receive invalid file descriptor"; |
| 977 return false; // NB: not reached |
| 978 } |
| 979 value->PutValue(fd); |
| 980 return true; |
| 981 } |
| 982 |
| 939 } // namespace dbus | 983 } // namespace dbus |
| OLD | NEW |