Commit | Line | Data |
---|---|---|
f1b539a1 MW |
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 |