disable two ClientCertStoreChromeOSTest.* unit_tests on Valgrind bots
[chromium-blink-merge.git] / ipc / attachment_broker_privileged_win.cc
blob20eb4f3beaaadb2ab31825dce2603f6a26b17d5f
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ipc/attachment_broker_privileged_win.h"
7 #include <windows.h>
9 #include "base/process/process.h"
10 #include "ipc/attachment_broker_messages.h"
11 #include "ipc/brokerable_attachment.h"
12 #include "ipc/handle_attachment_win.h"
13 #include "ipc/ipc_channel.h"
15 namespace IPC {
17 AttachmentBrokerPrivilegedWin::AttachmentBrokerPrivilegedWin() {}
19 AttachmentBrokerPrivilegedWin::~AttachmentBrokerPrivilegedWin() {}
21 bool AttachmentBrokerPrivilegedWin::SendAttachmentToProcess(
22 const BrokerableAttachment* attachment,
23 base::ProcessId destination_process) {
24 switch (attachment->GetBrokerableType()) {
25 case BrokerableAttachment::WIN_HANDLE: {
26 const internal::HandleAttachmentWin* handle_attachment =
27 static_cast<const internal::HandleAttachmentWin*>(attachment);
28 HandleWireFormat wire_format =
29 handle_attachment->GetWireFormat(destination_process);
30 HandleWireFormat new_wire_format =
31 DuplicateWinHandle(wire_format, base::Process::Current().Pid());
32 if (new_wire_format.handle == 0)
33 return false;
34 RouteDuplicatedHandle(new_wire_format);
35 return true;
37 case BrokerableAttachment::PLACEHOLDER:
38 NOTREACHED();
39 return false;
41 return false;
44 bool AttachmentBrokerPrivilegedWin::OnMessageReceived(const Message& msg) {
45 bool handled = true;
46 switch (msg.type()) {
47 IPC_MESSAGE_HANDLER_GENERIC(AttachmentBrokerMsg_DuplicateWinHandle,
48 OnDuplicateWinHandle(msg))
49 IPC_MESSAGE_UNHANDLED(handled = false)
51 return handled;
54 void AttachmentBrokerPrivilegedWin::OnDuplicateWinHandle(
55 const IPC::Message& message) {
56 AttachmentBrokerMsg_DuplicateWinHandle::Param param;
57 if (!AttachmentBrokerMsg_DuplicateWinHandle::Read(&message, &param))
58 return;
59 IPC::internal::HandleAttachmentWin::WireFormat wire_format =
60 base::get<0>(param);
62 if (wire_format.destination_process == base::kNullProcessId)
63 return;
65 HandleWireFormat new_wire_format =
66 DuplicateWinHandle(wire_format, message.get_sender_pid());
67 RouteDuplicatedHandle(new_wire_format);
70 void AttachmentBrokerPrivilegedWin::RouteDuplicatedHandle(
71 const HandleWireFormat& wire_format) {
72 // This process is the destination.
73 if (wire_format.destination_process == base::Process::Current().Pid()) {
74 scoped_refptr<BrokerableAttachment> attachment(
75 new internal::HandleAttachmentWin(wire_format));
76 HandleReceivedAttachment(attachment);
77 return;
80 // Another process is the destination.
81 base::ProcessId dest = wire_format.destination_process;
82 Sender* sender = GetSenderWithProcessId(dest);
83 if (!sender) {
84 // Assuming that this message was not sent from a malicious process, the
85 // channel endpoint that would have received this message will block
86 // forever.
87 LOG(ERROR) << "Failed to deliver brokerable attachment to process with id: "
88 << dest;
89 return;
92 sender->Send(new AttachmentBrokerMsg_WinHandleHasBeenDuplicated(wire_format));
95 AttachmentBrokerPrivilegedWin::HandleWireFormat
96 AttachmentBrokerPrivilegedWin::DuplicateWinHandle(
97 const HandleWireFormat& wire_format,
98 base::ProcessId source_pid) {
99 HandleWireFormat new_wire_format;
100 new_wire_format.destination_process = wire_format.destination_process;
101 new_wire_format.attachment_id = wire_format.attachment_id;
102 new_wire_format.permissions = wire_format.permissions;
103 new_wire_format.handle = 0;
105 HANDLE original_handle = LongToHandle(wire_format.handle);
107 base::Process source_process =
108 base::Process::OpenWithExtraPrivileges(source_pid);
109 base::Process dest_process =
110 base::Process::OpenWithExtraPrivileges(wire_format.destination_process);
111 if (source_process.Handle() && dest_process.Handle()) {
112 DWORD desired_access = 0;
113 DWORD options = 0;
114 switch (wire_format.permissions) {
115 case HandleWin::INVALID:
116 LOG(ERROR) << "Received invalid permissions for duplication.";
117 return new_wire_format;
118 case HandleWin::DUPLICATE:
119 options = DUPLICATE_SAME_ACCESS;
120 break;
121 case HandleWin::FILE_READ_WRITE:
122 desired_access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
123 break;
126 HANDLE new_handle;
127 DWORD result = ::DuplicateHandle(source_process.Handle(), original_handle,
128 dest_process.Handle(), &new_handle,
129 desired_access, FALSE, options);
131 new_wire_format.handle = (result != 0) ? HandleToLong(new_handle) : 0;
134 return new_wire_format;
137 } // namespace IPC