From c5b447359303979ac91e8cea126d14480536df94 Mon Sep 17 00:00:00 2001 From: Silvio Rhatto Date: Sat, 22 Jan 2011 13:00:43 -0200 Subject: Renaming lib/keyringer to lib/bash --- lib/bash/functions | 321 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 lib/bash/functions (limited to 'lib/bash/functions') diff --git a/lib/bash/functions b/lib/bash/functions new file mode 100644 index 0000000..11d1b86 --- /dev/null +++ b/lib/bash/functions @@ -0,0 +1,321 @@ +#!/bin/bash +# +# Common functions. +# + +# Setup main configuration and load preferences +function keyringer_config_load { + if [ -f "$HOME/.$NAME" ]; then + echo "Converting legacy configuration scheme..." + mv "$HOME/.$NAME" "$HOME/.$NAME.tmp" + mkdir "$HOME/.$NAME" + mv "$HOME/.$NAME.tmp" "$CONFIG" + fi + + if [ ! -e "$CONFIG" ]; then + echo "Creating $CONFIG..." + mkdir -p `dirname $CONFIG` + touch "$CONFIG" + chmod 600 "$CONFIG" + echo "# Keyringer config file." > "$CONFIG" + echo "" >> "$CONFIG" + fi + + keyringer_config_load_preferences +} + +# Load config preferences +function keyringer_config_load_preferences { + # Load custom keyring preferences + if [ ! -z "$PREFERENCES" ] && [ -f "$PREFERENCES" ]; then + source "$PREFERENCES" + fi +} + +# Load a parameter from config +function keyringer_config { + if [ -z "$CONFIG" ]; then + echo "Your have to set CONFIG variable in the code" + exit 1 + elif [ -e "$CONFIG" ]; then + grep -e "^$1=" "$CONFIG" | tail -n 1 | cut -d = -f 2 | sed -e 's/"//g' -e "s/'//g" | sed -e 's/ *#.*$//' + else + echo "Config file not found: $CONFIG" + exit 1 + fi +} + +# Return the list of recipients +function keyringer_recipients { + grep -v '^#' "$1" | grep -v '^$' | awk '{ print "-r " $2 }' | xargs +} + +# Check if keyringer has a given action +function keyringer_has_action { + if [ -z "$ACTIONS" ]; then + echo "Your have to set ACTIONS variable in the code" + exit 1 + fi + + if [ -e "$ACTIONS/$1" ]; then + true + else + false + fi +} + +# Execute an action +function keyringer_exec { + # Setup + action="$1" + basedir="$2" + shift 2 + + # Dispatch + if keyringer_has_action "$action"; then + "$ACTIONS/$action" "$basedir" $* + fi +} + +# Return a filename with correct extension +function keyringer_filename { + if [ -z "$1" ]; then + return + else + printf "%s/%s.asc\n" "$(dirname "$1")" "$(basename "$1" .asc)" + fi +} + +# Check if a folder is inside a git repository +function keyringer_is_git { + if [ -z "$1" ]; then + false + elif [ ! -d "$1" ]; then + false + elif [ -d "$1/.git" ]; then + true + else + cwd="`pwd`" + cd "$1" && git="`git status &> /dev/null`" && cd "$cwd" + + if [ "$git" != "128" ]; then + true + else + false + fi + fi +} + +# Setup a temporary file +function keyringer_set_tmpfile { + if [ -z "$BASEDIR" ]; then + echo "Please set BASEDIR before creating a tmp file" + exit 1 + fi + + if [ -z "$1" ]; then + template="$BASEDIR/tmp/keyringer.XXXXXXXXXX" + else + template="$BASEDIR/tmp/$1.XXXXXXXXXX" + fi + + mkdir -p "$BASEDIR/tmp" + keyringer_git_ignore 'tmp/*' + + if [ "$2" == "-d" ]; then + TMPWORK="$(mktemp -d "$template")" + else + TMPWORK="$(mktemp "$template")" + fi + + if [ "$?" != "0" ]; then + printf "Error: can't set TMPWORK %s\n" "$TMPWORK" + exit 1 + fi + + trap "keyringer_unset_tmpfile $TMPWORK; exit" INT TERM EXIT +} + +# Remove a temporary file +function keyringer_unset_tmpfile { + if [ -z "$1" ]; then + echo "No tmp file set" + fi + + rm -f "$1" + + if [ "$?" != "0" ]; then + echo "Warning: could not delete file $1. Please delete it manually as it might have sensitive information." + exit 1 + fi +} + +# Add a pattern into gitignore +function keyringer_git_ignore { + if [ ! -z "$BASEDIR/.gitignore" ]; then + echo "$1" > "$BASEDIR/.gitignore" + keyringer_exec git "$BASEDIR" add .gitignore + else + if ! grep -q -e "^$1$" "$BASEDIR/.gitignore"; then + echo "$1" >> "$BASEDIR/.gitignore" + fi + fi +} + +# Set needed environment variables and do basic checks. +function keyringer_set_env { + if [ -z "$1" ]; then + echo "Error: missing arguments for keyringer_set_env" + exit 1 + fi + + ACTIONS="`dirname $0`" + BASENAME="`basename $0`" + BASEDIR="$1" + SUBCOMMAND="$2" + KEYDIR="$BASEDIR/keys" + RECIPIENTS="$BASEDIR/config/recipients" + OPTIONS="$BASEDIR/config/options" + VERSION_INFO="$BASEDIR/config/version" + + if [ -z "$BASEDIR" ]; then + keyringer_action_usage + exit 1 + fi + + if [ ! -f "$RECIPIENTS" ]; then + echo "No recipient config was found" + exit 1 + fi + + if [ -z "$EDITOR" ]; then + if type sensible-editor > /dev/null 2>&1 ; then + EDITOR=sensible-editor + elif type editor > /dev/null 2>&1 ; then + EDITOR=editor + else + echo "You have to set EDITOR env variable" + exit 1 + fi + fi + + if [ ! -f "$OPTIONS" ]; then + echo "No option config was found" + exit 1 + fi + + # Check recipients file + keyringer_check_recipients $SUBCOMMAND + + # Ensure that keydir exists + mkdir -p "$KEYDIR" && chmod 700 "$KEYDIR" + + # Check keyring config version + keyringer_check_version +} + +# Configuration version tracking to help keyring upgrades +function keyringer_check_version { + if [ ! -f "$VERSION_INFO" ]; then + echo "Creating configuration version file..." + echo 0 > "$VERSION_INFO" + keyringer_exec git "$BASEDIR" add config/version + fi + + VERSION="`cat $VERSION_INFO`" +} + +# Get a file argument +function keyringer_get_file { + FILE="$(keyringer_filename "$1")" + + if [ -z "$FILE" ]; then + keyringer_action_usage + exit 1 + elif [ ! -f "$KEYDIR/$FILE" ]; then + echo "File not found: $KEYDIR/$FILE" + exit 1 + fi +} + +# Get a new file argument +function keyringer_get_new_file { + FILE="$(keyringer_filename "$1")" + + if [ -z "$FILE" ]; then + keyringer_action_usage + exit 1 + fi +} + +# Get a command argument +function keyringer_get_command { + # Aditional parameters + COMMAND="$1" + + if [ -z "$COMMAND" ]; then + keyringer_action_usage command + exit 1 + fi +} + +# Run the action usage +function keyringer_action_usage { + if [ "`type -t "keyringer_usage_$BASENAME"`" == "function" ]; then + # Use custom action usage + "keyringer_usage_$BASENAME" + else + # Default usage + if [ "$1" == "command" ]; then + echo "Usage: keyringer $BASENAME [arguments]" + else + echo "Usage: keyringer $BASENAME " + fi + fi +} + +# Check recipients +function keyringer_check_recipients { + # Check recipients header for updates. + if grep -qe ' XXXXXXXX$' "$RECIPIENTS"; then + echo "Updating recipients file..." + sed -i -e 's/ XXXXXXXX$/ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/' "$RECIPIENTS" + fi + + if [ "$1" == "edit" ]; then + # Don't do the other checks at edit mode. + return + fi + + for recipient in $(cat "$RECIPIENTS" | grep -v '^#' | awk '{ print $2 }'); do + size=$(echo "$recipient" | wc -c) + if (( $size < 41 )); then + 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. + +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. +EOF + exit 1 + else + gpg --list-key "$recipient" &> /dev/null + if [ "$?" != "0" ]; then + echo "Fatal: no such key $recipient on your GPG keyring." + echo "Please check for this key or fix the recipient file." + exit 1 + fi + fi + done +} + +# Setup environment +if [ "$(basename "$0")" != "keyringer" ]; then + keyringer_set_env $* +fi -- cgit v1.2.3