|
#! /bin/bash |
|
|
|
# |
|
# ubuntu 14.04 cryptsetup luks suspend/resume root partition sleep cryptsetup |
|
# |
|
|
|
# target location: /etc/pm/sleep.d/80-cryptsetup.sh |
|
# hook must be run at order 80, at least before 90-video |
|
# http://manpages.ubuntu.com/manpages/trusty/man8/pm-action.8.html |
|
|
|
SLEEP=3 # convinience delay for debugging |
|
|
|
# list of crypto mapper device names |
|
luks_list() { |
|
local list=$(dmsetup ls --target crypt | awk '{print $1}') |
|
if [ "$list" == "No" ] ; then # match "No devices found" |
|
echo "" |
|
else |
|
echo $list |
|
fi |
|
} |
|
|
|
# flat line list of crypto mapper device names |
|
luks_line() { |
|
luks_list | tr '\\n' ',' |
|
} |
|
|
|
# read password from current console |
|
read_pass() { # note: need bash |
|
|
|
local char="" |
|
local star="" |
|
local pass="" |
|
local size=0 |
|
|
|
while IFS='' read -p "$star" -r -s -n 1 char ; do |
|
if [[ $char == $'\0' ]] ; then |
|
break |
|
fi |
|
if [[ $char == $'\177' ]] ; then |
|
if [ $size -gt 0 ] ; then |
|
size=$((size-1)) |
|
star=$'\b \b' |
|
pass="${pass%?}" |
|
else |
|
star="" |
|
fi |
|
else |
|
size=$((size+1)) |
|
star='*' |
|
pass+="$char" |
|
fi |
|
done |
|
|
|
echo "$pass" |
|
} |
|
|
|
# suspend all present crypto devices |
|
do_suspend() { |
|
local list=$(luks_list) |
|
if [ "$list" == "" ]; then |
|
echo "Suspend: no crypto devices" |
|
else |
|
echo "Suspend: [$(luks_line)]" |
|
sync # note: ensure pm-utils are not using sync |
|
for name in $list; do |
|
echo "Suspend: $name" |
|
cryptsetup luksSuspend $name |
|
done |
|
echo "Suspend complete." |
|
fi |
|
local word="" |
|
read -t $SLEEP -p ">" word |
|
if [ "$word" == "bash" ] ; then |
|
bash -i # manual error handling |
|
fi |
|
} |
|
|
|
# resume all present crypto devices |
|
do_resume() { |
|
local list=$(luks_list) |
|
if [ "$list" == "" ]; then |
|
echo "Resume: no crypto devices" |
|
else |
|
echo "Resume: [$(luks_line)]" |
|
echo -n ">" |
|
local pass=$(read_pass) # assume shared pass for all devices |
|
echo "" |
|
for name in $list; do |
|
echo "Resume: $name" |
|
printf "$pass" | cryptsetup luksResume $name || { |
|
echo "Resume failure: cryptsetup luksResume $name" |
|
bash -i # manual error handling |
|
} |
|
done |
|
echo "Resume complete." |
|
fi |
|
sleep $SLEEP |
|
} |
|
|
|
# recurse script again in a terminal |
|
do_terminal() { |
|
self="$0" |
|
mode="$1" |
|
openvt -s -w -- "$self" "$mode" |
|
exit 0 |
|
} |
|
|
|
# pm-utils entry point |
|
case $1 in |
|
suspend) |
|
echo "Crypto device list: [$(luks_line)]" |
|
do_terminal terminal-suspend |
|
;; |
|
resume) |
|
echo "Crypto device list: [$(luks_line)]" |
|
do_terminal terminal-resume |
|
;; |
|
terminal-suspend) |
|
# now running on terminal |
|
do_suspend |
|
;; |
|
terminal-resume) |
|
# now running on terminal |
|
do_resume |
|
;; |
|
*) |
|
echo "Crypto error: $1" |
|
exit $NA |
|
;; |
|
esac |