#!/bin/bash
#
# sendsignedkey -- send a specific key to the owner via signed/encryted email
#
# Hacked together by Ewen McNeill <ewen@naos.co.nz>
#
# Assumes:
# - the key is already signed
# - it should be sent to the primary email address
# - GPG agent mode is in use, or you like typing your passphrase
# - loosely based on key-party-signing by Mark Suter, downloaded from:
#   http://zwitterion.org/software/key-party-signing/
#
# $Id: key-party-signing,v 1.3 2004/01/16 23:50:50 suter Exp suter $
# Copyright (C) 2003 Mark Suter <mark.suter@miju.com.au>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

## Configuration
from="Ewen McNeill <ewen@naos.co.nz>"
gpgflags="--use-agent"

# Auto-add a keyring in the current directory (for, eg, keysigning parties)
# 
# Seems to confuse process of adding signatures...; do export/import trick
#if ls *.gpg | grep -v '\*'; then
#  gpgflags="${gpgflags} --keyring `pwd`/`ls *.gpg | head`"
#  #echo "FLAGS: ${gpgflags}"
#fi

## Our "die" function (think perl)
function die () { echo "$@" 1>&2 ; exit 1 ; }

## Set our PATH and test for needed binaries
export PATH=${HOME}/.bin:/usr/local/sbin:/usr/local/bin:/opt/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
hash test mktemp gpg sort perl rm sendmail vi head || die $0: required binaries not present

## Some defaults
test -e "${EDITOR:=vi}"
test -e "${PAGER:=head}"

## A temp dir for the emails
emails=$(mktemp -d -t sendsignedkey) || die $0: mktemp failed

## Pick up the keyid
keyid="${1}"
test -z "$keyid" && die usage: $0 keyid ...

## Process each key
for keyid; do
    ## Announce what we're doing
    perl -e 'printf("%s\n%s\n%s\n", "-" x 80, $ARGV[0], "-" x 80);' "Doing key  $keyid"
    gpg $gpgflags --fingerprint $keyid

    ## Offer to skip the key :)
    action=""
    read -p "Send this key (y/n) ? " -n 1 action ; echo
    if [ "$action" != "n" ] ; then
	## Construct an email
	email=$emails/$keyid.email

	# 2006/01/28 - gpg output format has changed; now need to match
	# the first uid.  If they revoke that, too bad, no signature for
	# them.
	#to=$(gpg $gpgflags --list-keys $keyid | perl -lne 'm{pub \s+ \d+ [DR] / .{8} \s .*? <(\S+ @ \S+)> }x and print $1')
	to=$(gpg $gpgflags --list-keys $keyid | grep '^uid' | head -1 | sed 's/^.*<//; s/>.*$//')
	echo "From: $from" > $email
	echo "To: $to" >> $email
	echo "Subject: Signed OpenPGP key (ID $keyid)" >> $email
	echo "" >> $email
	echo "Enclosed below is a (signed) copy of the OpenPGP public key for" >>$email
	echo "" >> $email
	echo "$to" >>$email
	echo "" >> $email
	echo "encrypted with that public key (id $keyid)." >>$email
	echo "" >>$email
	echo "The key/signatures can be added to your local OpenPGP agent" >>$email
	echo "by decrypting the OpenPGP block below and importing the resulting" >>$email
	echo "ascii armoured public key, eg" >>$email
	echo "" >>$email
	echo "gpg --decrypt MESSAGE | gpg --import" >>$email
	echo "" >>$email
	gpg $gpgflags --export --armor $keyid | \
	    gpg $gpgflags --sign --encrypt --armour --recipient $keyid >> $email
	echo "" >> $email

	## Let the user handle the email
	action=""
	$PAGER $email
	while [ "$action" != "d" -a "$action" != "m" ] ; do
	    read -p "$keyid: (d)elete, (e)dit, or (m)ail ? " -n 1 action
	    case $action in
		"d" ) rm $email && echo eleted. ;;
		"e" ) echo diting... && $EDITOR $email ;;
		"m" ) sendmail -t < $email && rm $email && echo ailed. ;;
		*   ) echo " - Huh?" ;;
	    esac
	done
    fi
done

## Clean up
rmdir $emails || die $0: something weird happened - file are still in $emails
