| 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 sharedAllAppContainersSid.reset(static_cast<SID*>(allAppContainersSid), Fr
eeSid); // Just to simplify cleanup | 93 sharedAllAppContainersSid.reset(static_cast<SID*>(allAppContainersSid), Fr
eeSid); // Just to simplify cleanup |
| 94 | 94 |
| 95 explicitAccess[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RI
GHTS_ALL; | 95 explicitAccess[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RI
GHTS_ALL; |
| 96 explicitAccess[1].grfAccessMode = SET_ACCESS; | 96 explicitAccess[1].grfAccessMode = SET_ACCESS; |
| 97 explicitAccess[1].grfInheritance= NO_INHERITANCE; | 97 explicitAccess[1].grfInheritance= NO_INHERITANCE; |
| 98 explicitAccess[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; | 98 explicitAccess[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; |
| 99 explicitAccess[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; | 99 explicitAccess[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; |
| 100 explicitAccess[1].Trustee.ptstrName = static_cast<LPWSTR>(allAppContainers
Sid); | 100 explicitAccess[1].Trustee.ptstrName = static_cast<LPWSTR>(allAppContainers
Sid); |
| 101 | 101 |
| 102 PACL acl = 0; | 102 PACL acl = 0; |
| 103 // acl has to be released after this |
| 103 if (SetEntriesInAcl(2, explicitAccess, 0, &acl) != ERROR_SUCCESS) | 104 if (SetEntriesInAcl(2, explicitAccess, 0, &acl) != ERROR_SUCCESS) |
| 104 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 105 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
| 105 std::tr1::shared_ptr<ACL> sharedAcl(static_cast<ACL*>(acl), LocalFree); //
Just to simplify cleanup | |
| 106 | 106 |
| 107 // This only references the acl, not copies it |
| 107 if (!SetSecurityDescriptorDacl(securityDescriptor.get(), TRUE, acl, FALSE)
) | 108 if (!SetSecurityDescriptorDacl(securityDescriptor.get(), TRUE, acl, FALSE)
) |
| 108 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 109 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
| 109 | |
| 110 } | 110 } |
| 111 | 111 |
| 112 // Create a dummy security descriptor with low integrirty preset and copy it
s SACL into ours | 112 // Create a dummy security descriptor with low integrirty preset and copy it
s SACL into ours |
| 113 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; | 113 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; |
| 114 PSECURITY_DESCRIPTOR dummySecurityDescriptorLow; | 114 PSECURITY_DESCRIPTOR dummySecurityDescriptorLow; |
| 115 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDD
L_REVISION_1, &dummySecurityDescriptorLow, 0); | 115 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 | 116 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedDummySecurityDescriptor(stat
ic_cast<SECURITY_DESCRIPTOR*>(dummySecurityDescriptorLow), LocalFree); // Just t
o simplify cleanup |
| 117 BOOL saclPresent = FALSE; | 117 BOOL saclPresent = FALSE; |
| 118 BOOL saclDefaulted = FALSE; | 118 BOOL saclDefaulted = FALSE; |
| 119 PACL sacl; | 119 PACL sacl; |
| 120 GetSecurityDescriptorSacl(dummySecurityDescriptorLow, &saclPresent, &sacl, &
saclDefaulted); | 120 GetSecurityDescriptorSacl(dummySecurityDescriptorLow, &saclPresent, &sacl, &
saclDefaulted); |
| 121 if (saclPresent) | 121 if (saclPresent) |
| 122 { | 122 { |
| 123 if (!SetSecurityDescriptorSacl(securityDescriptor.get(), TRUE, sacl, FALSE
)) | 123 if (!SetSecurityDescriptorSacl(securityDescriptor.get(), TRUE, sacl, FALSE
)) |
| 124 { | 124 { |
| 125 DWORD err = GetLastError(); | 125 DWORD err = GetLastError(); |
| 126 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 126 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
| 127 } | 127 } |
| 128 } | 128 } |
| 129 | 129 |
| 130 return securityDescriptor; | 130 return securityDescriptor; |
| 131 } | 131 } |
| 132 } | 132 } |
| 133 | 133 |
| 134 // Releases the DACL structure in the provided security descriptor |
| 135 void ReleaseDacl(PSECURITY_DESCRIPTOR securityDescriptor) |
| 136 { |
| 137 BOOL aclPresent = FALSE; |
| 138 BOOL aclDefaulted = FALSE; |
| 139 PACL acl; |
| 140 GetSecurityDescriptorDacl(securityDescriptor, &aclPresent, &acl, &aclDefault
ed); |
| 141 if (aclPresent) |
| 142 { |
| 143 LocalFree(acl); |
| 144 } |
| 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 { |
| 138 if (!hasType) | 150 if (!hasType) |
| 139 ReadBinary(currentType); | 151 ReadBinary(currentType); |
| 140 | 152 |
| 141 if (currentType != expectedType) | 153 if (currentType != expectedType) |
| 142 { | 154 { |
| 143 // Make sure we don't attempt to read the type again | 155 // Make sure we don't attempt to read the type again |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod
e mode) | 187 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod
e mode) |
| 176 { | 188 { |
| 177 pipe = INVALID_HANDLE_VALUE; | 189 pipe = INVALID_HANDLE_VALUE; |
| 178 if (mode == MODE_CREATE) | 190 if (mode == MODE_CREATE) |
| 179 { | 191 { |
| 180 SECURITY_ATTRIBUTES securityAttributes = {}; | 192 SECURITY_ATTRIBUTES securityAttributes = {}; |
| 181 securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); | 193 securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); |
| 182 securityAttributes.bInheritHandle = TRUE; | 194 securityAttributes.bInheritHandle = TRUE; |
| 183 | 195 |
| 184 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedSecurityDescriptor; // Just
to simplify cleanup | 196 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedSecurityDescriptor; // Just
to simplify cleanup |
| 185 | 197 |
| 186 AutoHandle token; | 198 AutoHandle token; |
| 187 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, token); | 199 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, token); |
| 188 | 200 |
| 189 if (IsWindowsVistaOrLater()) | 201 if (IsWindowsVistaOrLater()) |
| 190 { | 202 { |
| 191 std::auto_ptr<SID> logonSid = GetLogonSid(token); | 203 std::auto_ptr<SID> logonSid = GetLogonSid(token); |
| 192 // Create a SECURITY_DESCRIPTOR that has both Low Integrity and allows acc
ess to all AppContainers | 204 // 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) | 205 // This is needed since IE likes to jump out of Enhanced Protected Mode fo
r specific pages (bing.com) |
| 206 |
| 207 // ATTENTION: DACL in the returned securityDescriptor has to be manually r
eleased by ReleaseDacl |
| 194 std::auto_ptr<SECURITY_DESCRIPTOR> securityDescriptor = CreateSecurityDesc
riptor(logonSid.get()); | 208 std::auto_ptr<SECURITY_DESCRIPTOR> securityDescriptor = CreateSecurityDesc
riptor(logonSid.get()); |
| 209 |
| 195 securityAttributes.lpSecurityDescriptor = securityDescriptor.release(); | 210 securityAttributes.lpSecurityDescriptor = securityDescriptor.release(); |
| 196 sharedSecurityDescriptor.reset(static_cast<SECURITY_DESCRIPTOR*>(securityA
ttributes.lpSecurityDescriptor)); | 211 sharedSecurityDescriptor.reset(static_cast<SECURITY_DESCRIPTOR*>(securityA
ttributes.lpSecurityDescriptor)); |
| 197 } | 212 } |
| 198 pipe = CreateNamedPipeW(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MES
SAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, | 213 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); | 214 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &securityAttributes); |
| 215 |
| 216 if (IsWindowsVistaOrLater()) |
| 217 { |
| 218 ReleaseDacl(securityAttributes.lpSecurityDescriptor); |
| 219 } |
| 200 } | 220 } |
| 201 else | 221 else |
| 202 { | 222 { |
| 203 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPE
N_EXISTING, 0, 0); | 223 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) | 224 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) |
| 205 { | 225 { |
| 206 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) | 226 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) |
| 207 throw PipeBusyError(); | 227 throw PipeBusyError(); |
| 208 | 228 |
| 209 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O
PEN_EXISTING, 0, 0); | 229 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O
PEN_EXISTING, 0, 0); |
| 210 } | 230 } |
| 211 } | 231 } |
| 212 | 232 |
| 213 if (pipe == INVALID_HANDLE_VALUE) | 233 if (pipe == INVALID_HANDLE_VALUE) |
| 214 throw PipeConnectionError(); | 234 throw PipeConnectionError(); |
| 215 | 235 |
| 216 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; | 236 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; |
| 217 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) | 237 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) |
| 218 throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastE
rror()); | 238 throw std::runtime_error(AppendErrorCode("SetNamedPipeHandleState failed")); |
| 219 | 239 |
| 220 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) | 240 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) |
| 221 { | 241 { |
| 222 DWORD err = GetLastError(); | 242 DWORD err = GetLastError(); |
| 223 throw std::runtime_error("Client failed to connect: error " + GetLastError()
); | 243 throw std::runtime_error(AppendErrorCode("Client failed to connect")); |
| 224 } | 244 } |
| 225 } | 245 } |
| 226 | 246 |
| 227 Communication::Pipe::~Pipe() | 247 Communication::Pipe::~Pipe() |
| 228 { | 248 { |
| 229 CloseHandle(pipe); | 249 CloseHandle(pipe); |
| 230 } | 250 } |
| 231 | 251 |
| 232 Communication::InputBuffer Communication::Pipe::ReadMessage() | 252 Communication::InputBuffer Communication::Pipe::ReadMessage() |
| 233 { | 253 { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 259 return Communication::InputBuffer(stream.str()); | 279 return Communication::InputBuffer(stream.str()); |
| 260 } | 280 } |
| 261 | 281 |
| 262 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) | 282 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) |
| 263 { | 283 { |
| 264 DWORD bytesWritten; | 284 DWORD bytesWritten; |
| 265 std::string data = message.Get(); | 285 std::string data = message.Get(); |
| 266 if (!WriteFile(pipe, data.c_str(), static_cast<DWORD>(data.length()), &bytesWr
itten, 0)) | 286 if (!WriteFile(pipe, data.c_str(), static_cast<DWORD>(data.length()), &bytesWr
itten, 0)) |
| 267 throw std::runtime_error("Failed to write to pipe"); | 287 throw std::runtime_error("Failed to write to pipe"); |
| 268 } | 288 } |
| OLD | NEW |