Re: [Mimedefang] PGP encyption of outging email

2009-05-27 Thread Gary Funck
On 05/06/09 12:52:59, Pete wrote:
> Is there a method for encrypting outgoing email using PGP (or other
> methods). I am thinking of doing this on a per recipient basis. I.e encrypt
> email to people I regularly email and leave plain the rest. 
> 
> Any suggestions or ideas welcome. 

Something that I've done in the past is to set up a Mailman
mailing list and to then direct secure email via that
mailing list.  A public/private key pair is created for
each secure mailing list; this key pair is distributed
to the mailing list recipients.  List members configure
their mail client to encrypt mail sent to the list with
the private key, and to decode with the public key.

A more general purpose method is described here:
"The Secure List Server: an OpenPGP and S/MIME aware Mailman"
http://non-gnu.uvt.nl/mailman-pgp-smime/

Attached, is a Perl script that I use, that is called
via procmail that decodes PGP-encrypted attachments; it
is derived from mgpg-test, part of the Mail::GPG package.
The script handles most commonly occurring PGP attachments.
You'll note that it looks for a passphrase that is read
from a file in the user's home directory.
(You wouldn't want to use this method for extremely
confidential/secure mail.)

#!/usr/bin/perl -w
#
# derived from mgpg-test, part of the Mail::GPG package
#
use strict;
use lib 'lib';
use Mail::GPG;
use Mail::Address;
use MIME::Parser;
use MIME::Entity;
use MIME::Head;
use MIME::Body;
use Getopt::Std;
use Socket;
use Net::Domain qw(hostname hostfqdn hostdomain);


sub decrypt_part ($)
{
  my $entity_ref = shift;
  my $entity = $$entity_ref;
  my $mg = Mail::GPG->new ();
  # mail is encrypted, ask Mail::GPG for the
  # key to decrypt this mail
  my ($key_id, $key_mail) = $mg->get_decrypt_key (entity => $entity);
  return 0 if !defined $key_id;
  my ($addr) = Mail::Address->parse($key_mail);
  return 0 if !defined $addr;
  my $uid = $addr->user;
  return 0 if !defined $uid;
  # obtain passphrase from file.
  my $home = $ENV{'HOME'} || '~';
  my $passfile = "$home/.gnupg/passphrase-${uid}.txt";
  my $passphrase;
  open (PASSPHRASE, "<$passfile") || return 0;
  chomp ( $passphrase =  );
  close (PASSPHRASE);
  # decode the mail
  my ($decrypted, $result) = eval { $mg->decrypt (entity => $entity,
  passphrase => $passphrase) };
  return 0 if $@;
  $$entity_ref = $decrypted;
  return 1;
}

sub decrypt_msg ($);
sub decrypt_msg ($)
{
  my $entity_ref = shift;
  my $entity = $$entity_ref;
  my $decrypted = 0;
  my $mg = Mail::GPG->new ();
  if ( $mg->is_encrypted ( entity => $entity ) )
{
  $decrypted = decrypt_part ($entity_ref);
  $entity = $$entity_ref;
  my $body = $entity->bodyhandle;
  if ($body) {
my $btext = $body->as_string;
if ($btext =~ /^[[:print:][:space:]]*$/)
  {
# remove spurious 's
if ($btext =~ s/\r\n/\n/g)
  {
my $B = $body->open("w") || return 0;
$B->print($btext);
$B->close;
  }
$entity->effective_type('plain/text');
  }
  }
}
  elsif ($entity->parts)
{
  my @new_parts;
  for my $p ($entity->parts)
{
  $decrypted |= decrypt_msg (\$p);
  push @new_parts, $p;
}
  $entity->parts (\...@new_parts) if $decrypted;
}
  return $decrypted;
}

$| = 1;

#  for debugging;
open (STDIN, "; # slurp
}


my $entity = Mail::GPG->parse ( mail_sref => \$msg );

exit 2 if !decrypt_msg (\$entity);

# remove temp. files created by MIME::Entity
$entity->purge;

# Dump the decoded message
my ($from_line) = ($msg =~ /^(From [^\n]*)/);
print "$from_line\n" if defined $from_line;

my $host = hostfqdn();
my $ip_addr = inet_ntoa( scalar gethostbyname( $host || 'localhost' ));

my $head = $entity->head;
my $old_content_type = $head->get('Old-Content-Type');
if ($old_content_type)
  {
$head->replace('Content-Type', $old_content_type);
$head->delete('Old-Content-Type');
  }
$head->replace('X-GPG-Decrypt:', "Decrypted on host $ip_addr at " . scalar 
localtime);

$entity->print(\*STDOUT);
___
NOTE: If there is a disclaimer or other legal boilerplate in the above
message, it is NULL AND VOID.  You may ignore it.

Visit http://www.mimedefang.org and http://www.roaringpenguin.com
MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang


Re: [Mimedefang] Greylisting post-data (was Re: [PATCH] filter_data implementation)

2009-05-27 Thread -

--- On Wed, 5/27/09, David F. Skoll  wrote:
> Date: Wednesday, May 27, 2009, 6:17 PM - wrote:
> ...
> > However, if subject were not part of your mix, then greylisting
> > (with a "421" as that's really the only temp-error code that should
> > occur in response to DATA) would work.
> 
> 421 responses to DATA probably cause seldom-tested code to
> execute. :-) Many SMTP implementations don't handle edge
> cases in the SMTP state machine very well.

Perhaps so, but in RFC 5321 (and predecessors, 2821 and 821), the ONLY tempfail 
code valid at that point is 421, so if these programs didn't plan for it, they 
failed to follow the historical design for an SMTP client, and are thus 
completely broken.

As spamware is also broken, perhaps we should assume that such a client is 
hostile?
___
NOTE: If there is a disclaimer or other legal boilerplate in the above
message, it is NULL AND VOID.  You may ignore it.

Visit http://www.mimedefang.org and http://www.roaringpenguin.com
MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang


Re: [Mimedefang] Greylisting post-data (was Re: [PATCH] filter_data implementation)

2009-05-27 Thread David F. Skoll
- wrote:

>> 1) To make greylisting work with marginal SMTP servers that don't handle
>> 4xx responses to RCPT properly.

> I can accept that - although I've never knowingly observed it.

Old versions of Novell Groupwise failed to handle this properly (though
it has been fixed for a long time.)  I believe the same applies to old
versions of Lotus Notes.

> However, if subject were not part of your mix, then greylisting
> (with a "421" as that's really the only temp-error code that should
> occur in response to DATA) would work.

421 responses to DATA probably cause seldom-tested code to
execute. :-) Many SMTP implementations don't handle edge cases in the
SMTP state machine very well.

Regards,

David.
___
NOTE: If there is a disclaimer or other legal boilerplate in the above
message, it is NULL AND VOID.  You may ignore it.

Visit http://www.mimedefang.org and http://www.roaringpenguin.com
MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang


Re: [Mimedefang] Greylisting post-data (was Re: [PATCH] filter_data implementation)

2009-05-27 Thread -

--- On Wed, 5/27/09, David F. Skoll  wrote:
> Martin Blapp wrote:
> > Ask David, AFAIK he's using such a post DATA graylisting
> > implementation, but at filter_begin() instead of filter_data().
> 
> Yes, we filter post-DATA for two reasons:
> 
> 1) To make greylisting work with marginal SMTP servers that don't handle
> 4xx responses to RCPT properly.

I can accept that - although I've never knowingly observed it.
 
> 2) We greylist on:  HASHFUNC(sender, recipient, sending_ip, subject)
> because some spammers got around greylisting by sticking to the same
> IP address, but mutating the subject header.  Because we include the
> subject line in our greylisting mix, we couldn't greylist in filter_data
> even if it were available.

However, if subject were not part of your mix, then greylisting (with a "421" 
as that's really the only temp-error code that should occur in response to 
DATA) would work.

I was just looking for a potential use.  Looks like there is one.
___
NOTE: If there is a disclaimer or other legal boilerplate in the above
message, it is NULL AND VOID.  You may ignore it.

Visit http://www.mimedefang.org and http://www.roaringpenguin.com
MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang


[Mimedefang] Greylisting post-data (was Re: [PATCH] filter_data implementation)

2009-05-27 Thread David F. Skoll

Martin Blapp wrote:


Ask David, AFAIK he's using such a post DATA graylisting
implementation, but at filter_begin() instead of filter_data().


Yes, we filter post-DATA for two reasons:

1) To make greylisting work with marginal SMTP servers that don't handle
4xx responses to RCPT properly.

2) We greylist on:  HASHFUNC(sender, recipient, sending_ip, subject)
because some spammers got around greylisting by sticking to the same
IP address, but mutating the subject header.  Because we include the
subject line in our greylisting mix, we couldn't greylist in filter_data
even if it were available.

Regards,

David.

PS: To make our greylisting tolerable, we mark a host that successfully
makes it past greylisting as not-to-be-greylisted for 40 days.
___
NOTE: If there is a disclaimer or other legal boilerplate in the above
message, it is NULL AND VOID.  You may ignore it.

Visit http://www.mimedefang.org and http://www.roaringpenguin.com
MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang


Re: [Mimedefang] [PATCH] filter_data implementation

2009-05-27 Thread David F. Skoll

Martin Blapp wrote:


If there is more than one recpient in @Recipients, the mail is
definitly not a bounce.


That's not necessarily true. :-)

Scenario:  Mail from list-boun...@example.com bounces.  It goes to
example.com's front-end servers which explode list-bounces into
adm...@example.com and admin2.example.com.  This mail then gets forwarded
on to a MIMEDefang box.

Yes, it's an edge case. :-)

[Re: Why not proper literals, etc.] Let's put those on the TODO list...

Regards,

David
___
NOTE: If there is a disclaimer or other legal boilerplate in the above
message, it is NULL AND VOID.  You may ignore it.

Visit http://www.mimedefang.org and http://www.roaringpenguin.com
MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang


Re: [Mimedefang] [PATCH] filter_data implementation

2009-05-27 Thread Martin Blapp
Hi,

> 1)  The routine appears to want response codes of 2xx, 4xx, or 5xx.
>  However, the appropriate response code for continuing a message
> in SMTP is 354.  2xx codes are not valid here (RFC 5321, Section 4.3.2):

Thanks, I'll test if it works with 3xx error codes too. I did my tests with
2xx and
they worked.

>2)  What information is there at this stage that wasn't available at the
>filter_recipient() call, other than knowing that all (original) recipients
have
>been collected?  Are we trying to check for a "missing recipient?"  Zero
accepted
>or too many recipients are issues handled by the MTA itself.

That's correct. The only information we have is that ALL recipients have
been
collected. For BATV this is important. If there is more than one recpient in
@Recipients, the mail is definitly not a bounce.  In my BATV implementation
I
also look at senders like "postmaster" and other abused admin-adresses.
And as I said before, adress probes are still allowed here for some extent.

There is also an other use here. There exist some bad SMTP implementations
(some MS-Mailservers IMHO) which can't cope with graylisting at recipient
level
all the time. If we do after DATA, but before content graylisting, we could
circumvent those limitations. Ask David, AFAIK he's using such a post DATA
graylisting implementation, but at filter_begin() instead of filter_data().

>If our author chooses to implement this, why not implement the per-header
>and end-of-headers calls too?  However, just because we can do something
>doesn't mean we should do it if there's no reason to.  I don't see what the
call is trying to accomplish.

You are free to implement it ;-) I only needed filter_data() and have no
time
to code the others. But of course, for completeness sake, it would be a good
thing.

>3)  In MXDataOK(), why are we mangling 5 of the variables?  Some we set to 
>"UNKNOWN", but I don't see that elsewhere.  For $name, we're setting it to
$ip,
>but why not set a PROPER literal, "[$ip]", and if it's IPv6, then
"[IPv6:$ip]"? 
>Hasn't sendmail (or another MTA package) already done that for us?

I've just copied some code from MXRecipientOK (2.68 Beta) and did it in a
similar manner. If you like to review that code, ask David why he did it
that
way ;-) The literal thing would be a good thing to have, but David needs to
decide here. A proper interface for those things would be good to have, it
would save us a lot of code in mimedefang-filter and lead to cleaner code.

--
Martin


___
NOTE: If there is a disclaimer or other legal boilerplate in the above
message, it is NULL AND VOID.  You may ignore it.

Visit http://www.mimedefang.org and http://www.roaringpenguin.com
MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang


Re: [Mimedefang] [PATCH] filter_data implementation

2009-05-27 Thread -

I have a few issues with the patch presented below:

1)  The routine appears to want response codes of 2xx, 4xx, or 5xx.  However, 
the appropriate response code for continuing a message in SMTP is 354.  2xx 
codes are not valid here (RFC 5321, Section 4.3.2):

  DATA
 I: 354 -> data -> S: 250
   E: 552, 554, 451, 452
   E: 450, 550 (rejections for policy reasons)
 E: 503, 554

So, technically the only valid results to "DATA" BEFORE receipt of the headers 
and body are:  354, 421, 500, 501, 503, and 554.  2xx codes are not permitted.  
This is easy to fix.

2)  What information is there at this stage that wasn't available at the 
filter_recipient() call, other than knowing that all (original) recipients have 
been collected?  Are we trying to check for a "missing recipient?"  Zero 
accepted or too many recipients are issues handled by the MTA itself.

If our author chooses to implement this, why not implement the per-header and 
end-of-headers calls too?  However, just because we can do something doesn't 
mean we should do it if there's no reason to.  I don't see what the call is 
trying to accomplish.

If there's a specific issue this is being added to address, then please let us 
(or at least me) know.

3)  In MXDataOK(), why are we mangling 5 of the variables?  Some we set to 
"UNKNOWN", but I don't see that elsewhere.  For $name, we're setting it to $ip, 
but why not set a PROPER literal, "[$ip]", and if it's IPv6, then "[IPv6:$ip]"? 
 Hasn't sendmail (or another MTA package) already done that for us?

4)  Some minor comments are inline with the patch.

That is all.

--- On Wed, 5/27/09, Martin Blapp  wrote:
> And here it is, a filter_data implementation. David, please
...
> --- mimedefang.c2009-05-24 07:40:40.0 +0200
> +++ mimedefang.c2009-05-24 06:27:35.0 +0200
> @@ -978,12 +981,67 @@
> ...
>  static sfsistat mf_data(SMFICTX *ctx)
>  ...
> +syslog(LOG_WARNING, "postdata: Unable to obtain private data from milter 
> context");

Eliminate the above syslog() line in the final version.  The other milter 
interface routines don't have it when they perform this check.

> +DEBUG_EXIT("mf_data", "SMFIS_TEMPFAIL");
> ...

> +if (n == MD_ACCEPT_AND_NO_MORE_FILTERING) {
> +/* Called in case we don't need content filtering */
> +set_dsn(ctx, ans, 2);
 ^  - Accept -> "3", not "2"
> +cleanup(ctx);
> ...
> +if (n == MD_DISCARD) {
> +set_dsn(ctx, ans, 2);
 ^  - Accept -> "3", not "2"
> +
> +cleanup(ctx);
> ...
> +if (n == MD_CONTINUE) {
> +/* Called only in case we need to delay */
> +set_dsn(ctx, ans, 2);
 ^  - Accept -> "3", not "2"
> +return SMFIS_CONTINUE;
> ...
> @@ -2092,6 +2150,7 @@
>  fprintf(stderr, "  -r-- Do relay check before processing 
> body\n");
>  fprintf(stderr, "  -s-- Do sender check before 
> processing body\n");
>  fprintf(stderr, "  -t-- Do recipient checks before 
> processing body\n");
> +fprintf(stderr, "  -A-- Process body. If not set, 
> content filtering will be skipped\n");

   Process DATA command BEFORE receipt of message body?
   It's NOT processing the body.

>  fprintf(stderr, "  -q-- Allow new connections to be 
> queued by multiplexor\n");
> ...
> --- utils.c2009-05-24 07:40:40.0 +0200
> +++ utils.c2009-05-24 06:29:06.0 +0200
> @@ -801,6 +801,69 @@
>  ...
> +int
> +MXDataOK(char const *sockname,
> ...
> +*msg = 0;
> +

  WHY? (following)

> +if (!sender || !*sender) {
> +sender = "UNKNOWN";
> +}
> +
> +if (!ip || !*ip) {
> +ip = "UNKNOWN";
> +}
> +if (!name || !*name) {
> +name = ip;
> +}
> +
> +if (!firstRecip || !*firstRecip) {
> +firstRecip = "UNKNOWN";
> +}
> +if (!helo) {
> +helo = "UNKNOWN";
> +}

  WHY? (above)

> ...
___
NOTE: If there is a disclaimer or other legal boilerplate in the above
message, it is NULL AND VOID.  You may ignore it.

Visit http://www.mimedefang.org and http://www.roaringpenguin.com
MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang


[Mimedefang] [PATCH] filter_data implementation

2009-05-27 Thread Martin Blapp
Hi all,

And here the patch again, this time with examples and parts
of the manpage.

--
Martin

--- mimedefang.c2009-05-24 07:40:40.0 +0200
+++ mimedefang.c2009-05-24 06:27:35.0 +0200
@@ -233,6 +233,9 @@
 /* Do recipient check? */
 static int doRecipientCheck = 0;
 
+/* Do precontent check */
+static int doPreContentCheck = 0;
+
 /* Keep directories around if multiplexor fails? */
 static int keepFailedDirectories = 0;
 
@@ -978,12 +981,67 @@
 *%RETURNS:
 * Standard milter reply code
 *%DESCRIPTION:
-* Does a post-DATA callback
+* Does a post-DATA callback before any content is submitted
 ***/
 #ifdef MILTER_BUILDLIB_HAS_DATA
 static sfsistat mf_data(SMFICTX *ctx)
 {
-return SMFIS_CONTINUE;
+struct privdata *data = DATA;
+char ans[SMALLBUF];
+sfsistat retcode = SMFIS_CONTINUE;
+int i;
+
+DEBUG_ENTER("mf_data");
+if (!data) {
+   syslog(LOG_WARNING, "postdata: Unable to obtain private data from milter
context");
+   DEBUG_EXIT("mf_data", "SMFIS_TEMPFAIL");
+   return SMFIS_TEMPFAIL;
+}
+
+/* Post data check if enabled */
+if (doPreContentCheck) {
+   int n;
+
+   n = MXDataOK(MultiplexorSocketName, ans, data->sender, data->hostip,
+ data->hostname, data->firstRecip, data->heloArg,
+ data->dir, data->qid);
+
+   if (n == MD_REJECT) {
+   /* Reject this mail with all recipients */
+   set_dsn(ctx, ans, 5);
+
+   DEBUG_EXIT("mf_data", "SMFIS_REJECT");
+   return SMFIS_REJECT;
+   }
+   if (n <= MD_TEMPFAIL) {
+   /* Tempfail this mail with all recipients */
+   set_dsn(ctx, ans, 4);
+
+   DEBUG_EXIT("mf_data", "SMFIS_TEMPFAIL");
+   return SMFIS_TEMPFAIL;
+   }
+   if (n == MD_ACCEPT_AND_NO_MORE_FILTERING) {
+   /* Called in case we don't need content filtering */
+   set_dsn(ctx, ans, 2);
+   cleanup(ctx);
+   DEBUG_EXIT("mf_data", "SMFIS_ACCEPT");
+   return SMFIS_ACCEPT;
+   }
+   if (n == MD_DISCARD) {
+   set_dsn(ctx, ans, 2);
+
+   cleanup(ctx);
+   DEBUG_EXIT("mf_data", "SMFIS_DISCARD");
+   return SMFIS_DISCARD;
+   }
+   if (n == MD_CONTINUE) {
+   /* Called only in case we need to delay */
+   set_dsn(ctx, ans, 2);
+   return SMFIS_CONTINUE;
+   }
+}
+DEBUG_EXIT("mf_data", "SMFIS_CONTINUE");
+return retcode;
 }
 #endif
 
@@ -2092,6 +2150,7 @@
 fprintf(stderr, "  -r-- Do relay check before
processing body\n");
 fprintf(stderr, "  -s-- Do sender check before
processing body\n");
 fprintf(stderr, "  -t-- Do recipient checks before
processing body\n");
+fprintf(stderr, "  -A-- Do pre content check for
processing body\n");
 fprintf(stderr, "  -q-- Allow new connections to be
queued by multiplexor\n");
 fprintf(stderr, "  -P file   -- Write process-ID of daemon to
specified file\n");
 fprintf(stderr, "  -T-- Log filter times to syslog\n");
@@ -2189,7 +2248,7 @@
 }
 
 /* Process command line options */
-while ((c = getopt(argc, argv,
"NCDHL:MP:R:S:TU:Xa:b:cdhkm:p:qrstvx:z:")) != -1) {
+while ((c = getopt(argc, argv,
"ANCDHL:MP:R:S:TU:Xa:b:cdhkm:p:qrstvx:z:")) != -1) {
switch (c) {
case 'N':
 #ifdef MILTER_BUILDLIB_HAS_NEGOTIATE
@@ -2346,6 +2405,9 @@
case 't':
doRecipientCheck = 1;
break;
+   case 'A':
+   doPreContentCheck = 1;
+   break;
case 'h':
usage();
break;
--- mimedefang.h2009-05-24 07:40:40.0 +0200
+++ mimedefang.h2009-05-24 06:26:27.0 +0200
@@ -40,6 +40,10 @@
 char const *dir, char const *qid,
 char const *rcpt_mailer, char const *rcpt_host,
 char const *rcpt_addr);
+extern int MXDataOK(char const *sockname, char *msg,
+char const *sender, char const *ip, char const *name,
+char const *firstRecip, char const *helo,
+char const *dir, char const *qid);
 
 extern int safeWriteHeader(int fd, char *str);
 extern void split_on_space(char *buf, char **first, char **rest);
--- mimedefang.pl.in2009-05-24 07:41:08.0 +0200
+++ mimedefang.pl.in2009-05-24 07:10:42.0 +0200
@@ -5645,6 +5645,21 @@
chdir($Features{'Path:SPOOLDIR'});
next;
}
+   if ($_ =~ /^dataok 
(\S*)\s+(\S*)\s+(\S*)\s+(\S*)\s+(\S*)\s+(\S*)\s+(\S*)/)
{
+   $sender = percent_decode($1);
+   $ip = percent_decode($2);
+   $name = percent_decode($3);
+   $firstRecip = percent_decode($4);
+   $helo = percent_decode($5);
+  

Re: [Mimedefang] Adding headers during filter sender () and 2.68 Beta 1 issue.

2009-05-27 Thread Martin Blapp
Hi all,

And here it is, a filter_data implementation. David, please
add a 'sponsored by T-Systems Switzerland' notice to the
changelog if that is possible.

Some of you may notice that only the first recipient is available
here. If the complete list of recipients is needed, one needs to
parse/read the COMMANDs/Result files to get the recipient list.

There may be issues with the LOG because I'm receiving now this
error message. Maybe david knows how to fix it, else I'll have a
look at it this evening.

May 24 07:53:11 vm1 mimedefang-multiplexor[81799]: Slave 0 stderr: Warning:
unable to close filehandle LOGF properly.

--
Martin

--- mimedefang.c2009-05-24 07:40:40.0 +0200
+++ mimedefang.c2009-05-24 06:27:35.0 +0200
@@ -233,6 +233,9 @@
 /* Do recipient check? */
 static int doRecipientCheck = 0;
 
+/* Do precontent check */
+static int doPreContentCheck = 0;
+
 /* Keep directories around if multiplexor fails? */
 static int keepFailedDirectories = 0;
 
@@ -978,12 +981,67 @@
 *%RETURNS:
 * Standard milter reply code
 *%DESCRIPTION:
-* Does a post-DATA callback
+* Does a post-DATA callback before any content is submitted
 ***/
 #ifdef MILTER_BUILDLIB_HAS_DATA
 static sfsistat mf_data(SMFICTX *ctx)
 {
-return SMFIS_CONTINUE;
+struct privdata *data = DATA;
+char ans[SMALLBUF];
+sfsistat retcode = SMFIS_CONTINUE;
+int i;
+
+DEBUG_ENTER("mf_data");
+if (!data) {
+   syslog(LOG_WARNING, "postdata: Unable to obtain private data from milter
context");
+   DEBUG_EXIT("mf_data", "SMFIS_TEMPFAIL");
+   return SMFIS_TEMPFAIL;
+}
+
+/* Post data check if enabled */
+if (doPreContentCheck) {
+   int n;
+
+   n = MXDataOK(MultiplexorSocketName, ans, data->sender, data->hostip,
+ data->hostname, data->firstRecip, data->heloArg,
+ data->dir, data->qid);
+
+   if (n == MD_REJECT) {
+   /* Reject this mail with all recipients */
+   set_dsn(ctx, ans, 5);
+
+   DEBUG_EXIT("mf_data", "SMFIS_REJECT");
+   return SMFIS_REJECT;
+   }
+   if (n <= MD_TEMPFAIL) {
+   /* Tempfail this mail with all recipients */
+   set_dsn(ctx, ans, 4);
+
+   DEBUG_EXIT("mf_data", "SMFIS_TEMPFAIL");
+   return SMFIS_TEMPFAIL;
+   }
+   if (n == MD_ACCEPT_AND_NO_MORE_FILTERING) {
+   /* Called in case we don't need content filtering */
+   set_dsn(ctx, ans, 2);
+   cleanup(ctx);
+   DEBUG_EXIT("mf_data", "SMFIS_ACCEPT");
+   return SMFIS_ACCEPT;
+   }
+   if (n == MD_DISCARD) {
+   set_dsn(ctx, ans, 2);
+
+   cleanup(ctx);
+   DEBUG_EXIT("mf_data", "SMFIS_DISCARD");
+   return SMFIS_DISCARD;
+   }
+   if (n == MD_CONTINUE) {
+   /* Called only in case we need to delay */
+   set_dsn(ctx, ans, 2);
+   return SMFIS_CONTINUE;
+   }
+}
+DEBUG_EXIT("mf_data", "SMFIS_CONTINUE");
+return retcode;
 }
 #endif
 
@@ -2092,6 +2150,7 @@
 fprintf(stderr, "  -r-- Do relay check before
processing body\n");
 fprintf(stderr, "  -s-- Do sender check before
processing body\n");
 fprintf(stderr, "  -t-- Do recipient checks before
processing body\n");
+fprintf(stderr, "  -A-- Process body. If not set,
content filtering will be skipped\n");
 fprintf(stderr, "  -q-- Allow new connections to be
queued by multiplexor\n");
 fprintf(stderr, "  -P file   -- Write process-ID of daemon to
specified file\n");
 fprintf(stderr, "  -T-- Log filter times to syslog\n");
@@ -2189,7 +2248,7 @@
 }
 
 /* Process command line options */
-while ((c = getopt(argc, argv,
"NCDHL:MP:R:S:TU:Xa:b:cdhkm:p:qrstvx:z:")) != -1) {
+while ((c = getopt(argc, argv,
"ANCDHL:MP:R:S:TU:Xa:b:cdhkm:p:qrstvx:z:")) != -1) {
switch (c) {
case 'N':
 #ifdef MILTER_BUILDLIB_HAS_NEGOTIATE
@@ -2346,6 +2405,9 @@
case 't':
doRecipientCheck = 1;
break;
+   case 'A':
+   doPreContentCheck = 1;
+   break;
case 'h':
usage();
break;
--- mimedefang.h2009-05-24 07:40:40.0 +0200
+++ mimedefang.h2009-05-24 06:26:27.0 +0200
@@ -40,6 +40,10 @@
 char const *dir, char const *qid,
 char const *rcpt_mailer, char const *rcpt_host,
 char const *rcpt_addr);
+extern int MXDataOK(char const *sockname, char *msg,
+char const *sender, char const *ip, char const *name,
+char const *firstRecip, char const *helo,
+char const *dir, char const *qid);
 
 extern int safeWriteHeader(int fd, char *str);
 extern void split_

Re: [Mimedefang] Adding headers during filter sender () and 2.68 Beta 1 issue.

2009-05-27 Thread Martin Blapp
Hi,

>Can't do it.  Such is a limitation of the MILTER interface.
>These changes can only be submitted during the xxfi_eom()
>call from the interface.

Just checked the milter code. This seems to be true. So a post-data
graylisting is definitly only possible at a later stage until
the milter guys change it in the library.

Fortunatly bounces have only ONE recipient, so the return
answer is enough at this place and one could implement
it in filter_data. I'll now code a filter_data() and send it to the
list.

--
Martin


___
NOTE: If there is a disclaimer or other legal boilerplate in the above
message, it is NULL AND VOID.  You may ignore it.

Visit http://www.mimedefang.org and http://www.roaringpenguin.com
MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang


Re: [Mimedefang] DCC, Pyzor, and Razor header additions

2009-05-27 Thread Steffen Kaiser

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On Tue, 26 May 2009, afo cliff wrote:


Thanks.  I must be using the stock spam_assassin_check because I see
this in mimedefang-filter:

my($hits, $req, $names, $report) = spam_assassin_check();

I tried adding the line below under the change_header lines and all
that ended up in the email header was "X-Spam-Tests:" with no data

action_add_header("X-Spam-Tests", "$test");


Hmm, read up man mimedefang-filter, $test is the 3rd return value of 
spam_assassin_check(), hence, it's named $names in your filter.


Also, in this particular case it is not necessary to quote the variable, 
in fact, it would waste a bit of ressources, use these lines for example:


my($hits, $req, $names, $report) = spam_assassin_check();
action_add_header("X-Spam-Tests", $names);
action_add_header("X-Spam-Score", $hits);



On Mon, May 25, 2009 at 2:50 AM, Steffen Kaiser
 wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On Thu, 21 May 2009, afo cliff wrote:


add_header all Pyzor _PYZOR_
add_header all DCC _DCCG_: _DCCR_


If you use the stock spam_assassin_check() function, there is a '$test'
return value of the comma separated list of SpamAssassin test names.

Use it in combination with action_add_header().


- -- 
Steffen Kaiser

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.6 (GNU/Linux)

iQEVAwUBShzl99lJzF6z/k3SAQJS3wf+MCCrRDwTM12+w1N27EldFhb5y+aT9/6o
BFiRKi28BAqWA2tfEf0otzJ//75sG02ZsSf8+lD43wxijnZaltWu21YD9Km7PTw2
VZFw5NgdjSAAFUKL5o8mGIs1xQyXAazMRrnUWZWR0mGXy1hbaVQ/HVMv2EH6NLSX
7B4Mru7JqFkGH3R7r/kTY0Y+p0b47ySourHGqNYqDvf3lqwWMOBIoiuB6OJ0vgzv
9Y1QE4TzFsdI11cCcUy87WTgzXpjYMhUF30S+fYSpKNZdAj/8BrVXb4HFxxzwQRv
q73+BipG7O2VDFAPqxzBtsnWQc+tbaWFrAMf2EFOeSNBuQW2suwDgA==
=+axd
-END PGP SIGNATURE-
___
NOTE: If there is a disclaimer or other legal boilerplate in the above
message, it is NULL AND VOID.  You may ignore it.

Visit http://www.mimedefang.org and http://www.roaringpenguin.com
MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang