diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml
index 7ffadd2..eb7fab9 100644
--- a/.github/workflows/workflow.yml
+++ b/.github/workflows/workflow.yml
@@ -15,13 +15,6 @@ jobs:
steps:
- uses: actions/checkout@v3
- - name: setup ndk
- uses: nttld/setup-ndk@v1
- id: setup-ndk
- with:
- ndk-version: r23
- add-to-path: true
-
- name: build dist
run: |
git submodule init && git submodule update
@@ -35,3 +28,18 @@ jobs:
artifacts: "adguardcert-*.zip"
token: ${{ secrets.GITHUB_TOKEN }}
generateReleaseNotes: true
+
+ - name: write PR url
+ if: github.event_name == 'pull_request'
+ run: |
+ echo "${{ github.event.pull_request.html_url }}" > pull_request_url.txt
+
+ - name: upload artifact
+ uses: actions/upload-artifact@v3
+ if: github.event_name == 'pull_request'
+ with:
+ name: adguardcert module build
+ path: |
+ adguardcert-*.zip
+ README.md
+ pull_request_url.txt
diff --git a/.gitmodules b/.gitmodules
index b2f6d09..e69de29 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "zygisk_module/jni/libcxx"]
- path = zygisk_module/jni/libcxx
- url = https://github.com/topjohnwu/libcxx.git
diff --git a/README.md b/README.md
index dbe6f37..22feda9 100644
--- a/README.md
+++ b/README.md
@@ -5,15 +5,38 @@ Based on [Move Certificates](https://github.com/Magisk-Modules-Repo/movecert).
This Magisk module supplements [AdGuard for Android][agandroid] and allows installing
AdGuard's CA certificate to the System store on rooted devices.
-## Why could you need it?
+**Attention**
+[Current version](https://github.com/AdguardTeam/adguardcert/releases/latest)
+of this module is designed for Adguard for Android 4.2 and newer.
+
+If you're using AdGuard for Android v4.1 or older, please use the earlier version of
+this magisk module: https://github.com/AdguardTeam/adguardcert/releases/tag/v1.2.
+
+## Explanation
+
+Chrome (and subsequently many other Chromium-based browsers)
+has recently started requiring Certificate Transparency logs
+for CA certs found in the **system certificate store**.
+
+If your device is rooted, and you want AdGuard's CA certificate to be installed
+in the **system store** , then AdGuard will generate two CA certificates and ask you
+to install both of them in the **user store**. This module moves one of them to the
+**system store**. The certificate that is left in the **user store** is cross-signed
+with the one that goes into the **system store**. This allows apps that don't trust
+user certificates to still accept AdGuard's certificate, while apps that do trust
+user certificates (like Chrome or other browsers) will construct a shorter validation
+path to the certificate stored in the **user store**. And since it is stored in the
+**user store**, they won't require CT logs.
+
+## Why would I want AdGuard's certificate in the system store?
AdGuard for Android provides a feature called [HTTPS filtering][httpsfiltering]. It allows
filtering of encrypted HTTPS traffic on your Android device. This feature requires
adding the AdGuard's CA certificate to the list of trusted certificates.
By default, on a non-rooted device only a limited subset of apps (mostly, browsers)
-trust the CA certificates installed to the **User store**. The only option to allow
-filtering of all other apps' traffic is to install the certificate to the **System store**.
+trust the CA certificates installed to the **user store**. The only option to allow
+filtering of all other apps' traffic is to install the certificate to the **system store**.
Unfortunately, this is only possible on rooted devices.
[agandroid]: https://adguard.com/adguard-android/overview.html
@@ -21,26 +44,19 @@ Unfortunately, this is only possible on rooted devices.
## Usage
-1. Enable HTTPS filtering in AdGuard for Android and save AdGuard's certificate to the User store.
-2. Go to *Magisk -> Settings* and enable **Zygisk**.
-3. Download the `.zip` file from the [latest release][latestrelease].
-4. Go to *Magisk -> Modules -> Install from storage* and select the downloaded `.zip` file.
-5. Reboot.
+1. Enable HTTPS filtering in AdGuard for Android and save AdGuard's certificate(s) to the User store
+2. Download the `.zip` file from the [latest release][latestrelease].
+3. Go to *Magisk -> Modules -> Install from storage* and select the downloaded `.zip` file.
+4. Reboot.
-If a new version comes out, repeat steps 3-5 to update the module.
+If a new version comes out, repeat steps 2-4 to update the module.
-The module does its work during the system boot. If your AdGuard certificate changes,
+The module does its work during the system boot. If your AdGuard certificate(s) change,
you'll have to reboot the device for the new certificate to be copied to the system store.
Illustrated instruction
-![Open Magisk settings](https://user-images.githubusercontent.com/5947035/161061257-680c784b-b476-432d-8dfd-2528fe239346.png)
-
-![Enable Zygisk](https://user-images.githubusercontent.com/5947035/161061268-3367d668-cbbd-441d-9e6d-a4cbc3978b3e.png)
-
-![Go back to Magisk main screen](https://user-images.githubusercontent.com/5947035/161061273-329e3f8a-c957-4005-a8f7-2056b1866b08.png)
-
![Open Magisk modules](https://user-images.githubusercontent.com/5947035/161061277-1ada3a87-d0cb-44c0-9edd-77b00669759c.png)
![Install from storage](https://user-images.githubusercontent.com/5947035/161061283-8e3d6ed2-ca36-4825-bca4-fbb9f9185f68.png)
@@ -51,7 +67,7 @@ you'll have to reboot the device for the new certificate to be copied to the sys
-Please note that in order for **Bromite** browser to work properly, you need to set flag "Allow user certificates" in `chrome://flags` to "Enabled" state.
+Please note that in order for **Bromite** browser to work properly, you need to set the "Allow user certificates" flag in `chrome://flags` to "Enabled".
Bromite setup
@@ -62,39 +78,11 @@ Please note that in order for **Bromite** browser to work properly, you need to
[latestrelease]: https://github.com/AdguardTeam/adguardcert/releases/latest/
-## Chrome and Chromium-based browsers
-
-Chrome (and subsequently many other Chromium-based browsers)
-has recently started requiring CT logs for CA certs found in the **System store**.
-This module copies AdGuard's CA certificate from the **User store** to the **System store**.
-It also contains a Zygisk module that reverts any modifications done by Magisk for
-[certain browsers](./zygisk_module/jni/browsers.inc).
-This way the browsers only find AdGuard's certificate in the User store
-and don't complain about the missing CT log, while other apps continue to use the
-same certificate from the System store.
-
## Building
-
-Update git modules:
-
-```shell
-git submodule init && git submodule update
-```
-
-You'll need an Android SDK with NDK installed (tested with NDK 22 and 23). Run:
-
```shell
-ANDROID_HOME= ./dist.sh
+./dist.sh
```
How to release a new version:
1. Push a new tag with a name like `v*`.
2. A new release will be automatically created.
-
-## Advanced
-
-If you prefer to manage your Zygisk denylist yourself, simply remove the Zygisk part of the module:
-
-```shell
-zip adguardcert-v1.0.zip -d "zygisk/*"
-```
diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index 8ca4829..0000000
--- a/build.gradle
+++ /dev/null
@@ -1,17 +0,0 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-buildscript {
- repositories {
- google()
- mavenCentral()
- }
- dependencies {
- classpath "com.android.tools.build:gradle:7.0.3"
-
- // NOTE: Do not place your application dependencies here; they belong
- // in the individual module build.gradle files
- }
-}
-
-task clean(type: Delete) {
- delete rootProject.buildDir
-}
diff --git a/dist.sh b/dist.sh
index ffdd090..4bdf8a3 100755
--- a/dist.sh
+++ b/dist.sh
@@ -1,27 +1,5 @@
#!/bin/bash
-if [ -z "${ANDROID_HOME}" ]; then
- echo "Specify the Android SDK directory through the ANDROID_HOME environment variable"
- exit 1
-fi
-
-NDK_PATH=$(./ndk_path.py)
-
-if [ ! -d "${NDK_PATH}" ]; then
- echo "NDK version ${NDK_VERSION} is required and was not found at ${NDK_PATH}"
- exit 1
-fi
-
-NDK_BUILD="${NDK_PATH}/ndk-build"
-
-(cd ./zygisk_module && ${NDK_BUILD} -j8) || exit 1
-
-mkdir ./module/zygisk
-
-for i in $(ls ./zygisk_module/libs); do
- cp -f ./zygisk_module/libs/$i/*.so ./module/zygisk/$i.so
-done
-
UPDATE_BINARY_URL="https://raw.githubusercontent.com/topjohnwu/Magisk/master/scripts/module_installer.sh"
mkdir -p ./module/META-INF/com/google/android
diff --git a/gradle.properties b/gradle.properties
deleted file mode 100644
index 01b80d7..0000000
--- a/gradle.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-# Project-wide Gradle settings.
-# IDE (e.g. Android Studio) users:
-# Gradle settings configured through the IDE *will override*
-# any settings specified in this file.
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
-# AndroidX package structure to make it clearer which packages are bundled with the
-# Android operating system, and which are packaged with your app"s APK
-# https://developer.android.com/topic/libraries/support-library/androidx-rn
-android.useAndroidX=true
-# Automatically convert third-party libraries to use AndroidX
-android.enableJetifier=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index e708b1c..0000000
Binary files a/gradle/wrapper/gradle-wrapper.jar and /dev/null differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index f4bd034..0000000
--- a/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Sun Sep 26 02:13:18 PDT 2021
-distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip
-distributionPath=wrapper/dists
-zipStorePath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
deleted file mode 100755
index 4f906e0..0000000
--- a/gradlew
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/usr/bin/env sh
-
-#
-# Copyright 2015 the original author or authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-##############################################################################
-##
-## Gradle start up script for UN*X
-##
-##############################################################################
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn () {
- echo "$*"
-}
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=`expr $i + 1`
- done
- case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
-fi
-
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=`save "$@"`
-
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-
-exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
deleted file mode 100644
index ac1b06f..0000000
--- a/gradlew.bat
+++ /dev/null
@@ -1,89 +0,0 @@
-@rem
-@rem Copyright 2015 the original author or authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem https://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-@rem
-
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Resolve any "." and ".." in APP_HOME to make it shorter.
-for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto execute
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/module/module.prop b/module/module.prop
index 3e7d000..d73ed25 100644
--- a/module/module.prop
+++ b/module/module.prop
@@ -1,7 +1,7 @@
id=adguardcert
name=AdGuard Certificate
-version=v1.2
-versionCode=3
+version=v2.0
+versionCode=35
author=AdGuard
-description=Copies AdGuard's CA certificate from the user certificate store to the system store and forces Zygisk unmount procedures for certain browsers.
+description=Moves AdGuard's root CA certificate from the user certificate store to the system certificate store.
updateJson=https://raw.githubusercontent.com/AdguardTeam/adguardcert/master/update.json
diff --git a/module/post-fs-data.sh b/module/post-fs-data.sh
index a823a50..3492e0f 100644
--- a/module/post-fs-data.sh
+++ b/module/post-fs-data.sh
@@ -1,33 +1,73 @@
#!/system/bin/sh
+
+exec > /data/local/tmp/adguardcert.log
+exec 2>&1
+
+set -x
+
MODDIR=${0%/*}
+set_context() {
+ [ "$(getenforce)" = "Enforcing" ] || return 0
+
+ default_selinux_context=u:object_r:system_file:s0
+ selinux_context=$(ls -Zd $1 | awk '{print $1}')
+
+ if [ -n "$selinux_context" ] && [ "$selinux_context" != "?" ]; then
+ chcon -R $selinux_context $2
+ else
+ chcon -R $default_selinux_context $2
+ fi
+}
+
# Android hashes the subject to get the filename, field order is significant.
+# (`openssl x509 -in ... -noout -hash`)
# AdGuard's certificate is "/C=EN/O=AdGuard/CN=AdGuard Personal CA".
# The filename is then . where is an integer to disambiguate
# different certs with the same hash (e.g. when the same cert is installed repeatedly).
-#
+#
# Due to https://github.com/AdguardTeam/AdguardForAndroid/issues/2108
-# 1. Take the last cert with our hash from the user store.
-# Assuming the last installed AdGuard's cert is the correct one.
-# 2. Copy it to the system store under the name ".0".
-# Apparently, some apps may ignore other certs.
+# 1. Retrieve the most recent certificate with our hash from the user store.
+# It is assumed that the last installed AdGuard's cert is the correct one.
+# 2. Copy the AdGuard certificate to the system store under the name ".0".
+# Note that some apps may ignore other certs.
# 3. Remove all certs with our hash from the `cacerts-removed` directory.
# They get there if a certificate is "disabled" in the security settings.
# Apps will reject certs that are in the `cacerts-removed`.
AG_CERT_HASH=0f4ed297
-AG_CERT_FILE=$(ls /data/misc/user/*/cacerts-added/${AG_CERT_HASH}.* | sort | tail -n1)
-cp -f ${AG_CERT_FILE} ${MODDIR}/system/etc/security/cacerts/${AG_CERT_HASH}.0
+AG_CERT_FILE=$(ls /data/misc/user/*/cacerts-added/${AG_CERT_HASH}.* | (IFS=.; while read -r left right; do echo $right $left.$right; done) | sort -nr | (read -r left right; echo $right))
+
+if ! [ -e "${AG_CERT_FILE}" ]; then
+ exit 0
+fi
+
rm -f /data/misc/user/*/cacerts-removed/${AG_CERT_HASH}.*
+cp -f ${AG_CERT_FILE} ${MODDIR}/system/etc/security/cacerts/${AG_CERT_HASH}.0
chown -R 0:0 ${MODDIR}/system/etc/security/cacerts
+set_context /system/etc/security/cacerts ${MODDIR}/system/etc/security/cacerts
-[ "$(getenforce)" = "Enforcing" ] || exit 0
+# Android 14 support
+# Since Magisk ignore /apex for module file injections, use non-Magisk way
+if [ -d /apex/com.android.conscrypt/cacerts ]; then
+ # Clone directory into tmpfs
+ rm -f /data/local/tmp/adg-ca-copy
+ mkdir -p /data/local/tmp/adg-ca-copy
+ mount -t tmpfs tmpfs /data/local/tmp/adg-ca-copy
+ cp -f /apex/com.android.conscrypt/cacerts/* /data/local/tmp/adg-ca-copy/
-default_selinux_context=u:object_r:system_file:s0
-selinux_context=$(ls -Zd /system/etc/security/cacerts | awk '{print $1}')
+ # Do the same as in Magisk module
+ cp -f ${AG_CERT_FILE} /data/local/tmp/adg-ca-copy
+ chown -R 0:0 /data/local/tmp/adg-ca-copy
+ set_context /apex/com.android.conscrypt/cacerts /data/local/tmp/adg-ca-copy
-if [ -n "$selinux_context" ] && [ "$selinux_context" != "?" ]; then
- chcon -R $selinux_context $MODDIR/system/etc/security/cacerts
-else
- chcon -R $default_selinux_context $MODDIR/system/etc/security/cacerts
+ # Mount directory inside APEX if it is valid, and remove temporary one.
+ CERTS_NUM="$(ls -1 /data/local/tmp/adg-ca-copy | wc -l)"
+ if [ "$CERTS_NUM" -gt 10 ]; then
+ mount --bind /data/local/tmp/adg-ca-copy /apex/com.android.conscrypt/cacerts
+ else
+ echo "Cancelling replacing CA storage due to safety"
+ fi
+ umount /data/local/tmp/adg-ca-copy
+ rmdir /data/local/tmp/adg-ca-copy
fi
diff --git a/ndk_path.py b/ndk_path.py
deleted file mode 100755
index 30f4a1c..0000000
--- a/ndk_path.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-
-def get_ndk_path():
- sdk_path = os.environ.get('ANDROID_HOME')
- if os.path.isdir(sdk_path):
- path = os.path.join(sdk_path, 'ndk')
- if os.path.isdir(path):
- # Android Studio can install multiple ndk versions in 'ndk'.
- # Find the newest one.
- ndk_version = None
- for name in os.listdir(path):
- if not ndk_version or ndk_version < name:
- ndk_version = name
- if ndk_version:
- return os.path.join(path, ndk_version)
- ndk_path = os.path.join(sdk_path, 'ndk-bundle')
- if os.path.isdir(ndk_path):
- return ndk_path
- return None
-
-print(get_ndk_path())
diff --git a/settings.gradle b/settings.gradle
deleted file mode 100644
index d0da8c5..0000000
--- a/settings.gradle
+++ /dev/null
@@ -1,8 +0,0 @@
-dependencyResolutionManagement {
- repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
- repositories {
- google()
- mavenCentral()
- }
-}
-include ':zygisk_module'
diff --git a/zygisk_module/.gitignore b/zygisk_module/.gitignore
deleted file mode 100644
index a264cd9..0000000
--- a/zygisk_module/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/build
-/libs
-/obj
diff --git a/zygisk_module/build.gradle b/zygisk_module/build.gradle
deleted file mode 100644
index c2019b7..0000000
--- a/zygisk_module/build.gradle
+++ /dev/null
@@ -1,14 +0,0 @@
-plugins {
- id 'com.android.library'
-}
-
-android {
- compileSdkVersion 31
- ndkVersion "23.1.7779620"
-
- externalNativeBuild {
- ndkBuild {
- path("jni/Android.mk")
- }
- }
-}
diff --git a/zygisk_module/jni/Android.mk b/zygisk_module/jni/Android.mk
deleted file mode 100644
index cc263e6..0000000
--- a/zygisk_module/jni/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := copycert
-LOCAL_SRC_FILES := module.cpp companion.cpp common.cpp
-LOCAL_STATIC_LIBRARIES := libcxx
-LOCAL_LDLIBS := -llog
-include $(BUILD_SHARED_LIBRARY)
-
-include jni/libcxx/Android.mk
-
-# If you do not want to use libc++, link to system stdc++
-# so that you can at least call the new operator in your code
-
-# include $(CLEAR_VARS)
-# LOCAL_MODULE := example
-# LOCAL_SRC_FILES := example.cpp
-# LOCAL_LDLIBS := -llog -lstdc++
-# include $(BUILD_SHARED_LIBRARY)
diff --git a/zygisk_module/jni/Application.mk b/zygisk_module/jni/Application.mk
deleted file mode 100644
index 96948f8..0000000
--- a/zygisk_module/jni/Application.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
-APP_CPPFLAGS := -std=c++17 -fno-exceptions -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden
-APP_STL := none
-APP_PLATFORM := android-21
diff --git a/zygisk_module/jni/browsers.inc b/zygisk_module/jni/browsers.inc
deleted file mode 100644
index cf4d2bb..0000000
--- a/zygisk_module/jni/browsers.inc
+++ /dev/null
@@ -1,48 +0,0 @@
-"com.android.chrome",
-"com.chrome.beta",
-"com.chrome.canary",
-"com.chrome.dev",
-"org.chromium.chrome",
-"com.brave.browser",
-"com.hsv.freeadblockerbrowser",
-"com.microsoft.emmx",
-"com.microsoft.emmx.canary",
-"com.yandex.browser",
-"com.yandex.browser.alpha",
-"com.yandex.browser.beta",
-"com.sec.android.app.sbrowser",
-"com.sec.android.app.sbrowser.beta",
-"com.yandex.browser.lite",
-"jp.co.fenrir.android.sleipnir",
-"jp.co.fenrir.android.sleipnir_black",
-"jp.co.fenrir.android.sleipnir_test",
-"jp.hazuki.yuzubrowser",
-"org.mozilla.fennec",
-"org.mozilla.fennec_aurora",
-"org.mozilla.fennec_fdroid",
-"cn.mozilla.firefox",
-"mobi.browser.flashfox",
-"mobi.browser.flfoxpro",
-"org.adblockplus.browser",
-"org.iron.srware",
-"org.mozilla.firefox",
-"org.mozilla.firefox_beta",
-"org.mozilla.fenix",
-"com.android.browser",
-"com.droid.browser",
-"com.vionika.firephoenix",
-"com.kiwibrowser.browser",
-"org.bromite.bromite",
-"com.vivaldi.browser",
-"com.vivaldi.browser.snapshot",
-"com.brave.browser",
-"com.brave.browser_dev",
-"com.brave.browser_beta",
-"com.brave.browser_default",
-"com.brave.browser_nightly",
-"com.huawei.browser",
-"io.github.forkmaintainers.iceraven",
-"com.stoutner.privacybrowser.free",
-"com.stoutner.privacybrowser.standard",
-"com.naver.whale",
-"us.spotco.mulch",
diff --git a/zygisk_module/jni/common.cpp b/zygisk_module/jni/common.cpp
deleted file mode 100644
index 4e0ba97..0000000
--- a/zygisk_module/jni/common.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "common.h"
-#include
-
-int ag::read_int(int fd) {
- int i;
- if (read(fd, &i, sizeof(i)) != sizeof(i)) {
- return INT_MIN;
- }
- return i;
-}
-
-std::string ag::read_string(int fd) {
- size_t size = 0;
- if (read(fd, &size, sizeof(size)) != sizeof(size)) {
- return "";
- }
- std::string s;
- s.resize(size);
- if (read(fd, s.data(), s.size()) != s.size()) {
- return "";
- }
- return s;
-}
-
-void ag::write_int(int fd, int v) {
- write(fd, &v, sizeof(v));
-}
-
-void ag::write_string(int fd, std::string_view s) {
- size_t size = s.size();
- write(fd, &size, sizeof(size));
- write(fd, s.data(), size);
-}
diff --git a/zygisk_module/jni/common.h b/zygisk_module/jni/common.h
deleted file mode 100644
index 9d2968d..0000000
--- a/zygisk_module/jni/common.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#include
-#include
-#include
-#include
-
-#include
-
-#include
-
-#define LOG_TAG "AdGuardCertificate"
-
-#ifndef NDEBUG
-#define dbglog(fmt_, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "%s(): " fmt_, __func__, ##__VA_ARGS__)
-#else
-#define dbglog(fmt_, ...) ((void) fmt_)
-#endif
-
-#define warnlog(fmt_, ...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "%s(): " fmt_, __func__, ##__VA_ARGS__)
-
-namespace ag {
-
-template
-using Ftor = std::integral_constant;
-using Dir = std::unique_ptr>;
-
-int read_int(int fd);
-std::string read_string(int fd);
-
-void write_int(int fd, int v);
-void write_string(int fd, std::string_view s);
-
-}
diff --git a/zygisk_module/jni/companion.cpp b/zygisk_module/jni/companion.cpp
deleted file mode 100644
index 68cc9cc..0000000
--- a/zygisk_module/jni/companion.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include "common.h"
-#include "zygisk.hpp"
-
-#define APP_ID(uid) (uid % 100000)
-
-using Map = std::unordered_map;
-static std::shared_ptr