3 # Purpose: Program to format, mount and unmount encrypted devices/files
4 # Authors: Michael Gebetsroither <gebi@grml.org>
5 # Bug-Reports: see http://grml.org/bugs/
6 # License: This file is licensed under the GPL v2.
7 # Latest change: Mon Aug 08 11:37:20 CEST 2005
8 ################################################################################
15 #. /etc/grml/sysexits-sh
24 DEV_MAPPER_="/dev/mapper"
25 CRYPTSETUP_="cryptsetup"
36 DM_PREFIX_="grml-crypt_"
38 OVERWRITE_SOURCE_DEV_='/dev/urandom'
39 OPTIMIZED_MODE_SET_='false'
42 CIPHER_="aes-cbc-essiv:sha256"
44 ADDITIONAL_CRYPTSETUP_ARGS_=""
46 ADDITIONAL_MOUNT_ARGS_=""
47 BATCH_MODE_="--batch-mode"
56 Usage: "$PROG_NAME__" [OPTIONS] action <device/file> [mountpoint]
58 $PROG_NAME__ is a wrapper arround cryptsetup with LUKS support to format a device
61 -s size of the loop-filesystem to create, in MB (default=$SIZE_)
62 -t type of filesystem (default=$FSTYPE_)
63 -r read only mode (fully supported only by start)
64 -z insecure mode, using /dev/zero for most of the initialisation (INSECURE!)
65 -o optimized initialisation mode (should be as secure as the default but faster)
66 -y verifies the passphrase by asking for it twice
67 -f force file overwriting in format mode and/or disable confirmation dialog
68 -m additional arguments to mount
69 -v verbose (show what is going on, v++)
72 CRYPTSETUP FORMAT OPTIONS:
73 -S cipher size, could be 128, 192 or 256 (default=$CIPHER_SIZE_)
74 -C cipher, should be aes-plain for pre-2.6.10 (default=$CIPHER_)
75 -I iteration time spend with PBKDF2 password processing in seconds (default=$ITERATION_TIME_)
76 -A additional arguments for cryptsetup (only supportet by format)
79 format <device/file> [mountpoint]
80 Format a device or a file (is created with the given size if it
81 does not exist) with the given filesystem and mount it, if a
83 start <device/file> <mountpoint>
84 Mount the device/file in the mountpoint.
86 Umount the given mountpoint (umount, luksClose, losetup -d)
96 # first trying normal devicename
97 tmp_="${DM_PREFIX_}${device_}"
98 if [ ! -e "$tmp_" ]; then
103 # second trying uuid of luks
104 #uuid_=`execute "$CRYPTSETUP_ luksUUID $1"`
105 #if [[ $? == 0 ]]; then
106 # echo "$prefix_$uuid_"
109 warn "could not create device-mapper name for $1"
114 function formatDevice
116 type_="$1" # could be donothing or init
119 args_="$VERIFY_PW_ $BATCH_MODE_ --key-size $CIPHER_SIZE_ --cipher $CIPHER_ --iter-time $ITERATION_TIME_ $ADDITIONAL_CRYPTSETUP_ARGS_"
120 #args_=`echo "$args_" |tr -s ' '`
121 execute "$CRYPTSETUP_ $args_ luksFormat $TARGET_" warn || return 1
123 execute "$CRYPTSETUP_ luksOpen $TARGET_ $DM_NAME_" warn \
124 "could not open $DM_PATH_ to create a filesystem on it!" || return 1
125 if [[ $type_ == 'init' && $OPTIMIZED_MODE_SET_ == 'true' ]]; then
126 echo "finishing optimized initialisation (this could take some time)"
128 execute "dd if=/dev/zero of=$DM_PATH_ bs=1M &>/dev/null" # || \
129 # warn "could not finish optimized initialisation properly"
131 # cutted out because of no space left on device error :(
132 #if [[ $ret_ != 0 ]]; then
133 # execute "$CRYPTSETUP_ luksClose $DM_NAME_" warn
138 execute "$MKFS_ $DM_PATH_ >/dev/null" warn
139 if [[ $? != 0 ]]; then
140 execute "$CRYPTSETUP_ luksClose $DM_NAME_"
141 warn "could not create filesystem on $DM_PATH_" 1
144 echo "Successully created $FSTYPE_ on encrypted $TARGET_"
154 # no mountpoint, by-by
155 if [[ "$MOUNT_POINT_" == "" ]]; then
157 die 'no mountpoint given'
159 if [ ! -d "$MOUNT_POINT_" ]; then
160 die "mountpoint $MOUNT_POINT_ does not exist"
162 # removed due to unionfs problem isLuks does not work with filesystem images
164 #$CRYPTSETUP_ isLuks $TARGET_ || die "$TARGET_ is not a luks partition"
166 # TARGET (is/should be) a filesystem image
167 if [ ! -b "$TARGET_" ]; then
168 notice "Operating on a file"
169 isExistent "$TARGET_" die "image does not exist"
170 TARGET_=`findNextFreeLoop` || die "could not find a free loop device"
172 # TARGET_ is now /dev/loop<x>
173 execute "losetup $TARGET_ $ORIG_TARGET_" die
176 $READONLY_SET_ && cargs_='--readonly'
177 execute "$CRYPTSETUP_ $cargs_ luksOpen $TARGET_ $DM_NAME_" warn || execute "losetup -d $TARGET_" || \
178 die "could not luksOpen $TARGET_"
180 $READONLY_SET_ && margs_='-r'
181 execute "mount $margs_ $ADDITIONAL_MOUNT_ARGS_ $DM_PATH_ $MOUNT_POINT_" die
190 isExistent "$mp_" die
191 tmp_=`realpath $mp_` || die "could not get realpath of $mp_"
192 dprint "realpath_=\"$tmp_\""
194 dm_path_=`mount |grep "$tmp_ "` || die "$tmp_ is not mounted"
195 dprint "dm_path_=\"$dm_path_\""
196 dm_path_=`echo $dm_path_ |awk '{print $1}'` || die "could not get devicemapper name for $tmp_"
197 dprint "dm_path_=\"$dm_path_\""
199 dm_name_="${dm_path_##*/}"
200 dprint "dm_name_=\"$dm_name_\""
202 dmsetup info $dm_name_ >/dev/null ||die "$dm_name_ is not aktive"
203 device_=`$CRYPTSETUP_ status $dm_name_ |awk '/device:/{print $2}'` || \
204 die "could not get underlying device of $dm_path_"
205 dprint "device_=\"$device_\""
207 execute "umount $dm_path_" die "could not unmount $device_"
208 execute "$CRYPTSETUP_ luksClose $dm_name_" die "could not close $dm_path_"
209 echo "$device_" |grep loop &>/dev/null && execute "losetup -d $device_" \
210 die "could not delete loop device $device_" || \
211 execute "losetup -d $device_ &>/dev/null" eprint "could not delete loop device $device_, \
212 this device could possible not be a loop device => maybe bogus error"
213 notice "$mp_ successfully unmountet/closed/deleted"
223 echo -n " (type uppercase yes): " >&2
225 if [[ $input == 'YES' ]]; then
232 function actionFormat
238 if (( $SIZE_ < 3 )); then
239 die "the minimum size of an encrypted luks partition should be 2"
242 # TARGET (is/should be) a filesystem image
243 if [ ! -b "$TARGET_" ]; then
244 notice "Operating on a file"
246 if [ -e "$TARGET_" ]; then
247 $FORCE_ || die "file $TARGET_ does allready exist"
248 warn "overwriting file $TARGET_"
251 echo -n "Initialising file with "
252 if [[ $OPTIMIZED_MODE_SET_ == 'true' ]]; then
253 echo "optimized SECURE mode"
254 execute "dd if=/dev/zero of=$TARGET_ bs=1M count=${SIZE_} &>/dev/null" \
255 die "could not initialise $TARGET_ with /dev/zero"
257 if [[ $OVERWRITE_SOURCE_DEV_ == '/dev/zero' ]]; then
258 echo "INSERCURE mode"
260 echo "SECURE mode (taking /dev/urandom as source, this could take some time)"
262 execute "dd if=$OVERWRITE_SOURCE_DEV_ of=$TARGET_ bs=1M count=${SIZE_} &>/dev/null" ||\
263 die "could not initialise $TARGET_ with $OVERWRITE_SOURCE_DEV_"
267 TARGET_=`findNextFreeLoop` || die "could not find a free loop device"
269 # TARGET_ is now /dev/loop<x>
270 execute "losetup $TARGET_ $ORIG_TARGET_" die
271 if [[ $OPTIMIZED_MODE_SET_ == 'true' || $OVERWRITE_SOURCE_DEV_ == '/dev/zero' ]]; then
272 execute "dd if=/dev/urandom of=$TARGET_ bs=1M count=2 &>/dev/null" \
273 die "could not initialise the fist 2MB of $TARGET_ with /dev/urandom"
275 formatDevice "$init_"
278 $FORCE_ || (yesDialog "Are you shure you want to overwrite $TARGET_ ?" || die 'You are not sure')
279 notice 'Operating on a device'
280 echo -n 'Initialising device with '
281 if [[ $OPTIMIZED_MODE_SET_ == 'true' ]]; then
282 echo "optimised SECURE mode"
283 execute "dd if=/dev/urandom of=$TARGET_ bs=1M count=2 &>/dev/null" ||\
284 die "could not initialise the first 2MB of $TARGET_ with /dev/urandom"
285 elif [[ $OVERWRITE_SOURCE_DEV_ != '/dev/zero' ]]; then
287 echo "SECURE mode (taking /dev/urandom as source, this could take some time)"
288 execute "dd if=/dev/urandom of=$TARGET_ bs=1M &>/dev/null" ||\
289 die "could not initialise $TARGET_ with /dev/zero"
291 echo 'INSECURE mode (only initialising the fist 2MB with /dev/urandom)'
292 execute "dd if=/dev/urandom of=$TARGET_ bs=1M count=2 &>/dev/null" \
293 die "could not initialise the first 2MB of $TARGET_ with /dev/urandom"
296 formatDevice "$init_"
300 # formatDevice was successfully
301 if (( $ret_ == 0 )); then
302 # a mountpoint was given (don't luksClose the device)
303 local mount_point_exists_='true'
304 test -d "$MOUNT_POINT_" || mount_point_exists_='false'
306 if [[ "$MOUNT_POINT_" != "" && "$mount_point_exists_" == 'true' ]]; then
307 $READONLY_SET_ && margs_='-r'
308 execute "mount $margs_ $ADDITIONAL_MOUNT_ARGS_ $DM_PATH_ $MOUNT_POINT_" die
310 $mount_point_exists_ || warn "mountpoint $MOUNT_POINT_ does not exist, not mounting. please use \"grml-crypt start $ORIG_TARGET_ <mountpoint>\" to start the device"
311 execute "$CRYPTSETUP_ luksClose $DM_NAME_" warn
312 $IS_IMAGE_ && execute "losetup -d $TARGET_" warn
315 $IS_IMAGE_ && execute "losetup -d $TARGET_" warn
325 while getopts "s:t:rzoyfm:hvS:C:I:A:" opt; do
327 s) SIZE_="$OPTARG"; SIZE_SET_='true' ;;
328 t) FSTYPE_="$OPTARG" ;;
329 r) READONLY_SET_='true' ;;
330 z) let OPTIMIZING_LEVEL_=$OPTIMIZING_LEVEL_+1
331 OVERWRITE_SOURCE_DEV_='/dev/zero'
332 warn 'initialising from INSECURE source /dev/zero' ;;
333 o) let OPTIMIZING_LEVEL_=$OPTIMIZING_LEVEL_+1
334 OPTIMIZED_MODE_SET_='true' ;;
335 y) VERIFY_PW_="--verify-passphrase" ;;
337 m) ADDITIONAL_MOUNT_ARGS_="$OPTARG" ;;
338 h) printUsage; exit ;;
339 v) let verbose_=$verbose_+1 ;;
340 S) CIPHER_SIZE_="$OPTARG" ;;
341 C) CIPHER_="$OPTARG" ;;
342 I) ITERATION_TIME_="$OPTARG" ;;
343 A) ADDITIONAL_CRYPTSETUP_ARGS_="$OPTARG" ;;
344 ?) printUsage; exit 64 ;;
347 shift $(($OPTIND - 1)) # set ARGV to the first not parsed commandline parameter
350 checkRoot die "You have to be root to use this program"
353 if [[ $1 == 'help' ]]; then
357 if (( $# < 2 )); then
359 die "wrong number of arguments ($#)" 1
361 if (( $OPTIMIZING_LEVEL_ > 1 )); then
363 die "please choose ONE initialisation methode"
367 MKFS_="/sbin/mkfs.$FSTYPE_"
368 if [ ! -x "$MKFS_" ]; then
369 die "invalid filesystem type \"$FSTYPE_\"" 1
372 # use batch-mode if available
373 $CRYPTSETUP_ $BATCH_MODE_ --help &>/dev/null;
376 0) dprint "your cryptsetup understands --batch-mode" ;;
377 1) BATCH_MODE_=""; notice "your cryptsetup does NOT understand --batch-mode, trying without" ;;
378 127) die "could not execute cryptsetup" 127 ;;
379 *) warn "problems executing $CRYPTSETUP_" $ret_
382 DM_NAME_="`getDMName $TARGET_`"
383 DM_PATH_="$DEV_MAPPER_/$DM_NAME_"
384 ORIG_TARGET_="$TARGET_"
388 format) ACTION_='format'; actionFormat ;;
389 start) ACTION_='start'; actionStart ;;
390 stop) ACTION_='stop'; actionStop "$TARGET_" ;;
395 ################################################################################
396 # vim:foldmethod=marker