Files
Magisk-ProxyPinCA/service.sh

117 lines
3.6 KiB
Bash

#!/system/bin/sh
# ProxyPin Certificate Installer - Service Script
# Runs after boot to ensure APEX injection persists for all apps
MODDIR=${0%/*}
LOG_FILE="/data/local/tmp/ProxyPinCert.log"
CERT_DIR="${MODDIR}/system/etc/security/cacerts"
TEMP_DIR="/data/local/tmp/proxypin-apex-ca"
APEX_CACERTS="/apex/com.android.conscrypt/cacerts"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [service] $1" >> "$LOG_FILE"
}
log ""
log "══════════════════════════════════════════════════════"
log "Service script started"
API=$(getprop ro.build.version.sdk)
log "Android API: $API"
# Wait for boot
count=0
while [ "$(getprop sys.boot_completed)" != "1" ] && [ $count -lt 60 ]; do
sleep 1
count=$((count + 1))
done
log "Boot completed (${count}s)"
# Skip for Android < 14
if [ "$API" -lt 34 ]; then
log "Android < 14, skipping"
exit 0
fi
# Find our cert
CERT_FILE=$(find "$CERT_DIR" -maxdepth 1 -type f -name "*.0" 2>/dev/null | head -1)
CERT_NAME=$(basename "$CERT_FILE" 2>/dev/null)
if [ -z "$CERT_NAME" ]; then
log "ERROR: No certificate found"
exit 1
fi
log "Certificate: $CERT_NAME"
# Check if already mounted correctly
if [ -f "$APEX_CACERTS/$CERT_NAME" ]; then
log "✓ Certificate already in APEX"
else
log "Certificate not in APEX, re-injecting..."
# Ensure tmpfs is mounted
if ! mountpoint -q "$TEMP_DIR" 2>/dev/null; then
mkdir -p "$TEMP_DIR"
mount -t tmpfs tmpfs "$TEMP_DIR"
cp -a "$APEX_CACERTS"/* "$TEMP_DIR/" 2>/dev/null
cp -f "$CERT_FILE" "$TEMP_DIR/"
chown -R 0:0 "$TEMP_DIR"
chmod 755 "$TEMP_DIR"
chmod 644 "$TEMP_DIR"/*
APEX_CONTEXT=$(ls -Zd "$APEX_CACERTS" 2>/dev/null | awk '{print $1}')
[ -n "$APEX_CONTEXT" ] && chcon -R "$APEX_CONTEXT" "$TEMP_DIR" 2>/dev/null
fi
# Mount globally
mount --bind "$TEMP_DIR" "$APEX_CACERTS" 2>/dev/null
nsenter --mount=/proc/1/ns/mnt -- mount --bind "$TEMP_DIR" "$APEX_CACERTS" 2>/dev/null
fi
# CRITICAL: Mount in all zygote namespaces
# This ensures ALL apps can see the certificate
log "Injecting to zygote namespaces..."
for zygote in zygote zygote64; do
PID=$(pidof "$zygote" 2>/dev/null)
if [ -n "$PID" ]; then
nsenter --mount=/proc/$PID/ns/mnt -- mount --bind "$TEMP_DIR" "$APEX_CACERTS" 2>/dev/null
log " $zygote (PID $PID)"
fi
done
# Also inject to Settings app (for Trusted Credentials visibility)
SETTINGS_PID=$(pidof com.android.settings 2>/dev/null)
if [ -n "$SETTINGS_PID" ]; then
nsenter --mount=/proc/$SETTINGS_PID/ns/mnt -- mount --bind "$TEMP_DIR" "$APEX_CACERTS" 2>/dev/null
log " Settings app (PID $SETTINGS_PID)"
fi
# Inject to ProxyPin if running
PROXYPIN_PID=$(pidof com.proxy.pin 2>/dev/null)
if [ -z "$PROXYPIN_PID" ]; then
# Try alternative package names
PROXYPIN_PID=$(pidof com.network.proxy 2>/dev/null)
fi
if [ -n "$PROXYPIN_PID" ]; then
nsenter --mount=/proc/$PROXYPIN_PID/ns/mnt -- mount --bind "$TEMP_DIR" "$APEX_CACERTS" 2>/dev/null
log " ProxyPin app (PID $PROXYPIN_PID)"
fi
# Final verification
sleep 2
if [ -f "$APEX_CACERTS/$CERT_NAME" ]; then
log "✓ SUCCESS: Certificate in APEX"
else
log "✗ Certificate may not be visible to all apps"
fi
# Count
APEX_COUNT=$(ls -1 "$APEX_CACERTS"/*.0 2>/dev/null | wc -l)
log "APEX certificates: $APEX_COUNT"
log ""
log "Service completed"
log "══════════════════════════════════════════════════════"