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