From: "Amadeusz Żołnowski" <aidecoe-2qtfh70TtYba5EbDDlwbIw@public.gmane.org>
To: initramfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [PATCH] 90crypt: keys on external devices support
Date: Tue, 13 Jul 2010 19:14:47 +0200 [thread overview]
Message-ID: <20100713191447.0d09d065@etiriah> (raw)
[-- Attachment #1: Type: text/plain, Size: 9266 bytes --]
99base/dracut-lib.sh: new fun.: getoptcomma, foreach_uuid_until
---
modules.d/90crypt/cryptroot-ask.sh | 121 ++++++++++++++++++++++++++++--------
modules.d/90crypt/parse-crypt.sh | 45 +++++++++----
modules.d/99base/dracut-lib.sh | 57 +++++++++++++++++
3 files changed, 182 insertions(+), 41 deletions(-)
diff --git a/modules.d/90crypt/cryptroot-ask.sh b/modules.d/90crypt/cryptroot-ask.sh
index a6a9af1..58bf667 100755
--- a/modules.d/90crypt/cryptroot-ask.sh
+++ b/modules.d/90crypt/cryptroot-ask.sh
@@ -26,40 +26,107 @@ fi
if [ -f /etc/crypttab ] && ! getargs rd_NO_CRYPTTAB; then
while read name dev rest; do
- # ignore blank lines and comments
- if [ -z "$name" -o "${name#\#}" != "$name" ]; then
- continue
- fi
-
- # UUID used in crypttab
- if [ "${dev%%=*}" = "UUID" ]; then
- if [ "luks-${dev##UUID=}" = "$2" ]; then
- luksname="$name"
- break
- fi
-
- # path used in crypttab
- else
- cdev=$(readlink -f $dev)
- mdev=$(readlink -f $device)
- if [ "$cdev" = "$mdev" ]; then
- luksname="$name"
- break
- fi
- fi
+ # ignore blank lines and comments
+ if [ -z "$name" -o "${name#\#}" != "$name" ]; then
+ continue
+ fi
+
+ # UUID used in crypttab
+ if [ "${dev%%=*}" = "UUID" ]; then
+ if [ "luks-${dev##UUID=}" = "$2" ]; then
+ luksname="$name"
+ break
+ fi
+
+ # path used in crypttab
+ else
+ cdev=$(readlink -f $dev)
+ mdev=$(readlink -f $device)
+ if [ "$cdev" = "$mdev" ]; then
+ luksname="$name"
+ break
+ fi
+ fi
done < /etc/crypttab
unset name dev rest
fi
+#
+# Search key on external devices
+#
+
+# Try to mount device specified by UUID and probe for existence of any of
+# the paths. On success return 0 and print "<uuid> <first-existing-path>",
+# otherwise return 1.
+# Function leaves mount point created.
+probe_keydev() {
+ local uuid="$1"; shift; local keypaths="$*"
+ local ret=1; local mount_point=/mnt/keydev
+ local path
+
+ [ -n "${uuid}" -a -n "${keypaths}" ] || return 1
+ [ -d ${mount_point} ] || mkdir -p "${mount_point}" || return 1
+
+ if mount -r -U "${uuid}" "${mount_point}" 2>/dev/null >/dev/null; then
+ for path in ${keypaths}; do
+ if [ -f "${mount_point}/${path}" ]; then
+ echo "${uuid} ${path}"
+ ret=0
+ break
+ fi
+ done
+ fi
+
+ umount "${mount_point}" 2>/dev/null >/dev/null
+
+ return ${ret}
+}
+
+keypaths="$(getargs rd_LUKS_KEYPATH)"
+unset keydev_uuid keypath
+
+if [ -n "$keypaths" ]; then
+ keydev_uuids="$(getargs rd_LUKS_KEYDEV_UUID)"
+ [ -n "$keydev_uuids" ] || {
+ warn 'No UUID of device storing LUKS key specified.'
+ warn 'It is recommended to set rd_LUKS_KEYDEV_UUID.'
+ warn 'Performing scan of *all* devices accessible by UUID...'
+ }
+ tmp=$(foreach_uuid_until "probe_keydev \$full_uuid $keypaths" \
+ $keydev_uuids) && {
+ keydev_uuid="${tmp%% *}"
+ keypath="${tmp#* }"
+ } || {
+ warn "Key for $device not found."
+ }
+ unset tmp keydev_uuids
+fi
+
+unset keypaths
+
+#
+# Open LUKS device
+#
+
info "luksOpen $device $luksname"
-# flock against other interactive activities
-{ flock -s 9;
- echo -n "$device ($luksname) is password protected"
- cryptsetup luksOpen -T1 $1 $luksname
-} 9>/.console.lock
+
+if [ -n "$keydev_uuid" ]; then
+ mntp=/mnt/keydev
+ mkdir -p "$mntp"
+ mount -r -U "$keydev_uuid" "$mntp"
+ cryptsetup -d "$mntp/$keypath" luksOpen "$device" "$luksname"
+ umount "$mntp"
+ rmdir -p "$mntp" 2>/dev/null
+else
+ # flock against other interactive activities
+ { flock -s 9;
+ echo -n "$device ($luksname) is password protected"
+ cryptsetup luksOpen -T1 $1 $luksname
+ } 9>/.console.lock
+fi
# mark device as asked
>> /tmp/cryptroot-asked-$2
exit 0
-# vim:ts=8:sw=4:sts=4:et
\ No newline at end of file
+# vim:ts=8:sw=4:sts=4:et
diff --git a/modules.d/90crypt/parse-crypt.sh b/modules.d/90crypt/parse-crypt.sh
index 04d9ecb..fce952d 100755
--- a/modules.d/90crypt/parse-crypt.sh
+++ b/modules.d/90crypt/parse-crypt.sh
@@ -4,23 +4,40 @@ if getarg rd_NO_LUKS; then
rm -f /etc/udev/rules.d/70-luks.rules
else
{
- echo 'SUBSYSTEM!="block", GOTO="luks_end"'
- echo 'ACTION!="add|change", GOTO="luks_end"'
+ echo 'SUBSYSTEM!="block", GOTO="luks_end"'
+ echo 'ACTION!="add|change", GOTO="luks_end"'
} > /etc/udev/rules.d/70-luks.rules
- LUKS=$(getargs rd_LUKS_UUID=)
+
+ LUKS=$(getargs rd_LUKS_UUID)
+ unset settled
+ [ -n "$(getargs rd_LUKS_KEYPATH)" ] && \
+ [ -z "$(getargs rd_LUKS_KEYDEV_UUID)" ] && \
+ settled='--settled'
+
if [ -n "$LUKS" ]; then
- echo '. /lib/dracut-lib.sh' > /emergency/crypt.sh
- for luksid in $LUKS; do
- printf 'ENV{ID_FS_TYPE}=="crypto_LUKS", ENV{ID_FS_UUID}=="*%s*", RUN+="/sbin/initqueue --unique --onetime --name cryptroot-ask-%%k /sbin/cryptroot-ask $env{DEVNAME} luks-$env{ID_FS_UUID}"\n' $luksid \
- >> /etc/udev/rules.d/70-luks.rules
- printf '[ -e /dev/disk/by-uuid/*%s* ] || exit 1 \n' $luksid >> /initqueue-finished/crypt.sh
- printf '[ -e /dev/disk/by-uuid/*%s* ] || warn "crypto LUKS UUID "%s" not found" \n' $luksid $luksid >> /emergency/00-crypt.sh
- done
+ echo '. /lib/dracut-lib.sh' > /emergency/crypt.sh
+ for luksid in $LUKS; do
+ {
+ printf 'ENV{ID_FS_TYPE}=="crypto_LUKS", '
+ printf 'ENV{ID_FS_UUID}=="*%s*", ' $luksid
+ printf 'RUN+="/sbin/initqueue --unique --onetime %s ' "$settled"
+ printf '--name cryptroot-ask-%%k /sbin/cryptroot-ask '
+ printf '$env{DEVNAME} luks-$env{ID_FS_UUID}"\n'
+ } >> /etc/udev/rules.d/70-luks.rules
+
+ printf '[ -e /dev/disk/by-uuid/*%s* ] || exit 1\n' $luksid \
+ >> /initqueue-finished/crypt.sh
+ {
+ printf '[ -e /dev/disk/by-uuid/*%s* ] || ' $luksid
+ printf 'warn "crypto LUKS UUID "%s" not found"\n' $luksid
+ } >> /emergency/00-crypt.sh
+ done
else
- echo 'ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/initqueue --unique --onetime --name cryptroot-ask-%k /sbin/cryptroot-ask $env{DEVNAME} luks-$env{ID_FS_UUID}"' \
- >> /etc/udev/rules.d/70-luks.rules
+ echo 'ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/initqueue' $settled \
+ '--unique --onetime --name cryptroot-ask-%k' \
+ '/sbin/cryptroot-ask $env{DEVNAME} luks-$env{ID_FS_UUID}"' \
+ >> /etc/udev/rules.d/70-luks.rules
fi
- echo 'LABEL="luks_end"' >> /etc/udev/rules.d/70-luks.rules
+ echo 'LABEL="luks_end"' >> /etc/udev/rules.d/70-luks.rules
fi
-
diff --git a/modules.d/99base/dracut-lib.sh b/modules.d/99base/dracut-lib.sh
index 2624f7d..84bb5fa 100755
--- a/modules.d/99base/dracut-lib.sh
+++ b/modules.d/99base/dracut-lib.sh
@@ -48,6 +48,31 @@ getargs() {
return 1;
}
+# Prints value of given option. If option is a flag and it's present,
+# it just returns 0. Otherwise 1 is returned.
+# $1 = options separated by commas
+# $2 = option we are interested in
+#
+# Example:
+# $1 = cipher=aes-cbc-essiv:sha256,hash=sha256,verify
+# $2 = hash
+# Output:
+# sha256
+getoptcomma() {
+ local line=",$1,"; local opt="$2"; local tmp
+
+ case "${line}" in
+ *,${opt}=*,*)
+ tmp="${line#*,${opt}=}"
+ echo "${tmp%%,*}"
+ return 0
+ ;;
+ *,${opt},*) return 0 ;;
+ esac
+
+ return 1
+}
+
setdebug() {
if [ -z "$RDDEBUG" ]; then
if [ -e /proc/cmdline ]; then
@@ -243,3 +268,35 @@ ip_to_var() {
esac
}
+# Evaluate command for UUIDs either given as arguments for this function or all
+# listed in /dev/disk/by-uuid. UUIDs doesn't have to be fully specified. If
+# beginning is given it is expanded to all matching UUIDs. To pass full UUID
+# to your command use '${full_uuid}'. Remember to escape '$'!
+#
+# $1 = command to be evaluated
+# $2 = list of UUIDs separated by space
+#
+# The function returns after *first successful evaluation* of the given command
+# with status 0. If evaluation fails for every UUID function returns with
+# status 1.
+#
+# Example:
+# foreach_uuid_until "mount -U \${full_uuid} /mnt; echo OK; umount /mnt" \
+# "01234 f512 a235567f-12a3-c123-a1b1-01234567abcb"
+foreach_uuid_until() (
+ cd /dev/disk/by-uuid
+
+ local cmd="$1"; shift; local uuids_list="$*"
+ local uuid; local full_uuid
+
+ [ -n "${cmd}" ] || return 1
+
+ for uuid in ${uuids_list:-*}; do
+ for full_uuid in ${uuid}*; do
+ [ -e "${full_uuid}" ] || continue
+ eval ${cmd} && return 0
+ done
+ done
+
+ return 1
+)
--
1.7.1
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
next reply other threads:[~2010-07-13 17:14 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-13 17:14 Amadeusz Żołnowski [this message]
2010-07-21 11:41 ` [PATCH] 90crypt: keys on external devices support Harald Hoyer
-- strict thread matches above, loose matches on Subject: below --
2010-10-19 13:54 Mr Dash Four
[not found] ` <4CBDA328.40401-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
2010-10-19 14:19 ` Amadeusz Żołnowski
2010-10-19 14:33 ` Mr Dash Four
[not found] ` <4CBDAC3D.7050906-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
2010-10-20 1:24 ` Mr Dash Four
[not found] ` <4CBE44D3.6070000-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
2010-10-20 14:12 ` Amadeusz Żołnowski
2010-10-20 14:44 ` Mr Dash Four
[not found] ` <4CBF004F.9070201-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
2010-10-20 15:17 ` Amadeusz Żołnowski
2010-10-20 15:37 ` Mr Dash Four
[not found] ` <4CBF0CA3.1070801-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
2010-10-22 16:51 ` Amadeusz Żołnowski
2010-10-21 13:29 ` Karel Zak
[not found] ` <20101021132916.GC22186-sHeGUpI7y9L/9pzu0YdTqQ@public.gmane.org>
2010-10-21 13:54 ` Mr Dash Four
[not found] ` <4CC0462E.20507-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
2010-10-21 15:18 ` Karel Zak
[not found] ` <20101021151802.GD22186-sHeGUpI7y9L/9pzu0YdTqQ@public.gmane.org>
2010-10-21 15:48 ` Mr Dash Four
[not found] ` <4CC060B3.3050508-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
2010-10-22 16:40 ` Amadeusz Żołnowski
2010-10-22 18:34 ` Karel Zak
2010-10-20 13:19 ` Amadeusz Żołnowski
2010-10-20 14:06 ` Mr Dash Four
[not found] ` <4CBEF768.90908-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
2010-10-20 14:25 ` Amadeusz Żołnowski
2010-10-20 14:48 ` Mr Dash Four
[not found] ` <4CBF0133.2070709-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
2010-10-20 15:26 ` Amadeusz Żołnowski
2010-10-20 15:39 ` Mr Dash Four
2010-10-22 11:50 ` Mr Dash Four
[not found] ` <4CC17A87.7050804-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
2010-10-22 17:07 ` Amadeusz Żołnowski
2010-10-23 15:13 ` Mr Dash Four
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100713191447.0d09d065@etiriah \
--to=aidecoe-2qtfh70ttyba5ebddlwbiw@public.gmane.org \
--cc=initramfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.