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