Projet

Général

Profil

Télécharger (4,94 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / ntlm_sasl_client.inc @ 34bb5eb0

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

    
9
define("SASL_NTLM_STATE_START",             0);
10
define("SASL_NTLM_STATE_IDENTIFY_DOMAIN",   1);
11
define("SASL_NTLM_STATE_RESPOND_CHALLENGE", 2);
12
define("SASL_NTLM_STATE_DONE",              3);
13

    
14
class ntlm_sasl_client_class
15
{
16
	var $credentials=array();
17
	var $state=SASL_NTLM_STATE_START;
18

    
19
	Function Initialize(&$client)
20
	{
21
		if(!function_exists($function="mcrypt_encrypt")
22
               || !function_exists($function="hash"))
23
		{
24
			$extensions=array(
25
				"mcrypt_encrypt"=>"mcrypt",
26
                               "hash"=>"hash"
27
			);
28
			$client->error="the extension ".$extensions[$function]." required by the NTLM SASL client class is not available in this PHP configuration";
29
			return(0);
30
		}
31
		return(1);
32
	}
33

    
34
	Function ASCIIToUnicode($ascii)
35
	{
36
		for($unicode="",$a=0;$a<strlen($ascii);$a++)
37
			$unicode.=substr($ascii,$a,1).chr(0);
38
		return($unicode);
39
	}
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

    
62
	Function NTLMResponse($challenge,$password)
63
	{
64
		$unicode=$this->ASCIIToUnicode($password);
65
               $md4=hash("md4", $unicode);
66
		$padded=$md4.str_repeat(chr(0),21-strlen($md4));
67
		$iv_size=mcrypt_get_iv_size(MCRYPT_DES,MCRYPT_MODE_ECB);
68
		$iv=mcrypt_create_iv($iv_size,MCRYPT_RAND);
69
		for($response="",$third=0;$third<21;$third+=7)
70
		{
71
			for($packed="",$p=$third;$p<$third+7;$p++)
72
				$packed.=str_pad(decbin(ord(substr($padded,$p,1))),8,"0",STR_PAD_LEFT);
73
			for($key="",$p=0;$p<strlen($packed);$p+=7)
74
			{
75
				$s=substr($packed,$p,7);
76
				$b=$s.((substr_count($s,"1") % 2) ? "0" : "1");
77
				$key.=chr(bindec($b));
78
			}
79
			$ciphertext=mcrypt_encrypt(MCRYPT_DES,$key,$challenge,MCRYPT_MODE_ECB,$iv);
80
			$response.=$ciphertext;
81
		}
82
		return $response;
83
	}
84

    
85
	Function TypeMsg3($ntlm_response,$user,$domain,$workstation)
86
	{
87
		$domain_unicode=$this->ASCIIToUnicode($domain);
88
		$domain_length=strlen($domain_unicode);
89
		$domain_offset=64;
90
		$user_unicode=$this->ASCIIToUnicode($user);
91
		$user_length=strlen($user_unicode);
92
		$user_offset=$domain_offset+$domain_length;
93
		$workstation_unicode=$this->ASCIIToUnicode($workstation);
94
		$workstation_length=strlen($workstation_unicode);
95
		$workstation_offset=$user_offset+$user_length;
96
		$lm="";
97
		$lm_length=strlen($lm);
98
		$lm_offset=$workstation_offset+$workstation_length;
99
		$ntlm=$ntlm_response;
100
		$ntlm_length=strlen($ntlm);
101
		$ntlm_offset=$lm_offset+$lm_length;
102
		$session="";
103
		$session_length=strlen($session);
104
		$session_offset=$ntlm_offset+$ntlm_length;
105
		return(
106
			"NTLMSSP\0".
107
			"\x03\x00\x00\x00".
108
			pack("v",$lm_length).
109
			pack("v",$lm_length).
110
			pack("V",$lm_offset).
111
			pack("v",$ntlm_length).
112
			pack("v",$ntlm_length).
113
			pack("V",$ntlm_offset).
114
			pack("v",$domain_length).
115
			pack("v",$domain_length).
116
			pack("V",$domain_offset).
117
			pack("v",$user_length).
118
			pack("v",$user_length).
119
			pack("V",$user_offset).
120
			pack("v",$workstation_length).
121
			pack("v",$workstation_length).
122
			pack("V",$workstation_offset).
123
			pack("v",$session_length).
124
			pack("v",$session_length).
125
			pack("V",$session_offset).
126
			"\x01\x02\x00\x00".
127
			$domain_unicode.
128
			$user_unicode.
129
			$workstation_unicode.
130
			$lm.
131
			$ntlm
132
		);
133
	}
134

    
135
	Function Start(&$client, &$message, &$interactions)
136
	{
137
		if($this->state!=SASL_NTLM_STATE_START)
138
		{
139
			$client->error="NTLM authentication state is not at the start";
140
			return(SASL_FAIL);
141
		}
142
		$this->credentials=array(
143
			"user"=>"",
144
			"password"=>"",
145
			"realm"=>"",
146
			"workstation"=>""
147
		);
148
		$defaults=array();
149
		$status=$client->GetCredentials($this->credentials,$defaults,$interactions);
150
		if($status==SASL_CONTINUE)
151
			$this->state=SASL_NTLM_STATE_IDENTIFY_DOMAIN;
152
		Unset($message);
153
		return($status);
154
	}
155

    
156
	Function Step(&$client, $response, &$message, &$interactions)
157
	{
158
		switch($this->state)
159
		{
160
			case SASL_NTLM_STATE_IDENTIFY_DOMAIN:
161
				$message=$this->TypeMsg1($this->credentials["realm"],$this->credentials["workstation"]);
162
				$this->state=SASL_NTLM_STATE_RESPOND_CHALLENGE;
163
				break;
164
			case SASL_NTLM_STATE_RESPOND_CHALLENGE:
165
				$ntlm_response=$this->NTLMResponse(substr($response,24,8),$this->credentials["password"]);
166
				$message=$this->TypeMsg3($ntlm_response,$this->credentials["user"],$this->credentials["realm"],$this->credentials["workstation"]);
167
				$this->state=SASL_NTLM_STATE_DONE;
168
				break;
169
			case SASL_NTLM_STATE_DONE:
170
				$client->error="NTLM authentication was finished without success";
171
				return(SASL_FAIL);
172
			default:
173
				$client->error="invalid NTLM authentication step state";
174
				return(SASL_FAIL);
175
		}
176
		return(SASL_CONTINUE);
177
	}
178
};
179

    
180
?>
(34-34/67)