aboutsummaryrefslogtreecommitdiff
path: root/scripts/naskpass.initscript
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/naskpass.initscript')
-rwxr-xr-xscripts/naskpass.initscript373
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