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.
31 #define SECURITY_WIN32
34 #include "wine/test.h"
36 static HMODULE secdll;
37 static PSecurityFunctionTableA (SEC_ENTRY * pInitSecurityInterfaceA)(void);
38 static SECURITY_STATUS (SEC_ENTRY * pFreeContextBuffer)(PVOID pv);
39 static SECURITY_STATUS (SEC_ENTRY * pQuerySecurityPackageInfoA)(SEC_CHAR*, PSecPkgInfoA*);
40 static SECURITY_STATUS (SEC_ENTRY * pAcquireCredentialsHandleA)(SEC_CHAR*, SEC_CHAR*,
41 ULONG, PLUID, PVOID, SEC_GET_KEY_FN, PVOID, PCredHandle, PTimeStamp);
42 static SECURITY_STATUS (SEC_ENTRY * pInitializeSecurityContextA)(PCredHandle, PCtxtHandle,
43 SEC_CHAR*, ULONG, ULONG, ULONG, PSecBufferDesc, ULONG,
44 PCtxtHandle, PSecBufferDesc, PULONG, PTimeStamp);
45 static SECURITY_STATUS (SEC_ENTRY * pCompleteAuthToken)(PCtxtHandle, PSecBufferDesc);
46 static SECURITY_STATUS (SEC_ENTRY * pAcceptSecurityContext)(PCredHandle, PCtxtHandle,
47 PSecBufferDesc, ULONG, ULONG, PCtxtHandle, PSecBufferDesc,
49 static SECURITY_STATUS (SEC_ENTRY * pFreeCredentialsHandle)(PCredHandle);
50 static SECURITY_STATUS (SEC_ENTRY * pDeleteSecurityContext)(PCtxtHandle);
51 static SECURITY_STATUS (SEC_ENTRY * pQueryContextAttributesA)(PCtxtHandle, ULONG, PVOID);
52 static SECURITY_STATUS (SEC_ENTRY * pMakeSignature)(PCtxtHandle, ULONG,
53 PSecBufferDesc, ULONG);
54 static SECURITY_STATUS (SEC_ENTRY * pVerifySignature)(PCtxtHandle, PSecBufferDesc,
56 static SECURITY_STATUS (SEC_ENTRY * pEncryptMessage)(PCtxtHandle, ULONG,
57 PSecBufferDesc, ULONG);
58 static SECURITY_STATUS (SEC_ENTRY * pDecryptMessage)(PCtxtHandle, PSecBufferDesc,
61 typedef struct _SspiData {
64 PSecBufferDesc in_buf;
65 PSecBufferDesc out_buf;
66 PSEC_WINNT_AUTH_IDENTITY id;
70 static BYTE network_challenge[] =
71 {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00,
72 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00,
73 0x05, 0x82, 0x82, 0xa0, 0xe9, 0x58, 0x7f, 0x14, 0xa2, 0x86,
74 0x3b, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00,
76 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
77 0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00,
78 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
79 0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00,
80 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
81 0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00,
82 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
83 0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00,
84 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
85 0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00};
87 static BYTE native_challenge[] =
88 {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00,
89 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00,
90 0x05, 0x82, 0x82, 0xa0, 0xb5, 0x60, 0x8e, 0x95, 0xb5, 0x3c,
91 0xee, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00,
93 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
94 0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00,
95 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
96 0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00,
97 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
98 0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00,
99 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
100 0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00,
101 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
102 0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00};
104 static BYTE message_signature[] =
105 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
108 static BYTE message_binary[] =
109 {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72,
112 static char message[] = "Hello, world!";
114 static char message_header[] = "Header Test";
116 static BYTE crypt_trailer_client[] =
117 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xc7,
118 0xaa, 0x26, 0x16, 0x39, 0x07, 0x4e};
120 static BYTE crypt_message_client[] =
121 {0x86, 0x9c, 0x5a, 0x10, 0x78, 0xb3, 0x30, 0x98, 0x46, 0x15,
124 static BYTE crypt_trailer_client2[] =
125 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0xa7,
126 0xf7, 0x0f, 0x5b, 0x25, 0xbe, 0xa4};
128 static BYTE crypt_message_client2[] =
129 {0x20, 0x6c, 0x01, 0xab, 0xb0, 0x4c, 0x93, 0xe4, 0x1e, 0xfc,
132 static BYTE crypt_trailer_server[] =
133 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x46,
134 0x2e, 0x77, 0xeb, 0xf0, 0xf6, 0x9e};
136 static BYTE crypt_message_server[] =
137 {0xf6, 0xb7, 0x92, 0x0c, 0xac, 0xea, 0x98, 0xe6, 0xef, 0xa0,
140 static void InitFunctionPtrs(void)
142 secdll = LoadLibraryA("secur32.dll");
144 secdll = LoadLibraryA("security.dll");
147 pInitSecurityInterfaceA = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceA");
148 pFreeContextBuffer = (PVOID)GetProcAddress(secdll, "FreeContextBuffer");
149 pQuerySecurityPackageInfoA = (PVOID)GetProcAddress(secdll, "QuerySecurityPackageInfoA");
150 pAcquireCredentialsHandleA = (PVOID)GetProcAddress(secdll, "AcquireCredentialsHandleA");
151 pInitializeSecurityContextA = (PVOID)GetProcAddress(secdll, "InitializeSecurityContextA");
152 pCompleteAuthToken = (PVOID)GetProcAddress(secdll, "CompleteAuthToken");
153 pAcceptSecurityContext = (PVOID)GetProcAddress(secdll, "AcceptSecurityContext");
154 pFreeCredentialsHandle = (PVOID)GetProcAddress(secdll, "FreeCredentialsHandle");
155 pDeleteSecurityContext = (PVOID)GetProcAddress(secdll, "DeleteSecurityContext");
156 pQueryContextAttributesA = (PVOID)GetProcAddress(secdll, "QueryContextAttributesA");
157 pMakeSignature = (PVOID)GetProcAddress(secdll, "MakeSignature");
158 pVerifySignature = (PVOID)GetProcAddress(secdll, "VerifySignature");
159 pEncryptMessage = (PVOID)GetProcAddress(secdll, "EncryptMessage");
160 pDecryptMessage = (PVOID)GetProcAddress(secdll, "DecryptMessage");
164 static const char* getSecError(SECURITY_STATUS status)
168 #define _SEC_ERR(x) case (x): return #x;
172 _SEC_ERR(SEC_E_INSUFFICIENT_MEMORY);
173 _SEC_ERR(SEC_E_INVALID_HANDLE);
174 _SEC_ERR(SEC_E_UNSUPPORTED_FUNCTION);
175 _SEC_ERR(SEC_E_TARGET_UNKNOWN);
176 _SEC_ERR(SEC_E_INTERNAL_ERROR);
177 _SEC_ERR(SEC_E_SECPKG_NOT_FOUND);
178 _SEC_ERR(SEC_E_NOT_OWNER);
179 _SEC_ERR(SEC_E_CANNOT_INSTALL);
180 _SEC_ERR(SEC_E_INVALID_TOKEN);
181 _SEC_ERR(SEC_E_CANNOT_PACK);
182 _SEC_ERR(SEC_E_QOP_NOT_SUPPORTED);
183 _SEC_ERR(SEC_E_NO_IMPERSONATION);
184 _SEC_ERR(SEC_I_CONTINUE_NEEDED);
185 _SEC_ERR(SEC_E_BUFFER_TOO_SMALL);
186 _SEC_ERR(SEC_E_ILLEGAL_MESSAGE);
187 _SEC_ERR(SEC_E_LOGON_DENIED);
188 _SEC_ERR(SEC_E_NO_CREDENTIALS);
189 _SEC_ERR(SEC_E_OUT_OF_SEQUENCE);
190 _SEC_ERR(SEC_E_MESSAGE_ALTERED);
192 sprintf(buf, "%08x\n", status);
198 /**********************************************************************/
200 static SECURITY_STATUS setupBuffers(SspiData *sspi_data, SecPkgInfoA *sec_pkg_info)
203 sspi_data->in_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
204 sspi_data->out_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
205 sspi_data->max_token = sec_pkg_info->cbMaxToken;
207 if(sspi_data->in_buf != NULL)
209 PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
211 if(sec_buffer == NULL){
212 trace("in_buf: sec_buffer == NULL\n");
213 return SEC_E_INSUFFICIENT_MEMORY;
216 sspi_data->in_buf->ulVersion = SECBUFFER_VERSION;
217 sspi_data->in_buf->cBuffers = 1;
218 sspi_data->in_buf->pBuffers = sec_buffer;
220 sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
221 sec_buffer->BufferType = SECBUFFER_TOKEN;
222 if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0,
223 sec_pkg_info->cbMaxToken)) == NULL)
225 trace("in_buf: sec_buffer->pvBuffer == NULL\n");
226 return SEC_E_INSUFFICIENT_MEMORY;
231 trace("HeapAlloc in_buf returned NULL\n");
232 return SEC_E_INSUFFICIENT_MEMORY;
235 if(sspi_data->out_buf != NULL)
237 PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
240 if(sec_buffer == NULL){
241 trace("out_buf: sec_buffer == NULL\n");
242 return SEC_E_INSUFFICIENT_MEMORY;
245 sspi_data->out_buf->ulVersion = SECBUFFER_VERSION;
246 sspi_data->out_buf->cBuffers = 1;
247 sspi_data->out_buf->pBuffers = sec_buffer;
249 sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
250 sec_buffer->BufferType = SECBUFFER_TOKEN;
251 if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0,
252 sec_pkg_info->cbMaxToken)) == NULL){
253 trace("out_buf: sec_buffer->pvBuffer == NULL\n");
254 return SEC_E_INSUFFICIENT_MEMORY;
259 trace("HeapAlloc out_buf returned NULL\n");
260 return SEC_E_INSUFFICIENT_MEMORY;
266 /**********************************************************************/
268 static void cleanupBuffers(SspiData *sspi_data)
272 if(sspi_data->in_buf != NULL)
274 for(i = 0; i < sspi_data->in_buf->cBuffers; ++i)
276 HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers[i].pvBuffer);
278 HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers);
279 HeapFree(GetProcessHeap(), 0, sspi_data->in_buf);
282 if(sspi_data->out_buf != NULL)
284 for(i = 0; i < sspi_data->out_buf->cBuffers; ++i)
286 HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers[i].pvBuffer);
288 HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers);
289 HeapFree(GetProcessHeap(), 0, sspi_data->out_buf);
293 /**********************************************************************/
295 static SECURITY_STATUS setupClient(SspiData *sspi_data, SEC_CHAR *provider)
299 SecPkgInfoA *sec_pkg_info;
301 trace("Running setupClient\n");
303 sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
304 sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
306 ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
308 ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
310 setupBuffers(sspi_data, sec_pkg_info);
312 if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_OUTBOUND,
313 NULL, sspi_data->id, NULL, NULL, sspi_data->cred, &ttl))
316 trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
319 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
324 /**********************************************************************/
326 static SECURITY_STATUS setupServer(SspiData *sspi_data, SEC_CHAR *provider)
330 SecPkgInfoA *sec_pkg_info;
332 trace("Running setupServer\n");
334 sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
335 sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
337 ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
339 ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
341 setupBuffers(sspi_data, sec_pkg_info);
343 if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_INBOUND,
344 NULL, NULL, NULL, NULL, sspi_data->cred, &ttl)) != SEC_E_OK)
346 trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
349 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
355 /**********************************************************************/
357 static SECURITY_STATUS setupFakeServer(SspiData *sspi_data, SEC_CHAR *provider)
360 SecPkgInfoA *sec_pkg_info;
362 trace("Running setupFakeServer\n");
364 sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
365 sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
367 ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
369 ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
371 ret = setupBuffers(sspi_data, sec_pkg_info);
377 /**********************************************************************/
379 static SECURITY_STATUS runClient(SspiData *sspi_data, BOOL first, ULONG data_rep)
385 PSecBufferDesc in_buf = sspi_data->in_buf;
386 PSecBufferDesc out_buf = sspi_data->out_buf;
388 assert(in_buf->cBuffers >= 1);
389 assert(in_buf->pBuffers[0].pvBuffer != NULL);
390 assert(in_buf->pBuffers[0].cbBuffer != 0);
392 assert(out_buf->cBuffers >= 1);
393 assert(out_buf->pBuffers[0].pvBuffer != NULL);
394 assert(out_buf->pBuffers[0].cbBuffer != 0);
396 trace("Running the client the %s time.\n", first?"first":"second");
398 /* We can either use ISC_REQ_ALLOCATE_MEMORY flag to ask the provider
399 * always allocate output buffers for us, or initialize cbBuffer
400 * before each call because the API changes it to represent actual
401 * amount of data in the buffer.
404 /* test a failing call only the first time, otherwise we get
405 * SEC_E_OUT_OF_SEQUENCE
411 /* pass NULL as an output buffer */
412 ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
413 0, data_rep, NULL, 0, sspi_data->ctxt, NULL,
416 ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
418 /* pass NULL as an output buffer */
419 old_buf = out_buf->pBuffers[0].pvBuffer;
420 out_buf->pBuffers[0].pvBuffer = NULL;
422 ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
423 0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
426 ok(ret == SEC_E_INTERNAL_ERROR, "expected SEC_E_INTERNAL_ERROR, got %s\n", getSecError(ret));
428 out_buf->pBuffers[0].pvBuffer = old_buf;
430 /* pass an output buffer of 0 size */
431 out_buf->pBuffers[0].cbBuffer = 0;
433 ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
434 0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
437 ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
439 ok(out_buf->pBuffers[0].cbBuffer == 0,
440 "InitializeSecurityContext set buffer size to %lu\n", out_buf->pBuffers[0].cbBuffer);
443 out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
445 ret = pInitializeSecurityContextA(sspi_data->cred, first?NULL:sspi_data->ctxt, NULL, req_attr,
446 0, data_rep, first?NULL:in_buf, 0, sspi_data->ctxt, out_buf,
449 if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
451 pCompleteAuthToken(sspi_data->ctxt, out_buf);
452 if(ret == SEC_I_COMPLETE_AND_CONTINUE)
453 ret = SEC_I_CONTINUE_NEEDED;
454 else if(ret == SEC_I_COMPLETE_NEEDED)
458 ok(out_buf->pBuffers[0].cbBuffer < sspi_data->max_token,
459 "InitializeSecurityContext set buffer size to %lu\n", out_buf->pBuffers[0].cbBuffer);
464 /**********************************************************************/
466 static SECURITY_STATUS runServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
472 trace("Running the server the %s time\n", first?"first":"second");
474 ret = pAcceptSecurityContext(sspi_data->cred, first?NULL:sspi_data->ctxt,
475 sspi_data->in_buf, 0, data_rep, sspi_data->ctxt,
476 sspi_data->out_buf, &ctxt_attr, &ttl);
478 if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
480 pCompleteAuthToken(sspi_data->ctxt, sspi_data->out_buf);
481 if(ret == SEC_I_COMPLETE_AND_CONTINUE)
482 ret = SEC_I_CONTINUE_NEEDED;
483 else if(ret == SEC_I_COMPLETE_NEEDED)
490 /**********************************************************************/
492 static SECURITY_STATUS runFakeServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
494 trace("Running the fake server the %s time\n", first?"first":"second");
498 sspi_data->out_buf->pBuffers[0].cbBuffer = 0;
502 if(data_rep == SECURITY_NATIVE_DREP)
504 sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(native_challenge);
505 memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, native_challenge,
506 sspi_data->out_buf->pBuffers[0].cbBuffer);
510 sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(network_challenge);
511 memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, network_challenge,
512 sspi_data->out_buf->pBuffers[0].cbBuffer);
515 return SEC_I_CONTINUE_NEEDED;
518 /**********************************************************************/
520 static void communicate(SspiData *from, SspiData *to)
522 if(from->out_buf != NULL && to->in_buf != NULL)
524 trace("Running communicate.\n");
525 if((from->out_buf->cBuffers >= 1) && (to->in_buf->cBuffers >= 1))
527 if((from->out_buf->pBuffers[0].pvBuffer != NULL) &&
528 (to->in_buf->pBuffers[0].pvBuffer != NULL))
530 memset(to->in_buf->pBuffers[0].pvBuffer, 0, to->max_token);
532 memcpy(to->in_buf->pBuffers[0].pvBuffer,
533 from->out_buf->pBuffers[0].pvBuffer,
534 from->out_buf->pBuffers[0].cbBuffer);
536 to->in_buf->pBuffers[0].cbBuffer = from->out_buf->pBuffers[0].cbBuffer;
538 memset(from->out_buf->pBuffers[0].pvBuffer, 0, from->max_token);
544 /**********************************************************************/
546 static void testAuth(ULONG data_rep, BOOL fake)
548 SECURITY_STATUS client_stat = SEC_I_CONTINUE_NEEDED;
549 SECURITY_STATUS server_stat = SEC_I_CONTINUE_NEEDED;
550 SECURITY_STATUS sec_status;
551 PSecPkgInfo pkg_info = NULL;
553 SspiData client, server;
554 SEC_WINNT_AUTH_IDENTITY id;
555 SecPkgContext_Sizes ctxt_sizes;
556 static char sec_pkg_name[] = "NTLM";
558 if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)== SEC_E_OK)
560 pFreeContextBuffer(pkg_info);
561 id.User = (unsigned char*) "testuser";
562 id.UserLength = strlen((char *) id.User);
563 id.Domain = (unsigned char *) "WORKGROUP";
564 id.DomainLength = strlen((char *) id.Domain);
565 id.Password = (unsigned char*) "testpass";
566 id.PasswordLength = strlen((char *) id.Password);
567 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
571 sec_status = setupClient(&client, sec_pkg_name);
573 if(sec_status != SEC_E_OK)
575 trace("Error: Setting up the client returned %s, exiting test!\n",
576 getSecError(sec_status));
577 pFreeCredentialsHandle(client.cred);
582 sec_status = setupFakeServer(&server, sec_pkg_name);
584 sec_status = setupServer(&server, sec_pkg_name);
586 if(sec_status != SEC_E_OK)
588 trace("Error: Setting up the server returned %s, exiting test!\n",
589 getSecError(sec_status));
590 pFreeCredentialsHandle(server.cred);
591 pFreeCredentialsHandle(client.cred);
596 while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
598 client_stat = runClient(&client, first, data_rep);
600 ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED,
601 "Running the client returned %s, more tests will fail.\n",
602 getSecError(client_stat));
604 communicate(&client, &server);
607 server_stat = runFakeServer(&server, first, data_rep);
609 server_stat = runServer(&server, first, data_rep);
611 ok(server_stat == SEC_E_OK || server_stat == SEC_I_CONTINUE_NEEDED ||
612 server_stat == SEC_E_LOGON_DENIED,
613 "Running the server returned %s, more tests will fail from now.\n",
614 getSecError(server_stat));
616 communicate(&server, &client);
621 if(client_stat == SEC_E_OK)
623 sec_status = pQueryContextAttributesA(client.ctxt,
624 SECPKG_ATTR_SIZES, &ctxt_sizes);
626 ok(sec_status == SEC_E_OK,
627 "pQueryContextAttributesA(SECPKG_ATTR_SIZES) returned %s\n",
628 getSecError(sec_status));
629 ok(ctxt_sizes.cbMaxToken == 1904,
630 "cbMaxToken should be 1904 but is %lu\n",
631 ctxt_sizes.cbMaxToken);
632 ok(ctxt_sizes.cbMaxSignature == 16,
633 "cbMaxSignature should be 16 but is %lu\n",
634 ctxt_sizes.cbMaxSignature);
635 ok(ctxt_sizes.cbSecurityTrailer == 16,
636 "cbSecurityTrailer should be 16 but is %lu\n",
637 ctxt_sizes.cbSecurityTrailer);
638 ok(ctxt_sizes.cbBlockSize == 0,
639 "cbBlockSize should be 0 but is %lu\n",
640 ctxt_sizes.cbBlockSize);
643 trace("Authentication failed, skipping test.\n");
645 cleanupBuffers(&client);
646 cleanupBuffers(&server);
650 sec_status = pDeleteSecurityContext(server.ctxt);
651 ok(sec_status == SEC_E_OK, "DeleteSecurityContext(server) returned %s\n",
652 getSecError(sec_status));
655 sec_status = pDeleteSecurityContext(client.ctxt);
656 ok(sec_status == SEC_E_OK, "DeleteSecurityContext(client) returned %s\n",
657 getSecError(sec_status));
661 sec_status = pFreeCredentialsHandle(server.cred);
662 ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(server) returned %s\n",
663 getSecError(sec_status));
666 sec_status = pFreeCredentialsHandle(client.cred);
667 ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(client) returned %s\n",
668 getSecError(sec_status));
672 trace("Package not installed, skipping test.\n");
676 static void testSignSeal()
678 SECURITY_STATUS client_stat = SEC_I_CONTINUE_NEEDED;
679 SECURITY_STATUS server_stat = SEC_I_CONTINUE_NEEDED;
680 SECURITY_STATUS sec_status;
681 PSecPkgInfo pkg_info = NULL;
683 SspiData client, server;
684 SEC_WINNT_AUTH_IDENTITY id;
685 static char sec_pkg_name[] = "NTLM";
687 SecBuffer data[2], fake_data[2], complex_data[4];
689 SecPkgContext_Sizes ctxt_sizes;
691 /****************************************************************
692 * This is basically the same as in testAuth with a fake server,
693 * as we need a valid, authenticated context.
695 if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)== SEC_E_OK)
697 pFreeContextBuffer(pkg_info);
698 id.User = (unsigned char*) "testuser";
699 id.UserLength = strlen((char *) id.User);
700 id.Domain = (unsigned char *) "WORKGROUP";
701 id.DomainLength = strlen((char *) id.Domain);
702 id.Password = (unsigned char*) "testpass";
703 id.PasswordLength = strlen((char *) id.Password);
704 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
708 sec_status = setupClient(&client, sec_pkg_name);
710 if(sec_status != SEC_E_OK)
712 trace("Error: Setting up the client returned %s, exiting test!\n",
713 getSecError(sec_status));
714 pFreeCredentialsHandle(client.cred);
718 sec_status = setupFakeServer(&server, sec_pkg_name);
720 while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
722 client_stat = runClient(&client, first, SECURITY_NETWORK_DREP);
724 communicate(&client, &server);
726 server_stat = runFakeServer(&server, first, SECURITY_NETWORK_DREP);
728 communicate(&server, &client);
733 /********************************************
734 * Now start with the actual testing *
735 ********************************************/
737 if(pQueryContextAttributesA(client.ctxt, SECPKG_ATTR_SIZES,
738 &ctxt_sizes) != SEC_E_OK)
740 trace("Failed to get context sizes, aborting test.\n");
744 crypt.ulVersion = SECBUFFER_VERSION;
747 crypt.pBuffers = fake_data;
749 fake_data[0].BufferType = SECBUFFER_DATA;
750 fake_data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
751 fake_data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[0].cbBuffer);
753 fake_data[1].BufferType = SECBUFFER_DATA;
754 fake_data[1].cbBuffer = lstrlen(message);
755 fake_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[1].cbBuffer);
757 sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
758 ok(sec_status == SEC_E_INVALID_TOKEN,
759 "MakeSignature returned %s, not SEC_E_INVALID_TOKEN.\n",
760 getSecError(sec_status));
762 crypt.pBuffers = data;
764 data[0].BufferType = SECBUFFER_TOKEN;
765 data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
766 data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[0].cbBuffer);
768 data[1].BufferType = SECBUFFER_DATA;
769 data[1].cbBuffer = lstrlen(message);
770 data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
771 memcpy(data[1].pvBuffer, message, data[1].cbBuffer);
773 /* As we forced NTLM to fall back to a password-derived session key,
774 * we should get the same signature for our data, no matter if
775 * it is sent by the client or the server
777 sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
778 ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
779 getSecError(sec_status));
780 ok(!memcmp(crypt.pBuffers[0].pvBuffer, message_signature,
781 crypt.pBuffers[0].cbBuffer), "Signature is not as expected.\n");
783 data[0].cbBuffer = sizeof(message_signature);
785 memcpy(data[0].pvBuffer, crypt_trailer_client, data[0].cbBuffer);
787 sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
788 ok(sec_status == SEC_E_MESSAGE_ALTERED,
789 "VerifySignature returned %s, not SEC_E_MESSAGE_ALTERED.\n",
790 getSecError(sec_status));
792 memcpy(data[0].pvBuffer, message_signature, data[0].cbBuffer);
794 sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
795 ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK.\n",
796 getSecError(sec_status));
798 sec_status = pEncryptMessage(client.ctxt, 0, &crypt, 0);
799 ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
800 getSecError(sec_status));
802 ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client,
803 crypt.pBuffers[0].cbBuffer), "Crypt trailer not as expected.\n");
804 ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
805 crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
807 data[0].cbBuffer = sizeof(crypt_trailer_server);
808 data[1].cbBuffer = sizeof(crypt_message_server);
809 memcpy(data[0].pvBuffer, crypt_trailer_server, data[0].cbBuffer);
810 memcpy(data[1].pvBuffer, crypt_message_server, data[1].cbBuffer);
812 sec_status = pDecryptMessage(client.ctxt, &crypt, 0, &qop);
814 ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
815 getSecError(sec_status));
816 ok(!memcmp(crypt.pBuffers[1].pvBuffer, message_binary,
817 crypt.pBuffers[1].cbBuffer),
818 "Failed to decrypt message correctly.\n");
820 trace("Testing with more than one buffer.\n");
822 crypt.cBuffers = sizeof(complex_data)/sizeof(complex_data[0]);
823 crypt.pBuffers = complex_data;
825 complex_data[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
826 complex_data[0].cbBuffer = sizeof(message_header);
827 complex_data[0].pvBuffer = message_header;
829 complex_data[1].BufferType = SECBUFFER_DATA;
830 complex_data[1].cbBuffer = lstrlen(message);
831 complex_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
832 memcpy(complex_data[1].pvBuffer, message, complex_data[1].cbBuffer);
834 complex_data[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
835 complex_data[2].cbBuffer = sizeof(message_header);
836 complex_data[2].pvBuffer = message_header;
838 complex_data[3].BufferType = SECBUFFER_TOKEN;
839 complex_data[3].cbBuffer = ctxt_sizes.cbSecurityTrailer;
840 complex_data[3].pvBuffer = HeapAlloc(GetProcessHeap(), 0, complex_data[3].cbBuffer);
842 /* We should get a dummy signature again. */
843 sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
844 ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
845 getSecError(sec_status));
846 ok(!memcmp(crypt.pBuffers[3].pvBuffer, message_signature,
847 crypt.pBuffers[3].cbBuffer), "Signature is not as expected.\n");
849 sec_status = pEncryptMessage(client.ctxt, 0, &crypt, 0);
850 ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
851 getSecError(sec_status));
853 ok(!memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
854 crypt.pBuffers[3].cbBuffer), "Crypt trailer not as expected.\n");
856 ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
857 crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
860 cleanupBuffers(&client);
861 cleanupBuffers(&server);
863 pDeleteSecurityContext(client.ctxt);
864 pFreeCredentialsHandle(client.cred);
866 HeapFree(GetProcessHeap(), 0, fake_data[0].pvBuffer);
867 HeapFree(GetProcessHeap(), 0, fake_data[1].pvBuffer);
868 HeapFree(GetProcessHeap(), 0, data[0].pvBuffer);
869 HeapFree(GetProcessHeap(), 0, data[1].pvBuffer);
873 trace("Package not installed, skipping test.\n");
881 if(pFreeCredentialsHandle && pDeleteSecurityContext &&
882 pDeleteSecurityContext && pAcquireCredentialsHandleA &&
883 pInitializeSecurityContextA && pCompleteAuthToken &&
884 pQuerySecurityPackageInfoA)
886 if(pAcceptSecurityContext)
888 testAuth(SECURITY_NATIVE_DREP, TRUE);
889 testAuth(SECURITY_NETWORK_DREP, TRUE);
890 testAuth(SECURITY_NATIVE_DREP, FALSE);
891 testAuth(SECURITY_NETWORK_DREP, FALSE);
893 if(pMakeSignature && pVerifySignature && pEncryptMessage &&