PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/zendframework/zendframework/library/Zend/Mail/Protocol/Smtp/Auth/Crammd5.php

https://bitbucket.org/pcelta/zf2
PHP | 159 lines | 70 code | 20 blank | 69 comment | 7 complexity | 6d5657ed2eb0ac265c66f2aa8f48ed55 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Mail
  9. */
  10. namespace Zend\Mail\Protocol\Smtp\Auth;
  11. use Zend\Mail\Protocol\Smtp;
  12. /**
  13. * Performs CRAM-MD5 authentication
  14. *
  15. * @category Zend
  16. * @package Zend_Mail
  17. * @subpackage Protocol
  18. */
  19. class Crammd5 extends Smtp
  20. {
  21. /**
  22. * @var string
  23. */
  24. protected $username;
  25. /**
  26. * @var string
  27. */
  28. protected $password;
  29. /**
  30. * Constructor.
  31. *
  32. * All parameters may be passed as an array to the first argument of the
  33. * constructor. If so,
  34. *
  35. * @param string|array $host (Default: 127.0.0.1)
  36. * @param null|int $port (Default: null)
  37. * @param null|array $config Auth-specific parameters
  38. */
  39. public function __construct($host = '127.0.0.1', $port = null, $config = null)
  40. {
  41. // Did we receive a configuration array?
  42. $origConfig = $config;
  43. if (is_array($host)) {
  44. // Merge config array with principal array, if provided
  45. if (is_array($config)) {
  46. $config = array_replace_recursive($host, $config);
  47. } else {
  48. $config = $host;
  49. }
  50. }
  51. if (is_array($config)) {
  52. if (isset($config['username'])) {
  53. $this->setUsername($config['username']);
  54. }
  55. if (isset($config['password'])) {
  56. $this->setPassword($config['password']);
  57. }
  58. }
  59. // Call parent with original arguments
  60. parent::__construct($host, $port, $origConfig);
  61. }
  62. /**
  63. * @todo Perform CRAM-MD5 authentication with supplied credentials
  64. *
  65. */
  66. public function auth()
  67. {
  68. // Ensure AUTH has not already been initiated.
  69. parent::auth();
  70. $this->_send('AUTH CRAM-MD5');
  71. $challenge = $this->_expect(334);
  72. $challenge = base64_decode($challenge);
  73. $digest = $this->_hmacMd5($this->getPassword(), $challenge);
  74. $this->_send(base64_encode($this->getUsername() . ' ' . $digest));
  75. $this->_expect(235);
  76. $this->auth = true;
  77. }
  78. /**
  79. * Set value for username
  80. *
  81. * @param string $username
  82. * @return Crammd5
  83. */
  84. public function setUsername($username)
  85. {
  86. $this->username = $username;
  87. return $this;
  88. }
  89. /**
  90. * Get username
  91. *
  92. * @return string
  93. */
  94. public function getUsername()
  95. {
  96. return $this->username;
  97. }
  98. /**
  99. * Set value for password
  100. *
  101. * @param string $password
  102. * @return Crammd5
  103. */
  104. public function setPassword($password)
  105. {
  106. $this->password = $password;
  107. return $this;
  108. }
  109. /**
  110. * Get password
  111. *
  112. * @return string
  113. */
  114. public function getPassword()
  115. {
  116. return $this->password;
  117. }
  118. /**
  119. * Prepare CRAM-MD5 response to server's ticket
  120. *
  121. * @param string $key Challenge key (usually password)
  122. * @param string $data Challenge data
  123. * @param int $block Length of blocks
  124. * @return string
  125. */
  126. protected function _hmacMd5($key, $data, $block = 64)
  127. {
  128. if (strlen($key) > 64) {
  129. $key = pack('H32', md5($key));
  130. } elseif (strlen($key) < 64) {
  131. $key = str_pad($key, $block, "\0");
  132. }
  133. $k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64);
  134. $k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64);
  135. $inner = pack('H32', md5($k_ipad . $data));
  136. $digest = md5($k_opad . $inner);
  137. return $digest;
  138. }
  139. }