diff --git a/app/src/main/java/com/topjohnwu/magisk/core/Config.kt b/app/src/main/java/com/topjohnwu/magisk/core/Config.kt index 93486830993c..e3bd21b433b0 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/Config.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/Config.kt @@ -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) diff --git a/app/src/main/java/com/topjohnwu/magisk/di/NetworkingModule.kt b/app/src/main/java/com/topjohnwu/magisk/di/NetworkingModule.kt index 4e63e0140c4a..c40b39273152 100644 --- a/app/src/main/java/com/topjohnwu/magisk/di/NetworkingModule.kt +++ b/app/src/main/java/com/topjohnwu/magisk/di/NetworkingModule.kt @@ -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 { + 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() } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsItems.kt b/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsItems.kt index 3111453a321a..49e497e24cfa 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsItems.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsItems.kt @@ -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() diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsViewModel.kt index a6fd0cea6145..2915c1b50115 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsViewModel.kt @@ -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) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 66deedde57f1..0e9d592d152e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -175,6 +175,8 @@ Unsupported device or no biometric settings are enabled Customization Add a pretty shortcut in the home screen in case the name and icon are difficult to recognize after hiding the app + DNS over HTTPS + Workaround DNS poisoning in some nations Multiuser Mode Device Owner Only