diff --git a/defaults/initrd.d/00-crypt.sh b/defaults/initrd.d/00-crypt.sh new file mode 100755 index 0000000..bf35df4 --- /dev/null +++ b/defaults/initrd.d/00-crypt.sh @@ -0,0 +1,237 @@ +#!/bin/sh + +. /etc/initrd.d/00-common.sh +. /etc/initrd.d/00-devmgr.sh +. /etc/initrd.d/00-splash.sh +. /etc/initrd.d/00-fsdev.sh + +_bootstrap_key() { + # $1 = ROOT/SWAP + local keydevs=$(device_list) + eval local keyloc='"${CRYPT_'${1}'_KEY}"' + + media_find "key" "${keyloc}" "CRYPT_${1}_KEYDEV" "/mnt/key" ${keydevs} +} + +_crypt_exec() { + # TODO(lxnay): this fugly crypt_silent should really go away + if [ "${CRYPT_SILENT}" = "1" ]; then + eval ${1} >/dev/null 2>/dev/null + else + ask_for_password --ply-tries 5 \ + --ply-cmd "${1}" \ + --ply-prompt "Encryption password (${LUKS_DEVICE}): " \ + --tty-tries 5 \ + --tty-cmd "${1}" || return 1 + return 0 + fi +} + +_open_luks() { + case ${1} in + root) + local ltype=ROOT + ;; + swap) + local ltype=SWAP + ;; + esac + + eval local LUKS_DEVICE='"${CRYPT_'${ltype}'}"' + eval local LUKS_NAME="${1}" # no idea, really, this was old code + eval local LUKS_KEY='"${CRYPT_'${ltype}'_KEY}"' + eval local LUKS_KEYDEV='"${CRYPT_'${ltype}'_KEYDEV}"' + eval local LUKS_TRIM='"${CRYPT_'${ltype}'_TRIM}"' + + local dev_error=0 key_error=0 keydev_error=0 + local mntkey="/mnt/key/" cryptsetup_opts="" + + if [ ! -e /sbin/cryptsetup ]; then + bad_msg "The ramdisk does not support LUKS" + return 1 + fi + + while true; do + local gpg_cmd="" + + # if crypt_silent=1 and some error occurs, bail out. + local any_error= + [ "${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" + return 1 + fi + + if [ "${dev_error}" = "1" ]; then + prompt_user "LUKS_DEVICE" "${LUKS_NAME}" + dev_error=0 + continue + fi + + if [ "${key_error}" = "1" ]; then + prompt_user "LUKS_KEY" "${LUKS_NAME} key" + key_error=0 + continue + fi + + if [ "${keydev_error}" = "1" ]; then + prompt_user "LUKS_KEYDEV" "${LUKS_NAME} key device" + keydev_error=0 + continue + fi + + local luks_dev=$(find_real_device "${LUKS_DEVICE}") + [ -n "${luks_dev}" ] && LUKS_DEVICE="${luks_dev}" # otherwise hope... + + setup_md_device "${LUKS_DEVICE}" + cryptsetup isLuks "${LUKS_DEVICE}" || { + 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_NAME}." + cryptsetup_opts="${cryptsetup_opts} --allow-discards" + fi + + if [ -n "${LUKS_KEY}" ]; then + local real_luks_keydev="${LUKS_KEYDEV}" + + if [ ! -e "${mntkey}${LUKS_KEY}" ]; then + real_luks_keydev=$(find_real_device "${LUKS_KEYDEV}") + good_msg "Using key device ${real_luks_keydev}." + + if [ ! -b "${real_luks_keydev}" ]; then + err_msg "Insert device ${LUKS_KEYDEV} for ${LUKS_NAME}" + err_msg "You have 10 seconds..." + 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 + + if [ ! -b "${real_luks_keydev}" ]; then + eval CRYPT_${ltype}_KEY=${LUKS_KEY} + _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 "Removable device ${LUKS_KEYDEV} not found." + continue + fi + + # continue otherwise will mount keydev which is + # mounted by bootstrap + continue + fi + fi + + # At this point a device was recognized, now let's see + # 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." + + # TODO(lxnay): horrible sleep, what are we waiting for? + sleep 2 + 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 + fi + fi + + # At this point a candidate key exists + # (either mounted before or not) + good_msg "${LUKS_KEY} on device ${real_luks_keydev} found" + if [ "$(echo ${LUKS_KEY} | grep -o '.gpg$')" = ".gpg" ] && \ + [ -e /usr/bin/gpg ]; then + + # TODO(lxnay): WTF is this? + [ -e /dev/tty ] && mv /dev/tty /dev/tty.org + mknod /dev/tty c 5 1 + + cryptsetup_opts="${cryptsetup_opts} -d -" + gpg_cmd="/usr/bin/gpg --logger-file /dev/null" + gpg_cmd="${gpg_cmd} --quiet --decrypt ${mntkey}${LUKS_KEY} | " + else + cryptsetup_opts="${cryptsetup_opts} -d ${mntkey}${LUKS_KEY}" + fi + fi + + # At this point, keyfile or not, we're ready! + local cmd="${gpg_cmd}/sbin/cryptsetup" + cmd="${cmd} ${cryptsetup_opts} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}" + _crypt_exec "${cmd}" + local ret="${?}" + + # TODO(lxnay): WTF is this? + [ -e /dev/tty.org ] \ + && rm -f /dev/tty \ + && mv /dev/tty.org /dev/tty + + if [ "${ret}" = "0" ]; then + good_msg "LUKS device ${LUKS_DEVICE} opened" + break + fi + + bad_msg "Failed to open LUKS device ${LUKS_DEVICE}" + dev_error=1 + key_error=1 + keydev_error=1 + done + + umount -l "${mntkey}" 2>/dev/null >/dev/null + rmdir -p "${mntkey}" 2>/dev/null >/dev/null +} + +start_luks() { + # TODO(lxnay): this sleep 6 thing is hurting my eyes sooooo much. + # if key is set but key device isn't, find it + [ -n "${CRYPT_ROOT_KEY}" ] && [ -z "${CRYPT_ROOT_KEYDEV}" ] \ + && sleep 6 && _bootstrap_key "ROOT" + + if [ -n "${CRYPT_ROOT}" ]; then + _open_luks "root" + if [ -n "${REAL_ROOT}" ]; then + # Rescan volumes + start_volumes + else + REAL_ROOT="/dev/mapper/root" + fi + fi + + # TODO(lxnay): this sleep 6 thing is hurting my eyes sooooo much. + # same for swap, but no need to sleep if root was unencrypted + [ -n "${CRYPT_SWAP_KEY}" ] && [ -z "${CRYPT_SWAP_KEYDEV}" ] \ + && { [ -z "${CRYPT_ROOT}" ] && sleep 6; _bootstrap_key "SWAP"; } + + if [ -n "${CRYPT_SWAP}" ]; then + _open_luks "swap" + if [ -z "${REAL_RESUME}" ]; then + # Resume from swap as default + REAL_RESUME="/dev/mapper/swap" + fi + fi +} diff --git a/defaults/initrd.d/00-livecd.sh b/defaults/initrd.d/00-livecd.sh index 13cd00c..2fd23e7 100755 --- a/defaults/initrd.d/00-livecd.sh +++ b/defaults/initrd.d/00-livecd.sh @@ -347,7 +347,6 @@ livecd_mount() { losetup /dev/loop0 "${CDROOT_PATH}/${LOOPEXT}${LOOP}" test_success "Preparing loop filesystem" - # TODO(lxnay): start_luks is still in livecd.scripts start_luks case ${LOOPTYPE} in diff --git a/defaults/initrd.scripts b/defaults/initrd.scripts index 49a67d6..e425b9b 100755 --- a/defaults/initrd.scripts +++ b/defaults/initrd.scripts @@ -10,6 +10,7 @@ . /etc/initrd.d/00-livecd.sh . /etc/initrd.d/00-nfs.sh . /etc/initrd.d/00-keymaps.sh +. /etc/initrd.d/00-crypt.sh real_root_init() { @@ -24,28 +25,6 @@ real_root_init() { fi } -bootstrap_key() { - # $1 = ROOT/SWAP - local KEYDEVS=$(device_list) - eval local keyloc='"${CRYPT_'${1}'_KEY}"' - - media_find "key" "${keyloc}" "CRYPT_${1}_KEYDEV" "/mnt/key" ${KEYDEVS} -} - -crypt_exec() { - if [ "${CRYPT_SILENT}" = '1' ] - then - eval ${1} >/dev/null 2>/dev/null - else - ask_for_password --ply-tries 5 \ - --ply-cmd "${1}" \ - --ply-prompt "Encryption password (${LUKS_DEVICE}): " \ - --tty-tries 5 \ - --tty-cmd "${1}" || return 1 - return 0 - fi -} - start_iscsi() { if [ ! -e /usr/sbin/iscsistart ]; then return 0 # disabled @@ -105,192 +84,6 @@ start_iscsi() { fi } -# Open a LUKS device -# It is either the root or a swap, other devices are supported in the scripts provided with sys-fs/cryptsetup-luks -# $1 - root/swap -open_luks() { - # TODO(lxnay): what has been seen, cannot be unseen. - # TODO(lxnay): there is so much wrong in this function... - - case $1 in - root) - local TYPE=ROOT - ;; - swap) - local TYPE=SWAP - ;; - esac - - eval local LUKS_DEVICE='"${CRYPT_'${TYPE}'}"' LUKS_NAME="$1" LUKS_KEY='"${CRYPT_'${TYPE}'_KEY}"' LUKS_KEYDEV='"${CRYPT_'${TYPE}'_KEYDEV}"' LUKS_TRIM='"${CRYPT_'${TYPE}'_TRIM}"' - local DEV_ERROR=0 KEY_ERROR=0 KEYDEV_ERROR=0 - local mntkey="/mnt/key/" cryptsetup_options='' - - [ ! -e /sbin/cryptsetup ] && bad_msg "The ramdisk does not support LUKS" && exit 1 - while [ 1 ] - do - local gpg_cmd="" - # if crypt_silent=1 and some error occurs, enter shell quietly - if [ \( ${CRYPT_SILENT} -eq 1 \) -a \( \( \( ${DEV_ERROR} -eq 1 \) -o \( ${KEY_ERROR} -eq 1 \) \) -o \( ${KEYDEV_ERROR} -eq 1 \) \) ] - then - run_shell - elif [ ${DEV_ERROR} -eq 1 ] - then - prompt_user "LUKS_DEVICE" "${LUKS_NAME}" - DEV_ERROR=0 - elif [ ${KEY_ERROR} -eq 1 ] - then - prompt_user "LUKS_KEY" "${LUKS_NAME} key" - KEY_ERROR=0 - elif [ ${KEYDEV_ERROR} -eq 1 ] - then - prompt_user "LUKS_KEYDEV" "${LUKS_NAME} key device" - KEYDEV_ERROR=0 - else - local luks_dev=$(find_real_device "${LUKS_DEVICE}") - [ -n "${luks_dev}" ] && LUKS_DEVICE="${luks_dev}" # otherwise hope... - - setup_md_device "${LUKS_DEVICE}" - /sbin/cryptsetup isLuks "${LUKS_DEVICE}" - if [ $? -ne 0 ] - then - bad_msg "The LUKS device ${LUKS_DEVICE} does not contain a LUKS header" ${CRYPT_SILENT} - DEV_ERROR=1 - continue - else - # Handle keys - if [ "x${LUKS_TRIM}" = "xyes" ] - then - good_msg "Enabling TRIM support for ${LUKS_NAME}." ${CRYPT_SILENT} - cryptsetup_options="${cryptsetup_options} --allow-discards" - fi - - if [ -n "${LUKS_KEY}" ] - then - local REAL_LUKS_KEYDEV="${LUKS_KEYDEV}" - if [ ! -e "${mntkey}${LUKS_KEY}" ] - then - REAL_LUKS_KEYDEV=$(find_real_device "${LUKS_KEYDEV}") - if [ -b "${REAL_LUKS_KEYDEV}" ] && [ -n "${REAL_LUKS_KEYDEV}" ] - then good_msg "Using key device ${REAL_LUKS_KEYDEV}." ${CRYPT_SILENT} - else - good_msg "Please insert removable device ${LUKS_KEYDEV} for ${LUKS_NAME}" ${CRYPT_SILENT} - # abort after 10 secs - local count=10 - while [ ${count} -gt 0 ] - do - count=$((count-1)) - sleep 1 - REAL_LUKS_KEYDEV=$(find_real_device "${LUKS_KEYDEV}") - if [ -b "${REAL_LUKS_KEYDEV}" ] && [ -n "${REAL_LUKS_KEYDEV}" ] - then - good_msg "Removable device ${REAL_LUKS_KEYDEV} detected." ${CRYPT_SILENT} - break - fi - done - if [ ! -b "${REAL_LUKS_KEYDEV}" ] - then - eval CRYPT_${TYPE}_KEY=${LUKS_KEY} - bootstrap_key ${TYPE} - eval LUKS_KEYDEV='"${CRYPT_'${TYPE}'_KEYDEV}"' - REAL_LUKS_KEYDEV=$(find_real_device "${LUKS_KEYDEV}") - if [ ! -b "${REAL_LUKS_KEYDEV}" ]; then - KEYDEV_ERROR=1 - bad_msg "Removable device ${LUKS_KEYDEV} not found." ${CRYPT_SILENT} - continue - fi - # continue otherwise will mount keydev which is mounted by bootstrap - continue - fi - fi - # At this point a device was recognized, now let's see if the key is there - [ ! -d "$mntkey" ] && mkdir -p ${mntkey} 2>/dev/null >/dev/null - - mount -n -o ro ${REAL_LUKS_KEYDEV} ${mntkey} >/dev/null 2>/dev/null - if [ "$?" != '0' ] - then - KEYDEV_ERROR=1 - bad_msg "Mounting of device ${REAL_LUKS_KEYDEV} failed." ${CRYPT_SILENT} - continue - else - good_msg "Removable device ${REAL_LUKS_KEYDEV} mounted." ${CRYPT_SILENT} - sleep 2 - # keyfile exists? - if [ ! -e "${mntkey}${LUKS_KEY}" ]; then - umount -n ${mntkey} 2>/dev/null >/dev/null - KEY_ERROR=1 - KEYDEV_ERROR=1 - bad_msg "Key {LUKS_KEY} on device ${REAL_LUKS_KEYDEV} not found." ${CRYPT_SILENT} - continue - fi - fi - fi - # At this point a candidate key exists (either mounted before or not) - good_msg "${LUKS_KEY} on device ${REAL_LUKS_KEYDEV} found" ${CRYPT_SILENT} - if [ "$(echo ${LUKS_KEY} | grep -o '.gpg$')" = ".gpg" ] && [ -e /usr/bin/gpg ] ; then - [ -e /dev/tty ] && mv /dev/tty /dev/tty.org - mknod /dev/tty c 5 1 - cryptsetup_options="${cryptsetup_options} -d -" - gpg_cmd="/usr/bin/gpg --logger-file /dev/null --quiet --decrypt ${mntkey}${LUKS_KEY} |" - else - cryptsetup_options="${cryptsetup_options} -d ${mntkey}${LUKS_KEY}" - fi - fi - # At this point, keyfile or not, we're ready! - crypt_exec "${gpg_cmd}/sbin/cryptsetup ${cryptsetup_options} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}" - crypt_exec_ret=$? - - [ -e /dev/tty.org ] \ - && rm -f /dev/tty \ - && mv /dev/tty.org /dev/tty - - if [ ${crypt_exec_ret} -eq 0 ] - then - good_msg "LUKS device ${LUKS_DEVICE} opened" ${CRYPT_SILENT} - break - else - bad_msg "Failed to open LUKS device ${LUKS_DEVICE}" ${CRYPT_SILENT} - DEV_ERROR=1 - KEY_ERROR=1 - KEYDEV_ERROR=1 - fi - fi - fi - done - umount ${mntkey} 2>/dev/null >/dev/null - rmdir -p ${mntkey} 2>/dev/null >/dev/null -} - -start_luks() { - # if key is set but key device isn't, find it - [ -n "${CRYPT_ROOT_KEY}" ] && [ -z "${CRYPT_ROOT_KEYDEV}" ] \ - && sleep 6 && bootstrap_key "ROOT" - - if [ -n "${CRYPT_ROOT}" ]; then - open_luks "root" - if [ -n "${REAL_ROOT}" ] - then - # Rescan volumes - start_volumes - else - REAL_ROOT="/dev/mapper/root" - fi - fi - - # TODO(lxnay): this sleep 6 thing is hurting my eyes sooooo much. - # same for swap, but no need to sleep if root was unencrypted - [ -n "${CRYPT_SWAP_KEY}" ] && [ -z "${CRYPT_SWAP_KEYDEV}" ] \ - && { [ -z "${CRYPT_ROOT}" ] && sleep 6; bootstrap_key "SWAP"; } - - if [ -n "${CRYPT_SWAP}" ]; then - open_luks "swap" - if [ -z "${REAL_RESUME}" ] - then - # Resume from swap as default - REAL_RESUME="/dev/mapper/swap" - fi - fi -} - resume_init() { if [ -z "${REAL_RESUME}" ]; then return 0