#! /bin/sh ### ### unlock-root KEY-FILE set -e ## Fetch the argument. case $# in 1) keyfile=$1 ;; *) echo >&2 "Usage: $0 KEY-FILE"; exit 16 ;; esac ## Some preflight checks. if [ ! -x /usr/bin/gpg ]; then echo >&2 "$0: can't find GnuPG executable" exit 8 fi ## Arrange to have somewhere for the key token. mkdir -p /mnt/keys ## Now we try to find a token. lastuuid=no-match prompt=t win=nil while :; do ## Wait for a different device to be inserted. The first time through, ## we'll accept any device. while :; do ## If there's a token already inserted then go with that. if info=$(blkid -o full -t LABEL=keys); then eval DEVICE=$info case "$UUID" in "$lastuuid") ;; *) lastuuid=$UUID; break ;; esac else lastuuid=no-token fi ## Otherwise we could be here for a while. case "$prompt" in t) echo >&2 -n "Waiting for key token..."; prompt=nil ;; esac ## Wait for a bit. sleep 1 udevadm settle done ## Mount the device somewhere. mount -o ro -t ext2 UUID="$UUID" /mnt/keys ## If we have the key file, then we're done. if [ -f /mnt/keys/"$keyfile".gpg ]; then ## Update the eyecandy, such as it is. case "$prompt" in nil) >&2 echo " ok"; prompt=t ;; esac ## Get GnuPG to decrypt the key. The enormous `gpg' rune is taken from ## the cryptsetup `decrypt_gnupg' script. The here-document prevents ## the key ending up in a ps(1) listing, though the expected use-case is ## to run this script from an initramfs so there won't be anyone ## watching. while :; do key=$(/lib/cryptsetup/askpass "Enter passphrase for key $1: ") case "$key" in "") break ;; esac if /usr/bin/gpg -q --batch --no-options --no-mdc-warning \ --no-random-seed-file --no-default-keyring \ --keyring /dev/null --secret-keyring /dev/null \ --trustdb-name /dev/null --passphrase-fd 0 --decrypt \ /mnt/keys/"$keyfile".gpg <