 Issue 11756012:
  Enhanced Protected Mode support  (Closed)
    
  
    Issue 11756012:
  Enhanced Protected Mode support  (Closed) 
  | Index: src/shared/Communication.cpp | 
| =================================================================== | 
| --- a/src/shared/Communication.cpp | 
| +++ b/src/shared/Communication.cpp | 
| @@ -1,10 +1,18 @@ | 
| #include <Windows.h> | 
| 
Wladimir Palant
2013/09/17 07:53:48
From what I can tell, none of my comments in this
 | 
| #include <Lmcons.h> | 
| #include <Sddl.h> | 
| +#include <aclapi.h> | 
| +#include <strsafe.h> | 
| #include "Communication.h" | 
| #include "Utils.h" | 
| +#ifndef SECURITY_APP_PACKAGE_AUTHORITY | 
| +#define SECURITY_APP_PACKAGE_AUTHORITY {0,0,0,0,0,15} | 
| +#endif | 
| + | 
| +std::wstring Communication::browserSID; | 
| + | 
| namespace | 
| { | 
| const int bufferSize = 1024; | 
| @@ -25,6 +33,130 @@ | 
| 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) | 
| + { | 
| + if (ppsid == NULL) | 
| + return false; | 
| + | 
| + // Get required buffer size and allocate the TOKEN_GROUPS buffer. | 
| + DWORD dwLength = 0; | 
| + PTOKEN_GROUPS ptg = NULL; | 
| + if (!GetTokenInformation(hToken, TokenLogonSid, ptg, 0, &dwLength)) | 
| + { | 
| + 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, ptg, dwLength, &dwLength) || ptg->GroupCount != 1) | 
| + { | 
| + HeapFree(GetProcessHeap(), 0, 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, ptg); | 
| + return false; | 
| + } | 
| + if (!CopySid(dwLength, *ppsid, ptg->Groups[0].Sid)) | 
| + { | 
| + HeapFree(GetProcessHeap(), 0, ptg); | 
| + HeapFree(GetProcessHeap(), 0, *ppsid); | 
| + return false; | 
| + } | 
| + | 
| + HeapFree(GetProcessHeap(), 0, ptg); | 
| + return true; | 
| + } | 
| + | 
| + bool CreateObjectSecurityDescriptor(PSID pLogonSid, PSECURITY_DESCRIPTOR* ppSD) | 
| + { | 
| + BOOL bSuccess = FALSE; | 
| + 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 +199,6 @@ | 
| : std::runtime_error("Pipe disconnected") | 
| { | 
| } | 
| - | 
| Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mode mode) | 
| 
Wladimir Palant
2013/09/17 07:53:48
Not addressed: the empty line before this function
 | 
| { | 
| pipe = INVALID_HANDLE_VALUE; | 
| @@ -76,25 +207,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) ) | 
| + { | 
| + sa.nLength = sizeof(SECURITY_ATTRIBUTES); | 
| + sa.bInheritHandle = TRUE; | 
| + sa.lpSecurityDescriptor = securitydescriptor; | 
| + } | 
| + } | 
| + pipe = CreateNamedPipe(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, | 
| + PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &sa); | 
| + } | 
| else | 
| { | 
| pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); | 
| @@ -121,6 +263,9 @@ | 
| Communication::Pipe::~Pipe() | 
| { | 
| CloseHandle(pipe); | 
| + if (securitydescriptor) | 
| + LocalFree(securitydescriptor); | 
| + | 
| } | 
| Communication::InputBuffer Communication::Pipe::ReadMessage() |