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" />
+
+