debian-keyring/scripts/replace-key
2015-04-13 12:04:33 -05:00

172 lines
4.8 KiB
Bash
Executable file

#!/bin/bash
# Copyright (c) 2014 Gunnar Wolf <gwolf@debian.org>,
# Based on 2008 Jonathan McDowell <noodles@earth.li>
# GNU GPL; v2 or later
# Replaces an existing key with a new one in its same keyring directory
set -e
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Usage: replace-key oldkeyid newkeyid" >&2
exit 1
fi
scriptdir=`dirname $0`
oldkey=$1
newkey=$2
# avoid gnupg touching ~/.gnupg
GNUPGHOME=$(mktemp -d -t jetring.XXXXXXXX)
export GNUPGHOME
cat > "$GNUPGHOME"/gpg.conf <<EOF
keyid-format 0xlong
keyserver hkps.pool.sks-keyservers.net
EOF
trap cleanup exit
cleanup () {
rm -rf "$GNUPGHOME"
}
newkeytemp=`mktemp -t newkey.XXXXXXXXX`
gpg --recv-key "$newkey"
gpg --export "$newkey" > $newkeytemp
# strip leading 0x from fingerprints
oldkey=${oldkey##0x}
newkey=${newkey##0x}
if [ $(echo -n $oldkey|wc -c) -eq 16 ]; then
key='0x'$(echo $oldkey|tr a-z A-Z)
elif [ $(echo -n $oldkey|wc -c) -eq 40 ] ; then
key='0x'$(echo -n $oldkey | cut -b 25-)
else
echo "Please supply either a long keyid or a full fingerprint for the old key."
exit 1
fi
for dir in *-gpg/; do
if [ -f $dir/$key ]; then
oldkeyfile=$(readlink -f "$dir/$key")
keydir=$(readlink -f $dir)
keyring=`basename $keydir`
break
fi
done
if [ -z "$oldkeyfile" -o -z "$keydir" ]; then
echo "Requested key '$oldkey' not found (looked for '*-gpg/$key')"
exit 1
fi
oldkeyfp=$(gpg --with-colons --fingerprint --no-auto-check-trustdb --no-default-keyring --keyring $oldkeyfile| grep '^fpr' | cut -d : -f 10)
newkeyfp=$(gpg --with-colons --fingerprint --no-auto-check-trustdb --no-default-keyring --keyring $newkeytemp| grep '^fpr' | cut -d : -f 10)
oldkeydata=$(gpg --with-colons --keyid long --options /dev/null --no-auto-check-trustdb < $oldkeyfile|grep '^pub')
newkeydata=$(gpg --with-colons --keyid long --options /dev/null --no-auto-check-trustdb < $newkeytemp|grep '^pub')
oldkeyuser=$(echo $oldkeydata | cut -d : -f 10)
newkeyuser=$(echo $newkeydata | cut -d : -f 10)
oldkeylen=$(echo $oldkeydata | cut -d : -f 3)
newkeylen=$(echo $newkeydata | cut -d : -f 3)
oldkeyalg=$(echo $oldkeydata | cut -d : -f 4)
if [ "$oldkeyalg" == "1" ]; then
oldkeyalg='R'
elif [ "$oldkeyalg" == "17" ]; then
oldkeyalg='D'
else
oldkeyalg='UNK'
fi
newkeyalg=$(echo $newkeydata | cut -d : -f 4)
if [ "$newkeyalg" == "1" ]; then
newkeyalg='R'
elif [ "$newkeyalg" == "17" ]; then
newkeyalg='D'
else
newkeyalg='UNK'
fi
echo $oldkeydata
echo ""
echo "About to replace key $oldkey ($oldkeyuser)"
echo " with NEW key $newkey ($newkeyuser)"
echo " in the $keyring keyring."
echo "Are you sure you want to update this key? (y/n)"
read n
if [ "x$n" = "xy" -o "x$n" = "xY" ]; then
if [ "$keyring" = "removed-1024-gpg" ]; then
destkeyring="debian-keyring-gpg"
else
destkeyring="$keyring"
fi
if ! $scriptdir/add-key $newkeytemp $destkeyring ; then
echo "add-key failed"
exit 1
fi
if [ "$keyring" = "debian-keyring-gpg" -o "$keyring" = "debian-nonupload-gpg" -o "$keyring" = "removed-1024-gpg" ]; then
name=`grep $newkey keyids | sed 's/^[^ ]* //'|sed s/\<.*//`
account=`grep $newkey keyids | sed 's/.*\<//'|sed s/\>$//`
if [ "$keyring" = "debian-nonupload-gpg" ]; then
role='DD-NU'
else
# Both debian-keyring-gpg and removed-1024-gpg are DDs.
role='DD'
fi
elif [ "$keyring" = "debian-maintainers-gpg" ]; then
echo -n "Enter full name of new key: "
read name
role='DM'
else
echo "*** Key to be replaced is of a strange type (not DD, NonUplDD, DM)"
echo " Be sure you are doing the right thing before committing. Double-check"
echo " the log message, as it will most likely not be correct."
name="Unknown"
fi
echo -n 'RT issue ID this change closes, if any: '
read rtid
name=$(echo $name | sed -r 's/^ *(.*) *$/\1/')
log="Replace 0x$oldkey with 0x$newkey ($name) (RT #$rtid)"
git mv $oldkeyfile removed-keys-gpg/
VERSION=$(head -1 debian/changelog | awk '{print $2}' | sed 's/[\(\)]//g')
RELEASE=$(head -1 debian/changelog | awk '{print $3}' | sed 's/;$//')
case $RELEASE in
UNRELEASED)
dch --multimaint-merge -D UNRELEASED -a "$log"
;;
unstable)
NEWVER=$(date +%Y.%m.xx)
if [ "$VERSION" = "$NEWVER" ]
then
echo '* Warning: New version and previous released version are'
echo " the same: $VERSION. This should not be so!"
echo ' Check debian/changelog'
fi
dch -D UNRELEASED -v $NEWVER "$log"
;;
*)
echo "Last release $VERSION for unknown distribution «$RELEASE»."
echo "Not calling dch, do it manually."
;;
esac
git add debian/changelog
cat > git-commit-template <<EOF
$log
Action: replace
Subject: $name
Username: $account
Role: $role
Old-key: $oldkeyfp
Old-key-type: $oldkeylen$oldkeyalg
New-key: $newkeyfp
New-key-type: $newkeylen$newkeyalg
RT-Ticket: $rtid
Request-signed-by: \$oldkey
New-key-certified-by: \$oldkey,
EOF
fi