Fix out-of-bounds error when incorporating email from stdin
[mmh] / uip / mhpgp.sh
1 #!/bin/sh
2 # Based on mhpgp 1.1.0.7 2005/11/29 06:25:05 by Neil Rickert
3 # Adjusted to mmh by markus schnalke <meillo@marmaro.de>, 2012-07
4
5
6 # mhpgp:
7 #   -write:  Save the decrypted message to the current folder
8
9 usage="Usage: mhpgp [-write] [-Version] [-help] [+folder] [msg]"
10
11 # prepend the default options from the profile
12 set -- `mhparam -nocomp ${0##*/}` "$@"
13
14 while : ; do
15         case "$1" in
16         -w*)
17                 wflag=1
18                 ;;
19         -V*)
20                 echo "${0##*/} has no own version number, thus this instead:"
21                 folder -Version
22                 exit 0
23                 ;;
24         -h*|-*)
25                 echo "$usage" >&2
26                 exit 1
27                 ;;
28         *)
29                 break
30                 ;;
31         esac
32         shift
33 done
34
35 TEMP=/tmp/${0##*/}.$$
36 umask 077
37 mkdir $TEMP || exit 1
38 trap "rm -rf $TEMP" 0 1 2 15
39
40
41 ### verify a mime message
42 mimeverify() {
43         bdry=`echo "$CH" | sed -n \
44                         -e 's/[Bb][Oo][Uu][Nn][Dd][Aa][Rr][Yy]=/;boundary=/' \
45                         -e 's/.*;boundary=/boundary=/' \
46                         -e 's/^boundary=\([^;]*\);.*/boundary=\1/' \
47                         -e 's/^boundary="\([^"]*\)".*/boundary=\1/' \
48                         -e 's/[ \r       ][ \r    ]*$//' \
49                         -e 's/^boundary=//p'`
50
51         xbdry=`echo "$bdry" | sed -e 's"/"\\\\/"g' -e 's"\."\\\\."g'`
52
53         sed -e '1,/^--'"$xbdry"'[ \r     ]*$/d' $FILE > $TEMP/body
54
55         sed -e '/^--'"$xbdry"'[ \r       ]*$/,$d' \
56                         -e 's/[ \r       ][ \r    ]*$//' $TEMP/body |
57                         sed -e '$d' -e 's/$/\r/' > $TEMP/msg
58         if grep "[ ^M   ]$" $TEMP/body >/dev/null 2>&1 ; then
59                 echo 'Warning: trailing blanks removed from message body' >&2
60         fi
61
62         sed -e '1,/^--'"$xbdry"'[ \r     ]*$/d' $TEMP/body |
63                 sed -n -e '/BEGIN PGP /,/END PGP /p' > $TEMP/msg.asc
64
65         gpg --verify $TEMP/msg.asc
66 }
67
68 ### decrypt MIME and non-MIME messages (type is in $1)
69 ###; invoke the pager as needed
70 decrypt() {
71         sed -n -e '
72                 /^-----BEGIN PGP MESSAGE/b x
73                 d
74                 :x
75                 p
76                 /^-----END PGP MESSAGE/b y
77                 n
78                 b x
79                 :y
80                 n
81                 b y' $FILE | gpg --decrypt >$TEMP/msg
82         X=`tail -1c $TEMP/msg`
83         if [ "$X" != "" ] ; then
84                 # ensure trailing newline
85                 echo >> $TEMP/msg
86         fi
87         if [ "$1" = "plain" ] ; then
88                 sedcmd="/^[Mm][Ii][Mm][Ee]-.*:/b r"
89         else
90                 sedcmd='/^-*$/q'
91         fi
92
93         sed -n ':a
94                 /^-*$/q
95                 '"$sedcmd"'
96                 /^[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-/b r
97                 p
98                 n
99                 b a
100                 :r
101                 n
102                 /^[     ]/b r
103                 b a' "$FILE" > "$TEMP/outfile"
104
105         if [ "$1" = "plain" ] ; then echo "" >> "$TEMP/outfile" ; fi
106         sed -e 's/\r$//' $TEMP/msg >> "$TEMP/outfile" || exit 1
107
108         if [ "$wflag" = "1" ] ; then
109                 refile -file "$TEMP/outfile" @
110         else
111                 show -file "$TEMP/outfile"
112         fi
113 }
114
115
116 ### Mainline processing
117
118 case "$#" in
119 0)
120         FILE=`mhpath c` || exit 1 ;;
121 *)
122         case "$*" in
123         /*)     FILE=`echo "$@"` ;;
124         *)      FILE=`mhpath "$@"` || exit 1 ;;
125         esac ;;
126 esac
127
128 set X $FILE
129
130 if [ $# != 2 ] ; then
131         echo "One message at a time, please!" >&2
132         exit 1
133 fi
134
135 # get mime-version and content-type headers.
136 CH=`sed -n -e '\
137         :a
138         /^-*$/q
139         /^[Mm][Ii][Mm][Ee]-[Vv][Ee][Rr][Ss][Ii][Oo][Nn]:/b x
140         /^[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-[Tt][Yy][Pp][Ee]:/b x
141         d
142         :x
143         p
144         n
145         /^[     ]/b x
146         b a' $FILE`
147
148 if echo "$CH" | grep -i mime-version >/dev/null 2>&1; then
149         :       ## nothing, this is good
150 else
151         CH=
152 fi
153
154 # Handle MIME variants
155 case "$CH" in
156 *application/pgp-signature*)
157         mimeverify
158         exit
159         ;;
160 *application/pgp-encrypted*)
161         decrypt mime
162         exit
163         ;;
164 esac
165
166 # Handle plain variants
167 case "`grep '^-----BEGIN PGP' $FILE 2>/dev/null`" in
168 *"PGP SIGNED MESSAGE"*)
169         gpg --verify "$FILE"
170         exit
171         ;;
172 *"BEGIN PGP MESSAGE"*)
173         decrypt plain
174         exit
175         ;;
176 esac
177
178 echo "I can't find a PGP message there" >&2
179 exit 1