[Cast channel] Add feature to allow Cast devices on all IPs.
This is a workaround for enterprise setups (such as universities) where
the network topology assigns public IP addresses to their Cast devices
(presumably these devices are protected behind a firewall). Public IP
addresses were disallowed in crrev.com/519857 which causes such setup
to be broken, as users can no longer connect to those devices. To our
knowledge there are at least 2 EDU setups (and a handful of individual
users) that were affected by this.
The workaround is implemented as a feature that is disabled by default.
The intended target is affected users for whom the option of changing
the Cast devices is infeasible (mostly EDU organizations). It can be
enabled by passing in --enable-features=CastAllowAllIPs in the
command line, or by turning it on in chrome://flags.
Bug: 813974
Change-Id: Ia02702315f02544245862561dc6925f0e15725db
Reviewed-on: https://chromium-review.googlesource.com/954345
Reviewed-by: mark a. foltz <[email protected]>
Commit-Queue: Derek Cheng <[email protected]>
Cr-Commit-Position: refs/heads/master@{#542557}
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index b66cf1d..b7dd534e 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -44,6 +44,7 @@
#include "components/autofill/core/common/autofill_util.h"
#include "components/browser_sync/browser_sync_switches.h"
#include "components/browsing_data/core/features.h"
+#include "components/cast_channel/cast_channel_util.h"
#include "components/cloud_devices/common/cloud_devices_switches.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
@@ -2133,6 +2134,10 @@
"1",
switches::kLoadMediaRouterComponentExtension,
"0")},
+ {"media-router-cast-allow-all-ips",
+ flag_descriptions::kMediaRouterCastAllowAllIPsName,
+ flag_descriptions::kMediaRouterCastAllowAllIPsDescription, kOsDesktop,
+ FEATURE_VALUE_TYPE(cast_channel::kCastAllowAllIPsFeature)},
#endif // !OS_ANDROID
// Since Drive Search is not available when app list is disabled, flag guard
// enable-drive-search-in-chrome-launcher flag.
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 44d3b0f..22a7666 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -874,6 +874,12 @@
const char kLoadMediaRouterComponentExtensionDescription[] =
"Loads the Media Router component extension at startup.";
+const char kMediaRouterCastAllowAllIPsName[] =
+ "Connect to Cast devices on all IP addresses";
+const char kMediaRouterCastAllowAllIPsDescription[] =
+ "Have the Media Router connect to Cast devices on all IP addresses, not "
+ "just RFC1918/RFC4913 private addresses.";
+
const char kManualPasswordGenerationName[] = "Manual password generation.";
const char kManualPasswordGenerationDescription[] =
"Show a 'Generate Password' option on the context menu for all password "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 4aa1ae9c..fda80c9d 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -546,6 +546,9 @@
extern const char kLoadMediaRouterComponentExtensionName[];
extern const char kLoadMediaRouterComponentExtensionDescription[];
+extern const char kMediaRouterCastAllowAllIPsName[];
+extern const char kMediaRouterCastAllowAllIPsDescription[];
+
extern const char kManualPasswordGenerationName[];
extern const char kManualPasswordGenerationDescription[];
diff --git a/components/cast_channel/BUILD.gn b/components/cast_channel/BUILD.gn
index 64a0bdc..1c6011e 100644
--- a/components/cast_channel/BUILD.gn
+++ b/components/cast_channel/BUILD.gn
@@ -62,6 +62,7 @@
testonly = true
sources = [
"cast_auth_util_unittest.cc",
+ "cast_channel_util_unittest.cc",
"cast_framer_unittest.cc",
"cast_message_handler_unittest.cc",
"cast_socket_service_unittest.cc",
diff --git a/components/cast_channel/cast_channel_util.cc b/components/cast_channel/cast_channel_util.cc
index 0c83ae5..532ebe6 100644
--- a/components/cast_channel/cast_channel_util.cc
+++ b/components/cast_channel/cast_channel_util.cc
@@ -6,9 +6,14 @@
namespace cast_channel {
+const base::Feature kCastAllowAllIPsFeature{"CastAllowAllIPs",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
bool IsValidCastIPAddress(const net::IPAddress& ip_address) {
- // A valid Cast IP address must be private.
- return ip_address.IsReserved();
+ // A valid Cast IP address must be private unless all IP addresses are
+ // explicitly allowed.
+ return ip_address.IsReserved() ||
+ base::FeatureList::IsEnabled(kCastAllowAllIPsFeature);
}
bool IsValidCastIPAddressString(const std::string& ip_address_string) {
diff --git a/components/cast_channel/cast_channel_util.h b/components/cast_channel/cast_channel_util.h
index 3df5525..df4ca07 100644
--- a/components/cast_channel/cast_channel_util.h
+++ b/components/cast_channel/cast_channel_util.h
@@ -5,10 +5,16 @@
#ifndef COMPONENTS_CAST_CHANNEL_CAST_CHANNEL_UTIL_H_
#define COMPONENTS_CAST_CHANNEL_CAST_CHANNEL_UTIL_H_
+#include "base/feature_list.h"
#include "net/base/ip_address.h"
namespace cast_channel {
+// If enabled, allows Media Router to connect to Cast devices on all IP
+// addresses, not just RFC1918/RFC4913 private addresses. Workaround for
+// https://crbug.com/813974.
+extern const base::Feature kCastAllowAllIPsFeature;
+
// Returns true if |ip_address| represents a valid IP address of a Cast device.
bool IsValidCastIPAddress(const net::IPAddress& ip_address);
diff --git a/components/cast_channel/cast_channel_util_unittest.cc b/components/cast_channel/cast_channel_util_unittest.cc
new file mode 100644
index 0000000..badceae
--- /dev/null
+++ b/components/cast_channel/cast_channel_util_unittest.cc
@@ -0,0 +1,49 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/cast_channel/cast_channel_util.h"
+
+#include "base/test/scoped_feature_list.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cast_channel {
+
+TEST(CastChannelUtilTest, IsValidCastIPAddress) {
+ std::string private_ip_address_string = "192.168.0.1";
+ net::IPAddress private_ip_address;
+ ASSERT_TRUE(
+ private_ip_address.AssignFromIPLiteral(private_ip_address_string));
+ EXPECT_TRUE(IsValidCastIPAddress(private_ip_address));
+ EXPECT_TRUE(IsValidCastIPAddressString(private_ip_address_string));
+
+ std::string public_ip_address_string = "133.1.2.3";
+ net::IPAddress public_ip_address;
+ ASSERT_TRUE(public_ip_address.AssignFromIPLiteral(public_ip_address_string));
+ EXPECT_FALSE(IsValidCastIPAddress(public_ip_address));
+ EXPECT_FALSE(IsValidCastIPAddressString(public_ip_address_string));
+
+ EXPECT_FALSE(IsValidCastIPAddressString("not a valid ip address"));
+}
+
+TEST(CastChannelUtilTest, IsValidCastIPAddressAllowAllIPs) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(kCastAllowAllIPsFeature);
+
+ std::string private_ip_address_string = "192.168.0.1";
+ net::IPAddress private_ip_address;
+ ASSERT_TRUE(
+ private_ip_address.AssignFromIPLiteral(private_ip_address_string));
+ EXPECT_TRUE(IsValidCastIPAddress(private_ip_address));
+ EXPECT_TRUE(IsValidCastIPAddressString(private_ip_address_string));
+
+ std::string public_ip_address_string = "133.1.2.3";
+ net::IPAddress public_ip_address;
+ ASSERT_TRUE(public_ip_address.AssignFromIPLiteral(public_ip_address_string));
+ EXPECT_TRUE(IsValidCastIPAddress(public_ip_address));
+ EXPECT_TRUE(IsValidCastIPAddressString(public_ip_address_string));
+
+ EXPECT_FALSE(IsValidCastIPAddressString("not a valid ip address"));
+}
+
+} // namespace cast_channel
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 84e7ca60..8a4c666 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -25767,6 +25767,7 @@
<int value="-1832221649" label="disable-out-of-process-pac"/>
<int value="-1821058653" label="enable-delay-agnostic-aec"/>
<int value="-1817209284" label="PayWithGoogleV1:enabled"/>
+ <int value="-1816066138" label="CastAllowAllIPs:enabled"/>
<int value="-1812579951" label="ContentSuggestionsCategoryRanker:enabled"/>
<int value="-1811394154" label="disable-webrtc-hw-vp8-encoding"/>
<int value="-1810294310" label="AndroidPaymentApps:enabled"/>
@@ -26942,6 +26943,7 @@
<int value="1126061778" label="CaptureThumbnailOnLoadFinished:enabled"/>
<int value="1127183523" label="PassiveEventListenersDueToFling:enabled"/>
<int value="1127427821" label="OmniboxEntitySuggestions:disabled"/>
+ <int value="1129542111" label="CastAllowAllIPs:disabled"/>
<int value="1129888794" label="ash-touch-hud"/>
<int value="1133635187" label="force-gpu-rasterization"/>
<int value="1139226452" label="enable-nacl-debug"/>