Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / sandbox / win / tests / validation_tests / commands.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <Aclapi.h>
6 #include <windows.h>
7 #include <string>
8
9 #include "sandbox/win/tests/validation_tests/commands.h"
10
11 #include "sandbox/win/tests/common/controller.h"
12
13 namespace {
14
15 // Returns the HKEY corresponding to name. If there is no HKEY corresponding
16 // to the name it returns NULL.
17 HKEY GetHKEYFromString(const base::string16 &name) {
18   if (name == L"HKLM")
19     return HKEY_LOCAL_MACHINE;
20   if (name == L"HKCR")
21     return HKEY_CLASSES_ROOT;
22   if (name == L"HKCC")
23     return HKEY_CURRENT_CONFIG;
24   if (name == L"HKCU")
25     return HKEY_CURRENT_USER;
26   if (name == L"HKU")
27     return HKEY_USERS;
28
29   return NULL;
30 }
31
32 // Modifies string to remove the leading and trailing quotes.
33 void trim_quote(base::string16* string) {
34   base::string16::size_type pos1 = string->find_first_not_of(L'"');
35   base::string16::size_type pos2 = string->find_last_not_of(L'"');
36
37   if (pos1 == base::string16::npos || pos2 == base::string16::npos)
38     string->clear();
39   else
40     (*string) = string->substr(pos1, pos2 + 1);
41 }
42
43 int TestOpenFile(base::string16 path, bool for_write) {
44   wchar_t path_expanded[MAX_PATH + 1] = {0};
45   DWORD size = ::ExpandEnvironmentStrings(path.c_str(), path_expanded,
46                                           MAX_PATH);
47   if (!size)
48     return sandbox::SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
49
50   HANDLE file;
51   file = ::CreateFile(path_expanded,
52                       for_write ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ,
53                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
54                       NULL,  // No security attributes.
55                       OPEN_EXISTING,
56                       FILE_FLAG_BACKUP_SEMANTICS,
57                       NULL);  // No template.
58
59   if (file != INVALID_HANDLE_VALUE) {
60     ::CloseHandle(file);
61     return sandbox::SBOX_TEST_SUCCEEDED;
62   }
63   return (::GetLastError() == ERROR_ACCESS_DENIED) ?
64       sandbox::SBOX_TEST_DENIED : sandbox::SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
65 }
66
67 }  // namespace
68
69 namespace sandbox {
70
71 SBOX_TESTS_COMMAND int ValidWindow(int argc, wchar_t **argv) {
72   return (argc == 1) ?
73       TestValidWindow(
74           reinterpret_cast<HWND>(static_cast<ULONG_PTR>(_wtoi(argv[0])))) :
75       SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
76 }
77
78 int TestValidWindow(HWND window) {
79   return ::IsWindow(window) ? SBOX_TEST_SUCCEEDED : SBOX_TEST_DENIED;
80 }
81
82 SBOX_TESTS_COMMAND int OpenProcessCmd(int argc, wchar_t **argv) {
83   return (argc == 2) ?
84       TestOpenProcess(_wtol(argv[0]), _wtol(argv[1])) :
85       SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
86 }
87
88 int TestOpenProcess(DWORD process_id, DWORD access_mask) {
89   HANDLE process = ::OpenProcess(access_mask,
90                                  FALSE,  // Do not inherit handle.
91                                  process_id);
92   if (process != NULL) {
93     ::CloseHandle(process);
94     return SBOX_TEST_SUCCEEDED;
95   }
96   return (::GetLastError() == ERROR_ACCESS_DENIED) ?
97       sandbox::SBOX_TEST_DENIED : sandbox::SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
98 }
99
100 SBOX_TESTS_COMMAND int OpenThreadCmd(int argc, wchar_t **argv) {
101   return (argc == 1) ?
102       TestOpenThread(_wtoi(argv[0])) : SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
103 }
104
105 int TestOpenThread(DWORD thread_id) {
106   HANDLE thread = ::OpenThread(THREAD_QUERY_INFORMATION,
107                                FALSE,  // Do not inherit handles.
108                                thread_id);
109   if (thread != NULL) {
110     ::CloseHandle(thread);
111     return SBOX_TEST_SUCCEEDED;
112   }
113   return (::GetLastError() == ERROR_ACCESS_DENIED) ?
114       sandbox::SBOX_TEST_DENIED : sandbox::SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
115 }
116
117 SBOX_TESTS_COMMAND int OpenFileCmd(int argc, wchar_t **argv) {
118   if (1 != argc)
119     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
120
121   base::string16 path = argv[0];
122   trim_quote(&path);
123
124   return TestOpenReadFile(path);
125 }
126
127 int TestOpenReadFile(const base::string16& path) {
128   return TestOpenFile(path, false);
129 }
130
131 int TestOpenWriteFile(int argc, wchar_t **argv) {
132   if (argc != 1)
133     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
134
135   base::string16 path = argv[0];
136   trim_quote(&path);
137   return TestOpenWriteFile(path);
138 }
139
140 int TestOpenWriteFile(const base::string16& path) {
141   return TestOpenFile(path, true);
142 }
143
144 SBOX_TESTS_COMMAND int OpenKey(int argc, wchar_t **argv) {
145   if (argc != 1 && argc != 2)
146     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
147
148   // Get the hive.
149   HKEY base_key = GetHKEYFromString(argv[0]);
150
151   // Get the subkey.
152   base::string16 subkey;
153   if (argc == 2) {
154     subkey = argv[1];
155     trim_quote(&subkey);
156   }
157
158   return TestOpenKey(base_key, subkey);
159 }
160
161 int TestOpenKey(HKEY base_key, base::string16 subkey) {
162   HKEY key;
163   LONG err_code = ::RegOpenKeyEx(base_key,
164                                  subkey.c_str(),
165                                  0,  // Reserved, must be 0.
166                                  MAXIMUM_ALLOWED,
167                                  &key);
168   if (err_code == ERROR_SUCCESS) {
169     ::RegCloseKey(key);
170     return SBOX_TEST_SUCCEEDED;
171   }
172   return (err_code == ERROR_INVALID_HANDLE || err_code == ERROR_ACCESS_DENIED) ?
173       SBOX_TEST_DENIED : SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
174 }
175
176 // Returns true if the current's thread desktop is the interactive desktop.
177 // In Vista there is a more direct test but for XP and w2k we need to check
178 // the object name.
179 bool IsInteractiveDesktop(bool* is_interactive) {
180   HDESK current_desk = ::GetThreadDesktop(::GetCurrentThreadId());
181   if (current_desk == NULL)
182     return false;
183   wchar_t current_desk_name[256] = {0};
184   if (!::GetUserObjectInformationW(current_desk, UOI_NAME, current_desk_name,
185                                    sizeof(current_desk_name), NULL))
186     return false;
187   *is_interactive = (0 == _wcsicmp(L"default", current_desk_name));
188   return true;
189 }
190
191 SBOX_TESTS_COMMAND int OpenInteractiveDesktop(int, wchar_t **) {
192   return TestOpenInputDesktop();
193 }
194
195 int TestOpenInputDesktop() {
196   bool is_interactive = false;
197   if (IsInteractiveDesktop(&is_interactive) && is_interactive)
198     return SBOX_TEST_SUCCEEDED;
199   HDESK desk = ::OpenInputDesktop(0, FALSE, DESKTOP_CREATEWINDOW);
200   if (desk) {
201     ::CloseDesktop(desk);
202     return SBOX_TEST_SUCCEEDED;
203   }
204   return SBOX_TEST_DENIED;
205 }
206
207 SBOX_TESTS_COMMAND int SwitchToSboxDesktop(int, wchar_t **) {
208   return TestSwitchDesktop();
209 }
210
211 int TestSwitchDesktop() {
212   HDESK desktop = ::GetThreadDesktop(::GetCurrentThreadId());
213   if (desktop == NULL)
214     return SBOX_TEST_FAILED;
215   return ::SwitchDesktop(desktop) ? SBOX_TEST_SUCCEEDED : SBOX_TEST_DENIED;
216 }
217
218 SBOX_TESTS_COMMAND int OpenAlternateDesktop(int, wchar_t **argv) {
219   return TestOpenAlternateDesktop(argv[0]);
220 }
221
222 int TestOpenAlternateDesktop(wchar_t *desktop_name) {
223   // Test for WRITE_DAC permission on the handle.
224   HDESK desktop = ::GetThreadDesktop(::GetCurrentThreadId());
225   if (desktop) {
226     HANDLE test_handle;
227     if (::DuplicateHandle(::GetCurrentProcess(), desktop,
228                           ::GetCurrentProcess(), &test_handle,
229                           WRITE_DAC, FALSE, 0)) {
230       DWORD result = ::SetSecurityInfo(test_handle, SE_WINDOW_OBJECT,
231                                        DACL_SECURITY_INFORMATION, NULL, NULL,
232                                        NULL, NULL);
233       ::CloseHandle(test_handle);
234       if (result == ERROR_SUCCESS)
235         return SBOX_TEST_SUCCEEDED;
236     } else if (::GetLastError() != ERROR_ACCESS_DENIED) {
237       return SBOX_TEST_FAILED;
238     }
239   }
240
241   // Open by name with WRITE_DAC.
242   desktop = ::OpenDesktop(desktop_name, 0, FALSE, WRITE_DAC);
243   if (!desktop && ::GetLastError() == ERROR_ACCESS_DENIED)
244     return SBOX_TEST_DENIED;
245   ::CloseDesktop(desktop);
246   return SBOX_TEST_SUCCEEDED;
247 }
248
249 BOOL CALLBACK DesktopTestEnumProc(LPTSTR desktop_name, LPARAM result) {
250   return TRUE;
251 }
252
253 SBOX_TESTS_COMMAND int EnumAlternateWinsta(int, wchar_t **) {
254   return TestEnumAlternateWinsta();
255 }
256
257 int TestEnumAlternateWinsta() {
258   // Try to enumerate the destops on the alternate windowstation.
259   return ::EnumDesktopsW(NULL, DesktopTestEnumProc, 0) ?
260       SBOX_TEST_SUCCEEDED : SBOX_TEST_DENIED;
261 }
262
263 SBOX_TESTS_COMMAND int SleepCmd(int argc, wchar_t **argv) {
264   if (argc != 1)
265     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
266
267   ::Sleep(_wtoi(argv[0]));
268   return SBOX_TEST_SUCCEEDED;
269 }
270
271 SBOX_TESTS_COMMAND int AllocateCmd(int argc, wchar_t **argv) {
272   if (argc != 1)
273     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
274
275   size_t mem_size = static_cast<size_t>(_wtoll(argv[0]));
276   void* memory = ::VirtualAlloc(NULL, mem_size, MEM_COMMIT | MEM_RESERVE,
277                                 PAGE_READWRITE);
278   if (!memory) {
279     // We need to give the broker a chance to kill our process on failure.
280     ::Sleep(5000);
281     return SBOX_TEST_DENIED;
282   }
283
284   return ::VirtualFree(memory, 0, MEM_RELEASE) ?
285       SBOX_TEST_SUCCEEDED : SBOX_TEST_FAILED;
286 }
287
288
289 }  // namespace sandbox