1<?php 2 3/** 4 * Swift Mailer CRAM-MD5 Authenticator Mechanism 5 * Please read the LICENSE file 6 * @author Chris Corbyn <chris@w3style.co.uk> 7 * @package Swift_Authenticator 8 * @license GNU Lesser General Public License 9 */ 10 11require_once dirname(__FILE__) . "/../ClassLoader.php"; 12Swift_ClassLoader::load("Swift_Authenticator"); 13 14/** 15 * Swift CRAM-MD5 Authenticator 16 * This form of authentication is a secure challenge-response method 17 * @package Swift_Authenticator 18 * @author Chris Corbyn <chris@w3style.co.uk> 19 */ 20class Swift_Authenticator_CRAMMD5 implements Swift_Authenticator 21{ 22 /** 23 * Try to authenticate using the username and password 24 * Returns false on failure 25 * @param string The username 26 * @param string The password 27 * @param Swift The instance of Swift this authenticator is used in 28 * @return boolean 29 */ 30 public function isAuthenticated($user, $pass, Swift $swift) 31 { 32 try { 33 $encoded_challenge = substr($swift->command("AUTH CRAM-MD5", 334)->getString(), 4); 34 $challenge = base64_decode($encoded_challenge); 35 $response = base64_encode($user . " " . self::generateCRAMMD5Hash($pass, $challenge)); 36 $swift->command($response, 235); 37 } catch (Swift_ConnectionException $e) { 38 $swift->reset(); 39 return false; 40 } 41 return true; 42 } 43 /** 44 * Return the name of the AUTH extension this is for 45 * @return string 46 */ 47 public function getAuthExtensionName() 48 { 49 return "CRAM-MD5"; 50 } 51 /** 52 * Generate a CRAM-MD5 hash from a challenge 53 * @param string The string to get a hash from 54 * @param string The challenge to use to make the hash 55 * @return string 56 */ 57 public static function generateCRAMMD5Hash($password, $challenge) 58 { 59 if (strlen($password) > 64) 60 $password = pack('H32', md5($password)); 61 62 if (strlen($password) < 64) 63 $password = str_pad($password, 64, chr(0)); 64 65 $k_ipad = substr($password, 0, 64) ^ str_repeat(chr(0x36), 64); 66 $k_opad = substr($password, 0, 64) ^ str_repeat(chr(0x5C), 64); 67 68 $inner = pack('H32', md5($k_ipad.$challenge)); 69 $digest = md5($k_opad.$inner); 70 71 return $digest; 72 } 73} 74