#! /usr/bin/env bash # change credentials - symlink different credential files # # Usage: be [options] who # arguments # who name of identity # # options # # Select credentials # # -a|--aws change/list aws credentials ONLY # -g|--gnupg change/list gnupgcredentials ONLY # -p|--pass change/list pas credentials ONLY # -s|--ssh change/list ssh credentials ONLY # -t|--git change/list git credentials ONLY # # Select operation # # -l|--list list availabe credentials. # -w|--whoami list current identities # # Other # # -d|--debug debug output # -h|--help print usage # -v|--verbose verbose output # # e.g. # # If ~/.gnupg.$1 exists, link to ~/.gnupg # If ~/.ssh/id_{dsa,rsa}.$1 exists, link to ~/.ssh/id_{dsa,rsa} and add to ssh agent # If ~/.aws/credentials.$1 exists, link to ~/.aws/credentials # # FILES # * SSH Files # # ~/.ssh/id_{dsa,rsa}.IDENTITY - SSH identify file for IDENTITY # ~/.ssh/id_{dsa,rsa} - Symlink to SSH identity # # ~/.ssh/authorized_keys.IDENTITY - SSH authorized keys for IDENTITY # ~/.ssh/authorized_keys - Symlink to SSH authorized_keys file # # ~/.ssh/config.IDENTITY - SSH config for IDENTITY # ~/.ssh/config - Symlink to SSH config file # # ~/,gitconfig.IDENTITY - git config file # # * GPG Files # # * AWS files # # * pass(1) files # # * org files # # TO DO ITEMS # # * TODO finish documenting FILES # * TODO deal with .pem files # * TODO maybe make this not bash (python? go?) # * TODO make a general configruation format for different identites # - e.g. so that there would only be one "list" or "whoami" function # for all identities # * TODO add documentation # # * TODO deal with git identities # + Use XDG-CONFIG-HOME to switch identities? # http://git.661346.n2.nabble.com/What-is-XDG-CONFIG-HOME-for-exactly-td7627117.html # + See https://gist.github.com/jexchan/2351996 set -e; set -u # this is bash. Be safe out there. unalias cd 2>/dev/null || true # Helper functions PROG=`basename "$0" | tr -d '\n'` function info() { echo ${PROG}\: info: "$@" 1>&2; } function warn() { echo ${PROG}\: warning: "$@" 1>&2; } function error() { echo ${PROG}\: error: "$@" 1>&2; } function debug() { [[ -v DEBUG ]] && echo ${PROG}\: debug: "$@" 1>&2 || true ; } function die() { echo ${PROG}\: fatal: "$@" 1>&2 && exit 1; } function usage() { debug "in ${FUNCNAME[0]}" if [[ "$#" -gt 0 ]]; then warn $@ fi cat <&2 Usage: be [options] who arguments who name of identity options Select credentials -a|--aws change/list aws credentials ONLY -g|--gnupg change/list gnupgcredentials ONLY -p|--pass change/list pas credentials ONLY -s|--ssh change/list ssh credentials ONLY -t|--git change/list git credentials ONLY Select operation -l|--list list availabe credentials. -w|--whoami list current identities Other -d|--debug debug output -h|--help print usage -v|--verbose verbose output END exit 1 } # See # # https://wiki.archlinux.org/index.php/GnuPG#gpg-agent # # I'm pretty sure mere mortals can't grok gpg in fullness. function gpg_list() { # list available gpg credentail sets (diretories) info available GPG credentials sets ls -ld ~/.gnupg.* || true echo } function gpg_whoami() { # list current gpg identity if [ ! -L ~/.gnupg ]; then warn "No ~/.gnupg directory"; echo; return; fi info Current gpg credential set info ls -ld ~/.gnupg || true echo "GET_PASSPHRASE --no-ask NotCachedID Err Pmt Des" | gpg-connect-agent echo } function gpg_become() { # change gpg identity rm -f ~/.gnupg || true ln -s ~/.gnupg."${who}" ~/.gnupg } function aws_list() { # list available aws credentials if ! cd ~/.aws; then warn "No ~/.aws credentials"; echo; return; fi info available AWS credentials and configs ls -ld credentials.* config.* || true echo } function aws_whoami() { # list current aws identity echo foo if ! cd ~/.aws; then warn "No ~/.aws credentials"; echo; return; fi info Current aws credentials info ls -ld credentials config || true echo } function aws_become() { # change aws identity if ! cd ~/.aws; then warn "No ~/.aws credentials"; echo; return; fi aws_creds="credentials.""${who}" if [ ! -f "${aws_creds}" ]; then warn file "${aws_creds}" does not exist. Not changing aws identity. else [[ -v VERBOSE ]] && set -x rm -f credentials || true ln -s "${aws_creds}" credentials [[ -v VERBOSE ]] && set +x fi aws_config="config.""${who}" if [ ! -f "${aws_config}" ]; then warn file "${aws_config}" does not exist. Not installing. else [[ -v VERBOSE ]] && set -x rm -f config || true ln -s "${aws_config}" config [[ -v VERBOSE ]] && set +x fi } function ssh_list() { # list available ssh credentials if ! cd ~/.ssh; then warn "No ~/.ssh credentials"; echo; return; fi info available SSH credentials ls -ld id_rsa.* id_dsa.* authorized_keys.* config.* || true echo } function ssh_whoami() { # list current ssh identity if ! cd ~/.ssh; then warn "No ~/.ssh credentials"; echo; return; fi info Current SSH identities info ls -ld id_??? || warn "no ~/.ssh/id_{rsa,dsa} file" ls -ld authorized_keys || warn "no authorized_keys file" ls -ld config || warn "no config file" info SSH Agent Identities ssh-add -l echo } function ssh_become() { # change ssh identity if ! cd ~/.ssh; then warn "No ~/.ssh credentials"; echo; return; fi rsa_creds="id_rsa.""${who}" dsa_creds="id_dsa.""${who}" authorized_keys="authorized_keys.""${who}" config="config.""${who}" if [ -f "${dsa_creds}" ]; then ssh_creds="${dsa_creds}" elif [ -f "${rsa_creds}" ]; then ssh_creds="${rsa_creds}" else echo "No ssh creds found. "${rsa_creds}" and "${dsa_creds}" do not exist." exit 1 fi # symlnk ssh creds into ~/.ssh target=`basename $ssh_creds ".""${who}"` if [ -f "${ssh_creds}" ]; then [[ -v VERBOSE ]] && set +x rm -f "${target}" || true ln -s "${ssh_creds}" "${target}" chmod 400 "${target}" ssh-add "${ssh_creds}" [[ -v VERBOSE ]] && set -x fi # symlnk authinfo creds into ~/.ssh target=`basename $authorized_keys ".""${who}"` if [ -f "${authorized_keys}" ]; then [[ -v VERBOSE ]] && set +x rm -f "${target}" || true ln -s "${authorized_keys}" "${target}" chmod 644 "${target}" [[ -v VERBOSE ]] && set -x fi # symlnk config into ~/.ssh target=`basename $config ".""${who}"` if [ -f "${config}" ]; then [[ -v VERBOSE ]] && set +x rm -f "${target}" || true ln -s "${config}" "${target}" chmod 644 "${target}" [[ -v VERBOSE ]] && set -x fi } function pass_list() { # list available pass credentail sets (diretories) info available pass credentials sets ls -ld ~/.password-store.* || true echo } function pass_whoami() { # list current pass identity if [ ! -L ~/.password-store ]; then warn "No ~/.password-store directory"; echo; return; fi info Current pass credential set info ls -ld ~/.password-store || true echo } function pass_become() { # change pass identity rm -f ~/.password-store || true ln -s ~/.password-store."${who}" ~/.password-store gpg_become # need to switch GPG IDs too } function org_list() { # list available org credentail sets (diretories) info available org credentials sets ls -ld ~/Org.* || true echo } function org_whoami() { # list current org identity if [ ! -L ~/Org ]; then warn "No ~/Org directory"; echo; return; fi info Current org credential set info ls -ld ~/Org || true echo } function org_become() { # change org identity rm -f ~/Org || true ln -s ~/Org."${who}" ~/Org } function git_list() { # list available git credentail sets (diretories) info available git credentials sets ls -ld ~/.gitconfig.* || true echo } function git_whoami() { # list current git identity if [ ! -L ~/.gitconfig ]; then warn "No git config"; echo; return; fi info Current git credential set info ls -ld ~/.gitconfig || true echo } function git_become() { # change git identity rm -f ~/.gitconfig || true ln -s ~/.gitconfig."${who}" ~/.gitconfig #gpg_become # need to switch GPG IDs too } # # "main()" begins here # # Defaults SSH=1 AWS=1 GPG=1 PASSWORD=1 ORG=1 GIT=1 # parse global options for i in "$@" do case $i in -a|--aws) AWS=1 unset GIT unset SSH unset GPG unset PASSWORD unset ORG d_flag="-d" shift # past argument with no value ;; -d|--debug) DEBUG=1 d_flag="-d" shift # past argument with no value ;; -g|--gnupg) GPG=1 unset GIT unset AWS unset SSH unset PASSWORD unset ORG g_flag="-g" shift # past argument with no value ;; -h|--help) usage ;; -l|--list) LIST=1 d_flag="-d" shift # past argument with no value ;; -o|--org) ORG=1 unset GIT unset PASSWORD unset AWS unset SSH unset GPG p_flag="-p" shift # past argument with no value ;; -p|--pass) PASSWORD=1 unset GIT unset AWS unset SSH unset GPG unset ORG p_flag="-p" shift # past argument with no value ;; -t|--git) GIT=1 unset PASSWORD unset AWS unset SSH unset GPG unset ORG p_flag="-p" shift # past argument with no value ;; -s|--ssh) SSH=1 unset GIT unset AWS unset GPG unset PASSWORD unset ORG d_flag="-d" shift # past argument with no value ;; -v|--verbose) VERBOSE=1 v_flag="-v" shift # past argument with no value ;; -w|--whoami) WHOAMI=1 v_flag="-v" shift # past argument with no value ;; -*|--*) usage "Unknown state option: $i" ;; esac done # Pull off command line args if [[ ! -v LIST && ! -v WHOAMI ]]; then if [ "$#" -ne 1 ]; then usage need a username fi who="${1}" fi if [[ ! -v SSH && ! -v AWS && ! -v ORG && ! -v PASSWORD && ! -v GPG && ! -v GIT ]]; then die "Must specify at least one of '--aws' '--ssh' '--gnupg' '--pass'" fi # list/show/become aws credentials if [ -v AWS ]; then if [[ -v LIST ]]; then aws_list elif [[ -v WHOAMI ]]; then aws_whoami else aws_become fi fi # list/show/become ssh credentials if [ -v SSH ]; then if [[ -v LIST ]]; then ssh_list elif [[ -v WHOAMI ]]; then ssh_whoami else ssh_become fi fi # list/show/become GPG credentials if [ -v GPG ]; then if [[ -v LIST ]]; then gpg_list elif [[ -v WHOAMI ]]; then gpg_whoami else gpg_become fi fi # list/show/become pass credentials if [ -v PASSWORD ]; then if [[ -v LIST ]]; then pass_list elif [[ -v WHOAMI ]]; then pass_whoami else pass_become fi fi # list/show/become git credentials if [ -v GIT ]; then if [[ -v LIST ]]; then git_list elif [[ -v WHOAMI ]]; then git_whoami else git_become fi fi # list/show/become org credentials if [ -v ORG ]; then if [[ -v LIST ]]; then org_list elif [[ -v WHOAMI ]]; then org_whoami else org_become fi fi