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