418 lines
9.9 KiB
Bash
Executable File
418 lines
9.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
if [ -f ~/.shcrtrc ]; then
|
|
source ~/.shcrtrc
|
|
else
|
|
cat > ~/.shcrtrc << EOF
|
|
## GUI mode
|
|
#
|
|
# Console based:
|
|
# dialog - ncurses, runs fine on WSL
|
|
# none - works everywhere
|
|
#
|
|
# GUI based:
|
|
# yad, gtkdialog, kdialog, Xdialog - GNU/Linux only
|
|
# zenity - Windows port available, doesn't work very well because Microsoft is a little bitch and
|
|
# argument passing between Linux and Windows doesn't work well.
|
|
#export supermode="zenity"
|
|
|
|
## Emojis - auto, yes, no
|
|
#export emojis="auto"
|
|
|
|
## Custom SecureCRT config path
|
|
# Set to override defaults:
|
|
# - GNU/Linux: ~/.vandyke/SecureCRT/Config
|
|
# - Windows: %APPDATA%/VanDyke/Config
|
|
# On WSL it needs to be a Linux path!
|
|
|
|
#export crtconfig="/your/path/to/Config"
|
|
|
|
## Session default action
|
|
# You can define the action that will be run when you select a session
|
|
# file. Default is "ask"
|
|
# - ask
|
|
# - print
|
|
# - exec_ssh
|
|
# - exec_sftp
|
|
|
|
#export default_action="ask"
|
|
|
|
## SFTP runner
|
|
# To run a SFTP program, you need to specify an helper command.
|
|
# It needs to accept an SSH-like command:
|
|
# sftp_client_runner user@host -p port
|
|
#
|
|
# A FileZilla runner is provided and it should work on GNU/Linux and WSL
|
|
|
|
#export sftp_client_runner=run_filezilla
|
|
EOF
|
|
fi
|
|
|
|
function is_wsl {
|
|
grep -q Microsoft /proc/version
|
|
return $?
|
|
}
|
|
|
|
if is_wsl; then
|
|
function zenity {
|
|
zenity.exe "$@" | tr -d '\r'
|
|
}
|
|
fi
|
|
|
|
# Determine script location
|
|
SOURCE="${BASH_SOURCE[0]}"
|
|
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
|
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
|
|
SOURCE="$(readlink "$SOURCE")"
|
|
# if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
|
|
done
|
|
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
|
|
|
|
export supertitle="shcrt"
|
|
|
|
export SHELL_LIBRARY_PATH="$SHELL_LIBRARY_PATH:$DIR/easybashgui/lib"
|
|
export PATH="$PATH:$DIR/easybashgui/src"
|
|
source easybashgui
|
|
|
|
source "$DIR/sftp_runners.sh"
|
|
|
|
function wsl_win_var {
|
|
cmd.exe /C "echo $1" | tr -d '\r'
|
|
}
|
|
|
|
function win_path_to_wsl {
|
|
if [[ "$1" != "" ]]; then
|
|
echo "$1" | sed -e 's|\\|/|g' -e 's|\(.*\):|/mnt/\L\1|'
|
|
else
|
|
cat - | sed -e 's|\\|/|g' -e 's|\(.*\):|/mnt/\L\1|'
|
|
fi
|
|
}
|
|
|
|
function copy_to_clipboard {
|
|
if is_wsl; then
|
|
cat - | clip.exe
|
|
elif [[ "$WAYLAND_DISPLAY" != "" ]] && which wl-copy > /dev/null; then
|
|
cat - | wl-copy
|
|
elif which xclip > /dev/null; then
|
|
cat - | xclip -selection clipboard
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Escape bash variables
|
|
function no_dollars {
|
|
sed 's/\$/\\$/g'
|
|
}
|
|
|
|
function scrt_session_path {
|
|
if [[ "$crtconfig" != "" ]]; then
|
|
echo "$crtconfig/Sessions"
|
|
else
|
|
if is_wsl; then
|
|
appdata="$(wsl_win_var '%APPDATA%' | win_path_to_wsl)"
|
|
echo "$appdata/VanDyke/Config/Sessions"
|
|
else
|
|
echo "$HOME/.vandyke/SecureCRT/Config/Sessions"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
if [[ "$emojis" == "no" ]] || ([[ "$emojis" != "yes" ]] && is_wsl); then
|
|
dir_char="+"
|
|
file_char=" "
|
|
search_entry="> Search"
|
|
up_entry=".. Back"
|
|
exit_search_entry="X Exit search"
|
|
query_question="Enter search query: "
|
|
now_at_entry="Now at: "
|
|
else
|
|
dir_char="📁"
|
|
file_char="🔗"
|
|
search_entry="🔍 Search"
|
|
up_entry="↩️ .. Back"
|
|
exit_search_entry="❌ Exit search"
|
|
query_question="🔍 Enter search query: "
|
|
now_at_entry="📍 Now at: "
|
|
fi
|
|
run_ssh_entry="Run SSH"
|
|
run_sftp_entry="Run SFTP client"
|
|
print_details_entry="Print details and exit"
|
|
|
|
session_path="$(scrt_session_path)"
|
|
current_path="."
|
|
|
|
function scrt_cd {
|
|
newdir="$session_path/$current_path/$1"
|
|
if [ ! -d "$newdir" ]; then
|
|
return 1
|
|
fi
|
|
current_path="$(realpath --no-symlinks --relative-to "$session_path" "$newdir")"
|
|
}
|
|
|
|
function scrt_pwd {
|
|
echo "$session_path/$current_path"
|
|
}
|
|
|
|
function find_dirs_or_symlinks {
|
|
while read -r name; do
|
|
[ -d "$name" ] && echo "$name";
|
|
done < <(find $@)
|
|
}
|
|
|
|
function find_files_or_symlinks {
|
|
while read -r name; do
|
|
[ -f "$name" ] && echo "$name";
|
|
done < <(find $@)
|
|
}
|
|
|
|
function scrt_session_name {
|
|
local file="$1"
|
|
|
|
proto="$(cat "$file" | grep 'S:"Protocol Name"' | cut -d '=' -f 2 | tr -d '\r')"
|
|
echo "$file_char $(echo "$(basename "$file")" | sed 's/.ini$//') ($proto)"
|
|
}
|
|
|
|
function scrt_ls {
|
|
cwd="$(pwd)"
|
|
cd "$(scrt_pwd)"
|
|
|
|
find_dirs_or_symlinks -maxdepth 1 -mindepth 1 | sort | sed "s|./||" | while read dir; do
|
|
echo "$dir_char $dir\\$dir"
|
|
done
|
|
|
|
find_files_or_symlinks -maxdepth 1 -mindepth 1 | grep '.ini$' | grep -v 'Default.ini' | grep -v '__FolderData__.ini' | sort | sed 's|./||' | while read file; do
|
|
echo "$(scrt_session_name "$file")\\$file"
|
|
done
|
|
|
|
cd "$cwd"
|
|
}
|
|
|
|
function scrt_find {
|
|
query="$1"
|
|
(
|
|
find "$session_path/$current_path" -type d -iname '*'"$query"'*'
|
|
find "$session_path/$current_path" -type f -iname '*'"$query"'*.ini$' | grep -v "__FolderData__.ini" | grep -v "Default.ini"
|
|
)| while read result; do
|
|
if basename "$result" | grep -qi "$query"; then
|
|
realpath --relative-to "$session_path/$current_path" "$result"
|
|
fi
|
|
done
|
|
}
|
|
|
|
function scrt_search {
|
|
input 1 "$query_question"
|
|
query="$(cat "${dir_tmp}/${file_tmp}")"
|
|
query="${query#"$query_question"}"
|
|
|
|
if [[ "$query" == "" ]]; then
|
|
return 1
|
|
fi
|
|
|
|
results="$(scrt_find "$query")"
|
|
|
|
if [[ "$results" == "" ]]; then
|
|
alert_message "No results"
|
|
return 1;
|
|
fi
|
|
|
|
IFSBAK="$IFS"
|
|
IFS=$'\n'
|
|
menu "$exit_search_entry" $results
|
|
IFS="$IFSBAK"
|
|
|
|
menu_choice="$(0< "${dir_tmp}/${file_tmp}" )"
|
|
if [[ "$menu_choice" == "$exit_search_entry" ]]; then
|
|
return 1
|
|
else
|
|
choice_path="$(scrt_pwd)/$menu_choice"
|
|
if [ -d "$choice_path" ]; then
|
|
scrt_cd "$menu_choice"
|
|
return 1
|
|
else
|
|
scrt_session_run "$menu_choice"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function scrt_menu {
|
|
listing="$(scrt_ls)"
|
|
menu_listing="$(echo "$listing" | cut -d "\\" -f 1 | no_dollars)"
|
|
|
|
now_at="$(echo "$current_path" | sed -e 's|^[.]|/|' -e 's|//|/|' | no_dollars)"
|
|
|
|
IFSBAK="$IFS"
|
|
IFS=$'\n'
|
|
if [[ "$current_path" != "" ]] && [[ "$current_path" != "." ]]; then
|
|
menu "$now_at_entry $now_at" "$search_entry" "$up_entry" "$menu_listing"
|
|
else
|
|
menu "$now_at_entry $now_at" "$search_entry" "$menu_listing"
|
|
fi
|
|
IFS="$IFSBAK"
|
|
|
|
menu_choice="$(0< "${dir_tmp}/${file_tmp}" )"
|
|
choice="$(echo "$listing" | grep "$menu_choice" | cut -d "\\" -f 2)"
|
|
choice_path="$(scrt_pwd)/$choice"
|
|
|
|
if [[ "$menu_choice" == "" ]] || [[ "$menu_choice" == "$up_entry" ]]; then
|
|
scrt_cd ..
|
|
if [[ "$current_path" == "" ]] || [[ "$current_path" == ".." ]]; then
|
|
return
|
|
fi
|
|
elif [[ "$menu_choice" == "$search_entry" ]]; then
|
|
if scrt_search; then
|
|
return
|
|
fi
|
|
elif [[ "$menu_choice" == "$now_at_entry"* ]]; then
|
|
scrt_menu
|
|
elif [ -d "$choice_path" ]; then
|
|
scrt_cd "$choice"
|
|
elif [ -f "$choice_path" ]; then
|
|
scrt_session_run "$choice_path"
|
|
else
|
|
alert_message "Could not find selected item \"$menu_choice\""
|
|
fi
|
|
|
|
scrt_menu
|
|
}
|
|
|
|
function scrt_has_password {
|
|
cat "$1" | grep -q '"Password"'
|
|
return $?
|
|
}
|
|
|
|
function scrt_get_cleartext_pwd {
|
|
session="$1"
|
|
encrypted="$(cat "$session" | grep '"Password V2"' | cut -d '=' -f 2 | cut -c 1-3 --complement | tr -d '\r')"
|
|
if [[ "$encrypted" == "" ]]; then
|
|
encrypted="$(cat "$session" | grep '"Password"' | cut -d '=' -f 2 | cut -c 1 --complement | tr -d '\r')"
|
|
"$DIR/SecureCRTCipher.py" dec "$encrypted"
|
|
else
|
|
"$DIR/SecureCRTCipher.py" dec -v2 "$encrypted"
|
|
fi
|
|
}
|
|
|
|
function scrt_session_run {
|
|
local session="$1"
|
|
|
|
if [[ "$default_action" == run* ]]; then
|
|
# No stack overflows, bitch
|
|
default_action="ask"
|
|
fi
|
|
|
|
(type "scrt_session_$default_action") 2>&1 >/dev/null && \
|
|
"scrt_session_$default_action" "$session" || \
|
|
scrt_session_ask "$@"
|
|
}
|
|
|
|
function scrt_session_ask {
|
|
local session="$1"
|
|
local file="$(realpath --no-symlinks "$session")"
|
|
|
|
menu \
|
|
"$run_ssh_entry" \
|
|
"$run_sftp_entry" \
|
|
"$print_details_entry" \
|
|
"------" \
|
|
"Session: $(scrt_session_name "$session")"
|
|
|
|
menu_choice="$(0< "${dir_tmp}/${file_tmp}" )"
|
|
|
|
case "$menu_choice" in
|
|
"$run_ssh_entry")
|
|
scrt_session_exec_ssh "$file"
|
|
;;
|
|
"$run_sftp_entry")
|
|
scrt_session_exec_sftp "$file"
|
|
;;
|
|
"$print_details_entry")
|
|
scrt_session_print "$session"
|
|
;;
|
|
"")
|
|
return
|
|
;;
|
|
esac
|
|
|
|
scrt_session_ask "$session"
|
|
}
|
|
|
|
function scrt_session_exec_ssh {
|
|
local session="$1"
|
|
|
|
scrt_session_copy_pass "$session"
|
|
|
|
echo
|
|
|
|
cmd="$("$DIR/crt2foss.py" "$session_path/../" "$session" | grep '^ssh')"
|
|
echo "\$ $cmd"
|
|
exec $cmd
|
|
}
|
|
|
|
function scrt_session_exec_sftp {
|
|
local session="$1"
|
|
|
|
(type "sftp_client_runner") 2>&1 >/dev/null
|
|
|
|
if [[ "$?" != 0 ]]; then
|
|
alert_message "You need to provide an SFTP client helper.\n\nYou can either provide it as a function named\n'sftp_client_runner' in ~/.shcrtrc or place it in \$PATH"
|
|
return 1
|
|
fi
|
|
|
|
scrt_session_copy_pass "$session"
|
|
|
|
echo
|
|
|
|
cmd="$("$DIR/crt2foss.py" "$session_path/../" "$session" | grep '^ssh' | sed 's/^ssh/sftp_client_runner/')"
|
|
$cmd
|
|
exit
|
|
}
|
|
|
|
function scrt_session_copy_pass {
|
|
local session="$1"
|
|
|
|
if scrt_has_password "$session"; then
|
|
echo
|
|
if scrt_get_cleartext_pwd "$session" 2> /dev/null | tr -d '\r\n' | copy_to_clipboard; then
|
|
echo "Password copied to clipboard."
|
|
else
|
|
echo "Unable to copy password to clipboard."
|
|
read -p "Do you want me to print it to the console? [yN] " yn
|
|
case $yn in
|
|
[Yy]*) scrt_get_cleartext_pwd "$session";;
|
|
esac
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function scrt_session_print {
|
|
if [[ "$mode" == "dialog" ]] || [[ "$supermode" == "dialog" ]]; then
|
|
clear
|
|
fi
|
|
|
|
local session="$1"
|
|
|
|
echo
|
|
echo "Session file:"
|
|
realpath --no-symlinks "$session"
|
|
echo
|
|
echo "Commands:"
|
|
"$DIR/crt2foss.py" "$session_path/../" "$session"
|
|
|
|
scrt_session_copy_pass "$session"
|
|
|
|
exit
|
|
}
|
|
|
|
function main {
|
|
if [ ! -d "$session_path" ]; then
|
|
alert_message "SecureCRT session path not found.\nLooked for it at:\n$session_path"
|
|
return 1
|
|
fi
|
|
scrt_menu
|
|
}
|
|
|
|
# Run if not sourced
|
|
BASH_SOURCE=".$0"
|
|
test ".$0" != ".$BASH_SOURCE" || main $@
|