msvcp: Prevent overflows while operating on string sizes.
[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         ok(0, "NTLM 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         ok(0, "NTLM 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         ok(0, "NTLM 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     /* first 8 bytes must always be the same */
1062     ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client, 8), "Crypt trailer not as expected.\n");
1063
1064     /* the rest depends on the session key */
1065     if (!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client, crypt.pBuffers[0].cbBuffer))
1066     {
1067         ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client,
1068                    crypt.pBuffers[0].cbBuffer), "Crypt trailer not as expected.\n");
1069         ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1070                    crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1071         if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1072                    crypt.pBuffers[1].cbBuffer))
1073         {
1074             int i;
1075             for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
1076             {
1077                 if (i % 8 == 0) printf("     ");
1078                 printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
1079                 if (i % 8 == 7) printf("\n");
1080             }
1081             printf("\n");
1082         }
1083
1084         data[0].cbBuffer = sizeof(crypt_trailer_server);
1085         data[1].cbBuffer = sizeof(crypt_message_server);
1086         memcpy(data[0].pvBuffer, crypt_trailer_server, data[0].cbBuffer);
1087         memcpy(data[1].pvBuffer, crypt_message_server, data[1].cbBuffer);
1088
1089         sec_status = pDecryptMessage(&client.ctxt, &crypt, 0, &qop);
1090
1091         ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1092            getSecError(sec_status));
1093         ok(!memcmp(crypt.pBuffers[1].pvBuffer, message_binary,
1094                    crypt.pBuffers[1].cbBuffer),
1095            "Failed to decrypt message correctly.\n");
1096     }
1097     else trace( "A different session key is being used\n" );
1098
1099     trace("Testing with more than one buffer.\n");
1100
1101     crypt.cBuffers = sizeof(complex_data)/sizeof(complex_data[0]);
1102     crypt.pBuffers = complex_data;
1103
1104     complex_data[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1105     complex_data[0].cbBuffer = sizeof(message_header);
1106     complex_data[0].pvBuffer = message_header;
1107
1108     complex_data[1].BufferType = SECBUFFER_DATA;
1109     complex_data[1].cbBuffer = lstrlen(message);
1110     complex_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1111     memcpy(complex_data[1].pvBuffer, message, complex_data[1].cbBuffer);
1112
1113     complex_data[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1114     complex_data[2].cbBuffer = sizeof(message_header);
1115     complex_data[2].pvBuffer = message_header;
1116
1117     complex_data[3].BufferType = SECBUFFER_TOKEN;
1118     complex_data[3].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1119     complex_data[3].pvBuffer = HeapAlloc(GetProcessHeap(), 0, complex_data[3].cbBuffer);
1120
1121     /* We should get a dummy signature again. */
1122     sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0);
1123     ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1124             getSecError(sec_status));
1125     ok(!memcmp(crypt.pBuffers[3].pvBuffer, message_signature,
1126                crypt.pBuffers[3].cbBuffer), "Signature is not as expected.\n");
1127
1128     /* Being a dummy signature, it will verify right away, as if the server
1129      * sent it */
1130     sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop);
1131     ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK\n",
1132             getSecError(sec_status));
1133
1134     sec_status = pEncryptMessage(&client.ctxt, 0, &crypt, 0);
1135     ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1136             getSecError(sec_status));
1137
1138     ok(!memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2, 8), "Crypt trailer not as expected.\n");
1139
1140     if (memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
1141                crypt.pBuffers[3].cbBuffer)) goto end;
1142
1143     ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1144                crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1145     if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1146                crypt.pBuffers[1].cbBuffer))
1147     {
1148         int i;
1149         for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
1150         {
1151             if (i % 8 == 0) printf("     ");
1152             printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
1153             if (i % 8 == 7) printf("\n");
1154         }
1155         printf("\n");
1156     }
1157
1158     memcpy(complex_data[1].pvBuffer, crypt_message_server2, complex_data[1].cbBuffer);
1159     memcpy(complex_data[3].pvBuffer, crypt_trailer_server2, complex_data[3].cbBuffer);
1160
1161     sec_status = pDecryptMessage(&client.ctxt, &crypt, 0, &qop);
1162     ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1163             getSecError(sec_status));
1164
1165
1166 end:
1167     cleanupBuffers(&client);
1168     cleanupBuffers(&server);
1169
1170     pDeleteSecurityContext(&client.ctxt);
1171     pFreeCredentialsHandle(&client.cred);
1172
1173     HeapFree(GetProcessHeap(), 0, fake_data[0].pvBuffer);
1174     HeapFree(GetProcessHeap(), 0, fake_data[1].pvBuffer);
1175     HeapFree(GetProcessHeap(), 0, data[0].pvBuffer);
1176     HeapFree(GetProcessHeap(), 0, data[1].pvBuffer);
1177     HeapFree(GetProcessHeap(), 0, complex_data[1].pvBuffer);
1178     HeapFree(GetProcessHeap(), 0, complex_data[3].pvBuffer);
1179 }
1180
1181 static BOOL testAcquireCredentialsHandle(void)
1182 {
1183     CredHandle cred;
1184     TimeStamp ttl;
1185     static char test_user[] = "testuser",
1186                 workgroup[] = "WORKGROUP",
1187                 test_pass[] = "testpass",
1188                 sec_pkg_name[] = "NTLM";
1189     SECURITY_STATUS ret;
1190     SEC_WINNT_AUTH_IDENTITY id;
1191     PSecPkgInfo             pkg_info = NULL;
1192
1193     if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1194     {
1195         ok(0, "NTLM package not installed, skipping test\n");
1196         return FALSE;
1197     }
1198     pFreeContextBuffer(pkg_info);
1199
1200     id.User = (unsigned char*) test_user;
1201     id.UserLength = strlen((char *) id.User);
1202     id.Domain = (unsigned char *) workgroup;
1203     id.DomainLength = strlen((char *) id.Domain);
1204     id.Password = (unsigned char*) test_pass;
1205     id.PasswordLength = strlen((char *) id.Password);
1206     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1207
1208     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1209             NULL, &id, NULL, NULL, &cred, &ttl);
1210     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1211             getSecError(ret));
1212     pFreeCredentialsHandle(&cred);
1213
1214     id.DomainLength = 0;
1215     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1216             NULL, &id, NULL, NULL, &cred, &ttl);
1217     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1218             getSecError(ret));
1219     pFreeCredentialsHandle(&cred);
1220
1221     id.Domain = NULL;
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.Domain = (unsigned char *) workgroup;
1229     id.DomainLength = strlen((char *) id.Domain);
1230     id.UserLength = 0;
1231     id.User = NULL;
1232     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1233             NULL, &id, NULL, NULL, &cred, &ttl);
1234     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1235             getSecError(ret));
1236     pFreeCredentialsHandle(&cred);
1237
1238     id.User = (unsigned char*) test_user;
1239     id.UserLength = strlen((char *) id.User);
1240     id.Password = NULL;
1241     id.PasswordLength = 0;
1242     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1243             NULL, &id, NULL, NULL, &cred, &ttl);
1244     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1245             getSecError(ret));
1246     pFreeCredentialsHandle(&cred);
1247     return TRUE;
1248 }
1249
1250 static void test_cred_multiple_use(void)
1251 {
1252     static char test_user[] = "testuser",
1253                 workgroup[] = "WORKGROUP",
1254                 test_pass[] = "testpass",
1255                 sec_pkg_name[] = "NTLM";
1256     SECURITY_STATUS ret;
1257     SEC_WINNT_AUTH_IDENTITY id;
1258     PSecPkgInfo             pkg_info = NULL;
1259     CredHandle              cred;
1260     CtxtHandle              ctxt1;
1261     CtxtHandle              ctxt2;
1262     SecBufferDesc           buffer_desc;
1263     SecBuffer               buffers[1];
1264     ULONG                   ctxt_attr;
1265     TimeStamp               ttl;
1266
1267     if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1268     {
1269         ok(0, "NTLM package not installed, skipping test\n");
1270         return;
1271     }
1272     buffers[0].cbBuffer = pkg_info->cbMaxToken;
1273     buffers[0].BufferType = SECBUFFER_TOKEN;
1274     buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1275
1276     pFreeContextBuffer(pkg_info);
1277
1278     id.User = (unsigned char*) test_user;
1279     id.UserLength = strlen((char *) id.User);
1280     id.Domain = (unsigned char *) workgroup;
1281     id.DomainLength = strlen((char *) id.Domain);
1282     id.Password = (unsigned char*) test_pass;
1283     id.PasswordLength = strlen((char *) id.Password);
1284     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1285
1286     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1287             NULL, &id, NULL, NULL, &cred, &ttl);
1288     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1289             getSecError(ret));
1290
1291     buffer_desc.ulVersion = SECBUFFER_VERSION;
1292     buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
1293     buffer_desc.pBuffers = buffers;
1294
1295     ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1296             0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt1, &buffer_desc,
1297             &ctxt_attr, &ttl);
1298     ok(ret == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed with error 0x%x\n", ret);
1299
1300     ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1301             0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt2, &buffer_desc,
1302             &ctxt_attr, &ttl);
1303     ok(ret == SEC_I_CONTINUE_NEEDED, "Second InitializeSecurityContextA on cred handle failed with error 0x%x\n", ret);
1304
1305     ret = pDeleteSecurityContext(&ctxt1);
1306     ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1307     ret = pDeleteSecurityContext(&ctxt2);
1308     ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1309     ret = pFreeCredentialsHandle(&cred);
1310     ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret);
1311
1312     HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer);
1313 }
1314
1315 static void test_null_auth_data(void)
1316 {
1317     SECURITY_STATUS status;
1318     PSecPkgInfo info;
1319     CredHandle cred;
1320     CtxtHandle ctx;
1321     SecBufferDesc buffer_desc;
1322     SecBuffer buffers[1];
1323     char user[256];
1324     TimeStamp ttl;
1325     ULONG attr, size;
1326     BOOLEAN ret;
1327
1328     if(pQuerySecurityPackageInfoA((SEC_CHAR *)"NTLM", &info) != SEC_E_OK)
1329     {
1330         ok(0, "NTLM package not installed, skipping test\n");
1331         return;
1332     }
1333
1334     status = pAcquireCredentialsHandleA(NULL, (SEC_CHAR *)"NTLM", SECPKG_CRED_OUTBOUND,
1335                                         NULL, NULL, NULL, NULL, &cred, &ttl);
1336     ok(status == SEC_E_OK, "AcquireCredentialsHande() failed %s\n", getSecError(status));
1337
1338     buffers[0].cbBuffer = info->cbMaxToken;
1339     buffers[0].BufferType = SECBUFFER_TOKEN;
1340     buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1341
1342     buffer_desc.ulVersion = SECBUFFER_VERSION;
1343     buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
1344     buffer_desc.pBuffers = buffers;
1345
1346     size = sizeof(user);
1347     ret = pGetUserNameExA(NameSamCompatible, user, &size);
1348     ok(ret, "GetUserNameExA failed %u\n", GetLastError());
1349
1350     status = pInitializeSecurityContextA(&cred, NULL, (SEC_CHAR *)user,
1351                                          ISC_REQ_CONNECTION, 0, SECURITY_NETWORK_DREP,
1352                                          NULL, 0, &ctx, &buffer_desc, &attr, &ttl);
1353     ok(status == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed %s\n", getSecError(status));
1354
1355     ret = pDeleteSecurityContext(&ctx);
1356     ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1357     ret = pFreeCredentialsHandle(&cred);
1358     ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret);
1359
1360     pFreeContextBuffer(info);
1361     HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer);
1362 }
1363
1364 START_TEST(ntlm)
1365 {
1366     InitFunctionPtrs();
1367
1368     if(pFreeCredentialsHandle && pDeleteSecurityContext &&
1369        pDeleteSecurityContext && pAcquireCredentialsHandleA &&
1370        pInitializeSecurityContextA && pCompleteAuthToken &&
1371        pQuerySecurityPackageInfoA)
1372     {
1373         if(!testAcquireCredentialsHandle())
1374             goto cleanup;
1375         testInitializeSecurityContextFlags();
1376         if(pAcceptSecurityContext)
1377         {
1378             testAuth(SECURITY_NATIVE_DREP, TRUE);
1379             testAuth(SECURITY_NETWORK_DREP, TRUE);
1380             testAuth(SECURITY_NATIVE_DREP, FALSE);
1381             testAuth(SECURITY_NETWORK_DREP, FALSE);
1382         }
1383         if(pMakeSignature && pVerifySignature && pEncryptMessage &&
1384            pDecryptMessage)
1385             testSignSeal();
1386
1387         test_cred_multiple_use();
1388         if (pGetUserNameExA) test_null_auth_data();
1389     }
1390     else
1391         win_skip("Needed functions are not available\n");
1392
1393 cleanup:
1394     if(secdll)
1395         FreeLibrary(secdll);
1396 }