From 5eb7d21c3c819826477ef3862ea0fda1d4c62cd6 Mon Sep 17 00:00:00 2001 From: Silvio Rhatto Date: Mon, 15 Feb 2010 15:19:55 -0200 Subject: Adding misc files --- misc/poc/firma-0.2.4 | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100755 misc/poc/firma-0.2.4 (limited to 'misc/poc/firma-0.2.4') diff --git a/misc/poc/firma-0.2.4 b/misc/poc/firma-0.2.4 new file mode 100755 index 0000000..6418782 --- /dev/null +++ b/misc/poc/firma-0.2.4 @@ -0,0 +1,211 @@ +#!/bin/bash +# +# firma v0.2.4: encrypted mailing list manager +# 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 +# LISTNAME= list email +# LISTADMIN= list administrator email addresses (space separated) +# GPGDIR= gpg dir for the lists' keyring +# PASSWD= passwd for the lists' keyring +# + +VERSION=0.2.4 + +function usage { + echo usage: $0 firma \ \ + echo -c: create a new list using config-file + echo -p: process a message + echo -a: admin commands +} + +function check_config { + # check configuration file parameters + if [ ! -f $GPG -o ! -x $GPG ]; then + echo -e "\n$1: GPG binary ($GPG) could not be found.\n" + exit 1 + elif [ ! -f $MAIL -o ! -x $MAIL ]; then + echo -e "\n$1: Mail program ($MAIL) could not be found.\n" + exit 1 + 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 1 + elif [ -z "$(cat $CONFIG | 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$CONFIG: 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 "$CONFIG: itself, though, cannot contain any single quote.\n" + exit 1 + elif [ -z "$($GPGLIST | grep ^pub | cut -d : -f 10 | grep -i \<$LISTNAME\>$)" ]; then + echo -e "\n$CONFIG: GPG key for list \"$LISTNAME\" could not be found." + echo -e "$CONFIG: Note that this parameter expects an email address.\n" + exit 1 + else + for ADMIN in $LISTADMIN; do { + if [ -z "$($GPGLIST | grep ^pub | cut -d : -f 10 | grep -i \<$ADMIN\>$)" ]; then + echo -e "\n$CONFIG: GPG key for list administrator \"$ADMIN\" could not be found." + echo -e "$CONFIG: Note that this parameter expects one or more space separated email addresses.\n" + exit 1 + fi; } + done + fi +} + +function GPGSTDERR { + # discard $GPGDECRYPT STDOUT and get its STDERR instead, for signature checking + echo -e "$PASSWD\n${GPG_MESSAGE[@]}" | sed -e 's/^ //' | ($GPGDECRYPT --status-fd 2 1> /dev/null) 2>&1 ; +} + +function SUBSCRIBERS { + # get list susbscriber's addresses + $GPGLIST | sed -ne "/$LISTNAME/Id" -e '/pub/p' | cut -d : -f 10 | grep -o '<[^<>]*>$' | sed -e 's/[<>]//g' ; +} + +function get_message { + n=0; + while read STDIN; do + MESSAGE[$n]="$STDIN\n" + ((++n)) + done +} + +function get_gpg_message { + signal=0; x=0; + for ((count=0;count<=n;count++)); do + if [[ $signal == "0" ]] && [[ "$(echo "${MESSAGE[$count]}" | grep -v -e "-----BEGIN PGP MESSAGE-----")" == "" ]]; then + GPG_MESSAGE[$x]=${MESSAGE[$count]}; ((++x)) + signal=1 + elif [[ $signal == "1" ]]; then + GPG_MESSAGE[$x]=${MESSAGE[$count]} + ((++x)) + if [[ "$(echo "${MESSAGE[$count]}" | grep -v -e "-----END PGP MESSAGE-----")" == "" ]]; then + signal=0 + fi + fi + done +} + +function get_headers { + # get the message headers and the sender's email address + FROM=$(echo -e "${MESSAGE[@]}" | grep -m 1 "From:" | 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=$(echo -e "${MESSAGE[@]}" | grep -m 1 "Date:") + SUBJECT=$(echo -e "${MESSAGE[@]}" | grep -m 1 "Subject:" | cut -d : -f 2- | sed -e 's/^ //') +} + +function process_message { + # process a message sent to the list + + get_message + get_headers + get_gpg_message + + # 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 -e "$PASSWD\n${GPG_MESSAGE[@]}" | $GPGDECRYPT 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 -e "$PASSWD\n${GPG_MESSAGE[@]}" | $GPGDECRYPT 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 v$VERSION" | $MAIL -r $LISTNAME $FROMADD + + fi + +} + +# main - +# command line checking +if [ -z $2 ]; then + usage; exit 1 +else + CONFIG=$2 +fi + +# if the configuration file exists, disable "sourcepath" and evaluate the parameters +if [ -f $CONFIG ] && [[ $1 != "-c" ]]; then + shopt -u sourcepath && source $CONFIG +else + echo -e "\nConfiguration file \"$CONFIG\" could not be found.\n" + exit 1 +fi + +declare -a MESSAGE +declare -a GPG_MESSAGE +declare n +export LANG=en_US + +# 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" + +# then check the config +check_config + +# command line parsing +if [[ $1 == "-c" ]]; then + newlist +elif [[ $1 == "-p" ]]; then + process_message +elif [[ $1 == "-a" ]]; then + admin_task +else + usage; exit 1 +fi + -- cgit v1.2.3