#!/usr/bin/bash

get_binary() {
    temp=`whereis -b $1`
    array=( $temp )
    length=${#array[@]}
    if [ "$length" -eq 1 ]; then
        echo $1
    fi
    length=$(($length - 1))
    for i in `seq 1 $length`; do
        if [ -x "${array[$i]}" ]; then
            echo ${array[$i]}
        fi
    done
}

ID=$(get_binary id)
WHOAMI=$(get_binary whoami)
TAIL=$(get_binary tail)
PWD=$(get_binary pwd)
SSH=$(get_binary ssh)
CAT=$(get_binary cat)
GREP=$(get_binary grep)

is_cagefs_enabled() {
    # return 0 when cagefs is enabled for user
    /bin/cagefs_enter.proxied ls -ld /var/.cagefs > /dev/null 2>&1
    return $?
}

is_proxy_enabled() {
    # return 0 when execution via proxy is enabled
    if $GREP -P '^cagefs_enter_proxied\s*=\s*0' /etc/sysconfig/cloudlinux > /dev/null 2>&1; then
        return 1
    fi
    return 0
}

##CageFS proxyexec wrapper - ver 16

# POSIX single-quote escaping for values embedded in the ssh remote command.
# Unlike `printf %q`, single-quoted output re-parses correctly under any POSIX
# shell (the origin login shell need not be bash) and is lossless for arbitrary
# bytes. Each embedded ' becomes the '\'' sequence. (parity with
# proxyexec/cagefs.proxy.program, CLOS-4596)
sq() {
    local s=${1//\'/\'\\\'\'}
    printf "'%s'" "$s"
}

USR=`$WHOAMI`

if [ "$USR" == "root" ]; then
    echo "This program can not be run as root"
    exit 1
fi

is_proxy_enabled
proxy_enabled=$?

if [ "$proxy_enabled" -ne 0 ]; then
    # when proxy is disabled - call original cagefs_enter binary
    /bin/cagefs_enter.proxied "$@"
    exit $?
fi

PREFIX=`$ID -u|$TAIL -c 3`
USER_TOKEN_PATH="/var/cagefs/$PREFIX/$USR/.cagefs/.cagefs.token"
WEBSITE_ISOLATION_FLAG="/opt/cloudlinux/flags/enabled-flags.d/website-isolation.flag"

# WEBSITE_TOKEN_PATH override — DO NOT REMOVE.
#
# This is the IPC contract that lets `cagefs_enter_site DOMAIN cmd` enter the
# per-website jail (where proxyexec applies the :secure-flag policy and the
# per-domain bind-mount over /var/.cagefs/ exposes .cagefs.website). The Python
# wrapper at clcagefslib.webisolation.libenter.enter_site() invokes this script
# with WEBSITE_TOKEN_PATH set to the per-website token path; without this block
# we silently fall back to the user-level jail and website isolation becomes a
# no-op (broke `cagefs.python_tests.test_isolated_domains_enter` and
# `test_proxyexec_secure` when removed in CLOS-4125 / 0.7.13-2).
#
# Why it's safe despite looking like a "user-controlled path read":
#   - This script runs as the calling user, never setuid; reading $TOKEN gives
#     no privilege the user does not already have.
#   - Token files are mode 0400 owned by the rightful user; another user cannot
#     read them, so the override cannot be used to enter another user's jail.
#   - The token value is sent to proxyexec which validates it server-side
#     against its registry. An invented or wrong token is rejected.
#   - The override is gated by WEBSITE_ISOLATION_FLAG: it activates only on
#     hosts where the website-isolation feature is enabled.
#   - The shell-injection risk that the AI scanner originally flagged was the
#     unquoted `$CAT $USER_TOKEN_PATH` below (now `$("$CAT" "$USER_TOKEN_PATH")`).
#     Quoting fixed that independently; removing the override gave no further
#     security gain but broke the feature.
#
# If you ever need to close this env-var IPC channel, you must replace it with
# an alternative contract (e.g. an explicit CLI flag) AND simultaneously update
# clcagefslib.webisolation.libenter.enter_site to use it.
if [ -f "$WEBSITE_ISOLATION_FLAG" ] && [ -n "$WEBSITE_TOKEN_PATH" ]; then
    USER_TOKEN_PATH="$WEBSITE_TOKEN_PATH"
else
    if [ ! -f "$USER_TOKEN_PATH" ]; then
        # try to create token
        is_cagefs_enabled
        cagefs_enabled=$?
    fi
fi

if [ ! -f "$USER_TOKEN_PATH" ]; then
    # when token does not exist - call original cagefs_enter binary
    /bin/cagefs_enter.proxied "$@"
    exit $?
fi

TOKEN=$("$CAT" "$USER_TOKEN_PATH")
CWD=`$PWD`

# Reject a non-alphanumeric token before it is forwarded. Tokens are generated
# as fixed-length alphanumerics, so anything else indicates tampering. POSIX
# `case` (not [[ =~ ]]) so this also works under dash.
case "$TOKEN" in
    "" | *[!A-Za-z0-9]*)
        echo "cagefs_enter: refusing to forward malformed token from $USER_TOKEN_PATH" >&2
        exit 1
        ;;
esac

if [ -e /var/.cagefs/origin ]; then
    ORIGIN=`$CAT /var/.cagefs/origin`
    # Single-quote every caller-controlled value (CWD and each "$@") with sq()
    # before composing the ssh remote command, which the origin login shell
    # re-parses; sq() output survives one re-parse unchanged. The validated
    # alphanumeric $TOKEN needs no quoting. Rationale: see CLOS-4583 / git log.
    Q_ARGS=
    for _arg in "$@"; do
        Q_ARGS="$Q_ARGS $(sq "$_arg")"
    done
    $SSH -F /etc/ssh/cagefs-rexec_config "$USR@$ORIGIN" \
        "CAGEFS_TOKEN=$TOKEN /usr/sbin/proxyexec -c cagefs.sock $(sq "$USR") $(sq "$CWD") CAGEFS_ENTER $$$Q_ARGS"
else
    CAGEFS_TOKEN="$TOKEN" /usr/sbin/proxyexec -c cagefs.sock "$USR" "$CWD" CAGEFS_ENTER $$ "$@"
fi

exit $?
