diff --git a/module/module.prop b/module/module.prop index 85ccaf3..0db5eac 100644 --- a/module/module.prop +++ b/module/module.prop @@ -1,6 +1,6 @@ id=adguardcert name=AdGuard Certificate -version=v2.0-beta4 -versionCode=33 +version=v2.0-beta5 +versionCode=34 author=AdGuard description=Moves AdGuard's root CA certificate from the user certificate store to the system certificate store. diff --git a/module/post-fs-data.sh b/module/post-fs-data.sh index 5229c6c..e6864aa 100644 --- a/module/post-fs-data.sh +++ b/module/post-fs-data.sh @@ -1,6 +1,25 @@ #!/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". @@ -18,20 +37,36 @@ MODDIR=${0%/*} AG_CERT_HASH=0f4ed297 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 - cp -f ${AG_CERT_FILE} ${MODDIR}/system/etc/security/cacerts/${AG_CERT_HASH}.0 - rm -f /data/misc/user/*/cacerts-removed/${AG_CERT_HASH}.* +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 [ -e /apex/com.android.conscrypt/cacerts ]; then + # Clone directory into tmpfs + mkdir -p /data/local/tmp-ca-copy + mount -t tmpfs tmpfs /data/local/tmp/tmp-ca-copy + cp -f /apex/com.android.conscrypt/cacerts/* /data/local/tmp/tmp-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/tmp-ca-copy + chown -R 0:0 /data/local/tmp/tmp-ca-copy + set_context /apex/com.android.conscrypt/cacerts /data/local/tmp/tmp-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 /apex/com.android.conscrypt/cacerts | wc -l)" + if [ "$CERTS_NUM" -gt 10 ]; then + mount --bind /data/local/tmp/tmp-ca-copy /apex/com.android.conscrypt/cacerts + else + echo "Cancelling replacing CA storage due to safety" + fi + umount /data/local/tmp/tmp-ca-copy + rmdir /data/local/tmp/tmp-ca-copy fi