| 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 |