diff options
author | toni <matzeton@googlemail.com> | 2014-04-12 02:27:35 +0200 |
---|---|---|
committer | toni <matzeton@googlemail.com> | 2014-04-12 02:27:35 +0200 |
commit | 47b459fe55a098076bd167f8b13d79e3a0705d1d (patch) | |
tree | 3c62b6ae46bd0f784a27f079d11d43811ae41066 /scripts/naskpass.initscript |
initial commit
Diffstat (limited to 'scripts/naskpass.initscript')
-rwxr-xr-x | scripts/naskpass.initscript | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/scripts/naskpass.initscript b/scripts/naskpass.initscript new file mode 100755 index 0000000..51f0683 --- /dev/null +++ b/scripts/naskpass.initscript @@ -0,0 +1,373 @@ +#!/bin/sh + +PREREQ="cryptroot-prepare" + +# +# Standard initramfs preamble +# +prereqs() +{ + # Make sure that cryptroot is run last in local-top + for req in $(dirname $0)/*; do + script=${req##*/} + if [ $script != cryptroot ]; then + echo $script + fi + done +} + +case $1 in +prereqs) + prereqs + exit 0 + ;; +esac + +# source for log_*_msg() functions, see LP: #272301 +. /scripts/functions + +# +# Helper functions +# +message() +{ + if [ -x /bin/plymouth ] && plymouth --ping; then + plymouth message --text="$@" + else + echo "$@" >&2 + fi + return 0 +} + +udev_settle() +{ + # Wait for udev to be ready, see https://launchpad.net/bugs/85640 + if [ -x /sbin/udevadm ]; then + /sbin/udevadm settle --timeout=30 + elif [ -x /sbin/udevsettle ]; then + /sbin/udevsettle --timeout=30 + fi + return 0 +} + +parse_options() +{ + local cryptopts + cryptopts="$1" + + if [ -z "$cryptopts" ]; then + return 1 + fi + + # Defaults + cryptcipher=aes-cbc-essiv:sha256 + cryptsize=256 + crypthash=ripemd160 + crypttarget=cryptroot + cryptsource="" + cryptlvm="" + cryptkeyscript="" + cryptkey="" # This is only used as an argument to an eventual keyscript + crypttries=1 + cryptrootdev="" + cryptdiscard="" + CRYPTTAB_OPTIONS="" + + local IFS=" ," + for x in $cryptopts; do + case $x in + hash=*) + crypthash=${x#hash=} + ;; + size=*) + cryptsize=${x#size=} + ;; + cipher=*) + cryptcipher=${x#cipher=} + ;; + target=*) + crypttarget=${x#target=} + export CRYPTTAB_NAME="$crypttarget" + ;; + source=*) + cryptsource=${x#source=} + if [ ${cryptsource#UUID=} != $cryptsource ]; then + cryptsource="/dev/disk/by-uuid/${cryptsource#UUID=}" + elif [ ${cryptsource#LABEL=} != $cryptsource ]; then + cryptsource="/dev/disk/by-label/${cryptsource#LABEL=}" + fi + export CRYPTTAB_SOURCE="$cryptsource" + ;; + lvm=*) + cryptlvm=${x#lvm=} + ;; + key=*) + if [ "${x#key=}" != "none" ]; then + cryptkey=${x#key=} + fi + export CRYPTTAB_KEY="$cryptkey" + ;; + rootdev) + cryptrootdev="yes" + ;; + discard) + cryptdiscard="yes" + ;; + esac + PARAM="${x%=*}" + if [ "$PARAM" = "$x" ]; then + VALUE="yes" + else + VALUE="${x#*=}" + fi + CRYPTTAB_OPTIONS="$CRYPTTAB_OPTIONS $PARAM" + eval export CRYPTTAB_OPTION_$PARAM="\"$VALUE\"" + done + export CRYPTTAB_OPTIONS + + if [ -z "$cryptsource" ]; then + message "cryptsetup: source parameter missing" + return 1 + fi + return 0 +} + +activate_vg() +{ + # Sanity checks + if [ ! -x /sbin/lvm ]; then + message "cryptsetup: lvm is not available" + return 1 + fi + + # Detect and activate available volume groups + /sbin/lvm vgscan + /sbin/lvm vgchange -a y --sysinit + return $? +} + +activate_evms() +{ + local dev module + + # Sanity checks + if [ ! -x /sbin/evms_activate ]; then + message "cryptsetup: evms_activate is not available" + return 1 + fi + + # Load modules used by evms + for module in dm-mod linear raid0 raid1 raid10 raid5 raid6; do + modprobe -q $module + done + + # Activate it + /sbin/evms_activate + return $? +} + +setup_mapping() +{ + local opts count cryptcreate cryptremove NEWROOT + opts="$1" + + if [ -z "$opts" ]; then + return 0 + fi + + parse_options "$opts" || return 1 + + if [ -n "$cryptkeyscript" ] && ! type "$cryptkeyscript" >/dev/null; then + message "cryptsetup: error - script \"$cryptkeyscript\" missing" + return 1 + fi + + # The same target can be specified multiple times + # e.g. root and resume lvs-on-lvm-on-crypto + if [ -e "/dev/mapper/$crypttarget" ]; then + return 0 + fi + + modprobe -q dm_crypt + + # Make sure the cryptsource device is available + if [ ! -e $cryptsource ]; then + activate_vg + activate_evms + fi + + # If the encrypted source device hasn't shown up yet, give it a + # little while to deal with removable devices + + # the following lines below have been taken from + # /usr/share/initramfs-tools/scripts/local, as suggested per + # https://launchpad.net/bugs/164044 + if [ ! -e "$cryptsource" ]; then + log_begin_msg "Waiting for encrypted source device..." + + # Default delay is 180s + if [ -z "${ROOTDELAY}" ]; then + slumber=180 + else + slumber=${ROOTDELAY} + fi + + slumber=$(( ${slumber} * 10 )) + while [ ! -e "$cryptsource" ]; do + /bin/sleep 0.1 + slumber=$(( ${slumber} - 1 )) + [ ${slumber} -gt 0 ] || break + done + + if [ ${slumber} -gt 0 ]; then + log_end_msg 0 + else + log_end_msg 1 || true + fi + fi + udev_settle + + # We've given up, but we'll let the user fix matters if they can + while [ ! -e "${cryptsource}" ]; do + echo " Check cryptopts=source= bootarg: cat /proc/cmdline" + echo " or missing modules, devices: cat /proc/modules; ls /dev" + panic -r "ALERT! ${cryptsource} does not exist. Dropping to a shell!" + done + + # Prepare commands + cryptcreate="/sbin/cryptsetup -T 1" + if [ "$cryptdiscard" = "yes" ]; then + cryptcreate="$cryptcreate --allow-discards" + fi + if /sbin/cryptsetup isLuks $cryptsource >/dev/null 2>&1; then + cryptcreate="$cryptcreate luksOpen $cryptsource $crypttarget" + else + cryptcreate="$cryptcreate -c $cryptcipher -s $cryptsize -h $crypthash create $crypttarget $cryptsource" + fi + cryptremove="/sbin/cryptsetup remove $crypttarget" + NEWROOT="/dev/mapper/$crypttarget" + + # Try to get a satisfactory password $crypttries times + count=0 + while [ $crypttries -le 0 ] || [ $count -lt $crypttries ]; do + count=$(( $count + 1 )) + + if [ $count -gt 1 ]; then + /bin/sleep 3 + fi + + if [ -z "$cryptkeyscript" ]; then + cryptkey="Unlocking the disk $cryptsource ($crypttarget)\nEnter passphrase: " + if [ -x /bin/plymouth ] && plymouth --ping; then + cryptkeyscript="plymouth ask-for-password --prompt" + cryptkey=$(printf "$cryptkey") + else + cryptkeyscript="/lib/cryptsetup/naskpass" + fi + fi + + + if [ ! -e "$NEWROOT" ]; then + if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \ + $cryptkeyscript "$cryptcreate" ; then + continue; + fi + fi + + if [ ! -e "$NEWROOT" ]; then + message "cryptsetup: unknown error setting up device mapping" + return 1 + fi + + #FSTYPE='' + #eval $(fstype < "$NEWROOT") + FSTYPE="$(blkid -s TYPE -o value "$NEWROOT")" + + # See if we need to setup lvm on the crypto device + #if [ "$FSTYPE" = "lvm" ] || [ "$FSTYPE" = "lvm2" ]; then + if [ "$FSTYPE" = "LVM_member" ] || [ "$FSTYPE" = "LVM2_member" ]; then + if [ -z "$cryptlvm" ]; then + message "cryptsetup: lvm fs found but no lvm configured" + return 1 + elif ! activate_vg; then + # disable error message, LP: #151532 + #message "cryptsetup: failed to setup lvm device" + return 1 + fi + + NEWROOT=${cmdline_root:-/dev/mapper/$cryptlvm} + if [ "$cryptrootdev" = "yes" ]; then + # required for lilo to find the root device + echo "ROOT=$NEWROOT" >>/conf/param.conf + fi + eval $(fstype < "$NEWROOT") + fi + + #if [ -z "$FSTYPE" ] || [ "$FSTYPE" = "unknown" ]; then + if [ -z "$FSTYPE" ]; then + message "cryptsetup: unknown fstype, bad password or options?" + udev_settle + $cryptremove + continue + fi + + message "cryptsetup: $crypttarget set up successfully" + break + done + + if [ $crypttries -gt 0 ] && [ $count -gt $crypttries ]; then + message "cryptsetup: maximum number of tries exceeded for $crypttarget" + return 1 + fi + + udev_settle + return 0 +} + +# +# Begin real processing +# + +# Do we have any kernel boot arguments? +cmdline_cryptopts='' +unset cmdline_root +for opt in $(cat /proc/cmdline); do + case $opt in + cryptopts=*) + opt="${opt#cryptopts=}" + if [ -n "$opt" ]; then + if [ -n "$cmdline_cryptopts" ]; then + cmdline_cryptopts="$cmdline_cryptopts $opt" + else + cmdline_cryptopts="$opt" + fi + fi + ;; + root=*) + opt="${opt#root=}" + case $opt in + /*) # Absolute path given. Not lilo major/minor number. + cmdline_root=$opt + ;; + *) # lilo major/minor number (See #398957). Ignore + esac + ;; + esac +done + +if [ -n "$cmdline_cryptopts" ]; then + # Call setup_mapping separately for each possible cryptopts= setting + for cryptopt in $cmdline_cryptopts; do + setup_mapping "$cryptopt" + done + exit 0 +fi + +# Do we have any settings from the /conf/conf.d/cryptroot file? +if [ -r /conf/conf.d/cryptroot ]; then + while read mapping <&3; do + setup_mapping "$mapping" 3<&- + done 3< /conf/conf.d/cryptroot +fi + +exit 0 |