1 /*
2 * Tests for the NTLM security provider
3 *
4 * Copyright 2005, 2006 Kai Blin
5 * Copyright 2006 Dmitry Timoshkov
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 *
21 * The code that tests for the behaviour of ISC_REQ_ALLOCATE_MEMORY is based
22 * on code written by Dmitry Timoshkov.
23
24 */
25
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <assert.h>
29 #include <windef.h>
30 #include <winbase.h>
31 #define SECURITY_WIN32
32 #include <sspi.h>
33 #include <rpc.h>
34 #include <rpcdce.h>
35 #include <secext.h>
36
37 #include "wine/test.h"
38
39 static HMODULE secdll;
40 static PSecurityFunctionTableA (SEC_ENTRY * pInitSecurityInterfaceA)(void);
41 static SECURITY_STATUS (SEC_ENTRY * pFreeContextBuffer)(PVOID pv);
42 static SECURITY_STATUS (SEC_ENTRY * pQuerySecurityPackageInfoA)(SEC_CHAR*, PSecPkgInfoA*);
43 static SECURITY_STATUS (SEC_ENTRY * pAcquireCredentialsHandleA)(SEC_CHAR*, SEC_CHAR*,
44 ULONG, PLUID, PVOID, SEC_GET_KEY_FN, PVOID, PCredHandle, PTimeStamp);
45 static SECURITY_STATUS (SEC_ENTRY * pInitializeSecurityContextA)(PCredHandle, PCtxtHandle,
46 SEC_CHAR*, ULONG, ULONG, ULONG, PSecBufferDesc, ULONG,
47 PCtxtHandle, PSecBufferDesc, PULONG, PTimeStamp);
48 static SECURITY_STATUS (SEC_ENTRY * pCompleteAuthToken)(PCtxtHandle, PSecBufferDesc);
49 static SECURITY_STATUS (SEC_ENTRY * pAcceptSecurityContext)(PCredHandle, PCtxtHandle,
50 PSecBufferDesc, ULONG, ULONG, PCtxtHandle, PSecBufferDesc,
51 PULONG, PTimeStamp);
52 static SECURITY_STATUS (SEC_ENTRY * pFreeCredentialsHandle)(PCredHandle);
53 static SECURITY_STATUS (SEC_ENTRY * pDeleteSecurityContext)(PCtxtHandle);
54 static SECURITY_STATUS (SEC_ENTRY * pQueryContextAttributesA)(PCtxtHandle, ULONG, PVOID);
55 static SECURITY_STATUS (SEC_ENTRY * pMakeSignature)(PCtxtHandle, ULONG,
56 PSecBufferDesc, ULONG);
57 static SECURITY_STATUS (SEC_ENTRY * pVerifySignature)(PCtxtHandle, PSecBufferDesc,
58 ULONG, PULONG);
59 static SECURITY_STATUS (SEC_ENTRY * pEncryptMessage)(PCtxtHandle, ULONG,
60 PSecBufferDesc, ULONG);
61 static SECURITY_STATUS (SEC_ENTRY * pDecryptMessage)(PCtxtHandle, PSecBufferDesc,
62 ULONG, PULONG);
63 static BOOLEAN (WINAPI * pGetUserNameExA)(EXTENDED_NAME_FORMAT, LPSTR, PULONG);
64
65 typedef struct _SspiData {
66 CredHandle cred;
67 CtxtHandle ctxt;
68 PSecBufferDesc in_buf;
69 PSecBufferDesc out_buf;
70 PSEC_WINNT_AUTH_IDENTITY id;
71 ULONG max_token;
72 } SspiData;
73
74 static BYTE network_challenge[] =
75 {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00,
76 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00,
77 0x05, 0x82, 0x82, 0xa0, 0xe9, 0x58, 0x7f, 0x14, 0xa2, 0x86,
78 0x3b, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00,
80 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
81 0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00,
82 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
83 0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00,
84 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
85 0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00,
86 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
87 0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00,
88 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
89 0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00};
90
91 static BYTE native_challenge[] =
92 {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00,
93 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00,
94 0x05, 0x82, 0x82, 0xa0, 0xb5, 0x60, 0x8e, 0x95, 0xb5, 0x3c,
95 0xee, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00,
97 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
98 0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00,
99 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
100 0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00,
101 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
102 0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00,
103 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
104 0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00,
105 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
106 0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00};
107
108 static BYTE message_signature[] =
109 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
111
112 static BYTE message_binary[] =
113 {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72,
114 0x6c, 0x64, 0x21};
115
116 static char message[] = "Hello, world!";
117
118 static char message_header[] = "Header Test";
119
120 static BYTE crypt_trailer_client[] =
121 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xc7,
122 0xaa, 0x26, 0x16, 0x39, 0x07, 0x4e};
123
124 static BYTE crypt_message_client[] =
125 {0x86, 0x9c, 0x5a, 0x10, 0x78, 0xb3, 0x30, 0x98, 0x46, 0x15,
126 0xa0, 0x31, 0xd9};
127
128 static BYTE crypt_trailer_client2[] =
129 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0xa7,
130 0xf7, 0x0f, 0x5b, 0x25, 0xbe, 0xa4};
131
132 static BYTE crypt_message_client2[] =
133 {0x20, 0x6c, 0x01, 0xab, 0xb0, 0x4c, 0x93, 0xe4, 0x1e, 0xfc,
134 0xe1, 0xfa, 0xfe};
135
136 static BYTE crypt_trailer_server[] =
137 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x46,
138 0x2e, 0x77, 0xeb, 0xf0, 0xf6, 0x9e};
139
140 static BYTE crypt_message_server[] =
141 {0xf6, 0xb7, 0x92, 0x0c, 0xac, 0xea, 0x98, 0xe6, 0xef, 0xa0,
142 0x29, 0x66, 0xfd};
143
144 static BYTE crypt_trailer_server2[] =
145 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x4e,
146 0x46, 0xb7, 0xca, 0xf7, 0x7f, 0xb3};
147
148 static BYTE crypt_message_server2[] =
149 {0xc8, 0xf2, 0x39, 0x7f, 0x0c, 0xaf, 0xf5, 0x5d, 0xef, 0x0c,
150 0x8b, 0x5f, 0x82};
151
152 static void InitFunctionPtrs(void)
153 {
154 secdll = LoadLibraryA("secur32.dll");
155 if(!secdll)
156 secdll = LoadLibraryA("security.dll");
157 if(secdll)
158 {
159 pInitSecurityInterfaceA = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceA");
160 pFreeContextBuffer = (PVOID)GetProcAddress(secdll, "FreeContextBuffer");
161 pQuerySecurityPackageInfoA = (PVOID)GetProcAddress(secdll, "QuerySecurityPackageInfoA");
162 pAcquireCredentialsHandleA = (PVOID)GetProcAddress(secdll, "AcquireCredentialsHandleA");
163 pInitializeSecurityContextA = (PVOID)GetProcAddress(secdll, "InitializeSecurityContextA");
164 pCompleteAuthToken = (PVOID)GetProcAddress(secdll, "CompleteAuthToken");
165 pAcceptSecurityContext = (PVOID)GetProcAddress(secdll, "AcceptSecurityContext");
166 pFreeCredentialsHandle = (PVOID)GetProcAddress(secdll, "FreeCredentialsHandle");
167 pDeleteSecurityContext = (PVOID)GetProcAddress(secdll, "DeleteSecurityContext");
168 pQueryContextAttributesA = (PVOID)GetProcAddress(secdll, "QueryContextAttributesA");
169 pMakeSignature = (PVOID)GetProcAddress(secdll, "MakeSignature");
170 pVerifySignature = (PVOID)GetProcAddress(secdll, "VerifySignature");
171 pEncryptMessage = (PVOID)GetProcAddress(secdll, "EncryptMessage");
172 pDecryptMessage = (PVOID)GetProcAddress(secdll, "DecryptMessage");
173 pGetUserNameExA = (PVOID)GetProcAddress(secdll, "GetUserNameExA");
174 }
175 }
176
177 static const char* getSecError(SECURITY_STATUS status)
178 {
179 static char buf[20];
180
181 #define _SEC_ERR(x) case (x): return #x;
182 switch(status)
183 {
184 _SEC_ERR(SEC_E_OK);
185 _SEC_ERR(SEC_E_INSUFFICIENT_MEMORY);
186 _SEC_ERR(SEC_E_INVALID_HANDLE);
187 _SEC_ERR(SEC_E_UNSUPPORTED_FUNCTION);
188 _SEC_ERR(SEC_E_TARGET_UNKNOWN);
189 _SEC_ERR(SEC_E_INTERNAL_ERROR);
190 _SEC_ERR(SEC_E_SECPKG_NOT_FOUND);
191 _SEC_ERR(SEC_E_NOT_OWNER);
192 _SEC_ERR(SEC_E_CANNOT_INSTALL);
193 _SEC_ERR(SEC_E_INVALID_TOKEN);
194 _SEC_ERR(SEC_E_CANNOT_PACK);
195 _SEC_ERR(SEC_E_QOP_NOT_SUPPORTED);
196 _SEC_ERR(SEC_E_NO_IMPERSONATION);
197 _SEC_ERR(SEC_I_CONTINUE_NEEDED);
198 _SEC_ERR(SEC_E_BUFFER_TOO_SMALL);
199 _SEC_ERR(SEC_E_ILLEGAL_MESSAGE);
200 _SEC_ERR(SEC_E_LOGON_DENIED);
201 _SEC_ERR(SEC_E_NO_CREDENTIALS);
202 _SEC_ERR(SEC_E_OUT_OF_SEQUENCE);
203 _SEC_ERR(SEC_E_MESSAGE_ALTERED);
204 default:
205 sprintf(buf, "%08x\n", status);
206 return buf;
207 }
208 #undef _SEC_ERR
209 }
210
211 /**********************************************************************/
212
213 static SECURITY_STATUS setupBuffers(SspiData *sspi_data, SecPkgInfoA *sec_pkg_info)
214 {
215
216 sspi_data->in_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
217 sspi_data->out_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
218 sspi_data->max_token = sec_pkg_info->cbMaxToken;
219
220 if(sspi_data->in_buf != NULL)
221 {
222 PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
223 sizeof(SecBuffer));
224 if(sec_buffer == NULL){
225 trace("in_buf: sec_buffer == NULL\n");
226 return SEC_E_INSUFFICIENT_MEMORY;
227 }
228
229 sspi_data->in_buf->ulVersion = SECBUFFER_VERSION;
230 sspi_data->in_buf->cBuffers = 1;
231 sspi_data->in_buf->pBuffers = sec_buffer;
232
233 sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
234 sec_buffer->BufferType = SECBUFFER_TOKEN;
235 if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0,
236 sec_pkg_info->cbMaxToken)) == NULL)
237 {
238 trace("in_buf: sec_buffer->pvBuffer == NULL\n");
239 return SEC_E_INSUFFICIENT_MEMORY;
240 }
241 }
242 else
243 {
244 trace("HeapAlloc in_buf returned NULL\n");
245 return SEC_E_INSUFFICIENT_MEMORY;
246 }
247
248 if(sspi_data->out_buf != NULL)
249 {
250 PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
251 sizeof(SecBuffer));
252
253 if(sec_buffer == NULL){
254 trace("out_buf: sec_buffer == NULL\n");
255 return SEC_E_INSUFFICIENT_MEMORY;
256 }
257
258 sspi_data->out_buf->ulVersion = SECBUFFER_VERSION;
259 sspi_data->out_buf->cBuffers = 1;
260 sspi_data->out_buf->pBuffers = sec_buffer;
261
262 sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
263 sec_buffer->BufferType = SECBUFFER_TOKEN;
264 if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0,
265 sec_pkg_info->cbMaxToken)) == NULL){
266 trace("out_buf: sec_buffer->pvBuffer == NULL\n");
267 return SEC_E_INSUFFICIENT_MEMORY;
268 }
269 }
270 else
271 {
272 trace("HeapAlloc out_buf returned NULL\n");
273 return SEC_E_INSUFFICIENT_MEMORY;
274 }
275
276 return SEC_E_OK;
277 }
278
279 /**********************************************************************/
280
281 static void cleanupBuffers(SspiData *sspi_data)
282 {
283 ULONG i;
284
285 if(sspi_data->in_buf != NULL)
286 {
287 for(i = 0; i < sspi_data->in_buf->cBuffers; ++i)
288 {
289 HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers[i].pvBuffer);
290 }
291 HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers);
292 HeapFree(GetProcessHeap(), 0, sspi_data->in_buf);
293 }
294
295 if(sspi_data->out_buf != NULL)
296 {
297 for(i = 0; i < sspi_data->out_buf->cBuffers; ++i)
298 {
299 HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers[i].pvBuffer);
300 }
301 HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers);
302 HeapFree(GetProcessHeap(), 0, sspi_data->out_buf);
303 }
304 }
305
306 /**********************************************************************/
307
308 static SECURITY_STATUS setupClient(SspiData *sspi_data, SEC_CHAR *provider)
309 {
310 SECURITY_STATUS ret;
311 TimeStamp ttl;
312 SecPkgInfoA *sec_pkg_info;
313
314 trace("Running setupClient\n");
315
316 ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
317
318 ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
319
320 setupBuffers(sspi_data, sec_pkg_info);
321 pFreeContextBuffer(sec_pkg_info);
322
323 if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_OUTBOUND,
324 NULL, sspi_data->id, NULL, NULL, &sspi_data->cred, &ttl))
325 != SEC_E_OK)
326 {
327 trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
328 }
329
330 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
331 getSecError(ret));
332
333 return ret;
334 }
335 /**********************************************************************/
336
337 static SECURITY_STATUS setupServer(SspiData *sspi_data, SEC_CHAR *provider)
338 {
339 SECURITY_STATUS ret;
340 TimeStamp ttl;
341 SecPkgInfoA *sec_pkg_info;
342
343 trace("Running setupServer\n");
344
345 ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
346
347 ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
348
349 setupBuffers(sspi_data, sec_pkg_info);
350 pFreeContextBuffer(sec_pkg_info);
351
352 if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_INBOUND,
353 NULL, NULL, NULL, NULL, &sspi_data->cred, &ttl)) != SEC_E_OK)
354 {
355 trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
356 }
357
358 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
359 getSecError(ret));
360
361 return ret;
362 }
363
364 /**********************************************************************/
365
366 static SECURITY_STATUS setupFakeServer(SspiData *sspi_data, SEC_CHAR *provider)
367 {
368 SECURITY_STATUS ret;
369 SecPkgInfoA *sec_pkg_info;
370
371 trace("Running setupFakeServer\n");
372
373 ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
374
375 ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
376
377 ret = setupBuffers(sspi_data, sec_pkg_info);
378 pFreeContextBuffer(sec_pkg_info);
379
380 return ret;
381 }
382
383
384 /**********************************************************************/
385
386 static SECURITY_STATUS runClient(SspiData *sspi_data, BOOL first, ULONG data_rep)
387 {
388 SECURITY_STATUS ret;
389 ULONG req_attr = 0;
390 ULONG ctxt_attr;
391 TimeStamp ttl;
392 PSecBufferDesc in_buf = sspi_data->in_buf;
393 PSecBufferDesc out_buf = sspi_data->out_buf;
394
395 assert(in_buf->cBuffers >= 1);
396 assert(in_buf->pBuffers[0].pvBuffer != NULL);
397 assert(in_buf->pBuffers[0].cbBuffer != 0);
398
399 assert(out_buf->cBuffers >= 1);
400 assert(out_buf->pBuffers[0].pvBuffer != NULL);
401 assert(out_buf->pBuffers[0].cbBuffer != 0);
402
403 trace("Running the client the %s time.\n", first?"first":"second");
404
405 /* We can either use ISC_REQ_ALLOCATE_MEMORY flag to ask the provider
406 * always allocate output buffers for us, or initialize cbBuffer
407 * before each call because the API changes it to represent actual
408 * amount of data in the buffer.
409 */
410
411 /* test a failing call only the first time, otherwise we get
412 * SEC_E_OUT_OF_SEQUENCE
413 */
414 if (first)
415 {
416 void *old_buf;
417
418 /* pass NULL as an output buffer */
419 ret = pInitializeSecurityContextA(&sspi_data->cred, NULL, NULL, req_attr,
420 0, data_rep, NULL, 0, &sspi_data->ctxt, NULL,
421 &ctxt_attr, &ttl);
422
423 ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
424
425 /* pass NULL as an output buffer */
426 old_buf = out_buf->pBuffers[0].pvBuffer;
427 out_buf->pBuffers[0].pvBuffer = NULL;
428
429 ret = pInitializeSecurityContextA(&sspi_data->cred, NULL, NULL, req_attr,
430 0, data_rep, NULL, 0, &sspi_data->ctxt, out_buf,
431 &ctxt_attr, &ttl);
432
433 ok(ret == SEC_E_INTERNAL_ERROR || ret == SEC_I_CONTINUE_NEEDED,
434 "expected SEC_E_INTERNAL_ERROR or SEC_I_CONTINUE_NEEDED, got %s\n", getSecError(ret));
435
436 out_buf->pBuffers[0].pvBuffer = old_buf;
437
438 /* pass an output buffer of 0 size */
439 out_buf->pBuffers[0].cbBuffer = 0;
440
441 ret = pInitializeSecurityContextA(&sspi_data->cred, NULL, NULL, req_attr,
442 0, data_rep, NULL, 0, &sspi_data->ctxt, out_buf,
443 &ctxt_attr, &ttl);
444
445 ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
446
447 ok(out_buf->pBuffers[0].cbBuffer == 0,
448 "InitializeSecurityContext set buffer size to %u\n", out_buf->pBuffers[0].cbBuffer);
449
450 out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
451 out_buf->pBuffers[0].BufferType = SECBUFFER_DATA;
452
453 ret = pInitializeSecurityContextA(&sspi_data->cred, NULL, NULL, req_attr,
454 0, data_rep, NULL, 0, &sspi_data->ctxt, out_buf,
455 &ctxt_attr, &ttl);
456
457 ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
458 out_buf->pBuffers[0].BufferType = SECBUFFER_TOKEN;
459 }
460
461 out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
462
463 ret = pInitializeSecurityContextA(first?&sspi_data->cred:NULL, first?NULL:&sspi_data->ctxt, NULL, req_attr,
464 0, data_rep, first?NULL:in_buf, 0, &sspi_data->ctxt, out_buf,
465 &ctxt_attr, &ttl);
466
467 if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
468 {
469 pCompleteAuthToken(&sspi_data->ctxt, out_buf);
470 if(ret == SEC_I_COMPLETE_AND_CONTINUE)
471 ret = SEC_I_CONTINUE_NEEDED;
472 else if(ret == SEC_I_COMPLETE_NEEDED)
473 ret = SEC_E_OK;
474 }
475
476 ok(out_buf->pBuffers[0].BufferType == SECBUFFER_TOKEN,
477 "buffer type was changed from SECBUFFER_TOKEN to %d\n", out_buf->pBuffers[0].BufferType);
478 ok(out_buf->pBuffers[0].cbBuffer < sspi_data->max_token,
479 "InitializeSecurityContext set buffer size to %u\n", out_buf->pBuffers[0].cbBuffer);
480
481 return ret;
482 }
483
484 /**********************************************************************/
485
486 static SECURITY_STATUS runServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
487 {
488 SECURITY_STATUS ret;
489 ULONG ctxt_attr;
490 TimeStamp ttl;
491
492 trace("Running the server the %s time\n", first?"first":"second");
493
494 ret = pAcceptSecurityContext(&sspi_data->cred, first?NULL:&sspi_data->ctxt,
495 sspi_data->in_buf, 0, data_rep, &sspi_data->ctxt,
496 sspi_data->out_buf, &ctxt_attr, &ttl);
497
498 if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
499 {
500 pCompleteAuthToken(&sspi_data->ctxt, sspi_data->out_buf);
501 if(ret == SEC_I_COMPLETE_AND_CONTINUE)
502 ret = SEC_I_CONTINUE_NEEDED;
503 else if(ret == SEC_I_COMPLETE_NEEDED)
504 ret = SEC_E_OK;
505 }
506
507 return ret;
508 }
509
510 /**********************************************************************/
511
512 static SECURITY_STATUS runFakeServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
513 {
514 trace("Running the fake server the %s time\n", first?"first":"second");
515
516 if(!first)
517 {
518 sspi_data->out_buf->pBuffers[0].cbBuffer = 0;
519 return SEC_E_OK;
520 }
521
522 if(data_rep == SECURITY_NATIVE_DREP)
523 {
524 sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(native_challenge);
525 memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, native_challenge,
526 sspi_data->out_buf->pBuffers[0].cbBuffer);
527 }
528 else
529 {
530 sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(network_challenge);
531 memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, network_challenge,
532 sspi_data->out_buf->pBuffers[0].cbBuffer);
533 }
534
535 return SEC_I_CONTINUE_NEEDED;
536 }
537
538 /**********************************************************************/
539
540 static void communicate(SspiData *from, SspiData *to)
541 {
542 if(from->out_buf != NULL && to->in_buf != NULL)
543 {
544 trace("Running communicate.\n");
545 if((from->out_buf->cBuffers >= 1) && (to->in_buf->cBuffers >= 1))
546 {
547 if((from->out_buf->pBuffers[0].pvBuffer != NULL) &&
548 (to->in_buf->pBuffers[0].pvBuffer != NULL))
549 {
550 memset(to->in_buf->pBuffers[0].pvBuffer, 0, to->max_token);
551
552 memcpy(to->in_buf->pBuffers[0].pvBuffer,
553 from->out_buf->pBuffers[0].pvBuffer,
554 from->out_buf->pBuffers[0].cbBuffer);
555
556 to->in_buf->pBuffers[0].cbBuffer = from->out_buf->pBuffers[0].cbBuffer;
557
558 memset(from->out_buf->pBuffers[0].pvBuffer, 0, from->max_token);
559 }
560 }
561 }
562 }
563
564 /**********************************************************************/
565 static void testInitializeSecurityContextFlags(void)
566 {
567 SECURITY_STATUS sec_status;
568 PSecPkgInfo pkg_info = NULL;
569 SspiData client;
570 SEC_WINNT_AUTH_IDENTITY id;
571 static char sec_pkg_name[] = "NTLM",
572 test_user[] = "testuser",
573 workgroup[] = "WORKGROUP",
574 test_pass[] = "testpass";
575 ULONG req_attr, ctxt_attr;
576 TimeStamp ttl;
577 PBYTE packet;
578
579 if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
580 {
581 ok(0, "NTLM package not installed, skipping test.\n");
582 return;
583 }
584
585 pFreeContextBuffer(pkg_info);
586 id.User = (unsigned char*) test_user;
587 id.UserLength = strlen((char *) id.User);
588 id.Domain = (unsigned char *) workgroup;
589 id.DomainLength = strlen((char *) id.Domain);
590 id.Password = (unsigned char*) test_pass;
591 id.PasswordLength = strlen((char *) id.Password);
592 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
593
594 client.id = &id;
595
596 if((sec_status = setupClient(&client, sec_pkg_name)) != SEC_E_OK)
597 {
598 skip("Setting up the client returned %s, skipping test!\n",
599 getSecError(sec_status));
600 return;
601 }
602
603 packet = client.out_buf->pBuffers[0].pvBuffer;
604
605 /* Due to how the requesting of the flags is implemented in ntlm_auth,
606 * the tests need to be in this order, as there is no way to specify
607 * "I request no special features" in ntlm_auth */
608
609 /* Without any flags, the lowest byte should not have bits 0x20 or 0x10 set*/
610 req_attr = 0;
611
612 if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
613 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
614 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
615 {
616 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
617 getSecError(sec_status));
618 goto tISCFend;
619 }
620
621 ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
622 "With req_attr == 0, flags are 0x%02x%02x%02x%02x.\n",
623 packet[15], packet[14], packet[13], packet[12]);
624 pDeleteSecurityContext(&client.ctxt);
625
626 /* With ISC_REQ_CONNECTION, the lowest byte should not have bits 0x20 or 0x10 set*/
627 req_attr = ISC_REQ_CONNECTION;
628
629 if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
630 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
631 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
632 {
633 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
634 getSecError(sec_status));
635 goto tISCFend;
636 }
637
638 ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
639 "For ISC_REQ_CONNECTION, flags are 0x%02x%02x%02x%02x.\n",
640 packet[15], packet[14], packet[13], packet[12]);
641 pDeleteSecurityContext(&client.ctxt);
642
643 /* With ISC_REQ_EXTENDED_ERROR, the lowest byte should not have bits 0x20 or 0x10 set*/
644 req_attr = ISC_REQ_EXTENDED_ERROR;
645
646 if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
647 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
648 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
649 {
650 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
651 getSecError(sec_status));
652 goto tISCFend;
653 }
654
655 ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
656 "For ISC_REQ_EXTENDED_ERROR, flags are 0x%02x%02x%02x%02x.\n",
657 packet[15], packet[14], packet[13], packet[12]);
658 pDeleteSecurityContext(&client.ctxt);
659
660 /* With ISC_REQ_MUTUAL_AUTH, the lowest byte should not have bits 0x20 or 0x10 set*/
661 req_attr = ISC_REQ_MUTUAL_AUTH;
662
663 if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
664 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
665 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
666 {
667 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
668 getSecError(sec_status));
669 goto tISCFend;
670 }
671
672 ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
673 "For ISC_REQ_MUTUAL_AUTH, flags are 0x%02x%02x%02x%02x.\n",
674 packet[15], packet[14], packet[13], packet[12]);
675 pDeleteSecurityContext(&client.ctxt);
676
677 /* With ISC_REQ_USE_DCE_STYLE, the lowest byte should not have bits 0x20 or 0x10 set*/
678 req_attr = ISC_REQ_USE_DCE_STYLE;
679
680 if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
681 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
682 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
683 {
684 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
685 getSecError(sec_status));
686 goto tISCFend;
687 }
688
689 ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
690 "For ISC_REQ_USE_DCE_STYLE, flags are 0x%02x%02x%02x%02x.\n",
691 packet[15], packet[14], packet[13], packet[12]);
692 pDeleteSecurityContext(&client.ctxt);
693
694 /* With ISC_REQ_DELEGATE, the lowest byte should not have bits 0x20 or 0x10 set*/
695 req_attr = ISC_REQ_DELEGATE;
696
697 if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
698 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
699 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
700 {
701 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
702 getSecError(sec_status));
703 goto tISCFend;
704 }
705
706 ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
707 "For ISC_REQ_DELEGATE, flags are 0x%02x%02x%02x%02x.\n",
708 packet[15], packet[14], packet[13], packet[12]);
709 pDeleteSecurityContext(&client.ctxt);
710
711 /* With ISC_REQ_INTEGRITY, the lowest byte should have bit 0x10 set */
712 req_attr = ISC_REQ_INTEGRITY;
713
714 if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
715 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
716 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
717 {
718 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
719 getSecError(sec_status));
720 goto tISCFend;
721 }
722
723 ok((packet[12] & 0x10) != 0,
724 "For ISC_REQ_INTEGRITY, flags are 0x%02x%02x%02x%02x.\n",
725 packet[15], packet[14], packet[13], packet[12]);
726 pDeleteSecurityContext(&client.ctxt);
727
728 /* With ISC_REQ_REPLAY_DETECT, the lowest byte should have bit 0x10 set */
729 req_attr = ISC_REQ_REPLAY_DETECT;
730
731 if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
732 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
733 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
734 {
735 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
736 getSecError(sec_status));
737 goto tISCFend;
738 }
739
740 ok((packet[12] & 0x10) != 0,
741 "For ISC_REQ_REPLAY_DETECT, flags are 0x%02x%02x%02x%02x.\n",
742 packet[15], packet[14], packet[13], packet[12]);
743 pDeleteSecurityContext(&client.ctxt);
744
745 /* With ISC_REQ_SEQUENCE_DETECT, the lowest byte should have bit 0x10 set */
746 req_attr = ISC_REQ_SEQUENCE_DETECT;
747
748 if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
749 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
750 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
751 {
752 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
753 getSecError(sec_status));
754 goto tISCFend;
755 }
756
757 ok((packet[12] & 0x10) != 0,
758 "For ISC_REQ_SEQUENCE_DETECT, flags are 0x%02x%02x%02x%02x.\n",
759 packet[15], packet[14], packet[13], packet[12]);
760 pDeleteSecurityContext(&client.ctxt);
761
762 /* With ISC_REQ_CONFIDENTIALITY, the lowest byte should have bit 0x20 set */
763 req_attr = ISC_REQ_CONFIDENTIALITY;
764
765 if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
766 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
767 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
768 {
769 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
770 getSecError(sec_status));
771 goto tISCFend;
772 }
773
774 ok((packet[12] & 0x20) != 0,
775 "For ISC_REQ_CONFIDENTIALITY, flags are 0x%02x%02x%02x%02x.\n",
776 packet[15], packet[14], packet[13], packet[12]);
777 pDeleteSecurityContext(&client.ctxt);
778
779 tISCFend:
780 cleanupBuffers(&client);
781 pFreeCredentialsHandle(&client.cred);
782 }
783
784 /**********************************************************************/
785
786 static void testAuth(ULONG data_rep, BOOL fake)
787 {
788 SECURITY_STATUS client_stat = SEC_I_CONTINUE_NEEDED;
789 SECURITY_STATUS server_stat = SEC_I_CONTINUE_NEEDED;
790 SECURITY_STATUS sec_status;
791 PSecPkgInfo pkg_info = NULL;
792 BOOL first = TRUE;
793 SspiData client, server;
794 SEC_WINNT_AUTH_IDENTITY id;
795 SecPkgContext_Sizes ctxt_sizes;
796 static char sec_pkg_name[] = "NTLM",
797 test_user[] = "testuser",
798 workgroup[] = "WORKGROUP",
799 test_pass[] = "testpass";
800
801 if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)!= SEC_E_OK)
802 {
803 ok(0, "NTLM package not installed, skipping test.\n");
804 return;
805 }
806
807 pFreeContextBuffer(pkg_info);
808 id.User = (unsigned char*) test_user;
809 id.UserLength = strlen((char *) id.User);
810 id.Domain = (unsigned char *) workgroup;
811 id.DomainLength = strlen((char *) id.Domain);
812 id.Password = (unsigned char*) test_pass;
813 id.PasswordLength = strlen((char *) id.Password);
814 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
815
816 client.id = &id;
817
818 sec_status = setupClient(&client, sec_pkg_name);
819
820 if(sec_status != SEC_E_OK)
821 {
822 skip("Error: Setting up the client returned %s, exiting test!\n",
823 getSecError(sec_status));
824 pFreeCredentialsHandle(&client.cred);
825 return;
826 }
827
828 if(fake)
829 sec_status = setupFakeServer(&server, sec_pkg_name);
830 else
831 sec_status = setupServer(&server, sec_pkg_name);
832
833 if(sec_status != SEC_E_OK)
834 {
835 skip("Error: Setting up the server returned %s, exiting test!\n",
836 getSecError(sec_status));
837 pFreeCredentialsHandle(&server.cred);
838 pFreeCredentialsHandle(&client.cred);
839 return;
840 }
841
842 while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
843 {
844 client_stat = runClient(&client, first, data_rep);
845
846 ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED,
847 "Running the client returned %s, more tests will fail.\n",
848 getSecError(client_stat));
849
850 communicate(&client, &server);
851
852 if(fake)
853 server_stat = runFakeServer(&server, first, data_rep);
854 else
855 server_stat = runServer(&server, first, data_rep);
856
857 ok(server_stat == SEC_E_OK || server_stat == SEC_I_CONTINUE_NEEDED ||
858 server_stat == SEC_E_LOGON_DENIED,
859 "Running the server returned %s, more tests will fail from now.\n",
860 getSecError(server_stat));
861
862 communicate(&server, &client);
863 trace("Looping\n");
864 first = FALSE;
865 }
866
867 if(client_stat != SEC_E_OK)
868 {
869 skip("Authentication failed, skipping test.\n");
870 goto tAuthend;
871 }
872
873 sec_status = pQueryContextAttributesA(&client.ctxt,
874 SECPKG_ATTR_SIZES, &ctxt_sizes);
875
876 ok(sec_status == SEC_E_OK,
877 "pQueryContextAttributesA(SECPKG_ATTR_SIZES) returned %s\n",
878 getSecError(sec_status));
879 ok((ctxt_sizes.cbMaxToken == 1904) || (ctxt_sizes.cbMaxToken == 2888),
880 "cbMaxToken should be 1904 or 2888 but is %u\n",
881 ctxt_sizes.cbMaxToken);
882 ok(ctxt_sizes.cbMaxSignature == 16,
883 "cbMaxSignature should be 16 but is %u\n",
884 ctxt_sizes.cbMaxSignature);
885 ok(ctxt_sizes.cbSecurityTrailer == 16,
886 "cbSecurityTrailer should be 16 but is %u\n",
887 ctxt_sizes.cbSecurityTrailer);
888 ok(ctxt_sizes.cbBlockSize == 0,
889 "cbBlockSize should be 0 but is %u\n",
890 ctxt_sizes.cbBlockSize);
891
892 tAuthend:
893 cleanupBuffers(&client);
894 cleanupBuffers(&server);
895
896 if(!fake)
897 {
898 sec_status = pDeleteSecurityContext(&server.ctxt);
899 ok(sec_status == SEC_E_OK, "DeleteSecurityContext(server) returned %s\n",
900 getSecError(sec_status));
901 }
902
903 sec_status = pDeleteSecurityContext(&client.ctxt);
904 ok(sec_status == SEC_E_OK, "DeleteSecurityContext(client) returned %s\n",
905 getSecError(sec_status));
906
907 if(!fake)
908 {
909 sec_status = pFreeCredentialsHandle(&server.cred);
910 ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(server) returned %s\n",
911 getSecError(sec_status));
912 }
913
914 sec_status = pFreeCredentialsHandle(&client.cred);
915 ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(client) returned %s\n",
916 getSecError(sec_status));
917 }
918
919 static void testSignSeal(void)
920 {
921 SECURITY_STATUS client_stat = SEC_I_CONTINUE_NEEDED;
922 SECURITY_STATUS server_stat = SEC_I_CONTINUE_NEEDED;
923 SECURITY_STATUS sec_status;
924 PSecPkgInfo pkg_info = NULL;
925 BOOL first = TRUE;
926 SspiData client, server;
927 SEC_WINNT_AUTH_IDENTITY id;
928 static char sec_pkg_name[] = "NTLM";
929 SecBufferDesc crypt;
930 SecBuffer data[2], fake_data[2], complex_data[4];
931 ULONG qop = 0;
932 SecPkgContext_Sizes ctxt_sizes;
933 static char test_user[] = "testuser",
934 workgroup[] = "WORKGROUP",
935 test_pass[] = "testpass";
936
937 complex_data[1].pvBuffer = complex_data[3].pvBuffer = NULL;
938
939 /****************************************************************
940 * This is basically the same as in testAuth with a fake server,
941 * as we need a valid, authenticated context.
942 */
943 if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
944 {
945 ok(0, "NTLM package not installed, skipping test.\n");
946 return;
947 }
948
949 pFreeContextBuffer(pkg_info);
950 id.User = (unsigned char*) test_user;
951 id.UserLength = strlen((char *) id.User);
952 id.Domain = (unsigned char *) workgroup;
953 id.DomainLength = strlen((char *) id.Domain);
954 id.Password = (unsigned char*) test_pass;
955 id.PasswordLength = strlen((char *) id.Password);
956 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
957
958 client.id = &id;
959
960 sec_status = setupClient(&client, sec_pkg_name);
961
962 if(sec_status != SEC_E_OK)
963 {
964 skip("Error: Setting up the client returned %s, exiting test!\n",
965 getSecError(sec_status));
966 pFreeCredentialsHandle(&client.cred);
967 return;
968 }
969
970 sec_status = setupFakeServer(&server, sec_pkg_name);
971 ok(sec_status == SEC_E_OK, "setupFakeServer returned %s\n", getSecError(sec_status));
972
973 while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
974 {
975 client_stat = runClient(&client, first, SECURITY_NETWORK_DREP);
976
977 communicate(&client, &server);
978
979 server_stat = runFakeServer(&server, first, SECURITY_NETWORK_DREP);
980
981 communicate(&server, &client);
982 trace("Looping\n");
983 first = FALSE;
984 }
985
986 /********************************************
987 * Now start with the actual testing *
988 ********************************************/
989
990 if(pQueryContextAttributesA(&client.ctxt, SECPKG_ATTR_SIZES,
991 &ctxt_sizes) != SEC_E_OK)
992 {
993 skip("Failed to get context sizes, aborting test.\n");
994 goto end;
995 }
996
997 crypt.ulVersion = SECBUFFER_VERSION;
998 crypt.cBuffers = 2;
999
1000 crypt.pBuffers = fake_data;
1001
1002 fake_data[0].BufferType = SECBUFFER_DATA;
1003 fake_data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1004 fake_data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[0].cbBuffer);
1005
1006 fake_data[1].BufferType = SECBUFFER_DATA;
1007 fake_data[1].cbBuffer = lstrlen(message);
1008 fake_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[1].cbBuffer);
1009
1010 sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0);
1011 ok(sec_status == SEC_E_INVALID_TOKEN,
1012 "MakeSignature returned %s, not SEC_E_INVALID_TOKEN.\n",
1013 getSecError(sec_status));
1014
1015 crypt.pBuffers = data;
1016
1017 data[0].BufferType = SECBUFFER_TOKEN;
1018 data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1019 data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[0].cbBuffer);
1020
1021 data[1].BufferType = SECBUFFER_DATA;
1022 data[1].cbBuffer = lstrlen(message);
1023 data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1024 memcpy(data[1].pvBuffer, message, data[1].cbBuffer);
1025
1026 /* As we forced NTLM to fall back to a password-derived session key,
1027 * we should get the same signature for our data, no matter if
1028 * it is sent by the client or the server
1029 */
1030 sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0);
1031 ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1032 getSecError(sec_status));
1033 ok(!memcmp(crypt.pBuffers[0].pvBuffer, message_signature,
1034 crypt.pBuffers[0].cbBuffer), "Signature is not as expected.\n");
1035
1036 data[0].cbBuffer = sizeof(message_signature);
1037
1038 memcpy(data[0].pvBuffer, crypt_trailer_client, data[0].cbBuffer);
1039
1040 sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop);
1041 ok(sec_status == SEC_E_MESSAGE_ALTERED,
1042 "VerifySignature returned %s, not SEC_E_MESSAGE_ALTERED.\n",
1043 getSecError(sec_status));
1044
1045 memcpy(data[0].pvBuffer, message_signature, data[0].cbBuffer);
1046
1047 sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop);
1048 ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK.\n",
1049 getSecError(sec_status));
1050
1051 sec_status = pEncryptMessage(&client.ctxt, 0, &crypt, 0);
1052 if (sec_status == SEC_E_UNSUPPORTED_FUNCTION)
1053 {
1054 skip("Encrypt message returned SEC_E_UNSUPPORTED_FUNCTION. "
1055 "Expected on Vista.\n");
1056 goto end;
1057 }
1058 ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1059 getSecError(sec_status));
1060
1061 /* first 8 bytes must always be the same */
1062 ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client, 8), "Crypt trailer not as expected.\n");
1063
1064 /* the rest depends on the session key */
1065 if (!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client, crypt.pBuffers[0].cbBuffer))
1066 {
1067 ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client,
1068 crypt.pBuffers[0].cbBuffer), "Crypt trailer not as expected.\n");
1069 ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1070 crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1071 if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1072 crypt.pBuffers[1].cbBuffer))
1073 {
1074 int i;
1075 for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
1076 {
1077 if (i % 8 == 0) printf(" ");
1078 printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
1079 if (i % 8 == 7) printf("\n");
1080 }
1081 printf("\n");
1082 }
1083
1084 data[0].cbBuffer = sizeof(crypt_trailer_server);
1085 data[1].cbBuffer = sizeof(crypt_message_server);
1086 memcpy(data[0].pvBuffer, crypt_trailer_server, data[0].cbBuffer);
1087 memcpy(data[1].pvBuffer, crypt_message_server, data[1].cbBuffer);
1088
1089 sec_status = pDecryptMessage(&client.ctxt, &crypt, 0, &qop);
1090
1091 ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1092 getSecError(sec_status));
1093 ok(!memcmp(crypt.pBuffers[1].pvBuffer, message_binary,
1094 crypt.pBuffers[1].cbBuffer),
1095 "Failed to decrypt message correctly.\n");
1096 }
1097 else trace( "A different session key is being used\n" );
1098
1099 trace("Testing with more than one buffer.\n");
1100
1101 crypt.cBuffers = sizeof(complex_data)/sizeof(complex_data[0]);
1102 crypt.pBuffers = complex_data;
1103
1104 complex_data[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1105 complex_data[0].cbBuffer = sizeof(message_header);
1106 complex_data[0].pvBuffer = message_header;
1107
1108 complex_data[1].BufferType = SECBUFFER_DATA;
1109 complex_data[1].cbBuffer = lstrlen(message);
1110 complex_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1111 memcpy(complex_data[1].pvBuffer, message, complex_data[1].cbBuffer);
1112
1113 complex_data[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1114 complex_data[2].cbBuffer = sizeof(message_header);
1115 complex_data[2].pvBuffer = message_header;
1116
1117 complex_data[3].BufferType = SECBUFFER_TOKEN;
1118 complex_data[3].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1119 complex_data[3].pvBuffer = HeapAlloc(GetProcessHeap(), 0, complex_data[3].cbBuffer);
1120
1121 /* We should get a dummy signature again. */
1122 sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0);
1123 ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1124 getSecError(sec_status));
1125 ok(!memcmp(crypt.pBuffers[3].pvBuffer, message_signature,
1126 crypt.pBuffers[3].cbBuffer), "Signature is not as expected.\n");
1127
1128 /* Being a dummy signature, it will verify right away, as if the server
1129 * sent it */
1130 sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop);
1131 ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK\n",
1132 getSecError(sec_status));
1133
1134 sec_status = pEncryptMessage(&client.ctxt, 0, &crypt, 0);
1135 ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1136 getSecError(sec_status));
1137
1138 ok(!memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2, 8), "Crypt trailer not as expected.\n");
1139
1140 if (memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
1141 crypt.pBuffers[3].cbBuffer)) goto end;
1142
1143 ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1144 crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1145 if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1146 crypt.pBuffers[1].cbBuffer))
1147 {
1148 int i;
1149 for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
1150 {
1151 if (i % 8 == 0) printf(" ");
1152 printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
1153 if (i % 8 == 7) printf("\n");
1154 }
1155 printf("\n");
1156 }
1157
1158 memcpy(complex_data[1].pvBuffer, crypt_message_server2, complex_data[1].cbBuffer);
1159 memcpy(complex_data[3].pvBuffer, crypt_trailer_server2, complex_data[3].cbBuffer);
1160
1161 sec_status = pDecryptMessage(&client.ctxt, &crypt, 0, &qop);
1162 ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1163 getSecError(sec_status));
1164
1165
1166 end:
1167 cleanupBuffers(&client);
1168 cleanupBuffers(&server);
1169
1170 pDeleteSecurityContext(&client.ctxt);
1171 pFreeCredentialsHandle(&client.cred);
1172
1173 HeapFree(GetProcessHeap(), 0, fake_data[0].pvBuffer);
1174 HeapFree(GetProcessHeap(), 0, fake_data[1].pvBuffer);
1175 HeapFree(GetProcessHeap(), 0, data[0].pvBuffer);
1176 HeapFree(GetProcessHeap(), 0, data[1].pvBuffer);
1177 HeapFree(GetProcessHeap(), 0, complex_data[1].pvBuffer);
1178 HeapFree(GetProcessHeap(), 0, complex_data[3].pvBuffer);
1179 }
1180
1181 static BOOL testAcquireCredentialsHandle(void)
1182 {
1183 CredHandle cred;
1184 TimeStamp ttl;
1185 static char test_user[] = "testuser",
1186 workgroup[] = "WORKGROUP",
1187 test_pass[] = "testpass",
1188 sec_pkg_name[] = "NTLM";
1189 SECURITY_STATUS ret;
1190 SEC_WINNT_AUTH_IDENTITY id;
1191 PSecPkgInfo pkg_info = NULL;
1192
1193 if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1194 {
1195 ok(0, "NTLM package not installed, skipping test\n");
1196 return FALSE;
1197 }
1198 pFreeContextBuffer(pkg_info);
1199
1200 id.User = (unsigned char*) test_user;
1201 id.UserLength = strlen((char *) id.User);
1202 id.Domain = (unsigned char *) workgroup;
1203 id.DomainLength = strlen((char *) id.Domain);
1204 id.Password = (unsigned char*) test_pass;
1205 id.PasswordLength = strlen((char *) id.Password);
1206 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1207
1208 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1209 NULL, &id, NULL, NULL, &cred, &ttl);
1210 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1211 getSecError(ret));
1212 pFreeCredentialsHandle(&cred);
1213
1214 id.DomainLength = 0;
1215 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1216 NULL, &id, NULL, NULL, &cred, &ttl);
1217 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1218 getSecError(ret));
1219 pFreeCredentialsHandle(&cred);
1220
1221 id.Domain = NULL;
1222 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1223 NULL, &id, NULL, NULL, &cred, &ttl);
1224 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1225 getSecError(ret));
1226 pFreeCredentialsHandle(&cred);
1227
1228 id.Domain = (unsigned char *) workgroup;
1229 id.DomainLength = strlen((char *) id.Domain);
1230 id.UserLength = 0;
1231 id.User = NULL;
1232 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1233 NULL, &id, NULL, NULL, &cred, &ttl);
1234 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1235 getSecError(ret));
1236 pFreeCredentialsHandle(&cred);
1237
1238 id.User = (unsigned char*) test_user;
1239 id.UserLength = strlen((char *) id.User);
1240 id.Password = NULL;
1241 id.PasswordLength = 0;
1242 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1243 NULL, &id, NULL, NULL, &cred, &ttl);
1244 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1245 getSecError(ret));
1246 pFreeCredentialsHandle(&cred);
1247 return TRUE;
1248 }
1249
1250 static void test_cred_multiple_use(void)
1251 {
1252 static char test_user[] = "testuser",
1253 workgroup[] = "WORKGROUP",
1254 test_pass[] = "testpass",
1255 sec_pkg_name[] = "NTLM";
1256 SECURITY_STATUS ret;
1257 SEC_WINNT_AUTH_IDENTITY id;
1258 PSecPkgInfo pkg_info = NULL;
1259 CredHandle cred;
1260 CtxtHandle ctxt1;
1261 CtxtHandle ctxt2;
1262 SecBufferDesc buffer_desc;
1263 SecBuffer buffers[1];
1264 ULONG ctxt_attr;
1265 TimeStamp ttl;
1266
1267 if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1268 {
1269 ok(0, "NTLM package not installed, skipping test\n");
1270 return;
1271 }
1272 buffers[0].cbBuffer = pkg_info->cbMaxToken;
1273 buffers[0].BufferType = SECBUFFER_TOKEN;
1274 buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1275
1276 pFreeContextBuffer(pkg_info);
1277
1278 id.User = (unsigned char*) test_user;
1279 id.UserLength = strlen((char *) id.User);
1280 id.Domain = (unsigned char *) workgroup;
1281 id.DomainLength = strlen((char *) id.Domain);
1282 id.Password = (unsigned char*) test_pass;
1283 id.PasswordLength = strlen((char *) id.Password);
1284 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1285
1286 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1287 NULL, &id, NULL, NULL, &cred, &ttl);
1288 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1289 getSecError(ret));
1290
1291 buffer_desc.ulVersion = SECBUFFER_VERSION;
1292 buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
1293 buffer_desc.pBuffers = buffers;
1294
1295 ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1296 0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt1, &buffer_desc,
1297 &ctxt_attr, &ttl);
1298 ok(ret == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed with error 0x%x\n", ret);
1299
1300 ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1301 0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt2, &buffer_desc,
1302 &ctxt_attr, &ttl);
1303 ok(ret == SEC_I_CONTINUE_NEEDED, "Second InitializeSecurityContextA on cred handle failed with error 0x%x\n", ret);
1304
1305 ret = pDeleteSecurityContext(&ctxt1);
1306 ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1307 ret = pDeleteSecurityContext(&ctxt2);
1308 ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1309 ret = pFreeCredentialsHandle(&cred);
1310 ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret);
1311
1312 HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer);
1313 }
1314
1315 static void test_null_auth_data(void)
1316 {
1317 SECURITY_STATUS status;
1318 PSecPkgInfo info;
1319 CredHandle cred;
1320 CtxtHandle ctx;
1321 SecBufferDesc buffer_desc;
1322 SecBuffer buffers[1];
1323 char user[256];
1324 TimeStamp ttl;
1325 ULONG attr, size;
1326 BOOLEAN ret;
1327
1328 if(pQuerySecurityPackageInfoA((SEC_CHAR *)"NTLM", &info) != SEC_E_OK)
1329 {
1330 ok(0, "NTLM package not installed, skipping test\n");
1331 return;
1332 }
1333
1334 status = pAcquireCredentialsHandleA(NULL, (SEC_CHAR *)"NTLM", SECPKG_CRED_OUTBOUND,
1335 NULL, NULL, NULL, NULL, &cred, &ttl);
1336 ok(status == SEC_E_OK, "AcquireCredentialsHande() failed %s\n", getSecError(status));
1337
1338 buffers[0].cbBuffer = info->cbMaxToken;
1339 buffers[0].BufferType = SECBUFFER_TOKEN;
1340 buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1341
1342 buffer_desc.ulVersion = SECBUFFER_VERSION;
1343 buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
1344 buffer_desc.pBuffers = buffers;
1345
1346 size = sizeof(user);
1347 ret = pGetUserNameExA(NameSamCompatible, user, &size);
1348 ok(ret, "GetUserNameExA failed %u\n", GetLastError());
1349
1350 status = pInitializeSecurityContextA(&cred, NULL, (SEC_CHAR *)user,
1351 ISC_REQ_CONNECTION, 0, SECURITY_NETWORK_DREP,
1352 NULL, 0, &ctx, &buffer_desc, &attr, &ttl);
1353 ok(status == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed %s\n", getSecError(status));
1354
1355 ret = pDeleteSecurityContext(&ctx);
1356 ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1357 ret = pFreeCredentialsHandle(&cred);
1358 ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret);
1359
1360 pFreeContextBuffer(info);
1361 HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer);
1362 }
1363
1364 START_TEST(ntlm)
1365 {
1366 InitFunctionPtrs();
1367
1368 if(pFreeCredentialsHandle && pDeleteSecurityContext &&
1369 pDeleteSecurityContext && pAcquireCredentialsHandleA &&
1370 pInitializeSecurityContextA && pCompleteAuthToken &&
1371 pQuerySecurityPackageInfoA)
1372 {
1373 if(!testAcquireCredentialsHandle())
1374 goto cleanup;
1375 testInitializeSecurityContextFlags();
1376 if(pAcceptSecurityContext)
1377 {
1378 testAuth(SECURITY_NATIVE_DREP, TRUE);
1379 testAuth(SECURITY_NETWORK_DREP, TRUE);
1380 testAuth(SECURITY_NATIVE_DREP, FALSE);
1381 testAuth(SECURITY_NETWORK_DREP, FALSE);
1382 }
1383 if(pMakeSignature && pVerifySignature && pEncryptMessage &&
1384 pDecryptMessage)
1385 testSignSeal();
1386
1387 test_cred_multiple_use();
1388 if (pGetUserNameExA) test_null_auth_data();
1389 }
1390 else
1391 win_skip("Needed functions are not available\n");
1392
1393 cleanup:
1394 if(secdll)
1395 FreeLibrary(secdll);
1396 }
1397
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.