diff options
author | Silvio Rhatto <rhatto@riseup.net> | 2013-09-05 23:24:05 -0300 |
---|---|---|
committer | Silvio Rhatto <rhatto@riseup.net> | 2013-09-05 23:24:05 -0300 |
commit | 5811e07b6caca8023d823b8e7cf3eedc1dc1f8d9 (patch) | |
tree | 761fe9a3e67eb9f36d518e06a962f92cfcd8ded6 /lib | |
parent | 3e01335b6df32dbbc251aface2cb3e3bad61c05b (diff) | |
parent | f91709c2abaa2b3011ef0b9799ce2fa010f9d534 (diff) | |
download | keyringer-5811e07b6caca8023d823b8e7cf3eedc1dc1f8d9.tar.gz keyringer-5811e07b6caca8023d823b8e7cf3eedc1dc1f8d9.tar.bz2 |
Merge branch 'master' into debian
Diffstat (limited to 'lib')
-rw-r--r-- | lib/keyringer/completions/bash/keyringer | 124 | ||||
-rw-r--r-- | lib/keyringer/completions/zsh/_keyringer | 88 | ||||
-rw-r--r-- | lib/keyringer/functions | 41 |
3 files changed, 245 insertions, 8 deletions
diff --git a/lib/keyringer/completions/bash/keyringer b/lib/keyringer/completions/bash/keyringer new file mode 100644 index 0000000..e33977a --- /dev/null +++ b/lib/keyringer/completions/bash/keyringer @@ -0,0 +1,124 @@ +#!bash +# +# Keyringer bash completion +# + +if [[ -n ${ZSH_VERSION-} ]]; then + autoload -U +X bashcompinit && bashcompinit +fi + +# Completion for git subcommand +_keyringer_git_complete() { + if [ -e "/etc/bash_completion.d/git" ]; then + ( + source /etc/bash_completion.d/git + cd $path + COMP_WORDS=(git $*) + COMP_CWORD=$((${#COMP_WORDS[*]} - 1)) + + if [ "$COMP_CWORD" == "0" ]; then + COMP_CWORD=1 + fi + + _git + + LAST=${COMP_WORDS[COMP_CWORD]} + REPLY=${COMPREPLY[@]} + + if [ "$REPLY" == "$LAST" ]; then + return + fi + + echo ${COMPREPLY[@]} + ) + fi +} + +_keyringer() { + # Standard stuff + local cur prev opts config + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + command="${COMP_WORDS[2]}" + + # Initial options + config="$HOME/.keyringer" + + # Check if we have initial configuration + if [ ! -d "$config" ]; then + return + fi + + # Process config + source $config/config + path="`eval echo '$'$instance`" + keyrings="`ls $config | sed -e 's/config//'`" + + # Available instances + instances="`echo $keyrings | sed -e 's/ /|/'`" + + # The current instance + instance="${COMP_WORDS[1]}" + + # Command completions + if [ "${#COMP_WORDS[@]}" == "2" ]; then + opts="$keyrings" + elif [ "${#COMP_WORDS[@]}" == "3" ] && echo "${prev}" | grep -qe "[$instances]"; then + opts="`keyringer $instance commands`" + elif [ "${#COMP_WORDS[@]}" == "4" ]; then + case "${prev}" in + options|preferences) + opts="ls edit add" + ;; + recipients) + opts="ls edit" + ;; + ls|encrypt|encrypt-batch|decrypt|edit|append|append-batch|del|recrypt) + opts="$(bash -c "set -f && keyringer $instance ls -p -d ${cur}*" 2> /dev/null)" + ;; + genpair) + opts="gpg ssh ssl ssl-self" + ;; + git) + opts="$(_keyringer_git_complete ${cur})" + ;; + *) + ;; + esac + elif [ "${#COMP_WORDS[@]}" == "5" ]; then + case "${command}" in + recipients) + opts="$(cd $path/config/recipients && ls -p ${cur}* 2> /dev/null)" + ;; + genpair) + opts="$(bash -c "set -f && keyringer $instance ls -p -d ${cur}*" 2> /dev/null)" + ;; + git) + # TODO + opts="$(_keyringer_git_complete ${prev} ${cur})" + ;; + *) + ;; + esac + elif [ "${command}" == "git" ]; then + # TODO + opts="$(_keyringer_git_complete ${COMP_WORDS[@]:3})" + fi + + # Avoid annoying bell and extra tab + if [ -z "$ZSH_VERSION" ]; then + bind 'set show-all-if-ambiguous on' + fi + + # Return the available options + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + + if [ -z "$ZSH_VERSION" ]; then + [[ $COMPREPLY == */ ]] && compopt -o nospace + fi + + return 0 +} + +complete -F _keyringer keyringer diff --git a/lib/keyringer/completions/zsh/_keyringer b/lib/keyringer/completions/zsh/_keyringer new file mode 100644 index 0000000..c8ada9b --- /dev/null +++ b/lib/keyringer/completions/zsh/_keyringer @@ -0,0 +1,88 @@ +#compdef keyringer + +# Completion for git subcommand +_keyringer_git_complete() { + # TODO: how to call _git() properly? + return +} + +_keyringer() { + local curcontext="$curcontext" state line + typeset -A opt_args + + # Initial options + local config="$HOME/.keyringer" + + # Check if we have initial configuration + if [ ! -d "$config" ]; then + return + fi + + # Process config + local keyrings="`ls $config | sed -e 's/config//'`" + source $config/config + keyring_path="`eval echo '$'$words[2]`" + + _arguments \ + '1: :->keyring' \ + '2: :->action' \ + '3: :->options' \ + '4: :->misc' \ + '*: :->final' + + case $state in + keyring) + _arguments "1:Keyrings:($keyrings)" + ;; + action) + compadd "$@" `keyringer $words[2] commands` + ;; + options) + case $words[3] in + options|preferences) + compadd "$@" ls edit add + ;; + recipients) + compadd "$@" ls edit + ;; + ls|encrypt|encrypt-batch|decrypt|edit|append|append-batch|del|recrypt) + # TODO: do not rely on bash + compadd "$@" $(bash -c "set -f && keyringer $words[2] ls -p -d $words[4]*" 2> /dev/null) + ;; + genpair) + compadd "$@" gpg ssh ssl ssl-self + ;; + git) + compadd "$@" $(_keyringer_git_complete $words[4]) + ;; + *) + ;; + esac + ;; + misc) + case "$words[3]" in + recipients) + compadd "$@" $(cd $keyring_path/config/recipients && ls -p $words[5]* 2> /dev/null) + ;; + genpair) + # TODO: do not rely on bash + compadd "$@" $(bash -c "set -f && keyringer $words[2] ls -p -d $words[5]*" 2> /dev/null) + ;; + git) + # TODO + compadd "$@" $(_keyringer_git_complete $words[4] $words[5]) + ;; + *) + ;; + esac + ;; + *) + if [ $words[3] == "git" ]; then + # TODO + true + fi + ;; + esac +} + +_keyringer "$@" diff --git a/lib/keyringer/functions b/lib/keyringer/functions index 6ac8bf8..3fa7170 100644 --- a/lib/keyringer/functions +++ b/lib/keyringer/functions @@ -74,6 +74,10 @@ function keyringer_exec { # Dispatch if keyringer_has_action "$action"; then "$ACTIONS/$action" "$basedir" $* + err="$?" + if [ "$err" != "0" ]; then + exit "$err" + fi fi } @@ -338,8 +342,24 @@ function keyringer_action_usage { fi } +# Return available actions +function keyringer_show_actions { + ls $ACTIONS +} + +# Usage +function keyringer_usage { + printf "Usage: %s <keyring> <action> [arguments]\n" "$BASENAME" + printf "Available commands: \n" + keyringer_show_actions | sed -e 's/^/\t/' +} + # Check recipients function keyringer_check_recipients { + if [ "$KEYRINGER_CHECK_RECIPIENTS" == "false" ]; then + return + fi + # Check if recipients file is empty. if [ "`grep -vE "^#|^$" "$RECIPIENTS"/* | wc -l`" == 0 ] && [ "$SUBCOMMAND" != "edit" ]; then echo "Fatal: no recipients configured for this keyring." @@ -364,15 +384,19 @@ function keyringer_check_recipients { echo "Fatal: please set the full GPG signature hash for key ID $recipient:" cat <<-EOF -Recipients file can't have 32-bit keyids (e.g. DEADBEEF or DECAF123). These -are trivial to spoof. With a few gigs of disk space and a day of time on -cheap, readily-available hardware, it's possible to build keys to match every -possible 32-bit keyid. The search space just isn't big enough. +Please provide a full OpenPGP fingerprint, for example: + + john@doe.com ABCD1234ABCD12345678ABCD1234ABCD12345678 -If you're going to specify keys by keyid, they should be specified by full -160-bit OpenPGP fingerprint. It would be very bad if someone spoofed a keyID -and caused another participant in a keyringer instance to reencrypt a secret -store to the spoofed key in addition to your own. +Short key ids (for example, DEADBEEF or DECAF123) are not allowed in +recipient files because they are easy to spoof. Researchers have proven +that it is possible to build fake keys to match any possible short key +id by using a few gigabytes of disk space, and a day of computation on +common hardware. + +Otherwise, the encryption can be broken, if someone spoofs a short key +id, and causes a participant in a keyringer repository to encrypt +secrets to a fake key. EOF exit 1 else @@ -446,5 +470,6 @@ function keyringer_create_new_recipients { # Setup environment if [ "$(basename "$0")" != "keyringer" ]; then + keyringer_config_load_preferences keyringer_set_env $* fi |