aboutsummaryrefslogtreecommitdiff
path: root/misc/poc/firma-0.2.1
blob: 13ee6dae10da9b46b97af5840caa14f14a31faaa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/bin/bash
#
# firma v0.2.1: simple encrypted mailing list aliases
# feedback: rhatto@riseup.net luis@riseup.net | GPL
#
# list configuration is passed thru the config file,
# where you put PARAMETER=value (whithout spaces)
#
# MAIL= path for mail program
# GPG= path for gnupg binary
# TMP= where you want the temp files
# LISTNAME= list email
# LISTADMIN= list administrator email addresses (space separated)
# GPGDIR= gpg dir for the lists' keyring
# PASSWD= passwd for the lists' keyring

# eval the config file
source $1

# declare GPG variables
GPGCOMMAND="$GPG --quiet --homedir $GPGDIR --batch --no-tty --no-use-agent --no-permission-warning"
GPGLIST="$GPGCOMMAND --list-keys --with-colons"
GPGDECRYPT="$GPGCOMMAND --passphrase-fd 0 --decrypt"
GPGENCRYPT="$GPGCOMMAND --passphrase-fd 0 --always-trust --encrypt --sign --armor --hidden-recipient"

# check configuration file parameters
# todo: check if $TMP directory/files exist and if password is at least n characters long
if [ ! -x $GPG -o ! -f $GPG ]; then
  echo -e "\n$1: GPG binary ($GPG) could not be found.\n"
  exit
elif [ ! -x $MAIL -o ! -f $MAIL ]; then
  echo -e "\n$1: Mail program ($MAIL) could not be found.\n"
  exit
elif [ ! -d $GPGDIR -o ! -f $GPGDIR/pubring.gpg -o ! -f $GPGDIR/secring.gpg ]; then
  echo -e "\n$1: GPG home directory ($GPGDIR) or the GPG keyrings could not be found.\n"
  exit
elif [ -z $($GPGLIST | grep -o "<$LISTNAME>") ]; then
  echo -e "\n$1: GPG key for list \"$LISTNAME\" could not be found."
  echo -e "$1: Note that this parameter expects an email address.\n"
  exit
else
  for ADMIN in $LISTADMIN; do {
    if [ -z $($GPGLIST | grep -o "<$ADMIN>") ]; then
      echo -e "\n$1: GPG key for list administrator \"$ADMIN\" could not be found."
      echo -e "$1: Note that this parameter expects one or more email addresses.\n"
      exit
    fi; }
  done
fi

# declare functions
# discard $GPGDECRYPT STDOUT and get its STDERR instead, for signature checking
function GPGSTDERR {
  echo "$PASSWD" | ($GPGDECRYPT --status-fd 2 $TMP.gpg 1> /dev/null) 2>&1 ;
}

# get list susbscriber addresses
function SUBSCRIBERS {
  $GPGLIST | sed -n "/$LISTNAME/d;/pub/p" | grep -o "<.*>" | sed -e "s/[<>]//g" ;
}

# create the temporary files and restrict their permissions
rm -f $TMP $TMP.gpg
touch $TMP; chmod 600 $TMP;
touch $TMP.gpg; chmod 600 $TMP.gpg;

# todo: use an array
while read STDIN; do
  echo $STDIN >> $TMP
done

# get the message headers
# todo: find a better place for $FROMADD since its not part of the message headers
FROM=$(grep -m 1 "^From:" $TMP | cut -d : -f 2- | sed "s/^ //")
FROMADD=$(echo $FROM | if grep -q "<" ; then echo $FROM | grep -o "<.*>" | sed -e "s/[<>]//g" ; else echo $FROM ; fi)
DATE=$(grep -m 1 "^Date:" $TMP)
SUBJECT=$(grep -m 1 "^Subject:" $TMP | cut -d : -f 2- | sed "s/^ //")

# get the encrypted message
sed -n "/-----BEGIN PGP MESSAGE-----/,/-----END PGP MESSAGE-----/p" $TMP >> $TMP.gpg

# if signature is Good, encrypt and send it for each list subscriber
# todo: declare a function to decrypt, re-encrypt and send the list messages
if (GPGSTDERR | grep -q "GOODSIG") ; then

  for EMAIL in $(SUBSCRIBERS); do 

    echo "$PASSWD
    Message from: $FROM
    Subject: $SUBJECT
    $DATE

    $(GPGSTDERR | grep "gpg: Signature made")
    $(GPGSTDERR | grep "gpg: Good signature from")

$(echo "$PASSWD" | $GPGDECRYPT $TMP.gpg 2> /dev/null)" | sed -e "s/=20$//" | $GPGENCRYPT $EMAIL | $MAIL -r $LISTNAME $EMAIL

  done

# else, if signature is BAD, email it back to sender and to list admins
elif (GPGSTDERR | grep -q "BADSIG") ; then

    echo "$PASSWD
    Message from: $FROM
    Subject: [BAD SIGNATURE] $SUBJECT
    $DATE

    $(GPGSTDERR | grep "gpg: Signature made")
    $(GPGSTDERR | grep "gpg: BAD signature from")

$(echo "$PASSWD" | $GPGDECRYPT $TMP.gpg 2> /dev/null)" | sed -e "s/=20$//" | $GPGENCRYPT $LISTADMIN $FROMADD | $MAIL -r $LISTNAME $LISTADMIN $FROMADD

# else, probably either the message was not signed or the sender is not subscribed to the list
# email the message back to sender including a note about this
# todo: parse STDERR to find out why the signature couldn't be checked and send more specific errors back to sender
else

    echo "
    Message from: $FROM
    Subject: [RETURNED MAIL] $SUBJECT
    $DATE

    [ It was not possible to process this message. Either or both
      the message was not encrypted and/or signed, or you are not
      subscribed to this list.  Contact the list administrator if
      you have any questions. ]

    -- 
    firma v0.2.1" | $MAIL -r $LISTNAME $FROMADD

fi
 
rm -f $TMP $TMP.gpg