OLD | NEW |
| (Empty) |
1 // Copyright 2008-2010 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 | |
16 #include "omaha/base/app_util.h" | |
17 #include "omaha/base/const_object_names.h" | |
18 #include "omaha/base/constants.h" | |
19 #include "omaha/base/error.h" | |
20 #include "omaha/base/omaha_version.h" | |
21 #include "omaha/base/path.h" | |
22 #include "omaha/base/reg_key.h" | |
23 #include "omaha/base/scoped_any.h" | |
24 #include "omaha/base/synchronized.h" | |
25 #include "omaha/base/system.h" | |
26 #include "omaha/base/timer.h" | |
27 #include "omaha/base/vistautil.h" | |
28 #include "omaha/common/command_line_builder.h" | |
29 #include "omaha/common/const_cmd_line.h" | |
30 #include "omaha/common/const_goopdate.h" | |
31 #include "omaha/common/goopdate_utils.h" | |
32 #include "omaha/core/google_update_core.h" | |
33 #include "omaha/setup/setup_service.h" | |
34 #include "omaha/testing/unit_test.h" | |
35 | |
36 namespace omaha { | |
37 | |
38 namespace { | |
39 | |
40 const TCHAR update_key[] = MACHINE_REG_UPDATE; | |
41 const TCHAR appid_key[] = MACHINE_REG_CLIENTS_GOOPDATE; | |
42 const TCHAR appid_state_key[] = MACHINE_REG_CLIENT_STATE_GOOPDATE; | |
43 | |
44 } // namespace | |
45 | |
46 class GoogleUpdateCoreTest : public testing::Test { | |
47 protected: | |
48 GoogleUpdateCoreTest() { | |
49 } | |
50 | |
51 static void SetUpTestCase() { | |
52 if (vista_util::IsUserAdmin()) { | |
53 System::AdjustPrivilege(SE_DEBUG_NAME, true); | |
54 TerminateAllGoogleUpdateProcesses(); | |
55 } | |
56 | |
57 const CString shell_path = goopdate_utils::BuildGoogleUpdateExePath(true); | |
58 EXPECT_SUCCEEDED(RegKey::SetValue(update_key, | |
59 kRegValueInstalledPath, | |
60 shell_path)); | |
61 | |
62 EXPECT_SUCCEEDED(RegKey::SetValue(update_key, | |
63 kRegValueInstalledVersion, | |
64 GetVersionString())); | |
65 | |
66 EXPECT_SUCCEEDED(RegKey::SetValue(appid_key, | |
67 kRegValueProductVersion, | |
68 GetVersionString())); | |
69 | |
70 EXPECT_SUCCEEDED(RegKey::SetValue(appid_key, _T("fc"), _T("fc /?"))); | |
71 | |
72 EXPECT_SUCCEEDED(RegKey::SetValue(appid_state_key, | |
73 kRegValueProductVersion, | |
74 GetVersionString())); | |
75 | |
76 CopyGoopdateFiles(GetGoogleUpdateMachinePath(), GetVersionString()); | |
77 } | |
78 | |
79 static void TearDownTestCase() { | |
80 if (vista_util::IsUserAdmin()) { | |
81 TerminateAllGoogleUpdateProcesses(); | |
82 } | |
83 | |
84 EXPECT_SUCCEEDED(RegKey::DeleteValue(appid_key, _T("fc"))); | |
85 } | |
86 | |
87 void DoLaunchCmdElevatedTests(IUnknown* core_object); | |
88 }; | |
89 | |
90 void GoogleUpdateCoreTest::DoLaunchCmdElevatedTests(IUnknown* core_object) { | |
91 CComQIPtr<IGoogleUpdateCore> google_update_core = core_object; | |
92 EXPECT_TRUE(google_update_core != NULL); | |
93 if (!google_update_core) { | |
94 return; | |
95 } | |
96 | |
97 ULONG_PTR proc_handle = 0; | |
98 DWORD caller_proc_id = ::GetCurrentProcessId(); | |
99 | |
100 // Returns ERROR_BAD_IMPERSONATION_LEVEL when explicit security blanket is not | |
101 // set. | |
102 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_BAD_IMPERSONATION_LEVEL), | |
103 google_update_core->LaunchCmdElevated(kGoogleUpdateAppId, | |
104 _T("cmd"), | |
105 caller_proc_id, | |
106 &proc_handle)); | |
107 EXPECT_EQ(0, proc_handle); | |
108 | |
109 // Sets a security blanket that will allow the server to impersonate the | |
110 // client. | |
111 EXPECT_SUCCEEDED(::CoSetProxyBlanket(google_update_core, | |
112 RPC_C_AUTHN_DEFAULT, RPC_C_AUTHZ_DEFAULT, COLE_DEFAULT_PRINCIPAL, | |
113 RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, | |
114 EOAC_DEFAULT)); | |
115 | |
116 // Returns GOOPDATE_E_CORE_MISSING_CMD when the command is missing in | |
117 // the registry. | |
118 EXPECT_EQ(GOOPDATE_E_CORE_MISSING_CMD, | |
119 google_update_core->LaunchCmdElevated(kGoogleUpdateAppId, | |
120 _T("cmd"), | |
121 caller_proc_id, | |
122 &proc_handle)); | |
123 EXPECT_EQ(0, proc_handle); | |
124 | |
125 // Returns E_INVALIDARG when the app_guid is not a guid. | |
126 EXPECT_EQ(E_INVALIDARG, | |
127 google_update_core->LaunchCmdElevated(_T("noguid"), | |
128 _T("cmd"), | |
129 caller_proc_id, | |
130 &proc_handle)); | |
131 | |
132 EXPECT_SUCCEEDED(google_update_core->LaunchCmdElevated(kGoogleUpdateAppId, | |
133 _T("fc"), | |
134 caller_proc_id, | |
135 &proc_handle)); | |
136 EXPECT_NE(0, proc_handle); | |
137 | |
138 // TODO(Omaha): Perhaps attempt some negative tests here, either by testing | |
139 // the permissions on the handle explicitly, or by attempting VM operations or | |
140 // such on the process handle, since it's a serious security issue if the | |
141 // handle permissions are too wide. | |
142 HANDLE handle = reinterpret_cast<HANDLE>(proc_handle); | |
143 EXPECT_NE(WAIT_FAILED, ::WaitForSingleObject(handle, 10000)); | |
144 EXPECT_TRUE(::CloseHandle(handle)); | |
145 } | |
146 | |
147 TEST_F(GoogleUpdateCoreTest, LaunchCmdElevated_LocalServerRegistered) { | |
148 RegisterOrUnregisterGoopdateLocalServer(true); | |
149 | |
150 CComPtr<IUnknown> local_server_com; | |
151 EXPECT_SUCCEEDED(System::CoCreateInstanceAsAdmin( | |
152 NULL, __uuidof(GoogleUpdateCoreMachineClass), | |
153 IID_PPV_ARGS(&local_server_com))); | |
154 | |
155 DoLaunchCmdElevatedTests(local_server_com); | |
156 | |
157 local_server_com.Release(); | |
158 | |
159 RegisterOrUnregisterGoopdateLocalServer(false); | |
160 } | |
161 | |
162 TEST_F(GoogleUpdateCoreTest, | |
163 LaunchCmdElevated_ServiceAndLocalServerRegistered) { | |
164 RegisterOrUnregisterGoopdateService(true); | |
165 RegisterOrUnregisterGoopdateLocalServer(true); | |
166 | |
167 CComPtr<IUnknown> service_com; | |
168 EXPECT_SUCCEEDED( | |
169 service_com.CoCreateInstance(__uuidof(GoogleUpdateCoreClass))); | |
170 | |
171 DoLaunchCmdElevatedTests(service_com); | |
172 | |
173 CComPtr<IUnknown> local_server_com; | |
174 EXPECT_SUCCEEDED(System::CoCreateInstanceAsAdmin( | |
175 NULL, __uuidof(GoogleUpdateCoreMachineClass), | |
176 IID_PPV_ARGS(&local_server_com))); | |
177 | |
178 DoLaunchCmdElevatedTests(local_server_com); | |
179 | |
180 service_com.Release(); | |
181 local_server_com.Release(); | |
182 | |
183 RegisterOrUnregisterGoopdateLocalServer(false); | |
184 RegisterOrUnregisterGoopdateService(false); | |
185 } | |
186 | |
187 TEST_F(GoogleUpdateCoreTest, LaunchCmdElevated_ServiceRunning) { | |
188 if (!vista_util::IsUserAdmin()) { | |
189 SUCCEED() << "\tTest did not run because the user is not an admin."; | |
190 return; | |
191 } | |
192 | |
193 RegisterOrUnregisterGoopdateService(true); | |
194 | |
195 // RegisterOrUnregisterGoopdateLocalServer is needed for handler registration. | |
196 RegisterOrUnregisterGoopdateLocalServer(true); | |
197 | |
198 EXPECT_SUCCEEDED(SetupUpdateMediumService::StartService()); | |
199 CComPtr<IUnknown> service_com; | |
200 EXPECT_SUCCEEDED( | |
201 service_com.CoCreateInstance(__uuidof(GoogleUpdateCoreClass))); | |
202 | |
203 DoLaunchCmdElevatedTests(service_com); | |
204 | |
205 service_com.Release(); | |
206 | |
207 RegisterOrUnregisterGoopdateLocalServer(false); | |
208 RegisterOrUnregisterGoopdateService(false); | |
209 } | |
210 | |
211 } // namespace omaha | |
212 | |
OLD | NEW |