diff --git a/class.smtp.php b/class.smtp.php
index e5d86bc1..ddb624a6 100644
--- a/class.smtp.php
+++ b/class.smtp.php
@@ -414,10 +414,81 @@ class SMTP {
return false;
}
break;
+ case 'CRAM-MD5':
+ // Start authentication
+ fputs($this->smtp_conn,"AUTH CRAM-MD5" . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($code != 334) {
+ $this->error =
+ array("error" => "AUTH not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
');
+ }
+ return false;
+ }
+
+ // Get the challenge
+ $challenge = base64_decode(substr($rply,4));
+
+ // Build the response
+ $response = $username . ' ' . $this->hmac($challenge, $password);
+
+ // Send encoded credentials
+ fputs($this->smtp_conn, base64_encode($response) . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($code != 334) {
+ $this->error =
+ array("error" => "Credentials not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
');
+ }
+ return false;
+ }
+ break;
}
return true;
}
+ /**
+ * Works like hash_hmac('md5', $data, $key) in case that function is not available
+ * @access private
+ * @return string
+ */
+ private function hmac($data, $key) {
+ if (function_exists('hash_hmac')) {
+ return hash_hmac('md5', $data, $key);
+ }
+
+ // The following borrowed from http://php.net/manual/en/function.mhash.php#27225
+
+ // RFC 2104 HMAC implementation for php.
+ // Creates an md5 HMAC.
+ // Eliminates the need to install mhash to compute a HMAC
+ // Hacked by Lance Rushing
+
+ $b = 64; // byte length for md5
+ if (strlen($key) > $b) {
+ $key = pack("H*",md5($key));
+ }
+ $key = str_pad($key, $b, chr(0x00));
+ $ipad = str_pad('', $b, chr(0x36));
+ $opad = str_pad('', $b, chr(0x5c));
+ $k_ipad = $key ^ $ipad ;
+ $k_opad = $key ^ $opad;
+
+ return md5($k_opad . pack("H*",md5($k_ipad . $data)));
+ }
+
/**
* Returns true if connected to a server otherwise false
* @access public