-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Previous threads about hashcash headers:
http://mla.libertine.org/tmda-workers/2003-08/msg00078.html http://mla.libertine.org/tmda-workers/2004-01/msg00077.html They basically conclude that there's no easy way to add hashcash to outgoing mail. I wrote a tmda-sendmail wrapper that adds hashcash headers to email as it passes through. To make it work, I tell Mutt to invoke this instead of tmda-sendmail. I need to have the hashcash binary in my path (to create the tokens), and the wrapper is in Perl. My testing has been light but successful. I'm sharing this here in case someone else might benefit. According to the hashcash FAQ, SpamAssassin 2.70 supports hashcash checking, so adding hashcash to emails will become more valuable as that version becomes more widely deployed. http://www.hashcash.org/faq.html I'm accepting hashcash into my mailbox in .procmailrc this way: # -c check # -q no output # -y valid tokens are good even if not fully checked # -X look for the X-Hashcash header # -e expiration time for tokens (default 28 days) # -d use a database to avoid double spending # -f where the double spending DB is. # -p purge the double spending database if it hasn't been done in that long # -b number of bits of work to require # -r "resource" to verify (e.g., [EMAIL PROTECTED]) :0 * ^Delivered-To: \/.* * ^X-Hashcash: * $? $HOME/bin/hashcash -c -q -y -X -e 31d -d -f $HOME/.tmda/hashcash.db -p 10d -b16 -r '$MATCH' $DEFAULT This is basically mental exercise at the moment. A quick audit shows that I've never received a X-Hashcash header on any ham (I didn't check spam). Finally, here's the script (which I'm calling add_hashcash): #!/usr/bin/perl # # This script is a wrapper for tmda-sendmail. # It reads the incoming message and adds X-Hashcash headers for the recipients. # It tries to parse the To: and Cc: lines to determine for whom to add # hashcash. Any Bcc: recipients will be left out. # # To: and Cc: parsing code lifted from Benjamin J. Stassart's tmda-incoming # script. # # FUTURE: Need to limit the time we'll spend on this, either by limiting # how many recipients we'll pay for, or how much total time we'll spend on # all recipients collectively. # use strict; use IPC::Open3; my $bits_to_compute = 16; my $com = "|/usr/bin/tmda-sendmail"; foreach my $arg ( @ARGV ) { $com .= " \"" . shell_escape( $arg ) . "\""; } #my @rcpt = grep( /[EMAIL PROTECTED]/, @ARGV ); my @rcpt = (); open( SENDMAIL, $com ) || die "Can't sendmail: $!\n"; my $in_headers = 1; my $in_to = 0; while ( <STDIN> ) { $in_to = 0 if ( $in_to && ! /^\s/ ); my $line = $_; if ( $in_headers && ( $in_to || $line =~ s/^(Cc|To): // ) ) { # Get rid of all whitespace $line =~ s/\s+//g; # Get rid of any quoted text $line =~ s/\"[^\"]*\"//g; foreach my $addr ( split( ',', $line ) ) { next if ( $addr =~ m/undisclosed-recipients/i ); next if ( $addr =~ m/recipientlistsuppressed/i ); # Does it contain a route-addr? if ($addr =~ m/<(.*)>/) { # Use the route-addr $addr = $1; } # Does it have single quotes around it? # Microsoft Exchange sometimes does this $addr =~ s/^\'//; $addr =~ s/\'$//; # Get rid of comments in ()'s $addr =~ s/\(.*\)//g; if ( defined( $addr ) && $addr =~ m/[EMAIL PROTECTED]/) { push( @rcpt, $addr ); } } $in_to = 1; } if ( $in_headers && ! /\S/ ) { foreach my $recipient ( @rcpt ) { my $r = shell_escape( $recipient ); # Why does hashcash produce its token on stderr?? my $pid = open3( \*WTRFH, \*RDRFH, \*ERRFH, "hashcash -m -r \"$r\" -b $bits_to_compute -X" ); if ( ! $pid ) { warn "Can't hashcash: $!\n"; } else { close( WTRFH ); close( RDRFH ); my $tok = <ERRFH>; close( ERRFH ); print SENDMAIL $tok if ( $tok ); } } $in_headers = 0; } print SENDMAIL; } if ( ! close( SENDMAIL ) && ! $! ) { exit( $? ); } # Escapes shell meta characters, so I can safely use it on the command line. # This does NOT escape spaces. What you get from this is meant to be put in # double quotes on the command line. sub shell_escape { my ( $string ) = @_; $string =~ s/\\/\\\\/g; $string =~ s/\"/\\\"/g; $string =~ s/\$/\\\$/g; $string =~ s/\`/\\\`/g; return $string; } - -- Kyle Hasselbacher | If you don't know where you're going, [EMAIL PROTECTED] | you might end up somewhere else. -- Yogi Berra -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iD8DBQFAMpAf10sofiqUxIQRAk41AKCO1SgiajdR66hqTYTWc7q5WxOkAgCfRtUe NshLZpIbzwdSBg1KXNT/xzI= =RO1p -----END PGP SIGNATURE----- _____________________________________________ tmda-users mailing list ([EMAIL PROTECTED]) http://tmda.net/lists/listinfo/tmda-users
