From bf7d01ac66682cd6aea5a3f7c010164c8670a48a Mon Sep 17 00:00:00 2001 From: ndm2 Date: Fri, 18 Jul 2014 14:53:22 +0200 Subject: [PATCH] Make SMTP auth reply code checks work properly. --- lib/Cake/Network/Email/SmtpTransport.php | 20 +++-- .../Case/Network/Email/SmtpTransportTest.php | 83 +++++++++++++++++++ 2 files changed, 95 insertions(+), 8 deletions(-) diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php index e4dd51d43..c2009b475 100644 --- a/lib/Cake/Network/Email/SmtpTransport.php +++ b/lib/Cake/Network/Email/SmtpTransport.php @@ -191,18 +191,22 @@ class SmtpTransport extends AbstractTransport { */ protected function _auth() { if (isset($this->_config['username']) && isset($this->_config['password'])) { - $authRequired = $this->_smtpSend('AUTH LOGIN', '334|503'); - if ($authRequired == '334') { - if (!$this->_smtpSend(base64_encode($this->_config['username']), '334')) { + $replyCode = $this->_smtpSend('AUTH LOGIN', '334|500|502|504'); + if ($replyCode == '334') { + try { + $this->_smtpSend(base64_encode($this->_config['username']), '334'); + } catch (SocketException $e) { throw new SocketException(__d('cake_dev', 'SMTP server did not accept the username.')); } - if (!$this->_smtpSend(base64_encode($this->_config['password']), '235')) { + try { + $this->_smtpSend(base64_encode($this->_config['password']), '235'); + } catch (SocketException $e) { throw new SocketException(__d('cake_dev', 'SMTP server did not accept the password.')); } - } elseif ($authRequired == '504') { - throw new SocketException(__d('cake_dev', 'SMTP authentication method not allowed, check if SMTP server requires TLS')); - } elseif ($authRequired != '503') { - throw new SocketException(__d('cake_dev', 'SMTP does not require authentication.')); + } elseif ($replyCode == '504') { + throw new SocketException(__d('cake_dev', 'SMTP authentication method not allowed, check if SMTP server requires TLS.')); + } else { + throw new SocketException(__d('cake_dev', 'AUTH command not recognized or not implemented, SMTP server may not require authentication.')); } } } diff --git a/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php b/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php index 1eecd8893..880039737 100644 --- a/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php +++ b/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php @@ -223,6 +223,89 @@ class SmtpTransportTest extends CakeTestCase { $this->SmtpTransport->auth(); } +/** + * testAuthNotRecognized method + * + * @expectedException SocketException + * @expectedExceptionMessage AUTH command not recognized or not implemented, SMTP server may not require authentication. + * @return void + */ + public function testAuthNotRecognized() { + $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n"); + $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("500 5.3.3 Unrecognized command\r\n")); + $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story')); + $this->SmtpTransport->auth(); + } + +/** + * testAuthNotImplemented method + * + * @expectedException SocketException + * @expectedExceptionMessage AUTH command not recognized or not implemented, SMTP server may not require authentication. + * @return void + */ + public function testAuthNotImplemented() { + $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n"); + $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("502 5.3.3 Command not implemented\r\n")); + $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story')); + $this->SmtpTransport->auth(); + } + +/** + * testAuthBadSequence method + * + * @expectedException SocketException + * @return void + */ + public function testAuthBadSequence() { + $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n"); + $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("503 5.5.1 Already authenticated\r\n")); + $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story')); + $this->SmtpTransport->auth(); + } + +/** + * testAuthBadUsername method + * + * @expectedException SocketException + * @expectedExceptionMessage SMTP server did not accept the username. + * @return void + */ + public function testAuthBadUsername() { + $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n"); + $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("334 Login\r\n")); + $this->socket->expects($this->at(3))->method('write')->with("bWFyaw==\r\n"); + $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("535 5.7.8 Authentication failed\r\n")); + $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story')); + $this->SmtpTransport->auth(); + } + +/** + * testAuthBadPassword method + * + * @expectedException SocketException + * @expectedExceptionMessage SMTP server did not accept the password. + * @return void + */ + public function testAuthBadPassword() { + $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n"); + $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("334 Login\r\n")); + $this->socket->expects($this->at(3))->method('write')->with("bWFyaw==\r\n"); + $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("334 Pass\r\n")); + $this->socket->expects($this->at(6))->method('write')->with("c3Rvcnk=\r\n"); + $this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("535 5.7.8 Authentication failed\r\n")); + $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story')); + $this->SmtpTransport->auth(); + } + /** * testAuthNoAuth method *