Linux/Ubuntu/HardyRAID5EncryptedLVM: crypto-usb-key.sh

File crypto-usb-key.sh, 7.7 KB (added by tj, 9 years ago)

Usplash-aware crypto shell-script to locate key-file

Line 
1#!/bin/sh
2
3# Created by TJ <linux@tjworld.net> 7 July 2008
4# Copyright 2008,2009 TJ
5# Licensed on the terms of the GNU GPL v2
6# See /usr/share/common-licenses/GPL-2
7
8# Inspired and initially based upon the script in the
9# passwordless cryptofs setup in Debian Etch.
10# See: http://wejn.org/how-to-make-passwordless-cryptsetup.html
11# Author: Wejn <wejn at box dot cz>
12# As updated by Rodolfo Garcia (kix) <kix at kix dot com>
13# For multiple partitions
14# http://www.kix.es/
15#
16# Updated by TJ <linux@tjworld.net> 7 July 2008
17#  For use with Ubuntu Hardy, usplash, automatic detection of USB devices,
18#  detection and examination of *all* partitions on the device (not just partition #1),
19#  automatic detection of partition type, refactored, commented, debugging code.
20# Updated by TJ, 4 December 2008
21#  * Dropped detection of specific USB devices because Intrepid and kernel
22#    2.6.27 no longer include "usb" in the /sys/block/.../device path. Now
23#    the script relies purely on the 'removable' flag in determining which
24#    devices to look on for the keyfile.
25#  * Fixed msg() not printing to console when using Intrepid.
26#  * Simplified detection of running usplash.
27# Updated by TJ, 8 February 2009
28# * Jaunty support additions
29# * Added /lib/udev/ to PATH to access the vol_id binary
30# * Removed reliance on basename - using ${VAR##*/} instead
31# * Use vol_id to determine FSTYPE and LABEL
32# * Modify USB device wait to monitor dmesg and exit as soon as an attachment is reported
33# * Ensure script will work in intrd and after root is mounted from /etc/init.d/cryptdisks-early
34# * Make LABEL and FSTYPE logic fall-back to using old method if vol_id isn't available
35# * Added logic to reduce initial USB-device delay to the minimum possible
36# * Added udevadm settle prior to using vol_id to read block device
37# TODO:
38#  * Test fully on Gutsy, Hardy, Intrepid
39
40# define counter-intuitive shell logic values (based on /bin/true & /bin/false)
41TRUE=0
42FALSE=1
43
44# set DEBUG=$TRUE to display debug messages, DEBUG=$FALSE to be quiet
45DEBUG=$FALSE
46
47# is usplash available? default false
48USPLASH=$FALSE
49if [ -p /dev/.initramfs/usplash_outfifo ]; then
50        # usplash is available
51        USPLASH=$TRUE
52        # enable verbose messages (required to display messages if kernel boot option "quiet" is enabled)
53        /sbin/usplash_write "VERBOSE on"
54fi
55
56# print message to usplash or stderr
57# usage: msg <command> "message" [switch]
58# command: TEXT | STATUS | SUCCESS | FAILURE | CLEAR (see 'man usplash_write' for all commands)
59# switch : switch used for echo to stderr (ignored for usplash)
60# when using usplash the command will cause "message" to be
61# printed according to the usplash <command> definition.
62# using the switch -n will allow echo to write multiple messages
63# to the same line
64msg()
65{
66        if [ $# -gt 0 ]; then
67                # handle multi-line messages
68                echo $2 | while read LINE; do
69                        if [ $USPLASH -eq $TRUE ]; then
70                                # use usplash
71                                /sbin/usplash_write "$1 $LINE"         
72                        else
73                                # use stderr for all messages since the result has to be written to stdout
74                                echo $3 "$2" >&2
75                                # return now since entire message has been printed (using $2 not $LINE)
76                                break;
77                        fi
78                done
79        fi
80}
81
82[ $DEBUG -eq $TRUE ] && msg STATUS "Executing crypto-usb-key.sh $1..."
83
84# flag tracking key-file availability
85OPENED=$FALSE
86
87# temporary mount path for USB key
88MD=/tmp-usb-mount
89
90if [ "x$1" = "x" -o "x$1" = "xnone" ]; then
91        # default key-file on the USB disk
92        KEYFILE=.key
93else
94        KEYFILE=$1
95fi
96
97# If the file already exists use it.
98# This is useful where an encrypted volume contains keyfile(s) for later
99# volumes and is now mounted and accessible
100if [ -f $KEYFILE ]; then
101        [ $DEBUG -eq $TRUE ] && msg TEXT "Found $KEYFILE"
102        cat $KEYFILE
103        OPENED=$TRUE
104        DEV="existing mount"
105        LABEL=""
106else
107        # Is the USB driver loaded?
108        cat /proc/modules | grep usb_storage >/dev/null 2>&1
109        USBLOAD=0$?
110        if [ $USBLOAD -gt 0 ]; then
111                [ $DEBUG -eq $TRUE ] && msg TEXT "Loading driver 'usb_storage'"
112                modprobe usb_storage >/dev/null 2>&1
113        fi
114        # before deciding to wait for 30 seconds, check if any removable SCSI block devices are already present
115        if ! cat /sys/block/sd*/sd??/../removable | grep -q 1 >/dev/null 2>&1; then
116                # give the system time to settle and open the USB devices
117                COUNT=30
118                msg TEXT "Waiting up to $COUNT seconds for removable devices..."
119                while [ $COUNT -gt 0 ]; do
120                        if dmesg | grep -q 'Attached.*removable disk' >/dev/null 2>&1; then
121                                [ $DEBUG -eq $TRUE ] && msg TEXT "Detected device attachment"
122                                break;
123                        fi
124                        sleep 1
125                        COUNT=$(($COUNT - 1))
126                done
127        else
128                [ $DEBUG -eq $TRUE ] && msg TEXT "Found removable device so not waiting for USB to settle"
129        fi
130        # Are there any SCSI block devices?
131        ls -d /sys/block/sd* >/dev/null 2>&1
132        SBD=$?
133
134        if [ $SBD -eq $TRUE ]; then
135                mkdir -p $MD
136                # enhance path but preserve original
137                OLDPATH=$PATH
138                [ $DEBUG -eq $TRUE ] && msg TEXT "Old PATH=$PATH"
139                PATH="/lib/udev/:$PATH"
140                [ $DEBUG -eq $TRUE ] && msg TEXT "New PATH=$PATH"
141                [ $DEBUG -eq $TRUE ] && msg TEXT "Trying to get key-file '$KEYFILE' ..."
142                for SFS in /sys/block/sd*/sd??; do
143                        [ $DEBUG -eq $TRUE ] && msg TEXT "Examining $SFS" -n
144                        # is it a USB device?
145                        #ls -l ${SFS}/../device |  grep 'usb' >/dev/null 2>&1
146                        #USB=0$?
147                        #[ $DEBUG -eq $TRUE ] && msg TEXT ", USB=$USB" -n
148                        # Is the device removable?
149                        REMOVABLE=0`cat ${SFS}/../removable`
150                        [ $DEBUG -eq $TRUE ] && msg TEXT ", REMOVABLE=$REMOVABLE" -n
151                        if [ $REMOVABLE -eq 1 -a -f $SFS/dev ]; then
152                                [ $DEBUG -eq $TRUE ] && msg TEXT ", *possible key device*" -n
153                                DEV=${SFS##*/}
154                                [ $DEBUG -eq $TRUE ] && msg TEXT ", device $DEV" -n
155                                DEVPATH="/dev/$DEV"
156                                if [ -x /lib/udev/vol_id ]; then
157                                        udevadm settle --timeout=10
158                                        LABEL=`vol_id --label ${DEVPATH}`
159                                        FSTYPE=`vol_id --type ${DEVPATH}`
160                                else
161                                        # No access to vol_id so query the UDEV database directly
162                                        LABEL=" (`cat /dev/.udev/db/*${DEV} | sed -n 's/.*ID_FS_LABEL_SAFE=\(.*\)/\1/p'`) "
163                                        # No access to vol_id and /bin/fstype reports vfat/msdos/ntfs as 'unknown', so
164                                        # query the UDEV database directly to get the file-system type
165                                        FSTYPE=`cat /dev/.udev/db/*${DEV} | sed -n 's/.*ID_FS_TYPE=\(.*\)/\1/p'`
166                                fi
167                                [ $DEBUG -eq $TRUE ] && msg TEXT ", label $LABEL" -n
168                                [ $DEBUG -eq $TRUE ] && msg TEXT ", fstype $FSTYPE" -n
169                                # Is the file-system driver loaded?
170                                cat /proc/modules | grep $FSTYPE >/dev/null 2>&1
171                                FSLOAD=0$?
172                                if [ $FSLOAD -gt 0 ]; then
173                                        [ $DEBUG -eq $TRUE ] && msg TEXT ", loading driver for $FSTYPE" -n
174                                        # load the correct file-system driver
175                                        modprobe $FSTYPE >/dev/null 2>&1
176                                fi
177                                [ $DEBUG -eq $TRUE ] && msg TEXT ", mounting $DEVPATH on $MD" -n
178                                mount ${DEVPATH} $MD -t $FSTYPE -o ro 2>/dev/null
179                                [ $DEBUG -eq $TRUE ] && msg TEXT ", (`mount |  grep $DEV`)" -n
180                                if [ -f $MD/$KEYFILE ]; then
181                                        [ $DEBUG -eq $TRUE ] && msg TEXT ", found $MD/$KEYFILE" -n
182                                        cat $MD/$KEYFILE
183                                        [ $DEBUG -eq $TRUE ] && msg TEXT ", umount $MD"
184                                        umount $MD 2>/dev/null
185                                        OPENED=$TRUE
186                                        break
187                                fi
188                                [ $DEBUG -eq $TRUE ] && msg TEXT ", umount $MD" -n
189                                umount $MD 2>/dev/null
190                                [ $DEBUG -eq $TRUE ] && msg TEXT ", done\n\n" -n
191                        else
192                                [ $DEBUG -eq $TRUE ] && msg TEXT ", device $DEV ignored" -n
193                        fi
194                        [ $DEBUG -eq $TRUE ] && msg CLEAR ""
195                done
196                PATH=$OLDPATH
197        fi
198fi
199
200# clear existing usplash text and status messages
201[ $USPLASH -eq $TRUE ] && msg STATUS "                               " && msg CLEAR ""
202
203if [ $OPENED -eq $FALSE ]; then
204        msg TEXT "FAILED to find USB key-file $KEYFILE"
205        msg TEXT "(The key device may have been slow, try pressing"
206        msg TEXT " Enter twice to retry)"
207        msg TEXT "Alternatively, enter the LUKS password: "
208        read -r A </dev/console >/dev/null
209        echo -n "$A"
210else
211        msg TEXT "Success loading key-file"
212        [ $DEBUG -eq $TRUE ] && msg TEXT "from $DEVPATH $LABEL"
213fi
214
215#
216[ $USPLASH -eq $TRUE ] && /sbin/usplash_write "VERBOSE default"