File: usbcrypto.hotplug

package info (click to toggle)
cryptsetup 20050111-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 252 kB
  • ctags: 156
  • sloc: ansic: 1,305; sh: 675; makefile: 159
file content (188 lines) | stat: -rw-r--r-- 6,733 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/bin/bash
#
# 	/etc/hotplug.d/block/cryptostick.hotplug
#
#	description:
#	skript checks for certain USB-sticks plugged in, loads and reconstructs 
#	AES256 keys by xor and runs cryptsetup to setup a dm-crypt device to decrypt 
#	an encrypted raw partition. it automatically mounts the dm-crypt device.
#
# 	depends on: cryptsetup, procmail (lockfile), e2fsprogs
#
#	Author: Volker Sauer <vsauer@dvs1.informatik.tu-darmstadt.de>
# 	Version: 1.0
#	License: GPL
#
# Only use USB stick partition with the following ext2/3 UUID (leave empty to disable check):
FS_UUID="c3d9cb8e-1cb5-485c-9369-6404ec57b2c0"
#
CRYPTRAWVOL=/dev/loop0					# RAW volume to be decrypted
CRYPTVOLNAME=stuff						# name of decrypted volume (in /dev/mapper)
CRYPTVOLMNT=/export/stuff				# mountpoint the decrypted volume
STICKKEYDIR=/keys						# directory with the keys on the USB stick
HOSTKEYDIR=/etc/keys					# directory with host keys of this computer
CRYPTSETUP=/sbin/cryptsetup				# needed to setup dm-crypt (package cryptsetup)
MOUNT=/bin/mount						# just in case you have your own mount program...
RUN_EXPORTFS=no							# run "exportfs -r" after successfull mount? 
TUNE2FS=/sbin/tune2fs					# tune2fs needed to check for ext2/3 fs UUID (e2fsprogs)
LOCKFILE=/var/lock/cryptostick.hotplug	# lockfile for this script
LOCK_CMD=/usr/bin/lockfile				# lock programm from procmail (package procmail)

export DEBUG=yes

source /etc/hotplug/hotplug.functions

# devices need a little time to appear in /sys:
sleep 1

# Serialize script execution
$LOCK_CMD -sleeptime 2 -r 1 -locktimeout 5 $LOCKFILE

DEVICE=$(echo "${DEVPATH}" | awk -F\/ '{ print $3 }')
PARTITION=$(echo "${DEVPATH}" | awk -F\/ '{ print $4 }')
BUS=`ls -l /sys/block/$DEVICE/device|awk -F/ '{print $10}'`

myexit(){
	rm -f $LOCKFILE
	exit $1
}

# I only handle block device messages
if [ "$1" != "block" ]; then
	debug_mesg "I only handle block device messages. Exiting"
	myexit 0
fi
# I'm only interested in "add" events
if [ "$ACTION" != "add" ]; then
	debug_mesg "Got action $ACTION. Not interested in that. Exiting"
	myexit 0
fi
# I'm only interested in USB devices
if [ "$(echo $BUS|cut -b 1-3)" != "usb" ]; then
	debug_mesg "I only care about USB devices but not $DEVICE. Exititing"
	myexit 0
fi
# Check if RAW-Volume exists
if [ ! -b $CRYPTRAWVOL ]; then
	mesg "(RAW) Volume $CRYPTRAWVOL does not exist or is not a block device"
	myexit 1
fi
# Check if volume is already mounted
while read dev mntpath rest; do
	if [ "$mntpath" = "$CRYPTVOLMNT" ]; then
		debug_mesg "Volume $CRYPTVOLMNT is already mounted, exiting."
		myexit 0
	fi
done < /proc/self/mounts

# Check if dm-crypt is already setup
if [ -b /dev/mapper/$CRYPTVOLNAME ]; then
	mesg "/dev/mapper/$CRYPTVOLNAME already exists. Trying to mount...."
	$MOUNT /dev/mapper/$CRYPTVOLNAME $CRYPTVOLMNT
	if [ "$?" == "0" ]; then
		mesg "/dev/mapper/$CRYPTVOLNAME successfully mounted in $CRYPTVOLMNT"
		myexit 0
	else
		mesg "($?) could not mount /dev/mapper/$CRYPTVOLNAME. Exiting"
		myexit 0
	fi
fi

# Fetches the key from the partition/device and runs crypsetup
get_key_from_device(){
	# Check if fs uuid is wanted and correct
	if [ ! -z $FS_UUID ]; then
		debug_mesg "Checking UUID of /dev/$1"
		uid=`$TUNE2FS -l /dev/$1 2>/dev/null |grep "Filesystem UUID:"` || exit 1;
		uid=`echo $uid|awk '{print $3}'`
		debug_mesg "Found UUID: $uid on /dev/$1"
		if [ "$uid" != "$FS_UUID" ]; then
			mesg "Wrong filesystem UUID $uid found on /dev/$1. Exititing"
			myexit 1
		fi
	fi
	STICKMNT=`mktemp -d`|| exit 1				# where to (temporarily) mount usb stick 
	debug_mesg "Trying to get key from /dev/$1. Mounting at $STICKMNT"
	$MOUNT -o ro /dev/$1 $STICKMNT
	if [ "$?" != "0" ]; then
		debug_mesg "Unable to mount /dev/$1. Exiting"
		rmdir $STICKMNT || mesg "Unable to remove temporary mountpoint $STICKMNT"
		myexit 1
	fi
	if [ ! -d $STICKMNT/$STICKKEYDIR ]; then
		debug_mesg "Directory $STICKMNT/$STICKKEYDIR does not exist. Unmounting /dev/$1"
		umount $STICKMNT
		rmdir $STICKMNT || mesg "Unable to remove temporary mountpoint $STICKMNT"
		myexit 1
	fi
	HOSTNAME=`hostname`
	if [ ! -e $STICKMNT/$STICKKEYDIR/$HOSTNAME*.key ]; then
		debug_mesg "There is no key for $HOSTNAME in $STICKMNT/$STICKKEYDIR/. Unmounting $1"
		umount $STICKMNT
		rmdir $STICKMNT || mesg "Unable to remove temporary mountpoint $STICKMNT"
		myexit 1
	else
		COUNT=`ls $STICKMNT/$STICKKEYDIR/$HOSTNAME*.key|wc -w`
		if [ $COUNT -gt 1 ]; then
			mesg "I found $COUNT keys for $HOSTNAME on /dev/$1. Please provide only one key per host. Exiting"
			umount $STICKMNT
			rmdir $STICKMNT || mesg "Unable to remove temporary mountpoint $STICKMNT"
			myexit 1
		else
			KEYNAME=`ls $STICKMNT/$STICKKEYDIR/$HOSTNAME*.key`
			KEYNAME=`basename $KEYNAME`
			mesg "Using /dev/$1/keys/$KEYNAME as userkey"
			HOSTKEY=`echo $KEYNAME|cut -d. -f1`.host
			if [ ! -e $HOSTKEYDIR/$HOSTKEY ]; then
				mesg "Machtching hostkey $HOSTKEYDIR/$HOSTKEY. Exiting"
				rmdir $STICKMNT || mesg "Unable to remove temporary mountpoint $STICKMNT"
				myexit 1
			else 
				mesg "Using $HOSTKEYDIR/$HOSTKEY as hostkey"
			fi
			perl -e 'open(F2,@ARGV[0]) && open(F1,@ARGV[1]) or die "Usage: $0 <file1> <file2>\n"; print $buf1 ^ $buf2 while (read (F1,$buf1,65536) && read (F2,$buf2,65536));' -- $STICKMNT/$STICKKEYDIR/$KEYNAME $HOSTKEYDIR/$HOSTKEY | $CRYPTSETUP create $CRYPTVOLNAME $CRYPTRAWVOL
			if [ "$?" != "0" ]; then
				mesg "($?) cryptsetup failed. This should not happen"
				rmdir $STICKMNT || mesg "Unable to remove temporary mountpoint $STICKMNT"
				myexit 1
			fi

			debug_mesg "mount /dev/mapper/$CRYPTVOLNAME $CRYPTVOLMNT"
			$MOUNT /dev/mapper/$CRYPTVOLNAME $CRYPTVOLMNT
			if [ "$?" = "0" ]; then
				mesg "/dev/mapper/$CRYPTVOLNAME successfully mounted at $CRYPTVOLMNT"
				if [ "$RUN_EXPORTFS" == "yes" ]; then
					if [ -x /usr/sbin/exportfs ]; then
						debug_mesg "Running exportfs -r"
						/usr/sbin/exportfs -r
						if [ "$?" != "0" ]; then
							mesg "Could not run exportfs -r"
						fi
					else
						mesg "/usr/sbin/exportfs does not exist on this computer. Maybe it isn't an NFS-Server?"
					fi
				fi
			else
				mesg "($?) could not mount /dev/mapper/$CRYPTVOLNAME. Exiting"
				umount $STICKMNT
				rmdir $STICKMNT || mesg "Unable to remove temporary mountpoint $STICKMNT"
				mesg "Removing cryptsetup for $CRYPTVOLNAME"
				$CRYPTSETUP remove $CRYPTVOLNAME || mesg "done"
				myexit 1
			fi
			umount $STICKMNT
			rmdir $STICKMNT || mesg "Unable to remove temporary mountpoint $STICKMNT"
		fi
	fi
}

debug_mesg "Action: $ACTION of $DEVICE, partition: $PARTITION on bus $BUS"

if [ -z $PARTITION ]; then
#	debug_mesg "Trying block device $DEVICE *without* partition."
	get_key_from_device $DEVICE
else
	get_key_from_device $PARTITION
fi

rm -f $LOCKFILE