Left: | ||
Right: |
OLD | NEW |
---|---|
1 #include <Windows.h> | 1 #include <Windows.h> |
Wladimir Palant
2013/09/17 07:53:48
From what I can tell, none of my comments in this
| |
2 #include <Lmcons.h> | 2 #include <Lmcons.h> |
3 #include <Sddl.h> | 3 #include <Sddl.h> |
4 #include <aclapi.h> | |
5 #include <strsafe.h> | |
4 | 6 |
5 #include "Communication.h" | 7 #include "Communication.h" |
6 #include "Utils.h" | 8 #include "Utils.h" |
7 | 9 |
10 #ifndef SECURITY_APP_PACKAGE_AUTHORITY | |
11 #define SECURITY_APP_PACKAGE_AUTHORITY {0,0,0,0,0,15} | |
12 #endif | |
13 | |
14 std::wstring Communication::browserSID; | |
15 | |
8 namespace | 16 namespace |
9 { | 17 { |
10 const int bufferSize = 1024; | 18 const int bufferSize = 1024; |
11 | 19 |
12 std::string AppendErrorCode(const std::string& message) | 20 std::string AppendErrorCode(const std::string& message) |
13 { | 21 { |
14 std::stringstream stream; | 22 std::stringstream stream; |
15 stream << message << " (Error code: " << GetLastError() << ")"; | 23 stream << message << " (Error code: " << GetLastError() << ")"; |
16 return stream.str(); | 24 return stream.str(); |
17 } | 25 } |
18 | 26 |
19 std::wstring GetUserName() | 27 std::wstring GetUserName() |
20 { | 28 { |
21 const DWORD maxLength = UNLEN + 1; | 29 const DWORD maxLength = UNLEN + 1; |
22 std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]); | 30 std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]); |
23 DWORD length = maxLength; | 31 DWORD length = maxLength; |
24 if (!::GetUserNameW(buffer.get(), &length)) | 32 if (!::GetUserNameW(buffer.get(), &length)) |
25 throw std::runtime_error(AppendErrorCode("Failed to get the current user's name")); | 33 throw std::runtime_error(AppendErrorCode("Failed to get the current user's name")); |
26 return std::wstring(buffer.get(), length); | 34 return std::wstring(buffer.get(), length); |
27 } | 35 } |
36 | |
37 // See http://msdn.microsoft.com/en-us/library/windows/desktop/hh448493(v=vs.8 5).aspx | |
38 bool GetLogonSid (HANDLE hToken, PSID *ppsid) | |
39 { | |
40 if (ppsid == NULL) | |
41 return false; | |
42 | |
43 // Get required buffer size and allocate the TOKEN_GROUPS buffer. | |
44 DWORD dwLength = 0; | |
45 PTOKEN_GROUPS ptg = NULL; | |
46 if (!GetTokenInformation(hToken, TokenLogonSid, ptg, 0, &dwLength)) | |
47 { | |
48 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) | |
49 return false; | |
50 | |
51 ptg = (PTOKEN_GROUPS) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLeng th); | |
52 | |
53 if (ptg == NULL) | |
54 return false; | |
55 } | |
56 | |
57 // Get the token group information from the access token. | |
58 if (!GetTokenInformation(hToken, TokenLogonSid, ptg, dwLength, &dwLength) || ptg->GroupCount != 1) | |
59 { | |
60 HeapFree(GetProcessHeap(), 0, ptg); | |
61 return false; | |
62 } | |
63 | |
64 // Found the logon SID; make a copy of it. | |
65 dwLength = GetLengthSid(ptg->Groups[0].Sid); | |
66 *ppsid = (PSID) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); | |
67 if (*ppsid == NULL) | |
68 { | |
69 HeapFree(GetProcessHeap(), 0, ptg); | |
70 return false; | |
71 } | |
72 if (!CopySid(dwLength, *ppsid, ptg->Groups[0].Sid)) | |
73 { | |
74 HeapFree(GetProcessHeap(), 0, ptg); | |
75 HeapFree(GetProcessHeap(), 0, *ppsid); | |
76 return false; | |
77 } | |
78 | |
79 HeapFree(GetProcessHeap(), 0, ptg); | |
80 return true; | |
81 } | |
82 | |
83 bool CreateObjectSecurityDescriptor(PSID pLogonSid, PSECURITY_DESCRIPTOR* ppSD ) | |
84 { | |
85 BOOL bSuccess = FALSE; | |
86 DWORD dwRes; | |
87 PSID pBrowserSID = NULL; | |
88 PACL pACL = NULL; | |
89 PSECURITY_DESCRIPTOR pSD = NULL; | |
90 EXPLICIT_ACCESS ea[2]; | |
91 SID_IDENTIFIER_AUTHORITY ApplicationAuthority = SECURITY_APP_PACKAGE_AUTHORI TY; | |
92 | |
93 ConvertStringSidToSid(Communication::browserSID.c_str(), &pBrowserSID); | |
94 | |
95 // Initialize an EXPLICIT_ACCESS structure for an ACE. | |
96 // The ACE will allow LogonSid generic all access | |
97 ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS)); | |
98 ea[0].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; | |
99 ea[0].grfAccessMode = SET_ACCESS; | |
100 ea[0].grfInheritance= NO_INHERITANCE; | |
101 ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; | |
102 ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER; | |
103 ea[0].Trustee.ptstrName = (LPTSTR) pLogonSid; | |
104 | |
105 // Initialize an EXPLICIT_ACCESS structure for an ACE. | |
106 // The ACE will give the browser SID all permissions | |
107 ea[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; | |
108 ea[1].grfAccessMode = SET_ACCESS; | |
109 ea[1].grfInheritance= NO_INHERITANCE; | |
110 ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; | |
111 ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; | |
112 ea[1].Trustee.ptstrName = (LPTSTR) pBrowserSID; | |
113 | |
114 // Create a new ACL that contains the new ACEs. | |
115 dwRes = SetEntriesInAcl(2, ea, NULL, &pACL); | |
116 if (ERROR_SUCCESS != dwRes) | |
117 { | |
118 FreeSid(pBrowserSID); | |
119 return false; | |
120 } | |
121 | |
122 // Initialize a security descriptor. | |
123 pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH ); | |
124 if (NULL == pSD) | |
125 { | |
126 FreeSid(pBrowserSID); | |
127 LocalFree(pACL); | |
128 return false;; | |
129 } | |
130 | |
131 if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) | |
132 { | |
133 FreeSid(pBrowserSID); | |
134 LocalFree(pACL); | |
135 LocalFree((LPVOID)pSD); | |
136 return false; | |
137 } | |
138 | |
139 // Add the ACL to the security descriptor. | |
140 if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) // not a default D ACL | |
141 { | |
142 FreeSid(pBrowserSID); | |
143 LocalFree(pACL); | |
144 LocalFree((LPVOID)pSD); | |
145 return false; | |
146 } | |
147 | |
148 *ppSD = pSD; | |
149 pSD = NULL; | |
150 | |
151 if (pBrowserSID) | |
152 FreeSid(pBrowserSID); | |
153 if (pACL) | |
154 LocalFree(pACL); | |
155 | |
156 return true; | |
157 } | |
158 | |
159 | |
28 } | 160 } |
29 | 161 |
30 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName(); | 162 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName(); |
31 | 163 |
32 void Communication::InputBuffer::CheckType(Communication::ValueType expectedType ) | 164 void Communication::InputBuffer::CheckType(Communication::ValueType expectedType ) |
33 { | 165 { |
34 if (!hasType) | 166 if (!hasType) |
35 ReadBinary(currentType); | 167 ReadBinary(currentType); |
36 | 168 |
37 if (currentType != expectedType) | 169 if (currentType != expectedType) |
(...skipping 22 matching lines...) Expand all Loading... | |
60 | 192 |
61 Communication::PipeBusyError::PipeBusyError() | 193 Communication::PipeBusyError::PipeBusyError() |
62 : std::runtime_error("Timeout while trying to connect to a named pipe, pipe is busy") | 194 : std::runtime_error("Timeout while trying to connect to a named pipe, pipe is busy") |
63 { | 195 { |
64 } | 196 } |
65 | 197 |
66 Communication::PipeDisconnectedError::PipeDisconnectedError() | 198 Communication::PipeDisconnectedError::PipeDisconnectedError() |
67 : std::runtime_error("Pipe disconnected") | 199 : std::runtime_error("Pipe disconnected") |
68 { | 200 { |
69 } | 201 } |
70 | |
71 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod e mode) | 202 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod e mode) |
Wladimir Palant
2013/09/17 07:53:48
Not addressed: the empty line before this function
| |
72 { | 203 { |
73 pipe = INVALID_HANDLE_VALUE; | 204 pipe = INVALID_HANDLE_VALUE; |
74 if (mode == MODE_CREATE) | 205 if (mode == MODE_CREATE) |
75 { | 206 { |
76 SECURITY_ATTRIBUTES sa; | 207 SECURITY_ATTRIBUTES sa; |
77 memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); | 208 memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); |
78 sa.nLength = sizeof(SECURITY_ATTRIBUTES); | 209 sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
79 | 210 |
80 PSECURITY_DESCRIPTOR securitydescriptor; | 211 HANDLE hToken = NULL; |
81 if (IsWindowsVistaOrLater()) | 212 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken); |
213 | |
214 if (browserSID.empty()) | |
82 { | 215 { |
83 // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb6259 58.aspx | 216 if (IsWindowsVistaOrLater()) |
84 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; | 217 { |
85 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, S DDL_REVISION_1, &securitydescriptor, 0); | 218 // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb62 5958.aspx |
86 sa.lpSecurityDescriptor = securitydescriptor; | 219 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; |
220 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDDL_REVISION_1, &securitydescriptor, 0); | |
221 sa.lpSecurityDescriptor = securitydescriptor; | |
222 } | |
223 | |
224 sa.bInheritHandle = TRUE; | |
87 } | 225 } |
88 | 226 else // IE is in AppContainer |
89 sa.bInheritHandle = TRUE; | |
90 | |
91 pipe = CreateNamedPipeW (pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MES SAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, | |
92 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSi ze, 0, &sa); | |
93 if (IsWindowsVistaOrLater() && securitydescriptor) | |
94 { | 227 { |
95 LocalFree(securitydescriptor); | 228 PSID pLogonSid = NULL; |
229 //Allowing LogonSid and IE's appcontainer. | |
230 if (GetLogonSid(hToken, &pLogonSid) && CreateObjectSecurityDescriptor(pLog onSid, &securitydescriptor) ) | |
231 { | |
232 sa.nLength = sizeof(SECURITY_ATTRIBUTES); | |
233 sa.bInheritHandle = TRUE; | |
234 sa.lpSecurityDescriptor = securitydescriptor; | |
235 } | |
96 } | 236 } |
97 } | 237 pipe = CreateNamedPipe(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESS AGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, |
238 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &sa); | |
239 } | |
98 else | 240 else |
99 { | 241 { |
100 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPE N_EXISTING, 0, 0); | 242 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPE N_EXISTING, 0, 0); |
101 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) | 243 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) |
102 { | 244 { |
103 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) | 245 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) |
104 throw PipeBusyError(); | 246 throw PipeBusyError(); |
105 | 247 |
106 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O PEN_EXISTING, 0, 0); | 248 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O PEN_EXISTING, 0, 0); |
107 } | 249 } |
108 } | 250 } |
109 | 251 |
110 if (pipe == INVALID_HANDLE_VALUE) | 252 if (pipe == INVALID_HANDLE_VALUE) |
111 throw PipeConnectionError(); | 253 throw PipeConnectionError(); |
112 | 254 |
113 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; | 255 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; |
114 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) | 256 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) |
115 throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastE rror()); | 257 throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastE rror()); |
116 | 258 |
117 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) | 259 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) |
118 throw std::runtime_error("Client failed to connect: error " + GetLastError() ); | 260 throw std::runtime_error("Client failed to connect: error " + GetLastError() ); |
119 } | 261 } |
120 | 262 |
121 Communication::Pipe::~Pipe() | 263 Communication::Pipe::~Pipe() |
122 { | 264 { |
123 CloseHandle(pipe); | 265 CloseHandle(pipe); |
266 if (securitydescriptor) | |
267 LocalFree(securitydescriptor); | |
268 | |
124 } | 269 } |
125 | 270 |
126 Communication::InputBuffer Communication::Pipe::ReadMessage() | 271 Communication::InputBuffer Communication::Pipe::ReadMessage() |
127 { | 272 { |
128 std::stringstream stream; | 273 std::stringstream stream; |
129 std::auto_ptr<char> buffer(new char[bufferSize]); | 274 std::auto_ptr<char> buffer(new char[bufferSize]); |
130 bool doneReading = false; | 275 bool doneReading = false; |
131 while (!doneReading) | 276 while (!doneReading) |
132 { | 277 { |
133 DWORD bytesRead; | 278 DWORD bytesRead; |
(...skipping 19 matching lines...) Expand all Loading... | |
153 return Communication::InputBuffer(stream.str()); | 298 return Communication::InputBuffer(stream.str()); |
154 } | 299 } |
155 | 300 |
156 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) | 301 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) |
157 { | 302 { |
158 DWORD bytesWritten; | 303 DWORD bytesWritten; |
159 std::string data = message.Get(); | 304 std::string data = message.Get(); |
160 if (!WriteFile(pipe, data.c_str(), static_cast<DWORD>(data.length()), &bytesWr itten, 0)) | 305 if (!WriteFile(pipe, data.c_str(), static_cast<DWORD>(data.length()), &bytesWr itten, 0)) |
161 throw std::runtime_error("Failed to write to pipe"); | 306 throw std::runtime_error("Failed to write to pipe"); |
162 } | 307 } |
OLD | NEW |