From f7708feda1e91f5da6e8ca2797d7594ed2f3350f Mon Sep 17 00:00:00 2001 From: Laurent Ghigonis Date: Mon, 17 Jun 2013 20:08:58 +0200 Subject: jsaccess: WIP on a real file store --- jsaccess/store.sh | 225 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 191 insertions(+), 34 deletions(-) (limited to 'jsaccess/store.sh') diff --git a/jsaccess/store.sh b/jsaccess/store.sh index d730160..d797245 100755 --- a/jsaccess/store.sh +++ b/jsaccess/store.sh @@ -1,7 +1,7 @@ #!/bin/sh # jsaccess - private web file sharing using client side crypto -# store.sh: file encrytion script +# store.sh: file store manager for encrypting new files and deploy to server # Copyright (c) 2013 Laurent Ghigonis # @@ -17,18 +17,140 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +VERSION=0.2 + +usage_exit() { + echo "usage: store.sh [-v] [action] [action arguments...] [store]" + echo + echo "actions:" + echo " ls [store] # default action if no arguments" + echo " init " + echo " add [store] # default action if one argument" + echo " rm [store]" + echo " wipe " + echo " pull [store]" + echo " push [store]" + echo " rset [store]" + echo " help|-h" + echo " version|-V" + echo + echo "By default store is ./store/ or ./jsa/store/" + echo "Use \"unset HISTFILE; export JSA_PASS=mypass\" to avoid typing the passphrase" + echo "Use \"unset JSA_PASS\" to forget the passphrase" + exit 1 +} + cleanup() { rm -f $tmp umask $sumask exit 0 } -if [ $# -ne 1 ]; then - echo "usage: store.sh " - exit 1 -fi -clear_path=$1 -clear_name=`basename $clear_path` +_store_get() { + store="" + [[ -d ./jsa/store/ ]] && store="`readlink -f ./jsa/store/`" # priority 3 + [[ -d ./store/ ]] && store="`readlink -f ./store/`" # priority 2 + [[ X"$1" != X"" ]] && store=$1 # priority 1 + [[ -z $store ]] && echo "ERROR: store not found !" && \ + echo "Not specified as argument and local stores" \ + "./store/ or ./jsa/store/ not found" && exit 2 + echo "Using store $store" +} + +_pass_read() { + if [ X"$JSA_PASS" != X"" ]; then + pass=$JSA_PASS + else + echo "Enter encryption passphrase" + echo -n "> " + read pass + fi + enc_dir_hash=`echo -n $pass |openssl rmd160 |cut -d' ' -f2` + enc_path="$store/$enc_dir_hash" +} + +_index_decrypt() { + if [ -f $enc_path/index.txt ]; then + echo -n $pass |openssl enc -d -a -aes-256-cbc -in $enc_path/index.txt -out $tmp -pass stdin ||exit $? + else + echo > $tmp + fi +} + +_index_encrypt() { + rm -f $enc_path/index.txt + echo -n $pass |openssl enc -e -a -aes-256-cbc -in $tmp -out $enc_path/index.txt -pass stdin ||exit $? + echo "UPDATED $enc_path/index.txt" +} + +_file_add() { + # Path / name generation + clear_path=$1 + clear_name=`basename $clear_path` + enc_name=`echo -n ${enc_dir_hash}${clear_name} |openssl rmd160 |cut -d' ' -f2` + mkdir -p $enc_path + touch $enc_path/index.html + + # Encrypt + base64 -w0 $clear_path > $tmp + echo -n $pass |openssl enc -e -a -aes-256-cbc -in $tmp -out $enc_path/$enc_name -pass stdin ||exit $? + echo "CREATED $enc_path/$enc_name" +} + +_file_rm() { + pass # XXX +} + +_rset() { + pass # XXX +} + +_rget() { + pass # XXX +} + +action_ls() { + _pass_read + _index_decrypt + [ ! -f $enc_path/index.txt ] && \ + echo "Passphrase not used in store !" && exit 1 + echo "$enc_dir_hash/index.txt:" + cat $tmp +} + +action_add() { + _pass_read + _file_add $1 + _index_decrypt + echo $1 >> $tmp + _index_encrypt +} + +action_rm() { + _pass_read + _file_rm $1 + _index_decrypt + sed -i d/$1/ $tmp + _index_encrypt +} + +action_wipe() { + _rset $1 +} + +action_pull() { + _rget $1 + rsync $tmp . +} + +action_push() { + _rget $1 + rsync . $tmp +} + +action_rset() { + _rset $1 +} # Check for dependencies if [ X"`which base64`" == X"" \ @@ -43,30 +165,65 @@ umask 077 tmp=`mktemp ./jsaXXXXXXXX` trap cleanup INT TERM EXIT -# Read passphrase -echo -n "Enter encryption passphrase: " -read pass - -# Generate file/directory names -enc_dir_hash=`echo -n $pass |openssl rmd160 |cut -d' ' -f2` -enc_path="jsa/files/$enc_dir_hash" -enc_name=`echo -n ${enc_dir_hash}${clear_name} |openssl rmd160 |cut -d' ' -f2` -echo $enc_path -mkdir -p $enc_path -touch $enc_path/index.html - -# Encrypt file -base64 -w0 $clear_path > $tmp -echo -n $pass |openssl enc -e -a -aes-256-cbc -in $tmp -out $enc_path/$enc_name -pass stdin ||exit $? -echo "CREATED $enc_path/$enc_name" - -# Add to passphrase index -if [ -f $enc_path/index.txt ]; then - echo -n $pass |openssl enc -d -a -aes-256-cbc -in $enc_path/index.txt -out $tmp -pass stdin ||exit $? -else - echo > $tmp -fi -echo $clear_name >> $tmp -rm -f $enc_path/index.txt -echo -n $pass |openssl enc -e -a -aes-256-cbc -in $tmp -out $enc_path/index.txt -pass stdin ||exit $? -echo "UPDATED $enc_path/index.txt" +# Run action +case $1 in +ls) + [ $# -ne 1 -a $# -ne 2 ] && usage_exit + _store_get $2 + action_ls + ;; +init) + [ $# -ne 2 ] && usage_exit + _store_get $2 + action_init + ;; +add) + [ $# -ne 2 -a $# -ne 3 ] && usage_exit + _store_get $3 + action_add $2 + ;; +rm) + [ $# -ne 2 -a $# -ne 3 ] && usage_exit + _store_get $3 + action_rm $1 + ;; +wipe) + [ $# -ne 2 ] && usage_exit + _store_get $2 + action_wipe + ;; +pull) + [ $# -ne 1 -a $# -ne 2 ] && usage_exit + _store_get $2 + action_pull $1 + ;; +push) + [ $# -ne 1 -a $# -ne 2 ] && usage_exit + _store_get $2 + action_push $1 + ;; +rset) + [ $# -ne 2 -a $# -ne 3 ] && usage_exit + _store_get $3 + action_rset $1 + ;; +help|-h) + usage_exit + ;; +version|-V) + echo "v$VERSION" + usage_exit + ;; +"") + [ $# -ne 0 ] && usage_exit + _store_get + action_ls + ;; +*) + [ $# -ne 1 ] && usage_exit + _store_get $2 + action_add $1 +esac + +# cleanup() executed in trap + -- cgit v1.2.3-59-g8ed1b