Add settings to disable DoH

Close #3130
This commit is contained in:
topjohnwu 2020-09-13 04:34:00 -07:00
parent 8a338de696
commit 765b51285a
5 changed files with 53 additions and 32 deletions

View File

@ -9,6 +9,7 @@ import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.core.magiskdb.SettingsDao
import com.topjohnwu.magisk.core.magiskdb.StringDao
import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.core.utils.defaultLocale
import com.topjohnwu.magisk.core.utils.refreshLocale
import com.topjohnwu.magisk.data.preference.PreferenceModel
import com.topjohnwu.magisk.data.repository.DBConfig
@ -54,6 +55,7 @@ object Config : PreferenceModel, DBConfig {
const val THEME_ORDINAL = "theme_ordinal"
const val BOOT_ID = "boot_id"
const val ASKED_HOME = "asked_home"
const val DOH = "doh"
// system state
const val MAGISKHIDE = "magiskhide"
@ -126,6 +128,7 @@ object Config : PreferenceModel, DBConfig {
var themeOrdinal by preference(Key.THEME_ORDINAL, Theme.Piplup.ordinal)
var suReAuth by preference(Key.SU_REAUTH, false)
var checkUpdate by preference(Key.CHECK_UPDATES, true)
var doh by preference(Key.DOH, defaultLocale.country == "CN")
var magiskHide by preference(Key.MAGISKHIDE, true)
var showSystemApp by preference(Key.SHOW_SYSTEM_APP, false)

View File

@ -3,6 +3,7 @@ package com.topjohnwu.magisk.di
import android.content.Context
import android.os.Build
import com.squareup.moshi.Moshi
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.data.network.GithubApiServices
@ -32,6 +33,42 @@ val networkingModule = module {
single { createMarkwon(get(), get()) }
}
private class DnsResolver(client: OkHttpClient) : Dns {
private var dohError = false
private val poisonedHosts = listOf("raw.githubusercontent.com")
private val doh by lazy {
DnsOverHttps.Builder().client(client)
.url(HttpUrl.get("https://cloudflare-dns.com/dns-query"))
.bootstrapDnsHosts(listOf(
InetAddress.getByName("162.159.36.1"),
InetAddress.getByName("162.159.46.1"),
InetAddress.getByName("1.1.1.1"),
InetAddress.getByName("1.0.0.1"),
InetAddress.getByName("162.159.132.53"),
InetAddress.getByName("2606:4700:4700::1111"),
InetAddress.getByName("2606:4700:4700::1001"),
InetAddress.getByName("2606:4700:4700::0064"),
InetAddress.getByName("2606:4700:4700::6400")
))
.resolvePrivateAddresses(true) /* To make PublicSuffixDatabase never used */
.build()
}
override fun lookup(hostname: String): List<InetAddress> {
return if (!dohError && Config.doh && poisonedHosts.contains(hostname)) {
try {
doh.lookup(hostname)
} catch (e: UnknownHostException) {
dohError = true
Dns.SYSTEM.lookup(hostname)
}
} else {
Dns.SYSTEM.lookup(hostname)
}
}
}
@Suppress("DEPRECATION")
fun createOkHttpClient(context: Context): OkHttpClient {
val builder = OkHttpClient.Builder()
@ -46,37 +83,7 @@ fun createOkHttpClient(context: Context): OkHttpClient {
if (Build.VERSION.SDK_INT < 21)
builder.sslSocketFactory(NoSSLv3SocketFactory())
}
val doh = DnsOverHttps.Builder().client(builder.build())
.url(HttpUrl.get("https://cloudflare-dns.com/dns-query"))
.bootstrapDnsHosts(listOf(
InetAddress.getByName("162.159.36.1"),
InetAddress.getByName("162.159.46.1"),
InetAddress.getByName("1.1.1.1"),
InetAddress.getByName("1.0.0.1"),
InetAddress.getByName("162.159.132.53"),
InetAddress.getByName("2606:4700:4700::1111"),
InetAddress.getByName("2606:4700:4700::1001"),
InetAddress.getByName("2606:4700:4700::0064"),
InetAddress.getByName("2606:4700:4700::6400")
))
.resolvePrivateAddresses(true) /* To make PublicSuffixDatabase never used */
.build()
var skipDoH = false
builder.dns { hostname ->
// Only resolve via DoH for known DNS polluted hostnames
if (!skipDoH && hostname == "raw.githubusercontent.com") {
try {
doh.lookup(hostname)
} catch (e: UnknownHostException) {
skipDoH = true
Dns.SYSTEM.lookup(hostname)
}
} else {
Dns.SYSTEM.lookup(hostname)
}
}
builder.dns(DnsResolver(builder.build()))
return builder.build()
}

View File

@ -174,6 +174,15 @@ object UpdateChecker : BaseSettingsItem.Toggle() {
}
}
object DoHToggle : BaseSettingsItem.Toggle() {
override val title = R.string.settings_doh_title.asTransitive()
override val description = R.string.settings_doh_description.asTransitive()
override var value = Config.doh
set(value) = setV(value, field, { field = it }) {
Config.doh = it
}
}
// check whether is module already installed beforehand?
object SystemlessHosts : BaseSettingsItem.Blank() {
override val title = R.string.settings_hosts_title.asTransitive()

View File

@ -58,7 +58,7 @@ class SettingsViewModel(
// Manager
list.addAll(listOf(
Manager,
UpdateChannel, UpdateChannelUrl, UpdateChecker, DownloadPath
UpdateChannel, UpdateChannelUrl, DoHToggle, UpdateChecker, DownloadPath
))
if (Info.env.isActive) {
list.add(ClearRepoCache)

View File

@ -175,6 +175,8 @@
<string name="no_biometric">Unsupported device or no biometric settings are enabled</string>
<string name="settings_customization">Customization</string>
<string name="setting_add_shortcut_summary">Add a pretty shortcut in the home screen in case the name and icon are difficult to recognize after hiding the app</string>
<string name="settings_doh_title">DNS over HTTPS</string>
<string name="settings_doh_description">Workaround DNS poisoning in some nations</string>
<string name="multiuser_mode">Multiuser Mode</string>
<string name="settings_owner_only">Device Owner Only</string>