OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ssl/ssl_error_handler.h" | 5 #include "chrome/browser/ssl/ssl_error_handler.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
11 #include "base/time/time.h" | 11 #include "base/time/time.h" |
12 #include "chrome/browser/captive_portal/captive_portal_service.h" | 12 #include "chrome/browser/captive_portal/captive_portal_service.h" |
13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
14 #include "chrome/browser/ssl/common_name_mismatch_handler.h" | |
14 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 15 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
15 #include "chrome/test/base/testing_profile.h" | 16 #include "chrome/test/base/testing_profile.h" |
16 #include "components/captive_portal/captive_portal_testing_utils.h" | 17 #include "components/captive_portal/captive_portal_testing_utils.h" |
17 #include "content/public/browser/notification_service.h" | 18 #include "content/public/browser/notification_service.h" |
18 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
20 #include "net/base/test_data_directory.h" | |
21 #include "net/cert/x509_certificate.h" | |
19 #include "net/ssl/ssl_info.h" | 22 #include "net/ssl/ssl_info.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "net/test/cert_test_util.h" |
davidben
2015/08/17 18:59:19
This include should still be there due to IWYU.
Bhanu Dev
2015/08/18 05:09:10
Done.
| |
24 #include "net/test/test_certificate_data.h" | |
21 | 25 |
22 class TestSSLErrorHandler : public SSLErrorHandler { | 26 class TestSSLErrorHandler : public SSLErrorHandler { |
23 public: | 27 public: |
24 TestSSLErrorHandler(Profile* profile, | 28 TestSSLErrorHandler(Profile* profile, |
25 content::WebContents* web_contents, | 29 content::WebContents* web_contents, |
26 const net::SSLInfo& ssl_info) | 30 const net::SSLInfo& ssl_info) |
27 : SSLErrorHandler(web_contents, | 31 : SSLErrorHandler(web_contents, |
28 net::ERR_CERT_COMMON_NAME_INVALID, | 32 net::ERR_CERT_COMMON_NAME_INVALID, |
29 ssl_info, | 33 ssl_info, |
30 GURL(), | 34 GURL(), |
31 0, | 35 0, |
32 nullptr, | 36 nullptr, |
33 base::Callback<void(bool)>()), | 37 base::Callback<void(bool)>()), |
34 profile_(profile), | 38 profile_(profile), |
35 captive_portal_checked_(false), | 39 captive_portal_checked_(false), |
40 suggested_url_exists_(false), | |
41 suggested_url_checked_(false), | |
36 ssl_interstitial_shown_(false), | 42 ssl_interstitial_shown_(false), |
37 captive_portal_interstitial_shown_(false) {} | 43 captive_portal_interstitial_shown_(false), |
44 common_name_mismatch_redirect_(false) {} | |
38 | 45 |
39 ~TestSSLErrorHandler() override { | 46 ~TestSSLErrorHandler() override { |
40 } | 47 } |
41 | 48 |
42 using SSLErrorHandler::StartHandlingError; | 49 using SSLErrorHandler::StartHandlingError; |
43 | 50 |
44 void SendCaptivePortalNotification( | 51 void SendCaptivePortalNotification( |
45 captive_portal::CaptivePortalResult result) { | 52 captive_portal::CaptivePortalResult result) { |
46 CaptivePortalService::Results results; | 53 CaptivePortalService::Results results; |
47 results.previous_result = captive_portal::RESULT_INTERNET_CONNECTED; | 54 results.previous_result = captive_portal::RESULT_INTERNET_CONNECTED; |
48 results.result = result; | 55 results.result = result; |
49 content::NotificationService::current()->Notify( | 56 content::NotificationService::current()->Notify( |
50 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT, | 57 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT, |
51 content::Source<Profile>(profile_), | 58 content::Source<Profile>(profile_), |
52 content::Details<CaptivePortalService::Results>(&results)); | 59 content::Details<CaptivePortalService::Results>(&results)); |
53 } | 60 } |
54 | 61 |
62 void SendSuggestedUrlCheckResult( | |
63 const CommonNameMismatchHandler::SuggestedUrlCheckResult& result, | |
64 const GURL& suggested_url) { | |
65 CommonNameMismatchHandlerCallback(result, suggested_url); | |
66 } | |
67 | |
55 bool IsTimerRunning() const { | 68 bool IsTimerRunning() const { |
56 return get_timer().IsRunning(); | 69 return get_timer().IsRunning(); |
57 } | 70 } |
58 | 71 |
59 int captive_portal_checked() const { | 72 int captive_portal_checked() const { |
60 return captive_portal_checked_; | 73 return captive_portal_checked_; |
61 } | 74 } |
62 | 75 |
63 int ssl_interstitial_shown() const { | 76 int ssl_interstitial_shown() const { |
64 return ssl_interstitial_shown_; | 77 return ssl_interstitial_shown_; |
65 } | 78 } |
66 | 79 |
67 int captive_portal_interstitial_shown() const { | 80 int captive_portal_interstitial_shown() const { |
68 return captive_portal_interstitial_shown_; | 81 return captive_portal_interstitial_shown_; |
69 } | 82 } |
70 | 83 |
84 void SetSuggestedUrlExists(bool suggested_url_exists) { | |
85 suggested_url_exists_ = suggested_url_exists; | |
86 } | |
87 | |
88 bool GetSuggestedUrl(const std::vector<std::string>& dns_names, | |
89 GURL* suggested_url) const override { | |
90 if (!suggested_url_exists_) | |
91 return false; | |
92 *suggested_url = GURL("www.example.com"); | |
93 return true; | |
94 } | |
95 | |
96 bool suggested_url_checked() const { return suggested_url_checked_; } | |
97 | |
98 bool common_name_mismatch_redirect() const { | |
99 return common_name_mismatch_redirect_; | |
100 } | |
101 | |
71 void Reset() { | 102 void Reset() { |
72 captive_portal_checked_ = false; | 103 captive_portal_checked_ = false; |
104 suggested_url_exists_ = false; | |
105 suggested_url_checked_ = false; | |
73 ssl_interstitial_shown_ = false; | 106 ssl_interstitial_shown_ = false; |
74 captive_portal_interstitial_shown_ = false; | 107 captive_portal_interstitial_shown_ = false; |
108 common_name_mismatch_redirect_ = false; | |
75 } | 109 } |
76 | 110 |
77 private: | 111 private: |
78 void CheckForCaptivePortal() override { | 112 void CheckForCaptivePortal() override { |
79 captive_portal_checked_ = true; | 113 captive_portal_checked_ = true; |
80 } | 114 } |
81 | 115 |
82 void ShowSSLInterstitial() override { | 116 void ShowSSLInterstitial() override { ssl_interstitial_shown_ = true; } |
83 ssl_interstitial_shown_ = true; | |
84 } | |
85 | 117 |
86 void ShowCaptivePortalInterstitial(const GURL& landing_url) override { | 118 void ShowCaptivePortalInterstitial(const GURL& landing_url) override { |
87 captive_portal_interstitial_shown_ = true; | 119 captive_portal_interstitial_shown_ = true; |
88 } | 120 } |
89 | 121 |
122 void CheckSuggestedUrl(const GURL& suggested_url) override { | |
123 suggested_url_checked_ = true; | |
124 } | |
125 | |
126 void NavigateToSuggestedURL(const GURL& suggested_url) override { | |
127 common_name_mismatch_redirect_ = true; | |
128 } | |
129 | |
90 Profile* profile_; | 130 Profile* profile_; |
91 bool captive_portal_checked_; | 131 bool captive_portal_checked_; |
132 bool suggested_url_exists_; | |
133 bool suggested_url_checked_; | |
92 bool ssl_interstitial_shown_; | 134 bool ssl_interstitial_shown_; |
93 bool captive_portal_interstitial_shown_; | 135 bool captive_portal_interstitial_shown_; |
136 bool common_name_mismatch_redirect_; | |
94 | 137 |
95 DISALLOW_COPY_AND_ASSIGN(TestSSLErrorHandler); | 138 DISALLOW_COPY_AND_ASSIGN(TestSSLErrorHandler); |
96 }; | 139 }; |
97 | 140 |
98 class SSLErrorHandlerTest : public ChromeRenderViewHostTestHarness { | 141 class SSLErrorHandlerTest : public ChromeRenderViewHostTestHarness { |
99 public: | 142 public: |
100 SSLErrorHandlerTest() | 143 SSLErrorHandlerTest() |
101 : field_trial_list_(NULL) { | 144 : field_trial_list_(NULL) { |
102 } | 145 } |
103 | 146 |
104 void SetUp() override { | 147 void SetUp() override { |
105 ChromeRenderViewHostTestHarness::SetUp(); | 148 ChromeRenderViewHostTestHarness::SetUp(); |
106 SSLErrorHandler::SetInterstitialDelayTypeForTest(SSLErrorHandler::NONE); | 149 SSLErrorHandler::SetInterstitialDelayTypeForTest(SSLErrorHandler::NONE); |
150 ssl_info_.cert = | |
151 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); | |
152 ssl_info_.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID; | |
107 error_handler_.reset(new TestSSLErrorHandler(profile(), | 153 error_handler_.reset(new TestSSLErrorHandler(profile(), |
108 web_contents(), | 154 web_contents(), |
109 ssl_info_)); | 155 ssl_info_)); |
110 // Enable finch experiment for captive portal interstitials. | 156 // Enable finch experiment for captive portal interstitials. |
111 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( | 157 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( |
112 "CaptivePortalInterstitial", "Enabled")); | 158 "CaptivePortalInterstitial", "Enabled")); |
113 } | 159 } |
114 | 160 |
115 void TearDown() override { | 161 void TearDown() override { |
116 EXPECT_FALSE(error_handler()->IsTimerRunning()); | 162 EXPECT_FALSE(error_handler()->IsTimerRunning()); |
117 error_handler_.reset(NULL); | 163 error_handler_.reset(NULL); |
118 ChromeRenderViewHostTestHarness::TearDown(); | 164 ChromeRenderViewHostTestHarness::TearDown(); |
119 } | 165 } |
120 | 166 |
121 TestSSLErrorHandler* error_handler() { return error_handler_.get(); } | 167 TestSSLErrorHandler* error_handler() { return error_handler_.get(); } |
122 | 168 |
123 private: | 169 private: |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
184 error_handler()->SendCaptivePortalNotification( | 230 error_handler()->SendCaptivePortalNotification( |
185 captive_portal::RESULT_INTERNET_CONNECTED); | 231 captive_portal::RESULT_INTERNET_CONNECTED); |
186 base::MessageLoop::current()->RunUntilIdle(); | 232 base::MessageLoop::current()->RunUntilIdle(); |
187 | 233 |
188 EXPECT_FALSE(error_handler()->IsTimerRunning()); | 234 EXPECT_FALSE(error_handler()->IsTimerRunning()); |
189 EXPECT_FALSE(error_handler()->captive_portal_checked()); | 235 EXPECT_FALSE(error_handler()->captive_portal_checked()); |
190 EXPECT_TRUE(error_handler()->ssl_interstitial_shown()); | 236 EXPECT_TRUE(error_handler()->ssl_interstitial_shown()); |
191 EXPECT_FALSE(error_handler()->captive_portal_interstitial_shown()); | 237 EXPECT_FALSE(error_handler()->captive_portal_interstitial_shown()); |
192 } | 238 } |
193 | 239 |
240 TEST_F(SSLErrorHandlerTest, ShouldNotCheckSuggestedUrlIfNoSuggestedUrl) { | |
241 error_handler()->SetSuggestedUrlExists(false); | |
242 error_handler()->StartHandlingError(); | |
243 | |
244 EXPECT_TRUE(error_handler()->IsTimerRunning()); | |
davidben
2015/08/17 18:59:19
To confirm, the timer is running due to the captiv
Bhanu Dev
2015/08/18 05:09:10
Done.
| |
245 EXPECT_FALSE(error_handler()->suggested_url_checked()); | |
246 base::RunLoop().RunUntilIdle(); | |
247 | |
248 EXPECT_FALSE(error_handler()->IsTimerRunning()); | |
249 EXPECT_TRUE(error_handler()->ssl_interstitial_shown()); | |
250 } | |
251 | |
252 TEST_F(SSLErrorHandlerTest, ShouldNotCheckCaptivePortalIfSuggestedUrlExists) { | |
253 EXPECT_FALSE(error_handler()->IsTimerRunning()); | |
254 error_handler()->SetSuggestedUrlExists(true); | |
255 error_handler()->StartHandlingError(); | |
256 | |
257 EXPECT_TRUE(error_handler()->IsTimerRunning()); | |
258 EXPECT_TRUE(error_handler()->suggested_url_checked()); | |
259 EXPECT_FALSE(error_handler()->captive_portal_checked()); | |
260 base::RunLoop().RunUntilIdle(); | |
261 | |
262 EXPECT_FALSE(error_handler()->IsTimerRunning()); | |
263 EXPECT_TRUE(error_handler()->ssl_interstitial_shown()); | |
264 } | |
265 | |
194 #else // #if !defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | 266 #else // #if !defined(ENABLE_CAPTIVE_PORTAL_DETECTION) |
195 | 267 |
196 TEST_F(SSLErrorHandlerTest, | 268 TEST_F(SSLErrorHandlerTest, |
197 ShouldShowSSLInterstitialOnCaptivePortalDetectionDisabled) { | 269 ShouldShowSSLInterstitialOnCaptivePortalDetectionDisabled) { |
198 EXPECT_FALSE(error_handler()->IsTimerRunning()); | 270 EXPECT_FALSE(error_handler()->IsTimerRunning()); |
271 error_handler()->SetSuggestedUrlExists(false); | |
199 error_handler()->StartHandlingError(); | 272 error_handler()->StartHandlingError(); |
200 EXPECT_FALSE(error_handler()->IsTimerRunning()); | 273 EXPECT_FALSE(error_handler()->IsTimerRunning()); |
201 EXPECT_FALSE(error_handler()->captive_portal_checked()); | 274 EXPECT_FALSE(error_handler()->captive_portal_checked()); |
202 EXPECT_TRUE(error_handler()->ssl_interstitial_shown()); | 275 EXPECT_TRUE(error_handler()->ssl_interstitial_shown()); |
203 EXPECT_FALSE(error_handler()->captive_portal_interstitial_shown()); | 276 EXPECT_FALSE(error_handler()->captive_portal_interstitial_shown()); |
204 } | 277 } |
205 | 278 |
206 #endif // defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | 279 #endif // defined(ENABLE_CAPTIVE_PORTAL_DETECTION) |
280 | |
281 TEST_F(SSLErrorHandlerTest, | |
282 ShouldShowSSLInterstitialOnTimerExpiredWhenSuggestedUrlExists) { | |
283 error_handler()->SetSuggestedUrlExists(true); | |
284 error_handler()->StartHandlingError(); | |
285 | |
286 EXPECT_TRUE(error_handler()->IsTimerRunning()); | |
287 EXPECT_TRUE(error_handler()->suggested_url_checked()); | |
288 EXPECT_FALSE(error_handler()->ssl_interstitial_shown()); | |
289 EXPECT_FALSE(error_handler()->common_name_mismatch_redirect()); | |
290 | |
291 base::RunLoop().RunUntilIdle(); | |
292 | |
293 EXPECT_FALSE(error_handler()->IsTimerRunning()); | |
294 EXPECT_TRUE(error_handler()->ssl_interstitial_shown()); | |
295 EXPECT_FALSE(error_handler()->common_name_mismatch_redirect()); | |
296 } | |
297 | |
298 TEST_F(SSLErrorHandlerTest, ShouldRedirectOnSuggestedUrlCheckResult) { | |
299 error_handler()->SetSuggestedUrlExists(true); | |
300 error_handler()->StartHandlingError(); | |
301 | |
302 EXPECT_TRUE(error_handler()->IsTimerRunning()); | |
303 EXPECT_TRUE(error_handler()->suggested_url_checked()); | |
304 EXPECT_FALSE(error_handler()->ssl_interstitial_shown()); | |
305 EXPECT_FALSE(error_handler()->common_name_mismatch_redirect()); | |
306 // Fake a valid suggested URL check result. | |
307 // The URL returned by |SuggestedUrlCheckResult| can be different from | |
308 // |suggested_url|, if there is a redirect. | |
309 error_handler()->SendSuggestedUrlCheckResult( | |
310 CommonNameMismatchHandler::SuggestedUrlCheckResult:: | |
311 SUGGESTED_URL_AVAILABLE, | |
312 GURL("https://random.example.com")); | |
313 | |
314 EXPECT_FALSE(error_handler()->IsTimerRunning()); | |
315 EXPECT_FALSE(error_handler()->ssl_interstitial_shown()); | |
316 EXPECT_TRUE(error_handler()->common_name_mismatch_redirect()); | |
317 } | |
318 | |
319 TEST_F(SSLErrorHandlerTest, ShouldShowSSLInterstitialOnInvalidUrlCheckResult) { | |
320 error_handler()->SetSuggestedUrlExists(true); | |
321 error_handler()->StartHandlingError(); | |
322 | |
323 EXPECT_TRUE(error_handler()->IsTimerRunning()); | |
324 EXPECT_TRUE(error_handler()->suggested_url_checked()); | |
325 EXPECT_FALSE(error_handler()->ssl_interstitial_shown()); | |
326 EXPECT_FALSE(error_handler()->common_name_mismatch_redirect()); | |
327 // Fake an Invalid Suggested URL Check result. | |
328 error_handler()->SendSuggestedUrlCheckResult( | |
329 CommonNameMismatchHandler::SuggestedUrlCheckResult:: | |
330 SUGGESTED_URL_NOT_AVAILABLE, | |
331 GURL()); | |
332 | |
333 EXPECT_FALSE(error_handler()->IsTimerRunning()); | |
334 EXPECT_TRUE(error_handler()->ssl_interstitial_shown()); | |
335 EXPECT_FALSE(error_handler()->common_name_mismatch_redirect()); | |
336 } | |
OLD | NEW |