[arch-projects] [initscripts][RFC] cryptsetup: deprecate old syntax and default to the systemd one

teg at jklm.no teg at jklm.no
Tue Jul 10 22:33:07 EDT 2012


From: Tom Gundersen <teg at jklm.no>

We detect if the old syntax is used, and if so print a warning and use
the old parsing code. Otherwise, we pass everything on to
systemd-cryptsetup. Similarly to what was done with the network syntax,
we intend to keep the legacy stuff working for a long time.

See crypttab(5) for the new syntax[0].

The main reason for this change, is to be closer to what other distros
do. The systemd syntax is based on Debian's format, and is essentially
what is being used by at least Debian, Ubuntu, Fedora and Suse. Such
widespread use means that it will be better documented in
non-Arch-specific documentation, and is more likely to see integration
with third-party tools. It is also surely appreciated by admins who
use more than one distro, that they don't have to know more than one
config format for these sorts of basic things.

Furthermore, by actually sharing the code with systemd we get to rely on
their much more widespread testing and review compared to what we are able
to do ourselves. This is particularly important for the encryption code,
as it is the most obscure code in initscripts and any bugs in it would
have potentially very severe consequences.

Lastly, there are a few (albeit minor) issues I see with our current
format: /etc/crypttab is not a plaintext file, but needs to be parsed
through bash. The (deprecated) embedded passwords have been a source
of problems in the past. And, there is no level of abstraction between
the crypttab options and cryptsetup, we just pass them on blindly.

The new format and the old one cover roughly the same usecases. To the
best of my knowledge, the only use-case not (yet) supported by
systemd-cryptsetup, is mounting a removable device and reading
the key from a file on that device. For this, stick with the old syntax
(though be careful, it is inherently racy).

[0]: <http://0pointer.de/public/systemd-man/systemd.unit.html> (note
     that keyfile-offset support is coming in the next systemd version).
---
 functions | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 58 insertions(+), 4 deletions(-)

diff --git a/functions b/functions
index 16f8d8f..7fd5258 100644
--- a/functions
+++ b/functions
@@ -381,12 +381,13 @@ activate_vgs() {
 	(( $? == 0 )) && stat_done || stat_fail
 }
 
-do_unlock() {
+do_unlock_legacy() {
 	# $1 = requested name
 	# $2 = source device
 	# $3 = password
 	# $4 = options
 	stat_append "${1}.."
+	printf "${C_FAIL}Using legacy crypttab format. This will stop working in the future. See crypttab(5).${C_OTHER}\n"
 	local open=create a=$1 b=$2 failed=0
 	# Ordering of options is different if you are using LUKS vs. not.
 	# Use ugly swizzling to deal with it.
@@ -448,7 +449,6 @@ do_unlock() {
 		/*)
 			cryptsetup -d "$3" $4 $open "$a" "$b" >/dev/null;;
 		*)
-			printf "${C_FAIL}crypttab contains a literal encryption key. This will stop working in the future.${C_OTHER}\n"
 			echo "$3" | cryptsetup $4 $open "$a" "$b" >/dev/null;;
 	esac
 	if (( $? )); then
@@ -460,10 +460,64 @@ do_unlock() {
 	return $failed
 }
 
+do_unlock_systemd() {
+	stat_append "${1}.."
+	local failed=0
+	if ! /usr/lib/systemd/systemd-cryptsetup attach "$1" "$2" "$3" $4; then
+		failed=1
+	else
+		IFS=,
+		if in_array swap ${options[@]}; then
+			if ! mkswap /dev/mapper/$name >/dev/null; then
+				failed=1
+			fi
+		elif in_array tmp ${options[@]}; then
+			if ! mke2fs /dev/mapper/$name >/dev/null; then
+				failed=1
+			fi
+		fi
+	fi
+	if (( $failed )); then
+		stat_append "failed "
+	else
+		stat_append "ok "
+	fi
+	return $failed
+}
+
+do_unlock() {
+	local name=$1 device=$2 password=$3 options=$4
+
+	if [[ ${options:0:2} =~ -. ]]; then
+		do_unlock_legacy "$name" "$device" "$password" "$options"
+		return $?
+	fi
+
+	case $password in
+		ASK|SWAP)
+			do_unlock_legacy "$name" "$device" "$password" "$options"
+			;;
+		/dev/*)
+			if [[ ${password##*:} == $password ]]; then
+				do_unlock_systemd "$name" "$device" "$password" "$options"
+			else
+				do_unlock_legacy "$name" "$device" "$password" "$options"
+			fi
+			;;
+		/*|none|-)
+			do_unlock_systemd "$name" "$device" "$password" "$options"
+			;;
+		*)
+			do_unlock_legacy "$name" "$device" "$password" "$options"
+			;;
+	esac
+	return $?
+}
+
 read_crypttab() {
 	# $1 = function to call with the split out line from the crypttab
 	local line nspo failed=0
-	while read line; do
+	while read line <&3; do
 		[[ $line && $line != '#'* ]] || continue
 		eval nspo=("${line%#*}")
 		if $1 "${nspo[0]}" "${nspo[1]}" "${nspo[2]}" "${nspo[*]:3}"; then
@@ -471,7 +525,7 @@ read_crypttab() {
 		else
 			failed=1
 		fi
-	done < /etc/crypttab
+	done 3< /etc/crypttab
 	return $failed
 }
 
-- 
1.7.11.1



More information about the arch-projects mailing list