| 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) |
|---|
| 41 | TRUE=0 |
|---|
| 42 | FALSE=1 |
|---|
| 43 | |
|---|
| 44 | # set DEBUG=$TRUE to display debug messages, DEBUG=$FALSE to be quiet |
|---|
| 45 | DEBUG=$FALSE |
|---|
| 46 | |
|---|
| 47 | # is usplash available? default false |
|---|
| 48 | USPLASH=$FALSE |
|---|
| 49 | if [ -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" |
|---|
| 54 | fi |
|---|
| 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 |
|---|
| 64 | msg() |
|---|
| 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 |
|---|
| 85 | OPENED=$FALSE |
|---|
| 86 | |
|---|
| 87 | # temporary mount path for USB key |
|---|
| 88 | MD=/tmp-usb-mount |
|---|
| 89 | |
|---|
| 90 | if [ "x$1" = "x" -o "x$1" = "xnone" ]; then |
|---|
| 91 | # default key-file on the USB disk |
|---|
| 92 | KEYFILE=.key |
|---|
| 93 | else |
|---|
| 94 | KEYFILE=$1 |
|---|
| 95 | fi |
|---|
| 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 |
|---|
| 100 | if [ -f $KEYFILE ]; then |
|---|
| 101 | [ $DEBUG -eq $TRUE ] && msg TEXT "Found $KEYFILE" |
|---|
| 102 | cat $KEYFILE |
|---|
| 103 | OPENED=$TRUE |
|---|
| 104 | DEV="existing mount" |
|---|
| 105 | LABEL="" |
|---|
| 106 | else |
|---|
| 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 |
|---|
| 198 | fi |
|---|
| 199 | |
|---|
| 200 | # clear existing usplash text and status messages |
|---|
| 201 | [ $USPLASH -eq $TRUE ] && msg STATUS " " && msg CLEAR "" |
|---|
| 202 | |
|---|
| 203 | if [ $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" |
|---|
| 210 | else |
|---|
| 211 | msg TEXT "Success loading key-file" |
|---|
| 212 | [ $DEBUG -eq $TRUE ] && msg TEXT "from $DEVPATH $LABEL" |
|---|
| 213 | fi |
|---|
| 214 | |
|---|
| 215 | # |
|---|
| 216 | [ $USPLASH -eq $TRUE ] && /sbin/usplash_write "VERBOSE default" |
|---|