aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2012-07-01 01:43:15 +0200
committerTom Gundersen <teg@jklm.no>2012-07-11 04:32:09 +0200
commit3779f7002c8417a77745e1e02273ed5e19ed75b7 (patch)
tree138f79425e2c4b736e60508f4bcf8e7cf53af37c
parent27c29c2b95864e4844ef644400ebf59a08d08abd (diff)
downloadinitscripts-3779f7002c8417a77745e1e02273ed5e19ed75b7.tar.xz
cryptsetup: deprecate old syntax and default to the systemd one
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).
-rw-r--r--functions62
1 files 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
}