Options to re-enable WOL and start a full shell

Adding ethtool - to allows chaning WOL settings - does not add much more
dependencies compared to the core ones (network, dropbear, cryptsetup).

Refactor script for easier maintenance.

v1.0-1
master 1.0-1
Julien Coloos 2021-11-13 21:02:45 +01:00
parent a2924457d3
commit f20941d376
6 changed files with 557 additions and 334 deletions

View File

@ -1,3 +1,10 @@
2021-11-13 Julien Coloos <julien.coloos [at] gmail [dot] com>
* v1.0-1
Option to use login shell instead of cryptsetup unlocking script
Option to re-enable Wake-on-LAN on network device
2021-11-12 Julien Coloos <julien.coloos [at] gmail [dot] com> 2021-11-12 Julien Coloos <julien.coloos [at] gmail [dot] com>
* v0.9-2 * v0.9-2

View File

@ -1,20 +1,21 @@
# Maintainer: Julien Coloos <julien.coloos [at] gmail [dot] com> # Maintainer: Julien Coloos <julien.coloos [at] gmail [dot] com>
pkgname=initrd-ssh-cryptsetup pkgname=initrd-ssh-cryptsetup
pkgver=0.9 pkgver=1.0
pkgrel=2 pkgrel=1
pkgdesc="Allows for LUKS-encrypted devices to be unlocked remotely over SSH" pkgdesc="Allows to remotely unlock LUKS-encrypted devices over SSH"
arch=('any') arch=('any')
url="https://github.com/suiryc/archlinux-$pkgname" url="https://github.com/suiryc/archlinux-$pkgname"
license=('GPL3') license=('GPL3')
depends=('dropbear' 'cryptsetup' 'mkinitcpio-nfs-utils' 'iproute2') depends=('dropbear' 'cryptsetup' 'mkinitcpio-nfs-utils' 'iproute2' 'ethtool')
install=$pkgname.install install=$pkgname.install
changelog='ChangeLog' changelog='ChangeLog'
source=("http://julien.coloos.free.fr/archlinux/$pkgname-$pkgver.tar.xz" "$pkgname.install") source=("http://julien.coloos.free.fr/archlinux/$pkgname-$pkgver.tar.xz" "$pkgname.install")
sha256sums=('c3fa91fc8ba2228b3492d3709231918c8015cc3da49f516c3eacea5c0217536c' sha256sums=('de6ef287ecfd57614835fec1fcaa01eb3a7f999d42a749e20b6747671320508f'
'b84978b3c2ef32208c2b104ee2d3ce8aaec26da0bd4e9e1c83942f373bbf6285') 'b84978b3c2ef32208c2b104ee2d3ce8aaec26da0bd4e9e1c83942f373bbf6285')
package() { package() {
install -Dm644 "$srcdir/src/install/ssh-cryptsetup" "$pkgdir/usr/lib/initcpio/install/ssh-cryptsetup" install -Dm644 "$srcdir/src/install/ssh-cryptsetup" "$pkgdir/usr/lib/initcpio/install/ssh-cryptsetup"
install -Dm644 "$srcdir/src/hooks/ssh-cryptsetup" "$pkgdir/usr/lib/initcpio/hooks/ssh-cryptsetup" install -Dm644 "$srcdir/src/hooks/ssh-cryptsetup" "$pkgdir/usr/lib/initcpio/hooks/ssh-cryptsetup"
install -Dm644 "$srcdir/src/hooks/ssh-cryptsetup-tools" "$pkgdir/usr/lib/initcpio/hooks/ssh-cryptsetup-tools"
} }

View File

@ -1,4 +1,4 @@
Personal ArchLinux package combining dropbear and cryptsetup in initrd for unlocking LUKS-encrypted devices either locally (boot console) or remotely over SSH. Personal ArchLinux package combining dropbear and cryptsetup in initramfs for unlocking LUKS-encrypted devices either locally (boot console) or remotely over SSH.
The code was reworked from legacy dropbear_initrd_encrypt AUR package. The code was reworked from legacy dropbear_initrd_encrypt AUR package.
@ -37,33 +37,43 @@ As explained upon installation, the following things need to be done:
The LUKS-encrypted devices to unlock are derived from `/etc/crypttab`. The LUKS-encrypted devices to unlock are derived from `/etc/crypttab`.
Some options can be set in `/etc/initcpio/sshcs_env` (file is sourced in initrd shell): Some options can be set in `/etc/initcpio/sshcs_env` (file is sourced in initramfs shell):
* `sshcs_opt_debug`: whether to be more verbose about ongoing actions * `sshcs_opt_debug`: whether to be more verbose about ongoing actions
- default: 0 - default: `0`
- any non-zero value to enable - any non-zero value to enable
* `sshcs_opt_net_wol`: Wake-on-LAN option to set on network device
- default: `g` (MagicPacket™)
- usually WOL is disabled once in initramfs shell
- set empty to not change network device WOL setting
* `sshcs_opt_timeout_ipconfig`: time (in seconds) to configure IP * `sshcs_opt_timeout_ipconfig`: time (in seconds) to configure IP
- default: 10 seconds - default: `10`
* `sshcs_opt_listen`: SSH listening port * `sshcs_opt_listen`: SSH listening port
- default: 22 - default: `22`
* `sshcs_opt_timeout_poweroff`: time (in seconds) to unlock devices before automatic powering off * `sshcs_opt_timeout_poweroff`: time (in seconds) to unlock devices before automatic powering off
- default (and minimum value): 2 minutes - default (and minimum value): `120` (2 minutes)
- negative value to deactivate - negative value to deactivate
* `sshcs_opt_use_shell`: whether to start a full `ash` shell
- default: `0`
- `1` to enable
- when disabled (the default), a script to unlock devices is executed instead
For example: For example:
sshcs_opt_timeout_ipconfig=30 sshcs_opt_timeout_ipconfig=30
sshcs_opt_listen=2222 sshcs_opt_listen=2222
sshcs_opt_timeout_poweroff=-1 sshcs_opt_timeout_poweroff=-1
sshcs_opt_use_shell=1
## Building notes ## Building notes
1. Modify the sources (features in `src`, and/or package building files) 1. Modify the sources (features in `src`, and/or package building files)
2. If `src` was modified 2. If `src` was modified
* archive the `src` folder in `$pkgname-$pkgver.tar.xz` file; e.g.: `tar -cJf initrd-ssh-cryptsetup-0.9.tar.xz src` * bump `pkgver` in `PKGBUILD`
* archive the `src` folder in `$pkgname-$pkgver.tar.xz` file; e.g.: `tar -cJf initrd-ssh-cryptsetup-$(grep "^pkgver=" PKGBUILD | cut -d'=' -f2).tar.xz src`
* upload the archive on the online repository (pointed by `PKGBUILD`) * upload the archive on the online repository (pointed by `PKGBUILD`)
3. Update ChangeLog 3. Update ChangeLog
4. Update `PKGBUILD` 4. Update `PKGBUILD`
* bump `pkgver` if `src` was modified, or `pkgrel` if building files were modified * bump `pkgrel` if only building files were modified
* refresh `sha256sums` with `updpkgsums` if necessary * refresh `sha256sums` with `updpkgsums` if necessary
- or manually, based on `sha256sum initrd-ssh-cryptsetup-*.tar.xz initrd-ssh-cryptsetup.install` output - or manually, based on `sha256sum initrd-ssh-cryptsetup-*.tar.xz initrd-ssh-cryptsetup.install` output
5. Delete generated archive file if any 5. Delete generated archive file if any

View File

@ -1,23 +1,10 @@
#!/usr/bin/ash #!/usr/bin/ash
dbg () { . "/usr/local/bin/ssh-cryptsetup-tools"
[ ${sshcs_opt_debug} != 0 ] && echo "$@"
}
sshcs_env_load() {
local debug_default=0
local timeout_ipconfig_default=10
local timeout_poweroff_min=120
[ -e "${sshcs_env}" ] && . "${sshcs_env}"
[ -z "${sshcs_opt_debug}" ] && sshcs_opt_debug=${debug_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}
[ ${sshcs_opt_timeout_poweroff} -ge 0 ] && [ ${sshcs_opt_timeout_poweroff} -lt ${timeout_poweroff_min} ] && sshcs_opt_timeout_poweroff=${timeout_poweroff_min}
}
sshcs_net_start() { sshcs_net_start() {
local iparg net_address ipconfig_out net_netmask net_gateway net_dns0 net_dns1
# we must have an 'ip' setting, and a device in it # we must have an 'ip' setting, and a device in it
[ -z "${ip}" ] && [ -n "${nfsaddrs}" ] && ip="${nfsaddrs}" [ -z "${ip}" ] && [ -n "${nfsaddrs}" ] && ip="${nfsaddrs}"
[ -z "${ip}" ] && { [ -z "${ip}" ] && {
@ -31,6 +18,11 @@ sshcs_net_start() {
return 1 return 1
} }
if [ "${sshcs_opt_net_wol:-d}" != "d" ]; then
dbg "Setting network device=${net_device} wol=${sshcs_opt_net_wol}"
ethtool -s "${net_device}" wol "${sshcs_opt_net_wol}"
fi
# Setup network and save some values # Setup network and save some values
# Note: some useful redirection means ('< <(...)' and '<<< "$(...)"') are # Note: some useful redirection means ('< <(...)' and '<<< "$(...)"') are
# not supported in the available shell. So we have to write code in a # not supported in the available shell. So we have to write code in a
@ -93,7 +85,6 @@ sshcs_trap_timeout() {
echo "" echo ""
echo "WARNING! Automatic poweroff will be triggered in ${sshcs_opt_timeout_poweroff}s" echo "WARNING! Automatic poweroff will be triggered in ${sshcs_opt_timeout_poweroff}s"
echo "To deactivate, please unlock devices" echo "To deactivate, please unlock devices"
echo ""
trap sshcs_trapped_timeout SIGALRM trap sshcs_trapped_timeout SIGALRM
( (
sleep ${sshcs_opt_timeout_poweroff} sleep ${sshcs_opt_timeout_poweroff}
@ -107,21 +98,25 @@ sshcs_trap_timeout() {
sshcs_untrap_timeout() { sshcs_untrap_timeout() {
[ -z "${pid_timeout}" ] && return 0 [ -z "${pid_timeout}" ] && return 0
kill ${pid_timeout} # Notes:
# If there was a running SSH shell, it may also try to kill it.
# This only kills the spawned subshell, leaving the 'sleep' command still
# running until done (which is not an issue).
proc_parse_stat ${pid_timeout} && kill ${pid_timeout}
pid_timeout=
trap - SIGALRM trap - SIGALRM
msg "Timeout cleared." msg "Timeout cleared."
} }
sshcs_unlock() { sshcs_shell_run() {
sshcs_trap_timeout sshcs_trap_timeout
# actual script (shared with SSH login) unlocking encrypted devices # actual script (shared with SSH login) with which we can unlock devices
. "${sshcs_cryptsetup_script}" sshcs_unlocked_test=0
. "${sshcs_shell_script}"
sshcs_untrap_timeout
} }
sshcs_dropbear_unlock() { sshcs_dropbear_run() {
local pid_timeout= local pid_timeout=
local dev_pts_mounted=0 local dev_pts_mounted=0
local listen= local listen=
@ -133,34 +128,29 @@ sshcs_dropbear_unlock() {
dev_pts_mounted=1 dev_pts_mounted=1
fi fi
# /etc/passwd file for the root user if [ ${sshcs_opt_use_shell} -eq 0 ]; then
echo "root:x:0:0:root:/root:${dropbear_login_shell}" > "/etc/passwd" sshcs_shell_script=${sshcs_cryptsetup_script}
echo "${dropbear_login_shell}" > "/etc/shells" else
cat <<EOF > "${sshcs_shell_script}"
# root login script
cat <<EOF > "${dropbear_login_shell}"
#!/usr/bin/ash #!/usr/bin/ash
. "/init_functions" . "/usr/local/bin/ssh-cryptsetup-tools"
if [ ! -f "${sshcs_cryptsetup_script}" ]; then
err "No cryptsetup script present! Please retry."
exit 0
fi
if [ -c "/dev/mapper/control" ]; then
CSQUIET=
. "${sshcs_cryptsetup_script}"
echo "" echo ""
echo "cryptsetup succeeded! Boot sequence should go on." echo "Call ${sshcs_cryptsetup_script} to try unlocking device(s)"
echo "Please wait and retry for standard SSH service."
else # Now give the user its shell
err "Device resources missing! Please retry." /usr/bin/ash
fi
echo "" # Check whether we are fully done
sshcs_check_done 1
EOF EOF
chmod a+x "${dropbear_login_shell}" chmod a+x "${sshcs_shell_script}"
fi
# /etc/passwd file for the root user
echo "root:x:0:0:root:/root:${sshcs_shell_script}" > "/etc/passwd"
echo "${sshcs_shell_script}" > "/etc/shells"
[ ! -d "/var/log" ] && mkdir -p "/var/log" [ ! -d "/var/log" ] && mkdir -p "/var/log"
touch "/var/log/lastlog" touch "/var/log/lastlog"
@ -168,25 +158,13 @@ EOF
msg "Starting dropbear ..." msg "Starting dropbear ..."
dropbear -Esgjk -P "${path_dropbear_pid}" ${sshcs_opt_listen} dropbear -Esgjk -P "${path_dropbear_pid}" ${sshcs_opt_listen}
# Actual unlocking # Actual unlocking shell
sshcs_unlock sshcs_shell_run
# cleanup dropbear
if [ -f "${path_dropbear_pid}" ]; then
msg "Stopping dropbear ..."
kill $(cat "${path_dropbear_pid}")
rm -f "${path_dropbear_pid}"
fi
rm -f "${sshcs_cryptsetup_script}" "${dropbear_login_shell}" "/etc/passwd" "/etc/shells" "/var/log/lastlog"
# cleanup /dev/pts if necessary
if [ ${dev_pts_mounted} -ne 0 ]; then
umount "/dev/pts"
rm -R "/dev/pts"
fi
} }
sshcs_cryptpart_process() { sshcs_cryptpart_process() {
local cryptdev_orig cryptopt cryptargs
# ensure there is a device (handle 'UUID=' format) # ensure there is a device (handle 'UUID=' format)
[ -z "${cryptdev}" ] && return 0 [ -z "${cryptdev}" ] && return 0
[ "${cryptdev#UUID=}" != "${cryptdev}" ] && cryptdev="/dev/disk/by-uuid/${cryptdev#UUID=}" [ "${cryptdev#UUID=}" != "${cryptdev}" ] && cryptdev="/dev/disk/by-uuid/${cryptdev#UUID=}"
@ -215,23 +193,30 @@ sshcs_cryptpart_process() {
dbg "Adding crypt device=${cryptdev} type=${crypttype} name=${cryptname} args=<${cryptargs}> in setup script" dbg "Adding crypt device=${cryptdev} type=${crypttype} name=${cryptname} args=<${cryptargs}> in setup script"
# update script used to unlock device either in console or SSH # update script used to unlock device either in console or SSH
[ -s "${sshcs_cryptsetup_script}" ] || cat <<EOF > "${sshcs_cryptsetup_script}" [ -s "${sshcs_cryptsetup_script}" ] || cat <<'EOF' > "${sshcs_cryptsetup_script}"
#!/usr/bin/ash
. "/usr/local/bin/ssh-cryptsetup-tools"
cycle_or_retry() { cycle_or_retry() {
local res local res
read -n 1 -s -t 5 -p "Whithin 5s press 'P' to poweroff, 'R' to reboot or any other key to retry. " res read -n 1 -s -t 5 -p "Within 5s press 'P' to poweroff, 'R' to reboot or any other key to retry. " res
echo "" echo ""
if [ "\${res}" = "P" ]; then [ "${res}" == "P" ] && poweroff -f
poweroff -f [ "${res}" == "R" ] && reboot -f
elif [ "\${res}" = "R" ]; then
reboot -f
fi
} }
try_unlock() {
EOF EOF
cat <<EOF >> "${sshcs_cryptsetup_script}" cat <<EOF >> "${sshcs_cryptsetup_script}"
# loop until device is available # loop until device is available
while [ ! -e "/dev/mapper/${cryptname}" ]; do while [ ! -e "/dev/mapper/${cryptname}" ]; do
if [ \${sshcs_unlocked_test:-0} -eq 1 ]; then
sshcs_unlocked=0
return
fi
if cryptsetup open --type "${crypttype}" "${cryptdev}" "${cryptname}" ${cryptargs} "\${CSQUIET}"; then if cryptsetup open --type "${crypttype}" "${cryptdev}" "${cryptname}" ${cryptargs} "\${CSQUIET}"; then
if poll_device "/dev/mapper/${cryptname}" ${rootdelay}; then if poll_device "/dev/mapper/${cryptname}" ${rootdelay}; then
killall cryptsetup > /dev/null 2>&1 killall cryptsetup > /dev/null 2>&1
@ -253,29 +238,8 @@ EOF
fi fi
} }
run_hook() { sshcs_cryptpart_setup() {
local etc_crypttab="/etc/crypttab" local cryptdev crypttype cryptname cryptpass cryptoptions
local sshcs_env="/etc/initcpio/sshcs_env"
local path_dropbear_pid="/.dropbear.pid"
local dropbear_login_shell="/.cryptsetup_shell.sh"
local sshcs_cryptsetup_script="/.cryptsetup_script.sh"
local net_env="/.net_env.sh"
local line iparg net_address net_device ipconfig_out net_netmask net_gateway net_dns0 net_dns1
local cryptdev cryptdev_orig crypttype cryptname cryptpass cryptoptions cryptopt cryptargs CSQUIET
# Load our options
sshcs_env_load
# sanity check: crypttab should be present
[ ! -e "${etc_crypttab}" ] && {
dbg "No crypttab configuration to process"
return 0
}
modprobe -a -q dm-crypt >/dev/null 2>&1
[ "${quiet}" = "y" ] && CSQUIET=">/dev/null"
umask 0022
# check encrypted devices to handle # check encrypted devices to handle
cryptdev= cryptdev=
@ -289,6 +253,59 @@ run_hook() {
sshcs_cryptpart_process sshcs_cryptpart_process
done < "${etc_crypttab}" done < "${etc_crypttab}"
# Nothing else to do if there is no device we can unlock
[ -s "${sshcs_cryptsetup_script}" ] || return 0
cat <<'EOF' >> "${sshcs_cryptsetup_script}"
# No other device to unlock
}
if [ -c "/dev/mapper/control" ]; then
CSQUIET=
try_unlock
[ ${sshcs_unlocked_test:-0} -eq 1 ] && return
sshcs_check_done 0
else
if [ \${sshcs_unlocked_test:-0} -eq 1 ]; then
sshcs_unlocked=0
return
fi
echo ""
err "Device resources missing! Please retry."
fi
EOF
chmod a+x "${sshcs_cryptsetup_script}"
}
run_hook() {
local etc_crypttab="/etc/crypttab"
local path_dropbear_pid="/.dropbear.pid"
local sshcs_shell_script="/.sshcs_shell.sh"
local net_env="/.sshcs_net_env.sh"
local line net_device
local CSQUIET
# Note: options were loaded already
# sanity check: crypttab should be present
[ ! -e "${etc_crypttab}" ] && {
dbg "No crypttab configuration to process"
return 0
}
# Initialize random generator ASAP.
# May delay first SSH login by a few seconds otherwise.
(dd if=/dev/urandom of=/dev/null bs=4 count=1 status=none > /dev/null 2>&1) &
(dd if=/dev/random of=/dev/null bs=4 count=1 status=none > /dev/null 2>&1) &
modprobe -a -q dm-crypt >/dev/null 2>&1
[ "${quiet}" = "y" ] && CSQUIET=">/dev/null"
umask 0022
# Setup script used to unlock device either in console or SSH
sshcs_cryptpart_setup
if [ ! -e "${sshcs_cryptsetup_script}" ]; then if [ ! -e "${sshcs_cryptsetup_script}" ]; then
err "No encrypted device found! Skipping crypt remote unlocking." err "No encrypted device found! Skipping crypt remote unlocking."
return 0 return 0
@ -298,14 +315,10 @@ run_hook() {
if ! sshcs_net_start; then if ! sshcs_net_start; then
err "Net interface not available! Skipping crypt remote unlocking." err "Net interface not available! Skipping crypt remote unlocking."
# We still allow to unlock locally with timeout # We still allow to unlock locally with timeout
sshcs_unlock sshcs_shell_run
# stop the network if possible
sshcs_net_done
return 0 return 0
fi fi
# time to unlock (through console or dropbear) # time to unlock (through console or dropbear)
sshcs_dropbear_unlock sshcs_dropbear_run
# stop the network before going on in boot sequence
sshcs_net_done
} }

View File

@ -0,0 +1,188 @@
#!/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

View File

@ -72,10 +72,14 @@ build() {
add_binary "dmsetup" add_binary "dmsetup"
add_binary "dropbear" add_binary "dropbear"
add_binary "ip" add_binary "ip"
add_binary "/usr/lib/initcpio/ipconfig" "/sbin/ipconfig" add_binary "/usr/lib/initcpio/ipconfig" "/bin/ipconfig"
add_binary "ethtool"
# Our hook files # Our hook files
[ -e "${sshcs_env}" ] && add_file "${sshcs_env}" [ -e "${sshcs_env}" ] && add_file "${sshcs_env}"
# Note: use /usr/local/bin, even though everything actually points to /usr/bin
# in initramfs.
add_file "/usr/lib/initcpio/hooks/ssh-cryptsetup-tools" "/usr/local/bin/ssh-cryptsetup-tools"
# auth-related files # auth-related files
add_file "/lib/libnss_files.so" add_file "/lib/libnss_files.so"