Compare commits

..

No commits in common. "main" and "master" have entirely different histories.
main ... master

20 changed files with 880 additions and 1577 deletions

672
bin/idmgr
View File

@ -26,35 +26,42 @@ IDM_DATE='03/01/18'
IDM_LICENSE='MIT' IDM_LICENSE='MIT'
IDM_SCRIPT_NAME=idmgr IDM_SCRIPT_NAME=idmgr
# Ensure XDG vars
XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-$HOME/.local/run}
mkdir -p "$XDG_RUNTIME_DIR"
# Global app variables # Global app variables
IDM_BIN=${IDM_BIN:-$0} IDM_BIN=${IDM_BIN:-$0}
IDM_DIR_ROOT=${IDM_DIR_ROOT:-$( realpath "$(dirname $(realpath $0))/../" )} IDM_DIR_ROOT=${IDM_DIR_ROOT:-$( realpath "$(dirname $0)/../" )}
IDM_ID_ENV_DIR=${IDM_ID_ENV_DIR:-${XDG_CONFIG_HOME:-~/.config}/idmgr} IDM_CONFIG_DIR=${IDM_CONFIG_DIR:-${XDG_CONFIG_HOME:-~/.config}/idmgr}
IDM_DIR_ID=${IDM_DIR_ID:-$IDM_ID_ENV_DIR/id} IDM_DIR_ID=${IDM_DIR_ID:-$IDM_CONFIG_DIR/id}
IDM_DIR_LIB=${IDM_DIR_LIB:-$IDM_DIR_ROOT/lib} IDM_DIR_LIB=${IDM_DIR_LIB:-$IDM_DIR_ROOT/lib}
IDM_DIR_CACHE=${IDM_DIR_CACHE:-${XDG_CACHE_HOME:-~/.cache}/idmgr} IDM_DIR_CACHE=${IDM_DIR_CACHE:-${XDG_CACHE_HOME:-~/.cache}/idmgr}
IDM_SRC_WORDS='enable disable kill shell quit e d k s q' mkdir -p $IDM_CONFIG_DIR $IDM_DIR_ID $IDM_DIR_CACHE
mkdir -p $IDM_ID_ENV_DIR $IDM_DIR_ID $IDM_DIR_CACHE
# Mod vars ... # Mod vars ...
IDM_DISABLE_AUTO= IDM_DISABLE_AUTO=
IDM_ID_ENV=
# Main initialisation settings
idm_init ()
{
export EDITOR=${EDITOR:-vim}
# Create directories
mkdir -p $IDM_CONFIG_DIR $IDM_DIR_ID
IDM_MOD_FILES=$(idm_mod_files)
IDM_MOD_ORDER=$(idm_mod_list)
export IDM_TIMEOUT_USER=5
# Load modules
for i in $IDM_MOD_FILES ; do
source $i
done
}
## Required functions
## Base CLI commands
########################################## ##########################################
# Required libs:
# idm_core
idm_core__help () idm_core__help ()
{ {
@ -66,10 +73,9 @@ idm_core__help ()
echo " your pgp keys, kerberos and many other related identity item." echo " your pgp keys, kerberos and many other related identity item."
echo "" echo ""
echo "Sourced commands:" echo "Sourced commands:"
printf " %-20s: %s\n" "enable [id]" "Enable (and start) id" printf " %-20s: %s\n" "enable <id>" "Enable (and start) id"
printf " %-20s: %s\n" "disable [id]" "Disable id" printf " %-20s: %s\n" "disable id" "Disable id"
printf " %-20s: %s\n" "kill [id]" "Kill id and its processes" printf " %-20s: %s\n" "kill id" "Kill id and its associated processes"
echo
printf " %-20s: %s\n" "shell " "Show bash code" printf " %-20s: %s\n" "shell " "Show bash code"
printf " %-20s: %s\n" "comp " "Show completion code" printf " %-20s: %s\n" "comp " "Show completion code"
echo echo
@ -79,11 +85,7 @@ idm_core__help ()
printf " %-20s: %s\n" "fun " "Show internal function (debug)" printf " %-20s: %s\n" "fun " "Show internal function (debug)"
printf " %-20s: %s\n" "hier " "Show cli function (debug)" printf " %-20s: %s\n" "hier " "Show cli function (debug)"
local mods=$(idm_lib_order_get status) idm_core_exec_mod $id __help "\n%s" ${IDM_MOD_ORDER//:/ }
echo
echo "Loaded mods: $mods"
idm_core_exec_mod $id __help "\n%s" $mods
echo echo
lib_log NOTICE "License:" lib_log NOTICE "License:"
@ -95,30 +97,40 @@ idm_core__help ()
idm_core__ls () idm_core__ls ()
{ {
local id=${1} local id=${1}
idm_core_exec_mod $id __ls "%s ls" $(idm_lib_order_get status) #set -x
idm_core_exec_mod $id __ls "%s ls" ${IDM_MOD_ORDER//:/ }
} }
idm_core__enable () idm_core__enable ()
{ {
local id=${1:-${SHELL_ID-}} local id=${1:-${SHELL_ID-}}
local conf
#set -x
# Local checks # Local checks
#lib_id_is_valid_syntax $id || idm_exit 1 ERR "You must provide an id"
lib_id_has_config $id || idm_exit 1 ERR "Configuration '$id' does not exists" lib_id_has_config $id || idm_exit 1 ERR "Configuration '$id' does not exists"
# Check if workspace is enabled # Check if workspace is enabled
#idm_validate is_enabled $id
if [ "${SHELL_ID-}" == "$id" ]; then if [ "${SHELL_ID-}" == "$id" ]; then
#idm_exit 0 INFO "Your workspace is already activated"
lib_log WARN "Your workspace is already activated" lib_log WARN "Your workspace is already activated"
elif [ -n "${SHELL_ID-}" ]; then elif [ -n "${SHELL_ID-}" ]; then
lib_log WARN "Changing $SHELL_ID workspace to $id" idm_exit 0 WARN "Your workspace is already activated with $SHELL_ID"
$IDM_BIN disable "${SHELL_ID-}"
fi fi
# Retrieve environment config
conf="$IDM_DIR_ID/$id.env"
# Notice user # Notice user
{ {
# Reload user config . $conf
. "$IDM_ID_ENV" idm_core_exec_mod $id __enable "Enabling %s ..." ${IDM_MOD_ORDER//:/ }
idm_core_exec_mod $id __enable "Enabling %s ..." $(idm_lib_order_get enable)
} # | lib_log DUMP - } # | lib_log DUMP -
lib_log NOTICE "Identity '$id' is loaded" lib_log NOTICE "Identity '$id' is loaded"
@ -129,31 +141,37 @@ idm_core__disable ()
{ {
local id=${1} local id=${1}
lib_id_is_enabled $id lib_id_is_enabled $id
idm_core_exec_mod $id __disable "Disabling %s ..." $(idm_lib_order_get disable)
lib_log NOTICE "Identity '$id' is unloaded" # Reverse module unloading
IDM_MOD_ORDER="$( lib_reverse_doted_list $IDM_MOD_ORDER )"
idm_core_exec_mod $id __disable "Disabling %s ..." ${IDM_MOD_ORDER//:/ }
# Inform user
lib_log NOTICE "Id $id is disabled"
} }
idm_core__kill () idm_core__kill ()
{ {
local id=${1} local id=${1}
lib_id_is_enabled $id lib_id_is_enabled $id
idm_core_exec_mod $id __disable "Killing %s ..." $(idm_lib_order_get disable)
lib_log NOTICE "Id $id has been safely killed" # Reverse module killing
IDM_MOD_ORDER="$( lib_reverse_doted_list $IDM_MOD_ORDER )"
idm_core_exec_mod $id __disable "Killing %s ..." ${IDM_MOD_ORDER//:/ }
# Inform user
lib_log NOTICE "Id $id is safely killed"
} }
## Shell integration CLI commands
##########################################
idm_core__shell () idm_core__shell ()
{ {
IDM_SRC_WORDS=$( $IDM_DIR_ROOT/bin/idmgr sourced_words )
echo "export IDM_BIN=${IDM_BIN:-$IDM_DIR_ROOT/bin/idmgr}" echo "export IDM_BIN=${IDM_BIN:-$IDM_DIR_ROOT/bin/idmgr}"
echo "export IDM_DIR_ROOT='$IDM_DIR_ROOT'" echo "export IDM_DIR_ROOT='$IDM_DIR_ROOT'"
#echo "IDM_SRC_WORDS='$IDM_SRC_WORDS $(lib_id_get_all_id | xargs)'"
echo "IDM_SRC_WORDS='$IDM_SRC_WORDS'" echo "IDM_SRC_WORDS='$IDM_SRC_WORDS'"
echo "IDM_DIR_ID='$IDM_DIR_ID'"
tail -n +2 $IDM_DIR_ROOT/shell/bash.sh tail -n +2 $IDM_DIR_ROOT/shell/bash.sh
} }
@ -168,7 +186,7 @@ idm_core__comp ()
} }
## Debugging CLI commands ## Extended functions
########################################## ##########################################
@ -190,106 +208,22 @@ idm_core__hier ()
| sed -e 's/__/ /' -e 's/()//' | sed -e 's/__/ /' -e 's/()//'
} }
idm_core__sourced_words()
## Mod libs
##########################################
# Return a list of mod source files that can be sourced
# Input: none
# Return: linelist
# Example return:
# idmgr_mod_git.sh
# idmgr_mod_ssh.sh
# ...
idm_mod_files ()
{ {
#p=$IDM_DIR_ROOT/lib ${PATH//:/ } local id=${1-}
local p=$IDM_DIR_LIB local words=
find $p -name 'idmgr_mod_*.sh' | xargs
# When we are asking to output source words
words="enable disable kill shell quit q $(lib_id_get_all_id | xargs)"
echo ":${words// /:}:"
} }
# Takes a list of files to scan for deps. This
# will tell idmgr in which order to load its deps
# Input: wordlist of paths
# Return: wordlist
# Usage:
# idm_mod_order mod1 mod2 modN
idm_mod_order ()
{
>&2 echo "DEPRECATED: idm_mod_order"
local mods=$@
export IDM_MOD_FILES="$( xargs <<< $mods)"
# Generate dependency order
#result=$(
for f in $IDM_MOD_FILES; do
mod_name=${f##*mod_}
mod_name=${mod_name%\.sh}
# A bit hackish ...
IDM_MOD_DEPS=$( grep '^IDM_MOD_DEPS=' $f )
IDM_MOD_DEPS=${IDM_MOD_DEPS##*=}
IDM_MOD_DEPS=${IDM_MOD_DEPS//[^a-z0-9 ]}
IDM_MOD_DEPS="$( tr ' ' '\n' <<<${IDM_MOD_DEPS} )"
# Output
# TOCHECK? echo -e "$( xargs -I{} echo {} "$mod_name" <<<"$IDM_MOD_DEPS" )"
echo -e "$( xargs -n1 -I{} echo {} "$mod_name" <<<"$IDM_MOD_DEPS" )"
done | tsort | grep -v 'core' | xargs
#)
#lib_log DEBUG "Dependencies order: $result"
#echo $result
}
# Return a list of mods. Rescan mod source if
# no input mods provided.
# Input: [wordlist]
# Return: comalist
# Usage:
# idm_mod_list # Reload mods
# idm_mod_list mod1 mod2 modN
idm_mod_list ()
{
local mods="${@:-$(idm_mod_files)}"
mods=$(idm_mod_order ${mods})
echo ":${mods// /:}:"
}
## Core internal libs ## Core internal libs
########################################## ##########################################
# Required libs:
# idm_mod
# Return the list of required mods to run. High level
# call, can use cache.
idm_core_mods ()
{
local id=${1-}
idm_mod_list
}
# This function is the module execution engine.
# id: The current id to use
# action: The current command to run, ie `enable`
# sep: '_' Or a text to be displayed for the user
# mods: mod[,mod,...] list of mods to be triggered
idm_core_exec_mod () idm_core_exec_mod ()
{ {
local id=$1 local id=$1
@ -303,8 +237,18 @@ idm_core_exec_mod ()
if [ "$( type -t $val )" = function ]; then if [ "$( type -t $val )" = function ]; then
#set -x
# Skip if disabled ... # Skip if disabled ...
[[ ":${IDM_DISABLE_AUTO// /:}" =~ :${i}${action}: ]] && continue [[ ":${IDM_DISABLE_AUTO// /:}" =~ :${i}${action}: ]] && continue
#set +x
#lib_log INFO "Loading module $i ..."
#${val} $id || \
# {
# # DO NOT DISABLE THIS BLOCK, that force plugin to load in anyway
# true
# lib_log WARN "Module $i failed in some way ... ($action)"
# }
export IDM_MOD_EXEC=chain export IDM_MOD_EXEC=chain
local rc=0 local rc=0
@ -326,25 +270,94 @@ idm_core_exec_mod ()
done done
} }
idm_mod_files ()
{
#p=$IDM_DIR_ROOT/lib ${PATH//:/ }
p=$IDM_DIR_LIB
find $p -name 'idmgr_mod_*.sh' | xargs
}
## Application exit teardown idm_core_mods()
########################################## {
local id=${1-}
idm_mod_list
}
# Required libs:
# idm_std
# Call this function to exit main cli. You can idm_core_load_lib ()
# give some parameters as well. It use {
# lib_log to display error messages. Usage examples: local lib_name=${1}
# idm_exit rc lvl msg local lib_args=${@-}
# idm_exit rc msg local env_var=IDM_LIB_${lib_name^^}
# idm_exit
#lib_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
lib_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
}
idm_mod_list ()
{
local mods=
if [ -z "${@-}" ] ; then
mods=$( idm_mod_order $(idm_mod_files) )
else
mods=$( idm_mod_order ${@} )
fi
echo ":${mods// /:}:"
}
# Takes a list of files to scan for deps
idm_mod_order ()
{
export IDM_MOD_FILES="$( xargs <<<$@ )"
# Generate dependency order
#result=$(
for f in $IDM_MOD_FILES; do
mod_name=${f##*mod_}
mod_name=${mod_name%\.sh}
# A bit hackish ...
IDM_MOD_DEPS=$( grep '^IDM_MOD_DEPS=' $f )
IDM_MOD_DEPS=${IDM_MOD_DEPS##*=}
IDM_MOD_DEPS=${IDM_MOD_DEPS//[^a-z0-9 ]}
IDM_MOD_DEPS="$( tr ' ' '\n' <<<${IDM_MOD_DEPS} )"
# Output
echo -e "$( xargs -n1 -I{} echo {} "$mod_name" <<<"$IDM_MOD_DEPS" )"
done | tsort | grep -v 'core' | xargs
#)
#lib_log DEBUG "Dependencies order: $result"
#echo $result
}
## Internal/Debug
idm_exit () idm_exit ()
{ {
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
@ -364,175 +377,194 @@ idm_exit ()
lib_log $lvl "$msg" lib_log $lvl "$msg"
fi fi
# Remove trap to avoid to be called for normal and exit for good # Remove trap
trap "" INT TERM EXIT trap "" INT TERM EXIT
# Exit for good
exit $rc exit $rc
} }
# Script called when the script quits unexpectedly.
# Pretty useful for debugginf purpose.
idm_exit_trap () { idm_exit_trap () {
local rc=$? rc=$?
set +x set +x
echo "EXIT TRAP" >/dev/null
if [[ $rc -ne 0 ]]; then if [[ $rc -ne 0 ]]; then
lib_log ERR "The script exited with exit code: $rc" lib_log ERR "The script exited with exit code: $rc"
lib_trace || true lib_trace || true
#else #else
#lib_log INFO "The script exit has been correctly trapped." # lib_log WARN "The script exit has been trapped !"
# lib_trace || true # lib_trace || true
fi fi
exit $rc exit $rc
} }
## Compat ## Data, tests
# DEPRECATRED, replaced by lib_id
# Should be replaced by idm_validate ?
# Is a wrapper for enduser !!!
# idm_is_enabled ()
# {
# lib_log DEPRECATED "call: idm_is enabled $@, use lib_id_is_enabled ${1-} instead"
# lib_trace
# local id=${1}
# idm_validate is_enabled $id
# {
# lib_log WARN "You need to activate an id first"
# return 1
# }
# }
# # DEPRECATRED, replaced by lib_id
# idm_get ()
# {
# lib_log DEPRECATED "call: idm_get $@, use lib_id_has_config instead"
# lib_trace
# local item=$1
# local value=${2-}
#
# case $item in
# all_id)
# # idm_get all_id
# # => lib_id_get_all_id
# for id in $( find $IDM_DIR_ID -type f -name '*.env' 2>/dev/null ); do
# id=${id%%\.env}
# echo "${id##*/}"
# done
# ;;
#
# all_id_files)
# # => lib_id_get_all_file
# ls $IDM_DIR_ID/*.env || true
# ;;
#
# id_config)
# # => lib_id_get_config
# if [ -f "$IDM_DIR_ID/$value.env" ]; then
# echo "id=$value"
# cat $IDM_DIR_ID/$value.env
# else
# return 1
# fi
# ;;
#
# *)
# lib_log ERR "Cannot get item '$item'"
# ;;
# esac
# }
# # DEPRECATRED, replaced by lib_id
# idm_validate ()
# {
# #lib_log DEPRECATED "call: idm_validate $@, sed with: lib_id_has_config or equivalent"
# local type=$1
# local value=${2-}
#
# case $type in
# id_filter|id)
# lib_log DEPRECATED "call: idm_validate id_filter $@, sed with: lib_id_is_valid_syntax \$id"
# [ "$value" != '_' ] && \
# [[ "$value" =~ ^[a-zA-Z0-9_-]+$ ]] && return $?
# ;;
# id_config)
# lib_log DEPRECATED "call: idm_validate id_config $@, sed with: lib_id_has_config \$id"
# if [[ -f "$IDM_DIR_ID/$value.env" ]]; then
# return 0
# fi
# ;;
# is_enabled)
# lib_log DEPRECATED "call: idm_validate is_enabled $@, sed with: lib_id_is_enabled \$id"
# if [[ -z "${value-}" && "${value-}" != '_' ]]; then
# if [ -z "${SHELL_ID-}" ] ; then
# return 1
# else
# return 0
# fi
# else
# if [ "${value-}" == "${SHELL_ID-}" ]; then
# return 0
# else
# return 1
# fi
# fi
# ;;
# is_disabled)
# lib_log DEPRECATED "call: idm_validate is_disabled $@, sed with: ! lib_id_is_enabled \$id"
# [ -z "${SHELL_ID-}" ] && return $?
# ;;
#
# *)
# lib_log ERR "Cannot validate type '$type'"
# ;;
# esac
#
# return 1
# }
## User interface
########################################## ##########################################
# This function display a user skippable timeout. # This function display a user skippable timeout.
idm_cli_timeout () idm_cli_timeout ()
{ {
lib_log WARN "Deprecated use of idm_cli_timeout ..." local default_rc=${1:-1}
lib_cli_timeout $@ local wait_time=${2:-$IDM_TIMEOUT_USER}
} local start=$(date '+%s')
local human_word go_word
# Humanise ...
[ "$default_rc" -ge 0 ] || default_rc=1
## Mods internal libs if [ "$default_rc" -eq 0 ]; then
########################################## human_word="abort"
go_word=Q
# Required libs: None elif [ "$default_rc" -ne 0 ]; then
human_word="continue"
go_word=Y
idm_lib_names ()
{
local type=$1
find "$IDM_DIR_LIB" \
-name "idmgr_${type}_*.sh" \
-printf '%f\n' |
sed -E "s@idmgr_${type}_([^\.]*).*@\\1@" |
xargs
}
idm_lib_order_set ()
{
local id args rec
id=$1
shift 1
args=$@
# Does not allow modifications
! grep -q "^$id," <<< "$IDM_LIB_TABLE" || return
rec="$id,${args// /,}"
IDM_LIB_TABLE=$(
grep -v "^$id," <<< "$IDM_LIB_TABLE";
echo "$rec"
)
}
idm_lib_order_get ()
{
#set +x
local f=${1}
# >&2 echo "fmt: ${IDM_LIB_TABLEFMT%%$f*}"
#>&2 echo -e "\n>order: $f\n>table: $IDM_LIB_TABLE"
local w="ignore ${IDM_LIB_TABLEFMT%%$f*}"
f=$( wc -w <<< "$w" )
sort -t, -k${f} <<< "$IDM_LIB_TABLE" | cut -d, -f1 | xargs
}
# This is the library wrapper. Any loading
# must use this function. Create environment vars.
# Input: [type] [wordlist of mods]
# Output: none
# Usage:
# idm_lib_load # Load all default libs
# idm_lib_load lib # Same
# idm_lib_load mod # Load all mods
# idm_lib_load mod mod1 mod2 # loads specific mods
idm_lib_load ()
{
local type=${1:-lib}
shift 1
local names=${@-}
# Create variables
local var_name
[ -n "$names" ] || names=$(idm_lib_names $type)
var_name="IDM_${type^^}_LOADED"
# Source lib/mods
for name in $names; do
source "$IDM_DIR_LIB/idmgr_${type}_${name}.sh"
if [ "$?" -eq 0 ] ; then
# Add mod/lib to the loaded list
declare -g $var_name="${!var_name-}:$name"
# Load the infile mod order
if [ "$type" == 'mod' ]; then
local p_var="IDM_${type^^}_${name^^}_PRIO"
local p_val="${!p_var-}"
[ -z "$p_val" ] || idm_lib_order_set $name ${p_val}
fi
else
echo " WARN: Error while loading $type: ${name:-NONE}"
fi fi
done # Notifying user
# set +x 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
} }
## Entry points ## Entry points
########################################## ##########################################
# Main initialisation settings idm_menu_main ()
idm_core_init ()
{
export EDITOR=${EDITOR:-vim}
mkdir -p $IDM_ID_ENV_DIR $IDM_DIR_ID
# Configure libraries
IDM_LIB_TABLE=
IDM_LIB_TABLEFMT="mod enable disable status"
# Force native library display order
idm_lib_order_set id 10 90 10
idm_lib_order_set ssh 12 88 12
idm_lib_order_set ps1 60 40 60
idm_lib_order_set alias 60 40 60
# idm_lib_order_set cd 60 40 60
idm_lib_order_set gpg 11 89 11
#idm_lib_order_set git 50 50 50
#idm_lib_order_set tomb 50 50 50
idm_lib_order_set gh 50 50 50
idm_lib_order_set gitea 50 50 50
# Load external lib
idm_lib_load lib
idm_lib_load mod
trap "idm_exit_trap" INT TERM EXIT
}
idm_core_cli ()
{ {
#set -x #set -x
@ -542,10 +574,20 @@ idm_core_cli ()
local opt= local opt=
local shell_id=${SHELL_ID:-_} local shell_id=${SHELL_ID:-_}
idm_core_init # Load external libs
#for lib in $( find $IDM_DIR_LIB -name 'idm_lib_*.sh'); do
while read -r lib; do
#. $lib || lib_log WARN "Error while loading lib $lib :/"
. ${lib:-/dev/null} || echo " WARN: Error while loading lib: ${lib:-NONE}"
done <<< "$( find $IDM_DIR_LIB -name 'idm_lib_*.sh')"
trap "idm_exit_trap" INT TERM EXIT
idm_init
#set -x
# Three way parsing # Three way parsing
local dep_order="$(idm_lib_order_get enable)"
if [ "$#" -eq 0 ]; then if [ "$#" -eq 0 ]; then
if [ -z "${SHELL_ID-}" ]; then if [ -z "${SHELL_ID-}" ]; then
@ -579,7 +621,7 @@ idm_core_cli ()
shift 3 && opt=${@} || true shift 3 && opt=${@} || true
# Check mod contraint # Check mod contraint
elif [[ ":${dep_order// /:}:" =~ :$1: ]]; then elif [[ "${IDM_MOD_ORDER}" =~ :$1: ]]; then
menu=$1 menu=$1
action=${2:-ls} action=${2:-ls}
id=$shell_id id=$shell_id
@ -608,23 +650,11 @@ idm_core_cli ()
# Aliases # Aliases
case $action in case $action in
--help|-h)
action=help
;;
quit|q) quit|q)
action=disable action=disable
;; ;;
esac esac
# Retrieve environment config
local IDM_ID_ENV="$IDM_DIR_ID/$id.env"
if [[ -f "$IDM_ID_ENV" ]]; then
. "$IDM_ID_ENV"
fi
if [[ -f "$IDM_DIR_ID/$id.secrets" ]]; then
. "$IDM_DIR_ID/$id.secrets"
fi
# Dispatch # Dispatch
#lib_log DEBUG "menu=$menu action=${action:-_} id=$id opt=$opt" #lib_log DEBUG "menu=$menu action=${action:-_} id=$id opt=$opt"
#set -x #set -x
@ -647,5 +677,49 @@ idm_core_cli ()
## Main ## Main
########################################## ##########################################
idm_core_cli $@ idm_menu_main $@
# 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"

View File

@ -1 +0,0 @@
idmgr

View File

@ -1,43 +0,0 @@
## Environment vars
* `IDM_DEBUG`:
* Type: Bool
* Desc: Set true for shell debugging
### Core Config
* `IDM_BIN`:
* Type: String/Path
* desc: Path of the idmgr executable script
* `IDM_DIR_ROOT`:
* Type: String/Path
* desc: Path of the idmgr code/library path
* `IDM_NO_BG`:
* Type: Bool
* Default: false
* Desc: Disable background service start
* Note: Will not start ssh-agent or other services ...
* `IDM_DISABLE_AUTO`:
* Default: ''
* Type: Words
* Desc: Disable some module components
* Example:
* `IDM_DISABLE_AUTO+=" git__enable git__disable git__kill "`
* `IDM_DISABLE_AUTO+="ps1__ls"`
### Id
* `IDM_LAST_ID_SAVE`:
* Type: Bool
* Default: true
* desc: Should the last loaded ID saved
* `IDM_LAST_ID_AUTOLOAD`:
* Type: Bool
* Default: true
* desc: Should the last saved ID should be enabled at shell startup

View File

@ -1,118 +0,0 @@
## Create a new ssh key pair
In this example, we will create an `ed25519` and `rsa4096` ssh keys. The first one is more recent and faster while the second is slow as
fuck, but compatible everywhere. Then will see how to enable them.
> Note: For practical reasons, it's not recommanded to have more than 3 SSH key pairs per ID, as SSH client does not try more than 3 keys
before trying other authentications methods. Also you can use the same password for your ssh keys (belonging to the same ID!) if you want to
be able to unlock all your SSH keys at once.
### Create key pairs
First enable your id:
```
[joey@joeylaptop .ssh]$ i joey
NOTICE: Enabling id ...
NOTICE: Enabling ssh ...
NOTICE: Enabling ps1 ...
NOTICE: Identity 'joey' is loaded
```
Then create your new `ed25519` SSH key:
```
(joey) [joey@joeylaptop .ssh]$ i ssh new
INFO: Key destination dir: /home/joey/.ssh/joey
> Username [joey]:
> Hostname [joeylaptop.myhome.net]:
Please choose key types:
n) ed25519 strongest, fast
s) rsa4096 most compatible, slow
o) rsa2048 old compatility
> Key types [ns]: n
Define key passphrase for the key(s).
Leave it empty for no password (not recommemded).
> Key passphrase [none]:
> Confirm passphrase:
> Generating key ...
Generating public/private ed25519 key pair.
Your identification has been saved in /home/joey/.ssh/joey/joey_ed25519_20201104
Your public key has been saved in /home/joey/.ssh/joey/joey_ed25519_20201104.pub
The key fingerprint is:
SHA256:tMLyxatG1TtK+qaPV14wArZUqU/cGojvUycKVp/JDIw joey@joeylaptop.myhome.net:ed25519_20201104
The key's randomart image is:
+--[ED25519 256]--+
| ... |
| + . |
| * *.o |
| E.Bo*.= |
| .ooOS* + |
| oooo%.= . |
| . +.=.* o |
| *o+ . |
| .+Bo |
+----[SHA256]-----+
INFO: Key(s) has been created in /home/joey/.ssh/joey
```
Let's create another key `rsa4096`, with the same password as the previous one:
```
(joey) [joey@joeylaptop .ssh]$ i ssh new
INFO: Key destination dir: /home/joey/.ssh/joey
> Username [joey]:
> Hostname [joeylaptop.myhome.net]:
Please choose key types:
n) ed25519 strongest, fast
s) rsa4096 most compatible, slow
o) rsa2048 old compatility
> Key types [ns]: s
Define key passphrase for the key(s).
Leave it empty for no password (not recommemded).
> Key passphrase [none]:
> Confirm passphrase:
> Generating key ...
Generating public/private rsa key pair.
Your identification has been saved in /home/joey/.ssh/joey/joey_rsa4096_20201104
Your public key has been saved in /home/joey/.ssh/joey/joey_rsa4096_20201104.pub
The key fingerprint is:
SHA256:mxcxTOj57nXB5y6h5mQV9d+pFSxIoxJgvTtzn+6PJdw joey@joeylaptop.myhome.net:rsa4096_20201104
The key's randomart image is:
+---[RSA 4096]----+
| oo. ..o .|
| . .ooo o ...|
| o.o+. ..o.|
| .+ o ...=|
| S.. +o+|
| + +o...++ |
| *.oo=E...|
| ..**... |
| .+*o. ..|
+----[SHA256]-----+
INFO: Key(s) has been created in /home/joey/.ssh/joey
```
### Enable keypairs
Then you can enable with one password your ssh keys:
```
(joey) [joey@joeylaptop .ssh]$ i ssh add
INFO__: Adding keys:
~/.ssh/joey/joey_ed25519_20201104
~/.ssh/joey/joey_rsa4096_20201104
Enter passphrase for /home/joey/.ssh/joey/joey_ed25519_20201104:
Identity added: /home/joey/.ssh/joey/joey_ed25519_20201104 (joey@joeylaptop.myhome.net:ed25519_20201104)
Identity added: /home/joey/.ssh/joey/joey_rsa4096_20201104 (joey@joeylaptop.myhome.net:rsa4096_20201104)
(joey) [joey@joeylaptop .ssh]$ i ssh
256 SHA256:tMLyxatG1TtK+qaPV14wArZUqU/cGojvUycKVp/JDIw joey@joeylaptop.myhome.net:ed25519_20201104 (ED25519)
4096 SHA256:mxcxTOj57nXB5y6h5mQV9d+pFSxIoxJgvTtzn+6PJdw joey@joeylaptop.myhome.net:rsa4096_20201104 (RSA)
```

View File

@ -4,24 +4,97 @@
## Special libraries ## Special libraries
############################# #############################
lib_shred ()
{
lib_lob WARN "Will destroy all your secrets! (nor implemented yet)"
}
## Standard libraries ## 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 () lib_parse_filerules ()
{ {
local id=$1 local id=$1
local f=$2 local f=$2
#set -x
local YADM_ENCRYPT="$2" local YADM_ENCRYPT="$2"
ENCRYPT_INCLUDE_FILES=() ENCRYPT_INCLUDE_FILES=()
ENCRYPT_EXCLUDE_FILES=() ENCRYPT_EXCLUDE_FILES=()
#cd_work "Parsing encrypt" || return
cd ~ cd ~
exclude_pattern="^!(.+)" exclude_pattern="^!(.+)"
if [ -f "$YADM_ENCRYPT" ] ; then if [ -f "$YADM_ENCRYPT" ] ; then
#; parse both included/excluded #; parse both included/excluded
@ -32,13 +105,17 @@ lib_parse_filerules ()
if [[ "$pattern" =~ $exclude_pattern ]]; then if [[ "$pattern" =~ $exclude_pattern ]]; then
for ex_file in ${BASH_REMATCH[1]}; do for ex_file in ${BASH_REMATCH[1]}; do
for f in $( find $ex_file -type f ); do for f in $( find $ex_file -type f ); do
#if [ -e "$ex_file" ]; then
ENCRYPT_EXCLUDE_FILES+=("$f") ENCRYPT_EXCLUDE_FILES+=("$f")
#fi
done done
done done
else else
for in_file in $pattern; do for in_file in $pattern; do
for f in $( find $in_file -type f ); do for f in $( find $in_file -type f ); do
#if [ -e "$in_file" ]; then
ENCRYPT_INCLUDE_FILES+=("$f") ENCRYPT_INCLUDE_FILES+=("$f")
#fi
done done
done done
fi fi
@ -67,6 +144,106 @@ lib_parse_filerules ()
lib_log ()
{
set +x
[[ "${1-}" =~ ERR|WARN|TIP|NOTICE|INFO|DEBUG|RUN|CODE|DUMP|DEPRECATED|ASK ]] ||
{
lib_log ERR "Wrong message level while calling '${1-}'"
return 1
}
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|DEPRECATED)
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
>&2 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
}
@ -124,10 +301,8 @@ lib_vars_load ()
} }
## UI lib
#############################
## Id lib ## Id lib
@ -200,7 +375,6 @@ lib_id_get_all_config ()
lib_id_get_all_id () lib_id_get_all_id ()
{ {
local id=
for id in $( find $IDM_DIR_ID -type f -name '*.env' 2>/dev/null ); do for id in $( find $IDM_DIR_ID -type f -name '*.env' 2>/dev/null ); do
id=${id%%\.env} id=${id%%\.env}
echo "${id##*/}" echo "${id##*/}"

View File

@ -1,158 +0,0 @@
lib_log ()
{
set +x
[[ "${1-}" =~ ERR|WARN|TIP|NOTICE|INFO|DEBUG|RUN|CODE|DUMP|DEPRECATED|ASK ]] ||
{
lib_log ERR "Wrong message level while calling '${1-}'"
return 1
}
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|DEPRECATED)
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
>&2 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_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 -
}
## CLI lib
#############################
# This function display a user skippable timeout.
lib_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=Q
elif [ "$default_rc" -ne 0 ]; then
human_word="continue"
go_word=Y
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
}

View File

@ -1,61 +0,0 @@
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" | sed -E -e 's/ 00*/ /g' -e 's/ [ydhms]//g' | xargs
}
# Nifty trick to set var from pipes
lib_set_var () { read "$@" <&0; }
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"
}
# Ensure a binary is available in PATH and declare a global variable
# to call the binary with some prefixed options if any.
# Example:
# lib_require_bin ansible --dry
# Creates : ANSIBLE_BIN var with valude: "ansible --dry"
lib_require_bin () {
local bin=$1
shift 1 || true
local opts=${@-}
if command -v "$bin" &> /dev/null; then
local var_name=${bin^^}_BIN
declare -g ${var_name//-/_}="$bin $opts"
return 0
else
lib_log ERR "Missing '$bin'"
return 1
fi
}
# Securely delete a file or a folder
# lib_shred [DIR/FILE]
lib_shred ()
{
lib_log WARN "Will destroy all your secrets! (nor implemented yet)"
}

View File

@ -1,164 +0,0 @@
#!/bin/bash
#IDM_MOD_SSH_DEPS="s0 id gpg"
# trap 'idm_alias_kill' 0
## SSH functions
##########################################
idm_alias__help ()
{
echo "Aliases"
printf " %-20s: %s\n" "alias virsh" "Start virsh"
printf " %-20s: %s\n" "alias virt-manager" "Start virt-manager"
printf " %-20s: %s\n" "alias sshuttle" "Start sshuttle on SSH host"
printf " %-20s: %s\n" "alias sshuttle_ls" "Display net routes on SSH host"
#printf " %-20s: %s\n" "alias set" "Set alias"
#printf " %-20s: %s\n" "alias rm" "Remove alias"
#printf " %-20s: %s\n" "alias enable" "Enable agent"
#printf " %-20s: %s\n" "alias disable" "Disable agent"
#printf " %-20s: %s\n" "alias kill" "Kill agent"
# cat <<EOF
#
# Documentation:
#
# You can create a new alias key with the assistant:
# i alias set NAME VALUE
# The you can add this key to your agent, it will ask you your key password:
# i alias rm NAME
# To see current aliases:
# i alias ls
#
# EOF
}
idm_alias ()
{
# Argument maangement
if [ "$#" -eq 1 ]; then
local id=$1
idm_alias__ls $id
return 0
else
local action=$1
local id=$2
shift 2 || true
local opt=${@-}
fi
# Internal override case
# Fallback to command
idm_alias__help
return 1
}
## Required functions
##########################################
idm_alias__ls ()
{
local id=$1
local opt=${2:--l}
echo "i alias virsh HOST"
echo "i alias virt_manager HOST"
echo "i alias shuttle HOST [NET,...]"
echo "i alias shuttle_ls HOST"
}
idm_alias__disable ()
{
local id=$1
lib_id_has_config $id
}
idm_alias__enable ()
{
local id=$1
lib_id_has_config $id
}
# LOGOUT
idm_alias__kill ()
{
#set -x
local id=$1
local run_dir="${XDG_RUNTIME_DIR}/alias-agent/${id}"
}
## Hardcoded aliases
##########################################
idm_alias__virsh ()
{
local id=$1
local host=${2-}
[[ -n "$host" ]] || idm_exit 0 ERR "Missing SSH hostname in command line"
shift 2
local key=$(idm_ssh_search_private_keys "$id" | head -n 1 )
[[ -f "$key" ]] || idm_exit 0 WARN "No keys found"
local cmd="virsh -c "qemu+ssh://root@$host/system?keyfile=$key" $@"
lib_log RUN "$cmd"
exec $cmd
}
idm_alias__virt_manager ()
{
local id=$1
local host=${2-}
[[ -n "$host" ]] || idm_exit 0 ERR "Missing SSH hostname in command line"
shift 2
local key=$(idm_ssh_search_private_keys "$id" | head -n 1 )
[[ -f "$key" ]] || idm_exit 0 WARN "No keys found"
local cmd="virt-manager -c "qemu+ssh://root@$host/system?keyfile=$key" $@"
lib_log RUN "$cmd"
exec $cmd
}
idm_alias__sshuttle ()
{
local id=$1
local host=${2-}
[[ -n "$host" ]] || idm_exit 0 ERR "Missing SSH hostname in command line"
shift 2
idm_alias__sshuttle_ls $id $host || true
local cmd="sshuttle --remote $host --auto-hosts ${@:---auto-nets --dns}"
lib_log RUN "$cmd"
exec $cmd
}
idm_alias__sshuttle_ls ()
{
local id=$1
local host=${2-}
[[ -n "$host" ]] || idm_exit 0 ERR "Missing SSH hostname in command line"
shift 2
local cmd="ssh $host ip route"
lib_log RUN "$cmd"
$cmd
}

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
#IDM_MOD_CLOUD_DEPS="s3" IDM_MOD_DEPS="id pass gpg ssh"
## Prompt functions ## Prompt functions
########################################## ##########################################

View File

@ -1,55 +0,0 @@
#!/bin/bash
#IDM_MOD_PS1_DEPS="s4 id pass gpg ssh"
#IDM_DISABLE_AUTO+="gh__ls"
## Prompt functions
##########################################
#SHELL_PS1="${SHELL_PS1:-${PS1}"
idm_gh ()
{
local action=${1-}
shift || true
idm_gh__ls
}
idm_gh__ls ()
{
local id=${1}
if [[ -n "${GH_TOKEN-}" ]] ; then
echo " enabled (repo: ${GH_REPO})"
else
echo " disabled"
fi
}
idm_gh__help ()
{
echo "Github CLI"
printf " %-20s: %s\n" "gh enable" "Enable gh token"
printf " %-20s: %s\n" "gh disable" "Disable gh token"
}
idm_gh__enable ()
{
if [[ -n "${gh_token-}" ]] ; then
echo "export GH_TOKEN=\"$gh_token\""
echo "export GH_REPO=\"$gh_repo\""
fi
}
idm_gh__disable ()
{
echo "unset GH_TOKEN"
echo "unset GH_REPO"
}
idm_gh__kill () { idm_gh__disable ${@-}; }

View File

@ -1,9 +1,7 @@
#!/bin/bash #!/bin/bash
#IDM_MOD_GIT_DEPS="s1 id ssh" IDM_MOD_DEPS="id"
#IDM_DISABLE_AUTO+=" git__enable git__disable git__kill " IDM_DISABLE_AUTO+=" git__enable git__disable git__kill "
#idm_hook_register enable idm_git__enable 5
## Environments ## Environments
@ -420,11 +418,10 @@ idm_git__ls ()
fi fi
# Display repo infos # Display repo infos
{
echo " Work tree : $git_id_work_tree" echo " Work tree : $git_id_work_tree"
echo " Local config : $git_id_config" echo " Local config : $git_id_config"
echo " Git dir : $git_id_dir" echo " Git dir : $git_id_dir"
} | sed "s:$HOME:~:g"
} }
idm_git__enable () idm_git__enable ()

View File

@ -1,78 +0,0 @@
#!/bin/bash
#IDM_MOD_PS1_DEPS="s4 id pass gpg ssh"
#IDM_DISABLE_AUTO+="gitea__ls"
## Prompt functions
##########################################
#SHELL_PS1="${SHELL_PS1:-${PS1}"
idm_gitea ()
{
local action=${1-}
shift || true
idm_gitea__ls
}
idm_gitea__ls ()
{
local id=${1}
if [[ -n "${GITEA_LOGIN-}" ]] ; then
echo " enabled (repo: ${GITEA_LOGIN} ${GITEA_URL})"
else
echo " disabled"
fi
}
idm_gitea__help ()
{
echo "Github CLI"
printf " %-20s: %s\n" "gitea enable" "Enable gitea token"
printf " %-20s: %s\n" "gitea disable" "Disable gitea token"
}
idm_gitea__register ()
{
local gitea_url=$1
local gitea_login=$2
local gitea_token=$3
if tea login list -o simple | grep -q "^$gitea_login"; then
:
else
tea login add \
--url "$gitea_url" \
--name "$gitea_login" \
--token "$gitea_token" > /dev/null
>&2 echo "Tea login installed: $gitea_login ($gitea_url)"
fi
}
idm_gitea__enable ()
{
[[ -n "${gitea_url-}" ]] || return 0
[[ -n "${gitea_login-}" ]] || return 0
[[ -n "${gitea_token-}" ]] || return 0
idm_gitea__register $gitea_url $gitea_login $gitea_token
echo "export GITEA_SERVER_URL=\"$gitea_token\""
echo "export GITEA_LOGIN=\"$gitea_login\""
}
idm_gitea__disable ()
{
echo "unset GITEA_SERVER_URL"
echo "unset GITEA_LOGIN"
}
idm_gitea__kill () { idm_gitea__disable ${@-}; }

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
#IDM_MOD_GPG_DEPS="s0 id" IDM_MOD_DEPS="id"
idm_gpg__help () idm_gpg__help ()
@ -34,7 +34,7 @@ idm_gpg__cheat ()
sub: Public subkey sub: Public subkey
fpr: Fingerprint fpr: Fingerprint
grp: Keygrip grp: Keygrip
uid: Personal identification string uid: Persona identification string
Usage: Usage:
S: Signing S: Signing
C: Certification C: Certification
@ -52,7 +52,6 @@ idm_gpg__cheat ()
EOF EOF
# Notes: # Notes:
# ED25... : https://www.digitalneanderthal.com/post/gpg/
# See uses cases: http://www.saminiir.com/establish-cryptographic-identity-using-gnupg/ # See uses cases: http://www.saminiir.com/establish-cryptographic-identity-using-gnupg/
# Pass helper: https://github.com/avinson/gpg-helper # Pass helper: https://github.com/avinson/gpg-helper
@ -80,7 +79,6 @@ idm_gpg__enable ()
local id=${1} local id=${1}
lib_id_has_config $id lib_id_has_config $id
idm_gpg_header $id
# Source environment # Source environment
if [ -f "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env" ]; then if [ -f "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env" ]; then
@ -89,10 +87,6 @@ idm_gpg__enable ()
unset GPG_AGENT_INFO unset GPG_AGENT_INFO
fi fi
if [[ "${IDM_NO_BG:-false}" == true ]] || [[ -n "${DIRENV_IN_ENVRC-}" ]] ; then
lib_log WARN "Start of gpg-agent background process disabled because of: IDM_NO_BG=${IDM_NO_BG-} or DIRENV_IN_ENVRC=${DIRENV_IN_ENVRC-}"
else
# Check if socket is present # Check if socket is present
if [ ! -S "${GPG_AGENT_INFO-}" ]; then if [ ! -S "${GPG_AGENT_INFO-}" ]; then
rm -f "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env" rm -f "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env"
@ -103,11 +97,9 @@ idm_gpg__enable ()
if [ -f "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env" ]; then if [ -f "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env" ]; then
cat "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env" cat "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env"
fi fi
fi
# Export tty to the current shell # Export tty to the current shell
echo "export GPG_TTY=$(tty)" echo "export GPG_TTY=$(tty)"
echo "export GNUPGHOME=$GNUPGHOME"
} }
@ -205,10 +197,7 @@ idm_gpg__init ()
envsubst < $IDM_DIR_ROOT/shell/gpg_gen.tpl > $IDM_DIR_CACHE/gpg_gen_$id envsubst < $IDM_DIR_ROOT/shell/gpg_gen.tpl > $IDM_DIR_CACHE/gpg_gen_$id
) )
echo $IDM_DIR_CACHE
# Generate key # Generate key
mkdir -p "$gpghome"
gpg2 --batch --gen-key $IDM_DIR_CACHE/gpg_gen_$id gpg2 --batch --gen-key $IDM_DIR_CACHE/gpg_gen_$id
#gpg --verbose --batch --gen-key $IDM_DIR_CACHE/gpg_gen_$id #gpg --verbose --batch --gen-key $IDM_DIR_CACHE/gpg_gen_$id
#echo $? #echo $?
@ -465,7 +454,7 @@ lib_gpg_decrypt_dir ()
# Check required bin # Check required bin
lib_require_bin tar || idm_exit 1 lib_require_bin tar || idm_exit 1
lib_require_bin gpg2 || idm_exit 1 lib_require_bin gpg2 || idm_exit 1
export GPG=${GPG2:-$GPG_BIN} export GPG=${GPG2:-$GPG}
tar_opts=" -C ${dst%/*} -zx " tar_opts=" -C ${dst%/*} -zx "
if [ ! -z "$key" ]; then if [ ! -z "$key" ]; then
@ -474,7 +463,7 @@ lib_gpg_decrypt_dir ()
gpg_opts+="-d" gpg_opts+="-d"
fi fi
$GPG_BIN $gpg_opts $src | $TAR_BIN $tar_opts || \ $GPG $gpg_opts $src | $TAR $tar_opts || \
idm_exit 1 ERR "Could not decrypt file: $src into $dst" idm_exit 1 ERR "Could not decrypt file: $src into $dst"
} }
@ -490,7 +479,7 @@ lib_gpg_encrypt_dir ()
# Check required bin # Check required bin
lib_require_bin tar || idm_exit 1 lib_require_bin tar || idm_exit 1
lib_require_bin gpg2 || idm_exit 1 lib_require_bin gpg2 || idm_exit 1
export GPG=${GPG2:-$GPG_BIN} 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-}"
@ -548,8 +537,8 @@ lib_gpg_encrypt_dir ()
#set -x #set -x
# Encrypt all the stuffs # Encrypt all the stuffs
$TAR_BIN -C "${src%/*}" -cz "${src##*/}" 2>/dev/null | \ $TAR -C "${src%/*}" -cz "${src##*/}" 2>/dev/null | \
$GPG_BIN -a $gpg_opts --yes -o $dst || \ $GPG -a $gpg_opts --yes -o $dst || \
idm_exit 1 ERR "Could not encrypt directory: $src" idm_exit 1 ERR "Could not encrypt directory: $src"
#set +x #set +x
@ -557,7 +546,7 @@ lib_gpg_encrypt_dir ()
# File descritor tests ... # File descritor tests ...
#exec 3<> /tmp/foo #exec 3<> /tmp/foo
#>&3 echo "$pass" #>&3 echo "$pass"
#{ echo "$pass\n" >&3 ; $TAR_BIN -C "$(dirname $src)" -cz "$src" 2>/dev/null; } | \ #{ echo "$pass\n" >&3 ; $TAR -C "$(dirname $src)" -cz "$src" 2>/dev/null; } | \
#exec 3>&- #close fd 3. #exec 3>&- #close fd 3.
} }

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
#IDM_MOD_ID_DEPS="s0" IDM_MOD_DEPS=""
## Identity functions ## Identity functions
########################################## ##########################################
@ -27,8 +27,7 @@ idm_id ()
idm_id__disable() idm_id__disable()
{ {
# Disable internal variables # Disable internal variables
echo "unset SHELL_ID GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL" | lib_log CODE - echo "unset SHELL_ID GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL" | lib_log CODE -
idm_id_save_last_id _
} }
idm_id__kill () { idm_id__disable ${@-}; } idm_id__kill () { idm_id__disable ${@-}; }
@ -40,13 +39,9 @@ idm_id__enable ()
[ -f "$conf" ] && source "$conf" [ -f "$conf" ] && source "$conf"
echo "export SHELL_ID='${id}'" echo "export SHELL_ID=${id}"
echo "export GIT_AUTHOR_NAME='${common_name:-$id}'" echo "export GIT_AUTHOR_NAME=${common_name:-$id}"
echo "export GIT_AUTHOR_EMAIL='${email}'" echo "export GIT_AUTHOR_EMAIL=${email}"
echo "export GIT_COMMITTER_NAME='${common_name:-$id}'"
echo "export GIT_COMMITTER_EMAIL='${email}'"
idm_id_save_last_id $id
# echo "export PATH=${XDG_OPT_HOME}/bin:$PATH" # echo "export PATH=${XDG_OPT_HOME}/bin:$PATH"
# echo "export SSH_CONFIG=${id}" # echo "export SSH_CONFIG=${id}"
@ -112,6 +107,7 @@ idm_id__show ()
idm_id__ls () idm_id__ls ()
{ {
local active local active
#set -x
for id in $(lib_id_get_all_id); do for id in $(lib_id_get_all_id); do
@ -133,12 +129,6 @@ idm_id__ls ()
done | column -t -s: -o' ' #| lib_log DUMP - done | column -t -s: -o' ' #| lib_log DUMP -
} }
# List all available IDs names
idm_id__names ()
{
lib_id_get_all_id | xargs
}
idm_id__edit () idm_id__edit ()
{ {
@ -190,6 +180,19 @@ idm_id__dump ()
done done
} }
idm_id_template ()
{
local cn=${1-}
local tz lang
# Auto guess
tz=$( timedatectl | grep "Time zone" | awk '{print $3}' || true )
echo "common_name=${cn}"
echo "email="
echo "tz=$tz"
}
idm_id__rm () idm_id__rm ()
{ {
local id=${1} local id=${1}
@ -207,28 +210,3 @@ idm_id__rm ()
lib_log WARN "File '$IDM_DIR_ID/$id.env' was already deleted" lib_log WARN "File '$IDM_DIR_ID/$id.env' was already deleted"
fi fi
} }
idm_id_save_last_id ()
{
local id=${1}
[[ "${IDM_LAST_ID_SAVE:-true}" == "true" ]] || return 0
echo "$id" > "$IDM_DIR_CACHE/last_id"
}
idm_id_template ()
{
local cn=${1-}
local hostname=${2-}
local tz lang
# Auto guess
tz=$( timedatectl | grep "Time zone" | awk '{print $3}' || true )
echo "common_name=${cn}"
echo "login=${cn}"
echo "email="
echo "tz=$tz"
echo "public=false"
echo "hostname=${hostname:-$(hostname -f)}"
}

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
#IDM_MOD_PASS_DEPS="s2" IDM_MOD_DEPS="id gpg"
## Pass functions ## Pass functions

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
#IDM_MOD_PS1_DEPS="s4 id pass gpg ssh" IDM_MOD_DEPS="id pass gpg ssh"
#IDM_DISABLE_AUTO+="ps1__ls" IDM_DISABLE_AUTO+="ps1__ls"
## Prompt functions ## Prompt functions
########################################## ##########################################
@ -13,15 +13,17 @@ idm_ps1 ()
local action=${1-} local action=${1-}
shift || true shift || true
idm_ps1__ls idm_ps1_ls
} }
idm_ps1__ls () idm_ps1__ls ()
{ {
local id=${1} local id=${1}
# Bug here: PS1 and vars are like nk existing ... weird #set -x
if grep -q "($id)" <<<"${IDM_SHELL_PS1:-${PS1-}}" ; then #echo "PS1=${SHELL_PS1:-${PS1-}}"
if grep -q "($id)" <<<"${SHELL_PS1:-${PS1-}}" ; then
echo " enabled" echo " enabled"
else else
echo " disabled" echo " disabled"
@ -37,49 +39,21 @@ idm_ps1__help ()
} }
idm_ps1__enable () idm_ps1__enable ()
{
# Detect is PS1_*FIX vars exists
if [ "${PS1_PREFIX+x}" == x ]; then
#>&2 echo "Prefix PS1_PREFIX: ${PS1_PREFIX+x}"
idm_ps1__enable_suffix $@
else
#>&2 echo "Classic PS1: ${PS1_PREFIX+x}"
idm_ps1__enable_raw $@
fi
}
idm_ps1__enable_raw ()
{ {
local id=${1} local id=${1}
id="\[\033[0;34m\]($id)\[\033[00m\]" id="\[\033[0;34m\]($id)\[\033[00m\]"
echo "export PS1=\"$id \${IDM_SHELL_PS1}\"" echo "export PS1=\"$id \${IDM_SHELL_PS1}\""
# Notes about colors: # Notes about colors:
# \033]00m # for shell # \033]00m\] # for shell
# \[\033]01;31m\] # for ps1 # \[\033]01;31m\] for ps1
} }
idm_ps1__enable_suffix ()
{
local id=${1}
id="\033[0;34m($id)\033[00m"
echo "export PS1_PREFIX=\"$id${PS1_PREFIX:+ $PS1_PREFIX}\""
}
idm_ps1__disable () idm_ps1__disable ()
{ {
# Detect is PS1_*FIX vars exists
if [ "${PS1_PREFIX+x}" == x ]; then
#>&2 echo "Prefix PS1_PREFIX: ${PS1_PREFIX+x}"
echo "unset PS1_PREFIX"
else
#>&2 echo "Classic PS1: ${PS1_PREFIX+x}"
echo "export PS1=\"\${IDM_SHELL_PS1}\"" echo "export PS1=\"\${IDM_SHELL_PS1}\""
fi return
} }
idm_ps1__kill () { idm_ps1__disable ${@-}; } idm_ps1__kill () { idm_ps1__disable ${@-}; }

View File

@ -1,21 +1,19 @@
#!/bin/bash #!/bin/bash
#IDM_MOD_SSH_DEPS="s0 id gpg"
IDM_MOD_DEPS="id gpg"
# trap 'idm_ssh_kill' 0 # trap 'idm_ssh_kill' 0
# See: https://github.com/kalbasit/ssh-agents
## SSH functions ## SSH functions
########################################## ##########################################
idm_ssh__help () idm_ssh__help ()
{ {
echo "Secure Shell" echo "Secure Shell"
# printf " %-20s: %s\n" "info" "Info submenu"
printf " %-20s: %s\n" "ssh ls" "List unlocked keys" printf " %-20s: %s\n" "ssh ls" "List unlocked keys"
printf " %-20s: %s\n" "ssh pub" "Show public keys" printf " %-20s: %s\n" "ssh new" "Create new ssh key (ssh-keygen)"
printf " %-20s: %s\n" "ssh tree" "Show keypairs tree"
printf " %-20s: %s\n" "ssh new [dir]" "Create new ssh key dest dir"
printf " %-20s: %s\n" "ssh add" "Unlock known keypairs" printf " %-20s: %s\n" "ssh add" "Unlock known keypairs"
printf " %-20s: %s\n" "ssh rm" "Lock known keypairs" printf " %-20s: %s\n" "ssh rm" "Lock known keypairs"
printf " %-20s: %s\n" "ssh del" "Delete keypair" printf " %-20s: %s\n" "ssh del" "Delete keypair"
@ -24,21 +22,6 @@ idm_ssh__help ()
printf " %-20s: %s\n" "ssh disable" "Disable agent" printf " %-20s: %s\n" "ssh disable" "Disable agent"
printf " %-20s: %s\n" "ssh kill" "Kill agent" printf " %-20s: %s\n" "ssh kill" "Kill agent"
cat <<EOF
Documentation:
You can create a new ssh key with the assistant:
i ssh new
The you can add this key to your agent, it will ask you your key password:
i ssh add
If you want to kill the agent:
i ssh rm
If you want to delete your key files, simply run:
i ssh rm
EOF
} }
idm_ssh () idm_ssh ()
@ -73,6 +56,7 @@ idm_ssh__ls ()
local opt=${2:--l} local opt=${2:--l}
lib_id_is_enabled $id || return 0 lib_id_is_enabled $id || return 0
{ ssh-add $opt || true ; } 2>/dev/null | sed 's/^/ /' { ssh-add $opt || true ; } 2>/dev/null | sed 's/^/ /'
} }
@ -91,40 +75,31 @@ idm_ssh__enable ()
{ {
local id=$1 local id=$1
lib_id_has_config $id lib_id_has_config $id
local socket="${XDG_RUNTIME_DIR}/ssh-agent/${id}/socket"
# 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 SSH_AGENT_PID
# fi
unset SSH_AUTH_SOCK SSH_AGENT_PID unset SSH_AUTH_SOCK SSH_AGENT_PID
fi
# Check status # Check status
export SSH_AUTH_SOCK=$socket if ! idm_ssh__is_agent_working $id ${SSH_AUTH_SOCK:-_} ${SSH_AGENT_PID:-0}; then
if ! idm_ssh__is_agent_working $socket ; then if ! idm_ssh__agent_start $id; then
if [[ "${IDM_NO_BG:-false}" == true ]] || [[ -n "${DIRENV_IN_ENVRC-}" ]] ; then lib_log WARN "Could not start ssh agent :("
lib_log WARN "Start of background process disabled because of: IDM_NO_BG=${IDM_NO_BG:-false}" return 1
lib_log TIPS "Run '${0##*/} $id' to start ssh-agent"
else
idm_ssh__agent_start $id
fi fi
fi fi
# Display config to load # Display config to load
# >&2 ls -ahl ${XDG_RUNTIME_DIR}/ssh-agent/${id}/ cat "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env"
# cat "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env" || true
echo "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK"
} }
# LOGOUT # LOGOUT
idm_ssh__kill () idm_ssh__kill ()
{ {
#set -x
local id=$1 local id=$1
local run_dir="${XDG_RUNTIME_DIR}/ssh-agent/${id}" local run_dir="${XDG_RUNTIME_DIR}/ssh-agent/${id}"
@ -151,139 +126,7 @@ idm_ssh__kill ()
# Disable agent # Disable agent
idm_ssh__disable $id idm_ssh__disable $id
set +x
}
## Extra functions
##########################################
idm_ssh__tree ()
{
local id=$1
if lib_id_has_config $id &>/dev/null; then
tree -C "$HOME/.ssh/$id"
else
tree -C "$HOME/.ssh/"
fi
}
idm_ssh__pub ()
{
local id=$1
local path="$HOME/.ssh"
if lib_id_has_config $id &>/dev/null; then
path="$HOME/.ssh/$id"
fi
head -n 3 "$path"/*.pub
}
idm_ssh__new ()
{
local id=${1-}
local dest=${2-}
local default=
local key_vers=
local key_user=
local key_host=
local key_sizes=
local key_vers="$(date +'%Y%m%d')"
# Guess defaults
default=$(id -un)
if lib_id_has_config $id &>/dev/null; then
default=${login:-$id}
if [ -z "$dest" ]; then
dest="$HOME/.ssh/$id"
fi
else
dest=${dest:-.}
fi
mkdir -p "$dest"
echo "INFO: Key destination dir: $dest"
# Login
while ! grep -q '\w\+' <<< "$key_user"; do
read -rp "> Username [$default]: " ans
key_user="${ans:-$default}"
done
# Host name
default="${hostname:-$(hostname -f)}"
while ! grep -q '[a-zA-Z0-9.-]\+' <<< "$key_host"; do
read -rp "> Hostname [$default]: " ans
#echo ""
key_host="${ans:-$default}"
done
# Keys sizes
default="ns"
echo "Please choose key types:"
echo "n) ed25519 strongest, fast"
echo "s) rsa4096 most compatible, slow"
echo "o) rsa2048 old compatility"
while ! grep -q '[nso]\+' <<< "$key_sizes"; do
echo -n "> Key types [$default]: "
read -n 3 -r ans
echo ""
key_sizes="${ans:-$default}"
done
# Ask password
echo "Define key passphrase for the key(s)."
echo "Leave it empty for no password (not recommemded)."
echo -n "> Key passphrase [none]: "
read -rs key_pass
echo
key_pass="${key_pass:-}"
ans=""
while [ "$ans" != "$key_pass" ]; do
echo -n "> Confirm passphrase: "
read -rs ans
echo
done
# Create keys
local size=$key_sizes
while [ -n "$size" ]; do
local k=${size:0:1}
echo -e "\n> Generating key ..."
set +e
case $k in
n)
ssh-keygen -f "$dest/${key_user}_ed25519_${key_vers}" \
-t ed25519 -a 100 \
-N "$key_pass" \
-C "${key_user}@${key_host}:ed25519_${key_vers}"
;;
s)
ssh-keygen -f "$dest/${key_user}_rsa4096_${key_vers}" \
-t rsa -b 4096 -o -a 500 \
-N "$key_pass" \
-C "${key_user}@${key_host}:rsa4096_${key_vers}"
;;
o)
ssh-keygen -f "$dest/${key_user}_rsa2048_${key_vers}" \
-t rsa -b 2048 -o -a 100 \
-N "$key_pass" \
-C "${key_user}@${key_host}:rsa2048_${key_vers}"
;;
esac
set -e
size=${size:1}
done
echo
echo "INFO: Key(s) has been created in $dest"
} }
@ -293,118 +136,45 @@ idm_ssh__new ()
idm_ssh__is_agent_working () idm_ssh__is_agent_working ()
{ {
local socket=$1 local id=$1
local socket=${2:-_}
local pid=${3:-0}
local rc= local rc=
set +e set +e
SSH_AUTH_SOCK=$socket ssh-add -l &>/dev/null SSH_AUTH_SOCK=$socket SSH_AGENT_PID=$pid ssh-add -l &>/dev/null
rc=$? rc=$?
set -e set -e
if ! [ "$rc" -lt 2 ]; then [ "$rc" -lt 2 ] && return 0
[[ -e "$socket" ]] && rm "$socket"
return 1
fi
return 0
} }
background() {
>&2 echo "MY COMMAND: $@"
set +e
exec 0>&- || true
exec 1>&- || true
exec 2>&- || true
exec 3>&- || true
"$@" &
local pid=$!
disown $pid
echo $pid
set -e
}
idm_ssh__agent_start() { idm_ssh__agent_start() {
# local socket=$1
local id=$1 local id=$1
local life=4w local life=5d
local run_dir="${XDG_RUNTIME_DIR}/ssh-agent/${id}"
local socket_dir="${XDG_RUNTIME_DIR}/ssh-agent/${id}"
local socket="${socket_dir}/socket"
# Ensure directory are present
[ -d "$socket_dir" ] || \
mkdir -p "$socket_dir"
# Start the agent
rm "$socket" 2>/dev/null || true
export SSH_AUTH_SOCK=
export SSH_AGENT_PID=
#nohup ssh-agent -D -a "$socket" -t $life 2>&1 >$socket_dir/env &
# local pid=$(background ssh-agent -a "$socket" -t $life)
ssh-agent -a "$socket" -t $life |& grep 'SSH_' > $socket_dir/env
source "$socket_dir/env"
#echo "SSH_AUTH_SOCK=$socket"
#echo "SSH_AGENT_PID=$pid"
# >&2 echo "PID=$pid"
# echo "SSH_AUTH_SOCK=$socket" > $socket_dir/env
# echo "SSH_AGENT_PID=$pid" >> $socket_dir/env
# # local pid=$!
# # ps aux | grep $pid >&2
# # Wait for service to be started
# . $socket_dir/env > /dev/null
# until [ ! -z "${SSH_AUTH_SOCK:-}" ]; do
# . $socket_dir/env > /dev/null
# >&2 echo "WAiting socket .... "
# sleep 3
# done
# # . $socket_dir/env
# >&2 jobs
# disown -ar
# >&2 jobs
# return
#local run_dir="${XDG_RUNTIME_DIR}/ssh-agent/${id}"
# Check if we can recover from previous instance # Check if we can recover from previous instance
# idm_ssh__agent_clean $id "$run_dir/socket" 0 || true idm_ssh__agent_clean $id "$run_dir/socket" 0 || true
# Ensure directory are present
[ -d "$run_dir" ] || \
mkdir -p "$run_dir"
# # Ensure env file is not present # Ensure env file is not present
# [ ! -f "${run_dir}/env" ] || \ [ ! -f "${run_dir}/env" ] || \
# rm -f "${run_dir}/env" rm -f "${run_dir}/env"
# #set -x #set -x
# DEVEL # Start the agent # Start the agent
# DEVEL lib_log INFO "Start ssh-agent ..." if ssh-agent -a "$run_dir/socket" -t $life -s | grep ^SSH_ > "$run_dir/env"; then
# DEVEL $IDM_DIR_ROOT/bin/start_ssh_agent.sh "$run_dir/socket" $life
# DEVEL
# DEVEL # nohup ssh-agent -D -a "$run_dir/socket" -t $life
# DEVEL # export SSH_AGENT_PID=$!
# DEVEL export SSH_AUTH_SOCK="$socket"
# DEVEL echo "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK" > "$run_dir/env"
# DEVEL echo "export SSH_AGENT_PID=$SSH_AGENT_PID" >> "$run_dir/env"
# DEVEL #echo "VALUE='$SSH_AUTH_SOCK $SSH_AGENT_PID'"
echo "$run_dir/env"
# if nohup ssh-agent -a "$socket" -t $life ; then lib_log INFO "Start ssh-agent ..."
# disown $pid else
# #source "$run_dir/env" lib_log WARN "Could not start ssh agent :("
# #cat "$run_dir/env" return 1
# export SSH_AUTH_SOCK="$socket" fi
# lib_log INFO "Start ssh-agent ... ($pid)"
# else
# lib_log WARN "Could not start ssh agent :("
# return 1
# fi
} }
@ -416,6 +186,7 @@ idm_ssh__agent_clean ()
# We should kill all agents .... # We should kill all agents ....
if [ "${pid}" == '0' ]; then if [ "${pid}" == '0' ]; then
#set +x
pid=$(grep -a "$socket" /proc/*/cmdline \ pid=$(grep -a "$socket" /proc/*/cmdline \
| grep -a -v 'thread-self' \ | grep -a -v 'thread-self' \
| strings -s' ' -1 \ | strings -s' ' -1 \
@ -424,6 +195,7 @@ idm_ssh__agent_clean ()
#set -x #set -x
pid="$( sed -E 's@/proc/([0-9]*)/.*@\1@' <<<"$pid" )" pid="$( sed -E 's@/proc/([0-9]*)/.*@\1@' <<<"$pid" )"
fi fi
#set -x
# Remove process # Remove process
if [ ! -z "$pid" ]; then if [ ! -z "$pid" ]; then
@ -445,121 +217,110 @@ idm_ssh__agent_clean ()
## Extended functions ## Extended functions
########################################## ##########################################
idm_ssh__add () idm_ssh_add ()
{ {
local id=$1 local id=$1
local key=${2-} local key=${2-}
local maxdepth=2
#lib_id_is_enabled $id #lib_id_is_enabled $id
lib_id_is_enabled $id lib_id_is_enabled $id
key_list=$(idm_ssh_search_private_keys "$id" "$key")
[ -n "$key_list" ] || \ if [[ ! -z "$key" ]]; then
pub_keys=$(
{
# Compat mode
find ~/.ssh/id -maxdepth $maxdepth -name "${id}_*" -name '*pub' -name "*$1*" | sort
# New mode (test)
find ~/.ssh/$id -maxdepth $maxdepth -name "${id}_*" -name '*pub' -name "*$1*" | sort
} | sort | uniq
)
else
pub_keys=$(find ~/.ssh/$id -maxdepth $maxdepth -name "${id}_*" -name '*pub' | sort)
fi
echo "$pub_keys"
# Get list of key
local key_list=""
while read -r pub_key; do
#if [[ -f "$(sed 's/\.pub$/.key/' <<< "${pub_key}" )" ]]; then
if [[ -f "${pub_key//\.pub/.key}" ]]; then
key_list="$key_list ${pub_key//\.pub/.key}"
else
#if [[ -f "$(sed 's/\.pub$//' <<< "${pub_key}" )" ]]; then
if [[ -f "${pub_key%\.pub}" ]]; then
key_list="$key_list ${pub_key%\.pub}"
fi
fi
done <<< "$pub_keys"
[ -n "$pub_keys" ] || \
idm_exit 0 WARN "No keys found" idm_exit 0 WARN "No keys found"
lib_log INFO "Adding keys:" lib_log INFO "Adding keys:"
xargs -n 1 <<<$key_list | sed "s:$HOME:~:" | lib_log DUMP - xargs -n 1 <<<$key_list | lib_log DUMP -
echo "" echo ""
ssh-add $key_list ssh-add $key_list
} }
## SSH Library
##########################################
# This function search the bests ssh key file to use matching to an ID
idm_ssh_search_private_keys ()
{
local id=$1
local key=${2-}
local maxdepth=2
if [[ ! -z "$key" ]]; then
pub_keys=$(
{
# Compat mode
find -L ~/.ssh/$id -maxdepth $maxdepth -name "${id}_*" -name '*pub' -name "*$id*" | sort
} | sort | uniq
)
else
pub_keys=$(find -L ~/.ssh/$id -maxdepth $maxdepth -name '*pub' | sort)
fi
# Get list of key
local key_list=""
while read -r pub_key; do
if [[ -z "$pub_key" ]]; then
continue
elif [[ -f "${pub_key//\.pub/.key}" ]]; then
key_list="${key_list:+$key_list\n}${pub_key//\.pub/.key}"
else
if [[ -f "${pub_key%\.pub}" ]]; then
key_list="${key_list:+$key_list\n}${pub_key%\.pub}"
else
lib_log WARN "Can't find private key of: $pub_key"
fi
fi
done <<< "$pub_keys"
echo -e "$key_list"
}
## Deprecated functions ## Deprecated functions
########################################## ##########################################
### DEPRECATED # Useless at this stage i guess # Useless at this stage i guess
### DEPRECATED idm_ssh__agent_check () idm_ssh__agent_check ()
### DEPRECATED { {
### DEPRECATED #set -x #set -x
### DEPRECATED local id=$1 local id=$1
### DEPRECATED local socket=${2:-_} local socket=${2:-_}
### DEPRECATED local pid=${3:-0} local pid=${3:-0}
### DEPRECATED
### DEPRECATED if [ "$socket" == '_' ] && [ "$pid" == '0' ] ; then if [ "$socket" == '_' ] && [ "$pid" == '0' ] ; then
### DEPRECATED # Parameters are not valid, we assume ssh-agent is not launched at all # Parameters are not valid, we assume ssh-agent is not launched at all
### DEPRECATED return 1 return 1
### DEPRECATED elif SSH_AUTH_SOCK=$socket SSH_AGENT_PID=$pid ssh-add -l &>/dev/null ; then elif SSH_AUTH_SOCK=$socket SSH_AGENT_PID=$pid ssh-add -l &>/dev/null ; then
### DEPRECATED return 0 return 0
### DEPRECATED else else
### DEPRECATED lib_log WARN "ssh-agent is not working as expected" lib_log WARN "ssh-agent is not working as expected"
### DEPRECATED fi fi
### DEPRECATED
### DEPRECATED # Is the socket valid ? # Is the socket valid ?
### DEPRECATED if [ "$socket" != '_' -a ! -S "$socket" ]; then if [ "$socket" != '_' -a ! -S "$socket" ]; then
### DEPRECATED lib_log WARN "Socket '$socket' is dead, can't recover ssh-agent" lib_log WARN "Socket '$socket' is dead, can't recover ssh-agent"
### DEPRECATED idm_ssh__agent_clean $id $socket 0 idm_ssh__agent_clean $id $socket 0
### DEPRECATED return 1 return 1
### DEPRECATED fi fi
### DEPRECATED
### DEPRECATED if [ "$pid" != '0' -a "$pid" -lt 1 ]; then if [ "$pid" != '0' -a "$pid" -lt 1 ]; then
### DEPRECATED local pid="$( ps aux | grep "$socket" | grep -v 'grep' | head -n 1 | awk '{ print $2 }' )" || \ local pid="$( ps aux | grep "$socket" | grep -v 'grep' | head -n 1 | awk '{ print $2 }' )" || \
### DEPRECATED pid="$( ps aux | grep "" | grep -v 'grep' | head -n 1 | awk '{ print $2 }' )" || \ pid="$( ps aux | grep "" | grep -v 'grep' | head -n 1 | awk '{ print $2 }' )" || \
### DEPRECATED { {
### DEPRECATED lib_log WARN "Process ssh-agent is dead, cannot recover" lib_log WARN "Process ssh-agent is dead, cannot recover"
### DEPRECATED idm_ssh__agent_clean $id $socket 0 idm_ssh__agent_clean $id $socket 0
### DEPRECATED return 1 return 1
### DEPRECATED } }
### DEPRECATED
### DEPRECATED # Kill all processes # Kill all processes
### DEPRECATED lib_log DEBUG "Multiple PID founds for ssh-agent: $pid" lib_log DEBUG "Multiple PID founds for ssh-agent: $pid"
### DEPRECATED q=0 q=0
### DEPRECATED for p in $pid; do for p in $pid; do
### DEPRECATED return return
### DEPRECATED idm_ssh__agent_clean $id $socket $pid || true idm_ssh__agent_clean $id $socket $pid || true
### DEPRECATED q=1 q=1
### DEPRECATED done done
### DEPRECATED [ "$q" -eq 0 ] || return 1 [ "$q" -eq 0 ] || return 1
### DEPRECATED
### DEPRECATED fi fi
### DEPRECATED
### DEPRECATED # Ok, now we can try to recover the things # Ok, now we can try to recover the things
### DEPRECATED
### DEPRECATED
### DEPRECATED # Hmm, we should not arrive here ... # Hmm, we should not arrive here ...
### DEPRECATED lib_log WARN "ssh-agent is in a really weird state :/" lib_log WARN "ssh-agent is in a really weird state :/"
### DEPRECATED return 1 return 1
### DEPRECATED
### DEPRECATED } }

View File

@ -1,12 +1,12 @@
#!/bin/bash #!/bin/bash
#IDM_MOD_TOMB_DEPS="s3 id gpg git" 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"
#
#IDM_DISABLE_AUTO+=" tomb__enable tomb__disable tomb__kill " IDM_DISABLE_AUTO+=" tomb__enable tomb__disable tomb__kill "
#
## Environments ## Environments

View File

@ -6,29 +6,19 @@ IDM_BIN=${IDM_BIN:-idmgr}
i () i ()
{ {
local IDM_SRC_IDS=$($IDM_BIN id names)
local result=
local idents=$()
local id=
for id in $( find $IDM_DIR_ID -type f -name '*.env' 2>/dev/null ); do
id=${id##*/}
idents="${idents:+$idents }${id%%\.env}"
done
local patterns=" ${IDM_SRC_WORDS} ${IDM_SRC_IDS} $idents" if grep -q ":${1:-NONE}:" <<<"${IDM_SRC_WORDS}"; then
if grep -q " ${1:-NONE} " <<<" $patterns "; then
result="$( $IDM_BIN $@)" result="$( $IDM_BIN $@)"
# Debug module # Debug module
if [ "${IDM_DEBUG-}" == "true" ]; then if [ "${ID_DEBUG-}" == "true" ]; then
>&2 echo "DEBUG: Source: $IDM_BIN $@"
if [ "${result:-NONE}" == "NONE" ]; then if [ "${result:-NONE}" == "NONE" ]; then
>&2 echo "DEBUG: ======= ${result:-NONE}" echo "======= ${result:-NONE}"
else else
>&2 echo "DEBUG: ======= Shell has sourced =======" echo ======= Shell has sourced =======
echo "${result:-NONE}" echo "${result:-NONE}"
>&2 echo "DEBUG: =======" echo =======
fi fi
fi fi
@ -36,43 +26,149 @@ i ()
eval "$result" eval "$result"
else else
if [ "${IDM_DEBUG-}" == "true" ]; then
>&2 echo "DEBUG: Command: $IDM_BIN $@"
>&2 echo "DEBUG: ======="
fi
$IDM_BIN $@ $IDM_BIN $@
fi fi
} }
i_restore_last_id () # Disable when pressing C-b in shell :)
{ bind -x '"\C-b": i disable'
[[ "$IDM_LAST_ID_AUTOLOAD" == 'true' ]] || return 0
# Restore from SHELL_ID
if [[ -n "${SHELL_ID:-}" ]]; then
i enable $SHELL_ID # completion file for bash
return
# Copyright (C) 2012 - 2014 Jason A. Donenfeld <Jason@zx2c4.com> and
# Brian Mattern <rephorm@rephorm.com>. All Rights Reserved.
# This file is licensed under the GPLv2+. Please see COPYING for more information.
_pass_complete_entries () {
prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store/}"
prefix="${prefix%/}/"
suffix=".gpg"
autoexpand=${1:-0}
local IFS=$'\n'
local items=($(compgen -f $prefix$cur))
# Remember the value of the first item, to see if it is a directory. If
# it is a directory, then don't add a space to the completion
local firstitem=""
# Use counter, can't use ${#items[@]} as we skip hidden directories
local i=0
for item in ${items[@]}; do
[[ $item =~ /\.[^/]*$ ]] && continue
# if there is a unique match, and it is a directory with one entry
# autocomplete the subentry as well (recursively)
if [[ ${#items[@]} -eq 1 && $autoexpand -eq 1 ]]; then
while [[ -d $item ]]; do
local subitems=($(compgen -f "$item/"))
local filtereditems=( )
for item2 in "${subitems[@]}"; do
[[ $item2 =~ /\.[^/]*$ ]] && continue
filtereditems+=( "$item2" )
done
if [[ ${#filtereditems[@]} -eq 1 ]]; then
item="${filtereditems[0]}"
else
break
fi
done
fi fi
# Restore from last loaded shell # append / to directories
local IDM_DIR_CACHE=${IDM_DIR_CACHE:-${XDG_CACHE_HOME:-~/.cache}/idmgr} [[ -d $item ]] && item="$item/"
local state_file=$IDM_DIR_CACHE/last_id
if [ -f "$state_file" ]; then item="${item%$suffix}"
local id=$(cat "$state_file") COMPREPLY+=("${item#$prefix}")
if ! [ -z "${id//_/}" ]; then if [[ $i -eq 0 ]]; then
# BUG: Should not reload if already loaded !!!! firstitem=$item
>&2 echo "INFO: Auto enabling last id: $id"
i enable $id
fi fi
let i+=1
done
# The only time we want to add a space to the end is if there is only
# one match, and it is not a directory
if [[ $i -gt 1 || ( $i -eq 1 && -d $firstitem ) ]]; then
compopt -o nospace
fi fi
} }
_pass_complete_folders () {
prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store/}"
prefix="${prefix%/}/"
# Disable when pressing C-b in shell :) local IFS=$'\n'
bind -x '"\C-b": i disable' local items=($(compgen -d $prefix$cur))
i_restore_last_id for item in ${items[@]}; do
[[ $item == $prefix.* ]] && continue
COMPREPLY+=("${item#$prefix}/")
done
}
_pass_complete_keys () {
local IFS=$'\n'
# Extract names and email addresses from gpg --list-keys
local keys="$(gpg2 --list-secret-keys --with-colons | cut -d : -f 10 | sort -u | sed '/^$/d')"
COMPREPLY+=($(compgen -W "${keys}" -- ${cur}))
}
_pass()
{
COMPREPLY=()
local cur="${COMP_WORDS[COMP_CWORD]}"
local commands="init ls find grep show insert generate edit rm mv cp git help version"
if [[ $COMP_CWORD -gt 1 ]]; then
local lastarg="${COMP_WORDS[$COMP_CWORD-1]}"
case "${COMP_WORDS[1]}" in
init)
if [[ $lastarg == "-p" || $lastarg == "--path" ]]; then
_pass_complete_folders
compopt -o nospace
else
COMPREPLY+=($(compgen -W "-p --path" -- ${cur}))
_pass_complete_keys
fi
;;
ls|list|edit)
_pass_complete_entries
;;
show|-*)
COMPREPLY+=($(compgen -W "-c --clip" -- ${cur}))
_pass_complete_entries 1
;;
insert)
COMPREPLY+=($(compgen -W "-e --echo -m --multiline -f --force" -- ${cur}))
_pass_complete_entries
;;
generate)
COMPREPLY+=($(compgen -W "-n --no-symbols -c --clip -f --force -i --in-place" -- ${cur}))
_pass_complete_entries
;;
cp|copy|mv|rename)
COMPREPLY+=($(compgen -W "-f --force" -- ${cur}))
_pass_complete_entries
;;
rm|remove|delete)
COMPREPLY+=($(compgen -W "-r --recursive -f --force" -- ${cur}))
_pass_complete_entries
;;
git)
COMPREPLY+=($(compgen -W "init push pull config log reflog rebase" -- ${cur}))
;;
esac
else
COMPREPLY+=($(compgen -W "${commands}" -- ${cur}))
_pass_complete_entries 1
fi
}
complete -o filenames -F _pass pass
# Show current identities
echo "INFO: idmgr has been loaded, use 'idmgr' or 'i' to call it"
#$IDM_BIN id ls

View File

@ -1,62 +0,0 @@
#!/bin/bash
idmgr_shell_words ()
{
# Generate command/ids list to be sourced
local IDM_SRC_CMDS='enable disable kill shell quit e d k s q'
local IDM_SRC_IDS=$(find "$XDG_CONFIG_HOME/idmgr/id/" \
-type f -name "*.env" \
-printf "%f " | sed 's/\.env//g')
echo "$IDM_SRC_CMDS $IDM_SRC_IDS"
}
idmgr_shell ()
{
IDM_SRC_WORDS="${IDM_SRC_WORDS:-$(idmgr_shell_words)}"
# Check if must be sourced or not
if [[ "${IDM_SRC_WORDS// /:}" =~ :$1: ]]; then
# Get output source
>&2 echo "INFO : Running sourced command ..."
shell_exec="$( command idmgr $@)"
# Debug module
if [ "${ID_DEBUG-}" == "true" ]; then
if [ "${shell_exec:-NONE}" == "NONE" ]; then
echo "======= ${shell_exec:-NONE}"
else
echo ======= Shell has sourced =======
echo "${shell_exec:-NONE}"
echo =======
fi
fi
# Exec output
eval "$shell_exec"
else
# Execute as regular command
command idmgr $@
fi
}
# Set aliases
alias idmgr='idmgr_shell'
alias i='idmgr'
# Save current state
export PS1="$PS1"
export IDM_SHELL_PS1=${IDM_SHELL_PS1:-${PS1-}}
# Disable when pressing C-b in shell :)
bind -x '"\C-b": i disable'
# Show current identities
echo "INFO: idmgr has been loaded, use 'idmgr' or 'i' to call it"
idmgr id ls