Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/chrome_security_state_model_client.h" | 5 #include "chrome/browser/ssl/chrome_security_state_model_client.h" |
| 6 | 6 |
| 7 #include <openssl/ssl.h> | 7 #include <openssl/ssl.h> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1115 security_info.security_level); | 1115 security_info.security_level); |
| 1116 | 1116 |
| 1117 // The SSLStatus flags should only be set if the top-level page load was HTTP, | 1117 // The SSLStatus flags should only be set if the top-level page load was HTTP, |
| 1118 // which it was not in this case. | 1118 // which it was not in this case. |
| 1119 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); | 1119 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| 1120 ASSERT_TRUE(entry); | 1120 ASSERT_TRUE(entry); |
| 1121 EXPECT_FALSE(entry->GetSSL().content_status & | 1121 EXPECT_FALSE(entry->GetSSL().content_status & |
| 1122 content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); | 1122 content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
| 1123 } | 1123 } |
| 1124 | 1124 |
| 1125 // A Browser subclass that keeps track of messages that have been | |
| 1126 // added to the console. Messages can be retrieved or cleared with | |
| 1127 // console_messages() and ClearConsoleMessages(). The user of this class | |
| 1128 // can set a callback to run when the next console message notification | |
| 1129 // arrives. | |
| 1130 class ConsoleWebContentsDelegate : public Browser { | |
| 1131 public: | |
| 1132 explicit ConsoleWebContentsDelegate(const Browser::CreateParams& params) | |
| 1133 : Browser(params) {} | |
| 1134 ~ConsoleWebContentsDelegate() override {} | |
| 1135 | |
| 1136 const std::vector<base::string16>& console_messages() const { | |
| 1137 return console_messages_; | |
| 1138 } | |
| 1139 | |
| 1140 void set_console_message_callback(const base::Closure& callback) { | |
| 1141 console_message_callback_ = callback; | |
| 1142 } | |
| 1143 | |
| 1144 void ClearConsoleMessages() { console_messages_.clear(); } | |
| 1145 | |
| 1146 // content::WebContentsDelegate | |
| 1147 bool AddMessageToConsole(content::WebContents* source, | |
| 1148 int32_t level, | |
| 1149 const base::string16& message, | |
| 1150 int32_t line_no, | |
| 1151 const base::string16& source_id) override { | |
| 1152 console_messages_.push_back(message); | |
| 1153 if (!console_message_callback_.is_null()) { | |
| 1154 console_message_callback_.Run(); | |
| 1155 console_message_callback_.Reset(); | |
| 1156 } | |
| 1157 return true; | |
| 1158 } | |
| 1159 | |
| 1160 private: | |
| 1161 std::vector<base::string16> console_messages_; | |
| 1162 base::Closure console_message_callback_; | |
| 1163 | |
| 1164 DISALLOW_COPY_AND_ASSIGN(ConsoleWebContentsDelegate); | |
| 1165 }; | |
| 1166 | |
| 1167 // Checks that |delegate| has observed exactly one console message for | |
| 1168 // HTTP_SHOW_WARNING. This does not check for the exact string (for fear | |
| 1169 // of being too brittle) but rather just a keyword ("not secure"). | |
| 1170 void CheckForOneHttpWarningConsoleMessage( | |
| 1171 ConsoleWebContentsDelegate* delegate) { | |
| 1172 const std::vector<base::string16>& messages = delegate->console_messages(); | |
| 1173 ASSERT_EQ(1u, messages.size()); | |
| 1174 EXPECT_NE(base::string16::npos, | |
| 1175 messages[0].find(base::ASCIIToUTF16("not secure"))); | |
| 1176 } | |
| 1177 | |
| 1178 // Tests that console messages are printed upon a call to | |
| 1179 // GetSecurityInfo() on an HTTP_SHOW_WARNING page, exactly once per | |
| 1180 // main-frame navigation. | |
| 1181 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, | |
| 1182 ConsoleMessage) { | |
| 1183 ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( | |
| 1184 Browser::CreateParams(browser()->profile())); | |
| 1185 content::WebContents* original_contents = | |
| 1186 browser()->tab_strip_model()->GetActiveWebContents(); | |
| 1187 content::WebContents* contents = | |
| 1188 content::WebContents::Create(content::WebContents::CreateParams( | |
| 1189 original_contents->GetBrowserContext())); | |
| 1190 ASSERT_TRUE(contents); | |
| 1191 contents->SetDelegate(delegate); | |
| 1192 delegate->tab_strip_model()->AppendWebContents(contents, true); | |
| 1193 int index = delegate->tab_strip_model()->GetIndexOfWebContents(contents); | |
| 1194 delegate->tab_strip_model()->ActivateTabAt(index, true); | |
| 1195 ASSERT_EQ(contents, delegate->tab_strip_model()->GetActiveWebContents()); | |
| 1196 | |
| 1197 // Navigate to an HTTP page. Use a non-local hostname so that is it | |
| 1198 // not considered secure. | |
| 1199 GURL http_url = | |
| 1200 GetURLWithNonLocalHostname(embedded_test_server(), "/title1.html"); | |
| 1201 ui_test_utils::NavigateToURL(delegate, http_url); | |
| 1202 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); | |
| 1203 ASSERT_TRUE(entry); | |
| 1204 EXPECT_EQ(http_url, entry->GetURL()); | |
| 1205 EXPECT_TRUE(delegate->console_messages().empty()); | |
| 1206 | |
| 1207 // Trigger the HTTP_SHOW_WARNING state. | |
| 1208 base::RunLoop first_message; | |
| 1209 delegate->set_console_message_callback(first_message.QuitClosure()); | |
| 1210 contents->OnPasswordInputShownOnHttp(); | |
| 1211 first_message.Run(); | |
| 1212 | |
| 1213 // Check that the HTTP_SHOW_WARNING state was actually triggered. | |
| 1214 ChromeSecurityStateModelClient* client = | |
| 1215 ChromeSecurityStateModelClient::FromWebContents(contents); | |
| 1216 ASSERT_TRUE(client); | |
| 1217 security_state::SecurityStateModel::SecurityInfo security_info; | |
| 1218 client->GetSecurityInfo(&security_info); | |
| 1219 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, | |
| 1220 security_info.security_level); | |
| 1221 | |
| 1222 // Check that the expected console message is present. | |
| 1223 ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); | |
| 1224 delegate->ClearConsoleMessages(); | |
| 1225 | |
| 1226 // Two subsequent triggers of VisibleSSLStateChanged -- one on the | |
| 1227 // same navigation and one on another navigation -- should only result | |
| 1228 // in one additional console message. | |
| 1229 contents->OnCreditCardInputShownOnHttp(); | |
| 1230 GURL second_http_url = | |
| 1231 GetURLWithNonLocalHostname(embedded_test_server(), "/title2.html"); | |
| 1232 ui_test_utils::NavigateToURL(delegate, second_http_url); | |
| 1233 entry = contents->GetController().GetVisibleEntry(); | |
| 1234 ASSERT_TRUE(entry); | |
| 1235 EXPECT_EQ(second_http_url, entry->GetURL()); | |
| 1236 | |
| 1237 base::RunLoop second_message; | |
| 1238 delegate->set_console_message_callback(second_message.QuitClosure()); | |
| 1239 contents->OnPasswordInputShownOnHttp(); | |
| 1240 second_message.Run(); | |
| 1241 | |
| 1242 client->GetSecurityInfo(&security_info); | |
| 1243 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, | |
| 1244 security_info.security_level); | |
| 1245 | |
| 1246 ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); | |
| 1247 } | |
| 1248 | |
| 1249 // Tests that additional HTTP_SHOW_WARNING console messages are not | |
| 1250 // printed after subframe navigations. | |
| 1251 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, | |
|
sky
2016/10/14 22:21:47
Wow, this sure is a lot of test code for a simple
estark
2016/10/14 23:50:01
I couldn't figure out how to do them as unit tests
| |
| 1252 ConsoleMessageNotPrintedForFrameNavigation) { | |
| 1253 ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( | |
| 1254 Browser::CreateParams(browser()->profile())); | |
| 1255 content::WebContents* original_contents = | |
| 1256 browser()->tab_strip_model()->GetActiveWebContents(); | |
| 1257 content::WebContents* contents = | |
| 1258 content::WebContents::Create(content::WebContents::CreateParams( | |
| 1259 original_contents->GetBrowserContext())); | |
| 1260 ASSERT_TRUE(contents); | |
| 1261 contents->SetDelegate(delegate); | |
| 1262 delegate->tab_strip_model()->AppendWebContents(contents, true); | |
| 1263 int index = delegate->tab_strip_model()->GetIndexOfWebContents(contents); | |
| 1264 delegate->tab_strip_model()->ActivateTabAt(index, true); | |
| 1265 ASSERT_EQ(contents, delegate->tab_strip_model()->GetActiveWebContents()); | |
| 1266 | |
| 1267 // Navigate to an HTTP page. Use a non-local hostname so that is it | |
| 1268 // not considered secure. | |
| 1269 GURL http_url = GetURLWithNonLocalHostname(embedded_test_server(), | |
| 1270 "/ssl/page_with_frame.html"); | |
| 1271 ui_test_utils::NavigateToURL(delegate, http_url); | |
| 1272 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); | |
| 1273 ASSERT_TRUE(entry); | |
| 1274 EXPECT_EQ(http_url, entry->GetURL()); | |
| 1275 EXPECT_TRUE(delegate->console_messages().empty()); | |
| 1276 | |
| 1277 // Trigger the HTTP_SHOW_WARNING state. | |
| 1278 base::RunLoop first_message; | |
| 1279 delegate->set_console_message_callback(first_message.QuitClosure()); | |
| 1280 contents->OnPasswordInputShownOnHttp(); | |
| 1281 first_message.Run(); | |
| 1282 | |
| 1283 // Check that the HTTP_SHOW_WARNING state was actually triggered. | |
| 1284 ChromeSecurityStateModelClient* client = | |
| 1285 ChromeSecurityStateModelClient::FromWebContents(contents); | |
| 1286 ASSERT_TRUE(client); | |
| 1287 security_state::SecurityStateModel::SecurityInfo security_info; | |
| 1288 client->GetSecurityInfo(&security_info); | |
| 1289 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, | |
| 1290 security_info.security_level); | |
| 1291 | |
| 1292 // Check that the expected console message is present. | |
| 1293 ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); | |
| 1294 delegate->ClearConsoleMessages(); | |
| 1295 | |
| 1296 // Navigate the subframe and trigger VisibleSSLStateChanged | |
| 1297 // again. While the security level is still HTTP_SHOW_WARNING, an | |
| 1298 // additional console message should not be logged because there was | |
| 1299 // already a console message logged for the current main-frame | |
| 1300 // navigation. | |
| 1301 content::WindowedNotificationObserver subframe_observer( | |
| 1302 content::NOTIFICATION_LOAD_STOP, | |
| 1303 content::Source<content::NavigationController>( | |
| 1304 &contents->GetController())); | |
| 1305 EXPECT_TRUE(content::ExecuteScript( | |
| 1306 contents, "document.getElementById('navFrame').src = '/title2.html';")); | |
| 1307 subframe_observer.Wait(); | |
| 1308 contents->OnCreditCardInputShownOnHttp(); | |
| 1309 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, | |
| 1310 security_info.security_level); | |
| 1311 | |
| 1312 // Do a main frame navigation and then trigger HTTP_SHOW_WARNING | |
| 1313 // again. From the above subframe navigation and this main-frame | |
| 1314 // navigation, exactly one console message is expected. | |
| 1315 GURL second_http_url = | |
| 1316 GetURLWithNonLocalHostname(embedded_test_server(), "/title2.html"); | |
| 1317 ui_test_utils::NavigateToURL(delegate, second_http_url); | |
| 1318 entry = contents->GetController().GetVisibleEntry(); | |
| 1319 ASSERT_TRUE(entry); | |
| 1320 EXPECT_EQ(second_http_url, entry->GetURL()); | |
| 1321 | |
| 1322 base::RunLoop second_message; | |
| 1323 delegate->set_console_message_callback(second_message.QuitClosure()); | |
| 1324 contents->OnPasswordInputShownOnHttp(); | |
| 1325 second_message.Run(); | |
| 1326 | |
| 1327 client->GetSecurityInfo(&security_info); | |
| 1328 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, | |
| 1329 security_info.security_level); | |
| 1330 ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); | |
| 1331 } | |
| 1332 | |
| 1333 // Tests that additional HTTP_SHOW_WARNING console messages are not | |
| 1334 // printed after pushState navigations. | |
| 1335 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, | |
| 1336 ConsoleMessageNotPrintedForPushStateNavigation) { | |
| 1337 ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( | |
| 1338 Browser::CreateParams(browser()->profile())); | |
| 1339 content::WebContents* original_contents = | |
| 1340 browser()->tab_strip_model()->GetActiveWebContents(); | |
| 1341 content::WebContents* contents = | |
| 1342 content::WebContents::Create(content::WebContents::CreateParams( | |
| 1343 original_contents->GetBrowserContext())); | |
| 1344 ASSERT_TRUE(contents); | |
| 1345 contents->SetDelegate(delegate); | |
| 1346 delegate->tab_strip_model()->AppendWebContents(contents, true); | |
| 1347 int index = delegate->tab_strip_model()->GetIndexOfWebContents(contents); | |
| 1348 delegate->tab_strip_model()->ActivateTabAt(index, true); | |
| 1349 ASSERT_EQ(contents, delegate->tab_strip_model()->GetActiveWebContents()); | |
| 1350 | |
| 1351 // Navigate to an HTTP page. Use a non-local hostname so that is it | |
| 1352 // not considered secure. | |
| 1353 GURL http_url = | |
| 1354 GetURLWithNonLocalHostname(embedded_test_server(), "/title1.html"); | |
| 1355 ui_test_utils::NavigateToURL(delegate, http_url); | |
| 1356 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); | |
| 1357 ASSERT_TRUE(entry); | |
| 1358 EXPECT_EQ(http_url, entry->GetURL()); | |
| 1359 EXPECT_TRUE(delegate->console_messages().empty()); | |
| 1360 | |
| 1361 // Trigger the HTTP_SHOW_WARNING state. | |
| 1362 base::RunLoop first_message; | |
| 1363 delegate->set_console_message_callback(first_message.QuitClosure()); | |
| 1364 contents->OnPasswordInputShownOnHttp(); | |
| 1365 first_message.Run(); | |
| 1366 | |
| 1367 // Check that the HTTP_SHOW_WARNING state was actually triggered. | |
| 1368 ChromeSecurityStateModelClient* client = | |
| 1369 ChromeSecurityStateModelClient::FromWebContents(contents); | |
| 1370 ASSERT_TRUE(client); | |
| 1371 security_state::SecurityStateModel::SecurityInfo security_info; | |
| 1372 client->GetSecurityInfo(&security_info); | |
| 1373 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, | |
| 1374 security_info.security_level); | |
| 1375 | |
| 1376 // Check that the expected console message is present. | |
| 1377 ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); | |
| 1378 delegate->ClearConsoleMessages(); | |
| 1379 | |
| 1380 // Navigate with pushState and trigger VisibleSSLStateChanged | |
| 1381 // again. While the security level is still HTTP_SHOW_WARNING, an | |
| 1382 // additional console message should not be logged because there was | |
| 1383 // already a console message logged for the current main-frame | |
| 1384 // navigation. | |
| 1385 EXPECT_TRUE(content::ExecuteScript( | |
| 1386 contents, "history.pushState({ foo: 'bar' }, 'foo', 'bar');")); | |
| 1387 contents->OnCreditCardInputShownOnHttp(); | |
| 1388 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, | |
| 1389 security_info.security_level); | |
| 1390 | |
| 1391 // Do a main frame navigation and then trigger HTTP_SHOW_WARNING | |
| 1392 // again. From the above pushState navigation and this main-frame | |
| 1393 // navigation, exactly one console message is expected. | |
| 1394 GURL second_http_url = | |
| 1395 GetURLWithNonLocalHostname(embedded_test_server(), "/title2.html"); | |
| 1396 ui_test_utils::NavigateToURL(delegate, second_http_url); | |
| 1397 entry = contents->GetController().GetVisibleEntry(); | |
| 1398 ASSERT_TRUE(entry); | |
| 1399 EXPECT_EQ(second_http_url, entry->GetURL()); | |
| 1400 | |
| 1401 base::RunLoop second_message; | |
| 1402 delegate->set_console_message_callback(second_message.QuitClosure()); | |
| 1403 contents->OnPasswordInputShownOnHttp(); | |
| 1404 second_message.Run(); | |
| 1405 | |
| 1406 client->GetSecurityInfo(&security_info); | |
| 1407 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, | |
| 1408 security_info.security_level); | |
| 1409 ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); | |
| 1410 } | |
| 1411 | |
| 1125 // Tests that the SecurityStateModel for a WebContents is up to date | 1412 // Tests that the SecurityStateModel for a WebContents is up to date |
| 1126 // when the WebContents is inserted into a Browser's TabStripModel. | 1413 // when the WebContents is inserted into a Browser's TabStripModel. |
| 1127 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, AddedTab) { | 1414 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, AddedTab) { |
| 1128 ASSERT_TRUE(https_server_.Start()); | 1415 ASSERT_TRUE(https_server_.Start()); |
| 1129 SetUpMockCertVerifierForHttpsServer(0, net::OK); | 1416 SetUpMockCertVerifierForHttpsServer(0, net::OK); |
| 1130 | 1417 |
| 1131 content::WebContents* tab = | 1418 content::WebContents* tab = |
| 1132 browser()->tab_strip_model()->GetActiveWebContents(); | 1419 browser()->tab_strip_model()->GetActiveWebContents(); |
| 1133 ASSERT_TRUE(tab); | 1420 ASSERT_TRUE(tab); |
| 1134 | 1421 |
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1672 ChromeSecurityStateModelClient* model_client = | 1959 ChromeSecurityStateModelClient* model_client = |
| 1673 ChromeSecurityStateModelClient::FromWebContents(web_contents); | 1960 ChromeSecurityStateModelClient::FromWebContents(web_contents); |
| 1674 ASSERT_TRUE(model_client); | 1961 ASSERT_TRUE(model_client); |
| 1675 SecurityStateModel::SecurityInfo security_info; | 1962 SecurityStateModel::SecurityInfo security_info; |
| 1676 model_client->GetSecurityInfo(&security_info); | 1963 model_client->GetSecurityInfo(&security_info); |
| 1677 EXPECT_EQ(SecurityStateModel::SECURE, security_info.security_level); | 1964 EXPECT_EQ(SecurityStateModel::SECURE, security_info.security_level); |
| 1678 EXPECT_EQ(kTestSCTStatuses, security_info.sct_verify_statuses); | 1965 EXPECT_EQ(kTestSCTStatuses, security_info.sct_verify_statuses); |
| 1679 } | 1966 } |
| 1680 | 1967 |
| 1681 } // namespace | 1968 } // namespace |
| OLD | NEW |