#!/usr/bin/env bash set -euo pipefail real_ssh="/usr/bin/ssh" ssh_config="$HOME/.ssh/config" remote_agent="/run/user/0/gnupg/S.gpg-agent.ssh" # Access model, May 2026 # ---------------------- # # Cheia fizica este montata pe is-jumper. Wrapper-ul local nu mai face bridge # de agent in /tmp; in schimb ruleaza clientul SSH activ pe is-jumper: # # local ssh wrapper # -> is-jumper (192.168.2.100, acces local cu id_ed25519) # -> J1/J2/j1/j2 (autentificare cu agentul fizic de pe is-jumper) # -> ssh final-host # # Custom jump flags (stripped by wrapper, not passed to real ssh): # -J1 use J1 via VPN (default for configured hosts) # -J2 use J2 via VPN # -j1 use j1 via public DNS (urgente, fara ruta VPN) # -j2 use j2 via public DNS (urgente, fara ruta VPN) # # Hosturi arbitrare (fara config SSH): wrapper-ul le ruteza prin jump doar daca # unul dintre flagurile de mai sus este prezent explicit. target_user="" target_host="" target_port="" target_auth="" found_target=0 cmd_args=() ssh_config_args=() jump_alias="j1" custom_jump_set=0 host_configured=1 target_is_jump=0 want_subsystem=0 user_option="" port_option="" has_explicit_config() { local arg for arg in "$@"; do case "$arg" in -F|-F*) return 0 ;; esac done return 1 } quote_cmd() { local out="" q part for part in "$@"; do printf -v q "%q" "$part" out+="$q " done printf "%s" "$out" } resolve_ssh_config() { local target=$1 local line target_user="" target_host="" target_port="" target_auth="" while IFS= read -r line; do case "$line" in user\ *) target_user=${line#user } ;; hostname\ *) target_host=${line#hostname } ;; port\ *) target_port=${line#port } ;; setenv\ *NG_SSH_AUTH=password-interactive*) target_auth="password_interactive" ;; esac done < <("$real_ssh" ${ssh_config_args[@]+"${ssh_config_args[@]}"} -G "$target" 2>/dev/null) [[ -n "$target_user" && -n "$target_host" && -n "$target_port" ]] } run_real_ssh() { exec "$real_ssh" ${ssh_config_args[@]+"${ssh_config_args[@]}"} "$@" } resolve_target_from_config() { local target=$1 local default_user=${USER:-${LOGNAME:-}} local user_override="" local target_route="" case "$target" in *@*) user_override=${target%@*} target=${target#*@} ;; esac case "$target" in is-jumper|192.168.2.100) return 1 ;; J1|J2|j1|j2) target_is_jump=1 ;; esac resolve_ssh_config "$target" || return 1 # Check for SSH_ROUTE in config while IFS= read -r line; do case "$line" in setenv\ SSH_ROUTE=*) target_route=${line#setenv SSH_ROUTE=} ;; esac done < <("$real_ssh" ${ssh_config_args[@]+"${ssh_config_args[@]}"} -G "$target" 2>/dev/null) # If route is "local", no jump needed if [[ "$target_route" == "local" ]]; then return 1 fi if [[ -n "$user_override" ]]; then target_user=$user_override fi if [[ -n "$user_option" ]]; then target_user=$user_option fi if [[ -n "$port_option" ]]; then target_port=$port_option fi # Unconfigured host (ssh -G returns defaults): bypass unless a custom jump # was requested explicitly. if [[ "$target_is_jump" -eq 0 && "$target_host" == "$target" && "$target_port" == "22" && "$target_user" == "$default_user" ]]; then [[ $custom_jump_set -eq 0 ]] && return 1 host_configured=0 fi [[ -n "$target_user" && -n "$target_host" && -n "$target_port" ]] } resolve_jump() { local saved_user saved_host saved_port saved_auth saved_user=$target_user saved_host=$target_host saved_port=$target_port saved_auth=$target_auth resolve_ssh_config "$jump_alias" || { printf "ssh-wrapper: cannot resolve jump alias %s\n" "$jump_alias" >&2 exit 255 } jump_user=$target_user jump_host=$target_host jump_port=$target_port target_user=$saved_user target_host=$saved_host target_port=$saved_port target_auth=$saved_auth } # Pre-process: extract custom jump flags and strip them from args. filtered_args=() for arg in "$@"; do case "$arg" in -J1) jump_alias="j1"; custom_jump_set=1 ;; -J2) jump_alias="j2"; custom_jump_set=1 ;; -j1) jump_alias="j1"; custom_jump_set=1 ;; -j2) jump_alias="j2"; custom_jump_set=1 ;; *) filtered_args+=("$arg") ;; esac done set -- "${filtered_args[@]+"${filtered_args[@]}"}" if [[ -f "$ssh_config" ]] && ! has_explicit_config "$@"; then ssh_config_args=(-F "$ssh_config") fi skip_next=0 capture_user=0 capture_port=0 after_double_dash=0 for arg in "$@"; do if [[ $found_target -eq 1 ]]; then cmd_args+=("$arg") continue fi if [[ $capture_user -eq 1 ]]; then user_option=$arg capture_user=0 continue fi if [[ $capture_port -eq 1 ]]; then port_option=$arg capture_port=0 continue fi if [[ $skip_next -eq 1 ]]; then skip_next=0 continue fi case "$arg" in -G|-Q|-V|-h|--help) run_real_ssh "$@" ;; --) after_double_dash=1 continue ;; esac if [[ $after_double_dash -eq 0 ]]; then case "$arg" in -s) want_subsystem=1 continue ;; -l) capture_user=1 continue ;; -l*) user_option=${arg#-l} continue ;; -p) capture_port=1 continue ;; -p*) port_option=${arg#-p} continue ;; -b|-c|-D|-E|-e|-F|-I|-i|-J|-L|-m|-O|-o|-Q|-R|-S|-W|-w) skip_next=1 continue ;; -b*|-c*|-D*|-E*|-e*|-F*|-I*|-i*|-J*|-L*|-m*|-O*|-o*|-Q*|-R*|-S*|-W*|-w*) continue ;; -*) continue ;; esac fi if ! resolve_target_from_config "$arg"; then run_real_ssh "$@" fi found_target=1 done if [[ $found_target -eq 0 ]]; then run_real_ssh "$@" fi tty_flag="-tt" if [[ ${#cmd_args[@]} -gt 0 || $want_subsystem -eq 1 ]]; then tty_flag="-T" fi if [[ $target_is_jump -eq 1 ]]; then jump_cmd=(ssh "$tty_flag" -A -o BatchMode=yes -o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new -p "$target_port" "$target_user@$target_host") jump_cmd+=(${cmd_args[@]+"${cmd_args[@]}"}) else resolve_jump final_cmd=(ssh "$tty_flag" -o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new -o ProxyJump=none -o ProxyCommand=none) if [[ "$target_auth" == "password_interactive" ]]; then final_cmd+=( -o BatchMode=no -o PreferredAuthentications=keyboard-interactive,password -o PubkeyAuthentication=no ) elif [[ $host_configured -eq 1 ]]; then final_cmd+=( -o BatchMode=yes ) fi if [[ $want_subsystem -eq 1 ]]; then final_cmd+=( -s ) fi final_cmd+=( -p "$target_port" "$target_user@$target_host" ) final_cmd+=(${cmd_args[@]+"${cmd_args[@]}"}) jump_cmd=(ssh "$tty_flag" -A -o BatchMode=yes -o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new -p "$jump_port" "$jump_user@$jump_host" "$(quote_cmd "${final_cmd[@]}")") fi is_jumper_cmd="SSH_AUTH_SOCK=$remote_agent exec $(quote_cmd "${jump_cmd[@]}")" exec "$real_ssh" ${ssh_config_args[@]+"${ssh_config_args[@]}"} "$tty_flag" -o BatchMode=yes -o ConnectTimeout=10 is-jumper "$is_jumper_cmd"