Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/shared/Communication.cpp

Issue 11756012: Enhanced Protected Mode support (Closed)
Patch Set: Addressing comments Created Sept. 17, 2013, 2:51 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« src/shared/Communication.h ('K') | « src/shared/Communication.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #include <Windows.h> 1 #include <Windows.h>
Wladimir Palant 2013/09/17 07:53:48 From what I can tell, none of my comments in this
2 #include <Lmcons.h> 2 #include <Lmcons.h>
3 #include <Sddl.h> 3 #include <Sddl.h>
4 #include <aclapi.h>
5 #include <strsafe.h>
4 6
5 #include "Communication.h" 7 #include "Communication.h"
6 #include "Utils.h" 8 #include "Utils.h"
7 9
10 #ifndef SECURITY_APP_PACKAGE_AUTHORITY
11 #define SECURITY_APP_PACKAGE_AUTHORITY {0,0,0,0,0,15}
12 #endif
13
14 std::wstring Communication::browserSID;
15
8 namespace 16 namespace
9 { 17 {
10 const int bufferSize = 1024; 18 const int bufferSize = 1024;
11 19
12 std::string AppendErrorCode(const std::string& message) 20 std::string AppendErrorCode(const std::string& message)
13 { 21 {
14 std::stringstream stream; 22 std::stringstream stream;
15 stream << message << " (Error code: " << GetLastError() << ")"; 23 stream << message << " (Error code: " << GetLastError() << ")";
16 return stream.str(); 24 return stream.str();
17 } 25 }
18 26
19 std::wstring GetUserName() 27 std::wstring GetUserName()
20 { 28 {
21 const DWORD maxLength = UNLEN + 1; 29 const DWORD maxLength = UNLEN + 1;
22 std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]); 30 std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]);
23 DWORD length = maxLength; 31 DWORD length = maxLength;
24 if (!::GetUserNameW(buffer.get(), &length)) 32 if (!::GetUserNameW(buffer.get(), &length))
25 throw std::runtime_error(AppendErrorCode("Failed to get the current user's name")); 33 throw std::runtime_error(AppendErrorCode("Failed to get the current user's name"));
26 return std::wstring(buffer.get(), length); 34 return std::wstring(buffer.get(), length);
27 } 35 }
36
37 // See http://msdn.microsoft.com/en-us/library/windows/desktop/hh448493(v=vs.8 5).aspx
38 bool GetLogonSid (HANDLE hToken, PSID *ppsid)
39 {
40 if (ppsid == NULL)
41 return false;
42
43 // Get required buffer size and allocate the TOKEN_GROUPS buffer.
44 DWORD dwLength = 0;
45 PTOKEN_GROUPS ptg = NULL;
46 if (!GetTokenInformation(hToken, TokenLogonSid, ptg, 0, &dwLength))
47 {
48 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
49 return false;
50
51 ptg = (PTOKEN_GROUPS) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLeng th);
52
53 if (ptg == NULL)
54 return false;
55 }
56
57 // Get the token group information from the access token.
58 if (!GetTokenInformation(hToken, TokenLogonSid, ptg, dwLength, &dwLength) || ptg->GroupCount != 1)
59 {
60 HeapFree(GetProcessHeap(), 0, ptg);
61 return false;
62 }
63
64 // Found the logon SID; make a copy of it.
65 dwLength = GetLengthSid(ptg->Groups[0].Sid);
66 *ppsid = (PSID) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
67 if (*ppsid == NULL)
68 {
69 HeapFree(GetProcessHeap(), 0, ptg);
70 return false;
71 }
72 if (!CopySid(dwLength, *ppsid, ptg->Groups[0].Sid))
73 {
74 HeapFree(GetProcessHeap(), 0, ptg);
75 HeapFree(GetProcessHeap(), 0, *ppsid);
76 return false;
77 }
78
79 HeapFree(GetProcessHeap(), 0, ptg);
80 return true;
81 }
82
83 bool CreateObjectSecurityDescriptor(PSID pLogonSid, PSECURITY_DESCRIPTOR* ppSD )
84 {
85 BOOL bSuccess = FALSE;
86 DWORD dwRes;
87 PSID pBrowserSID = NULL;
88 PACL pACL = NULL;
89 PSECURITY_DESCRIPTOR pSD = NULL;
90 EXPLICIT_ACCESS ea[2];
91 SID_IDENTIFIER_AUTHORITY ApplicationAuthority = SECURITY_APP_PACKAGE_AUTHORI TY;
92
93 ConvertStringSidToSid(Communication::browserSID.c_str(), &pBrowserSID);
94
95 // Initialize an EXPLICIT_ACCESS structure for an ACE.
96 // The ACE will allow LogonSid generic all access
97 ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
98 ea[0].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
99 ea[0].grfAccessMode = SET_ACCESS;
100 ea[0].grfInheritance= NO_INHERITANCE;
101 ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
102 ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
103 ea[0].Trustee.ptstrName = (LPTSTR) pLogonSid;
104
105 // Initialize an EXPLICIT_ACCESS structure for an ACE.
106 // The ACE will give the browser SID all permissions
107 ea[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
108 ea[1].grfAccessMode = SET_ACCESS;
109 ea[1].grfInheritance= NO_INHERITANCE;
110 ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
111 ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
112 ea[1].Trustee.ptstrName = (LPTSTR) pBrowserSID;
113
114 // Create a new ACL that contains the new ACEs.
115 dwRes = SetEntriesInAcl(2, ea, NULL, &pACL);
116 if (ERROR_SUCCESS != dwRes)
117 {
118 FreeSid(pBrowserSID);
119 return false;
120 }
121
122 // Initialize a security descriptor.
123 pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH );
124 if (NULL == pSD)
125 {
126 FreeSid(pBrowserSID);
127 LocalFree(pACL);
128 return false;;
129 }
130
131 if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
132 {
133 FreeSid(pBrowserSID);
134 LocalFree(pACL);
135 LocalFree((LPVOID)pSD);
136 return false;
137 }
138
139 // Add the ACL to the security descriptor.
140 if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) // not a default D ACL
141 {
142 FreeSid(pBrowserSID);
143 LocalFree(pACL);
144 LocalFree((LPVOID)pSD);
145 return false;
146 }
147
148 *ppSD = pSD;
149 pSD = NULL;
150
151 if (pBrowserSID)
152 FreeSid(pBrowserSID);
153 if (pACL)
154 LocalFree(pACL);
155
156 return true;
157 }
158
159
28 } 160 }
29 161
30 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName(); 162 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName();
31 163
32 void Communication::InputBuffer::CheckType(Communication::ValueType expectedType ) 164 void Communication::InputBuffer::CheckType(Communication::ValueType expectedType )
33 { 165 {
34 if (!hasType) 166 if (!hasType)
35 ReadBinary(currentType); 167 ReadBinary(currentType);
36 168
37 if (currentType != expectedType) 169 if (currentType != expectedType)
(...skipping 22 matching lines...) Expand all
60 192
61 Communication::PipeBusyError::PipeBusyError() 193 Communication::PipeBusyError::PipeBusyError()
62 : std::runtime_error("Timeout while trying to connect to a named pipe, pipe is busy") 194 : std::runtime_error("Timeout while trying to connect to a named pipe, pipe is busy")
63 { 195 {
64 } 196 }
65 197
66 Communication::PipeDisconnectedError::PipeDisconnectedError() 198 Communication::PipeDisconnectedError::PipeDisconnectedError()
67 : std::runtime_error("Pipe disconnected") 199 : std::runtime_error("Pipe disconnected")
68 { 200 {
69 } 201 }
70
71 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod e mode) 202 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod e mode)
Wladimir Palant 2013/09/17 07:53:48 Not addressed: the empty line before this function
72 { 203 {
73 pipe = INVALID_HANDLE_VALUE; 204 pipe = INVALID_HANDLE_VALUE;
74 if (mode == MODE_CREATE) 205 if (mode == MODE_CREATE)
75 { 206 {
76 SECURITY_ATTRIBUTES sa; 207 SECURITY_ATTRIBUTES sa;
77 memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); 208 memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
78 sa.nLength = sizeof(SECURITY_ATTRIBUTES); 209 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
79 210
80 PSECURITY_DESCRIPTOR securitydescriptor; 211 HANDLE hToken = NULL;
81 if (IsWindowsVistaOrLater()) 212 OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken);
213
214 if (browserSID.empty())
82 { 215 {
83 // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb6259 58.aspx 216 if (IsWindowsVistaOrLater())
84 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; 217 {
85 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, S DDL_REVISION_1, &securitydescriptor, 0); 218 // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb62 5958.aspx
86 sa.lpSecurityDescriptor = securitydescriptor; 219 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)";
220 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDDL_REVISION_1, &securitydescriptor, 0);
221 sa.lpSecurityDescriptor = securitydescriptor;
222 }
223
224 sa.bInheritHandle = TRUE;
87 } 225 }
88 226 else // IE is in AppContainer
89 sa.bInheritHandle = TRUE;
90
91 pipe = CreateNamedPipeW (pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MES SAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
92 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSi ze, 0, &sa);
93 if (IsWindowsVistaOrLater() && securitydescriptor)
94 { 227 {
95 LocalFree(securitydescriptor); 228 PSID pLogonSid = NULL;
229 //Allowing LogonSid and IE's appcontainer.
230 if (GetLogonSid(hToken, &pLogonSid) && CreateObjectSecurityDescriptor(pLog onSid, &securitydescriptor) )
231 {
232 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
233 sa.bInheritHandle = TRUE;
234 sa.lpSecurityDescriptor = securitydescriptor;
235 }
96 } 236 }
97 } 237 pipe = CreateNamedPipe(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESS AGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
238 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &sa);
239 }
98 else 240 else
99 { 241 {
100 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPE N_EXISTING, 0, 0); 242 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPE N_EXISTING, 0, 0);
101 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) 243 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY)
102 { 244 {
103 if (!WaitNamedPipeW(pipeName.c_str(), 10000)) 245 if (!WaitNamedPipeW(pipeName.c_str(), 10000))
104 throw PipeBusyError(); 246 throw PipeBusyError();
105 247
106 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O PEN_EXISTING, 0, 0); 248 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O PEN_EXISTING, 0, 0);
107 } 249 }
108 } 250 }
109 251
110 if (pipe == INVALID_HANDLE_VALUE) 252 if (pipe == INVALID_HANDLE_VALUE)
111 throw PipeConnectionError(); 253 throw PipeConnectionError();
112 254
113 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; 255 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT;
114 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) 256 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0))
115 throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastE rror()); 257 throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastE rror());
116 258
117 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) 259 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0))
118 throw std::runtime_error("Client failed to connect: error " + GetLastError() ); 260 throw std::runtime_error("Client failed to connect: error " + GetLastError() );
119 } 261 }
120 262
121 Communication::Pipe::~Pipe() 263 Communication::Pipe::~Pipe()
122 { 264 {
123 CloseHandle(pipe); 265 CloseHandle(pipe);
266 if (securitydescriptor)
267 LocalFree(securitydescriptor);
268
124 } 269 }
125 270
126 Communication::InputBuffer Communication::Pipe::ReadMessage() 271 Communication::InputBuffer Communication::Pipe::ReadMessage()
127 { 272 {
128 std::stringstream stream; 273 std::stringstream stream;
129 std::auto_ptr<char> buffer(new char[bufferSize]); 274 std::auto_ptr<char> buffer(new char[bufferSize]);
130 bool doneReading = false; 275 bool doneReading = false;
131 while (!doneReading) 276 while (!doneReading)
132 { 277 {
133 DWORD bytesRead; 278 DWORD bytesRead;
(...skipping 19 matching lines...) Expand all
153 return Communication::InputBuffer(stream.str()); 298 return Communication::InputBuffer(stream.str());
154 } 299 }
155 300
156 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) 301 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message)
157 { 302 {
158 DWORD bytesWritten; 303 DWORD bytesWritten;
159 std::string data = message.Get(); 304 std::string data = message.Get();
160 if (!WriteFile(pipe, data.c_str(), static_cast<DWORD>(data.length()), &bytesWr itten, 0)) 305 if (!WriteFile(pipe, data.c_str(), static_cast<DWORD>(data.length()), &bytesWr itten, 0))
161 throw std::runtime_error("Failed to write to pipe"); 306 throw std::runtime_error("Failed to write to pipe");
162 } 307 }
OLDNEW
« src/shared/Communication.h ('K') | « src/shared/Communication.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld