| OLD | NEW |
| 1 #include <Windows.h> | 1 #include <Windows.h> |
| 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 #include <strsafe.h> |
| 6 | 6 |
| 7 #include "AutoHandle.h" | 7 #include "AutoHandle.h" |
| 8 #include "Communication.h" | 8 #include "Communication.h" |
| 9 #include "Utils.h" | 9 #include "Utils.h" |
| 10 | 10 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 { | 66 { |
| 67 EXPLICIT_ACCESSW explicitAccess[2] = {}; | 67 EXPLICIT_ACCESSW explicitAccess[2] = {}; |
| 68 | 68 |
| 69 explicitAccess[0].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RI
GHTS_ALL; | 69 explicitAccess[0].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RI
GHTS_ALL; |
| 70 explicitAccess[0].grfAccessMode = SET_ACCESS; | 70 explicitAccess[0].grfAccessMode = SET_ACCESS; |
| 71 explicitAccess[0].grfInheritance= NO_INHERITANCE; | 71 explicitAccess[0].grfInheritance= NO_INHERITANCE; |
| 72 explicitAccess[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; | 72 explicitAccess[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; |
| 73 explicitAccess[0].Trustee.TrusteeType = TRUSTEE_IS_USER; | 73 explicitAccess[0].Trustee.TrusteeType = TRUSTEE_IS_USER; |
| 74 explicitAccess[0].Trustee.ptstrName = static_cast<LPWSTR>(logonSid); | 74 explicitAccess[0].Trustee.ptstrName = static_cast<LPWSTR>(logonSid); |
| 75 | 75 |
| 76 std::tr1::shared_ptr<SID> sharedAllAppContainersSid; | |
| 77 | |
| 78 // Create a well-known SID for the all appcontainers group. | 76 // Create a well-known SID for the all appcontainers group. |
| 79 // We need to allow access to all AppContainers, since, apparently, | 77 // We need to allow access to all AppContainers, since, apparently, |
| 80 // giving access to specific AppContainer (for example AppContainer of IE)
| 78 // giving access to specific AppContainer (for example AppContainer of IE)
|
| 81 // tricks Windows into thinking that token is IN AppContainer. | 79 // tricks Windows into thinking that token is IN AppContainer. |
| 82 // Which blocks all the calls from outside, making it impossible to commun
icate | 80 // Which blocks all the calls from outside, making it impossible to commun
icate |
| 83 // with the engine when IE is launched with different security settings. | 81 // with the engine when IE is launched with different security settings. |
| 84 PSID allAppContainersSid = 0; | 82 PSID allAppContainersSid = 0; |
| 85 SID_IDENTIFIER_AUTHORITY applicationAuthority = SECURITY_APP_PACKAGE_AUTHO
RITY; | 83 SID_IDENTIFIER_AUTHORITY applicationAuthority = SECURITY_APP_PACKAGE_AUTHO
RITY; |
| 86 | 84 |
| 87 AllocateAndInitializeSid(&applicationAuthority, | 85 AllocateAndInitializeSid(&applicationAuthority, |
| 88 SECURITY_BUILTIN_APP_PACKAGE_RID_COUNT, | 86 SECURITY_BUILTIN_APP_PACKAGE_RID_COUNT, |
| 89 SECURITY_APP_PACKAGE_BASE_RID, | 87 SECURITY_APP_PACKAGE_BASE_RID, |
| 90 SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE, | 88 SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE, |
| 91 0, 0, 0, 0, 0, 0, | 89 0, 0, 0, 0, 0, 0, |
| 92 &allAppContainersSid); | 90 &allAppContainersSid); |
| 93 sharedAllAppContainersSid.reset(static_cast<SID*>(allAppContainersSid), Fr
eeSid); // Just to simplify cleanup | 91 std::tr1::shared_ptr<SID> sharedAllAppContainersSid(static_cast<SID*>(allA
ppContainersSid), FreeSid); // Just to simplify cleanup |
| 94 | 92 |
| 95 explicitAccess[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RI
GHTS_ALL; | 93 explicitAccess[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RI
GHTS_ALL; |
| 96 explicitAccess[1].grfAccessMode = SET_ACCESS; | 94 explicitAccess[1].grfAccessMode = SET_ACCESS; |
| 97 explicitAccess[1].grfInheritance= NO_INHERITANCE; | 95 explicitAccess[1].grfInheritance= NO_INHERITANCE; |
| 98 explicitAccess[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; | 96 explicitAccess[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; |
| 99 explicitAccess[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; | 97 explicitAccess[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; |
| 100 explicitAccess[1].Trustee.ptstrName = static_cast<LPWSTR>(allAppContainers
Sid); | 98 explicitAccess[1].Trustee.ptstrName = static_cast<LPWSTR>(allAppContainers
Sid); |
| 101 | 99 |
| 100 // Will be released later |
| 102 PACL acl = 0; | 101 PACL acl = 0; |
| 103 if (SetEntriesInAcl(2, explicitAccess, 0, &acl) != ERROR_SUCCESS) | 102 if (SetEntriesInAcl(2, explicitAccess, 0, &acl) != ERROR_SUCCESS) |
| 104 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 103 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
| 105 std::tr1::shared_ptr<ACL> sharedAcl(static_cast<ACL*>(acl), LocalFree); //
Just to simplify cleanup | |
| 106 | 104 |
| 105 // NOTE: This only references the acl, not copies it. |
| 106 // DO NOT release the ACL before it's actually used |
| 107 if (!SetSecurityDescriptorDacl(securityDescriptor.get(), TRUE, acl, FALSE)
) | 107 if (!SetSecurityDescriptorDacl(securityDescriptor.get(), TRUE, acl, FALSE)
) |
| 108 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 108 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
| 109 | |
| 110 } | 109 } |
| 111 | 110 |
| 112 // Create a dummy security descriptor with low integrirty preset and copy it
s SACL into ours | 111 // Create a dummy security descriptor with low integrirty preset and reffere
nce its SACL in ours |
| 113 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; | 112 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; |
| 114 PSECURITY_DESCRIPTOR dummySecurityDescriptorLow; | 113 PSECURITY_DESCRIPTOR dummySecurityDescriptorLow; |
| 115 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDD
L_REVISION_1, &dummySecurityDescriptorLow, 0); | 114 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDD
L_REVISION_1, &dummySecurityDescriptorLow, 0); |
| 116 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedDummySecurityDescriptor(stat
ic_cast<SECURITY_DESCRIPTOR*>(dummySecurityDescriptorLow), LocalFree); // Just t
o simplify cleanup | 115 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedDummySecurityDescriptor(stat
ic_cast<SECURITY_DESCRIPTOR*>(dummySecurityDescriptorLow), LocalFree); // Just t
o simplify cleanup |
| 117 BOOL saclPresent = FALSE; | 116 |
| 118 BOOL saclDefaulted = FALSE; | 117 DWORD sdSize(0), saclSize(0), daclSize(0), ownerSize(0), primaryGroupSize(0)
; |
| 119 PACL sacl; | 118 MakeAbsoluteSD(dummySecurityDescriptorLow, 0, &sdSize, 0, &daclSize, 0, &sac
lSize, 0, &ownerSize, 0, &primaryGroupSize); |
| 120 GetSecurityDescriptorSacl(dummySecurityDescriptorLow, &saclPresent, &sacl, &
saclDefaulted); | 119 if (saclSize == 0 || sdSize == 0) |
| 121 if (saclPresent) | |
| 122 { | 120 { |
| 123 if (!SetSecurityDescriptorSacl(securityDescriptor.get(), TRUE, sacl, FALSE
)) | |
| 124 { | |
| 125 DWORD err = GetLastError(); | |
| 126 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 121 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
| 127 } | 122 } |
| 123 // Will be released later |
| 124 PACL sacl = static_cast<PACL>(malloc(saclSize)); |
| 125 std::auto_ptr<SECURITY_DESCRIPTOR> absoluteDummySecurityDescriptorLow(static
_cast<SECURITY_DESCRIPTOR*>(malloc(sdSize))); |
| 126 daclSize = 0; |
| 127 ownerSize = 0; |
| 128 primaryGroupSize = 0; |
| 129 BOOL res = MakeAbsoluteSD(dummySecurityDescriptorLow, absoluteDummySecurityD
escriptorLow.get(), &sdSize, 0, &daclSize, sacl, &saclSize, 0, &ownerSize, 0, &p
rimaryGroupSize); |
| 130 if (res == 0 || absoluteDummySecurityDescriptorLow.get() == 0 || saclSize ==
0) |
| 131 { |
| 132 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
| 133 } |
| 134 |
| 135 // NOTE: This only references the acl, not copies it. |
| 136 // DO NOT release the ACL before it's actually used |
| 137 if (!SetSecurityDescriptorSacl(securityDescriptor.get(), TRUE, sacl, FALSE)) |
| 138 { |
| 139 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
| 128 } | 140 } |
| 129 | 141 |
| 130 return securityDescriptor; | 142 return securityDescriptor; |
| 131 } | 143 } |
| 132 } | 144 } |
| 133 | 145 |
| 134 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_"
+ GetUserName(); | 146 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_"
+ GetUserName(); |
| 135 | 147 |
| 136 void Communication::InputBuffer::CheckType(Communication::ValueType expectedType
) | 148 void Communication::InputBuffer::CheckType(Communication::ValueType expectedType
) |
| 137 { | 149 { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 165 Communication::PipeBusyError::PipeBusyError() | 177 Communication::PipeBusyError::PipeBusyError() |
| 166 : std::runtime_error("Timeout while trying to connect to a named pipe, pipe is
busy") | 178 : std::runtime_error("Timeout while trying to connect to a named pipe, pipe is
busy") |
| 167 { | 179 { |
| 168 } | 180 } |
| 169 | 181 |
| 170 Communication::PipeDisconnectedError::PipeDisconnectedError() | 182 Communication::PipeDisconnectedError::PipeDisconnectedError() |
| 171 : std::runtime_error("Pipe disconnected") | 183 : std::runtime_error("Pipe disconnected") |
| 172 { | 184 { |
| 173 } | 185 } |
| 174 | 186 |
| 187 void FreeAbsoluteSecurityDescriptor(SECURITY_DESCRIPTOR* securityDescriptor) |
| 188 { |
| 189 BOOL aclPresent = FALSE; |
| 190 BOOL aclDefaulted = FALSE; |
| 191 PACL acl = 0; |
| 192 GetSecurityDescriptorDacl(securityDescriptor, &aclPresent, &acl, &aclDefaulted
); |
| 193 if (aclPresent) |
| 194 { |
| 195 LocalFree(acl); |
| 196 } |
| 197 aclPresent = FALSE; |
| 198 aclDefaulted = FALSE; |
| 199 acl = 0; |
| 200 GetSecurityDescriptorSacl(securityDescriptor, &aclPresent, &acl, &aclDefaulted
); |
| 201 if (aclPresent) |
| 202 { |
| 203 free(acl); |
| 204 } |
| 205 free(securityDescriptor); |
| 206 } |
| 207 |
| 175 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod
e mode) | 208 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod
e mode) |
| 176 { | 209 { |
| 177 pipe = INVALID_HANDLE_VALUE; | 210 pipe = INVALID_HANDLE_VALUE; |
| 178 if (mode == MODE_CREATE) | 211 if (mode == MODE_CREATE) |
| 179 { | 212 { |
| 180 SECURITY_ATTRIBUTES securityAttributes = {}; | 213 SECURITY_ATTRIBUTES securityAttributes = {}; |
| 181 securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); | 214 securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); |
| 182 securityAttributes.bInheritHandle = TRUE; | 215 securityAttributes.bInheritHandle = TRUE; |
| 183 | 216 |
| 184 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedSecurityDescriptor; // Just
to simplify cleanup | 217 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedSecurityDescriptor; // Just
to simplify cleanup |
| 185 | |
| 186 AutoHandle token; | 218 AutoHandle token; |
| 187 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, token); | 219 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, token); |
| 188 | 220 |
| 189 if (IsWindowsVistaOrLater()) | 221 if (IsWindowsVistaOrLater()) |
| 190 { | 222 { |
| 191 std::auto_ptr<SID> logonSid = GetLogonSid(token); | 223 std::auto_ptr<SID> logonSid = GetLogonSid(token); |
| 192 // Create a SECURITY_DESCRIPTOR that has both Low Integrity and allows acc
ess to all AppContainers | 224 // Create a SECURITY_DESCRIPTOR that has both Low Integrity and allows acc
ess to all AppContainers |
| 193 // This is needed since IE likes to jump out of Enhanced Protected Mode fo
r specific pages (bing.com) | 225 // This is needed since IE likes to jump out of Enhanced Protected Mode fo
r specific pages (bing.com) |
| 194 std::auto_ptr<SECURITY_DESCRIPTOR> securityDescriptor = CreateSecurityDesc
riptor(logonSid.get()); | 226 std::auto_ptr<SECURITY_DESCRIPTOR> securityDescriptor = CreateSecurityDesc
riptor(logonSid.get()); |
| 227 |
| 195 securityAttributes.lpSecurityDescriptor = securityDescriptor.release(); | 228 securityAttributes.lpSecurityDescriptor = securityDescriptor.release(); |
| 196 sharedSecurityDescriptor.reset(static_cast<SECURITY_DESCRIPTOR*>(securityA
ttributes.lpSecurityDescriptor)); | 229 sharedSecurityDescriptor.reset(static_cast<SECURITY_DESCRIPTOR*>(securityA
ttributes.lpSecurityDescriptor), FreeAbsoluteSecurityDescriptor); |
| 197 } | 230 } |
| 198 pipe = CreateNamedPipeW(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MES
SAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, | 231 pipe = CreateNamedPipeW(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MES
SAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, |
| 199 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &securityAttributes); | 232 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &securityAttributes); |
| 200 } | 233 } |
| 201 else | 234 else |
| 202 { | 235 { |
| 203 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPE
N_EXISTING, 0, 0); | 236 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPE
N_EXISTING, 0, 0); |
| 204 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) | 237 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) |
| 205 { | 238 { |
| 206 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) | 239 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) |
| 207 throw PipeBusyError(); | 240 throw PipeBusyError(); |
| 208 | 241 |
| 209 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O
PEN_EXISTING, 0, 0); | 242 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O
PEN_EXISTING, 0, 0); |
| 210 } | 243 } |
| 211 } | 244 } |
| 212 | 245 |
| 213 if (pipe == INVALID_HANDLE_VALUE) | 246 if (pipe == INVALID_HANDLE_VALUE) |
| 214 throw PipeConnectionError(); | 247 throw PipeConnectionError(); |
| 215 | 248 |
| 216 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; | 249 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; |
| 217 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) | 250 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) |
| 218 throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastE
rror()); | 251 throw std::runtime_error(AppendErrorCode("SetNamedPipeHandleState failed")); |
| 219 | 252 |
| 220 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) | 253 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) |
| 221 { | 254 { |
| 222 DWORD err = GetLastError(); | 255 DWORD err = GetLastError(); |
| 223 throw std::runtime_error("Client failed to connect: error " + GetLastError()
); | 256 throw std::runtime_error(AppendErrorCode("Client failed to connect")); |
| 224 } | 257 } |
| 225 } | 258 } |
| 226 | 259 |
| 227 Communication::Pipe::~Pipe() | 260 Communication::Pipe::~Pipe() |
| 228 { | 261 { |
| 229 CloseHandle(pipe); | 262 CloseHandle(pipe); |
| 230 } | 263 } |
| 231 | 264 |
| 232 Communication::InputBuffer Communication::Pipe::ReadMessage() | 265 Communication::InputBuffer Communication::Pipe::ReadMessage() |
| 233 { | 266 { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 259 return Communication::InputBuffer(stream.str()); | 292 return Communication::InputBuffer(stream.str()); |
| 260 } | 293 } |
| 261 | 294 |
| 262 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) | 295 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) |
| 263 { | 296 { |
| 264 DWORD bytesWritten; | 297 DWORD bytesWritten; |
| 265 std::string data = message.Get(); | 298 std::string data = message.Get(); |
| 266 if (!WriteFile(pipe, data.c_str(), static_cast<DWORD>(data.length()), &bytesWr
itten, 0)) | 299 if (!WriteFile(pipe, data.c_str(), static_cast<DWORD>(data.length()), &bytesWr
itten, 0)) |
| 267 throw std::runtime_error("Failed to write to pipe"); | 300 throw std::runtime_error("Failed to write to pipe"); |
| 268 } | 301 } |
| OLD | NEW |