Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: recovery/client/google_update_recovery_unittest.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2007-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 //
17 // Unit tests for the Google Update recovery mechanism.
18 // All apps that are using the mechanism must also run this test.
19 //
20 // Unlike the mechanism code, this code relies on code from common because it
21 // makes writing the tests much simpler and size is not a concern.
22
23 #include <windows.h>
24 #include <atlstr.h>
25 #include "omaha/base/app_util.h"
26 #include "omaha/base/const_addresses.h"
27 #include "omaha/base/error.h"
28 #include "omaha/base/file.h"
29 #include "omaha/base/path.h"
30 #include "omaha/base/reg_key.h"
31 #include "omaha/base/signaturevalidator.h"
32 #include "omaha/base/system_info.h"
33 #include "omaha/base/scope_guard.h"
34 #include "omaha/base/utils.h"
35 #include "omaha/base/vistautil.h"
36 #include "omaha/common/const_group_policy.h"
37 #include "omaha/net/network_config.h"
38 #include "omaha/net/network_request.h"
39 #include "omaha/net/simple_request.h"
40 #include "omaha/recovery/client/google_update_recovery.h"
41 #include "omaha/third_party/gtest/include/gtest/gtest.h"
42
43 // TODO(omaha): Replicate some of these tests in signaturevalidator_unittest.cc.
44
45 // As of Google Test 1.4.0, expressions get converted to 'bool', resulting in
46 // "warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance
47 // warning)" in some uses.
48 // These must be kept in sync with gtest.h.
49 // TODO(omaha): Try to get this fixed in Google Test.
50 #undef EXPECT_TRUE
51 #define EXPECT_TRUE(condition) \
52 GTEST_TEST_BOOLEAN_(!!(condition), #condition, false, true, \
53 GTEST_NONFATAL_FAILURE_)
54 #undef ASSERT_TRUE
55 #define ASSERT_TRUE(condition) \
56 GTEST_TEST_BOOLEAN_(!!(condition), #condition, false, true, \
57 GTEST_FATAL_FAILURE_)
58
59 namespace omaha {
60
61 namespace {
62
63 const TCHAR kDummyAppGuid[] = _T("{8E472B0D-3E8B-43b1-B89A-E8506AAF1F16}");
64 const TCHAR kDummyAppVersion[] = _T("3.4.5.6");
65 const TCHAR kDummyAppLang[] = _T("en-us");
66
67 const TCHAR kTempDirectory[] = _T("C:\\WINDOWS\\Temp");
68
69 const TCHAR kFullMachineOmahaMainKeyPath[] =
70 _T("HKLM\\Software\\Google\\Update\\");
71 const TCHAR kFullUserOmahaMainKeyPath[] =
72 _T("HKCU\\Software\\Google\\Update\\");
73 const TCHAR kFullMachineOmahaClientKeyPath[] =
74 _T("HKLM\\Software\\Google\\Update\\Clients\\")
75 _T("{430FD4D0-B729-4f61-AA34-91526481799D}");
76 const TCHAR kFullUserOmahaClientKeyPath[] =
77 _T("HKCU\\Software\\Google\\Update\\Clients\\")
78 _T("{430FD4D0-B729-4f61-AA34-91526481799D}");
79
80 const HRESULT kDummyNoFileError = 0x80041234;
81
82 const TCHAR kArgumentSavingExecutableRelativePath[] =
83 _T("unittest_support\\SaveArguments.exe");
84 const TCHAR kSavedArgumentsFileName[] = _T("saved_arguments.txt");
85 const TCHAR* const kInvalidFileUrl = _T("http://www.google.com/robots.txt");
86
87 #define MACHINE_KEY_NAME _T("HKLM")
88 #define MACHINE_KEY MACHINE_KEY_NAME _T("\\")
89 #define USER_KEY_NAME _T("HKCU")
90 #define USER_KEY USER_KEY_NAME _T("\\")
91
92 // These methods were copied from omaha/testing/omaha_unittest.cpp.
93 const TCHAR kRegistryHiveOverrideRoot[] =
94 _T("HKCU\\Software\\Google\\Update\\UnitTest\\");
95
96 const TCHAR kExpectedUrlForDummyAppAndNoOmahaValues[] = _T("http://cr-tools.clie nts.google.com/service/check2?appid=%7B8E472B0D-3E8B-43b1-B89A-E8506AAF1F16%7D&a ppversion=3.4.5.6&applang=en-us&machine=1&version=0.0.0.0&osversion="); // NOLI NT
97 const int kExpectedUrlForDummyAppAndNoOmahaValuesLength =
98 arraysize(kExpectedUrlForDummyAppAndNoOmahaValues) - 1;
99
100 // Overrides the HKLM and HKCU registry hives so that accesses go to the
101 // specified registry key instead.
102 // This method is most often used in SetUp().
103 void OverrideRegistryHives(const CString& hive_override_key_name) {
104 // Override the destinations of HKLM and HKCU to use a special location
105 // for the unit tests so that we don't disturb the actual Omaha state.
106 RegKey machine_key;
107 RegKey user_key;
108 EXPECT_HRESULT_SUCCEEDED(
109 machine_key.Create(hive_override_key_name + MACHINE_KEY));
110 EXPECT_HRESULT_SUCCEEDED(user_key.Create(hive_override_key_name + USER_KEY));
111 EXPECT_HRESULT_SUCCEEDED(::RegOverridePredefKey(HKEY_LOCAL_MACHINE,
112 machine_key.Key()));
113 EXPECT_HRESULT_SUCCEEDED(::RegOverridePredefKey(HKEY_CURRENT_USER,
114 user_key.Key()));
115 }
116
117 // Restores HKLM and HKCU registry accesses to the real hives.
118 // This method is most often used in TearDown().
119 void RestoreRegistryHives() {
120 EXPECT_HRESULT_SUCCEEDED(::RegOverridePredefKey(HKEY_LOCAL_MACHINE, NULL));
121 EXPECT_HRESULT_SUCCEEDED(::RegOverridePredefKey(HKEY_CURRENT_USER, NULL));
122 }
123
124 CString GetTmp() {
125 TCHAR temp_dir[MAX_PATH] = {0};
126 EXPECT_NE(0, ::GetEnvironmentVariable(_T("TMP"), temp_dir, MAX_PATH));
127 return temp_dir;
128 }
129
130 } // namespace
131
132 HRESULT VerifyFileSignature(const CString& filename);
133 HRESULT VerifyRepairFileMarkup(const CString& filename);
134
135 class GoogleUpdateRecoveryTest : public testing::Test {
136 public:
137 static void set_saved_url(const CString& saved_url) {
138 saved_url_ = saved_url;
139 }
140
141 static void set_saved_file_path(const CString& saved_file_path) {
142 saved_file_path_ = saved_file_path;
143 }
144
145 static void set_saved_context(void* context) {
146 saved_context_ = context;
147 }
148
149 protected:
150 GoogleUpdateRecoveryTest() {
151 saved_url_.Empty();
152 saved_file_path_.Empty();
153 saved_context_ = NULL;
154 }
155
156 virtual void SetUp() {
157 }
158
159 virtual void TearDown() {
160 }
161
162 void CheckSavedUrlOSFragment() {
163 OSVERSIONINFO os_version_info = { 0 };
164 os_version_info.dwOSVersionInfoSize = sizeof(os_version_info);
165 EXPECT_NE(0, ::GetVersionEx(&os_version_info));
166
167 CString escaped_service_pack;
168 EXPECT_HRESULT_SUCCEEDED(StringEscape(os_version_info.szCSDVersion,
169 false,
170 &escaped_service_pack));
171
172 CString expected_os_fragment;
173 expected_os_fragment.Format(_T("%d.%d&servicepack="),
174 os_version_info.dwMajorVersion,
175 os_version_info.dwMinorVersion);
176 expected_os_fragment += escaped_service_pack;
177
178 EXPECT_TRUE(expected_os_fragment ==
179 saved_url_.Right(expected_os_fragment.GetLength()));
180 }
181
182 void VerifySavedArgumentsFile(const CString& expected_string) {
183 CString saved_arguments_path = ConcatenatePath(
184 GetDirectoryFromPath(saved_file_path_),
185 kSavedArgumentsFileName);
186 bool is_found = false;
187 for (int tries = 0; tries < 100 && !is_found; ++tries) {
188 ::Sleep(50);
189 is_found = File::Exists(saved_arguments_path);
190 }
191 EXPECT_TRUE(is_found);
192
193 scoped_hfile file(::CreateFile(saved_arguments_path,
194 GENERIC_READ,
195 0, // do not share
196 NULL, // default security
197 OPEN_EXISTING, // existing file only
198 FILE_ATTRIBUTE_NORMAL,
199 NULL)); // no template
200 EXPECT_NE(INVALID_HANDLE_VALUE, get(file));
201
202 const int kBufferLen = 50;
203 TCHAR buffer[kBufferLen + 1] = {0};
204 DWORD bytes_read = 0;
205
206 EXPECT_TRUE(::ReadFile(get(file),
207 buffer,
208 kBufferLen * sizeof(TCHAR),
209 &bytes_read,
210 NULL));
211 EXPECT_EQ(0, bytes_read % sizeof(TCHAR));
212 buffer[bytes_read / sizeof(TCHAR)] = _T('\0');
213
214 EXPECT_STREQ(expected_string, buffer);
215 }
216
217 void VerifyExpectedSavedFilePath(const CString& expected_temp_directory) {
218 const int kMaxUniqueChars = 4;
219 const CString expected_path_part_a = expected_temp_directory + _T("\\GUR");
220 const CString expected_path_part_b = _T(".exe");
221 EXPECT_STREQ(expected_path_part_a,
222 saved_file_path_.Left(expected_path_part_a.GetLength()));
223 EXPECT_STREQ(expected_path_part_b,
224 saved_file_path_.Right(expected_path_part_b.GetLength()));
225 const int constant_chars = expected_path_part_a.GetLength() +
226 expected_path_part_b.GetLength();
227 EXPECT_GT(saved_file_path_.GetLength(), constant_chars);
228 EXPECT_LE(saved_file_path_.GetLength(), constant_chars + kMaxUniqueChars);
229 }
230
231 static CString saved_url_;
232 static CString saved_file_path_;
233 static void* saved_context_;
234
235 protected:
236 // Copies SaveArguments.exe to the specified location.
237 static HRESULT DownloadArgumentSavingFile(const TCHAR* url,
238 const TCHAR* file_path,
239 void* context) {
240 ASSERT1(url);
241 ASSERT1(file_path);
242
243 GoogleUpdateRecoveryTest::set_saved_url(url);
244 GoogleUpdateRecoveryTest::set_saved_file_path(file_path);
245 GoogleUpdateRecoveryTest::set_saved_context(context);
246
247 CString executable_full_path(app_util::GetCurrentModuleDirectory());
248 VERIFY1(::PathAppend(CStrBuf(executable_full_path, MAX_PATH),
249 kArgumentSavingExecutableRelativePath));
250
251 if (!::CopyFile(executable_full_path, file_path, false)) {
252 HRESULT hr = HRESULTFromLastError();
253 return hr;
254 }
255
256 return S_OK;
257 }
258
259 // Returns kDummyNoFileError, simulating no file to download.
260 static HRESULT DownloadFileNoFile(const TCHAR* url,
261 const TCHAR* file_path,
262 void* context) {
263 ASSERT1(url);
264 ASSERT1(file_path);
265
266 GoogleUpdateRecoveryTest::set_saved_url(url);
267 GoogleUpdateRecoveryTest::set_saved_file_path(file_path);
268 GoogleUpdateRecoveryTest::set_saved_context(context);
269
270 return kDummyNoFileError;
271 }
272
273 // Overrides the address to cause a file to be downloaded via HTTP.
274 // Uses a real HTTP stack, so it is similar to a real implementation.
275 // The file is invalid, so signature verification should return
276 // TRUST_E_SUBJECT_FORM_UNKNOWN.
277 static HRESULT DownloadFileInvalidFile(const TCHAR* url,
278 const TCHAR* file_path,
279 void* context) {
280 ASSERT1(url);
281 UNREFERENCED_PARAMETER(url);
282
283 return DownloadFileFromServer(kInvalidFileUrl, file_path, context);
284 }
285
286 // Uses a real HTTP stack, so it is similar to a real implementation.
287 static HRESULT DownloadFileFromServer(const TCHAR* url,
288 const TCHAR* file_path,
289 void* context) {
290 UTIL_LOG(L2, (_T("[DownloadFileFromServer][%s][%s]"), url, file_path));
291
292 ASSERT1(url);
293 ASSERT1(file_path);
294
295 GoogleUpdateRecoveryTest::set_saved_url(url);
296 GoogleUpdateRecoveryTest::set_saved_file_path(file_path);
297 GoogleUpdateRecoveryTest::set_saved_context(context);
298
299 NetworkConfig* network_config = NULL;
300 NetworkConfigManager& network_manager = NetworkConfigManager::Instance();
301 HRESULT hr = network_manager.GetUserNetworkConfig(&network_config);
302 if (FAILED(hr)) {
303 UTIL_LOG(LE, (_T("[GetUserNetworkConfig failed][0x%08x]"), hr));
304 return hr;
305 }
306 ON_SCOPE_EXIT_OBJ(*network_config, &NetworkConfig::Clear);
307 NetworkRequest network_request(network_config->session());
308
309 network_config->Clear();
310 network_config->Add(new UpdateDevProxyDetector);
311 network_config->Add(new FirefoxProxyDetector);
312 network_config->Add(new IEProxyDetector);
313
314 network_request.AddHttpRequest(new SimpleRequest);
315
316 hr = network_request.DownloadFile(url, CString(file_path));
317 if (FAILED(hr)) {
318 UTIL_LOG(LE, (_T("[DownloadFile failed][%s][0x%08x]"), url, hr));
319 return hr;
320 }
321
322 int status_code = network_request.http_status_code();
323 UTIL_LOG(L2, (_T("[HTTP status][%u]"), status_code));
324
325 if (HTTP_STATUS_OK == status_code) {
326 return S_OK;
327 } else if (HTTP_STATUS_NO_CONTENT == status_code) {
328 return kDummyNoFileError;
329 } else {
330 // Apps would not have this assumption.
331 ASSERT(false, (_T("Status code %i received. Expected 200 or 204."),
332 status_code));
333 return E_FAIL;
334 }
335 }
336 };
337
338 CString GoogleUpdateRecoveryTest::saved_url_;
339 CString GoogleUpdateRecoveryTest::saved_file_path_;
340 void* GoogleUpdateRecoveryTest::saved_context_;
341
342 class GoogleUpdateRecoveryRegistryProtectedTest
343 : public GoogleUpdateRecoveryTest {
344 protected:
345 GoogleUpdateRecoveryRegistryProtectedTest()
346 : hive_override_key_name_(kRegistryHiveOverrideRoot) {
347 }
348
349 CString hive_override_key_name_;
350
351 virtual void SetUp() {
352 GoogleUpdateRecoveryTest::SetUp();
353 RegKey::DeleteKey(hive_override_key_name_, true);
354 OverrideRegistryHives(hive_override_key_name_);
355 }
356
357 virtual void TearDown() {
358 RestoreRegistryHives();
359 EXPECT_HRESULT_SUCCEEDED(RegKey::DeleteKey(hive_override_key_name_, true));
360 GoogleUpdateRecoveryTest::TearDown();
361 }
362 };
363
364 //
365 // FixGoogleUpdate Tests
366 //
367
368 TEST_F(GoogleUpdateRecoveryTest, FixGoogleUpdate_UseRealHttpClient) {
369 EXPECT_EQ(TRUST_E_SUBJECT_FORM_UNKNOWN,
370 FixGoogleUpdate(kDummyAppGuid,
371 kDummyAppVersion,
372 kDummyAppLang,
373 true,
374 DownloadFileInvalidFile,
375 NULL));
376 }
377
378 TEST_F(GoogleUpdateRecoveryTest, FixGoogleUpdate_FileReturned_Machine) {
379 CString saved_arguments_path = ConcatenatePath(app_util::GetTempDir(),
380 kSavedArgumentsFileName);
381
382 ::DeleteFile(saved_arguments_path);
383 EXPECT_FALSE(File::Exists(saved_arguments_path));
384
385 CString context_string(_T("some context"));
386 EXPECT_HRESULT_SUCCEEDED(FixGoogleUpdate(kDummyAppGuid,
387 kDummyAppVersion,
388 kDummyAppLang,
389 true,
390 DownloadArgumentSavingFile,
391 &context_string));
392
393 EXPECT_EQ(&context_string, saved_context_);
394 EXPECT_STREQ(_T("some context"), *static_cast<CString*>(saved_context_));
395
396 ::Sleep(200);
397 EXPECT_TRUE(File::Exists(saved_file_path_));
398 VerifySavedArgumentsFile(_T("/recover /machine"));
399
400 EXPECT_TRUE(::DeleteFile(saved_file_path_));
401 EXPECT_TRUE(::DeleteFile(saved_arguments_path));
402 }
403
404 TEST_F(GoogleUpdateRecoveryTest, FixGoogleUpdate_FileReturned_User) {
405 CString saved_arguments_path = ConcatenatePath(app_util::GetTempDir(),
406 kSavedArgumentsFileName);
407
408 ::DeleteFile(saved_arguments_path);
409 EXPECT_FALSE(File::Exists(saved_arguments_path));
410
411 CString context_string(_T("more context"));
412 EXPECT_HRESULT_SUCCEEDED(FixGoogleUpdate(kDummyAppGuid,
413 kDummyAppVersion,
414 kDummyAppLang,
415 false,
416 DownloadArgumentSavingFile,
417 &context_string));
418
419 EXPECT_EQ(&context_string, saved_context_);
420 EXPECT_STREQ(_T("more context"), *static_cast<CString*>(saved_context_));
421
422 ::Sleep(200);
423 EXPECT_TRUE(File::Exists(saved_file_path_));
424 VerifySavedArgumentsFile(_T("/recover"));
425
426 EXPECT_TRUE(::DeleteFile(saved_file_path_));
427 EXPECT_TRUE(::DeleteFile(saved_arguments_path));
428 }
429
430 TEST_F(GoogleUpdateRecoveryTest, FixGoogleUpdate_NoFile_Machine) {
431 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
432 kDummyAppVersion,
433 kDummyAppLang,
434 true,
435 DownloadFileNoFile,
436 NULL));
437
438 EXPECT_EQ(static_cast<void*>(NULL), saved_context_);
439 EXPECT_FALSE(File::Exists(saved_file_path_));
440
441 TCHAR temp_dir[MAX_PATH] = {0};
442 EXPECT_TRUE(::GetEnvironmentVariable(_T("TMP"), temp_dir, MAX_PATH));
443 EXPECT_TRUE(File::Exists(temp_dir))
444 << _T("The temp directory was deleted or not created.");
445 }
446
447 TEST_F(GoogleUpdateRecoveryTest, FixGoogleUpdate_NoFile_User) {
448 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
449 kDummyAppVersion,
450 kDummyAppLang,
451 false,
452 DownloadFileNoFile,
453 NULL));
454
455 EXPECT_EQ(static_cast<void*>(NULL), saved_context_);
456 EXPECT_FALSE(File::Exists(saved_file_path_));
457
458 TCHAR temp_dir[MAX_PATH] = {0};
459 EXPECT_TRUE(::GetEnvironmentVariable(_T("TMP"), temp_dir, MAX_PATH));
460 EXPECT_TRUE(File::Exists(temp_dir))
461 << _T("The temp directory was deleted or not created.");
462 }
463
464 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
465 FixGoogleUpdate_AllValues_MachineApp) {
466 const TCHAR kExpectedUrl[] = _T("http://cr-tools.clients.google.com/service/ch eck2?appid=%7B8E472B0D-3E8B-43b1-B89A-E8506AAF1F16%7D&appversion=3.4.5.6&applang =en-us&machine=1&version=5.6.78.1&osversion="); // NOLINT
467
468 const CString prev_tmp = GetTmp();
469 EXPECT_TRUE(::SetEnvironmentVariable(_T("TMP"), kTempDirectory));
470
471 EXPECT_HRESULT_SUCCEEDED(RegKey::SetValue(kFullMachineOmahaClientKeyPath,
472 _T("pv"),
473 _T("5.6.78.1")));
474
475 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
476 kDummyAppVersion,
477 kDummyAppLang,
478 true,
479 DownloadFileNoFile,
480 NULL));
481
482 EXPECT_STREQ(kExpectedUrl, saved_url_.Left(arraysize(kExpectedUrl) - 1));
483 CheckSavedUrlOSFragment();
484 VerifyExpectedSavedFilePath(kTempDirectory);
485
486 EXPECT_TRUE(::SetEnvironmentVariable(_T("TMP"), prev_tmp));
487 }
488
489 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
490 FixGoogleUpdate_AllValues_UserApp) {
491 const TCHAR kExpectedUrl[] = _T("http://cr-tools.clients.google.com/service/ch eck2?appid=%7B8E472B0D-3E8B-43b1-B89A-E8506AAF1F16%7D&appversion=3.4.5.6&applang =en-us&machine=0&version=5.6.78.1&osversion="); // NOLINT
492
493 const CString prev_tmp = GetTmp();
494 EXPECT_TRUE(::SetEnvironmentVariable(_T("TMP"), kTempDirectory));
495
496 EXPECT_HRESULT_SUCCEEDED(RegKey::SetValue(kFullUserOmahaClientKeyPath,
497 _T("pv"),
498 _T("5.6.78.1")));
499
500 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
501 kDummyAppVersion,
502 kDummyAppLang,
503 false,
504 DownloadFileNoFile,
505 NULL));
506
507 EXPECT_STREQ(kExpectedUrl, saved_url_.Left(arraysize(kExpectedUrl) - 1));
508 CheckSavedUrlOSFragment();
509 VerifyExpectedSavedFilePath(kTempDirectory);
510
511 EXPECT_TRUE(::SetEnvironmentVariable(_T("TMP"), prev_tmp));
512 }
513
514 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
515 FixGoogleUpdate_NoOmahaRegKeys) {
516 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
517 kDummyAppVersion,
518 kDummyAppLang,
519 true,
520 DownloadFileNoFile,
521 NULL));
522 EXPECT_STREQ(kExpectedUrlForDummyAppAndNoOmahaValues,
523 saved_url_.Left(kExpectedUrlForDummyAppAndNoOmahaValuesLength));
524 CheckSavedUrlOSFragment();
525 }
526
527 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
528 FixGoogleUpdate_EmptyAppInfo) {
529 const TCHAR kExpectedUrl[] = _T("http://cr-tools.clients.google.com/service/ch eck2?appid=&appversion=&applang=&machine=1&version=0.0.0.0&osversion="); // NOL INT
530
531 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(_T(""),
532 _T(""),
533 _T(""),
534 true,
535 DownloadFileNoFile,
536 NULL));
537 EXPECT_STREQ(kExpectedUrl, saved_url_.Left(arraysize(kExpectedUrl) - 1));
538 CheckSavedUrlOSFragment();
539 }
540
541 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
542 FixGoogleUpdate_NullArgs) {
543 EXPECT_EQ(E_INVALIDARG, FixGoogleUpdate(NULL,
544 _T(""),
545 _T(""),
546 true,
547 DownloadFileNoFile,
548 NULL));
549 EXPECT_EQ(E_INVALIDARG, FixGoogleUpdate(_T(""),
550 NULL,
551 _T(""),
552 true,
553 DownloadFileNoFile,
554 NULL));
555 EXPECT_EQ(E_INVALIDARG, FixGoogleUpdate(_T(""),
556 _T(""),
557 NULL,
558 true,
559 DownloadFileNoFile,
560 NULL));
561 EXPECT_EQ(E_INVALIDARG, FixGoogleUpdate(_T(""),
562 _T(""),
563 _T(""),
564 true,
565 NULL,
566 NULL));
567 }
568
569 // Setting kRegValueAutoUpdateCheckPeriodOverrideMinutes to zero disables
570 // Code Red checks just as it does regular update checks.
571 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
572 FixGoogleUpdate_AutoUpdateCheckPeriodMinutesIsZeroDword) {
573 EXPECT_HRESULT_SUCCEEDED(
574 RegKey::SetValue(kRegKeyGoopdateGroupPolicy,
575 kRegValueAutoUpdateCheckPeriodOverrideMinutes,
576 static_cast<DWORD>(0)));
577
578 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_ACCESS_DISABLED_BY_POLICY),
579 FixGoogleUpdate(kDummyAppGuid,
580 kDummyAppVersion,
581 kDummyAppLang,
582 true,
583 DownloadFileNoFile,
584 NULL));
585 EXPECT_TRUE(saved_url_.IsEmpty());
586 }
587
588 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
589 FixGoogleUpdate_AutoUpdateCheckPeriodMinutesIsZeroDwordInHkcu) {
590 EXPECT_HRESULT_SUCCEEDED(
591 RegKey::SetValue(USER_KEY GOOPDATE_POLICIES_RELATIVE,
592 kRegValueAutoUpdateCheckPeriodOverrideMinutes,
593 static_cast<DWORD>(0)));
594
595 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
596 kDummyAppVersion,
597 kDummyAppLang,
598 true,
599 DownloadFileNoFile,
600 NULL));
601 EXPECT_STREQ(kExpectedUrlForDummyAppAndNoOmahaValues,
602 saved_url_.Left(kExpectedUrlForDummyAppAndNoOmahaValuesLength));
603 CheckSavedUrlOSFragment();
604 }
605
606 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
607 FixGoogleUpdate_AutoUpdateCheckPeriodMinutesIsNonZeroDword) {
608 EXPECT_HRESULT_SUCCEEDED(
609 RegKey::SetValue(kRegKeyGoopdateGroupPolicy,
610 kRegValueAutoUpdateCheckPeriodOverrideMinutes,
611 static_cast<DWORD>(1400)));
612
613 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
614 kDummyAppVersion,
615 kDummyAppLang,
616 true,
617 DownloadFileNoFile,
618 NULL));
619 EXPECT_STREQ(kExpectedUrlForDummyAppAndNoOmahaValues,
620 saved_url_.Left(kExpectedUrlForDummyAppAndNoOmahaValuesLength));
621 CheckSavedUrlOSFragment();
622 }
623
624 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
625 FixGoogleUpdate_AutoUpdateCheckPeriodMinutesIsZeroDword64) {
626 EXPECT_HRESULT_SUCCEEDED(
627 RegKey::SetValue(kRegKeyGoopdateGroupPolicy,
628 kRegValueAutoUpdateCheckPeriodOverrideMinutes,
629 static_cast<DWORD64>(0)));
630
631 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
632 kDummyAppVersion,
633 kDummyAppLang,
634 true,
635 DownloadFileNoFile,
636 NULL));
637 EXPECT_STREQ(kExpectedUrlForDummyAppAndNoOmahaValues,
638 saved_url_.Left(kExpectedUrlForDummyAppAndNoOmahaValuesLength));
639 CheckSavedUrlOSFragment();
640 }
641
642 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
643 FixGoogleUpdate_AutoUpdateCheckPeriodMinutesIsNonZeroDword64) {
644 EXPECT_HRESULT_SUCCEEDED(
645 RegKey::SetValue(kRegKeyGoopdateGroupPolicy,
646 kRegValueAutoUpdateCheckPeriodOverrideMinutes,
647 static_cast<DWORD64>(1400)));
648
649 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
650 kDummyAppVersion,
651 kDummyAppLang,
652 true,
653 DownloadFileNoFile,
654 NULL));
655 EXPECT_STREQ(kExpectedUrlForDummyAppAndNoOmahaValues,
656 saved_url_.Left(kExpectedUrlForDummyAppAndNoOmahaValuesLength));
657 CheckSavedUrlOSFragment();
658 }
659
660 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
661 FixGoogleUpdate_AutoUpdateCheckPeriodMinutesIsZeroAsString) {
662 EXPECT_HRESULT_SUCCEEDED(
663 RegKey::SetValue(kRegKeyGoopdateGroupPolicy,
664 kRegValueAutoUpdateCheckPeriodOverrideMinutes,
665 _T("0")));
666
667 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
668 kDummyAppVersion,
669 kDummyAppLang,
670 true,
671 DownloadFileNoFile,
672 NULL));
673 EXPECT_STREQ(kExpectedUrlForDummyAppAndNoOmahaValues,
674 saved_url_.Left(kExpectedUrlForDummyAppAndNoOmahaValuesLength));
675 CheckSavedUrlOSFragment();
676 }
677
678 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
679 FixGoogleUpdate_AutoUpdateCheckPeriodMinutesIsZeroAsBinary) {
680 const byte zero = 0;
681 EXPECT_HRESULT_SUCCEEDED(
682 RegKey::SetValue(kRegKeyGoopdateGroupPolicy,
683 kRegValueAutoUpdateCheckPeriodOverrideMinutes,
684 &zero,
685 sizeof(zero)));
686
687 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
688 kDummyAppVersion,
689 kDummyAppLang,
690 true,
691 DownloadFileNoFile,
692 NULL));
693 EXPECT_STREQ(kExpectedUrlForDummyAppAndNoOmahaValues,
694 saved_url_.Left(kExpectedUrlForDummyAppAndNoOmahaValuesLength));
695 CheckSavedUrlOSFragment();
696 }
697
698 TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,
699 FixGoogleUpdate_GroupPolicyKeyExistsButNoAutoUpdateCheckPeriodMinutes) {
700 EXPECT_HRESULT_SUCCEEDED(RegKey::CreateKey(kRegKeyGoopdateGroupPolicy));
701
702 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
703 kDummyAppVersion,
704 kDummyAppLang,
705 true,
706 DownloadFileNoFile,
707 NULL));
708 EXPECT_STREQ(kExpectedUrlForDummyAppAndNoOmahaValues,
709 saved_url_.Left(kExpectedUrlForDummyAppAndNoOmahaValuesLength));
710 CheckSavedUrlOSFragment();
711 }
712
713 // Verifies that the file is saved even if the temp directory doesn't exist.
714 TEST_F(GoogleUpdateRecoveryTest, FixGoogleUpdate_SaveToNonExistantDirectory) {
715 const TCHAR kNonExistantDirectory[] = _T("c:\\directory_does_not_exist");
716 DeleteDirectory(kNonExistantDirectory);
717 EXPECT_FALSE(File::Exists(kNonExistantDirectory));
718
719 const CString prev_tmp = GetTmp();
720 EXPECT_TRUE(::SetEnvironmentVariable(_T("TMP"), kNonExistantDirectory));
721
722 EXPECT_EQ(TRUST_E_SUBJECT_FORM_UNKNOWN,
723 FixGoogleUpdate(kDummyAppGuid,
724 kDummyAppVersion,
725 kDummyAppLang,
726 true,
727 DownloadFileInvalidFile,
728 NULL));
729
730 VerifyExpectedSavedFilePath(kNonExistantDirectory);
731
732 EXPECT_TRUE(::SetEnvironmentVariable(_T("TMP"), prev_tmp));
733 EXPECT_HRESULT_SUCCEEDED(DeleteDirectory(kNonExistantDirectory));
734 }
735
736 TEST_F(GoogleUpdateRecoveryTest, FixGoogleUpdate_FileCollision) {
737 const CString prev_tmp = GetTmp();
738 EXPECT_TRUE(::SetEnvironmentVariable(_T("TMP"), kTempDirectory));
739
740 CString saved_arguments_path = ConcatenatePath(app_util::GetTempDir(),
741 kSavedArgumentsFileName);
742
743 EXPECT_HRESULT_SUCCEEDED(FixGoogleUpdate(kDummyAppGuid,
744 kDummyAppVersion,
745 kDummyAppLang,
746 false,
747 DownloadArgumentSavingFile,
748 NULL));
749
750 EXPECT_TRUE(File::Exists(saved_file_path_));
751 VerifyExpectedSavedFilePath(kTempDirectory);
752
753 CString first_saved_file_path = saved_file_path_;
754
755 // Ensure that the first downloaded file is in use.
756 FileLock lock;
757 EXPECT_HRESULT_SUCCEEDED(lock.Lock(first_saved_file_path));
758
759 EXPECT_HRESULT_SUCCEEDED(FixGoogleUpdate(kDummyAppGuid,
760 kDummyAppVersion,
761 kDummyAppLang,
762 false,
763 DownloadArgumentSavingFile,
764 NULL));
765 EXPECT_TRUE(File::Exists(saved_file_path_));
766 VerifyExpectedSavedFilePath(kTempDirectory);
767
768 EXPECT_STRNE(first_saved_file_path, saved_file_path_);
769
770 EXPECT_HRESULT_SUCCEEDED(lock.Unlock());
771
772 bool is_deleted = false;
773 for (int tries = 0; tries < 100 && !is_deleted; ++tries) {
774 ::Sleep(50);
775 is_deleted = !!::DeleteFile(saved_file_path_);
776 }
777 EXPECT_TRUE(is_deleted);
778
779 EXPECT_TRUE(::DeleteFile(first_saved_file_path));
780 EXPECT_TRUE(::DeleteFile(saved_arguments_path));
781
782 EXPECT_TRUE(::SetEnvironmentVariable(_T("TMP"), prev_tmp));
783 }
784
785 //
786 // VerifyFileSignature Tests
787 //
788 TEST_F(GoogleUpdateRecoveryTest, VerifyFileSignature_SignedValid) {
789 CString executable_full_path(app_util::GetCurrentModuleDirectory());
790 EXPECT_TRUE(::PathAppend(CStrBuf(executable_full_path, MAX_PATH),
791 kArgumentSavingExecutableRelativePath));
792 EXPECT_TRUE(File::Exists(executable_full_path));
793 EXPECT_HRESULT_SUCCEEDED(VerifyFileSignature(executable_full_path));
794 }
795
796 TEST_F(GoogleUpdateRecoveryTest, VerifyFileSignature_NotSigned) {
797 const TCHAR kUnsignedExecutable[] = _T("GoogleUpdate_unsigned.exe");
798
799 CString executable_full_path(app_util::GetCurrentModuleDirectory());
800 EXPECT_TRUE(::PathAppend(CStrBuf(executable_full_path, MAX_PATH),
801 kUnsignedExecutable));
802 EXPECT_TRUE(File::Exists(executable_full_path));
803 EXPECT_EQ(TRUST_E_NOSIGNATURE, VerifyFileSignature(executable_full_path));
804 }
805
806 // The certificate is still valid, but the executable was signed more than N
807 // days ago.
808 TEST_F(GoogleUpdateRecoveryTest, VerifyFileSignature_SignedOldWithValidCert) {
809 const TCHAR kRelativePath[] =
810 _T("unittest_support\\GoogleUpdate_old_signature.exe");
811
812 CString executable_full_path(app_util::GetCurrentModuleDirectory());
813 EXPECT_TRUE(::PathAppend(CStrBuf(executable_full_path, MAX_PATH),
814 kRelativePath));
815 EXPECT_TRUE(File::Exists(executable_full_path));
816 EXPECT_EQ(TRUST_E_TIME_STAMP, VerifyFileSignature(executable_full_path));
817 }
818
819 // The certificate was valid when it was used to sign the executable, but it has
820 // since expired.
821 // TRUST_E_TIME_STAMP is returned because the file was signed more than the
822 // allowable number of dates ago for the repair file. Otherwise, the signature
823 // is fine.
824 TEST_F(GoogleUpdateRecoveryTest, VerifyFileSignature_SignedWithNowExpiredCert) {
825 const TCHAR kRelativePath[] =
826 _T("unittest_support\\GoogleUpdate_now_expired_cert.exe");
827
828 CString executable_full_path(app_util::GetCurrentModuleDirectory());
829 EXPECT_TRUE(::PathAppend(CStrBuf(executable_full_path, MAX_PATH),
830 kRelativePath));
831 EXPECT_TRUE(File::Exists(executable_full_path));
832 EXPECT_EQ(TRUST_E_TIME_STAMP, VerifyFileSignature(executable_full_path));
833 }
834
835 TEST_F(GoogleUpdateRecoveryTest, VerifyFileSignature_UntrustedChain) {
836 const TCHAR kUntrustedChainExecutable[] =
837 _T("unittest_support\\SaveArguments_OmahaTestSigned.exe");
838
839 CString executable_full_path(app_util::GetCurrentModuleDirectory());
840 EXPECT_TRUE(::PathAppend(CStrBuf(executable_full_path, MAX_PATH),
841 kUntrustedChainExecutable));
842 EXPECT_TRUE(File::Exists(executable_full_path));
843 EXPECT_EQ(CERT_E_UNTRUSTEDROOT, VerifyFileSignature(executable_full_path));
844 }
845
846 TEST_F(GoogleUpdateRecoveryTest, VerifyFileSignature_HashFails) {
847 const TCHAR kCorruptedExecutable[] =
848 _T("unittest_support\\GoogleUpdate_corrupted.exe");
849
850 CString executable_full_path(app_util::GetCurrentModuleDirectory());
851 EXPECT_TRUE(::PathAppend(CStrBuf(executable_full_path, MAX_PATH),
852 kCorruptedExecutable));
853 EXPECT_TRUE(File::Exists(executable_full_path));
854 EXPECT_EQ(TRUST_E_BAD_DIGEST, VerifyFileSignature(executable_full_path));
855 }
856
857 // The file for Windows Vista and later may not exist on all systems.
858 TEST_F(GoogleUpdateRecoveryTest,
859 VerifyFileSignature_NonGoogleSignature) {
860 CString file_path = SystemInfo::IsRunningOnVistaOrLater() ?
861 _T("%SYSTEM%\\rcagent.exe") : _T("%SYSTEM%\\wuauclt.exe");
862 if (!File::Exists(file_path) && SystemInfo::IsRunningOnVistaOrLater()) {
863 std::wcout << _T("\tTest did not run because '") << file_path
864 << _T("' was not found.") << std::endl;
865 return;
866 }
867 EXPECT_HRESULT_SUCCEEDED(ExpandStringWithSpecialFolders(&file_path));
868 EXPECT_TRUE(File::Exists(file_path));
869 EXPECT_TRUE(SignatureIsValid(file_path, false));
870 EXPECT_EQ(CERT_E_CN_NO_MATCH, VerifyFileSignature(file_path));
871 }
872
873 TEST_F(GoogleUpdateRecoveryTest, VerifyFileSignature_BadFilenames) {
874 EXPECT_EQ(CRYPT_E_FILE_ERROR, VerifyFileSignature(_T("NoSuchFile.exe")));
875
876 EXPECT_EQ(CRYPT_E_FILE_ERROR, VerifyFileSignature(NULL));
877
878 EXPECT_EQ(CRYPT_E_FILE_ERROR, VerifyFileSignature(_T("")));
879 }
880
881 //
882 // VerifyRepairFileMarkup Tests
883 //
884 TEST_F(GoogleUpdateRecoveryTest, VerifyRepairFileMarkup_ValidMarkup) {
885 const TCHAR kExecutableWithMarkup[] =
886 _T("unittest_support\\SaveArguments.exe");
887 EXPECT_HRESULT_SUCCEEDED(VerifyRepairFileMarkup(kExecutableWithMarkup));
888 }
889
890 TEST_F(GoogleUpdateRecoveryTest, VerifyRepairFileMarkup_InvalidMarkups) {
891 const TCHAR kNoResourcesExecutable[] =
892 _T("unittest_support\\SaveArguments_unsigned_no_resources.exe");
893 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_RESOURCE_DATA_NOT_FOUND),
894 VerifyRepairFileMarkup(kNoResourcesExecutable));
895
896 const TCHAR kResourcesButNoMarkupExecutable[] = _T("GoogleUpdate.exe");
897 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND),
898 VerifyRepairFileMarkup(kResourcesButNoMarkupExecutable));
899
900 const TCHAR kWrongMarkupResourceNameExecutable[] =
901 _T("unittest_support\\SaveArguments_unsigned_wrong_resource_name.exe");
902 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_RESOURCE_NAME_NOT_FOUND),
903 VerifyRepairFileMarkup(kWrongMarkupResourceNameExecutable));
904
905 const TCHAR kWrongMarkupSizeExecutable[] =
906 _T("unittest_support\\SaveArguments_unsigned_wrong_markup_size.exe");
907 EXPECT_EQ(E_UNEXPECTED, VerifyRepairFileMarkup(kWrongMarkupSizeExecutable));
908
909 const TCHAR kWrongMarkupValueExecutable[] =
910 _T("unittest_support\\SaveArguments_unsigned_wrong_markup_value.exe");
911 EXPECT_EQ(E_UNEXPECTED, VerifyRepairFileMarkup(kWrongMarkupValueExecutable));
912 }
913
914 TEST_F(GoogleUpdateRecoveryTest, VerifyRepairFileMarkup_BadFilenames) {
915 const TCHAR kMissingFile[] = _T("NoSuchFile.exe");
916 EXPECT_EQ(FALSE, ::PathFileExists(kMissingFile));
917 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
918 VerifyRepairFileMarkup(kMissingFile));
919 EXPECT_HRESULT_FAILED(VerifyRepairFileMarkup(_T("")));
920 }
921
922 //
923 // VerifyRepairFileMarkup Tests
924 //
925 // TODO(omaha): Unit test VerifyIsValidRepairFile.
926
927 //
928 // Production Server Response Tests Tests
929 //
930 TEST_F(GoogleUpdateRecoveryTest, ProductionServerResponseTest) {
931 EXPECT_EQ(kDummyNoFileError, FixGoogleUpdate(kDummyAppGuid,
932 kDummyAppVersion,
933 kDummyAppLang,
934 true,
935 DownloadFileFromServer,
936 NULL)) <<
937 _T("The production server did not return 204. This may indicate network ")
938 _T("issues or that the Code Red server is configured incorrectly");
939 }
940
941 } // namespace omaha
942
OLDNEW
« no previous file with comments | « recovery/client/google_update_recovery.cc ('k') | recovery/lib/bin/dbg/google_update_recovery.lib » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698