advapi32/tests: Test SystemFunction036.
[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
972     while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
973     {
974         client_stat = runClient(&client, first, SECURITY_NETWORK_DREP);
975
976         communicate(&client, &server);
977
978         server_stat = runFakeServer(&server, first, SECURITY_NETWORK_DREP);
979
980         communicate(&server, &client);
981         trace("Looping\n");
982         first = FALSE;
983     }
984
985     /********************************************
986      *    Now start with the actual testing     *
987      ********************************************/
988
989     if(pQueryContextAttributesA(&client.ctxt, SECPKG_ATTR_SIZES,
990                 &ctxt_sizes) != SEC_E_OK)
991     {
992         skip("Failed to get context sizes, aborting test.\n");
993         goto end;
994     }
995
996     crypt.ulVersion = SECBUFFER_VERSION;
997     crypt.cBuffers = 2;
998
999     crypt.pBuffers = fake_data;
1000
1001     fake_data[0].BufferType = SECBUFFER_DATA;
1002     fake_data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1003     fake_data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[0].cbBuffer);
1004
1005     fake_data[1].BufferType = SECBUFFER_DATA;
1006     fake_data[1].cbBuffer = lstrlen(message);
1007     fake_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[1].cbBuffer);
1008
1009     sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0);
1010     ok(sec_status == SEC_E_INVALID_TOKEN,
1011             "MakeSignature returned %s, not SEC_E_INVALID_TOKEN.\n",
1012             getSecError(sec_status));
1013
1014     crypt.pBuffers = data;
1015
1016     data[0].BufferType = SECBUFFER_TOKEN;
1017     data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1018     data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[0].cbBuffer);
1019
1020     data[1].BufferType = SECBUFFER_DATA;
1021     data[1].cbBuffer = lstrlen(message);
1022     data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1023     memcpy(data[1].pvBuffer, message, data[1].cbBuffer);
1024
1025     /* As we forced NTLM to fall back to a password-derived session key,
1026      * we should get the same signature for our data, no matter if
1027      * it is sent by the client or the server
1028      */
1029     sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0);
1030     ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1031             getSecError(sec_status));
1032     ok(!memcmp(crypt.pBuffers[0].pvBuffer, message_signature,
1033                crypt.pBuffers[0].cbBuffer), "Signature is not as expected.\n");
1034
1035     data[0].cbBuffer = sizeof(message_signature);
1036
1037     memcpy(data[0].pvBuffer, crypt_trailer_client, data[0].cbBuffer);
1038
1039     sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop);
1040     ok(sec_status == SEC_E_MESSAGE_ALTERED,
1041             "VerifySignature returned %s, not SEC_E_MESSAGE_ALTERED.\n",
1042             getSecError(sec_status));
1043
1044     memcpy(data[0].pvBuffer, message_signature, data[0].cbBuffer);
1045
1046     sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop);
1047     ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK.\n",
1048             getSecError(sec_status));
1049
1050     sec_status = pEncryptMessage(&client.ctxt, 0, &crypt, 0);
1051     if (sec_status == SEC_E_UNSUPPORTED_FUNCTION)
1052     {
1053         skip("Encrypt message returned SEC_E_UNSUPPORTED_FUNCTION. "
1054              "Expected on Vista.\n");
1055         goto end;
1056     }
1057     ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1058             getSecError(sec_status));
1059
1060     ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client,
1061                crypt.pBuffers[0].cbBuffer), "Crypt trailer not as expected.\n");
1062     if (memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client,
1063                crypt.pBuffers[0].cbBuffer))
1064     {
1065         int i;
1066         for (i = 0; i < crypt.pBuffers[0].cbBuffer; i++)
1067         {
1068             if (i % 8 == 0) printf("     ");
1069             printf("0x%02x,", ((unsigned char *)crypt.pBuffers[0].pvBuffer)[i]);
1070             if (i % 8 == 7) printf("\n");
1071         }
1072         printf("\n");
1073     }
1074     ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1075                crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1076     if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1077                crypt.pBuffers[1].cbBuffer))
1078     {
1079         int i;
1080         for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
1081         {
1082             if (i % 8 == 0) printf("     ");
1083             printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
1084             if (i % 8 == 7) printf("\n");
1085         }
1086         printf("\n");
1087     }
1088
1089     data[0].cbBuffer = sizeof(crypt_trailer_server);
1090     data[1].cbBuffer = sizeof(crypt_message_server);
1091     memcpy(data[0].pvBuffer, crypt_trailer_server, data[0].cbBuffer);
1092     memcpy(data[1].pvBuffer, crypt_message_server, data[1].cbBuffer);
1093
1094     sec_status = pDecryptMessage(&client.ctxt, &crypt, 0, &qop);
1095
1096     ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1097             getSecError(sec_status));
1098     ok(!memcmp(crypt.pBuffers[1].pvBuffer, message_binary,
1099                crypt.pBuffers[1].cbBuffer),
1100             "Failed to decrypt message correctly.\n");
1101
1102     trace("Testing with more than one buffer.\n");
1103
1104     crypt.cBuffers = sizeof(complex_data)/sizeof(complex_data[0]);
1105     crypt.pBuffers = complex_data;
1106
1107     complex_data[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1108     complex_data[0].cbBuffer = sizeof(message_header);
1109     complex_data[0].pvBuffer = message_header;
1110
1111     complex_data[1].BufferType = SECBUFFER_DATA;
1112     complex_data[1].cbBuffer = lstrlen(message);
1113     complex_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1114     memcpy(complex_data[1].pvBuffer, message, complex_data[1].cbBuffer);
1115
1116     complex_data[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1117     complex_data[2].cbBuffer = sizeof(message_header);
1118     complex_data[2].pvBuffer = message_header;
1119
1120     complex_data[3].BufferType = SECBUFFER_TOKEN;
1121     complex_data[3].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1122     complex_data[3].pvBuffer = HeapAlloc(GetProcessHeap(), 0, complex_data[3].cbBuffer);
1123
1124     /* We should get a dummy signature again. */
1125     sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0);
1126     ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1127             getSecError(sec_status));
1128     ok(!memcmp(crypt.pBuffers[3].pvBuffer, message_signature,
1129                crypt.pBuffers[3].cbBuffer), "Signature is not as expected.\n");
1130
1131     /* Being a dummy signature, it will verify right away, as if the server
1132      * sent it */
1133     sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop);
1134     ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK\n",
1135             getSecError(sec_status));
1136
1137     sec_status = pEncryptMessage(&client.ctxt, 0, &crypt, 0);
1138     ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1139             getSecError(sec_status));
1140
1141     ok(!memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
1142                crypt.pBuffers[3].cbBuffer), "Crypt trailer not as expected.\n");
1143     if (memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
1144                crypt.pBuffers[3].cbBuffer))
1145     {
1146         int i;
1147         for (i = 0; i < crypt.pBuffers[3].cbBuffer; i++)
1148         {
1149             if (i % 8 == 0) printf("     ");
1150             printf("0x%02x,", ((unsigned char *)crypt.pBuffers[3].pvBuffer)[i]);
1151             if (i % 8 == 7) printf("\n");
1152         }
1153         printf("\n");
1154     }
1155
1156     ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1157                crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1158     if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1159                crypt.pBuffers[1].cbBuffer))
1160     {
1161         int i;
1162         for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
1163         {
1164             if (i % 8 == 0) printf("     ");
1165             printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
1166             if (i % 8 == 7) printf("\n");
1167         }
1168         printf("\n");
1169     }
1170
1171     memcpy(complex_data[1].pvBuffer, crypt_message_server2, complex_data[1].cbBuffer);
1172     memcpy(complex_data[3].pvBuffer, crypt_trailer_server2, complex_data[3].cbBuffer);
1173
1174     sec_status = pDecryptMessage(&client.ctxt, &crypt, 0, &qop);
1175     ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1176             getSecError(sec_status));
1177
1178
1179 end:
1180     cleanupBuffers(&client);
1181     cleanupBuffers(&server);
1182
1183     pDeleteSecurityContext(&client.ctxt);
1184     pFreeCredentialsHandle(&client.cred);
1185
1186     HeapFree(GetProcessHeap(), 0, fake_data[0].pvBuffer);
1187     HeapFree(GetProcessHeap(), 0, fake_data[1].pvBuffer);
1188     HeapFree(GetProcessHeap(), 0, data[0].pvBuffer);
1189     HeapFree(GetProcessHeap(), 0, data[1].pvBuffer);
1190     HeapFree(GetProcessHeap(), 0, complex_data[1].pvBuffer);
1191     HeapFree(GetProcessHeap(), 0, complex_data[3].pvBuffer);
1192 }
1193
1194 static void testAcquireCredentialsHandle(void)
1195 {
1196     CredHandle cred;
1197     TimeStamp ttl;
1198     static char test_user[] = "testuser",
1199                 workgroup[] = "WORKGROUP",
1200                 test_pass[] = "testpass",
1201                 sec_pkg_name[] = "NTLM";
1202     SECURITY_STATUS ret;
1203     SEC_WINNT_AUTH_IDENTITY id;
1204     PSecPkgInfo             pkg_info = NULL;
1205
1206     if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1207     {
1208         skip("NTLM package not installed, skipping test\n");
1209         return;
1210     }
1211     pFreeContextBuffer(pkg_info);
1212
1213     id.User = (unsigned char*) test_user;
1214     id.UserLength = strlen((char *) id.User);
1215     id.Domain = (unsigned char *) workgroup;
1216     id.DomainLength = strlen((char *) id.Domain);
1217     id.Password = (unsigned char*) test_pass;
1218     id.PasswordLength = strlen((char *) id.Password);
1219     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1220
1221     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1222             NULL, &id, NULL, NULL, &cred, &ttl);
1223     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1224             getSecError(ret));
1225     pFreeCredentialsHandle(&cred);
1226
1227     id.DomainLength = 0;
1228     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1229             NULL, &id, NULL, NULL, &cred, &ttl);
1230     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1231             getSecError(ret));
1232     pFreeCredentialsHandle(&cred);
1233
1234     id.Domain = NULL;
1235     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1236             NULL, &id, NULL, NULL, &cred, &ttl);
1237     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1238             getSecError(ret));
1239     pFreeCredentialsHandle(&cred);
1240
1241     id.Domain = (unsigned char *) workgroup;
1242     id.DomainLength = strlen((char *) id.Domain);
1243     id.UserLength = 0;
1244     id.User = NULL;
1245     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1246             NULL, &id, NULL, NULL, &cred, &ttl);
1247     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1248             getSecError(ret));
1249     pFreeCredentialsHandle(&cred);
1250
1251     id.User = (unsigned char*) test_user;
1252     id.UserLength = strlen((char *) id.User);
1253     id.Password = NULL;
1254     id.PasswordLength = 0;
1255     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1256             NULL, &id, NULL, NULL, &cred, &ttl);
1257     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1258             getSecError(ret));
1259     pFreeCredentialsHandle(&cred);
1260 }
1261
1262 static void test_cred_multiple_use(void)
1263 {
1264     static char test_user[] = "testuser",
1265                 workgroup[] = "WORKGROUP",
1266                 test_pass[] = "testpass",
1267                 sec_pkg_name[] = "NTLM";
1268     SECURITY_STATUS ret;
1269     SEC_WINNT_AUTH_IDENTITY id;
1270     PSecPkgInfo             pkg_info = NULL;
1271     CredHandle              cred;
1272     CtxtHandle              ctxt1;
1273     CtxtHandle              ctxt2;
1274     SecBufferDesc           buffer_desc;
1275     SecBuffer               buffers[1];
1276     ULONG                   ctxt_attr;
1277     TimeStamp               ttl;
1278
1279     if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1280     {
1281         skip("NTLM package not installed, skipping test\n");
1282         return;
1283     }
1284     buffers[0].cbBuffer = pkg_info->cbMaxToken;
1285     buffers[0].BufferType = SECBUFFER_TOKEN;
1286     buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1287
1288     pFreeContextBuffer(pkg_info);
1289
1290     id.User = (unsigned char*) test_user;
1291     id.UserLength = strlen((char *) id.User);
1292     id.Domain = (unsigned char *) workgroup;
1293     id.DomainLength = strlen((char *) id.Domain);
1294     id.Password = (unsigned char*) test_pass;
1295     id.PasswordLength = strlen((char *) id.Password);
1296     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1297
1298     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1299             NULL, &id, NULL, NULL, &cred, &ttl);
1300     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1301             getSecError(ret));
1302
1303     buffer_desc.ulVersion = SECBUFFER_VERSION;
1304     buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
1305     buffer_desc.pBuffers = buffers;
1306
1307     ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1308             0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt1, &buffer_desc,
1309             &ctxt_attr, &ttl);
1310     ok(ret == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed with error 0x%x\n", ret);
1311
1312     ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1313             0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt2, &buffer_desc,
1314             &ctxt_attr, &ttl);
1315     ok(ret == SEC_I_CONTINUE_NEEDED, "Second InitializeSecurityContextA on cred handle failed with error 0x%x\n", ret);
1316
1317     ret = pDeleteSecurityContext(&ctxt1);
1318     ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1319     ret = pDeleteSecurityContext(&ctxt2);
1320     ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1321     ret = pFreeCredentialsHandle(&cred);
1322     ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret);
1323
1324     HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer);
1325 }
1326
1327 static void test_null_auth_data(void)
1328 {
1329     SECURITY_STATUS status;
1330     PSecPkgInfo info;
1331     CredHandle cred;
1332     CtxtHandle ctx;
1333     SecBufferDesc buffer_desc;
1334     SecBuffer buffers[1];
1335     char user[256];
1336     TimeStamp ttl;
1337     ULONG attr, size;
1338     BOOLEAN ret;
1339
1340     if(pQuerySecurityPackageInfoA((SEC_CHAR *)"NTLM", &info) != SEC_E_OK)
1341     {
1342         skip("NTLM package not installed, skipping test\n");
1343         return;
1344     }
1345
1346     status = pAcquireCredentialsHandleA(NULL, (SEC_CHAR *)"NTLM", SECPKG_CRED_OUTBOUND,
1347                                         NULL, NULL, NULL, NULL, &cred, &ttl);
1348     ok(status == SEC_E_OK, "AcquireCredentialsHande() failed %s\n", getSecError(status));
1349
1350     buffers[0].cbBuffer = info->cbMaxToken;
1351     buffers[0].BufferType = SECBUFFER_TOKEN;
1352     buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1353
1354     buffer_desc.ulVersion = SECBUFFER_VERSION;
1355     buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
1356     buffer_desc.pBuffers = buffers;
1357
1358     size = sizeof(user);
1359     ret = pGetUserNameExA(NameSamCompatible, user, &size);
1360     ok(ret, "GetUserNameExA failed %u\n", GetLastError());
1361
1362     status = pInitializeSecurityContextA(&cred, NULL, (SEC_CHAR *)user,
1363                                          ISC_REQ_CONNECTION, 0, SECURITY_NETWORK_DREP,
1364                                          NULL, 0, &ctx, &buffer_desc, &attr, &ttl);
1365     ok(status == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed %s\n", getSecError(status));
1366
1367     ret = pDeleteSecurityContext(&ctx);
1368     ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1369     ret = pFreeCredentialsHandle(&cred);
1370     ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret);
1371
1372     pFreeContextBuffer(info);
1373     HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer);
1374 }
1375
1376 START_TEST(ntlm)
1377 {
1378     InitFunctionPtrs();
1379
1380     if(pFreeCredentialsHandle && pDeleteSecurityContext &&
1381        pDeleteSecurityContext && pAcquireCredentialsHandleA &&
1382        pInitializeSecurityContextA && pCompleteAuthToken &&
1383        pQuerySecurityPackageInfoA)
1384     {
1385         testAcquireCredentialsHandle();
1386         testInitializeSecurityContextFlags();
1387         if(pAcceptSecurityContext)
1388         {
1389             testAuth(SECURITY_NATIVE_DREP, TRUE);
1390             testAuth(SECURITY_NETWORK_DREP, TRUE);
1391             testAuth(SECURITY_NATIVE_DREP, FALSE);
1392             testAuth(SECURITY_NETWORK_DREP, FALSE);
1393         }
1394         if(pMakeSignature && pVerifySignature && pEncryptMessage &&
1395            pDecryptMessage)
1396             testSignSeal();
1397
1398         test_cred_multiple_use();
1399         if (pGetUserNameExA) test_null_auth_data();
1400     }
1401     else
1402         win_skip("Needed functions are not available\n");
1403
1404     if(secdll)
1405         FreeLibrary(secdll);
1406 }