]> gitweb.fluxo.info Git - keyringer.git/commitdiff
Multiple recipients file support
authorSilvio Rhatto <rhatto@riseup.net>
Mon, 27 Feb 2012 14:25:28 +0000 (11:25 -0300)
committerSilvio Rhatto <rhatto@riseup.net>
Mon, 27 Feb 2012 14:25:28 +0000 (11:25 -0300)
README
keyringer
lib/keyringer/functions
share/keyringer/edit
share/keyringer/encrypt
share/keyringer/recipients
share/keyringer/recrypt

diff --git a/README b/README
index 585550a150085b2db4405e68de6b39c3edc65453..a20c32c75ea7cdaff18a24364c8365eb3fa67223 100644 (file)
--- 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
 ----------------
 
index 391646a95ee8fa2d40d9eac2972bc062ab3e8f69..890468532d308d132f3f9212cdbd25d4b73666cd 100755 (executable)
--- 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"
index da8be2e8cc3f916ee4e34eaea2b443d1e657a870..a1c95a86051152bd731e82cce0f246b33f64ccd4 100644 (file)
@@ -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 $*
index 73a59d90e799fddcd9a9b343a5ce728d89a152da..10798e2292c3f846cbc0e41c2590f6c85676aeb7 100755 (executable)
@@ -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"
index 709aac32867b2112f0df82d24ca2d0a22eef3e1f..da0941fbfc84df463beab73c38e13f96fba50c36 100755 (executable)
@@ -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
index 2fe2ddfd70783c3a120430098af62168a51c0168..ab61bd7ac97544fd250ded331718644b0ad07a13 100755 (executable)
@@ -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
index 438039d2e7c5c897d390e3a777494de1750f357b..cbf1af9e926817492d54c84980a7929b637334d9 100755 (executable)
@@ -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