mkaptsrc: Use `local' for tracking paintedness of tags.
[distorted-bits] / unlock-root
1 #! /bin/sh
2 ###
3 ### unlock-root KEY-FILE
4
5 set -e
6
7 ## Fetch the argument.
8 case $# in
9 1) keyfile=$1 ;;
10 *) echo >&2 "Usage: $0 KEY-FILE"; exit 16 ;;
11 esac
12
13 ## Some preflight checks.
14 if [ ! -x /usr/bin/gpg ]; then
15 echo >&2 "$0: can't find GnuPG executable"
16 exit 8
17 fi
18
19 ## Arrange to have somewhere for the key token.
20 mkdir -p /mnt/keys
21
22 ## Now we try to find a token.
23 lastuuid=no-match
24 prompt=t
25 win=nil
26 while :; do
27
28 ## Wait for a different device to be inserted. The first time through,
29 ## we'll accept any device.
30 while :; do
31
32 ## If there's a token already inserted then go with that.
33 if info=$(blkid -o full -t LABEL=keys); then
34 eval DEVICE=$info
35 case "$UUID" in
36 "$lastuuid") ;;
37 *) lastuuid=$UUID; break ;;
38 esac
39 else
40 lastuuid=no-token
41 fi
42
43 ## Otherwise we could be here for a while.
44 case "$prompt" in
45 t) echo >&2 -n "Waiting for key token..."; prompt=nil ;;
46 esac
47
48 ## Wait for a bit.
49 sleep 1
50 udevadm settle
51 done
52
53 ## Mount the device somewhere.
54 mount -o ro -t ext2 UUID="$UUID" /mnt/keys
55
56 ## If we have the key file, then we're done.
57 if [ -f /mnt/keys/"$keyfile".gpg ]; then
58
59 ## Update the eyecandy, such as it is.
60 case "$prompt" in
61 nil) >&2 echo " ok"; prompt=t ;;
62 esac
63
64 ## Get GnuPG to decrypt the key. The enormous `gpg' rune is taken from
65 ## the cryptsetup `decrypt_gnupg' script. The here-document prevents
66 ## the key ending up in a ps(1) listing, though the expected use-case is
67 ## to run this script from an initramfs so there won't be anyone
68 ## watching.
69 while :; do
70 key=$(/lib/cryptsetup/askpass "Enter passphrase for key $1: ")
71 case "$key" in "") break ;; esac
72 if /usr/bin/gpg -q --batch --no-options --no-mdc-warning \
73 --no-random-seed-file --no-default-keyring \
74 --keyring /dev/null --secret-keyring /dev/null \
75 --trustdb-name /dev/null --passphrase-fd 0 --decrypt \
76 /mnt/keys/"$keyfile".gpg <<EOF
77 $key
78 EOF
79 then win=t; break; fi
80 done
81 fi
82
83 ## Unmount the filesystem.
84 umount /mnt/keys
85
86 ## If we did anything, stop.
87 case "$win" in t) break ;; esac
88 done
89
90 ## Done.
91 exit 0