feat: initial commit — antigravity proxy with MITM, standalone LS, and snapshot tooling
This commit is contained in:
331
scripts/mitm-wrapper.sh
Executable file
331
scripts/mitm-wrapper.sh
Executable file
@@ -0,0 +1,331 @@
|
||||
#!/usr/bin/env bash
|
||||
# ╔═══════════════════════════════════════════════════════════════════════════╗
|
||||
# ║ Antigravity MITM LS Wrapper ║
|
||||
# ║ ║
|
||||
# ║ This script replaces the real Antigravity language server binary. ║
|
||||
# ║ It injects HTTPS_PROXY and NODE_EXTRA_CA_CERTS environment variables ║
|
||||
# ║ so the MITM proxy can intercept LS<->API traffic. ║
|
||||
# ║ ║
|
||||
# ║ Install: ./mitm-wrapper.sh install ║
|
||||
# ║ Uninstall: ./mitm-wrapper.sh uninstall ║
|
||||
# ║ (No args = act as wrapper, exec the real binary with injected env) ║
|
||||
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
||||
set -euo pipefail
|
||||
|
||||
# ── Config ────────────────────────────────────────────────────────────────────
|
||||
# Resolve the real user's home (not /root when running under sudo)
|
||||
if [[ -n "${SUDO_USER:-}" ]]; then
|
||||
REAL_HOME="$(getent passwd "$SUDO_USER" | cut -d: -f6)"
|
||||
else
|
||||
REAL_HOME="$HOME"
|
||||
fi
|
||||
MITM_PORT_FILE="${REAL_HOME}/.config/antigravity-proxy/mitm-port"
|
||||
if [[ -n "${ANTIGRAVITY_MITM_PORT:-}" ]]; then
|
||||
MITM_PORT="$ANTIGRAVITY_MITM_PORT"
|
||||
elif [[ -f "$MITM_PORT_FILE" ]]; then
|
||||
MITM_PORT="$(cat "$MITM_PORT_FILE" 2>/dev/null || echo 8742)"
|
||||
else
|
||||
MITM_PORT="8742"
|
||||
fi
|
||||
CA_PATH="${REAL_HOME}/.config/antigravity-proxy/mitm-ca.pem"
|
||||
|
||||
# Antigravity LS — discovered dynamically from running processes.
|
||||
# Hardcoded paths are only used as a fallback if no LS process is running.
|
||||
LS_FALLBACK_DIRS=(
|
||||
"/usr/share/antigravity/resources/app/extensions/antigravity/bin"
|
||||
"${REAL_HOME}/.antigravity/extensions/antigravity.antigravity-*/dist/bundled/language-server/bin"
|
||||
"${REAL_HOME}/.cursor/extensions/antigravity.antigravity-*/dist/bundled/language-server/bin"
|
||||
"${REAL_HOME}/.vscode/extensions/antigravity.antigravity-*/dist/bundled/language-server/bin"
|
||||
"/opt/antigravity/language-server/bin"
|
||||
)
|
||||
|
||||
BACKUP_SUFFIX=".real"
|
||||
|
||||
# ── Colors ────────────────────────────────────────────────────────────────────
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
CYAN='\033[0;36m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m'
|
||||
|
||||
# ── Find LS binary ───────────────────────────────────────────────────────────
|
||||
find_ls_binary() {
|
||||
# Method 1: Find from running process via /proc
|
||||
if [[ -d /proc ]]; then
|
||||
for pid_dir in /proc/[0-9]*; do
|
||||
local exe_target
|
||||
exe_target="$(readlink "${pid_dir}/exe" 2>/dev/null)" || continue
|
||||
# Strip " (deleted)" suffix that appears when the binary was unlinked
|
||||
exe_target="${exe_target% (deleted)}"
|
||||
if [[ "$exe_target" == *language_server_linux* ]] || \
|
||||
[[ "$exe_target" == *antigravity-language-server* ]]; then
|
||||
# FIX: If the running process is the backup (.real), strip the suffix
|
||||
# so we return the path to the base binary name.
|
||||
echo "${exe_target%$BACKUP_SUFFIX}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Method 2: Fallback — scan known directories for common binary names
|
||||
local bin_names=("language_server_linux_x64" "language_server_linux_arm64" "antigravity-language-server")
|
||||
for dir_pattern in "${LS_FALLBACK_DIRS[@]}"; do
|
||||
for dir in $dir_pattern; do
|
||||
[[ -d "$dir" ]] || continue
|
||||
for name in "${bin_names[@]}"; do
|
||||
local path="${dir}/${name}"
|
||||
if [[ -f "$path" || -f "${path}${BACKUP_SUFFIX}" ]]; then
|
||||
echo "$path"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# ── Install ──────────────────────────────────────────────────────────────────
|
||||
cmd_install() {
|
||||
# Find the LS binary first (quiet, just to check permissions)
|
||||
local ls_path
|
||||
ls_path=$(find_ls_binary) || ls_path="${1:-}"
|
||||
|
||||
# Allow override
|
||||
if [[ -n "${1:-}" ]]; then
|
||||
ls_path="$1"
|
||||
fi
|
||||
|
||||
# Check permissions upfront — re-exec with sudo before doing anything
|
||||
if [[ -n "$ls_path" ]]; then
|
||||
local ls_dir
|
||||
ls_dir="$(dirname "$ls_path")"
|
||||
if [[ ! -w "$ls_dir" ]] && [[ "$EUID" -ne 0 ]]; then
|
||||
echo -e " ${RED}✗${NC} ${ls_dir} requires elevated permissions"
|
||||
echo -e " run: sudo $0 install ${1:-}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "${BOLD}${CYAN}Antigravity MITM Wrapper Installer${NC}"
|
||||
echo -e "───────────────────────────────────"
|
||||
echo ""
|
||||
|
||||
# Find the LS binary (for real this time, with output)
|
||||
if [[ -z "$ls_path" ]]; then
|
||||
echo -e " ${RED}✗${NC} Could not find Antigravity language server binary."
|
||||
echo -e " No LS process found in /proc, and fallback paths didn't match."
|
||||
echo ""
|
||||
echo -e " Set the path manually:"
|
||||
echo -e " $0 install /path/to/language_server_linux_x64"
|
||||
exit 1
|
||||
fi
|
||||
echo -e " ${GREEN}✓${NC} Found LS: ${ls_path}"
|
||||
|
||||
local real_path="${ls_path}${BACKUP_SUFFIX}"
|
||||
local wrapper_dir
|
||||
wrapper_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
local wrapper_src="${wrapper_dir}/mitm-wrapper.sh"
|
||||
|
||||
# Verify the binary exists and is not already wrapped
|
||||
if [[ -f "$real_path" ]]; then
|
||||
echo -e " ${YELLOW}!${NC} Already installed (backup exists at ${real_path})"
|
||||
echo -e " Run '$0 uninstall' first to reinstall."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ! -f "$ls_path" ]]; then
|
||||
echo -e " ${RED}✗${NC} Binary not found: ${ls_path}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify it's a real binary, not already our wrapper
|
||||
if head -c 100 "$ls_path" | grep -q 'ANTIGRAVITY_MITM_PORT'; then
|
||||
echo -e " ${YELLOW}!${NC} Already wrapped (script detected). Run '$0 uninstall' first."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check CA cert
|
||||
if [[ ! -f "$CA_PATH" ]]; then
|
||||
echo -e " ${YELLOW}!${NC} CA cert not found at ${CA_PATH}"
|
||||
echo -e " Start the proxy first to generate it."
|
||||
echo -e " Continuing install anyway..."
|
||||
else
|
||||
echo -e " ${GREEN}✓${NC} CA cert: ${CA_PATH}"
|
||||
fi
|
||||
|
||||
# Back up the real binary
|
||||
cp -p "$ls_path" "$real_path"
|
||||
echo -e " ${GREEN}✓${NC} Backed up real binary to ${real_path}"
|
||||
|
||||
# Remove the original before writing (avoids "Text file busy" if LS is running)
|
||||
rm -f "$ls_path"
|
||||
|
||||
# Create the wrapper script in-place
|
||||
tee "$ls_path" > /dev/null << 'WRAPPER_EOF'
|
||||
#!/usr/bin/env bash
|
||||
# Antigravity MITM LS Wrapper — auto-generated, do not edit.
|
||||
# The LS is a Go binary — it reads HTTPS_PROXY and SSL_CERT_FILE (not NODE_EXTRA_CA_CERTS).
|
||||
# Go's gRPC library also reads GRPC_DEFAULT_SSL_ROOTS_FILE_PATH for root certs.
|
||||
# We build a combined CA bundle (system CAs + MITM CA) and inject it.
|
||||
|
||||
REAL_BINARY="${BASH_SOURCE[0]}.real"
|
||||
|
||||
if [[ ! -f "$REAL_BINARY" ]]; then
|
||||
echo "ERROR: Real LS binary not found at $REAL_BINARY" >&2
|
||||
echo "Run 'mitm-wrapper.sh uninstall' and reinstall." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Inject MITM proxy (don't override if already set)
|
||||
export HTTPS_PROXY="${HTTPS_PROXY:-http://127.0.0.1:__MITM_PORT__}"
|
||||
|
||||
# Build combined CA bundle: system CAs + MITM CA
|
||||
MITM_CA="__CA_PATH__"
|
||||
COMBINED_CA="/tmp/antigravity-mitm-combined-ca.pem"
|
||||
if [[ -f "$MITM_CA" ]]; then
|
||||
# Find system CA bundle
|
||||
SYS_CA=""
|
||||
for candidate in /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt /etc/ssl/cert.pem; do
|
||||
if [[ -f "$candidate" ]]; then
|
||||
SYS_CA="$candidate"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ -n "$SYS_CA" ]]; then
|
||||
cat "$SYS_CA" "$MITM_CA" > "$COMBINED_CA" 2>/dev/null
|
||||
export SSL_CERT_FILE="$COMBINED_CA"
|
||||
# Go's gRPC library may use this instead of SSL_CERT_FILE
|
||||
export GRPC_DEFAULT_SSL_ROOTS_FILE_PATH="$COMBINED_CA"
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "$REAL_BINARY" "$@"
|
||||
WRAPPER_EOF
|
||||
|
||||
# Substitute actual values
|
||||
sed -i "s|__MITM_PORT__|${MITM_PORT}|g" "$ls_path"
|
||||
sed -i "s|__CA_PATH__|${CA_PATH}|g" "$ls_path"
|
||||
|
||||
# Make executable
|
||||
chmod +x "$ls_path"
|
||||
|
||||
echo -e " ${GREEN}✓${NC} Wrapper installed at ${ls_path}"
|
||||
echo ""
|
||||
echo -e " ${BOLD}How it works:${NC}"
|
||||
echo -e " When Antigravity starts the LS, the wrapper will:"
|
||||
echo -e " 1. Set ${CYAN}HTTPS_PROXY${NC}=http://127.0.0.1:${MITM_PORT}"
|
||||
echo -e " 2. Build combined CA bundle (system + MITM) at /tmp/antigravity-mitm-combined-ca.pem"
|
||||
echo -e " 3. Set ${CYAN}SSL_CERT_FILE${NC} to the combined bundle"
|
||||
echo -e " 4. Exec the real LS binary with all original args"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}Note:${NC} Restart Antigravity for the wrapper to take effect."
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ── Uninstall ────────────────────────────────────────────────────────────────
|
||||
cmd_uninstall() {
|
||||
# Check permissions upfront
|
||||
local ls_path
|
||||
ls_path=$(find_ls_binary) || true
|
||||
if [[ -n "$ls_path" ]] && [[ ! -w "$(dirname "$ls_path")" ]] && [[ "$EUID" -ne 0 ]]; then
|
||||
echo -e " ${RED}✗${NC} $(dirname "$ls_path") requires elevated permissions"
|
||||
echo -e " run: sudo $0 uninstall"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${BOLD}${CYAN}Antigravity MITM Wrapper Uninstaller${NC}"
|
||||
echo -e "─────────────────────────────────────"
|
||||
echo ""
|
||||
|
||||
if [[ -n "$ls_path" ]]; then
|
||||
local real_path="${ls_path}${BACKUP_SUFFIX}"
|
||||
if [[ -f "$real_path" ]]; then
|
||||
mv -f "$real_path" "$ls_path"
|
||||
echo -e " ${GREEN}✓${NC} Restored real binary at ${ls_path}"
|
||||
else
|
||||
echo -e " ${YELLOW}!${NC} No backup found at ${real_path}"
|
||||
echo -e " The LS binary may not be wrapped."
|
||||
fi
|
||||
else
|
||||
echo -e " ${RED}✗${NC} Could not find Antigravity language server binary."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e " ${YELLOW}Note:${NC} Restart Antigravity for the change to take effect."
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ── Status ───────────────────────────────────────────────────────────────────
|
||||
cmd_status() {
|
||||
echo -e "${BOLD}${CYAN}Antigravity MITM Wrapper Status${NC}"
|
||||
echo -e "────────────────────────────────"
|
||||
echo ""
|
||||
|
||||
local ls_path
|
||||
if ls_path=$(find_ls_binary); then
|
||||
echo -e " ${GREEN}✓${NC} LS binary: ${ls_path}"
|
||||
|
||||
local real_path="${ls_path}${BACKUP_SUFFIX}"
|
||||
if [[ -f "$real_path" ]]; then
|
||||
echo -e " ${GREEN}✓${NC} Wrapper: ${BOLD}installed${NC}"
|
||||
echo -e " ${GREEN}✓${NC} Real binary: ${real_path}"
|
||||
|
||||
# Check if wrapper is valid
|
||||
if head -c 200 "$ls_path" | grep -q 'MITM LS Wrapper'; then
|
||||
echo -e " ${GREEN}✓${NC} Wrapper script: valid"
|
||||
else
|
||||
echo -e " ${RED}✗${NC} Wrapper script: ${BOLD}corrupted or replaced${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e " ${YELLOW}○${NC} Wrapper: ${BOLD}not installed${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e " ${RED}✗${NC} LS binary: not found"
|
||||
fi
|
||||
|
||||
# Check CA cert
|
||||
if [[ -f "$CA_PATH" ]]; then
|
||||
echo -e " ${GREEN}✓${NC} CA cert: ${CA_PATH}"
|
||||
else
|
||||
echo -e " ${RED}✗${NC} CA cert: not found (start proxy first)"
|
||||
fi
|
||||
|
||||
# Check MITM port
|
||||
if ss -tlnp 2>/dev/null | grep -q ":${MITM_PORT} "; then
|
||||
echo -e " ${GREEN}✓${NC} MITM proxy: listening on :${MITM_PORT}"
|
||||
else
|
||||
echo -e " ${YELLOW}○${NC} MITM proxy: not running on :${MITM_PORT}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ── Main ─────────────────────────────────────────────────────────────────────
|
||||
case "${1:-}" in
|
||||
install)
|
||||
shift
|
||||
cmd_install "${1:-}"
|
||||
;;
|
||||
uninstall)
|
||||
cmd_uninstall
|
||||
;;
|
||||
status)
|
||||
cmd_status
|
||||
;;
|
||||
-h|--help)
|
||||
echo "Usage: $0 {install|uninstall|status}"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " install [path] Install MITM wrapper (auto-detect or specify path)"
|
||||
echo " uninstall Restore original LS binary"
|
||||
echo " status Show wrapper installation status"
|
||||
echo ""
|
||||
echo "Environment:"
|
||||
echo " ANTIGRAVITY_MITM_PORT MITM proxy port (default: 8742)"
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {install|uninstall|status}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user