Net_SMTP - deadlock / robustness
| From: | Matthias Pigulla | Date: | Mon, 20 Dec 2004 15:12:01 +0000 |
| Subject: | Net_SMTP - deadlock / robustness | ||
| Groups: | php.pear.dev | ||
| Request: | Send a blank email to pear-dev+get-35182@lists.php.net to get a copy of this message | ||
Dear (Net_SMTP) devs,
I just stumbled across this and would like to hear some opinions on that
issue. Passing "broken" parameters to Net_SMTP's smptTo() together with
a certain remote MTA/SMTP server behaviour (actually, qmail) may cause
the SMTP connection to hang in a deadlock state.
Example:
<?php
require 'Net/SMTP.php';
$host = 'my.qmail.server';
$from = "some@email.address";
$subj = "Subject: Test Message\n";
$body = "Body Line 1\nBody Line 2";
$smtp = new Net_SMTP($host);
$smtp->connect();
$smtp->mailFrom($from);
// NOTE THIS ONE:
// It's broken - normally you would check addresses first,
however, accept it for now :)
$smtp->rcptTo("broken@host.name \r\nbroken@host.name");
$smtp->data($subj . "\r\n" . $body);
$smtp->rset();
$smtp->disconnect();
?>
Now things happen as follows:
<== 220 my.qmail.server ESMTP
==> EHLO localhost
<== 250-my.qmail.server
<== 250-PIPELINING
<== 250 8BITMIME
==> MAIL FROM:<some@email.address>
<== 250 ok
Now Net_SMTP thinks it would send a single RCPT TO, but the server
interprets it as two commands (as the parameter to rcptTo is carefully
crafted)!
==> RCPT TO:<broken@host.name
<== 250 ok
==> broken@host.name>
<== 502 unimplemented (#5.5.1)
Now Net_SMTP only reads "250 ok" from the inbound buffer - 502 remains
uninterpreted in the buffer!
==> DATA
<== 354 go ahead
Now Net_SMTP sees a 502, which is not what we expected! data() will fail
and return an error. 354 remains in the buffer, Net_SMTP thinks DATA
failed, but for the mail server, DATA succeeded. Now our script will
send RSET, QUIT, but the remote server takes it for the message itself.
==> RSET
The extra status code in the inbound buffer is removed, so Net_SMTP will
return from rset() with a 354 code (an error, of course).
==> QUIT
Finally, both sides keep hanging: The mail server waits for "\n.\n" (the
single period, as it is still in DATA mode), and Net_SMTP expects some
reply for the QUIT command.
--
I know that what I passed to rcptTo() here is clearly broken (and maybe
the way qmail reacts is broken, too?). However, we might want to improve
Net_SMTPs robustness. I wonder wheter you consider this no real problem
at all?
Otherwise, we might want to check parameters more carefully; or we might
even improve handling of the return codes to make sure no "extra"
replies keep hanging around in the buffers. Actually, having the extra
502 return code hanging in the buffer is what makes us running into this
dead end street - if we would completely read the return buffer after
each command, we could see that the DATA command actually succeeded.
Any opinions?
Best regards,
Matthias