104 lines
3.2 KiB
Bash
104 lines
3.2 KiB
Bash
|
#!/bin/bash
|
||
|
|
||
|
function get_ssh_param () {
|
||
|
local session_name ssh_param
|
||
|
session_name="${1:?}"
|
||
|
ssh_param="${2:?}"
|
||
|
|
||
|
# SSHtunnelUser -> ssh_user
|
||
|
# SSHtunnelHost -> ssh_target_server
|
||
|
# SSHtunnelHostPort -> ssh_target_port
|
||
|
# SSHtunnelPort -> ssh_local_port
|
||
|
# Host -> tunneled_target_host
|
||
|
# Port -> tunneled_target_port
|
||
|
|
||
|
local value
|
||
|
value="$(grep -Pio -- '(?<=^Servers\\'"${session_name}"'\\'"${ssh_param}"'<\|\|\|>[[:digit:]]<\|\|\|>)[^\r\n\f]+' "${settings_file}")"
|
||
|
if [[ ! "${value}" ]]; then
|
||
|
case "${ssh_param}" in
|
||
|
SSHtunnelUser)
|
||
|
value="${USER}"
|
||
|
;;
|
||
|
SSHtunnelHostPort)
|
||
|
value='22'
|
||
|
;;
|
||
|
Host)
|
||
|
value='127.0.0.1'
|
||
|
;;
|
||
|
*)
|
||
|
return 1
|
||
|
;;
|
||
|
esac
|
||
|
fi
|
||
|
printf -- '%s' "${value}"
|
||
|
}
|
||
|
|
||
|
function local_port_is_free () {
|
||
|
local local_port local_listeners
|
||
|
local_port="${1:?}"
|
||
|
local_listeners="$(ss --no-header -tln 'sport :'"${local_port}")"
|
||
|
if [[ "${local_listeners}" ]]; then
|
||
|
return 1
|
||
|
fi
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
function prep_tunnel () {
|
||
|
local session_name
|
||
|
session_name="${1:?}"
|
||
|
|
||
|
local ssh_user ssh_target_server ssh_target_port ssh_local_port tunneled_target_host tunneled_target_port
|
||
|
|
||
|
ssh_user="$(get_ssh_param "${session_name}" 'SSHtunnelUser')"
|
||
|
ssh_target_server="$(get_ssh_param "${session_name}" 'SSHtunnelHost')"
|
||
|
ssh_target_port="$(get_ssh_param "${session_name}" 'SSHtunnelHostPort')"
|
||
|
ssh_local_port="$(get_ssh_param "${session_name}" 'SSHtunnelPort')"
|
||
|
tunneled_target_host="$(get_ssh_param "${session_name}" 'Host')"
|
||
|
tunneled_target_port="$(get_ssh_param "${session_name}" 'Port')"
|
||
|
|
||
|
if [[ ! "${ssh_user}" ]] || \
|
||
|
[[ ! "${ssh_target_server}" ]] || \
|
||
|
[[ ! "${ssh_target_port}" ]] || \
|
||
|
[[ ! "${ssh_local_port}" ]] || \
|
||
|
[[ ! "${tunneled_target_host}" ]] || \
|
||
|
[[ ! "${tunneled_target_port}" ]]; then
|
||
|
printf 'Session name\n\n %s\n\nUnable to set all necessary SSH vars, exiting 256 ...\n' "'${session_name}'"
|
||
|
exit 256
|
||
|
fi
|
||
|
|
||
|
printf '%s\n' 'Starting SSH tunnel ...'
|
||
|
|
||
|
if local_port_is_free "${ssh_local_port}"; then
|
||
|
set -xv
|
||
|
ssh "${ssh_user}"'@'"${ssh_target_server}" \
|
||
|
-o 'ExitOnForwardFailure=yes' \
|
||
|
-o 'ConnectTimeout=2' \
|
||
|
-f \
|
||
|
-p "${ssh_target_port}" \
|
||
|
-N \
|
||
|
-L "${ssh_local_port}"':'"${tunneled_target_host}"':'"${tunneled_target_port}" && {
|
||
|
set +xv
|
||
|
printf -- 'Done!'
|
||
|
local_port_is_free "${ssh_local_port}"
|
||
|
}
|
||
|
set +xv
|
||
|
else
|
||
|
printf -- '%s\n' \
|
||
|
'Failed! Something is listening on local TCP port '"${ssh_local_port}"'.' \
|
||
|
'Try ss --no-header -tlpn '"'"'sport :'"${ssh_local_port}"''"'"' to ID processes.' \
|
||
|
'Exiting 256 ...'
|
||
|
exit 256
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
function main () {
|
||
|
settings_file=~/'.heidisql/portable_settings.txt'
|
||
|
if [[ ! -r "${settings_file}" ]]; then
|
||
|
COMPREPLY="$(printf -- '%s' '<File '"${settings_file}"' not readable, nothing to auto-complete>')"
|
||
|
return 1
|
||
|
fi
|
||
|
prep_tunnel "${@}"
|
||
|
}
|
||
|
|
||
|
main "${@}"
|