Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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 | |
Felix Dahlke
2014/07/03 13:38:07
I don't really understand, it has to be released a
Oleksandr
2014/07/03 13:51:49
1. This allocates a new ACL, so it has to be relea
Felix Dahlke
2014/07/03 13:56:33
The comment is on top of "SetEntries", so I presum
| |
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. |
Felix Dahlke
2014/07/03 13:38:07
I think this is not necessary, the official docs s
Oleksandr
2014/07/03 13:51:49
I don't really understand your point here. Could y
Felix Dahlke
2014/07/03 13:56:33
My point is that the Microsoft documentation says
Oleksandr
2014/07/15 14:16:55
This comment is quite important, IMHO. It's pretty
Felix Dahlke
2014/07/16 14:40:03
Alright.
| |
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 referen ce its SACL in ours |
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(0), saclSize(0), daclSize(0), ownerSize(0), primaryGroupSize(0) ; |
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) |
119 if (saclPresent) | 120 { |
120 { | |
121 if (!SetSecurityDescriptorSacl(securityDescriptor.get(), TRUE, sacl, FALSE )) | |
122 { | |
123 DWORD err = GetLastError(); | |
124 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); | 121 return std::auto_ptr<SECURITY_DESCRIPTOR>(0); |
125 } | 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); | |
126 } | 140 } |
127 | 141 |
128 return securityDescriptor; | 142 return securityDescriptor; |
129 } | 143 } |
130 } | 144 } |
131 | 145 |
132 // Releases the DACL structure in the provided security descriptor | |
Felix Dahlke
2014/07/03 13:38:07
I think the function name communicates this quite
| |
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(); | 146 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName(); |
145 | 147 |
146 void Communication::InputBuffer::CheckType(Communication::ValueType expectedType ) | 148 void Communication::InputBuffer::CheckType(Communication::ValueType expectedType ) |
147 { | 149 { |
148 if (!hasType) | 150 if (!hasType) |
149 ReadBinary(currentType); | 151 ReadBinary(currentType); |
150 | 152 |
151 if (currentType != expectedType) | 153 if (currentType != expectedType) |
152 { | 154 { |
153 // Make sure we don't attempt to read the type again | 155 // Make sure we don't attempt to read the type again |
(...skipping 21 matching lines...) Expand all Loading... | |
175 Communication::PipeBusyError::PipeBusyError() | 177 Communication::PipeBusyError::PipeBusyError() |
176 : 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") |
177 { | 179 { |
178 } | 180 } |
179 | 181 |
180 Communication::PipeDisconnectedError::PipeDisconnectedError() | 182 Communication::PipeDisconnectedError::PipeDisconnectedError() |
181 : std::runtime_error("Pipe disconnected") | 183 : std::runtime_error("Pipe disconnected") |
182 { | 184 { |
183 } | 185 } |
184 | 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 | |
185 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) |
186 { | 209 { |
187 pipe = INVALID_HANDLE_VALUE; | 210 pipe = INVALID_HANDLE_VALUE; |
188 if (mode == MODE_CREATE) | 211 if (mode == MODE_CREATE) |
189 { | 212 { |
190 SECURITY_ATTRIBUTES securityAttributes = {}; | 213 SECURITY_ATTRIBUTES securityAttributes = {}; |
191 securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); | 214 securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); |
192 securityAttributes.bInheritHandle = TRUE; | 215 securityAttributes.bInheritHandle = TRUE; |
193 | 216 |
194 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedSecurityDescriptor; // Just to simplify cleanup | 217 std::tr1::shared_ptr<SECURITY_DESCRIPTOR> sharedSecurityDescriptor; // Just to simplify cleanup |
195 | |
Felix Dahlke
2014/07/03 13:38:07
Whitespace change?
| |
196 AutoHandle token; | 218 AutoHandle token; |
197 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, token); | 219 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, token); |
198 | 220 |
199 if (IsWindowsVistaOrLater()) | 221 if (IsWindowsVistaOrLater()) |
200 { | 222 { |
201 std::auto_ptr<SID> logonSid = GetLogonSid(token); | 223 std::auto_ptr<SID> logonSid = GetLogonSid(token); |
202 // 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 |
203 // 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) |
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()); | 226 std::auto_ptr<SECURITY_DESCRIPTOR> securityDescriptor = CreateSecurityDesc riptor(logonSid.get()); |
207 | 227 |
208 securityAttributes.lpSecurityDescriptor = securityDescriptor.release(); | 228 securityAttributes.lpSecurityDescriptor = securityDescriptor.release(); |
209 sharedSecurityDescriptor.reset(static_cast<SECURITY_DESCRIPTOR*>(securityA ttributes.lpSecurityDescriptor)); | 229 sharedSecurityDescriptor.reset(static_cast<SECURITY_DESCRIPTOR*>(securityA ttributes.lpSecurityDescriptor), FreeAbsoluteSecurityDescriptor); |
210 } | 230 } |
211 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, |
212 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &securityAttributes); | 232 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &securityAttributes); |
213 | |
214 if (IsWindowsVistaOrLater()) | |
215 { | |
216 ReleaseDacl(securityAttributes.lpSecurityDescriptor); | |
Felix Dahlke
2014/07/03 13:38:07
Wouldn't it'd be cleaner to put this in a custom f
| |
217 } | |
218 } | 233 } |
219 else | 234 else |
220 { | 235 { |
221 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); |
222 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) | 237 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) |
223 { | 238 { |
224 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) | 239 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) |
225 throw PipeBusyError(); | 240 throw PipeBusyError(); |
226 | 241 |
227 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); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
277 return Communication::InputBuffer(stream.str()); | 292 return Communication::InputBuffer(stream.str()); |
278 } | 293 } |
279 | 294 |
280 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) | 295 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) |
281 { | 296 { |
282 DWORD bytesWritten; | 297 DWORD bytesWritten; |
283 std::string data = message.Get(); | 298 std::string data = message.Get(); |
284 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)) |
285 throw std::runtime_error("Failed to write to pipe"); | 300 throw std::runtime_error("Failed to write to pipe"); |
286 } | 301 } |
LEFT | RIGHT |