Skip to content

refactor: remove conscrypt lib, use own trust manager, refine networking #1319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
android:banner="@mipmap/ic_banner"
android:fullBackupContent="@xml/backup_descriptor"
android:dataExtractionRules="@xml/data_extraction_rules"
android:networkSecurityConfig="@xml/network_security_config"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import okhttp3.Request
import okhttp3.Response
import java.net.URI


@AnyThread
class CloudflareKiller : Interceptor {
companion object {
Expand Down Expand Up @@ -100,8 +99,7 @@ class CloudflareKiller : Interceptor {
mapOf("user-agent" to it)
} ?: emptyMap()

val headers =
getHeaders(request.headers.toMap() + userAgentMap, cookies + request.cookies)
val headers = getHeaders(request.headers.toMap() + userAgentMap, cookies + request.cookies)
return app.baseClient.newCall(
request.newBuilder()
.headers(headers)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,43 @@
package com.lagradost.cloudstream3.network

import android.annotation.SuppressLint
import android.content.Context
import androidx.preference.PreferenceManager
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.USER_AGENT
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.nicehttp.Requests
import com.lagradost.nicehttp.ignoreAllSSLErrors
import okhttp3.Cache
import okhttp3.ConnectionSpec
import okhttp3.Headers
import okhttp3.Headers.Companion.toHeaders
import okhttp3.OkHttpClient
import org.conscrypt.Conscrypt
import java.io.File
import java.security.Security
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

fun Requests.initClient(context: Context) {
this.baseClient = buildDefaultClient(context)
}

fun buildDefaultClient(context: Context): OkHttpClient {
normalSafeApiCall { Security.insertProviderAt(Conscrypt.newProvider(), 1) }


// see trust manager function below, this lib was used earlier
// normalSafeApiCall { Security.insertProviderAt(Conscrypt.newProvider(), 1) }

val settingsManager = PreferenceManager.getDefaultSharedPreferences(context)
val dns = settingsManager.getInt(context.getString(R.string.dns_pref), 0)

val builder = OkHttpClient.Builder()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not understand, you never use this builder anywhere? Are you sure you dont mean val baseClient = builder....

Copy link
Contributor Author

@IndusAryan IndusAryan Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we building the base client only right with custom dns ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but where exactly is builder variable used below this line? It looks like it is garbage collected after the return, as it is not used or returned.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merged into a single builder and returned as one base client

.ignoreAllSSLErrors()
.sslSocketFactory(getUnsafeSSLSocketFactory(), TrustAllCerts())
.hostnameVerifier { _, _ -> true }
.connectionSpecs(listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS))
val baseClient = OkHttpClient.Builder()
.followRedirects(true)
.followSslRedirects(true)
.ignoreAllSSLErrors()
.cache(
// Note that you need to add a ResponseInterceptor to make this 100% active.
// The server response dictates if and when stuff should be cached.
Expand All @@ -37,31 +47,62 @@ fun buildDefaultClient(context: Context): OkHttpClient {
)
).apply {
when (dns) {
1 -> addGoogleDns()
2 -> addCloudFlareDns()
// 3 -> addOpenDns()
4 -> addAdGuardDns()
5 -> addDNSWatchDns()
6 -> addQuad9Dns()
1 -> builder.addGoogleDns()
2 -> builder.addCloudFlareDns()
// 3 -> builder.addOpenDns()
4 -> builder.addAdGuardDns()
5 -> builder.addDNSWatchDns()
6 -> builder.addQuad9Dns()
7 -> addDnsSbDns()
8 -> addCanadianShieldDns()
else -> { }
}
}
// Needs to be build as otherwise the other builders will change this object
.build()
}.build()
return baseClient
}

//val Request.cookies: Map<String, String>
// get() {
// return this.headers.getCookies("Cookie")
// }
/** So what happens in older android versions like 9 is that their network security provider is
* not much robust, and some extensions store data in non protected cheap servers and urls, thus
* the app rejects connection, We used google conscrypt provider lib earlier but its version 5.2.3
* broke and crashed the app without resolving certs, so we removed it and implemented own trust
* manager that trust all certificates + network_security_config.xml especially for Android 9 =-below
**/
@SuppressLint("CustomX509TrustManager")
class TrustAllCerts : X509TrustManager {
@SuppressLint("TrustAllX509TrustManager")
override fun checkClientTrusted(
chain: Array<java.security.cert.X509Certificate>,
authType: String
) {} // Trust all client certificates

@SuppressLint("TrustAllX509TrustManager")
override fun checkServerTrusted(
chain: Array<java.security.cert.X509Certificate>,
authType: String
) {} // Trust all server certificates

@SuppressLint("TrustAllX509TrustManager")
override fun getAcceptedIssuers(): Array<java.security.cert.X509Certificate> {
return emptyArray()
}
}

/**
* Creates an SSLSocketFactory that uses a TrustManager which trusts all certificates.
* @return A custom SSLSocketFactory for bypassing SSL verification.
*/
fun getUnsafeSSLSocketFactory(): SSLSocketFactory {
val trustAllCerts = arrayOf<TrustManager>(TrustAllCerts())

val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, trustAllCerts, java.security.SecureRandom())
return sslContext.socketFactory
}

private val DEFAULT_HEADERS = mapOf("user-agent" to USER_AGENT)
private val DEFAULT_HEADERS = mapOf("User-Agent" to USER_AGENT)

/**
* Set headers > Set cookies > Default headers > Default Cookies
* TODO REMOVE AND REPLACE WITH NICEHTTP
*/
fun getHeaders(
headers: Map<String, String>,
Expand Down
20 changes: 20 additions & 0 deletions app/src/main/res/xml/network_security_config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<!-- Allow all domains, including subdomains -->
<domain includeSubdomains="true">.</domain>

<!-- Allow any certificate, including those with errors -->
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</domain-config>

<debug-overrides>
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>
Loading