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 BYTE crypt_trailer_client[] =
115 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xc7,
116 0xaa, 0x26, 0x16, 0x39, 0x07, 0x4e};
118 static BYTE crypt_message_client[] =
119 {0x86, 0x9c, 0x5a, 0x10, 0x78, 0xb3, 0x30, 0x98, 0x46, 0x15,
122 static BYTE crypt_trailer_server[] =
123 {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x46,
124 0x2e, 0x77, 0xeb, 0xf0, 0xf6, 0x9e};
126 static BYTE crypt_message_server[] =
127 {0xf6, 0xb7, 0x92, 0x0c, 0xac, 0xea, 0x98, 0xe6, 0xef, 0xa0,
130 static void InitFunctionPtrs(void)
132 secdll = LoadLibraryA("secur32.dll");
134 secdll = LoadLibraryA("security.dll");
137 pInitSecurityInterfaceA = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceA");
138 pFreeContextBuffer = (PVOID)GetProcAddress(secdll, "FreeContextBuffer");
139 pQuerySecurityPackageInfoA = (PVOID)GetProcAddress(secdll, "QuerySecurityPackageInfoA");
140 pAcquireCredentialsHandleA = (PVOID)GetProcAddress(secdll, "AcquireCredentialsHandleA");
141 pInitializeSecurityContextA = (PVOID)GetProcAddress(secdll, "InitializeSecurityContextA");
142 pCompleteAuthToken = (PVOID)GetProcAddress(secdll, "CompleteAuthToken");
143 pAcceptSecurityContext = (PVOID)GetProcAddress(secdll, "AcceptSecurityContext");
144 pFreeCredentialsHandle = (PVOID)GetProcAddress(secdll, "FreeCredentialsHandle");
145 pDeleteSecurityContext = (PVOID)GetProcAddress(secdll, "DeleteSecurityContext");
146 pQueryContextAttributesA = (PVOID)GetProcAddress(secdll, "QueryContextAttributesA");
147 pMakeSignature = (PVOID)GetProcAddress(secdll, "MakeSignature");
148 pVerifySignature = (PVOID)GetProcAddress(secdll, "VerifySignature");
149 pEncryptMessage = (PVOID)GetProcAddress(secdll, "EncryptMessage");
150 pDecryptMessage = (PVOID)GetProcAddress(secdll, "DecryptMessage");
154 static const char* getSecError(SECURITY_STATUS status)
158 #define _SEC_ERR(x) case (x): return #x;
162 _SEC_ERR(SEC_E_INSUFFICIENT_MEMORY);
163 _SEC_ERR(SEC_E_INVALID_HANDLE);
164 _SEC_ERR(SEC_E_UNSUPPORTED_FUNCTION);
165 _SEC_ERR(SEC_E_TARGET_UNKNOWN);
166 _SEC_ERR(SEC_E_INTERNAL_ERROR);
167 _SEC_ERR(SEC_E_SECPKG_NOT_FOUND);
168 _SEC_ERR(SEC_E_NOT_OWNER);
169 _SEC_ERR(SEC_E_CANNOT_INSTALL);
170 _SEC_ERR(SEC_E_INVALID_TOKEN);
171 _SEC_ERR(SEC_E_CANNOT_PACK);
172 _SEC_ERR(SEC_E_QOP_NOT_SUPPORTED);
173 _SEC_ERR(SEC_E_NO_IMPERSONATION);
174 _SEC_ERR(SEC_I_CONTINUE_NEEDED);
175 _SEC_ERR(SEC_E_BUFFER_TOO_SMALL);
176 _SEC_ERR(SEC_E_ILLEGAL_MESSAGE);
177 _SEC_ERR(SEC_E_LOGON_DENIED);
178 _SEC_ERR(SEC_E_NO_CREDENTIALS);
179 _SEC_ERR(SEC_E_OUT_OF_SEQUENCE);
180 _SEC_ERR(SEC_E_MESSAGE_ALTERED);
182 sprintf(buf, "%08lx\n", status);
188 /**********************************************************************/
190 static SECURITY_STATUS setupBuffers(SspiData *sspi_data, SecPkgInfoA *sec_pkg_info)
193 sspi_data->in_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
194 sspi_data->out_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
195 sspi_data->max_token = sec_pkg_info->cbMaxToken;
197 if(sspi_data->in_buf != NULL)
199 PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
201 if(sec_buffer == NULL){
202 trace("in_buf: sec_buffer == NULL\n");
203 return SEC_E_INSUFFICIENT_MEMORY;
206 sspi_data->in_buf->ulVersion = SECBUFFER_VERSION;
207 sspi_data->in_buf->cBuffers = 1;
208 sspi_data->in_buf->pBuffers = sec_buffer;
210 sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
211 sec_buffer->BufferType = SECBUFFER_TOKEN;
212 if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0,
213 sec_pkg_info->cbMaxToken)) == NULL)
215 trace("in_buf: sec_buffer->pvBuffer == NULL\n");
216 return SEC_E_INSUFFICIENT_MEMORY;
221 trace("HeapAlloc in_buf returned NULL\n");
222 return SEC_E_INSUFFICIENT_MEMORY;
225 if(sspi_data->out_buf != NULL)
227 PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
230 if(sec_buffer == NULL){
231 trace("out_buf: sec_buffer == NULL\n");
232 return SEC_E_INSUFFICIENT_MEMORY;
235 sspi_data->out_buf->ulVersion = SECBUFFER_VERSION;
236 sspi_data->out_buf->cBuffers = 1;
237 sspi_data->out_buf->pBuffers = sec_buffer;
239 sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
240 sec_buffer->BufferType = SECBUFFER_TOKEN;
241 if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0,
242 sec_pkg_info->cbMaxToken)) == NULL){
243 trace("out_buf: sec_buffer->pvBuffer == NULL\n");
244 return SEC_E_INSUFFICIENT_MEMORY;
249 trace("HeapAlloc out_buf returned NULL\n");
250 return SEC_E_INSUFFICIENT_MEMORY;
256 /**********************************************************************/
258 static void cleanupBuffers(SspiData *sspi_data)
262 if(sspi_data->in_buf != NULL)
264 for(i = 0; i < sspi_data->in_buf->cBuffers; ++i)
266 HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers[i].pvBuffer);
268 HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers);
269 HeapFree(GetProcessHeap(), 0, sspi_data->in_buf);
272 if(sspi_data->out_buf != NULL)
274 for(i = 0; i < sspi_data->out_buf->cBuffers; ++i)
276 HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers[i].pvBuffer);
278 HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers);
279 HeapFree(GetProcessHeap(), 0, sspi_data->out_buf);
283 /**********************************************************************/
285 static SECURITY_STATUS setupClient(SspiData *sspi_data, SEC_CHAR *provider)
289 SecPkgInfoA *sec_pkg_info;
291 trace("Running setupClient\n");
293 sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
294 sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
296 ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
298 ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
300 setupBuffers(sspi_data, sec_pkg_info);
302 if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_OUTBOUND,
303 NULL, sspi_data->id, NULL, NULL, sspi_data->cred, &ttl))
306 trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
309 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
314 /**********************************************************************/
316 static SECURITY_STATUS setupServer(SspiData *sspi_data, SEC_CHAR *provider)
320 SecPkgInfoA *sec_pkg_info;
322 trace("Running setupServer\n");
324 sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
325 sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
327 ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
329 ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
331 setupBuffers(sspi_data, sec_pkg_info);
333 if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_INBOUND,
334 NULL, NULL, NULL, NULL, sspi_data->cred, &ttl)) != SEC_E_OK)
336 trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
339 ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
345 /**********************************************************************/
347 static SECURITY_STATUS setupFakeServer(SspiData *sspi_data, SEC_CHAR *provider)
350 SecPkgInfoA *sec_pkg_info;
352 trace("Running setupFakeServer\n");
354 sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
355 sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
357 ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
359 ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
361 ret = setupBuffers(sspi_data, sec_pkg_info);
367 /**********************************************************************/
369 static SECURITY_STATUS runClient(SspiData *sspi_data, BOOL first, ULONG data_rep)
375 PSecBufferDesc in_buf = sspi_data->in_buf;
376 PSecBufferDesc out_buf = sspi_data->out_buf;
378 assert(in_buf->cBuffers >= 1);
379 assert(in_buf->pBuffers[0].pvBuffer != NULL);
380 assert(in_buf->pBuffers[0].cbBuffer != 0);
382 assert(out_buf->cBuffers >= 1);
383 assert(out_buf->pBuffers[0].pvBuffer != NULL);
384 assert(out_buf->pBuffers[0].cbBuffer != 0);
386 trace("Running the client the %s time.\n", first?"first":"second");
388 /* We can either use ISC_REQ_ALLOCATE_MEMORY flag to ask the provider
389 * always allocate output buffers for us, or initialize cbBuffer
390 * before each call because the API changes it to represent actual
391 * amount of data in the buffer.
394 /* test a failing call only the first time, otherwise we get
395 * SEC_E_OUT_OF_SEQUENCE
401 /* pass NULL as an output buffer */
402 ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
403 0, data_rep, NULL, 0, sspi_data->ctxt, NULL,
406 ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
408 /* pass NULL as an output buffer */
409 old_buf = out_buf->pBuffers[0].pvBuffer;
410 out_buf->pBuffers[0].pvBuffer = NULL;
412 ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
413 0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
416 ok(ret == SEC_E_INTERNAL_ERROR, "expected SEC_E_INTERNAL_ERROR, got %s\n", getSecError(ret));
418 out_buf->pBuffers[0].pvBuffer = old_buf;
420 /* pass an output buffer of 0 size */
421 out_buf->pBuffers[0].cbBuffer = 0;
423 ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
424 0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
427 ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
429 ok(out_buf->pBuffers[0].cbBuffer == 0,
430 "InitializeSecurityContext set buffer size to %lu\n", out_buf->pBuffers[0].cbBuffer);
433 out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
435 ret = pInitializeSecurityContextA(sspi_data->cred, first?NULL:sspi_data->ctxt, NULL, req_attr,
436 0, data_rep, first?NULL:in_buf, 0, sspi_data->ctxt, out_buf,
439 if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
441 pCompleteAuthToken(sspi_data->ctxt, out_buf);
442 if(ret == SEC_I_COMPLETE_AND_CONTINUE)
443 ret = SEC_I_CONTINUE_NEEDED;
444 else if(ret == SEC_I_COMPLETE_NEEDED)
448 ok(out_buf->pBuffers[0].cbBuffer < sspi_data->max_token,
449 "InitializeSecurityContext set buffer size to %lu\n", out_buf->pBuffers[0].cbBuffer);
454 /**********************************************************************/
456 static SECURITY_STATUS runServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
462 trace("Running the server the %s time\n", first?"first":"second");
464 ret = pAcceptSecurityContext(sspi_data->cred, first?NULL:sspi_data->ctxt,
465 sspi_data->in_buf, 0, data_rep, sspi_data->ctxt,
466 sspi_data->out_buf, &ctxt_attr, &ttl);
468 if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
470 pCompleteAuthToken(sspi_data->ctxt, sspi_data->out_buf);
471 if(ret == SEC_I_COMPLETE_AND_CONTINUE)
472 ret = SEC_I_CONTINUE_NEEDED;
473 else if(ret == SEC_I_COMPLETE_NEEDED)
480 /**********************************************************************/
482 static SECURITY_STATUS runFakeServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
484 trace("Running the fake server the %s time\n", first?"first":"second");
488 sspi_data->out_buf->pBuffers[0].cbBuffer = 0;
492 if(data_rep == SECURITY_NATIVE_DREP)
494 sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(native_challenge);
495 memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, native_challenge,
496 sspi_data->out_buf->pBuffers[0].cbBuffer);
500 sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(network_challenge);
501 memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, network_challenge,
502 sspi_data->out_buf->pBuffers[0].cbBuffer);
505 return SEC_I_CONTINUE_NEEDED;
508 /**********************************************************************/
510 static void communicate(SspiData *from, SspiData *to)
512 if(from->out_buf != NULL && to->in_buf != NULL)
514 trace("Running communicate.\n");
515 if((from->out_buf->cBuffers >= 1) && (to->in_buf->cBuffers >= 1))
517 if((from->out_buf->pBuffers[0].pvBuffer != NULL) &&
518 (to->in_buf->pBuffers[0].pvBuffer != NULL))
520 memset(to->in_buf->pBuffers[0].pvBuffer, 0, to->max_token);
522 memcpy(to->in_buf->pBuffers[0].pvBuffer,
523 from->out_buf->pBuffers[0].pvBuffer,
524 from->out_buf->pBuffers[0].cbBuffer);
526 to->in_buf->pBuffers[0].cbBuffer = from->out_buf->pBuffers[0].cbBuffer;
528 memset(from->out_buf->pBuffers[0].pvBuffer, 0, from->max_token);
534 /**********************************************************************/
536 static void testAuth(ULONG data_rep, BOOL fake)
538 SECURITY_STATUS client_stat = SEC_I_CONTINUE_NEEDED;
539 SECURITY_STATUS server_stat = SEC_I_CONTINUE_NEEDED;
540 SECURITY_STATUS sec_status;
541 PSecPkgInfo pkg_info = NULL;
543 SspiData client, server;
544 SEC_WINNT_AUTH_IDENTITY id;
545 SecPkgContext_Sizes ctxt_sizes;
546 static char sec_pkg_name[] = "NTLM";
548 if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)== SEC_E_OK)
550 pFreeContextBuffer(pkg_info);
551 id.User = (unsigned char*) "testuser";
552 id.UserLength = strlen((char *) id.User);
553 id.Domain = (unsigned char *) "WORKGROUP";
554 id.DomainLength = strlen((char *) id.Domain);
555 id.Password = (unsigned char*) "testpass";
556 id.PasswordLength = strlen((char *) id.Password);
557 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
561 sec_status = setupClient(&client, sec_pkg_name);
563 if(sec_status != SEC_E_OK)
565 trace("Error: Setting up the client returned %s, exiting test!\n",
566 getSecError(sec_status));
567 pFreeCredentialsHandle(client.cred);
572 sec_status = setupFakeServer(&server, sec_pkg_name);
574 sec_status = setupServer(&server, sec_pkg_name);
576 if(sec_status != SEC_E_OK)
578 trace("Error: Setting up the server returned %s, exiting test!\n",
579 getSecError(sec_status));
580 pFreeCredentialsHandle(server.cred);
581 pFreeCredentialsHandle(client.cred);
586 while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
588 client_stat = runClient(&client, first, data_rep);
590 ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED,
591 "Running the client returned %s, more tests will fail.\n",
592 getSecError(client_stat));
594 communicate(&client, &server);
597 server_stat = runFakeServer(&server, first, data_rep);
599 server_stat = runServer(&server, first, data_rep);
601 ok(server_stat == SEC_E_OK || server_stat == SEC_I_CONTINUE_NEEDED ||
602 server_stat == SEC_E_LOGON_DENIED,
603 "Running the server returned %s, more tests will fail from now.\n",
604 getSecError(server_stat));
606 communicate(&server, &client);
611 if(client_stat == SEC_E_OK)
613 sec_status = pQueryContextAttributesA(client.ctxt,
614 SECPKG_ATTR_SIZES, &ctxt_sizes);
616 ok(sec_status == SEC_E_OK,
617 "pQueryContextAttributesA(SECPKG_ATTR_SIZES) returned %s\n",
618 getSecError(sec_status));
619 ok(ctxt_sizes.cbMaxToken == 1904,
620 "cbMaxToken should be 1904 but is %lu\n",
621 ctxt_sizes.cbMaxToken);
622 ok(ctxt_sizes.cbMaxSignature == 16,
623 "cbMaxSignature should be 16 but is %lu\n",
624 ctxt_sizes.cbMaxSignature);
625 ok(ctxt_sizes.cbSecurityTrailer == 16,
626 "cbSecurityTrailer should be 16 but is %lu\n",
627 ctxt_sizes.cbSecurityTrailer);
628 ok(ctxt_sizes.cbBlockSize == 0,
629 "cbBlockSize should be 0 but is %lu\n",
630 ctxt_sizes.cbBlockSize);
633 trace("Authentication failed, skipping test.\n");
635 cleanupBuffers(&client);
636 cleanupBuffers(&server);
640 sec_status = pDeleteSecurityContext(server.ctxt);
641 ok(sec_status == SEC_E_OK, "DeleteSecurityContext(server) returned %s\n",
642 getSecError(sec_status));
645 sec_status = pDeleteSecurityContext(client.ctxt);
646 ok(sec_status == SEC_E_OK, "DeleteSecurityContext(client) returned %s\n",
647 getSecError(sec_status));
651 sec_status = pFreeCredentialsHandle(server.cred);
652 ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(server) returned %s\n",
653 getSecError(sec_status));
656 sec_status = pFreeCredentialsHandle(client.cred);
657 ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(client) returned %s\n",
658 getSecError(sec_status));
662 trace("Package not installed, skipping test.\n");
666 static void testSignSeal()
668 SECURITY_STATUS client_stat = SEC_I_CONTINUE_NEEDED;
669 SECURITY_STATUS server_stat = SEC_I_CONTINUE_NEEDED;
670 SECURITY_STATUS sec_status;
671 PSecPkgInfo pkg_info = NULL;
673 SspiData client, server;
674 SEC_WINNT_AUTH_IDENTITY id;
675 static char sec_pkg_name[] = "NTLM";
676 PSecBufferDesc crypt = NULL;
677 PSecBuffer data = NULL, fake_data = NULL;
679 SecPkgContext_Sizes ctxt_sizes;
681 /****************************************************************
682 * This is basically the same as in testAuth with a fake server,
683 * as we need a valid, authenticated context.
685 if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)== SEC_E_OK)
687 pFreeContextBuffer(pkg_info);
688 id.User = (unsigned char*) "testuser";
689 id.UserLength = strlen((char *) id.User);
690 id.Domain = (unsigned char *) "WORKGROUP";
691 id.DomainLength = strlen((char *) id.Domain);
692 id.Password = (unsigned char*) "testpass";
693 id.PasswordLength = strlen((char *) id.Password);
694 id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
698 sec_status = setupClient(&client, sec_pkg_name);
700 if(sec_status != SEC_E_OK)
702 trace("Error: Setting up the client returned %s, exiting test!\n",
703 getSecError(sec_status));
704 pFreeCredentialsHandle(client.cred);
708 sec_status = setupFakeServer(&server, sec_pkg_name);
710 while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
712 client_stat = runClient(&client, first, SECURITY_NETWORK_DREP);
714 communicate(&client, &server);
716 server_stat = runFakeServer(&server, first, SECURITY_NETWORK_DREP);
718 communicate(&server, &client);
723 /********************************************
724 * Now start with the actual testing *
725 ********************************************/
727 if(pQueryContextAttributesA(client.ctxt, SECPKG_ATTR_SIZES,
728 &ctxt_sizes) != SEC_E_OK)
730 trace("Failed to get context sizes, aborting test.\n");
734 if((crypt = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc))) == NULL)
736 trace("Failed to allocate the crypto buffer, aborting test.\n");
740 crypt->ulVersion = SECBUFFER_VERSION;
743 if((fake_data = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBuffer) * 2)) == NULL)
745 trace("Failed to allocate the fake crypto buffer, aborting test.\n");
749 crypt->pBuffers = fake_data;
751 fake_data[0].BufferType = SECBUFFER_DATA;
752 fake_data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
753 fake_data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[0].cbBuffer);
755 fake_data[1].BufferType = SECBUFFER_DATA;
756 fake_data[1].cbBuffer = lstrlen(message);
757 fake_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[1].cbBuffer);
759 sec_status = pMakeSignature(client.ctxt, 0, crypt, 0);
760 ok(sec_status == SEC_E_INVALID_TOKEN,
761 "MakeSignature returned %s, not SEC_E_INVALID_TOKEN.\n",
762 getSecError(sec_status));
765 if((data = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBuffer) * 2)) == NULL)
767 trace("Failed to allocate the crypto buffer, aborting test.\n");
771 crypt->pBuffers = data;
773 data[0].BufferType = SECBUFFER_TOKEN;
774 data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
775 data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[0].cbBuffer);
777 data[1].BufferType = SECBUFFER_DATA;
778 data[1].cbBuffer = lstrlen(message);
779 data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
780 memcpy(data[1].pvBuffer, message, data[1].cbBuffer);
782 /* As we forced NTLM to fall back to a password-derived session key,
783 * we should get the same signature for our data, no matter if
784 * it is sent by the client or the server
786 sec_status = pMakeSignature(client.ctxt, 0, crypt, 0);
787 ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
788 getSecError(sec_status));
789 ok(!memcmp(crypt->pBuffers[0].pvBuffer, message_signature,
790 crypt->pBuffers[0].cbBuffer), "Signature is not as expected.\n");
792 data[0].cbBuffer = sizeof(message_signature);
794 memcpy(data[0].pvBuffer, crypt_trailer_client, data[0].cbBuffer);
796 sec_status = pVerifySignature(client.ctxt, crypt, 0, &qop);
797 ok(sec_status == SEC_E_MESSAGE_ALTERED,
798 "VerifySignature returned %s, not SEC_E_MESSAGE_ALTERED.\n",
799 getSecError(sec_status));
801 memcpy(data[0].pvBuffer, message_signature, data[0].cbBuffer);
803 sec_status = pVerifySignature(client.ctxt, crypt, 0, &qop);
804 ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK.\n",
805 getSecError(sec_status));
807 sec_status = pEncryptMessage(client.ctxt, 0, crypt, 0);
808 ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
809 getSecError(sec_status));
811 ok(!memcmp(crypt->pBuffers[0].pvBuffer, crypt_trailer_client,
812 crypt->pBuffers[0].cbBuffer), "Crypt trailer not as expected.\n");
813 ok(!memcmp(crypt->pBuffers[1].pvBuffer, crypt_message_client,
814 crypt->pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
816 data[0].cbBuffer = sizeof(crypt_trailer_server);
817 data[1].cbBuffer = sizeof(crypt_message_server);
818 memcpy(data[0].pvBuffer, crypt_trailer_server, data[0].cbBuffer);
819 memcpy(data[1].pvBuffer, crypt_message_server, data[1].cbBuffer);
821 sec_status = pDecryptMessage(client.ctxt, crypt, 0, &qop);
823 ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
824 getSecError(sec_status));
825 ok(!memcmp(crypt->pBuffers[1].pvBuffer, message_binary,
826 crypt->pBuffers[1].cbBuffer),
827 "Failed to decrypt message correctly.\n");
830 cleanupBuffers(&client);
831 cleanupBuffers(&server);
833 pDeleteSecurityContext(client.ctxt);
834 pFreeCredentialsHandle(client.cred);
837 HeapFree(GetProcessHeap(), 0, fake_data[0].pvBuffer);
838 HeapFree(GetProcessHeap(), 0, fake_data[1].pvBuffer);
842 HeapFree(GetProcessHeap(), 0, data[0].pvBuffer);
843 HeapFree(GetProcessHeap(), 0, data[1].pvBuffer);
845 HeapFree(GetProcessHeap(), 0, data);
846 HeapFree(GetProcessHeap(), 0, crypt);
850 trace("Package not installed, skipping test.\n");
858 if(pFreeCredentialsHandle && pDeleteSecurityContext &&
859 pDeleteSecurityContext && pAcquireCredentialsHandleA &&
860 pInitializeSecurityContextA && pCompleteAuthToken &&
861 pQuerySecurityPackageInfoA)
863 if(pAcceptSecurityContext)
865 testAuth(SECURITY_NATIVE_DREP, TRUE);
866 testAuth(SECURITY_NETWORK_DREP, TRUE);
867 testAuth(SECURITY_NATIVE_DREP, FALSE);
868 testAuth(SECURITY_NETWORK_DREP, FALSE);
870 if(pMakeSignature && pVerifySignature && pEncryptMessage &&