| Index: src/shared/Communication.cpp |
| =================================================================== |
| --- a/src/shared/Communication.cpp |
| +++ b/src/shared/Communication.cpp |
| @@ -1,9 +1,17 @@ |
| #include <Windows.h> |
| #include <Lmcons.h> |
| #include <Sddl.h> |
| +#include <aclapi.h> |
| #include "Communication.h" |
| #include "Utils.h" |
| +#include <strsafe.h> |
|
Wladimir Palant
2013/09/16 13:45:07
Please move that up, to the built-in include files
|
| + |
| +#ifndef SECURITY_APP_PACKAGE_AUTHORITY |
| +#define SECURITY_APP_PACKAGE_AUTHORITY {0,0,0,0,0,15} |
| +#endif |
| + |
| +std::wstring Communication::browserSID; |
| namespace |
| { |
| @@ -25,6 +33,132 @@ |
| throw std::runtime_error(AppendErrorCode("Failed to get the current user's name")); |
| return std::wstring(buffer.get(), length); |
| } |
| + |
| + // See http://msdn.microsoft.com/en-us/library/windows/desktop/hh448493(v=vs.85).aspx |
| + bool GetLogonSid (HANDLE hToken, PSID *ppsid) |
|
Felix Dahlke
2013/09/16 16:30:12
Nit: No space after GetLogonSid?
|
| + { |
| + DWORD dwLength = 0; |
| + PTOKEN_GROUPS ptg = NULL; |
| + |
| + // 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
|
| + if (NULL == ppsid) |
|
Felix Dahlke
2013/09/16 16:30:12
We normally don't use Yoda conditions :D But it's
|
| + return false; |
| + |
| + // Get required buffer size and allocate the TOKEN_GROUPS buffer. |
| + 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
|
| + { |
| + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) |
| + return false; |
| + |
| + ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); |
| + |
| + if (ptg == NULL) |
| + return false; |
| + } |
| + |
| + // Get the token group information from the access token. |
| + if (!GetTokenInformation(hToken, TokenLogonSid, (LPVOID) ptg, dwLength, &dwLength) || ptg->GroupCount != 1) |
| + { |
| + HeapFree(GetProcessHeap(), 0, (LPVOID)ptg); |
| + return false; |
| + } |
| + |
| + // Found the logon SID; make a copy of it. |
| + dwLength = GetLengthSid(ptg->Groups[0].Sid); |
| + *ppsid = (PSID) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); |
| + if (*ppsid == NULL) |
| + { |
| + HeapFree(GetProcessHeap(), 0, (LPVOID)ptg); |
| + return false; |
| + } |
| + if (!CopySid(dwLength, *ppsid, ptg->Groups[0].Sid)) |
| + { |
| + HeapFree(GetProcessHeap(), 0, (LPVOID)ptg); |
| + HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid); |
| + return false; |
| + } |
| + |
| + HeapFree(GetProcessHeap(), 0, (LPVOID)ptg); |
| + return true; |
| + } |
| + |
| + bool CreateObjectSecurityDescriptor(PSID pLogonSid, PSECURITY_DESCRIPTOR* ppSD) |
| + { |
| + BOOL bSuccess = FALSE; |
|
Felix Dahlke
2013/09/16 16:30:12
I'd rather have these declarations closer to their
|
| + DWORD dwRes; |
| + PSID pBrowserSID = NULL; |
| + PACL pACL = NULL; |
| + PSECURITY_DESCRIPTOR pSD = NULL; |
| + EXPLICIT_ACCESS ea[2]; |
| + SID_IDENTIFIER_AUTHORITY ApplicationAuthority = SECURITY_APP_PACKAGE_AUTHORITY; |
| + |
| + ConvertStringSidToSid(Communication::browserSID.c_str(), &pBrowserSID); |
| + |
| + // Initialize an EXPLICIT_ACCESS structure for an ACE. |
| + // The ACE will allow LogonSid generic all access |
| + ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS)); |
| + ea[0].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; |
| + ea[0].grfAccessMode = SET_ACCESS; |
| + ea[0].grfInheritance= NO_INHERITANCE; |
| + ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; |
| + ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER; |
| + ea[0].Trustee.ptstrName = (LPTSTR) pLogonSid; |
| + |
| + // Initialize an EXPLICIT_ACCESS structure for an ACE. |
| + // The ACE will give the browser SID all permissions |
| + ea[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; |
| + ea[1].grfAccessMode = SET_ACCESS; |
| + ea[1].grfInheritance= NO_INHERITANCE; |
| + ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; |
| + ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; |
| + ea[1].Trustee.ptstrName = (LPTSTR) pBrowserSID; |
| + |
| + // Create a new ACL that contains the new ACEs. |
| + dwRes = SetEntriesInAcl(2, ea, NULL, &pACL); |
| + if (ERROR_SUCCESS != dwRes) |
| + { |
| + FreeSid(pBrowserSID); |
| + return false; |
| + } |
| + |
| + // Initialize a security descriptor. |
| + pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); |
| + if (NULL == pSD) |
| + { |
| + FreeSid(pBrowserSID); |
| + LocalFree(pACL); |
| + return false;; |
| + } |
| + |
| + if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) |
| + { |
| + FreeSid(pBrowserSID); |
| + LocalFree(pACL); |
| + LocalFree((LPVOID)pSD); |
| + return false; |
| + } |
| + |
| + // Add the ACL to the security descriptor. |
| + if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) // not a default DACL |
| + { |
| + FreeSid(pBrowserSID); |
| + LocalFree(pACL); |
| + LocalFree((LPVOID)pSD); |
| + return false; |
| + } |
| + |
| + *ppSD = pSD; |
| + pSD = NULL; |
| + |
| + if (pBrowserSID) |
| + FreeSid(pBrowserSID); |
| + if (pACL) |
| + LocalFree(pACL); |
| + |
| + return true; |
| + } |
| + |
| + |
| } |
| const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName(); |
| @@ -67,7 +201,6 @@ |
| : std::runtime_error("Pipe disconnected") |
| { |
| } |
| - |
| Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mode mode) |
|
Wladimir Palant
2013/09/16 13:45:07
Nit: Please keep an empty line before this one.
|
| { |
| pipe = INVALID_HANDLE_VALUE; |
| @@ -76,25 +209,36 @@ |
| SECURITY_ATTRIBUTES sa; |
| memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); |
| sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
| + |
| + HANDLE hToken = NULL; |
| + OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken); |
| + |
| + if (browserSID.empty()) |
| + { |
| + if (IsWindowsVistaOrLater()) |
| + { |
| + // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb625958.aspx |
| + LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; |
| + ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDDL_REVISION_1, &securitydescriptor, 0); |
| + sa.lpSecurityDescriptor = securitydescriptor; |
| + } |
| - PSECURITY_DESCRIPTOR securitydescriptor; |
| - if (IsWindowsVistaOrLater()) |
| - { |
| - // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb625958.aspx |
| - LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; |
| - ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDDL_REVISION_1, &securitydescriptor, 0); |
| - sa.lpSecurityDescriptor = securitydescriptor; |
| - } |
| - |
| - sa.bInheritHandle = TRUE; |
| - |
| - pipe = CreateNamedPipeW (pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, |
| - PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &sa); |
| - if (IsWindowsVistaOrLater() && securitydescriptor) |
| - { |
| - LocalFree(securitydescriptor); |
| - } |
| - } |
| + sa.bInheritHandle = TRUE; |
| + } |
| + else // IE is in AppContainer |
| + { |
| + PSID pLogonSid = NULL; |
| + //Allowing LogonSid and IE's appcontainer. |
| + if (GetLogonSid(hToken, &pLogonSid) && CreateObjectSecurityDescriptor(pLogonSid, &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
|
| + { |
| + sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
| + sa.bInheritHandle = TRUE; |
|
Wladimir Palant
2013/09/16 13:45:07
I think that we still want to set this in any case
|
| + sa.lpSecurityDescriptor = securitydescriptor; |
| + } |
| + } |
| + pipe = CreateNamedPipe(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, |
|
Wladimir Palant
2013/09/16 13:45:07
Please use CreateNamedPipeW explicitly, as we had
|
| + PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &sa); |
| + } |
|
Wladimir Palant
2013/09/16 13:45:07
Bad indentation?
|
| else |
| { |
| pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); |
| @@ -121,6 +265,9 @@ |
| Communication::Pipe::~Pipe() |
| { |
| CloseHandle(pipe); |
| + if (securitydescriptor) |
| + LocalFree(securitydescriptor); |
| + |
| } |
| Communication::InputBuffer Communication::Pipe::ReadMessage() |