| Left: | ||
| Right: | 
| 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 90 &allAppContainersSid); | 90 &allAppContainersSid); | 
| 91 std::tr1::shared_ptr<SID> sharedAllAppContainersSid(static_cast<SID*>(allA ppContainersSid), FreeSid); // Just to simplify cleanup | 91 std::tr1::shared_ptr<SID> sharedAllAppContainersSid(static_cast<SID*>(allA ppContainersSid), FreeSid); // Just to simplify cleanup | 
| 92 | 92 | 
| 93 explicitAccess[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RI GHTS_ALL; | 93 explicitAccess[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RI GHTS_ALL; | 
| 94 explicitAccess[1].grfAccessMode = SET_ACCESS; | 94 explicitAccess[1].grfAccessMode = SET_ACCESS; | 
| 95 explicitAccess[1].grfInheritance= NO_INHERITANCE; | 95 explicitAccess[1].grfInheritance= NO_INHERITANCE; | 
| 96 explicitAccess[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; | 96 explicitAccess[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; | 
| 97 explicitAccess[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; | 97 explicitAccess[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; | 
| 98 explicitAccess[1].Trustee.ptstrName = static_cast<LPWSTR>(allAppContainers Sid); | 98 explicitAccess[1].Trustee.ptstrName = static_cast<LPWSTR>(allAppContainers Sid); | 
| 99 | 99 | 
| 100 // Will be released later | |
| 100 PACL acl = 0; | 101 PACL acl = 0; | 
| 101 // acl has to be released after this | |
| 102 if (SetEntriesInAcl(2, explicitAccess, 0, &acl) != ERROR_SUCCESS) | 102 if (SetEntriesInAcl(2, explicitAccess, 0, &acl) != ERROR_SUCCESS) | 
| 103 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 103 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 
| 104 | 104 | 
| 105 // This only references the acl, not copies it | 105 // NOTE: This only references the acl, not copies it. | 
| 106 // DO NOT release the ACL before it's actually used | |
| 106 if (!SetSecurityDescriptorDacl(securityDescriptor.get(), TRUE, acl, FALSE) ) | 107 if (!SetSecurityDescriptorDacl(securityDescriptor.get(), TRUE, acl, FALSE) ) | 
| 107 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 108 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 
| 108 } | 109 } | 
| 109 | 110 | 
| 110 // 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 | 
| 
 
Felix Dahlke
2014/07/16 14:40:03
s/refference/reference/
 
Oleksandr
2014/07/17 17:32:48
Um. Refference is meant to be a verb here. 
On 201
 
Felix Dahlke
2014/07/18 12:40:57
But it's still one f too many! :)
 
Oleksandr
2014/07/18 12:48:34
Oh. Totally missread your correction. 
On 2014/07/
 
 | |
| 111 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; | 112 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; | 
| 112 PSECURITY_DESCRIPTOR dummySecurityDescriptorLow; | 113 PSECURITY_DESCRIPTOR dummySecurityDescriptorLow; | 
| 113 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDD L_REVISION_1, &dummySecurityDescriptorLow, 0); | 114 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDD L_REVISION_1, &dummySecurityDescriptorLow, 0); | 
| 114 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 | 
| 115 BOOL saclPresent = FALSE; | 116 | 
| 116 BOOL saclDefaulted = FALSE; | 117 DWORD sdSize, saclSize, daclSize, ownerSize, primaryGroupSize; | 
| 
 
Felix Dahlke
2014/07/16 14:40:03
Shouldn't we initialise all the sizes to 0 here? S
 
 | |
| 117 PACL sacl; | 118 MakeAbsoluteSD(dummySecurityDescriptorLow, 0, &sdSize, 0, &daclSize, 0, &sac lSize, 0, &ownerSize, 0, &primaryGroupSize); | 
| 118 GetSecurityDescriptorSacl(dummySecurityDescriptorLow, &saclPresent, &sacl, & saclDefaulted); | 119 if ((saclSize == 0) || (sdSize == 0)) | 
| 
 
Felix Dahlke
2014/07/16 14:40:03
Redundant parentheses around both comparisons.
 
 | |
| 119 if (saclPresent) | |
| 120 { | 120 { | 
| 121 if (!SetSecurityDescriptorSacl(securityDescriptor.get(), TRUE, sacl, FALSE )) | |
| 122 { | |
| 123 DWORD err = GetLastError(); | 121 DWORD err = GetLastError(); | 
| 
 
Felix Dahlke
2014/07/16 14:40:03
Unused variable.
 
 | |
| 124 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 122 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 
| 125 } | 123 } | 
| 124 // Will be released later | |
| 125 PACL sacl = (PACL) new byte[saclSize]; | |
| 
 
Felix Dahlke
2014/07/16 14:40:03
I'd actually find malloc more intuitive here. byte
 
 | |
| 126 std::auto_ptr<SECURITY_DESCRIPTOR> absoluteDummySecurityDescriptorLow((SECUR ITY_DESCRIPTOR*) new byte[sdSize]); | |
| 127 daclSize = 0; | |
| 128 ownerSize = 0; | |
| 129 primaryGroupSize = 0; | |
| 130 BOOL res = MakeAbsoluteSD(dummySecurityDescriptorLow, absoluteDummySecurityD escriptorLow.get(), &sdSize, 0, &daclSize, sacl, &saclSize, 0, &ownerSize, 0, &p rimaryGroupSize); | |
| 131 if ((res == 0) || (absoluteDummySecurityDescriptorLow.get() == 0) || (saclSi ze == 0)) | |
| 
 
Felix Dahlke
2014/07/16 14:40:03
Redundant parentheses here as well.
Also, !res wo
 
 | |
| 132 { | |
| 133 DWORD err = GetLastError(); | |
| 
 
Felix Dahlke
2014/07/16 14:40:03
Also unused.
 
 | |
| 134 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | |
| 135 } | |
| 136 | |
| 137 // NOTE: This only references the acl, not copies it. | |
| 138 // DO NOT release the ACL before it's actually used | |
| 139 if (!SetSecurityDescriptorSacl(securityDescriptor.get(), TRUE, sacl, FALSE)) | |
| 140 { | |
| 141 DWORD err = GetLastError(); | |
| 142 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | |
| 126 } | 143 } | 
| 127 | 144 | 
| 128 return securityDescriptor; | 145 return securityDescriptor; | 
| 129 } | 146 } | 
| 130 } | 147 } | 
| 131 | 148 | 
| 132 // Releases the DACL structure in the provided security descriptor | |
| 133 void ReleaseDacl(PSECURITY_DESCRIPTOR securityDescriptor) | |
| 134 { | |
| 135 BOOL aclPresent = FALSE; | |
| 136 BOOL aclDefaulted = FALSE; | |
| 137 PACL acl; | |
| 138 GetSecurityDescriptorDacl(securityDescriptor, &aclPresent, &acl, &aclDefault ed); | |
| 139 if (aclPresent) | |
| 140 { | |
| 141 LocalFree(acl); | |
| 142 } | |
| 143 } | |
| 144 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName(); | 149 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName(); | 
| 145 | 150 | 
| 146 void Communication::InputBuffer::CheckType(Communication::ValueType expectedType ) | 151 void Communication::InputBuffer::CheckType(Communication::ValueType expectedType ) | 
| 147 { | 152 { | 
| 148 if (!hasType) | 153 if (!hasType) | 
| 149 ReadBinary(currentType); | 154 ReadBinary(currentType); | 
| 150 | 155 | 
| 151 if (currentType != expectedType) | 156 if (currentType != expectedType) | 
| 152 { | 157 { | 
| 153 // Make sure we don't attempt to read the type again | 158 // Make sure we don't attempt to read the type again | 
| (...skipping 21 matching lines...) Expand all Loading... | |
| 175 Communication::PipeBusyError::PipeBusyError() | 180 Communication::PipeBusyError::PipeBusyError() | 
| 176 : std::runtime_error("Timeout while trying to connect to a named pipe, pipe is busy") | 181 : std::runtime_error("Timeout while trying to connect to a named pipe, pipe is busy") | 
| 177 { | 182 { | 
| 178 } | 183 } | 
| 179 | 184 | 
| 180 Communication::PipeDisconnectedError::PipeDisconnectedError() | 185 Communication::PipeDisconnectedError::PipeDisconnectedError() | 
| 181 : std::runtime_error("Pipe disconnected") | 186 : std::runtime_error("Pipe disconnected") | 
| 182 { | 187 { | 
| 183 } | 188 } | 
| 184 | 189 | 
| 190 void FreeAbsoluteSecurityDescriptor(SECURITY_DESCRIPTOR* securityDescriptor) | |
| 191 { | |
| 192 BOOL aclPresent = FALSE; | |
| 193 BOOL aclDefaulted = FALSE; | |
| 194 PACL acl = 0; | |
| 195 GetSecurityDescriptorDacl(securityDescriptor, &aclPresent, &acl, &aclDefaulted ); | |
| 196 if (aclPresent) | |
| 197 { | |
| 198 LocalFree(acl); | |
| 199 } | |
| 200 aclPresent = FALSE; | |
| 201 aclDefaulted = false; | |
| 
 
Felix Dahlke
2014/07/16 14:40:03
Should also be that Windows FALSE macro for consis
 
 | |
| 202 acl = 0; | |
| 203 GetSecurityDescriptorSacl(securityDescriptor, &aclPresent, &acl, &aclDefaulted ); | |
| 204 if (aclPresent) | |
| 205 { | |
| 206 delete acl; | |
| 
 
Felix Dahlke
2014/07/16 14:40:03
You need to use delete[], since it was allocated u
 
 | |
| 207 } | |
| 208 delete securityDescriptor; | |
| 209 } | |
| 210 | |
| 185 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod e mode) | 211 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod e mode) | 
| 186 { | 212 { | 
| 187 pipe = INVALID_HANDLE_VALUE; | 213 pipe = INVALID_HANDLE_VALUE; | 
| 188 if (mode == MODE_CREATE) | 214 if (mode == MODE_CREATE) | 
| 189 { | 215 { | 
| 190 SECURITY_ATTRIBUTES securityAttributes = {}; | 216 SECURITY_ATTRIBUTES securityAttributes = {}; | 
| 191 securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); | 217 securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); | 
| 192 securityAttributes.bInheritHandle = TRUE; | 218 securityAttributes.bInheritHandle = TRUE; | 
| 193 | 219 | 
| 194 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedSecurityDescriptor; // Just to simplify cleanup | 220 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedSecurityDescriptor; // Just to simplify cleanup | 
| 195 | |
| 196 AutoHandle token; | 221 AutoHandle token; | 
| 197 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, token); | 222 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, token); | 
| 198 | 223 | 
| 199 if (IsWindowsVistaOrLater()) | 224 if (IsWindowsVistaOrLater()) | 
| 200 { | 225 { | 
| 201 std::auto_ptr<SID> logonSid = GetLogonSid(token); | 226 std::auto_ptr<SID> logonSid = GetLogonSid(token); | 
| 202 // Create a SECURITY_DESCRIPTOR that has both Low Integrity and allows acc ess to all AppContainers | 227 // Create a SECURITY_DESCRIPTOR that has both Low Integrity and allows acc ess to all AppContainers | 
| 203 // This is needed since IE likes to jump out of Enhanced Protected Mode fo r specific pages (bing.com) | 228 // This is needed since IE likes to jump out of Enhanced Protected Mode fo r specific pages (bing.com) | 
| 204 | |
| 205 // ATTENTION: DACL in the returned securityDescriptor has to be manually r eleased by ReleaseDacl | |
| 206 std::auto_ptr<SECURITY_DESCRIPTOR> securityDescriptor = CreateSecurityDesc riptor(logonSid.get()); | 229 std::auto_ptr<SECURITY_DESCRIPTOR> securityDescriptor = CreateSecurityDesc riptor(logonSid.get()); | 
| 207 | 230 | 
| 208 securityAttributes.lpSecurityDescriptor = securityDescriptor.release(); | 231 securityAttributes.lpSecurityDescriptor = securityDescriptor.release(); | 
| 209 sharedSecurityDescriptor.reset(static_cast<SECURITY_DESCRIPTOR*>(securityA ttributes.lpSecurityDescriptor)); | 232 sharedSecurityDescriptor.reset(static_cast<SECURITY_DESCRIPTOR*>(securityA ttributes.lpSecurityDescriptor), FreeAbsoluteSecurityDescriptor); | 
| 210 } | 233 } | 
| 211 pipe = CreateNamedPipeW(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MES SAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, | 234 pipe = CreateNamedPipeW(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MES SAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, | 
| 212 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &securityAttributes); | 235 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &securityAttributes); | 
| 213 | |
| 214 if (IsWindowsVistaOrLater()) | |
| 215 { | |
| 216 ReleaseDacl(securityAttributes.lpSecurityDescriptor); | |
| 217 } | |
| 218 } | 236 } | 
| 219 else | 237 else | 
| 220 { | 238 { | 
| 221 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPE N_EXISTING, 0, 0); | 239 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPE N_EXISTING, 0, 0); | 
| 222 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) | 240 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) | 
| 223 { | 241 { | 
| 224 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) | 242 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) | 
| 225 throw PipeBusyError(); | 243 throw PipeBusyError(); | 
| 226 | 244 | 
| 227 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O PEN_EXISTING, 0, 0); | 245 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O PEN_EXISTING, 0, 0); | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 return Communication::InputBuffer(stream.str()); | 295 return Communication::InputBuffer(stream.str()); | 
| 278 } | 296 } | 
| 279 | 297 | 
| 280 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) | 298 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) | 
| 281 { | 299 { | 
| 282 DWORD bytesWritten; | 300 DWORD bytesWritten; | 
| 283 std::string data = message.Get(); | 301 std::string data = message.Get(); | 
| 284 if (!WriteFile(pipe, data.c_str(), static_cast<DWORD>(data.length()), &bytesWr itten, 0)) | 302 if (!WriteFile(pipe, data.c_str(), static_cast<DWORD>(data.length()), &bytesWr itten, 0)) | 
| 285 throw std::runtime_error("Failed to write to pipe"); | 303 throw std::runtime_error("Failed to write to pipe"); | 
| 286 } | 304 } | 
| OLD | NEW |