Bonjour,

Le vendredi 23 octobre 09 à 16:41, Christophe Mehay a écrit :
| J'ai reconfiguré les paquets (consolekit console-terminus console-setup
|     et console-tools avec dpkg-reconfigure) et exécuté "update-initramfs
| -u", mais luks est toujours en qwerty après reboot...

Je suis dans une configuration similaire (partition racine chiffrée avec
LUKS) et j'ai deux scripts qui manipulent le clavier.

En revanche, je ne sais pas du tout d'où ils viennent. Ils ne sont pas
issus directement d'un paquet, cryptsetup fournit des scripts qui
s'appellent pareil dans /usr/share, mais ils sont différents de ceux dans
/etc.

Je n'ai pas le temps d'investiguer plus, je les mets en pièce-jointe au
cas-où ça pourrait aider...

Seb
#!/bin/sh

PREREQ=""

prereqs()
{
        echo "$PREREQ"
}

case $1 in
prereqs)
        prereqs
        exit 0
        ;;
esac

. /usr/share/initramfs-tools/hook-functions

get_root_device() {
        local device mount type options dump pass

        if [ ! -r /etc/fstab ]; then
                return 1
        fi

        grep '^[^#]' /etc/fstab | \
        while read device mount type options dump pass; do
                if [ "$mount" = "/" ]; then
                        echo "$device"
                        return
                fi
        done
}

get_resume_devices() {
        local device opt count dupe candidates devices
        candidates=""

        # First, get a list of potential resume devices

        # uswsusp
        if [ -e /etc/uswsusp.conf ]; then
                device=$(sed -rn 's/^resume 
device[[:space:]]+[:=][[:space:]]+// p' /etc/uswsusp.conf)
                if [ -n "$device" ]; then
                        candidates="$candidates $device"
                fi
        fi

        # uswsusp - again...
        if [ -e /etc/suspend.conf ]; then
                device=$(sed -rn 's/^resume 
device[[:space:]]+[:=][[:space:]]+// p' /etc/suspend.conf)
                if [ -n "$device" ]; then
                        candidates="$candidates $device"
                fi
        fi

        # regular swsusp
        for opt in $(cat /proc/cmdline); do
                case $opt in
                resume=*)
                        device="${opt#resume=}"
                        candidates="$candidates $device"
                        ;;
                esac
        done

        # initramfs-tools
        if [ -e /etc/initramfs-tools/conf.d/resume ]; then
                device=$(sed -rn 's/^RESUME[[:space:]]+=[[:space:]]+// p' 
/etc/initramfs-tools/conf.d/resume)
                if [ -n "$device" ]; then
                        candidates="$candidates $device"
                fi
        fi

        # Now check the sanity of all candidates
        devices=""
        count=0
        for device in $candidates; do
                # Weed out clever defaults
                if [ "$device" = "<path_to_resume_device_file>" ]; then
                        continue
                fi

                # Weed out duplicates
                dupe=0
                for opt in $devices; do
                        if [ "$device" = "$opt" ]; then
                                dupe=1
                        fi
                done
                if [ $dupe -eq 1 ]; then
                        continue
                fi

                # This device seems ok
                devices="$devices $device"
                count=$(( $count + 1 ))
        done

        if [ $count -gt 1 ]; then
                echo "cryptsetup: WARNING: found more than one resume device 
candidate:" >&2
                for device in $devices; do
                        echo "                     $device" >&2
                done
        fi

        if [ $count -gt 0 ]; then
                echo $devices
        fi

        return 0
}

node_is_in_crypttab() {
        local node
        node="$1"

        grep -q ^$node /etc/crypttab
        return $?
}

get_lvm_deps() {
        local node deps maj min depnode
        node="$1"

        if [ -z $node ]; then
                echo "cryptsetup: WARNING: get_lvm_deps - invalid arguments" >&2
                return 1
        fi

        if ! deps=$(dmsetup deps "$node" 2> /dev/null | sed 's/[^:]*: *//;s/[ 
(]//g;s/)/ /g'); then
                echo "cryptsetup: WARNING: failed to find deps for $node" >&2
                return 1
        fi

        # We should now have a list of major,minor pairs, e.g. "3,2 3,3"
        for dep in $deps; do
                maj=${dep%,*}
                min=${dep#*,}
                depnode=$(dmsetup ls | sed -n "s/\\([^ ]*\\) *($maj, 
$min)/\\1/p")
                if [ -z "$depnode" ]; then
                        continue
                fi
                if [ "$(dmsetup table $depnode 2> /dev/null | cut -d' ' -f3)" 
!= "crypt" ]; then
                        continue
                fi
                echo "$depnode"
        done

        return 0
}

get_device_opts() {
        local target source link extraopts rootopts opt
        target="$1"
        extraopts="$2"
        KEYSCRIPT=""
        OPTIONS=""

        if [ -z "$target" ]; then
                echo "cryptsetup: WARNING: get_device_opts - invalid arguments" 
>&2
                return 1
        fi

        opt=$( grep ^$target /etc/crypttab | head -1 | sed 's/[[:space:]]\+/ 
/g' )
        source=$( echo $opt | cut -d " " -f2 )
        key=$( echo $opt | cut -d " " -f3 )
        rootopts=$( echo $opt | cut -d " " -f4- )

        if [ -z "$opt" ] || [ -z "$source" ] || [ -z "$key" ] || [ -z 
"$rootopts" ]; then
                echo "cryptsetup: WARNING: invalid line in /etc/crypttab - 
$opt" >&2
                return 1
        fi

        # Sanity checks for $source
        if [ -h "$source" ]; then
                link=$(readlink -nqe "$source")
                if [ -z "$link" ]; then
                        echo "cryptsetup: WARNING: $source is a dangling 
symlink" >&2
                        return 1
                fi

                if [ "$link" != "${link#/dev/mapper/}" ]; then
                        echo "cryptsetup: NOTE: using $link instead of $source 
for $target" >&2
                        source="$link"
                fi
        fi

        # Sanity checks for $key
        if [ "$key" = "/dev/random" ] || [ "$key" = "/dev/urandom" ]; then
                echo "cryptsetup: WARNING: target $target has a random key, 
skipped" >&2
                return 1
        fi

        if [ -n "$extraopts" ]; then
                rootopts="$extraopts,$rootopts"
        fi

        # We have all the basic options, let's go trough them
        OPTIONS="target=$target,source=$source,key=$key"
        local IFS=", "
        for opt in $rootopts; do
                case $opt in
                        cipher=*)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        hash=*)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        size=*)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        lvm=*)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        keyscript=*)
                                opt=${opt#keyscript=}
                                if [ ! -x "$opt" ]; then
                                        echo "cryptsetup: WARNING: target 
$target has an invalid keyscript, skipped" >&2
                                        return 1
                                fi
                                KEYSCRIPT="$opt"
                                opt=$(basename "$opt")
                                OPTIONS="$OPTIONS,keyscript=/keyscripts/$opt"
                                ;;
                        *)
                                # Presumably a non-supported option
                                ;;
                esac
        done

        # If keyscript is set, the "key" is just an argument to the script
        if [ "$key" != "none" ] && [ -z "$KEYSCRIPT" ]; then
                echo "cryptsetup: WARNING: target $target uses a key file, 
skipped" >&2
                return 1
        fi
}

get_device_modules() {
        local node value cipher blockcipher ivhash
        node="$1"

        # Check the ciphers used by the active root mapping
        value=$(dmsetup table "$node" | cut -d " " -f4)
        cipher=$(echo "$value" | cut -d ":" -f1 | cut -d "-" -f1)
        blockcipher=$(echo "$value" | cut -d ":" -f1 | cut -d "-" -f2)
        ivhash=$(echo "$value" | cut -d ":" -s -f2)

        if [ -n "$cipher" ]; then
                echo "$cipher"
        else
                return 1
        fi

        if [ -n "$blockcipher" ] && [ "$blockcipher" != "plain" ]; then
                echo "$blockcipher"
        fi

        if [ -n "$ivhash" ] && [ "$ivhash" != "plain" ]; then
                echo "$ivhash"
        fi
        return 0
}

prepare_keymap() {
        local env charmap

        # Allow the correct keymap to be loaded if possible
        if [ ! -x /bin/loadkeys ] || [ ! -r /etc/console/boottime.kmap.gz ]; 
then
                return 1
        fi

        copy_exec /bin/loadkeys /bin/
        cp /etc/console/boottime.kmap.gz $DESTDIR/etc/

        # Check for UTF8 console
        if [ ! -x /usr/bin/kbd_mode ]; then
                return 0
        fi

        if [ -r /etc/environment ]; then
                env="/etc/environment"
        elif [ -r /etc/default/locale ]; then
                env="/etc/default/locale"
        else
                return 0
        fi

        for var in LANG LC_ALL LC_CTYPE; do
                value=$(egrep "^[^#]*${var}=" $env | tail -n1 | cut -d= -f2)
                eval $var=$value
        done

        charmap=$(LANG=$LANG LC_ALL=$LC_ALL LC_CTYPE=$LC_CTYPE locale charmap)
        if [ "$charmap" = "UTF-8" ]; then
                copy_exec /usr/bin/kbd_mode /bin/
        fi
        return 0
}

add_device() {
        local node nodes opts lastopts i count
        nodes="$1"
        opts=""     # Applied to all nodes
        lastopts="" # Applied to last node

        if [ -z "$nodes" ]; then
                return 0
        fi

        # Check that it is a node under /dev/mapper/
        nodes="${nodes#/dev/mapper/}"
        if [ "$nodes" = "$1" ]; then
                return 0
        fi

        # Can we find this node in crypttab
        if ! node_is_in_crypttab "$nodes"; then
                # dm node but not in crypttab, is it a lvm device backed by 
dm-crypt nodes?
                lvmnodes=$(get_lvm_deps "$nodes") || return 1

                # not backed by any dm-crypt nodes; stop here
                if [ -z "$lvmnodes" ]; then
                    return 0
                fi

                # It is a lvm device!
                lastopts="lvm=$nodes"
                nodes="$lvmnodes"
        fi

        # Prepare to setup each node
        count=$(echo "$nodes" | wc -w)
        i=1
        for node in $nodes; do
                # Prepare the additional options
                if [ $i -eq $count ]; then
                        if [ -z "$opts" ]; then
                                opts="$lastopts"
                        else
                                opts="$opts,$lastopts"
                        fi
                fi

                # Get crypttab root options
                if ! get_device_opts $node $opts; then
                        continue
                fi
                echo "$OPTIONS" >> "$DESTDIR/conf/conf.d/cryptroot"

                # If we have a keyscript, make sure it is included
                if [ -n "$KEYSCRIPT" ]; then
                        if [ ! -d "$DESTDIR/keyscripts" ]; then
                                mkdir "$DESTDIR/keyscripts"
                        fi
                        copy_exec "$KEYSCRIPT" /keyscripts
                fi

                # Calculate needed modules
                modules=$(get_device_modules $node | sort | uniq)
                if [ -z "$modules" ]; then
                        echo "cryptsetup: WARNING: failed to determine cipher 
modules to load for $node" >&2
                        continue
                fi
                echo dm_mod
                echo dm_crypt
                echo "$modules"

                i=$(( $i + 1 ))
        done

        return 0
}


#
# Begin real processing
#

# Unless MODULES = "dep", we always add a basic subset of modules/tools
if [ "$MODULES" != "dep" ]; then
        for mod in dm_mod dm_crypt aes sha256 cbc; do
                manual_add_modules $mod
        done
        copy_exec /sbin/cryptsetup /sbin
        copy_exec /sbin/dmsetup /sbin
        prepare_keymap
fi

# We can't do anything without a config file
if [ ! -r /etc/crypttab ]; then
        exit 0
fi

# Find out which devices to add to the config file
rootdev=$(get_root_device)
if [ -z "$rootdev" ]; then
        echo "cryptsetup: WARNING: could not determine root device from 
/etc/fstab" >&2
fi
resumedevs=$(get_resume_devices)
if [ -z "$rootdev" ] && [ -z "$resumedevs" ]; then
        exit 0
fi

# Load the config opts and modules for each device
for dev in $rootdev $resumedevs; do
        if ! modules=$(add_device "$dev"); then
                echo "cryptsetup: FAILURE: could not determine configuration 
for $dev" >&2
                continue
        fi

        for mod in $modules; do
                manual_add_modules $mod
        done
done

# Prepare the initramfs
copy_exec /sbin/cryptsetup /sbin
copy_exec /sbin/dmsetup /sbin
prepare_keymap

# Done
exit 0
#!/bin/sh

#
# Standard initramfs preamble
#
prereqs()
{
        # Make sure that cryptroot is run last in local-top
        for req in /scripts/local-top/*; do
                script=$(basename $req)
                if [ $script != cryptroot ]; then
                        echo $script
                fi
        done
}

case $1 in
prereqs)
        prereqs
        exit 0
        ;;
esac


#
# Helper functions
#
parse_options()
{
        local cryptopts
        cryptopts="$1"

        if [ -z "$cryptopts" ]; then
                return 1
        fi

        # Defaults
        cryptcipher=aes-cbc-essiv:sha256
        cryptsize=256
        crypthash=sha256
        crypttarget=cryptroot
        cryptsource=""
        cryptlvm=""
        cryptkeyscript=""
        cryptkey="" # This is only used as an argument to an eventual keyscript

        local IFS=" ,"
        for x in $cryptopts; do
                case $x in
                hash=*)
                        crypthash=${x#hash=}
                        ;;
                size=*)
                        cryptsize=${x#size=}
                        ;;
                cipher=*)
                        cryptcipher=${x#cipher=}
                        ;;
                target=*)
                        crypttarget=${x#target=}
                        ;;
                source=*)
                        cryptsource=${x#source=}
                        ;;
                lvm=*)
                        cryptlvm=${x#lvm=}
                        ;;
                keyscript=*)
                        cryptkeyscript=${x#keyscript=}
                        ;;
                key=*)
                        if [ "${x#key=}" != "none" ]; then
                                cryptkey=${x#key=}
                        fi
                        ;;
                esac
        done

        if [ -z "$cryptsource" ]; then
                echo "cryptsetup: source parameter missing"
                return 1
        fi
        return 0
}

activate_vg()
{
        local vg
        vg="${1#/dev/mapper/}"

        # Sanity checks
        if [ ! -x /sbin/vgchange ] || [ "$vg" = "$1" ]; then
                return 1
        fi

        # Make sure that the device contains at least one dash
        if [ "${vg%%-*}" = "$vg" ]; then
                return 1
        fi

        # Split volume group from logical volume.
        vg=$(echo ${vg} | sed -e 's#\(.*\)\([^-]\)-[^-].*#\1\2#')

        # Reduce padded --'s to -'s
        vg=$(echo ${vg} | sed -e 's#--#-#g')

        vgchange -ay ${vg}
        return $?
}

activate_evms()
{
        local dev module
        dev="${1#/dev/evms/}"

        # Sanity checks
        if [ ! -x /sbin/evms_activate ] || [ "$dev" = "$1" ]; then
                return 1
        fi

        # Load modules used by evms
        for module in dm-mod linear raid0 raid1 raid10 raid5 raid6; do
                modprobe -q $module
        done

        # Activate it
        /sbin/evms_activate
        return $?
}

load_keymap()
{
        local opts
        opts="-q"

        # Should terminal be in UTF8 mode?
        if [ -x /bin/kbd_mode ]; then
                /bin/kbd_mode -u
                opts="$opts -u"
        fi

        # Load custom keymap
        if [ -x /bin/loadkeys -a -r /etc/boottime.kmap.gz ]; then
                loadkeys $opts /etc/boottime.kmap.gz
        fi
}

setup_mapping()
{
        local opts count cryptcreate cryptremove NEWROOT
        opts="$1"

        if [ -z "$opts" ]; then
                return 0
        fi

        parse_options "$opts" || return 1

        # The same target can be specified multiple times
        # e.g. root and resume lvs-on-lvm-on-crypto
        if [ -e "/dev/mapper/$crypttarget" ]; then
                return 0
        fi

        modprobe -q dm_crypt
        
        # Add delay
        echo "Sleeping for 5 seconds to allow USB detection."
        sleep 5
        echo "Awake, attempting to mount encrypted partitions."

        echo "Setting up cryptographic volume $crypttarget (based on 
$cryptsource)"

        # Make sure the cryptsource device is available
        if [ ! -e $cryptsource ]; then
                activate_vg $cryptsource
                activate_evms $cryptsource
        fi

        if [ ! -e $cryptsource ]; then
                echo "cryptsetup: Source device $cryptsource not found"
                return 1
        fi

        # Prepare commands
        if /sbin/cryptsetup isLuks $cryptsource > /dev/null 2>&1; then
                cryptcreate="/sbin/cryptsetup luksOpen $cryptsource 
$crypttarget"
        else
                cryptcreate="/sbin/cryptsetup -c $cryptcipher -s $cryptsize -h 
$crypthash create $crypttarget $cryptsource"
        fi
        cryptremove="/sbin/cryptsetup remove $crypttarget"
        NEWROOT="/dev/mapper/$crypttarget"

        # Try to get a satisfactory password three times
        count=0
        while [ $count -lt 3 ]; do
                count=$(( $count + 1 ))

                if [ -n "$cryptkeyscript" ]; then
                        if [ ! -x "$cryptkeyscript" ]; then
                                echo "cryptsetup: error - $cryptkeyscript 
missing"
                                return 1
                        fi
                        $cryptkeyscript $cryptkey < /dev/console | $cryptcreate 
--key-file=-
                else
                        $cryptcreate < /dev/console
                fi

                if [ $? -ne 0 ]; then
                        echo "cryptsetup: cryptsetup failed, bad password or 
options?"
                        sleep 3
                        continue
                elif [ ! -e "$NEWROOT" ]; then
                        echo "cryptsetup: unknown error setting up device 
mapping"
                        return 1
                fi

                FSTYPE=''
                eval $(fstype < "$NEWROOT")

                # See if we need to setup lvm on the crypto device
                if [ "$FSTYPE" = "lvm" ] || [ "$FSTYPE" = "lvm2" ]; then
                        if [ -z "$cryptlvm" ]; then
                                echo "cryptsetup: lvm fs found but no lvm 
configured"
                                return 1
                        elif ! activate_vg "/dev/mapper/$cryptlvm"; then
                                echo "cryptsetup: failed to setup lvm device"
                                return 1
                        fi

                        NEWROOT="/dev/mapper/$cryptlvm"
                        eval $(fstype < "$NEWROOT")
                fi

                if [ -z "$FSTYPE" ] || [ "$FSTYPE" = "unknown" ]; then
                        echo "cryptsetup: unknown fstype, bad password or 
options?"
                        $cryptremove
                        sleep 3
                        continue
                fi

                break
        done

        if [ $count -lt 3 ]; then
                return 0
        else
                echo "cryptsetup: maximum number of tries exceeded"
                return 1
        fi
}

#
# Begin real processing
#

# If possible, load the keymap so that the user can input non-en characters
load_keymap

# Do we have any kernel boot arguments?
found=''
for opt in $(cat /proc/cmdline); do
        case $opt in
        cryptopts=*)
                found=yes
                setup_mapping "${opt#cryptopts=}"
                ;;
        esac
done

if [ -n "$found" ]; then
        exit 0
fi

# Do we have any settings from the /conf/conf.d/cryptroot file?
if [ -r /conf/conf.d/cryptroot ]; then
        while read mapping; do
                setup_mapping "$mapping"
        done < /conf/conf.d/cryptroot
fi

exit 0

Répondre à