Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a77bc91b authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Android (Google) Code Review
Browse files

Merge "CaptivePortalLogin ignores some ssl errors." into oc-dr1-dev

parents 90bf56da 2da66192
Loading
Loading
Loading
Loading
+41 −19
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ import android.net.NetworkRequest;
import android.net.Proxy;
import android.net.Proxy;
import android.net.Uri;
import android.net.Uri;
import android.net.http.SslError;
import android.net.http.SslError;
import android.os.Build;
import android.os.Bundle;
import android.os.Bundle;
import android.provider.Settings;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArrayMap;
@@ -56,6 +57,7 @@ import java.net.URL;
import java.lang.InterruptedException;
import java.lang.InterruptedException;
import java.lang.reflect.Field;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.Random;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicBoolean;


@@ -285,6 +287,18 @@ public class CaptivePortalLoginActivity extends Activity {
        return null;
        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() {
    private void testForCaptivePortal() {
        // TODO: reuse NetworkMonitor facilities for consistent captive portal detection.
        // TODO: reuse NetworkMonitor facilities for consistent captive portal detection.
        new Thread(new Runnable() {
        new Thread(new Runnable() {
@@ -338,6 +352,8 @@ public class CaptivePortalLoginActivity extends Activity {
                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1,
                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1,
                    getResources().getDisplayMetrics());
                    getResources().getDisplayMetrics());
        private int mPagesLoaded;
        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.
        // If we haven't finished cleaning up the history, don't allow going back.
        public boolean allowBack() {
        public boolean allowBack() {
@@ -345,8 +361,8 @@ public class CaptivePortalLoginActivity extends Activity {
        }
        }


        @Override
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
        public void onPageStarted(WebView view, String urlString, Bitmap favicon) {
            if (url.contains(mBrowserBailOutToken)) {
            if (urlString.contains(mBrowserBailOutToken)) {
                mLaunchBrowser = true;
                mLaunchBrowser = true;
                done(Result.WANTED_AS_IS);
                done(Result.WANTED_AS_IS);
                return;
                return;
@@ -354,11 +370,17 @@ public class CaptivePortalLoginActivity extends Activity {
            // The first page load is used only to cause the WebView to
            // The first page load is used only to cause the WebView to
            // fetch the proxy settings.  Don't update the URL bar, and
            // fetch the proxy settings.  Don't update the URL bar, and
            // don't check if the captive portal is still there.
            // 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
            // For internally generated pages, leave URL bar listing prior URL as this is the URL
            // the page refers to.
            // the page refers to.
            if (!url.startsWith(INTERNAL_ASSETS)) {
            if (!urlString.startsWith(INTERNAL_ASSETS)) {
                getActionBar().setSubtitle(getHeaderSubtitle(url));
                String subtitle = (url != null) ? getHeaderSubtitle(url) : urlString;
                getActionBar().setSubtitle(subtitle);
            }
            }
            getProgressBar().setVisibility(View.VISIBLE);
            getProgressBar().setVisibility(View.VISIBLE);
            testForCaptivePortal();
            testForCaptivePortal();
@@ -400,15 +422,18 @@ public class CaptivePortalLoginActivity extends Activity {


        @Override
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        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);
            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();
            final String sslErrorPage = makeSslErrorPage();
            if (VDBG) {
                Log.d(TAG, sslErrorPage);
            }
            view.loadDataWithBaseURL(INTERNAL_ASSETS, sslErrorPage, "text/HTML", "UTF-8", null);
            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);
        return getString(R.string.action_bar_label);
    }
    }


    private String getHeaderSubtitle(String urlString) {
    private String getHeaderSubtitle(URL url) {
        URL url = makeURL(urlString);
        String host = host(url);
        if (url == null) {
            return urlString;
        }
        final String https = "https";
        final String https = "https";
        if (https.equals(url.getProtocol())) {
        if (https.equals(url.getProtocol())) {
            return https + "://" + url.getHost();
            return https + "://" + host;
        }
        }
        return url.getHost();
        return host;
    }
    }


    private void logMetricsEvent(int event) {
    private void logMetricsEvent(int event) {