From 36210aed4856fa4f4f94029a18e295167637f149 Mon Sep 17 00:00:00 2001 From: NekoInverter <7741672-NekoInverter@users.noreply.gitlab.com> Date: Sat, 12 Dec 2020 23:24:14 +0800 Subject: [PATCH] Allow turn off domain fronting --- .../com/hippo/ehviewer/EhApplication.java | 29 ++++++++++++++++--- .../java/com/hippo/ehviewer/Settings.java | 15 ++++++++++ .../ehviewer/client/EhSSLSocketFactory.java | 25 +++++++++------- app/src/main/res/values-zh-rCN/strings.xml | 2 ++ app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/xml/advanced_settings.xml | 7 +++++ 6 files changed, 66 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/hippo/ehviewer/EhApplication.java b/app/src/main/java/com/hippo/ehviewer/EhApplication.java index 7f14cd5f8..4b4009d1e 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhApplication.java +++ b/app/src/main/java/com/hippo/ehviewer/EhApplication.java @@ -63,12 +63,18 @@ import com.hippo.yorozuya.OSUtils; import com.hippo.yorozuya.SimpleHandler; import java.io.File; +import java.security.KeyStore; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.concurrent.TimeUnit; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + import okhttp3.Cache; import okhttp3.OkHttpClient; @@ -135,18 +141,33 @@ public class EhApplication extends RecordingApplication { public static OkHttpClient getOkHttpClient(@NonNull Context context) { EhApplication application = ((EhApplication) context.getApplicationContext()); if (application.mOkHttpClient == null) { - application.mOkHttpClient = new OkHttpClient.Builder() + OkHttpClient.Builder builder = new OkHttpClient.Builder() .connectTimeout(5, TimeUnit.SECONDS) .readTimeout(5, TimeUnit.SECONDS) .writeTimeout(5, TimeUnit.SECONDS) .callTimeout(10, TimeUnit.SECONDS) .cookieJar(getEhCookieStore(application)) .cache(getOkHttpCache(application)) - .sslSocketFactory(new EhSSLSocketFactory(), new EhX509TrustManager()) .hostnameVerifier((hostname, session) -> true) .dns(new EhDns(application)) - .proxySelector(getEhProxySelector(application)) - .build(); + .proxySelector(getEhProxySelector(application)); + if (Settings.getDF()) { + try { + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( + TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init((KeyStore) null); + TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); + if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { + throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers)); + } + X509TrustManager trustManager = (X509TrustManager) trustManagers[0]; + builder.sslSocketFactory(new EhSSLSocketFactory(), trustManager); + } catch (Exception e) { + e.printStackTrace(); + builder.sslSocketFactory(new EhSSLSocketFactory(), new EhX509TrustManager()); + } + } + application.mOkHttpClient = builder.build(); } return application.mOkHttpClient; } diff --git a/app/src/main/java/com/hippo/ehviewer/Settings.java b/app/src/main/java/com/hippo/ehviewer/Settings.java index a971ce8d9..27b3c3edb 100755 --- a/app/src/main/java/com/hippo/ehviewer/Settings.java +++ b/app/src/main/java/com/hippo/ehviewer/Settings.java @@ -95,6 +95,7 @@ public class Settings { public static final int DEFAULT_READ_CACHE_SIZE = 160; public static final String KEY_BUILT_IN_HOSTS = "built_in_hosts_2"; public static final String KEY_DOH = "dns_over_https"; + public static final String KEY_DOMAIN_FRONTING = "domain_fronting"; public static final String KEY_APP_LANGUAGE = "app_language"; private static final String TAG = Settings.class.getSimpleName(); private static final String KEY_VERSION_CODE = "version_code"; @@ -243,6 +244,7 @@ public class Settings { private static final boolean DEFAULT_SAVE_CRASH_LOG = true; private static final boolean DEFAULT_BUILT_IN_HOSTS = false; private static final boolean DEFAULT_DOH = false; + private static final boolean DEFAULT_FRONTING = false; private static final String DEFAULT_APP_LANGUAGE = "system"; private static final String KEY_PROXY_TYPE = "proxy_type"; private static final int DEFAULT_PROXY_TYPE = EhProxySelector.TYPE_SYSTEM; @@ -285,6 +287,11 @@ public class Settings { putDoH(true); } } + if (!sSettingsPre.contains(KEY_DOMAIN_FRONTING)) { + if ("CN".equals(Locale.getDefault().getCountry())) { + putDF(true); + } + } // Enable show tag translations if the country is CN if (!sSettingsPre.contains(KEY_SHOW_TAG_TRANSLATIONS)) { if ("CN".equals(Locale.getDefault().getCountry())) { @@ -1056,6 +1063,14 @@ public class Settings { putBoolean(KEY_DOH, value); } + public static boolean getDF() { + return getBoolean(KEY_DOMAIN_FRONTING, DEFAULT_FRONTING); + } + + public static void putDF(boolean value) { + putBoolean(KEY_DOMAIN_FRONTING, value); + } + public static String getAppLanguage() { return getString(KEY_APP_LANGUAGE, DEFAULT_APP_LANGUAGE); } diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhSSLSocketFactory.java b/app/src/main/java/com/hippo/ehviewer/client/EhSSLSocketFactory.java index 6730b06c6..5b1d4b525 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhSSLSocketFactory.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhSSLSocketFactory.java @@ -2,6 +2,8 @@ package com.hippo.ehviewer.client; import android.util.Log; +import com.hippo.ehviewer.Settings; + import java.io.IOException; import java.net.InetAddress; import java.net.Socket; @@ -11,16 +13,19 @@ import javax.net.ssl.SSLSocketFactory; public class EhSSLSocketFactory extends SSLSocketFactory { @Override public String[] getDefaultCipherSuites() { - return new String[0]; + return ((SSLSocketFactory) getDefault()).getDefaultCipherSuites(); } @Override public String[] getSupportedCipherSuites() { - return new String[0]; + return ((SSLSocketFactory) getDefault()).getSupportedCipherSuites(); } @Override public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { + if (!Settings.getDF()) { + return ((SSLSocketFactory) getDefault()).createSocket(s, host, port, autoClose); + } InetAddress address = s.getInetAddress(); Log.d("EhSSLSocketFactory", "Host: " + host + " Address: " + address.getHostAddress()); if (autoClose) s.close(); @@ -28,23 +33,23 @@ public class EhSSLSocketFactory extends SSLSocketFactory { } @Override - public Socket createSocket(String host, int port) { - return null; + public Socket createSocket(String host, int port) throws IOException { + return getDefault().createSocket(host, port); } @Override - public Socket createSocket(String host, int port, InetAddress localHost, int localPort) { - return null; + public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException { + return getDefault().createSocket(host, port, localHost, localPort); } @Override - public Socket createSocket(InetAddress host, int port) { - return null; + public Socket createSocket(InetAddress host, int port) throws IOException { + return getDefault().createSocket(host, port); } @Override - public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) { - return null; + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { + return getDefault().createSocket(address, port, localAddress, localPort); } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index cef05ed00..449d85f84 100755 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -736,6 +736,8 @@ 从搜索记录中删除“%s”? 安全 DNS(DoH) 解决某些地区的 DNS 污染问题 + 域名前置 + 绕过 SNI 封锁 色彩主题 跟随应用 墨水屏模式 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c2a39f1a5..9ef846679 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -600,6 +600,8 @@ Apply the built-in host-to-IP mapping provided by the app.\nIt can be overridden by custom hosts.txt. DNS over HTTPS Workaround DNS poisoning in some nations. + Domain fronting + Bypass SNI blocking. Custom hosts.txt Map hostnames to IP addresses.\nIt can override built-in hosts.txt. Pattern protection diff --git a/app/src/main/res/xml/advanced_settings.xml b/app/src/main/res/xml/advanced_settings.xml index f7ae1da8f..e70444a99 100644 --- a/app/src/main/res/xml/advanced_settings.xml +++ b/app/src/main/res/xml/advanced_settings.xml @@ -93,6 +93,13 @@ android:title="@string/settings_advanced_dns_over_http_title" app:iconSpaceReserved="false" /> + +