RSS Feed

tcplay script

Posted on

Recently, when I was using TrueCrypt in Arch Linux to mount a truecrypt container file, it was very slow to mount the container. Furthermore, I also read that the TrueCrypt is discontinued.

Therefore, I decided to use the tcplay. However, it is a command-line. Arch Linux wiki page shows a good tutorial on how to use tcplay.

When using tcplay in Linux, unlike mounting the folder like encfs, tcplay requires losetup for loop device. Thus, it involves 3 steps to mount a truecrypt container: i) setup loop device, ii) setup device-mapper with tcplay, and iii) mount. Consequently, to unmount the truecrypt containter need to reverse these 3 steps.

In order to make my life easier, I wrote a simple script as following. Feel free to modify it.

# @author Allen Choong
# @date    2014-06-29
# @version    1.0.1
#
# Easy mount the truecrypt encryptinog by using tcplay.
# Assuming the truecrypt mounting name does not have whitespace.
#
# Changelog:
# 2014-06-29    1.0.1    Add display help if there is no argument
# 2014-06-02    1.0    Initial

tc_mount() {
  lo=`losetup -f`
  losetup "$lo" "$1"
  tcplay -m "`basename "$1"`" -d "$lo"
  mount "/dev/mapper/`basename "$1"`" "$2"
}

tc_unmount() {
  echo -en "Unmount ... "
  umount "/dev/mapper/$1"
  lo=`losetup -l | grep "$1" | cut -d ' ' -f 1`
  dmsetup remove "$1"
  losetup -d "$lo"
  echo "OK!"
}

mklist() {
  start="$1"
  num="$2"
  ret="$1"
  for ((i=1;$i<=$num;i++)) ; do
    ret+=$(echo " `expr $start + $i`")
  done
  echo $ret
}

show_mount() {
  mount|grep '/dev/mapper' |while read l ; do num=`echo "$l" | tr ' ' '\n' | wc -l`;
    cutnum=$(mklist 3 `expr $num - 6`)
    echo "$l" | cut -d ' ' -f "1 $cutnum" | sed -e 's/\s/ => /'
  done
}

#Get arguments
for ((i=0;i<=$#;i++)) ; do
  args[$i]=${!i}
done

action="mount"

#Print help
if [ $# == "0" ] ; then
  echo "This command requires root privilege."
  echo "Usage:"
  echo "`basename $0` TRUECRYPT_CONTAINER MOUNT_POINT"
  echo ""
  echo "To list the mounted container:"
  echo "`basename $0` -l"
  echo ""
  echo "To unmount (requires root):"
  echo "`basename $0` -u CONTAINER_FILENAME"
  echo "where CONTAINER_FILENAME is the device mapper name"
  echo ""
  exit
fi

for ((i=1;i<=$#;i++)) ; do
  case ${args[$i]} in
    -l)
      show_mount
      exit
      ;;
    -u)
      unmnt=`echo ${args[$i+1]}`
      action="unmount"
      ;;
    esac
done

if [[ "$action" == "mount" ]] ; then
  tc_mount "$1" "$2"
elif [[ "$action" == "unmount" ]] ; then
  tc_unmount "$unmnt"
fi

Update (2014-06-29):
In order to use this script, if you have a file called foobar.tc (already make file system),

sudo tcplay.sh foobar.tc /path/to/mnt

After this, you can list the mounted point as,

tcplay.sh -l

To unmount the container,

sudo tcplay.sh -u foobar.tc #where the foobar.tc is the device mapper name, not the path to the file

About Allen Choong

A cognitive science student, a programmer, a philosopher, a Catholic.

2 responses »

  1. Great script!

    for me to work, i had to change the following syntax:

    lo=`losetup -l | grep “$1” | cut -d ‘ ‘ -f 1`

    should be

    lo=`losetup -a | grep “$1” | cut -d ‘:’ -f 1`

    Reply
  2. Works after a reboot only first time. No instructions on how to close. attempting to run script second time always receive errors like:

    device-mapper: create ioctl on xxxx.xxx.1 failed: Device or resource busy
    dm_task_run failed
    Could not set up mapping my_encrypted_file
    mount: mount point does not exist

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: