1 |
--- ppp-2.4.4.orig/pppd/chap_ms.c 2006-05-21 07:56:40.000000000 -0400 |
2 |
+++ ppp-2.4.4/pppd/chap_ms.c 2006-11-21 17:19:28.000000000 -0500 |
3 |
@@ -100,25 +100,18 @@ |
4 |
static void ascii2unicode __P((char[], int, u_char[])); |
5 |
static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE])); |
6 |
static void ChallengeResponse __P((u_char *, u_char *, u_char[24])); |
7 |
-static void ChapMS_NT __P((u_char *, char *, int, u_char[24])); |
8 |
-static void ChapMS2_NT __P((u_char *, u_char[16], char *, char *, int, |
9 |
+static void ChapMS_NT __P((u_char *, u_char[16], u_char[24])); |
10 |
+static void ChapMS2_NT __P((u_char *, u_char[16], char *, u_char[16], |
11 |
u_char[24])); |
12 |
static void GenerateAuthenticatorResponsePlain |
13 |
- __P((char*, int, u_char[24], u_char[16], u_char *, |
14 |
+ __P((u_char[16], u_char[24], u_char[16], u_char *, |
15 |
char *, u_char[41])); |
16 |
-#ifdef MSLANMAN |
17 |
-static void ChapMS_LANMan __P((u_char *, char *, int, u_char *)); |
18 |
-#endif |
19 |
- |
20 |
#ifdef MPPE |
21 |
-static void Set_Start_Key __P((u_char *, char *, int)); |
22 |
-static void SetMasterKeys __P((char *, int, u_char[24], int)); |
23 |
+static void Set_Start_Key __P((u_char *, u_char[16])); |
24 |
+static void SetMasterKeys __P((u_char[16], u_char[24], int)); |
25 |
#endif |
26 |
|
27 |
-#ifdef MSLANMAN |
28 |
-bool ms_lanman = 0; /* Use LanMan password instead of NT */ |
29 |
- /* Has meaning only with MS-CHAP challenges */ |
30 |
-#endif |
31 |
+bool chapms_secret_cleartext = 1; |
32 |
|
33 |
#ifdef MPPE |
34 |
u_char mppe_send_key[MPPE_MAX_KEY_LEN]; |
35 |
@@ -152,6 +145,8 @@ |
36 |
{ "mschap2-peer-challenge", o_string, &mschap2_peer_challenge, |
37 |
"specify CHAP peer challenge" }, |
38 |
#endif |
39 |
+ { "chapms_secret_cleartext", o_bool, &chapms_secret_cleartext, |
40 |
+ "chap secrets is cleartext (otherwise hex encoded NT-hash)" }, |
41 |
{ NULL } |
42 |
}; |
43 |
|
44 |
@@ -185,6 +180,40 @@ |
45 |
random_bytes(challenge, 16); |
46 |
} |
47 |
|
48 |
+static bool |
49 |
+secret_to_passwordhash(unsigned char *secret, int secret_len, |
50 |
+ u_char PasswordHash[MD4_SIGNATURE_SIZE]) |
51 |
+{ |
52 |
+ if (chapms_secret_cleartext) |
53 |
+ { |
54 |
+ /* secret is cleartext - convert to NT hash */ |
55 |
+ u_char unicodePassword[MAX_NT_PASSWORD * 2]; |
56 |
+ |
57 |
+ /* Hash the Unicode version of the secret (== password). */ |
58 |
+ ascii2unicode(secret, secret_len, unicodePassword); |
59 |
+ NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); |
60 |
+ } |
61 |
+ else |
62 |
+ { |
63 |
+ /* convert hex encoded NT hash into binary */ |
64 |
+ int i; |
65 |
+ unsigned char lonybble, hinybble; |
66 |
+ |
67 |
+ if (secret_len != 32) |
68 |
+ return 0; |
69 |
+ for (i = 0; i < 32; i++) { |
70 |
+ lonybble = toupper(secret[i]); |
71 |
+ if (lonybble < '0') |
72 |
+ return 0; |
73 |
+ if (lonybble > 'F') |
74 |
+ return 0; |
75 |
+ PasswordHash[i / 2] = (hinybble << 4) | lonybble; |
76 |
+ hinybble = lonybble; |
77 |
+ } |
78 |
+ } |
79 |
+ return 1; |
80 |
+} |
81 |
+ |
82 |
static int |
83 |
chapms_verify_response(int id, char *name, |
84 |
unsigned char *secret, int secret_len, |
85 |
@@ -194,6 +223,7 @@ |
86 |
unsigned char md[MS_CHAP_RESPONSE_LEN]; |
87 |
int diff; |
88 |
int challenge_len, response_len; |
89 |
+ u_char PasswordHash[MD4_SIGNATURE_SIZE]; |
90 |
|
91 |
challenge_len = *challenge++; /* skip length, is 8 */ |
92 |
response_len = *response++; |
93 |
@@ -208,8 +238,10 @@ |
94 |
} |
95 |
#endif |
96 |
|
97 |
+ if (!secret_to_passwordhash(secret, secret_len, PasswordHash)) |
98 |
+ goto bad; |
99 |
/* Generate the expected response. */ |
100 |
- ChapMS(challenge, (char *)secret, secret_len, md); |
101 |
+ ChapMS(challenge, PasswordHash, md); |
102 |
|
103 |
#ifdef MSLANMAN |
104 |
/* Determine which part of response to verify against */ |
105 |
@@ -241,6 +273,7 @@ |
106 |
{ |
107 |
unsigned char md[MS_CHAP2_RESPONSE_LEN]; |
108 |
char saresponse[MS_AUTH_RESPONSE_LENGTH+1]; |
109 |
+ u_char PasswordHash[MD4_SIGNATURE_SIZE]; |
110 |
int challenge_len, response_len; |
111 |
|
112 |
challenge_len = *challenge++; /* skip length, is 16 */ |
113 |
@@ -248,9 +281,12 @@ |
114 |
if (response_len != MS_CHAP2_RESPONSE_LEN) |
115 |
goto bad; /* not even the right length */ |
116 |
|
117 |
+ if (!secret_to_passwordhash(secret, secret_len, PasswordHash)) |
118 |
+ goto bad; |
119 |
+ |
120 |
/* Generate the expected response and our mutual auth. */ |
121 |
ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name, |
122 |
- (char *)secret, secret_len, md, |
123 |
+ PasswordHash, md, |
124 |
(unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR); |
125 |
|
126 |
/* compare MDs and send the appropriate status */ |
127 |
@@ -315,9 +351,12 @@ |
128 |
unsigned char *challenge, char *secret, int secret_len, |
129 |
unsigned char *private) |
130 |
{ |
131 |
+ u_char PasswordHash[MD4_SIGNATURE_SIZE]; |
132 |
+ |
133 |
challenge++; /* skip length, should be 8 */ |
134 |
*response++ = MS_CHAP_RESPONSE_LEN; |
135 |
- ChapMS(challenge, secret, secret_len, response); |
136 |
+ secret_to_passwordhash(secret, secret_len, PasswordHash); |
137 |
+ ChapMS(challenge, PasswordHash, response); |
138 |
} |
139 |
|
140 |
static void |
141 |
@@ -325,6 +364,9 @@ |
142 |
unsigned char *challenge, char *secret, int secret_len, |
143 |
unsigned char *private) |
144 |
{ |
145 |
+ u_char PasswordHash[MD4_SIGNATURE_SIZE]; |
146 |
+ |
147 |
+ secret_to_passwordhash(secret, secret_len, PasswordHash); |
148 |
challenge++; /* skip length, should be 16 */ |
149 |
*response++ = MS_CHAP2_RESPONSE_LEN; |
150 |
ChapMS2(challenge, |
151 |
@@ -333,7 +375,7 @@ |
152 |
#else |
153 |
NULL, |
154 |
#endif |
155 |
- our_name, secret, secret_len, response, private, |
156 |
+ our_name, PasswordHash, response, private, |
157 |
MS_CHAP2_AUTHENTICATEE); |
158 |
} |
159 |
|
160 |
@@ -530,60 +572,22 @@ |
161 |
} |
162 |
|
163 |
static void |
164 |
-ChapMS_NT(u_char *rchallenge, char *secret, int secret_len, |
165 |
+ChapMS_NT(u_char *rchallenge, u_char PasswordHash[MD4_SIGNATURE_SIZE], |
166 |
u_char NTResponse[24]) |
167 |
{ |
168 |
- u_char unicodePassword[MAX_NT_PASSWORD * 2]; |
169 |
- u_char PasswordHash[MD4_SIGNATURE_SIZE]; |
170 |
- |
171 |
- /* Hash the Unicode version of the secret (== password). */ |
172 |
- ascii2unicode(secret, secret_len, unicodePassword); |
173 |
- NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); |
174 |
- |
175 |
ChallengeResponse(rchallenge, PasswordHash, NTResponse); |
176 |
} |
177 |
|
178 |
static void |
179 |
ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username, |
180 |
- char *secret, int secret_len, u_char NTResponse[24]) |
181 |
+ u_char PasswordHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24]) |
182 |
{ |
183 |
- u_char unicodePassword[MAX_NT_PASSWORD * 2]; |
184 |
- u_char PasswordHash[MD4_SIGNATURE_SIZE]; |
185 |
u_char Challenge[8]; |
186 |
|
187 |
ChallengeHash(PeerChallenge, rchallenge, username, Challenge); |
188 |
- |
189 |
- /* Hash the Unicode version of the secret (== password). */ |
190 |
- ascii2unicode(secret, secret_len, unicodePassword); |
191 |
- NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); |
192 |
- |
193 |
ChallengeResponse(Challenge, PasswordHash, NTResponse); |
194 |
} |
195 |
|
196 |
-#ifdef MSLANMAN |
197 |
-static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ |
198 |
- |
199 |
-static void |
200 |
-ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, |
201 |
- unsigned char *response) |
202 |
-{ |
203 |
- int i; |
204 |
- u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ |
205 |
- u_char PasswordHash[MD4_SIGNATURE_SIZE]; |
206 |
- |
207 |
- /* LANMan password is case insensitive */ |
208 |
- BZERO(UcasePassword, sizeof(UcasePassword)); |
209 |
- for (i = 0; i < secret_len; i++) |
210 |
- UcasePassword[i] = (u_char)toupper(secret[i]); |
211 |
- (void) DesSetkey(UcasePassword + 0); |
212 |
- DesEncrypt( StdText, PasswordHash + 0 ); |
213 |
- (void) DesSetkey(UcasePassword + 7); |
214 |
- DesEncrypt( StdText, PasswordHash + 8 ); |
215 |
- ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]); |
216 |
-} |
217 |
-#endif |
218 |
- |
219 |
- |
220 |
void |
221 |
GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], |
222 |
u_char NTResponse[24], u_char PeerChallenge[16], |
223 |
@@ -632,18 +636,13 @@ |
224 |
|
225 |
static void |
226 |
GenerateAuthenticatorResponsePlain |
227 |
- (char *secret, int secret_len, |
228 |
+ (u_char PasswordHash[16], |
229 |
u_char NTResponse[24], u_char PeerChallenge[16], |
230 |
u_char *rchallenge, char *username, |
231 |
u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) |
232 |
{ |
233 |
- u_char unicodePassword[MAX_NT_PASSWORD * 2]; |
234 |
- u_char PasswordHash[MD4_SIGNATURE_SIZE]; |
235 |
u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; |
236 |
|
237 |
- /* Hash (x2) the Unicode version of the secret (== password). */ |
238 |
- ascii2unicode(secret, secret_len, unicodePassword); |
239 |
- NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); |
240 |
NTPasswordHash(PasswordHash, sizeof(PasswordHash), |
241 |
PasswordHashHash); |
242 |
|
243 |
@@ -680,15 +679,10 @@ |
244 |
* Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079) |
245 |
*/ |
246 |
static void |
247 |
-Set_Start_Key(u_char *rchallenge, char *secret, int secret_len) |
248 |
+Set_Start_Key(u_char *rchallenge, u_char PasswordHash[MD4_SIGNATURE_SIZE]) |
249 |
{ |
250 |
- u_char unicodePassword[MAX_NT_PASSWORD * 2]; |
251 |
- u_char PasswordHash[MD4_SIGNATURE_SIZE]; |
252 |
u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; |
253 |
|
254 |
- /* Hash (x2) the Unicode version of the secret (== password). */ |
255 |
- ascii2unicode(secret, secret_len, unicodePassword); |
256 |
- NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); |
257 |
NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); |
258 |
|
259 |
mppe_set_keys(rchallenge, PasswordHashHash); |
260 |
@@ -795,14 +789,9 @@ |
261 |
* Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) |
262 |
*/ |
263 |
static void |
264 |
-SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer) |
265 |
+SetMasterKeys(u_char PasswordHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24], int IsServer) |
266 |
{ |
267 |
- u_char unicodePassword[MAX_NT_PASSWORD * 2]; |
268 |
- u_char PasswordHash[MD4_SIGNATURE_SIZE]; |
269 |
u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; |
270 |
- /* Hash (x2) the Unicode version of the secret (== password). */ |
271 |
- ascii2unicode(secret, secret_len, unicodePassword); |
272 |
- NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); |
273 |
NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); |
274 |
mppe_set_keys2(PasswordHashHash, NTResponse, IsServer); |
275 |
} |
276 |
@@ -811,24 +800,17 @@ |
277 |
|
278 |
|
279 |
void |
280 |
-ChapMS(u_char *rchallenge, char *secret, int secret_len, |
281 |
+ChapMS(u_char *rchallenge, u_char PasswordHash[MD4_SIGNATURE_SIZE], |
282 |
unsigned char *response) |
283 |
{ |
284 |
BZERO(response, MS_CHAP_RESPONSE_LEN); |
285 |
|
286 |
- ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]); |
287 |
+ ChapMS_NT(rchallenge, PasswordHash, &response[MS_CHAP_NTRESP]); |
288 |
|
289 |
-#ifdef MSLANMAN |
290 |
- ChapMS_LANMan(rchallenge, secret, secret_len, &response); |
291 |
- |
292 |
- /* preferred method is set by option */ |
293 |
- response[MS_CHAP_USENT] = !ms_lanman; |
294 |
-#else |
295 |
response[MS_CHAP_USENT] = 1; |
296 |
-#endif |
297 |
|
298 |
#ifdef MPPE |
299 |
- Set_Start_Key(rchallenge, secret, secret_len); |
300 |
+ Set_Start_Key(rchallenge, PasswordHash); |
301 |
#endif |
302 |
} |
303 |
|
304 |
@@ -845,7 +827,7 @@ |
305 |
*/ |
306 |
void |
307 |
ChapMS2(u_char *rchallenge, u_char *PeerChallenge, |
308 |
- char *user, char *secret, int secret_len, unsigned char *response, |
309 |
+ char *user, u_char PasswordHash[16], unsigned char *response, |
310 |
u_char authResponse[], int authenticator) |
311 |
{ |
312 |
/* ARGSUSED */ |
313 |
@@ -864,16 +846,16 @@ |
314 |
|
315 |
/* Generate the NT-Response */ |
316 |
ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user, |
317 |
- secret, secret_len, &response[MS_CHAP2_NTRESP]); |
318 |
+ PasswordHash, &response[MS_CHAP2_NTRESP]); |
319 |
|
320 |
/* Generate the Authenticator Response. */ |
321 |
- GenerateAuthenticatorResponsePlain(secret, secret_len, |
322 |
+ GenerateAuthenticatorResponsePlain(PasswordHash, |
323 |
&response[MS_CHAP2_NTRESP], |
324 |
&response[MS_CHAP2_PEER_CHALLENGE], |
325 |
rchallenge, user, authResponse); |
326 |
|
327 |
#ifdef MPPE |
328 |
- SetMasterKeys(secret, secret_len, |
329 |
+ SetMasterKeys(PasswordHash, |
330 |
&response[MS_CHAP2_NTRESP], authenticator); |
331 |
#endif |
332 |
} |
333 |
--- ppp-2.4.4.orig/pppd/chap_ms.h 2004-11-15 17:13:26.000000000 -0500 |
334 |
+++ ppp-2.4.4/pppd/chap_ms.h 2006-11-21 17:08:39.000000000 -0500 |
335 |
@@ -87,8 +87,8 @@ |
336 |
#define MS_CHAP2_AUTHENTICATEE 0 |
337 |
#define MS_CHAP2_AUTHENTICATOR 1 |
338 |
|
339 |
-void ChapMS __P((u_char *, char *, int, u_char *)); |
340 |
-void ChapMS2 __P((u_char *, u_char *, char *, char *, int, |
341 |
+void ChapMS __P((u_char *, u_char[MD4_SIGNATURE_SIZE], u_char *)); |
342 |
+void ChapMS2 __P((u_char *, u_char *, char *, u_char[MD4_SIGNATURE_SIZE], |
343 |
u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int)); |
344 |
#ifdef MPPE |
345 |
void mppe_set_keys __P((u_char *, u_char[MD4_SIGNATURE_SIZE])); |