Skip to content
This repository
Browse code

adding a tls option to SmtpTransport to support TLS SMTP servers like…

… MS Exchange 2010
  • Loading branch information...
commit 55c92065c674a9241b2ee36c32865a85b75d4443 1 parent 27a895d
Jorge M. González Martín authored July 21, 2012
13  lib/Cake/Network/Email/SmtpTransport.php
@@ -79,7 +79,8 @@ public function config($config = array()) {
79 79
 			'timeout' => 30,
80 80
 			'username' => null,
81 81
 			'password' => null,
82  
-			'client' => null
  82
+			'client' => null,
  83
+			'tls' => false
83 84
 		);
84 85
 		$this->_config = $config + $default;
85 86
 	}
@@ -107,7 +108,15 @@ protected function _connect() {
107 108
 
108 109
 		try {
109 110
 			$this->_smtpSend("EHLO {$host}", '250');
  111
+			if ($this->_config['tls']) {
  112
+				$this->_smtpSend("STARTTLS", '220');
  113
+				$this->_socket->enableCrypto('tls');
  114
+				$this->_smtpSend("EHLO {$host}", '250');
  115
+			}
110 116
 		} catch (SocketException $e) {
  117
+			if ($this->_config['tls']) {
  118
+				throw new SocketException(__d('cake_dev', 'SMTP server did not accept the connection or trying to connect to non TLS SMTP server using TLS.'));
  119
+			}
111 120
 			try {
112 121
 				$this->_smtpSend("HELO {$host}", '250');
113 122
 			} catch (SocketException $e2) {
@@ -132,6 +141,8 @@ protected function _auth() {
132 141
 				if (!$this->_smtpSend(base64_encode($this->_config['password']), '235')) {
133 142
 					throw new SocketException(__d('cake_dev', 'SMTP server did not accept the password.'));
134 143
 				}
  144
+			} elseif ($authRequired == '504') {
  145
+				throw new SocketException(__d('cake_dev', 'SMTP authentication method not allowed, check if SMTP server requires TLS'));
135 146
 			} elseif ($authRequired != '503') {
136 147
 				throw new SocketException(__d('cake_dev', 'SMTP does not require authentication.'));
137 148
 			}
66  lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php
@@ -81,7 +81,7 @@ class SmtpTransportTest extends CakeTestCase {
81 81
  */
82 82
 	public function setUp() {
83 83
 		if (!class_exists('MockSocket')) {
84  
-			$this->getMock('CakeSocket', array('read', 'write', 'connect'), array(), 'MockSocket');
  84
+			$this->getMock('CakeSocket', array('read', 'write', 'connect', 'enableCrypto'), array(), 'MockSocket');
85 85
 		}
86 86
 		$this->socket = new MockSocket();
87 87
 
@@ -106,6 +106,70 @@ public function testConnectEhlo() {
106 106
 	}
107 107
 
108 108
 /**
  109
+ * testConnectEhloTls method
  110
+ *
  111
+ * @return void
  112
+ */
  113
+	public function testConnectEhloTls() {
  114
+		$this->SmtpTransport->config(array('tls' => true));
  115
+		$this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
  116
+		$this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
  117
+		$this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
  118
+		$this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
  119
+		$this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
  120
+		$this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250 Accepted\r\n"));
  121
+		$this->socket->expects($this->at(5))->method('write')->with("STARTTLS\r\n");
  122
+		$this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
  123
+		$this->socket->expects($this->at(7))->method('read')->will($this->returnValue("220 Server ready\r\n"));
  124
+		$this->socket->expects($this->at(8))->method('other')->with('tls')->will($this->returnValue(true));
  125
+		$this->socket->expects($this->at(9))->method('write')->with("EHLO localhost\r\n");
  126
+		$this->socket->expects($this->at(10))->method('read')->will($this->returnValue(false));
  127
+		$this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250 Accepted\r\n"));
  128
+		$this->SmtpTransport->connect();
  129
+	}
  130
+
  131
+/**
  132
+ * testConnectEhloTlsOnNonTlsServer method
  133
+ *
  134
+ * @return void
  135
+ */
  136
+	public function testConnectEhloTlsOnNonTlsServer() {
  137
+		$this->SmtpTransport->config(array('tls' => true));
  138
+		$this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
  139
+		$this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
  140
+		$this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
  141
+		$this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
  142
+		$this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
  143
+		$this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250 Accepted\r\n"));
  144
+		$this->socket->expects($this->at(5))->method('write')->with("STARTTLS\r\n");
  145
+		$this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
  146
+		$this->socket->expects($this->at(7))->method('read')->will($this->returnValue("500 5.3.3 Unrecognized command\r\n"));
  147
+		$this->setExpectedException('SocketException');
  148
+		$this->SmtpTransport->connect();
  149
+	}
  150
+	
  151
+/**
  152
+ * testConnectEhloNoTlsOnRequiredTlsServer method
  153
+ *
  154
+ * @return void
  155
+ */
  156
+	public function testConnectEhloNoTlsOnRequiredTlsServer() {
  157
+		$this->SmtpTransport->config(array('tls' => false, 'username' => 'user', 'password' => 'pass'));
  158
+		$this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
  159
+		$this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
  160
+		$this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
  161
+		$this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
  162
+		$this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
  163
+		$this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250 Accepted\r\n"));
  164
+		$this->socket->expects($this->at(5))->method('read')->with("AUTH LOGIN\r\n");
  165
+		$this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
  166
+		$this->socket->expects($this->at(7))->method('read')->will($this->returnValue("504 5.7.4 Unrecognized authentication type\r\n"));
  167
+		$this->setExpectedException('SocketException');
  168
+		$this->SmtpTransport->connect();
  169
+		$this->SmtpTransport->auth();
  170
+	}
  171
+	
  172
+/**
109 173
  * testConnectHelo method
110 174
  *
111 175
  * @return void

0 notes on commit 55c9206

Please sign in to comment.
Something went wrong with that request. Please try again.