diff options
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 |
commit | 2c18a56cc5f231c1409eb73c9cc0995492e68924 (patch) | |
tree | 7cc2721f4722a84bc91f76e67a454b14ed5752ce | |
parent | bd9476ece7e875b38c9ad11a739865f5cdb294cc (diff) | |
download | CaptivePortalLogin-2c18a56cc5f231c1409eb73c9cc0995492e68924.tar.gz |
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-- | src/com/android/captiveportallogin/CaptivePortalLoginActivity.java | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java index 3dc170f..be74a48 100644 --- a/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java +++ b/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) { |