Dev: Completely refactor the code

This commit is contained in:
mrjk 2018-02-16 02:23:03 -05:00
parent 2c3ccab6ad
commit 9dea6bf7ef
11 changed files with 1694 additions and 1091 deletions

BIN
bin/.idmgr.swp Normal file

Binary file not shown.

887
bin/idmgr

File diff suppressed because it is too large Load Diff

272
lib/idm_lib_std.sh Normal file
View File

@ -0,0 +1,272 @@
#!/bin/bash
## Special libraries
#############################
lib_shred ()
{
lib_lob WARN "Will destroy all your secrets! (nor implemented yet)"
}
## Standard libraries
#############################
lib_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
lib_log ERR "Missing '$bin'"
return 1
fi
}
# Nifty trick to set var from pipes
lib_set_var () { read "$@" <&0; }
# Take an environment var name, an a list of vars to inject
lib_vars_inject ()
{
local env_name=$1
shift 1
# Check if not already loaded
if [ "${last_env_name}" == "$env_name" ]; then
return 0
fi
last_env_name=$env_name
# check if valid environment
[ "$( type -t idm_vars_${env_name} )" = function ] || return 1
# Inject var list
for var in ${@-}; do
name=${env}_${var}
$i=${!name}
done
}
lib_trace ()
{
local msg=${@}
local traces=
(
echo "Stack trace:"
for i in {0..10}; do
trace=$(caller $i 2>&1 || true )
if [ -z "$trace" ] ; then
continue
else
#lib_log DEBUG "Trace $i: $trace"
#traces="${traces}${trace}\n"
echo "$trace"
fi
done | tac | column -t
[ -z "$msg" ] || echo "Trace ctx: $msg"
) | >&2 lib_log DUMP -
}
lib_reverse_doted_list ()
{
local list=$1
awk 'BEGIN{FS=OFS=":"} {s=$NF; for (i=NF-1; i>=1; i--) s = s OFS $i; print s}' <<<"$list"
}
lib_parse_filerules ()
{
local id=$1
local f=$2
#set -x
local YADM_ENCRYPT="$2"
ENCRYPT_INCLUDE_FILES=()
ENCRYPT_EXCLUDE_FILES=()
#cd_work "Parsing encrypt" || return
cd ~
exclude_pattern="^!(.+)"
if [ -f "$YADM_ENCRYPT" ] ; then
#; parse both included/excluded
while IFS='' read -r line || [ -n "$line" ]; do
if [[ ! $line =~ ^# && ! $line =~ ^[[:space:]]*$ ]] ; then
local IFS=$'\n'
for pattern in $line; do
if [[ "$pattern" =~ $exclude_pattern ]]; then
for ex_file in ${BASH_REMATCH[1]}; do
for f in $( find $ex_file -type f ); do
#if [ -e "$ex_file" ]; then
ENCRYPT_EXCLUDE_FILES+=("$f")
#fi
done
done
else
for in_file in $pattern; do
for f in $( find $in_file -type f ); do
#if [ -e "$in_file" ]; then
ENCRYPT_INCLUDE_FILES+=("$f")
#fi
done
done
fi
done
fi
done < "$YADM_ENCRYPT"
#; remove excludes from the includes
#(SC2068 is disabled because in this case, we desire globbing)
FINAL_INCLUDE=()
#shellcheck disable=SC2068
for included in "${ENCRYPT_INCLUDE_FILES[@]}"; do
skip=
#shellcheck disable=SC2068
for ex_file in ${ENCRYPT_EXCLUDE_FILES[@]}; do
[ "$included" == "$ex_file" ] && { skip=1; break; }
done
[ -n "$skip" ] || FINAL_INCLUDE+=("$included")
done
ENCRYPT_INCLUDE_FILES=("${FINAL_INCLUDE[@]}")
echo "${ENCRYPT_INCLUDE_FILES[@]}"
fi
}
lib_log ()
{
set +x
local level=$1
shift || true
local msg="$@"
# Take from stdin if no message ...
[ "$msg" = - ] && msg=$( cat < /dev/stdin )
[ -z "$msg" ] && {
echo
return 0
}
if [ "$( wc -l <<<"$msg" )" -gt 1 ]; then
while read -r line; do
lib_log $level $line
done <<< "$msg"
return
fi
local color=
local reset='\033[0m'
case $level in
ERR)
color='\033[0;31m'
;;
WARN|TIP)
color='\033[0;33m'
;;
NOTICE)
color='\033[0;32m'
;;
INFO)
color='\033[0;37m'
;;
DEBUG)
color='\033[0;31m'
;;
RUN)
color='\033[0;34m'
;;
CODE)
echo "$msg"
return
;;
DUMP)
color='\033[0;36m'
echo -e "$color$msg$reset" | sed 's/^/ /'
return
;;
PREFIX)
color='\033[0;34m'
;;
esac
if [[ -n "$level" ]]; then
printf "$color%*.6s$reset: %s\n" 6 "${level}_____" "$msg" >&2
else
echo "Error while log output msg: $msg"
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="lib_log_wrap \$FUNCNAME "
#lib_date_diff ()
#{
#
#}
lib_date_diff_human ()
{
local early_date=$1
local late_date=${2:-$(date '+%s')}
local diff
diff=$(( $late_date - $early_date ))
data="$(date -d@$diff -u '+%yy %jd %Hh %Mm %Ss')"
IFS=, read -r y d h m s <<<"${data// /,}"
y=$(( ${y::-1} - 70 ))y
d=$(( ${d::-1} - 1 ))d
#echo " $y $d $h $m $s"
echo " $y $d $h $m $s" | sed -E -e 's/ 00*/ /g' -e 's/ [ydhms]//g' | xargs
}
# OLD PIEECES OF CODE
# echo "export MANPAGER=less"
# #echo "export VIMINIT=let \$MYVIMRC='$XDG_CONFIG_HOME/vim/vimrc' \| source \$MYVIMRC"
# #echo "export VIMINIT='let \$MYVIMRC="$XDG_CONFIG_HOME/vim/vimrc"'"
# # Misc
# echo "export PYENV_ROOT=${XDG_OPT_HOME}/pyenv"
# echo "export PYTHONUSERBASE=${XDG_OPT_HOME}/python"
# echo "export PYTHONZ_ROOT=${XDG_OPT_HOME}/pythonz"
# echo "export PIPSI_BIN_DIR=${XDG_OPT_HOME}/python-venv/bin"
# echo "export LUA_CPATH=${XDG_OPT_HOME}/lua/?.so"
# echo "export LUA_PATH=${XDG_OPT_HOME}/lua/?.lua"
# echo "export LUAROCKS_CONFIG=~/.config/lua-${id}/luarocks.lua"
# echo "export GEM_HOME=${XDG_OPT_HOME}/ruby"
# echo "export GEMRC=~/.config/ruby-${id}/gemrc"
# echo "export GEM_SPEC_CACHE=${XDG_OPT_HOME}/ruby/gem/specs"
# echo "export COMPOSER_CACHE_DIR=${XDG_OPT_HOME}/composer"
# echo "export COMPOSER_HOME=${XDG_OPT_HOME}/composer"
# echo "export NPM_CONFIG_USERCONFIG=~/.config/npmrc"
# echo "export VAGRANT_HOME=${XDG_OPT_HOME}/vagrant"
# echo "export GOPATH=${XDG_OPT_HOME}/go"

58
lib/idmgr_mod_cloud.sh Normal file
View File

@ -0,0 +1,58 @@
#!/bin/bash
IDM_MOD_DEPS="id pass gpg ssh"
## Prompt functions
##########################################
#SHELL_PS1="${SHELL_PS1:-${PS1}"
idm_cloud ()
{
local action=${1-}
shift || true
idm_cloud_ls
}
idm_cloud__ls ()
{
local id=${1}
if idm_validate is_enabled $id; then
if [ -f "${OS_CLOUD-}" ]; then
echo " enabled ($OS_CLOUD)"
else
echo " disabled (config is absent ${OS_CLOUD:-${OS_CLOUD:+$OS_CLOUD}})"
fi
else
echo " disabled"
fi
}
idm_cloud__help ()
{
echo "S"
printf " %-20s: %s\n" "clouds enable" "Enable prompt"
printf " %-20s: %s\n" "clouds disable" "Disable prompt"
}
idm_cloud__enable ()
{
local id=${1}
if [ -f "~/.config/openstack/${id}_clouds.yaml" ]; then
echo "export OS_CLOUD=~/.config/openstack/${id}_clouds.yaml"
#echo "export OS_REGION_NAME=~/.config/openstack/${id}_clouds.yaml"
fi
}
idm_cloud__disable ()
{
echo "unset OS_CLOUD"
return
}
idm_cloud__kill () { idm_cloud__disable ${@-}; }

View File

@ -2,20 +2,234 @@
IDM_MOD_DEPS="id"
## Required functions
##########################################
## User functions
##############################
idm_git__help ()
{
local id=$1
echo "Git"
printf " %-20s: %s\n" "git init" "Start a local repo"
printf " %-20s: %s\n" "git scan" "Search and add interesting files"
printf " %-20s: %s\n" "git enabled" "Enable as default git"
printf " %-20s: %s\n" "git ls" "Show tracked files"
printf " %-20s: %s\n" "git disable" "Disable as default git"
printf " %-20s: %s\n" "git kill" "Like disable"
echo
printf " %-20s: %s\n" "git --help" "Git wrapper"
printf " %-20s: %s\n" "git [cmd]" "Git wrapper"
if idm_validate id_config $id; then
idm_git_init $id
if lib_git_is_repo $git_local_dir $git_local_work_tree ; then
echo
idm_git_init $id
echo " Config:"
$GIT_LOCAL config -l | sort \
| grep -E '(core|remote|include|remote|user|status)\.' #| sed 's/^/ /'
fi
fi
}
idm_git__init ()
{
local id=$1
shift 1
opts=${*-}
# Sanity check
idm_validate id_config $id
idm_git_init $id
# Check local repo
if lib_git_is_repo $git_local_dir $git_local_work_tree ; then
lib_log WARN "Do you want to override the esixting repo?"
idm_cli_timeout 1 || idm_exit 1 "User cancelled"
fi
$GIT_LOCAL init $opts
lib_log NOTICE "Repository has been created into '$git_local_dir'"
# Generate
$GIT_LOCAL config --add include.path "$git_local_config"
idm_git__gen_git_config > $git_local_config
}
idm_git__scan ()
{
local id=$1
idm_validate id_config $id
idm_git_init $id
# Ensure we have a valid repository
if ! lib_git_is_repo $git_local_dir $git_local_work_tree ; then
lib_log WARN "Do you want to create a local repository of your secrets?"
idm_cli_timeout 1 || idm_exit 1 "User cancelled"
$GIT_LOCAL init
fi
# Add all files
$GIT_LOCAL add -f $( xargs <<<"$( idm_git__get_files_of_interest $id )" )
# Check uncommited changes
if ! lib_git_is_all_commited $git_local_dir $git_local_work_tree ; then
lib_log INFO "There are the files we could add:"
$GIT_LOCAL status -s
lib_log PROMPT "Do you want to add these files to your repo?"
if idm_cli_timeout 1; then
tty=$(tty)
#$GIT_LOCAL commit -e
echo "Add: Import $(hostname) data" | $GIT_LOCAL commit --file=-
else
lib_log TIP "Commit your files with 'i git commit '"
fi
else
lib_log INFO "Nothing to add ..."
fi
}
idm_git__ls ()
{
local id=$1
idm_git_init $id
$GIT_LOCAL ls-files | sort
#$GIT_LOCAL ls-files | sort | sed 's@/[^\/]*@@'
return
if idm_validate id_config $id; then
idm_git_init $id
if lib_git_is_repo $git_local_dir $git_local_work_tree ; then
$GIT_LOCAL ls-files | sort | sed 's/^/ ~\//'
else
echo "Repository is not created"
fi
fi
#tree $
}
idm_git__enable ()
{
local id=$1
idm_git_init $id
cat <<EOF -
export GIT_DIR="$git_local_dir"
export GIT_WORK_TREE="$git_local_work_tree"
EOF
}
idm_git__disable ()
{
echo "unset GIT_DIR GIT_WORK_TREE"
}
idm_git__kill () { idm_git__disable ${@-}; }
idm_git ()
{
local action=$1
local id=$2
shift 2
local opts=${*-}
idm_git_init $id
$GIT_LOCAL $action $opts
}
## External deps
##############################
_git_local2 ()
{
lib_git_bin $git_local_dir $git_local_work_tree ${*-}
}
idm_vars_git_local () {
git_local_work_tree=$HOME
git_local_dir=$IDM_DIR_CACHE/git/$id/local.git
git_local_config=${IDM_CONFIG_DIR}/git/$id/local_gitconfig
git_local="lib_git_bin $git_local_dir $git_local_work_tree"
GIT_LOCAL=$git_local
}
idm_git_init ()
{
local id=$1
# Sanity check
idm_validate id_config $id
# Load local repo vars
idm_vars_git_local
}
####
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 $HOME/.openstack/$id/ $find_args 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"
}
idm_git__gen_git_config ()
{
(
cat <<EOF -
[status]
showuntrackedfiles = no
EOF
) | sed "s@$HOME/@~/@g"
}
# Debug libs
########################
# Debug and shortcuts
_git () { idm_git__bin ${@-}; }
idm_git_f () {
local id=$1
local cmd=$2
shift 2
local opts=${*-}
local rc=0
trap '' INT TERM EXIT
idm_validate id_config $id
idm_vars_git_local $id
idm_git_init $id
set -e
idm_git_${cmd#idm_git_} $opts
@ -30,209 +244,73 @@ idm_git_f () {
}
idm_git ()
idm_git__d ()
{
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_BIN git l
$IDM_BIN git status -s
$IDM_BIN git remote -v
{
$IDM_BIN git config -l \
| sort \
| grep -E '(core|remote|include|remote|user|status)\.'
}
}
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
## Future lib
##############################
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 ()
lib_git_bin ()
{
local git_dir=$1
local git_work_tree=$2
shift 2
local opts=${@-}
# Check if config is loaded (when called from other mods)
[ -n "${git_dir:-}" ] || idm_vars_git_local $id
local rc=0
# Check binary presence
#idm_require_bin git || \
# idm_exit 1 "Please install git first."
lib_require_bin git || \
idm_exit 1 "Please install git first."
# REALLY FUN BREAKER :(
#lib_log RUN "git --git-dir "$git_dir" --work-tree "$git_work_tree" $opts"
set +e
git \
--git-dir "$git_dir" \
--work-tree "$git_work_tree" \
-C "$git_work_tree" \
$opts
# --file "$git_config" \
# -C indlude.path=$gitconfig
# --include $gitconfig
$opts || rc=$?
set -e
#echo "You should be able to see $rc"
return ${rc:-0}
}
idm_git__is_repo ()
lib_git_is_repo ()
{
[ -d "$git_dir" ] && _git rev-parse > /dev/null 2>&1
local git_dir=$1
local git_work_tree=$2
[ -d "$git_dir" ] && lib_git_bin $git_dir $git_work_tree rev-parse > /dev/null 2>&1 ; return $?
}
idm_git__has_commits ()
lib_git_has_commits ()
{
if idm_git__is_repo $id; then
find "$git_dir" -type f &>/dev/null && return 0
fi
local git_dir=$1
local git_work_tree=$2
return 1
lib_git_is_repo $git_dir $git_work_tree || return $?
find "$git_dir" -type f &>/dev/null || return 1
}
idm_git__is_all_commited ()
lib_git_is_all_commited ()
{
[ "$( _git status -s | wc -l)" -eq 0 ]
local git_dir=$1
local git_work_tree=$2
[ "$( lib_git_bin $git_dir $git_work_tree 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
}

View File

@ -3,7 +3,7 @@
IDM_MOD_DEPS="id"
idm_gpg_help ()
idm_gpg__help ()
{
echo "Not implemented yet"
}
@ -11,10 +11,10 @@ idm_gpg_help ()
## Required functions
##########################################
idm_gpg_enable ()
idm_gpg__enable ()
{
local id=${1}
idm_is_enabled $id
idm_validate id_config $id
# Source environment
if [ -f "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env" ]; then
@ -26,7 +26,7 @@ idm_gpg_enable ()
# Check if socket is present
if [ ! -S "${GPG_AGENT_INFO-}" ]; then
rm -f "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env"
idm_gpg__start $id
idm_gpg_start $id
fi
# Show config to source
@ -39,40 +39,89 @@ idm_gpg_enable ()
}
idm_gpg_disable ()
idm_gpg__disable ()
{
local id=${1}
idm_is_enabled $id
idm_validate id_config $id
echo "unset GPG_AGENT_INFO GNUPGHOME GPG_TTY"
}
idm_gpg_kill ()
idm_gpg__kill ()
{
local id=${1}
idm_is_enabled $id
gpgconf --kill gpg-agent
idm_log NOTICE "Kill gpg-agent ..."
lib_log NOTICE "Kill gpg-agent ..."
idm_gpg_disable $id
idm_gpg__disable $id
#killall gpg-agent || true
#echo "echo 'GPG kill is not implemented yet ...'"
}
idm_gpg_ls ()
idm_gpg__ls ()
{
local id=${1}
idm_validate is_enabled $id || return 0
gpg --list-keys | sed 's/^/ /' #| lib_log DUMP -
}
idm_gpg__new ()
{
local id=${1}
idm_is_enabled $id
key="$( idm_gpg_match_one_pubkey $id )"
idm_gpg_cli_helper $id sub
gpg --edit-key $key addkey
lib_log NOTICE "Your subkey $name is ready :)"
}
# Should be used for subkeys ....
idm_gpg__init ()
{
local id=${1}
idm_is_enabled $id
gpg --list-keys | idm_log DUMP -
! idm_gpg_match_one_pubkey $id &>/dev/null || \
idm_exit 1 "You already have an id !"
# Generate top secret id
idm_gpg_cli_helper $id main
gpg --gen-key
# Generate encyption key
idm_gpg_new $id
lib_log NOTICE "Your personal key $name is ready :)"
}
idm_gpg__del ()
{
local id=${1}
local key=${2:-$1}
# Scan key
key=$(idm_gpg_match_one_pubkey $key)
lib_log WARN "Do you really want to destroy the '$key' key?"
idm_cli_timeout 1 || rc=$?
gpg --delete-key "$key" || true
gpg --delete-secret-key "$key" || true
}
## Internal functions
##########################################
idm_gpg__start ()
idm_gpg_start ()
{
local id=${1}
local gpghome=~/.config/gpg/$id
@ -98,15 +147,12 @@ idm_gpg__start ()
echo "export GPG_DEFAULT_ID=${GIT_AUTHOR_EMAIL:-$id}" >> "$runtime/env"
# Start agent
idm_log INFO "Start gpg-agent ..."
gpg-agent --daemon --extra-socket "$runtime/socket"
lib_log INFO "Start gpg-agent ..."
gpg-agent --daemon --extra-socket "$runtime/socket" || true
}
## Extended functions
##########################################
idm_gpg__cli_helper ()
idm_gpg_cli_helper ()
{
local id=${1}
local type=${2:-sub}
@ -119,65 +165,34 @@ idm_gpg__cli_helper ()
name=${GIT_AUTHOR_NAME}
fi
idm_log NOTICE "Please follow this recommendations:"
lib_log NOTICE "Please follow this recommendations:"
if [ "$type" == "sub" ]; then
idm_log $lvl "You may have to enter your principal key password."
idm_log $lvl "Type: 6 - RSA (encrypt only)"
lib_log $lvl "You may have to enter your principal key password."
lib_log $lvl "Type: 6 - RSA (encrypt only)"
elif [ "$type" == "main" ]; then
idm_log $lvl "Type: 4 - RSA (sign only)"
lib_log $lvl "Type: 4 - RSA (sign only)"
fi
# Common
idm_log $lvl "Size: 4096"
idm_log $lvl "Type: 2y"
lib_log $lvl "Size: 4096"
lib_log $lvl "Type: 2y"
if [ "$type" == "main" ]; then
idm_log $lvl "Name: ${name} (must be 5 char min!)"
idm_log $lvl "Email: ${GIT_AUTHOR_EMAIL}"
idm_log $lvl "Comment: <none>"
idm_log $lvl "Passphrase: Very strong"
lib_log $lvl "Name: ${name} (must be 5 char min!)"
lib_log $lvl "Email: ${GIT_AUTHOR_EMAIL}"
lib_log $lvl "Comment: <none>"
lib_log $lvl "Passphrase: Very strong"
elif [ "$type" == "main" ]; then
idm_log $lvl "Type: quit and save changes"
lib_log $lvl "Type: quit and save changes"
fi
idm_log NOTICE "PGP key generation interface"
lib_log NOTICE "PGP key generation interface"
}
idm_gpg_new ()
{
local id=${1}
idm_is_enabled $id
key="$( idm_gpg__get_def_key $id )"
idm_gpg__cli_helper $id sub
gpg --edit-key $key addkey
idm_log NOTICE "Your subkey $name is ready :)"
}
# Should be used for subkeys ....
idm_gpg_init ()
{
local id=${1}
idm_is_enabled $id
! idm_gpg__get_def_key $id &>/dev/null || \
idm_exit 1 "You already have an id !"
# Generate top secret id
idm_gpg__cli_helper $id main
gpg --gen-key
# Generate encyption key
idm_gpg_new $id
idm_log NOTICE "Your personal key $name is ready :)"
}
idm_gpg__get_def_key ()
idm_gpg_match_one_pubkey ()
{
key=${1}
@ -185,40 +200,26 @@ idm_gpg__get_def_key ()
gpg2 --list-keys | grep "uid"| grep "${key:-}" \
| sed -E 's/[^<]*<([^>]*)>.*/\1/'
) || {
idm_log WARN "Could not find a matching key for '$key'"
lib_log WARN "Could not find a matching key for '$key'"
return 1
}
if [ "$( wc -l <<<"$key")" -ne 1 ]; then
idm_log WARN "Too much keys for matching '$1'"
idm_log DUMP - <<<"$key"
lib_log WARN "Too much keys for matching '$1'"
lib_log DUMP - <<<"$key"
return 1
fi
echo "$key"
}
idm_gpg_del ()
{
local id=${1}
local key=${2:-$1}
# Scan key
key=$(idm_gpg__get_def_key $key)
idm_log WARN "Do you really want to destroy the '$key' key?"
idm_cli_timeout 1 || rc=$?
gpg --delete-key "$key" || true
gpg --delete-secret-key "$key" || true
}
## GPG shared lib
##############################
# 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() {
lib_gpg_is_valid_recipients() {
typeset -a recipients
recipients=($@)
@ -226,13 +227,13 @@ idm_gpg__is_valid_recipients() {
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."
lib_log ERR "${gpg_id} is not a valid key ID."
return 1
fi
done
}
idm_gpg__is_valid_key() {
lib_gpg_is_valid_key() {
typeset -a recipients
recipients=($@)
# At least one private key must be present
@ -244,3 +245,109 @@ idm_gpg__is_valid_key() {
done
return 1
}
lib_gpg_decrypt_dir ()
{
local src=$1
local dst=${2-}
local key=${3-}
local gpg_opts=""
local tar_opts=
#set -x
# Check required bin
lib_require_bin tar || idm_exit 1
lib_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
$GPG $gpg_opts $src | $TAR $tar_opts || \
idm_exit 1 ERR "Could not decrypt file: $src into $dst"
}
lib_gpg_encrypt_dir ()
{
local src=$1
local dst=$2
local key=${3-}
local pass=
local recipients=
# Check required bin
lib_require_bin tar || idm_exit 1
lib_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 lib_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
lib_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"
lib_log NOTICE "Secret will be encrypted with pass '$pass'"
else
lib_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"
lib_log NOTICE "User will be prompted for known recipients"
elif [ -z "$key" -o "$key" == "_PASS" ]; then
pass=
key=
gpg_opts="-c"
lib_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 "
lib_log NOTICE "Secret will be encrypted with pass '***' (symetric)"
fi
fi
# 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.
}

View File

@ -6,7 +6,7 @@ IDM_MOD_DEPS=""
##########################################
idm_id_help ()
idm_id__help ()
{
echo "Identity management:"
printf " %-20s: %s\n" "id ls" "List all disks of all policies"
@ -20,19 +20,19 @@ idm_id_help ()
idm_id ()
{
idm_id_ls ${@-}
idm_id__ls ${@-}
}
idm_id_disable()
idm_id__disable()
{
# Disable internal variables
echo "unset SHELL_ID GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL" | idm_log CODE -
echo "unset SHELL_ID GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL" | lib_log CODE -
}
idm_id_kill () { idm_id_disable ${@-}; }
idm_id__kill () { idm_id__disable ${@-}; }
idm_id_enable()
idm_id__enable()
{
local id=${1}
local conf="$IDM_DIR_ID/$id.env"
@ -65,7 +65,7 @@ idm_id_enable()
# echo "export XDG_OPT_HOME=$XDG_OPT_HOME"
}
idm_id_new ()
idm_id__new ()
{
local id=${2:-$1}
@ -81,12 +81,12 @@ idm_id_new ()
$EDITOR "$conf"
# Notice user
idm_log NOTICE "Id '$id' has been created:"
cat $conf | idm_log CODE -
lib_log NOTICE "Id '$id' has been created:"
cat $conf | lib_log CODE -
}
idm_id_show ()
idm_id__show ()
{
local id=${1}
local conf
@ -98,15 +98,16 @@ idm_id_show ()
conf="$IDM_DIR_ID/$id.env"
# Notice user
idm_log INFO "Id '$id' configuration:"
idm_get id_config $id | idm_log CODE -
# cat $conf | idm_log CODE
lib_log INFO "Id '$id' configuration:"
idm_get id_config $id | lib_log CODE -
# cat $conf | lib_log CODE
}
idm_id_ls ()
idm_id__ls ()
{
local active
#set -x
for id in $(idm_get all_id); do
@ -125,11 +126,11 @@ idm_id_ls ()
eval "$(idm_get id_config $id)"
echo "$active:$id::::${common_name-} (${email-})"
)
done | column -t -s: -o' ' | idm_log DUMP -
done | column -t -s: -o' ' #| lib_log DUMP -
}
idm_id_edit ()
idm_id__edit ()
{
local id=${1}
local md5 conf
@ -144,14 +145,14 @@ idm_id_edit ()
# Notice user
if [[ "$md5" == "$(md5sum $conf)" ]] ;then
idm_log INFO "Id '$id' has not been updated:"
lib_log INFO "Id '$id' has not been updated:"
else
idm_log NOTICE "Id '$id' has been updated:"
lib_log NOTICE "Id '$id' has been updated:"
fi
cat $conf | idm_log CODE -
cat $conf | lib_log CODE -
}
idm_id_get ()
idm_id__get ()
{
local id=${1}
@ -168,14 +169,14 @@ idm_id_get ()
}
idm_id_dump ()
idm_id__dump ()
{
for id in $(idm_get all_id); do
#idm_log NOTICE "Identity $id"
#lib_log NOTICE "Identity $id"
{
idm_get id_config $id
echo " "
} | idm_log CODE -
} | lib_log CODE -
done
}
@ -192,7 +193,7 @@ idm_id_template ()
echo "tz=$tz"
}
idm_id_rm ()
idm_id__rm ()
{
local id=${1}
@ -206,6 +207,6 @@ idm_id_rm ()
rm "$IDM_DIR_ID/$id.env" || \
idm_exit 1 ERR "File '$IDM_DIR_ID/$id.env' could not be deleted"
else
idm_log WARN "File '$IDM_DIR_ID/$id.env' was already deleted"
lib_log WARN "File '$IDM_DIR_ID/$id.env' was already deleted"
fi
}

View File

@ -11,7 +11,7 @@ idm_pass ()
#set -x
if [ "$#" -eq 1 ]; then
local id=$1
idm_pass_ls $id
idm_pass__ls $id
return 0
else
local action=$1
@ -28,15 +28,15 @@ idm_pass ()
}
idm_pass_ls ()
idm_pass__ls ()
{
local id=${1}
idm_is_enabled $id
idm_validate is_enabled $id || return 0
PASSWORD_STORE_DIR=~/.config/pass/${id} pass ls
PASSWORD_STORE_DIR=~/.config/pass/${id} pass ls | sed 's/^/ /'
}
idm_pass_help ()
idm_pass__help ()
{
echo "Standard UNIX Password Manager"
printf " %-20s: %s\n" "pass ls" "List passwords"
@ -49,19 +49,19 @@ idm_pass_help ()
}
idm_pass_enable ()
idm_pass__enable ()
{
local id=${1}
idm_is_enabled $id
! idm_validate id_config $id
echo "export PASSWORD_STORE_DIR=~/.config/pass/${id}"
}
idm_pass_disable ()
idm_pass__disable ()
{
local id=${1}
idm_is_enabled $id
idm_validate id_config $id
echo "unset PASSWORD_STORE_DIR"
}

View File

@ -15,7 +15,7 @@ idm_ps1 ()
idm_ps1_ls
}
idm_ps1_ls ()
idm_ps1__ls ()
{
local id=${1}
@ -23,21 +23,21 @@ idm_ps1_ls ()
#echo "PS1=${SHELL_PS1:-${PS1-}}"
if grep -q "($id)" <<<"${SHELL_PS1:-${PS1-}}" ; then
echo "enabled"
echo " enabled"
else
echo "disabled"
echo " disabled"
fi
}
idm_ps1_help ()
idm_ps1__help ()
{
echo "Shell Prompt"
printf " %-20s: %s\n" "ps1 enable" "Enable prompt"
printf " %-20s: %s\n" "ps1 disable" "Disable prompt"
}
idm_ps1_enable ()
idm_ps1__enable ()
{
local id=${1}
id="\[\033[0;34m\]($id)\[\033[00m\]"
@ -49,10 +49,10 @@ idm_ps1_enable ()
}
idm_ps1_disable ()
idm_ps1__disable ()
{
echo "export PS1=\"\${IDM_SHELL_PS1}\""
return
}
idm_ps1_kill () { idm_ps1_disable ${@-}; }
idm_ps1__kill () { idm_ps1__disable ${@-}; }

View File

@ -8,7 +8,7 @@ IDM_MOD_DEPS="id gpg"
## SSH functions
##########################################
idm_ssh_help ()
idm_ssh__help ()
{
echo "Secure Shell"
# printf " %-20s: %s\n" "info" "Info submenu"
@ -29,7 +29,7 @@ idm_ssh ()
# Argument maangement
if [ "$#" -eq 1 ]; then
local id=$1
idm_ssh_ls $id
idm_ssh__ls $id
return 0
else
local action=$1
@ -50,30 +50,32 @@ idm_ssh ()
## Required functions
##########################################
idm_ssh_ls ()
idm_ssh__ls ()
{
local id=$1
local opt=${2:--l}
local opt=-l
idm_is_enabled $id
idm_validate is_enabled $id || return 0
{ ssh-add $opt || true ; } | idm_log DUMP -
{ ssh-add $opt || true ; } | sed 's/^/ /'
}
idm_ssh_disable ()
idm_ssh__disable ()
{
local id=$1
idm_is_enabled $id
#idm_is_enabled $id
idm_validate id_config $id
# Return portion of code to clean
echo "unset SSH_AUTH_SOCK SSH_AGENT_PID"
}
idm_ssh_enable ()
idm_ssh__enable ()
{
local id=$1
idm_is_enabled $id
idm_validate id_config $id
# Source environment
if [ -f "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env" ] ; then
@ -85,7 +87,7 @@ idm_ssh_enable ()
# Check status
if ! idm_ssh__is_agent_working $id ${SSH_AUTH_SOCK:-_} ${SSH_AGENT_PID:-0}; then
if ! idm_ssh__agent_start $id; then
idm_log WARN "Could not start ssh agent :("
lib_log WARN "Could not start ssh agent :("
return 1
fi
fi
@ -95,7 +97,7 @@ idm_ssh_enable ()
}
# LOGOUT
idm_ssh_kill () {
idm_ssh__kill () {
#set -x
@ -104,7 +106,7 @@ idm_ssh_kill () {
idm_is_enabled $id
#idm_log NOTICE "Cleaning ssh-agent ..."
#lib_log NOTICE "Cleaning ssh-agent ..."
[ -z "${SSH_AGENT_PID-}" ] && \
[ -f "$run_dir/env" ] && \
@ -113,7 +115,7 @@ idm_ssh_kill () {
# Clean ssh-agent process
if kill -0 ${SSH_AGENT_PID-} &>/dev/null; then
/usr/bin/ssh-agent -k >/dev/null
idm_log NOTICE "Kill ssh-agent ..."
lib_log NOTICE "Kill ssh-agent ..."
fi
#eval "$(/usr/bin/ssh-agent -k 2>/dev/null)"
@ -122,7 +124,7 @@ idm_ssh_kill () {
rm "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env"
# Disable agent
idm_ssh_disable $id
idm_ssh__disable $id
set +x
@ -168,9 +170,9 @@ idm_ssh__agent_start() {
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 ..."
lib_log INFO "Start ssh-agent ..."
else
idm_log WARN "Could not start ssh agent :("
lib_log WARN "Could not start ssh agent :("
return 1
fi
@ -205,7 +207,7 @@ idm_ssh__agent_clean () {
fi
unset SSH_AUTH_SOCK SSH_AGENT_PID
#idm_log INFO "ssh-agent env cleaned is now clean"
#lib_log INFO "ssh-agent env cleaned is now clean"
}
@ -244,8 +246,8 @@ idm_ssh_add ()
[ -n "$pub_keys" ] || \
idm_exit 0 WARN "No keys found"
idm_log INFO "Adding keys:"
xargs -n 1 <<<$key_list | idm_log DUMP -
lib_log INFO "Adding keys:"
xargs -n 1 <<<$key_list | lib_log DUMP -
echo ""
ssh-add $key_list
@ -269,12 +271,12 @@ idm_ssh__agent_check ()
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"
lib_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"
lib_log WARN "Socket '$socket' is dead, can't recover ssh-agent"
idm_ssh__agent_clean $id $socket 0
return 1
fi
@ -283,13 +285,13 @@ idm_ssh__agent_check ()
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"
lib_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"
lib_log DEBUG "Multiple PID founds for ssh-agent: $pid"
q=0
for p in $pid; do
return
@ -304,7 +306,7 @@ idm_ssh__agent_check ()
# Hmm, we should not arrive here ...
idm_log WARN "ssh-agent is in a really weird state :/"
lib_log WARN "ssh-agent is in a really weird state :/"
return 1
}

View File

@ -14,17 +14,22 @@ IDM_MOD_PREF="core id"
#
# This allow to secure your things ....
#set -x
idm_vars_git_tomb () {
git_tomb_work_tree=$HOME
git_tomb_dir=$IDM_DIR_CACHE/git/$id/tomb.git
git_tomb_config=${IDM_CONFIG_DIR}/git/$id/tomb_gitconfig
git_tomb_enc=$IDM_CONFIG_DIR/enc/$id.tomb
}
## Common functions
## Front functions
##############################
idm_tomb_help ()
idm_tomb__help ()
{
local id=$1
idm_vars_git_tomb $id
idm_vars_git_tomb
echo "tomb"
echo " workflow:"
@ -33,286 +38,501 @@ idm_tomb_help ()
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 push <remote>|all" "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"
printf " %-20s: %s\n" "git_tomb_enc" "$git_tomb_enc"
printf " %-20s: %s\n" "git_tomb_dir" "$git_tomb_dir"
printf " %-20s: %s\n" "git_tomb_config" "$git_tomb_config"
return 0
}
idm_tomb_ls ()
idm_tomb__ls ()
{
local id=$1
idm_vars_git_tomb $id
idm_vars_git_tomb
local g_st=
local t_st=
local d_c=
local d_m=
local date_today=$(date '+%s')
if [ -d "$git_tomb_dir" ]; then
g_st=open
g_m=$( lib_date_diff_human $(find $git_tomb_dir -maxdepth 0 -printf "%Ts") )
g_m=" $d_m"
else
g_st=closed
g_m=
fi
if [ -f "$git_tomb_enc" ]; then
t_st=present
t_m=$( lib_date_diff_human $(find $git_tomb_enc -printf "%Ts") )
t_m=", $t_m old"
else
t_st=absent
t_m=
fi
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" ""
printf " %-20s: %s\n" "encrypted tomb" "$t_st${t_m}"
printf " %-20s: %s\n" "encrypted file" "$git_tomb_enc"
printf " %-20s: %s\n" "tomb git status" "$g_st$g_m"
printf " %-20s: %s\n" "tomb git dir" "$git_tomb_dir"
echo " Remotes:"
_git_local remote -v | sed 's/^/ /'
if lib_git_is_repo $git_tomb_dir $git_tomb_work_tree; then
echo " Git remotes:"
_git_tomb remote -v | sed 's/^/ /'
fi
}
# This leave everything open at this stage !!!
idm_tomb__sync ()
{
local id=$1
local repo_name=${2:-tomb}
# Sanity check: id and local repo
idm_tomb_require_enabled $id
idm_tomb_require_valid_local_repo
# Tomb repo check
#set -x
if ! lib_git_is_repo $git_tomb_dir $git_tomb_work_tree; then
if [ -f "$git_tomb_enc" ]; then
lib_log WARN "An encrypted tomb has been found. Do you want to decrypt it?"
idm_cli_timeout 1 || idm_exit 1 ERR "Refuse to create a tomb duplicate"
idm_tomb__decrypt $id || idm_exit 1 ERR "Failed to create tomb repo"
elif [ ! -d "$git_tomb_dir" ]; then
idm_tomb__init $id || idm_exit 1 ERR "Tomb cannot be used without git"
lib_log NOTICE "A tomb has been created"
return 0
else
idm_exit 1 ERR "Unknow error"
fi
fi
# Work on local
_git_tomb remote show $repo_name &>/dev/null ||
_git_tomb remote add $repo_name $git_tomb_dir ||
idm_exit 1 ERR "Failed to add tomb remote to local git"
{
_git_tomb fetch --all --tags &&
_git_tomb push -u $repo_name --all &&
_git_tomb push -u $repo_name --tags
} >/dev/null || idm_exit 1 ERR "Something where wrong while syncinc"
lib_log NOTICE "Tomb and local repository are now synced"
# Restore ctx
}
# We manage distribution of our repo
# but maybe it should be the lib_git_local roles ...
idm_tomb__push ()
{
local id=$1
local arg=${2-}
idm_tomb__init $id
# Manage argument
if grep -sq "$arg" $IDM_CONFIG_DIR/git/$id/known_hosts ; then
arg=$( grep -sq "$arg" $IDM_CONFIG_DIR/git/$id/known_hosts | head -n 1 )
idm_tomb_ssh_sync $arg ||
idm_exit 1 "Could not copy tomb to $arg"
lib_log NOTICE "Tomb has been exported: $arg:$dst/$id.tomb"
elif [ "$arg" == 'all' ]; then
remotes="$(_git_tomb remote -v | awk '{ print $1 }' | uniq )"
for repo_name in $remotes; do
lib_log INFO "Synchronising remote $repo_name ..."
_git_tomb fetch --all --tags &&
_git_tomb push -u $repo_name --all &&
_git_tomb push -u $repo_name --tags ||
lib_log WARN "Could not sync with $reponame"
done
elif _git_tomb remote -v | grep -q "^$arg"; then
idm_tomb__sync $id $arg
else
# Actually export the tomb :p
#ssh $arg "hostname" ||
# idm_exit 1 "Could not connect to $arg"
#idm_tomb_gen_script_export | lib_log DUMP -
lib_log INFO "Trying to connect to $arg ..."
dst=$( ssh $arg "$(idm_tomb_gen_script_export)" ) ||
idm_exit 1 "Something failed $arg"
echo "$arg" >> $IDM_CONFIG_DIR/git/$id/known_hosts
scp $git_tomb_enc $arg:$dst/$id.tomb ||
idm_exit 1 "Could not copy tomb to $arg"
lib_log NOTICE "Tomb has been exported: $arg:$dst/$id.tomb"
fi
#if ssh $arg "hostname" > /den/null; then
# idm_exit 0 "SSH sync not implemented yet "
#else
# # Propagate with git
# idm_tomb__sync $id
#fi
}
idm_tomb_ssh_sync ()
{
local host=$1
local dst=
# Test connection and prepare destination
lib_log INFO "Trying to connect to $host ..."
dst=$( ssh $host "$(idm_tomb_gen_script_export)" ) ||
idm_exit 1 "Something failed $host"
# Save host
echo "$host" >> $IDM_CONFIG_DIR/git/$id/known_hosts
# Copy tomb to remote
scp $git_tomb_enc $host:$dst/$id.tomb
}
idm_tomb_gen_script_export ()
{
cat <<EOF -
dest=\${IDM_CONFIG_DIR:-\${XDG_CONFIG_HOME:-~/.config}/idmgr}/enc
mkdir -p \$dest || {
echo "Could not create destination dir: \$dest"
exit 1
}
echo \$dest
EOF
}
idm_tomb__encrypt ()
{
local id=$1
# Sanity check: id and local repo
idm_tomb__init $id
#idm_tomb_require_enabled $id
#idm_tomb_require_valid_local_repo || idm_exit 1 ERR "Cound not continue"
# We check tomb repo here
lib_git_is_repo $git_tomb_dir $git_tomb_work_tree || \
idm_tomb__init $id || \
idm_exit 1 ERR "Tomb cannot be used without git"
# Full sync both repo
idm_tomb__sync $id ||
idm_exit 1 ERR "Failed to push commits to tomb repo"
# Encrypt tomb data
lib_gpg_encrypt_dir $git_tomb_dir $git_tomb_enc || \
idm_exit 1 ERR "Failed to create tomb"
## Encrypt local data
lib_gpg_encrypt_dir $git_local_dir $git_local_enc $GIT_AUTHOR_EMAIL || \
idm_exit 1 ERR "Could not create local repo data"
# Clean tomb
rm -rf $git_tomb_dir
lib_log NOTICE "Tomb has been closed into: $git_tomb_enc"
}
idm_tomb__decrypt ()
{
local id=$1
shift || true
local opt=${@-}
# Sanity check
idm_tomb_require_enabled $id
idm_tomb_require_valid_local_repo || idm_exit 1 ERR "Cound not continue"
# Check if tomb repo is absent
##_load_tomb_env
if lib_git_is_repo $git_tomb_dir $git_local_work_tree ; then
lib_log WARN "A local repo is already present, we will overwrite it. Do you want to continue?"
idm_cli_timeout 0 || idm_exit 1 ERR "Refuse to override existing repo"
# Let's not delete existing repo, just for fun and wee how git react :p
fi
# Extract tomb
lib_gpg_decrypt_dir $git_tomb_enc $git_tomb_dir || \
idm_exit 1 ERR "Could not extract tomb"
# Extract local repo
if idm_tomb_require_valid_local_repo; then
# Local repo always win !, so we just sync
lib_log INFO "Local repo already present, we just start sync"
idm_tomb__sync $id
else
lib_gpg_decrypt_dir $git_tomb_enc $git_tomb_dir || \
idm_exit 1 ERR "Could not extract tomb"
fi
lib_log NOTICE "Your tomb has been decrypted"
}
idm_tomb__init()
{
local id=$1
shift
# Sanity check: id and local repo
idm_tomb_require_enabled $id
idm_tomb_require_valid_local_repo || idm_exit 1 ERR "Cound not continue"
# Load tomb environment from local
if [ ! -d "$git_tomb_dir" ] ; then
mkdir -p "$git_tomb_dir"
_git_tomb clone --bare $git_local_dir $git_tomb_dir || \
idm_exit 1 ERR "Could not create tomb repo"
lib_log NOTICE "Tomb repository has been created"
else
lib_log INFO "Tomb repository alreay exists"
fi
# Load tomb environment from encrypted_tomb
# Load tomb environment from user@server/encrypted.tomb
# Syncrhonise with tomb
if lib_git_has_commits $git_local_dir $git_local_work_tree ; then
idm_tomb__sync $id
fi
lib_log NOTICE "Tomb repository has been created"
}
idm_tomb__shred ()
{
local id=$1
local arg=${2-}
local files=
idm_tomb_require_enabled $id
case $arg in
local) files="$git_local_dir" ;;
tomb) files="$git_tomb_dir" ;;
all) files="$git_tomb_dir $git_local_dir" ;;
full) files="$git_tomb_dir $git_local_dir $git_local_enc" ;;
disapear) files="$git_tomb_dir $git_local_dir $git_local_enc $( idm_git__get_files_of_interest $id | sed 's@^@~/@' | xargs )" ;;
*)
idm_exit 1 "You need to say: local|tomb|all|full"
;;
esac
lib_log WARN "All these files will be IRREVOCABLY DELETED."
xargs -n 1 <<< "$files" | lib_log DUMP -
lib_log WARN "Do you want to continue ?"
idm_cli_timeout 1 || idm_exit 1 ERR "No data deleted"
lib_log WARN "Run it yourself: rm -rf $files"
}
idm_tomb__enable () { return 0; }
idm_tomb__disable () { return 0; }
idm_tomb__kill () { return 0; }
## IDM API functions
##############################
## Internal functions
##############################
idm_git__bin_git ()
idm_tomb_require_enabled ()
{
if idm_validate id_config $1; then
id=${1} ;shift
fi
idm_vars_git_local $id
idm_git__bin ${*-}
local id=$1
# Sanity check
idm_validate id_config $id
# Load local repo vars
idm_vars_git_local
git_local_enc=$IDM_CONFIG_DIR/enc/$id.tomb
# Load tomb vars
idm_vars_git_tomb
}
# A wrapper before calling git
idm_tomb__bin_git ()
_git_tomb ()
{
# Ugly bugfix :(
if idm_validate id_config $1; then
id=${1} ;shift
fi
idm_vars_git_tomb $id
idm_git__bin ${*-}
lib_git_bin $git_tomb_dir $git_tomb_work_tree $@ || return
rc=$?
#echo "RETURN2: $rc"
return $rc
}
# 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 ${*-}; }
_git_local ()
{
local rc=0
lib_git_bin $git_tomb_dir $git_tomb_work_tree $@ || rc=$?
return $rc
}
## Module functions
##############################
idm_vars_git_tomb()
idm_tomb_require_valid_local_repo ()
{
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
if ! lib_git_is_repo $git_local_dir $git_local_work_tree ; then
idm_exit 1 NOTICE "You need to have a local repo first"
elif ! idm_git__has_commits ; then
elif ! lib_git_has_commits $git_local_dir $git_local_work_tree ; 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.
}
# Moved to mod_gpg
# ## GPG functions
# ##############################
#
#
# lib_gpg_decrypt_dir ()
# {
# local src=$1
# local dst=${2-}
# local key=${3-}
# local gpg_opts=""
# local tar_opts=
#
# # Check required bin
# lib_require_bin tar || idm_exit 1
# lib_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
#
# $GPG $gpg_opts $src | $TAR $tar_opts || \
# idm_exit 1 ERR "Could not decrypt file: $src into $dst"
#
# }
#
#
# lib_gpg_encrypt_dir ()
# {
# local src=$1
# local dst=$2
# local key=${3-}
# local pass=
# local recipients=
#
# # Check required bin
# lib_require_bin tar || idm_exit 1
# lib_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 lib_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
# lib_gpg_is_valid_recipients $r &>/dev/null \
# && ok=$(( $ok + 1 ))\
# || ko=$(( $ko + 1 ))
#
# if [[ "$ok" -ne 0 && "$ko" -ne 0 ]]; then
# idm_exit 1 ERR "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"
# lib_log NOTICE "Secret will be encrypted with pass '$pass'"
# else
# lib_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"
# lib_log NOTICE "User will be prompted for known recipients"
# elif [ -z "$key" -o "$key" == "_PASS" ]; then
# pass=
# key=
# gpg_opts="-c"
# lib_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 "
# lib_log NOTICE "Secret will be encrypted with pass '***' (symetric)"
# fi
# fi
#
# # 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.
#
# }
#
#
#
#
#
#
#