implement webdav method + fix remote create

This commit is contained in:
zawz 2021-08-03 19:22:47 +02:00
parent d79363b0a6
commit 4b4c398ee7
8 changed files with 90 additions and 35 deletions

View file

@ -1,6 +1,6 @@
var_exclude = ZPASS_.* XDG_.* REMOTE_.* DISPLAY CONFIGFILE TMPDIR DEBUG var_exclude = ZPASS_.* XDG_.* REMOTE_.* DISPLAY CONFIGFILE TMPDIR DEBUG
fct_exclude = _tty_on sftp_cmd ftps_cmd upload download list delete fct_exclude = _tty_on sftp_cmd ftps_cmd upload download list delete create
zpass: src/* zpass: src/*
lxsh -o zpass -M --exclude-var "$(var_exclude)" --exclude-fct "$(fct_exclude)" src/main.sh lxsh -o zpass -M --exclude-var "$(var_exclude)" --exclude-fct "$(fct_exclude)" src/main.sh

View file

@ -26,7 +26,7 @@ pack()
fi fi
tar -cf - -- * | encrypt "$key" > "$1/$archive" || exit $? tar -cf - -- * | encrypt "$key" > "$1/$archive" || exit $?
) || return $? ) || return $?
if [ -n "$ZPASS_REMOTE_ADDR" ] if [ -n "$remote_host" ]
then then
ret=0 ret=0
remote upload "$1/$archive" "$datapath/$ZPASS_FILE$ZPASS_EXTENSION" || ret=$? remote upload "$1/$archive" "$datapath/$ZPASS_FILE$ZPASS_EXTENSION" || ret=$?
@ -61,7 +61,7 @@ archive_exec()
} }
# no argument # no argument
create() { create_file() {
if [ -f "$file" ] if [ -f "$file" ]
then then
tmpdir="$TMPDIR/zpass_$(randalnum 20)" tmpdir="$TMPDIR/zpass_$(randalnum 20)"
@ -70,8 +70,8 @@ create() {
pack "$tmpdir" || { echo "Encryption error" >&2 && return 1 ; } pack "$tmpdir" || { echo "Encryption error" >&2 && return 1 ; }
rm -rf "$tmpdir" rm -rf "$tmpdir"
else else
# if remote: file tmp # if remote: file tmp and try to get file
[ -n "$ZPASS_REMOTE_ADDR" ] && { [ -n "$remote_host" ] && {
file="$TMPDIR/zpass_$(filehash)$ZPASS_EXTENSION" file="$TMPDIR/zpass_$(filehash)$ZPASS_EXTENSION"
} }
# get key # get key
@ -85,10 +85,10 @@ create() {
rm "$file" rm "$file"
return 1 return 1
} }
[ -n "$ZPASS_REMOTE_ADDR" ] && { # if is remote: create remote file
[ -n "$remote_host" ] && {
ret=0 ret=0
ssh "$ZPASS_REMOTE_ADDR" "mkdir -p '$datapath'" remote create "$file" "$datapath/$ZPASS_FILE$ZPASS_EXTENSION" || ret=$?
remote upload "$file" "$datapath/$ZPASS_FILE$ZPASS_EXTENSION" || ret=$?
rm -rf "$file" 2>/dev/null rm -rf "$file" 2>/dev/null
return $ret return $ret
} }

View file

@ -6,7 +6,7 @@ cachepath="$HOME/.cache/zpass"
configpath="$HOME/.config/zpass" configpath="$HOME/.config/zpass"
[ -n "$XDG_CONFIG_HOME" ] && configpath="$XDG_CONFIG_HOME/zpass" [ -n "$XDG_CONFIG_HOME" ] && configpath="$XDG_CONFIG_HOME/zpass"
[ -n "$XDG_CACHE_HOME" ] && cachepath="$XDG_CACHE_HOME/zpass" [ -n "$XDG_CACHE_HOME" ] && cachepath="$XDG_CACHE_HOME/zpass"
[ -z "$CONFIGFILE" ] && CONFIGFILE="$configpath/default.conf" CONFIGFILE=${CONFIGFILE-$configpath/default.conf}
[ -z "$TMPDIR" ] && TMPDIR=/tmp [ -z "$TMPDIR" ] && TMPDIR=/tmp
@ -23,16 +23,16 @@ env | grep '^ZPASS_.*=' | sed "s/'/'\\\''/g;s/=/='/;s/$/'/g" > "$tmpenv"
rm -f "$tmpenv" 2>/dev/null rm -f "$tmpenv" 2>/dev/null
# resolve zpass_path # resolve zpass_path
[ -n "$ZPASS_PATH" ] && datapath="$ZPASS_PATH" datapath=${ZPASS_PATH-$datapath}
[ -n "$ZPASS_CACHE_PATH" ] && cachepath="$ZPASS_CACHE_PATH" cachepath=${ZPASS_CACHE_PATH-$cachepath}
# default ZPASS config # default ZPASS
[ -z "$ZPASS_FILE" ] && ZPASS_FILE=default ZPASS_FILE=${ZPASS_FILE-default}
[ -z "$ZPASS_EXTENSION" ] && ZPASS_EXTENSION=.tar.gpg ZPASS_EXTENSION=${ZPASS_EXTENSION-.tar.gpg}
[ -z "$ZPASS_KEY_CACHE_TIME" ] && ZPASS_KEY_CACHE_TIME=60 # in seconds ZPASS_KEY_CACHE_TIME=${ZPASS_KEY_CACHE_TIME-60}
[ -z "$ZPASS_CLIPBOARD_TIME" ] && ZPASS_CLIPBOARD_TIME=30 # in seconds ZPASS_CLIPBOARD_TIME=${ZPASS_CLIPBOARD_TIME-30}
[ -z "$ZPASS_UNK_OP_CALL" ] && ZPASS_UNK_OP_CALL=copy ZPASS_UNK_OP_CALL=${ZPASS_UNK_OP_CALL-copy}
[ -z "$ZPASS_RAND_LEN" ] && ZPASS_RAND_LEN=20 ZPASS_RAND_LEN=${ZPASS_RAND_LEN-20}
# datapath resolution # datapath resolution
# remove tildes # remove tildes
@ -44,5 +44,17 @@ datapath="${datapath#\~/}"
file="$datapath/$ZPASS_FILE$ZPASS_EXTENSION" file="$datapath/$ZPASS_FILE$ZPASS_EXTENSION"
FILE=$file FILE=$file
[ -z "$ZPASS_REMOTE_ADDR" ] && { mkdir -p "$datapath" 2>/dev/null || error 1 "Could not create '$datapath'"; } ## Resolve remote
remote_user=$ZPASS_REMOTE_USER
# remote addr has @
if [ "${ZPASS_REMOTE_ADDR}" != "${ZPASS_REMOTE_ADDR##*@*}" ] ; then
remote_user=${ZPASS_REMOTE_ADDR%%@*}
remote_host=${ZPASS_REMOTE_ADDR#*@}
else
remote_host=$ZPASS_REMOTE_ADDR
fi
[ -z "$remote_host" ] && { mkdir -p "$datapath" 2>/dev/null || error 1 "Could not create '$datapath'"; }
mkdir -p "$cachepath" 2>/dev/null && chmod -R go-rwx "$cachepath" 2>/dev/null mkdir -p "$cachepath" 2>/dev/null && chmod -R go-rwx "$cachepath" 2>/dev/null

View file

@ -17,7 +17,7 @@ decrypt_with_key()
decrypt() decrypt()
{ {
# get remote file # get remote file
[ -n "$ZPASS_REMOTE_ADDR" ] && { [ -n "$remote_host" ] && {
file="$TMPDIR/zpass_$(filehash)$ZPASS_EXTENSION" file="$TMPDIR/zpass_$(filehash)$ZPASS_EXTENSION"
remote download "$datapath/$ZPASS_FILE$ZPASS_EXTENSION" "$file" >/dev/null || return $? remote download "$datapath/$ZPASS_FILE$ZPASS_EXTENSION" "$file" >/dev/null || return $?
} }
@ -46,7 +46,7 @@ decrypt()
fi fi
# remove temporary file # remove temporary file
[ -n "$ZPASS_REMOTE_ADDR" ] && rm -rf "$file" 2>/dev/null [ -n "$remote_host" ] && rm -rf "$file" 2>/dev/null
[ $ret -ne 0 ] && { echo "Could not decrypt '$file'" >&2 ; } [ $ret -ne 0 ] && { echo "Could not decrypt '$file'" >&2 ; }
return $ret return $ret

View file

@ -36,11 +36,13 @@ usage()
ZPASS_KEY_CACHE_TIME '60' Time a key stays in cache for decrypting, in seconds ZPASS_KEY_CACHE_TIME '60' Time a key stays in cache for decrypting, in seconds
ZPASS_CLIPBOARD_TIME '30' Time until clipboard gets cleared after copy, in seconds ZPASS_CLIPBOARD_TIME '30' Time until clipboard gets cleared after copy, in seconds
ZPASS_UNK_OP_CALL 'copy' Operation to call on unrecognized first argument ZPASS_UNK_OP_CALL 'copy' Operation to call on unrecognized first argument
ZPASS_RAND_LEN Length of random passwords generated by 'new' ZPASS_RAND_LEN '20' Length of random passwords generated by 'new'
ZPASS_REMOTE_METHOD 'scp' Method to use for remote file. scp/sftp/ftps ZPASS_REMOTE_METHOD 'scp' Method to use for remote file. scp/sftp/ftps/webdav
ZPASS_REMOTE_ADDR Server the file is on ZPASS_REMOTE_ADDR Server the file is on
ZPASS_REMOTE_PORT Server port ZPASS_REMOTE_PORT Server port
ZPASS_SSH_ID SSH private key to use for scp/sftp ZPASS_SSH_ID SSH private key to use for scp/sftp
ZPASS_REMOTE_USER User for login
ZPASS_REMOTE_PASSWORD Password for ftps/webdav login. Not for SSH
All operations can be shortened to their first char unless specified All operations can be shortened to their first char unless specified
Unknown first argument will perform the operation described in 'ZPASS_UNK_OP_CALL' on that argument Unknown first argument will perform the operation described in 'ZPASS_UNK_OP_CALL' on that argument

View file

@ -21,7 +21,7 @@ case $arg in
cc|cache-clear) clear_cache 2>/dev/null ;; cc|cache-clear) clear_cache 2>/dev/null ;;
ch|cached) get_key_cached >/dev/null ;; ch|cached) get_key_cached >/dev/null ;;
rmc|rm-cache) delete_cache 0 >/dev/null ;; rmc|rm-cache) delete_cache 0 >/dev/null ;;
c|create) create ;; c|create) create_file ;;
t|tree) sanitize_paths "$@" && _tree "$@" ;; t|tree) sanitize_paths "$@" && _tree "$@" ;;
s|set) sanitize_paths "$1" && _set "$@" ;; s|set) sanitize_paths "$1" && _set "$@" ;;
f|file) sanitize_paths "$1" && fileset "$@" ;; f|file) sanitize_paths "$1" && fileset "$@" ;;

View file

@ -6,24 +6,22 @@ cond_gen() {
# $@ = command # $@ = command
ftps_cmd() { ftps_cmd() {
shift 3 shift 3
user=${ZPASS_REMOTE_ADDR%%@*}
host=${ZPASS_REMOTE_ADDR#*@}
lftp << EOF lftp << EOF
set ftp:ssl-allow true ; set ssl:verify-certificate no ; set ftp:ssl-auth TLS set ftp:ssl-allow true ; set ssl:verify-certificate no ; set ftp:ssl-auth TLS
open ftp://$host$(cond_gen "$ZPASS_REMOTE_PORT" ":") open ftp://$remote_host$(cond_gen "$ZPASS_REMOTE_PORT" ":")
user $user $ZPASS_REMOTE_PASSWORD user $remote_user $ZPASS_REMOTE_PASSWORD
$(cat) $(cat)
EOF EOF
} }
# $@ = args # $@ = args
sftp_cmd() { sftp_cmd() {
{ sftp -b- $(cond_gen "$ZPASS_REMOTE_PORT" -P " ") $(cond_gen "$ZPASS_SSH_ID" -i " ") "$@" "$ZPASS_REMOTE_ADDR" || return $?; } | grep -v "^sftp>" || true { sftp -oStrictHostKeyChecking=no -b- $(cond_gen "$ZPASS_REMOTE_PORT" -P " ") $(cond_gen "$ZPASS_SSH_ID" -i " ") "$@" "${remote_user+${remote_user}@}$remote_host" || return $?; } | grep -v "^sftp>" || true
} }
# $@ args # $@ args
scp_cmd() { scp_cmd() {
scp $(cond_gen "$ZPASS_REMOTE_PORT" -P " ") $(cond_gen "$ZPASS_SSH_ID" -i " ") "$@" scp -oStrictHostKeyChecking=no -q $(cond_gen "$ZPASS_REMOTE_PORT" -P " ") $(cond_gen "$ZPASS_SSH_ID" -i " ") "$@"
} }
# $@ = args # $@ = args
@ -34,7 +32,8 @@ ssh_cmd() {
# $1 = protocol , $2 = local file , $3 = remote file # $1 = protocol , $2 = local file , $3 = remote file
upload() { upload() {
case $1 in case $1 in
scp) scp_cmd "$2" "$ZPASS_REMOTE_ADDR:$3" ;; scp) scp_cmd "$2" "${remote_user+${remote_user}@}$remote_host:$3" ;;
webdav) webdav_cmd "$3" -T "$2" ;;
sftp|ftps) "$1"_cmd >/dev/null << EOF sftp|ftps) "$1"_cmd >/dev/null << EOF
put "$2" "$3" put "$2" "$3"
EOF EOF
@ -44,10 +43,12 @@ EOF
# $1 = protocol, $2 = remote file , $3 = local file # $1 = protocol, $2 = remote file , $3 = local file
download() { download() {
case $1 in case $1 in
scp) scp_cmd "$ZPASS_REMOTE_ADDR:$2" "$3" ;; scp) scp_cmd "${remote_user+${remote_user}@}$remote_host:$2" "$3" ;;
webdav) webdav_cmd "$2" > "$3" ;;
sftp|ftps) ${1}_cmd >/dev/null << EOF sftp|ftps) ${1}_cmd >/dev/null << EOF
get "$2" "$3" get "$2" "$3"
EOF EOF
;;
esac esac
} }
@ -55,7 +56,8 @@ EOF
list() { list() {
case $1 in case $1 in
scp) ssh_cmd "cd '$datapath' && ls -1" ;; scp) ssh_cmd "cd '$datapath' && ls -1" ;;
sftp|ftps) ${1}_cmd >/dev/null << EOF webdav) webdav_list ;;
sftp|ftps) ${1}_cmd << EOF
cd "$datapath" cd "$datapath"
ls -1 ls -1
EOF EOF
@ -66,18 +68,31 @@ EOF
delete() { delete() {
case $1 in case $1 in
scp) ssh_cmd "rm '$2'" ;; scp) ssh_cmd "rm '$2'" ;;
webdav) webdav_delete "$2" ;;
sftp|ftps) ${1}_cmd >/dev/null << EOF sftp|ftps) ${1}_cmd >/dev/null << EOF
rm "$2" rm "$2"
EOF EOF
esac esac
} }
# $1 = protocol , $2 = local file , $3 = remote file
create() {
case $1 in
scp) ssh_cmd "mkdir -p '$(dirname "$3")' && cat > '$3'" < "$2" ;;
webdav) webdav_create "$2" "$3" ;;
sftp|ftps) ${1}_cmd >/dev/null << EOF
mkdir "$datapath"
put "$2" "$3"
EOF
esac
}
# $1 = action , $@ = arguments # $1 = action , $@ = arguments
remote() { remote() {
action=$1 action=$1
shift 1 shift 1
case "${ZPASS_REMOTE_METHOD-scp}" in case "${ZPASS_REMOTE_METHOD-scp}" in
scp|sftp|ftps) $action "${ZPASS_REMOTE_METHOD-scp}" "$@" ;; scp|sftp|ftps|webdav) $action "${ZPASS_REMOTE_METHOD-scp}" "$@" ;;
*) echo "Unknown remote method: $ZPASS_REMOTE_METHOD" ;; *) echo "Unknown remote method: $ZPASS_REMOTE_METHOD" >&2 ;;
esac esac
} }

26
src/webdav.sh Normal file
View file

@ -0,0 +1,26 @@
#!/bin/sh
webdav_folder_url() {
echo "https://$remote_host${ZPASS_REMOTE_PORT+:$ZPASS_REMOTE_PORT}/"
}
# $1 = url complement , $@ = curl args
webdav_cmd() {
complement=$1
shift 1
curl -f -s --digest --user $remote_user:$ZPASS_REMOTE_PASSWORD "$@" "$(webdav_folder_url)$complement"
}
webdav_list() {
webdav_cmd "$datapath/" -X PROPFIND --upload-file - -H "Depth: 1" << EOF | grep '<D:href>' | cut -d'>' -f2 | cut -d'<' -f1 | sed "s|^/$datapath/||g"
<?xml version="1.0"?>
<a:propfind xmlns:a="DAV:">
<a:prop><a:resourcetype/></a:prop>
</a:propfind>
EOF
}
webdav_create() {
webdav_cmd "$datapath/" -X MKCOL
webdav_cmd "$2" -T "$1"
}