idmgr/lib/idmgr_mod_tomb.sh

319 lines
6.7 KiB
Bash

#!/bin/bash
IDM_MOD_DEPS="id gpg git"
IDM_MOD_TAGS="id tool"
IDM_MOD_PROG="safe yadm"
IDM_MOD_PREF="core id"
## Tomb functions
##########################################
# Install yadm
# git clone https://github.com/TheLocehiliosan/yadm.git ~/.usr/opt/yadm
#
# This allow to secure your things ....
#set -x
## Common functions
##############################
idm_tomb_help ()
{
local id=$1
idm_vars_git_tomb $id
echo "tomb"
echo " workflow:"
printf " %-20s: %s\n" "tomb ls" "Show tomb status"
printf " %-20s: %s\n" "tomb import <id> [<file>] " "Import a config"
printf " %-20s: %s\n" "tomb decrypt" "Decrypt the tomb"
printf " %-20s: %s\n" "tomb sync" "Synchronise tomb(s)"
printf " %-20s: %s\n" "tomb encrypt" "Save the current configuration into the tomb"
printf " %-20s: %s\n" "tomb leave" "Remove all traces of your passage"
echo " config:"
printf " %-20s: %s\n" "tomb_enc" "$tomb_enc"
printf " %-20s: %s\n" "git_dir" "$git_dir"
printf " %-20s: %s\n" "git_config" "$git_config"
return 0
}
idm_tomb_ls ()
{
local id=$1
idm_vars_git_tomb $id
echo " Info:"
printf " %-20s: %s\n" "opened" "yes"
printf " %-20s: %s\n" "last mod." "yes"
printf " %-20s: %s\n" "git" "$git_dir"
printf " %-20s: %s\n" "last date" ""
echo " Remotes:"
_git_local remote -v | sed 's/^/ /'
}
## Internal functions
##############################
idm_git__bin_git ()
{
if idm_validate id_config $1; then
id=${1} ;shift
fi
idm_vars_git_local $id
idm_git__bin ${*-}
}
# A wrapper before calling git
idm_tomb__bin_git ()
{
# Ugly bugfix :(
if idm_validate id_config $1; then
id=${1} ;shift
fi
idm_vars_git_tomb $id
idm_git__bin ${*-}
}
# Shortcuts
_git_local () { idm_git__bin_git ${*-}; }
_git_tomb () { idm_tomb__bin_git ${*-}; }
_load_local_env () { idm_vars_git_local ${*-}; }
_load_tomb_env () { idm_vars_git_tomb ${*-}; }
## Module functions
##############################
idm_vars_git_tomb()
{
var_id=git_tomb
id=${id:-$SHELL_ID}
git_work_tree=$HOME
git_dir=$IDM_DIR_CACHE/git/$id/tomb.git
git_config=${IDM_CONFIG_DIR}/git/$id/tomb_gitconfig
tomb_enc=$IDM_CONFIG_DIR/enc/$id.tomb
}
idm_tomb_init()
{
local id=$1
shift || true
# Sanity check
idm_validate id_config $id
local old_var_id=${var_id-}
# Check local repository state
_load_local_env
local local_git_dir=$git_dir
if ! idm_git__is_repo; then
idm_exit 1 NOTICE "You need to have a local repo first"
elif ! idm_git__has_commits ; then
idm_exit 1 NOTICE "You need to commit all your changes"
fi
# Load tomb environment from local
_load_tomb_env
if [ ! -d "$git_dir" ] ; then
mkdir -p "$git_dir"
_git_tomb clone --bare $local_git_dir $git_dir || \
idm_exit 1 "Could not create tomb repo"
idm_exit 0 NOTICE "Tomb repository has been created"
fi
idm_log INFO "Tomb repository alreay exists"
# Load tomb environment from encrypted_tomb
# Load tomb environment from user@server/encrypted.tomb
[ "$old_var_id" == "$var_id" ] || idm_vars_${old_var_id} ${id}
}
idm_tomb_sync ()
{
local id=$1
shift || true
# Sanity check
idm_validate id_config $id
# Load tomb config
_load_tomb_env
local repo_url=$git_dir
local repo_name=tomb
# Work on local
_git_local remote add $repo_name $repo_url || true
_git_local fetch --all
_git_local fetch --all --tags
_git_local push -u $repo_name --all
_git_local push -u $repo_name --tags
idm_log NOTICE "Tomb and local repository are now synced"
}
idm_tomb_encrypt ()
{
local id=$1
shift || true
local opt=${@-}
local TOFIX_opt=$opt
local old_var_id=${var_id-}
# Sanity check
idm_validate id_config $id
# We load LOCAL VARS HERE
_load_local_env
idm_git__has_commits || \
idm_exit 1 "You need to commit first"
idm_git__is_all_commited || \
idm_exit 1 "You need to clean your stuffs"
# Full sync both repo
idm_tomb_sync $id
# Encrypt data
idm_tomb__encrypt_dir $git_dir $tomb_enc || \
idm_exit 1 "Could not create tomb"
idm_log NOTICE "Tomb has been created: $tomb_enc"
}
## GPG functions
##############################
idm_tomb__decrypt_dir ()
{
local src=$1
local dst=${2-}
local key=${3-}
local gpg_opts=""
local tar_opts=
set -x
# Check required bin
idm_require_bin tar || idm_exit 1
idm_require_bin gpg2 || idm_exit 1
export GPG=${GPG2:-$GPG}
tar_opts=" -C ${dst%/*} -zx "
if [ ! -z "$key" ]; then
gpg_opts+="--batch -d"
else
gpg_opts+="-d"
fi
#set -x
$GPG $gpg_opts $src | $TAR $tar_opts || \
idm_exit 1 ERR "Could not decrypt file: $src into $dst"
}
idm_tomb__encrypt_dir ()
{
local src=$1
local dst=$2
local key=${3-}
local pass=
local recipients=
# Check required bin
idm_require_bin tar || idm_exit 1
idm_require_bin gpg2 || idm_exit 1
export GPG=${GPG2:-$GPG}
#GPG_KEY="$(yadm config yadm.gpg-recipient || true )"
#GPG_KEY="${GPG_DEFAULT_ID-}"
# Check pgp key and arguments
if idm_gpg__is_valid_key $key; then
shift 3
local ok=0 ko=0
recipients=${@:-${GPG_DEFAULT_ID-}}
gpg_opts="-e -r $recipients"
# Determine if we are looking for key or password
for r in $recipients; do
idm_gpg__is_valid_recipients $r &>/dev/null \
&& ok=$(( $ok + 1 ))\
|| ko=$(( $ko + 1 ))
if [[ "$ok" -ne 0 && "$ko" -ne 0 ]]; then
idm_exit 1 "One of the recipients is not known: $r in '$recipients'"
fi
done
# Act according our pattern
if [[ "$ok" -eq 0 && "$ko" -ne 0 ]]; then
pass="$@"
recipients=
gpg_opts="-c"
idm_log NOTICE "Secret will be encrypted with pass '$pass'"
else
idm_log NOTICE "Secret will be encrypted with key '$key' ${recipients:+ to '$recipients'}"
fi
else
if [ "$key" == "_ASK" ]; then
pass=_ASK
key=
gpg_opts="--no-default-recipient -e"
idm_log NOTICE "User will be prompted for known recipients"
elif [ -z "$key" -o "$key" == "_PASS" ]; then
pass=
key=
gpg_opts="-c"
idm_log NOTICE "User will be prompted for password (symetric)"
else
# Not available yet, see stdin for password input
# To fix: passwords in clear :/ use stdout3
pass="$key"
key=
gpg_opts="-c --passphrase $pass --batch "
idm_log NOTICE "Secret will be encrypted with pass '***' (symetric)"
fi
fi
#set -x
# Encrypt all the stuffs
$TAR -C "${src%/*}" -cz "${src##*/}" 2>/dev/null | \
$GPG -a $gpg_opts --yes -o $dst || \
idm_exit 1 ERR "Could not encrypt directory: $src"
# File descritor tests ...
#exec 3<> /tmp/foo
#>&3 echo "$pass"
#{ echo "$pass\n" >&3 ; $TAR -C "$(dirname $src)" -cz "$src" 2>/dev/null; } | \
#exec 3>&- #close fd 3.
}