[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
sendmail -bv workaround on postfix.
From: |
Shadwick, Tony |
Subject: |
sendmail -bv workaround on postfix. |
Date: |
Fri, 25 Mar 2011 10:34:03 -0500 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.14) Gecko/20110223 Lightning/1.0b2 Thunderbird/3.1.8 |
So I've been putting off writing to the list about this, because I'm not
sure what a good way to deal with the result is without creating another
security vulnerability.
To bring some of you up to speed, way back in like 2002/2003, I wrote
this very list stating that I needed to be able to call `sendmail -bv`
on email addresses so that aliases correctly resolved. A very short
time later, the -x flag was added, and all was well.
Years later, sendmail miltering support is added to Postfix, and there
is much rejoicing. But all is not well. `sendmail -bv` on postfix,
instead of resolving the name and returning the output to stdout,
instead delivers the information to the user's inbox. This is not at
all helpful for spamass-milter.
The problem for us, as I see it, is that depending on how virtual maps
are configured in postfix, the actual replacement for `sendmail -bv`
could be very different from one server to another. It should always be
(I think) `postmap -q <email address> /path/to/virtual/map`, except that
too will fail for addresses with plus signs - an example:
The username I have on my box is tshadwick.
The email address I tend to use is address@hidden, so I have an
entry in /etc/posfix/virtual:
address@hidden tshadwick
postmap -q address@hidden /etc/postfix/virtual
tshadwick
Life is good, right? Nope. I create throwaway addresses using
plussing. If I were to register with say, foobar.com, when registering,
I would give them address@hidden
postmap -q address@hidden /etc/postfix/virtual
<null return>
Make no mistake though - that would be delivered to my mailbox. So on
my own system, I edited spamass-milter.cpp to look like this:
--------------
if (flag_expand)
{
/* open a pipe to sendmail so we can do address
expansion */
char buf[1024];
char *popen_argv[3];
popen_argv[0] =
"/home/tshadwick/perl-scripts/postfix-address-verification";
popen_argv[1] = envrcpt[0];
popen_argv[2] = NULL;
debug(D_RCPT, "calling %s %s",
"/home/tshadwick/perl-scripts/postfix-address-verification", envrcpt[0]);
p = popenv(popen_argv, "r");
if (!p)
{
debug(D_RCPT, "popenv failed(%s). Will not
expand aliases", strerror(errno));
assassin->expandedrcpt.push_back(envrcpt[0]);
} else
{
while (fgets(buf, sizeof(buf), p) != NULL)
{
int i = strlen(buf);
/* strip trailing EOLs */
while (i > 0 && buf[i - 1] <= ' ')
i--;
buf[i] = '\0';
debug(D_RCPT, "expansion output: %s", buf);
/* From a quick scan of the
sendmail source, a valid email
address gets printed via either
"deliverable: mailer %s,
host %s, user %s"
or "deliverable: mailer %s,
user %s"
*/
// if (strstr(buf, "... deliverable: mailer "))
// {
// char *p=strstr(buf,", user ");
// /* anything after ", user " is
the email address */
// debug(D_RCPT, "user: %s", p+7);
//
assassin->expandedrcpt.push_back(p+7);
assassin->expandedrcpt.push_back(buf);
// }
}
fclose(p); p = NULL;
}
} else
{
assassin->expandedrcpt.push_back(envrcpt[0]);
}
debug(D_RCPT, "Total of %d actual recipients",
(int)assassin->expandedrcpt.size());
--------------
In short, I I changed it from calling `sendmail -bv` to call
`/home/tshadwick/perl-script/postfix-address-verification`, that way I
could deal with this in a language that I actually understand. That
script looks like this today:
--------------
#!/usr/bin/env perl
use strict;
my $postmap = '/usr/sbin/postmap';
my $virtual = '/etc/postfix/virtual';
exit() unless $ARGV[0];
my $recipient = $ARGV[0];
# Strip the envelope.
$recipient =~ s/<(.*?)>/$1/;
# Handle plussed addresses.
$recipient =~ s/(.+?)\+.+?(address@hidden)$/$1$2/;
# Strip out any pipes or semicolons.
$recipient =~ s/\||\;//g;
my $command = "$postmap -q $recipient $virtual";
my $output = `$command`;
exit unless $output;
print $output unless $output =~ /error:nouser/;
exit;
--------------
There are a few drawbacks to this that I'm aware of:
1. It's insecure. There's a known attack vector to it. I attempt to
mitigate with how I have postfix configured and within the perl script
itself, but it would be nice to do this "the right way". Unfortunately,
I'm not sure how to make the resolution command both configurable *and*
secure. Help?
2. It causes spamass-milter to leave zombies. I restart spamass-milter
nightly to clean them up. From the looks of it, if a transaction drops
out while my script is still executing, spamass-milter drops a zombie.
Presumably the only reason that would happen is a lack of input, and
I've attempted to account for that, but still with the zombies.
3. It's not supported by anyone but me. :) Seriously, I'd like to get
a solution mainlined that everyone agrees upon so that postfix
deployments of this type are supportable.
Anyone have thoughts? When it comes right down to it, I'm just not a c
or c++ programmer, else I would have attempted a better solution
already. This is a trial-and-error hack I thew together just to get it
to let me write a perl script resolver. Gotta be a better way, right?
A way to put a proper resolver command in spamass-milter's config?
Tony Shadwick
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- sendmail -bv workaround on postfix.,
Shadwick, Tony <=