189 lines
5.8 KiB
Bash
189 lines
5.8 KiB
Bash
#!/usr/bin/ash
|
|
|
|
. "/init_functions"
|
|
|
|
dbg () {
|
|
[ ${sshcs_opt_debug} != 0 ] && echo "$@"
|
|
}
|
|
|
|
sshcs_env_load() {
|
|
local sshcs_env="/etc/initcpio/sshcs_env"
|
|
|
|
local debug_default=0
|
|
local net_wol_default=g
|
|
local timeout_ipconfig_default=10
|
|
local timeout_poweroff_min=120
|
|
local use_shell_default=0
|
|
|
|
[ ${sshcs_env_loaded:-0} -eq 1 ] && return
|
|
[ -e "${sshcs_env}" ] && . "${sshcs_env}"
|
|
sshcs_env_loaded=1
|
|
[ -z "${sshcs_opt_debug}" ] && sshcs_opt_debug=${debug_default}
|
|
[ -z "${sshcs_opt_net_wol}" ] && sshcs_opt_net_wol=${net_wol_default}
|
|
[ -z "${sshcs_opt_timeout_ipconfig}" ] && sshcs_opt_timeout_ipconfig=${timeout_ipconfig_default}
|
|
[ -n "${sshcs_opt_listen}" ] && sshcs_opt_listen="-p ${sshcs_opt_listen}"
|
|
[ -z "${sshcs_opt_timeout_poweroff}" ] && sshcs_opt_timeout_poweroff=${timeout_poweroff_min}
|
|
[ -z "${sshcs_opt_use_shell}" ] && sshcs_opt_use_shell=${use_shell_default}
|
|
[ ${sshcs_opt_timeout_poweroff} -ge 0 ] && [ ${sshcs_opt_timeout_poweroff} -lt ${timeout_poweroff_min} ] && sshcs_opt_timeout_poweroff=${timeout_poweroff_min}
|
|
|
|
sshcs_cryptsetup_script="/.sshcs_cryptsetup_script.sh"
|
|
}
|
|
|
|
proc_parse_stat() {
|
|
local unused
|
|
|
|
pid=$1
|
|
cmd=
|
|
ppid=
|
|
[ ! -e /proc/${pid}/stat ] && return 1
|
|
read unused cmd unused ppid unused < /proc/${pid}/stat
|
|
}
|
|
|
|
proc_find_parent_cmd() {
|
|
pid=$1
|
|
proc_parse_stat ${pid} || return 1
|
|
while [ ${ppid} -gt 1 ]
|
|
do
|
|
proc_parse_stat ${ppid} || return 1
|
|
if [ "${cmd}" == "($2)" ]; then
|
|
ppid=${pid}
|
|
pid=$1
|
|
return 0
|
|
fi
|
|
pid=${ppid}
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
proc_is_console() {
|
|
if [ -z "${is_console:-}" ]; then
|
|
# We are in console if we were not forked from dropbear.
|
|
is_console=1
|
|
proc_find_parent_cmd $$ "dropbear" && is_console=0
|
|
fi
|
|
|
|
[ "${is_console}" -eq 1 ]
|
|
}
|
|
|
|
sshcs_cleanup() {
|
|
local pgrep_output
|
|
|
|
# Reminders:
|
|
# We are called when devices have been unlocked.
|
|
#
|
|
# We are only called as part of the main shell (whether on console - the init
|
|
# script - or through SSH - as the user login shell), and once we return our
|
|
# parent shell will end.
|
|
#
|
|
# The unlocking script does 'killall cryptsetup' after each successful unlock,
|
|
# which is used to wakeup any other running unlocking script.
|
|
# Thus as long as all devices have been unlocked, we don't expect any script
|
|
# to be stuck on 'cryptsetup' calls.
|
|
|
|
if proc_is_console; then
|
|
# We are in the console.
|
|
# It is time to properly end the processes we started and files we created.
|
|
# When using a shell - instead of directly calling the unlocking script -
|
|
# we also need to signal any SSH shell so that it is properly cleaned too.
|
|
|
|
# cleanup dropbear
|
|
if [ -f "${path_dropbear_pid}" ]; then
|
|
msg "Stopping dropbear ..."
|
|
kill $(cat "${path_dropbear_pid}")
|
|
rm -f "${path_dropbear_pid}"
|
|
fi
|
|
|
|
if [ ${sshcs_opt_use_shell} -eq 1 ]; then
|
|
# Find and kill all shells spawned by SSH.
|
|
# This is necessary to properly terminate both these shells and the spawned
|
|
# SSH processes.
|
|
# Reminder: "... | ..." does fork a subshell
|
|
dbg "Searching SSH shells ..."
|
|
pgrep_output=$(pgrep /usr/bin/ash)
|
|
pgrep_output=$(echo "${pgrep_output}" | grep -E -v "^(|1|$$)$")
|
|
echo "${pgrep_output}" | while read pid; do
|
|
proc_parse_stat ${pid} || continue
|
|
proc_find_parent_cmd ${pid} "dropbear" || continue
|
|
dbg "Killing SSH shell pid=${pid}"
|
|
kill -SIGHUP ${pid}
|
|
done
|
|
fi
|
|
|
|
# cleanup /dev/pts if necessary
|
|
if [ ${dev_pts_mounted} -ne 0 ]; then
|
|
umount "/dev/pts"
|
|
rm -R "/dev/pts"
|
|
fi
|
|
|
|
# stop the network before going on in boot sequence
|
|
sshcs_net_done
|
|
|
|
rm -f "${sshcs_cryptsetup_script}" "${sshcs_shell_script}" "/etc/passwd" "/etc/shells" "/var/log/lastlog"
|
|
elif [ ${sshcs_opt_use_shell} -eq 1 ]; then
|
|
# We are in a SSH shell session.
|
|
|
|
# Find and kill console shell.
|
|
# This is necessary so that our script launched from the init process can
|
|
# finally check that devices have been properly unlocked, properly end and
|
|
# let the init process end booting.
|
|
# Note: as a side effect, this will also kill the shell that was forked to
|
|
# trigger a timeout, which is fine (we want to kill it, either from here or
|
|
# from the init shell).
|
|
dbg "Searching console shells ..."
|
|
pgrep_output=$(pgrep /usr/bin/ash)
|
|
pgrep_output=$(echo "${pgrep_output}" | grep -E -v "^(|1|$$)$")
|
|
echo "${pgrep_output}" | while read pid; do
|
|
proc_find_parent_cmd ${pid} "dropbear" && continue
|
|
dbg "Killing console shell pid=${pid}"
|
|
kill -SIGHUP ${pid}
|
|
done
|
|
fi
|
|
# else: when in SSH shell script, we have nothing else to do other than exit.
|
|
}
|
|
|
|
sshcs_check_done() {
|
|
# Whether we are called from the main script: that is whether the shell will
|
|
# end when we return.
|
|
local finalize=$1
|
|
|
|
# This is always the main script when not using shell
|
|
[ ${sshcs_opt_use_shell} -eq 0 ] && finalize=1
|
|
|
|
# Reset timeout when applicable: only possible from init script.
|
|
proc_is_console && type sshcs_untrap_timeout > /dev/null 2>&1 && sshcs_untrap_timeout
|
|
|
|
# Check devices are unlocked.
|
|
sshcs_unlocked_test=1
|
|
sshcs_unlocked=1
|
|
. "${sshcs_cryptsetup_script}"
|
|
if [ ${sshcs_unlocked} -ne 1 ]; then
|
|
echo ""
|
|
# When finalizing in console, power off
|
|
if [ ${finalize} -eq 1 ] && proc_is_console; then
|
|
err "Devices are still locked! Powering off."
|
|
poweroff -f
|
|
fi
|
|
|
|
# When in shell or SSH, let user try again
|
|
err "Devices are still locked! Please retry."
|
|
return
|
|
fi
|
|
|
|
if [ ${finalize} -eq 0 ]; then
|
|
# Kill our parent (the interactive shell); the script that launched it will
|
|
# do finalization.
|
|
proc_parse_stat $$
|
|
kill -SIGHUP ${ppid}
|
|
exit 0
|
|
fi
|
|
|
|
echo ""
|
|
echo "cryptsetup succeeded! Boot sequence should go on."
|
|
proc_is_console || echo "Please wait and reconnect to nominal SSH service."
|
|
|
|
sshcs_cleanup
|
|
}
|
|
|
|
sshcs_env_load
|