#! /bin/bash
### sendmail-cryptoml --- sendmail for ciphered distributed mailing lists.

# Filename: sendmail-cryptoml
# Version: 0.4.0 of the 23th of June 2005 codename you-really-cannot-stop-the-revolt
# Keywords: anonymous, ciphered, distributed, mailing list, cryptography
# Description: anonymous ciphered distributed mailing lists implementation.
# Language: Shell, Awk
# Compatibility: GNU bash 2.05b, GNU Awk 3.1.4, mixmaster 3.0b2
# Location: https://www.inventati.org/inventa/doku.php?id=sendmail-cryptoml

# NO Copyright (C)  2005  NonfirmareNiente.
# Released in the Public Domain.
#
# Copying and distribution of this file, with or without modification,
# are permitted worldwide, without royalty, in any medium.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

### Commentary:

# sendmail-cryptoml is a wrapper for sendmail.
#
# It is meant to provide fully distributed, ciphered and anonymous (or
# pseudonymous) mailing list.
#
# Each subscriber to a distributed mailing list has a list of the others
# subscribers and their PGP keys.  It would be fine but not so needed
# that all the subscribers have the same subscribers list.
#
# For using sendmail-cryptoml, copy this script somewhere and make it
# executable, then edit the configuration section, then configure your
# mail client to use sendmail-cryptoml instead of sendmail (if you
# can't, then change mail client).
#
# Now, to send a message to a configured mailing list send it to
# LISTNAME@cryptoml.  It will be ciphered for the mailing list
# subscribers and will be sent to them.  Messages not sent to the
# fake domain cryptoml are send in the usual way by passing them to
# sendmail.
#
# If you are not used to use remailers, then be aware that it can take
# some time to deliver a message, it is not as fast as plain smtp.
#
# Add bug-reports and fixes directly to the home page (see `Location:'
# above).

### Warning:

# Please consider that you are getting this program from a wiki.
#
# If you want to use this program, then YOU WANT to understand and
# check each single line of code of this program, or as an alternative
# you want to get this program from a really trusted person who will
# do it for you.
#
# Certifications are trendy, if you want to be useful at this project,
# study/verify a version the sources (possibly the last), sign it
# and make it available to the public in other places (for example
# put it in your web space).

### Hacking:

# If you are going to modify this program, PLEASE keep it clean and
# readable, as it should be easily understanded and checked by its
# users.  Also, be coherent with the coding style, if you don't like
# it: fork.

### Bug reports:

# Put bug reports here.

### Whishlist:

# Put whishlist items here.
#
# Do enought testing, bug-hunting and misfeature-hunting, so to be
# able to label a release as "usable by end users".
#
# Anonymous mailing lists support: use reply-blocks instead of email
# addresses for the subscribers, plus use a remailer chain yourself.
#
# Automatic mailing list management support: subscribing,
# unsubscribing, addresses and reply-blocks updates, sync with other's
# subscribers mailing list, and other fuzzy stuff, with related
# options.  Procmail can help here.  It seems that configuration is
# going to exit from the script to go to a separate file.
#
# When we will involve procmail and fetchmail, then we can implement
# other really funny things, like automated file sharing over
# anonymous email, with archive listing and such, or glue an anonymous
# remailer to our pop3/wtf mailbox, maybe choosing another anonymous
# remailer (chain/set with randomizing and whatever) as the remailer
# equivalent of an smtp smarthost.
#
# Add mixmaster-update calling when N time is passed from the previous
# time.

### Questions and comments:

# Put here questions and comments.

### ChangeLog:

# 0.4.0: Now join all the messages for a ML to 1 single message.
# So now just 1 message leaves your host.  
#
# 0.3.0: Stopped re-inventing the wheel: now the mixmaster client
# is used for interfacing with the remailers.  Now using the remailers
# is not an option (however, this is a script...).
#
# 0.2.99: Started implemeting remailers chains support. well, it
# should work but I did not get ONE positive result as now, so 0.3.0
# is delayed to the next time.
#
# 0.2.0: The message is ciphered and sent for each single ML subscriber.

### Configuration:

# Enable (true) or disable (false) debugging output.
debug=false

# Set debug log path.
dlog=~/cryptoml.log

# The sendmail program (you can put some options too here).
#sendmail=./logthefuck
sendmail=/usr/sbin/sendmail

# The mixmaster client, you can put some options too here (like
# remailer-chain selection `-l').
#
#mixmaster=./logthefuck
mixmaster=mixmaster

# Address and key id for `lastactionhero', aka the last remailer which
# dispatches all the emails to the subscribers of the yadda yadda bla
# bla bla mailing list.  Change this to another one (we don't want to
# use all the same remailer, do we?).
#
lastactionhero_address=mixmaster@ecn.org
lastactionhero_keyid=0x02F8D381

# The gpg program (you can put some options too here).
gpg="gpg --always-trust"

# Configuration for each mailing list.
#
# format: LISTNAME="MAILADDRESS,GPGKEYID,COMMENTS:..."
#
# You can use the comments field for alternative addresses, or you can
# keep an alternative list with alternative addresses.
#
examplelist="esempio1@autistici.org,0x12345678,esempio 1:esempio2@inventati.org,0x87654321,un altro"

# The headers that will be preserved (to the recipient) in messages
# sent through an anonymous remailer (chain).
#
# format: PRESERVE_HEADERS_WHEN_REMAILING="HEADER1:..."
#
PRESERVE_HEADERS_WHEN_REMAILING="To:Cc:Subject:References:In-Reply-To"

### Code:

# Copy the message in memory.
msg=`cat /dev/stdin`

# Get the headers
headers=`echo "$msg" \
          | awk 'BEGIN { RS = "\n\n" } \
                 // { if (FNR == 1) print $0; }'`
if [ $? != 0 ]; then exit 1; fi

# Get the body
body=`echo "$msg" \
       | awk 'BEGIN { RS = "\n\n" } \
              // { if (FNR != 1) print $0; }'`
if [ $? != 0 ]; then exit 1; fi

# Flags for sendmail
sflags=`echo -n ${1+"$@"} \
         | awk 'BEGIN { RS = " " } \
                /^-f/ { nextissender = "yes" } \
                /@/ { if (nextissender == "yes") \
                        print $0; \
		      nextissender = "no"; \
                    } \
                /^[^@]*$/ { previous=NR; print $0 } \
                /^-/ { if (NR != previous) print $0 }'`
if [ $? != 0 ]; then exit 1; fi

# Recipients for sendmail
srecip=`echo -n ${1+"$@"} \
         | awk 'BEGIN { RS = " " } \
           /^-f/ { nextissender = "yes" } \
           /^-[^f]/ { nextissender = "no" } \
           /^[^-].*@/ { \
                        if (nextissender != "yes") \
                          print $0; \
                        nextissender = "no"; \
                      }'`
if [ $? != 0 ]; then exit 1; fi

if $debug; then
    echo approaching to do the fuck > $dlog
    echo args: ${1+"$@"} >> $dlog
    echo sflags: $sflags >> $dlog
    echo srecip: $srecip >> $dlog
fi

# If the -t option is present, use the recipients from the message,
# remove the recipients from the command line from these, and remove
# the `-t' option.
#
if echo $sflags | grep -q ' *-t'; then

    # Remove the `-t' option.
    sflags=`echo $sflags | sed 's/-t//g'`

    # Get the recipient addresses.
    nrecip=`echo "$headers" \
             | awk 'BEGIN { RS="\n "} // { x=x$0 } END { print x }' \
	     | grep -i '\(^To\|^Cc\|^Bcc\)' \
	     | sed 's/^[^:]*:[ ]*//' \
             | awk 'BEGIN { RS="," } // { print $0 }' \
	     | grep @ \
             | sed 's/\([A-Za-z0-9._+\-]*@[A-Za-z0-9._+\-]*\).*/\1/' \
             | rev \
             | sed 's/\([A-Za-z0-9._+\-]*@[A-Za-z0-9._+\-]*\).*/\1/' \
	     | rev`
    if [ $? != 0 ]; then exit 1; fi

    # Remove the recipients from the command line.
    for x in $srecip; do
	nrecip=`echo "$nrecip" | sed "s/^$x\\$//"`
    done

    srecip=$nrecip
fi

if $debug; then echo srecip reloaded: $srecip >> $dlog; fi

# At some point this will contain a message for the last remailer in
# the chain, and all the ciphered messages for the lusers.
#
bigbuffer=""

# The emails @cryptoml are ciphered and sent to the
# configured subscribers, the others are sent directly using sendmail.
#
for recip in $srecip; do

    if echo $recip | grep -q '@cryptoml$'; then

	if $debug; then echo doing the fuck >> $dlog; fi

	# The domain part of the recipient address.
	recipdomain=`echo $recip | sed 's/^[^@]*@//'`

	# The name of the mailing list.
	listname=`echo $recip | sed 's/\([^@]*\).*/\1/'`

	# The content of the list
	if [ "$listname" != '' ]; then 
	    listcontent=`eval echo '$'$listname`
	fi

	# Check if the mailing list exists.
	case "$listcontent" in
	    "") echo list not found > /dev/stderr; exit 1
	esac

	# The number of subscribers.
	subn=`echo $listcontent | awk 'BEGIN { FS=":" } END { print NF }'`

	# For each subscriber.
	for sub in `x=0
                    while test $(($x<$subn)) == 1; do
                      x=$(($x+1))
                      echo $x
                    done`; do

	  if $debug; then echo for subscriber number $sub >> $dlog; fi
	  
          # The ML subscriber address.
	  address=`echo $listcontent \
                     | awk "BEGIN { RS=\":\"; FS=\",\" } \
                            // { if (NR==$sub) print \\$1 }"`

          # The ML subscriber GPG key id.
	  key=`echo $listcontent \
                 | awk "BEGIN { RS=\":\"; FS=\",\" } \
                        // { if (NR==$sub) print \\$2 }"`
	  if [ "$key" == "" ]; then
	      echo "sendmail-cryptoml: no key for subscriber #$sub." \
		  > /dev/stderr
	      exit 1
	  fi

	  if $debug; then echo "  aka <$address> [$key]" >> $dlog; fi

	  # Cipher the message body.
	  nbody=`echo "$body" | $gpg --batch -a -e -r "$key"`
	  if [ $? != 0 ] ; then
	      echo "sendmail-cryptoml: cannot cipher for $key" \
		  > /dev/stderr
	      exit 1
	  fi

          # Unmultilined headers.
	  uheaders=`echo "$headers" | awk '// { 
                                   if ($0 ~ "^ ") { prev=$prev$0; }
                                     else { print $prev; prev=$0; }}'`

          # Preserved headers.
	  pheaders=""
	  for preserve_header \
	      in `echo $PRESERVE_HEADERS_WHEN_REMAILING | tr : ' '`; do
	    pheader=`echo "$uheaders" | grep $preserve_header`
	    if [ "$pheader" != "" ]; then
		pheaders="$pheader
$pheaders"
	    fi
	  done

	  # Collect the message to the BIG BUFFER :DDD
	  bigbuffer="$bigbuffer
::
Anon-To: $address
Cutmarks: --

##
$pheaders
$nbody
--"
	done

        if $debug; then echo -e "cleartext:\n$bigbuffer" >> $dlog; fi
	bigbuffer=`echo "$bigbuffer" \
                    | $gpg --batch -a -e -r "$lastactionhero_keyid"`
        bigbuffer="::
Encrypted: PGP

$bigbuffer"
        if $debug; then echo -e "ciphered:\n$bigbuffer" >> $dlog; fi

        # Send the message using the mixmaster client.
	echo "$bigbuffer" | $mixmaster -t $lastactionhero_address

    else
	if $debug; then echo not doing the fuck >> $dlog; fi
	echo "$msg" | $sendmail $sflags $recip
    fi
done

#### sendmail-cryptoml ends here.
 
  sendmail-cryptoml.txt · Ultima modifica: 23.06.2005 19:59 by 127.0.0.1
 
RSS: Modifiche Recenti Contenuti: Licenza Creative Commons Valid XHTML 1.0 Valid CSS Sito fatto con: DokuWiki Sito ospitato da: Inventati.org