comctl32/listview: Free ID array when removing all items.
[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 #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     PCredHandle cred;
67     PCtxtHandle 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     sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
317     sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
318     
319     ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
320
321     ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
322
323     setupBuffers(sspi_data, sec_pkg_info);
324     
325     if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_OUTBOUND,
326             NULL, sspi_data->id, NULL, NULL, sspi_data->cred, &ttl))
327             != SEC_E_OK)
328     {
329         trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
330     }
331
332     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n", 
333             getSecError(ret));
334
335     return ret;
336 }
337 /**********************************************************************/
338
339 static SECURITY_STATUS setupServer(SspiData *sspi_data, SEC_CHAR *provider)
340 {
341     SECURITY_STATUS ret;
342     TimeStamp ttl;
343     SecPkgInfoA *sec_pkg_info;
344
345     trace("Running setupServer\n");
346
347     sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
348     sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
349
350     ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
351
352     ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
353
354     setupBuffers(sspi_data, sec_pkg_info);
355
356     if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_INBOUND, 
357             NULL, NULL, NULL, NULL, sspi_data->cred, &ttl)) != SEC_E_OK)
358     {
359         trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
360     }
361
362     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
363             getSecError(ret));
364
365     return ret;
366 }
367
368 /**********************************************************************/
369
370 static SECURITY_STATUS setupFakeServer(SspiData *sspi_data, SEC_CHAR *provider)
371 {
372     SECURITY_STATUS ret;
373     SecPkgInfoA *sec_pkg_info;
374
375     trace("Running setupFakeServer\n");
376
377     sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
378     sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
379
380     ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
381
382     ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
383
384     ret = setupBuffers(sspi_data, sec_pkg_info);
385     
386     return ret;
387 }
388
389
390 /**********************************************************************/
391
392 static SECURITY_STATUS runClient(SspiData *sspi_data, BOOL first, ULONG data_rep)
393 {
394     SECURITY_STATUS ret;
395     ULONG req_attr = 0;
396     ULONG ctxt_attr;
397     TimeStamp ttl;
398     PSecBufferDesc in_buf = sspi_data->in_buf;
399     PSecBufferDesc out_buf = sspi_data->out_buf;
400
401     assert(in_buf->cBuffers >= 1);
402     assert(in_buf->pBuffers[0].pvBuffer != NULL);
403     assert(in_buf->pBuffers[0].cbBuffer != 0);
404
405     assert(out_buf->cBuffers >= 1);
406     assert(out_buf->pBuffers[0].pvBuffer != NULL);
407     assert(out_buf->pBuffers[0].cbBuffer != 0);
408
409     trace("Running the client the %s time.\n", first?"first":"second");
410
411     /* We can either use ISC_REQ_ALLOCATE_MEMORY flag to ask the provider
412      * always allocate output buffers for us, or initialize cbBuffer
413      * before each call because the API changes it to represent actual
414      * amount of data in the buffer.
415      */
416
417     /* test a failing call only the first time, otherwise we get
418      * SEC_E_OUT_OF_SEQUENCE
419      */
420     if (first)
421     {
422         void *old_buf;
423
424         /* pass NULL as an output buffer */
425         ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
426             0, data_rep, NULL, 0, sspi_data->ctxt, NULL,
427             &ctxt_attr, &ttl);
428
429         ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
430
431         /* pass NULL as an output buffer */
432         old_buf = out_buf->pBuffers[0].pvBuffer;
433         out_buf->pBuffers[0].pvBuffer = NULL;
434
435         ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr, 
436             0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
437             &ctxt_attr, &ttl);
438
439         ok(ret == SEC_E_INTERNAL_ERROR || ret == SEC_I_CONTINUE_NEEDED,
440            "expected SEC_E_INTERNAL_ERROR or SEC_I_CONTINUE_NEEDED, got %s\n", getSecError(ret));
441
442         out_buf->pBuffers[0].pvBuffer = old_buf;
443
444         /* pass an output buffer of 0 size */
445         out_buf->pBuffers[0].cbBuffer = 0;
446
447         ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr, 
448             0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
449             &ctxt_attr, &ttl);
450
451         ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
452
453         ok(out_buf->pBuffers[0].cbBuffer == 0,
454            "InitializeSecurityContext set buffer size to %u\n", out_buf->pBuffers[0].cbBuffer);
455
456         out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
457         out_buf->pBuffers[0].BufferType = SECBUFFER_DATA;
458
459         ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
460             0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
461             &ctxt_attr, &ttl);
462
463         ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
464         out_buf->pBuffers[0].BufferType = SECBUFFER_TOKEN;
465     }
466
467     out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
468
469     ret = pInitializeSecurityContextA(first?sspi_data->cred:NULL, first?NULL:sspi_data->ctxt, NULL, req_attr,
470             0, data_rep, first?NULL:in_buf, 0, sspi_data->ctxt, out_buf,
471             &ctxt_attr, &ttl);
472
473     if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
474     {
475         pCompleteAuthToken(sspi_data->ctxt, out_buf);
476         if(ret == SEC_I_COMPLETE_AND_CONTINUE)
477             ret = SEC_I_CONTINUE_NEEDED;
478         else if(ret == SEC_I_COMPLETE_NEEDED)
479             ret = SEC_E_OK;
480     }
481
482     ok(out_buf->pBuffers[0].BufferType == SECBUFFER_TOKEN,
483        "buffer type was changed from SECBUFFER_TOKEN to %d\n", out_buf->pBuffers[0].BufferType);
484     ok(out_buf->pBuffers[0].cbBuffer < sspi_data->max_token,
485        "InitializeSecurityContext set buffer size to %u\n", out_buf->pBuffers[0].cbBuffer);
486
487     return ret;
488 }
489
490 /**********************************************************************/
491
492 static SECURITY_STATUS runServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
493 {
494     SECURITY_STATUS ret;
495     ULONG ctxt_attr;
496     TimeStamp ttl;
497
498     trace("Running the server the %s time\n", first?"first":"second");
499
500     ret = pAcceptSecurityContext(sspi_data->cred, first?NULL:sspi_data->ctxt, 
501             sspi_data->in_buf, 0, data_rep, sspi_data->ctxt, 
502             sspi_data->out_buf, &ctxt_attr, &ttl);
503
504     if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
505     {
506         pCompleteAuthToken(sspi_data->ctxt, sspi_data->out_buf);
507         if(ret == SEC_I_COMPLETE_AND_CONTINUE)
508             ret = SEC_I_CONTINUE_NEEDED;
509         else if(ret == SEC_I_COMPLETE_NEEDED)
510             ret = SEC_E_OK;
511     }
512
513     return ret;
514 }
515
516 /**********************************************************************/
517
518 static SECURITY_STATUS runFakeServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
519 {
520     trace("Running the fake server the %s time\n", first?"first":"second");
521
522     if(!first)
523     {
524         sspi_data->out_buf->pBuffers[0].cbBuffer = 0;
525         return SEC_E_OK;
526     }
527     
528     if(data_rep == SECURITY_NATIVE_DREP)
529     {
530         sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(native_challenge);
531         memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, native_challenge, 
532                 sspi_data->out_buf->pBuffers[0].cbBuffer);
533     }
534     else
535     {
536         sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(network_challenge);
537         memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, network_challenge, 
538                 sspi_data->out_buf->pBuffers[0].cbBuffer);
539     }
540
541     return SEC_I_CONTINUE_NEEDED;
542 }
543
544 /**********************************************************************/
545
546 static void communicate(SspiData *from, SspiData *to)
547 {
548     if(from->out_buf != NULL && to->in_buf != NULL)
549     {
550         trace("Running communicate.\n");
551         if((from->out_buf->cBuffers >= 1) && (to->in_buf->cBuffers >= 1))
552         {
553             if((from->out_buf->pBuffers[0].pvBuffer != NULL) && 
554                     (to->in_buf->pBuffers[0].pvBuffer != NULL))
555             {
556                 memset(to->in_buf->pBuffers[0].pvBuffer, 0, to->max_token);
557                 
558                 memcpy(to->in_buf->pBuffers[0].pvBuffer, 
559                     from->out_buf->pBuffers[0].pvBuffer,
560                     from->out_buf->pBuffers[0].cbBuffer);
561                 
562                 to->in_buf->pBuffers[0].cbBuffer = from->out_buf->pBuffers[0].cbBuffer;
563                 
564                 memset(from->out_buf->pBuffers[0].pvBuffer, 0, from->max_token);
565             }
566         }
567     }
568 }
569
570 /**********************************************************************/
571 static void testInitializeSecurityContextFlags(void)
572 {
573     SECURITY_STATUS         sec_status;
574     PSecPkgInfo             pkg_info = NULL;
575     SspiData                client;
576     SEC_WINNT_AUTH_IDENTITY id;
577     static char             sec_pkg_name[] = "NTLM",
578                             test_user[]    = "testuser",
579                             workgroup[]    = "WORKGROUP",
580                             test_pass[]    = "testpass";
581     ULONG                   req_attr, ctxt_attr;
582     TimeStamp               ttl;
583     PBYTE                   packet;
584
585     if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
586     {
587         skip("Package not installed, skipping test!\n");
588         return;
589     }
590
591     pFreeContextBuffer(pkg_info);
592     id.User = (unsigned char*) test_user;
593     id.UserLength = strlen((char *) id.User);
594     id.Domain = (unsigned char *) workgroup;
595     id.DomainLength = strlen((char *) id.Domain);
596     id.Password = (unsigned char*) test_pass;
597     id.PasswordLength = strlen((char *) id.Password);
598     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
599
600     client.id = &id;
601
602     if((sec_status = setupClient(&client, sec_pkg_name)) != SEC_E_OK)
603     {
604         skip("Setting up the client returned %s, skipping test!\n",
605                 getSecError(sec_status));
606         return;
607     }
608
609     packet = client.out_buf->pBuffers[0].pvBuffer;
610
611     /* Due to how the requesting of the flags is implemented in ntlm_auth,
612      * the tests need to be in this order, as there is no way to specify
613      * "I request no special features" in ntlm_auth */
614
615     /* Without any flags, the lowest byte should not have bits 0x20 or 0x10 set*/
616     req_attr = 0;
617
618     if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
619         0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
620         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
621     {
622         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
623                 getSecError(sec_status));
624         goto tISCFend;
625     }
626
627     ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
628             "With req_attr == 0, flags are 0x%02x%02x%02x%02x.\n",
629             packet[15], packet[14], packet[13], packet[12]);
630
631     /* With ISC_REQ_CONNECTION, the lowest byte should not have bits 0x20 or 0x10 set*/
632     req_attr = ISC_REQ_CONNECTION;
633
634     if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
635         0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
636         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
637     {
638         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
639                 getSecError(sec_status));
640         goto tISCFend;
641     }
642
643     ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
644             "For ISC_REQ_CONNECTION, flags are 0x%02x%02x%02x%02x.\n",
645             packet[15], packet[14], packet[13], packet[12]);
646
647     /* With ISC_REQ_EXTENDED_ERROR, the lowest byte should not have bits 0x20 or 0x10 set*/
648     req_attr = ISC_REQ_EXTENDED_ERROR;
649
650     if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
651         0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
652         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
653     {
654         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
655                 getSecError(sec_status));
656         goto tISCFend;
657     }
658
659     ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
660             "For ISC_REQ_EXTENDED_ERROR, flags are 0x%02x%02x%02x%02x.\n",
661             packet[15], packet[14], packet[13], packet[12]);
662
663     /* With ISC_REQ_MUTUAL_AUTH, the lowest byte should not have bits 0x20 or 0x10 set*/
664     req_attr = ISC_REQ_MUTUAL_AUTH;
665
666     if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
667         0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
668         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
669     {
670         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
671                 getSecError(sec_status));
672         goto tISCFend;
673     }
674
675     ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
676             "For ISC_REQ_MUTUAL_AUTH, flags are 0x%02x%02x%02x%02x.\n",
677             packet[15], packet[14], packet[13], packet[12]);
678
679     /* With ISC_REQ_USE_DCE_STYLE, the lowest byte should not have bits 0x20 or 0x10 set*/
680     req_attr = ISC_REQ_USE_DCE_STYLE;
681
682     if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
683         0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
684         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
685     {
686         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
687                 getSecError(sec_status));
688         goto tISCFend;
689     }
690
691     ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
692             "For ISC_REQ_USE_DCE_STYLE, flags are 0x%02x%02x%02x%02x.\n",
693             packet[15], packet[14], packet[13], packet[12]);
694
695     /* With ISC_REQ_DELEGATE, the lowest byte should not have bits 0x20 or 0x10 set*/
696     req_attr = ISC_REQ_DELEGATE;
697
698     if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
699         0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
700         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
701     {
702         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
703                 getSecError(sec_status));
704         goto tISCFend;
705     }
706
707     ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
708             "For ISC_REQ_DELEGATE, flags are 0x%02x%02x%02x%02x.\n",
709             packet[15], packet[14], packet[13], packet[12]);
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
727     /* With ISC_REQ_REPLAY_DETECT, the lowest byte should have bit 0x10 set */
728     req_attr = ISC_REQ_REPLAY_DETECT;
729
730     if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
731         0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
732         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
733     {
734         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
735                 getSecError(sec_status));
736         goto tISCFend;
737     }
738
739     ok((packet[12] & 0x10) != 0,
740             "For ISC_REQ_REPLAY_DETECT, flags are 0x%02x%02x%02x%02x.\n",
741             packet[15], packet[14], packet[13], packet[12]);
742
743     /* With ISC_REQ_SEQUENCE_DETECT, the lowest byte should have bit 0x10 set */
744     req_attr = ISC_REQ_SEQUENCE_DETECT;
745
746     if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
747         0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
748         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
749     {
750         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
751                 getSecError(sec_status));
752         goto tISCFend;
753     }
754
755     ok((packet[12] & 0x10) != 0,
756             "For ISC_REQ_SEQUENCE_DETECT, flags are 0x%02x%02x%02x%02x.\n",
757             packet[15], packet[14], packet[13], packet[12]);
758
759     /* With ISC_REQ_CONFIDENTIALITY, the lowest byte should have bit 0x20 set */
760     req_attr = ISC_REQ_CONFIDENTIALITY;
761
762     if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
763         0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
764         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
765     {
766         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
767                 getSecError(sec_status));
768         goto tISCFend;
769     }
770
771     ok((packet[12] & 0x20) != 0,
772             "For ISC_REQ_CONFIDENTIALITY, flags are 0x%02x%02x%02x%02x.\n",
773             packet[15], packet[14], packet[13], packet[12]);
774
775 tISCFend:
776     cleanupBuffers(&client);
777     pFreeCredentialsHandle(client.cred);
778
779 }
780
781 /**********************************************************************/
782
783 static void testAuth(ULONG data_rep, BOOL fake)
784 {
785     SECURITY_STATUS         client_stat = SEC_I_CONTINUE_NEEDED;
786     SECURITY_STATUS         server_stat = SEC_I_CONTINUE_NEEDED;
787     SECURITY_STATUS         sec_status;
788     PSecPkgInfo             pkg_info = NULL;
789     BOOL                    first = TRUE;
790     SspiData                client, server;
791     SEC_WINNT_AUTH_IDENTITY id;
792     SecPkgContext_Sizes     ctxt_sizes;
793     static char             sec_pkg_name[] = "NTLM",
794                             test_user[] = "testuser",
795                             workgroup[] = "WORKGROUP",
796                             test_pass[] = "testpass";
797
798     if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)!= SEC_E_OK)
799     {
800         skip("Package not installed, skipping test.\n");
801         return;
802     }
803
804     pFreeContextBuffer(pkg_info);
805     id.User = (unsigned char*) test_user;
806     id.UserLength = strlen((char *) id.User);
807     id.Domain = (unsigned char *) workgroup;
808     id.DomainLength = strlen((char *) id.Domain);
809     id.Password = (unsigned char*) test_pass;
810     id.PasswordLength = strlen((char *) id.Password);
811     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
812
813     client.id = &id;
814
815     sec_status = setupClient(&client, sec_pkg_name);
816
817     if(sec_status != SEC_E_OK)
818     {
819         skip("Error: Setting up the client returned %s, exiting test!\n",
820                 getSecError(sec_status));
821         pFreeCredentialsHandle(client.cred);
822         return;
823     }
824
825     if(fake)
826         sec_status = setupFakeServer(&server, sec_pkg_name);
827     else
828         sec_status = setupServer(&server, sec_pkg_name);
829
830     if(sec_status != SEC_E_OK)
831     {
832         skip("Error: Setting up the server returned %s, exiting test!\n",
833                 getSecError(sec_status));
834         pFreeCredentialsHandle(server.cred);
835         pFreeCredentialsHandle(client.cred);
836         return;
837     }
838
839     while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
840     {
841         client_stat = runClient(&client, first, data_rep);
842
843         ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED,
844                 "Running the client returned %s, more tests will fail.\n",
845                 getSecError(client_stat));
846
847         communicate(&client, &server);
848
849         if(fake)
850             server_stat = runFakeServer(&server, first, data_rep);
851         else
852             server_stat = runServer(&server, first, data_rep);
853
854         ok(server_stat == SEC_E_OK || server_stat == SEC_I_CONTINUE_NEEDED ||
855                 server_stat == SEC_E_LOGON_DENIED,
856                 "Running the server returned %s, more tests will fail from now.\n",
857                 getSecError(server_stat));
858
859         communicate(&server, &client);
860         trace("Looping\n");
861         first = FALSE;
862     }
863
864     if(client_stat != SEC_E_OK)
865     {
866         skip("Authentication failed, skipping test.\n");
867         goto tAuthend;
868     }
869
870     sec_status = pQueryContextAttributesA(client.ctxt,
871             SECPKG_ATTR_SIZES, &ctxt_sizes);
872
873     ok(sec_status == SEC_E_OK,
874             "pQueryContextAttributesA(SECPKG_ATTR_SIZES) returned %s\n",
875             getSecError(sec_status));
876     ok((ctxt_sizes.cbMaxToken == 1904) || (ctxt_sizes.cbMaxToken == 2888),
877             "cbMaxToken should be 1904 or 2888 but is %u\n",
878             ctxt_sizes.cbMaxToken);
879     ok(ctxt_sizes.cbMaxSignature == 16,
880             "cbMaxSignature should be 16 but is %u\n",
881             ctxt_sizes.cbMaxSignature);
882     ok(ctxt_sizes.cbSecurityTrailer == 16,
883             "cbSecurityTrailer should be 16 but is  %u\n",
884             ctxt_sizes.cbSecurityTrailer);
885     ok(ctxt_sizes.cbBlockSize == 0,
886             "cbBlockSize should be 0 but is %u\n",
887             ctxt_sizes.cbBlockSize);
888
889 tAuthend:
890     cleanupBuffers(&client);
891     cleanupBuffers(&server);
892
893     if(!fake)
894     {
895         sec_status = pDeleteSecurityContext(server.ctxt);
896         ok(sec_status == SEC_E_OK, "DeleteSecurityContext(server) returned %s\n",
897             getSecError(sec_status));
898     }
899
900     sec_status = pDeleteSecurityContext(client.ctxt);
901     ok(sec_status == SEC_E_OK, "DeleteSecurityContext(client) returned %s\n",
902             getSecError(sec_status));
903
904     if(!fake)
905     {
906         sec_status = pFreeCredentialsHandle(server.cred);
907         ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(server) returned %s\n",
908             getSecError(sec_status));
909     }
910
911     sec_status = pFreeCredentialsHandle(client.cred);
912     ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(client) returned %s\n",
913             getSecError(sec_status));
914 }
915
916 static void testSignSeal(void)
917 {
918     SECURITY_STATUS         client_stat = SEC_I_CONTINUE_NEEDED;
919     SECURITY_STATUS         server_stat = SEC_I_CONTINUE_NEEDED;
920     SECURITY_STATUS         sec_status;
921     PSecPkgInfo             pkg_info = NULL;
922     BOOL                    first = TRUE;
923     SspiData                client, server;
924     SEC_WINNT_AUTH_IDENTITY id;
925     static char             sec_pkg_name[] = "NTLM";
926     SecBufferDesc           crypt;
927     SecBuffer               data[2], fake_data[2], complex_data[4];
928     ULONG                   qop = 0;
929     SecPkgContext_Sizes     ctxt_sizes;
930     static char             test_user[] = "testuser",
931                             workgroup[] = "WORKGROUP",
932                             test_pass[] = "testpass";
933
934     complex_data[1].pvBuffer = complex_data[3].pvBuffer = NULL;
935
936     /****************************************************************
937      * This is basically the same as in testAuth with a fake server,
938      * as we need a valid, authenticated context.
939      */
940     if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
941     {
942         skip("Package not installed, skipping test.\n");
943         return;
944     }
945
946     pFreeContextBuffer(pkg_info);
947     id.User = (unsigned char*) test_user;
948     id.UserLength = strlen((char *) id.User);
949     id.Domain = (unsigned char *) workgroup;
950     id.DomainLength = strlen((char *) id.Domain);
951     id.Password = (unsigned char*) test_pass;
952     id.PasswordLength = strlen((char *) id.Password);
953     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
954
955     client.id = &id;
956
957     sec_status = setupClient(&client, sec_pkg_name);
958
959     if(sec_status != SEC_E_OK)
960     {
961         skip("Error: Setting up the client returned %s, exiting test!\n",
962                 getSecError(sec_status));
963         pFreeCredentialsHandle(client.cred);
964         return;
965     }
966
967     sec_status = setupFakeServer(&server, sec_pkg_name);
968
969     while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
970     {
971         client_stat = runClient(&client, first, SECURITY_NETWORK_DREP);
972
973         communicate(&client, &server);
974
975         server_stat = runFakeServer(&server, first, SECURITY_NETWORK_DREP);
976
977         communicate(&server, &client);
978         trace("Looping\n");
979         first = FALSE;
980     }
981
982     /********************************************
983      *    Now start with the actual testing     *
984      ********************************************/
985
986     if(pQueryContextAttributesA(client.ctxt, SECPKG_ATTR_SIZES,
987                 &ctxt_sizes) != SEC_E_OK)
988     {
989         skip("Failed to get context sizes, aborting test.\n");
990         goto end;
991     }
992
993     crypt.ulVersion = SECBUFFER_VERSION;
994     crypt.cBuffers = 2;
995
996     crypt.pBuffers = fake_data;
997
998     fake_data[0].BufferType = SECBUFFER_DATA;
999     fake_data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1000     fake_data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[0].cbBuffer);
1001
1002     fake_data[1].BufferType = SECBUFFER_DATA;
1003     fake_data[1].cbBuffer = lstrlen(message);
1004     fake_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[1].cbBuffer);
1005
1006     sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
1007     ok(sec_status == SEC_E_INVALID_TOKEN,
1008             "MakeSignature returned %s, not SEC_E_INVALID_TOKEN.\n",
1009             getSecError(sec_status));
1010
1011     crypt.pBuffers = data;
1012
1013     data[0].BufferType = SECBUFFER_TOKEN;
1014     data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1015     data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[0].cbBuffer);
1016
1017     data[1].BufferType = SECBUFFER_DATA;
1018     data[1].cbBuffer = lstrlen(message);
1019     data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1020     memcpy(data[1].pvBuffer, message, data[1].cbBuffer);
1021
1022     /* As we forced NTLM to fall back to a password-derived session key,
1023      * we should get the same signature for our data, no matter if
1024      * it is sent by the client or the server
1025      */
1026     sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
1027     ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1028             getSecError(sec_status));
1029     ok(!memcmp(crypt.pBuffers[0].pvBuffer, message_signature,
1030                crypt.pBuffers[0].cbBuffer), "Signature is not as expected.\n");
1031
1032     data[0].cbBuffer = sizeof(message_signature);
1033
1034     memcpy(data[0].pvBuffer, crypt_trailer_client, data[0].cbBuffer);
1035
1036     sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
1037     ok(sec_status == SEC_E_MESSAGE_ALTERED,
1038             "VerifySignature returned %s, not SEC_E_MESSAGE_ALTERED.\n",
1039             getSecError(sec_status));
1040
1041     memcpy(data[0].pvBuffer, message_signature, data[0].cbBuffer);
1042
1043     sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
1044     ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK.\n",
1045             getSecError(sec_status));
1046
1047     sec_status = pEncryptMessage(client.ctxt, 0, &crypt, 0);
1048     if (sec_status == SEC_E_UNSUPPORTED_FUNCTION)
1049     {
1050         skip("Encrypt message returned SEC_E_UNSUPPORTED_FUNCTION. "
1051              "Expected on Vista.\n");
1052         goto end;
1053     }
1054     ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1055             getSecError(sec_status));
1056
1057     ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client,
1058                crypt.pBuffers[0].cbBuffer), "Crypt trailer not as expected.\n");
1059     ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1060                crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1061
1062     data[0].cbBuffer = sizeof(crypt_trailer_server);
1063     data[1].cbBuffer = sizeof(crypt_message_server);
1064     memcpy(data[0].pvBuffer, crypt_trailer_server, data[0].cbBuffer);
1065     memcpy(data[1].pvBuffer, crypt_message_server, data[1].cbBuffer);
1066
1067     sec_status = pDecryptMessage(client.ctxt, &crypt, 0, &qop);
1068
1069     ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1070             getSecError(sec_status));
1071     ok(!memcmp(crypt.pBuffers[1].pvBuffer, message_binary,
1072                crypt.pBuffers[1].cbBuffer),
1073             "Failed to decrypt message correctly.\n");
1074
1075     trace("Testing with more than one buffer.\n");
1076
1077     crypt.cBuffers = sizeof(complex_data)/sizeof(complex_data[0]);
1078     crypt.pBuffers = complex_data;
1079
1080     complex_data[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1081     complex_data[0].cbBuffer = sizeof(message_header);
1082     complex_data[0].pvBuffer = message_header;
1083
1084     complex_data[1].BufferType = SECBUFFER_DATA;
1085     complex_data[1].cbBuffer = lstrlen(message);
1086     complex_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1087     memcpy(complex_data[1].pvBuffer, message, complex_data[1].cbBuffer);
1088
1089     complex_data[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1090     complex_data[2].cbBuffer = sizeof(message_header);
1091     complex_data[2].pvBuffer = message_header;
1092
1093     complex_data[3].BufferType = SECBUFFER_TOKEN;
1094     complex_data[3].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1095     complex_data[3].pvBuffer = HeapAlloc(GetProcessHeap(), 0, complex_data[3].cbBuffer);
1096
1097     /* We should get a dummy signature again. */
1098     sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
1099     ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1100             getSecError(sec_status));
1101     ok(!memcmp(crypt.pBuffers[3].pvBuffer, message_signature,
1102                crypt.pBuffers[3].cbBuffer), "Signature is not as expected.\n");
1103
1104     /* Being a dummy signature, it will verify right away, as if the server
1105      * sent it */
1106     sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
1107     ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK\n",
1108             getSecError(sec_status));
1109
1110     sec_status = pEncryptMessage(client.ctxt, 0, &crypt, 0);
1111     ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1112             getSecError(sec_status));
1113
1114     ok(!memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
1115                crypt.pBuffers[3].cbBuffer), "Crypt trailer not as expected.\n");
1116
1117     ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1118                crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1119
1120     memcpy(complex_data[1].pvBuffer, crypt_message_server2, complex_data[1].cbBuffer);
1121     memcpy(complex_data[3].pvBuffer, crypt_trailer_server2, complex_data[3].cbBuffer);
1122
1123     sec_status = pDecryptMessage(client.ctxt, &crypt, 0, &qop);
1124     ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1125             getSecError(sec_status));
1126
1127
1128 end:
1129     cleanupBuffers(&client);
1130     cleanupBuffers(&server);
1131
1132     pDeleteSecurityContext(client.ctxt);
1133     pFreeCredentialsHandle(client.cred);
1134
1135     HeapFree(GetProcessHeap(), 0, fake_data[0].pvBuffer);
1136     HeapFree(GetProcessHeap(), 0, fake_data[1].pvBuffer);
1137     HeapFree(GetProcessHeap(), 0, data[0].pvBuffer);
1138     HeapFree(GetProcessHeap(), 0, data[1].pvBuffer);
1139     HeapFree(GetProcessHeap(), 0, complex_data[1].pvBuffer);
1140     HeapFree(GetProcessHeap(), 0, complex_data[3].pvBuffer);
1141 }
1142
1143 static void testAcquireCredentialsHandle(void)
1144 {
1145     CredHandle cred;
1146     TimeStamp ttl;
1147     static char test_user[] = "testuser",
1148                 workgroup[] = "WORKGROUP",
1149                 test_pass[] = "testpass",
1150                 sec_pkg_name[] = "NTLM";
1151     SECURITY_STATUS ret;
1152     SEC_WINNT_AUTH_IDENTITY id;
1153     PSecPkgInfo             pkg_info = NULL;
1154
1155     if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1156     {
1157         skip("NTLM package not installed, skipping test\n");
1158         return;
1159     }
1160     pFreeContextBuffer(pkg_info);
1161
1162     id.User = (unsigned char*) test_user;
1163     id.UserLength = strlen((char *) id.User);
1164     id.Domain = (unsigned char *) workgroup;
1165     id.DomainLength = strlen((char *) id.Domain);
1166     id.Password = (unsigned char*) test_pass;
1167     id.PasswordLength = strlen((char *) id.Password);
1168     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1169
1170     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1171             NULL, &id, NULL, NULL, &cred, &ttl);
1172     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1173             getSecError(ret));
1174     pFreeCredentialsHandle(&cred);
1175
1176     id.DomainLength = 0;
1177     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1178             NULL, &id, NULL, NULL, &cred, &ttl);
1179     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1180             getSecError(ret));
1181     pFreeCredentialsHandle(&cred);
1182
1183     id.Domain = NULL;
1184     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1185             NULL, &id, NULL, NULL, &cred, &ttl);
1186     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1187             getSecError(ret));
1188     pFreeCredentialsHandle(&cred);
1189
1190     id.Domain = (unsigned char *) workgroup;
1191     id.DomainLength = strlen((char *) id.Domain);
1192     id.UserLength = 0;
1193     id.User = NULL;
1194     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1195             NULL, &id, NULL, NULL, &cred, &ttl);
1196     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1197             getSecError(ret));
1198     pFreeCredentialsHandle(&cred);
1199
1200     id.User = (unsigned char*) test_user;
1201     id.UserLength = strlen((char *) id.User);
1202     id.Password = NULL;
1203     id.PasswordLength = 0;
1204     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1205             NULL, &id, NULL, NULL, &cred, &ttl);
1206     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1207             getSecError(ret));
1208     pFreeCredentialsHandle(&cred);
1209 }
1210
1211 static void test_cred_multiple_use(void)
1212 {
1213     static char test_user[] = "testuser",
1214                 workgroup[] = "WORKGROUP",
1215                 test_pass[] = "testpass",
1216                 sec_pkg_name[] = "NTLM";
1217     SECURITY_STATUS ret;
1218     SEC_WINNT_AUTH_IDENTITY id;
1219     PSecPkgInfo             pkg_info = NULL;
1220     CredHandle              cred;
1221     CtxtHandle              ctxt1;
1222     CtxtHandle              ctxt2;
1223     SecBufferDesc           buffer_desc;
1224     SecBuffer               buffers[1];
1225     ULONG                   ctxt_attr;
1226     TimeStamp               ttl;
1227
1228     if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1229     {
1230         skip("NTLM package not installed, skipping test\n");
1231         return;
1232     }
1233     buffers[0].cbBuffer = pkg_info->cbMaxToken;
1234     buffers[0].BufferType = SECBUFFER_TOKEN;
1235     buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1236
1237     pFreeContextBuffer(pkg_info);
1238
1239     id.User = (unsigned char*) test_user;
1240     id.UserLength = strlen((char *) id.User);
1241     id.Domain = (unsigned char *) workgroup;
1242     id.DomainLength = strlen((char *) id.Domain);
1243     id.Password = (unsigned char*) test_pass;
1244     id.PasswordLength = strlen((char *) id.Password);
1245     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1246
1247     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1248             NULL, &id, NULL, NULL, &cred, &ttl);
1249     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1250             getSecError(ret));
1251
1252     buffer_desc.ulVersion = SECBUFFER_VERSION;
1253     buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
1254     buffer_desc.pBuffers = buffers;
1255
1256     ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1257             0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt1, &buffer_desc,
1258             &ctxt_attr, &ttl);
1259     ok(ret == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed with error 0x%x\n", ret);
1260
1261     ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1262             0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt2, &buffer_desc,
1263             &ctxt_attr, &ttl);
1264     ok(ret == SEC_I_CONTINUE_NEEDED, "Second InitializeSecurityContextA on cred handle failed with error 0x%x\n", ret);
1265
1266     ret = pDeleteSecurityContext(&ctxt1);
1267     ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1268     ret = pDeleteSecurityContext(&ctxt2);
1269     ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1270     ret = pFreeCredentialsHandle(&cred);
1271     ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret);
1272 }
1273
1274 static void test_null_auth_data(void)
1275 {
1276     SECURITY_STATUS status;
1277     PSecPkgInfo info;
1278     CredHandle cred;
1279     CtxtHandle ctx;
1280     SecBufferDesc buffer_desc;
1281     SecBuffer buffers[1];
1282     char user[256];
1283     TimeStamp ttl;
1284     ULONG attr, size;
1285     BOOLEAN ret;
1286
1287     if(pQuerySecurityPackageInfoA((SEC_CHAR *)"NTLM", &info) != SEC_E_OK)
1288     {
1289         skip("NTLM package not installed, skipping test\n");
1290         return;
1291     }
1292
1293     status = pAcquireCredentialsHandleA(NULL, (SEC_CHAR *)"NTLM", SECPKG_CRED_OUTBOUND,
1294                                         NULL, NULL, NULL, NULL, &cred, &ttl);
1295     ok(status == SEC_E_OK, "AcquireCredentialsHande() failed %s\n", getSecError(status));
1296
1297     buffers[0].cbBuffer = info->cbMaxToken;
1298     buffers[0].BufferType = SECBUFFER_TOKEN;
1299     buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1300
1301     buffer_desc.ulVersion = SECBUFFER_VERSION;
1302     buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
1303     buffer_desc.pBuffers = buffers;
1304
1305     size = sizeof(user);
1306     ret = pGetUserNameExA(NameSamCompatible, user, &size);
1307     ok(ret, "GetUserNameExA failed %u\n", GetLastError());
1308
1309     status = pInitializeSecurityContextA(&cred, NULL, (SEC_CHAR *)user,
1310                                          ISC_REQ_CONNECTION, 0, SECURITY_NETWORK_DREP,
1311                                          NULL, 0, &ctx, &buffer_desc, &attr, &ttl);
1312     todo_wine
1313     ok(status == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed %s\n", getSecError(status));
1314 }
1315
1316 START_TEST(ntlm)
1317 {
1318     InitFunctionPtrs();
1319
1320     if(pFreeCredentialsHandle && pDeleteSecurityContext &&
1321        pDeleteSecurityContext && pAcquireCredentialsHandleA &&
1322        pInitializeSecurityContextA && pCompleteAuthToken &&
1323        pQuerySecurityPackageInfoA)
1324     {
1325         testAcquireCredentialsHandle();
1326         testInitializeSecurityContextFlags();
1327         if(pAcceptSecurityContext)
1328         {
1329             testAuth(SECURITY_NATIVE_DREP, TRUE);
1330             testAuth(SECURITY_NETWORK_DREP, TRUE);
1331             testAuth(SECURITY_NATIVE_DREP, FALSE);
1332             testAuth(SECURITY_NETWORK_DREP, FALSE);
1333         }
1334         if(pMakeSignature && pVerifySignature && pEncryptMessage &&
1335            pDecryptMessage)
1336             testSignSeal();
1337
1338         test_cred_multiple_use();
1339         if (pGetUserNameExA) test_null_auth_data();
1340     }
1341     else
1342         win_skip("Needed functions are not available\n");
1343
1344     if(secdll)
1345         FreeLibrary(secdll);
1346 }