SVN: geninitrd/trunk/geninitrd

glen glen at pld-linux.org
Mon Nov 10 02:04:57 CET 2008


Author: glen
Date: Mon Nov 10 02:04:57 2008
New Revision: 9976

Modified:
   geninitrd/trunk/geninitrd
Log:
- add cryptsetup luks support on rootfs

Modified: geninitrd/trunk/geninitrd
==============================================================================
--- geninitrd/trunk/geninitrd	(original)
+++ geninitrd/trunk/geninitrd	Mon Nov 10 02:04:57 2008
@@ -73,6 +73,9 @@
 # VG for suspend resume dev
 SUSPENDVG=""
 
+# DM name for cryptsetup luks
+LUKSNAME=""
+
 # resume device
 resume_dev=""
 
@@ -84,6 +87,8 @@
 have_md=no
 # if we should init dmraid at boot
 have_dmraid=no
+# if we should init cryptsetup luks at boot
+have_luks=no
 # if we should init dm-multipath at boot
 have_multipath=no
 # dm-multipath wwid which is used for rootfs
@@ -102,7 +107,7 @@
 	echo "       [--with-suspend] [--without-suspend]"
 	echo "       [--with-tuxonice] [--without-tuxonice]"
 	echo "       [--without-dmraid] [--without-multipath]"
-	echo "       [--without-blkid]"
+	echo "       [--without-blkid] [--without-luks]"
 	echo "       <initrd-image> <kernel-version>"
 	echo ""
 	echo "example:"
@@ -673,6 +678,32 @@
 	return $rc
 }
 
+# return true if node is cryptsetup luks encrypted
+is_luks() {
+	local node="$1"
+	if [ ! -e "$node" ]; then
+		warn "is_luks(): node $node doesn't exist!"
+		return 1
+	fi
+
+	local dev dm_name=${node#/dev/mapper/}
+	if [ "$node" = "$dm_name" ]; then
+		debug "is_luks: $node is not device mapper name"
+		return 1
+	fi
+
+	dev=$(cryptsetup status $dm_name 2>/dev/null | awk '/device:/{print $2}')
+	cryptsetup isLuks $dev
+	rc=$?
+
+	if [ $rc = 0 ]; then
+		debug "is_luks: $node is cryptsetup luks"
+	else
+		debug "is_luks: $node is not cryptsetup luks"
+	fi
+	return $rc
+}
+
 # return dependencies MAJOR:MINOR [MAJOR:MINOR] for DM_NAME
 # TODO: patch `dmsetup export`
 dm_deps() {
@@ -782,6 +813,26 @@
 }
 
 # find modules for $devpath
+find_modules_luks() {
+	local devpath="$1"
+	local dev
+
+	LUKSNAME=${devpath#/dev/mapper/}
+	LUKSDEV=$(cryptsetup status $LUKSNAME 2>/dev/null | awk '/device:/{print $2}')
+	if [ -z "$LUKSDEV" ]; then
+		die "Lost cryptsetup device meanwhile?"
+	fi
+
+	findmodule "dm-crypt"
+
+	have_luks=yes
+
+	# recurse
+	find_modules_for_devpath $LUKSDEV
+	return 0
+}
+
+# find modules for $devpath
 find_modules_for_devpath() {
 	local devpath="$1"
 	if [ -z "$devpath" ]; then
@@ -796,6 +847,11 @@
 	esac
 	debug "Finding modules for device path $devpath"
 
+	if is_luks "$devpath"; then
+		find_modules_luks "$devpath"
+		return
+	fi
+
 	if is_yes "`echo "$devpath" | awk '/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:|\/dev\/nfs)/ { print "yes"; }'`"; then
 		if [ ! -x /usr/bin/pcidev -a -z "$NFS_ETH_MODULES" ]; then
 			die "root on NFS but /usr/bin/pcidev not found. Please install correct pci-database package and rerun $PROGRAM."
@@ -1199,6 +1255,68 @@
 	EOF
 }
 
+key_is_random() {
+	[ "$1" = "/dev/urandom" -o "$1" = "/dev/hw_random" -o "$1" = "/dev/random" ]
+}
+
+# produce cryptsetup from $name from /etc/crypttab
+luks_crypttab() {
+	local LUKSNAME="$1"
+	local LUKSDEV="$2"
+
+	# copy from /etc/rc.d/init.d/cryptsetup
+	local dst src key opt mode owner
+
+	while read dst src key opt; do
+		[ -z "$dst" -o "${dst#\#}" != "$dst" ] && continue
+		[ "$dst" != "$LUKSNAME" ] && continue
+
+		if [ -n "$key" -a "x$key" != "xnone" ]; then
+			if test -e "$key" ; then
+				mode=$(LC_ALL=C ls -l "$key" | cut -c 5-10)
+				owner=$(LC_ALL=C ls -l $key | awk '{ print $3 }')
+				if [ "$mode" != "------" ] && ! key_is_random "$key"; then
+					die "INSECURE MODE FOR $key"
+				fi
+				if [ "$owner" != root ]; then
+					die "INSECURE OWNER FOR $key"
+				fi
+			else
+				die "Key file for $dst not found"
+			fi
+		else
+			key=""
+		fi
+
+		if /sbin/cryptsetup isLuks "$src" 2>/dev/null; then
+			if key_is_random "$key"; then
+				die "$dst: LUKS requires non-random key, skipping"
+			fi
+			if [ -n "$opt" ]; then
+				warn "$dst: options are invalid for LUKS partitions, ignoring them"
+			fi
+			echo "/sbin/cryptsetup ${key:+-d $key} luksOpen '$src' '$dst' <&1" | add_linuxrc
+		else
+			die "$dst: only LUKS encryption supported"
+		fi
+	done < /etc/crypttab
+}
+
+initrd_gen_luks() {
+	if [ ! -x /sbin/cryptsetup-initrd ]; then
+		die "/sbin/cryptsetup-initrd is missing!"
+	fi
+
+	inst_d /sbin
+	inst_exec /sbin/cryptsetup-initrd /sbin/cryptsetup
+
+	mount_dev
+	mount_sys
+	initrd_gen_devices
+
+	luks_crypttab $LUKSNAME $LUKSDEV
+}
+
 initrd_gen_bootsplash() {
 	local target="$1"
 
@@ -1601,6 +1719,10 @@
 	USE_DMRAID=yes
 fi
 
+if [ -x /sbin/cryptsetup ]; then
+	USE_LUKS=yes
+fi
+
 if [ -x /sbin/multipath ]; then
 	USE_MULTIPATH=yes
 fi
@@ -1704,6 +1826,9 @@
 	--without-blkid)
 		USE_BLKID=no
 		;;
+	--without-luks)
+		USE_LUKS=no
+		;;
 	--with=*)
 		BASICMODULES="$BASICMODULES ${1#--with=}"
 		;;
@@ -2040,6 +2165,10 @@
 	initrd_gen_v86d
 fi
 
+if is_yes "$have_luks"; then
+	initrd_gen_luks
+fi
+
 if is_yes "$have_dmraid"; then
 	initrd_gen_dmraid
 fi


More information about the pld-cvs-commit mailing list