mkinitrd unification across distributions
 help / color / mirror / Atom feed
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
> +)

  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