secur32/tests: Fix a couple of memory leaks.
[wine/multimedia.git] / dlls / secur32 / tests / ntlm.c
blobd9f95389264b115f7223e22c6d98b4fa68a40e73
1 /*
2 * Tests for the NTLM security provider
4 * Copyright 2005, 2006 Kai Blin
5 * Copyright 2006 Dmitry Timoshkov
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.
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.
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
21 * The code that tests for the behaviour of ISC_REQ_ALLOCATE_MEMORY is based
22 * on code written by Dmitry Timoshkov.
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>
37 #include "wine/test.h"
39 static HMODULE secdll;
40 static PSecurityFunctionTableA (SEC_ENTRY * pInitSecurityInterfaceA)(void);
41 static SECURITY_STATUS (SEC_ENTRY * pFreeContextBuffer)(PVOID pv);
42 static SECURITY_STATUS (SEC_ENTRY * pQuerySecurityPackageInfoA)(SEC_CHAR*, PSecPkgInfoA*);
43 static SECURITY_STATUS (SEC_ENTRY * pAcquireCredentialsHandleA)(SEC_CHAR*, SEC_CHAR*,
44 ULONG, PLUID, PVOID, SEC_GET_KEY_FN, PVOID, PCredHandle, PTimeStamp);
45 static SECURITY_STATUS (SEC_ENTRY * pInitializeSecurityContextA)(PCredHandle, PCtxtHandle,
46 SEC_CHAR*, ULONG, ULONG, ULONG, PSecBufferDesc, ULONG,
47 PCtxtHandle, PSecBufferDesc, PULONG, PTimeStamp);
48 static SECURITY_STATUS (SEC_ENTRY * pCompleteAuthToken)(PCtxtHandle, PSecBufferDesc);
49 static SECURITY_STATUS (SEC_ENTRY * pAcceptSecurityContext)(PCredHandle, PCtxtHandle,
50 PSecBufferDesc, ULONG, ULONG, PCtxtHandle, PSecBufferDesc,
51 PULONG, PTimeStamp);
52 static SECURITY_STATUS (SEC_ENTRY * pFreeCredentialsHandle)(PCredHandle);
53 static SECURITY_STATUS (SEC_ENTRY * pDeleteSecurityContext)(PCtxtHandle);
54 static SECURITY_STATUS (SEC_ENTRY * pQueryContextAttributesA)(PCtxtHandle, ULONG, PVOID);
55 static SECURITY_STATUS (SEC_ENTRY * pMakeSignature)(PCtxtHandle, ULONG,
56 PSecBufferDesc, ULONG);
57 static SECURITY_STATUS (SEC_ENTRY * pVerifySignature)(PCtxtHandle, PSecBufferDesc,
58 ULONG, PULONG);
59 static SECURITY_STATUS (SEC_ENTRY * pEncryptMessage)(PCtxtHandle, ULONG,
60 PSecBufferDesc, ULONG);
61 static SECURITY_STATUS (SEC_ENTRY * pDecryptMessage)(PCtxtHandle, PSecBufferDesc,
62 ULONG, PULONG);
63 static BOOLEAN (WINAPI * pGetUserNameExA)(EXTENDED_NAME_FORMAT, LPSTR, PULONG);
65 typedef struct _SspiData {
66 PCredHandle cred;
67 PCtxtHandle ctxt;
68 PSecBufferDesc in_buf;
69 PSecBufferDesc out_buf;
70 PSEC_WINNT_AUTH_IDENTITY id;
71 ULONG max_token;
72 } SspiData;
74 static BYTE network_challenge[] =
75 {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00,
76 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00,
77 0x05, 0x82, 0x82, 0xa0, 0xe9, 0x58, 0x7f, 0x14, 0xa2, 0x86,
78 0x3b, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00,
80 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
81 0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00,
82 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
83 0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00,
84 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
85 0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00,
86 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
87 0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00,
88 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
89 0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00};
91 static BYTE native_challenge[] =
92 {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00,
93 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00,
94 0x05, 0x82, 0x82, 0xa0, 0xb5, 0x60, 0x8e, 0x95, 0xb5, 0x3c,
95 0xee, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00,
97 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
98 0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00,
99 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
100 0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00,
101 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
102 0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00,
103 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
104 0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00,
105 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
106 0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00};
108 static BYTE message_signature[] =
109 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
112 static BYTE message_binary[] =
113 {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72,
114 0x6c, 0x64, 0x21};
116 static char message[] = "Hello, world!";
118 static char message_header[] = "Header Test";
120 static BYTE crypt_trailer_client[] =
121 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xc7,
122 0xaa, 0x26, 0x16, 0x39, 0x07, 0x4e};
124 static BYTE crypt_message_client[] =
125 {0x86, 0x9c, 0x5a, 0x10, 0x78, 0xb3, 0x30, 0x98, 0x46, 0x15,
126 0xa0, 0x31, 0xd9};
128 static BYTE crypt_trailer_client2[] =
129 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0xa7,
130 0xf7, 0x0f, 0x5b, 0x25, 0xbe, 0xa4};
132 static BYTE crypt_message_client2[] =
133 {0x20, 0x6c, 0x01, 0xab, 0xb0, 0x4c, 0x93, 0xe4, 0x1e, 0xfc,
134 0xe1, 0xfa, 0xfe};
136 static BYTE crypt_trailer_server[] =
137 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x46,
138 0x2e, 0x77, 0xeb, 0xf0, 0xf6, 0x9e};
140 static BYTE crypt_message_server[] =
141 {0xf6, 0xb7, 0x92, 0x0c, 0xac, 0xea, 0x98, 0xe6, 0xef, 0xa0,
142 0x29, 0x66, 0xfd};
144 static BYTE crypt_trailer_server2[] =
145 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x4e,
146 0x46, 0xb7, 0xca, 0xf7, 0x7f, 0xb3};
148 static BYTE crypt_message_server2[] =
149 {0xc8, 0xf2, 0x39, 0x7f, 0x0c, 0xaf, 0xf5, 0x5d, 0xef, 0x0c,
150 0x8b, 0x5f, 0x82};
152 static void InitFunctionPtrs(void)
154 secdll = LoadLibraryA("secur32.dll");
155 if(!secdll)
156 secdll = LoadLibraryA("security.dll");
157 if(secdll)
159 pInitSecurityInterfaceA = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceA");
160 pFreeContextBuffer = (PVOID)GetProcAddress(secdll, "FreeContextBuffer");
161 pQuerySecurityPackageInfoA = (PVOID)GetProcAddress(secdll, "QuerySecurityPackageInfoA");
162 pAcquireCredentialsHandleA = (PVOID)GetProcAddress(secdll, "AcquireCredentialsHandleA");
163 pInitializeSecurityContextA = (PVOID)GetProcAddress(secdll, "InitializeSecurityContextA");
164 pCompleteAuthToken = (PVOID)GetProcAddress(secdll, "CompleteAuthToken");
165 pAcceptSecurityContext = (PVOID)GetProcAddress(secdll, "AcceptSecurityContext");
166 pFreeCredentialsHandle = (PVOID)GetProcAddress(secdll, "FreeCredentialsHandle");
167 pDeleteSecurityContext = (PVOID)GetProcAddress(secdll, "DeleteSecurityContext");
168 pQueryContextAttributesA = (PVOID)GetProcAddress(secdll, "QueryContextAttributesA");
169 pMakeSignature = (PVOID)GetProcAddress(secdll, "MakeSignature");
170 pVerifySignature = (PVOID)GetProcAddress(secdll, "VerifySignature");
171 pEncryptMessage = (PVOID)GetProcAddress(secdll, "EncryptMessage");
172 pDecryptMessage = (PVOID)GetProcAddress(secdll, "DecryptMessage");
173 pGetUserNameExA = (PVOID)GetProcAddress(secdll, "GetUserNameExA");
177 static const char* getSecError(SECURITY_STATUS status)
179 static char buf[20];
181 #define _SEC_ERR(x) case (x): return #x;
182 switch(status)
184 _SEC_ERR(SEC_E_OK);
185 _SEC_ERR(SEC_E_INSUFFICIENT_MEMORY);
186 _SEC_ERR(SEC_E_INVALID_HANDLE);
187 _SEC_ERR(SEC_E_UNSUPPORTED_FUNCTION);
188 _SEC_ERR(SEC_E_TARGET_UNKNOWN);
189 _SEC_ERR(SEC_E_INTERNAL_ERROR);
190 _SEC_ERR(SEC_E_SECPKG_NOT_FOUND);
191 _SEC_ERR(SEC_E_NOT_OWNER);
192 _SEC_ERR(SEC_E_CANNOT_INSTALL);
193 _SEC_ERR(SEC_E_INVALID_TOKEN);
194 _SEC_ERR(SEC_E_CANNOT_PACK);
195 _SEC_ERR(SEC_E_QOP_NOT_SUPPORTED);
196 _SEC_ERR(SEC_E_NO_IMPERSONATION);
197 _SEC_ERR(SEC_I_CONTINUE_NEEDED);
198 _SEC_ERR(SEC_E_BUFFER_TOO_SMALL);
199 _SEC_ERR(SEC_E_ILLEGAL_MESSAGE);
200 _SEC_ERR(SEC_E_LOGON_DENIED);
201 _SEC_ERR(SEC_E_NO_CREDENTIALS);
202 _SEC_ERR(SEC_E_OUT_OF_SEQUENCE);
203 _SEC_ERR(SEC_E_MESSAGE_ALTERED);
204 default:
205 sprintf(buf, "%08x\n", status);
206 return buf;
208 #undef _SEC_ERR
211 /**********************************************************************/
213 static SECURITY_STATUS setupBuffers(SspiData *sspi_data, SecPkgInfoA *sec_pkg_info)
216 sspi_data->in_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
217 sspi_data->out_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
218 sspi_data->max_token = sec_pkg_info->cbMaxToken;
220 if(sspi_data->in_buf != NULL)
222 PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
223 sizeof(SecBuffer));
224 if(sec_buffer == NULL){
225 trace("in_buf: sec_buffer == NULL\n");
226 return SEC_E_INSUFFICIENT_MEMORY;
229 sspi_data->in_buf->ulVersion = SECBUFFER_VERSION;
230 sspi_data->in_buf->cBuffers = 1;
231 sspi_data->in_buf->pBuffers = sec_buffer;
233 sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
234 sec_buffer->BufferType = SECBUFFER_TOKEN;
235 if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0,
236 sec_pkg_info->cbMaxToken)) == NULL)
238 trace("in_buf: sec_buffer->pvBuffer == NULL\n");
239 return SEC_E_INSUFFICIENT_MEMORY;
242 else
244 trace("HeapAlloc in_buf returned NULL\n");
245 return SEC_E_INSUFFICIENT_MEMORY;
248 if(sspi_data->out_buf != NULL)
250 PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
251 sizeof(SecBuffer));
253 if(sec_buffer == NULL){
254 trace("out_buf: sec_buffer == NULL\n");
255 return SEC_E_INSUFFICIENT_MEMORY;
258 sspi_data->out_buf->ulVersion = SECBUFFER_VERSION;
259 sspi_data->out_buf->cBuffers = 1;
260 sspi_data->out_buf->pBuffers = sec_buffer;
262 sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
263 sec_buffer->BufferType = SECBUFFER_TOKEN;
264 if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0,
265 sec_pkg_info->cbMaxToken)) == NULL){
266 trace("out_buf: sec_buffer->pvBuffer == NULL\n");
267 return SEC_E_INSUFFICIENT_MEMORY;
270 else
272 trace("HeapAlloc out_buf returned NULL\n");
273 return SEC_E_INSUFFICIENT_MEMORY;
276 return SEC_E_OK;
279 /**********************************************************************/
281 static void cleanupBuffers(SspiData *sspi_data)
283 ULONG i;
285 if(sspi_data->in_buf != NULL)
287 for(i = 0; i < sspi_data->in_buf->cBuffers; ++i)
289 HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers[i].pvBuffer);
291 HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers);
292 HeapFree(GetProcessHeap(), 0, sspi_data->in_buf);
295 if(sspi_data->out_buf != NULL)
297 for(i = 0; i < sspi_data->out_buf->cBuffers; ++i)
299 HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers[i].pvBuffer);
301 HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers);
302 HeapFree(GetProcessHeap(), 0, sspi_data->out_buf);
306 /**********************************************************************/
308 static SECURITY_STATUS setupClient(SspiData *sspi_data, SEC_CHAR *provider)
310 SECURITY_STATUS ret;
311 TimeStamp ttl;
312 SecPkgInfoA *sec_pkg_info;
314 trace("Running setupClient\n");
316 sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
317 sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
319 ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
321 ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
323 setupBuffers(sspi_data, sec_pkg_info);
325 if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_OUTBOUND,
326 NULL, sspi_data->id, NULL, NULL, sspi_data->cred, &ttl))
327 != SEC_E_OK)
329 trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
332 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
333 getSecError(ret));
335 return ret;
337 /**********************************************************************/
339 static SECURITY_STATUS setupServer(SspiData *sspi_data, SEC_CHAR *provider)
341 SECURITY_STATUS ret;
342 TimeStamp ttl;
343 SecPkgInfoA *sec_pkg_info;
345 trace("Running setupServer\n");
347 sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
348 sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
350 ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
352 ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
354 setupBuffers(sspi_data, sec_pkg_info);
356 if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_INBOUND,
357 NULL, NULL, NULL, NULL, sspi_data->cred, &ttl)) != SEC_E_OK)
359 trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
362 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
363 getSecError(ret));
365 return ret;
368 /**********************************************************************/
370 static SECURITY_STATUS setupFakeServer(SspiData *sspi_data, SEC_CHAR *provider)
372 SECURITY_STATUS ret;
373 SecPkgInfoA *sec_pkg_info;
375 trace("Running setupFakeServer\n");
377 sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
378 sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
380 ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
382 ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
384 ret = setupBuffers(sspi_data, sec_pkg_info);
386 return ret;
390 /**********************************************************************/
392 static SECURITY_STATUS runClient(SspiData *sspi_data, BOOL first, ULONG data_rep)
394 SECURITY_STATUS ret;
395 ULONG req_attr = 0;
396 ULONG ctxt_attr;
397 TimeStamp ttl;
398 PSecBufferDesc in_buf = sspi_data->in_buf;
399 PSecBufferDesc out_buf = sspi_data->out_buf;
401 assert(in_buf->cBuffers >= 1);
402 assert(in_buf->pBuffers[0].pvBuffer != NULL);
403 assert(in_buf->pBuffers[0].cbBuffer != 0);
405 assert(out_buf->cBuffers >= 1);
406 assert(out_buf->pBuffers[0].pvBuffer != NULL);
407 assert(out_buf->pBuffers[0].cbBuffer != 0);
409 trace("Running the client the %s time.\n", first?"first":"second");
411 /* We can either use ISC_REQ_ALLOCATE_MEMORY flag to ask the provider
412 * always allocate output buffers for us, or initialize cbBuffer
413 * before each call because the API changes it to represent actual
414 * amount of data in the buffer.
417 /* test a failing call only the first time, otherwise we get
418 * SEC_E_OUT_OF_SEQUENCE
420 if (first)
422 void *old_buf;
424 /* pass NULL as an output buffer */
425 ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
426 0, data_rep, NULL, 0, sspi_data->ctxt, NULL,
427 &ctxt_attr, &ttl);
429 ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
431 /* pass NULL as an output buffer */
432 old_buf = out_buf->pBuffers[0].pvBuffer;
433 out_buf->pBuffers[0].pvBuffer = NULL;
435 ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
436 0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
437 &ctxt_attr, &ttl);
439 ok(ret == SEC_E_INTERNAL_ERROR || ret == SEC_I_CONTINUE_NEEDED,
440 "expected SEC_E_INTERNAL_ERROR or SEC_I_CONTINUE_NEEDED, got %s\n", getSecError(ret));
442 out_buf->pBuffers[0].pvBuffer = old_buf;
444 /* pass an output buffer of 0 size */
445 out_buf->pBuffers[0].cbBuffer = 0;
447 ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
448 0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
449 &ctxt_attr, &ttl);
451 ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
453 ok(out_buf->pBuffers[0].cbBuffer == 0,
454 "InitializeSecurityContext set buffer size to %u\n", out_buf->pBuffers[0].cbBuffer);
456 out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
457 out_buf->pBuffers[0].BufferType = SECBUFFER_DATA;
459 ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
460 0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
461 &ctxt_attr, &ttl);
463 ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
464 out_buf->pBuffers[0].BufferType = SECBUFFER_TOKEN;
467 out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
469 ret = pInitializeSecurityContextA(first?sspi_data->cred:NULL, first?NULL:sspi_data->ctxt, NULL, req_attr,
470 0, data_rep, first?NULL:in_buf, 0, sspi_data->ctxt, out_buf,
471 &ctxt_attr, &ttl);
473 if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
475 pCompleteAuthToken(sspi_data->ctxt, out_buf);
476 if(ret == SEC_I_COMPLETE_AND_CONTINUE)
477 ret = SEC_I_CONTINUE_NEEDED;
478 else if(ret == SEC_I_COMPLETE_NEEDED)
479 ret = SEC_E_OK;
482 ok(out_buf->pBuffers[0].BufferType == SECBUFFER_TOKEN,
483 "buffer type was changed from SECBUFFER_TOKEN to %d\n", out_buf->pBuffers[0].BufferType);
484 ok(out_buf->pBuffers[0].cbBuffer < sspi_data->max_token,
485 "InitializeSecurityContext set buffer size to %u\n", out_buf->pBuffers[0].cbBuffer);
487 return ret;
490 /**********************************************************************/
492 static SECURITY_STATUS runServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
494 SECURITY_STATUS ret;
495 ULONG ctxt_attr;
496 TimeStamp ttl;
498 trace("Running the server the %s time\n", first?"first":"second");
500 ret = pAcceptSecurityContext(sspi_data->cred, first?NULL:sspi_data->ctxt,
501 sspi_data->in_buf, 0, data_rep, sspi_data->ctxt,
502 sspi_data->out_buf, &ctxt_attr, &ttl);
504 if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
506 pCompleteAuthToken(sspi_data->ctxt, sspi_data->out_buf);
507 if(ret == SEC_I_COMPLETE_AND_CONTINUE)
508 ret = SEC_I_CONTINUE_NEEDED;
509 else if(ret == SEC_I_COMPLETE_NEEDED)
510 ret = SEC_E_OK;
513 return ret;
516 /**********************************************************************/
518 static SECURITY_STATUS runFakeServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
520 trace("Running the fake server the %s time\n", first?"first":"second");
522 if(!first)
524 sspi_data->out_buf->pBuffers[0].cbBuffer = 0;
525 return SEC_E_OK;
528 if(data_rep == SECURITY_NATIVE_DREP)
530 sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(native_challenge);
531 memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, native_challenge,
532 sspi_data->out_buf->pBuffers[0].cbBuffer);
534 else
536 sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(network_challenge);
537 memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, network_challenge,
538 sspi_data->out_buf->pBuffers[0].cbBuffer);
541 return SEC_I_CONTINUE_NEEDED;
544 /**********************************************************************/
546 static void communicate(SspiData *from, SspiData *to)
548 if(from->out_buf != NULL && to->in_buf != NULL)
550 trace("Running communicate.\n");
551 if((from->out_buf->cBuffers >= 1) && (to->in_buf->cBuffers >= 1))
553 if((from->out_buf->pBuffers[0].pvBuffer != NULL) &&
554 (to->in_buf->pBuffers[0].pvBuffer != NULL))
556 memset(to->in_buf->pBuffers[0].pvBuffer, 0, to->max_token);
558 memcpy(to->in_buf->pBuffers[0].pvBuffer,
559 from->out_buf->pBuffers[0].pvBuffer,
560 from->out_buf->pBuffers[0].cbBuffer);
562 to->in_buf->pBuffers[0].cbBuffer = from->out_buf->pBuffers[0].cbBuffer;
564 memset(from->out_buf->pBuffers[0].pvBuffer, 0, from->max_token);
570 /**********************************************************************/
571 static void testInitializeSecurityContextFlags(void)
573 SECURITY_STATUS sec_status;
574 PSecPkgInfo pkg_info = NULL;
575 SspiData client;
576 SEC_WINNT_AUTH_IDENTITY id;
577 static char sec_pkg_name[] = "NTLM",
578 test_user[] = "testuser",
579 workgroup[] = "WORKGROUP",
580 test_pass[] = "testpass";
581 ULONG req_attr, ctxt_attr;
582 TimeStamp ttl;
583 PBYTE packet;
585 if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
587 skip("Package not installed, skipping test!\n");
588 return;
591 pFreeContextBuffer(pkg_info);
592 id.User = (unsigned char*) test_user;
593 id.UserLength = strlen((char *) id.User);
594 id.Domain = (unsigned char *) workgroup;
595 id.DomainLength = strlen((char *) id.Domain);
596 id.Password = (unsigned char*) test_pass;
597 id.PasswordLength = strlen((char *) id.Password);
598 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
600 client.id = &id;
602 if((sec_status = setupClient(&client, sec_pkg_name)) != SEC_E_OK)
604 skip("Setting up the client returned %s, skipping test!\n",
605 getSecError(sec_status));
606 return;
609 packet = client.out_buf->pBuffers[0].pvBuffer;
611 /* Due to how the requesting of the flags is implemented in ntlm_auth,
612 * the tests need to be in this order, as there is no way to specify
613 * "I request no special features" in ntlm_auth */
615 /* Without any flags, the lowest byte should not have bits 0x20 or 0x10 set*/
616 req_attr = 0;
618 if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
619 0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
620 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
622 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
623 getSecError(sec_status));
624 goto tISCFend;
627 ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
628 "With req_attr == 0, flags are 0x%02x%02x%02x%02x.\n",
629 packet[15], packet[14], packet[13], packet[12]);
631 /* With ISC_REQ_CONNECTION, the lowest byte should not have bits 0x20 or 0x10 set*/
632 req_attr = ISC_REQ_CONNECTION;
634 if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
635 0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
636 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
638 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
639 getSecError(sec_status));
640 goto tISCFend;
643 ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
644 "For ISC_REQ_CONNECTION, flags are 0x%02x%02x%02x%02x.\n",
645 packet[15], packet[14], packet[13], packet[12]);
647 /* With ISC_REQ_EXTENDED_ERROR, the lowest byte should not have bits 0x20 or 0x10 set*/
648 req_attr = ISC_REQ_EXTENDED_ERROR;
650 if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
651 0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
652 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
654 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
655 getSecError(sec_status));
656 goto tISCFend;
659 ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
660 "For ISC_REQ_EXTENDED_ERROR, flags are 0x%02x%02x%02x%02x.\n",
661 packet[15], packet[14], packet[13], packet[12]);
663 /* With ISC_REQ_MUTUAL_AUTH, the lowest byte should not have bits 0x20 or 0x10 set*/
664 req_attr = ISC_REQ_MUTUAL_AUTH;
666 if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
667 0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
668 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
670 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
671 getSecError(sec_status));
672 goto tISCFend;
675 ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
676 "For ISC_REQ_MUTUAL_AUTH, flags are 0x%02x%02x%02x%02x.\n",
677 packet[15], packet[14], packet[13], packet[12]);
679 /* With ISC_REQ_USE_DCE_STYLE, the lowest byte should not have bits 0x20 or 0x10 set*/
680 req_attr = ISC_REQ_USE_DCE_STYLE;
682 if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
683 0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
684 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
686 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
687 getSecError(sec_status));
688 goto tISCFend;
691 ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
692 "For ISC_REQ_USE_DCE_STYLE, flags are 0x%02x%02x%02x%02x.\n",
693 packet[15], packet[14], packet[13], packet[12]);
695 /* With ISC_REQ_DELEGATE, the lowest byte should not have bits 0x20 or 0x10 set*/
696 req_attr = ISC_REQ_DELEGATE;
698 if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
699 0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
700 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
702 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
703 getSecError(sec_status));
704 goto tISCFend;
707 ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
708 "For ISC_REQ_DELEGATE, flags are 0x%02x%02x%02x%02x.\n",
709 packet[15], packet[14], packet[13], packet[12]);
711 /* With ISC_REQ_INTEGRITY, the lowest byte should have bit 0x10 set */
712 req_attr = ISC_REQ_INTEGRITY;
714 if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
715 0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
716 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
718 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
719 getSecError(sec_status));
720 goto tISCFend;
723 ok((packet[12] & 0x10) != 0,
724 "For ISC_REQ_INTEGRITY, flags are 0x%02x%02x%02x%02x.\n",
725 packet[15], packet[14], packet[13], packet[12]);
727 /* With ISC_REQ_REPLAY_DETECT, the lowest byte should have bit 0x10 set */
728 req_attr = ISC_REQ_REPLAY_DETECT;
730 if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
731 0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
732 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
734 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
735 getSecError(sec_status));
736 goto tISCFend;
739 ok((packet[12] & 0x10) != 0,
740 "For ISC_REQ_REPLAY_DETECT, flags are 0x%02x%02x%02x%02x.\n",
741 packet[15], packet[14], packet[13], packet[12]);
743 /* With ISC_REQ_SEQUENCE_DETECT, the lowest byte should have bit 0x10 set */
744 req_attr = ISC_REQ_SEQUENCE_DETECT;
746 if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
747 0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
748 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
750 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
751 getSecError(sec_status));
752 goto tISCFend;
755 ok((packet[12] & 0x10) != 0,
756 "For ISC_REQ_SEQUENCE_DETECT, flags are 0x%02x%02x%02x%02x.\n",
757 packet[15], packet[14], packet[13], packet[12]);
759 /* With ISC_REQ_CONFIDENTIALITY, the lowest byte should have bit 0x20 set */
760 req_attr = ISC_REQ_CONFIDENTIALITY;
762 if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
763 0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
764 &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
766 trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
767 getSecError(sec_status));
768 goto tISCFend;
771 ok((packet[12] & 0x20) != 0,
772 "For ISC_REQ_CONFIDENTIALITY, flags are 0x%02x%02x%02x%02x.\n",
773 packet[15], packet[14], packet[13], packet[12]);
775 tISCFend:
776 cleanupBuffers(&client);
777 pFreeCredentialsHandle(client.cred);
778 HeapFree(GetProcessHeap(), 0, client.cred);
779 HeapFree(GetProcessHeap(), 0, client.ctxt);
783 /**********************************************************************/
785 static void testAuth(ULONG data_rep, BOOL fake)
787 SECURITY_STATUS client_stat = SEC_I_CONTINUE_NEEDED;
788 SECURITY_STATUS server_stat = SEC_I_CONTINUE_NEEDED;
789 SECURITY_STATUS sec_status;
790 PSecPkgInfo pkg_info = NULL;
791 BOOL first = TRUE;
792 SspiData client, server;
793 SEC_WINNT_AUTH_IDENTITY id;
794 SecPkgContext_Sizes ctxt_sizes;
795 static char sec_pkg_name[] = "NTLM",
796 test_user[] = "testuser",
797 workgroup[] = "WORKGROUP",
798 test_pass[] = "testpass";
800 if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)!= SEC_E_OK)
802 skip("Package not installed, skipping test.\n");
803 return;
806 pFreeContextBuffer(pkg_info);
807 id.User = (unsigned char*) test_user;
808 id.UserLength = strlen((char *) id.User);
809 id.Domain = (unsigned char *) workgroup;
810 id.DomainLength = strlen((char *) id.Domain);
811 id.Password = (unsigned char*) test_pass;
812 id.PasswordLength = strlen((char *) id.Password);
813 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
815 client.id = &id;
817 sec_status = setupClient(&client, sec_pkg_name);
819 if(sec_status != SEC_E_OK)
821 skip("Error: Setting up the client returned %s, exiting test!\n",
822 getSecError(sec_status));
823 pFreeCredentialsHandle(client.cred);
824 return;
827 if(fake)
828 sec_status = setupFakeServer(&server, sec_pkg_name);
829 else
830 sec_status = setupServer(&server, sec_pkg_name);
832 if(sec_status != SEC_E_OK)
834 skip("Error: Setting up the server returned %s, exiting test!\n",
835 getSecError(sec_status));
836 pFreeCredentialsHandle(server.cred);
837 pFreeCredentialsHandle(client.cred);
838 return;
841 while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
843 client_stat = runClient(&client, first, data_rep);
845 ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED,
846 "Running the client returned %s, more tests will fail.\n",
847 getSecError(client_stat));
849 communicate(&client, &server);
851 if(fake)
852 server_stat = runFakeServer(&server, first, data_rep);
853 else
854 server_stat = runServer(&server, first, data_rep);
856 ok(server_stat == SEC_E_OK || server_stat == SEC_I_CONTINUE_NEEDED ||
857 server_stat == SEC_E_LOGON_DENIED,
858 "Running the server returned %s, more tests will fail from now.\n",
859 getSecError(server_stat));
861 communicate(&server, &client);
862 trace("Looping\n");
863 first = FALSE;
866 if(client_stat != SEC_E_OK)
868 skip("Authentication failed, skipping test.\n");
869 goto tAuthend;
872 sec_status = pQueryContextAttributesA(client.ctxt,
873 SECPKG_ATTR_SIZES, &ctxt_sizes);
875 ok(sec_status == SEC_E_OK,
876 "pQueryContextAttributesA(SECPKG_ATTR_SIZES) returned %s\n",
877 getSecError(sec_status));
878 ok((ctxt_sizes.cbMaxToken == 1904) || (ctxt_sizes.cbMaxToken == 2888),
879 "cbMaxToken should be 1904 or 2888 but is %u\n",
880 ctxt_sizes.cbMaxToken);
881 ok(ctxt_sizes.cbMaxSignature == 16,
882 "cbMaxSignature should be 16 but is %u\n",
883 ctxt_sizes.cbMaxSignature);
884 ok(ctxt_sizes.cbSecurityTrailer == 16,
885 "cbSecurityTrailer should be 16 but is %u\n",
886 ctxt_sizes.cbSecurityTrailer);
887 ok(ctxt_sizes.cbBlockSize == 0,
888 "cbBlockSize should be 0 but is %u\n",
889 ctxt_sizes.cbBlockSize);
891 tAuthend:
892 cleanupBuffers(&client);
893 cleanupBuffers(&server);
895 if(!fake)
897 sec_status = pDeleteSecurityContext(server.ctxt);
898 ok(sec_status == SEC_E_OK, "DeleteSecurityContext(server) returned %s\n",
899 getSecError(sec_status));
902 sec_status = pDeleteSecurityContext(client.ctxt);
903 ok(sec_status == SEC_E_OK, "DeleteSecurityContext(client) returned %s\n",
904 getSecError(sec_status));
906 if(!fake)
908 sec_status = pFreeCredentialsHandle(server.cred);
909 ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(server) returned %s\n",
910 getSecError(sec_status));
913 sec_status = pFreeCredentialsHandle(client.cred);
914 ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(client) returned %s\n",
915 getSecError(sec_status));
917 HeapFree(GetProcessHeap(), 0, client.cred);
918 HeapFree(GetProcessHeap(), 0, client.ctxt);
919 HeapFree(GetProcessHeap(), 0, server.cred);
920 HeapFree(GetProcessHeap(), 0, server.ctxt);
923 static void testSignSeal(void)
925 SECURITY_STATUS client_stat = SEC_I_CONTINUE_NEEDED;
926 SECURITY_STATUS server_stat = SEC_I_CONTINUE_NEEDED;
927 SECURITY_STATUS sec_status;
928 PSecPkgInfo pkg_info = NULL;
929 BOOL first = TRUE;
930 SspiData client, server;
931 SEC_WINNT_AUTH_IDENTITY id;
932 static char sec_pkg_name[] = "NTLM";
933 SecBufferDesc crypt;
934 SecBuffer data[2], fake_data[2], complex_data[4];
935 ULONG qop = 0;
936 SecPkgContext_Sizes ctxt_sizes;
937 static char test_user[] = "testuser",
938 workgroup[] = "WORKGROUP",
939 test_pass[] = "testpass";
941 complex_data[1].pvBuffer = complex_data[3].pvBuffer = NULL;
943 /****************************************************************
944 * This is basically the same as in testAuth with a fake server,
945 * as we need a valid, authenticated context.
947 if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
949 skip("Package not installed, skipping test.\n");
950 return;
953 pFreeContextBuffer(pkg_info);
954 id.User = (unsigned char*) test_user;
955 id.UserLength = strlen((char *) id.User);
956 id.Domain = (unsigned char *) workgroup;
957 id.DomainLength = strlen((char *) id.Domain);
958 id.Password = (unsigned char*) test_pass;
959 id.PasswordLength = strlen((char *) id.Password);
960 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
962 client.id = &id;
964 sec_status = setupClient(&client, sec_pkg_name);
966 if(sec_status != SEC_E_OK)
968 skip("Error: Setting up the client returned %s, exiting test!\n",
969 getSecError(sec_status));
970 pFreeCredentialsHandle(client.cred);
971 return;
974 sec_status = setupFakeServer(&server, sec_pkg_name);
976 while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
978 client_stat = runClient(&client, first, SECURITY_NETWORK_DREP);
980 communicate(&client, &server);
982 server_stat = runFakeServer(&server, first, SECURITY_NETWORK_DREP);
984 communicate(&server, &client);
985 trace("Looping\n");
986 first = FALSE;
989 /********************************************
990 * Now start with the actual testing *
991 ********************************************/
993 if(pQueryContextAttributesA(client.ctxt, SECPKG_ATTR_SIZES,
994 &ctxt_sizes) != SEC_E_OK)
996 skip("Failed to get context sizes, aborting test.\n");
997 goto end;
1000 crypt.ulVersion = SECBUFFER_VERSION;
1001 crypt.cBuffers = 2;
1003 crypt.pBuffers = fake_data;
1005 fake_data[0].BufferType = SECBUFFER_DATA;
1006 fake_data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1007 fake_data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[0].cbBuffer);
1009 fake_data[1].BufferType = SECBUFFER_DATA;
1010 fake_data[1].cbBuffer = lstrlen(message);
1011 fake_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[1].cbBuffer);
1013 sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
1014 ok(sec_status == SEC_E_INVALID_TOKEN,
1015 "MakeSignature returned %s, not SEC_E_INVALID_TOKEN.\n",
1016 getSecError(sec_status));
1018 crypt.pBuffers = data;
1020 data[0].BufferType = SECBUFFER_TOKEN;
1021 data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1022 data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[0].cbBuffer);
1024 data[1].BufferType = SECBUFFER_DATA;
1025 data[1].cbBuffer = lstrlen(message);
1026 data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1027 memcpy(data[1].pvBuffer, message, data[1].cbBuffer);
1029 /* As we forced NTLM to fall back to a password-derived session key,
1030 * we should get the same signature for our data, no matter if
1031 * it is sent by the client or the server
1033 sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
1034 ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1035 getSecError(sec_status));
1036 ok(!memcmp(crypt.pBuffers[0].pvBuffer, message_signature,
1037 crypt.pBuffers[0].cbBuffer), "Signature is not as expected.\n");
1039 data[0].cbBuffer = sizeof(message_signature);
1041 memcpy(data[0].pvBuffer, crypt_trailer_client, data[0].cbBuffer);
1043 sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
1044 ok(sec_status == SEC_E_MESSAGE_ALTERED,
1045 "VerifySignature returned %s, not SEC_E_MESSAGE_ALTERED.\n",
1046 getSecError(sec_status));
1048 memcpy(data[0].pvBuffer, message_signature, data[0].cbBuffer);
1050 sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
1051 ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK.\n",
1052 getSecError(sec_status));
1054 sec_status = pEncryptMessage(client.ctxt, 0, &crypt, 0);
1055 if (sec_status == SEC_E_UNSUPPORTED_FUNCTION)
1057 skip("Encrypt message returned SEC_E_UNSUPPORTED_FUNCTION. "
1058 "Expected on Vista.\n");
1059 goto end;
1061 ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1062 getSecError(sec_status));
1064 ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client,
1065 crypt.pBuffers[0].cbBuffer), "Crypt trailer not as expected.\n");
1066 if (memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client,
1067 crypt.pBuffers[0].cbBuffer))
1069 int i;
1070 for (i = 0; i < crypt.pBuffers[0].cbBuffer; i++)
1072 if (i % 8 == 0) printf(" ");
1073 printf("0x%02x,", ((unsigned char *)crypt.pBuffers[0].pvBuffer)[i]);
1074 if (i % 8 == 7) printf("\n");
1076 printf("\n");
1078 ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1079 crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1080 if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1081 crypt.pBuffers[1].cbBuffer))
1083 int i;
1084 for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
1086 if (i % 8 == 0) printf(" ");
1087 printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
1088 if (i % 8 == 7) printf("\n");
1090 printf("\n");
1093 data[0].cbBuffer = sizeof(crypt_trailer_server);
1094 data[1].cbBuffer = sizeof(crypt_message_server);
1095 memcpy(data[0].pvBuffer, crypt_trailer_server, data[0].cbBuffer);
1096 memcpy(data[1].pvBuffer, crypt_message_server, data[1].cbBuffer);
1098 sec_status = pDecryptMessage(client.ctxt, &crypt, 0, &qop);
1100 ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1101 getSecError(sec_status));
1102 ok(!memcmp(crypt.pBuffers[1].pvBuffer, message_binary,
1103 crypt.pBuffers[1].cbBuffer),
1104 "Failed to decrypt message correctly.\n");
1106 trace("Testing with more than one buffer.\n");
1108 crypt.cBuffers = sizeof(complex_data)/sizeof(complex_data[0]);
1109 crypt.pBuffers = complex_data;
1111 complex_data[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1112 complex_data[0].cbBuffer = sizeof(message_header);
1113 complex_data[0].pvBuffer = message_header;
1115 complex_data[1].BufferType = SECBUFFER_DATA;
1116 complex_data[1].cbBuffer = lstrlen(message);
1117 complex_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1118 memcpy(complex_data[1].pvBuffer, message, complex_data[1].cbBuffer);
1120 complex_data[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1121 complex_data[2].cbBuffer = sizeof(message_header);
1122 complex_data[2].pvBuffer = message_header;
1124 complex_data[3].BufferType = SECBUFFER_TOKEN;
1125 complex_data[3].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1126 complex_data[3].pvBuffer = HeapAlloc(GetProcessHeap(), 0, complex_data[3].cbBuffer);
1128 /* We should get a dummy signature again. */
1129 sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
1130 ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1131 getSecError(sec_status));
1132 ok(!memcmp(crypt.pBuffers[3].pvBuffer, message_signature,
1133 crypt.pBuffers[3].cbBuffer), "Signature is not as expected.\n");
1135 /* Being a dummy signature, it will verify right away, as if the server
1136 * sent it */
1137 sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
1138 ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK\n",
1139 getSecError(sec_status));
1141 sec_status = pEncryptMessage(client.ctxt, 0, &crypt, 0);
1142 ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1143 getSecError(sec_status));
1145 ok(!memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
1146 crypt.pBuffers[3].cbBuffer), "Crypt trailer not as expected.\n");
1147 if (memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
1148 crypt.pBuffers[3].cbBuffer))
1150 int i;
1151 for (i = 0; i < crypt.pBuffers[3].cbBuffer; i++)
1153 if (i % 8 == 0) printf(" ");
1154 printf("0x%02x,", ((unsigned char *)crypt.pBuffers[3].pvBuffer)[i]);
1155 if (i % 8 == 7) printf("\n");
1157 printf("\n");
1160 ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1161 crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1162 if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1163 crypt.pBuffers[1].cbBuffer))
1165 int i;
1166 for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
1168 if (i % 8 == 0) printf(" ");
1169 printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
1170 if (i % 8 == 7) printf("\n");
1172 printf("\n");
1175 memcpy(complex_data[1].pvBuffer, crypt_message_server2, complex_data[1].cbBuffer);
1176 memcpy(complex_data[3].pvBuffer, crypt_trailer_server2, complex_data[3].cbBuffer);
1178 sec_status = pDecryptMessage(client.ctxt, &crypt, 0, &qop);
1179 ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1180 getSecError(sec_status));
1183 end:
1184 cleanupBuffers(&client);
1185 cleanupBuffers(&server);
1187 pDeleteSecurityContext(client.ctxt);
1188 pFreeCredentialsHandle(client.cred);
1190 HeapFree(GetProcessHeap(), 0, fake_data[0].pvBuffer);
1191 HeapFree(GetProcessHeap(), 0, fake_data[1].pvBuffer);
1192 HeapFree(GetProcessHeap(), 0, data[0].pvBuffer);
1193 HeapFree(GetProcessHeap(), 0, data[1].pvBuffer);
1194 HeapFree(GetProcessHeap(), 0, complex_data[1].pvBuffer);
1195 HeapFree(GetProcessHeap(), 0, complex_data[3].pvBuffer);
1196 HeapFree(GetProcessHeap(), 0, server.cred);
1197 HeapFree(GetProcessHeap(), 0, server.ctxt);
1200 static void testAcquireCredentialsHandle(void)
1202 CredHandle cred;
1203 TimeStamp ttl;
1204 static char test_user[] = "testuser",
1205 workgroup[] = "WORKGROUP",
1206 test_pass[] = "testpass",
1207 sec_pkg_name[] = "NTLM";
1208 SECURITY_STATUS ret;
1209 SEC_WINNT_AUTH_IDENTITY id;
1210 PSecPkgInfo pkg_info = NULL;
1212 if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1214 skip("NTLM package not installed, skipping test\n");
1215 return;
1217 pFreeContextBuffer(pkg_info);
1219 id.User = (unsigned char*) test_user;
1220 id.UserLength = strlen((char *) id.User);
1221 id.Domain = (unsigned char *) workgroup;
1222 id.DomainLength = strlen((char *) id.Domain);
1223 id.Password = (unsigned char*) test_pass;
1224 id.PasswordLength = strlen((char *) id.Password);
1225 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1227 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1228 NULL, &id, NULL, NULL, &cred, &ttl);
1229 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1230 getSecError(ret));
1231 pFreeCredentialsHandle(&cred);
1233 id.DomainLength = 0;
1234 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1235 NULL, &id, NULL, NULL, &cred, &ttl);
1236 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1237 getSecError(ret));
1238 pFreeCredentialsHandle(&cred);
1240 id.Domain = NULL;
1241 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1242 NULL, &id, NULL, NULL, &cred, &ttl);
1243 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1244 getSecError(ret));
1245 pFreeCredentialsHandle(&cred);
1247 id.Domain = (unsigned char *) workgroup;
1248 id.DomainLength = strlen((char *) id.Domain);
1249 id.UserLength = 0;
1250 id.User = NULL;
1251 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1252 NULL, &id, NULL, NULL, &cred, &ttl);
1253 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1254 getSecError(ret));
1255 pFreeCredentialsHandle(&cred);
1257 id.User = (unsigned char*) test_user;
1258 id.UserLength = strlen((char *) id.User);
1259 id.Password = NULL;
1260 id.PasswordLength = 0;
1261 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1262 NULL, &id, NULL, NULL, &cred, &ttl);
1263 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1264 getSecError(ret));
1265 pFreeCredentialsHandle(&cred);
1268 static void test_cred_multiple_use(void)
1270 static char test_user[] = "testuser",
1271 workgroup[] = "WORKGROUP",
1272 test_pass[] = "testpass",
1273 sec_pkg_name[] = "NTLM";
1274 SECURITY_STATUS ret;
1275 SEC_WINNT_AUTH_IDENTITY id;
1276 PSecPkgInfo pkg_info = NULL;
1277 CredHandle cred;
1278 CtxtHandle ctxt1;
1279 CtxtHandle ctxt2;
1280 SecBufferDesc buffer_desc;
1281 SecBuffer buffers[1];
1282 ULONG ctxt_attr;
1283 TimeStamp ttl;
1285 if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1287 skip("NTLM package not installed, skipping test\n");
1288 return;
1290 buffers[0].cbBuffer = pkg_info->cbMaxToken;
1291 buffers[0].BufferType = SECBUFFER_TOKEN;
1292 buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1294 pFreeContextBuffer(pkg_info);
1296 id.User = (unsigned char*) test_user;
1297 id.UserLength = strlen((char *) id.User);
1298 id.Domain = (unsigned char *) workgroup;
1299 id.DomainLength = strlen((char *) id.Domain);
1300 id.Password = (unsigned char*) test_pass;
1301 id.PasswordLength = strlen((char *) id.Password);
1302 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1304 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1305 NULL, &id, NULL, NULL, &cred, &ttl);
1306 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1307 getSecError(ret));
1309 buffer_desc.ulVersion = SECBUFFER_VERSION;
1310 buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
1311 buffer_desc.pBuffers = buffers;
1313 ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1314 0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt1, &buffer_desc,
1315 &ctxt_attr, &ttl);
1316 ok(ret == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed with error 0x%x\n", ret);
1318 ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1319 0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt2, &buffer_desc,
1320 &ctxt_attr, &ttl);
1321 ok(ret == SEC_I_CONTINUE_NEEDED, "Second InitializeSecurityContextA on cred handle failed with error 0x%x\n", ret);
1323 ret = pDeleteSecurityContext(&ctxt1);
1324 ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1325 ret = pDeleteSecurityContext(&ctxt2);
1326 ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1327 ret = pFreeCredentialsHandle(&cred);
1328 ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret);
1330 HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer);
1333 static void test_null_auth_data(void)
1335 SECURITY_STATUS status;
1336 PSecPkgInfo info;
1337 CredHandle cred;
1338 CtxtHandle ctx;
1339 SecBufferDesc buffer_desc;
1340 SecBuffer buffers[1];
1341 char user[256];
1342 TimeStamp ttl;
1343 ULONG attr, size;
1344 BOOLEAN ret;
1346 if(pQuerySecurityPackageInfoA((SEC_CHAR *)"NTLM", &info) != SEC_E_OK)
1348 skip("NTLM package not installed, skipping test\n");
1349 return;
1352 status = pAcquireCredentialsHandleA(NULL, (SEC_CHAR *)"NTLM", SECPKG_CRED_OUTBOUND,
1353 NULL, NULL, NULL, NULL, &cred, &ttl);
1354 ok(status == SEC_E_OK, "AcquireCredentialsHande() failed %s\n", getSecError(status));
1356 buffers[0].cbBuffer = info->cbMaxToken;
1357 buffers[0].BufferType = SECBUFFER_TOKEN;
1358 buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1360 buffer_desc.ulVersion = SECBUFFER_VERSION;
1361 buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
1362 buffer_desc.pBuffers = buffers;
1364 size = sizeof(user);
1365 ret = pGetUserNameExA(NameSamCompatible, user, &size);
1366 ok(ret, "GetUserNameExA failed %u\n", GetLastError());
1368 status = pInitializeSecurityContextA(&cred, NULL, (SEC_CHAR *)user,
1369 ISC_REQ_CONNECTION, 0, SECURITY_NETWORK_DREP,
1370 NULL, 0, &ctx, &buffer_desc, &attr, &ttl);
1371 ok(status == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed %s\n", getSecError(status));
1373 HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer);
1376 START_TEST(ntlm)
1378 InitFunctionPtrs();
1380 if(pFreeCredentialsHandle && pDeleteSecurityContext &&
1381 pDeleteSecurityContext && pAcquireCredentialsHandleA &&
1382 pInitializeSecurityContextA && pCompleteAuthToken &&
1383 pQuerySecurityPackageInfoA)
1385 testAcquireCredentialsHandle();
1386 testInitializeSecurityContextFlags();
1387 if(pAcceptSecurityContext)
1389 testAuth(SECURITY_NATIVE_DREP, TRUE);
1390 testAuth(SECURITY_NETWORK_DREP, TRUE);
1391 testAuth(SECURITY_NATIVE_DREP, FALSE);
1392 testAuth(SECURITY_NETWORK_DREP, FALSE);
1394 if(pMakeSignature && pVerifySignature && pEncryptMessage &&
1395 pDecryptMessage)
1396 testSignSeal();
1398 test_cred_multiple_use();
1399 if (pGetUserNameExA) test_null_auth_data();
1401 else
1402 win_skip("Needed functions are not available\n");
1404 if(secdll)
1405 FreeLibrary(secdll);