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