PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/phpmailer/extras/ntlm_sasl_client.php

https://gitlab.com/x33n/ampache
PHP | 185 lines | 164 code | 10 blank | 11 comment | 8 complexity | 362d79dfcbd380c9595c94011310049e MD5 | raw file
  1. <?php
  2. /*
  3. * ntlm_sasl_client.php
  4. *
  5. * @(#) $Id: ntlm_sasl_client.php,v 1.3 2004/11/17 08:00:37 mlemos Exp $
  6. *
  7. **
  8. ** Source: http://www.phpclasses.org/browse/file/7495.html
  9. ** License: BSD (http://www.phpclasses.org/package/1888-PHP-Single-API-for-standard-authentication-mechanisms.html)
  10. ** Bundled with Permission
  11. **
  12. */
  13. define("SASL_NTLM_STATE_START", 0);
  14. define("SASL_NTLM_STATE_IDENTIFY_DOMAIN", 1);
  15. define("SASL_NTLM_STATE_RESPOND_CHALLENGE", 2);
  16. define("SASL_NTLM_STATE_DONE", 3);
  17. class ntlm_sasl_client_class
  18. {
  19. var $credentials=array();
  20. var $state=SASL_NTLM_STATE_START;
  21. Function Initialize(&$client)
  22. {
  23. if(!function_exists($function="mcrypt_encrypt")
  24. || !function_exists($function="mhash"))
  25. {
  26. $extensions=array(
  27. "mcrypt_encrypt"=>"mcrypt",
  28. "mhash"=>"mhash"
  29. );
  30. $client->error="the extension ".$extensions[$function]." required by the NTLM SASL client class is not available in this PHP configuration";
  31. return(0);
  32. }
  33. return(1);
  34. }
  35. Function ASCIIToUnicode($ascii)
  36. {
  37. for($unicode="",$a=0;$a<strlen($ascii);$a++)
  38. $unicode.=substr($ascii,$a,1).chr(0);
  39. return($unicode);
  40. }
  41. Function TypeMsg1($domain,$workstation)
  42. {
  43. $domain_length=strlen($domain);
  44. $workstation_length=strlen($workstation);
  45. $workstation_offset=32;
  46. $domain_offset=$workstation_offset+$workstation_length;
  47. return(
  48. "NTLMSSP\0".
  49. "\x01\x00\x00\x00".
  50. "\x07\x32\x00\x00".
  51. pack("v",$domain_length).
  52. pack("v",$domain_length).
  53. pack("V",$domain_offset).
  54. pack("v",$workstation_length).
  55. pack("v",$workstation_length).
  56. pack("V",$workstation_offset).
  57. $workstation.
  58. $domain
  59. );
  60. }
  61. Function NTLMResponse($challenge,$password)
  62. {
  63. $unicode=$this->ASCIIToUnicode($password);
  64. $md4=mhash(MHASH_MD4,$unicode);
  65. $padded=$md4.str_repeat(chr(0),21-strlen($md4));
  66. $iv_size=mcrypt_get_iv_size(MCRYPT_DES,MCRYPT_MODE_ECB);
  67. $iv=mcrypt_create_iv($iv_size,MCRYPT_RAND);
  68. for($response="",$third=0;$third<21;$third+=7)
  69. {
  70. for($packed="",$p=$third;$p<$third+7;$p++)
  71. $packed.=str_pad(decbin(ord(substr($padded,$p,1))),8,"0",STR_PAD_LEFT);
  72. for($key="",$p=0;$p<strlen($packed);$p+=7)
  73. {
  74. $s=substr($packed,$p,7);
  75. $b=$s.((substr_count($s,"1") % 2) ? "0" : "1");
  76. $key.=chr(bindec($b));
  77. }
  78. $ciphertext=mcrypt_encrypt(MCRYPT_DES,$key,$challenge,MCRYPT_MODE_ECB,$iv);
  79. $response.=$ciphertext;
  80. }
  81. return $response;
  82. }
  83. Function TypeMsg3($ntlm_response,$user,$domain,$workstation)
  84. {
  85. $domain_unicode=$this->ASCIIToUnicode($domain);
  86. $domain_length=strlen($domain_unicode);
  87. $domain_offset=64;
  88. $user_unicode=$this->ASCIIToUnicode($user);
  89. $user_length=strlen($user_unicode);
  90. $user_offset=$domain_offset+$domain_length;
  91. $workstation_unicode=$this->ASCIIToUnicode($workstation);
  92. $workstation_length=strlen($workstation_unicode);
  93. $workstation_offset=$user_offset+$user_length;
  94. $lm="";
  95. $lm_length=strlen($lm);
  96. $lm_offset=$workstation_offset+$workstation_length;
  97. $ntlm=$ntlm_response;
  98. $ntlm_length=strlen($ntlm);
  99. $ntlm_offset=$lm_offset+$lm_length;
  100. $session="";
  101. $session_length=strlen($session);
  102. $session_offset=$ntlm_offset+$ntlm_length;
  103. return(
  104. "NTLMSSP\0".
  105. "\x03\x00\x00\x00".
  106. pack("v",$lm_length).
  107. pack("v",$lm_length).
  108. pack("V",$lm_offset).
  109. pack("v",$ntlm_length).
  110. pack("v",$ntlm_length).
  111. pack("V",$ntlm_offset).
  112. pack("v",$domain_length).
  113. pack("v",$domain_length).
  114. pack("V",$domain_offset).
  115. pack("v",$user_length).
  116. pack("v",$user_length).
  117. pack("V",$user_offset).
  118. pack("v",$workstation_length).
  119. pack("v",$workstation_length).
  120. pack("V",$workstation_offset).
  121. pack("v",$session_length).
  122. pack("v",$session_length).
  123. pack("V",$session_offset).
  124. "\x01\x02\x00\x00".
  125. $domain_unicode.
  126. $user_unicode.
  127. $workstation_unicode.
  128. $lm.
  129. $ntlm
  130. );
  131. }
  132. Function Start(&$client, &$message, &$interactions)
  133. {
  134. if($this->state!=SASL_NTLM_STATE_START)
  135. {
  136. $client->error="NTLM authentication state is not at the start";
  137. return(SASL_FAIL);
  138. }
  139. $this->credentials=array(
  140. "user"=>"",
  141. "password"=>"",
  142. "realm"=>"",
  143. "workstation"=>""
  144. );
  145. $defaults=array();
  146. $status=$client->GetCredentials($this->credentials,$defaults,$interactions);
  147. if($status==SASL_CONTINUE)
  148. $this->state=SASL_NTLM_STATE_IDENTIFY_DOMAIN;
  149. Unset($message);
  150. return($status);
  151. }
  152. Function Step(&$client, $response, &$message, &$interactions)
  153. {
  154. switch($this->state)
  155. {
  156. case SASL_NTLM_STATE_IDENTIFY_DOMAIN:
  157. $message=$this->TypeMsg1($this->credentials["realm"],$this->credentials["workstation"]);
  158. $this->state=SASL_NTLM_STATE_RESPOND_CHALLENGE;
  159. break;
  160. case SASL_NTLM_STATE_RESPOND_CHALLENGE:
  161. $ntlm_response=$this->NTLMResponse(substr($response,24,8),$this->credentials["password"]);
  162. $message=$this->TypeMsg3($ntlm_response,$this->credentials["user"],$this->credentials["realm"],$this->credentials["workstation"]);
  163. $this->state=SASL_NTLM_STATE_DONE;
  164. break;
  165. case SASL_NTLM_STATE_DONE:
  166. $client->error="NTLM authentication was finished without success";
  167. return(SASL_FAIL);
  168. default:
  169. $client->error="invalid NTLM authentication step state";
  170. return(SASL_FAIL);
  171. }
  172. return(SASL_CONTINUE);
  173. }
  174. };
  175. ?>