chiark / gitweb /
Initial commit as found
[modbot-ulm.git] / stump / local / bin / pmcheck
1 #!/bin/sh
2
3 # @(#)pmcheck   1.9 (PGP Moose) 96/03/04
4 # Authorisation checking script for PGP Moose
5 # Written by Greg Rose, RoSecure Software, Copyright C 1995.
6
7 # Configuration:
8     # Where to create temporary files.
9     TMP=/tmp
10
11     # Name of the file with valid moderator's/individual's names
12     ACCEPT=PGP_Moose_accept
13
14 # End Configuration
15
16 # Be neat and tidy.
17 TF=$TMP/pmcheck$$
18 trap "rm -f $TF.?; exit 1" 1 2 3 15
19
20 VERBOSE=false
21 # Usage: $0 [newsgroup|user] [filename]
22 case $# in
23 0)
24     VERBOSE=true
25     NEWSGROUP=any
26     cat >$TF.f
27     FILE=$TF.f
28     FILENAME="standard input"
29     ;;
30 1)
31     if [ -f "$1" ]; then
32         VERBOSE=true
33         NEWSGROUP=any
34         FILE="$1"
35         FILENAME="$1"
36     else
37         cat >$TF.f
38         FILE=$TF.f
39         FILENAME="standard input"
40         NEWSGROUP="$1"
41     fi
42     ;;
43 2)
44     NEWSGROUP="$1"
45     FILE="$2"
46     FILENAME="$2"
47     ;;
48 *)
49     echo >&2 "Usage: $0 [newsgroup|user] [article]"
50     echo >&2 "       newsgroup may be "any" to check all signatures."
51     exit 1
52     ;;
53 esac
54
55 # Find all the authentication headers we can handle
56 grep -i '^X-Auth.*:  *PGPMoose ' $FILE | \
57     sed -e 's/.* //' >$TF.g
58
59 # For the time being, simply avoid cancel messages.
60 # Note that pmdaemon authenticates them, but you probably don't
61 # want to cancel them.
62 if grep -i -s '^Control:[       ]*cancel' $FILE >/dev/null; then
63     rm -f $TF.?
64     exit 0
65 fi
66
67 # The designated newsgroup must be validated.
68 if [ "x$NEWSGROUP" != "xany" ]; then
69     grep -i -s "^$NEWSGROUP\$" $TF.g >/dev/null || {
70         echo >&2 "$0: Posting for $NEWSGROUP not approved with PGP Moose."
71         rm -f $TF.?
72         exit 1
73     }
74     # Uncomment this line if you only want to check this one group
75     echo "$NEWSGROUP" >$TF.g
76 fi
77
78 # Make the document we are going to check signatures on.
79 pmcanon $FILE >$TF.m
80     
81 # Loop checking all X-Auth: lines required
82 echo 0 >$TF.b
83 while read GROUP; do
84     # Check whether this is an interesting X-Auth: line.
85     # This is determined by the existence of the $ACCEPT file.
86     # If it exists, only the groups/individuals mentioned are
87     # relevent. Otherwise, check everything in sight, but don't
88     # worry if you can't find a key or the signature doesn't match.
89     # CONTROLLED is 0 if there is a $ACCEPT file and this group/user is
90     # in it.
91     [ -f "$ACCEPT" ] && grep -i -s "^$GROUP[    ]" "$ACCEPT" >/dev/null
92     CONTROLLED=$?
93     if [ "$CONTROLLED" != 0 -a "$NEWSGROUP" != "any" ]; then
94         continue
95     fi
96     # $1      $2       $3   $4  $5
97     # X-Auth: PGPMoose V1.1 PGP sci.crypt.research
98     set -- `grep -i "^X-Auth.*:  *PGPMoose .* $GROUP\$" $FILE`
99
100     # Check for version mismatch, but at the moment we just warn.
101     # It is pretty hard to know just what to do in this case.
102     if [ "$3" != "V2.0" -o "$4" != "PGP" ]; then
103         echo >&2 "$0: warning: version mismatch V2.0 PGP != $3 $4"
104     fi
105
106     # reconstruct the input signature file.
107     cat <<-END_OF_SIG >$TF.s
108         -----BEGIN PGP SIGNATURE-----
109         Version: GnuPG v1.4.5 (NetBSD)
110
111         END_OF_SIG
112     sed -n -e "1,/^[Xx]-[Aa][Uu][Tt][Hh].*:  *PGPMoose .* $GROUP\$/d" \
113         -e '/^ *$/,$d' \
114         -e '/^[^        ]/,$d' \
115         -e 's/^[        ]*//p' \
116         $FILE >>$TF.s
117     cat <<-END_OF_SIG >>$TF.s
118         -----END PGP SIGNATURE-----
119         END_OF_SIG
120
121     # Now we can check the signature.
122     gpg --verify $TF.s $TF.m >$TF.e 2>&1
123     STATUS=$?
124 #    cat >&2 $TF.s 
125 #    echo ====
126 #    cat >&2 $TF.m 
127 #    echo ====
128 #    cat >&2 $TF.e 
129
130     # If this is a target newsgroup/user, any error is bad news.
131     if [ "$CONTROLLED" = 0 -a $STATUS != 0 ]; then
132         echo >&2 "$0: Invalid designated signature from $GROUP"
133         echo 2 >$TF.b
134         continue
135     fi
136     # There are various understood error codes, not to mention the others...
137     # These codes come from the PGP source, and are probably not immutable.
138     case "$STATUS" in
139     0)
140         # signature checks out... handle that case below
141         ;;
142     11)
143         # Non-existent key
144         if [ "$VERBOSE" = true ]; then
145             echo "No public key for signature $GROUP"
146         fi
147         continue
148         ;;
149     30)
150         # Signature check error
151         $VERBOSE || echo >&2 "Signature doesn't match $FILE for $GROUP"
152         echo 2 >$TF.b
153         continue
154         ;;
155     *)
156         # Some other unknown error. Treat same as Non-existent key.
157         if [ "$VERBOSE" = true ]; then
158             echo "Unknown PGP error, status = $STATUS"
159             cat $TF.e
160         fi
161         continue
162         ;;
163     esac
164
165     SIG=`sed -n 's/gpg: Good signature from "\(.*\)"/\1/p' $TF.e`
166     if [ "x$SIG" = "x" ]; then
167         # this one "can't happen"
168         echo >&2 "$0: MOOSE ERROR: Invalid signature for $GROUP on $FILE."
169     fi
170     if [ "$VERBOSE" = "true" ]; then
171         echo "$0: Verified signature from '$SIG'."
172     fi
173
174     # Finally, was it signed by the right person?
175     if [ "$CONTROLLED" = 0 ]; then
176         grep -i -s "^$GROUP[     ]*$SIG\$" "$ACCEPT" >/dev/null || {
177             echo >&2 "$0: '$SIG' not accepted for $GROUP."
178             echo 2 >$TF.b
179         }
180     fi
181 done <$TF.g
182
183 BADSIG=`cat $TF.b`
184 rm -f $TF.?
185 exit $BADSIG