tomb

the crypto undertaker
git clone git://parazyd.org/tomb.git
Log | Files | Refs | README | LICENSE

commit b34d3795965beeb0a0f716b7b4b0a7a4c59e52cb
parent 1a6fd48def3ed490c5435bfdf4d5317a319479bd
Author: Jaromil <jaromil@dyne.org>
Date:   Mon, 14 Feb 2011 15:57:37 +0100

backup function using duplicity

working, but hairy since duplicity continues trying to connect
and password handling is not optimal

Diffstat:
Msrc/tomb | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/tomb-status.c | 2+-
2 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/src/tomb b/src/tomb @@ -840,6 +840,124 @@ exec_post_hooks() { fi } +get_arg_tomb() { +# set up variables to be used by caller: +# tombfile - filename without path +# tombdir - directory where the tomb is +# tombname - name of the tomb (filename without extension) +# the full path is made with $tombdir/$tombfile + if [ -z $1 ]; then + error "internal: get_arg_tomb called without argument" + return 1 + fi + + # make sure there is a .tomb extension + arg=${1%%\.*}.tomb + + if ! [ -r ${arg} ]; then + error "file not found: $arg" + return 1 + fi + + tombfile=`basename $arg` + tombdir=`dirname $arg` + + file ${tombdir}/${tombfile} | grep -i 'luks encrypted file' 2>&1 >/dev/null + if [ $? != 0 ]; then + error "$arg is not a valid tomb file, operation aborted" + tomb-notify "Not a tomb." "$arg doesn't seems a real tomb." + return 1 + fi + + tombname=${tombfile%%\.*} + return 0 +} + +backup_tomb() { # FIXME - duplicity asks passwords too often + # using duplicity + which duplicity > /dev/null + if [ $? != 0 ]; then + error "duplicity not found, can't operate backup" + return 1 + fi + if [ -z $CMD3 ]; then + error "backup command needs 2 arguments: tomb and destination url" + error "please refer to tomb(1) and duplicity(1) manuals for more information" + return 1 + fi + + # is it a tomb? + get_arg_tomb ${CMD2} + if [ $? != 0 ]; then + error "there is no tomb to backup, operation aborted." + return 1 + fi + + # is it a url? + echo "${CMD3}" | grep -i -e '^.*:\/\/.*' 2>&1 > /dev/null + if ! [ $? = 0 ]; then + error "second argument is not a valid duplicity url." + error "read the tomb(1) and duplicity(1) manual for more information" + return 1 + fi + bckurl=${CMD3} + + # is it ssh? + protocol="`expr substr $bckurl 1 3`" + act "backup over protocol $protocol" + if [ "$protocol" = "ssh" ]; then + act "ssh connection requires a password" + FTP_PASSWORD="`exec_as_user tomb askpass $bckurl`" + dupopts="--ssh-askpass" +# TODO verify ssh access before duplicity does +# since it blocks the thing retrying 5 times and such crap +# i.e. try ssh true to sshurl="`echo $bckurl | sed -e 's/ssh:\/\///'`" +# --no-print-statistics + fi + + # duplicity works only on directories + # so we create a directory in tmpfs and bind the tomb inside it + # during backup the encrypted tomb will be exposed + # TODO: check that the tomb is not mounted and, if mounted + # remount it read-only so it doesn't gets modified during bck + bckname=${tombname}.bck + mkdir -p /dev/shm/${bckname} + if [ $? != 0 ]; then + error "cannot generate a temporary backup directory in /dev/shm, operation aborted." + return 1 + fi + bcktmpdir=/dev/shm/${bckname} + # mmm, maybe we should mount our own tmpfs? we need root anyway for mount -o bind + # if we reach to eliminate this mount trick and upload only one file with duplicity + # then this function doesn't needs to be root to work. + touch ${bcktmpdir}/${tombfile} + mount -o bind ${tombdir}/${tombfile} ${bcktmpdir}/${tombfile} + bcklast=`exec_as_user duplicity \ + ${(s: :)dupopts} \ + collection-status ${bckurl} \ + | awk '/^Last full backup date:/ { print $5 }'` + # we detect if backup already exists or not so we can handle + # password prompt (choosing a password for full, inserting for incr) + if [ "$bcklast" = "none" ]; then + notice "Creating a backup of tomb $tombname on url $bckurl" + exec_as_user FTP_PASSWORD="$FTP_PASSWORD" duplicity ${(s: :)dupopts} \ + full ${bcktmpdir} ${bckurl} + else + notice "Updating a backup of tomb $tombname on url $bckurl" + exec_as_user FTP_PASSWORD="$FTP_PASSWORD" duplicity ${(s: :)dupopts} \ + incr ${bcktmpdir} ${bckurl} + fi + unset FTP_PASSWORD + if [ $? != 0 ]; then + error "duplicity reported error, operation aborted" + umount ${bcktmpdir}/${tombfile} + return 1 + fi + notice "Operation successful." + umount ${bcktmpdir}/${tombfile} + return 0 +} + umount_tomb() { if ! [ $1 ]; then @@ -1029,6 +1147,8 @@ case "$CMD" in bury) encode_key ${CMD2} ${CMD3} ;; exhume) decode_key ${CMD2} ;; + backup) check_priv ; backup_tomb ${CMD2} ${CMD3} ;; + install) check_priv ; install_tomb ;; askpass) ask_password $CMD2 $CMD3 ;; diff --git a/src/tomb-status.c b/src/tomb-status.c @@ -89,7 +89,7 @@ int main(int argc, char **argv) { // gtk_status_icon_set_name(status_tomb, "tomb"); gtk_status_icon_set_title(status_tomb, "Tomb"); - snprintf(tooltip,255,"Tomb in %s",mountpoint); + snprintf(tooltip,255,"%s",mountpoint); gtk_status_icon_set_tooltip_text (status_tomb, tooltip); // LEFT click menu