generated from ReVanced/revanced-patches-template
-
-
Notifications
You must be signed in to change notification settings - Fork 604
feat: Add Custom network security patch
#6151
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
Merged
+182
−0
Merged
Changes from 10 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
0a7da89
Add CustomCertificatesPatch.kt
Pawloland c87c558
Fix case to be in line with variable name
Pawloland 873a5e1
Minor cleanup
Pawloland be013bf
Update patches/src/main/kotlin/app/revanced/patches/all/misc/customce…
Pawloland 03fddec
Update patches/src/main/kotlin/app/revanced/patches/all/misc/customce…
Pawloland 8eb3dc0
Update patches/src/main/kotlin/app/revanced/patches/all/misc/customce…
Pawloland c935b19
Update patches/src/main/kotlin/app/revanced/patches/all/misc/customce…
Pawloland b352276
Update patches/src/main/kotlin/app/revanced/patches/all/misc/customce…
Pawloland 119dd3e
Fix missing import
Pawloland a4e3a56
Refactor customNetworkSecurityPatch
Pawloland eb84df8
Change indent
Pawloland 8659135
Add temp variable
Pawloland 24163c3
Remove unnecessary method calls
Pawloland ab9ac12
Change val name to match key targetDomains
Pawloland 8deef55
Change capitalisation
Pawloland f0fd64d
Change more capitalizations
Pawloland 620738f
Move constant values to execute
Pawloland d32c175
Remove .apply() method call
Pawloland 3695c1e
Refactor generateNetworkSecurityConfig function
Pawloland File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
188 changes: 188 additions & 0 deletions
188
...c/main/kotlin/app/revanced/patches/all/misc/customcertificates/CustomCertificatesPatch.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,188 @@ | ||
| package app.revanced.patches.all.misc.customcertificates | ||
|
|
||
| import app.revanced.patcher.patch.PatchException | ||
| import app.revanced.patcher.patch.booleanOption | ||
| import app.revanced.patcher.patch.resourcePatch | ||
| import app.revanced.patcher.patch.stringsOption | ||
| import app.revanced.util.Utils.trimIndentMultiline | ||
| import org.w3c.dom.Element | ||
| import java.io.File | ||
|
|
||
|
|
||
| private const val NSC_FILE_NAME_BARE = "network_security_config" | ||
| private const val RES_XML_DIR = "res/xml" | ||
| private const val RES_RAW_DIR = "res/raw" | ||
| private const val NSC_FILE_NAME_WITH_SUFFIX = "$NSC_FILE_NAME_BARE.xml" | ||
|
|
||
|
|
||
| val customNetworkSecurityPatch = resourcePatch( | ||
| name = "Custom network security", | ||
| description = "Allows trusting custom certificate authorities for a specific domain.", | ||
| use = false | ||
| ) { | ||
|
|
||
| val domains by stringsOption( | ||
| key = "targetDomains", | ||
Pawloland marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| title = "Target Domains", | ||
Pawloland marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| description = "List of domains to which the custom trust configuration will be applied (one domain per entry).", | ||
| default = listOf("example.com"), | ||
| required = true | ||
| ) | ||
|
|
||
| val includeSubdomains by booleanOption( | ||
| key = "includeSubdomains", | ||
| title = "Include subdomains", | ||
| description = "Applies the configuration to all subdomains of the target domains.", | ||
| default = false, | ||
| required = true | ||
| ) | ||
|
|
||
| val customCAFilePaths by stringsOption( | ||
| key = "customCAFilePaths", | ||
Pawloland marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| title = "Custom CA file paths", | ||
| description = """ | ||
| List of paths to files in PEM or DER format (one file path per entry). | ||
|
|
||
| Makes an app trust the provided custom certificate authorities (CAs), | ||
| for the specified domains, and if the option "Include Subdomains" is enabled then also the subdomains. | ||
|
|
||
|
|
||
| CA files will be bundled in res/raw/ of resulting APK | ||
| """.trimIndentMultiline(), | ||
| default = null, | ||
| required = false | ||
| ) | ||
|
|
||
| val allowUserCerts by booleanOption( | ||
| key = "allowUserCerts", | ||
| title = "Trust User-Added CAs", | ||
Pawloland marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| description = "Makes an app trust certificates from the Android user store for the specified domains, and if the option \"Include Subdomains\" is enabled then also the subdomains.", | ||
|
|
||
| default = false, | ||
| required = true | ||
| ) | ||
|
|
||
| val allowSystemCerts by booleanOption( | ||
| key = "allowSystemCerts", | ||
| title = "Trust System CAs", | ||
Pawloland marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| description = "Makes an app trust certificates from the Android system store for the specified domains, and and if the option \"Include Subdomains\" is enabled then also the subdomains.", | ||
|
|
||
| default = true, | ||
| required = true | ||
| ) | ||
|
|
||
| val allowCleartextTraffic by booleanOption( | ||
| key = "allowCleartextTraffic", | ||
| title = "Allow Cleartext Traffic (HTTP)", | ||
Pawloland marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| description = "Allows unencrypted HTTP traffic for the specified domains, and if \"Include Subdomains\" is enabled then also the subdomains.", | ||
|
|
||
| default = false, | ||
| required = true | ||
| ) | ||
|
|
||
| val overridePins by booleanOption( | ||
| key = "overridePins", | ||
| title = "Override Certificate Pinning", | ||
Pawloland marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| description = "Overrides certificate pinning for the specified domains and their subdomains if the option \"Include Subdomains\" is enabled to allow inspecting app traffic via a proxy.", | ||
|
|
||
| default = false, | ||
| required = true | ||
| ) | ||
|
|
||
| fun generateNetworkSecurityConfig(): String { | ||
| val domains = domains ?: emptyList() | ||
| val includeSubdomains = includeSubdomains ?: false | ||
| val customCAFilePaths = customCAFilePaths ?: emptyList() | ||
| val allowUser = allowUserCerts ?: false | ||
| val allowSystem = allowSystemCerts ?: true | ||
| val allowCleartextTraffic = allowCleartextTraffic ?: false | ||
| val overridePins = overridePins ?: false | ||
|
|
||
|
|
||
| val domainsXMLString = StringBuilder() | ||
| domains.forEachIndexed { index, domain -> | ||
| val domainLine = """ <domain includeSubdomains="$includeSubdomains">$domain</domain>""" | ||
| if (index < domains.lastIndex) { | ||
| domainsXMLString.appendLine(domainLine) | ||
| } else { | ||
| domainsXMLString.append(domainLine) | ||
| } | ||
| } | ||
|
|
||
| val trustAnchorsXMLString = StringBuilder() | ||
| if (allowSystem) { | ||
| trustAnchorsXMLString.appendLine() | ||
| trustAnchorsXMLString.append(""" <certificates src="system" overridePins="$overridePins" />""") | ||
| } | ||
| if (allowUser) { | ||
| trustAnchorsXMLString.appendLine() | ||
| trustAnchorsXMLString.append(""" <certificates src="user" overridePins="$overridePins" />""") | ||
| } | ||
|
|
||
| for (caFilePath in customCAFilePaths) { | ||
| val caFileNameWithoutSuffix = caFilePath.substringAfterLast('/').substringBeforeLast('.') | ||
| trustAnchorsXMLString.appendLine() | ||
| trustAnchorsXMLString.append(""" <certificates src="@raw/$caFileNameWithoutSuffix" overridePins="$overridePins"/>""") | ||
| } | ||
|
|
||
| if (trustAnchorsXMLString.isBlank()) { | ||
| throw PatchException("At least one trust anchor (System, User, or Custom CA) must be enabled.") | ||
| } | ||
|
|
||
| return """ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <network-security-config> | ||
| <domain-config cleartextTrafficPermitted="$allowCleartextTraffic"> | ||
| $domainsXMLString | ||
| <trust-anchors>$trustAnchorsXMLString | ||
| </trust-anchors> | ||
| </domain-config> | ||
| </network-security-config> | ||
| """.trimIndent() | ||
| } | ||
|
|
||
|
|
||
| execute { | ||
| document("AndroidManifest.xml").use { document -> | ||
| val applicationNode = | ||
| document | ||
| .getElementsByTagName("application") | ||
Pawloland marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| .item(0) as Element | ||
|
|
||
| applicationNode.setAttribute("android:networkSecurityConfig", "@xml/$NSC_FILE_NAME_BARE") | ||
| } | ||
|
|
||
|
|
||
| File(get(RES_XML_DIR), NSC_FILE_NAME_WITH_SUFFIX).apply { | ||
| writeText(generateNetworkSecurityConfig()) | ||
| } | ||
|
|
||
|
|
||
|
|
||
| for (customCAFilePath in customCAFilePaths ?: emptyList()) { | ||
| File(customCAFilePath).apply { | ||
Pawloland marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (!exists()) { | ||
| throw PatchException( | ||
| "The custom CA file path cannot be found: " + | ||
| absolutePath | ||
| ) | ||
| } | ||
|
|
||
| if (!isFile) { | ||
| throw PatchException( | ||
| "The custom CA file path must be a file: " | ||
| + absolutePath | ||
| ) | ||
| } | ||
| } | ||
| val caFileNameWithoutSuffix = customCAFilePath.substringAfterLast('/').substringBefore('.') | ||
| File( | ||
| get(RES_RAW_DIR), | ||
| caFileNameWithoutSuffix | ||
| ).writeText(File(customCAFilePath).readText()) | ||
Pawloland marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
Pawloland marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
|
|
||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.