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