diff options
author | Hugo Benichi <hugobenichi@google.com> | 2017-06-17 13:36:35 +0900 |
---|---|---|
committer | Lorenzo Colitti <lorenzo@google.com> | 2017-07-16 00:30:36 +0900 |
commit | 8f87642af4b84092e0f53aa4a362a27c8f096895 (patch) | |
tree | b9421be52d45942da938e7f4b6260e5fea6988ce | |
parent | 404060acb053b88459c4936ae93ac14c5dfa5ae4 (diff) | |
download | CaptivePortalLogin-8f87642af4b84092e0f53aa4a362a27c8f096895.tar.gz |
CaptivePortalLogin ignores some ssl errors.oreo-dr1-dev
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
Merged-In: 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 a487632..7e4f1d0 100644 --- a/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java +++ b/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java @@ -30,6 +30,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; @@ -56,6 +57,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; import java.util.concurrent.atomic.AtomicBoolean; @@ -285,6 +287,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() { @@ -338,6 +352,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() { @@ -345,8 +361,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; @@ -354,11 +370,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(); @@ -400,15 +422,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); } @@ -493,16 +518,13 @@ public class CaptivePortalLoginActivity extends Activity { return getString(R.string.action_bar_label); } - 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) { |