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/README | 1 + misc/poc/firma-0.1 | 53 ++++++++++ misc/poc/firma-0.1.5 | 57 +++++++++++ misc/poc/firma-0.1.6 | 147 +++++++++++++++++++++++++++ misc/poc/firma-0.2 | 108 ++++++++++++++++++++ misc/poc/firma-0.2.1 | 133 ++++++++++++++++++++++++ misc/poc/firma-0.2.2 | 153 ++++++++++++++++++++++++++++ misc/poc/firma-0.2.3 | 192 +++++++++++++++++++++++++++++++++++ misc/poc/firma-0.2.4 | 211 ++++++++++++++++++++++++++++++++++++++ misc/poc/firma-0.2.x | 280 +++++++++++++++++++++++++++++++++++++++++++++++++++ misc/python/README | 2 + misc/python/firma.py | 85 ++++++++++++++++ 12 files changed, 1422 insertions(+) create mode 100644 misc/poc/README create mode 100755 misc/poc/firma-0.1 create mode 100755 misc/poc/firma-0.1.5 create mode 100755 misc/poc/firma-0.1.6 create mode 100755 misc/poc/firma-0.2 create mode 100755 misc/poc/firma-0.2.1 create mode 100755 misc/poc/firma-0.2.2 create mode 100755 misc/poc/firma-0.2.3 create mode 100755 misc/poc/firma-0.2.4 create mode 100755 misc/poc/firma-0.2.x create mode 100644 misc/python/README create mode 100755 misc/python/firma.py (limited to 'misc') diff --git a/misc/poc/README b/misc/poc/README new file mode 100644 index 0000000..693db64 --- /dev/null +++ b/misc/poc/README @@ -0,0 +1 @@ +Proof of concept and initial versions. diff --git a/misc/poc/firma-0.1 b/misc/poc/firma-0.1 new file mode 100755 index 0000000..eab39e6 --- /dev/null +++ b/misc/poc/firma-0.1 @@ -0,0 +1,53 @@ +#!/bin/bash +# +# firma v0.1: simple encrypted mailing list aliases +# feedback: rhatto@riseup.net | GPL +# +# list configuration is passed thru the a 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 +# GPGDIR= gpg dir for the lists' keyring +# PASSWD= passwd for the lists' keyring + +# eval the config file +source $1 + +GPGCOMMAND="$GPG -q --homedir $GPGDIR" +GPGLIST="$GPGCOMMAND --list-keys" +GPGDECRYPT="$GPGCOMMAND --decrypt" +GPGENCRYPT="$GPGCOMMAND --always-trust -e -s -a -r" + +rm $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 headers +FROM=$(grep -m 1 ^From: $TMP | cut -f 2 -d :) +DATE=$(grep -m 1 ^Date: $TMP) +SUBJECT=$(grep -m 1 ^Subject: $TMP) + +# detect the encrypted message +sed -n '/-----BEGIN PGP MESSAGE-----/,/-----END PGP MESSAGE-----/p' $TMP >> $TMP.gpg + +# encrypting and sending for each recipient on the list +for EMAIL in $($GPGLIST | grep pub | cut -d "<" -f 2 | sed -e 's/>//' | grep @ | grep -v $LISTNAME); do + + echo "$PASSWD + Message from: $FROM + $SUBJECT + $DATE + + $(echo "$PASSWD" | $GPGDECRYPT $TMP.gpg)" | sed -e 's/=20$//' | $GPGENCRYPT $EMAIL | $MAIL -r $LISTNAME $EMAIL + +done + +rm $TMP $TMP.gpg diff --git a/misc/poc/firma-0.1.5 b/misc/poc/firma-0.1.5 new file mode 100755 index 0000000..029a09d --- /dev/null +++ b/misc/poc/firma-0.1.5 @@ -0,0 +1,57 @@ +#!/bin/bash +# +# firma v0.2: simple encrypted mailing list aliases +# feedback: rhatto@riseup.net | GPL +# +# list configuration is passed through a 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 +# GPGDIR= gpg dir for the lists' keyring +# PASSWD= passwd for the lists' keyring +# FOOTER= message footer + +# eval the config file +source $1 + +GPGCOMMAND="$GPG -q --homedir $GPGDIR" +GPGLIST="$GPGCOMMAND --list-keys" +GPGDECRYPT="$GPGCOMMAND --decrypt" +GPGENCRYPT="$GPGCOMMAND --always-trust -e -s -a -r" + +rm $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 headers +FROM=$(grep -m 1 ^From: $TMP | cut -f 2 -d :) +DATE=$(grep -m 1 ^Date: $TMP) +SUBJECT=$(grep -m 1 ^Subject: $TMP) + +# detect the encrypted message +sed -n '/-----BEGIN PGP MESSAGE-----/,/-----END PGP MESSAGE-----/p' $TMP >> $TMP.gpg + +# encrypting and sending for each recipient on the list +for EMAIL in $($GPGLIST | grep pub | cut -d "<" -f 2 | sed -e 's/>//' | grep @ | grep -v $LISTNAME); do + + echo "$PASSWD + Message from: $FROM + $SUBJECT + $DATE + + $(echo "$PASSWD" | $GPGDECRYPT $TMP.gpg) + + --- + $FOOTER " | sed -e 's/=20$//' | $GPGENCRYPT $EMAIL | $MAIL -r $LISTNAME $EMAIL + +done + +rm $TMP $TMP.gpg diff --git a/misc/poc/firma-0.1.6 b/misc/poc/firma-0.1.6 new file mode 100755 index 0000000..239c9a5 --- /dev/null +++ b/misc/poc/firma-0.1.6 @@ -0,0 +1,147 @@ +#!/bin/bash +# +# firma v0.2: simple encrypted mailing list aliases +# feedback: rhatto@riseup.net | GPL +# +# list configuration is passed through a 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 +# GPGDIR= gpg dir for the lists' keyring +# PASSWD= passwd for the lists' keyring +# FOOTER= message footer +# ALLOWSENDKEY = set to 1 if you want people automatically receive the list +# key requesting through listname-request@example.tld +# with subject: key +# +# design / todo: +# +# - list-request: +# - key (allow send key) +# - help +# - subscribe: exchange pubkey +# - unsubscribe +# - strings +# - check signatures +# - create list +# - archive (optional) +# - logfile (optional) +# - gpg --no-tty --display-charset --utf8-strings ? +# +# sintax: firma -c || firma config-file +# -c: create a new list +# config-file: parse the email from stdin +# with the parameters specified in the +# config-file +# +# fix: +# +# - special chars +# - id's recipient selection +# + +fuction _refresh_cache { + rm $1 $1.gpg + touch $1; chmod 600 $1; + touch $1.gpg; chmod 600 $TMP.gpg; +} + +function _process_message { + # get the headers + FROM=$(grep -m 1 ^From: $1 | cut -f 2 -d :) + DATE=$(grep -m 1 ^Date: $1) + SUBJECT=$(grep -m 1 ^Subject: $1) + + # detect the encrypted message + sed -n '/-----BEGIN PGP MESSAGE-----/,/-----END PGP MESSAGE-----/p' $1 >> $1.gpg + + # encrypting and sending for each recipient on the list + for EMAIL in $($GPGLIST | grep pub | cut -d "<" -f 2 | sed -e 's/>//' | grep @ | grep -v $LISTNAME); do + + echo "$PASSWD + Message from: $FROM + $SUBJECT + $DATE + + $(echo "$PASSWD" | $GPGDECRYPT $1.gpg) + + --- + $FOOTER + " | sed -e 's/=20$//' | $GPGENCRYPT $EMAIL | $MAIL -r $LISTNAME $EMAIL + done +} + +function _process_request { + + # todo: support subjects like "key ", etc + FROM=$(grep -m 1 ^From: $1 | cut -f 2 -d :) + REQUEST=$(grep -m 1 ^Subject: $1) + if [[ $REQUEST == "key" ]]; then + if [[ $ALLOWSENDKEY == 1 ]]; then + # send key to From: recipient + else + # dont send the key; return error message + fi + else if [[ $REQUEST == "subscribe" ]]; then + # check if user put its pubkey and + # ask the list for subscribe From: recipient + else if [[ $REQUEST == "unsubscribe" ]]; then + # unsubscribe and advise the list + else + # error message + fi + +} + +function _process { + + # eval the config file + source $1 + + GPGCOMMAND="$GPG -q --homedir $GPGDIR" + GPGLIST="$GPGCOMMAND --list-keys" + GPGDECRYPT="$GPGCOMMAND --decrypt" + GPGENCRYPT="$GPGCOMMAND --always-trust --hidden-recipient --textmode -e -s -a -r" + + # clear the cache before read the message + _refresh_cache $TMP + + # todo: use an array + while read STDIN; do + echo $STDIN >> $TMP + done + + # check with action is requested depending on the To: field + TO=$(grep -m 1 ^To: $) + if [[ $TO == $LISTNAME ]]; then _process_message $TMP; + else _process_request $TMP; + fi + + # clear after process + _refresh_cache $TMP + +} + +function newlist { + + LISTHOME = + LISTNANE = + ... + + $GPGCOMMAND --gen-key + +} + +# check sintax +if [[ $1 = "-c" ]]; then + _newlist; +else if [ -f $1 ]; + then _process $1; +else + echo sintax: $0 [-c] [config-file]; +fi + +rm $TMP $TMP.gpg diff --git a/misc/poc/firma-0.2 b/misc/poc/firma-0.2 new file mode 100755 index 0000000..5cf85d2 --- /dev/null +++ b/misc/poc/firma-0.2 @@ -0,0 +1,108 @@ +#!/bin/bash +# +# firma v0.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 + +# 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" +GPGDECRYPT="$GPGCOMMAND --passphrase-fd 0 --decrypt" +GPGENCRYPT="$GPGCOMMAND --passphrase-fd 0 --always-trust --encrypt --sign --armor --recipient" + +# 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 -f 2 -d :) +FROMADD=$(echo $FROMADD | if grep -q '<' ; then echo $FROMADD | grep -o '<.*>' | sed -e 's/[<>]//g' ; else echo $FROMADD ; fi) +DATE=$(grep -m 1 ^Date: $TMP) +SUBJECT=$(grep -m 1 ^Subject: $TMP | cut -f 2 -d :) + +# get the encrypted message +sed -n '/-----BEGIN PGP MESSAGE-----/,/-----END PGP MESSAGE-----/p' $TMP >> $TMP.gpg + +# if signature is OK, 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" | $MAIL -r $LISTNAME $FROMADD + +fi + +rm -f $TMP $TMP.gpg diff --git a/misc/poc/firma-0.2.1 b/misc/poc/firma-0.2.1 new file mode 100755 index 0000000..13ee6da --- /dev/null +++ b/misc/poc/firma-0.2.1 @@ -0,0 +1,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 diff --git a/misc/poc/firma-0.2.2 b/misc/poc/firma-0.2.2 new file mode 100755 index 0000000..f1a8f27 --- /dev/null +++ b/misc/poc/firma-0.2.2 @@ -0,0 +1,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 diff --git a/misc/poc/firma-0.2.3 b/misc/poc/firma-0.2.3 new file mode 100755 index 0000000..2864115 --- /dev/null +++ b/misc/poc/firma-0.2.3 @@ -0,0 +1,192 @@ +#!/bin/bash +# +# firma v0.2.3: 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 +# 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 +# + +VERSION=0.2.3 + +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 + # 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 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 $PASSWD | ($GPGDECRYPT --status-fd 2 $TMP.gpg 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 process_message { + # process a message sent to the list + + # 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 v$VERSION" | $MAIL -r $LISTNAME $FROMADD + + fi + + rm -f $TMP $TMP.gpg + +} + +# 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 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 + 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 + diff --git a/misc/poc/firma-0.2.x b/misc/poc/firma-0.2.x new file mode 100755 index 0000000..126f998 --- /dev/null +++ b/misc/poc/firma-0.2.x @@ -0,0 +1,280 @@ +#!/bin/bash +# +# firma v0.3: 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 +# + +FIRMA_LIST_PATH=/usr/local/etc/lists +VERSION=0.3 + +# todo: +# errase all vars before quit the game +# unset MESSAGE +# unset GPG_MESSAGE +# umask .... + +function usage { + echo usage: $0 firma \ \ + echo -c: create a new list using config-file + echo -p: process a message + echo -r: admin and user requests (mail only) + 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 message_list { +# compose and send a message to the list +# $1: subscriber email +# sorry no identation :P +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 $1 | $MAIL -r $LISTNAME $1 +} + +function message_list_error { +# compose and send an error message +# sorry no identation :P +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 $1 | $MAIL -r $LISTNAME $1 +} + +function message_list_return { +# send a bouce message +# $1: sender email (usually $FROMADD) +# sorry no identation :P +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 $1 +} + +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 + message_list $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 + message_list_error $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 + message_list_return $FROMADD + fi + +} + +function newlist { + # create a list if it doesnt already exist + if [ ! -d "$CONFIG_PATH" ]; then + echo creating folder $CONFIG_PATH... + mkdir "$CONFIG_PATH" # || (echo "error creating $CONFIG_PATH: installation aborted"; exit 1) + echo "creating list config file and will ask some questions." + + GPGDIR="$CONFIG_PATH" + + read -p "path to nail command (eg, /usr/bin/nail): " MAIL + read -p "path to gpg binary (eg, /usr/bin/gpg): " GPG + + # if [ ! -x $GPG ]; then + + read -p "list keyring folder (defaults to $GPGDIR): " GPGDIR + + # todo: please no utf-8 (see DETAILS) + read -p "list email (eg, firma@domain.tld): " LISTNAME + read -p "list admins emails (space delimited)" LISTADMIN + read -p "password for list keyring (use a huge one): " PASSWD + + # todo: key specs (size, expiry date...) + + echo "creating your config..." + touch $CONFIG + chown root.root $CONFIG + chmod 600 $CONFIG + if [ -f $CONFIG ]; then + echo -e "MAIL=$MAIL\nGPG=$GPG\nGPGDIR=$GPGDIR\nLISTNAME=$LISTNAME\nLISTADMIN=$LISTADMIN\nPASSWD=$PASSWD" > $CONFIG + echo "now generating your keyring..." + # re-eval GPGCOMMAND + # todo: GPGFLAGS depende de GPGDIR + GPGCOMMAND="$GPG $GPGFLAGS" + $GPGCOMMAND --gen-key + + fi + else + echo error creating $CONFIG_FILE: list already exists + exit 1 + fi +} + +# main - +# command line checking +if [ -z $2 ]; then + usage; exit 1 +else + CONFIG_FILE="$2" + CONFIG_PATH="$FIRMA_LIST_PATH/$2" + CONFIG="$CONFIG_PATH/$2.conf" +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 +GPGFLAGS="--quiet --homedir $GPGDIR --batch --no-tty --no-use-agent --no-permission-warning" +GPGCOMMAND="$GPG $GPGFLAGS" +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 + list_admin +elif [[ $1 == "-r" ]]; then + list_request +else + usage; exit 1 +fi + diff --git a/misc/python/README b/misc/python/README new file mode 100644 index 0000000..4f75401 --- /dev/null +++ b/misc/python/README @@ -0,0 +1,2 @@ +Initial and broken code. Needs GnuPGInterface available at +http://py-gnupg.sourceforge.net. diff --git a/misc/python/firma.py b/misc/python/firma.py new file mode 100755 index 0000000..19f9c9d --- /dev/null +++ b/misc/python/firma.py @@ -0,0 +1,85 @@ +#!/usr/bin/python +""" Firma - Encrypted Mailing List Manager - Python Version + +firma: GnuPG-based encrypted mailing list manager +Feedback: firma@sarava.org + + Firma is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + Firma is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA + +Lets use: http://docs.python.org/lib/module-email.html + http://docs.python.org/lib/module-smtplib.html + http://py-gnupg.sourceforge.net/ + +Lets split the work: + + - create list + - create folder, set permissions + - create config file + - create keyring, set permissions again + - admin list + - parse config file + - from command line + - parse comand line args + - exec admin tasks + - display output + - from email + - decrypt message + - parse command line args + - exec admin tasks + - record output + - encrypt and send back output + - process message + - parse config file + - read stdin and store as original message + - decrypt message + - if encrypted and signed, encrypt again and send to all subscribers + +""" + +import GnuPGInterface + +# first we'll create just a routine that sets up a new gpg keyring + +class NewKey(GnuPGInterface.GnuPG): + """ Class used to create a new gpg keyring """ + def __init__(self): + GnuPGInterface.GnuPG.__init__(self) + self.options.armor = 0 + self.options.extra_args.append("--gen-key") + self.options.meta_interactive = 0 + + def __setitem__(self, key, value): + if key == "homedir" and value: + # TODO: check if --homedir already is on self.options.extra_args + # TODO: check if the folder referenced by "value" exists + self.options.extra_args.append("--homedir %s" % value) + # TODO: else raises an exception? + +class DelKey(GnuPGInterface.GnuPG): + """ Class used to delete a key from a keyring """ + def __init__(self): + GnuPGInterface.GnuPG.__init__(self) + +class RevokeKey(GnuPGInterface.GnuPG): + """ Class used to revoke a key """ + def __init__(self): + GnuPGInterface.GnuPG.__init__(self) + +# lets start the code + +passwd = "senha" +newkey = NewKey() +newkey = ["homedir"] = "firma-python/keyring-teste" + +print newkey.options.extra_args -- cgit v1.2.3