libwinpr-sspi: added Schannel test
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Sun, 23 Dec 2012 01:23:44 +0000 (20:23 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Sun, 23 Dec 2012 01:23:44 +0000 (20:23 -0500)
winpr/libwinpr/sspi/sspi.c
winpr/libwinpr/sspi/test/CMakeLists.txt
winpr/libwinpr/sspi/test/TestSchannel.c [new file with mode: 0644]

index 9a10a03..fffa38d 100644 (file)
 
 extern const SecPkgInfoA NTLM_SecPkgInfoA;
 extern const SecPkgInfoW NTLM_SecPkgInfoW;
-extern const SecPkgInfoA CREDSSP_SecPkgInfoA;
-extern const SecPkgInfoW CREDSSP_SecPkgInfoW;
-
 extern const SecurityFunctionTableA NTLM_SecurityFunctionTableA;
 extern const SecurityFunctionTableW NTLM_SecurityFunctionTableW;
+
+extern const SecPkgInfoA CREDSSP_SecPkgInfoA;
+extern const SecPkgInfoW CREDSSP_SecPkgInfoW;
 extern const SecurityFunctionTableA CREDSSP_SecurityFunctionTableA;
 extern const SecurityFunctionTableW CREDSSP_SecurityFunctionTableW;
 
+extern const SecPkgInfoA SCHANNEL_SecPkgInfoA;
+extern const SecPkgInfoW SCHANNEL_SecPkgInfoW;
+extern const SecurityFunctionTableA SCHANNEL_SecurityFunctionTableA;
+extern const SecurityFunctionTableW SCHANNEL_SecurityFunctionTableW;
+
 const SecPkgInfoA* SecPkgInfoA_LIST[] =
 {
        &NTLM_SecPkgInfoA,
-       &CREDSSP_SecPkgInfoA
+       &CREDSSP_SecPkgInfoA,
+       &SCHANNEL_SecPkgInfoA
 };
 
 const SecPkgInfoW* SecPkgInfoW_LIST[] =
 {
        &NTLM_SecPkgInfoW,
-       &CREDSSP_SecPkgInfoW
+       &CREDSSP_SecPkgInfoW,
+       &SCHANNEL_SecPkgInfoW
 };
 
 SecurityFunctionTableA SSPI_SecurityFunctionTableA;
@@ -80,16 +87,19 @@ typedef struct _SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME;
 const SecurityFunctionTableA_NAME SecurityFunctionTableA_NAME_LIST[] =
 {
        { "NTLM", &NTLM_SecurityFunctionTableA },
-       { "CREDSSP", &CREDSSP_SecurityFunctionTableA }
+       { "CREDSSP", &CREDSSP_SecurityFunctionTableA },
+       { "Schannel", &SCHANNEL_SecurityFunctionTableA }
 };
 
 WCHAR NTLM_NAME_W[] = { 'N','T','L','M','\0' };
 WCHAR CREDSSP_NAME_W[] = { 'C','r','e','d','S','S','P','\0' };
+WCHAR SCHANNEL_NAME_W[] = { 'S','c','h','a','n','n','e','l','\0' };
 
 const SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME_LIST[] =
 {
        { NTLM_NAME_W, &NTLM_SecurityFunctionTableW },
-       { CREDSSP_NAME_W, &CREDSSP_SecurityFunctionTableW }
+       { CREDSSP_NAME_W, &CREDSSP_SecurityFunctionTableW },
+       { SCHANNEL_NAME_W, &SCHANNEL_SecurityFunctionTableW }
 };
 
 #endif
index dddaa99..dba3e75 100644 (file)
@@ -8,7 +8,8 @@ set(${MODULE_PREFIX}_TESTS
        TestQuerySecurityPackageInfo.c
        TestEnumerateSecurityPackages.c
        TestInitializeSecurityContext.c
-       TestAcquireCredentialsHandle.c)
+       TestAcquireCredentialsHandle.c
+       TestSchannel.c)
 
 create_test_sourcelist(${MODULE_PREFIX}_SRCS
        ${${MODULE_PREFIX}_DRIVER}
@@ -23,7 +24,7 @@ endif()
 set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
        MONOLITHIC ${MONOLITHIC_BUILD}
        MODULE winpr
-       MODULES winpr-sspi)
+       MODULES winpr-sspi winpr-thread)
 
 target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
 
diff --git a/winpr/libwinpr/sspi/test/TestSchannel.c b/winpr/libwinpr/sspi/test/TestSchannel.c
new file mode 100644 (file)
index 0000000..15bf1e6
--- /dev/null
@@ -0,0 +1,158 @@
+
+#include <winpr/crt.h>
+#include <winpr/sspi.h>
+#include <winpr/thread.h>
+#include <winpr/schannel.h>
+
+static void* schannel_test_server_thread(void* arg)
+{
+       UINT32 cbMaxToken;
+       SCHANNEL_CRED cred;
+       CredHandle credentials;
+       SECURITY_STATUS status;
+       PSecPkgInfo pPackageInfo;
+       PSecurityFunctionTable table;
+
+       table = InitSecurityInterface();
+
+       status = QuerySecurityPackageInfo(SCHANNEL_NAME, &pPackageInfo);
+
+       if (status != SEC_E_OK)
+       {
+               printf("QuerySecurityPackageInfo failure: 0x%08X\n", status);
+               return -1;
+       }
+
+       cbMaxToken = pPackageInfo->cbMaxToken;
+
+       ZeroMemory(&cred, sizeof(SCHANNEL_CRED));
+       cred.dwVersion = SCHANNEL_CRED_VERSION;
+       cred.cSupportedAlgs = 0;
+       cred.palgSupportedAlgs = NULL;
+
+       status = table->AcquireCredentialsHandle(NULL, SCHANNEL_NAME,
+                       SECPKG_CRED_INBOUND, NULL, &cred, NULL, NULL, &credentials, NULL);
+
+       if (status != SEC_E_OK)
+       {
+               printf("AcquireCredentialsHandle failure: 0x%08X\n", status);
+               return -1;
+       }
+
+       return NULL;
+}
+
+int TestSchannel(int argc, char* argv[])
+{
+       HANDLE ServerThread;
+       UINT32 cbMaxToken;
+       SCHANNEL_CRED cred;
+       UINT32 fContextReq;
+       ULONG fContextAttr;
+       CtxtHandle context;
+       CredHandle credentials;
+       SECURITY_STATUS status;
+       PSecPkgInfo pPackageInfo;
+       SecBuffer SecBuffer_in[2];
+       SecBuffer SecBuffer_out[1];
+       SecBufferDesc SecBufferDesc_in;
+       SecBufferDesc SecBufferDesc_out;
+       PSecurityFunctionTable table;
+       SecPkgCred_SupportedAlgs SupportedAlgs;
+       SecPkgCred_CipherStrengths CipherStrengths;
+       SecPkgCred_SupportedProtocols SupportedProtocols;
+
+       sspi_GlobalInit();
+
+       CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) schannel_test_server_thread, NULL, 0, NULL);
+
+       table = InitSecurityInterface();
+
+       status = QuerySecurityPackageInfo(SCHANNEL_NAME, &pPackageInfo);
+
+       if (status != SEC_E_OK)
+       {
+               printf("QuerySecurityPackageInfo failure: 0x%08X\n", status);
+               return -1;
+       }
+
+       cbMaxToken = pPackageInfo->cbMaxToken;
+
+       ZeroMemory(&cred, sizeof(SCHANNEL_CRED));
+       cred.dwVersion = SCHANNEL_CRED_VERSION;
+       cred.cSupportedAlgs = 0;
+       cred.palgSupportedAlgs = NULL;
+
+       status = table->AcquireCredentialsHandle(NULL, SCHANNEL_NAME,
+                       SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &credentials, NULL);
+
+       if (status != SEC_E_OK)
+       {
+               printf("AcquireCredentialsHandle failure: 0x%08X\n", status);
+               return -1;
+       }
+
+       ZeroMemory(&SupportedAlgs, sizeof(SecPkgCred_SupportedAlgs));
+       status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_SUPPORTED_ALGS, &SupportedAlgs);
+
+       if (status != SEC_E_OK)
+       {
+               printf("QueryCredentialsAttributes SECPKG_ATTR_SUPPORTED_ALGS failure: 0x%08X\n", status);
+               return -1;
+       }
+
+       ZeroMemory(&CipherStrengths, sizeof(SecPkgCred_CipherStrengths));
+       status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_CIPHER_STRENGTHS, &CipherStrengths);
+
+       if (status != SEC_E_OK)
+       {
+               printf("QueryCredentialsAttributes SECPKG_ATTR_CIPHER_STRENGTHS failure: 0x%08X\n", status);
+               return -1;
+       }
+
+       ZeroMemory(&SupportedProtocols, sizeof(SecPkgCred_SupportedProtocols));
+       status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_SUPPORTED_PROTOCOLS, &SupportedProtocols);
+
+       if (status != SEC_E_OK)
+       {
+               printf("QueryCredentialsAttributes SECPKG_ATTR_SUPPORTED_PROTOCOLS failure: 0x%08X\n", status);
+               return -1;
+       }
+
+       fContextReq = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR |
+                       ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM | ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_INTEGRITY;
+
+       ZeroMemory(&SecBuffer_in, sizeof(SecBuffer_in));
+       ZeroMemory(&SecBuffer_out, sizeof(SecBuffer_out));
+       ZeroMemory(&SecBufferDesc_in, sizeof(SecBufferDesc));
+       ZeroMemory(&SecBufferDesc_out, sizeof(SecBufferDesc));
+
+       SecBuffer_in[0].BufferType = SECBUFFER_TOKEN;
+       SecBuffer_in[0].pvBuffer = malloc(cbMaxToken);
+       SecBuffer_in[0].cbBuffer = cbMaxToken;
+
+       SecBuffer_in[1].BufferType = SECBUFFER_EMPTY;
+
+       SecBufferDesc_in.ulVersion = SECBUFFER_VERSION;
+       SecBufferDesc_in.cBuffers = 2;
+       SecBufferDesc_in.pBuffers = SecBuffer_in;
+
+       SecBuffer_out[0].BufferType = SECBUFFER_TOKEN;
+
+       SecBufferDesc_out.ulVersion = SECBUFFER_VERSION;
+       SecBufferDesc_out.cBuffers = 1;
+       SecBufferDesc_out.pBuffers = SecBuffer_out;
+
+       status = table->InitializeSecurityContext(&credentials, NULL, _T("localhost"),
+                       fContextReq, 0, 0, NULL, 0, &context, &SecBufferDesc_out, &fContextAttr, NULL);
+
+       if (status != SEC_I_CONTINUE_NEEDED)
+       {
+               printf("InitializeSecurityContext unexpected status: 0x%08X\n", status);
+               return -1;
+       }
+
+       sspi_GlobalFinish();
+
+       return 0;
+}