crypt32: Implement file stores.
[wine] / dlls / secur32 / tests / main.c
1 /*
2  * Miscellaneous secur32 tests
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
22 #define SECURITY_WIN32
23
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <assert.h>
27 #include <windef.h>
28 #include <winbase.h>
29 #include <sspi.h>
30
31 #include "wine/test.h"
32
33 static HMODULE secdll;
34 static PSecurityFunctionTableA (SEC_ENTRY * pInitSecurityInterfaceA)(void);
35 static SECURITY_STATUS (SEC_ENTRY * pEnumerateSecurityPackagesA)(PULONG, PSecPkgInfoA*);
36 static SECURITY_STATUS (SEC_ENTRY * pFreeContextBuffer)(PVOID pv);
37 static SECURITY_STATUS (SEC_ENTRY * pQuerySecurityPackageInfoA)(SEC_CHAR*, PSecPkgInfoA*);
38 static SECURITY_STATUS (SEC_ENTRY * pAcquireCredentialsHandleA)(SEC_CHAR*, SEC_CHAR*,
39                             ULONG, PLUID, PVOID, SEC_GET_KEY_FN, PVOID, PCredHandle, PTimeStamp);
40 static SECURITY_STATUS (SEC_ENTRY * pInitializeSecurityContextA)(PCredHandle, PCtxtHandle,
41                             SEC_CHAR*, ULONG, ULONG, ULONG, PSecBufferDesc, ULONG, 
42                             PCtxtHandle, PSecBufferDesc, PULONG, PTimeStamp);
43 static SECURITY_STATUS (SEC_ENTRY * pCompleteAuthToken)(PCtxtHandle, PSecBufferDesc);
44 static SECURITY_STATUS (SEC_ENTRY * pAcceptSecurityContext)(PCredHandle, PCtxtHandle,
45                             PSecBufferDesc, ULONG, ULONG, PCtxtHandle, PSecBufferDesc,
46                             PULONG, PTimeStamp);
47 static SECURITY_STATUS (SEC_ENTRY * pFreeCredentialsHandle)(PCredHandle);
48 static SECURITY_STATUS (SEC_ENTRY * pDeleteSecurityContext)(PCtxtHandle);
49 static SECURITY_STATUS (SEC_ENTRY * pQueryContextAttributesA)(PCtxtHandle, ULONG, PVOID);
50
51 typedef struct _SspiData {
52     PCredHandle cred;
53     PCtxtHandle ctxt;
54     PSecBufferDesc in_buf;
55     PSecBufferDesc out_buf;
56     PSEC_WINNT_AUTH_IDENTITY id;
57     ULONG max_token;
58 } SspiData;
59
60 /* Forward declare some functions to avoid moving around the code */
61 SECURITY_STATUS setupBuffers(SspiData *sspi_data, SecPkgInfoA *sec_pkg_info);
62 void cleanupBuffers(SspiData *sspi_data);
63
64 void InitFunctionPtrs(void)
65 {
66     secdll = LoadLibraryA("secur32.dll");
67     if(!secdll)
68         secdll = LoadLibraryA("security.dll");
69     if(secdll)
70     {
71         pInitSecurityInterfaceA = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceA");
72         pEnumerateSecurityPackagesA = (PVOID)GetProcAddress(secdll, "EnumerateSecurityPackagesA");
73         pFreeContextBuffer = (PVOID)GetProcAddress(secdll, "FreeContextBuffer");
74         pQuerySecurityPackageInfoA = (PVOID)GetProcAddress(secdll, "QuerySecurityPackageInfoA");
75         pAcquireCredentialsHandleA = (PVOID)GetProcAddress(secdll, "AcquireCredentialsHandleA");
76         pInitializeSecurityContextA = (PVOID)GetProcAddress(secdll, "InitializeSecurityContextA");
77         pCompleteAuthToken = (PVOID)GetProcAddress(secdll, "CompleteAuthToken");
78         pAcceptSecurityContext = (PVOID)GetProcAddress(secdll, "AcceptSecurityContext");
79         pFreeCredentialsHandle = (PVOID)GetProcAddress(secdll, "FreeCredentialsHandle");
80         pDeleteSecurityContext = (PVOID)GetProcAddress(secdll, "DeleteSecurityContext");
81         pQueryContextAttributesA = (PVOID)GetProcAddress(secdll, "QueryContextAttributesA");
82     }
83 }
84
85 /*---------------------------------------------------------*/
86 /* General helper functions */
87
88 static const char* getSecError(SECURITY_STATUS status)
89 {
90     static char buf[20];
91
92 #define _SEC_ERR(x) case (x): return #x;
93     switch(status)
94     {
95         _SEC_ERR(SEC_E_OK);
96         _SEC_ERR(SEC_E_INSUFFICIENT_MEMORY);
97         _SEC_ERR(SEC_E_INVALID_HANDLE);
98         _SEC_ERR(SEC_E_UNSUPPORTED_FUNCTION);
99         _SEC_ERR(SEC_E_TARGET_UNKNOWN);
100         _SEC_ERR(SEC_E_INTERNAL_ERROR);
101         _SEC_ERR(SEC_E_SECPKG_NOT_FOUND);
102         _SEC_ERR(SEC_E_NOT_OWNER);
103         _SEC_ERR(SEC_E_CANNOT_INSTALL);
104         _SEC_ERR(SEC_E_INVALID_TOKEN);
105         _SEC_ERR(SEC_E_CANNOT_PACK);
106         _SEC_ERR(SEC_E_QOP_NOT_SUPPORTED);
107         _SEC_ERR(SEC_E_NO_IMPERSONATION);
108         _SEC_ERR(SEC_I_CONTINUE_NEEDED);
109         _SEC_ERR(SEC_E_BUFFER_TOO_SMALL);
110         _SEC_ERR(SEC_E_ILLEGAL_MESSAGE);
111         _SEC_ERR(SEC_E_LOGON_DENIED);
112         _SEC_ERR(SEC_E_NO_CREDENTIALS);
113         _SEC_ERR(SEC_E_OUT_OF_SEQUENCE);
114         default:
115             sprintf(buf, "%08lx\n", status);
116             return buf;
117     }
118 #undef _SEC_ERR
119 }
120
121 /*---------------------------------------------------------*/
122 /* Helper for testQuerySecurityPagageInfo */
123
124 static SECURITY_STATUS setupPackageA(SEC_CHAR *p_package_name, 
125         PSecPkgInfo *p_pkg_info)
126 {
127     SECURITY_STATUS ret;
128     
129     ret = pQuerySecurityPackageInfoA( p_package_name, p_pkg_info);
130     return ret;
131 }
132
133 /*---------------------------------------------------------*/
134 /* Helper for testAuth* */
135
136 SECURITY_STATUS setupClient(SspiData *sspi_data, SEC_CHAR *provider)
137 {
138     SECURITY_STATUS ret;
139     TimeStamp ttl;
140     SecPkgInfoA *sec_pkg_info;
141
142     trace("Running setupClient\n");
143     
144     sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
145     sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
146     
147     ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
148
149     ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
150
151     setupBuffers(sspi_data, sec_pkg_info);
152     
153     if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_OUTBOUND,
154             NULL, sspi_data->id, NULL, NULL, sspi_data->cred, &ttl))
155             != SEC_E_OK)
156     {
157         trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
158     }
159
160     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n", 
161             getSecError(ret));
162
163     return ret;
164 }
165
166 /**********************************************************************/
167
168 SECURITY_STATUS setupServer(SspiData *sspi_data, SEC_CHAR *provider)
169 {
170     SECURITY_STATUS ret;
171     TimeStamp ttl;
172     SecPkgInfoA *sec_pkg_info;
173
174     trace("Running setupServer\n");
175
176     sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
177     sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
178
179     ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
180
181     ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
182
183     setupBuffers(sspi_data, sec_pkg_info);
184
185     if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_INBOUND, 
186             NULL, NULL, NULL, NULL, sspi_data->cred, &ttl)) != SEC_E_OK)
187     {
188         trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
189     }
190
191     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
192             getSecError(ret));
193
194     return ret;
195 }
196  
197 /**********************************************************************/
198
199 SECURITY_STATUS setupBuffers(SspiData *sspi_data, SecPkgInfoA *sec_pkg_info)
200 {
201     
202     sspi_data->in_buf  = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
203     sspi_data->out_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
204     sspi_data->max_token = sec_pkg_info->cbMaxToken;
205
206     if(sspi_data->in_buf != NULL)
207     {
208         PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
209                 sizeof(SecBuffer));
210         if(sec_buffer == NULL){
211             trace("in_buf: sec_buffer == NULL\n");
212             return SEC_E_INSUFFICIENT_MEMORY;
213         }
214         
215         sspi_data->in_buf->ulVersion = SECBUFFER_VERSION;
216         sspi_data->in_buf->cBuffers = 1;
217         sspi_data->in_buf->pBuffers = sec_buffer;
218
219         sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
220         sec_buffer->BufferType = SECBUFFER_TOKEN;
221         if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0, 
222                         sec_pkg_info->cbMaxToken)) == NULL)
223         {
224             trace("in_buf: sec_buffer->pvBuffer == NULL\n");
225             return SEC_E_INSUFFICIENT_MEMORY;
226         }
227     }
228     else
229     {
230         trace("HeapAlloc in_buf returned NULL\n");
231         return SEC_E_INSUFFICIENT_MEMORY;
232     }
233     
234     if(sspi_data->out_buf != NULL)
235     {
236         PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
237                 sizeof(SecBuffer));
238         
239         if(sec_buffer == NULL){
240             trace("out_buf: sec_buffer == NULL\n");
241             return SEC_E_INSUFFICIENT_MEMORY;
242         }
243
244         sspi_data->out_buf->ulVersion = SECBUFFER_VERSION;
245         sspi_data->out_buf->cBuffers = 1;
246         sspi_data->out_buf->pBuffers = sec_buffer;
247
248         sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
249         sec_buffer->BufferType = SECBUFFER_TOKEN;
250         if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0, 
251                         sec_pkg_info->cbMaxToken)) == NULL){
252             trace("out_buf: sec_buffer->pvBuffer == NULL\n");
253             return SEC_E_INSUFFICIENT_MEMORY;
254         }
255     }
256     else
257     {
258         trace("HeapAlloc out_buf returned NULL\n");
259         return SEC_E_INSUFFICIENT_MEMORY;
260     }
261
262     return SEC_E_OK;
263 }
264
265 /**********************************************************************/
266
267 void cleanupBuffers(SspiData *sspi_data)
268 {
269     ULONG i;
270
271     if(sspi_data->in_buf != NULL)
272     {
273         for(i = 0; i < sspi_data->in_buf->cBuffers; ++i)
274         {
275             HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers[i].pvBuffer);
276         }
277         HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers);
278         HeapFree(GetProcessHeap(), 0, sspi_data->in_buf);
279     }
280     
281     if(sspi_data->out_buf != NULL)
282     {
283         for(i = 0; i < sspi_data->out_buf->cBuffers; ++i)
284         {
285             HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers[i].pvBuffer);
286         }
287         HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers);
288         HeapFree(GetProcessHeap(), 0, sspi_data->out_buf);
289     }
290 }
291
292 /**********************************************************************/
293
294 SECURITY_STATUS runClient(SspiData *sspi_data, BOOL first, ULONG data_rep)
295 {
296     SECURITY_STATUS ret;
297     ULONG req_attr = ISC_REQ_CONNECTION | ISC_REQ_CONFIDENTIALITY;
298     ULONG ctxt_attr;
299     TimeStamp ttl;
300     PSecBufferDesc in_buf = sspi_data->in_buf;
301     PSecBufferDesc out_buf = sspi_data->out_buf;
302
303     assert(in_buf->cBuffers >= 1);
304     assert(in_buf->pBuffers[0].pvBuffer != NULL);
305     assert(in_buf->pBuffers[0].cbBuffer != 0);
306
307     assert(out_buf->cBuffers >= 1);
308     assert(out_buf->pBuffers[0].pvBuffer != NULL);
309     assert(out_buf->pBuffers[0].cbBuffer != 0);
310
311     trace("Running the client the %s time.\n", first?"first":"second");
312
313     /* We can either use ISC_REQ_ALLOCATE_MEMORY flag to ask the provider
314      * always allocate output buffers for us, or initialize cbBuffer
315      * before each call because the API changes it to represent actual
316      * amount of data in the buffer.
317      */
318
319     /* test a failing call only the first time, otherwise we get
320      * SEC_E_OUT_OF_SEQUENCE
321      */
322     if (first)
323     {
324         void *old_buf;
325
326         /* pass NULL as an output buffer */
327         ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
328             0, data_rep, NULL, 0, sspi_data->ctxt, NULL,
329             &ctxt_attr, &ttl);
330
331         ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
332
333         /* pass NULL as an output buffer */
334         old_buf = out_buf->pBuffers[0].pvBuffer;
335         out_buf->pBuffers[0].pvBuffer = NULL;
336
337         ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr, 
338             0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
339             &ctxt_attr, &ttl);
340
341         ok(ret == SEC_E_INTERNAL_ERROR, "expected SEC_E_INTERNAL_ERROR, got %s\n", getSecError(ret));
342
343         out_buf->pBuffers[0].pvBuffer = old_buf;
344
345         /* pass an output buffer of 0 size */
346         out_buf->pBuffers[0].cbBuffer = 0;
347
348         ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr, 
349             0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
350             &ctxt_attr, &ttl);
351
352         ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
353
354         ok(out_buf->pBuffers[0].cbBuffer == 0,
355            "InitializeSecurityContext set buffer size to %lu\n", out_buf->pBuffers[0].cbBuffer);
356     }
357
358     out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
359
360     ret = pInitializeSecurityContextA(sspi_data->cred, first?NULL:sspi_data->ctxt, NULL, req_attr, 
361             0, data_rep, first?NULL:in_buf, 0, sspi_data->ctxt, out_buf,
362             &ctxt_attr, &ttl);
363
364     if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
365     {
366         pCompleteAuthToken(sspi_data->ctxt, out_buf);
367         if(ret == SEC_I_COMPLETE_AND_CONTINUE)
368             ret = SEC_I_CONTINUE_NEEDED;
369         else if(ret == SEC_I_COMPLETE_NEEDED)
370             ret = SEC_E_OK;
371     }       
372
373     ok(out_buf->pBuffers[0].cbBuffer < sspi_data->max_token,
374        "InitializeSecurityContext set buffer size to %lu\n", out_buf->pBuffers[0].cbBuffer);
375
376     return ret;
377 }
378
379 /**********************************************************************/
380
381 SECURITY_STATUS runServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
382 {
383     SECURITY_STATUS ret;
384     ULONG ctxt_attr;
385     TimeStamp ttl;
386
387     trace("Running the server the %s time\n", first?"first":"second");
388
389     ret = pAcceptSecurityContext(sspi_data->cred, first?NULL:sspi_data->ctxt, 
390             sspi_data->in_buf, 0, data_rep, sspi_data->ctxt, 
391             sspi_data->out_buf, &ctxt_attr, &ttl);
392
393     if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
394     {
395         pCompleteAuthToken(sspi_data->ctxt, sspi_data->out_buf);
396         if(ret == SEC_I_COMPLETE_AND_CONTINUE)
397             ret = SEC_I_CONTINUE_NEEDED;
398         else if(ret == SEC_I_COMPLETE_NEEDED)
399             ret = SEC_E_OK;
400     }
401
402     return ret;
403 }
404
405 /**********************************************************************/
406
407 void communicate(SspiData *from, SspiData *to)
408 {
409     if(from->out_buf != NULL && to->in_buf != NULL)
410     {
411         trace("Running communicate.\n");
412         if((from->out_buf->cBuffers >= 1) && (to->in_buf->cBuffers >= 1))
413         {
414             if((from->out_buf->pBuffers[0].pvBuffer != NULL) && 
415                     (to->in_buf->pBuffers[0].pvBuffer != NULL))
416             {
417                 memset(to->in_buf->pBuffers[0].pvBuffer, 0, to->max_token);
418                 
419                 memcpy(to->in_buf->pBuffers[0].pvBuffer, 
420                     from->out_buf->pBuffers[0].pvBuffer,
421                     from->out_buf->pBuffers[0].cbBuffer);
422                 
423                 to->in_buf->pBuffers[0].cbBuffer = from->out_buf->pBuffers[0].cbBuffer;
424                 
425                 memset(from->out_buf->pBuffers[0].pvBuffer, 0, from->max_token);
426             }
427         }
428     }
429 }
430    
431 /**********************************************************************/
432
433 /*--------------------------------------------------------- */
434 /* The test functions */
435
436 static void testInitSecurityInterface(void)
437 {
438     PSecurityFunctionTable sec_fun_table = NULL;
439
440     sec_fun_table = pInitSecurityInterfaceA();
441     ok(sec_fun_table != NULL, "InitSecurityInterface() returned NULL.\n");
442
443 }
444
445 static void testEnumerateSecurityPackages(void)
446 {
447
448     SECURITY_STATUS sec_status;
449     ULONG           num_packages, i;
450     PSecPkgInfo     pkg_info = NULL;
451
452     trace("Running testEnumerateSecurityPackages\n");
453     
454     sec_status = pEnumerateSecurityPackagesA(&num_packages, &pkg_info);
455
456     ok(sec_status == SEC_E_OK, 
457             "EnumerateSecurityPackages() should return %ld, not %08lx\n",
458             (LONG)SEC_E_OK, (LONG)sec_status);
459
460     ok(num_packages > 0, "Number of sec packages should be > 0 ,but is %ld\n",
461             num_packages);
462
463     ok(pkg_info != NULL, 
464             "pkg_info should not be NULL after EnumerateSecurityPackages\n");
465     
466     trace("Number of packages: %ld\n", num_packages);
467     for(i = 0; i < num_packages; ++i){
468         trace("%ld: Package \"%s\"\n", i, pkg_info[i].Name);
469         trace("Supported flags:\n");
470         if(pkg_info[i].fCapabilities & SECPKG_FLAG_INTEGRITY)
471             trace("\tSECPKG_FLAG_INTEGRITY\n");
472         if(pkg_info[i].fCapabilities & SECPKG_FLAG_PRIVACY)
473             trace("\tSECPKG_FLAG_PRIVACY\n");
474         if(pkg_info[i].fCapabilities & SECPKG_FLAG_TOKEN_ONLY)
475             trace("\tSECPKG_FLAG_TOKEN_ONLY\n");
476         if(pkg_info[i].fCapabilities & SECPKG_FLAG_DATAGRAM)
477             trace("\tSECPKG_FLAG_DATAGRAM\n");
478         if(pkg_info[i].fCapabilities & SECPKG_FLAG_CONNECTION)
479             trace("\tSECPKG_FLAG_CONNECTION\n");
480         if(pkg_info[i].fCapabilities & SECPKG_FLAG_MULTI_REQUIRED)
481             trace("\tSECPKG_FLAG_MULTI_REQUIRED\n");
482         if(pkg_info[i].fCapabilities & SECPKG_FLAG_CLIENT_ONLY)
483             trace("\tSECPKG_FLAG_CLIENT_ONLY\n");
484         if(pkg_info[i].fCapabilities & SECPKG_FLAG_EXTENDED_ERROR)
485             trace("\tSECPKG_FLAG_EXTENDED_ERROR\n");
486         if(pkg_info[i].fCapabilities & SECPKG_FLAG_IMPERSONATION)
487             trace("\tSECPKG_FLAG_IMPERSONATION\n");
488         if(pkg_info[i].fCapabilities & SECPKG_FLAG_ACCEPT_WIN32_NAME)
489             trace("\tSECPKG_FLAG_ACCEPT_WIN32_NAME\n");
490         if(pkg_info[i].fCapabilities & SECPKG_FLAG_STREAM)
491             trace("\tSECPKG_FLAG_STREAM\n");
492         if(pkg_info[i].fCapabilities & SECPKG_FLAG_READONLY_WITH_CHECKSUM)
493             trace("\tSECPKG_FLAG_READONLY_WITH_CHECKSUM\n");
494         trace("Comment: %s\n", pkg_info[i].Comment);
495         trace("\n");
496     }
497
498     pFreeContextBuffer(pkg_info);
499 }
500
501
502 static void testQuerySecurityPackageInfo(void)
503 {
504     SECURITY_STATUS     sec_status;
505     PSecPkgInfo         pkg_info;
506     
507     trace("Running testQuerySecurityPackageInfo\n");
508     
509     /* Test with an existing package. Test should pass */
510
511     pkg_info = (void *)0xdeadbeef;
512     sec_status = setupPackageA("NTLM", &pkg_info);
513
514     ok((sec_status == SEC_E_OK) || (sec_status == SEC_E_SECPKG_NOT_FOUND), 
515        "Return value of QuerySecurityPackageInfo() shouldn't be %s\n",
516        getSecError(sec_status) );
517         
518     if (sec_status == SEC_E_OK)
519     {
520         ok(pkg_info != (void *)0xdeadbeef, "wrong pkg_info address %p\n", pkg_info);
521         ok(pkg_info->wVersion == 1, "wVersion always should be 1, but is %d\n", pkg_info->wVersion);
522         /* there is no point in testing pkg_info->cbMaxToken since it varies
523          * between implementations.
524          */
525     }
526
527     sec_status = pFreeContextBuffer(pkg_info);
528
529     ok( sec_status == SEC_E_OK,
530         "Return value of FreeContextBuffer() shouldn't be %s\n",
531         getSecError(sec_status) );
532
533     /* Test with a nonexistent package, test should fail */
534
535     pkg_info = (void *)0xdeadbeef;
536     sec_status = pQuerySecurityPackageInfoA("Winetest", &pkg_info);
537
538     ok( sec_status != SEC_E_OK,
539         "Return value of QuerySecurityPackageInfo() should not be %s for a nonexistent package\n", getSecError(SEC_E_OK));
540
541     ok(pkg_info == (void *)0xdeadbeef, "wrong pkg_info address %p\n", pkg_info);
542
543     sec_status = pFreeContextBuffer(pkg_info);
544     
545     ok( sec_status == SEC_E_OK,
546         "Return value of FreeContextBuffer() shouldn't be %s\n",
547         getSecError(sec_status) );
548 }
549
550 void testAuth(SEC_CHAR* sec_pkg_name, ULONG data_rep)
551 {
552     SECURITY_STATUS         client_stat = SEC_I_CONTINUE_NEEDED;
553     SECURITY_STATUS         server_stat = SEC_I_CONTINUE_NEEDED;
554     SECURITY_STATUS         sec_status;
555     PSecPkgInfo             pkg_info = NULL;
556     BOOL                    first = TRUE;
557     SspiData                client, server;
558     SEC_WINNT_AUTH_IDENTITY id;
559     SecPkgContext_Sizes    ctxt_sizes;
560
561     if(setupPackageA(sec_pkg_name, &pkg_info) == SEC_E_OK)
562     {
563         pFreeContextBuffer(pkg_info);
564         id.User = (unsigned char*) "Administrator";
565         id.UserLength = strlen((char *) id.User);
566         id.Domain = (unsigned char *) "WORKGROUP";
567         id.DomainLength = strlen((char *) id.Domain);
568         id.Password = (unsigned char*) "testpass";
569         id.PasswordLength = strlen((char *) id.Password);
570         id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
571
572         client.id = &id;
573         
574         sec_status = setupClient(&client, sec_pkg_name);
575
576         if(sec_status != SEC_E_OK)
577         {
578             trace("Error: Setting up the client returned %s, exiting test!\n",
579                     getSecError(sec_status));
580             pFreeCredentialsHandle(client.cred);
581             return;
582         }
583
584         sec_status = setupServer(&server, sec_pkg_name);
585
586         if(sec_status != SEC_E_OK)
587         {
588             trace("Error: Setting up the server returned %s, exiting test!\n",
589                     getSecError(sec_status));
590             pFreeCredentialsHandle(server.cred);
591             pFreeCredentialsHandle(client.cred);
592             return;
593         }
594
595
596         while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
597         {
598             client_stat = runClient(&client, first, data_rep);
599
600             ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED,
601                     "Running the client returned %s, more tests will fail.\n",
602                     getSecError(client_stat));
603             
604             communicate(&client, &server);
605             
606             server_stat = runServer(&server, first, data_rep);
607
608             ok(server_stat == SEC_E_OK || server_stat == SEC_I_CONTINUE_NEEDED ||
609                     server_stat == SEC_E_LOGON_DENIED,
610                     "Running the server returned %s, more tests will fail from now.\n",
611                     getSecError(server_stat));
612
613             communicate(&server, &client);
614             trace("Looping\n");
615             first = FALSE;
616         }
617
618         if(!strcmp(sec_pkg_name, "NTLM"))
619         {
620             sec_status = pQueryContextAttributesA(server.ctxt,
621                     SECPKG_ATTR_SIZES, &ctxt_sizes);
622
623             ok(sec_status == SEC_E_OK, 
624                     "pQueryContextAttributesA(SECPKG_ATTR_SIZES) returned %s\n",
625                     getSecError(sec_status));
626             ok(ctxt_sizes.cbMaxToken == 1904,
627                     "cbMaxToken should be 1904 but is %lu\n", 
628                     ctxt_sizes.cbMaxToken);
629             ok(ctxt_sizes.cbMaxSignature == 16,
630                     "cbMaxSignature should be 16 but is %lu\n",
631                     ctxt_sizes.cbMaxSignature);
632             ok(ctxt_sizes.cbSecurityTrailer == 16,
633                     "cbSecurityTrailer should be 16 but is  %lu\n",
634                     ctxt_sizes.cbSecurityTrailer);
635             ok(ctxt_sizes.cbBlockSize == 1,
636                     "cbBlockSize should be 1 but is %lu\n", 
637                     ctxt_sizes.cbBlockSize);
638         }
639         else
640             trace("Unknown sec package %s\n", sec_pkg_name);
641
642         cleanupBuffers(&client);
643         cleanupBuffers(&server);
644         
645         sec_status = pDeleteSecurityContext(server.ctxt);
646         ok(sec_status == SEC_E_OK, "DeleteSecurityContext(server) returned %s\n",
647                 getSecError(sec_status));
648
649         sec_status = pDeleteSecurityContext(client.ctxt);
650         ok(sec_status == SEC_E_OK, "DeleteSecurityContext(client) returned %s\n",
651                 getSecError(sec_status));
652            
653         sec_status = pFreeCredentialsHandle(server.cred);
654         ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(server) returned %s\n",
655                 getSecError(sec_status));
656         
657         sec_status = pFreeCredentialsHandle(client.cred);
658         ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(client) returned %s\n",
659                 getSecError(sec_status));
660     }
661     else
662     {
663         trace("Package not installed, skipping test.\n");
664     }
665 }
666
667 START_TEST(main)
668 {
669     InitFunctionPtrs();
670     if(pInitSecurityInterfaceA)
671         testInitSecurityInterface();
672     if(pFreeContextBuffer)
673     {
674         if(pEnumerateSecurityPackagesA)
675             testEnumerateSecurityPackages();
676         if(pQuerySecurityPackageInfoA)
677         {
678             testQuerySecurityPackageInfo();
679             if(pInitSecurityInterfaceA)
680             {
681                 testAuth("NTLM", SECURITY_NATIVE_DREP);
682                 testAuth("NTLM", SECURITY_NETWORK_DREP);
683             }
684         }
685     }
686     if(secdll)
687         FreeLibrary(secdll);
688 }