From: Harald Hoyer <harald-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: "Amadeusz Żołnowski" <aidecoe-2qtfh70TtYba5EbDDlwbIw@public.gmane.org>
Cc: initramfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH] 90crypt: keys on external devices support
Date: Wed, 21 Jul 2010 13:41:57 +0200 [thread overview]
Message-ID: <4C46DD05.8060901@redhat.com> (raw)
In-Reply-To: <20100713191447.0d09d065@etiriah>
pushed
On 07/13/2010 07:14 PM, Amadeusz Żołnowski wrote:
> 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
> +)
next prev parent reply other threads:[~2010-07-21 11:41 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-13 17:14 [PATCH] 90crypt: keys on external devices support Amadeusz Żołnowski
2010-07-21 11:41 ` Harald Hoyer [this message]
-- 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=4C46DD05.8060901@redhat.com \
--to=harald-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
--cc=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox