- Add shquote() to escape single quotes in paths passed to remote_exec, preventing shell injection via REMOTE_BASE containing single quotes - Apply shquote to remote_exec calls in remotes.sh, backup.sh, transfer.sh, ssh.sh - Add DISK_USAGE_THRESHOLD validation in config.sh - Export SMTP_PASSWORD (was missing from export list) - Fix WEB_PORT default mismatch: use 2323 consistently in from_conf and settings save - Narrow exception catch in remotes.py disk info fetch to KeyError/LookupError - Quote REMOTE_KEY in build_rsync_ssh_cmd for paths with spaces Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
81 lines
2.2 KiB
Bash
81 lines
2.2 KiB
Bash
#!/usr/bin/env bash
|
|
# gniza4linux/lib/ssh.sh — SSH connectivity, remote exec, ssh_opts builder
|
|
|
|
[[ -n "${_GNIZA_SSH_LOADED:-}" ]] && return 0
|
|
_GNIZA_SSH_LOADED=1
|
|
|
|
_is_password_mode() {
|
|
[[ "${REMOTE_AUTH_METHOD:-key}" == "password" ]]
|
|
}
|
|
|
|
build_ssh_opts() {
|
|
local opts=()
|
|
opts+=(-n)
|
|
if _is_password_mode; then
|
|
opts+=(-o "StrictHostKeyChecking=yes")
|
|
else
|
|
opts+=(-i "$REMOTE_KEY")
|
|
opts+=(-o "StrictHostKeyChecking=yes")
|
|
opts+=(-o "BatchMode=yes")
|
|
fi
|
|
opts+=(-p "$REMOTE_PORT")
|
|
opts+=(-o "ConnectTimeout=$SSH_TIMEOUT")
|
|
opts+=(-o "ServerAliveInterval=60")
|
|
opts+=(-o "ServerAliveCountMax=3")
|
|
echo "${opts[*]}"
|
|
}
|
|
|
|
build_ssh_cmd() {
|
|
if _is_password_mode; then
|
|
echo "sshpass -e ssh $(build_ssh_opts)"
|
|
else
|
|
echo "ssh $(build_ssh_opts)"
|
|
fi
|
|
}
|
|
|
|
remote_exec() {
|
|
local cmd="$1"
|
|
local ssh_opts; ssh_opts=$(build_ssh_opts)
|
|
if _is_password_mode; then
|
|
log_debug "CMD: sshpass -e ssh $ssh_opts ${REMOTE_USER}@${REMOTE_HOST} '<cmd>'"
|
|
export SSHPASS="$REMOTE_PASSWORD"
|
|
# shellcheck disable=SC2086
|
|
sshpass -e ssh $ssh_opts "${REMOTE_USER}@${REMOTE_HOST}" "$cmd"
|
|
else
|
|
log_debug "CMD: ssh $ssh_opts ${REMOTE_USER}@${REMOTE_HOST} '$cmd'"
|
|
# shellcheck disable=SC2086
|
|
ssh $ssh_opts "${REMOTE_USER}@${REMOTE_HOST}" "$cmd"
|
|
fi
|
|
}
|
|
|
|
remote_exec_quiet() {
|
|
remote_exec "$1" 2>/dev/null
|
|
}
|
|
|
|
test_ssh_connection() {
|
|
log_info "Testing SSH connection to ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PORT}..."
|
|
if remote_exec "echo ok" &>/dev/null; then
|
|
log_info "SSH connection successful"
|
|
return 0
|
|
else
|
|
log_error "SSH connection failed to ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PORT}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
ensure_remote_dir() {
|
|
local dir; dir="$(shquote "$1")"
|
|
remote_exec "mkdir -p '$dir'" || {
|
|
log_error "Failed to create remote directory: $dir"
|
|
return 1
|
|
}
|
|
}
|
|
|
|
build_rsync_ssh_cmd() {
|
|
if _is_password_mode; then
|
|
echo "ssh -p $REMOTE_PORT -o StrictHostKeyChecking=yes -o ConnectTimeout=$SSH_TIMEOUT"
|
|
else
|
|
echo "ssh -i \"$REMOTE_KEY\" -p $REMOTE_PORT -o StrictHostKeyChecking=yes -o BatchMode=yes -o ConnectTimeout=$SSH_TIMEOUT"
|
|
fi
|
|
}
|