[Pkg-cryptsetup-devel] Bug#358452: Latest version of script files

David Härdeman david at 2gen.com
Tue Apr 11 17:19:54 UTC 2006


This is the latest and greatest version of the script with the previous 
fixes applied and a /dev/console redirection also added for the eventual 
cryptgetpw script.

I'll reattach this later as a proper patch to cryptsetup instead of just 
the two additional files...

Re,
David



-------------- next part --------------
#!/bin/sh

PREREQ=""

prereqs()
{
	echo "$PREREQ"
}

case $1 in
prereqs)
	prereqs
	exit 0
	;;
esac

. /usr/share/initramfs-tools/hook-functions

find_root_device() {
	[ -r /etc/fstab ] || return

	grep '^[^#]' /etc/fstab | ( \
	while read device mount type options dump pass; do
		if [ "$mount" = "/" ]; then
			echo "$device"
			return
		fi
	done )
}

get_root_opts() {
	local node rootopts
	node=$1

	[ -z $node ] && return
	[ -r /etc/crypttab ] || return

	rootopts=$( grep ^$node /etc/crypttab | \
		    head -1 | sed 's/[[:space:]]+*/ /g' | cut -d " " -f 4-)
	echo "$rootopts"
	[ ! -z $rootopts ] || return 1
	return 0
}

get_root_modules() {
	local rootopts
	rootopts=$1

	[ ! -z $rootopts ] || return

	echo "dm_mod"
	echo "dm_crypt"
	local IFS=", "
	for opt in $rootopts; do
		# Does option start with cipher=?
		value=${opt#cipher=}
		[ $value != $opt ] || continue

		# Add the cipher to the list of modules
		cipher=${value%%-*}
		echo $cipher

		# Possibly add a hash as well
		hash=${value##*:}
		[ ! -z $hash -o $hash != $value ] || continue
		echo $hash
	done
}

get_root_initramfsopts() {
	local rootnode rootopts
	rootnode=$1
	rootopts=$2

	[ ! -z $rootnode ] || return
	[ ! -z $rootopts ] || return

	echo -n "node=$rootnode"
	local IFS=", "
	for opt in $rootopts; do
		case $opt in
			cipher=*)
				echo -n ",$opt"
				;;
			hash=*)
				echo -n ",$opt"
				;;
			size=*)
				echo -n ",$opt"
				;;
			*)
				# Presumably a non-supported option
				;;
		esac
	done
	echo ""
}

# Find out which device root is on
rootdev=$(find_root_device)
[ ! -z $rootdev ] || exit 0

# Check that it is a node under /dev/mapper/
node=${rootdev#/dev/mapper/}
[ "$node" != $rootdev ] || exit 0

# Get crypttab root options
rootopts=$(get_root_opts $node $opts)
[ ! -z $rootopts ] || exit 0

# Calculate needed modules
modules=$(get_root_modules $rootopts | sort | uniq)
for x in $modules; do
	force_load ${x}
done

# Check the root options to write to the initramfs
initramfsopts=$(get_root_initramfsopts $node $rootopts)
echo "CRYPTOPTS=\"$initramfsopts\"" > ${DESTDIR}/conf/conf.d/cryptroot

copy_exec /sbin/cryptsetup /sbin
copy_exec /sbin/dmsetup /sbin
[ -x "/etc/mkinitramfs/cryptgetpw" ] && copy_exec /etc/mkinitramfs/cryptgetpw /sbin

exit 0
-------------- next part --------------
#!/bin/sh

PREREQ=""

prereqs()
{
	echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
	prereqs
	exit 0
	;;
esac

# Do we have any settings from the /conf/conf.d/cryptroot file?
[ -r /conf/conf.d/cryptroot ] && . /conf/conf.d/cryptroot
cryptopts="${CRYPTOPTS}"

# Does the kernel boot command line override them?
for x in $(cat /proc/cmdline); do
	case $x in
	cryptopts=*)
		cryptopts=${x#cryptopts=}
		;;
	esac
done

# Sanity checks
eval $(fstype < ${ROOT})
if [ "$FSTYPE" != "luks" -a -z "$cryptopts" ]; then
	# Apparently the root partition isn't encrypted
	echo "No cryptoroot configured or detected"
	exit 0
fi

# There are two possible scenarios here:
#
# 1) The fstype of the root device has been identified as "luks"
# 2) The fstype is not "luks" but cryptopts has been set
#
# The former means that we use the luks functionality of cryptsetup, the
# latter means that we do it the old-fashioned way.

# Start by parsing some options, all options are relevant to regular cryptsetup
# but only cryptnode is relevant to luks which picks up the rest of the 
# parameters by reading the partition header
cryptcipher=aes-cbc-essiv:sha256
cryptsize=256
crypthash=sha256
cryptnode=cryptroot
if [ -n "$cryptopts" ]; then
	IFS=" ,"
	for x in $cryptopts; do
		case $x in
		hash=*)
			crypthash=${x#hash=}
			;;
		size=*)
			cryptsize=${x#size=}
			;;
		cipher=*)
			cryptcipher=${x#cipher=}
			;;
		node=*)
			cryptnode=${x#node=}
			;;
		esac
	done
	unset IFS
fi
NEWROOT="/dev/mapper/$cryptnode"

# Check which cryptosolution we want
if [ "$FSTYPE" = "luks" ]; then
	# 1) The fstype of the root device has been identified as "luks"
	cryptcreate="/sbin/cryptsetup luksOpen $ROOT $cryptnode"
	cryptremove=""
else
	# 2) The fstype is not "luks" but cryptopts have been set
	cryptcreate="/sbin/cryptsetup -c $cryptcipher -s $cryptsize -h $crypthash create $cryptnode $ROOT"
	cryptremove="/sbin/cryptsetup remove $cryptnode"
fi

# Loop until we have a satisfactory password
while [ 1 ]; do
	if [ -x "/sbin/cryptgetpw" ]; then
		/sbin/cryptgetpw < /dev/console | $cryptcreate
	else
		$cryptcreate < /dev/console
	fi

	if [ $? -eq 0 ]; then
		fstype < "$NEWROOT" > /dev/.initramfs/source.me
		if [ $? -eq 0 ]; then
			. /dev/.initramfs/source.me
			if [ "$FSTYPE" != "unknown" ]; then
				break
			fi
		fi
	fi

	echo "$0: cryptsetup failed or fstype not recognized, bad password or options?"
	$cryptremove
	sleep 3
done

# init can now pick up new FSTYPE, FSSIZE and ROOT
echo "ROOT=\"$NEWROOT\"" >> /dev/.initramfs/source.me

exit 0


More information about the Pkg-cryptsetup-devel mailing list