#!/usr/bin/perl ########################### # # sendmail_wrapper v0.1 # Author: Marcelo Coelho ( marcelo _at_ tpn.com.br ) # # INSTALL INSTRUCTIONS: # # 1) Edit sendmail_wrapper.txt, set "Configuration variables" # 2) Copy and CHMOD this file # cp sendmail_wrapper.txt /usr/sbin/sendmail_wrapper # chmod 755 /usr/sbin/sendmail_wrapper # 3) Edit your php.ini, put sendmail_path=/usr/sbin/sendmail_wrapper # ########################### ########################### # Configuration variables # ########################### $mail_from = 'www@yourdomain.com'; $sendmail = '/usr/sbin/sendmail -t'; $abuse_email = 'abuse@yourdomain.com'; $max_recipients = 5; $debug = 0; ########################### @buffer = ; @headers = (); @body = (); $from = ""; $seen_from = 0; $seen_to = 0; $seen_cc = 0; $seen_bcc = 0; $seen_header = 0; $seen_subject = 0; $seen_dot = 0; $nto = 0; $ncc = 0; $nbcc = 0; $n = 0; $suspect = 0; $deny = ""; $deny2 = ""; $last_header = ""; foreach $line (@buffer) { chop($line); if ($seen_header == 0) { if ($line =~ /^From: /i) { if ($seen_from == 0) { if ($line =~ /<\s*([a-z0-9\=\+\.\_\-]+@[a-z0-9\=\+\_\-]+\.[a-z0-9\=\+\.\_\-]+)\s*>/i) { $from = $1; } elsif ($line =~ /([a-z0-9\=\+\.\_\-]+@[a-z0-9\=\+\_\-]+\.[a-z0-9\=\+\.\_\-]+)/i) { $from = $1; } elsif ($line =~ /^From:.*\<\>$/i) { $from = ""; } elsif ($line =~ /^From:\s*$/i) { $from = ""; } elsif ($line =~ /^From:\s*(\(\))*$/i) { $from = ""; } else { $deny = "INVALID_FROM"; $deny2 = $line; last; } } ++$seen_from; } if ($line =~ /^To: /i) { ++$seen_to; @tmp = split(/,/,$line); $nto += $#tmp + 1; } if ($line =~ /^Cc: /i) { ++$seen_cc; @tmp = split(/,/,$line); $ncc += $#tmp + 1; } if ($line =~ /^Bcc: /i) { ++$seen_bcc; @tmp = split(/,/,$line); $nbcc += $#tmp + 1; ++$suspect; } if ($line =~ /^Subject: /i) { ++$seen_subject; } if ($last_header ne '') { if ($last_header eq 'to') { @tmp = split(/,/,$line); $nto += $#tmp + 1; } elsif ($last_header eq 'cc') { @tmp = split(/,/,$line); $ncc += $#tmp + 1; } elsif ($last_header eq 'bcc') { @tmp = split(/,/,$line); $nbcc += $#tmp + 1; } } if ($line =~ /(To|Cc|Bcc):.*\,\s*$/i) { $last_header = $1; $last_header =~ tr/A-Z/a-z/; } elsif ($line !~ /^(|\s\t ).*\,\s*$/) { $last_header = ''; } if ($seen_from > 1) { $deny = "DOUBLE_FROM"; $deny2 = $line; last; } if ($seen_to > 1) { $deny = "DOUBLE_TO"; $deny2 = $line; last; } if ($seen_cc > 1) { $deny = "DOUBLE_CC"; $deny2 = $line; last; } if ($seen_bcc > 1) { $deny = "DOUBLE_BCC"; $deny2 = $line; last; } if ($seen_subject > 1) { $deny = "DOUBLE_SUBJECT"; $deny2 = $line; last; } $n = $nto + $ncc + $nbcc; if ($n > $max_recipients) { $deny = "MAX_RECIPIENTS"; $deny2 = $n; } if ($line eq '') { $seen_header = 1; next; } } else { if ($line eq '.' && ++$seen_dot > 1) { $deny = "DOUBLE_DOT"; $deny2 = $line; last; } if ($line =~ /^(From|To|Cc|Bcc|Subject): /i) { ++$suspect; } if ($suspect > 3) { $deny = "SUSPECT"; $deny2 = $line; last; } } if ($seen_header) { push @body, $line . "\n"; } else { if ($line ne '') { push @headers, $line . "\n"; } if ($line =~ /^From: /i) { push @headers, "X-AntiAbuse: report abuse to $abuse_email\n"; } } } if ($from eq '') { $deny = "NO_MAILFROM"; $deny2 = ""; } $arg = ""; foreach(@ARGV) { $arg .= " $_"; } if ($arg =~ m/\-f\s?([a-z0-9_.-]+@[a-z0-9_.-]+)/i) { $mail_from = $1; } elsif ($from ne '') { $mail_from = $from; } if ($deny eq '') { open(SENDMAIL,"|$sendmail -f$mail_from") or die("Couldn't start sendmail"); print SENDMAIL @headers; print SENDMAIL "\n"; print SENDMAIL @body; close(SENDMAIL); } else { open(LOG,">>/var/log/sendmail_wrapper.log") or die("Couldn't open log"); $tmp = `date`; chop($tmp); $log = "$tmp $deny $deny2 $mail_from\n"; print LOG $log; if ($debug == 1) { print $log; } close(LOG); } if ($debug == 1) { print "from = $from\n"; print "seen_from = $seen_from\n"; print "seen_to = $seen_to\n"; print "seen_cc = $seen_cc\n"; print "seen_bcc = $seen_bcc\n"; print "seen_header = $seen_header\n"; print "seen_subject = $seen_subject\n"; print "seen_dot = $seen_dot\n"; print "nto = $nto\n"; print "ncc = $ncc\n"; print "nbcc = $nbcc\n"; print "n = $n\n"; print "suspect = $suspect\n"; print "deny = $deny\n"; print "deny2 = $deny2\n"; } exit;