aboutsummaryrefslogtreecommitdiff
path: root/misc/poc/firma-0.2.2
blob: f1a8f27c399df41b05dd15276028e986a48cc075 (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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/bin/bash
#
# firma v0.2.2: 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

# if the configuration file exists, disable "sourcepath" and evaluate the parameters
if [ -f $1 ]; then
  shopt -u sourcepath && source $1
else
  echo -e "\nConfiguration file \"$1\" could not be found.\n"
  exit
fi

# 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 --recipient"

# check configuration file parameters
# todo: check if $TMP directory/files exist
if [ ! -f $GPG -o ! -x $GPG ]; then
  echo -e "\n$1: GPG binary ($GPG) could not be found.\n"
  exit
elif [ ! -f $MAIL -o ! -x $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 "$(cat $1 | grep -o ^PASSWD=\'[^\']*\'$)" -o \
       -z "$(echo -n $PASSWD)" -o \
       "$(echo -n $PASSWD | wc -m)" -lt "25" -o \
       -z "$(echo -n $PASSWD | grep -o [[:lower:][:upper:]])" -o \
       -z "$(echo -n $PASSWD | grep -o [[:digit:]])" -o \
       "$(echo -n $PASSWD | grep -o [[:punct:]] | wc -l)" -lt "5" ]; then
  echo -e "\n$1: PASSWD is empty or does not meet the minimum complexity requirements."
  echo "$1: Please set a new passphrase for the list's private key. Make it at least"
  echo "$1: 25 characters long (using a combination of letters, numbers and at least"
  echo "$1: 5 special characters) and enclose it in 'single quotes'. The passphrase"
  echo -e "$1: itself, though, cannot contain any single quote.\n"
  exit
elif [ -z "$($GPGLIST | grep ^pub | cut -d : -f 10 | grep -i \<$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 ^pub | cut -d : -f 10 | grep -i \<$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 space separated 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 -ne "/$LISTNAME/Id" -e '/pub/p' | cut -d : -f 10 | 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 and the sender's email address
FROM=$(grep -m 1 ^From: $TMP | cut -d : -f 2- | sed -e 's/^ //')
FROMADD=$(if [ -z "$(echo $FROM | grep '>$')" ] ; then echo $FROM ; else echo $FROM | grep -o '<[^<>]*>$' | sed -e 's/[<>]//g' ; fi)
DATE=$(grep -m 1 ^Date: $TMP)
SUBJECT=$(grep -m 1 ^Subject: $TMP | cut -d : -f 2- | sed -e 's/^ //')

# get the encrypted message
sed -ne '/-----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 -Fq GOODSIG) ; then

  for EMAIL in $(SUBSCRIBERS); do 

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

    $(GPGSTDERR | grep -F 'gpg: Signature made')
    $(GPGSTDERR | grep -F '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 the list admins and to sender
elif (GPGSTDERR | grep -Fq BADSIG) ; then

  for EMAIL in $(echo $LISTADMIN $FROMADD); do

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

    $(GPGSTDERR | grep -F 'gpg: Signature made')
    $(GPGSTDERR | grep -F 'gpg: BAD signature from')

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

  done

# 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.2" | $MAIL -r $LISTNAME $FROMADD

fi
 
rm -f $TMP $TMP.gpg