OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "ipc/ipc_channel_win.h" | 5 #include "ipc/ipc_channel_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <sddl.h> |
8 #include <sstream> | 9 #include <sstream> |
9 | 10 |
10 #include "base/auto_reset.h" | 11 #include "base/auto_reset.h" |
11 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
12 #include "base/logging.h" | 13 #include "base/logging.h" |
13 #include "base/non_thread_safe.h" | 14 #include "base/non_thread_safe.h" |
14 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
15 #include "base/win_util.h" | 16 #include "base/win_util.h" |
16 #include "ipc/ipc_logging.h" | 17 #include "ipc/ipc_logging.h" |
17 #include "ipc/ipc_message_utils.h" | 18 #include "ipc/ipc_message_utils.h" |
18 | 19 |
19 namespace IPC { | 20 namespace IPC { |
| 21 |
| 22 namespace { |
| 23 |
| 24 // Creates a security descriptor with a DACL that has one ace giving full |
| 25 // access to the current logon session. |
| 26 // The security descriptor returned must be freed using LocalFree. |
| 27 // The function returns true if it succeeds, false otherwise. |
| 28 bool GetLogonSessionOnlyDACL(SECURITY_DESCRIPTOR** security_descriptor) { |
| 29 // Get the current token. |
| 30 HANDLE token = NULL; |
| 31 if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token)) |
| 32 return false; |
| 33 ScopedHandle token_scoped(token); |
| 34 |
| 35 // Get the size of the TokenGroups structure. |
| 36 DWORD size = 0; |
| 37 BOOL result = GetTokenInformation(token, TokenGroups, NULL, 0, &size); |
| 38 if (result != FALSE && GetLastError() != ERROR_INSUFFICIENT_BUFFER) |
| 39 return false; |
| 40 |
| 41 // Get the data. |
| 42 scoped_array<char> token_groups_chars(new char[size]); |
| 43 TOKEN_GROUPS* token_groups = |
| 44 reinterpret_cast<TOKEN_GROUPS*>(token_groups_chars.get()); |
| 45 |
| 46 if (!GetTokenInformation(token, TokenGroups, token_groups, size, &size)) |
| 47 return false; |
| 48 |
| 49 // Look for the logon sid. |
| 50 SID* logon_sid = NULL; |
| 51 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { |
| 52 if ((token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) != 0) { |
| 53 logon_sid = static_cast<SID*>(token_groups->Groups[i].Sid); |
| 54 break; |
| 55 } |
| 56 } |
| 57 |
| 58 if (!logon_sid) |
| 59 return false; |
| 60 |
| 61 // Convert the data to a string. |
| 62 wchar_t* sid_string; |
| 63 if (!ConvertSidToStringSid(logon_sid, &sid_string)) |
| 64 return false; |
| 65 |
| 66 static const wchar_t dacl_format[] = L"D:(A;OICI;GA;;;%ls)"; |
| 67 wchar_t dacl[SECURITY_MAX_SID_SIZE + arraysize(dacl_format) + 1] = {0}; |
| 68 wsprintf(dacl, dacl_format, sid_string); |
| 69 |
| 70 LocalFree(sid_string); |
| 71 |
| 72 // Convert the string to a security descriptor |
| 73 if (!ConvertStringSecurityDescriptorToSecurityDescriptor( |
| 74 dacl, |
| 75 SDDL_REVISION_1, |
| 76 reinterpret_cast<PSECURITY_DESCRIPTOR*>(security_descriptor), |
| 77 NULL)) { |
| 78 return false; |
| 79 } |
| 80 |
| 81 return true; |
| 82 } |
| 83 |
| 84 } // namespace |
| 85 |
20 //------------------------------------------------------------------------------ | 86 //------------------------------------------------------------------------------ |
21 | 87 |
22 Channel::ChannelImpl::State::State(ChannelImpl* channel) : is_pending(false) { | 88 Channel::ChannelImpl::State::State(ChannelImpl* channel) : is_pending(false) { |
23 memset(&context.overlapped, 0, sizeof(context.overlapped)); | 89 memset(&context.overlapped, 0, sizeof(context.overlapped)); |
24 context.handler = channel; | 90 context.handler = channel; |
25 } | 91 } |
26 | 92 |
27 Channel::ChannelImpl::State::~State() { | 93 Channel::ChannelImpl::State::~State() { |
28 COMPILE_ASSERT(!offsetof(Channel::ChannelImpl::State, context), | 94 COMPILE_ASSERT(!offsetof(Channel::ChannelImpl::State, context), |
29 starts_with_io_context); | 95 starts_with_io_context); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 } | 178 } |
113 | 179 |
114 bool Channel::ChannelImpl::CreatePipe(const std::string& channel_id, | 180 bool Channel::ChannelImpl::CreatePipe(const std::string& channel_id, |
115 Mode mode) { | 181 Mode mode) { |
116 DCHECK(pipe_ == INVALID_HANDLE_VALUE); | 182 DCHECK(pipe_ == INVALID_HANDLE_VALUE); |
117 const std::wstring pipe_name = PipeName(channel_id); | 183 const std::wstring pipe_name = PipeName(channel_id); |
118 if (mode == MODE_SERVER) { | 184 if (mode == MODE_SERVER) { |
119 SECURITY_ATTRIBUTES security_attributes = {0}; | 185 SECURITY_ATTRIBUTES security_attributes = {0}; |
120 security_attributes.bInheritHandle = FALSE; | 186 security_attributes.bInheritHandle = FALSE; |
121 security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES); | 187 security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES); |
122 if (!win_util::GetLogonSessionOnlyDACL( | 188 if (!GetLogonSessionOnlyDACL( |
123 reinterpret_cast<SECURITY_DESCRIPTOR**>( | 189 reinterpret_cast<SECURITY_DESCRIPTOR**>( |
124 &security_attributes.lpSecurityDescriptor))) { | 190 &security_attributes.lpSecurityDescriptor))) { |
125 NOTREACHED(); | 191 NOTREACHED(); |
126 } | 192 } |
127 | 193 |
128 pipe_ = CreateNamedPipeW(pipe_name.c_str(), | 194 pipe_ = CreateNamedPipeW(pipe_name.c_str(), |
129 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | | 195 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | |
130 FILE_FLAG_FIRST_PIPE_INSTANCE, | 196 FILE_FLAG_FIRST_PIPE_INSTANCE, |
131 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, | 197 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, |
132 1, // number of pipe instances | 198 1, // number of pipe instances |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 | 496 |
431 void Channel::set_listener(Listener* listener) { | 497 void Channel::set_listener(Listener* listener) { |
432 channel_impl_->set_listener(listener); | 498 channel_impl_->set_listener(listener); |
433 } | 499 } |
434 | 500 |
435 bool Channel::Send(Message* message) { | 501 bool Channel::Send(Message* message) { |
436 return channel_impl_->Send(message); | 502 return channel_impl_->Send(message); |
437 } | 503 } |
438 | 504 |
439 } // namespace IPC | 505 } // namespace IPC |
OLD | NEW |