diff --git a/Makefile b/Makefile index 292abe9..e4edfb3 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ 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/* lxsh -o zpass -M --exclude-var "$(var_exclude)" --exclude-fct "$(fct_exclude)" src/main.sh diff --git a/src/archive.sh b/src/archive.sh index 844b5c1..1170258 100644 --- a/src/archive.sh +++ b/src/archive.sh @@ -26,7 +26,7 @@ pack() fi tar -cf - -- * | encrypt "$key" > "$1/$archive" || exit $? ) || return $? - if [ -n "$ZPASS_REMOTE_ADDR" ] + if [ -n "$remote_host" ] then ret=0 remote upload "$1/$archive" "$datapath/$ZPASS_FILE$ZPASS_EXTENSION" || ret=$? @@ -61,7 +61,7 @@ archive_exec() } # no argument -create() { +create_file() { if [ -f "$file" ] then tmpdir="$TMPDIR/zpass_$(randalnum 20)" @@ -70,8 +70,8 @@ create() { pack "$tmpdir" || { echo "Encryption error" >&2 && return 1 ; } rm -rf "$tmpdir" else - # if remote: file tmp - [ -n "$ZPASS_REMOTE_ADDR" ] && { + # if remote: file tmp and try to get file + [ -n "$remote_host" ] && { file="$TMPDIR/zpass_$(filehash)$ZPASS_EXTENSION" } # get key @@ -85,10 +85,10 @@ create() { rm "$file" return 1 } - [ -n "$ZPASS_REMOTE_ADDR" ] && { + # if is remote: create remote file + [ -n "$remote_host" ] && { ret=0 - ssh "$ZPASS_REMOTE_ADDR" "mkdir -p '$datapath'" - remote upload "$file" "$datapath/$ZPASS_FILE$ZPASS_EXTENSION" || ret=$? + remote create "$file" "$datapath/$ZPASS_FILE$ZPASS_EXTENSION" || ret=$? rm -rf "$file" 2>/dev/null return $ret } diff --git a/src/config.sh b/src/config.sh index bf17728..802ce43 100644 --- a/src/config.sh +++ b/src/config.sh @@ -6,7 +6,7 @@ cachepath="$HOME/.cache/zpass" configpath="$HOME/.config/zpass" [ -n "$XDG_CONFIG_HOME" ] && configpath="$XDG_CONFIG_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 @@ -23,16 +23,16 @@ env | grep '^ZPASS_.*=' | sed "s/'/'\\\''/g;s/=/='/;s/$/'/g" > "$tmpenv" rm -f "$tmpenv" 2>/dev/null # resolve zpass_path -[ -n "$ZPASS_PATH" ] && datapath="$ZPASS_PATH" -[ -n "$ZPASS_CACHE_PATH" ] && cachepath="$ZPASS_CACHE_PATH" +datapath=${ZPASS_PATH-$datapath} +cachepath=${ZPASS_CACHE_PATH-$cachepath} -# default ZPASS config -[ -z "$ZPASS_FILE" ] && ZPASS_FILE=default -[ -z "$ZPASS_EXTENSION" ] && ZPASS_EXTENSION=.tar.gpg -[ -z "$ZPASS_KEY_CACHE_TIME" ] && ZPASS_KEY_CACHE_TIME=60 # in seconds -[ -z "$ZPASS_CLIPBOARD_TIME" ] && ZPASS_CLIPBOARD_TIME=30 # in seconds -[ -z "$ZPASS_UNK_OP_CALL" ] && ZPASS_UNK_OP_CALL=copy -[ -z "$ZPASS_RAND_LEN" ] && ZPASS_RAND_LEN=20 +# default ZPASS +ZPASS_FILE=${ZPASS_FILE-default} +ZPASS_EXTENSION=${ZPASS_EXTENSION-.tar.gpg} +ZPASS_KEY_CACHE_TIME=${ZPASS_KEY_CACHE_TIME-60} +ZPASS_CLIPBOARD_TIME=${ZPASS_CLIPBOARD_TIME-30} +ZPASS_UNK_OP_CALL=${ZPASS_UNK_OP_CALL-copy} +ZPASS_RAND_LEN=${ZPASS_RAND_LEN-20} # datapath resolution # remove tildes @@ -44,5 +44,17 @@ datapath="${datapath#\~/}" file="$datapath/$ZPASS_FILE$ZPASS_EXTENSION" 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 diff --git a/src/crypt.sh b/src/crypt.sh index 0ad01cc..befb707 100644 --- a/src/crypt.sh +++ b/src/crypt.sh @@ -17,7 +17,7 @@ decrypt_with_key() decrypt() { # get remote file - [ -n "$ZPASS_REMOTE_ADDR" ] && { + [ -n "$remote_host" ] && { file="$TMPDIR/zpass_$(filehash)$ZPASS_EXTENSION" remote download "$datapath/$ZPASS_FILE$ZPASS_EXTENSION" "$file" >/dev/null || return $? } @@ -46,7 +46,7 @@ decrypt() fi # 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 ; } return $ret diff --git a/src/help.sh b/src/help.sh index b507701..ef09d59 100644 --- a/src/help.sh +++ b/src/help.sh @@ -36,11 +36,13 @@ usage() 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_UNK_OP_CALL 'copy' Operation to call on unrecognized first argument - ZPASS_RAND_LEN Length of random passwords generated by 'new' - ZPASS_REMOTE_METHOD 'scp' Method to use for remote file. scp/sftp/ftps + ZPASS_RAND_LEN '20' Length of random passwords generated by 'new' + ZPASS_REMOTE_METHOD 'scp' Method to use for remote file. scp/sftp/ftps/webdav ZPASS_REMOTE_ADDR Server the file is on ZPASS_REMOTE_PORT Server port 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 Unknown first argument will perform the operation described in 'ZPASS_UNK_OP_CALL' on that argument diff --git a/src/main.sh b/src/main.sh index 5d88d14..33319b6 100644 --- a/src/main.sh +++ b/src/main.sh @@ -21,7 +21,7 @@ case $arg in cc|cache-clear) clear_cache 2>/dev/null ;; ch|cached) get_key_cached >/dev/null ;; rmc|rm-cache) delete_cache 0 >/dev/null ;; - c|create) create ;; + c|create) create_file ;; t|tree) sanitize_paths "$@" && _tree "$@" ;; s|set) sanitize_paths "$1" && _set "$@" ;; f|file) sanitize_paths "$1" && fileset "$@" ;; diff --git a/src/remote.sh b/src/remote.sh index fa74322..35f687a 100644 --- a/src/remote.sh +++ b/src/remote.sh @@ -6,24 +6,22 @@ cond_gen() { # $@ = command ftps_cmd() { shift 3 - user=${ZPASS_REMOTE_ADDR%%@*} - host=${ZPASS_REMOTE_ADDR#*@} lftp << EOF set ftp:ssl-allow true ; set ssl:verify-certificate no ; set ftp:ssl-auth TLS -open ftp://$host$(cond_gen "$ZPASS_REMOTE_PORT" ":") -user $user $ZPASS_REMOTE_PASSWORD +open ftp://$remote_host$(cond_gen "$ZPASS_REMOTE_PORT" ":") +user $remote_user $ZPASS_REMOTE_PASSWORD $(cat) EOF } # $@ = args 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 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 @@ -34,7 +32,8 @@ ssh_cmd() { # $1 = protocol , $2 = local file , $3 = remote file upload() { 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 put "$2" "$3" EOF @@ -44,10 +43,12 @@ EOF # $1 = protocol, $2 = remote file , $3 = local file download() { 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 get "$2" "$3" EOF +;; esac } @@ -55,7 +56,8 @@ EOF list() { case $1 in scp) ssh_cmd "cd '$datapath' && ls -1" ;; - sftp|ftps) ${1}_cmd >/dev/null << EOF + webdav) webdav_list ;; + sftp|ftps) ${1}_cmd << EOF cd "$datapath" ls -1 EOF @@ -66,18 +68,31 @@ EOF delete() { case $1 in scp) ssh_cmd "rm '$2'" ;; + webdav) webdav_delete "$2" ;; sftp|ftps) ${1}_cmd >/dev/null << EOF rm "$2" EOF 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 remote() { action=$1 shift 1 case "${ZPASS_REMOTE_METHOD-scp}" in - scp|sftp|ftps) $action "${ZPASS_REMOTE_METHOD-scp}" "$@" ;; - *) echo "Unknown remote method: $ZPASS_REMOTE_METHOD" ;; + scp|sftp|ftps|webdav) $action "${ZPASS_REMOTE_METHOD-scp}" "$@" ;; + *) echo "Unknown remote method: $ZPASS_REMOTE_METHOD" >&2 ;; esac } diff --git a/src/webdav.sh b/src/webdav.sh new file mode 100644 index 0000000..b38a3af --- /dev/null +++ b/src/webdav.sh @@ -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 '' | cut -d'>' -f2 | cut -d'<' -f1 | sed "s|^/$datapath/||g" + + + + +EOF +} + +webdav_create() { + webdav_cmd "$datapath/" -X MKCOL + webdav_cmd "$2" -T "$1" +}