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 |