Hi *,
I've stumbled across a small problem and I'm not sure how to fix it
correctly.
Whenever a relay client sends an address which is not accepted by
Qpsmtpd::Address he never gets an error message. The mail is silently
redirected (in our case the admin's address). Some examples:
RCPT TO:<[EMAIL PROTECTED]>
250 <>, recipient ok
RCPT TO:<[EMAIL PROTECTED]>
250 <>, recipient ok
RCPT TO:<[EMAIL PROTECTED] >
250 <"\<hah"@uu-x.de>, recipient ok
The last one doesn't even match the MAIL FROM behaviour:
MAIL FROM:<[EMAIL PROTECTED] >
250 <>, sender OK - how exciting to get mail from you!
Sidenote: Qmail and Postfix both accept the trailing space or dot as
valid recipients from relay clients and the mail is delivered to the
"correct" recipient address.
My first attempt was to add a check to rcpt_ok to return an error if
$recipient->user is empty, but that didn't catch the third one with the
trailing space.
Now I need help for this one :)
Some questions (even some are without a "?" :-)):
- should Qpsmtpd::Address accept mails with a trailing "."? Like
$ host -t MX perl.org.
perl.org mail is handled by 5 mx.develooper.com.
- Qpsmtpd::SMTP: adjust parsing of mail addresses in rcpt() to the
one in mail(), i.e.
my ($from) = ($from_parameter =~ m/^from:\s*(<[^>]*>)/i)[0];
and not
my ($rcpt) = ($_[0] =~ m/to:(.*)/i)[0];
which causes the weird "rewriting".
... diff attached.
- Qpsmtpd::Address should be able to tell if it's a parsing error or
really an empty address. Then a plugin or Qpsmtpd::SMTP can drop an
error in the RCPT phase if it's an parsing error from an MAIL FROM
address.
The diff for rcpt_ok is attached.
Hanno
--- rcpt_ok.orig 2006-01-25 09:00:35.000000000 +0100
+++ rcpt_ok 2006-03-04 08:42:07.000000000 +0100
@@ -14,9 +14,15 @@
# qmail-smtpd will do this for all users without a domain, but we'll
# be a bit more picky. Maybe that's a bad idea.
my $user = $recipient->user;
+ return(DENY, "failed to parse address or nothing before the '\@' given")
+ if ($user eq "");
+
$host = $self->qp->config("me")
if ($host eq "" && (lc $user eq "postmaster" || lc $user eq "abuse"));
-
+
+ return(DENY, "no hostname in address")
+ if ($host eq "");
+
# Check if this recipient host is allowed
for my $allowed (@rcpt_hosts) {
$allowed =~ s/^\s*(\S+)/$1/;
--- lib/Qpsmtpd/SMTP.pm.orig 2006-03-04 08:36:21.000000000 +0100
+++ lib/Qpsmtpd/SMTP.pm 2006-03-04 09:21:46.000000000 +0100
@@ -335,14 +335,22 @@
my $self = shift;
return $self->respond(501, "syntax error in parameters") unless $_[0] and
$_[0] =~ m/^to:/i;
return $self->respond(503, "Use MAIL before RCPT") unless
$self->transaction->sender;
+ my $rcpt_parameter = join " ", @_;
+ my ($rcpt) = ($rcpt_parameter =~ m/^to:\s*(<[^>]*>)/i)[0];
+ # support addresses without <> ... maybe we shouldn't?
+ ($rcpt) = "<" . ($rcpt_parameter =~ m/^to:\s*(\S+)/i)[0] . ">"
+ unless $rcpt;
- my ($rcpt) = ($_[0] =~ m/to:(.*)/i)[0];
- $rcpt = $_[1] unless $rcpt;
$self->log(LOGALERT, "to email address : [$rcpt]");
- $rcpt = (Qpsmtpd::Address->parse($rcpt))[0];
+
+ $rcpt = (Qpsmtpd::Address->parse($rcpt))[0];
+ ### does this one ever happen?
return $self->respond(501, "could not parse recipient") unless $rcpt;
+ return $self->respond(501, "cound not parse recipient")
+ if $rcpt->format eq '<>';
+
my ($rc, $msg) = $self->run_hooks("rcpt", $rcpt);
if ($rc == DONE) {
return 1;