@ -14,15 +14,17 @@ _bootstrap_key() {
}
}
_crypt_exec( ) {
_crypt_exec( ) {
local luks_dev = " ${ 1 } "
local cmd = " ${ 2 } "
# TODO(lxnay): this fugly crypt_silent should really go away
# TODO(lxnay): this fugly crypt_silent should really go away
if [ " ${ CRYPT_SILENT } " = "1" ] ; then
if [ " ${ CRYPT_SILENT } " = "1" ] ; then
eval ${ 1 } >/dev/null 2>/dev/null
eval ${ cmd } >/dev/null 2>/dev/null
else
else
ask_for_password --ply-tries 5 \
ask_for_password --ply-tries 5 \
--ply-cmd " ${ 1 } " \
--ply-cmd " ${ cmd } " \
--ply-prompt " Encryption password ( ${ LUKS_DEVICE } ): " \
--ply-prompt " Encryption password ( ${ luks_dev } ): " \
--tty-tries 5 \
--tty-tries 5 \
--tty-cmd " ${ 1 } " || return 1
--tty-cmd " ${ cmd } " || return 1
return 0
return 0
fi
fi
}
}
@ -30,19 +32,22 @@ _crypt_exec() {
_open_luks( ) {
_open_luks( ) {
case ${ 1 } in
case ${ 1 } in
root)
root)
local ltypes = ROOTS
local ltype = ROOT
local ltype = ROOT
; ;
; ;
swap)
swap)
local ltypes = SWAPS
local ltype = SWAP
local ltype = SWAP
; ;
; ;
esac
esac
eval local LUKS_DEVICE = '"${CRYPT_' ${ ltype } '}"'
eval local luks_devices = '"${CRYPT_' ${ ltypes } '}"'
eval local LUKS_KEY = '"${CRYPT_' ${ ltype } '_KEY}"'
eval local luks_key = '"${CRYPT_' ${ ltype } '_KEY}"'
eval local LUKS_KEYDEV = '"${CRYPT_' ${ ltype } '_KEYDEV}"'
eval local luks_keydev = '"${CRYPT_' ${ ltype } '_KEYDEV}"'
eval local LUKS_TRIM = '"${CRYPT_' ${ ltype } '_TRIM}"'
eval local luks_trim = '"${CRYPT_' ${ ltype } '_TRIM}"'
local luks_name = " ${ 1 } "
local LUKS_NAME = " ${ 1 } "
local dev_error = 0 key_error = 0 keydev_error = 0
local dev_error = 0 key_error = 0 keydev_error = 0
local mntkey = "/mnt/key/" cryptsetup_opts = ""
local mntkey = "/mnt/key/" cryptsetup_opts = ""
@ -51,187 +56,204 @@ _open_luks() {
return 1
return 1
fi
fi
local exit_st =
local real_dev =
if [ " ${ ltype } " = "ROOT" ] ; then
while true; do
real_dev = " ${ REAL_ROOT } "
local gpg_cmd = ""
elif [ " ${ ltype } " = "SWAP" ] ; then
exit_st = 1
real_dev = " ${ REAL_RESUME } "
fi
# do not force the link to /dev/mapper/root
# but rather use the value from root=, which is
# in ${REAL_ROOT}
local luks_dev_name = $( basename " ${ LUKS_DEVICE } " )
local real_dev =
local luks_name_prefix =
if [ " ${ ltype } " = "ROOT" ] ; then
real_dev = " ${ REAL_ROOT } "
elif [ " ${ ltype } " = "SWAP" ] ; then
real_dev = " ${ REAL_RESUME } "
fi
if echo " ${ real_dev } " | grep -q "^/dev/mapper/" ; then
# If we use LVM + cryptsetup, we may have collisions between
# the two inside /dev/mapper. So, make up a way to avoid them.
LUKS_NAME = " ${ LUKS_NAME } _ ${ luks_dev_name } - $( basename ${ real_dev } ) "
fi
# if crypt_silent=1 and some error occurs, bail out.
local exit_st = luks_device =
local any_error =
for luks_device in ${ luks_devices } ; do
[ " ${ dev_error } " = "1" ] && any_error = 1
[ " ${ key_error } " = "1" ] && any_error = 1
[ " ${ keydev_error } " = "1" ] && any_error = 1
if [ " ${ CRYPT_SILENT } " = "1" ] && [ -n " ${ any_error } " ] ; then
bad_msg "Failed to setup the LUKS device"
exit_st = 1
break
fi
if [ " ${ dev_error } " = "1" ] ; then
good_msg " Working on device ${ luks_device } ... "
prompt_user "LUKS_DEVICE" " ${ LUKS_NAME } "
dev_error = 0
continue
fi
if [ " ${ key_error } " = "1" ] ; then
while true; do
prompt_user "LUKS_KEY" " ${ LUKS_NAME } key "
key_error = 0
continue
fi
if [ " ${ keydev_error } " = "1" ] ; then
local gpg_cmd = ""
prompt_user "LUKS_KEYDEV" " ${ LUKS_NAME } key device "
exit_st = 1
keydev_error = 0
continue
fi
local luks_dev = $( find_real_device " ${ LUKS_DEVICE } " )
# do not force the link to /dev/mapper/root
[ -n " ${ luks_dev } " ] && LUKS_DEVICE = " ${ luks_dev } " # otherwise hope...
# but rather use the value from root=, which is
# in ${REAL_ROOT}
local luks_dev_name = $( basename " ${ luks_device } " )
local luks_name_prefix =
setup_md_device " ${ LUKS_DEVICE } "
if echo " ${ real_dev } " | grep -q "^/dev/mapper/" ; then
cryptsetup isLuks " ${ LUKS_DEVICE } " || {
local real_dev_bn = $( basename " ${ real_dev } " )
bad_msg " ${ LUKS_DEVICE } does not contain a LUKS header "
# If we use LVM + cryptsetup, we may have collisions between
dev_error = 1
# the two inside /dev/mapper. So, make up a way to avoid them.
continue ;
luks_dev_name = " ${ luks_name } _ ${ luks_dev_name } - ${ real_dev_bn } "
}
fi
# Handle keys
# if crypt_silent=1 and some error occurs, bail out.
if [ " ${ LUKS_TRIM } " = "yes" ] ; then
local any_error =
good_msg " Enabling TRIM support for ${ LUKS_NAME } . "
[ " ${ dev_error } " = "1" ] && any_error = 1
cryptsetup_opts = " ${ cryptsetup_opts } --allow-discards "
[ " ${ key_error } " = "1" ] && any_error = 1
fi
[ " ${ keydev_error } " = "1" ] && any_error = 1
if [ " ${ CRYPT_SILENT } " = "1" ] && [ -n " ${ any_error } " ] ; then
bad_msg "Failed to setup the LUKS device"
exit_st = 1
break
fi
if [ " ${ dev_error } " = "1" ] ; then
prompt_user "luks_device" " ${ luks_dev_name } "
dev_error = 0
continue
fi
if [ -n " ${ LUKS_KEY } " ] ; then
if [ " ${ key_error } " = "1" ] ; then
local real_luks_keydev = " ${ LUKS_KEYDEV } "
prompt_user "luks_key" " ${ luks_dev_name } key "
key_error = 0
continue
fi
if [ ! -e " ${ mntkey } ${ LUKS_KEY } " ] ; then
if [ " ${ keydev_error } " = "1" ] ; then
real_luks_keydev = $( find_real_device " ${ LUKS_KEYDEV } " )
prompt_user "luks_keydev" " ${ luks_dev_name } key device "
good_msg " Using key device ${ real_luks_keydev } . "
keydev_error = 0
continue
fi
if [ ! -b " ${ real_luks_keydev } " ] ; then
local luks_dev = $( find_real_device " ${ luks_device } " )
bad_msg " Insert device ${ LUKS_KEYDEV } for ${ LUKS_NAME } "
[ -n " ${ luks_dev } " ] && \
bad_msg "You have 10 seconds..."
luks_device = " ${ luks_dev } " # otherwise hope...
local count = 10
while [ ${ count } -gt 0 ] ; do
setup_md_device " ${ luks_device } "
count = $(( count-1))
cryptsetup isLuks " ${ luks_device } " || {
sleep 1
bad_msg " ${ luks_device } does not contain a LUKS header "
dev_error = 1
continue ;
}
# Handle keys
if [ " ${ luks_trim } " = "yes" ] ; then
good_msg " Enabling TRIM support for ${ luks_dev_name } . "
cryptsetup_opts = " ${ cryptsetup_opts } --allow-discards "
fi
real_luks_keydev = $( find_real_device " ${ LUKS_KEYDEV } " )
if [ -n " ${ luks_key } " ] ; then
[ ! -b " ${ real_luks_keydev } " ] || {
local real_luks_keydev = " ${ luks_keydev } "
good_msg " Device ${ real_luks_keydev } detected. "
break;
if [ ! -e " ${ mntkey } ${ luks_key } " ] ; then
}
real_luks_keydev = $( find_real_device " ${ luks_keydev } " )
done
good_msg " Using key device ${ real_luks_keydev } . "
if [ ! -b " ${ real_luks_keydev } " ] ; then
if [ ! -b " ${ real_luks_keydev } " ] ; then
eval CRYPT_${ ltype } _KEY = ${ LUKS_KEY }
bad_msg " Insert device ${ luks_keydev } for ${ luks_dev_name } "
_bootstrap_key ${ ltype }
bad_msg "You have 10 seconds..."
eval LUKS_KEYDEV = '"${CRYPT_' ${ ltype } '_KEYDEV}"'
local count = 10
while [ ${ count } -gt 0 ] ; do
count = $(( count-1))
sleep 1
real_luks_keydev = $( find_real_device " ${ luks_keydev } " )
[ ! -b " ${ real_luks_keydev } " ] || {
good_msg " Device ${ real_luks_keydev } detected. "
break;
}
done
real_luks_keydev = $( find_real_device " ${ LUKS_KEYDEV } " )
if [ ! -b " ${ real_luks_keydev } " ] ; then
if [ ! -b " ${ real_luks_keydev } " ] ; then
keydev_error = 1
eval CRYPT_${ ltype } _KEY = ${ luks_key }
bad_msg " Removable device ${ LUKS_KEYDEV } not found. "
_bootstrap_key ${ ltype }
eval luks_keydev = '"${CRYPT_' ${ ltype } '_KEYDEV}"'
real_luks_keydev = $( find_real_device " ${ luks_keydev } " )
if [ ! -b " ${ real_luks_keydev } " ] ; then
keydev_error = 1
bad_msg " Device ${ luks_keydev } not found. "
continue
fi
# continue otherwise will mount keydev which is
# mounted by bootstrap
continue
continue
fi
fi
fi
# continue otherwise will mount keydev which is
# At this point a device was recognized, now let's see
# mounted by bootstrap
# if the key is there
mkdir -p " ${ mntkey } " # ignore
mount -n -o ro " ${ real_luks_keydev } " \
" ${ mntkey } " || {
keydev_error = 1
bad_msg " Mounting of device ${ real_luks_keydev } failed. "
continue ;
}
good_msg " Removable device ${ real_luks_keydev } mounted. "
if [ ! -e " ${ mntkey } ${ luks_key } " ] ; then
umount -n " ${ mntkey } "
key_error = 1
keydev_error = 1
bad_msg " {luks_key} on ${ real_luks_keydev } not found. "
continue
continue
fi
fi
fi
fi
# At this point a device was recognized, now let's see
# At this point a candidate key exists
# if the key is there
# (either mounted before or not)
mkdir -p " ${ mntkey } " # ignore
good_msg " ${ luks_key } on device ${ real_luks_keydev } found "
if [ " $( echo ${ luks_key } | grep -o '.gpg$' ) " = ".gpg" ] && \
mount -n -o ro " ${ real_luks_keydev } " \
[ -e /usr/bin/gpg ] ; then
" ${ mntkey } " || {
keydev_error = 1
# TODO(lxnay): WTF is this?
bad_msg " Mounting of device ${ real_luks_keydev } failed. "
[ -e /dev/tty ] && mv /dev/tty /dev/tty.org
continue ;
mknod /dev/tty c 5 1
}
cryptsetup_opts = " ${ cryptsetup_opts } -d - "
good_msg " Removable device ${ real_luks_keydev } mounted. "
gpg_cmd = "/usr/bin/gpg --logger-file /dev/null"
gpg_cmd = " ${ gpg_cmd } --quiet --decrypt ${ mntkey } ${ luks_key } | "
if [ ! -e " ${ mntkey } ${ LUKS_KEY } " ] ; then
else
umount -n " ${ mntkey } "
cryptsetup_opts = " ${ cryptsetup_opts } -d ${ mntkey } ${ luks_key } "
key_error = 1
keydev_error = 1
bad_msg " {LUKS_KEY} on ${ real_luks_keydev } not found. "
continue
fi
fi
fi
fi
# At this point a candidate key exists
# At this point, keyfile or not, we're ready!
# (either mounted before or not)
local cmd = " ${ gpg_cmd } /sbin/cryptsetup "
good_msg " ${ LUKS_KEY } on device ${ real_luks_keydev } found "
cmd = " ${ cmd } ${ cryptsetup_opts } open ${ luks_device } ${ luks_dev_name } "
if [ " $( echo ${ LUKS_KEY } | grep -o '.gpg$' ) " = ".gpg" ] && \
_crypt_exec " ${ luks_device } " " ${ cmd } "
[ -e /usr/bin/gpg ] ; then
local ret = " ${ ? } "
# TODO(lxnay): WTF is this?
# TODO(lxnay): WTF is this?
[ -e /dev/tty ] && mv /dev/tty /dev/tty.org
[ -e /dev/tty.org ] \
mknod /dev/tty c 5 1
&& rm -f /dev/tty \
&& mv /dev/tty.org /dev/tty
cryptsetup_opts = " ${ cryptsetup_opts } -d - "
gpg_cmd = "/usr/bin/gpg --logger-file /dev/null"
if [ " ${ ret } " = "0" ] ; then
gpg_cmd = " ${ gpg_cmd } --quiet --decrypt ${ mntkey } ${ LUKS_KEY } | "
exit_st = 0
else
good_msg " LUKS device ${ luks_device } opened "
cryptsetup_opts = " ${ cryptsetup_opts } -d ${ mntkey } ${ LUKS_KEY } "
fi
# This is fine if the crypt device is a physical device
fi
# like /dev/sdaX, however, if we have cryptsetup inside
# LVM, we must tweak REAL_ROOT if there is no device node.
# At this point, keyfile or not, we're ready!
start_volumes # this should create /dev/mapper links
local cmd = " ${ gpg_cmd } /sbin/cryptsetup "
if echo " ${ real_dev } " | grep -q "^/dev/mapper/" ; then
cmd = " ${ cmd } ${ cryptsetup_opts } luksOpen ${ LUKS_DEVICE } ${ LUKS_NAME } "
if [ ! -e " ${ real_dev } " ] ; then
_crypt_exec " ${ cmd } "
# WARN: while for ltype=SWAP this may not be a problem,
local ret = " ${ ? } "
# for ltype=ROOT this may render the system unbootable
# because lvm can get angry to see a symlink where it's
# TODO(lxnay): WTF is this?
# not supposed to be or we may fail to create the proper
[ -e /dev/tty.org ] \
# link (due to the if above), however, reordering the
&& rm -f /dev/tty \
# cmdline entries may solve this.
&& mv /dev/tty.org /dev/tty
good_msg " Creating symlink ${ luks_dev_name } -> ${ real_dev } "
ln -s " ${ luks_dev_name } " " ${ real_dev } " || exit_st = 1
if [ " ${ ret } " = "0" ] ; then
fi
exit_st = 0
good_msg " LUKS device ${ LUKS_DEVICE } opened "
# This is fine if the crypt device is a physical device
# like /dev/sdaX, however, if we have cryptsetup inside
# LVM, we must tweak REAL_ROOT if there is no device node.
start_volumes # this should create /dev/mapper links
if echo " ${ real_dev } " | grep -q "^/dev/mapper/" ; then
if [ ! -e " ${ real_dev } " ] ; then
good_msg " Creating symlink for ${ LUKS_NAME } to ${ real_dev } "
ln -s " ${ LUKS_NAME } " " ${ real_dev } " || exit_st = 1
fi
fi
break
fi
fi
break
bad_msg " Failed to open LUKS device ${ luks_device } "
fi
dev_error = 1
key_error = 1
keydev_error = 1
done
bad_msg " Failed to open LUKS device ${ LUKS_DEVICE } "
dev_error = 1
key_error = 1
keydev_error = 1
done
done
umount -l " ${ mntkey } " 2>/dev/null >/dev/null
umount -l " ${ mntkey } " 2>/dev/null >/dev/null
@ -246,7 +268,7 @@ start_luks() {
[ -n " ${ CRYPT_ROOT_KEY } " ] && [ -z " ${ CRYPT_ROOT_KEYDEV } " ] \
[ -n " ${ CRYPT_ROOT_KEY } " ] && [ -z " ${ CRYPT_ROOT_KEYDEV } " ] \
&& sleep 6 && _bootstrap_key "ROOT"
&& sleep 6 && _bootstrap_key "ROOT"
if [ -n " ${ CRYPT_ROOT } " ] ; then
if [ -n " ${ CRYPT_ROOT S } " ] ; then
if _open_luks "root" ; then
if _open_luks "root" ; then
# force REAL_ROOT= to some value if not set
# force REAL_ROOT= to some value if not set
# this is mainly for backward compatibility,
# this is mainly for backward compatibility,
@ -259,9 +281,9 @@ start_luks() {
# TODO(lxnay): this sleep 6 thing is hurting my eyes sooooo much.
# TODO(lxnay): this sleep 6 thing is hurting my eyes sooooo much.
# same for swap, but no need to sleep if root was unencrypted
# same for swap, but no need to sleep if root was unencrypted
[ -n " ${ CRYPT_SWAP_KEY } " ] && [ -z " ${ CRYPT_SWAP_KEYDEV } " ] \
[ -n " ${ CRYPT_SWAP_KEY } " ] && [ -z " ${ CRYPT_SWAP_KEYDEV } " ] \
&& { [ -z " ${ CRYPT_ROOT } " ] && sleep 6; _bootstrap_key "SWAP" ; }
&& { [ -z " ${ CRYPT_ROOT S } " ] && sleep 6; _bootstrap_key "SWAP" ; }
if [ -n " ${ CRYPT_SWAP } " ] ; then
if [ -n " ${ CRYPT_SWAP S } " ] ; then
if _open_luks "swap" ; then
if _open_luks "swap" ; then
# force REAL_RESUME= to some value if not set
# force REAL_RESUME= to some value if not set
[ -z " ${ REAL_RESUME } " ] && REAL_RESUME = "/dev/mapper/swap"
[ -z " ${ REAL_RESUME } " ] && REAL_RESUME = "/dev/mapper/swap"