#!/bin/sh
# @(#)pmcheck 1.10 (PGP Moose) 98/11/27
# Authorisation checking script for PGP Moose
# Written by Greg Rose, RoSecure Software, Copyright C 1995.
# Configuration:
# Where to create temporary files.
TMP=/tmp
# Name of the file with valid moderator's/individual's names
ACCEPT=PGP_Moose_accept
# End Configuration
# Be neat and tidy.
TF=$TMP/pgpmt$$
trap "rm -f $TF.?; exit 1" 1 2 3 15
VERBOSE=false
# Usage: $0 [newsgroup|user] [filename]
case $# in
0)
VERBOSE=true
NEWSGROUP=any
cat >$TF.f
FILE=$TF.f
FILENAME="standard input"
;;
1)
if [ -f "$1" ]; then
VERBOSE=true
NEWSGROUP=any
FILE="$1"
FILENAME="$1"
else
cat >$TF.f
FILE=$TF.f
FILENAME="standard input"
NEWSGROUP="$1"
fi
;;
2)
NEWSGROUP="$1"
FILE="$2"
FILENAME="$2"
;;
*)
echo >&2 "Usage: $0 [newsgroup|user] [article]"
echo >&2 " newsgroup may be "any" to check all signatures."
exit 1
;;
esac
# Find all the authentication headers we can handle
grep -i '^X-Auth.*: *PGPMoose ' $FILE | \
sed -e 's/X-Auth.*: *PGPMoose V[0-9]*[.][0-9]* [A-Z]* //' >$TF.g
# For the time being, simply avoid cancel messages.
# Note that pmdaemon authenticates them, but you probably don't
# want to cancel them.
if grep -i -s '^Control:[ ]*cancel' $FILE >/dev/null; then
rm -f $TF.?
exit 0
fi
# The designated newsgroup must be validated.
if [ "x$NEWSGROUP" != "xany" ]; then
grep -i -s "^$NEWSGROUP\$" $TF.g >/dev/null || {
echo >&2 "$0: Posting for $NEWSGROUP not approved with PGP Moose."
rm -f $TF.?
exit 1
}
# Uncomment this line if you only want to check this one group
echo "$NEWSGROUP" >$TF.g
fi
# Make the document we are going to check signatures on.
pmcanon $FILE >$TF.m
# Loop checking all X-Auth: lines required
echo 0 >$TF.b
while read GROUP ARMOR; do
# Check whether this is an interesting X-Auth: line.
# This is determined by the existence of the $ACCEPT file.
# If it exists, only the groups/individuals mentioned are
# relevent. Otherwise, check everything in sight, but don't
# worry if you can't find a key or the signature doesn't match.
# CONTROLLED is 0 if there is a $ACCEPT file and this group/user is
# in it.
[ -f "$ACCEPT" ] && grep -i -s "^$GROUP[ ]" "$ACCEPT" >/dev/null
CONTROLLED=$?
if [ "$CONTROLLED" != 0 -a "$NEWSGROUP" != "any" ]; then
echo "$0: Signature for $GROUP ignored -- not in $ACCEPT."
continue
fi
# $1 $2 $3 $4 $5
# X-Auth: PGPMoose V1.1 PGP sci.crypt.research
set -- `grep -i "^X-Auth.*: *PGPMoose .* $GROUP" $FILE`
# Check for version mismatch, but at the moment we just warn.
# It is pretty hard to know just what to do in this case.
if [ "$3" != "V1.1" -o "$4" != "PGP" ]; then
echo >&2 "$0: warning: version mismatch V1.0 PGP != $3 $4"
fi
# reconstruct the input signature file.
cat <<-END_OF_SIG >$TF.s
-----BEGIN PGP MESSAGE-----
Version: 2.6
END_OF_SIG
if [ "x$ARMOR" != "x" ]; then
for WORD in $ARMOR
do
echo $WORD >>$TF.s
done
fi
for WORD in `
sed -n -e "1,/^[Xx]-[Aa][Uu][Tt][Hh].*: *PGPMoose .* $GROUP/d" \
-e '/^ *$/,$d' \
-e '/^[^ ]/,$d' \
-e 's/^[ ]*//p' \
$FILE`
do
echo $WORD >>$TF.s
done
cat <<-END_OF_SIG >>$TF.s
-----END PGP MESSAGE-----
END_OF_SIG
# Now we can check the signature.
pgp +BATCHMODE=on -t $TF.s $TF.m </dev/null >$TF.e 2>&1
STATUS=$?
# Debugging aid
# cat >&2 $TF.s
# echo ====
# cat >&2 $TF.m
# echo ====
# cat >&2 $TF.e
# If this is a target newsgroup/user, any error is bad news.
if [ "$CONTROLLED" = 0 -a $STATUS != 0 ]; then
echo >&2 "$0: Invalid designated signature from $GROUP"
echo 2 >$TF.b
continue
fi
# There are various understood error codes, not to mention the others...
# These codes come from the PGP source, and are probably not immutable.
case "$STATUS" in
0)
# signature checks out... handle that case below
;;
11)
# Non-existent key
if [ "$VERBOSE" = true ]; then
echo "No public key for signature $GROUP"
fi
echo 2 >$TF.b
continue
;;
30)
# Signature check error
$VERBOSE || echo >&2 "Signature doesn't match $FILE for $GROUP"
echo 2 >$TF.b
continue
;;
*)
# Some other unknown error. Treat same as Non-existent key.
if [ "$VERBOSE" = true ]; then
echo "Unknown PGP error, status = $STATUS"
cat $TF.e
fi
echo 2 >$TF.b
continue
;;
esac
SIG=`sed -n 's/Good signature from user "\(.*\)"./\1/p' $TF.e`
if [ "x$SIG" = "x" ]; then
# this one "can't happen"
echo >&2 "$0: MOOSE ERROR: Invalid signature for $GROUP on $FILE."
fi
if [ "$VERBOSE" = "true" ]; then
echo "$0: Verified signature from '$SIG'."
fi
# Finally, was it signed by the right person?
if [ "$CONTROLLED" = 0 ]; then
grep -i -s "^$GROUP[ ]*$SIG\$" "$ACCEPT" >/dev/null || {
echo >&2 "$0: '$SIG' not accepted for $GROUP."
echo 2 >$TF.b
}
fi
done <$TF.g
BADSIG=`cat $TF.b`
rm -f $TF.?
exit $BADSIG
syntax highlighted by Code2HTML, v. 0.9.1