| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/base64.h" | 11 #include "base/base64.h" |
| 12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
| 14 #include "base/json/json_writer.h" | 14 #include "base/json/json_writer.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/path_service.h" | 16 #include "base/path_service.h" |
| 17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/strings/string_piece.h" | 18 #include "base/strings/string_piece.h" |
| 19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
| 21 #include "base/synchronization/waitable_event.h" | 21 #include "base/synchronization/waitable_event.h" |
| 22 #include "base/values.h" | 22 #include "base/values.h" |
| 23 #include "build/build_config.h" | 23 #include "build/build_config.h" |
| 24 #include "chrome/browser/chrome_notification_types.h" | 24 #include "chrome/browser/chrome_notification_types.h" |
| 25 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" | 25 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" |
| 26 #include "chrome/browser/extensions/extension_apitest.h" | 26 #include "chrome/browser/extensions/extension_apitest.h" |
| 27 #include "chrome/browser/extensions/extension_util.h" |
| 27 #include "chrome/browser/extensions/test_extension_dir.h" | 28 #include "chrome/browser/extensions/test_extension_dir.h" |
| 28 #include "chrome/browser/infobars/infobar_service.h" | 29 #include "chrome/browser/infobars/infobar_service.h" |
| 29 #include "chrome/browser/profiles/profile.h" | 30 #include "chrome/browser/profiles/profile.h" |
| 30 #include "chrome/browser/ui/browser.h" | 31 #include "chrome/browser/ui/browser.h" |
| 31 #include "chrome/browser/ui/browser_commands.h" | 32 #include "chrome/browser/ui/browser_commands.h" |
| 32 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 33 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 33 #include "chrome/common/chrome_paths.h" | 34 #include "chrome/common/chrome_paths.h" |
| 34 #include "chrome/common/chrome_switches.h" | 35 #include "chrome/common/chrome_switches.h" |
| 35 #include "chrome/test/base/ui_test_utils.h" | 36 #include "chrome/test/base/ui_test_utils.h" |
| 36 #include "content/public/browser/notification_registrar.h" | 37 #include "content/public/browser/notification_registrar.h" |
| 37 #include "content/public/browser/notification_service.h" | 38 #include "content/public/browser/notification_service.h" |
| 38 #include "content/public/test/browser_test_utils.h" | 39 #include "content/public/test/browser_test_utils.h" |
| 39 #include "content/public/test/test_utils.h" | 40 #include "content/public/test/test_utils.h" |
| 40 #include "extensions/browser/event_router.h" | 41 #include "extensions/browser/event_router.h" |
| 41 #include "extensions/browser/extension_prefs.h" | 42 #include "extensions/browser/extension_prefs.h" |
| 43 #include "extensions/browser/extension_registry.h" |
| 42 #include "extensions/browser/extension_system.h" | 44 #include "extensions/browser/extension_system.h" |
| 45 #include "extensions/browser/extension_util.h" |
| 43 #include "extensions/browser/process_manager.h" | 46 #include "extensions/browser/process_manager.h" |
| 47 #include "extensions/browser/test_extension_registry_observer.h" |
| 44 #include "extensions/common/api/runtime.h" | 48 #include "extensions/common/api/runtime.h" |
| 45 #include "extensions/common/extension_builder.h" | 49 #include "extensions/common/extension_builder.h" |
| 46 #include "extensions/common/value_builder.h" | 50 #include "extensions/common/value_builder.h" |
| 47 #include "extensions/test/extension_test_message_listener.h" | 51 #include "extensions/test/extension_test_message_listener.h" |
| 48 #include "extensions/test/result_catcher.h" | 52 #include "extensions/test/result_catcher.h" |
| 49 #include "net/cert/asn1_util.h" | 53 #include "net/cert/asn1_util.h" |
| 50 #include "net/cert/jwk_serializer.h" | 54 #include "net/cert/jwk_serializer.h" |
| 51 #include "net/dns/mock_host_resolver.h" | 55 #include "net/dns/mock_host_resolver.h" |
| 52 #include "net/ssl/channel_id_service.h" | 56 #include "net/ssl/channel_id_service.h" |
| 53 #include "net/test/embedded_test_server/embedded_test_server.h" | 57 #include "net/test/embedded_test_server/embedded_test_server.h" |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 | 345 |
| 342 GURL popup_opener_url() { | 346 GURL popup_opener_url() { |
| 343 return GetURLForPath("www.chromium.org", "/popup_opener.html"); | 347 return GetURLForPath("www.chromium.org", "/popup_opener.html"); |
| 344 } | 348 } |
| 345 | 349 |
| 346 GURL google_com_url() { | 350 GURL google_com_url() { |
| 347 return GetURLForPath("www.google.com", "/google.com.html"); | 351 return GetURLForPath("www.google.com", "/google.com.html"); |
| 348 } | 352 } |
| 349 | 353 |
| 350 scoped_refptr<const Extension> LoadChromiumConnectableExtension() { | 354 scoped_refptr<const Extension> LoadChromiumConnectableExtension() { |
| 351 scoped_refptr<const Extension> extension = | 355 scoped_refptr<const Extension> extension = LoadExtensionIntoDir( |
| 352 LoadExtensionIntoDir(&web_connectable_dir_, | 356 &web_connectable_dir_extension_, |
| 353 base::StringPrintf( | 357 base::StringPrintf("{" |
| 354 "{" | 358 " \"name\": \"chromium_connectable\"," |
| 355 " \"name\": \"chromium_connectable\"," | 359 " %s," |
| 356 " %s," | 360 " \"externally_connectable\": {" |
| 357 " \"externally_connectable\": {" | 361 " \"matches\": [\"*://*.chromium.org:*/*\"]" |
| 358 " \"matches\": [\"*://*.chromium.org:*/*\"]" | 362 " }" |
| 359 " }" | 363 "}", |
| 360 "}", | 364 common_manifest())); |
| 361 common_manifest())); | |
| 362 CHECK(extension.get()); | 365 CHECK(extension.get()); |
| 363 return extension; | 366 return extension; |
| 364 } | 367 } |
| 365 | 368 |
| 366 scoped_refptr<const Extension> LoadChromiumConnectableApp( | 369 scoped_refptr<const Extension> LoadChromiumConnectableApp( |
| 367 bool with_event_handlers = true) { | 370 bool with_event_handlers = true) { |
| 368 scoped_refptr<const Extension> extension = | 371 scoped_refptr<const Extension> extension = |
| 369 LoadExtensionIntoDir(&web_connectable_dir_, | 372 LoadExtensionIntoDir(&web_connectable_dir_app_, |
| 370 "{" | 373 "{" |
| 371 " \"app\": {" | 374 " \"app\": {" |
| 372 " \"background\": {" | 375 " \"background\": {" |
| 373 " \"scripts\": [\"background.js\"]" | 376 " \"scripts\": [\"background.js\"]" |
| 374 " }" | 377 " }" |
| 375 " }," | 378 " }," |
| 376 " \"externally_connectable\": {" | 379 " \"externally_connectable\": {" |
| 377 " \"matches\": [\"*://*.chromium.org:*/*\"]" | 380 " \"matches\": [\"*://*.chromium.org:*/*\"]" |
| 378 " }," | 381 " }," |
| 379 " \"manifest_version\": 2," | 382 " \"manifest_version\": 2," |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 args += include_tls_channel_id ? "true" : "false"; | 505 args += include_tls_channel_id ? "true" : "false"; |
| 503 if (message) | 506 if (message) |
| 504 args += std::string(", '") + message + "'"; | 507 args += std::string(", '") + message + "'"; |
| 505 CHECK(content::ExecuteScriptAndExtractString( | 508 CHECK(content::ExecuteScriptAndExtractString( |
| 506 browser()->tab_strip_model()->GetActiveWebContents(), | 509 browser()->tab_strip_model()->GetActiveWebContents(), |
| 507 base::StringPrintf("assertions.%s(%s)", method, args.c_str()), | 510 base::StringPrintf("assertions.%s(%s)", method, args.c_str()), |
| 508 &result)); | 511 &result)); |
| 509 return result; | 512 return result; |
| 510 } | 513 } |
| 511 | 514 |
| 512 TestExtensionDir web_connectable_dir_; | 515 TestExtensionDir web_connectable_dir_extension_; |
| 516 TestExtensionDir web_connectable_dir_app_; |
| 513 TestExtensionDir not_connectable_dir_; | 517 TestExtensionDir not_connectable_dir_; |
| 514 TestExtensionDir tls_channel_id_connectable_dir_; | 518 TestExtensionDir tls_channel_id_connectable_dir_; |
| 515 TestExtensionDir hosted_app_dir_; | 519 TestExtensionDir hosted_app_dir_; |
| 516 }; | 520 }; |
| 517 | 521 |
| 518 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, NotInstalled) { | 522 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, NotInstalled) { |
| 519 InitializeTestServer(); | 523 InitializeTestServer(); |
| 520 | 524 |
| 521 scoped_refptr<const Extension> extension = | 525 scoped_refptr<const Extension> extension = |
| 522 ExtensionBuilder() | 526 ExtensionBuilder() |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount()); | 768 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount()); |
| 765 } | 769 } |
| 766 | 770 |
| 767 // It's not possible to allow an app in incognito. | 771 // It's not possible to allow an app in incognito. |
| 768 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(app->id(), true); | 772 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(app->id(), true); |
| 769 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, | 773 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, |
| 770 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL)); | 774 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL)); |
| 771 } | 775 } |
| 772 | 776 |
| 773 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, | 777 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, |
| 774 FromIncognitoDenyExtension) { | 778 FromIncognitoDenyExtensionAndApp) { |
| 775 InitializeTestServer(); | 779 InitializeTestServer(); |
| 776 | 780 |
| 777 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension(); | 781 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension(); |
| 782 EXPECT_FALSE(util::IsIncognitoEnabled(extension->id(), profile())); |
| 778 | 783 |
| 779 Browser* incognito_browser = OpenURLOffTheRecord( | 784 Browser* incognito_browser = OpenURLOffTheRecord( |
| 780 profile()->GetOffTheRecordProfile(), chromium_org_url()); | 785 profile()->GetOffTheRecordProfile(), chromium_org_url()); |
| 781 content::RenderFrameHost* incognito_frame = | 786 content::RenderFrameHost* incognito_frame = |
| 782 incognito_browser->tab_strip_model() | 787 incognito_browser->tab_strip_model() |
| 783 ->GetActiveWebContents() | 788 ->GetActiveWebContents() |
| 784 ->GetMainFrame(); | 789 ->GetMainFrame(); |
| 785 | 790 |
| 786 { | 791 IncognitoConnectability::ScopedAlertTracker alert_tracker( |
| 787 IncognitoConnectability::ScopedAlertTracker alert_tracker( | 792 IncognitoConnectability::ScopedAlertTracker::ALWAYS_DENY); |
| 788 IncognitoConnectability::ScopedAlertTracker::ALWAYS_DENY); | |
| 789 | 793 |
| 790 // The alert doesn't show for extensions. | 794 // |extension| won't be loaded in the incognito renderer since it's not |
| 791 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, | 795 // enabled for incognito. Since there is no externally connectible extension |
| 792 CanConnectAndSendMessagesToFrame( | 796 // loaded into the incognito renderer, the chrome.runtime API won't be |
| 793 incognito_frame, extension.get(), NULL)); | 797 // defined. |
| 794 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount()); | 798 EXPECT_EQ(NAMESPACE_NOT_DEFINED, |
| 795 } | 799 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), |
| 800 nullptr)); |
| 796 | 801 |
| 797 // Allowing the extension in incognito mode will bypass the deny. | 802 // Loading a platform app in the renderer should cause the chrome.runtime |
| 798 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(extension->id(), true); | 803 // bindings to be generated in the renderer. A platform app is always loaded |
| 799 EXPECT_EQ( | 804 // in the incognito renderer. |
| 800 OK, | 805 LoadChromiumConnectableApp(); |
| 801 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), NULL)); | 806 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, |
| 807 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), |
| 808 nullptr)); |
| 809 |
| 810 // Allowing the extension in incognito mode loads the extension in the |
| 811 // incognito renderer, allowing it to receive connections. |
| 812 TestExtensionRegistryObserver observer( |
| 813 ExtensionRegistry::Get(profile()->GetOffTheRecordProfile()), |
| 814 extension->id()); |
| 815 util::SetIsIncognitoEnabled(extension->id(), |
| 816 profile()->GetOffTheRecordProfile(), true); |
| 817 const Extension* loaded_extension = observer.WaitForExtensionLoaded(); |
| 818 EXPECT_EQ(OK, CanConnectAndSendMessagesToFrame(incognito_frame, |
| 819 loaded_extension, nullptr)); |
| 820 |
| 821 // No alert is shown for extensions since they support being enabled in |
| 822 // incognito mode. |
| 823 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount()); |
| 802 } | 824 } |
| 803 | 825 |
| 804 // Tests connection from incognito tabs when the extension doesn't have an event | 826 // Tests connection from incognito tabs when the extension doesn't have an event |
| 805 // handler for the connection event. | 827 // handler for the connection event. |
| 806 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, | 828 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, |
| 807 FromIncognitoNoEventHandlerInApp) { | 829 FromIncognitoNoEventHandlerInApp) { |
| 808 InitializeTestServer(); | 830 InitializeTestServer(); |
| 809 | 831 |
| 810 scoped_refptr<const Extension> app = LoadChromiumConnectableApp(false); | 832 scoped_refptr<const Extension> app = LoadChromiumConnectableApp(false); |
| 811 ASSERT_TRUE(app->is_platform_app()); | 833 ASSERT_TRUE(app->is_platform_app()); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 943 browser()->tab_strip_model()->GetActiveWebContents(), | 965 browser()->tab_strip_model()->GetActiveWebContents(), |
| 944 "assertions.tryIllegalArguments()", &result)); | 966 "assertions.tryIllegalArguments()", &result)); |
| 945 EXPECT_TRUE(result); | 967 EXPECT_TRUE(result); |
| 946 } | 968 } |
| 947 | 969 |
| 948 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, | 970 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, |
| 949 FromIncognitoAllowExtension) { | 971 FromIncognitoAllowExtension) { |
| 950 InitializeTestServer(); | 972 InitializeTestServer(); |
| 951 | 973 |
| 952 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension(); | 974 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension(); |
| 975 EXPECT_FALSE(util::IsIncognitoEnabled(extension->id(), profile())); |
| 953 | 976 |
| 954 Browser* incognito_browser = OpenURLOffTheRecord( | 977 Browser* incognito_browser = OpenURLOffTheRecord( |
| 955 profile()->GetOffTheRecordProfile(), chromium_org_url()); | 978 profile()->GetOffTheRecordProfile(), chromium_org_url()); |
| 956 content::RenderFrameHost* incognito_frame = | 979 content::RenderFrameHost* incognito_frame = |
| 957 incognito_browser->tab_strip_model() | 980 incognito_browser->tab_strip_model() |
| 958 ->GetActiveWebContents() | 981 ->GetActiveWebContents() |
| 959 ->GetMainFrame(); | 982 ->GetMainFrame(); |
| 960 | 983 |
| 961 { | 984 IncognitoConnectability::ScopedAlertTracker alert_tracker( |
| 962 IncognitoConnectability::ScopedAlertTracker alert_tracker( | 985 IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW); |
| 963 IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW); | |
| 964 | 986 |
| 965 // No alert is shown. | 987 // |extension| won't be loaded in the incognito renderer since it's not |
| 966 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, | 988 // enabled for incognito. Since there is no externally connectible extension |
| 967 CanConnectAndSendMessagesToFrame( | 989 // loaded into the incognito renderer, the chrome.runtime API won't be |
| 968 incognito_frame, extension.get(), NULL)); | 990 // defined. |
| 969 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount()); | 991 EXPECT_EQ(NAMESPACE_NOT_DEFINED, |
| 970 } | 992 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), |
| 993 nullptr)); |
| 971 | 994 |
| 972 // Allowing the extension in incognito mode is what allows connections. | 995 // Allowing the extension in incognito mode loads the extension in the |
| 973 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(extension->id(), true); | 996 // incognito renderer, causing the chrome.runtime bindings to be generated in |
| 974 EXPECT_EQ( | 997 // the renderer and allowing the extension to receive connections. |
| 975 OK, | 998 TestExtensionRegistryObserver observer( |
| 976 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), NULL)); | 999 ExtensionRegistry::Get(profile()->GetOffTheRecordProfile()), |
| 1000 extension->id()); |
| 1001 util::SetIsIncognitoEnabled(extension->id(), |
| 1002 profile()->GetOffTheRecordProfile(), true); |
| 1003 const Extension* loaded_extension = observer.WaitForExtensionLoaded(); |
| 1004 EXPECT_EQ(OK, CanConnectAndSendMessagesToFrame(incognito_frame, |
| 1005 loaded_extension, nullptr)); |
| 1006 |
| 1007 // No alert is shown for extensions which support being enabled in incognito |
| 1008 // mode. |
| 1009 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount()); |
| 977 } | 1010 } |
| 978 | 1011 |
| 979 // Tests a connection from an iframe within a tab which doesn't have | 1012 // Tests a connection from an iframe within a tab which doesn't have |
| 980 // permission. Iframe should work. | 1013 // permission. Iframe should work. |
| 981 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, | 1014 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, |
| 982 FromIframeWithPermission) { | 1015 FromIframeWithPermission) { |
| 983 InitializeTestServer(); | 1016 InitializeTestServer(); |
| 984 | 1017 |
| 985 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension(); | 1018 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension(); |
| 986 | 1019 |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1324 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( | 1357 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( |
| 1325 background_contents, | 1358 background_contents, |
| 1326 "window.domAutomationController.send(window.messageCount);", | 1359 "window.domAutomationController.send(window.messageCount);", |
| 1327 &message_count)); | 1360 &message_count)); |
| 1328 EXPECT_EQ(1, message_count); | 1361 EXPECT_EQ(1, message_count); |
| 1329 } | 1362 } |
| 1330 | 1363 |
| 1331 } // namespace | 1364 } // namespace |
| 1332 | 1365 |
| 1333 }; // namespace extensions | 1366 }; // namespace extensions |
| OLD | NEW |