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 around 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)
92 losetup does _NOT_ work on unionfs => grml-crypt with a filesystem image does ONLY
93 work if the image is on a tmpfs (eg. in /home/grml or /tmp).
104 # first trying normal devicename
105 tmp_="${DM_PREFIX_}${device_}"
106 if [ ! -e "$tmp_" ]; then
111 # second trying uuid of luks
112 #uuid_=`execute "$CRYPTSETUP_ luksUUID $1"`
113 #if [[ $? == 0 ]]; then
114 # echo "$prefix_$uuid_"
117 warn "could not create device-mapper name for $1"
122 function formatDevice
124 type_="$1" # could be donothing or init
127 args_="$VERIFY_PW_ $BATCH_MODE_ --key-size $CIPHER_SIZE_ --cipher $CIPHER_ --iter-time $ITERATION_TIME_ $ADDITIONAL_CRYPTSETUP_ARGS_"
128 #args_=`echo "$args_" |tr -s ' '`
129 execute "$CRYPTSETUP_ $args_ luksFormat $TARGET_" warn || return 1
131 execute "$CRYPTSETUP_ luksOpen $TARGET_ $DM_NAME_" warn \
132 "could not open $DM_PATH_ to create a filesystem on it!" || return 1
133 if [[ $type_ == 'init' && $OPTIMIZED_MODE_SET_ == 'true' ]]; then
134 echo "finishing optimized initialisation (this could take some time)"
136 execute "dd if=/dev/zero of=$DM_PATH_ bs=1M &>/dev/null" # || \
137 # warn "could not finish optimized initialisation properly"
139 # cutted out because of no space left on device error :(
140 #if [[ $ret_ != 0 ]]; then
141 # execute "$CRYPTSETUP_ luksClose $DM_NAME_" warn
146 execute "$MKFS_ $DM_PATH_ >/dev/null" warn
147 if [[ $? != 0 ]]; then
148 execute "$CRYPTSETUP_ luksClose $DM_NAME_"
149 warn "could not create filesystem on $DM_PATH_" 1
152 echo "Successully created $FSTYPE_ on encrypted $TARGET_"
162 # no mountpoint, by-by
163 if [[ "$MOUNT_POINT_" == "" ]]; then
165 die 'no mountpoint given'
167 if [ ! -d "$MOUNT_POINT_" ]; then
168 die "mountpoint $MOUNT_POINT_ does not exist"
170 # removed due to unionfs problem isLuks does not work with filesystem images
172 #$CRYPTSETUP_ isLuks $TARGET_ || die "$TARGET_ is not a luks partition"
174 # TARGET (is/should be) a filesystem image
175 if [ ! -b "$TARGET_" ]; then
176 notice "Operating on a file"
177 isExistent "$TARGET_" die "image does not exist"
178 TARGET_=`findNextFreeLoop` || die "could not find a free loop device"
180 # TARGET_ is now /dev/loop<x>
181 execute "losetup $TARGET_ $ORIG_TARGET_" die
184 $READONLY_SET_ && cargs_='--readonly'
185 execute "$CRYPTSETUP_ $cargs_ luksOpen $TARGET_ $DM_NAME_" warn || execute "losetup -d $TARGET_" || \
186 die "could not luksOpen $TARGET_"
188 $READONLY_SET_ && margs_='-r'
189 execute "mount $margs_ $ADDITIONAL_MOUNT_ARGS_ $DM_PATH_ $MOUNT_POINT_" die
198 isExistent "$mp_" die
199 tmp_=`realpath $mp_` || die "could not get realpath of $mp_"
200 dprint "realpath_=\"$tmp_\""
202 dm_path_=`mount |grep "$tmp_ "` || die "$tmp_ is not mounted"
203 dprint "dm_path_=\"$dm_path_\""
204 dm_path_=`echo $dm_path_ |awk '{print $1}'` || die "could not get devicemapper name for $tmp_"
205 dprint "dm_path_=\"$dm_path_\""
207 dm_name_="${dm_path_##*/}"
208 dprint "dm_name_=\"$dm_name_\""
210 dmsetup info $dm_name_ >/dev/null ||die "$dm_name_ is not aktive"
211 device_=`$CRYPTSETUP_ status $dm_name_ |awk '/device:/{print $2}'` || \
212 die "could not get underlying device of $dm_path_"
213 dprint "device_=\"$device_\""
215 execute "umount $dm_path_" die "could not unmount $device_"
216 execute "$CRYPTSETUP_ luksClose $dm_name_" die "could not close $dm_path_"
217 echo "$device_" |grep loop &>/dev/null && execute "losetup -d $device_" \
218 die "could not delete loop device $device_" || \
219 execute "losetup -d $device_ &>/dev/null" eprint "could not delete loop device $device_, \
220 this device could possible not be a loop device => maybe bogus error"
221 notice "$mp_ successfully unmountet/closed/deleted"
231 echo -n " (type uppercase yes): " >&2
233 if [[ $input == 'YES' ]]; then
240 function actionFormat
246 if (( $SIZE_ < 3 )); then
247 die "the minimum size of an encrypted luks partition should be 2"
250 # TARGET (is/should be) a filesystem image
251 if [ ! -b "$TARGET_" ]; then
252 notice "Operating on a file"
254 if [ -e "$TARGET_" ]; then
255 $FORCE_ || die "$TARGET_ does already exist"
256 warn "overwriting file $TARGET_"
259 echo -n "Initialising file with "
260 if [[ $OPTIMIZED_MODE_SET_ == 'true' ]]; then
261 echo "optimized SECURE mode"
262 execute "dd if=/dev/zero of=$TARGET_ bs=1M count=${SIZE_} &>/dev/null" \
263 die "could not initialise $TARGET_ with /dev/zero"
265 if [[ $OVERWRITE_SOURCE_DEV_ == '/dev/zero' ]]; then
266 echo "INSERCURE mode"
268 echo "SECURE mode (taking /dev/urandom as source, this could take some time)"
270 execute "dd if=$OVERWRITE_SOURCE_DEV_ of=$TARGET_ bs=1M count=${SIZE_} &>/dev/null" ||\
271 die "could not initialise $TARGET_ with $OVERWRITE_SOURCE_DEV_"
275 TARGET_=`findNextFreeLoop` || die "could not find a free loop device"
277 # TARGET_ is now /dev/loop<x>
278 execute "losetup $TARGET_ $ORIG_TARGET_" die
279 if [[ $OPTIMIZED_MODE_SET_ == 'true' || $OVERWRITE_SOURCE_DEV_ == '/dev/zero' ]]; then
280 execute "dd if=/dev/urandom of=$TARGET_ bs=1M count=2 &>/dev/null" \
281 die "could not initialise the fist 2MB of $TARGET_ with /dev/urandom"
283 formatDevice "$init_"
286 $FORCE_ || (yesDialog "Are you shure you want to overwrite $TARGET_ ?" || die 'You are not sure')
287 notice 'Operating on a device'
288 echo -n 'Initialising device with '
289 if [[ $OPTIMIZED_MODE_SET_ == 'true' ]]; then
290 echo "optimised SECURE mode"
291 execute "dd if=/dev/urandom of=$TARGET_ bs=1M count=2 &>/dev/null" ||\
292 die "could not initialise the first 2MB of $TARGET_ with /dev/urandom"
293 elif [[ $OVERWRITE_SOURCE_DEV_ != '/dev/zero' ]]; then
295 echo "SECURE mode (taking $OVERWRITE_SOURCE_DEV_ as source, this could take some time)"
296 execute "dd if=$OVERWRITE_SOURCE_DEV_ of=$TARGET_ bs=1M &>/dev/null" #||\
297 # skipped because "no space left on device" from dd
298 # die "could not initialise $TARGET_ with $OVERWRITE_SOURCE_DEV_"
300 echo 'INSECURE mode (only initialising the fist 2MB with /dev/urandom)'
301 execute "dd if=/dev/urandom of=$TARGET_ bs=1M count=2 &>/dev/null" \
302 die "could not initialise the first 2MB of $TARGET_ with /dev/urandom"
305 formatDevice "$init_"
309 # formatDevice was successfully
310 if (( $ret_ == 0 )); then
311 # a mountpoint was given (don't luksClose the device)
312 local mount_point_exists_='true'
313 test -d "$MOUNT_POINT_" || mount_point_exists_='false'
315 if [[ $MOUNT_POINT_ != "" && "$mount_point_exists_" == 'true' ]]; then
316 $READONLY_SET_ && margs_='-r'
317 execute "mount $margs_ $ADDITIONAL_MOUNT_ARGS_ $DM_PATH_ $MOUNT_POINT_" die
319 if [[ $MOUNT_POINT_ != "" ]]; then
320 $mount_point_exists_ || warn "mountpoint $MOUNT_POINT_ does not exist, not mounting. please use \"grml-crypt start $ORIG_TARGET_ <mountpoint>\" to start the device"
322 execute "$CRYPTSETUP_ luksClose $DM_NAME_" warn
323 $IS_IMAGE_ && execute "losetup -d $TARGET_" warn
326 execute "$CRYPTSETUP_ luksClose $DM_NAME_" warn
327 $IS_IMAGE_ && execute "losetup -d $TARGET_" warn
337 while getopts "s:t:rzoyfm:hvS:C:I:A:" opt; do
339 s) SIZE_="$OPTARG"; SIZE_SET_='true' ;;
340 t) FSTYPE_="$OPTARG" ;;
341 r) READONLY_SET_='true' ;;
342 z) let OPTIMIZING_LEVEL_=$OPTIMIZING_LEVEL_+1
343 OVERWRITE_SOURCE_DEV_='/dev/zero'
344 warn 'initialising from INSECURE source /dev/zero' ;;
345 o) let OPTIMIZING_LEVEL_=$OPTIMIZING_LEVEL_+1
346 OPTIMIZED_MODE_SET_='true' ;;
347 y) VERIFY_PW_="--verify-passphrase" ;;
349 m) ADDITIONAL_MOUNT_ARGS_="$OPTARG" ;;
350 h) printUsage; exit ;;
351 v) let verbose_=$verbose_+1 ;;
352 S) CIPHER_SIZE_="$OPTARG" ;;
353 C) CIPHER_="$OPTARG" ;;
354 I) ITERATION_TIME_="$OPTARG" ;;
355 A) ADDITIONAL_CRYPTSETUP_ARGS_="$OPTARG" ;;
356 ?) printUsage; exit 64 ;;
359 shift $(($OPTIND - 1)) # set ARGV to the first not parsed commandline parameter
362 checkRoot die "You have to be root to use this program"
365 if [[ $1 == 'help' ]]; then
369 if (( $# < 2 )); then
371 die "wrong number of arguments ($#)" 1
373 if (( $OPTIMIZING_LEVEL_ > 1 )); then
375 die "please choose ONE initialisation methode"
379 MKFS_="/sbin/mkfs.$FSTYPE_"
380 if [ ! -x "$MKFS_" ]; then
381 die "invalid filesystem type \"$FSTYPE_\"" 1
384 # use batch-mode if available
385 $CRYPTSETUP_ $BATCH_MODE_ --help &>/dev/null;
388 0) dprint "your cryptsetup understands --batch-mode" ;;
389 1) BATCH_MODE_=""; notice "your cryptsetup does NOT understand --batch-mode, trying without" ;;
390 127) die "could not execute cryptsetup" 127 ;;
391 *) warn "problems executing $CRYPTSETUP_" $ret_
394 DM_NAME_="`getDMName $TARGET_`"
395 DM_PATH_="$DEV_MAPPER_/$DM_NAME_"
396 ORIG_TARGET_="$TARGET_"
400 format) ACTION_='format'; actionFormat ;;
401 start) ACTION_='start'; actionStart ;;
402 stop) ACTION_='stop'; actionStop "$TARGET_" ;;
407 ################################################################################
408 # vim:foldmethod=marker tabstop=2 expandtab shiftwidth=2