dev: clean ssh, separate tomb from git
This commit is contained in:
parent
cc6e4d7318
commit
2c3ccab6ad
47
bin/idmgr
47
bin/idmgr
@ -154,6 +154,12 @@ idm_log ()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# export PS4='+[${SECONDS}s][${BASH_SOURCE}:${LINENO}]: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'; set -x;
|
||||||
|
# export PS4='.[${SECONDS}s] \[\e[36m\] ${FUNCNAME[0]:+${FUNCNAME[0]}()[${LINENO}]: }\[\e[m\]'; set -x;
|
||||||
|
# export PS4='. $( f="${FUNCNAME[0]:+${FUNCNAME[0]//}}"; printf "%10s:%00d %00d %10s| " ${BASH_SOURCE#$HOME/} ${LINENO} ${SECONDS} "$f")' ; set -x;
|
||||||
|
# export PS4='. $(f="${FUNCNAME[0]:+${FUNCNAME[0]//}}"; s=${BASH_SOURCE#$HOME/}; l=${LINENO}; t=${SECONDS}; printf "%00d %0d %16.50s() " $l $t "$f")' ; set -x;
|
||||||
|
# export PS4=' \[\e[36m\]> $(f="${FUNCNAME[0]:+${FUNCNAME[0]//}}"; s=${BASH_SOURCE#$HOME/}; l=${LINENO}; t=${SECONDS}; printf "%00d %0d %s():" $l $t "$f")\[\e[m\]\n' ; set -x;
|
||||||
|
#export LOG="idm_log_wrap \$FUNCNAME "
|
||||||
|
|
||||||
|
|
||||||
idm_exit ()
|
idm_exit ()
|
||||||
@ -161,6 +167,9 @@ idm_exit ()
|
|||||||
set +x
|
set +x
|
||||||
local rc=${1:-0}
|
local rc=${1:-0}
|
||||||
local msg lvl
|
local msg lvl
|
||||||
|
#[ -p /dev/stdin ] \
|
||||||
|
# && dump="$(</dev/stdin)" \
|
||||||
|
# || dump=""
|
||||||
|
|
||||||
# Check exit status
|
# Check exit status
|
||||||
if [ "$#" -eq 3 ]; then
|
if [ "$#" -eq 3 ]; then
|
||||||
@ -175,6 +184,8 @@ idm_exit ()
|
|||||||
if [[ "$rc" -ne 0 ]]; then
|
if [[ "$rc" -ne 0 ]]; then
|
||||||
#idm_trace || true
|
#idm_trace || true
|
||||||
idm_log $lvl "$msg (rc=$rc)"
|
idm_log $lvl "$msg (rc=$rc)"
|
||||||
|
#[ -z "$dump" ] || \
|
||||||
|
# idm_log DUMP "$dump"
|
||||||
else
|
else
|
||||||
idm_log $lvl "$msg"
|
idm_log $lvl "$msg"
|
||||||
fi
|
fi
|
||||||
@ -207,17 +218,35 @@ idm_trace ()
|
|||||||
) | >&2 idm_log DUMP -
|
) | >&2 idm_log DUMP -
|
||||||
}
|
}
|
||||||
|
|
||||||
idm_exit_trap() {
|
idm_exit_trap () {
|
||||||
set +x
|
set +x
|
||||||
rc=$?
|
rc=$?
|
||||||
if [[ $rc -ne 0 ]]; then
|
if [[ $rc -ne 0 ]]; then
|
||||||
idm_trace || true
|
|
||||||
idm_log ERR "The script exited with exit code: $rc"
|
idm_log ERR "The script exited with exit code: $rc"
|
||||||
|
idm_trace || true
|
||||||
|
#else
|
||||||
|
# idm_log WARN "The script exit has been trapped !"
|
||||||
|
# idm_trace || true
|
||||||
fi
|
fi
|
||||||
exit $rc
|
exit $rc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
idm_require_bin () {
|
||||||
|
local bin=$1
|
||||||
|
shift 1 || true
|
||||||
|
local opts=${@-}
|
||||||
|
|
||||||
|
if command -v "$bin" &> /dev/null; then
|
||||||
|
declare -g ${bin^^}="$bin $opts"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
idm_log ERR "Missing '$bin'"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
idm__load_lib ()
|
idm__load_lib ()
|
||||||
{
|
{
|
||||||
local lib_name=${1}
|
local lib_name=${1}
|
||||||
@ -332,7 +361,7 @@ idm_validate ()
|
|||||||
case $type in
|
case $type in
|
||||||
id)
|
id)
|
||||||
[ "$value" != '_' ] && \
|
[ "$value" != '_' ] && \
|
||||||
[[ "$value" =~ ^[a-zA-Z0-9_-]+$ ]] && return
|
[[ "$value" =~ ^[a-zA-Z0-9_-]+$ ]] && return $?
|
||||||
;;
|
;;
|
||||||
id_config)
|
id_config)
|
||||||
if [[ -f "$IDM_DIR_ID/$value.env" ]]; then
|
if [[ -f "$IDM_DIR_ID/$value.env" ]]; then
|
||||||
@ -340,10 +369,10 @@ idm_validate ()
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
is_enabled)
|
is_enabled)
|
||||||
[ ! -z "${SHELL_ID}" ] && return
|
[ ! -z "${SHELL_ID}" ] && return $?
|
||||||
;;
|
;;
|
||||||
is_disabled)
|
is_disabled)
|
||||||
[ -z "${SHELL_ID}" ] && return
|
[ -z "${SHELL_ID}" ] && return $?
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
@ -732,12 +761,12 @@ idm_menu_main ()
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
# Dispatch
|
# Dispatch
|
||||||
#idm_log DEBUG "menu=$menu action=$action id=$id opt=$opt"
|
#idm_log DEBUG "menu=$menu action=${action:-_} id=$id opt=$opt"
|
||||||
if [ "$( type -t idm_${menu}_${action} )" = function ]; then
|
if [ "$( type -t idm_${menu}_${action:-_} )" = function ]; then
|
||||||
idm_${menu}_${action} $id $opt
|
idm_${menu}_${action:-_} $id $opt
|
||||||
return $?
|
return $?
|
||||||
elif [ "$( type -t idm_${menu} )" = function ]; then
|
elif [ "$( type -t idm_${menu} )" = function ]; then
|
||||||
idm_${menu} ${action} $id $opt
|
idm_${menu} ${action:-_} $id $opt
|
||||||
return $?
|
return $?
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
238
lib/idmgr_mod_git.sh
Normal file
238
lib/idmgr_mod_git.sh
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
IDM_MOD_DEPS="id"
|
||||||
|
|
||||||
|
## Required functions
|
||||||
|
##########################################
|
||||||
|
|
||||||
|
# Debug and shortcuts
|
||||||
|
_git () { idm_git__bin ${@-}; }
|
||||||
|
idm_git_f () {
|
||||||
|
local id=$1
|
||||||
|
local cmd=$2
|
||||||
|
shift 2
|
||||||
|
local opts=${*-}
|
||||||
|
|
||||||
|
trap '' INT TERM EXIT
|
||||||
|
idm_validate id_config $id
|
||||||
|
idm_vars_git_local $id
|
||||||
|
|
||||||
|
set -e
|
||||||
|
idm_git_${cmd#idm_git_} $opts
|
||||||
|
rc=$?
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$rc" -eq 0 ]; then
|
||||||
|
idm_exit 0 "Returns $rc"
|
||||||
|
else
|
||||||
|
idm_exit $rc WARN "Called: 'idm_git_${cmd#idm_git_} ${opts:+$opts }'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
idm_git ()
|
||||||
|
{
|
||||||
|
local action=$1
|
||||||
|
local id=$2
|
||||||
|
shift 2
|
||||||
|
local opts=${*-}
|
||||||
|
idm_validate id_config $id
|
||||||
|
idm_vars_git_local $id
|
||||||
|
|
||||||
|
idm_git__bin $action $opts
|
||||||
|
}
|
||||||
|
|
||||||
|
idm_git_help ()
|
||||||
|
{
|
||||||
|
echo "Git"
|
||||||
|
printf " %-20s: %s\n" "git ls" "List maanged files"
|
||||||
|
printf " "
|
||||||
|
}
|
||||||
|
|
||||||
|
idm_git_ls ()
|
||||||
|
{
|
||||||
|
local id=$1
|
||||||
|
idm_validate id_config $id
|
||||||
|
idm_vars_git_local $id
|
||||||
|
|
||||||
|
_git ls-files | sed 's/^/ ~\//' | idm_log DUMP -
|
||||||
|
}
|
||||||
|
|
||||||
|
idm_git_enable ()
|
||||||
|
{
|
||||||
|
local id=$1
|
||||||
|
idm_validate id_config $id
|
||||||
|
idm_vars_git_local $id
|
||||||
|
|
||||||
|
cat <<EOF -
|
||||||
|
export GIT_DIR="$git_dir"
|
||||||
|
export GIT_WORK_TREE="$git_work_tree"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
idm_git_disable ()
|
||||||
|
{
|
||||||
|
echo "unset GIT_DIR GIT_WORK_TREE"
|
||||||
|
}
|
||||||
|
|
||||||
|
idm_git_kill () { idm_git_disable ${@-}; }
|
||||||
|
|
||||||
|
|
||||||
|
## Internal functions
|
||||||
|
##############################
|
||||||
|
|
||||||
|
idm_vars_git_local()
|
||||||
|
{
|
||||||
|
#local id=$1
|
||||||
|
var_id=git_local
|
||||||
|
id=${id:-$SHELL_ID}
|
||||||
|
git_work_tree=$HOME
|
||||||
|
git_dir=$IDM_DIR_CACHE/git/$id/local.git
|
||||||
|
git_config=${IDM_CONFIG_DIR}/git/$id/local_gitconfig
|
||||||
|
#git_config=$git_dir/$config
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# A wrapper before calling git
|
||||||
|
# WARN: IMPLICIT $ID VARIABLE, will fail if not well used
|
||||||
|
idm_git__bin ()
|
||||||
|
{
|
||||||
|
local opts=${@-}
|
||||||
|
|
||||||
|
# Check if config is loaded (when called from other mods)
|
||||||
|
[ -n "${git_dir:-}" ] || idm_vars_git_local $id
|
||||||
|
|
||||||
|
|
||||||
|
# Check binary presence
|
||||||
|
#idm_require_bin git || \
|
||||||
|
# idm_exit 1 "Please install git first."
|
||||||
|
|
||||||
|
git \
|
||||||
|
--git-dir "$git_dir" \
|
||||||
|
--work-tree "$git_work_tree" \
|
||||||
|
-C "$git_work_tree" \
|
||||||
|
$opts
|
||||||
|
|
||||||
|
# --file "$git_config" \
|
||||||
|
# -C indlude.path=$gitconfig
|
||||||
|
# --include $gitconfig
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
idm_git__is_repo ()
|
||||||
|
{
|
||||||
|
[ -d "$git_dir" ] && _git rev-parse > /dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
idm_git__has_commits ()
|
||||||
|
{
|
||||||
|
if idm_git__is_repo $id; then
|
||||||
|
find "$git_dir" -type f &>/dev/null && return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
idm_git__is_all_commited ()
|
||||||
|
{
|
||||||
|
[ "$( _git status -s | wc -l)" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## Other internal functions
|
||||||
|
##############################
|
||||||
|
|
||||||
|
idm_git__get_files_of_interest ()
|
||||||
|
{
|
||||||
|
local id=${1}
|
||||||
|
|
||||||
|
find_args="-maxdepth 2 -type f "
|
||||||
|
{
|
||||||
|
find $HOME/.ssh/ $find_args -name "${id}*" 2>/dev/null
|
||||||
|
find $HOME/.ssh/known_hosts.d/ $find_args -name "${id}*" 2>/dev/null
|
||||||
|
find $GNUPGHOME/private-keys-v1.d/ $find_args 2>/dev/null
|
||||||
|
find $PASSWORD_STORE_DIR/ $find_args 2>/dev/null
|
||||||
|
find $IDM_DIR_ID/ $find_args -name "$id*" 2>/dev/null
|
||||||
|
} | sed -E "s@$HOME/?@@g"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## User functions
|
||||||
|
##############################
|
||||||
|
|
||||||
|
idm_git_init ()
|
||||||
|
{
|
||||||
|
local id=$1
|
||||||
|
shift
|
||||||
|
local opts=${@-}
|
||||||
|
idm_validate id_config $id
|
||||||
|
idm_vars_git_local $id
|
||||||
|
|
||||||
|
|
||||||
|
if idm_git__is_repo ; then
|
||||||
|
idm_log WARN "Do you want to override the esixting repo?"
|
||||||
|
idm_cli_timeout 1 || idm_exit 1 "User cancelled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_git init $opts
|
||||||
|
idm_log NOTICE "Repository has been created into '$git_dir'"
|
||||||
|
|
||||||
|
# Generate
|
||||||
|
_git config --add include.path "$git_config"
|
||||||
|
idm_tomb__gen_git_config > $git_config
|
||||||
|
}
|
||||||
|
|
||||||
|
idm_tomb__gen_git_config ()
|
||||||
|
{
|
||||||
|
(
|
||||||
|
cat <<EOF -
|
||||||
|
[status]
|
||||||
|
showuntrackedfiles = no
|
||||||
|
|
||||||
|
EOF
|
||||||
|
) | sed "s@$HOME/@~/@g"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
idm_git_scan ()
|
||||||
|
{
|
||||||
|
local id=$1
|
||||||
|
idm_validate id_config $id
|
||||||
|
idm_vars_git_local $id
|
||||||
|
|
||||||
|
# Ensure we have a valid repository
|
||||||
|
if ! idm_git__is_repo ; then
|
||||||
|
idm_log WARN "Do you want to create a local repository of your secrets?"
|
||||||
|
idm_cli_timeout 1 || idm_exit 1 "User cancelled"
|
||||||
|
_git init
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add all files
|
||||||
|
_git add -f $( xargs <<<"$( idm_git__get_files_of_interest $id )" )
|
||||||
|
|
||||||
|
# Check uncommited changes
|
||||||
|
if ! idm_git__is_all_commited ; then
|
||||||
|
|
||||||
|
idm_log INFO "There are the files we could add:"
|
||||||
|
_git status -s
|
||||||
|
|
||||||
|
idm_log PROMPT "Do you want to add these files to your repo?"
|
||||||
|
if idm_cli_timeout 1; then
|
||||||
|
tty=$(tty)
|
||||||
|
#_git commit -e
|
||||||
|
echo "Add: Import $(hostname) data" | _git commit --file=-
|
||||||
|
else
|
||||||
|
idm_log TIP "Commit your files with 'i git commit '"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -213,3 +213,34 @@ idm_gpg_del ()
|
|||||||
gpg --delete-secret-key "$key" || true
|
gpg --delete-secret-key "$key" || true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Source: https://github.com/roddhjav/pass-tomb/blob/master/tomb.bash
|
||||||
|
# $@ is the list of all the recipient used to encrypt a tomb key
|
||||||
|
idm_gpg__is_valid_recipients() {
|
||||||
|
typeset -a recipients
|
||||||
|
recipients=($@)
|
||||||
|
|
||||||
|
# All the keys ID must be valid (the public keys must be present in the database)
|
||||||
|
for gpg_id in "${recipients[@]}"; do
|
||||||
|
gpg --list-keys "$gpg_id" &> /dev/null
|
||||||
|
if [[ $? != 0 ]]; then
|
||||||
|
idm_log ERR "${gpg_id} is not a valid key ID."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
idm_gpg__is_valid_key() {
|
||||||
|
typeset -a recipients
|
||||||
|
recipients=($@)
|
||||||
|
# At least one private key must be present
|
||||||
|
for gpg_id in "${recipients[@]}"; do
|
||||||
|
gpg --list-secret-keys "$gpg_id" &> /dev/null
|
||||||
|
if [[ $? = 0 ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|||||||
@ -75,24 +75,23 @@ idm_ssh_enable ()
|
|||||||
local id=$1
|
local id=$1
|
||||||
idm_is_enabled $id
|
idm_is_enabled $id
|
||||||
|
|
||||||
#set -x
|
|
||||||
|
|
||||||
# Source environment
|
# Source environment
|
||||||
if [ -f "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env" ] ; then
|
if [ -f "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env" ] ; then
|
||||||
. "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env"
|
. "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env"
|
||||||
else
|
else
|
||||||
unset SSH_AUTH_SOCK
|
unset SSH_AUTH_SOCK SSH_AGENT_PID
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if the socket file is available
|
# Check status
|
||||||
if [ ! -S "${SSH_AUTH_SOCK-}" ]; then
|
if ! idm_ssh__is_agent_working $id ${SSH_AUTH_SOCK:-_} ${SSH_AGENT_PID:-0}; then
|
||||||
rm -f "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env"
|
if ! idm_ssh__agent_start $id; then
|
||||||
idm_ssh__start $id
|
idm_log WARN "Could not start ssh agent :("
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Show the things to source
|
# Display config to load
|
||||||
cat "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env"
|
cat "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# LOGOUT
|
# LOGOUT
|
||||||
@ -130,32 +129,86 @@ idm_ssh_kill () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
## Internal functions
|
## Agent functions
|
||||||
##########################################
|
##########################################
|
||||||
idm_ssh__start() {
|
|
||||||
|
idm_ssh__is_agent_working ()
|
||||||
|
{
|
||||||
|
local id=$1
|
||||||
|
local socket=${2:-_}
|
||||||
|
local pid=${3:-0}
|
||||||
|
local rc=
|
||||||
|
|
||||||
|
set +e
|
||||||
|
SSH_AUTH_SOCK=$socket SSH_AGENT_PID=$pid ssh-add -l &>/dev/null
|
||||||
|
rc=$?
|
||||||
|
set -e
|
||||||
|
|
||||||
|
[ "$rc" -lt 2 ] && return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
idm_ssh__agent_start() {
|
||||||
local id=$1
|
local id=$1
|
||||||
local life=5d
|
local life=5d
|
||||||
local run_dir="${XDG_RUNTIME_DIR}/ssh-agent/${id}"
|
local run_dir="${XDG_RUNTIME_DIR}/ssh-agent/${id}"
|
||||||
|
|
||||||
if [ -z "${SSH_AUTH_SOCK-}" ] ; then
|
# Check if we can recover from previous instance
|
||||||
|
idm_ssh__agent_clean $id "$run_dir/socket" 0 || true
|
||||||
|
|
||||||
if [ ! -d "$run_dir" ]; then
|
# Ensure directory are present
|
||||||
|
[ -d "$run_dir" ] || \
|
||||||
mkdir -p "$run_dir"
|
mkdir -p "$run_dir"
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -S "$run_dir/socket" ]; then
|
# Ensure env file is not present
|
||||||
ssh-agent -a "$run_dir/socket" -t $life -s | grep ^SSH_ > "$run_dir/env"
|
[ ! -f "${run_dir}/env" ] || \
|
||||||
|
rm -f "${run_dir}/env"
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# Start the agent
|
||||||
|
if ssh-agent -a "$run_dir/socket" -t $life -s | grep ^SSH_ > "$run_dir/env"; then
|
||||||
|
|
||||||
|
echo "$run_dir/env"
|
||||||
idm_log INFO "Start ssh-agent ..."
|
idm_log INFO "Start ssh-agent ..."
|
||||||
|
|
||||||
else
|
else
|
||||||
idm_log INFO "The ssh-agent is already started (but not managed by ourself)"
|
idm_log WARN "Could not start ssh agent :("
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
else
|
|
||||||
idm_log INFO "The ssh-agent is already started"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
idm_ssh__agent_clean () {
|
||||||
|
local id=$1
|
||||||
|
local socket=$2
|
||||||
|
local pid=${3:-0}
|
||||||
|
|
||||||
|
# We should kill all agents ....
|
||||||
|
if [ "${pid}" == '0' ]; then
|
||||||
|
set +x
|
||||||
|
pid=$(grep -a "$socket" /proc/*/cmdline \
|
||||||
|
| grep -a -v 'thread-self' \
|
||||||
|
| strings -s' ' -1 \
|
||||||
|
| sed -E 's@ /proc/@ \n/proc/@g'
|
||||||
|
)
|
||||||
|
set -x
|
||||||
|
pid="$( sed -E 's@/proc/([0-9]*)/.*@\1@' <<<"$pid" )"
|
||||||
|
fi
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# Remove process
|
||||||
|
if [ "$pid" != '0' ]; then
|
||||||
|
kill $pid
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove socket
|
||||||
|
if [ -f "$socket" ]; then
|
||||||
|
rm $socket
|
||||||
|
fi
|
||||||
|
|
||||||
|
unset SSH_AUTH_SOCK SSH_AGENT_PID
|
||||||
|
#idm_log INFO "ssh-agent env cleaned is now clean"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
## Extended functions
|
## Extended functions
|
||||||
##########################################
|
##########################################
|
||||||
|
|
||||||
@ -199,3 +252,59 @@ idm_ssh_add ()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## Deprecated functions
|
||||||
|
##########################################
|
||||||
|
|
||||||
|
# Useless at this stage i guess
|
||||||
|
idm_ssh__agent_check ()
|
||||||
|
{
|
||||||
|
set -x
|
||||||
|
local id=$1
|
||||||
|
local socket=${2:-_}
|
||||||
|
local pid=${3:-0}
|
||||||
|
|
||||||
|
if [ "$socket" == '_' ] && [ "$pid" == '0' ] ; then
|
||||||
|
# Parameters are not valid, we assume ssh-agent is not launched at all
|
||||||
|
return 1
|
||||||
|
elif SSH_AUTH_SOCK=$socket SSH_AGENT_PID=$pid ssh-add -l &>/dev/null ; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
idm_log WARN "ssh-agent is not working as expected"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Is the socket valid ?
|
||||||
|
if [ "$socket" != '_' -a ! -S "$socket" ]; then
|
||||||
|
idm_log WARN "Socket '$socket' is dead, can't recover ssh-agent"
|
||||||
|
idm_ssh__agent_clean $id $socket 0
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$pid" != '0' -a "$pid" -lt 1 ]; then
|
||||||
|
local pid="$( ps aux | grep "$socket" | grep -v 'grep' | head -n 1 | awk '{ print $2 }' )" || \
|
||||||
|
pid="$( ps aux | grep "" | grep -v 'grep' | head -n 1 | awk '{ print $2 }' )" || \
|
||||||
|
{
|
||||||
|
idm_log WARN "Process ssh-agent is dead, cannot recover"
|
||||||
|
idm_ssh__agent_clean $id $socket 0
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Kill all processes
|
||||||
|
idm_log DEBUG "Multiple PID founds for ssh-agent: $pid"
|
||||||
|
q=0
|
||||||
|
for p in $pid; do
|
||||||
|
return
|
||||||
|
idm_ssh__agent_clean $id $socket $pid || true
|
||||||
|
q=1
|
||||||
|
done
|
||||||
|
[ "$q" -eq 0 ] || return 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ok, now we can try to recover the things
|
||||||
|
|
||||||
|
|
||||||
|
# Hmm, we should not arrive here ...
|
||||||
|
idm_log WARN "ssh-agent is in a really weird state :/"
|
||||||
|
return 1
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
IDM_MOD_DEPS="ssh gpg"
|
IDM_MOD_DEPS="id gpg git"
|
||||||
IDM_MOD_TAGS="id tool"
|
IDM_MOD_TAGS="id tool"
|
||||||
IDM_MOD_PROG="safe yadm"
|
IDM_MOD_PROG="safe yadm"
|
||||||
IDM_MOD_PREF="core id"
|
IDM_MOD_PREF="core id"
|
||||||
@ -17,652 +17,302 @@ IDM_MOD_PREF="core id"
|
|||||||
#set -x
|
#set -x
|
||||||
|
|
||||||
|
|
||||||
## Dependencies
|
## Common functions
|
||||||
##############################
|
##############################
|
||||||
idm_tomb__load_safe ()
|
|
||||||
{
|
|
||||||
SOURCE_DIR=
|
|
||||||
MY_GPG_KEY=NOGPG
|
|
||||||
COMPARE_BACKUPS=false
|
|
||||||
|
|
||||||
export SOURCE_DIR=$YADM_DIR
|
|
||||||
export MY_GPG_KEY=
|
|
||||||
#set -x
|
|
||||||
set +u
|
|
||||||
idm__load_lib safe -v 2>&1 >/dev/null || true
|
|
||||||
set -u
|
|
||||||
#set +x
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
## Required functions
|
|
||||||
##############################
|
|
||||||
|
|
||||||
|
|
||||||
idm_tomb__init ()
|
|
||||||
{
|
|
||||||
local id=${1}
|
|
||||||
idm_validate id $id
|
|
||||||
|
|
||||||
# Module config
|
|
||||||
export IDM_TOMB_LOCAL_GIT=$IDM_DIR_CACHE/git/$id/local.git
|
|
||||||
export IDM_TOMB_LOCAL_ENC=$IDM_DIR_CACHE/git/$id/local.git.tar.gz.asc
|
|
||||||
export IDM_TOMB_ORIGIN_GIT=$IDM_DIR_CACHE/git/$id/origin.git
|
|
||||||
export IDM_TOMB_ORIGIN_ENC=$IDM_CONFIG_DIR/enc/$id.tomb
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
idm_tomb_help ()
|
idm_tomb_help ()
|
||||||
{
|
{
|
||||||
|
local id=$1
|
||||||
|
idm_vars_git_tomb $id
|
||||||
|
|
||||||
echo "tomb"
|
echo "tomb"
|
||||||
printf " %-20s: %s\n" "tomb ls" "List all tombable files"
|
echo " workflow:"
|
||||||
printf " %-20s: %s\n" "tomb encrypt" "Save the current configuration"
|
printf " %-20s: %s\n" "tomb ls" "Show tomb status"
|
||||||
printf " %-20s: %s\n" "tomb decrypt" "Restore a tomb"
|
|
||||||
printf " %-20s: %s\n" "tomb import <id> [<file>] " "Import a config"
|
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"
|
printf " %-20s: %s\n" "tomb leave" "Remove all traces of your passage"
|
||||||
echo ""
|
echo " config:"
|
||||||
echo " Tomb is completely backed by yadm, this may change later"
|
printf " %-20s: %s\n" "tomb_enc" "$tomb_enc"
|
||||||
echo " Use 'yadm help' to get backend help ..."
|
printf " %-20s: %s\n" "git_dir" "$git_dir"
|
||||||
|
printf " %-20s: %s\n" "git_config" "$git_config"
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo " Yadm documentation (yadm help):"
|
|
||||||
yadm help | sed 's/^/ /'
|
|
||||||
|
|
||||||
# printf " %-20s: %s\n" "tomb sync " "Synchronise with remote repo (how ???)"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
idm_tomb ()
|
|
||||||
{
|
|
||||||
|
|
||||||
# Argument maangement
|
|
||||||
if [ "$#" -eq 1 ]; then
|
|
||||||
local id=$1
|
|
||||||
idm_ssh_ls $id
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
local action=$1
|
|
||||||
local id=${2-}
|
|
||||||
shift 2 || true
|
|
||||||
local opt=${@-}
|
|
||||||
fi
|
|
||||||
|
|
||||||
idm_log INFO "Forward to yadm: yadm ${action} $opt"
|
|
||||||
yadm ${action} $opt || \
|
|
||||||
idm_log ERR "Tomb fail"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
idm_tomb_ls ()
|
idm_tomb_ls ()
|
||||||
{
|
{
|
||||||
local id=${1}
|
local id=$1
|
||||||
idm_validate id $id
|
idm_vars_git_tomb $id
|
||||||
idm_tomb__init $id
|
|
||||||
|
|
||||||
if [ -d $IDM_TOMB_ORIGIN_GIT ]; then
|
|
||||||
if [ -f $IDM_TOMB_ORIGIN_ENC ]; then
|
|
||||||
idm_log WARN "Tomb is available and secret repo is unlocked"
|
|
||||||
else
|
|
||||||
idm_log WARN "Tomb is not present and secret repo is unlocked"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Show secured files
|
|
||||||
yadm list -a | sed 's:^:~/:' | idm_log DUMP -
|
|
||||||
|
|
||||||
|
|
||||||
# Show modified files
|
echo " Info:"
|
||||||
if ! idm_tomb__is_all_commited ; then
|
printf " %-20s: %s\n" "opened" "yes"
|
||||||
idm_log WARN "Some files has been modified"
|
printf " %-20s: %s\n" "last mod." "yes"
|
||||||
yadm -c color.status=always status -s
|
printf " %-20s: %s\n" "git" "$git_dir"
|
||||||
fi
|
printf " %-20s: %s\n" "last date" ""
|
||||||
|
|
||||||
else
|
|
||||||
if [ -f $IDM_TOMB_ORIGIN_ENC ]; then
|
|
||||||
idm_log INFO "Tomb is available and secret repo is locked"
|
|
||||||
else
|
|
||||||
idm_log INFO "Tomb is absent and secret repo is locked"
|
|
||||||
fi
|
|
||||||
# export SOURCE_DIR=$IDM_TOMB_ORIGIN_GIT
|
|
||||||
# export SAFE_TAR_ENC=$IDM_TOMB_ORIGIN_ENC
|
|
||||||
# idm_log INFO "Encrypted files in $IDM_TOMB_ORIGIN_ENC: $(safe -l | wc -l )"
|
|
||||||
|
|
||||||
# export SOURCE_DIR=$IDM_TOMB_LOCAL_GIT
|
|
||||||
# export SAFE_TAR_ENC=$IDM_TOMB_LOCAL_ENC
|
|
||||||
# idm_log INFO "Encrypted files in $IDM_TOMB_LOCAL_ENC: $(safe -l | wc -l )"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
echo " Remotes:"
|
||||||
|
_git_local remote -v | sed 's/^/ /'
|
||||||
}
|
}
|
||||||
|
|
||||||
## Sourced functions
|
## Internal functions
|
||||||
##############################
|
##############################
|
||||||
|
|
||||||
idm_tomb_enable()
|
idm_git__bin_git ()
|
||||||
{
|
{
|
||||||
local id=${1}
|
if idm_validate id_config $1; then
|
||||||
idm_validate id $id
|
id=${1} ;shift
|
||||||
|
fi
|
||||||
#mkdir -p $IDM_DIR_CACHE/git/$id/ $IDM_CONFIG_DIR/git/ || true
|
idm_vars_git_local $id
|
||||||
|
idm_git__bin ${*-}
|
||||||
echo "export YADM_WORK=$HOME"
|
|
||||||
echo "export YADM_DIR=$IDM_CONFIG_DIR/git/$id"
|
|
||||||
echo "export YADM_OVERRIDE_REPO=$IDM_DIR_CACHE/git/$id/local.git"
|
|
||||||
|
|
||||||
echo "export IDM_TOMB_LOCAL_GIT=$IDM_DIR_CACHE/git/$id/local.git"
|
|
||||||
echo "export IDM_TOMB_LOCAL_ENC=$IDM_DIR_CACHE/git/$id/local.git.tar.gz.asc"
|
|
||||||
echo "export IDM_TOMB_ORIGIN_GIT=$IDM_DIR_CACHE/git/$id/origin.git"
|
|
||||||
echo "export IDM_TOMB_ORIGIN_ENC=$IDM_CONFIG_DIR/enc/$id.tomb"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
idm_tomb_disable()
|
|
||||||
|
# A wrapper before calling git
|
||||||
|
idm_tomb__bin_git ()
|
||||||
{
|
{
|
||||||
# Disable internal variables
|
# Ugly bugfix :(
|
||||||
echo "unset YADM_WORK YADM_DIR" | idm_log CODE -
|
if idm_validate id_config $1; then
|
||||||
|
id=${1} ;shift
|
||||||
|
fi
|
||||||
|
idm_vars_git_tomb $id
|
||||||
|
idm_git__bin ${*-}
|
||||||
}
|
}
|
||||||
|
|
||||||
idm_tomb_kill () { idm_tomb_disable ${@-}; }
|
# 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
|
||||||
## Git functions
|
|
||||||
##############################
|
##############################
|
||||||
|
|
||||||
idm_tomb_ls_local ()
|
|
||||||
|
idm_vars_git_tomb()
|
||||||
{
|
{
|
||||||
yadm list -a | sed 's:^: ~/:' | idm_log DUMP -
|
var_id=git_tomb
|
||||||
}
|
id=${id:-$SHELL_ID}
|
||||||
|
git_work_tree=$HOME
|
||||||
idm_tomb__is_all_commited ()
|
git_dir=$IDM_DIR_CACHE/git/$id/tomb.git
|
||||||
{
|
git_config=${IDM_CONFIG_DIR}/git/$id/tomb_gitconfig
|
||||||
return $( { yadm status -s || true; } | wc -l)
|
tomb_enc=$IDM_CONFIG_DIR/enc/$id.tomb
|
||||||
}
|
|
||||||
|
|
||||||
idm_tomb_init_local ()
|
|
||||||
{
|
|
||||||
local id=${1}
|
|
||||||
idm_validate id $id
|
|
||||||
|
|
||||||
|
|
||||||
[ -d $YADM_OVERRIDE_REPO ] || {
|
|
||||||
yadm init || true
|
|
||||||
idm_log NOTICE "New repository was created for secret in $YADM_OVERRIDE_REPO"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Regenerate configs
|
|
||||||
idm_tomb__gen_gitconfig $id > $IDM_CONFIG_DIR/git/$id/gitconfig
|
|
||||||
idm_tomb__gen_config $id > $IDM_CONFIG_DIR/git/$id/config
|
|
||||||
# idm_tomb__gen_ignore $id | sed -e '/^[^$]/ s/^/!/' > $IDM_CONFIG_DIR/git/$id/gitignore
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
idm_tomb_scan ()
|
idm_tomb_init()
|
||||||
{
|
{
|
||||||
local id=${1}
|
local id=$1
|
||||||
idm_validate id $id
|
shift || true
|
||||||
|
|
||||||
# We need the local repo at last
|
# Sanity check
|
||||||
idm_log WARN "Do you want to create a local repository of your secrets?"
|
idm_validate id_config $id
|
||||||
idm_cli_timeout 1 || idm_exit 1 "User cancelled"
|
local old_var_id=${var_id-}
|
||||||
idm_tomb_init_local $id
|
|
||||||
|
|
||||||
# ajoute une liste de fichier: git add
|
# Check local repository state
|
||||||
|
_load_local_env
|
||||||
file=$YADM_DIR/gitignore
|
local local_git_dir=$git_dir
|
||||||
result=$( idm_tomb__gen_ignore $id )
|
if ! idm_git__is_repo; then
|
||||||
|
idm_exit 1 NOTICE "You need to have a local repo first"
|
||||||
# Add all files
|
elif ! idm_git__has_commits ; then
|
||||||
( cd && xargs yadm add -f <<<${result} )
|
idm_exit 1 NOTICE "You need to commit all your changes"
|
||||||
|
|
||||||
# Check uncommited changes
|
|
||||||
if ! idm_tomb__is_all_commited; then
|
|
||||||
idm_log NOTICE "All those files will be added:"
|
|
||||||
yadm status -s
|
|
||||||
yadm commit -m "Initial import"
|
|
||||||
fi
|
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_replace ()
|
idm_tomb_sync ()
|
||||||
{
|
{
|
||||||
# Restore absent files
|
local id=$1
|
||||||
files="$( yadm status -s )"
|
shift || true
|
||||||
|
|
||||||
ok_files="$( sed -E '/^(D|.D)/!d;s/^...//' <<<$files | xargs || true)"
|
# Sanity check
|
||||||
fail_files="$( sed -E '/^(D|.D)/d;s/^...//' <<<$files | xargs || true )"
|
idm_validate id_config $id
|
||||||
|
|
||||||
if [ ! -z "$ok_files" ]; then
|
# Load tomb config
|
||||||
idm_log INFO "Will restore:"
|
_load_tomb_env
|
||||||
xargs -n1 <<<"$ok_files" | sed 's:^:~/:' | idm_log DUMP -
|
local repo_url=$git_dir
|
||||||
yadm co HEAD $ok_files
|
local repo_name=tomb
|
||||||
else
|
|
||||||
idm_log INFO "Tracked files are:"
|
|
||||||
yadm list -a | sed 's:^:~/:' | idm_log DUMP -
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -z "$fail_files" ]; then
|
# Work on local
|
||||||
idm_log WARN "Cannot restore:"
|
_git_local remote add $repo_name $repo_url || true
|
||||||
#sed 's:^:~/:' <<<"$fail_files" | xargs -n1 | idm_log DUMP -
|
_git_local fetch --all
|
||||||
yadm status -s
|
_git_local fetch --all --tags
|
||||||
fi
|
_git_local push -u $repo_name --all
|
||||||
|
_git_local push -u $repo_name --tags
|
||||||
|
|
||||||
|
idm_log NOTICE "Tomb and local repository are now synced"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
## Crypt functions
|
|
||||||
##############################
|
|
||||||
|
|
||||||
idm_tomb__encrypt_init ()
|
|
||||||
{
|
|
||||||
local id=${1}
|
|
||||||
idm_validate id $id
|
|
||||||
idm_tomb__init $id
|
|
||||||
idm_tomb__load_safe
|
|
||||||
|
|
||||||
env | sort | grep ^IDM | idm_log DUMP -
|
|
||||||
|
|
||||||
# Create destination paths
|
|
||||||
[ -d "$( dirname "$IDM_TOMB_LOCAL_ENC" )" ] || \
|
|
||||||
mkdir -p "$( dirname "$IDM_TOMB_LOCAL_ENC" )"
|
|
||||||
[ -d "$( dirname "$IDM_TOMB_ORIGIN_ENC" )" ] || \
|
|
||||||
mkdir -p "$( dirname "$IDM_TOMB_ORIGIN_ENC" )"
|
|
||||||
|
|
||||||
# Ensure permissions are open to be deleted later (not a good idea, shred is better)
|
|
||||||
#chmod u+w -R "$IDM_TOMB_LOCAL_GIT"
|
|
||||||
#chmod u+w -R "$IDM_TOMB_ORIGIN_GIT"
|
|
||||||
|
|
||||||
# Auto detect what to do
|
|
||||||
# We need the local repo at last
|
|
||||||
# idm_log WARN "Do you want to create a local repository of your secrets?"
|
|
||||||
# idm_cli_timeout 1 || idm_exit 1 "User cancelled"
|
|
||||||
# idm_tomb_init_local $id
|
|
||||||
|
|
||||||
|
|
||||||
# Check uncommited changes: We always want to have a stable state for git (absent is good)
|
|
||||||
if ! idm_tomb__is_all_commited; then
|
|
||||||
yadm status -s
|
|
||||||
idm_exit 0 "You need to commit all you changes"
|
|
||||||
fi
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
# option: Use -f to force overwrite of files
|
|
||||||
idm_tomb_encrypt ()
|
idm_tomb_encrypt ()
|
||||||
{
|
{
|
||||||
local id=${1}
|
local id=$1
|
||||||
shift || true
|
shift || true
|
||||||
local opt=${@-}
|
local opt=${@-}
|
||||||
local TOFIX_opt=$opt
|
local TOFIX_opt=$opt
|
||||||
idm_tomb__encrypt_init $id
|
local old_var_id=${var_id-}
|
||||||
|
|
||||||
# We need a local git repo
|
# Sanity check
|
||||||
if [ ! -d $IDM_TOMB_LOCAL_GIT ]; then
|
idm_validate id_config $id
|
||||||
idm_exit 1 "Git repo is not enabled ($IDM_TOMB_LOCAL_GIT)"
|
|
||||||
|
# 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
|
fi
|
||||||
|
|
||||||
# Do we overwrite ?
|
#set -x
|
||||||
if [ -f "$IDM_TOMB_LOCAL_ENC" ]; then
|
$GPG $gpg_opts $src | $TAR $tar_opts || \
|
||||||
[[ "$TOFIX_opt" =~ -f ]] || {
|
idm_exit 1 ERR "Could not decrypt file: $src into $dst"
|
||||||
idm_log WARN "Do you want to overwrite '$IDM_TOMB_LOCAL_ENC'?"
|
|
||||||
idm_cli_timeout 1 || idm_exit 1 "User cancelled"
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Push all commits to local origin
|
}
|
||||||
if [ -d "$IDM_TOMB_ORIGIN_GIT" ]; then
|
|
||||||
repo_name=origin
|
|
||||||
yadm remote add $repo_name $IDM_TOMB_ORIGIN_GIT 2>/dev/null || true
|
|
||||||
yadm push -u $repo_name --all 2>/dev/null || true
|
|
||||||
yadm push -u $repo_name --tags 2>/dev/null || true
|
|
||||||
elif [ -f "$IDM_TOMB_ORIGIN_ENC" ]; then
|
|
||||||
local rc=$?
|
|
||||||
idm_log NOTICE "An encrypted version of origin has been found: $IDM_TOMB_ORIGIN_ENC"
|
|
||||||
idm_log WARN "Do you want to sync with it before encrypt? (Need decrypt procedure!)"
|
|
||||||
idm_cli_timeout 1 || rc=$?
|
|
||||||
|
|
||||||
if [ "$rc" -eq 0 ]; then
|
|
||||||
echo "Launche function to decrypt origin ..."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Find out gpg author, it should be the local key of user !
|
|
||||||
|
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="$(yadm config yadm.gpg-recipient || true )"
|
||||||
GPG_KEY="${GPG_DEFAULT_ID-}"
|
#GPG_KEY="${GPG_DEFAULT_ID-}"
|
||||||
case "${GPG_KEY:-_}" in
|
|
||||||
ASK) GPG_OPTS=("--no-default-recipient -e") ;;
|
# Check pgp key and arguments
|
||||||
_) GPG_OPTS=("-c") ;;
|
if idm_gpg__is_valid_key $key; then
|
||||||
*)
|
|
||||||
GPG_OPTS="-e -r $GPG_KEY"
|
shift 3
|
||||||
idm_log NOTICE "Local tomb will be secured with your '$GPG_KEY' id"
|
local ok=0 ko=0
|
||||||
;;
|
recipients=${@:-${GPG_DEFAULT_ID-}}
|
||||||
esac
|
gpg_opts="-e -r $recipients"
|
||||||
#GPG_OPTS=("--no-default-recipient" "-e -r $GPG_KEY")
|
|
||||||
|
# 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
|
# Encrypt all the stuffs
|
||||||
TAR="tar -C $(dirname $IDM_TOMB_LOCAL_GIT)"
|
$TAR -C "${src%/*}" -cz "${src##*/}" 2>/dev/null | \
|
||||||
$TAR -cz $IDM_TOMB_LOCAL_GIT 2>/dev/null | gpg2 -a $GPG_OPTS --yes -o $IDM_TOMB_LOCAL_ENC || \
|
$GPG -a $gpg_opts --yes -o $dst || \
|
||||||
idm_exit 1 ERR "Could not encrypt tomb"
|
idm_exit 1 ERR "Could not encrypt directory: $src"
|
||||||
|
|
||||||
idm_log INFO "Local tomb closed into $IDM_TOMB_LOCAL_ENC"
|
# File descritor tests ...
|
||||||
|
#exec 3<> /tmp/foo
|
||||||
# Shred the local files?
|
#>&3 echo "$pass"
|
||||||
#find $IDM_TOMB_LOCAL_GIT -type f | xargs shred -u
|
#{ echo "$pass\n" >&3 ; $TAR -C "$(dirname $src)" -cz "$src" 2>/dev/null; } | \
|
||||||
#rm -fr $IDM_TOMB_LOCAL_GIT
|
#exec 3>&- #close fd 3.
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
# Origin part !
|
|
||||||
if [ ! -d $IDM_TOMB_ORIGIN_GIT ]; then
|
|
||||||
idm_log NOTICE "Creating remote tomb repo ..."
|
|
||||||
mkdir -p "$( dirname "$IDM_TOMB_ORIGIN_GIT" )"
|
|
||||||
git clone --bare $YADM_OVERRIDE_REPO $IDM_TOMB_ORIGIN_GIT || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
export SOURCE_DIR=$IDM_TOMB_ORIGIN_GIT
|
|
||||||
export SAFE_TAR_ENC=$IDM_TOMB_ORIGIN_ENC
|
|
||||||
#idm_log INFO "Origin tomb closed into $SAFE_TAR_ENC"
|
|
||||||
echo safe -c
|
|
||||||
|
|
||||||
idm_log NOTICE "Your tombs are secure"
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
idm_tomb_decrypt ()
|
|
||||||
{
|
|
||||||
local id=${1}
|
|
||||||
idm_tomb__encrypt_init $id
|
|
||||||
|
|
||||||
# Check status of repos ...
|
|
||||||
if [ ! -d $IDM_TOMB_LOCAL_GIT ]; then
|
|
||||||
if [ ! -f "$IDM_TOMB_LOCAL_ENC" ]; then
|
|
||||||
idm_exit 1 "Local tomb enc is not present, please encrypt first"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
idm_exit 0 "Local tomb enc is already decrypted in $IDM_TOMB_LOCAL_GIT"
|
|
||||||
fi
|
|
||||||
if [ ! -d $IDM_TOMB_ORIGIN_GIT ]; then
|
|
||||||
if [ ! -f "$IDM_TOMB_ORIGIN_ENC" ]; then
|
|
||||||
idm_exit 1 "Remote tomb enc is not present, please encrypt first"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
idm_exit 0 "Remote tomb enc is already decrypted in $IDM_TOMB_ORIGIN_GIT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Decrypt all the stuffs
|
|
||||||
export SOURCE_DIR=$IDM_TOMB_LOCAL_GIT
|
|
||||||
export SAFE_TAR_ENC=$IDM_TOMB_LOCAL_ENC
|
|
||||||
safe -x
|
|
||||||
|
|
||||||
export SOURCE_DIR=$IDM_TOMB_ORIGIN_GIT
|
|
||||||
export SAFE_TAR_ENC=$IDM_TOMB_ORIGIN_ENC
|
|
||||||
safe -x
|
|
||||||
|
|
||||||
# Did it success ?
|
|
||||||
if [ ! -d "$IDM_TOMB_ORIGIN_GIT" ]; then
|
|
||||||
idm_exit 1 "Origin tomb could not be decrypted"
|
|
||||||
else
|
|
||||||
idm_log INFO "Origin tomb opened into $SOURCE_DIR"
|
|
||||||
fi
|
|
||||||
if [ ! -d "$IDM_TOMB_ORIGIN_GIT" ]; then
|
|
||||||
idm_exit 1 "Local tomb could not be decrypted"
|
|
||||||
else
|
|
||||||
idm_log INFO "Local tomb opened into $SOURCE_DIR"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# Push all commits to remote
|
|
||||||
# TOFIX: warn if uncommited changes !
|
|
||||||
repo_name=origin
|
|
||||||
yadm remote add $repo_name $IDM_TOMB_ORIGIN_GIT 2>/dev/null || true
|
|
||||||
yadm fetch -u $repo_name --all 2>/dev/null || true
|
|
||||||
yadm fetch -u $repo_name --tags 2>/dev/null || true
|
|
||||||
|
|
||||||
idm_tomb_replace
|
|
||||||
|
|
||||||
# replace permission: git-cache-meta --store
|
|
||||||
idm_LOG DEBUG "Implement git cache permission"
|
|
||||||
|
|
||||||
|
|
||||||
idm_log NOTICE "Tombs are now open"
|
|
||||||
}
|
|
||||||
|
|
||||||
idm_tomb_leave ()
|
|
||||||
{
|
|
||||||
local id=${1}
|
|
||||||
idm_validate id $id
|
|
||||||
idm_tomb__init $id
|
|
||||||
|
|
||||||
#if yadm list -a >&/dev/null; then
|
|
||||||
list_of_files_to_del="$( yadm list -a || true )"
|
|
||||||
#else
|
|
||||||
# idm_exit 1 "There is no local repo"
|
|
||||||
#fi
|
|
||||||
|
|
||||||
idm_tomb_encrypt $id
|
|
||||||
|
|
||||||
idm_log WARN "All those files has been encrypted and safely removed:"
|
|
||||||
sed 's:^:~/:' <<<"$list_of_files_to_del" | idm_log DUMP -
|
|
||||||
sed "s:^:$HOME/:" <<<"$list_of_files_to_del" | xargs rm
|
|
||||||
#for f in $list_of_files_to_del; do
|
|
||||||
#done
|
|
||||||
|
|
||||||
idm_log INFO "Run 'i quit' to disapear"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# idm_tomb__gpg_enc
|
|
||||||
# idm_tomb__gpg_dec
|
|
||||||
# idm_tomb__gpg_rm_short
|
|
||||||
# idm_tomb__gpg_rm_long
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Import/Export functions
|
|
||||||
##############################
|
|
||||||
|
|
||||||
# export tomb files into a dir or on a remote host
|
|
||||||
idm_tomb_export ()
|
|
||||||
{
|
|
||||||
local id=${1}
|
|
||||||
local dest=${2-}
|
|
||||||
idm_validate id $id
|
|
||||||
idm_tomb__init $id
|
|
||||||
|
|
||||||
# Check if a local tomb is vaialable
|
|
||||||
if [ -f "$IDM_TOMB_ORIGIN_ENC" ]; then
|
|
||||||
src_file=$IDM_TOMB_ORIGIN_ENC
|
|
||||||
elif [ -f "$IDM_TOMB_LOCAL_ENC" ] ; then
|
|
||||||
idm_log WARN "Will synchronise local tomb to remote origin tomb. Are you sure they are the same ?"
|
|
||||||
idm_cli_timeout 1 || idm_exit 1 "User cancelled"
|
|
||||||
src_file=$IDM_TOMB_LOCAL_ENC
|
|
||||||
else
|
|
||||||
idm_exit 1 "No tomb file available ... :("
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check destination
|
|
||||||
if [ -z "$dest" ]; then
|
|
||||||
idm_exit 1 "You need to give a path or an host"
|
|
||||||
fi
|
|
||||||
local dest_host dest_dir dest_name
|
|
||||||
|
|
||||||
# Auto detect destination
|
|
||||||
if [ -d "$dest" ]; then
|
|
||||||
dest_host=_
|
|
||||||
dest_dir=$dest
|
|
||||||
dest_name=$id.enc
|
|
||||||
elif [ -f "$dest" ]; then
|
|
||||||
dest_host=_
|
|
||||||
dest_dir=$( dirname $dest )
|
|
||||||
dest_name=$( basename $dest )
|
|
||||||
else
|
|
||||||
|
|
||||||
# Test ssh connection
|
|
||||||
rc=0
|
|
||||||
#result=$( idm_tomb__remote_env_detect | ssh $dest 2>/dev/null ) || rc=$?
|
|
||||||
idm_log NOTICE "Trying to ssh $dest ..."
|
|
||||||
result=$( idm_tomb__remote_env_detect | ssh $dest ) || rc=$?
|
|
||||||
|
|
||||||
if [ "$rc" -ne 0 ]; then
|
|
||||||
idm_log DUMP - <<<"$result"
|
|
||||||
idm_exit 1 "Could not find host or dir for '$dest'"
|
|
||||||
fi
|
|
||||||
dest_host=$dest
|
|
||||||
dest_dir=$result/enc
|
|
||||||
dest_name=$id.tomb
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Cosmetic changes
|
|
||||||
dest_dir=$(realpath --relative-to . "$dest_dir" || echo "$dest_dir" )
|
|
||||||
src_file=$(realpath --relative-to . "$src_file" || echo "$src_file" )
|
|
||||||
|
|
||||||
idm_log INFO "Destination is: $dest_host:$dest_dir/$dest_name from $src_file"
|
|
||||||
if ! scp $src_file $dest_host:$dest_dir/$dest_name ; then
|
|
||||||
idm_log DUMP "scp $src_file $dest_host:$dest_dir/$dest_name "
|
|
||||||
idm_exit 1 "Cound not copy to remote host: $dest_host:$dest_dir/$dest_name"
|
|
||||||
fi
|
|
||||||
idm_log INFO "Remote $dest_host have the same tomb for '$id' "
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
idm_tomb_import ()
|
|
||||||
{
|
|
||||||
local id=${2-}
|
|
||||||
|
|
||||||
if [ -z "$id" ]; then
|
|
||||||
id=MY_ID
|
|
||||||
idm_exit 1 "You need to provide a file or an id (look into: $IDM_TOMB_ORIGIN_ENC)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! idm_validate id $id ; then
|
|
||||||
idm_exit 1 "The id '$id' is not valid"
|
|
||||||
fi
|
|
||||||
|
|
||||||
idm_tomb__init $id
|
|
||||||
if [ ! -f "$IDM_TOMB_ORIGIN_ENC" ]; then
|
|
||||||
idm_exit 1 "You need to provide a file to import or place it here $IDM_TOMB_ORIGIN_ENC"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
idm_tomb_decrypt $id
|
|
||||||
idm_log INFO "Run 'i $id' to enable it"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Template functions
|
|
||||||
##############################
|
|
||||||
|
|
||||||
idm_tomb__gen_ignore ()
|
|
||||||
{
|
|
||||||
local id=${1}
|
|
||||||
idm_validate id $id
|
|
||||||
|
|
||||||
find_args="-maxdepth 2 -type f "
|
|
||||||
conf=$( cat <<EOF -
|
|
||||||
$( find $HOME/.ssh/ $find_args -name "${id}*" 2>/dev/null )
|
|
||||||
$( find $HOME/.ssh/known_hosts.d/ $find_args -name "${id}*" 2>/dev/null )
|
|
||||||
$( find $GNUPGHOME/private-keys-v1.d/ $find_args 2>/dev/null )
|
|
||||||
$( find $PASSWORD_STORE_DIR/ $find_args 2>/dev/null )
|
|
||||||
$( find $IDM_DIR_ID/ $find_args -name "$id*" 2>/dev/null )
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
sed -E -e "s@$HOME/?@@g" <<<"$conf"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
idm_tomb__gen_gitconfig ()
|
|
||||||
{
|
|
||||||
local id=${1}
|
|
||||||
idm_validate id $id
|
|
||||||
|
|
||||||
(
|
|
||||||
cat <<EOF -
|
|
||||||
# To enable this file, you need to:
|
|
||||||
# git config --local include.path $IDM_CONFIG_DIR/gitconfig
|
|
||||||
# yadm gitconfig --local include.path $IDM_CONFIG_DIR/gitconfig
|
|
||||||
|
|
||||||
#[include]
|
|
||||||
# path = $IDM_CONFIG_DIR/gitconfig
|
|
||||||
|
|
||||||
[core]
|
|
||||||
excludesFile = $IDM_CONFIG_DIR/git/$id/gitignore
|
|
||||||
attributesFile = $IDM_CONFIG_DIR/git/$id/.yadm/gitattributes
|
|
||||||
|
|
||||||
EOF
|
|
||||||
) | sed "s@$HOME/@~/@g"
|
|
||||||
}
|
|
||||||
|
|
||||||
idm_tomb__gen_config ()
|
|
||||||
{
|
|
||||||
local id=${1}
|
|
||||||
idm_validate id $id
|
|
||||||
|
|
||||||
(
|
|
||||||
cat <<EOF -
|
|
||||||
[status]
|
|
||||||
showuntrackedfiles = yes
|
|
||||||
|
|
||||||
EOF
|
|
||||||
) | sed "s@$HOME/@~/@g"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
idm_tomb__remote_env_detect ()
|
|
||||||
{
|
|
||||||
local dest_host=${1:-remote}
|
|
||||||
|
|
||||||
cat - <<EOF
|
|
||||||
|
|
||||||
idm_autodetect ()
|
|
||||||
{
|
|
||||||
[ -d "\${IDM_CONFIG_DIR-}" ] && {
|
|
||||||
echo "\${IDM_CONFIG_DIR-}"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
[ -d "${IDM_CONFIG_DIR}" ] && {
|
|
||||||
echo "${IDM_CONFIG_DIR}"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
r=\$(find ~ -maxdepth 4 -wholename '*idmgr*' -a -name '*.git.tar.gz.asc' -type f | head -n1 )
|
|
||||||
[ ! -z "\$r" ] && {
|
|
||||||
echo "\$( dirname \$r )"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
r=\$( find ~ -maxdepth 4 -wholename '*idmgr' -type d )
|
|
||||||
[ ! -z "\$r" ] && {
|
|
||||||
r=\$( grep 'cnf|conf|data' <<<\$r | head -n1 )
|
|
||||||
[ ! -z "\$r" ] && {
|
|
||||||
echo "\$r/enc"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
echo "\$HOME/.config/idmgr"
|
|
||||||
}
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
d="\$( idm_autodetect )" && {
|
|
||||||
[ ! -d "\$d/enc" ] && {
|
|
||||||
mkdir -p "\$d/enc" && \
|
|
||||||
>&2 echo "REMOTE: Path has been created on $dest_host: \$d" || {
|
|
||||||
>&2 echo "REMOTE: Path couln't be created on $dest_host: \$d"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
} || {
|
|
||||||
>&2 echo "REMOTE: Path has been found on $dest_host: \$d"
|
|
||||||
}
|
|
||||||
echo "\$d"
|
|
||||||
}
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user