push 5bc4839baba05cc4333240c25295b8dd6e351557
[wine/hacks.git] / dlls / secur32 / tests / ntlm.c
blobdb00d730c090da6c1c062d8abbb3e7d7ce4c9e3b
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);
781 /**********************************************************************/
783 static void testAuth(ULONG data_rep, BOOL fake)
785 SECURITY_STATUS client_stat = SEC_I_CONTINUE_NEEDED;
786 SECURITY_STATUS server_stat = SEC_I_CONTINUE_NEEDED;
787 SECURITY_STATUS sec_status;
788 PSecPkgInfo pkg_info = NULL;
789 BOOL first = TRUE;
790 SspiData client, server;
791 SEC_WINNT_AUTH_IDENTITY id;
792 SecPkgContext_Sizes ctxt_sizes;
793 static char sec_pkg_name[] = "NTLM",
794 test_user[] = "testuser",
795 workgroup[] = "WORKGROUP",
796 test_pass[] = "testpass";
798 if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)!= SEC_E_OK)
800 skip("Package not installed, skipping test.\n");
801 return;
804 pFreeContextBuffer(pkg_info);
805 id.User = (unsigned char*) test_user;
806 id.UserLength = strlen((char *) id.User);
807 id.Domain = (unsigned char *) workgroup;
808 id.DomainLength = strlen((char *) id.Domain);
809 id.Password = (unsigned char*) test_pass;
810 id.PasswordLength = strlen((char *) id.Password);
811 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
813 client.id = &id;
815 sec_status = setupClient(&client, sec_pkg_name);
817 if(sec_status != SEC_E_OK)
819 skip("Error: Setting up the client returned %s, exiting test!\n",
820 getSecError(sec_status));
821 pFreeCredentialsHandle(client.cred);
822 return;
825 if(fake)
826 sec_status = setupFakeServer(&server, sec_pkg_name);
827 else
828 sec_status = setupServer(&server, sec_pkg_name);
830 if(sec_status != SEC_E_OK)
832 skip("Error: Setting up the server returned %s, exiting test!\n",
833 getSecError(sec_status));
834 pFreeCredentialsHandle(server.cred);
835 pFreeCredentialsHandle(client.cred);
836 return;
839 while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
841 client_stat = runClient(&client, first, data_rep);
843 ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED,
844 "Running the client returned %s, more tests will fail.\n",
845 getSecError(client_stat));
847 communicate(&client, &server);
849 if(fake)
850 server_stat = runFakeServer(&server, first, data_rep);
851 else
852 server_stat = runServer(&server, first, data_rep);
854 ok(server_stat == SEC_E_OK || server_stat == SEC_I_CONTINUE_NEEDED ||
855 server_stat == SEC_E_LOGON_DENIED,
856 "Running the server returned %s, more tests will fail from now.\n",
857 getSecError(server_stat));
859 communicate(&server, &client);
860 trace("Looping\n");
861 first = FALSE;
864 if(client_stat != SEC_E_OK)
866 skip("Authentication failed, skipping test.\n");
867 goto tAuthend;
870 sec_status = pQueryContextAttributesA(client.ctxt,
871 SECPKG_ATTR_SIZES, &ctxt_sizes);
873 ok(sec_status == SEC_E_OK,
874 "pQueryContextAttributesA(SECPKG_ATTR_SIZES) returned %s\n",
875 getSecError(sec_status));
876 ok((ctxt_sizes.cbMaxToken == 1904) || (ctxt_sizes.cbMaxToken == 2888),
877 "cbMaxToken should be 1904 or 2888 but is %u\n",
878 ctxt_sizes.cbMaxToken);
879 ok(ctxt_sizes.cbMaxSignature == 16,
880 "cbMaxSignature should be 16 but is %u\n",
881 ctxt_sizes.cbMaxSignature);
882 ok(ctxt_sizes.cbSecurityTrailer == 16,
883 "cbSecurityTrailer should be 16 but is %u\n",
884 ctxt_sizes.cbSecurityTrailer);
885 ok(ctxt_sizes.cbBlockSize == 0,
886 "cbBlockSize should be 0 but is %u\n",
887 ctxt_sizes.cbBlockSize);
889 tAuthend:
890 cleanupBuffers(&client);
891 cleanupBuffers(&server);
893 if(!fake)
895 sec_status = pDeleteSecurityContext(server.ctxt);
896 ok(sec_status == SEC_E_OK, "DeleteSecurityContext(server) returned %s\n",
897 getSecError(sec_status));
900 sec_status = pDeleteSecurityContext(client.ctxt);
901 ok(sec_status == SEC_E_OK, "DeleteSecurityContext(client) returned %s\n",
902 getSecError(sec_status));
904 if(!fake)
906 sec_status = pFreeCredentialsHandle(server.cred);
907 ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(server) returned %s\n",
908 getSecError(sec_status));
911 sec_status = pFreeCredentialsHandle(client.cred);
912 ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(client) returned %s\n",
913 getSecError(sec_status));
916 static void testSignSeal(void)
918 SECURITY_STATUS client_stat = SEC_I_CONTINUE_NEEDED;
919 SECURITY_STATUS server_stat = SEC_I_CONTINUE_NEEDED;
920 SECURITY_STATUS sec_status;
921 PSecPkgInfo pkg_info = NULL;
922 BOOL first = TRUE;
923 SspiData client, server;
924 SEC_WINNT_AUTH_IDENTITY id;
925 static char sec_pkg_name[] = "NTLM";
926 SecBufferDesc crypt;
927 SecBuffer data[2], fake_data[2], complex_data[4];
928 ULONG qop = 0;
929 SecPkgContext_Sizes ctxt_sizes;
930 static char test_user[] = "testuser",
931 workgroup[] = "WORKGROUP",
932 test_pass[] = "testpass";
934 complex_data[1].pvBuffer = complex_data[3].pvBuffer = NULL;
936 /****************************************************************
937 * This is basically the same as in testAuth with a fake server,
938 * as we need a valid, authenticated context.
940 if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
942 skip("Package not installed, skipping test.\n");
943 return;
946 pFreeContextBuffer(pkg_info);
947 id.User = (unsigned char*) test_user;
948 id.UserLength = strlen((char *) id.User);
949 id.Domain = (unsigned char *) workgroup;
950 id.DomainLength = strlen((char *) id.Domain);
951 id.Password = (unsigned char*) test_pass;
952 id.PasswordLength = strlen((char *) id.Password);
953 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
955 client.id = &id;
957 sec_status = setupClient(&client, sec_pkg_name);
959 if(sec_status != SEC_E_OK)
961 skip("Error: Setting up the client returned %s, exiting test!\n",
962 getSecError(sec_status));
963 pFreeCredentialsHandle(client.cred);
964 return;
967 sec_status = setupFakeServer(&server, sec_pkg_name);
969 while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
971 client_stat = runClient(&client, first, SECURITY_NETWORK_DREP);
973 communicate(&client, &server);
975 server_stat = runFakeServer(&server, first, SECURITY_NETWORK_DREP);
977 communicate(&server, &client);
978 trace("Looping\n");
979 first = FALSE;
982 /********************************************
983 * Now start with the actual testing *
984 ********************************************/
986 if(pQueryContextAttributesA(client.ctxt, SECPKG_ATTR_SIZES,
987 &ctxt_sizes) != SEC_E_OK)
989 skip("Failed to get context sizes, aborting test.\n");
990 goto end;
993 crypt.ulVersion = SECBUFFER_VERSION;
994 crypt.cBuffers = 2;
996 crypt.pBuffers = fake_data;
998 fake_data[0].BufferType = SECBUFFER_DATA;
999 fake_data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1000 fake_data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[0].cbBuffer);
1002 fake_data[1].BufferType = SECBUFFER_DATA;
1003 fake_data[1].cbBuffer = lstrlen(message);
1004 fake_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[1].cbBuffer);
1006 sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
1007 ok(sec_status == SEC_E_INVALID_TOKEN,
1008 "MakeSignature returned %s, not SEC_E_INVALID_TOKEN.\n",
1009 getSecError(sec_status));
1011 crypt.pBuffers = data;
1013 data[0].BufferType = SECBUFFER_TOKEN;
1014 data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1015 data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[0].cbBuffer);
1017 data[1].BufferType = SECBUFFER_DATA;
1018 data[1].cbBuffer = lstrlen(message);
1019 data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1020 memcpy(data[1].pvBuffer, message, data[1].cbBuffer);
1022 /* As we forced NTLM to fall back to a password-derived session key,
1023 * we should get the same signature for our data, no matter if
1024 * it is sent by the client or the server
1026 sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
1027 ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1028 getSecError(sec_status));
1029 ok(!memcmp(crypt.pBuffers[0].pvBuffer, message_signature,
1030 crypt.pBuffers[0].cbBuffer), "Signature is not as expected.\n");
1032 data[0].cbBuffer = sizeof(message_signature);
1034 memcpy(data[0].pvBuffer, crypt_trailer_client, data[0].cbBuffer);
1036 sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
1037 ok(sec_status == SEC_E_MESSAGE_ALTERED,
1038 "VerifySignature returned %s, not SEC_E_MESSAGE_ALTERED.\n",
1039 getSecError(sec_status));
1041 memcpy(data[0].pvBuffer, message_signature, data[0].cbBuffer);
1043 sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
1044 ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK.\n",
1045 getSecError(sec_status));
1047 sec_status = pEncryptMessage(client.ctxt, 0, &crypt, 0);
1048 if (sec_status == SEC_E_UNSUPPORTED_FUNCTION)
1050 skip("Encrypt message returned SEC_E_UNSUPPORTED_FUNCTION. "
1051 "Expected on Vista.\n");
1052 goto end;
1054 ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1055 getSecError(sec_status));
1057 ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client,
1058 crypt.pBuffers[0].cbBuffer), "Crypt trailer not as expected.\n");
1059 if (memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client,
1060 crypt.pBuffers[0].cbBuffer))
1062 int i;
1063 for (i = 0; i < crypt.pBuffers[0].cbBuffer; i++)
1065 if (i % 8 == 0) printf(" ");
1066 printf("0x%02x,", ((unsigned char *)crypt.pBuffers[0].pvBuffer)[i]);
1067 if (i % 8 == 7) printf("\n");
1069 printf("\n");
1071 ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1072 crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1073 if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1074 crypt.pBuffers[1].cbBuffer))
1076 int i;
1077 for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
1079 if (i % 8 == 0) printf(" ");
1080 printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
1081 if (i % 8 == 7) printf("\n");
1083 printf("\n");
1086 data[0].cbBuffer = sizeof(crypt_trailer_server);
1087 data[1].cbBuffer = sizeof(crypt_message_server);
1088 memcpy(data[0].pvBuffer, crypt_trailer_server, data[0].cbBuffer);
1089 memcpy(data[1].pvBuffer, crypt_message_server, data[1].cbBuffer);
1091 sec_status = pDecryptMessage(client.ctxt, &crypt, 0, &qop);
1093 ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1094 getSecError(sec_status));
1095 ok(!memcmp(crypt.pBuffers[1].pvBuffer, message_binary,
1096 crypt.pBuffers[1].cbBuffer),
1097 "Failed to decrypt message correctly.\n");
1099 trace("Testing with more than one buffer.\n");
1101 crypt.cBuffers = sizeof(complex_data)/sizeof(complex_data[0]);
1102 crypt.pBuffers = complex_data;
1104 complex_data[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1105 complex_data[0].cbBuffer = sizeof(message_header);
1106 complex_data[0].pvBuffer = message_header;
1108 complex_data[1].BufferType = SECBUFFER_DATA;
1109 complex_data[1].cbBuffer = lstrlen(message);
1110 complex_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1111 memcpy(complex_data[1].pvBuffer, message, complex_data[1].cbBuffer);
1113 complex_data[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1114 complex_data[2].cbBuffer = sizeof(message_header);
1115 complex_data[2].pvBuffer = message_header;
1117 complex_data[3].BufferType = SECBUFFER_TOKEN;
1118 complex_data[3].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1119 complex_data[3].pvBuffer = HeapAlloc(GetProcessHeap(), 0, complex_data[3].cbBuffer);
1121 /* We should get a dummy signature again. */
1122 sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
1123 ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1124 getSecError(sec_status));
1125 ok(!memcmp(crypt.pBuffers[3].pvBuffer, message_signature,
1126 crypt.pBuffers[3].cbBuffer), "Signature is not as expected.\n");
1128 /* Being a dummy signature, it will verify right away, as if the server
1129 * sent it */
1130 sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
1131 ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK\n",
1132 getSecError(sec_status));
1134 sec_status = pEncryptMessage(client.ctxt, 0, &crypt, 0);
1135 ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1136 getSecError(sec_status));
1138 ok(!memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
1139 crypt.pBuffers[3].cbBuffer), "Crypt trailer not as expected.\n");
1140 if (memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
1141 crypt.pBuffers[3].cbBuffer))
1143 int i;
1144 for (i = 0; i < crypt.pBuffers[3].cbBuffer; i++)
1146 if (i % 8 == 0) printf(" ");
1147 printf("0x%02x,", ((unsigned char *)crypt.pBuffers[3].pvBuffer)[i]);
1148 if (i % 8 == 7) printf("\n");
1150 printf("\n");
1153 ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1154 crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1155 if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1156 crypt.pBuffers[1].cbBuffer))
1158 int i;
1159 for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
1161 if (i % 8 == 0) printf(" ");
1162 printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
1163 if (i % 8 == 7) printf("\n");
1165 printf("\n");
1168 memcpy(complex_data[1].pvBuffer, crypt_message_server2, complex_data[1].cbBuffer);
1169 memcpy(complex_data[3].pvBuffer, crypt_trailer_server2, complex_data[3].cbBuffer);
1171 sec_status = pDecryptMessage(client.ctxt, &crypt, 0, &qop);
1172 ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1173 getSecError(sec_status));
1176 end:
1177 cleanupBuffers(&client);
1178 cleanupBuffers(&server);
1180 pDeleteSecurityContext(client.ctxt);
1181 pFreeCredentialsHandle(client.cred);
1183 HeapFree(GetProcessHeap(), 0, fake_data[0].pvBuffer);
1184 HeapFree(GetProcessHeap(), 0, fake_data[1].pvBuffer);
1185 HeapFree(GetProcessHeap(), 0, data[0].pvBuffer);
1186 HeapFree(GetProcessHeap(), 0, data[1].pvBuffer);
1187 HeapFree(GetProcessHeap(), 0, complex_data[1].pvBuffer);
1188 HeapFree(GetProcessHeap(), 0, complex_data[3].pvBuffer);
1191 static void testAcquireCredentialsHandle(void)
1193 CredHandle cred;
1194 TimeStamp ttl;
1195 static char test_user[] = "testuser",
1196 workgroup[] = "WORKGROUP",
1197 test_pass[] = "testpass",
1198 sec_pkg_name[] = "NTLM";
1199 SECURITY_STATUS ret;
1200 SEC_WINNT_AUTH_IDENTITY id;
1201 PSecPkgInfo pkg_info = NULL;
1203 if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1205 skip("NTLM package not installed, skipping test\n");
1206 return;
1208 pFreeContextBuffer(pkg_info);
1210 id.User = (unsigned char*) test_user;
1211 id.UserLength = strlen((char *) id.User);
1212 id.Domain = (unsigned char *) workgroup;
1213 id.DomainLength = strlen((char *) id.Domain);
1214 id.Password = (unsigned char*) test_pass;
1215 id.PasswordLength = strlen((char *) id.Password);
1216 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1218 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1219 NULL, &id, NULL, NULL, &cred, &ttl);
1220 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1221 getSecError(ret));
1222 pFreeCredentialsHandle(&cred);
1224 id.DomainLength = 0;
1225 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1226 NULL, &id, NULL, NULL, &cred, &ttl);
1227 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1228 getSecError(ret));
1229 pFreeCredentialsHandle(&cred);
1231 id.Domain = NULL;
1232 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1233 NULL, &id, NULL, NULL, &cred, &ttl);
1234 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1235 getSecError(ret));
1236 pFreeCredentialsHandle(&cred);
1238 id.Domain = (unsigned char *) workgroup;
1239 id.DomainLength = strlen((char *) id.Domain);
1240 id.UserLength = 0;
1241 id.User = NULL;
1242 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1243 NULL, &id, NULL, NULL, &cred, &ttl);
1244 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1245 getSecError(ret));
1246 pFreeCredentialsHandle(&cred);
1248 id.User = (unsigned char*) test_user;
1249 id.UserLength = strlen((char *) id.User);
1250 id.Password = NULL;
1251 id.PasswordLength = 0;
1252 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1253 NULL, &id, NULL, NULL, &cred, &ttl);
1254 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1255 getSecError(ret));
1256 pFreeCredentialsHandle(&cred);
1259 static void test_cred_multiple_use(void)
1261 static char test_user[] = "testuser",
1262 workgroup[] = "WORKGROUP",
1263 test_pass[] = "testpass",
1264 sec_pkg_name[] = "NTLM";
1265 SECURITY_STATUS ret;
1266 SEC_WINNT_AUTH_IDENTITY id;
1267 PSecPkgInfo pkg_info = NULL;
1268 CredHandle cred;
1269 CtxtHandle ctxt1;
1270 CtxtHandle ctxt2;
1271 SecBufferDesc buffer_desc;
1272 SecBuffer buffers[1];
1273 ULONG ctxt_attr;
1274 TimeStamp ttl;
1276 if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1278 skip("NTLM package not installed, skipping test\n");
1279 return;
1281 buffers[0].cbBuffer = pkg_info->cbMaxToken;
1282 buffers[0].BufferType = SECBUFFER_TOKEN;
1283 buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1285 pFreeContextBuffer(pkg_info);
1287 id.User = (unsigned char*) test_user;
1288 id.UserLength = strlen((char *) id.User);
1289 id.Domain = (unsigned char *) workgroup;
1290 id.DomainLength = strlen((char *) id.Domain);
1291 id.Password = (unsigned char*) test_pass;
1292 id.PasswordLength = strlen((char *) id.Password);
1293 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1295 ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1296 NULL, &id, NULL, NULL, &cred, &ttl);
1297 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
1298 getSecError(ret));
1300 buffer_desc.ulVersion = SECBUFFER_VERSION;
1301 buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
1302 buffer_desc.pBuffers = buffers;
1304 ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1305 0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt1, &buffer_desc,
1306 &ctxt_attr, &ttl);
1307 ok(ret == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed with error 0x%x\n", ret);
1309 ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1310 0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt2, &buffer_desc,
1311 &ctxt_attr, &ttl);
1312 ok(ret == SEC_I_CONTINUE_NEEDED, "Second InitializeSecurityContextA on cred handle failed with error 0x%x\n", ret);
1314 ret = pDeleteSecurityContext(&ctxt1);
1315 ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1316 ret = pDeleteSecurityContext(&ctxt2);
1317 ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1318 ret = pFreeCredentialsHandle(&cred);
1319 ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret);
1322 static void test_null_auth_data(void)
1324 SECURITY_STATUS status;
1325 PSecPkgInfo info;
1326 CredHandle cred;
1327 CtxtHandle ctx;
1328 SecBufferDesc buffer_desc;
1329 SecBuffer buffers[1];
1330 char user[256];
1331 TimeStamp ttl;
1332 ULONG attr, size;
1333 BOOLEAN ret;
1335 if(pQuerySecurityPackageInfoA((SEC_CHAR *)"NTLM", &info) != SEC_E_OK)
1337 skip("NTLM package not installed, skipping test\n");
1338 return;
1341 status = pAcquireCredentialsHandleA(NULL, (SEC_CHAR *)"NTLM", SECPKG_CRED_OUTBOUND,
1342 NULL, NULL, NULL, NULL, &cred, &ttl);
1343 ok(status == SEC_E_OK, "AcquireCredentialsHande() failed %s\n", getSecError(status));
1345 buffers[0].cbBuffer = info->cbMaxToken;
1346 buffers[0].BufferType = SECBUFFER_TOKEN;
1347 buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1349 buffer_desc.ulVersion = SECBUFFER_VERSION;
1350 buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
1351 buffer_desc.pBuffers = buffers;
1353 size = sizeof(user);
1354 ret = pGetUserNameExA(NameSamCompatible, user, &size);
1355 ok(ret, "GetUserNameExA failed %u\n", GetLastError());
1357 status = pInitializeSecurityContextA(&cred, NULL, (SEC_CHAR *)user,
1358 ISC_REQ_CONNECTION, 0, SECURITY_NETWORK_DREP,
1359 NULL, 0, &ctx, &buffer_desc, &attr, &ttl);
1360 ok(status == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed %s\n", getSecError(status));
1363 START_TEST(ntlm)
1365 InitFunctionPtrs();
1367 if(pFreeCredentialsHandle && pDeleteSecurityContext &&
1368 pDeleteSecurityContext && pAcquireCredentialsHandleA &&
1369 pInitializeSecurityContextA && pCompleteAuthToken &&
1370 pQuerySecurityPackageInfoA)
1372 testAcquireCredentialsHandle();
1373 testInitializeSecurityContextFlags();
1374 if(pAcceptSecurityContext)
1376 testAuth(SECURITY_NATIVE_DREP, TRUE);
1377 testAuth(SECURITY_NETWORK_DREP, TRUE);
1378 testAuth(SECURITY_NATIVE_DREP, FALSE);
1379 testAuth(SECURITY_NETWORK_DREP, FALSE);
1381 if(pMakeSignature && pVerifySignature && pEncryptMessage &&
1382 pDecryptMessage)
1383 testSignSeal();
1385 test_cred_multiple_use();
1386 if (pGetUserNameExA) test_null_auth_data();
1388 else
1389 win_skip("Needed functions are not available\n");
1391 if(secdll)
1392 FreeLibrary(secdll);