aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSilvio Rhatto <rhatto@riseup.net>2012-02-27 11:25:28 -0300
committerSilvio Rhatto <rhatto@riseup.net>2012-02-27 11:25:28 -0300
commite6d3f3e0c5671ff853404a962d856ec493b8dbdb (patch)
tree61959b54f3b2ac214de733472f77bf8872bd1c2b
parent8fa3ddbc6cdf5adb3414c782ff83c371b17d38d8 (diff)
downloadkeyringer-e6d3f3e0c5671ff853404a962d856ec493b8dbdb.tar.gz
keyringer-e6d3f3e0c5671ff853404a962d856ec493b8dbdb.tar.bz2
Multiple recipients file support
-rw-r--r--README14
-rwxr-xr-xkeyringer3
-rw-r--r--lib/keyringer/functions95
-rwxr-xr-xshare/keyringer/edit5
-rwxr-xr-xshare/keyringer/encrypt5
-rwxr-xr-xshare/keyringer/recipients31
-rwxr-xr-xshare/keyringer/recrypt5
7 files changed, 140 insertions, 18 deletions
diff --git a/README b/README
index 585550a..a20c32c 100644
--- a/README
+++ b/README
@@ -61,9 +61,21 @@ Managing recipients
Your next step is tell keyringer the GPG key ids to encrypt files to:
- keyringer <keyring> recipients edit
+ keyringer <keyring> recipients edit [recipient-name]
keyringer <keyring> recipients ls
+Keyringer support multiple recipients in a per-folder style. Try it by
+creating a sample keyringer
+
+ keyringer <keyring> recipients edit closest-friends
+
+Fill it with your friends key IDs. Now encrypt a secret just for then:
+
+ keyringer <keyring> encrypt closest-friends/secret
+
+In other words, if keyringer finds a recipient file matching a given path,
+it will use it instead of the global recipients file.
+
Managing keys
----------------
diff --git a/keyringer b/keyringer
index 391646a..8904685 100755
--- a/keyringer
+++ b/keyringer
@@ -57,8 +57,7 @@ function keyringer_init {
mkdir -p "$BASEDIR/"{config,keys}
# Setup recipients
- echo "# Use entries in the form of 'john@doe.com XXXXXXXX" > "$RECIPIENTS"
- echo "" >> "$RECIPIENTS"
+ keyringer_create_new_recipients "$RECIPIENTS/default"
# Setup options
touch "$OPTIONS"
diff --git a/lib/keyringer/functions b/lib/keyringer/functions
index da8be2e..a1c95a8 100644
--- a/lib/keyringer/functions
+++ b/lib/keyringer/functions
@@ -173,7 +173,8 @@ function keyringer_set_env {
BASEDIR="$1"
SUBCOMMAND="$2"
KEYDIR="$BASEDIR/keys"
- RECIPIENTS="$BASEDIR/config/recipients"
+ RECIPIENTS_BASE="config/recipients"
+ RECIPIENTS="$BASEDIR/$RECIPIENTS_BASE"
OPTIONS="$BASEDIR/config/options"
VERSION_INFO="$BASEDIR/config/version"
@@ -182,7 +183,7 @@ function keyringer_set_env {
exit 1
fi
- if [ ! -f "$RECIPIENTS" ]; then
+ if [ ! -e "$RECIPIENTS" ]; then
echo "No recipient config was found"
exit 1
fi
@@ -209,14 +210,17 @@ function keyringer_set_env {
GPG="gpg"
fi
+ # Check keyring config version
+ keyringer_check_version
+
+ # Upgrade configuration
+ keyringer_upgrade
+
# 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
@@ -232,6 +236,26 @@ function keyringer_check_version {
VERSION="`cat $VERSION_INFO`"
}
+# Configuration upgrades
+function keyringer_upgrade {
+ # Upgrade 0.1
+ if [ "$VERSION" == "0" ]; then
+ if [ ! -d "$RECIPIENTS" ]; then
+ echo "Converting recipients to the new scheme..."
+ mv $RECIPIENTS $RECIPIENTS.tmp
+ mkdir $RECIPIENTS
+ mv $RECIPIENTS.tmp $RECIPIENTS/default
+ keyringer_exec git "$BASEDIR" add $RECIPIENTS_BASE/default
+ keyringer_exec git "$BASEDIR" add config/version
+ keyringer_exec git "$BASEDIR" commit -m "Config-upgrade-0.1"
+ echo "Upgrade to version 0.1 completed"
+ fi
+
+ # Update version information
+ echo 0.1 > $VERSION_INFO
+ fi
+}
+
# Get a file argument
function keyringer_get_file {
FILE="$(keyringer_filename "$1")"
@@ -284,16 +308,16 @@ function keyringer_action_usage {
# Check recipients
function keyringer_check_recipients {
# Check if recipients file is empty.
- if [ "`grep -vE "^#|^$" "$RECIPIENTS" | wc -l`" == 0 ] && [ "$SUBCOMMAND" != "edit" ]; then
+ if [ "`grep -vE "^#|^$" "$RECIPIENTS"/* | wc -l`" == 0 ] && [ "$SUBCOMMAND" != "edit" ]; then
echo "Fatal: no recipients configured for this keyring."
echo "Please edit your recipients file first."
exit 1
fi
# Check recipients header for updates.
- if grep -qe ' XXXXXXXX$' "$RECIPIENTS"; then
+ if grep -qe ' XXXXXXXX$' "$RECIPIENTS"/*; then
echo "Updating recipients file..."
- sed -i -e 's/ XXXXXXXX$/ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/' "$RECIPIENTS"
+ sed -i -e 's/ XXXXXXXX$/ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/' "$RECIPIENTS"/*
fi
if [ "$1" == "edit" ]; then
@@ -301,7 +325,7 @@ function keyringer_check_recipients {
return
fi
- for recipient in $(cat "$RECIPIENTS" | grep -v '^#' | awk '{ print $2 }'); do
+ 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:"
@@ -329,6 +353,59 @@ EOF
done
}
+# Set recipients
+function keyringer_set_recipients {
+ if [ -z "$1" ]; then
+ keyringer_set_default_recipients
+ else
+ candidate="$1"
+
+ # Find the first matching recipient
+ while [ ! -z "$candidate" ] && [ "$candidate" != "." ] && [ "$candidate" != "/" ]; do
+ if [ -e "$RECIPIENTS/$candidate" ]; then
+ RECIPIENTS_FILE="$RECIPIENTS/$candidate"
+ RECIPIENTS_FILE_BASE="$RECIPIENTS_BASE/$candidate"
+ return
+ fi
+
+ candidate="`dirname $candidate`"
+ done
+
+ keyringer_set_default_recipients "$1"
+
+ fi
+}
+
+# Set default recipients
+function keyringer_set_default_recipients {
+ if [ -e "$RECIPIENTS/default" ]; then
+ RECIPIENTS_FILE="$RECIPIENTS/default"
+ RECIPIENTS_FILE_BASE="$RECIPIENTS_BASE/default"
+ else
+ echo "Fatal: no suitable recipient file found for path $1"
+ exit 1
+ fi
+}
+
+# Set a new recipient, avoid file checks
+function keyringer_set_new_recipients {
+ if [ -z "$1" ]; then
+ keyringer_set_default_recipients
+ else
+ RECIPIENTS_FILE="$RECIPIENTS/$1"
+ RECIPIENTS_FILE_BASE="$RECIPIENTS_BASE/$1"
+ fi
+}
+
+# Create a new recipients file
+function keyringer_create_new_recipients {
+ if [ ! -e "$1" ]; then
+ mkdir -p "`dirname $1`"
+ echo "# Use entries in the form of 'john@doe.com XXXXXXXX" > "$1"
+ echo "" >> "$1"
+ fi
+}
+
# Setup environment
if [ "$(basename "$0")" != "keyringer" ]; then
keyringer_set_env $*
diff --git a/share/keyringer/edit b/share/keyringer/edit
index 73a59d9..10798e2 100755
--- a/share/keyringer/edit
+++ b/share/keyringer/edit
@@ -10,6 +10,9 @@ source "$LIB" || exit 1
# Get file
keyringer_get_file "$2"
+# Set recipients file
+keyringer_set_recipients "$FILE"
+
# Warn user
echo "Make sure that $BASEDIR is atop of an encrypted volume."
@@ -25,7 +28,7 @@ read key
"$EDITOR" "$TMPWORK"
# Encrypt again
-$GPG --yes -o "$KEYDIR/$FILE" --use-agent --armor -e -s $(keyringer_recipients "$RECIPIENTS") "$TMPWORK"
+$GPG --yes -o "$KEYDIR/$FILE" --use-agent --armor -e -s $(keyringer_recipients "$RECIPIENTS_FILE") "$TMPWORK"
# Remove temp file
keyringer_unset_tmpfile "$TMPWORK"
diff --git a/share/keyringer/encrypt b/share/keyringer/encrypt
index 709aac3..da0941f 100755
--- a/share/keyringer/encrypt
+++ b/share/keyringer/encrypt
@@ -10,6 +10,9 @@ source "$LIB" || exit 1
# Aditional parameters
keyringer_get_new_file "$2"
+# Set recipients file
+keyringer_set_recipients "$FILE"
+
# Encrypt
mkdir -p "$KEYDIR/`dirname $FILE`"
@@ -18,7 +21,7 @@ if [ "$BASENAME" == "encrypt" ]; then
echo "Type your message and finish your input with EOF (Ctrl-D)."
fi
-$GPG --use-agent --armor -e -s $(keyringer_recipients "$RECIPIENTS") - > "$KEYDIR/$FILE"
+$GPG --use-agent --armor -e -s $(keyringer_recipients "$RECIPIENTS_FILE") - > "$KEYDIR/$FILE"
# Stage
if [ -d "$BASEDIR/.git" ]; then
diff --git a/share/keyringer/recipients b/share/keyringer/recipients
index 2fe2ddf..ab61bd7 100755
--- a/share/keyringer/recipients
+++ b/share/keyringer/recipients
@@ -10,11 +10,36 @@ source "$LIB/functions" || exit 1
# Command parser
keyringer_get_command "$2"
+# Set recipients file
+keyringer_set_new_recipients "$3"
+
if [ "$COMMAND" == "ls" ]; then
- cat "$RECIPIENTS"
+ if [ ! -z "$3" ]; then
+ if [ -e "$RECIPIENTS_FILE" ]; then
+ cat "$RECIPIENTS_FILE"
+ else
+ echo "Recipients file not found: $RECIPIENTS_FILE_BASE"
+ exit 1
+ fi
+ else
+ for recipients in `ls $RECIPIENTS`; do
+ echo "In recipients file $recipients:"
+ echo "-----------------------------------------------------------------------------------"
+ cat $RECIPIENTS/$recipients
+ echo ""
+ done
+ fi
elif [ "$COMMAND" == "edit" ]; then
- "$EDITOR" "$RECIPIENTS"
- keyringer_check_recipients
+ if [ ! -z "$3" ]; then
+ keyringer_create_new_recipients $RECIPIENTS_FILE
+ "$EDITOR" "$RECIPIENTS_FILE"
+ keyringer_check_recipients
+ keyringer_exec git "$BASEDIR" add "$RECIPIENTS_FILE_BASE"
+ else
+ echo "Please specify one recipient to edit among the available:"
+ ls $RECIPIENTS | sed -e 's/^/\t/'
+ exit 1
+ fi
else
printf "%s: No such command %s\n" "$BASENAME" "$COMMAND"
exit 1
diff --git a/share/keyringer/recrypt b/share/keyringer/recrypt
index 438039d..cbf1af9 100755
--- a/share/keyringer/recrypt
+++ b/share/keyringer/recrypt
@@ -11,8 +11,11 @@ function keyringer_recrypt {
# Get file
keyringer_get_file "$1"
+ # Set recipients file
+ keyringer_set_recipients "$FILE"
+
# Recrypt
- $GPG --use-agent -d "$KEYDIR/$FILE" | $GPG --use-agent --armor -e -s $(keyringer_recipients "$RECIPIENTS") > "$KEYDIR/$FILE"
+ $GPG --use-agent -d "$KEYDIR/$FILE" | $GPG --use-agent --armor -e -s $(keyringer_recipients "$RECIPIENTS_FILE") > "$KEYDIR/$FILE"
if [ "$?" != "0" ]; then
exit 1