diff --git a/README.md b/README.md index e69de29..20da6f4 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,48 @@ + + +## Quickstart +There you go +``` +git clone +dc idmgr +eval "$( bin/idmgr shell)" +``` + + +## Future doc + +Other scripts of interest to implement: + +* Pass mod: +** Install firefox +** Install Chromium +* Encrypt mod: + * https://github.com/essentialkaos/mkcryptpasswd + * https://github.com/dyne/Tomb (Need root :( ) + * https://github.com/nodesocket/cryptr => AES encyption, very nice + * https://github.com/vitalibarozzi/Flying-Tower , nice alt on upper link, best client ! + * https://github.com/Tinram/GPGit Encrypt with gpg + * https://github.com/burianvlastimil/openssl-file-encryption-decryption-shell-scripts , aes256 + * https://github.com/alexanderepstein/Bash-Snippets : many snippets + * https://github.com/elasticdog/transcrypt: Git transparent encryption , boaf, pk pas ... + * https://github.com/josh/senv : Encrypt env variables + * https://github.com/abemassry/wsend-gpg: Send a file to a remote + * https://github.com/SixArm/gpg-encrypt : encrypt/decrypt + * https://github.com/rolandshoemaker/raziel : Encrypted auto installer, why not ? + * https://github.com/morishin/locker : Password file encryption, with edition possible, pretty cool + * https://github.com/windowsrefund/safe : Dir encrypter + * https://github.com/chadoe/luks-triple-unlock : unlock luks + +* Proactive sec: + * https://blog.kintoandar.com/2012/01/attack-detection-and-notification-with.html : iptables IDS + +* VPN modules: + * https://github.com/kintoandar/shell_scripts/blob/master/automation/vpn_ssh.sh + * ssh_rport + +* x509 mod: +** pkictl +* Backup: +** https://github.com/ccztux/glsysbackup +* Other scripts +** https://github.com/tzhenghao/MagicSnippets diff --git a/bin/idmgr b/bin/idmgr index cdf7fa2..f48e291 100755 --- a/bin/idmgr +++ b/bin/idmgr @@ -54,6 +54,7 @@ idm_init () IDM_MOD_FILES=$(idm_mod_files) IDM_MOD_ORDER=$(idm_mod_list) + export IDM_TIMEOUT_USER=10 # Load modules for i in $IDM_MOD_FILES ; do @@ -101,7 +102,9 @@ idm_core_help () idm_log () -{ +{ + set +x + local level=$1 shift || true local msg="$@" @@ -151,6 +154,144 @@ idm_log () fi } + + +idm_exit () +{ + set +x + local rc=${1:-0} + local msg lvl + + # Check exit status + if [ "$#" -eq 3 ]; then + lvl=${2:-DEBUG} + msg=${3:-} + else + lvl=DEBUG + msg=${2:-} + fi + + + if [[ "$rc" -ne 0 ]]; then + #idm_trace || true + idm_log $lvl "$msg (rc=$rc)" + else + idm_log $lvl "$msg" + fi + + # Remove trap + trap "" INT TERM EXIT + + # Exit for good + exit $rc +} + +idm_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 + #idm_log DEBUG "Trace $i: $trace" + #traces="${traces}${trace}\n" + echo "$trace" + fi + done | tac | column -t + [ -z "$msg" ] || echo "Trace ctx: $msg" + ) | >&2 idm_log DUMP - +} + +idm_exit_trap() { + set +x + rc=$? + if [[ $rc -ne 0 ]]; then + idm_trace || true + idm_log ERR "The script exited with exit code: $rc" + fi + exit $rc +} + + +idm__load_lib () +{ + local lib_name=${1} + local lib_args=${@-} + local env_var=IDM_LIB_${lib_name^^} + + #idm_log DEBUG "$env_var=${!env_var}" + [ -z "${!env_var-}" ] || return 0 + + cmd="$(command -v $lib_name || true )" + + if [ -x "${cmd:-_}" ]; then + + . "$cmd" $lib_args + declare -g $env_var=$cmd + idm_log INFO "Loaded lib: $env_var=${!env_var}" + #set -x + + else + idm_exit 1 "Could not find 'safe' executable in \$PATH (missing module dependency)" + fi +} + +# This function display a user skippable timeout. +idm_cli_timeout () +{ + local default_rc=${1:-1} + local wait_time=${2:-$IDM_TIMEOUT_USER} + local start=$(date '+%s') + local human_word go_word + + # Humanise ... + [ "$default_rc" -ge 0 ] || default_rc=1 + if [ "$default_rc" -eq 0 ]; then + human_word="abort" + go_word=QUIT + elif [ "$default_rc" -ne 0 ]; then + human_word="continue" + go_word=GO + fi + + # Notifying user + local human_date="$(date -d@$wait_time -u '+%Hh%Mm%Ss' | sed 's/00.//g' )" + local human_msg="Type '$go_word' to $human_word ($human_date):" + + # Wait user input or timeout ... + local answer= + local rc=0 + read -t $wait_time -p " ASK: ${human_msg} " answer || rc=$? + local remaining=$(( $wait_time - ( $(date '+%s') - $start ) )) + + # Make a decision + if [[ "$rc" -eq 142 ]]; then + # We timeout, so GO! (142 is the timeout return code) + echo + return $default_rc + elif [[ "$answer" == "$go_word" ]]; then + # User asked to GO! + return 0 + elif [[ $remaining -le 0 ]]; then + # Whatever, time passed, so GO! + return $default_rc + elif [[ "$rc" -ne 0 ]]; then + # Hmm, something wrong, we quit with error... + urm_log ERROR "Something went wrong (return code=$rc)" + return 1 + fi + + # We loop back + idm_cli_timeout $default_rc $remaining + +} + + idm_get () { local item=$1 @@ -223,39 +364,6 @@ idm_is_enabled () } - -idm_exit () -{ - local rc=${1:-0} - local msg lvl - - # Check exit status - if [ "$#" -eq 3 ]; then - lvl=${2:-DEBUG} - msg=${3:-} - else - lvl=DEBUG - msg=${2:-} - fi - - if [[ "$rc" -ne 0 ]]; then - idm_log $lvl "$msg (rc=$rc)" - else - idm_log $lvl "$msg" - fi - - # Remove trap - trap "" INT TERM EXIT - - # Exit for good - exit $rc -} - -idm_exit_trap () -{ - idm_log DEBUG "Exit trap" -} - idm_reverse_doted_list () { local list=$1 @@ -347,7 +455,7 @@ idm_mod__order () # Output echo -e "$( xargs -n1 -I{} echo {} "$mod_name" <<<"$IDM_MOD_DEPS" )" - done | tsort | xargs + done | tsort | grep -v 'core' | xargs #) #idm_log DEBUG "Dependencies order: $result" @@ -386,7 +494,7 @@ idm_core_ls () local val="idm_${i}_ls" idm_log NOTICE "List $i" - ${val} $id 2>/dev/null || \ + ${val} $id || \ { true idm_log INFO "No listing function for $i" @@ -416,14 +524,14 @@ idm_core_enable () conf="$IDM_DIR_ID/$id.env" # Notice user - ( + { . $conf for i in ${IDM_MOD_ORDER//:/ } ; do local val="idm_${i}_enable" - #idm_log INFO "Loading $i ..." + idm_log INFO "Loading $i ..." - ${val} $id 2>/dev/null || \ + ${val} $id || \ { true idm_log INFO "No enable function for $i" @@ -431,7 +539,7 @@ idm_core_enable () echo "" done - ) | idm_log CODE - + } | idm_log CODE - idm_log NOTICE "Identity '$id' is loaded" @@ -539,11 +647,6 @@ idm_core_completion () ########################################## -idm_exit_trap() { - rc=$? - [[ $rc -ne 0 ]] && idm_log ERR "The script exited with exit code: $rc" - exit $rc -} trap "idm_exit_trap" INT TERM EXIT diff --git a/lib/idmgr_mod_gpg.sh b/lib/idmgr_mod_gpg.sh index 359a454..e9ca6f6 100644 --- a/lib/idmgr_mod_gpg.sh +++ b/lib/idmgr_mod_gpg.sh @@ -95,6 +95,7 @@ idm_gpg__start () #echo "export GPG_TTY=$GPG_TTY" > "$runtime/env" echo "export GNUPGHOME=$gpghome" > "$runtime/env" echo "export GPG_AGENT_INFO=$runtime/socket" >> "$runtime/env" + echo "export GPG_DEFAULT_ID=${GIT_AUTHOR_EMAIL:-$id}" >> "$runtime/env" # Start agent idm_log INFO "Start gpg-agent ..." @@ -105,11 +106,110 @@ idm_gpg__start () ## Extended functions ########################################## +idm_gpg__cli_helper () +{ + local id=${1} + local type=${2:-sub} + local lvl=WARN + + # Autodetect name ... + if [ "$( wc -c <<<${GIT_AUTHOR_NAME})" -lt 5 ]; then + name=${GIT_AUTHOR_EMAIL} + else + name=${GIT_AUTHOR_NAME} + fi + + idm_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)" + elif [ "$type" == "main" ]; then + idm_log $lvl "Type: 4 - RSA (sign only)" + fi + + # Common + + idm_log $lvl "Size: 4096" + idm_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: " + idm_log $lvl "Passphrase: Very strong" + elif [ "$type" == "main" ]; then + idm_log $lvl "Type: quit and save changes" + fi + + idm_log NOTICE "PGP key generation interface" + +} + idm_gpg_new () { local id=${1} idm_is_enabled $id + key="$( idm_gpg__get_def_key $id )" - gpg --gen-key + 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 () +{ + key=${1} + + key=$( + gpg2 --list-keys | grep "uid"| grep "${key:-}" \ + | sed -E 's/[^<]*<([^>]*)>.*/\1/' + ) || { + idm_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" + 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 + +} diff --git a/lib/idmgr_mod_tomb.sh b/lib/idmgr_mod_tomb.sh index 77e904d..dcb6e53 100644 --- a/lib/idmgr_mod_tomb.sh +++ b/lib/idmgr_mod_tomb.sh @@ -1,20 +1,74 @@ #!/bin/bash -IDM_MOD_DEPS="ssh" +IDM_MOD_DEPS="ssh gpg" +IDM_MOD_TAGS="id tool" +IDM_MOD_PROG="safe yadm" +IDM_MOD_PREF="core id" -## Identity functions + +## Tomb functions ########################################## +# Install yadm +# git clone https://github.com/TheLocehiliosan/yadm.git ~/.usr/opt/yadm +# +# This allow to secure your things .... + +#set -x + + +## Dependencies +############################## +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 () { echo "tomb" printf " %-20s: %s\n" "tomb ls" "List all tombable files" - printf " %-20s: %s\n" "tomb diff" "Show diff between tomb en \$HOME" - printf " %-20s: %s\n" "tomb show" "Show the list of tombed files" printf " %-20s: %s\n" "tomb encrypt" "Save the current configuration" printf " %-20s: %s\n" "tomb decrypt" "Restore a tomb" + printf " %-20s: %s\n" "tomb import [] " "Import a config" + printf " %-20s: %s\n" "tomb leave" "Remove all traces of your passage" + echo "" + echo " Tomb is completely backed by yadm, this may change later" + echo " Use 'yadm help' to get backend help ..." + return 0 + + echo "" + echo " Yadm documentation (yadm help):" + yadm help | sed 's/^/ /' # printf " %-20s: %s\n" "tomb sync " "Synchronise with remote repo (how ???)" } @@ -35,107 +89,72 @@ idm_tomb () fi idm_log INFO "Forward to yadm: yadm ${action} $opt" - yadm ${action} $opt || + yadm ${action} $opt || \ idm_log ERR "Tomb fail" } -idm_tomb_encrypt () -{ - local id=${1} - idm_validate id $id - export YADM_WORK=$HOME - export YADM_DIR=$IDM_CONFIG_DIR/git/$id - #set -x - - #yadm archive --prefix=2014-10-21/ --format=zip HEAD | head - - if [[ ! -f $IDM_CONFIG_DIR/$id.db ]]; then - idm_log INFO "New bundle creation ..." - yadm bundle create - HEAD > $IDM_CONFIG_DIR/$id.db - else - - name=${HOSTNAME:-ERROR} - yadm remote add $name $IDM_CONFIG_DIR/$id.db 2>/dev/null || true - yadm push -u $name --all 2>/dev/null || true - yadm push -u $name --tags 2>/dev/null || true - fi - - idm_log INFO "NON encrypted git bundle created $IDM_CONFIG_DIR/$id.db" -} -idm_tomb_decrypt () -{ - local id=${1} - idm_validate id $id - export YADM_WORK=$HOME - export YADM_DIR=$IDM_CONFIG_DIR/git/$id - - if [[ ! -f $IDM_CONFIG_DIR/$id.db ]]; then - idm_exit 1 ERR "You don't have tomb yet ... " - fi - - git clone --bare $IDM_CONFIG_DIR/$id.db -b master $YADM_DIR - - - name=${HOSTNAME:-ERROR} - yadm remote add $name $IDM_CONFIG_DIR/$id.db 2>/dev/null || true - yadm fetch -u $name --all 2>/dev/null || true - yadm fetch -u $name --tags 2>/dev/null || true - - idm_log INFO "Secret repo deployed ini: $IDM_CONFIG_DIR/$id.db" -} - - -idm_tomb_add () -{ - local id=${1} - idm_validate id $id - export YADM_WORK=$HOME - export YADM_DIR=$IDM_CONFIG_DIR/git/$id - - # ajoute une liste de fichier: git add - - file=$YADM_DIR/gitignore - result=$( idm_tomb__gen_ignore $id ) - - for file in $result; do - idm_log DEBUG "YOOO: $file" - yadm add -f $file - done - -} - -idm_tomb_init () -{ - local id=${1} - idm_validate id $id - - export YADM_WORK=$HOME - export YADM_DIR=$IDM_CONFIG_DIR/git/$id - - yadm init || true - # idm_tomb__gen_ignore $id | sed -e '/^[^$]/ s/^/!/' > $IDM_CONFIG_DIR/git/$id/gitignore - idm_tomb__gen_gitconfig $id > $IDM_CONFIG_DIR/git/$id/gitconfig - idm_tomb__gen_config $id > $IDM_CONFIG_DIR/git/$id/config - idm_tomb_add $id - -} - - idm_tomb_ls () { - export YADM_WORK=$HOME - export YADM_DIR=$IDM_CONFIG_DIR/git/$id + local id=${1} + idm_validate id $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 + if ! idm_tomb__is_all_commited ; then + idm_log WARN "Some files has been modified" + yadm -c color.status=always status -s + fi + + 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 - yadm list -a - } - ## Sourced functions ############################## +idm_tomb_enable() +{ + local id=${1} + idm_validate id $id + + #mkdir -p $IDM_DIR_CACHE/git/$id/ $IDM_CONFIG_DIR/git/ || true + + 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() { # Disable internal variables @@ -144,18 +163,400 @@ idm_tomb_disable() idm_tomb_kill () { idm_tomb_disable ${@-}; } -idm_tomb_enable() + +## Git functions +############################## + +idm_tomb_ls_local () +{ + yadm list -a | sed 's:^: ~/:' | idm_log DUMP - +} + +idm_tomb__is_all_commited () +{ + return $( { yadm status -s || true; } | wc -l) +} + +idm_tomb_init_local () { local id=${1} idm_validate id $id - echo "export YADM_WORK='$HOME'" - echo "export YADM_DIR='$IDM_CONFIG_DIR/git/$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 () +{ + local id=${1} + idm_validate id $id + + # 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 + + # ajoute une liste de fichier: git add + + file=$YADM_DIR/gitignore + result=$( idm_tomb__gen_ignore $id ) + + # Add all files + ( cd && xargs yadm add -f <<<${result} ) + + # 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 + +} + +idm_tomb_replace () +{ + # Restore absent files + files="$( yadm status -s )" + + ok_files="$( sed -E '/^(D|.D)/!d;s/^...//' <<<$files | xargs || true)" + fail_files="$( sed -E '/^(D|.D)/d;s/^...//' <<<$files | xargs || true )" + + if [ ! -z "$ok_files" ]; then + idm_log INFO "Will restore:" + xargs -n1 <<<"$ok_files" | sed 's:^:~/:' | idm_log DUMP - + yadm co HEAD $ok_files + else + idm_log INFO "Tracked files are:" + yadm list -a | sed 's:^:~/:' | idm_log DUMP - + fi + + if [ ! -z "$fail_files" ]; then + idm_log WARN "Cannot restore:" + #sed 's:^:~/:' <<<"$fail_files" | xargs -n1 | idm_log DUMP - + yadm status -s + fi + } -## Other functions +## 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 () +{ + local id=${1} + shift || true + local opt=${@-} + local TOFIX_opt=$opt + idm_tomb__encrypt_init $id + + # We need a local git repo + if [ ! -d $IDM_TOMB_LOCAL_GIT ]; then + idm_exit 1 "Git repo is not enabled ($IDM_TOMB_LOCAL_GIT)" + fi + + # Do we overwrite ? + if [ -f "$IDM_TOMB_LOCAL_ENC" ]; then + [[ "$TOFIX_opt" =~ -f ]] || { + 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 ! + #GPG_KEY="$(yadm config yadm.gpg-recipient || true )" + GPG_KEY="${GPG_DEFAULT_ID-}" + case "${GPG_KEY:-_}" in + ASK) GPG_OPTS=("--no-default-recipient -e") ;; + _) GPG_OPTS=("-c") ;; + *) + GPG_OPTS="-e -r $GPG_KEY" + idm_log NOTICE "Local tomb will be secured with your '$GPG_KEY' id" + ;; + esac + #GPG_OPTS=("--no-default-recipient" "-e -r $GPG_KEY") + + # Encrypt all the stuffs + TAR="tar -C $(dirname $IDM_TOMB_LOCAL_GIT)" + $TAR -cz $IDM_TOMB_LOCAL_GIT 2>/dev/null | gpg2 -a $GPG_OPTS --yes -o $IDM_TOMB_LOCAL_ENC || \ + idm_exit 1 ERR "Could not encrypt tomb" + + idm_log INFO "Local tomb closed into $IDM_TOMB_LOCAL_ENC" + + # Shred the local files? + #find $IDM_TOMB_LOCAL_GIT -type f | xargs shred -u + #rm -fr $IDM_TOMB_LOCAL_GIT + + 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 () @@ -211,49 +612,57 @@ idm_tomb__gen_config () EOF ) | sed "s@$HOME/@~/@g" } -# -# -# idm_tomb_init () -# { -# set -x -# -# local id=${2:-$1} -# -# export YADM_WORK=$HOME -# export YADM_DIR=$IDM_CONFIG_DIR/git/$id -# -# yadm init ${@} $YADM_WORK -# -# idm_tomb__gen_ignore > $YADM_DIR/tomb -# -# } -# -# -# idm_tomb_show () -# { -# local id=${1} -# -# # Local checks -# idm_validate id_config $id || idm_exit 1 ERR "Configuration '$id' does not exists" -# -# export YADM_WORK=$HOME -# export YADM_DIR=$IDM_CONFIG_DIR/git/$id -# -# yadm list -a -# } -# -# -# idm_tomb_ls () -# { -# local id=${1} -# -# # Local checks -# idm_validate id_config $id || idm_exit 1 ERR "Configuration '$id' does not exists" -# -# export YADM_WORK=$HOME -# export YADM_DIR=$IDM_CONFIG_DIR/git/$id -# -# yadm status -s -# } -# -# + + +idm_tomb__remote_env_detect () +{ + local dest_host=${1:-remote} + + cat - <&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 + +}