Re: qpsmtpd-async weird ParaDNS lookup problem + code fix

2014-08-07 Thread Matt Sergeant
To be fair I don't do perl coding any more, so I'm happy for someone 
to take over ParaDNS maintainence.


ParaDNS-XS is in my SVN server. Happy to share that with anyone who wants 
it. It's basically ParaDNS using adns backend rather than Net::DNS. It's a 
bit hacky and probably doesn't work 100%


Matt.

On Fri, 1 Aug 2014, David Favor wrote:


Matt Sergeant wrote:
Do you have ParaDNS::XS installed? If not, try installing it. It's 
generally likely to be better than plain ParaDNS (and will be used 
automatically if it's installed).


There is no ParaDNS::XS on cpan... At least nothing returned for...

   http://search.cpan.org/search?query=paradnsmode=all

Unsure what this has to do with setting a list of servers for ParaDNS
to query. Whether pure perl or XS, likely there still has to be a set
of servers to query.

The fix I'm using right now is a slight patch to Qpsmtpd/PollServer.pm
which simply gives ParaDNS a list of servers to check...

   my @nameservers = qw/127.0.0.1 8.8.8.8 8.8.4.4/;

   my $obj = ParaDNS-new(
   nameservers = \@nameservers,
   finished = sub { $self-continue_read(); 
$self-run_hooks(connect); },

   # NB: Setting remote_info to the same as remote_host
   callback = sub { $conn-remote_info($conn-remote_host($_[0])); },
   host = $ip,
   );

This works like a charm.

Reading through the ParaDNS code, it's unclear to me how qpsmtpd can work
at all without a list of servers for ParaDNS to query.




Re: qpsmtpd-async weird ParaDNS lookup problem

2014-07-22 Thread Matt Sergeant
Do you have ParaDNS::XS installed? If not, try installing it. It's 
generally likely to be better than plain ParaDNS (and will be used 
automatically if it's installed).


On Thu, 17 Jul 2014, David Favor wrote:


I've been running qpsmtpd-async for years on all sorts of servers.

Likely I have something in DNS setup slightly wrong on a new server
I'm setting up + what's wrong escapes me.

The symptom is qpsmtpd-async hanging forever in the HELO sequence.

Both forkserver + prefork work fine + async works so much better,
I'd like to resolve this problem.

Here's an example of the problem...

Listen child making a Qpsmtpd::PollServer for 7.
11869 in config(plugins)
11869 config(plugins) returning (resolve_sender_host 
dont_require_anglebrackets rcpt_simple t...@newswire.net ch...@newswire.net 
d...@newswire.net supp...@newswire.net account...@newswire.net
sa...@newswire.net debr...@newswire.net maildir /cluster/clients/ivan-budimir 
%d/users/%l/Maildir) from cache

DNS failure looking for 127.0.0.1 after 0 secs (looked for 1, got 0)
11869 (connect) running plugin: resolve_sender_host
11869 (connect) resolve_sender_host: DEBUG: ip=127.0.0.1 host=localhost 
domain=localhost

11869 Plugin resolve_sender_host, hook connect returned DECLINED,
11869 in config(smtpgreeting)
11869 config(smtpgreeting) returning (Ready!) from cache

Notice this line emitted from ParaDNS...

  DNS failure looking for 127.0.0.1 after 0 secs (looked for 1, got 0)

Bind looks good...

  biz-net2# netstat -pluten | grep named
  tcp0  0 127.0.0.1:530.0.0.0:*   LISTEN 
10560684715/named
  tcp0  0 127.0.0.1:953   0.0.0.0:*   LISTEN 
10560734715/named
  tcp6   0  0 ::1:53  :::*LISTEN 
10560704715/named
  tcp6   0  0 ::1:953 :::*LISTEN 
10560744715/named
  udp0  0 127.0.0.1:530.0.0.0:* 
10560674715/named
  udp6   0  0 ::1:53  :::* 
10560694715/named


And host seems to work too...

  biz-net2# host localhost
  localhost has address 127.0.0.1
  localhost has IPv6 address ::1

  biz-net2# host 127.0.0.1
  1.0.0.127.in-addr.arpa domain name pointer localhost.

If I turn on ParaDNS debugging (export PARADNS_DEBUG=100) I just see the 
lookup fail again...


  100/2 [17636] dns lookup: Trying to resolve A: 127.0.0.1
  100/2 [17636] dns lookup: NS Query: 127.0.0.1 (60806)
  DNS failure looking for 127.0.0.1 after 0 secs (looked for 1, got 0)

biz-net2# perl -MParaDNS -e 'print $ParaDNS::VERSION\n'
2.0

Anyone have any suggestions?




Re: Qpsmtpd vs Haraka performance

2011-09-14 Thread Matt Sergeant

Aleksandar Lazic wrote:

Hi Matt,

On Die 13.09.2011 11:10, Matt Sergeant wrote:

I just benchmarked Qpsmtpd vs Haraka and thought some here might find
the results interesting:

http://baudehlo.wordpress.com/2011/09/13/node-js-is-fast/

(not meant as inflammatory, obviously I still have love for Qpsmtpd)

Matt.


How about to check the regex performance with a plugin like:

check_badmailfrom_patterns
check_badrcptto_patterns
rcpt_regexp

I think the main benefit of perl is his regex engine.


Regular expressions are much faster in Javascript (well, in V8). They 
also suck (lots and lots of features missing). But if you don't need 
advanced features then they are going to be faster.


Matt.


Qpsmtpd vs Haraka performance

2011-09-13 Thread Matt Sergeant
I just benchmarked Qpsmtpd vs Haraka and thought some here might find 
the results interesting:


http://baudehlo.wordpress.com/2011/09/13/node-js-is-fast/

(not meant as inflammatory, obviously I still have love for Qpsmtpd)

Matt.


FYI: Qpsmtpd plugins were: logging/warn, rcpt_all_ok[1], queue/do_nothing[2]

[1]: sub hook_rcpt { return OK }
[2]: sub hook_queue { return (OK, Queued) }


Re: qpsmtp-async forwarder

2011-08-26 Thread Matt Sergeant
The forwarders (I supply 
both forwarder, after DATA, and full proxy) in Haraka is fully async. 
Maybe time to learn some _javascript_ :)


  
  
Alister WestAugust 25, 2011 9:10 PM
  
  Hi qpsmtpd,I came across an entry 
in the mail-archive link where Chris Lewismentions he has customised
 qpsmtp-async for forwarding to a list ofother servers.http://www.nntp.perl.org/group/perl.qpsmtpd/2009/07/msg8919.htmlChris
 My qpsmtp-async forwarder has a config list of IPs (and ports).I
 am about to write something that does something very similar (aload-balancer
 for smtp). As I'm not very familiar with qpsmtp I waswondering if 
Chris is still active here and if he would mind sharinghis altered 
forwarder so I could use it as base for my project.Any other 
suggestions, or modifications to qpsmtp-async,plugins/..smtp-forward,
 etc. welcome.Cheers for the good work!~~c|_| 
alisterwest.com - mmm coffee!



Re: [PATCH] tweak QP's header handling for messages with no body

2011-08-17 Thread Matt Sergeant

Yup. I should check if Haraka does the right thing with this too :)

On Tue, 16 Aug 2011, Jared Johnson wrote:


True, I was led astray by the comment that seemed to indicate it was all
about headers.  if the intention of the comment is correct, then it should
probably if ( $in_header and ... ), whether or not the new regex is added.
That block would also need to be moved to after the block that sets
$in_header = 0 if we've reached the end, to avoid catching the blank line
that separates headers and newlines.

At any rate, Chris has a point -- I was actually thinking the other day
that code like that original deferral would be better of sitting in a
plugin, so I could muck around with it in a more straightforward manner in
order to, say, log what we did to our own database, or change it to a
rejection, or whatever :)

Anyway, this is all kind of minutia compared to the original patch, which
I feel I should remind everyone has to do with accepting legitimate mail
from Lotus software without inadvertently stripping the headers :)

-Jared


That line of code doesn't look at the headers though, just at the final
dot at the end-of-data.




Jared Johnson mailto:jjohn...@efolder.net
August 16, 2011 3:00 PM


There's already a special case for something similar to this:

# Reject messages that have either bare LF or CR. rjkaes noticed a
# lot of spam that is malformed in the header.

($_ eq .\n or $_ eq .\r)
and $self-respond(421, See
http://smtpd.develooper.com/barelf.html;)
and return $self-disconnect;

you could just make it ( /\r\r\n$/ or $_ eq .\n or $_ eq .\r )
maybe?
and update the link to point to a URL that explains both?

-Jared





Matt Sergeant mailto:m...@sergeant.org
August 16, 2011 11:28 AM


Yup there's a lot of this going around right now. Just to be explicit
though, the header lines end in \r\r\n. Worth rejecting the bloody
lot, frankly :)



Chris Lewis mailto:cle...@nortel.com
August 15, 2011 4:21 PM




As a FYI, I've been seeing bot-emitted spam that appears to have extra
\r at the end of _all_ header lines, and the qpsmtpd parser seems to
be treating all of it as part of the _body_.  IOW: except for the
received line inserted by qpsmtpd, qpsmtpd doesn't see _any_ headers.

This implementation is backrev (0.80 I think), and as it's only spam
from one particular bot, we don't care about that particular wierdness
enough to investigate further.  But it's worth being aware of.



Jared Johnson mailto:jjohn...@efolder.net
August 15, 2011 3:39 PM


Hi,

We got a bug report from someone using IBM's Lotus suite (I think for
both
their MUA and MTA). Their users would often send messages where all the
content was in the subject and they didn't bother sending any message
content. I'm not sure if it's due to an apparently uncommon behavior for
their particular MUA or their MTA, but every one of these messages was
coming through with data in a form that looked like this:

Subject: howdy\r\n.\r\n

Rather than including the blank line that one might expect to follow
headers, since it's required in the event that a message body is
present:

Subject: howdy\r\n\r\n.\r\n

The customer reported these messages were having their subjects
stripped;
additional testing indicted all existing headers were being stripped. It
looks like this is because the loop that processes message data in
Qpsmtpd::SMTP::data_respond() and creates a Mail::Header object which is
later used to write out the header in delivery, only works if a blank
line
exists after the header, e.g. the second form above. The following is
all
I could find in RFC 5322 that elaborated on this blank line, which
obviously must exist if a message body is included:

A message consists of header fields (collectively called the header
section of the message) followed, optionally, by a body. The header
section is a sequence of lines of characters with special syntax as
defined in this specification. The body is simply a sequence of
characters that follows the header section and is separated from the
header section by an empty line (i.e., a line with nothing preceding the
CRLF).

I read this as implicitly allowing the exclusion of this blank line if
there is no message body: the specification for the blank line is only
mentioned in the description of the body, which is itself described as
optional. Considering we haven't run into this bug in years of usage, I
assume it's unconventional to exclude the blank line, but it looks like
it
is legitimate syntax.

At any rate this was effecting multiple legitimate end users so we put
together the attached patch, which pulls the header building into its
own
sub which is then called inside the loop if we

Re: [PATCH] tweak QP's header handling for messages with no body

2011-08-16 Thread Matt Sergeant
Yup there's a lot of this 
going around right now. Just to be explicit though, the header lines end
 in \r\r\n. Worth rejecting the bloody lot, frankly :)








  
Chris LewisAugust 15, 2011 4:21 PM
  
  
As a FYI, I've been seeing bot-emitted spam that appears to have 
extra 
\r at the end of _all_ header lines, and the qpsmtpd parser seems to be 
treating all of it as part of the _body_. IOW: except for the received 
line inserted by qpsmtpd, qpsmtpd doesn't see _any_ headers.

This implementation is backrev (0.80 I think), and as it's only spam
 
from one particular bot, we don't care about that particular wierdness 
enough to investigate further. But it's worth being aware of.


  
Jared JohnsonAugust 15, 2011 3:39 PM
  
  Hi,We got a bug report from 
someone using IBM's Lotus suite (I think for boththeir MUA and MTA).
  Their users would often send messages where all thecontent was in 
the subject and they didn't bother sending any messagecontent.  I'm 
not sure if it's due to an apparently uncommon behavior fortheir 
particular MUA or their MTA, but every one of these messages wascoming



 through with data in a form that looked like this:"Subject: 
howdy\r\n.\r\n"Rather than including the blank line that one 
might expect to followheaders, since it's required in the event that
 a message body is present:"Subject: howdy\r\n\r\n.\r\n"The



 customer reported these messages were having their subjects stripped;additional



 testing indicted all existing headers were being stripped.  Itlooks
 like this is because the loop that processes message data inQpsmtpd::SMTP::data_respond()



 and creates a Mail::Header object which islater used to write out 
the header in delivery, only works if a blank lineexists after the 
header, e.g. the second form above.  The following is allI could 
find in RFC 5322 that elaborated on this blank line, whichobviously 
must exist if a message body is included:"A message consists of 
header fields (collectively called "the headersection of the 
message") followed, optionally, by a body.  The headersection is a 
sequence of lines of characters with special syntax asdefined in 
this specification.  The body is simply a sequence ofcharacters that
 follows the header section and is separated from theheader section 
by an empty line (i.e., a line with nothing preceding theCRLF)."I
 read this as implicitly allowing the exclusion of this blank line ifthere



 is no message body:  the specification for the blank line is onlymentioned



 in the description of the body, which is itself described asoptional.



  Considering we haven't run into this bug in years of usage, Iassume



 it's unconventional to exclude the blank line, but it looks like itis



 legitimate syntax.At any rate this was effecting multiple 
legitimate end users so we puttogether the attached patch, which 
pulls the header building into its ownsub which is then called 
inside the loop if we reach the blank lineindicating the header 
section is complete; otherwise, it's called outsideof the loop if we
 have no more message data, indicating the header sectionis 
complete.  Sorry I'm not putting this on a github fork, I still don'thave



 my git stuff together, I may never get around to it but I thought youguys



 might find this useful.-Jared








Re: [PATCH] tweak QP's header handling for messages with no body

2011-08-16 Thread Matt Sergeant
That line of code doesn't 
look at the headers though, just at the final dot at the end-of-data.


  
  
Jared JohnsonAugust 16, 2011 3:00 PM
  
  There's already a special case for 
something similar to this:# Reject messages that have either
 bare LF or CR. rjkaes noticed a# lot of spam that is malformed 
in the header.($_ eq ".\n" or $_ eq ".\r")and 
$self-respond(421, "Seehttp://smtpd.develooper.com/barelf.html")
and return $self-disconnect;you could just make it (
 /\r\r\n$/ or $_ eq ".\n" or $_ eq ".\r" ) maybe? and update the 
link to point to a URL that explains both?-Jared
  
Matt SergeantAugust 16, 2011 11:28 AM
  
  




Yup there's a lot of this 
going around right now. Just to be explicit though, the header lines end
 in \r\r\n. Worth rejecting the bloody lot, frankly :)















  
Chris LewisAugust 15, 2011 4:21 PM
  
  
As a FYI, I've been seeing bot-emitted spam that appears to have 
extra 
\r at the end of _all_ header lines, and the qpsmtpd parser seems to be 
treating all of it as part of the _body_. IOW: except for the received 
line inserted by qpsmtpd, qpsmtpd doesn't see _any_ headers.

This implementation is backrev (0.80 I think), and as it's only spam
 
from one particular bot, we don't care about that particular wierdness 
enough to investigate further. But it's worth being aware of.


  
Jared JohnsonAugust 15, 2011 3:39 PM
  
  Hi,We got a bug report from 
someone using IBM's Lotus suite (I think for boththeir MUA and MTA).
  Their users would often send messages where all thecontent was in 
the subject and they didn't bother sending any messagecontent.  I'm 
not sure if it's due to an apparently uncommon behavior fortheir 
particular MUA or their MTA, but every one of these messages wascoming
 through with data in a form that looked like this:"Subject: 
howdy\r\n.\r\n"Rather than including the blank line that one 
might expect to followheaders, since it's required in the event that
 a message body is present:"Subject: howdy\r\n\r\n.\r\n"The
 customer reported these messages were having their subjects stripped;additional
 testing indicted all existing headers were being stripped.  Itlooks
 like this is because the loop that processes message data inQpsmtpd::SMTP::data_respond()
 and creates a Mail::Header object which islater used to write out 
the header in delivery, only works if a blank lineexists after the 
header, e.g. the second form above.  The following is allI could 
find in RFC 5322 that elaborated on this blank line, whichobviously 
must exist if a message body is included:"A message consists of 
header fields (collectively called "the headersection of the 
message") followed, optionally, by a body.  The headersection is a 
sequence of lines of characters with special syntax asdefined in 
this specification.  The body is simply a sequence ofcharacters that
 follows the header section and is separated from theheader section 
by an empty line (i.e., a line with nothing preceding theCRLF)."I
 read this as implicitly allowing the exclusion of this blank line ifthere
 is no message body:  the specification for the blank line is onlymentioned
 in the description of the body, which is itself described asoptional.
  Considering we haven't run into this bug in years of usage, Iassume
 it's unconventional to exclude the blank line, but it looks like itis
 legitimate syntax.At any rate this was effecting multiple 
legitimate end users so we puttogether the attached patch, which 
pulls the header building into its ownsub which is then called 
inside the loop if we reach the blank lineindicating the header 
section is complete; otherwise, it's called outsideof the loop if we
 have no more message data, indicating the header sectionis 
complete.  Sorry I'm not putting this on a github fork, I still don'thave
 my git stuff together, I may never get around to it but I thought youguys
 might find this useful.-Jared



Re: thoughts about a new module called check_spammer_connect

2011-07-27 Thread Matt Sergeant

On Wed, 27 Jul 2011, Jared Johnson wrote:


That sounds like a pretty sweet configuration!


[Note if you are running qpsmtpd-async, as we do, it's not really
possible to route DNS queries differently for DNSBLs versus other DNS
queries qpsmtpd does.  ParaDNS doesn't handle paralleled DNS queries to
different servers well.]


when I first mucked around with the uribl plugin (see other threads), I
switched the non-async plugin to use Net::DNS::Async, but as far as I
could tell, N::D::A wasn't truly async, so I left the async plugin using
ParaDNS.  As it turns out, one of my associates since determined a way to
use Net::DNS::Async in a truly async fashion.  We're still using the
prefork daemon, but when we inevitably switch to async I'll probably try
to switch the async to N::D::A.  We also have a consolidated feed so the
multi-feed thing isn't too much of a concern, but N::D::A just seems more
straightforward.  If anyone is interested in switching to N::D::A now,
feel free to ping me and I can get the details on how to use it in a way
that doesn't break the true async plugin... I'm also curious if anyone
knows of reasons why this switch would not be such a good idea ;)


I have an XS version of ParaDNS too, which may be useful to people. It's 
in the ParaDNS subversion repository. We use it at work and it seems 
stable now.


However I'm unlikely to maintain much on Qpsmtpd now that Haraka has taken 
off.


Matt.


Re: thoughts about a new module called check_spammer_connect

2011-07-27 Thread Matt Sergeant

On Wed, 27 Jul 2011, David Nicol wrote:


On Wed, Jul 27, 2011 at 2:05 PM, Matt Sergeant m...@sergeant.org wrote:

However I'm unlikely to maintain much on Qpsmtpd now that Haraka has taken
off.

Matt.


how about a plugin adapter, so Haraka can use Qpsmtpd plugins or v/v?
That probably implies
either a node.js -- perl integration layer, a V8 -- perl
integration layer, or use of
a more arm's-length plugin architecture (like sendmail's Milter)
around both parts.


Haraka ships with both smtp_forward and smtp_proxy plugins (with tradeoffs 
for each), so there's no reason you wouldn't just run both, if you needed 
qpsmtpd plugins too.


Matt.


Re: [Fwd: Re: [Fwd: STARTTLS vulnerabilty and qmail-spamcontrol ucspi-ssl qpsmtpd]]

2011-06-07 Thread Matt Sergeant

Jared Johnson wrote:

I ... disagree.  From my reading of plugins/tls, it looks like there is
no problem at all, in the non-async code path.  It resets STDIN and
STDOUT to a socket created from scratch by the IO::Socket::SSL module.

I haven't looked at IO::Socket::SSL to see if it has this sort of
issue, but it seems unlikely to me.


Ah good news then. Hopefully someone will apply my pull request for that 
patch.


Matt.


Re: [Fwd: STARTTLS vulnerabilty and qmail-spamcontrol ucspi-ssl qpsmtpd]

2011-06-04 Thread Matt Sergeant
No takers? I do consider the bug fairly minor (it's not like a remote 
root or anything)... But still?


Matt Sergeant wrote:

I'm forwarding this to the list since I didn't get a response from Ask...

The problem here is when someone sends the following packet:

STARTTLS\nSOME_COMMAND\n

The SOME_COMMAND bit gets cached internally (in PollServer/async 
that's in $qp-{line}, but in the other implementations I have no idea 
what happens) and then because SSL upgrading happens in external 
libraries, they don't see these bits of data, so what then happens is 
ssl gets upgraded, but then SOME_COMMAND gets executed after SSL has 
been negotiated.


I'm pretty sure this is enough to fix it for async:

diff --git a/plugins/tls b/plugins/tls
index 37fbc9a..f850d2c 100644
--- a/plugins/tls
+++ b/plugins/tls
@@ -275,6 +275,7 @@ sub upgrade_socket {
 my UpgradeClientSSL $self = shift;

 unless ( $self-{_ssl_started} ) {
+$self-{_stashed_qp}-clear_data();
 IO::Socket::SSL-start_SSL(
 $self-{_stashed_qp}-{sock}, {
 SSL_use_cert = 1,

I've submitted a pull request for that.

But for the non-async scenario I think it's a lot more complex because 
the caching would be done at the C-level, so a fix more like the fix 
(posted below) for postfix is required (switch to non-blocking, get 
whatever data is remaining, flush it, switch back off non-blocking).


 Original Message 
From: Graham Todd gt...@iciti.ca
Subject: STARTTLS vulnerabilty and qmail-spamcontrol ucspi-ssl 
qpsmtpd

Date: Wed, 01 Jun 2011 15:03:51 -0400
To: m...@fehcom.de, ga...@freebsd.org, Matt Sergeant 
m...@sergeant.org




Hi I'm a user of the qpsmtpd and qmail-spamcontrol ports on FreeBSD
(ga...@freebsd.org is the qmail-spamcontrol port maintainer), thanks to
you all for making qmail even more excellent by integrating all the
patches and making it easy to build and install on FreeBSD and using perl
to make it as flexible as Apache ;-)

As I understand it STARTTLS support in qmail-spamcontrol is handled by
ucspi-ssl with TLS patches. We're currently using qpsmtpd which has a
plugin that wraps qmail with perl based support for STARTTLS (using
IO::Socket::SSL).

Does Wietse Venema's STARTTLS vulnerability impact the STARTTLS
enhancements used in ucspi-ssl, qpsmtpd or qmail-spamcontrol? The
vulnerability is described here:

http://www.securityfocus.com/bid/46767

There is a fairly simple patch that fixes the TLS vulnerability and
applies to netqmail-1.06-tls - I am wondering how the vulnerabilty might
effect TLS functions in qpsmtpd and qmail-spamcontrol. The patch for TLS
enhanced versions of vanilla qmail-1.03 is here:

http://marc.info/?l=qmail-ldapm=130564281418177w=2

There's a long list of spots to look for the vulnerability on the 
Security

Focus site but neither qpsmtpd nor ucspi-ssl-tls are mentioned.

Cheers,

gtodd 


[Fwd: STARTTLS vulnerabilty and qmail-spamcontrol ucspi-ssl qpsmtpd]

2011-06-02 Thread Matt Sergeant

I'm forwarding this to the list since I didn't get a response from Ask...

The problem here is when someone sends the following packet:

STARTTLS\nSOME_COMMAND\n

The SOME_COMMAND bit gets cached internally (in PollServer/async that's 
in $qp-{line}, but in the other implementations I have no idea what 
happens) and then because SSL upgrading happens in external libraries, 
they don't see these bits of data, so what then happens is ssl gets 
upgraded, but then SOME_COMMAND gets executed after SSL has been negotiated.


I'm pretty sure this is enough to fix it for async:

diff --git a/plugins/tls b/plugins/tls
index 37fbc9a..f850d2c 100644
--- a/plugins/tls
+++ b/plugins/tls
@@ -275,6 +275,7 @@ sub upgrade_socket {
 my UpgradeClientSSL $self = shift;

 unless ( $self-{_ssl_started} ) {
+$self-{_stashed_qp}-clear_data();
 IO::Socket::SSL-start_SSL(
 $self-{_stashed_qp}-{sock}, {
 SSL_use_cert = 1,

I've submitted a pull request for that.

But for the non-async scenario I think it's a lot more complex because 
the caching would be done at the C-level, so a fix more like the fix 
(posted below) for postfix is required (switch to non-blocking, get 
whatever data is remaining, flush it, switch back off non-blocking).


 Original Message 
From:   Graham Todd gt...@iciti.ca
Subject:STARTTLS vulnerabilty and qmail-spamcontrol ucspi-ssl qpsmtpd
Date:   Wed, 01 Jun 2011 15:03:51 -0400
To: m...@fehcom.de, ga...@freebsd.org, Matt Sergeant m...@sergeant.org



Hi I'm a user of the qpsmtpd and qmail-spamcontrol ports on FreeBSD
(ga...@freebsd.org is the qmail-spamcontrol port maintainer), thanks to
you all for making qmail even more excellent by integrating all the
patches and making it easy to build and install on FreeBSD and using perl
to make it as flexible as Apache ;-)

As I understand it STARTTLS support in qmail-spamcontrol is handled by
ucspi-ssl with TLS patches. We're currently using qpsmtpd which has a
plugin that wraps qmail with perl based support for STARTTLS (using
IO::Socket::SSL).

Does Wietse Venema's STARTTLS vulnerability impact the STARTTLS
enhancements used in ucspi-ssl, qpsmtpd or qmail-spamcontrol? The
vulnerability is described here:

http://www.securityfocus.com/bid/46767

There is a fairly simple patch that fixes the TLS vulnerability and
applies to netqmail-1.06-tls - I am wondering how the vulnerabilty might
effect TLS functions in qpsmtpd and qmail-spamcontrol. The patch for TLS
enhanced versions of vanilla qmail-1.03 is here:

http://marc.info/?l=qmail-ldapm=130564281418177w=2

There's a long list of spots to look for the vulnerability on the Security
Focus site but neither qpsmtpd nor ucspi-ssl-tls are mentioned.

Cheers,

gtodd




Re: smtp proxy to external smtp server

2011-05-19 Thread Matt Sergeant

What do you mean by signed?

Do you mean like adding a banner to the text parts of the email? If so, 
that's a really hard problem (I mean it's doable in simple situations, 
but breaks very very easily).


Mike Korizek wrote:

On 05/17/2011 04:24 PM, Matt Sergeant wrote:
   

It can be done, but you'll need to customise the smtp-forward plugin
yourself to do it.
 

I checked the transaction object, I could not find a handle to the message.
How can I achieve the following:
An email shall be signed and then put back to the queue.
Before signing the email I parse it with a MIME::Parser, but how can I
put the new email back to the queue?
Thanks for any hint.
Mike

   


Re: smtp proxy to external smtp server

2011-05-17 Thread Matt Sergeant

Aleksandar Lazic wrote:

Just for my curiosity, why don't you use

qpsmtpd::smtp-forward =Any MTA Setup (postfix,courier,qmail, ...)? 


It's not sender dependent, and doesn't pass on AUTH. (but would be 
easily hackable to do that).


Announce: Haraka

2011-03-12 Thread Matt Sergeant

Some of you may be interested in this...

I decided I wanted to hack on node.js to see what all the fuss is about.

So to do that I have basically ported Qpsmtpd to Node.js (and given it a 
decent name while doing so!).


It's still early days - there are no plugins to speak of yet (i.e. no 
queue plugins at all yet), but you might be interested in just looking 
anyway:


https://github.com/baudehlo/Haraka


Re: Announce: Haraka

2011-03-12 Thread Matt Sergeant

Guy Hulbert wrote:

  https://github.com/baudehlo/Haraka
 


Had a look.  I recognize bits.  Do you have any feeling for how easy it
is to code versus perl


Once you get used to the idiosyncrasies of Javascript, just as easy 
really. Took me a while to understand the object model, but everything 
seems to work ok now I mostly figured it out.


There's still stuff I have no idea how to do (the lack of caller 
telling me line numbers is annoying for example), but I'm getting there.


The other big thing is the libraries are simultaneously both sparse and 
weak. There's a CPAN equivalent (called npm) but it's still very 
immature in terms of what's available. Even the core libraries are 
missing some fundamental stuff (like I can't do TLS as they removed 
support for upgrading a single client connection to TLS).



  and how the performance might be versus qpsmtpd.
   


It pretty much blows it away. Node can be pretty much as fast as a lisp 
or smalltalk implementation. All that research into dynamic languages is 
all going into Javascript these days, and none is going into perl (some 
is going into Python and Ruby, but not as much as JS). So I think it 
will always be quite a bit faster.


For reference I can (albeit without plugins) throw about 5000 mails/sec 
through it fairly easily it seems, though that's with persistent 
connections, and on localhost.


Performance was my main motivation for doing it.

The other thing is that everyone doing node.js is doing event 
programming, so all those libraries for database access and 
memcached/redis access and so on are all async already.


Matt.


Re: check_badrcptto, to prevent backscatter

2011-03-10 Thread Matt Sergeant

Should we have plugins/qmail and plugins/postfix dirs?

Todd Brunhoff wrote:
 Tim's view seems appropriate. His script is centered on qmail, and 
mine is centered on postfix (or more specifically, on /etc/aliases). 
Both scripts are probably best in their current form with appropriate 
disclosures. Let me know if there is any prep work you would like me 
to do to my script.


Todd

On 3/9/2011 7:23 AM, Tim Meadowcroft wrote:

On Sunday 06 March 2011 06:42:50 Robert Spier wrote:

Todd Brunhoff wrote:

   Your scripts look like they have a good deal of qmail
   sophistication. Some years ago I ran qmail 1.0.3, after each major
   system crash, I would revisit whether to use qmail, and eventually
   decided to switch to qpsmtp+postfix because both seem to have 
better

   support.  And in fact, the reason I included /etc/alias was to
   replace the very useful alias mechanism in qmail. I really didn't
   need much, so that was sufficient for me.

So it seems that among these collections of scripts there are
backscatter solutions for qmail sites and qpsmtp sites. Perhaps one of
the developers can fold these into a contrib folder? 

A lot of plugins are linked from the wiki, http://wiki.qpsmtpd.org.

check_goodrcptto looks like something that might be worth having in
core.  Tim and Todd, are you interested in reconciling the differences
between your versions?  (Maybe some sort of configuration interface?) 
Mine is very qmail specific - I sort of feel generalising it would 
make it
worse. Either you use qmail, in which case you might like it as it 
stands,
(possibly in addition to other recipient checks) or you don't use 
qmail, in

which case you can ignore it completely.

I've posted the source (with disclaimers - I'm still on qpsmtpd 
v0.28) at


   http://schmerg.com/checkgoodrcptto-a-qpsmtpd-plugin-for-checking

and will see about adding it to the wiki when I can set up an account 
there.


Cheers

--
Tim 


Re: rolling uribl and rbl plugins into a single plugin

2011-01-27 Thread Matt Sergeant

Jared Johnson wrote:

So our organization is planning doing some big changes to the rbl plugin
and it dawned on us that it seems a lot easier to just add an earlier hook
to the existing uribl plugin (and rename it to rbl?  or bl? or
something?).  But of course I still have in mind that someday I'll get the
plugin completely in shape and it will be in QP, and we'll get to share
code and all.  Would this be an undesirable direction to take the uribl
plugin in for QP proper, in the event that the uribl plugin was integrated
into QP proper?  It seems like it would be handy in terms of both code
organization and features (the main feature I can think of is proper mask
evaluation along with custom actions per mask, just like in the uribl
plugin).

Thoughts?
   
I'd much prefer they both used plugin inheritance to access shared code 
than have them merged.


Re: rctpto rejection based on smtp verify?

2011-01-14 Thread Matt Sergeant

Charlie Brady wrote:

On Fri, 14 Jan 2011, Nicholas Lee wrote:
   

Is there a plugin that will check rcpt addresses against a back end smtp
server?
 


I presume you intend to eventually deliver to the same smtp backend, via
the smtp-forward plugin.

I've long argued that the smtp-forward plugin should hook into different
phases of the transaction, and do the recipient validation directly
against the backend:

http://www.nntp.perl.org/group/perl.qpsmtpd/2008/11/msg8288.html
   


I think it should be optional, but yeah. There are downsides (such as 
keeping open the SMTP connection with the backend), but it'd be nice if 
you could choose.


Matt.


Re: AnyEvent mode?

2010-12-07 Thread Matt Sergeant

Aleksandar Lazic wrote:

On Mon 06.12.2010 16:34, Matt Sergeant wrote:

Aleksandar Lazic wrote:

Do you have benchmarked it with smtpstone from postfix or some other
tools? 


I just threw it on our spamtrap which does approx 50m emails/day. 


Do you really mean 50 Million?


Yes.

Wow that's a lot ;-) 


Not compared to another qpsmtpd spam trap I know of it's not. :-)

Matt.


Re: AnyEvent mode?

2010-12-06 Thread Matt Sergeant

Aleksandar Lazic wrote:

Do you have benchmarked it with smtpstone from postfix or some other
tools? 


I just threw it on our spamtrap which does approx 50m emails/day.


Re: AnyEvent mode?

2010-12-03 Thread Matt Sergeant

On Thu, 2 Dec 2010, Aleksandar Lazic wrote:


On Don 02.12.2010 19:04, Matt Sergeant wrote:

On Thu, 2 Dec 2010, Ask Bjørn Hansen wrote:



On Dec 2, 2010, at 10:37, Aleksandar Lazic wrote:


Maybe we can make another benchmark AnyEvent vs  Danga::Socket due to
the fact that AnyEvent with EV as underlaying event lib looks very fast
from the internet source ;-)


Matt was (I'm guessing) testing a load that's artificial to anyone who's 
not just archiving spam from a spam trap.  For the rest of us by far most 
of the resources go to the various spam filtering stuff, so the 
performance will be fine.


More important is the ease of use of the APIs, the general eco system etc. 
On those AnyEvent wins (in my opinion).


Sorry yeah I think I have it working, but our work data centre is down
right now so I can't get at the files :-(

Will email the latest ones here when I get the chance.


Thanks, I'am quite interested.


OK, the relevant files are attached. Nothing else needed changing I don't 
think.


AnyEvent.pm has to go in the lib/Qpsmtpd/ dir.#!/usr/bin/perl

use lib ./lib;
BEGIN {
delete $ENV{ENV};
delete $ENV{BASH_ENV};
$ENV{PATH} = '/bin:/usr/bin:/var/qmail/bin:/usr/local/bin';
}

# Profiling - requires Devel::Profiler 0.05
#BEGIN { $Devel::Profiler::NO_INIT = 1; }
#use Devel::Profiler;

use strict;
use vars qw($DEBUG);
use FindBin qw();
# TODO: need to make this taint friendly
use lib $FindBin::Bin/lib;
use Qpsmtpd::AnyEvent;
use Qpsmtpd::ConfigServer;
use Qpsmtpd::Constants;
use Carp;
use POSIX qw(WNOHANG);
use Getopt::Long;
use List::Util qw(shuffle);
use Socket;
use AnyEvent::Socket;
use AnyEvent::Util;

$|++;

$SIG{'PIPE'} = IGNORE;  # handled manually

$DEBUG  = 0;

my $PORT= 2525;
my $LOCALADDR   = '0.0.0.0';
my $PROCS   = 1;
my $USER= (getpwuid $)[0]; # user to suid to
   $USER= smtpd if $USER eq root;
my $PAUSED  = 0;
my $NUMACCEPT   = 20;
my $PID_FILE= '';
my $ACCEPT_RSET;
my $DETACH;   # daemonize on startup

# make sure we don't spend forever doing accept()
use constant ACCEPT_MAX = 1000;

sub reset_num_accept {
$NUMACCEPT = 20;
}

sub help {
print EOT;
Usage:
qpsmtpd [OPTIONS]

Options:
 -l, --listen-address addr : listen on a specific address; default 0.0.0.0
 -p, --port P  : listen on a specific port; default 2525
 -u, --user U  : run as a particular user; defualt 'smtpd'
 -j, --procs J : spawn J processes; default 1
 -d, --detach  : detach from controlling terminal (daemonize)
 --pid-file P  : print main servers PID to file P
 
 -h, --help: this page
EOT
exit(0);
}

GetOptions(
'p|port=i'  = \$PORT,
'l|listen-address=s'= \$LOCALADDR,
'j|procs=i' = \$PROCS,
'v|verbose+'  = \$DEBUG,
'u|user=s'  = \$USER,
'pid-file=s'= \$PID_FILE,
'd|detach'  = \$DETACH,
'h|help'= \help,
) || help();

# detaint the commandline
if ($PORT =~ /^(\d+)$/) { $PORT = $1 } else { help }
if ($LOCALADDR =~ /^([\d\w\-.]+)$/) { $LOCALADDR = $1 } else { help }
if ($USER =~ /^([\w\-]+)$/) { $USER = $1 } else { help }
if ($PROCS =~ /^(\d+)$/) { $PROCS = $1 } else { help }

use constant READY  = 1;
use constant ACCEPTING  = 2;
use constant RESTARTING = 999;

my $CURRENT_PROCS = 0;
my %childstatus = ();
my $SERVER;

if ($PID_FILE  -r $PID_FILE) {
open PID, $PID_FILE
or die open_pidfile $PID_FILE: $!\n;
my $running_pid = PID || ''; chomp $running_pid;
if ($running_pid =~ /^(\d+)/) {
if (kill 0, $running_pid) {
die Found an already running qpsmtpd with pid $running_pid.\n;
}
}
close(PID);
}

run_as_server();

exit(0);

sub spawn_child {
my ($plugin_loader) = @_;

my $pid = fork;

if ($pid) {
$childstatus{$pid}++;
$CURRENT_PROCS++;
return $pid;
}
elsif (!defined($pid)) {
die Unable to fork;
}

$plugin_loader-run_hooks('post-fork');

accept_loop();
}

sub accept_loop {
my $w = AE::io $SERVER, 0, sub {
print Connect?\n;
while ($SERVER  (my $peer = accept my $fh, $SERVER)) {
 fh_nonblocking $fh, 1; # POSIX requires inheritance, the outside 
world does not

 my ($service, $host) = AnyEvent::Socket::unpack_sockaddr $peer;
 my $qp = Qpsmtpd::AnyEvent-new($fh, format_address($host), 
$service);
 $qp-process_line(Connect);
  }
};

AnyEvent-condvar-wait;
exit;
}

sub sig_hup {
kill 1, keys %childstatus;
}

sub sig_chld {
my $spawn_count = 0;
while ( (my $child = waitpid(-1,WNOHANG))  0) {
if (!defined $childstatus{$child}) {
next;
}

last unless $child  0;
print SIGCHLD: child $child died\n;
delete $childstatus{$child};
$CURRENT_PROCS--;
}

$SIG

Re: Exim alternatives?

2010-09-14 Thread Matt Sergeant
I once wrote a very simple perl module which basically did outbound mail 
queueing for very simple needs... But then I discovered my needs were a 
bit more complex. LOL...


I second Ask's question - what's wrong with using exim?

David Favor wrote:

I'm looking for a simple alternative to exim, sendmail, postfix
for outgoing email.

So when and email comes into qpsmtpd which forwards offsite,
an outgoing mail server to forward these email.

If someone has a suggestion about other options, please let
me know.

Thanks. 


Re: Exim alternatives?

2010-09-14 Thread Matt Sergeant

On Tue, 14 Sep 2010, David Favor wrote:


The problem is two fold.

1) I could never get a straight answer about the correct
  configuration from the exim folks.

2) The config I have works for weeks to months, then develops
  odd (bitrot) challenges which seem to relate to DNS MX server
  changes in domains, which exim never senses.

  For example, message is queued and can't reach an MX record,
  then continually tries the bad MX record, never attempting
  to look up a new record.

I'm switching back to TipJar::MTA to do some testing.

What I require is a simple system, preferably perl based, so it's
fairly easy to understand + configure... that simply works... all
the time... no fuss, no muss.


OK... try my MrQueue stuff:

svn co svn://axkit.org/MrQueue

(axkit.org is having a bit of trouble resolving right now, so try 
sergeant.org if that doesn't work - same host).


Matt.


Re: Rewritten URIBL plugin

2010-07-29 Thread Matt Sergeant

Jared Johnson wrote:

sub parse_mime {


That works, only this should be called parsed_mime because you're 
asking for the parsed bit, not telling it to parse (every time).


Matt.


Re: Rewritten URIBL plugin

2010-07-27 Thread Matt Sergeant

On Sun, 25 Jul 2010, Jared Johnson wrote:


The plugin has the following advantages over the original:

- Uses MIME::Parser to unpack message text so that we can look for URI's
in base64-encoded data, etc., and _not_ look for URI's in noise.


I think we should probably consider putting support for parsed messages 
into core, with the parsing done lazily if requested by the API.


Thoughts?

Matt.


Re: Redirecting email

2010-05-13 Thread Matt Sergeant

Chris Lewis wrote:


The version I've derived from Steve's works during hook_rcpt.


Yes, but assigning to $_[0] is a horrible way to do it. We should have a 
supported and cleaner way to modify the email address at RCPT TO time...


Ah, we do have a supported way... a hook called rcpt_pre which returns 
OK, $new_address (with angle brackets).


Given the way my qpsmtpd works, hook_data is way way too late.  Too 
much has already been decided by that point. 


I don't mean data_post - I mean right on the DATA command, which happens 
immediately after the RCPT TOs in a normal SMTP transaction... But then 
see above for the right solution.


Matt.


spool files not temp?

2010-04-14 Thread Matt Sergeant

Hi,

Can anyone remember the reason that the spool files aren't proper temp 
files (deleted upon open)? We often end up with a hard restart of qpsmtpd 
and having these files left around is annoying...


Matt.


Re: I am probably doing something wrong

2010-04-05 Thread Matt Sergeant

Steve wrote:
  
  Note that qpsmtpd probably should reject the message as invalid format. If

  it doesn't do that in the core, at least a standard plugin should do that
  validation.

 

The message is not rejected. Anyway... what plugin is doing the validation? Can 
you point me to the plugin doing such a validation?


There isn't one. Charlie is saying there should be such a plugin.

Though honestly it should probably be in core not a plugin.

Matt.


Re: New plugin: smtptls-forward

2010-03-30 Thread Matt Sergeant

On Tue, 30 Mar 2010, Charlie Brady wrote:


On Thu, 25 Mar 2010, Jason Mills wrote:


I wrote this plugin to help me with my local debugging.
Basically a heavily modified version of smtp-foward.


I'd recommend you search the archives and find some earlier comments by me 
about smtp-forward. It really should be rewritten to hook into more than just 
the queue hook, and pass sender and recipient addresses to the backend as 
they are provided by the connecting client, and relay responses back to the 
client.


I think some people might not want that, as they want to reduce the load 
on their main SMTP server... I agree it should be an option though. 
Perhaps we need queue/smtp-passthru.


Matt.


ParaDNS 2.0 - now does dns0x20

2010-02-26 Thread Matt Sergeant
dns0x20 protects against things like the Kaminsky DNS attack by vastly 
increasing the size of the keyspace for DNS requests.


It's enabled by default in ParaDNS 2.0. You can disable with an env var.

Matt.


Re: Release soon

2010-02-16 Thread Matt Sergeant

On Fri, 12 Feb 2010, Ask Bjørn Hansen wrote:


Hi everyone,

I'm going to make a release soon, so if you have patches that aren't merged 
into my branch yet that you think should be, be sure to speak up!

I just merged the RPM packaging stuff Peter Holzer and Robin Bowes made (over 
the last 5 years; don't say anything is being rushed around here!)  :-)

The shortlog since the last release (so far) is below.


I have the AnyEvent version of Qpsmtpd working if people are interested in 
getting it added to core... It's slower than the Danga::Socket version 
though.


Matt.

Re: badmailfrom per domain

2010-01-22 Thread Matt Sergeant

Johan Almqvist wrote:

On 21. jan. 2010, at 16.57, Christian Herndler wrote:
   

I get a lot of spam where the sender uses a whole /24 Subnet as mail
relay, the helo uses the pattern

mx{last-octet-of-ip}.domainname.net

so it could be blocked using the check_spamhelo plugin, but to do that
this plugin would need a small change as it only works with hostnames.
 


I've had a similar problem at the MAIL FROM level (right-hand side VERP, you 
could say) and fixed this with this plugin:

http://github.com/tyskjohan/qpsmtpd/blob/master/plugins/check_badmailfrom_patterns

   

Also consider using Enemies List on the HELO. It's very effective.


ParaDNS 1.9 out

2009-12-14 Thread Matt Sergeant
This fixes a major bug when under high load causing overly quick timeouts 
for some requests. Recommended upgrade.


(only used by those using -async)

Matt.


Re: AnyEvent mode?

2009-11-24 Thread Matt Sergeant
OK, here's the files as they currently stand. The big note on this is that 
I have done very little testing, and most importantly I have NOT updated 
any of the plugins (see the async/* dir for those that need re-written to 
use AnyEvent, mostly to use AnyEvent::DNS. Also the tls plugin would 
need updated/rewritten, though it's probably a lot simpler with AnyEvent).


I'll be trying to do performance testing tomorrow (comparing with 
qpsmtpd-async, NOT any of the other models).


Matt.#!/usr/bin/perl

use lib ./lib;
BEGIN {
delete $ENV{ENV};
delete $ENV{BASH_ENV};
$ENV{PATH} = '/bin:/usr/bin:/var/qmail/bin:/usr/local/bin';
}

# Profiling - requires Devel::Profiler 0.05
#BEGIN { $Devel::Profiler::NO_INIT = 1; }
#use Devel::Profiler;

use strict;
use vars qw($DEBUG);
use FindBin qw();
# TODO: need to make this taint friendly
use lib $FindBin::Bin/lib;
use Qpsmtpd::AnyEvent;
use Qpsmtpd::ConfigServer;
use Qpsmtpd::Constants;
use Carp;
use POSIX qw(WNOHANG);
use Getopt::Long;
use List::Util qw(shuffle);
use Socket;
use AnyEvent::Socket;
use AnyEvent::Util;

$|++;

$SIG{'PIPE'} = IGNORE;  # handled manually

$DEBUG  = 0;

my $PORT= 2525;
my $LOCALADDR   = '0.0.0.0';
my $PROCS   = 1;
my $USER= (getpwuid $)[0]; # user to suid to
   $USER= smtpd if $USER eq root;
my $PAUSED  = 0;
my $NUMACCEPT   = 20;
my $PID_FILE= '';
my $ACCEPT_RSET;
my $DETACH;   # daemonize on startup

# make sure we don't spend forever doing accept()
use constant ACCEPT_MAX = 1000;

sub reset_num_accept {
$NUMACCEPT = 20;
}

sub help {
print EOT;
Usage:
qpsmtpd [OPTIONS]

Options:
 -l, --listen-address addr : listen on a specific address; default 0.0.0.0
 -p, --port P  : listen on a specific port; default 2525
 -u, --user U  : run as a particular user; defualt 'smtpd'
 -j, --procs J : spawn J processes; default 1
 -d, --detach  : detach from controlling terminal (daemonize)
 --pid-file P  : print main servers PID to file P
 
 -h, --help: this page
EOT
exit(0);
}

GetOptions(
'p|port=i'  = \$PORT,
'l|listen-address=s'= \$LOCALADDR,
'j|procs=i' = \$PROCS,
'v|verbose+'  = \$DEBUG,
'u|user=s'  = \$USER,
'pid-file=s'= \$PID_FILE,
'd|detach'  = \$DETACH,
'h|help'= \help,
) || help();

# detaint the commandline
if ($PORT =~ /^(\d+)$/) { $PORT = $1 } else { help }
if ($LOCALADDR =~ /^([\d\w\-.]+)$/) { $LOCALADDR = $1 } else { help }
if ($USER =~ /^([\w\-]+)$/) { $USER = $1 } else { help }
if ($PROCS =~ /^(\d+)$/) { $PROCS = $1 } else { help }

use constant READY  = 1;
use constant ACCEPTING  = 2;
use constant RESTARTING = 999;

my $CURRENT_PROCS = 0;
my %childstatus = ();
my $SERVER;

if ($PID_FILE  -r $PID_FILE) {
open PID, $PID_FILE
or die open_pidfile $PID_FILE: $!\n;
my $running_pid = PID || ''; chomp $running_pid;
if ($running_pid =~ /^(\d+)/) {
if (kill 0, $running_pid) {
die Found an already running qpsmtpd with pid $running_pid.\n;
}
}
close(PID);
}

run_as_server();

exit(0);

sub spawn_child {
my ($plugin_loader) = @_;

my $pid = fork;

if ($pid) {
$childstatus{$pid}++;
$CURRENT_PROCS++;
return $pid;
}
elsif (!defined($pid)) {
die Unable to fork;
}

$plugin_loader-run_hooks('post-fork');

accept_loop();
}

sub accept_loop {
my $w = AE::io $SERVER, 0, sub {
print Connect?\n;
while ($SERVER  (my $peer = accept my $fh, $SERVER)) {
 fh_nonblocking $fh, 1; # POSIX requires inheritance, the outside 
world does not

 my ($service, $host) = AnyEvent::Socket::unpack_sockaddr $peer;
 my $qp = Qpsmtpd::AnyEvent-new($fh, format_address($host), 
$service);
 $qp-process_line(Connect);
  }
};

AnyEvent-condvar-wait;
exit;
}

sub sig_hup {
kill 1, keys %childstatus;
}

sub sig_chld {
my $spawn_count = 0;
while ( (my $child = waitpid(-1,WNOHANG))  0) {
if (!defined $childstatus{$child}) {
next;
}

last unless $child  0;
print SIGCHLD: child $child died\n;
delete $childstatus{$child};
$CURRENT_PROCS--;
}

$SIG{CHLD} = \sig_chld;
}

sub HUNTSMAN {
$SIG{CHLD} = 'DEFAULT';
kill 'INT' = keys %childstatus;
if ($PID_FILE  -e $PID_FILE) {
unlink $PID_FILE or ::log(LOGERROR, unlink: $PID_FILE: $!);
}
exit(0);
}

sub _connect_sock {
my $ipn = parse_address($LOCALADDR) or die cannot parse '$LOCALADDR' as 
host address;

my $af = address_family $ipn;

socket(my $sock, $af, SOCK_STREAM, 0) or die socket: $!;
setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, 1)
or die tcp_server/so_reuseaddr: $!;

bind $sock, 

AnyEvent mode?

2009-11-23 Thread Matt Sergeant
Is anyone interested in an AnyEvent mode Qpsmtpd? I have the code written 
(mostly hacked right now, but should work).


In theory it might be faster than the Danga::Socket based one, and 
AnyEvent seems to receive regular updates more than Danga::Socket these 
days.


Matt.


Re: AnyEvent mode?

2009-11-23 Thread Matt Sergeant

On Mon, 23 Nov 2009, Ask Bjørn Hansen wrote:



On Nov 23, 2009, at 11:41, Matt Sergeant wrote:


Is anyone interested in an AnyEvent mode Qpsmtpd? I have the code written 
(mostly hacked right now, but should work).

In theory it might be faster than the Danga::Socket based one, and AnyEvent 
seems to receive regular updates more than Danga::Socket these days.


There are also more other stuff available with AnyEvent -- I think it'd be 
cool!


OK. How do I get this to you? It's basically just two new files, no 
patches to anything.


Matt.

Re: Language detection?

2009-11-09 Thread Matt Sergeant

On Sat, 7 Nov 2009, Johan Almqvist wrote:


Hi

On 5. nov. 2009, at 16.33, Matt Sergeant wrote:

Anyone got a language detection plugin? I get a lot of spam slipping 
through in spanish, and I'd like to just whack it on the head.


There's 
http://spamassassin.apache.org/full/3.1.x/doc/Mail_SpamAssassin_Plugin_TextCat.html 
but not sure if that's what you want.


Yeah there's plenty of ways to do it. Textcat being one of them. Google 
also has an API for language detection which is pretty good. I just 
wondered if anyone had anything pre-rolled for qpsmtpd.


Matt.


Re: [PATCH] Log even when we aren't in a transaction

2009-08-24 Thread Matt Sergeant
On Mon, 24 Aug 2009 09:55:52 -0500, Jared Johnson wrote:
 On 08/23/2009 04:03 PM, Matt Sergeant wrote:
 On Thu, 20 Aug 2009 10:18:39 -0500, Jared Johnson wrote:
 It looks like logging/file doesn't like the empty hashref returned by
 Qpsmtpd::transaction().
 
 I never understood why it did that. Any reason it can't return either
 undef or (preferably) a new Transaction object?
 
 I don't really understand it either, and I fear that which I don't 
 understand, so I worry about taking it out and breaking some hackage 
 that depends no it :)

Yeah agreed. I think it'd be worth checking with Ask why he made it 
this way.


Re: [PATCH] Log even when we aren't in a transaction

2009-08-23 Thread Matt Sergeant
On Thu, 20 Aug 2009 10:18:39 -0500, Jared Johnson wrote:
 It looks like logging/file doesn't like the empty hashref returned by 
 Qpsmtpd::transaction().

I never understood why it did that. Any reason it can't return either 
undef or (preferably) a new Transaction object?


Re: qpsmtpd-async authenticated relaying direction request

2009-05-31 Thread Matt Sergeant

On Sat, 30 May 2009, Baltasar Cevc wrote:


On May 28, 2009, at 4:37 PM, Matt Sergeant wrote:

Seems a little fragile. There aren't many bounces that quote all

headers. You'd be better off just rejecting all bounces in qpsmtpd,
then you only see legit bounces where the remote end issued an
immediate 5xx to your Exim's outgoing mail. Of course when I suggest
that (here and on other lists) mail admins tend to freak out a bit. But
I'm of the opinion that I've barely ever seen a useful full bounce in
years. So my qpsmtpd runs a no_bounces plugin, which I believe I've
posted here before.


While I would not freak out, it is surely not RFC conformant. And, even
worse, it is illegal in some legislations (I can tell for Germany):
suppressing mails (thus also failure notices that made sure the sender
knows a mail has not arrive) is punishable under the German Criminal
Code.


That's a major misunderstanding of both the RFCs and German law.


However, I think everybody should descide himself/herself.


Indeed.


I notice 'broken' systems that will send bounces instead of rejecting
mail from time to time...


I'm not suggesting there aren't. But as far as I can tell, there's 3 
options:


1) accept all bounces, and get flooded with invalid bounces when spammers 
spoof you.


2) implement BATV and the flaws it has.

3) reject all SMTP level bounces and the flaws it has.

All have problems. You just pick your acceptable failures.

Matt.


Re: qpsmtpd-async authenticated relaying direction request

2009-05-28 Thread Matt Sergeant
On Wed, 27 May 2009 09:18:32 -0500, David Favor wrote:
 I'm currently running qpsmtpd-async.
 
 I host many domains and I'd like to protect them all
 against backscatter using something like this:
 
 http://psg.com/~brian/software/authbounce/configure-authbounce.txt
 
 to add a bounce key to each outgoing message of the form:
 
 X-bounce-key: $mx-$number;$sender;$timestamp;$key
 
 This requires all mail sent by every user to go through
 qpsmtpd + exim on my local machine.

Seems a little fragile. There aren't many bounces that quote all 
headers. You'd be better off just rejecting all bounces in qpsmtpd, 
then you only see legit bounces where the remote end issued an 
immediate 5xx to your Exim's outgoing mail. Of course when I suggest 
that (here and on other lists) mail admins tend to freak out a bit. But 
I'm of the opinion that I've barely ever seen a useful full bounce in 
years. So my qpsmtpd runs a no_bounces plugin, which I believe I've 
posted here before.

Matt.


Re: qpsmtpd-async authenticated relaying direction request

2009-05-28 Thread Matt Sergeant
On Thu, 28 May 2009 12:04:27 -0400 (EDT), Charlie Brady wrote:
 
 On Thu, 28 May 2009, Matt Sergeant wrote:
 
 years. So my qpsmtpd runs a no_bounces plugin, which I believe I've
 posted here before.
 
 Google seems not to have heard of it.

Ah. OK. It basically just does this:

  if ($transaction-sender-format eq 
  or
  $transaction-sender-format =~ /MAILER-DAEMON/i
  or
  $transaction-sender-format =~ /postmaster\@/i
  )
  {
unless (grep { /(bounce-|-return-)/ } map { $_-address} 
$transaction-recip
ients) {
  return DENY, Mail from  not accepted here;
}
  }


Re: Feature request to disable CONTROL_PORT

2009-05-27 Thread Matt Sergeant

On Wed, 27 May 2009, David Favor wrote:


Having qpsmtpd listen on an additional control port
creates serious complexity when running multiple
copies of qpsmtpd, as each copy has to somehow figure
out which control port to use, hope it's free and then
connect.

I usually just strip this code out of qpsmtpd or
comment out the initial connection.

A great feature to add is a simple command line option
to turn this off.


Yeah, this is only on -async anyway. I'm wondering if we should just dump 
the feature, since it doesn't work when having multiple async children.


Matt.


Re: [qpsmtpd] Still looking: tcpserver startup for qpsmtpd-prefork 0.81

2009-05-21 Thread Matt Sergeant

On Thu, 21 May 2009, Devin Carraway wrote:


On Wed, May 20, 2009 at 09:40:21PM -0400, Charlie Brady wrote:

I think the -T *should* be there on the command line, but there are some
bugs in qpsmtpd and/or your plugins which need to be fixed before it will
work.


forkserver has used -T since 29ac2860, back in 2004.  Obviously prefork is
newer and has seen less testing, but most of the module code and plugins have
seen plenty of taint-checked use.


I guess this raises a question: The return values from config() are 
tainted. Should we de-taint them?


Matt.


Re: [qpsmtpd] Still looking: tcpserver startup for qpsmtpd-prefork 0.81

2009-05-20 Thread Matt Sergeant

On Wed, 20 May 2009, J wrote:


I compared the run file with other run files (i.e. djbdns and qmail) and I
think the problem is with the trailing ' \' on the 2nd line (the first
exec).


Indeed. That shouldn't be there.


When I remove that (and installed a missing Math::BigInt package from
CPAN), everything loads, but complains about an insecure dependency on
line 416 in setpriority (in qpsmtpd-prefork). (And the prefork processes
keep showing up in the process table, and dying.) I expect that this was
tested before being released, so there is probably still something wrong
with my setup :-(


I think the -T shouldn't be there on the command line. Though it is 
probably a bug, I'm guessing we don't test with taint on.


Matt.


Re: [qpsmtpd] Still looking: tcpserver startup for qpsmtpd-prefork 0.81

2009-05-20 Thread Matt Sergeant

On Wed, 20 May 2009, Charlie Brady wrote:


Though it is probably a bug, I'm guessing we don't test with taint on.


Perl taint mode is an underutilised gem.


It is, but it's also buggy and annoying.

(there's a completely ignored bug in perl with -T and hash keys which I 
filed months ago)


Matt.


Re: [qpsmtpd] Still looking: tcpserver startup for qpsmtpd-prefork 0.81

2009-05-20 Thread Matt Sergeant

On Wed, 20 May 2009, David Nicol wrote:


On Wed, May 20, 2009 at 10:28 PM, Matt Sergeant m...@sergeant.org wrote:


(there's a completely ignored bug in perl with -T and hash keys which I
filed months ago)



that hash keys are never tainted is documented, if that's your bug.  It
allows for a quick and dirty

  sub detaint($){ [ keys %{{ $_[0] = 1 }} ] - [0] }


Nope. #56842. Very annoying.

Matt.


Re: perltidy

2009-04-03 Thread Matt Sergeant
On Fri, 3 Apr 2009 08:38:59 -0500, Jared Johnson wrote:
 first of all, kudos on the frequent releasing :)
 
 I've attached a suggested patch to .perltidyrc.  I've been playing 
 around with perltidy'ing all QP code and some results I don't like. 
 This doesn't fix all the things that I don't like, but it's been 
 sitting on my laptop for a month so I thought I'd submit it to the ML 
 for discussion.  I haven't committed it to my git since I'd just 
 revert it if it wasn't accepted :)  Here's the relevant documentation 
 to go along with the additions:
 
-ce,   --cuddled-else

You're the first perl programmer I know who likes these :-)

I don't. And I'm fairly sure the rest of us probably don't either.

[-nbcc], -bbc,  --blanks-before-comments
A blank line will be introduced before a full-line 
 comment.  This is the default.  Use -nbbc or  
 --noblanks-before-comments to prevent such blank lines from being 
 introduced.

No idea what this does? Do you have a visual example?

-msc=n,  --minimum-space-to-comment=n
Side comments look best when lined up several spaces to 
 the right of code.  Perltidy will try to keep comments at least n 
 spaces to the right.  The default is n=4 spaces.

Same as above...

Matt.


Re: Who wants to play holy war over -ce ?

2009-04-03 Thread Matt Sergeant

On Fri, 3 Apr 2009, David Nicol wrote:


On Fri, Apr 3, 2009 at 12:36 PM, Matt Sergeant m...@sergeant.org wrote:


       -ce,   --cuddled-else


You're the first perl programmer I know who likes these :-)

I don't. And I'm fairly sure the rest of us probably don't either.


I use them; they appear in plenty of CPAN modules, production code,
examples in mailing lists.


Hehe, ok three of you then ;-)

By the rest of us I meant the core qpsmtpd developers btw. But I was 
speaking out of line - I should let people speak for themselves, so I 
apologise for that.


Matt.

Re: End of headers hook

2009-02-10 Thread Matt Sergeant
Also note this won't work with -async properly. I'll have a look how it 
can be made to work asynchronously (you need to follow the respond 
style in the rest of the code).

On Mon, 09 Feb 2009 23:43:05 -0800, Robert Spier wrote:
 
 Committed as 
 
 
http://github.com/rspier/qpsmtpd/commit/a0ae0453264fe8dd85c132f2e7305b5ac34bf7e8
 
 Did you actually test that this worked?  I had to tweak the code to
 make it make sense.  Also, you had a mix of tabs and spaces and didn't
 follow the style of the rest of the code.   I cleaned them up this
 time.
 
 -R
 
 Karl Y. Pradene wrote:
 
 On Mon, 09 Feb 2009 10:10:47 -0800 Robert Spier rsp...@pobox.com
 wrote:
 
 
 Functionally, just about anything you can do here you can do just as
 
 I don't see a problem with adding it per-se.  It'd make my
 plugins/config file ordering a trifle simpler, but it doesn't
 really add any functionality.  I agree there should be a big
 warning about rejects/disconnects potentially being very dangerous.
 
 Chris' analysis [mostly snipped] is compelling.
 
 Karl, 
   Can you update the patch with 
  - documentation 
  -   ... including a warning
  - changing the name?
 
   And then I'll happily apply it.
 
   As Ask said, don't worry about bad english, that's easy enough to
   fix later.
 
 
 -R
 
 And voila. Hook renamed to data_headers_end, documentation in
 README.plugins with a BIG warning.
 
 $self-transaction-header($header) was moved earlier to have headers
 in transaction object when we call the hook.
 
 Regards.
 
 -- 
 Karl Y. Pradene
 


Re: qpsmtpd-async under AnyEvent

2009-02-03 Thread Matt Sergeant

On Tue, 3 Feb 2009, Pedro Melo wrote:


Hi,

I have a AnyEvent-based project that requires a SMTP server. I was 
considering either write a AnyEvent::Impl::Danga::Socket so that I can run 
qpsmtpd directly.


Has anybody played with something like this here?


I don't think so... Though I have a backend that uses EventLib - does 
AnyEvent support that? Only thing is there's no async DNS libraries for 
the other event loops. ParaDNS seems to be the only one.


The other possibility is to rewrite parts of qpsmtpd to use AnyEvent::Socket 
(and probably AnyEvent::Handle).


Any suggestions?


I'd consider writing your own backend based on the current Async one. It's 
not that hard, as long as you grok this stuff.


Matt.


Re: Domain Alias in Qpsmtpd

2009-01-29 Thread Matt Sergeant
On Wed, 28 Jan 2009 16:23:01 +0100, Julien wrote:
 The config file (/var/qmail/control/aliasdomains) contain one
 remplacment per line, each remplacment consist of 'olddomain' and
 'newdomain' seperate by a ':' like :
 
 test.domain.com:domain.com
 
 So address jul...@test.domain.com sould be rewrite to jul...@domain.com
 
 I'm sure there is a very elegant way to do this in perl ...

Yeah it's pretty simple:

#!perl -w

my %domain_map;

sub init {
my ($self) = @_;
for ($self-qp-config('aliasdomains')) {
my ($from, $to) = split(/:/, $_, 2);
$domain_map{$from} = $to;
}
}

sub hook_rcpt {
my ($self, $transaction) = (shift, shift);
my $rcpt_domain = $_[0]-host;
if (my $rewrite_to_domain = $domain_map{$rcpt_domain}) {
$self-log(LOGINFO, Rewriting $rcpt_domain to 
$rewrite_to_domain);
$_[0]-host($rewrite_to_domain);
}
return DECLINED;
}


Re: Domain Alias in Qpsmtpd

2009-01-28 Thread Matt Sergeant
On Wed, 28 Jan 2009 15:13:31 +0100, Julien wrote:
 Without any success, I still got/get the original recipient.

What version of qpsmtpd? I think changing these values was only added 
in SVN.

Matt.


Re: File Permissions bug?

2009-01-25 Thread Matt Sergeant
On Sat, 24 Jan 2009 10:37:46 -0500 (EST), Charlie Brady wrote:
 Any time you spend doing useless system calls isn't available for 
 spamassassin or clamav. Run strace against qpsmtpd (at least 
 forkserver variant) some time and you'll see how often config files 
 are opened.

Well of course. Forkserver is unable to cache anything except for the 
lifetime of the fork.

And I would be willing to be the fork is way more expensive than extra 
stats().

Matt.


File Permissions bug?

2009-01-21 Thread Matt Sergeant
Should we fix qpsmtpd config loading to check for file permissions as 
described in: http://use.perl.org/~Alias/journal/38319 ?


Matt.


Re: indentation, line length, trailing whitespace

2009-01-14 Thread Matt Sergeant
On Wed, 14 Jan 2009 09:10:14 -0600, Jared Johnson wrote:
 Hi,
 
 Is there any interest in patches to conform current QP code to line 
 length and whitespace standards?
 
 1.  I notice that most of the codebase uses 4-space indents, but I 
 have seen some areas with 2-space indents and tab characters.

The original codebase (Ask's code) was all 2 space indents. The newer 
qpsmtpd coders all prefer 4 spaces, so we sort of overruled Ask (sorry 
mate :)). There was a plan at some point to run everything through 
perltidy to set 4 spaces everywhere, but nobody ever got around to it.

 2.  It's been pointed out that it is preferred that lines are kept to 
 80 characters are less, but this is violated in a number of places.

Meh, I'm not hardcore about this. Screens are bigger these days, or vim 
displays stuff nicely anyway. I think it's a good overall rule, but if 
you have a long string or something I don't have a problem violating it.

 Our organization conforms to similar coding guidelines WRT these 
 issues and I would be happy to submit patches to cleanup up each of 
 these areas if there's any desire.  I would also suggest creating a 
 'coding guidelines' page on the wiki for this and any other style 
 issues that are deemed useful to conform to.

Think we should do this after the git migration is complete.

Matt.


Re: [PATCH] Make remote_host available in hook_pre_connection

2009-01-12 Thread Matt Sergeant

On Mon, 12 Jan 2009, Jared Johnson wrote:


I propose something like the following in the connection package

   sub remote_hostname{
   my $self = shift;
   $self-{_remote_hostname} ||= 
Net::DNS::get_name($self-{_remote_ip})

   }


This seems reasonable to me on principal.


Except doesn't work with -async. Well, it works, but blocks.

Was the name 'remote_hostname' as 
opposed to 'remote_host' intentional?


Probably to match apache/mod_perl - most of us qpsmtpd hackers are ex 
mod_perl guys.


Matt.


Re: Christmas release?

2008-12-23 Thread Matt Sergeant
On Mon, 22 Dec 2008 11:58:23 +0100, Kaare Rasmussen wrote:
 On Dec 19, 2008, at 18:56, Matt Sergeant m...@sergeant.org wrote:
 Shall we do a release for xmas? It's been forever...
 
 On the topic of releasing, why isn't qpsmtpd released to CPAN?

Because we never really got it easily installable via the whole 
Makefile.PL route.


Re: general question about ClamAV plugin

2008-10-01 Thread Matt Sergeant
On Tue, 30 Sep 2008 17:03:36 -0700 (PDT), [EMAIL PROTECTED] wrote:
 When using the ClamAV plugin i realize that this is not the entire
 ClamAV application but how do I then keep the virus definitions for
 the plugin up to date? do I need to actually install the ClamAV
 application to use freshclam to update the virus definations and then

Yes.

 do i need to have the ClamAV plugin point to a different spot for it
 to see these newer definations?

No, that's automatic.


Re: Latest SMTP.pm causes fatal errors

2008-09-30 Thread Matt Sergeant
On Tue, 30 Sep 2008 08:34:05 +0200, Hanno Hecker wrote:
 I'm confused why the error is caused - anyone better with perl than me 
 can help out?
 Same confusion here... and I cannot reproduce it. 
   $ perl -v | grep 'This is perl'
   This is perl, v5.8.8 built for i486-linux-gnu-thread-multi
 
 Running -async works without a problem, with and without (start)tls.

Same here. Chris can you reduce it to a couple of plugins and let us 
know the setup required to reproduce?


Re: DNSBL and answer id check missing

2008-09-27 Thread Matt Sergeant
On Sat, 27 Sep 2008 13:56:58 +0200, Diego d'Ambra wrote:
 To me it seems that plugin DNSBL is using Net::DNS bgsend/bgread, but 
 is not checking the id of the reply received.
 
 If true this means that an attacker can white- or blacklist any email 
 by sending fake dns replies (only randomisation is source port). 
 Furthermore any other application on same machine also doing dns 
 lookup may end up using same source port and have it's replies being 
 mixed with those plugin DNSBL is waiting for.
 
 Spamassassin is also using Net::DNS bgsend/bgread, but does verify if 
 the dns answer id matched the request.
 
 Maybe Net::DNS requires the caller to do the validation, or did I 
 miss something?
 
 I'm working on a way to test this, but would love to hear others 
 opinion, before doing to much work for maybe nothing :-)

I'm pretty sure you're probably right. The async version uses ParaDNS 
which does do the id checking.

(we should probably do 0x20 checking too, but I think that's beyond my 
skill levels :-/ )


Re: DNSBL and answer id check missing

2008-09-27 Thread Matt Sergeant
On Sat, 27 Sep 2008 20:09:37 -0400, Chris Lewis wrote:
 I've extended the async dnsbl plugin to do scoring.  It occured to me a
 few days ago that DNSBLs with negative scores (DNSWLs) should be treated
 as a hit if they get a timeout or other failure.  This has prompted me
 to comment about checking ids too.
 
 The stock one doesn't do scoring, and hence can't do DNSWL.  You want my
 code?  You might not like my logging conventions however ;-)

Like I said, the async version doesn't suffer from this bug, because it 
uses ParaDNS which checks the id fields (but doesn't do 0x20 checking - 
I wish I knew enough to be able to extend it to do so).


RE: FIXED -- high CPU on lost processes with forkserver

2008-09-26 Thread Matt Sergeant
I've applied this, but without using a global for the client as that 
seems unnecessary. Please check this version works. (I've also made the 
relevant change to -forkserver too).

On Fri, 26 Sep 2008 11:59:57 -0500, Ed McLain wrote:
 Just an fyi for the group.  I've been running this patch for several 
 days now and my stuck processes are completely gone and no sign of 
 any problems arising from the changes.  Has anyone else had a chance 
 to look over the changes I made yet?  Also, the load on my boxes has 
 dropped dramatically.  Each of my boxes generally had 4-6 stuck 
 processes eating up cpu time talking down empty sockets (tls on some, 
 remote disconnected on others) which would give me load averages on 
 each box between 3 and 19.  Load averages now on each box are between 
 0.04 and 0.19 with each box processing roughly 6-12 connections per 
 second.
 
 --
 Thanks,
 Ed McLain
 
 -Original Message-
 From: Ed McLain
 Sent: Tuesday, September 23, 2008 2:31 PM
 To: qpsmtpd@perl.org
 Subject: RE: high CPU on lost processes with forkserver
 
 Does anyone have any problems with the patch to fix this bug?  
 Basically, when TcpServer's run method is called it is passed a copy 
 of the $client IO::Socket and $client-connected is called in the 
 respond method (for TcpServer and PreFork) to verify that the socket 
 is still open.  I've been testing it for a while and haven't seen any 
 issues, also don't have any stuck processes anymore either.  I'm not 
 a perl monger though so I just want to make sure I'm not doing 
 anything insane.  Any and all input is greatly welcome.
 
 --
 Thanks,
 Ed McLain
 
 -Original Message-
 From: Ed McLain
 Sent: Monday, September 22, 2008 10:51 AM
 To: Jose Luis Martinez; qpsmtpd@perl.org
 Subject: RE: high CPU on lost processes with forkserver
 
 Anything new on a fix for this bug?  I seem to have quite a few 
 connections hitting this these days.
 
 --
 Thanks,
 Ed McLain
 
 
 -Original Message-
 From: Jose Luis Martinez [mailto:[EMAIL PROTECTED]
 Sent: Tuesday, April 29, 2008 11:42 AM
 To: qpsmtpd@perl.org
 Subject: Re: high CPU on lost processes with forkserver
 
 Peter J. Holzer escribió:
 On 2008-04-25 21:24:17 +0200, Jose Luis Martinez wrote:
 Peter J. Holzer escribió:
 You caught it!!! It did the trick!
 
 As I wrote previously, my guess is that both the mysql library and the
 tls library catch SIGPIPE but don't call the previously installed
 signal handler. So only one of them gets called (whichever is
 registered last) and the other one loses.
 
 So before patching the qp core in the respond method (Matt Sergeant
 commented: But I removed it because then alarm() features VERY 
 heavily in the performance profiling as an expensive system call.).
 
 I chose to work around the DBD::mysql to make it behave...
 
my $sighandle = $SIG{'PIPE'};
 
my $dbh =
 DBI-connect('DBI:mysql:database=xxx;host=localhost;port=3306',
 'xxx','xxx') or
$self-log(LOGDEBUG, 'Could not connect ' . DBI-errstr()) ;
 
$SIG{'PIPE'} = $sighandle;
 
 It seems the DBD::mysql uses the SIGPIPE to reconnect to the mysql in 
 case the connection is lost. Good bye feature!
 
 Looks like Apache  DBD::mysql have or have had the same problem from 
 this post...
 Found this:
 
http://mail-archives.apache.org/mod_mbox/httpd-dev/199903.mbox/[EMAIL PROTECTED]
 
 No, but there are at least two layers below that: The PerlIO layer and
 the TLS layer. Either one could retry an unsuccessful write if the
 actual cause of the error was lost.
 
 I'll try to contact the author of the TLS layer so that instead of 
 depending on the signal, maybe he can depend on the return value of 
 the writes (EPIPE) to cancel out... (Seems like a more stable 
 solution...
 that way external modules cannot influence you).
 
 Thanks for all the help and comments.
 
 Jose Luis Martinez
 [EMAIL PROTECTED]
 CAPSiDE
 


EnemiesList plugin

2008-09-26 Thread Matt Sergeant
People who follow the SVN commits list will have seen that I posted an 
enemies_list plugin in contrib.

EnemiesList is a database of regular expressions that map to 
dynamic-looking hosts. It's non-free, which is why I've posted it in 
the contrib directory.

In the EL contrib directory (on their server) there's a perl module for 
loading the regular expressions and matching very quickly against a 
hostname in there (much faster than if you loaded all the regexps into 
perl itself). If you have all that working (the DNS::RE module) then 
the plugin queries the EL database for the HELO host given. This is 
generally a very strong spamware sign, though I've left it so that the 
plugin just stores the results in $transaction-notes so you can do 
with it as you wish.

http://enemieslist.com/about/


Re: $transaction-body_filename;

2008-09-15 Thread Matt Sergeant
On Mon, 15 Sep 2008 16:40:24 -0400, Chris Lewis wrote:
 According to the documentation, when you call
 $transaction-body_filename, you get a temporary file name that points
 at a file that contains the message.  If you examine body_filename, it
 has no headers.
 
 The clamdscan plugin uses body_filename to hand off to clamdscan.  Which
 means that ClamAV doesn't get to see the headers.  Which is important to
 some ClamAV detections (eg: the ClamAV self-test email is _not_ caught
 by the clamdscan plugin).
 
 [In contrast, the spamassassin plugin carefully spits out
 header-as_string and then the body into spamd.]
 
 Is this working as intended?

My gut instinct is to say no. But I worry a little bit that we might 
break something else by fixing it...


Re: $transaction-body_filename;

2008-09-15 Thread Matt Sergeant
On Mon, 15 Sep 2008 17:39:33 -0400, Chris Lewis wrote:
 Matt Sergeant wrote:
 On Mon, 15 Sep 2008 16:40:24 -0400, Chris Lewis wrote:
 According to the documentation, when you call
 $transaction-body_filename, you get a temporary file name that points
 at a file that contains the message.  If you examine body_filename, it
 has no headers.
 
 The clamdscan plugin uses body_filename to hand off to clamdscan.  Which
 means that ClamAV doesn't get to see the headers.  Which is important to
 some ClamAV detections (eg: the ClamAV self-test email is _not_ caught
 by the clamdscan plugin).
 
 [In contrast, the spamassassin plugin carefully spits out
 header-as_string and then the body into spamd.]
 
 Is this working as intended?
 
 My gut instinct is to say no. But I worry a little bit that we might 
 break something else by fixing it...
 
 Would it be worth considering have a data_filename() call, that does
 exactly the same thing as body_filename, but includes the headers too?
 Then we can fix the clamdscan plugin without breaking anything else.

I thought about that, but you'd have to write to a file twice then :-/


Re: $transaction-body_filename;

2008-09-15 Thread Matt Sergeant
On Mon, 15 Sep 2008 19:30:11 -0400, Matt Sergeant wrote:
 Would it be worth considering have a data_filename() call, that does
 exactly the same thing as body_filename, but includes the headers too?
 Then we can fix the clamdscan plugin without breaking anything else.
 
 I thought about that, but you'd have to write to a file twice then :-/

So I think we should just fix the bug, and see if anything breaks.


Re: $transaction-body_filename;

2008-09-15 Thread Matt Sergeant
On Mon, 15 Sep 2008 17:35:31 -0700, Ask Bjørn Hansen wrote:
 
 On Sep 15, 2008, at 13:40, Chris Lewis wrote:
 
 According to the documentation, when you call
 $transaction-body_filename, you get a temporary file name that points
 at a file that contains the message.  If you examine body_filename, it
 has no headers.
 
 
 It was made that way first because the headers can change, so we 
 needed to keep those in memory.
 
 If we put them into the file we have to document that they are there 
 as received from the client which isn't necessarily the same as what 
 they are now.   Also any plugins (queue plugins) that use the body 
 but need the correct headers will have to know to skip the headers 
 (maybe a method to give a filehandle starting at the right place?).

We already have that, with body_start().


Re: qpsmtpd-prefork - anyone using it and are patches accepted?

2008-08-04 Thread Matt Sergeant
On Mon, 4 Aug 2008 15:27:46 +0200, Diego d'Ambra wrote:
 The latest version of qpsmtpd-prefork (revision 935) seems to miss 
 some important patches, e.g.:
 
  - shared memory LOCK (qpsmtpd freezes)
  - clean shutdown of parent and any children (unable to restart qpsmtpd)
  - cleanup of STDIN (data from previous SMTP session still around 
 with next session)
 
 Some of these may have been solved in other places, but I would be 
 willing to test and check if they are still needed and patch against 
 latest revision.
 
 Any interest?

Yes of course.


Re: Correcting plugin syntax errors

2008-07-29 Thread Matt Sergeant

On Tue, 29 Jul 2008, Jose Luis Martinez wrote:

BTW: any comment on how to elaborate a testing framework. Comments from the 
QP-gurus would be helpful.


For some in house code here that's similar to Qpsmtpd we basically have a 
data driven test system. You specify in a config file what plugins to 
load, and any other config file contents (supports CDB files too), and it 
generates the right config, and starts the daemon. Then you specify things 
like HELO, IP, full email contents, etc and it talks to the daemon using 
those details, and checks for the expected outcome.


Obviously not all that is possible with qpsmtpd (e.g. you can't spoof the 
IP easily), but most of it is. And it makes developing tests much easier.


I can probably share a bit of the code if it helps.

Matt.


Re: [qpsmtpd] Decisions, Decisions

2008-07-08 Thread Matt Sergeant

On Tue, 8 Jul 2008, David Nicol wrote:


On Tue, Jul 8, 2008 at 3:14 PM,
[EMAIL PROTECTED] wrote:

Basically you just need an
understanding of how async programming works - from there everything
starts to become obvious.


never block for IO.  Work out the state so that you can drop
everything and pick it up later whenever you would be waiting for IO
from any source.  Keep all per-connection data in an object.


Yup, that and a basic understanding of how Danga::Socket works (easiest to 
do something like read the current queue/async/smtp-forward plugin to 
learn that).


But do note what I've said here previously: async is for high CONCURRENCY 
not necessarily performance. Up to a certain level of concurrency prefork 
is faster.


Matt.


Re: [qpsmtpd] Decisions, Decisions

2008-07-08 Thread Matt Sergeant

On Tue, 8 Jul 2008, David Nicol wrote:


On Tue, Jul 8, 2008 at 4:33 PM, Matt Sergeant [EMAIL PROTECTED] wrote:

But do note what I've said here previously: async is for high CONCURRENCY
not necessarily performance. Up to a certain level of concurrency prefork is
faster.


with SMTP one cares about throughput more than response time, and
properly implemented async will always provide better throughput than
an equivalent forking system on the same hardware simply because the
OS doesn't have to bother with as many context switches. (lots of
wiggle room in properly.)


It's true, but there seems to be an annoying inefficiency in -async 
somewhere compared to the simplicity of prefork - I'm fairly sure it's 
to do with reading lines from the buffer - perl just isn't very good at 
that sort of thing (whereas with C you can just move a pointer along, Perl 
doesn't do that very well). I suppose I could probably do a bit more 
benchmarking to improve it at some point.


Matt.


Re: [qpsmtpd] Decisions, Decisions

2008-07-07 Thread Matt Sergeant
On Mon, 7 Jul 2008 22:30:50 + (UTC), 
[EMAIL PROTECTED] wrote:
 Looking at the wiki deployment page, it looks like I could be considering
 the apache or prefork versions. I'm leaning towards prefork - the page
 says it's faster, but there's no comparison between it and the apache
 version. Are there any substantial, meaningful differences between
 forkserver, apache, and prefork? I should be able to run either of the
 three, so how do I determine which would be best?

Apache's downside is simply that it requires Apache. In most other 
aspects it's pretty good, including the fact that for free you get a 
working server-status page listing current connections. I think the 
performance of the Apache module is very slightly higher than prefork 
simply because all the I/O happens in C.

 (I definitely want stable, so pollserver looks like it's out of the
 question. BTW, are there any guidelines on how to write async modules to
 ensure they work with pollserver?)

There are lots of bits and pieces that I've posted to this mailing 
list. That's about all though :-/ Basically you just need an 
understanding of how async programming works - from there everything 
starts to become obvious.

Matt.


Re: questions re: async, perperl, new release

2008-06-27 Thread Matt Sergeant
On Fri, 27 Jun 2008 04:17:55 -0700, Ask Bjørn Hansen wrote:
 
 Has anyone run qpsmtpd under PersistentPerl (a.k.a SpeedyCGI). There
 is a mention of pperl, but I've never used it.
 
 qpsmtpd-forkserver is our closest equivalent.  I don't know if 
 anyone's been running it under pperl or PersistentPerl for a while.

Actually qpsmtpd-prefork is closer.

 I noticed a mention of a new release on 4 June. Any news on that? Is
 the CVS version stable enough for production?
 
 The subversion version is quite stable; indeed it's almost certainly 
 better than the last release.

There's a message there ... :-)


Interesting article on async-ness

2008-06-27 Thread Matt Sergeant
http://oubiwann.blogspot.com/2008/06/so-you-want-your-code-to-be-asynchonous.html

It's about Python, but the same stuff generally applies to working with 
qpsmtpd-async.


Re: require_resolvable_fromhost bug

2008-06-12 Thread Matt Sergeant
Heh, I was going through this code a week or so ago and thought this 
looked odd...

I'll apply the patch.

On Thu, 12 Jun 2008 14:53:22 +0200, Jose Luis Martinez wrote:
 Hi,
 
 We're using the require_resolvable_fromhost plugin, and have seen 
 that there is  a bug in it. MAIL FROM commands with legitimate 
 domains where getting rejected as not resolvable.
 
 The bug has been tracked down to domains that have zone files with 
 unresolvable MX records.
 
 example.com. 3600 IN MX 10 fakeserver.example.com.
 example.com. 3600 IN MX 20 mail.example.com.
 example.com. 3600 IN MX 30 anotherfakeserver.example.com.
 
 The plugin tries to resolve every MX record in the list (to see if it 
 has an A record), but gives up on the first unresolvable one, 
 considering the whole domain unresolvable.
 
 I consider this a bug, as leaving fake MX records is a known antispam 
 technique, and after all, the domain is resolvable if you have at 
 least one resolvable MX record.
 
 Patch attached:
 
 Index: plugins/require_resolvable_fromhost
 ===
 --- plugins/require_resolvable_fromhost   (revision 1)
 +++ plugins/require_resolvable_fromhost   (working copy)
 @@ -53,8 +53,14 @@
$res-udp_timeout(30);
my @mx = mx($res, $host);
foreach my $mx (@mx) {
 -return mx_valid($self, $mx-exchange, $host);
 +# if any MX is valid, then we consider the domain
 +# resolvable
 +return 1 if mx_valid($self, $mx-exchange, $host);
}
 +  # if there are MX records, and we got here,
 +  # then none of them are valid
 +  return 0 if (@mx  0);
 +
my $query = $res-search($host);
if ($query) {
  foreach my $rrA ($query-answer) {
 
 
 Jose Luis Martinez
 [EMAIL PROTECTED]
 CAPSiDE
 


Re: rcptto_vrfy

2008-06-10 Thread Matt Sergeant
On Tue, 10 Jun 2008 13:59:43 +0200, Jan Völkers wrote:
 Hello,
 
 has anyone written a rcptto_vrfy plugin?
 
 I set up a new mx in a hurry and now i am searching for a nice 
 check_rcpt plugin. Actually i am using only the smtp_forward plugin 
 which has two disadvantages:
 
 - it checks _after_ queueing the whole mail.
 
 - it rejects legitimate mails: If one sends mails to different users 
 in the same domain with one correct and one incorrect address also 
 the legitimate receiver will not get any mail as it is completely 
 rejected.
 
 
 I would appreciate a simple plugin that checks recipients via vrfy. Yes,
 my next hop answers vrfy correctly.
 
 Does anybody know something like this or has other suggestions? My Users
 are homed as virtual users and aliases in a mysql db, but i prefer 
 the vrfy way as it is more portable.

I don't think anyone has written one yet. We've talked a LOT about 
making smtp_forward be more of a direct proxy, or at least do that 
optionally, but different users seem to have different requirements for 
that.

It should be really easy to write. Just use Net::SMTP to make the 
connection and issue the VRFY.

Something like this:

use Net::SMTP;
sub hook_mail {
my ($self, $tran) = @_;
$tran-notes('my_smtp_server', Net::SMTP-new('wherever'));
return DECLINED;
}
sub hook_rcpt {
my ($self, $tran, $recipient) = @_;
my $smtp = $tran-notes('my_smtp_server');
if (!$smtp-verify($recipient-format)) {
return DENY, Bad recipient: $recipient;
}
return DECLINED;
}
sub hook_data {
my ($self, $tran) = @_;
my $smtp = $tran-notes('my_smtp_server');
$smtp-quit;
$tran-notes('my_smtp_server', undef);
return DECLINED;
}

Matt.


Re: [svn:qpsmtpd] r923 - in trunk: . lib/Qpsmtpd

2008-06-03 Thread Matt Sergeant

On 3-Jun-08, at 4:04 AM, Radu Greab wrote:


I think we need more consensus on this patch.


Due to the objections expressed so far I reverted the change. Should I
mention the overloaded meaning of remote_host in the pod?


No, because it's different with different backends. Currently only  
async will set it to SERVFAIL or TIMEOUT in those conditions.


And unfortunately there's no way for us to fix that in tcpserver mode.

Matt.


Re: Clarification of hooks with ignored return values

2008-06-03 Thread Matt Sergeant

On 3-Jun-08, at 4:36 AM, Radu Greab wrote:


The documentation says that for the following hooks the return values
are ignored or discarded:

  post-fork post-connection disconnect deny ok

I had however to change my custom plugins to return DECLINE from
post-fork hooks, otherwise, with no explicit return statement, only  
the
hook of the first plugin was called, the hooks of the other plugins  
were

not called.

I think that it is a bug that the code does not ignore the return  
values

of the hooks mentioned above and stops calling all the plugins which
registered interest in the hooks.

Am I right and should the code be changed to really ignore the return
values from those hooks?


No, the docs need changed :-)

While the return values are ignored, you must still abide by the  
qpsmtpd processing model (e.g. return DECLINED to allow the next hook  
to fire, return DONE to stop there, etc).


What it really means is you can't create an SMTP return code in one  
of those hooks, e.g. by returning DENY and hoping that a 5xx will be  
sent to the client.


Matt.


Re: [svn:qpsmtpd] r923 - in trunk: . lib/Qpsmtpd

2008-06-02 Thread Matt Sergeant

On 2-Jun-08, at 6:06 PM, Radu Greab wrote:


Matt Sergeant wrote:



I think that remote_host should not be the error code in case of
errors. That contradicts the description of the method and may force
other people using remote_host to do their own checks.


Well on regular qmail it's set to Unknown in case of errors, but
never tells you if the error was NXDOMAIN or SERVFAIL or TIMEOUT. I
find the distinction useful.


I find that Unknown as a value for remote_host looks more reasonable
than NXDOMAIN and the other values.


Why? That's less information. Unknown for NXDOMAIN always made sense.  
But Unknown in the case of a DNS timeout or a failure never made  
sense to me.



What do you think about setting only remote_info to either the
result of
a successful lookup or the error code? And remote_host will be  
either

the result of the successful lookup or [$remote_ip] in case of
errors?


Possibly... What will that result in in terms of Received headers?


The Received headers won't change. Only the logs created by  
logterse or

other logging plugins that use remote_host will change.


Wow, that seems MUCH worse to me - to have the logs *not* storing the  
dns failure reason seems completely at odds to me with what logs  
should be for.


I think we need more consensus on this patch.

Matt.


Re: Pulling my hair out...

2008-05-28 Thread Matt Sergeant

On Wed, 28 May 2008, Chris Lewis wrote:


I'm trying to implement a subroutine shared between plugins.

The library routine looks something like:

sub createpattern {}


It needs to be exported from your library, or called with a full package 
name, how are you doing that?


The most common way is to use Exporter - see the Exporter man page for 
details.



And is stored under ../qpsmtpd/lib/NTMqplib.pm

qpsmtpd-async is called from the qpsmtpd directory.

Each plugin then calls it thusly:

use NTMqplib;

sub register ... {

... = createpattern(...)


Note that the  in front is a nasty perl4-ism and tends to be frowned upon 
by other perl coders these days - fine if you're the only one maintaining 
your script, but will look ugly if someone ever takes over...


What happens is that the first plugin executed works fine, and the next one 
errors out saying it can't find createpattern().


Looks like the first plugin executed loads the library, and remembers it's 
loaded.  The second one thinks it's loaded, but the symbol table (or 
whatever) isn't in scope, or some such.


How do you do this properly?


Sounds like you're probably just trying to put it into the current 
namespace. Keep it in it's own namespace (i.e. have package NTMqplib; in 
your .pm file) and use Exporter, or call it as NTMqplib::createpattern()


Matt.


Re: Connection notes and TLS

2008-05-26 Thread Matt Sergeant

On 26-May-08, at 5:24 PM, John Peacock wrote:

Those are *connection* attributes, not *transaction* attributes.   
If a plugin is storing them in the transaction object, that is a  
mistake.  We can and probably should maintain the connection notes  
from before the TLS reset, but I maintain that we should not keep  
the transaction notes.


OK, I'm fine with that.


Re: Connection notes and TLS

2008-05-23 Thread Matt Sergeant

On 22-May-08, at 10:45 PM, John Peacock wrote:

STARTTLS is not required to happen immediately after EHLO (not  
HELO, which doesn't support ESMTP extensions).  And yes, you must  
completely discard every portion of the SMTP state that has  
occurred up to that point (just like with RSET).


The RFC is extremely plain on this point: after STARTTLS has been  
sent and negotiated, the MTA must behave as if a completely new  
transaction has started (as indeed, it has).  The transaction  
*must* be reset and all information contained therein must be  
thrown away.  In practice, there isn't anything there to begin  
with, since all of the well-formed MTA's always sent STARTTLS as  
soon as practical (i.e. as soon as they see the initial EHLO  
banner), if they are going to send it at all.


I don't think we should care so much about the RFCs. If there are  
bits in connection notes that might help determining if this is spam  
(or some other thing we're trying to detect) before STARTTLS we need  
to allow qpsmtpd to keep that information.


Matt.


Re: Creating global DB connection

2008-05-20 Thread Matt Sergeant

On 20-May-08, at 12:33 PM, Nighthawk wrote:


Hi,
I am trying to write plugin that does DB lookup and want to use the  
same db connection in more than 1 plugins.
Somwhere I read that we can save DB connection in qp-config(). But  
it is not working in my case.


Store it in $qp-connection-notes() in the same way you've done - 
config.


Re: Whitelist convention

2008-05-16 Thread Matt Sergeant

Do it.




Re: Next steps to release?

2008-05-12 Thread Matt Sergeant

On Mon, 12 May 2008, Hanno Hecker wrote:


On Wed, 7 May 2008 19:58:46 + (UTC)
Matt Sergeant [EMAIL PROTECTED] wrote:


So the next release I consider to be a fairly major step - we've got
async/smtp-forward and async tls working. That's most of the showstoppers
against using async in production.

So what's missing and what would you like to see before the next release?

Remove qpsmtpd-server and it's module Qpsmtpd::SelectServer? Does
anyone use it? Is it supported when we also have -async?


Good thought.


Re: [svn:qpsmtpd] r903 - trunk/lib/Qpsmtpd

2008-05-12 Thread Matt Sergeant
Note that this is probably worth doing for the other backends, though it's 
only for performance really.


On Mon, 12 May 2008, [EMAIL PROTECTED] wrote:


Author: msergeant
Date: Mon May 12 10:19:31 2008
New Revision: 903

Modified:
  trunk/lib/Qpsmtpd/PollServer.pm

Log:
Make sure non-responding hooks are called appropriately


Modified: trunk/lib/Qpsmtpd/PollServer.pm
==
--- trunk/lib/Qpsmtpd/PollServer.pm (original)
+++ trunk/lib/Qpsmtpd/PollServer.pm Mon May 12 10:19:31 2008
@@ -56,7 +56,7 @@
$self-load_plugins;
$self-load_logging;

-my ($rc, @msg) = $self-run_hooks(pre-connection);
+my ($rc, @msg) = $self-run_hooks_no_respond(pre-connection);
if ($rc == DENYSOFT || $rc == DENYSOFT_DISCONNECT) {
@msg = (Sorry, try again later)
  unless @msg;
@@ -164,7 +164,7 @@

sub close {
my Qpsmtpd::PollServer $self = shift;
-$self-run_hooks(post-connection);
+$self-run_hooks_no_respond(post-connection);
$self-connection-reset;
$self-SUPER::close;
}




Next steps to release?

2008-05-07 Thread Matt Sergeant
So the next release I consider to be a fairly major step - we've got 
async/smtp-forward and async tls working. That's most of the showstoppers 
against using async in production.


So what's missing and what would you like to see before the next release?

(obviously not limited to -async stuff)

Matt.


Re: async and tls take two

2008-05-05 Thread Matt Sergeant

On 5-May-08, at 10:45 AM, Steve Kemp wrote:

  Seeing changes like this makes me wonder if we should consider  
running

 all source through perltidy at some point.  Perhaps as part of a
 make update, or make commit target.


Yes, it has been discussed before. We just need the tuits to make it so.


  ObRelated:  I would be happy to submit a patch to unify plugin
 argument names.  I see big differences between:

 ./queue/exim-bsmtp:my ( $self, $txn ) = @_;
 ./logging/file:my ( $self, $txn ) = @_;

  And:

  ./virus/clamav:my ( $self, $transaction ) = @_;
  ./valid_users:my ( $self, $transaction, $sender, %param ) = @_;


  For example.  I'd suggest s/txn/transaction/g on all plugins
 shipped with the core distribution, because I think the verbosity
 and consistency wouldn't be a bad thing.


That would be a nice easy project for someone with a bit of time on  
their hands... (hint hint)


Matt.


Re: async and tls take two

2008-05-04 Thread Matt Sergeant

On 4-May-08, at 7:28 PM, Matt Sergeant wrote:

Yeah this makes a lot more sense... Though I wonder if we shouldn't  
modify Danga::Client to just have some sort of reader entry, so  
that anything else (not just TLS) can hook into the event_read  
stream. I'll have a poke.


Can you check if this works:

Index: plugins/tls
===
--- plugins/tls (revision 876)
+++ plugins/tls (working copy)
@@ -150,7 +150,7 @@
 return DECLINED unless $local_port == 465; # SMTPS

 unless ( _convert_to_ssl($self) ) {
-   return (DENY_DISCONNECT, Cannot establish SSL session);
+return (DENY_DISCONNECT, Cannot establish SSL session);
 }
 $self-log(LOGWARN, Connected via SMTPS);
 return DECLINED;
@@ -159,6 +159,10 @@
 sub _convert_to_ssl {
 my ($self) = @_;

+if ($self-qp-isa('Qpsmtpd::PollServer')) {
+return _convert_to_ssl_async($self);
+}
+
 eval {
 my $tlssocket = IO::Socket::SSL-new_from_fd(
 fileno(STDIN), '+',
@@ -178,13 +182,21 @@
 $self-connection-notes('tls_enabled', 1);
 };
 if ($@) {
-   return 0;
+return 0;
 }
 else {
-   return 1;
+return 1;
 }
 }

+sub _convert_to_ssl_async {
+my ($self) = @_;
+my $upgrader = $self-connection
+-notes( 'tls_upgrader', UpgradeClientSSL- 
new($self) );

+$upgrader-upgrade_socket();
+return 1;
+}
+
 sub can_do_tls {
 my ($self) = @_;
 $self-tls_cert  -r $self-tls_cert;
@@ -238,3 +250,81 @@
 $self-log(LOGWARN, Exiting because 'tls_enabled' was true.);
 exit;
 }
+
+package UpgradeClientSSL;
+
+# borrowed heavily from Perlbal::SocketSSL
+
+use strict;
+use warnings;
+no  warnings qw(deprecated);
+
+use Danga::Socket 1.44;
+use IO::Socket::SSL 0.98;
+use Errno qw( EAGAIN );
+
+use fields qw( _stashed_qp _stashed_plugin _ssl_started );
+
+sub new {
+my UpgradeClientSSL $self = shift;
+$self = fields::new($self) unless ref $self;
+$self-{_stashed_plugin} = shift;
+$self-{_stashed_qp} = $self-{_stashed_plugin}-qp;
+return $self;
+}
+
+sub upgrade_socket {
+my UpgradeClientSSL $self = shift;
+
+unless ( $self-{_ssl_started} ) {
+IO::Socket::SSL-start_SSL(
+$self-{_stashed_qp}-{sock}, {
+SSL_use_cert = 1,
+SSL_cert_file = $self-{_stashed_plugin}-tls_cert,
+SSL_key_file = $self-{_stashed_plugin}-tls_key,
+SSL_ca_file = $self-{_stashed_plugin}-tls_ca,
+SSL_cipher_list = $self-{_stashed_plugin}- 
tls_ciphers,

+SSL_startHandshake = 0,
+SSL_server = 1,
+SSL_reuse_ctx = $self-{_stashed_plugin}-ssl_context,
+}
+) or die Could not upgrade socket to SSL: $!;
+$self-{_ssl_started} = 1;
+}
+
+$self-event_read($self-{_stashed_qp});
+}
+
+sub event_read {
+my UpgradeClientSSL $self = shift;
+my $qp = shift;
+
+$qp-watch_read( 0 );
+
+my $sock = $qp-{sock}-accept_SSL;
+
+if (defined $sock) {
+$qp-connection( $qp-connection-clone );
+$qp-reset_transaction;
+$qp-connection-notes('tls_socket', $sock);
+$qp-connection-notes('tls_enabled', 1);
+$qp-watch_read(1);
+return 1;
+}
+
+# nope, let's see if we can continue the process
+if ($! == EAGAIN) {
+$qp-set_reader_object($self);
+if ($SSL_ERROR == SSL_WANT_READ) {
+$qp-watch_read(1);
+} elsif ($SSL_ERROR == SSL_WANT_WRITE) {
+$qp-watch_write(1);
+} else {
+$qp-disconnect();
+}
+} else {
+$qp-disconnect();
+}
+}
+
+1;
Index: lib/Danga/Client.pm
===
--- lib/Danga/Client.pm (revision 881)
+++ lib/Danga/Client.pm (working copy)
@@ -2,7 +2,15 @@

 package Danga::Client;
 use base 'Danga::TimeoutSocket';
-use fields qw(line pause_count read_bytes data_bytes callback  
get_chunks);

+use fields qw(
+line
+pause_count
+read_bytes
+data_bytes
+callback
+get_chunks
+reader_object
+);
 use Time::HiRes ();

 use bytes;
@@ -26,6 +34,7 @@
 $self-{pause_count} = 0;
 $self-{read_bytes} = 0;
 $self-{callback} = undef;
+$self-{reader_object} = undef;
 $self-{data_bytes} = '';
 $self-{get_chunks} = 0;
 return $self;
@@ -96,9 +105,18 @@
 }
 }

+sub set_reader_object {
+my Danga::Client $self = shift;
+$self-{reader_object} = shift;
+}
+
 sub event_read {
 my Danga::Client $self = shift;
-if ($self-{callback}) {
+if (my $obj = $self-{reader_object}) {
+$self-{reader_object} = undef;
+$obj-event_read($self);
+}
+elsif ($self-{callback}) {
 $self-{alive_time} = time;
 if ($self-{get_chunks}) {
 my $bref = $self-read($self-{read_bytes});



Re: high CPU on lost processes with forkserver

2008-04-25 Thread Matt Sergeant

On 25-Apr-08, at 1:15 AM, Peter J. Holzer wrote:

A better option might be to have the parent process watch for long
running children and terminate them.


Yup, but how long is long? If the client is trying to send a 600 MB
email that will take some time ...


Well we could set a max session time. Or even communicate aliveness  
via a pipe or something.


Re: high CPU on lost processes with forkserver

2008-04-24 Thread Matt Sergeant

On 24-Apr-08, at 5:52 PM, Brian Szymanski wrote:

Ask Bjørn Hansen wrote:


On Apr 24, 2008, at 11:02 AM, Charlie Brady wrote:


Ask said Yeah, this is a pretty bad bug in March 2007, but I
haven't seen anyone looking to fix it.


We must be in pretty good shape when billions (or whatever) of email
transactions are processed every day and nobody is bothered enough by
possibly our worst known bug to come up with a patch.  :-)

 - ask



We have a workaround to kill off any process that's been alive more  
than

5 minutes or so.

I'm anxious to get rid of it though, fixing things the right way,  
since

our mail server is struggling to keep up (only partially a result of
this). Any advice on where to start to tackle this one? And, just  
to be
clear we're talking about the same bug, this exists in .3x as well,  
yea?


I think the core used to do something like this:

Index: lib/Qpsmtpd.pm
===
--- lib/Qpsmtpd.pm  (revision 876)
+++ lib/Qpsmtpd.pm  (working copy)
@@ -390,7 +390,10 @@
 if ($hooks-{$hook}) {
 my @r;
 for my $code (@{$hooks-{$hook}}) {
+$SIG{ALRM} = sub { die Alarm };
+my $prev = alarm(10); # should be long enough for anyone!
 eval { (@r) = $code-{code}-($self, $self- 
transaction, @_); };

+alarm($prev);
 $@ and warn(FATAL PLUGIN ERROR: , $@) and next;
 if ($r[0] == YIELD) {
 die YIELD not valid from $hook hook;
@@ -419,7 +422,10 @@
 #warn(Got sampler called: ${hook}_$code-{name}\n);
 $self-varlog(LOGDEBUG, $hook, $code-{name});
 my $tran = $self-transaction;
+$SIG{ALRM} = sub { die Alarm };
+my $prev = alarm(10); # should be long enough for anyone!
 eval { (@r) = $code-{code}-($self, $tran, @$args); };
+alarm($prev);
 $@ and $self-log(LOGCRIT, FATAL PLUGIN ERROR: , $@) and next;

 !defined $r[0]


But I removed it because then alarm() features VERY heavily in the  
performance profiling as an expensive system call.


A better option might be to have the parent process watch for long  
running children and terminate them.


Matt.

Re: qpsmtpd-async: premature end of data problem

2008-04-14 Thread Matt Sergeant

On Sat, 12 Apr 2008, Radu Greab wrote:



I found a case where qpsmtpd-async detects the end of data marker
incorrectly: the previous packet did not end with CRLF and the current
packet starts with .CRLF. The code assumes that the previous packet
ended with CRLF.

Attached are a test script and a suggested patch.


So the test script is doing the wrong thing. Any . at the start of a 
line in SMTP needs to be encoded as .. and the SMTP line processor 
decodes it to a single dot.


So the test is wrong, and Qpsmtpd is doing the right thing in assuming the 
end of data has been reached. At least as far as I can tell.


Matt.


Re: qpsmtpd-async: premature end of data problem

2008-04-14 Thread Matt Sergeant

On Mon, 14 Apr 2008, Matt Sergeant wrote:


On Sat, 12 Apr 2008, Radu Greab wrote:



I found a case where qpsmtpd-async detects the end of data marker
incorrectly: the previous packet did not end with CRLF and the current
packet starts with .CRLF. The code assumes that the previous packet
ended with CRLF.

Attached are a test script and a suggested patch.


So the test script is doing the wrong thing. Any . at the start of a line 
in SMTP needs to be encoded as .. and the SMTP line processor decodes it 
to a single dot.


So the test is wrong, and Qpsmtpd is doing the right thing in assuming the 
end of data has been reached. At least as far as I can tell.


Ugh. Ignore me. Need more coffee :-)


Re: qpsmtpd-async: premature end of data problem

2008-04-14 Thread Matt Sergeant

On Sat, 12 Apr 2008, Radu Greab wrote:



I found a case where qpsmtpd-async detects the end of data marker
incorrectly: the previous packet did not end with CRLF and the current
packet starts with .CRLF. The code assumes that the previous packet
ended with CRLF.

Attached are a test script and a suggested patch.


I committed the patch 95% the same as yours.

I can't help feeling there's a better way to do it - I hate applying two 
regexps every time a DATA packet comes in... I'll have a think on it.


Matt.


Re: qpsmtpd-async: premature end of data problem

2008-04-14 Thread Matt Sergeant

On Mon, 14 Apr 2008, Guy Hulbert wrote:


On Mon, 2008-14-04 at 12:54 +, Matt Sergeant wrote:

Attached are a test script and a suggested patch.


I committed the patch 95% the same as yours.

I can't help feeling there's a better way to do it - I hate applying
two
regexps every time a DATA packet comes in... I'll have a think on it.


tr ?


I'm thinking more on the lines of pushing back reads if they're not full 
lines.


Probably needs a bit of support for that in lib/Danga/Client.pm

Matt.


Re: qpsmtpd-async: premature end of data problem

2008-04-13 Thread Matt Sergeant

Ask Bjørn Hansen wrote:


On Apr 12, 2008, at 6:33, Radu Greab wrote:


I found a case where qpsmtpd-async detects the end of data marker
incorrectly: the previous packet did not end with CRLF and the current
packet starts with .CRLF. The code assumes that the previous packet
ended with CRLF.


Hi Radu,

Can you add it to the issue tracker?

http://code.google.com/p/smtpd/issues/list

Wouldn't the non-pollserver servers have the same problem?


No, because they do $fh and block until there's a full line.

Though I could have sworn I fixed this - are you sure you're testing 
against latest SVN?


Matt.


Re: disabling plugins

2008-04-09 Thread Matt Sergeant

Hanno Hecker wrote:

Hi,

this patch sets a way to disable any loaded plugin(s) for the current
client. I'm not going to commit this before Ask released 0.43. Matt
(and others with high traffic) should be ok with the one more line
  next unless $code-{run}; 
per hook.

The plugins_loaded() should be in to Qpsmtpd.pm. Any other comments on
this?

I'm currently looking for a way to have plugins loaded but disabled (so
some other plugin can enable it later). Loading plugins on connect or
later at runtime would probably be possible, but too slow...
(Note to self: write docs before any commit)


I'm not sure this is the right way to do this. Surely you want something 
in the transaction object that can skip plugins at run time? Yours 
seems like a rather heavy hammer, which can be influenced in a very 
bizarre cross connection manner.


Matt.


  1   2   3   4   5   6   7   >