aboutsummaryrefslogblamecommitdiffstats
path: root/jsaccess/store.sh
blob: d797245254a74c93ea609246294e8c5323cd1b7f (plain) (tree)
1
2
3
4

         
                                                              
                                                                            














                                                                          






















                                                                                            




                     
 








































































































                                                                                                                     
 






                                                                           
                            




                          





























































                                              
#!/bin/sh

# jsaccess - private web file sharing using client side crypto
# store.sh: file store manager for encrypting new files and deploy to server

# Copyright (c) 2013 Laurent Ghigonis <laurent@gouloum.fr>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# 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                 <store>"
	echo "  add  <file_to_share> [store] # default action if one argument"
	echo "  rm   <file_in_store> [store]"
	echo "  wipe                 <store>"
	echo "  pull                 [store]"
	echo "  push                 [store]"
	echo "  rset <rsync_URI>     [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
}

_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"" \
	-o X"`which openssl`" == X"" ]; then
	echo "You need to have openssl and base64 available in your path !"
	exit 1
fi

# Initialize temporary stuff
sumask=$(umask)
umask 077
tmp=`mktemp ./jsaXXXXXXXX`
trap cleanup INT TERM EXIT

# 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