9define(
"SASL_NTLM_STATE_START", 0);
 
   10define(
"SASL_NTLM_STATE_IDENTIFY_DOMAIN", 1);
 
   11define(
"SASL_NTLM_STATE_RESPOND_CHALLENGE", 2);
 
   12define(
"SASL_NTLM_STATE_DONE", 3);
 
   13define(
"SASL_FAIL", -1);
 
   14define(
"SASL_CONTINUE", 1);
 
   23        if (!function_exists(
$function = 
"mcrypt_encrypt")
 
   27                "mcrypt_encrypt" => 
"mcrypt",
 
   31                " required by the NTLM SASL client class is not available in this PHP configuration";
 
   39        for ($unicode = 
"", $a = 0; $a < strlen($ascii); $a++) {
 
   40            $unicode .= substr($ascii, $a, 1) . chr(0);
 
   47        $domain_length = strlen(
$domain);
 
   48        $workstation_length = strlen($workstation);
 
   49        $workstation_offset = 32;
 
   50        $domain_offset = $workstation_offset + $workstation_length;
 
   55            pack(
"v", $domain_length) .
 
   56            pack(
"v", $domain_length) .
 
   57            pack(
"V", $domain_offset) .
 
   58            pack(
"v", $workstation_length) .
 
   59            pack(
"v", $workstation_length) .
 
   60            pack(
"V", $workstation_offset) .
 
   69        $md4 = mhash(MHASH_MD4, $unicode);
 
   70        $padded = $md4 . str_repeat(chr(0), 21 - strlen($md4));
 
   71        $iv_size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);
 
   72        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
 
   73        for (
$response = 
"", $third = 0; $third < 21; $third += 7) {
 
   74            for ($packed = 
"", $p = $third; $p < $third + 7; $p++) {
 
   75                $packed .= str_pad(decbin(ord(substr($padded, $p, 1))), 8, 
"0", STR_PAD_LEFT);
 
   77            for (
$key = 
"", $p = 0; $p < strlen($packed); $p += 7) {
 
   78                $s = substr($packed, $p, 7);
 
   79                $b = 
$s . ((substr_count(
$s, 
"1") % 2) ? 
"0" : 
"1");
 
   80                $key .= chr(bindec($b));
 
   82            $ciphertext = mcrypt_encrypt(MCRYPT_DES, 
$key, $challenge, MCRYPT_MODE_ECB, $iv);
 
   91        $domain_length = strlen($domain_unicode);
 
   94        $user_length = strlen($user_unicode);
 
   95        $user_offset = $domain_offset + $domain_length;
 
   97        $workstation_length = strlen($workstation_unicode);
 
   98        $workstation_offset = $user_offset + $user_length;
 
  100        $lm_length = strlen($lm);
 
  101        $lm_offset = $workstation_offset + $workstation_length;
 
  102        $ntlm = $ntlm_response;
 
  103        $ntlm_length = strlen($ntlm);
 
  104        $ntlm_offset = $lm_offset + $lm_length;
 
  107        $session_offset = $ntlm_offset + $ntlm_length;
 
  111            pack(
"v", $lm_length) .
 
  112            pack(
"v", $lm_length) .
 
  113            pack(
"V", $lm_offset) .
 
  114            pack(
"v", $ntlm_length) .
 
  115            pack(
"v", $ntlm_length) .
 
  116            pack(
"V", $ntlm_offset) .
 
  117            pack(
"v", $domain_length) .
 
  118            pack(
"v", $domain_length) .
 
  119            pack(
"V", $domain_offset) .
 
  120            pack(
"v", $user_length) .
 
  121            pack(
"v", $user_length) .
 
  122            pack(
"V", $user_offset) .
 
  123            pack(
"v", $workstation_length) .
 
  124            pack(
"v", $workstation_length) .
 
  125            pack(
"V", $workstation_offset) .
 
  126            pack(
"v", $session_length) .
 
  127            pack(
"v", $session_length) .
 
  128            pack(
"V", $session_offset) .
 
  132            $workstation_unicode .
 
  141            $client->error = 
"NTLM authentication state is not at the start";
 
  144        $this->credentials = array(
 
  151        $status = 
$client->GetCredentials($this->credentials, $defaults, $interactions);
 
  161        switch ($this->state) {
 
  163                $message = $this->
typeMsg1($this->credentials[
"realm"], $this->credentials[
"workstation"]);
 
  170                    $this->credentials[
"user"],
 
  171                    $this->credentials[
"realm"],
 
  172                    $this->credentials[
"workstation"]
 
  177                $client->error = 
"NTLM authentication was finished without success";
 
  180                $client->error = 
"invalid NTLM authentication step state";
 
if(!array_key_exists('domain', $_REQUEST)) $domain
An exception for terminatinating execution or to throw for unit testing.
step(&$client, $response, &$message, &$interactions)
NTLMResponse($challenge, $password)
start(&$client, &$message, &$interactions)
typeMsg3($ntlm_response, $user, $domain, $workstation)
typeMsg1($domain, $workstation)
catch(Exception $e) $message
const SASL_NTLM_STATE_DONE
const SASL_NTLM_STATE_START
const SASL_NTLM_STATE_IDENTIFY_DOMAIN
const SASL_NTLM_STATE_RESPOND_CHALLENGE