updated on Sat Jan 14 00:11:12 UTC 2012
[aur-mirror.git] / crypt / cryptcfg
blob7871d536822e8149c09edb3fe68076d5d03172f5
1 #!/bin/bash
4 # cryptcfg by Jakub Schmidtke <sjakub@gmail.com>
6 # Based on netcfg script from Arch's initscripts 0.8-12 package.
9 # Version 0.3 - added LUKS support
12 . /etc/rc.conf
13 . /etc/rc.d/functions
15 CRYPTCFG_VER=0.3
16 PATH="/bin:/usr/bin:/sbin:/usr/sbin:$PATH"
18 PROFILE_DIR="/etc/crypt-profiles"
21 version()
23 echo "cryptcfg v$CRYPTCFG_VER"
26 usage()
28 version
29 echo
30 echo "usage: cryptcfg <profile_name>"
31 echo " crypcfg --stop <profile_name>"
32 echo " cryptcfg --menu"
33 echo " cryptcfg --stopall"
34 echo
35 echo "Crypt profiles are stored in $PROFILE_DIR"
36 echo
39 is_started_prof()
41 [ "$1" = "" ] && return 0
43 [ ! -f $PROFILE_DIR/$1 ] && return 0
45 unset DISK_DEVICE MAP_DEVICE
47 . $PROFILE_DIR/$1
49 [ "$DISK_DEVICE" = "" ] && return 0
51 [ ! -b $DISK_DEVICE ] && return 0
53 if [ "$CRYPT_METHOD" = "truecrypt" ]; then
55 MAP_DEVICE=$( truecrypt -l | grep $DISK_DEVICE"$" | cut -d' ' -f1 )
57 [ ${#MAP_DEVICE} -eq 0 ] && return 0
59 return 1
61 elif [ "$CRYPT_METHOD" = "luks" ]; then
63 [ "$MAP_ALIAS" = "" ] && return 0
65 CRYPT_STATUS=$( cryptsetup status $MAP_ALIAS | grep /dev/mapper | cut -d ' ' -f3 | cut -d '.' -f 1 | cut -d ':' -f1 )
67 [ "$CRYPT_STATUS" = "active" ] && return 1
69 return 0
72 return 0
75 stop_profile()
77 if [ "$1" = "" ]; then
78 echo "error: missing profile name"
79 exit 1
82 PROF=$1
84 is_started_prof $PROF
85 ret=$?
87 if [ "$ret" = "0" ]; then
88 echo "error: profile $PROF not started"
89 exit 1
92 unset DISK_DEVICE
93 unset MAP_ALIAS
94 unset CRYPT_METHOD
96 . $PROFILE_DIR/$PROF
98 if [ ! -b $DISK_DEVICE ]; then
99 echo "error: $PROF profile contains no valid DISK_DEVICE!"
100 exit 1
103 if [ "$CRYPT_METHOD" = "truecrypt" ]; then
105 stat_busy "Shutting down profile: $PROF"
107 truecrypt -d $DISK_DEVICE
109 if [ $? -ne 0 ] ; then
110 echo "error dismounting and/or unmapping $DISK_DEVICE volume"
111 exit 1
114 elif [ "$CRYPT_METHOD" = "luks" ]; then
115 if [ ! -b /dev/mapper/$MAP_ALIAS ]; then
116 echo "error: /dev/mapper/$MAP_ALIAS is not a valid block device!"
117 exit 1
120 stat_busy "Shutting down profile: $PROF"
122 # space after MAP_ALIAS is important!
123 MOUNT_STATUS=$( mount | grep "/dev/mapper/$MAP_ALIAS " )
125 if [ ! "$MOUNT_STATUS" = "" ]; then
126 stat_busy "umounting /dev/mapper/$MAP_ALIAS"
128 umount "/dev/mapper/$MAP_ALIAS"
130 if [ $? -ne 0 ]; then
131 echo "error umounting /dev/mapper/$MAP_ALIAS"
132 exit 1
135 cryptsetup luksClose $MAP_ALIAS
137 if [ $? -ne 0 ]; then
138 echo "error closing $MAP_ALIAS crypt device!"
139 exit 1
143 else
144 echo "error: $PROF profile contains no valid CRYPT_METHOD!"
145 exit 1
149 stop_all()
151 for i in /dev/mapper/truecrypt*; do
152 if [ -b "$i" ]; then
153 echo "Closing $i..."
154 truecrypt -d $i
156 done
158 for i in /dev/mapper/*; do
159 if [ ! "$i" = "/dev/mapper/control" ]; then
160 if [ -b "$i" ]; then
161 echo "Closing $i..."
162 umount $i
163 cryptsetup luksClose $i
166 done
168 exit 0
171 password_prompt()
173 if [ "$DISK_DEVICE" = "" ]; then
174 echo "error: missing DISK_DEVICE"
175 exit 1
178 if [ ! -b $DISK_DEVICE ]; then
179 echo "error: $DISK_DEVICE block device does not exist"
180 exit 1
183 if [ "$MOUNT_DIR" = "" ]; then
184 echo "error: missing MOUNT_DIR"
185 exit 1
188 if [ "$CRYPT_METHOD" = "" ]; then
189 echo "error: missing CRYPT_METHOD"
190 exit 1
193 if [ "$CRYPT_METHOD" = "luks" ]; then
194 if [ "$MAP_ALIAS" = "" ]; then
195 echo "error: missing MAP_ALIAS"
196 exit 1
200 D_PARAMS=""
202 [ "$NO_ASTERISKS" = "" -o "$NO_ASTERISKS" = "0" ] && D_PARAMS="--insecure"
204 RESULT=$( mktemp ) || exit 1
206 if [ "$CRYPT_METHOD" = "truecrypt" ]; then
207 dialog \
208 --stdout \
209 $D_PARAMS \
210 --passwordbox \
211 "Enter password for encrypted volume $DISK_DEVICE:\n\n$DESCRIPTION\n " \
212 12 60 | truecrypt $CRYPT_OPTIONS $DISK_DEVICE > $RESULT 2>&1
213 elif [ "$CRYPT_METHOD" = "luks" ]; then
214 dialog \
215 --stdout \
216 $D_PARAMS \
217 --passwordbox \
218 "Enter password for encrypted volume $DISK_DEVICE:\n\n$DESCRIPTION\n " \
219 12 60 | cryptsetup $CRYPT_OPTIONS luksOpen $DISK_DEVICE $MAP_ALIAS > $RESULT 2>&1
220 else
221 rm $RESULT
222 echo "error: Unknown CRYPT_METHOD ($CRYPT_METHOD)"
223 exit 1
226 rets=( ${PIPESTATUS[0]} ${PIPESTATUS[1]} )
228 ret_dlg=${rets[0]}
229 ret_tc=${rets[1]}
231 res=$( cat $RESULT )
232 rm $RESULT
234 # If user pressed 'ok'
235 if [ "$ret_dlg" = "0" ]; then
236 if [ ! "$ret_tc" = "0" ]; then
237 dialog --msgbox "$res" 10 60
238 # Abnormal return status - report it
239 return 1
242 # Everything fine
243 return 0
246 # Otherwise it was cancel, or ESC
247 return 2
250 start_profile()
252 if [ "$1" = "" ]; then
253 echo "error: missing profile name"
254 exit 1
257 if [ ! -f $PROFILE_DIR/$1 ]; then
258 echo "error: $PROFILE_DIR/$1 is missing"
259 exit 1
262 is_started_prof $1
263 ret=$?
265 if [ "$ret" = "1" ]; then
266 echo "error: $1 profile is already started"
267 exit 1
270 stat_busy "Starting crypt profile: $1"
272 # ead the profile
273 unset DESCRIPTION DISK_DEVICE MAP_DEVICE CRYPT_OPTIONS NO_ASTERISKS MOUNT_DIR CRYPT_METHOD MAP_ALIAS
275 . $PROFILE_DIR/$1
277 password_prompt
279 ret=$?
281 # Password prompt was canceled
282 [ "$ret" = "2" ] && return 2
284 # There was an error in password prompt
285 [ "$ret" = "1" ] && return 1
287 if [ "$CRYPT_METHOD" = "truecrypt" ]; then
289 MAP_DEVICE=$( truecrypt -l | grep $DISK_DEVICE"$" | cut -d' ' -f1 )
291 if [ ${#MAP_DEVICE} -eq 0 ]; then
292 echo "$DISK_DEVICE volume not opened"
293 exit 1;
296 mount $MAP_DEVICE $MOUNT_DIR
298 ret=$?
300 [ "$ret" = "0" ] && return 0
302 sleep 2
304 truecrypt -d $MAP_DEVICE
306 echo "error mounting $MAP_DEVICE device to $MOUNT_DIR"
308 exit 1
309 elif [ "$CRYPT_METHOD" = "luks" ]; then
311 if [ "$MAP_ALIAS" = "" ]; then
312 echo "error: Missing MAP_ALIAS";
313 exit 1
316 if [ ! -b "/dev/mapper/$MAP_ALIAS" ]; then
317 echo "/dev/mapper/$MAP_ALIAS is not a block device!"
318 exit 1
321 mount "/dev/mapper/$MAP_ALIAS" $MOUNT_DIR
323 ret=$?
325 [ "$ret" = "0" ] && return 0
327 sleep 2
329 cryptsetup luksClose $MAP_ALIAS
331 echo "error mounting /dev/mapper/$MAP_ALIAS device to $MOUNT_DIR"
333 exit 1
336 # Not really needed (as password_prompt should fail already), but for completness
337 echo "Unknown CRYPT_METHOD"
338 exit 1
341 menu()
343 if [ "`ls $PROFILE_DIR 2>/dev/null | grep -v ^template$`" = "" -o ! -d $PROFILE_DIR ]; then
344 echo "No profiles found. Add profiles to $PROFILE_DIR"
345 exit 1
348 # scan all profiles
349 unset profiles
350 DEFAULT=
352 for prof in $( ls $PROFILE_DIR ); do
353 # ignore the template
354 [ "$prof" = "template" ] && continue
356 # ignore already started profiles
357 is_started_prof $prof
358 ret=$?
360 [ "$ret" = "1" ] && continue
362 NAME=$prof
364 # if there's a profile called "main", use that as default
365 [ "$NAME" = "main" ] && DEFAULT=$NAME
367 unset DESCRIPTION
368 . $PROFILE_DIR/$NAME
370 if [ "$DESCRIPTION" ]; then
371 profiles[$i]=$NAME
372 i=$((i+1))
373 profiles[$i]=$DESCRIPTION
374 i=$((i+1))
376 done
378 # No profiles to be started left
379 if [ ${#profiles} -eq 0 ]; then
380 echo "All available profiles started"
381 exit 0
384 # if no default yet, use the first entry
385 [ "$DEFAULT" = "" ] && DEFAULT=${profiles[0]}
387 # profiles[2] is null - so we have only one profile left.
388 # Don't display list of profiles, just ask fo a password.
389 if [ "${profiles[2]}" = "" ]; then
390 start_profile $DEFAULT
391 ret=$?
393 # Since this is the last profile, we can exit the script
394 # if it was successfully opened, or the dialog was canceled.
396 # It was successful
397 [ "$ret" = "0" ] && exit 0
399 # It was canceled
400 [ "$ret" = "2" ] && exit 0
402 # Otherwise there was an error
404 return
407 ANSWER=`mktemp` || exit 1
409 dialog \
410 --output-fd 1 \
411 --default-item $DEFAULT \
412 --menu "Select the crypt profile you wish to use" \
413 13 50 6 \
414 "${profiles[@]}" >$ANSWER
415 ret=$?
417 ans=$( cat $ANSWER )
418 rm $ANSWER
420 case $ret in
421 1) exit 0 ;; # cancel
422 255) exit 0 ;; # ESC pressed (or timeout, but we don't use it)
423 0) start_profile $ans ;; # user selection
424 # abnormal
425 *) echo "abnormal ret code from dialog: $ret"; exit 1 ;;
426 esac
430 # Begin
433 if [ "`id -u`" != "0" ]; then
434 echo "This script should be run as root."
435 exit 1
438 /sbin/modprobe -q dm-mod 2>/dev/null
440 # Parse command line
441 MODE="profile"
442 PROFILE=
443 SPROF=
444 while [ $# -ne 0 ]; do
445 case $1 in
446 --version) MODE="ver" ;;
447 --help) MODE="usage" ;;
448 --menu) MODE="menu" ;;
449 --stopall) MODE="stopall" ;;
450 --stop) MODE="stop"
451 shift
452 SPROF=$1 ;;
453 --*) MODE="usage" ;;
454 -*) MODE="usage" ;;
455 *) PROFILE=$1 ;;
456 esac
457 shift
458 done
460 if [ "$MODE" = "profile" -a "$PROFILE" = "" ]; then
461 MODE="usage"
464 # Figure out what we're doing...
465 [ "$MODE" = "ver" ] && version
466 [ "$MODE" = "usage" ] && usage
467 [ "$MODE" = "stop" ] && stop_profile $SPROF
468 [ "$MODE" = "stopall" ] && stop_all
469 [ "$MODE" = "menu" ] && while true; do menu; done;
471 if [ "$MODE" = "profile" ]; then
472 start_profile $PROFILE
473 ret=$?
475 [ "$ret" = "0" ] && exit 0
476 [ "$ret" = "2" ] && exit 0
478 exit 1
481 exit 0