--- /usr/portage/sys-fs/cryptsetup/files/2.4.3-dmcrypt.rc 2022-10-31 17:40:24.000000000 +0000 +++ /etc/init.d/dmcrypt 2023-12-02 09:52:20.856987113 +0000 @@ -35,6 +35,32 @@ : ${dmcrypt_retries:=5} : ${wait:=5} + read_abort() { + # some colors + local ans savetty resettty + [ -z "${NORMAL}" ] && eval $(eval_ecolors) + einfon " $1? (${WARN}yes${NORMAL}/${GOOD}No${NORMAL}) " + shift + # This is ugly as s**t. But POSIX doesn't provide `read -t`, so + # we end up having to implement our own crap with stty/etc... + savetty=$(stty -g) + resettty='stty ${savetty}; trap - EXIT HUP INT TERM' + trap 'eval "${resettty}"' EXIT HUP INT TERM + stty -icanon + stty min 0 time "$(( $2 * 10 ))" + ans=$(dd count=1 bs=1 2>/dev/null) || ans='' + eval "${resettty}" + if [ -z "${ans}" ] ; then + printf '\r' + else + echo + fi + case ${ans} in + [yY]) return 0;; + *) return 1;; + esac + } + # Handle automatic look up of the source path. if [ -z "${source}" -a -n "${loop_file}" ] ; then source=$(losetup --show -f "${loop_file}") @@ -58,7 +84,7 @@ return fi - if [ -n "${header}" ] ; then + if [ -n "${header}" ] && [ -z "${remdev}" ] ; then header_opt="--header=${header}" i=0 @@ -71,6 +97,41 @@ ewarn "Waited ${i} times for header file ${header}. Aborting ${target}." return fi + # handle header on removable device + elif [ -n "${header}" ] && [ -n "${remdev}" ] ; then + # temp directory to mount removable device + local mntrem="${RC_SVCDIR}/dm-crypt-remdev-header.$$" + if [ ! -d "${mntrem}" ] ; then + if ! mkdir -p "${mntrem}" ; then + ewarn "${source} will not be decrypted ..." + einfo "Reason: Unable to create temporary mount point '${mntrem}'" + return + fi + fi + i=0 + einfo "Please insert removable device for ${target}" + while [ ${i} -lt ${dmcrypt_max_timeout} ] ; do + foo="" + if mount -n -o ro "${remdev}" "${mntrem}" 2>/dev/null >/dev/null ; then + # header exists? + if [ ! -e "${mntrem}${header}" ] ; then + umount -n "${mntrem}" + rmdir "${mntrem}" + einfo "Cannot find ${header} on removable media." + read_abort "Abort" ${dmcrypt_key_timeout} && return + else + header="${mntrem}${header}" + break + fi + else + [ -e "${remdev}" ] \ + && foo="mount failed" \ + || foo="mount source not found" + fi + : $((i += 1)) + read_abort "Stop waiting after $i attempts (${foo})" -t 1 && return + done + header_opt="--header ${header}" else header_opt="" fi @@ -118,32 +179,6 @@ # Handle keys if [ -n "${key}" ] ; then - read_abort() { - # some colors - local ans savetty resettty - [ -z "${NORMAL}" ] && eval $(eval_ecolors) - einfon " $1? (${WARN}yes${NORMAL}/${GOOD}No${NORMAL}) " - shift - # This is ugly as s**t. But POSIX doesn't provide `read -t`, so - # we end up having to implement our own crap with stty/etc... - savetty=$(stty -g) - resettty='stty ${savetty}; trap - EXIT HUP INT TERM' - trap 'eval "${resettty}"' EXIT HUP INT TERM - stty -icanon - stty min 0 time "$(( $2 * 10 ))" - ans=$(dd count=1 bs=1 2>/dev/null) || ans='' - eval "${resettty}" - if [ -z "${ans}" ] ; then - printf '\r' - else - echo - fi - case ${ans} in - [yY]) return 0;; - *) return 1;; - esac - } - # Notes: sed not used to avoid case where /usr partition is encrypted. mode=${key##*:} && ( [ "${mode}" = "${key}" ] || [ -z "${mode}" ] ) && mode=reg key=${key%:*} @@ -237,6 +272,12 @@ if [ -d "${mntrem}" ] ; then umount -n ${mntrem} 2>/dev/null >/dev/null rmdir ${mntrem} 2>/dev/null >/dev/null + i=0 + while [ ${i} -lt ${rem_unplug_wait} ]; do + : $((i += 1)) + einfo "removable media unmounted - unplug now ${i}/${rem_unplug_wait} ..." + sleep 1 + done fi splash svc_input_end ${SVCNAME} >/dev/null 2>&1 @@ -266,7 +307,7 @@ start() { local print_header=true cryptfs_status=0 - local gpg_options key loop_file target targetline options pre_mount post_mount source swap remdev + local gpg_options key loop_file target targetline options pre_mount post_mount source swap remdev header local x for x in $(cat /proc/cmdline) ; do @@ -298,7 +339,7 @@ unset gpg_options key loop_file target options pre_mount post_mount source swap remdev wait header header_opt ;; - gpg_options=*|remdev=*|key=*|loop_file=*|options=*|pre_mount=*|post_mount=*|wait=*|source=*|header=*) + gpg_options=*|remdev=*|key=*|loop_file=*|options=*|pre_mount=*|post_mount=*|wait=*|source=*|header=*|rem_unplug_wait=*) if [ -z "${target}${swap}" ] ; then ewarn "Ignoring setting outside target/swap section: ${targetline}" continue