Try to bypass VPN when domain fronting is enabled

Note VPN may disallow bypass
This commit is contained in:
FooIbar authored and tarsin committed 2023-01-22 21:09:44 +08:00
1 parent 0ef11b58d2
commit 3b04f8c695
5 files changed
+69 -8

No files matched your search

@@ -85,6 +85,7 @@ public class Settings {
public static final int DEFAULT_READ_CACHE_SIZE = 320;
public static final String KEY_BUILT_IN_HOSTS = "built_in_hosts_2";
public static final String KEY_DOMAIN_FRONTING = "domain_fronting";
public static final String KEY_BYPASS_VPN = "bypass_vpn";
public static final String KEY_LIST_THUMB_SIZE = "list_tile_size";
private static final String KEY_HIDE_HV_EVENTS = "hide_hv_events";
private static final boolean DEFAULT_HIDE_HV_EVENTS = true;
@@ -179,6 +180,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_FRONTING = false;
private static final boolean DEFAULT_BYPASS_VPN = true;
private static final String KEY_PROXY_TYPE = "proxy_type";
private static final int DEFAULT_PROXY_TYPE = EhProxySelector.TYPE_SYSTEM;
private static final String KEY_PROXY_IP = "proxy_ip";
@@ -673,6 +675,10 @@ public class Settings {
putBoolean(KEY_DOMAIN_FRONTING, value);
}
public static boolean getBypassVPN() {
return getBoolean(KEY_BYPASS_VPN, DEFAULT_BYPASS_VPN);
}
public static int getProxyType() {
return getInt(KEY_PROXY_TYPE, DEFAULT_PROXY_TYPE);
}
@@ -24,15 +24,20 @@ import android.content.pm.verify.domain.DomainVerificationManager
import android.content.pm.verify.domain.DomainVerificationUserState
import android.graphics.Bitmap
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.annotation.RequiresApi
import androidx.annotation.StringRes
import androidx.core.content.getSystemService
import androidx.core.view.GravityCompat
import androidx.customview.widget.Openable
import androidx.drawerlayout.widget.DrawerLayout
@@ -83,6 +88,8 @@ import java.io.OutputStream
class MainActivity : EhActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var navController: NavController
private lateinit var connectivityManager: ConnectivityManager
private val availableNetworks: MutableList<Network> = mutableListOf()
private fun saveImageToTempFile(file: UniFile?): File? {
file ?: return null
@@ -217,6 +224,10 @@ class MainActivity : EhActivity() {
}
override fun onCreate(savedInstanceState: Bundle?) {
connectivityManager = getSystemService()!!
if (Settings.getDF() && Settings.getBypassVPN()) {
bypassVPN()
}
if (EhUtils.needSignedIn())
startActivity(Intent(this, LoginActivity::class.java))
super.onCreate(savedInstanceState)
@@ -276,6 +287,19 @@ class MainActivity : EhActivity() {
}
}
private fun bypassVPN() {
val network = connectivityManager.activeNetwork
val capabilities = connectivityManager.getNetworkCapabilities(network)
capabilities?.let {
if (it.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
val builder = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_FOREGROUND)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
connectivityManager.registerNetworkCallback(builder.build(), mNetworkCallback)
}
}
}
@RequiresApi(Build.VERSION_CODES.S)
@Throws(PackageManager.NameNotFoundException::class)
private fun checkAppLinkVerify() {
@@ -334,8 +358,7 @@ class MainActivity : EhActivity() {
}
private fun checkMeteredNetwork() {
val cm = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
if (cm.isActiveNetworkMetered) {
if (connectivityManager.isActiveNetworkMetered) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Snackbar.make(
binding.drawView,
@@ -503,4 +526,25 @@ class MainActivity : EhActivity() {
override fun onDrawerClosed(drawerView: View) {}
override fun onDrawerStateChanged(newState: Int) {}
}
private val mNetworkCallback = object : ConnectivityManager.NetworkCallback() {
private val TAG = "mNetworkCallback"
override fun onAvailable(network: Network) {
Log.d(TAG, "onAvailable: $network")
connectivityManager.bindProcessToNetwork(network)
availableNetworks.add(network)
}
override fun onLost(network: Network) {
Log.d(TAG, "onLost: $network")
val activeNetwork = availableNetworks.last()
availableNetworks.remove(network)
if (network == activeNetwork) {
connectivityManager.bindProcessToNetwork(
availableNetworks.takeIf { it.isNotEmpty() }?.last()
)
}
}
}
}