Add: Initial code

This commit is contained in:
mrjk 2018-02-10 22:06:33 -05:00
commit 4939567383
8 changed files with 1439 additions and 0 deletions

0
README.md Normal file
View File

617
bin/idmgr Executable file
View File

@ -0,0 +1,617 @@
#!/bin/bash
## Documentation
##########################################
# This script handles many identity
## Initialisation
##########################################
# Get the way the script is called
IDM_PATH=${_:-_none}
IDM_ARGS=${0-}
# Ensure we are running strict mode
set -euo pipefail
# Detect how this script was started
if [[ $IDM_PATH == $IDM_ARGS ]]; then
IDM_CTX=executed
else
IDM_CTX=sourced
IDM_SOURCED_ARGS=${@:-_none}
fi
# Versionning infos
IDM_AUTHORS='mrjk'
IDM_VERSION='0.1 (beta)'
IDM_DATE='03/01/18'
IDM_LICENSE='MIT'
IDM_SCRIPT_NAME=idmgr
IDM_DIR_ROOT=${IDM_DIR_ROOT:-$( realpath "$(dirname $0)/../" )}
# Main initialisation settings
idm_init ()
{
export EDITOR=${EDITOR:-vim}
# App variables
IDM_CONFIG_DIR=${XDG_CONFIG_HOME:-~/.config}/idmgr
IDM_DIR_ID=${IDM_DIR_ID:-$IDM_CONFIG_DIR/id}
IDM_DIR_LIB=${IDM_DIR_LIB:-$IDM_DIR_ROOT/lib}
# Create directories
mkdir -p $IDM_CONFIG_DIR $IDM_DIR_ID
IDM_MOD_FILES=$(idm_mod_files)
IDM_MOD_ORDER=$(idm_mod_list)
# Load modules
for i in $IDM_MOD_FILES ; do
source $i
done
}
idm_core_help ()
{
echo ""
echo " idmgr - Identity Manager for your shell"
echo ""
echo "Introduction:"
echo " Identity Manager can manage your ssh keys, your pass,"
echo " your pgp keys, kerberos and many other related identity item."
echo ""
echo "Core commands:"
printf " %-20s: %s\n" "enable <id>" "Enable (and start) id"
printf " %-20s: %s\n" "disable <id>" "Disable id"
printf " %-20s: %s\n" "kill <id>" "Kill id and its associated processes"
echo
for i in ${IDM_MOD_ORDER//:/ } ; do
local val="idm_${i}_help"
echo -n "$i: "
${val} 2>/dev/null || \
{
true
echo "No help"
}
echo ""
done
echo "License:"
echo " $IDM_VERSION, $IDM_DATE"
echo " $IDM_LICENSE, $IDM_AUTHORS"
}
## Utils
##########################################
idm_log ()
{
local level=$1
shift || true
local msg="$@"
# Take from stdin if no message ...
[[ "$msg" = - ]] && msg=$( cat < /dev/stdin )
local color=
local reset='\033[0m'
case $level in
ERR)
color='\033[0;31m'
;;
WARN|TIP)
color='\033[0;33m'
;;
NOTICE)
color='\033[0;32m'
;;
INFO)
color='\033[0;37m'
;;
DEBUG)
color='\033[0;31m'
;;
RUN)
color='\033[0;34m'
;;
CODE)
echo "$msg"
return
;;
DUMP)
color='\033[0;36m'
echo -e "$color$msg$reset" | sed 's/^/ /'
return
;;
PREFIX)
color='\033[0;34m'
;;
esac
if [[ -n "$level" ]]; then
printf "$color%6s$reset: %s\n" "$level" "$msg" >&2
else
echo "Error while log output msg: $message"
fi
}
idm_get ()
{
local item=$1
local value=${2-}
case $item in
all_id)
for id in $IDM_DIR_ID/*.env; do
id=${id%%\.env}
echo "${id##*/}"
done
;;
all_id_files)
ls $IDM_DIR_ID/*.env
;;
id_config)
echo "id=$value"
cat $IDM_DIR_ID/$value.env
;;
*)
idm_log ERR "Cannot get item '$item'"
;;
esac
}
idm_validate ()
{
local type=$1
local value=${2-}
case $type in
id)
[ "$value" != '_' ] && \
[[ "$value" =~ ^[a-zA-Z0-9_-]+$ ]] && return
;;
id_config)
[[ -f "$IDM_DIR_ID/$value.env" ]] && return
;;
is_enabled)
[ ! -z "${SHELL_ID}" ] && return
;;
is_disabled)
[ -z "${SHELL_ID}" ] && return
;;
*)
idm_log ERR "Cannot validate type '$type'"
;;
esac
return 1
}
# Should be replaced by idm_validate ?
idm_is_enabled ()
{
local id=${1}
idm_validate id $id || \
idm_exit 1 ERR "You need to activate an id first"
}
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"
}
idem_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"
}
## IDM Internal
##########################################
# 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 | xargs
#)
#idm_log DEBUG "Dependencies order: $result"
#echo $result
}
idm_mod_files ()
{
#p=$IDM_DIR_ROOT/lib ${PATH//:/ }
p=$IDM_DIR_LIB
find $p -name 'idmgr_mod_*.sh' | xargs
}
idm_mod_list ()
{
local mods=
if [ -z "${@-}" ] ; then
mods=$( idm_mod__order $(idm_mod_files) )
else
mods=$( idm_mod__order ${@} )
fi
echo ":${mods// /:}:"
}
## Required functions
##########################################
idm_core_ls ()
{
local id=${1}
for i in ${IDM_MOD_ORDER//:/ } ; do
local val="idm_${i}_ls"
idm_log NOTICE "List $i"
${val} $id 2>/dev/null || \
{
true
idm_log INFO "No listing function for $i"
}
echo ""
done
}
idm_core_enable ()
{
local id=${1:-${SHELL_ID-}}
local conf
# Local checks
idm_validate id $id || idm_exit 1 ERR "You must provide an id"
idm_validate id_config $id || idm_exit 1 ERR "Configuration '$id' does not exists"
# Check if workspace is enabled
if [ "${SHELL_ID-}" == "$id" ]; then
idm_exit 0 INFO "Your workspace is already activated"
elif [ -n "${SHELL_ID-}" ]; then
idm_exit 0 WARN "Your workspace is already activated with $SHELL_ID"
fi
# Retrieve environment config
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 ..."
${val} $id 2>/dev/null || \
{
true
idm_log INFO "No enable function for $i"
}
echo ""
done
) | idm_log CODE -
idm_log NOTICE "Identity '$id' is loaded"
}
idm_core_disable ()
{
local id=${1}
idm_is_enabled $id
# Reverse module unloading
IDM_MOD_ORDER="$( idem_reverse_doted_list $IDM_MOD_ORDER )"
# Loop over disable functions
(
for i in ${IDM_MOD_ORDER//:/ } ; do
local val="idm_${i}_disable"
#idm_log INFO "Disable $i ..."
${val} $id 2>/dev/null || \
{
true
idm_log INFO "No disable function for $i"
}
echo ""
done
) | idm_log CODE -
# Inform user
idm_log NOTICE "Id $id is disabled"
}
idm_core_kill ()
{
local id=${1}
idm_is_enabled $id
# Reverse module killing
IDM_MOD_ORDER="$( idem_reverse_doted_list $IDM_MOD_ORDER )"
# Kill all modules
(
for i in ${IDM_MOD_ORDER//:/ } ; do
local val="idm_${i}_kill"
#idm_log INFO "Disable $i ..."
${val} $id 2>/dev/null || \
{
true
idm_log INFO "No kill function for $i"
}
echo ""
done
) | idm_log CODE -
# Inform user
idm_log NOTICE "Id $id is safely killed"
}
## Extended functions
##########################################
idm_core_mods()
{
local id=${1-}
idm_mod_list
}
idm_core_sourced_words()
{
local id=${1-}
local words=
# When we are asking to output source words
words="enable disable kill shell quit q $(idm_get all_id | xargs)"
echo ":${words// /:}:"
}
idm_core_shell ()
{
IDM_SRC_WORDS=$( $IDM_DIR_ROOT/bin/idmgr sourced_words )
echo "IDM_DIR_ROOT='$IDM_DIR_ROOT'"
echo "IDM_SRC_WORDS='$IDM_SRC_WORDS'"
echo "IDM_BIN=${IDM_BIN:-$IDM_DIR_ROOT/bin/idmgr}"
tail -n +2 $IDM_DIR_ROOT/shell/bash.sh
}
idm_core_completion ()
{
cat $IDM_DIR_ROOT/comp/pass.sh
cat $IDM_DIR_ROOT/comp/yadm.sh
cat $IDM_DIR_ROOT/comp/ssh.sh
cat $IDM_DIR_ROOT/comp/gpg.sh
cat $IDM_DIR_ROOT/comp/idmgr.sh
}
## Entry points
##########################################
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
idm_menu_main ()
{
#set -x
local menu=
local action=
local id=
local opt=
local shell_id=${SHELL_ID-:_}
idm_init
# Three way parsing
if [ "$#" -eq 0 ]; then
if [ -z "${SHELL_ID-}" ]; then
# Not activated, show all ids
menu=id
action=ls
id=_
else
# Activated, show all id settings
menu=core
action=ls
id=$shell_id
fi
else
# Check id constraint
if idm_validate id_config $1 ; then
menu=core
action=enable
id=$1
elif idm_validate id_config ${2-} ; then
menu=core
action=ls
id=$2
shift 2 && opt=${@} || true
elif idm_validate id_config ${3-} ; then
menu=$1
action=$2
id=$3
shift 3 && opt=${@} || true
# Check mod contraint
elif [[ "${IDM_MOD_ORDER}" =~ :$1: ]]; then
menu=$1
action=${2:-ls}
id=$shell_id
shift 2 && opt=${@} || true
# Free form
else
if [ "$#" -eq 1 ]; then
menu=core
action=${1}
id=$shell_id
# elif [ "$#" -eq 2 ]; then
# menu=${1}
# action=${2}
# id=$shell_id
# shift 2 && opt=${@} || true
else
menu=${1}
action=${2}
id=$shell_id
shift 2 && opt=${@} || true
fi
fi
fi
# Aliases
case $action in
quit|q)
action=disable
;;
esac
# Dispatch
#idm_log DEBUG "menu=$menu action=$action id=$id opt=$opt"
if [ "$( type -t idm_${menu}_${action} )" = function ]; then
idm_${menu}_${action} $id $opt
return $?
elif [ "$( type -t idm_${menu} )" = function ]; then
idm_${menu} ${action} $id $opt
return $?
fi
idm_log DEBUG "menu=$menu action=$action id=$id opt=$opt"
idm_exit 1 "Command not matched"
}
## Main
##########################################
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"

115
lib/idmgr_mod_gpg.sh Normal file
View File

@ -0,0 +1,115 @@
#!/bin/bash
IDM_MOD_DEPS="id"
idm_gpg_help ()
{
echo "Not implemented yet"
}
## Required functions
##########################################
idm_gpg_enable ()
{
local id=${1}
idm_is_enabled $id
# Source environment
if [ -f "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env" ]; then
. "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env"
else
unset GPG_AGENT_INFO
fi
# Check if socket is present
if [ ! -S "${GPG_AGENT_INFO-}" ]; then
rm -f "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env"
idm_gpg__start $id
fi
# Show config to source
if [ -f "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env" ]; then
cat "${XDG_RUNTIME_DIR}/pgp-agent/${id}/env"
fi
# Export tty to the current shell
echo "export GPG_TTY=$(tty)"
}
idm_gpg_disable ()
{
local id=${1}
idm_is_enabled $id
echo "unset GPG_AGENT_INFO GNUPGHOME GPG_TTY"
}
idm_gpg_kill ()
{
local id=${1}
idm_is_enabled $id
gpgconf --kill gpg-agent
idm_log NOTICE "Kill gpg-agent ..."
idm_gpg_disable $id
#killall gpg-agent || true
#echo "echo 'GPG kill is not implemented yet ...'"
}
idm_gpg_ls ()
{
local id=${1}
idm_is_enabled $id
gpg --list-keys | idm_log DUMP -
}
## Internal functions
##########################################
idm_gpg__start ()
{
local id=${1}
local gpghome=~/.config/gpg/$id
local runtime=${XDG_RUNTIME_DIR}/pgp-agent/$id
export GPG_TTY=$(tty)
export GNUPGHOME=$gpghome
# Ensure directories exist
if [ ! -d "$GNUPGHOME" ]; then
mkdir -p "$GNUPGHOME"
chmod 700 "$GNUPGHOME"
fi
if [ ! -d "$runtime" ]; then
mkdir -p "$runtime"
chmod 700 "$runtime"
fi
# Generate environment file
#echo "export GPG_TTY=$GPG_TTY" > "$runtime/env"
echo "export GNUPGHOME=$gpghome" > "$runtime/env"
echo "export GPG_AGENT_INFO=$runtime/socket" >> "$runtime/env"
# Start agent
idm_log INFO "Start gpg-agent ..."
gpg-agent --daemon --extra-socket "$runtime/socket"
}
## Extended functions
##########################################
idm_gpg_new ()
{
local id=${1}
idm_is_enabled $id
gpg --gen-key
}

206
lib/idmgr_mod_id.sh Normal file
View File

@ -0,0 +1,206 @@
#!/bin/bash
IDM_MOD_DEPS=""
## Identity functions
##########################################
idm_id_help ()
{
echo "Identity management:"
printf " %-20s: %s\n" "id ls" "List all disks of all policies"
printf " %-20s: %s\n" "id new <id>" "Add new id"
printf " %-20s: %s\n" "id rm <id>" "Remove id"
printf " %-20s: %s\n" "id edit <id>" "Edit id"
printf " %-20s: %s\n" "id show <id>" "Show id"
printf " %-20s: %s\n" "id dump " "Dump all id configurations"
}
idm_id ()
{
idm_id_ls ${@-}
}
idm_id_rm ()
{
local id=${1}
# Local checks
idm_validate id $id || idm_exit 1 ERR "Id '$id' is not valid"
#idm_validate id_config $id && idm_exit 1 "Configuration '$id' already exists"
# Delete config
if [ -f "$IDM_DIR_ID/$id.env" ] ; then
rm "$IDM_DIR_ID/$id.env" || \
idm_exit 1 ERR "File '$IDM_DIR_ID/$id.env' could not be deleted"
else
idm_log WARN "File '$IDM_DIR_ID/$id.env' was already deleted"
fi
}
idm_id_disable()
{
# Disable internal variables
echo "unset SHELL_ID GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL" | idm_log CODE -
}
idm_id_kill () { idm_id_disable ${@-}; }
idm_id_get ()
{
local id=${1}
if [[ "$id" == "-" && -n "${SHELL_ID-}" ]]; then
echo "${SHELL_ID-}"
return 0
elif [[ "${id}" == "${SHELL_ID-}" ]]; then
return 0
else
return 1
fi
}
idm_id_enable()
{
local id=${1}
local conf="$IDM_DIR_ID/$id.env"
[ -f "$conf" ] && source "$conf"
echo "export SHELL_ID=${id}"
echo "export GIT_AUTHOR_NAME=${id}"
echo "export GIT_AUTHOR_EMAIL=${email}"
# # echo "export PATH=${XDG_OPT_HOME}/bin:$PATH"
# #echo "export SSH_CONFIG=${id}"
# #echo "export SSH_AUTH_SOCK=/tmp/ssh-S88jysAIp3qs/${id}-agent.1767"
# #echo "export LOGNAME=${id}"
# #echo "export USER=${id}"
# #echo "export GNUPGHOME=~/.config/gnupg/$id"
# #echo "export GPG_AGENT_INFO=..."
# #echo "export TZ=${tz-}"
# #echo "export MAIL=/var/spool/mail/${id}"
# #echo "export LANG=en_US.utf8"
# #echo "export TERM=xterm-256color"
# XDG_OPT_HOME=~/opt/${id}
# # echo "export XDG_CONFIG_HOME=~/.config"
# # echo "export XDG_DATA_HOME=~/.local/share"
# # echo "export XDG_CACHE_HOME=~/.local/cache"
# # echo "export XDG_OPT_HOME=$XDG_OPT_HOME"
}
idm_id_new ()
{
local id=${1}
# Local checks
idm_validate id $id || idm_exit 1 "Id '$id' is not valid"
idm_validate id_config $id && idm_exit 1 "Configuration '$id' already exists"
# Create new id
conf="$IDM_DIR_ID/$id.env"
idm_id_template $id > $conf
# Edit id
$EDITOR "$conf"
# Notice user
idm_log NOTICE "Id '$id' has been created:"
cat $conf | idm_log CODE -
}
idm_id_show ()
{
local id=${1}
local conf
# Local checks
idm_validate id_config $id || idm_exit 1 ERR "Configuration '$id' does not exists"
# Edit id
conf="$IDM_DIR_ID/$id.env"
# Notice user
idm_log INFO "Id '$id' configuration:"
idm_get id_config $id | idm_log CODE -
# cat $conf | idm_log CODE
}
idm_id_edit ()
{
local id=${1}
local md5 conf
# Local checks
idm_validate id_config $id || idm_exit 1 ERR "Configuration '$id' does not exists"
# Edit id
conf="$IDM_DIR_ID/$id.env"
md5=$(md5sum $conf)
$EDITOR $conf
# Notice user
if [[ "$md5" == "$(md5sum $conf)" ]] ;then
idm_log INFO "Id '$id' has not been updated:"
else
idm_log NOTICE "Id '$id' has been updated:"
fi
cat $conf | idm_log CODE -
}
idm_id_ls ()
{
local active
for id in $(idm_get all_id); do
if [ "$id" == "${SHELL_ID-}" ]; then
active='*'
else
active=' '
fi
echo $(
eval "$(idm_get id_config $id)"
echo "$active:$id:$common_name ($email)"
)
done | column -t -s: -o' ' | idm_log DUMP -
}
idm_id_dump ()
{
for id in $(idm_get all_id); do
#idm_log NOTICE "Identity $id"
{
idm_get id_config $id
echo " "
} | idm_log CODE -
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"
}

68
lib/idmgr_mod_pass.sh Normal file
View File

@ -0,0 +1,68 @@
#!/bin/bash
IDM_MOD_DEPS="id gpg"
## Pass functions
##########################################
idm_pass ()
{
#set -x
if [ "$#" -eq 1 ]; then
local id=$1
idm_pass_ls $id
return 0
else
local action=$1
local id=$2
shift 2 || true
local opt=${@-}
fi
# Interncal override case
# Fallback to command
idm_is_enabled $id
PASSWORD_STORE_DIR=~/.config/pass/${id} pass $action ${@-}
}
idm_pass_ls ()
{
local id=${1}
idm_is_enabled $id
PASSWORD_STORE_DIR=~/.config/pass/${id} pass ls
}
idm_pass_help ()
{
echo "Standard UNIX Password Manager"
printf " %-20s: %s\n" "pass ls" "List passwords"
printf " %-20s: %s\n" "pass insert|new" "Add new secret"
printf " %-20s: %s\n" "pass generate" "Generate random secret"
printf " %-20s: %s\n" "pass grep" "Search in secrets"
printf " %-20s: %s\n" "pass rm" "Delete secret"
printf " %-20s: %s\n" "pass mv" "Move secret"
printf " %-20s: %s\n" "pass cp" "Copy secret"
}
idm_pass_enable ()
{
local id=${1}
idm_is_enabled $id
echo "export PASSWORD_STORE_DIR=~/.config/pass/${id}"
}
idm_pass_disable ()
{
local id=${1}
idm_is_enabled $id
echo "unset PASSWORD_STORE_DIR"
}

63
lib/idmgr_mod_ps1.sh Normal file
View File

@ -0,0 +1,63 @@
#!/bin/bash
IDM_MOD_DEPS="id pass gpg ssh"
## Prompt functions
##########################################
SHELL_PS1="${SHELL_PS1:-[\\u@\\h \\W]\\$ }"
idm_ps1 ()
{
local action=${1-}
shift || true
idm_ps1_ls
}
idm_ps1_ls ()
{
local id=${1}
#set -x
#echo "PS1=${SHELL_PS1:-${PS1-}}"
if grep -q "($id)" <<<"${SHELL_PS1:-${PS1-}}" ; then
echo "enabled"
else
echo "disabled"
fi
}
idm_ps1_help ()
{
echo "Shell Prompt"
printf " %-20s: %s\n" "ps1 enable" "Enable prompt"
printf " %-20s: %s\n" "ps1 disable" "Disable prompt"
}
idm_ps1_enable ()
{
local id=${1}
# \033]00m\] # for shell
#\[\033]01;31m\] for ps1
id="\[\033[0;34m\]($id)\[\033[00m\]"
PS1="$id ${PS1:-$SHELL_PS1}"
echo "export PS1='$PS1'"
echo "export SHELL_PS1='$PS1'"
}
idm_ps1_disable ()
{
local id=${1}
PS1=$( sed "s/$id[^a-z]* //" <<<${PS1:-$SHELL_PS1} )
PS1='[\u@\h \W]\$ '
echo "export PS1='$PS1'"
echo "export SHELL_PS1='$PS1'"
}
idm_ps1_kill () { idm_ps1_disable ${@-}; }

201
lib/idmgr_mod_ssh.sh Normal file
View File

@ -0,0 +1,201 @@
#!/bin/bash
IDM_MOD_DEPS="id gpg"
# trap 'idm_ssh_kill' 0
## SSH functions
##########################################
idm_ssh_help ()
{
echo "Secure Shell"
# printf " %-20s: %s\n" "info" "Info submenu"
printf " %-20s: %s\n" "ssh ls" "List unlocked keys"
printf " %-20s: %s\n" "ssh new" "Create new ssh key (ssh-keygen)"
printf " %-20s: %s\n" "ssh add" "Unlock known keypairs"
printf " %-20s: %s\n" "ssh rm" "Lock known keypairs"
printf " %-20s: %s\n" "ssh del" "Delete keypair"
printf " %-20s: %s\n" "ssh enable" "Enable agent"
printf " %-20s: %s\n" "ssh disable" "Disable agent"
printf " %-20s: %s\n" "ssh kill" "Kill agent"
}
idm_ssh ()
{
# Argument maangement
if [ "$#" -eq 1 ]; then
local id=$1
idm_ssh_ls $id
return 0
else
local action=$1
local id=$2
shift 2 || true
local opt=${@-}
fi
# Internal override case
# Fallback to command
idm_ssh_help
return 1
}
## Required functions
##########################################
idm_ssh_ls ()
{
local id=$1
local opt=${2:--l}
idm_is_enabled $id
{ ssh-add $opt || true ; } | idm_log DUMP -
}
idm_ssh_disable ()
{
local id=$1
idm_is_enabled $id
# Return portion of code to clean
echo "unset SSH_AUTH_SOCK SSH_AGENT_PID"
}
idm_ssh_enable ()
{
local id=$1
idm_is_enabled $id
#set -x
# Source environment
if [ -f "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env" ] ; then
. "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env"
else
unset SSH_AUTH_SOCK
fi
# Check if the socket file is available
if [ ! -S "${SSH_AUTH_SOCK-}" ]; then
rm -f "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env"
idm_ssh__start $id
fi
# Show the things to source
cat "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env"
}
# LOGOUT
idm_ssh_kill () {
#set -x
local id=$1
local run_dir="${XDG_RUNTIME_DIR}/ssh-agent/${id}"
idm_is_enabled $id
#idm_log NOTICE "Cleaning ssh-agent ..."
[ -z "${SSH_AGENT_PID-}" ] && \
[ -f "$run_dir/env" ] && \
. "$run_dir/env"
# Clean ssh-agent process
if kill -0 ${SSH_AGENT_PID-} &>/dev/null; then
/usr/bin/ssh-agent -k >/dev/null
idm_log NOTICE "Kill ssh-agent ..."
fi
#eval "$(/usr/bin/ssh-agent -k 2>/dev/null)"
# Clean ssh-agent env file
[ ! -f "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env" ] || \
rm "${XDG_RUNTIME_DIR}/ssh-agent/${id}/env"
# Disable agent
idm_ssh_disable $id
set +x
}
## Internal functions
##########################################
idm_ssh__start() {
local id=$1
local life=5d
local run_dir="${XDG_RUNTIME_DIR}/ssh-agent/${id}"
if [ -z "${SSH_AUTH_SOCK-}" ] ; then
if [ ! -d "$run_dir" ]; then
mkdir -p "$run_dir"
fi
if [ ! -S "$run_dir/socket" ]; then
ssh-agent -a "$run_dir/socket" -t $life -s | grep ^SSH_ > "$run_dir/env"
idm_log INFO "Start ssh-agent ..."
else
idm_log INFO "The ssh-agent is already started (but not managed by ourself)"
fi
else
idm_log INFO "The ssh-agent is already started"
fi
}
## Extended functions
##########################################
idm_ssh_add ()
{
local id=$1
local key=${2-}
local maxdepth=1
idm_is_enabled $id
if [[ ! -z $key ]]; then
pub_keys=$(find ~/.ssh/id -maxdepth $maxdepth -name "${id}_*" -name '*pub' -name "*$1*" | sort)
else
pub_keys=$(find ~/.ssh/id -maxdepth $maxdepth -name "${id}_*" -name '*pub' | sort)
fi
# 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_log INFO "Adding keys:"
xargs -n 1 <<<$key_list | idm_log DUMP -
echo ""
ssh-add $key_list
}

169
shell/bash.sh Normal file
View File

@ -0,0 +1,169 @@
#!/bin/bash
IDM_SRC_WORDS=${IDM_SRC_WORDS-}
IDM_BIN=${IDM_BIN:-idmgr}
i ()
{
if grep -q ":${1:-NONE}:" <<<"${IDM_SRC_WORDS}"; then
result="$( $IDM_BIN $@)"
# Debug module
if [ "${ID_DEBUG-}" == "true" ]; then
if [ "${result:-NONE}" == "NONE" ]; then
echo "======= ${result:-NONE}"
else
echo ======= Shell has sourced =======
echo "${result:-NONE}"
echo =======
fi
fi
# Parse output
eval "$result"
else
$IDM_BIN $@
fi
}
# Disable when pressing C-b in shell :)
bind -x '"\C-b": i disable'
# completion file for bash
# 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
# append / to directories
[[ -d $item ]] && item="$item/"
item="${item%$suffix}"
COMPREPLY+=("${item#$prefix}")
if [[ $i -eq 0 ]]; then
firstitem=$item
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
}
_pass_complete_folders () {
prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store/}"
prefix="${prefix%/}/"
local IFS=$'\n'
local items=($(compgen -d $prefix$cur))
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