Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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> | 4 #include <aclapi.h> |
5 #include <strsafe.h> | |
5 | 6 |
6 #include "Communication.h" | 7 #include "Communication.h" |
7 #include "Utils.h" | 8 #include "Utils.h" |
8 #include <strsafe.h> | |
Wladimir Palant
2013/09/16 13:45:07
Please move that up, to the built-in include files
| |
9 | 9 |
10 #ifndef SECURITY_APP_PACKAGE_AUTHORITY | 10 #ifndef SECURITY_APP_PACKAGE_AUTHORITY |
11 #define SECURITY_APP_PACKAGE_AUTHORITY {0,0,0,0,0,15} | 11 #define SECURITY_APP_PACKAGE_AUTHORITY {0,0,0,0,0,15} |
12 #endif | 12 #endif |
13 | 13 |
14 std::wstring Communication::browserSID; | 14 std::wstring Communication::browserSID; |
15 | 15 |
16 namespace | 16 namespace |
17 { | 17 { |
18 const int bufferSize = 1024; | 18 const int bufferSize = 1024; |
19 | 19 |
20 std::string AppendErrorCode(const std::string& message) | 20 std::string AppendErrorCode(const std::string& message) |
21 { | 21 { |
22 std::stringstream stream; | 22 std::stringstream stream; |
23 stream << message << " (Error code: " << GetLastError() << ")"; | 23 stream << message << " (Error code: " << GetLastError() << ")"; |
24 return stream.str(); | 24 return stream.str(); |
25 } | 25 } |
26 | 26 |
27 std::wstring GetUserName() | 27 std::wstring GetUserName() |
28 { | 28 { |
29 const DWORD maxLength = UNLEN + 1; | 29 const DWORD maxLength = UNLEN + 1; |
30 std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]); | 30 std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]); |
31 DWORD length = maxLength; | 31 DWORD length = maxLength; |
32 if (!::GetUserNameW(buffer.get(), &length)) | 32 if (!::GetUserNameW(buffer.get(), &length)) |
33 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")); |
34 return std::wstring(buffer.get(), length); | 34 return std::wstring(buffer.get(), length); |
35 } | 35 } |
36 | 36 |
37 // See http://msdn.microsoft.com/en-us/library/windows/desktop/hh448493(v=vs.8 5).aspx | 37 // See http://msdn.microsoft.com/en-us/library/windows/desktop/hh448493(v=vs.8 5).aspx |
38 bool GetLogonSid (HANDLE hToken, PSID *ppsid) | 38 bool GetLogonSid (HANDLE hToken, PSID *ppsid) |
Felix Dahlke
2013/09/16 16:30:12
Nit: No space after GetLogonSid?
| |
39 { | 39 { |
40 if (ppsid == NULL) | |
41 return false; | |
42 | |
43 // Get required buffer size and allocate the TOKEN_GROUPS buffer. | |
40 DWORD dwLength = 0; | 44 DWORD dwLength = 0; |
41 PTOKEN_GROUPS ptg = NULL; | 45 PTOKEN_GROUPS ptg = NULL; |
42 | 46 if (!GetTokenInformation(hToken, TokenLogonSid, ptg, 0, &dwLength)) |
43 // Verify the parameter passed in is not NULL. | |
Felix Dahlke
2013/09/16 16:30:12
I do think this is kinda obvious from the conditio
| |
44 if (NULL == ppsid) | |
Felix Dahlke
2013/09/16 16:30:12
We normally don't use Yoda conditions :D But it's
| |
45 return false; | |
46 | |
47 // Get required buffer size and allocate the TOKEN_GROUPS buffer. | |
48 if (!GetTokenInformation(hToken, TokenLogonSid, (LPVOID) ptg, 0, &dwLength)) | |
Felix Dahlke
2013/09/16 16:30:12
This code looks very similar to what's in AdblockP
| |
49 { | 47 { |
50 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) | 48 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) |
51 return false; | 49 return false; |
52 | 50 |
53 ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLengt h); | 51 ptg = (PTOKEN_GROUPS) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLeng th); |
54 | 52 |
55 if (ptg == NULL) | 53 if (ptg == NULL) |
56 return false; | 54 return false; |
57 } | 55 } |
58 | 56 |
59 // Get the token group information from the access token. | 57 // Get the token group information from the access token. |
60 if (!GetTokenInformation(hToken, TokenLogonSid, (LPVOID) ptg, dwLength, &dwL ength) || ptg->GroupCount != 1) | 58 if (!GetTokenInformation(hToken, TokenLogonSid, ptg, dwLength, &dwLength) || ptg->GroupCount != 1) |
61 { | 59 { |
62 HeapFree(GetProcessHeap(), 0, (LPVOID)ptg); | 60 HeapFree(GetProcessHeap(), 0, ptg); |
63 return false; | 61 return false; |
64 } | 62 } |
65 | 63 |
66 // Found the logon SID; make a copy of it. | 64 // Found the logon SID; make a copy of it. |
67 dwLength = GetLengthSid(ptg->Groups[0].Sid); | 65 dwLength = GetLengthSid(ptg->Groups[0].Sid); |
68 *ppsid = (PSID) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); | 66 *ppsid = (PSID) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); |
69 if (*ppsid == NULL) | 67 if (*ppsid == NULL) |
70 { | 68 { |
71 HeapFree(GetProcessHeap(), 0, (LPVOID)ptg); | 69 HeapFree(GetProcessHeap(), 0, ptg); |
72 return false; | 70 return false; |
73 } | 71 } |
74 if (!CopySid(dwLength, *ppsid, ptg->Groups[0].Sid)) | 72 if (!CopySid(dwLength, *ppsid, ptg->Groups[0].Sid)) |
75 { | 73 { |
76 HeapFree(GetProcessHeap(), 0, (LPVOID)ptg); | 74 HeapFree(GetProcessHeap(), 0, ptg); |
77 HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid); | 75 HeapFree(GetProcessHeap(), 0, *ppsid); |
78 return false; | 76 return false; |
79 } | 77 } |
80 | 78 |
81 HeapFree(GetProcessHeap(), 0, (LPVOID)ptg); | 79 HeapFree(GetProcessHeap(), 0, ptg); |
82 return true; | 80 return true; |
83 } | 81 } |
84 | 82 |
85 bool CreateObjectSecurityDescriptor(PSID pLogonSid, PSECURITY_DESCRIPTOR* ppSD ) | 83 bool CreateObjectSecurityDescriptor(PSID pLogonSid, PSECURITY_DESCRIPTOR* ppSD ) |
86 { | 84 { |
87 BOOL bSuccess = FALSE; | 85 BOOL bSuccess = FALSE; |
Felix Dahlke
2013/09/16 16:30:12
I'd rather have these declarations closer to their
| |
88 DWORD dwRes; | 86 DWORD dwRes; |
89 PSID pBrowserSID = NULL; | 87 PSID pBrowserSID = NULL; |
90 PACL pACL = NULL; | 88 PACL pACL = NULL; |
91 PSECURITY_DESCRIPTOR pSD = NULL; | 89 PSECURITY_DESCRIPTOR pSD = NULL; |
92 EXPLICIT_ACCESS ea[2]; | 90 EXPLICIT_ACCESS ea[2]; |
93 SID_IDENTIFIER_AUTHORITY ApplicationAuthority = SECURITY_APP_PACKAGE_AUTHORI TY; | 91 SID_IDENTIFIER_AUTHORITY ApplicationAuthority = SECURITY_APP_PACKAGE_AUTHORI TY; |
94 | 92 |
95 ConvertStringSidToSid(Communication::browserSID.c_str(), &pBrowserSID); | 93 ConvertStringSidToSid(Communication::browserSID.c_str(), &pBrowserSID); |
96 | 94 |
97 // Initialize an EXPLICIT_ACCESS structure for an ACE. | 95 // Initialize an EXPLICIT_ACCESS structure for an ACE. |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
194 | 192 |
195 Communication::PipeBusyError::PipeBusyError() | 193 Communication::PipeBusyError::PipeBusyError() |
196 : 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") |
197 { | 195 { |
198 } | 196 } |
199 | 197 |
200 Communication::PipeDisconnectedError::PipeDisconnectedError() | 198 Communication::PipeDisconnectedError::PipeDisconnectedError() |
201 : std::runtime_error("Pipe disconnected") | 199 : std::runtime_error("Pipe disconnected") |
202 { | 200 { |
203 } | 201 } |
204 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/16 13:45:07
Nit: Please keep an empty line before this one.
|
Wladimir Palant
2013/09/17 07:53:48
Not addressed: the empty line before this function
|
205 { | 203 { |
206 pipe = INVALID_HANDLE_VALUE; | 204 pipe = INVALID_HANDLE_VALUE; |
207 if (mode == MODE_CREATE) | 205 if (mode == MODE_CREATE) |
208 { | 206 { |
209 SECURITY_ATTRIBUTES sa; | 207 SECURITY_ATTRIBUTES sa; |
210 memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); | 208 memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); |
211 sa.nLength = sizeof(SECURITY_ATTRIBUTES); | 209 sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
212 | 210 |
213 HANDLE hToken = NULL; | 211 HANDLE hToken = NULL; |
214 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken); | 212 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken); |
215 | 213 |
216 if (browserSID.empty()) | 214 if (browserSID.empty()) |
217 { | 215 { |
218 if (IsWindowsVistaOrLater()) | 216 if (IsWindowsVistaOrLater()) |
219 { | 217 { |
220 // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb62 5958.aspx | 218 // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb62 5958.aspx |
221 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; | 219 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; |
222 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDDL_REVISION_1, &securitydescriptor, 0); | 220 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDDL_REVISION_1, &securitydescriptor, 0); |
223 sa.lpSecurityDescriptor = securitydescriptor; | 221 sa.lpSecurityDescriptor = securitydescriptor; |
224 } | 222 } |
225 | 223 |
226 sa.bInheritHandle = TRUE; | 224 sa.bInheritHandle = TRUE; |
227 } | 225 } |
228 else // IE is in AppContainer | 226 else // IE is in AppContainer |
229 { | 227 { |
230 PSID pLogonSid = NULL; | 228 PSID pLogonSid = NULL; |
231 //Allowing LogonSid and IE's appcontainer. | 229 //Allowing LogonSid and IE's appcontainer. |
232 if (GetLogonSid(hToken, &pLogonSid) && CreateObjectSecurityDescriptor(pLog onSid, &securitydescriptor) ) | 230 if (GetLogonSid(hToken, &pLogonSid) && CreateObjectSecurityDescriptor(pLog onSid, &securitydescriptor) ) |
Wladimir Palant
2013/09/16 13:45:07
Why do we need to allow the logon sid? Is it for t
Oleksandr
2013/09/17 08:27:19
Our plugin is unable to access the named pipe if w
| |
233 { | 231 { |
234 sa.nLength = sizeof(SECURITY_ATTRIBUTES); | 232 sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
235 sa.bInheritHandle = TRUE; | 233 sa.bInheritHandle = TRUE; |
Wladimir Palant
2013/09/16 13:45:07
I think that we still want to set this in any case
| |
236 sa.lpSecurityDescriptor = securitydescriptor; | 234 sa.lpSecurityDescriptor = securitydescriptor; |
237 } | 235 } |
238 } | 236 } |
239 pipe = CreateNamedPipe(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESS AGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, | 237 pipe = CreateNamedPipe(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESS AGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, |
Wladimir Palant
2013/09/16 13:45:07
Please use CreateNamedPipeW explicitly, as we had
| |
240 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &sa); | 238 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &sa); |
241 } | 239 } |
Wladimir Palant
2013/09/16 13:45:07
Bad indentation?
| |
242 else | 240 else |
243 { | 241 { |
244 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); |
245 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) | 243 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) |
246 { | 244 { |
247 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) | 245 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) |
248 throw PipeBusyError(); | 246 throw PipeBusyError(); |
249 | 247 |
250 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); |
251 } | 249 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 return Communication::InputBuffer(stream.str()); | 298 return Communication::InputBuffer(stream.str()); |
301 } | 299 } |
302 | 300 |
303 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) | 301 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) |
304 { | 302 { |
305 DWORD bytesWritten; | 303 DWORD bytesWritten; |
306 std::string data = message.Get(); | 304 std::string data = message.Get(); |
307 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)) |
308 throw std::runtime_error("Failed to write to pipe"); | 306 throw std::runtime_error("Failed to write to pipe"); |
309 } | 307 } |
LEFT | RIGHT |