update from latest MirBSD CVS
[shellsnippets/shellsnippets.git] / mksh / pgpdemime
1 #!/bin/mksh
2 #-
3 # Copyright © 2015
4 #       Thorsten “mirabilos” Glaser <t.glaser@tarent.de>
5 #
6 # Provided that these terms and disclaimer and all copyright notices
7 # are retained or reproduced in an accompanying document, permission
8 # is granted to deal in this work without restriction, including un‐
9 # limited rights to use, publicly perform, distribute, sell, modify,
10 # merge, give away, or sublicence.
11 #
12 # This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
13 # the utmost extent permitted by applicable law, neither express nor
14 # implied; without malicious intent or gross negligence. In no event
15 # may a licensor, author or contributor be held liable for indirect,
16 # direct, other damage, loss, or other issues arising in any way out
17 # of dealing in the work, even if advised of the possibility of such
18 # damage or existence of a defect, except proven that it results out
19 # of said person’s immediate fault when using the work as intended.
20 #-
21 # Pipe a raw RFC822 message which is PGP/MIME encrypred through this
22 # script; optional argument is the target folder (‘+’ auto-prepended
23 # for dmail, otherwise dmail delivers to the INBOX) which uses dmail
24 # from uw-imapd; if not found, delivery is to #driver.unix/mail/x in
25 # unix/mbox format by hand, without locking.
26
27 rawinput=$(cat)
28 nl=$'\n'
29 unixpfx=$(date -u +'From MAILER-DAEMON %a %b %e %H:%M:%S %Y')
30
31 function die {
32         print -ru2 -- E: $*
33         exit 1
34 }
35
36 [[ $rawinput = *$nl$nl* ]] || die no RFC822 message
37 rawheader=$unixpfx$nl${rawinput%%$nl$nl*}
38 rawheader=${rawheader//$nl[      ]/\ 1 }
39 typeset -l loheader=$rawheader
40 rawbody=${rawinput#*$nl$nl}
41 rawbody=${rawbody//$'\r'}
42 [[ $loheader = *${nl}content-type:*([\ 1   ])multipart/encrypted*application/pgp-encrypted* ]] || \
43     die no PGP/MIME encrypted message content type
44 [[ $rawbody = *$nl'-----BEGIN PGP MESSAGE-----'$nl*$nl'-----END PGP MESSAGE-----'$nl* ]] || \
45     die no PGP/MIME encrypted message body
46
47 decoded=${rawbody#*$nl'-----BEGIN PGP MESSAGE-----'$nl}
48 decoded=${decoded%%$nl'-----END PGP MESSAGE-----'$nl*}
49 decoded=$(print -r -- "-----BEGIN PGP MESSAGE-----$nl$decoded$nl-----END PGP MESSAGE-----" | gpg)
50 [[ $decoded = *$nl$nl* ]] || die decoded message not RFC822
51
52 set -A transforms -- \
53     -e '/^[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-/d' \
54     -e '/^[Ss][Uu][Bb][Jj][Ee][Cc][Tt]:/s//& **DECRYPTED**/'
55 set -A extraheaders
56 msgid=
57 [[ $loheader = *${nl}message-id:* ]] && msgid=$(print -r -- "$rawheader" | \
58     sed -n '/^[Mm][Ee][Ss][Ss][Aa][Gg][Ee]-[Ii][Dd]:[\ 1   ]*\(<.*>\)[\ 1    ]*$/s//\1/p')
59 if [[ -n $msgid ]]; then
60         transforms+=(-e '/^[Mm][Ee][Ss][Ss][Aa][Gg][Ee]-[Ii][Dd]:/s/>/.by.pgpdemime.mirbsd.org>/')
61         if [[ $loheader = *${nl}references:* ]]; then
62                 transforms+=(-e '/^[Rr][Ee][Ff][Ee][Rr][Ee][Nn][Cc][Ee][Ss]:/s\ 2$\ 2'"\ 1 $msgid\ 2")
63         else
64                 extraheaders+=("References: $msgid")
65         fi
66 fi
67
68 mda=$(whence -p dmail) || mda=
69 [[ -z $mda && -x /usr/mpkg/libexec/dmail ]] && mda=/usr/mpkg/libexec/dmail
70
71 if [[ -n $mda ]]; then
72         transforms+=(-e '1d')
73         target='your INBOX'
74         [[ -n $1 ]] && mda="$mda ${1@Q}"
75         [[ -n $1 ]] && target="the selected folder $1"
76 else
77         decoded+=$nl
78         target='“x” folder'
79         mda='cat >>~/mail/x'
80 fi
81
82 if {
83         print -r -- "$rawheader" | sed "${transforms[@]}" | tr '\ 1' '\n'
84         for x in "${extraheaders[@]}"; do
85                 print -r -- "$x"
86         done
87         print -r -- "$decoded"
88     } | eval "$mda"; then
89         print I: decoded message written to $target
90 else
91         print W: decoded message maybe not written, error code $?
92         exit 1
93 fi
94 exit 0