All of lore.kernel.org
 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 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.