| /* | |
| * Tests for the NTLM security provider | |
| * | |
| * Copyright 2005, 2006 Kai Blin | |
| * Copyright 2006 Dmitry Timoshkov | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
| * | |
| * The code that tests for the behaviour of ISC_REQ_ALLOCATE_MEMORY is based | |
| * on code written by Dmitry Timoshkov. | |
| */ | |
| #include <stdarg.h> | |
| #include <stdio.h> | |
| #include <assert.h> | |
| #include <windef.h> | |
| #include <winbase.h> | |
| #define SECURITY_WIN32 | |
| #include <sspi.h> | |
| #include <rpc.h> | |
| #include <rpcdce.h> | |
| #include <secext.h> | |
| #include "wine/test.h" | |
| static HMODULE secdll; | |
| static PSecurityFunctionTableA (SEC_ENTRY * pInitSecurityInterfaceA)(void); | |
| static SECURITY_STATUS (SEC_ENTRY * pFreeContextBuffer)(PVOID pv); | |
| static SECURITY_STATUS (SEC_ENTRY * pQuerySecurityPackageInfoA)(SEC_CHAR*, PSecPkgInfoA*); | |
| static SECURITY_STATUS (SEC_ENTRY * pAcquireCredentialsHandleA)(SEC_CHAR*, SEC_CHAR*, | |
| ULONG, PLUID, PVOID, SEC_GET_KEY_FN, PVOID, PCredHandle, PTimeStamp); | |
| static SECURITY_STATUS (SEC_ENTRY * pAcquireCredentialsHandleW)(SEC_CHAR*, SEC_WCHAR*, | |
| ULONG, PLUID, void*, SEC_GET_KEY_FN, void*, CredHandle*, TimeStamp*); | |
| static SECURITY_STATUS (SEC_ENTRY * pInitializeSecurityContextA)(PCredHandle, PCtxtHandle, | |
| SEC_CHAR*, ULONG, ULONG, ULONG, PSecBufferDesc, ULONG, | |
| PCtxtHandle, PSecBufferDesc, PULONG, PTimeStamp); | |
| static SECURITY_STATUS (SEC_ENTRY * pCompleteAuthToken)(PCtxtHandle, PSecBufferDesc); | |
| static SECURITY_STATUS (SEC_ENTRY * pAcceptSecurityContext)(PCredHandle, PCtxtHandle, | |
| PSecBufferDesc, ULONG, ULONG, PCtxtHandle, PSecBufferDesc, | |
| PULONG, PTimeStamp); | |
| static SECURITY_STATUS (SEC_ENTRY * pFreeCredentialsHandle)(PCredHandle); | |
| static SECURITY_STATUS (SEC_ENTRY * pDeleteSecurityContext)(PCtxtHandle); | |
| static SECURITY_STATUS (SEC_ENTRY * pQueryContextAttributesA)(PCtxtHandle, ULONG, PVOID); | |
| static SECURITY_STATUS (SEC_ENTRY * pMakeSignature)(PCtxtHandle, ULONG, | |
| PSecBufferDesc, ULONG); | |
| static SECURITY_STATUS (SEC_ENTRY * pVerifySignature)(PCtxtHandle, PSecBufferDesc, | |
| ULONG, PULONG); | |
| static SECURITY_STATUS (SEC_ENTRY * pEncryptMessage)(PCtxtHandle, ULONG, | |
| PSecBufferDesc, ULONG); | |
| static SECURITY_STATUS (SEC_ENTRY * pDecryptMessage)(PCtxtHandle, PSecBufferDesc, | |
| ULONG, PULONG); | |
| static BOOLEAN (WINAPI * pGetUserNameExA)(EXTENDED_NAME_FORMAT, LPSTR, PULONG); | |
| typedef struct _SspiData { | |
| CredHandle cred; | |
| CtxtHandle ctxt; | |
| PSecBufferDesc in_buf; | |
| PSecBufferDesc out_buf; | |
| PSEC_WINNT_AUTH_IDENTITY_A id; | |
| ULONG max_token; | |
| } SspiData; | |
| static BYTE network_challenge[] = | |
| {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00, | |
| 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00, | |
| 0x05, 0x82, 0x82, 0xa0, 0xe9, 0x58, 0x7f, 0x14, 0xa2, 0x86, | |
| 0x3b, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00, | |
| 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, | |
| 0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00, | |
| 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, | |
| 0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00, | |
| 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, | |
| 0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00, | |
| 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00, | |
| 0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00, | |
| 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00, | |
| 0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00}; | |
| static BYTE native_challenge[] = | |
| {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00, | |
| 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00, | |
| 0x05, 0x82, 0x82, 0xa0, 0xb5, 0x60, 0x8e, 0x95, 0xb5, 0x3c, | |
| 0xee, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00, | |
| 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, | |
| 0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00, | |
| 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, | |
| 0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00, | |
| 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, | |
| 0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00, | |
| 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00, | |
| 0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00, | |
| 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00, | |
| 0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00}; | |
| static BYTE message_signature[] = | |
| {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | |
| static BYTE message_binary[] = | |
| {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, | |
| 0x6c, 0x64, 0x21}; | |
| static const char message[] = "Hello, world!"; | |
| static char message_header[] = "Header Test"; | |
| static BYTE crypt_trailer_client[] = | |
| {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xc7, | |
| 0xaa, 0x26, 0x16, 0x39, 0x07, 0x4e}; | |
| static BYTE crypt_message_client[] = | |
| {0x86, 0x9c, 0x5a, 0x10, 0x78, 0xb3, 0x30, 0x98, 0x46, 0x15, | |
| 0xa0, 0x31, 0xd9}; | |
| static BYTE crypt_trailer_client2[] = | |
| {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0xa7, | |
| 0xf7, 0x0f, 0x5b, 0x25, 0xbe, 0xa4}; | |
| static BYTE crypt_message_client2[] = | |
| {0x20, 0x6c, 0x01, 0xab, 0xb0, 0x4c, 0x93, 0xe4, 0x1e, 0xfc, | |
| 0xe1, 0xfa, 0xfe}; | |
| static BYTE crypt_trailer_server[] = | |
| {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x46, | |
| 0x2e, 0x77, 0xeb, 0xf0, 0xf6, 0x9e}; | |
| static BYTE crypt_message_server[] = | |
| {0xf6, 0xb7, 0x92, 0x0c, 0xac, 0xea, 0x98, 0xe6, 0xef, 0xa0, | |
| 0x29, 0x66, 0xfd}; | |
| static BYTE crypt_trailer_server2[] = | |
| {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x4e, | |
| 0x46, 0xb7, 0xca, 0xf7, 0x7f, 0xb3}; | |
| static BYTE crypt_message_server2[] = | |
| {0xc8, 0xf2, 0x39, 0x7f, 0x0c, 0xaf, 0xf5, 0x5d, 0xef, 0x0c, | |
| 0x8b, 0x5f, 0x82}; | |
| static char test_user[] = "testuser", | |
| workgroup[] = "WORKGROUP", | |
| test_pass[] = "testpass", | |
| sec_pkg_name[] = "NTLM"; | |
| static void InitFunctionPtrs(void) | |
| { | |
| secdll = LoadLibraryA("secur32.dll"); | |
| if(!secdll) | |
| secdll = LoadLibraryA("security.dll"); | |
| if(secdll) | |
| { | |
| pInitSecurityInterfaceA = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceA"); | |
| pFreeContextBuffer = (PVOID)GetProcAddress(secdll, "FreeContextBuffer"); | |
| pQuerySecurityPackageInfoA = (PVOID)GetProcAddress(secdll, "QuerySecurityPackageInfoA"); | |
| pAcquireCredentialsHandleA = (PVOID)GetProcAddress(secdll, "AcquireCredentialsHandleA"); | |
| pAcquireCredentialsHandleW = (void*)GetProcAddress(secdll, "AcquireCredentialsHandleW"); | |
| pInitializeSecurityContextA = (PVOID)GetProcAddress(secdll, "InitializeSecurityContextA"); | |
| pCompleteAuthToken = (PVOID)GetProcAddress(secdll, "CompleteAuthToken"); | |
| pAcceptSecurityContext = (PVOID)GetProcAddress(secdll, "AcceptSecurityContext"); | |
| pFreeCredentialsHandle = (PVOID)GetProcAddress(secdll, "FreeCredentialsHandle"); | |
| pDeleteSecurityContext = (PVOID)GetProcAddress(secdll, "DeleteSecurityContext"); | |
| pQueryContextAttributesA = (PVOID)GetProcAddress(secdll, "QueryContextAttributesA"); | |
| pMakeSignature = (PVOID)GetProcAddress(secdll, "MakeSignature"); | |
| pVerifySignature = (PVOID)GetProcAddress(secdll, "VerifySignature"); | |
| pEncryptMessage = (PVOID)GetProcAddress(secdll, "EncryptMessage"); | |
| pDecryptMessage = (PVOID)GetProcAddress(secdll, "DecryptMessage"); | |
| pGetUserNameExA = (PVOID)GetProcAddress(secdll, "GetUserNameExA"); | |
| } | |
| } | |
| static const char* getSecError(SECURITY_STATUS status) | |
| { | |
| static char buf[20]; | |
| #define _SEC_ERR(x) case (x): return #x; | |
| switch(status) | |
| { | |
| _SEC_ERR(SEC_E_OK); | |
| _SEC_ERR(SEC_E_INSUFFICIENT_MEMORY); | |
| _SEC_ERR(SEC_E_INVALID_HANDLE); | |
| _SEC_ERR(SEC_E_UNSUPPORTED_FUNCTION); | |
| _SEC_ERR(SEC_E_TARGET_UNKNOWN); | |
| _SEC_ERR(SEC_E_INTERNAL_ERROR); | |
| _SEC_ERR(SEC_E_SECPKG_NOT_FOUND); | |
| _SEC_ERR(SEC_E_NOT_OWNER); | |
| _SEC_ERR(SEC_E_CANNOT_INSTALL); | |
| _SEC_ERR(SEC_E_INVALID_TOKEN); | |
| _SEC_ERR(SEC_E_CANNOT_PACK); | |
| _SEC_ERR(SEC_E_QOP_NOT_SUPPORTED); | |
| _SEC_ERR(SEC_E_NO_IMPERSONATION); | |
| _SEC_ERR(SEC_I_CONTINUE_NEEDED); | |
| _SEC_ERR(SEC_E_BUFFER_TOO_SMALL); | |
| _SEC_ERR(SEC_E_ILLEGAL_MESSAGE); | |
| _SEC_ERR(SEC_E_LOGON_DENIED); | |
| _SEC_ERR(SEC_E_NO_CREDENTIALS); | |
| _SEC_ERR(SEC_E_OUT_OF_SEQUENCE); | |
| _SEC_ERR(SEC_E_MESSAGE_ALTERED); | |
| default: | |
| sprintf(buf, "%08x\n", status); | |
| return buf; | |
| } | |
| #undef _SEC_ERR | |
| } | |
| /**********************************************************************/ | |
| static SECURITY_STATUS setupBuffers(SspiData *sspi_data, SecPkgInfoA *sec_pkg_info) | |
| { | |
| sspi_data->in_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc)); | |
| sspi_data->out_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc)); | |
| sspi_data->max_token = sec_pkg_info->cbMaxToken; | |
| if(sspi_data->in_buf != NULL) | |
| { | |
| PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0, | |
| sizeof(SecBuffer)); | |
| if(sec_buffer == NULL){ | |
| trace("in_buf: sec_buffer == NULL\n"); | |
| return SEC_E_INSUFFICIENT_MEMORY; | |
| } | |
| sspi_data->in_buf->ulVersion = SECBUFFER_VERSION; | |
| sspi_data->in_buf->cBuffers = 1; | |
| sspi_data->in_buf->pBuffers = sec_buffer; | |
| sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken; | |
| sec_buffer->BufferType = SECBUFFER_TOKEN; | |
| if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0, | |
| sec_pkg_info->cbMaxToken)) == NULL) | |
| { | |
| trace("in_buf: sec_buffer->pvBuffer == NULL\n"); | |
| return SEC_E_INSUFFICIENT_MEMORY; | |
| } | |
| } | |
| else | |
| { | |
| trace("HeapAlloc in_buf returned NULL\n"); | |
| return SEC_E_INSUFFICIENT_MEMORY; | |
| } | |
| if(sspi_data->out_buf != NULL) | |
| { | |
| PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0, | |
| sizeof(SecBuffer)); | |
| if(sec_buffer == NULL){ | |
| trace("out_buf: sec_buffer == NULL\n"); | |
| return SEC_E_INSUFFICIENT_MEMORY; | |
| } | |
| sspi_data->out_buf->ulVersion = SECBUFFER_VERSION; | |
| sspi_data->out_buf->cBuffers = 1; | |
| sspi_data->out_buf->pBuffers = sec_buffer; | |
| sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken; | |
| sec_buffer->BufferType = SECBUFFER_TOKEN; | |
| if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0, | |
| sec_pkg_info->cbMaxToken)) == NULL){ | |
| trace("out_buf: sec_buffer->pvBuffer == NULL\n"); | |
| return SEC_E_INSUFFICIENT_MEMORY; | |
| } | |
| } | |
| else | |
| { | |
| trace("HeapAlloc out_buf returned NULL\n"); | |
| return SEC_E_INSUFFICIENT_MEMORY; | |
| } | |
| return SEC_E_OK; | |
| } | |
| /**********************************************************************/ | |
| static void cleanupBuffers(SspiData *sspi_data) | |
| { | |
| ULONG i; | |
| if(sspi_data->in_buf != NULL) | |
| { | |
| for(i = 0; i < sspi_data->in_buf->cBuffers; ++i) | |
| { | |
| HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers[i].pvBuffer); | |
| } | |
| HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers); | |
| HeapFree(GetProcessHeap(), 0, sspi_data->in_buf); | |
| } | |
| if(sspi_data->out_buf != NULL) | |
| { | |
| for(i = 0; i < sspi_data->out_buf->cBuffers; ++i) | |
| { | |
| HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers[i].pvBuffer); | |
| } | |
| HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers); | |
| HeapFree(GetProcessHeap(), 0, sspi_data->out_buf); | |
| } | |
| } | |
| /**********************************************************************/ | |
| static SECURITY_STATUS setupClient(SspiData *sspi_data, SEC_CHAR *provider) | |
| { | |
| SECURITY_STATUS ret; | |
| TimeStamp ttl; | |
| SecPkgInfoA *sec_pkg_info; | |
| trace("Running setupClient\n"); | |
| ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info); | |
| ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret)); | |
| setupBuffers(sspi_data, sec_pkg_info); | |
| pFreeContextBuffer(sec_pkg_info); | |
| if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_OUTBOUND, | |
| NULL, sspi_data->id, NULL, NULL, &sspi_data->cred, &ttl)) | |
| != SEC_E_OK) | |
| { | |
| trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret)); | |
| } | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n", | |
| getSecError(ret)); | |
| return ret; | |
| } | |
| /**********************************************************************/ | |
| static SECURITY_STATUS setupServer(SspiData *sspi_data, SEC_CHAR *provider) | |
| { | |
| SECURITY_STATUS ret; | |
| TimeStamp ttl; | |
| SecPkgInfoA *sec_pkg_info; | |
| trace("Running setupServer\n"); | |
| ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info); | |
| ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret)); | |
| setupBuffers(sspi_data, sec_pkg_info); | |
| pFreeContextBuffer(sec_pkg_info); | |
| if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_INBOUND, | |
| NULL, NULL, NULL, NULL, &sspi_data->cred, &ttl)) != SEC_E_OK) | |
| { | |
| trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret)); | |
| } | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n", | |
| getSecError(ret)); | |
| return ret; | |
| } | |
| /**********************************************************************/ | |
| static SECURITY_STATUS setupFakeServer(SspiData *sspi_data, SEC_CHAR *provider) | |
| { | |
| SECURITY_STATUS ret; | |
| SecPkgInfoA *sec_pkg_info; | |
| trace("Running setupFakeServer\n"); | |
| ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info); | |
| ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret)); | |
| ret = setupBuffers(sspi_data, sec_pkg_info); | |
| pFreeContextBuffer(sec_pkg_info); | |
| return ret; | |
| } | |
| /**********************************************************************/ | |
| static SECURITY_STATUS runClient(SspiData *sspi_data, BOOL first, ULONG data_rep) | |
| { | |
| SECURITY_STATUS ret; | |
| ULONG req_attr = 0; | |
| ULONG ctxt_attr; | |
| TimeStamp ttl; | |
| PSecBufferDesc in_buf = sspi_data->in_buf; | |
| PSecBufferDesc out_buf = sspi_data->out_buf; | |
| assert(in_buf->cBuffers >= 1); | |
| assert(in_buf->pBuffers[0].pvBuffer != NULL); | |
| assert(in_buf->pBuffers[0].cbBuffer != 0); | |
| assert(out_buf->cBuffers >= 1); | |
| assert(out_buf->pBuffers[0].pvBuffer != NULL); | |
| assert(out_buf->pBuffers[0].cbBuffer != 0); | |
| trace("Running the client the %s time.\n", first?"first":"second"); | |
| /* We can either use ISC_REQ_ALLOCATE_MEMORY flag to ask the provider | |
| * always allocate output buffers for us, or initialize cbBuffer | |
| * before each call because the API changes it to represent actual | |
| * amount of data in the buffer. | |
| */ | |
| /* test a failing call only the first time, otherwise we get | |
| * SEC_E_OUT_OF_SEQUENCE | |
| */ | |
| if (first) | |
| { | |
| void *old_buf; | |
| /* pass NULL as an output buffer */ | |
| ret = pInitializeSecurityContextA(&sspi_data->cred, NULL, NULL, req_attr, | |
| 0, data_rep, NULL, 0, &sspi_data->ctxt, NULL, | |
| &ctxt_attr, &ttl); | |
| ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret)); | |
| /* pass NULL as an output buffer */ | |
| old_buf = out_buf->pBuffers[0].pvBuffer; | |
| out_buf->pBuffers[0].pvBuffer = NULL; | |
| ret = pInitializeSecurityContextA(&sspi_data->cred, NULL, NULL, req_attr, | |
| 0, data_rep, NULL, 0, &sspi_data->ctxt, out_buf, | |
| &ctxt_attr, &ttl); | |
| ok(ret == SEC_E_INTERNAL_ERROR || ret == SEC_I_CONTINUE_NEEDED, | |
| "expected SEC_E_INTERNAL_ERROR or SEC_I_CONTINUE_NEEDED, got %s\n", getSecError(ret)); | |
| out_buf->pBuffers[0].pvBuffer = old_buf; | |
| /* pass an output buffer of 0 size */ | |
| out_buf->pBuffers[0].cbBuffer = 0; | |
| ret = pInitializeSecurityContextA(&sspi_data->cred, NULL, NULL, req_attr, | |
| 0, data_rep, NULL, 0, &sspi_data->ctxt, out_buf, | |
| &ctxt_attr, &ttl); | |
| ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret)); | |
| ok(out_buf->pBuffers[0].cbBuffer == 0, | |
| "InitializeSecurityContext set buffer size to %u\n", out_buf->pBuffers[0].cbBuffer); | |
| out_buf->pBuffers[0].cbBuffer = sspi_data->max_token; | |
| out_buf->pBuffers[0].BufferType = SECBUFFER_DATA; | |
| ret = pInitializeSecurityContextA(&sspi_data->cred, NULL, NULL, req_attr, | |
| 0, data_rep, NULL, 0, &sspi_data->ctxt, out_buf, | |
| &ctxt_attr, &ttl); | |
| ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret)); | |
| out_buf->pBuffers[0].BufferType = SECBUFFER_TOKEN; | |
| } | |
| out_buf->pBuffers[0].cbBuffer = sspi_data->max_token; | |
| ret = pInitializeSecurityContextA(first?&sspi_data->cred:NULL, first?NULL:&sspi_data->ctxt, NULL, req_attr, | |
| 0, data_rep, first?NULL:in_buf, 0, &sspi_data->ctxt, out_buf, | |
| &ctxt_attr, &ttl); | |
| if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED) | |
| { | |
| pCompleteAuthToken(&sspi_data->ctxt, out_buf); | |
| if(ret == SEC_I_COMPLETE_AND_CONTINUE) | |
| ret = SEC_I_CONTINUE_NEEDED; | |
| else if(ret == SEC_I_COMPLETE_NEEDED) | |
| ret = SEC_E_OK; | |
| } | |
| ok(out_buf->pBuffers[0].BufferType == SECBUFFER_TOKEN, | |
| "buffer type was changed from SECBUFFER_TOKEN to %d\n", out_buf->pBuffers[0].BufferType); | |
| ok(out_buf->pBuffers[0].cbBuffer < sspi_data->max_token, | |
| "InitializeSecurityContext set buffer size to %u\n", out_buf->pBuffers[0].cbBuffer); | |
| return ret; | |
| } | |
| /**********************************************************************/ | |
| static SECURITY_STATUS runServer(SspiData *sspi_data, BOOL first, ULONG data_rep) | |
| { | |
| SECURITY_STATUS ret; | |
| ULONG ctxt_attr; | |
| TimeStamp ttl; | |
| trace("Running the server the %s time\n", first?"first":"second"); | |
| ret = pAcceptSecurityContext(&sspi_data->cred, first?NULL:&sspi_data->ctxt, | |
| sspi_data->in_buf, 0, data_rep, &sspi_data->ctxt, | |
| sspi_data->out_buf, &ctxt_attr, &ttl); | |
| if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED) | |
| { | |
| pCompleteAuthToken(&sspi_data->ctxt, sspi_data->out_buf); | |
| if(ret == SEC_I_COMPLETE_AND_CONTINUE) | |
| ret = SEC_I_CONTINUE_NEEDED; | |
| else if(ret == SEC_I_COMPLETE_NEEDED) | |
| ret = SEC_E_OK; | |
| } | |
| return ret; | |
| } | |
| /**********************************************************************/ | |
| static SECURITY_STATUS runFakeServer(SspiData *sspi_data, BOOL first, ULONG data_rep) | |
| { | |
| trace("Running the fake server the %s time\n", first?"first":"second"); | |
| if(!first) | |
| { | |
| sspi_data->out_buf->pBuffers[0].cbBuffer = 0; | |
| return SEC_E_OK; | |
| } | |
| if(data_rep == SECURITY_NATIVE_DREP) | |
| { | |
| sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(native_challenge); | |
| memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, native_challenge, | |
| sspi_data->out_buf->pBuffers[0].cbBuffer); | |
| } | |
| else | |
| { | |
| sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(network_challenge); | |
| memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, network_challenge, | |
| sspi_data->out_buf->pBuffers[0].cbBuffer); | |
| } | |
| return SEC_I_CONTINUE_NEEDED; | |
| } | |
| /**********************************************************************/ | |
| static void communicate(SspiData *from, SspiData *to) | |
| { | |
| if(from->out_buf != NULL && to->in_buf != NULL) | |
| { | |
| trace("Running communicate.\n"); | |
| if((from->out_buf->cBuffers >= 1) && (to->in_buf->cBuffers >= 1)) | |
| { | |
| if((from->out_buf->pBuffers[0].pvBuffer != NULL) && | |
| (to->in_buf->pBuffers[0].pvBuffer != NULL)) | |
| { | |
| memset(to->in_buf->pBuffers[0].pvBuffer, 0, to->max_token); | |
| memcpy(to->in_buf->pBuffers[0].pvBuffer, | |
| from->out_buf->pBuffers[0].pvBuffer, | |
| from->out_buf->pBuffers[0].cbBuffer); | |
| to->in_buf->pBuffers[0].cbBuffer = from->out_buf->pBuffers[0].cbBuffer; | |
| memset(from->out_buf->pBuffers[0].pvBuffer, 0, from->max_token); | |
| } | |
| } | |
| } | |
| } | |
| /**********************************************************************/ | |
| static void testInitializeSecurityContextFlags(void) | |
| { | |
| SECURITY_STATUS sec_status; | |
| PSecPkgInfoA pkg_info = NULL; | |
| SspiData client = {{0}}; | |
| SEC_WINNT_AUTH_IDENTITY_A id; | |
| ULONG req_attr, ctxt_attr; | |
| TimeStamp ttl; | |
| PBYTE packet; | |
| if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK) | |
| { | |
| ok(0, "NTLM package not installed, skipping test.\n"); | |
| return; | |
| } | |
| pFreeContextBuffer(pkg_info); | |
| id.User = (unsigned char*) test_user; | |
| id.UserLength = strlen((char *) id.User); | |
| id.Domain = (unsigned char *) workgroup; | |
| id.DomainLength = strlen((char *) id.Domain); | |
| id.Password = (unsigned char*) test_pass; | |
| id.PasswordLength = strlen((char *) id.Password); | |
| id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; | |
| client.id = &id; | |
| if((sec_status = setupClient(&client, sec_pkg_name)) != SEC_E_OK) | |
| { | |
| skip("Setting up the client returned %s, skipping test!\n", | |
| getSecError(sec_status)); | |
| return; | |
| } | |
| packet = client.out_buf->pBuffers[0].pvBuffer; | |
| /* Due to how the requesting of the flags is implemented in ntlm_auth, | |
| * the tests need to be in this order, as there is no way to specify | |
| * "I request no special features" in ntlm_auth */ | |
| /* Without any flags, the lowest byte should not have bits 0x20 or 0x10 set*/ | |
| req_attr = 0; | |
| if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr, | |
| 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf, | |
| &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED) | |
| { | |
| trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n", | |
| getSecError(sec_status)); | |
| goto tISCFend; | |
| } | |
| ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0), | |
| "With req_attr == 0, flags are 0x%02x%02x%02x%02x.\n", | |
| packet[15], packet[14], packet[13], packet[12]); | |
| pDeleteSecurityContext(&client.ctxt); | |
| /* With ISC_REQ_CONNECTION, the lowest byte should not have bits 0x20 or 0x10 set*/ | |
| req_attr = ISC_REQ_CONNECTION; | |
| if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr, | |
| 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf, | |
| &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED) | |
| { | |
| trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n", | |
| getSecError(sec_status)); | |
| goto tISCFend; | |
| } | |
| ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0), | |
| "For ISC_REQ_CONNECTION, flags are 0x%02x%02x%02x%02x.\n", | |
| packet[15], packet[14], packet[13], packet[12]); | |
| pDeleteSecurityContext(&client.ctxt); | |
| /* With ISC_REQ_EXTENDED_ERROR, the lowest byte should not have bits 0x20 or 0x10 set*/ | |
| req_attr = ISC_REQ_EXTENDED_ERROR; | |
| if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr, | |
| 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf, | |
| &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED) | |
| { | |
| trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n", | |
| getSecError(sec_status)); | |
| goto tISCFend; | |
| } | |
| ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0), | |
| "For ISC_REQ_EXTENDED_ERROR, flags are 0x%02x%02x%02x%02x.\n", | |
| packet[15], packet[14], packet[13], packet[12]); | |
| pDeleteSecurityContext(&client.ctxt); | |
| /* With ISC_REQ_MUTUAL_AUTH, the lowest byte should not have bits 0x20 or 0x10 set*/ | |
| req_attr = ISC_REQ_MUTUAL_AUTH; | |
| if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr, | |
| 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf, | |
| &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED) | |
| { | |
| trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n", | |
| getSecError(sec_status)); | |
| goto tISCFend; | |
| } | |
| ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0), | |
| "For ISC_REQ_MUTUAL_AUTH, flags are 0x%02x%02x%02x%02x.\n", | |
| packet[15], packet[14], packet[13], packet[12]); | |
| pDeleteSecurityContext(&client.ctxt); | |
| /* With ISC_REQ_USE_DCE_STYLE, the lowest byte should not have bits 0x20 or 0x10 set*/ | |
| req_attr = ISC_REQ_USE_DCE_STYLE; | |
| if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr, | |
| 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf, | |
| &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED) | |
| { | |
| trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n", | |
| getSecError(sec_status)); | |
| goto tISCFend; | |
| } | |
| ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0), | |
| "For ISC_REQ_USE_DCE_STYLE, flags are 0x%02x%02x%02x%02x.\n", | |
| packet[15], packet[14], packet[13], packet[12]); | |
| pDeleteSecurityContext(&client.ctxt); | |
| /* With ISC_REQ_DELEGATE, the lowest byte should not have bits 0x20 or 0x10 set*/ | |
| req_attr = ISC_REQ_DELEGATE; | |
| if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr, | |
| 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf, | |
| &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED) | |
| { | |
| trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n", | |
| getSecError(sec_status)); | |
| goto tISCFend; | |
| } | |
| ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0), | |
| "For ISC_REQ_DELEGATE, flags are 0x%02x%02x%02x%02x.\n", | |
| packet[15], packet[14], packet[13], packet[12]); | |
| pDeleteSecurityContext(&client.ctxt); | |
| /* With ISC_REQ_INTEGRITY, the lowest byte should have bit 0x10 set */ | |
| req_attr = ISC_REQ_INTEGRITY; | |
| if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr, | |
| 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf, | |
| &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED) | |
| { | |
| trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n", | |
| getSecError(sec_status)); | |
| goto tISCFend; | |
| } | |
| ok((packet[12] & 0x10) != 0, | |
| "For ISC_REQ_INTEGRITY, flags are 0x%02x%02x%02x%02x.\n", | |
| packet[15], packet[14], packet[13], packet[12]); | |
| pDeleteSecurityContext(&client.ctxt); | |
| /* With ISC_REQ_REPLAY_DETECT, the lowest byte should have bit 0x10 set */ | |
| req_attr = ISC_REQ_REPLAY_DETECT; | |
| if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr, | |
| 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf, | |
| &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED) | |
| { | |
| trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n", | |
| getSecError(sec_status)); | |
| goto tISCFend; | |
| } | |
| ok((packet[12] & 0x10) != 0, | |
| "For ISC_REQ_REPLAY_DETECT, flags are 0x%02x%02x%02x%02x.\n", | |
| packet[15], packet[14], packet[13], packet[12]); | |
| pDeleteSecurityContext(&client.ctxt); | |
| /* With ISC_REQ_SEQUENCE_DETECT, the lowest byte should have bit 0x10 set */ | |
| req_attr = ISC_REQ_SEQUENCE_DETECT; | |
| if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr, | |
| 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf, | |
| &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED) | |
| { | |
| trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n", | |
| getSecError(sec_status)); | |
| goto tISCFend; | |
| } | |
| ok((packet[12] & 0x10) != 0, | |
| "For ISC_REQ_SEQUENCE_DETECT, flags are 0x%02x%02x%02x%02x.\n", | |
| packet[15], packet[14], packet[13], packet[12]); | |
| pDeleteSecurityContext(&client.ctxt); | |
| /* With ISC_REQ_CONFIDENTIALITY, the lowest byte should have bit 0x20 set */ | |
| req_attr = ISC_REQ_CONFIDENTIALITY; | |
| if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr, | |
| 0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf, | |
| &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED) | |
| { | |
| trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n", | |
| getSecError(sec_status)); | |
| goto tISCFend; | |
| } | |
| ok((packet[12] & 0x20) != 0, | |
| "For ISC_REQ_CONFIDENTIALITY, flags are 0x%02x%02x%02x%02x.\n", | |
| packet[15], packet[14], packet[13], packet[12]); | |
| pDeleteSecurityContext(&client.ctxt); | |
| tISCFend: | |
| cleanupBuffers(&client); | |
| pFreeCredentialsHandle(&client.cred); | |
| } | |
| /**********************************************************************/ | |
| static void testAuth(ULONG data_rep, BOOL fake) | |
| { | |
| SECURITY_STATUS client_stat = SEC_I_CONTINUE_NEEDED; | |
| SECURITY_STATUS server_stat = SEC_I_CONTINUE_NEEDED; | |
| SECURITY_STATUS sec_status; | |
| PSecPkgInfoA pkg_info = NULL; | |
| BOOL first = TRUE; | |
| SspiData client = {{0}}, server = {{0}}; | |
| SEC_WINNT_AUTH_IDENTITY_A id; | |
| SecPkgContext_Sizes ctxt_sizes; | |
| if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)!= SEC_E_OK) | |
| { | |
| ok(0, "NTLM package not installed, skipping test.\n"); | |
| return; | |
| } | |
| pFreeContextBuffer(pkg_info); | |
| id.User = (unsigned char*) test_user; | |
| id.UserLength = strlen((char *) id.User); | |
| id.Domain = (unsigned char *) workgroup; | |
| id.DomainLength = strlen((char *) id.Domain); | |
| id.Password = (unsigned char*) test_pass; | |
| id.PasswordLength = strlen((char *) id.Password); | |
| id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; | |
| client.id = &id; | |
| sec_status = setupClient(&client, sec_pkg_name); | |
| if(sec_status != SEC_E_OK) | |
| { | |
| skip("Error: Setting up the client returned %s, exiting test!\n", | |
| getSecError(sec_status)); | |
| pFreeCredentialsHandle(&client.cred); | |
| return; | |
| } | |
| if(fake) | |
| sec_status = setupFakeServer(&server, sec_pkg_name); | |
| else | |
| sec_status = setupServer(&server, sec_pkg_name); | |
| if(sec_status != SEC_E_OK) | |
| { | |
| skip("Error: Setting up the server returned %s, exiting test!\n", | |
| getSecError(sec_status)); | |
| pFreeCredentialsHandle(&server.cred); | |
| pFreeCredentialsHandle(&client.cred); | |
| return; | |
| } | |
| while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED) | |
| { | |
| client_stat = runClient(&client, first, data_rep); | |
| ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED, | |
| "Running the client returned %s, more tests will fail.\n", | |
| getSecError(client_stat)); | |
| communicate(&client, &server); | |
| if(fake) | |
| server_stat = runFakeServer(&server, first, data_rep); | |
| else | |
| server_stat = runServer(&server, first, data_rep); | |
| ok(server_stat == SEC_E_OK || server_stat == SEC_I_CONTINUE_NEEDED || | |
| server_stat == SEC_E_LOGON_DENIED, | |
| "Running the server returned %s, more tests will fail from now.\n", | |
| getSecError(server_stat)); | |
| communicate(&server, &client); | |
| trace("Looping\n"); | |
| first = FALSE; | |
| } | |
| if(client_stat != SEC_E_OK) | |
| { | |
| skip("Authentication failed, skipping test.\n"); | |
| goto tAuthend; | |
| } | |
| sec_status = pQueryContextAttributesA(&client.ctxt, | |
| SECPKG_ATTR_SIZES, &ctxt_sizes); | |
| ok(sec_status == SEC_E_OK, | |
| "pQueryContextAttributesA(SECPKG_ATTR_SIZES) returned %s\n", | |
| getSecError(sec_status)); | |
| ok((ctxt_sizes.cbMaxToken == 1904) || (ctxt_sizes.cbMaxToken == 2888), | |
| "cbMaxToken should be 1904 or 2888 but is %u\n", | |
| ctxt_sizes.cbMaxToken); | |
| ok(ctxt_sizes.cbMaxSignature == 16, | |
| "cbMaxSignature should be 16 but is %u\n", | |
| ctxt_sizes.cbMaxSignature); | |
| ok(ctxt_sizes.cbSecurityTrailer == 16, | |
| "cbSecurityTrailer should be 16 but is %u\n", | |
| ctxt_sizes.cbSecurityTrailer); | |
| ok(ctxt_sizes.cbBlockSize == 0, | |
| "cbBlockSize should be 0 but is %u\n", | |
| ctxt_sizes.cbBlockSize); | |
| tAuthend: | |
| cleanupBuffers(&client); | |
| cleanupBuffers(&server); | |
| if(!fake) | |
| { | |
| sec_status = pDeleteSecurityContext(&server.ctxt); | |
| ok(sec_status == SEC_E_OK, "DeleteSecurityContext(server) returned %s\n", | |
| getSecError(sec_status)); | |
| } | |
| sec_status = pDeleteSecurityContext(&client.ctxt); | |
| ok(sec_status == SEC_E_OK, "DeleteSecurityContext(client) returned %s\n", | |
| getSecError(sec_status)); | |
| if(!fake) | |
| { | |
| sec_status = pFreeCredentialsHandle(&server.cred); | |
| ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(server) returned %s\n", | |
| getSecError(sec_status)); | |
| } | |
| sec_status = pFreeCredentialsHandle(&client.cred); | |
| ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(client) returned %s\n", | |
| getSecError(sec_status)); | |
| } | |
| static void testSignSeal(void) | |
| { | |
| SECURITY_STATUS client_stat = SEC_I_CONTINUE_NEEDED; | |
| SECURITY_STATUS server_stat = SEC_I_CONTINUE_NEEDED; | |
| SECURITY_STATUS sec_status; | |
| PSecPkgInfoA pkg_info = NULL; | |
| BOOL first = TRUE; | |
| SspiData client = {{0}}, server = {{0}}; | |
| SEC_WINNT_AUTH_IDENTITY_A id; | |
| static char sec_pkg_name[] = "NTLM"; | |
| SecBufferDesc crypt; | |
| SecBuffer data[2], fake_data[2], complex_data[4]; | |
| ULONG qop = 0xdeadbeef; | |
| SecPkgContext_Sizes ctxt_sizes; | |
| complex_data[1].pvBuffer = complex_data[3].pvBuffer = NULL; | |
| /**************************************************************** | |
| * This is basically the same as in testAuth with a fake server, | |
| * as we need a valid, authenticated context. | |
| */ | |
| if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK) | |
| { | |
| ok(0, "NTLM package not installed, skipping test.\n"); | |
| return; | |
| } | |
| pFreeContextBuffer(pkg_info); | |
| id.User = (unsigned char*) test_user; | |
| id.UserLength = strlen((char *) id.User); | |
| id.Domain = (unsigned char *) workgroup; | |
| id.DomainLength = strlen((char *) id.Domain); | |
| id.Password = (unsigned char*) test_pass; | |
| id.PasswordLength = strlen((char *) id.Password); | |
| id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; | |
| client.id = &id; | |
| sec_status = setupClient(&client, sec_pkg_name); | |
| if(sec_status != SEC_E_OK) | |
| { | |
| skip("Error: Setting up the client returned %s, exiting test!\n", | |
| getSecError(sec_status)); | |
| pFreeCredentialsHandle(&client.cred); | |
| return; | |
| } | |
| sec_status = setupFakeServer(&server, sec_pkg_name); | |
| ok(sec_status == SEC_E_OK, "setupFakeServer returned %s\n", getSecError(sec_status)); | |
| while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED) | |
| { | |
| client_stat = runClient(&client, first, SECURITY_NETWORK_DREP); | |
| ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED, | |
| "Running the client returned %s, more tests will fail.\n", | |
| getSecError(client_stat)); | |
| communicate(&client, &server); | |
| server_stat = runFakeServer(&server, first, SECURITY_NETWORK_DREP); | |
| communicate(&server, &client); | |
| trace("Looping\n"); | |
| first = FALSE; | |
| } | |
| if(client_stat != SEC_E_OK) | |
| { | |
| skip("Authentication failed, skipping test.\n"); | |
| goto end; | |
| } | |
| /******************************************** | |
| * Now start with the actual testing * | |
| ********************************************/ | |
| if(pQueryContextAttributesA(&client.ctxt, SECPKG_ATTR_SIZES, | |
| &ctxt_sizes) != SEC_E_OK) | |
| { | |
| skip("Failed to get context sizes, aborting test.\n"); | |
| goto end; | |
| } | |
| crypt.ulVersion = SECBUFFER_VERSION; | |
| crypt.cBuffers = 2; | |
| crypt.pBuffers = fake_data; | |
| fake_data[0].BufferType = SECBUFFER_DATA; | |
| fake_data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer; | |
| fake_data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[0].cbBuffer); | |
| fake_data[1].BufferType = SECBUFFER_DATA; | |
| fake_data[1].cbBuffer = lstrlenA(message); | |
| fake_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[1].cbBuffer); | |
| sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0); | |
| ok(sec_status == SEC_E_INVALID_TOKEN, | |
| "MakeSignature returned %s, not SEC_E_INVALID_TOKEN.\n", | |
| getSecError(sec_status)); | |
| crypt.pBuffers = data; | |
| data[0].BufferType = SECBUFFER_TOKEN; | |
| data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer; | |
| data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[0].cbBuffer); | |
| data[1].BufferType = SECBUFFER_DATA; | |
| data[1].cbBuffer = lstrlenA(message); | |
| data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer); | |
| memcpy(data[1].pvBuffer, message, data[1].cbBuffer); | |
| /* As we forced NTLM to fall back to a password-derived session key, | |
| * we should get the same signature for our data, no matter if | |
| * it is sent by the client or the server | |
| */ | |
| sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0); | |
| ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n", | |
| getSecError(sec_status)); | |
| ok(!memcmp(crypt.pBuffers[0].pvBuffer, message_signature, | |
| crypt.pBuffers[0].cbBuffer), "Signature is not as expected.\n"); | |
| data[0].cbBuffer = sizeof(message_signature); | |
| memcpy(data[0].pvBuffer, crypt_trailer_client, data[0].cbBuffer); | |
| sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop); | |
| ok(sec_status == SEC_E_MESSAGE_ALTERED, | |
| "VerifySignature returned %s, not SEC_E_MESSAGE_ALTERED.\n", | |
| getSecError(sec_status)); | |
| ok(qop == 0xdeadbeef, "qop changed to %u\n", qop); | |
| memcpy(data[0].pvBuffer, message_signature, data[0].cbBuffer); | |
| sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop); | |
| ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK.\n", | |
| getSecError(sec_status)); | |
| ok(qop == 0xdeadbeef, "qop changed to %u\n", qop); | |
| sec_status = pEncryptMessage(&client.ctxt, 0, &crypt, 0); | |
| if (sec_status == SEC_E_UNSUPPORTED_FUNCTION) | |
| { | |
| skip("Encrypt message returned SEC_E_UNSUPPORTED_FUNCTION. " | |
| "Expected on Vista.\n"); | |
| goto end; | |
| } | |
| ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n", | |
| getSecError(sec_status)); | |
| /* first 8 bytes must always be the same */ | |
| ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client, 8), "Crypt trailer not as expected.\n"); | |
| /* the rest depends on the session key */ | |
| if (!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client, crypt.pBuffers[0].cbBuffer)) | |
| { | |
| ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client, | |
| crypt.pBuffers[0].cbBuffer), "Crypt trailer not as expected.\n"); | |
| ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client, | |
| crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n"); | |
| if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client, | |
| crypt.pBuffers[1].cbBuffer)) | |
| { | |
| int i; | |
| for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++) | |
| { | |
| if (i % 8 == 0) printf(" "); | |
| printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]); | |
| if (i % 8 == 7) printf("\n"); | |
| } | |
| printf("\n"); | |
| } | |
| data[0].cbBuffer = sizeof(crypt_trailer_server); | |
| data[1].cbBuffer = sizeof(crypt_message_server); | |
| memcpy(data[0].pvBuffer, crypt_trailer_server, data[0].cbBuffer); | |
| memcpy(data[1].pvBuffer, crypt_message_server, data[1].cbBuffer); | |
| sec_status = pDecryptMessage(&client.ctxt, &crypt, 0, &qop); | |
| ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n", | |
| getSecError(sec_status)); | |
| ok(!memcmp(crypt.pBuffers[1].pvBuffer, message_binary, | |
| crypt.pBuffers[1].cbBuffer), | |
| "Failed to decrypt message correctly.\n"); | |
| ok(qop == 0xdeadbeef, "qop changed to %u\n", qop); | |
| } | |
| else trace( "A different session key is being used\n" ); | |
| trace("Testing with more than one buffer.\n"); | |
| crypt.cBuffers = sizeof(complex_data)/sizeof(complex_data[0]); | |
| crypt.pBuffers = complex_data; | |
| complex_data[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM; | |
| complex_data[0].cbBuffer = sizeof(message_header); | |
| complex_data[0].pvBuffer = message_header; | |
| complex_data[1].BufferType = SECBUFFER_DATA; | |
| complex_data[1].cbBuffer = lstrlenA(message); | |
| complex_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer); | |
| memcpy(complex_data[1].pvBuffer, message, complex_data[1].cbBuffer); | |
| complex_data[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM; | |
| complex_data[2].cbBuffer = sizeof(message_header); | |
| complex_data[2].pvBuffer = message_header; | |
| complex_data[3].BufferType = SECBUFFER_TOKEN; | |
| complex_data[3].cbBuffer = ctxt_sizes.cbSecurityTrailer; | |
| complex_data[3].pvBuffer = HeapAlloc(GetProcessHeap(), 0, complex_data[3].cbBuffer); | |
| /* We should get a dummy signature again. */ | |
| sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0); | |
| ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n", | |
| getSecError(sec_status)); | |
| ok(!memcmp(crypt.pBuffers[3].pvBuffer, message_signature, | |
| crypt.pBuffers[3].cbBuffer), "Signature is not as expected.\n"); | |
| /* Being a dummy signature, it will verify right away, as if the server | |
| * sent it */ | |
| sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop); | |
| ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK\n", | |
| getSecError(sec_status)); | |
| ok(qop == 0xdeadbeef, "qop changed to %u\n", qop); | |
| sec_status = pEncryptMessage(&client.ctxt, 0, &crypt, 0); | |
| ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n", | |
| getSecError(sec_status)); | |
| ok(!memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2, 8), "Crypt trailer not as expected.\n"); | |
| if (memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2, | |
| crypt.pBuffers[3].cbBuffer)) goto end; | |
| ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2, | |
| crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n"); | |
| if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2, | |
| crypt.pBuffers[1].cbBuffer)) | |
| { | |
| int i; | |
| for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++) | |
| { | |
| if (i % 8 == 0) printf(" "); | |
| printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]); | |
| if (i % 8 == 7) printf("\n"); | |
| } | |
| printf("\n"); | |
| } | |
| memcpy(complex_data[1].pvBuffer, crypt_message_server2, complex_data[1].cbBuffer); | |
| memcpy(complex_data[3].pvBuffer, crypt_trailer_server2, complex_data[3].cbBuffer); | |
| sec_status = pDecryptMessage(&client.ctxt, &crypt, 0, &qop); | |
| ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n", | |
| getSecError(sec_status)); | |
| ok(qop == 0xdeadbeef, "qop changed to %u\n", qop); | |
| end: | |
| cleanupBuffers(&client); | |
| cleanupBuffers(&server); | |
| pDeleteSecurityContext(&client.ctxt); | |
| pFreeCredentialsHandle(&client.cred); | |
| HeapFree(GetProcessHeap(), 0, complex_data[1].pvBuffer); | |
| HeapFree(GetProcessHeap(), 0, complex_data[3].pvBuffer); | |
| } | |
| static BOOL testAcquireCredentialsHandle(void) | |
| { | |
| CredHandle cred; | |
| TimeStamp ttl; | |
| SECURITY_STATUS ret; | |
| SEC_WINNT_AUTH_IDENTITY_A id; | |
| PSecPkgInfoA pkg_info = NULL; | |
| if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK) | |
| { | |
| ok(0, "NTLM package not installed, skipping test\n"); | |
| return FALSE; | |
| } | |
| pFreeContextBuffer(pkg_info); | |
| id.User = (unsigned char*) test_user; | |
| id.UserLength = strlen((char *) id.User); | |
| id.Domain = (unsigned char *) workgroup; | |
| id.DomainLength = strlen((char *) id.Domain); | |
| id.Password = (unsigned char*) test_pass; | |
| id.PasswordLength = strlen((char *) id.Password); | |
| id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; | |
| ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND, | |
| NULL, &id, NULL, NULL, &cred, &ttl); | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n", | |
| getSecError(ret)); | |
| pFreeCredentialsHandle(&cred); | |
| id.DomainLength = 0; | |
| ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND, | |
| NULL, &id, NULL, NULL, &cred, &ttl); | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n", | |
| getSecError(ret)); | |
| pFreeCredentialsHandle(&cred); | |
| id.Domain = NULL; | |
| ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND, | |
| NULL, &id, NULL, NULL, &cred, &ttl); | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n", | |
| getSecError(ret)); | |
| pFreeCredentialsHandle(&cred); | |
| id.Domain = (unsigned char *) workgroup; | |
| id.DomainLength = strlen((char *) id.Domain); | |
| id.UserLength = 0; | |
| id.User = NULL; | |
| ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND, | |
| NULL, &id, NULL, NULL, &cred, &ttl); | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n", | |
| getSecError(ret)); | |
| pFreeCredentialsHandle(&cred); | |
| id.User = (unsigned char*) test_user; | |
| id.UserLength = strlen((char *) id.User); | |
| id.Password = NULL; | |
| id.PasswordLength = 0; | |
| ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND, | |
| NULL, &id, NULL, NULL, &cred, &ttl); | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n", | |
| getSecError(ret)); | |
| pFreeCredentialsHandle(&cred); | |
| return TRUE; | |
| } | |
| static void testAcquireCredentialsHandleW(void) | |
| { | |
| CredHandle cred; | |
| TimeStamp ttl; | |
| static WCHAR sec_pkg_nameW[] = {'N','T','L','M',0 }; | |
| static WCHAR test_userW[] = {'t','e','s','t','u','s','e','r',0 }; | |
| static WCHAR workgroupW[] = {'W','O','R','K','G','R','O','U','P',0}; | |
| static WCHAR test_passW[] = {'t','e','s','t','p','a','s','s',0}; | |
| SECURITY_STATUS ret; | |
| SEC_WINNT_AUTH_IDENTITY_A idA; | |
| SEC_WINNT_AUTH_IDENTITY_W id; | |
| PSecPkgInfoA pkg_info = NULL; | |
| if(!pAcquireCredentialsHandleW) | |
| { | |
| win_skip("AcquireCredentialsHandleW not available\n"); | |
| return; | |
| } | |
| if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK) | |
| { | |
| ok(0, "NTLM package not installed, skipping test\n"); | |
| return; | |
| } | |
| pFreeContextBuffer(pkg_info); | |
| id.User = test_userW; | |
| id.UserLength = lstrlenW(test_userW); | |
| id.Domain = workgroupW; | |
| id.DomainLength = lstrlenW(workgroupW); | |
| id.Password = test_passW; | |
| id.PasswordLength = lstrlenW(test_passW); | |
| id.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; | |
| ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND, | |
| NULL, &id, NULL, NULL, &cred, &ttl); | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n", | |
| getSecError(ret)); | |
| pFreeCredentialsHandle(&cred); | |
| id.DomainLength = 0; | |
| ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND, | |
| NULL, &id, NULL, NULL, &cred, &ttl); | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n", | |
| getSecError(ret)); | |
| pFreeCredentialsHandle(&cred); | |
| id.Domain = NULL; | |
| ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND, | |
| NULL, &id, NULL, NULL, &cred, &ttl); | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n", | |
| getSecError(ret)); | |
| pFreeCredentialsHandle(&cred); | |
| id.Domain = workgroupW; | |
| id.DomainLength = lstrlenW(workgroupW); | |
| id.UserLength = 0; | |
| id.User = NULL; | |
| ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND, | |
| NULL, &id, NULL, NULL, &cred, &ttl); | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n", | |
| getSecError(ret)); | |
| pFreeCredentialsHandle(&cred); | |
| id.User = test_userW; | |
| id.UserLength = lstrlenW(test_userW); | |
| id.Password = test_passW; /* NULL string causes a crash. */ | |
| id.PasswordLength = 0; | |
| ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND, | |
| NULL, &id, NULL, NULL, &cred, &ttl); | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n", | |
| getSecError(ret)); | |
| pFreeCredentialsHandle(&cred); | |
| /* Test using the ASCII structure. */ | |
| idA.User = (unsigned char*) test_user; | |
| idA.UserLength = strlen(test_user); | |
| idA.Domain = (unsigned char *) workgroup; | |
| idA.DomainLength = strlen(workgroup); | |
| idA.Password = (unsigned char*) test_pass; | |
| idA.PasswordLength = strlen(test_pass); | |
| idA.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; | |
| ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND, | |
| NULL, &idA, NULL, NULL, &cred, &ttl); | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n", | |
| getSecError(ret)); | |
| pFreeCredentialsHandle(&cred); | |
| } | |
| static void test_cred_multiple_use(void) | |
| { | |
| SECURITY_STATUS ret; | |
| SEC_WINNT_AUTH_IDENTITY_A id; | |
| PSecPkgInfoA pkg_info = NULL; | |
| CredHandle cred; | |
| CtxtHandle ctxt1 = {0}; | |
| CtxtHandle ctxt2 = {0}; | |
| SecBufferDesc buffer_desc; | |
| SecBuffer buffers[1]; | |
| ULONG ctxt_attr; | |
| TimeStamp ttl; | |
| if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK) | |
| { | |
| ok(0, "NTLM package not installed, skipping test\n"); | |
| return; | |
| } | |
| buffers[0].cbBuffer = pkg_info->cbMaxToken; | |
| buffers[0].BufferType = SECBUFFER_TOKEN; | |
| buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer); | |
| pFreeContextBuffer(pkg_info); | |
| id.User = (unsigned char*) test_user; | |
| id.UserLength = strlen((char *) id.User); | |
| id.Domain = (unsigned char *) workgroup; | |
| id.DomainLength = strlen((char *) id.Domain); | |
| id.Password = (unsigned char*) test_pass; | |
| id.PasswordLength = strlen((char *) id.Password); | |
| id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; | |
| ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND, | |
| NULL, &id, NULL, NULL, &cred, &ttl); | |
| ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n", | |
| getSecError(ret)); | |
| buffer_desc.ulVersion = SECBUFFER_VERSION; | |
| buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]); | |
| buffer_desc.pBuffers = buffers; | |
| ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION, | |
| 0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt1, &buffer_desc, | |
| &ctxt_attr, &ttl); | |
| ok(ret == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed with error 0x%x\n", ret); | |
| ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION, | |
| 0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt2, &buffer_desc, | |
| &ctxt_attr, &ttl); | |
| ok(ret == SEC_I_CONTINUE_NEEDED, "Second InitializeSecurityContextA on cred handle failed with error 0x%x\n", ret); | |
| ret = pDeleteSecurityContext(&ctxt1); | |
| ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret); | |
| ret = pDeleteSecurityContext(&ctxt2); | |
| ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret); | |
| ret = pFreeCredentialsHandle(&cred); | |
| ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret); | |
| HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer); | |
| } | |
| static void test_null_auth_data(void) | |
| { | |
| SECURITY_STATUS status; | |
| PSecPkgInfoA info; | |
| CredHandle cred; | |
| CtxtHandle ctx = {0}; | |
| SecBufferDesc buffer_desc; | |
| SecBuffer buffers[1]; | |
| char user[256]; | |
| TimeStamp ttl; | |
| ULONG attr, size; | |
| BOOLEAN ret; | |
| if(pQuerySecurityPackageInfoA((SEC_CHAR *)"NTLM", &info) != SEC_E_OK) | |
| { | |
| ok(0, "NTLM package not installed, skipping test\n"); | |
| return; | |
| } | |
| status = pAcquireCredentialsHandleA(NULL, (SEC_CHAR *)"NTLM", SECPKG_CRED_OUTBOUND, | |
| NULL, NULL, NULL, NULL, &cred, &ttl); | |
| ok(status == SEC_E_OK, "AcquireCredentialsHandle() failed %s\n", getSecError(status)); | |
| buffers[0].cbBuffer = info->cbMaxToken; | |
| buffers[0].BufferType = SECBUFFER_TOKEN; | |
| buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer); | |
| buffer_desc.ulVersion = SECBUFFER_VERSION; | |
| buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]); | |
| buffer_desc.pBuffers = buffers; | |
| size = sizeof(user); | |
| ret = pGetUserNameExA(NameSamCompatible, user, &size); | |
| ok(ret, "GetUserNameExA failed %u\n", GetLastError()); | |
| status = pInitializeSecurityContextA(&cred, NULL, (SEC_CHAR *)user, | |
| ISC_REQ_CONNECTION, 0, SECURITY_NETWORK_DREP, | |
| NULL, 0, &ctx, &buffer_desc, &attr, &ttl); | |
| ok(status == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed %s\n", getSecError(status)); | |
| ret = pDeleteSecurityContext(&ctx); | |
| ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret); | |
| ret = pFreeCredentialsHandle(&cred); | |
| ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret); | |
| pFreeContextBuffer(info); | |
| HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer); | |
| } | |
| START_TEST(ntlm) | |
| { | |
| InitFunctionPtrs(); | |
| if(pFreeCredentialsHandle && pDeleteSecurityContext && | |
| pAcquireCredentialsHandleA && pInitializeSecurityContextA && | |
| pCompleteAuthToken && pQuerySecurityPackageInfoA) | |
| { | |
| testAcquireCredentialsHandleW(); | |
| if(!testAcquireCredentialsHandle()) | |
| goto cleanup; | |
| testInitializeSecurityContextFlags(); | |
| if(pAcceptSecurityContext) | |
| { | |
| testAuth(SECURITY_NATIVE_DREP, TRUE); | |
| testAuth(SECURITY_NETWORK_DREP, TRUE); | |
| testAuth(SECURITY_NATIVE_DREP, FALSE); | |
| testAuth(SECURITY_NETWORK_DREP, FALSE); | |
| } | |
| if(pMakeSignature && pVerifySignature && pEncryptMessage && | |
| pDecryptMessage) | |
| testSignSeal(); | |
| test_cred_multiple_use(); | |
| if (pGetUserNameExA) test_null_auth_data(); | |
| } | |
| else | |
| win_skip("Needed functions are not available\n"); | |
| cleanup: | |
| if(secdll) | |
| FreeLibrary(secdll); | |
| } |