summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hugo Benichi <hugobenichi@google.com> 2017-06-17 13:36:35 +0900
committer Hugo Benichi <hugobenichi@google.com> 2017-07-14 14:54:58 +0900
commit12df465997c1be51c6802acad2dcf20f010c3576 (patch)
treed2cf116c309132e54d9ceab99795e255e41d31d2
parent1cdcaa8cf3ef1ec14014b0e84af3b1cd383c25db (diff)
CaptivePortalLogin ignores some ssl errors.
This patch changes the ssl error handler of the captive portal login activity to ignore errors for resources coming from a different hostname that the top-level page currently loading. This allows logging into misconfigured portals that incorrectly bans ssl to some hostnames necessary for loading their portal login pages. Bug: 62332137 Test: manually tested with captive portal entwork. (cherry pick from commit 22542ed48090e2e6e9474b658fdd368041a4060b which was skipped from merging into oc-dr1-dev-plus-aosp because of previous cherry picks and incorrect Merged-In annotations) Change-Id: Idb6ffac2d97b15cfdbe524b91c84dd29ae0be00b
-rw-r--r--packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java60
1 files changed, 41 insertions, 19 deletions
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 3dc170f0fa8d..be74a48a1c4f 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -31,6 +31,7 @@ import android.net.NetworkRequest;
import android.net.Proxy;
import android.net.Uri;
import android.net.http.SslError;
+import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.ArrayMap;
@@ -57,6 +58,7 @@ import java.net.URL;
import java.lang.InterruptedException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.util.Objects;
import java.util.Random;
public class CaptivePortalLoginActivity extends Activity {
@@ -283,6 +285,18 @@ public class CaptivePortalLoginActivity extends Activity {
return null;
}
+ private static String host(URL url) {
+ if (url == null) {
+ return null;
+ }
+ return url.getHost();
+ }
+
+ private static String sanitizeURL(URL url) {
+ // In non-Debug build, only show host to avoid leaking private info.
+ return Build.IS_DEBUGGABLE ? Objects.toString(url) : host(url);
+ }
+
private void testForCaptivePortal() {
// TODO: reuse NetworkMonitor facilities for consistent captive portal detection.
new Thread(new Runnable() {
@@ -336,6 +350,8 @@ public class CaptivePortalLoginActivity extends Activity {
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1,
getResources().getDisplayMetrics());
private int mPagesLoaded;
+ // the host of the page that this webview is currently loading. Can be null when undefined.
+ private String mHostname;
// If we haven't finished cleaning up the history, don't allow going back.
public boolean allowBack() {
@@ -343,8 +359,8 @@ public class CaptivePortalLoginActivity extends Activity {
}
@Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- if (url.contains(mBrowserBailOutToken)) {
+ public void onPageStarted(WebView view, String urlString, Bitmap favicon) {
+ if (urlString.contains(mBrowserBailOutToken)) {
mLaunchBrowser = true;
done(Result.WANTED_AS_IS);
return;
@@ -352,11 +368,17 @@ public class CaptivePortalLoginActivity extends Activity {
// The first page load is used only to cause the WebView to
// fetch the proxy settings. Don't update the URL bar, and
// don't check if the captive portal is still there.
- if (mPagesLoaded == 0) return;
+ if (mPagesLoaded == 0) {
+ return;
+ }
+ final URL url = makeURL(urlString);
+ Log.d(TAG, "onPageSarted: " + sanitizeURL(url));
+ mHostname = host(url);
// For internally generated pages, leave URL bar listing prior URL as this is the URL
// the page refers to.
- if (!url.startsWith(INTERNAL_ASSETS)) {
- getActionBar().setSubtitle(getHeaderSubtitle(url));
+ if (!urlString.startsWith(INTERNAL_ASSETS)) {
+ String subtitle = (url != null) ? getHeaderSubtitle(url) : urlString;
+ getActionBar().setSubtitle(subtitle);
}
getProgressBar().setVisibility(View.VISIBLE);
testForCaptivePortal();
@@ -398,15 +420,18 @@ public class CaptivePortalLoginActivity extends Activity {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
+ final URL url = makeURL(error.getUrl());
+ final String host = host(url);
+ Log.d(TAG, String.format("SSL error: %s, url: %s, certificate: %s",
+ error.getPrimaryError(), sanitizeURL(url), error.getCertificate()));
+ if (url == null || !Objects.equals(host, mHostname)) {
+ // Ignore ssl errors for resources coming from a different hostname than the page
+ // that we are currently loading, and only cancel the request.
+ handler.cancel();
+ return;
+ }
logMetricsEvent(MetricsEvent.CAPTIVE_PORTAL_LOGIN_ACTIVITY_SSL_ERROR);
- Log.w(TAG, "SSL error (error: " + error.getPrimaryError() + " host: " +
- // Only show host to avoid leaking private info.
- Uri.parse(error.getUrl()).getHost() + " certificate: " +
- error.getCertificate() + "); displaying SSL warning.");
final String sslErrorPage = makeSslErrorPage();
- if (VDBG) {
- Log.d(TAG, sslErrorPage);
- }
view.loadDataWithBaseURL(INTERNAL_ASSETS, sslErrorPage, "text/HTML", "UTF-8", null);
}
@@ -499,16 +524,13 @@ public class CaptivePortalLoginActivity extends Activity {
return getString(R.string.action_bar_title, info.getExtraInfo().replaceAll("^\"|\"$", ""));
}
- private String getHeaderSubtitle(String urlString) {
- URL url = makeURL(urlString);
- if (url == null) {
- return urlString;
- }
+ private String getHeaderSubtitle(URL url) {
+ String host = host(url);
final String https = "https";
if (https.equals(url.getProtocol())) {
- return https + "://" + url.getHost();
+ return https + "://" + host;
}
- return url.getHost();
+ return host;
}
private void logMetricsEvent(int event) {