Commit 64821367 authored by Mustafa Emre Acer's avatar Mustafa Emre Acer Committed by Commit Bot

Use NetworkListManager API for captive portal interstitial on Windows

This CL introduces chrome::GetIsCaptivePortal() which returns true if
the OS reports a captive portal. It uses NetworkListManager API on
Windows and net::android::GetIsCaptivePortal() on Android. The result
is used to determine whether to show a captive portal interstitial.

NetworkListManager API returns the WebHijack status for each
network adapter separately. GetIsCaptivePortal() returns true if all
connected adapters have the WebHijack bit set.

As a side note, captive_portal_helper_android.cc contains both the
JNI code and chrome::GetIsCaptivePortal() implementation for Android.
This is why this CL contains both captive_portal_helper.h and
captive_portal_helper_android.h files.


Bug: 380762
Change-Id: I9e1d9b709dd3e98b2d615ce2167cf39991f6564b
Reviewed-on: https://chromium-review.googlesource.com/665439
Commit-Queue: Mustafa Emre Acer <meacer@chromium.org>
Reviewed-by: default avatarEric Lawrence <elawrence@chromium.org>
Cr-Commit-Position: refs/heads/master@{#506605}
parent 8ae56a33
...@@ -1343,6 +1343,10 @@ split_static_library("browser") { ...@@ -1343,6 +1343,10 @@ split_static_library("browser") {
"ssl/bad_clock_blocking_page.h", "ssl/bad_clock_blocking_page.h",
"ssl/captive_portal_blocking_page.cc", "ssl/captive_portal_blocking_page.cc",
"ssl/captive_portal_blocking_page.h", "ssl/captive_portal_blocking_page.h",
"ssl/captive_portal_helper.h",
"ssl/captive_portal_helper_android.cc",
"ssl/captive_portal_helper_android.h",
"ssl/captive_portal_helper_win.cc",
"ssl/cert_report_helper.cc", "ssl/cert_report_helper.cc",
"ssl/cert_report_helper.h", "ssl/cert_report_helper.h",
"ssl/chrome_expect_ct_reporter.cc", "ssl/chrome_expect_ct_reporter.cc",
...@@ -2210,7 +2214,6 @@ split_static_library("browser") { ...@@ -2210,7 +2214,6 @@ split_static_library("browser") {
"search_engines/template_url_service_android.h", "search_engines/template_url_service_android.h",
"signin/oauth2_token_service_delegate_android.cc", "signin/oauth2_token_service_delegate_android.cc",
"signin/oauth2_token_service_delegate_android.h", "signin/oauth2_token_service_delegate_android.h",
"ssl/captive_portal_helper_android.cc",
"ssl/security_state_model_android.cc", "ssl/security_state_model_android.cc",
"sync/glue/synced_tab_delegate_android.cc", "sync/glue/synced_tab_delegate_android.cc",
"sync/glue/synced_tab_delegate_android.h", "sync/glue/synced_tab_delegate_android.h",
......
// Copyright 2017 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.
#ifndef CHROME_BROWSER_SSL_CAPTIVE_PORTAL_HELPER_H_
#define CHROME_BROWSER_SSL_CAPTIVE_PORTAL_HELPER_H_
namespace chrome {
// Returns true if the OS reports that the device is behind a captive portal.
bool IsBehindCaptivePortal();
} // namespace chrome
#endif // CHROME_BROWSER_SSL_CAPTIVE_PORTAL_HELPER_H_
...@@ -2,12 +2,18 @@ ...@@ -2,12 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ssl/captive_portal_helper_android.h"
#include "chrome/browser/ssl/captive_portal_helper.h"
#include <stddef.h>
#include "base/android/jni_string.h" #include "base/android/jni_string.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/ssl/ssl_error_handler.h" #include "chrome/browser/ssl/ssl_error_handler.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "jni/CaptivePortalHelper_jni.h" #include "jni/CaptivePortalHelper_jni.h"
#include "net/android/network_library.h"
namespace chrome { namespace chrome {
namespace android { namespace android {
...@@ -44,4 +50,9 @@ std::string GetCaptivePortalServerUrl(JNIEnv* env) { ...@@ -44,4 +50,9 @@ std::string GetCaptivePortalServerUrl(JNIEnv* env) {
} }
} // namespace android } // namespace android
bool IsBehindCaptivePortal() {
return net::android::GetIsCaptivePortal();
}
} // namespace chrome } // namespace chrome
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define CHROME_BROWSER_SSL_CAPTIVE_PORTAL_HELPER_ANDROID_H_ #define CHROME_BROWSER_SSL_CAPTIVE_PORTAL_HELPER_ANDROID_H_
#include <jni.h> #include <jni.h>
#include <stddef.h>
#include <string> #include <string>
namespace chrome { namespace chrome {
......
// Copyright 2017 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 "chrome/browser/ssl/captive_portal_helper.h"
#include <netlistmgr.h>
#include "base/win/scoped_comptr.h"
#include "base/win/scoped_variant.h"
namespace {
bool IsNetworkBehindCaptivePortal(INetwork* network) {
NLM_CONNECTIVITY connectivity;
if (FAILED(network->GetConnectivity(&connectivity)))
return false;
if (connectivity == NLM_CONNECTIVITY_DISCONNECTED)
return false;
base::win::ScopedComPtr<IPropertyBag> property_bag;
if (FAILED(network->QueryInterface(property_bag.GetAddressOf())) ||
!property_bag) {
return false;
}
base::win::ScopedVariant connectivity_variant;
if ((connectivity & NLM_CONNECTIVITY_IPV4_SUBNET) ||
(connectivity & NLM_CONNECTIVITY_IPV4_LOCALNETWORK) ||
(connectivity & NLM_CONNECTIVITY_IPV4_INTERNET)) {
// IPV4 connection:
if (SUCCEEDED(property_bag->Read(NA_InternetConnectivityV4,
connectivity_variant.Receive(),
nullptr)) &&
(V_UINT(connectivity_variant.ptr()) &
NLM_INTERNET_CONNECTIVITY_WEBHIJACK) ==
NLM_INTERNET_CONNECTIVITY_WEBHIJACK) {
return true;
}
} else if ((connectivity & NLM_CONNECTIVITY_IPV6_SUBNET) ||
(connectivity & NLM_CONNECTIVITY_IPV6_LOCALNETWORK) ||
(connectivity & NLM_CONNECTIVITY_IPV6_INTERNET)) {
// IPV6 connection:
if (SUCCEEDED(property_bag->Read(NA_InternetConnectivityV6,
connectivity_variant.Receive(),
nullptr)) &&
(V_UINT(connectivity_variant.ptr()) &
NLM_INTERNET_CONNECTIVITY_WEBHIJACK) ==
NLM_INTERNET_CONNECTIVITY_WEBHIJACK) {
return true;
}
}
return false;
}
} // namespace
namespace chrome {
bool IsBehindCaptivePortal() {
// Assume the device is behind a captive portal if there is at least one
// connected network and all connected networks are behind captive portals.
base::win::ScopedComPtr<INetworkListManager> network_list_manager;
if (FAILED(CoCreateInstance(CLSID_NetworkListManager, nullptr,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&network_list_manager)))) {
return false;
}
base::win::ScopedComPtr<IEnumNetworks> enum_networks;
if (FAILED(network_list_manager->GetNetworks(NLM_ENUM_NETWORK_CONNECTED,
enum_networks.GetAddressOf()))) {
return false;
}
if (!enum_networks)
return false;
bool found = false;
while (true) {
base::win::ScopedComPtr<INetwork> network;
ULONG items_returned = 0;
// Note: MSDN documentation at
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa370740(v=vs.85).aspx
// says items_returned is set to NULL if the first parameter is 1, but this
// seems incorrect. In this call, items_returned is 1 until there are no
// networks. Then it becomes zero.
if (FAILED(enum_networks->Next(1, network.GetAddressOf(), &items_returned)))
return false;
if (items_returned == 0)
break;
if (!IsNetworkBehindCaptivePortal(network.Get()))
return false;
found = true;
}
return found;
}
} // namespace chrome
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ssl/bad_clock_blocking_page.h" #include "chrome/browser/ssl/bad_clock_blocking_page.h"
#include "chrome/browser/ssl/captive_portal_blocking_page.h" #include "chrome/browser/ssl/captive_portal_blocking_page.h"
#include "chrome/browser/ssl/captive_portal_helper.h"
#include "chrome/browser/ssl/mitm_software_blocking_page.h" #include "chrome/browser/ssl/mitm_software_blocking_page.h"
#include "chrome/browser/ssl/ssl_blocking_page.h" #include "chrome/browser/ssl/ssl_blocking_page.h"
#include "chrome/browser/ssl/ssl_cert_reporter.h" #include "chrome/browser/ssl/ssl_cert_reporter.h"
...@@ -58,10 +59,6 @@ ...@@ -58,10 +59,6 @@
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#endif // #if defined(OS_WIN) #endif // #if defined(OS_WIN)
#if defined(OS_ANDROID)
#include "net/android/network_library.h"
#endif // #if defined(OS_ANDROID)
namespace { namespace {
const base::Feature kMITMSoftwareInterstitial{ const base::Feature kMITMSoftwareInterstitial{
...@@ -650,8 +647,8 @@ void SSLErrorHandlerDelegateImpl::CheckForCaptivePortal() { ...@@ -650,8 +647,8 @@ void SSLErrorHandlerDelegateImpl::CheckForCaptivePortal() {
} }
bool SSLErrorHandlerDelegateImpl::DoesOSReportCaptivePortal() { bool SSLErrorHandlerDelegateImpl::DoesOSReportCaptivePortal() {
#if defined(OS_ANDROID) #if defined(OS_ANDROID) || defined(OS_WIN)
return net::android::GetIsCaptivePortal(); return chrome::IsBehindCaptivePortal();
#else #else
return false; return false;
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment