7585 lines
207 KiB
C++
7585 lines
207 KiB
C++
//+--------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996-1996
|
|
//
|
|
// File: tlsrpc.c
|
|
//
|
|
// Contents: Various RPC function to accept client request
|
|
//
|
|
// History: 12-09-98 HueiWang Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
#include "pch.cpp"
|
|
#include "server.h"
|
|
#include "gencert.h"
|
|
#include "kp.h"
|
|
#include "keypack.h"
|
|
#include "clilic.h"
|
|
#include "postjob.h"
|
|
#include "srvlist.h"
|
|
#include "utils.h"
|
|
#include "misc.h"
|
|
#include "licreq.h"
|
|
#include "conlic.h"
|
|
#include "globals.h"
|
|
#include "db.h"
|
|
#include "tlscert.h"
|
|
#include "permlic.h"
|
|
#include "remotedb.h"
|
|
|
|
|
|
|
|
CCMutex g_AdminLock;
|
|
CCMutex g_RpcLock;
|
|
CCEvent g_ServerShutDown(TRUE, FALSE);
|
|
|
|
BOOL
|
|
VerifyLicenseRequest(
|
|
PTLSLICENSEREQUEST pLicenseRequest
|
|
)
|
|
/*++
|
|
|
|
--*/
|
|
{
|
|
BOOL bValid = FALSE;
|
|
|
|
if(pLicenseRequest == NULL)
|
|
{
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("VerifyLicenseRequest() invalid input\n")
|
|
);
|
|
|
|
goto cleanup;
|
|
}
|
|
|
|
if( pLicenseRequest->cbEncryptedHwid == 0 ||
|
|
pLicenseRequest->pbEncryptedHwid == NULL)
|
|
{
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("VerifyLicenseRequest() invalid HWID\n")
|
|
);
|
|
|
|
|
|
goto cleanup;
|
|
}
|
|
|
|
if( pLicenseRequest->ProductInfo.cbCompanyName == 0 ||
|
|
pLicenseRequest->ProductInfo.pbCompanyName == NULL )
|
|
{
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("VerifyLicenseRequest() invalid company name\n")
|
|
);
|
|
|
|
|
|
goto cleanup;
|
|
}
|
|
|
|
if( pLicenseRequest->ProductInfo.cbProductID == 0 ||
|
|
pLicenseRequest->ProductInfo.pbProductID == NULL )
|
|
{
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("VerifyLicenseRequest() invalid product id\n")
|
|
);
|
|
|
|
|
|
goto cleanup;
|
|
}
|
|
|
|
bValid = TRUE;
|
|
|
|
cleanup:
|
|
|
|
return bValid;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL
|
|
WaitForMyTurnOrShutdown(
|
|
HANDLE hHandle,
|
|
DWORD dwWaitTime
|
|
)
|
|
/*
|
|
|
|
|
|
*/
|
|
{
|
|
//
|
|
// Shutdown event is first one in the wait list
|
|
// reason is when service thread signal shutdow, at the same time,
|
|
// there might be a RPC call entering WaitForMultipleObjects() call and
|
|
// it will return WAIT_OBJECT_0 and continue on, this is not desirable
|
|
// since we want it to return can't get handle and exit RPC call immediately
|
|
//
|
|
HANDLE waitHandles[2]={g_ServerShutDown.hEvent, hHandle};
|
|
DWORD dwStatus;
|
|
|
|
//
|
|
// Could be return shutting down...
|
|
//
|
|
dwStatus=WaitForMultipleObjects(
|
|
sizeof(waitHandles)/sizeof(waitHandles[0]),
|
|
waitHandles,
|
|
FALSE,
|
|
dwWaitTime
|
|
);
|
|
|
|
return (dwStatus == WAIT_OBJECT_0 + 1) || (dwStatus == WAIT_ABANDONED_0 + 1);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
|
|
HANDLE
|
|
GetServiceShutdownHandle()
|
|
{
|
|
return g_ServerShutDown.hEvent;
|
|
}
|
|
|
|
void
|
|
ServiceSignalShutdown()
|
|
{
|
|
g_ServerShutDown.SetEvent();
|
|
}
|
|
|
|
void
|
|
ServiceResetShutdownEvent()
|
|
{
|
|
g_ServerShutDown.ResetEvent();
|
|
}
|
|
|
|
BOOL
|
|
IsServiceShuttingdown()
|
|
{
|
|
return (WaitForSingleObject(g_ServerShutDown.hEvent, 0) == WAIT_OBJECT_0);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
|
|
BOOL
|
|
AcquireRPCExclusiveLock(
|
|
IN DWORD dwWaitTime
|
|
)
|
|
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Acquire exclusive lock for RPC interface.
|
|
|
|
Parameter:
|
|
|
|
dwWaitTime : Wait time.
|
|
|
|
Return:
|
|
|
|
TRUE/FALSE
|
|
|
|
--*/
|
|
|
|
{
|
|
return WaitForMyTurnOrShutdown(
|
|
g_RpcLock.hMutex,
|
|
dwWaitTime
|
|
);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
|
|
void
|
|
ReleaseRPCExclusiveLock()
|
|
{
|
|
g_RpcLock.Unlock();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
|
|
BOOL
|
|
AcquireAdministrativeLock(
|
|
IN DWORD dwWaitTime
|
|
)
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Acquire lock for administrative action.
|
|
|
|
Parameter:
|
|
|
|
dwWaitTime : Time to wait for the lock.
|
|
|
|
Returns:
|
|
|
|
TRUE/FALSE.
|
|
|
|
--*/
|
|
|
|
{
|
|
return WaitForMyTurnOrShutdown(
|
|
g_AdminLock.hMutex,
|
|
dwWaitTime
|
|
);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
|
|
void
|
|
ReleaseAdministrativeLock()
|
|
/*++
|
|
|
|
--*/
|
|
{
|
|
g_AdminLock.Unlock();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
DWORD
|
|
TLSVerifyHydraCertificate(
|
|
PBYTE pHSCert,
|
|
DWORD cbHSCert
|
|
)
|
|
/*
|
|
|
|
*/
|
|
{
|
|
DWORD dwStatus;
|
|
|
|
dwStatus = TLSVerifyProprietyChainedCertificate(
|
|
g_hCryptProv,
|
|
pHSCert,
|
|
cbHSCert
|
|
);
|
|
|
|
if(dwStatus != ERROR_SUCCESS)
|
|
{
|
|
Hydra_Server_Cert hCert;
|
|
|
|
memset(&hCert, 0, sizeof(Hydra_Server_Cert));
|
|
|
|
dwStatus=UnpackHydraServerCertificate(pHSCert, cbHSCert, &hCert);
|
|
if(dwStatus == LICENSE_STATUS_OK)
|
|
{
|
|
dwStatus=LicenseVerifyServerCert(&hCert);
|
|
|
|
if(hCert.PublicKeyData.pBlob)
|
|
free(hCert.PublicKeyData.pBlob);
|
|
|
|
if(hCert.SignatureBlob.pBlob)
|
|
free(hCert.SignatureBlob.pBlob);
|
|
}
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
//
|
|
// General RPC routines
|
|
//
|
|
|
|
void * __RPC_USER
|
|
MIDL_user_allocate(size_t size)
|
|
{
|
|
void* ptr=AllocateMemory(size);
|
|
|
|
// DBGPrintf(0xFFFFFFFF, _TEXT("Allocate 0x%08x, size %d\n"), ptr, size);
|
|
return ptr;
|
|
}
|
|
|
|
void __RPC_USER
|
|
MIDL_user_free(void *pointer)
|
|
{
|
|
FreeMemory(pointer);
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
BOOL
|
|
ValidContextHandle(
|
|
IN PCONTEXT_HANDLE phContext
|
|
)
|
|
/*++
|
|
Description:
|
|
|
|
Verify client context handle.
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle return from TLSRpcConnect().
|
|
|
|
|
|
Return:
|
|
|
|
TRUE/FALSE
|
|
|
|
++*/
|
|
{
|
|
#if DBG
|
|
|
|
BOOL bValid;
|
|
LPCLIENTCONTEXT lpClientContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
bValid = (lpClientContext->m_PreDbg[0] == 0xcdcdcdcd && lpClientContext->m_PreDbg[1] == 0xcdcdcdcd &&
|
|
lpClientContext->m_PostDbg[0] == 0xcdcdcdcd && lpClientContext->m_PostDbg[1] == 0xcdcdcdcd);
|
|
if(!bValid)
|
|
{
|
|
DBGPrintf(
|
|
DBG_ERROR,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("ValidContextHandle : Bad client context\n")
|
|
);
|
|
|
|
TLSASSERT(FALSE);
|
|
}
|
|
|
|
return bValid;
|
|
|
|
#else
|
|
|
|
return TRUE;
|
|
|
|
#endif
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
void
|
|
__RPC_USER PCONTEXT_HANDLE_rundown(
|
|
PCONTEXT_HANDLE phContext
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Client context handle cleanup, called when client disconnect normally
|
|
or abnormally, see context handle rundown routine help on RPC
|
|
|
|
Argument:
|
|
|
|
phContext - client context handle.
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
++*/
|
|
{
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("PCONTEXT_HANDLE_rundown...\n")
|
|
);
|
|
|
|
TLSASSERT(phContext != NULL);
|
|
|
|
try {
|
|
|
|
//
|
|
// If service is shutting down, exit right away without freeing up memory,
|
|
//
|
|
// Durning shutdown, RPC wait until all call completed but it does not wait
|
|
// until all open connection has 'rundown' if client is still in enumeration,
|
|
// this will cause ReleaseWorkSpace() to assert. Instead of using one more
|
|
// HANDLE to wait until all open connection has been rundown, we return right
|
|
// away to speed up shutdown time
|
|
//
|
|
if( phContext && ValidContextHandle(phContext) )
|
|
{
|
|
LPCLIENTCONTEXT lpClientContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("Disconnect from %s\n"),
|
|
lpClientContext->m_Client
|
|
);
|
|
|
|
assert(lpClientContext->m_RefCount == 0);
|
|
|
|
if( IsServiceShuttingdown() == FALSE )
|
|
{
|
|
switch(lpClientContext->m_ContextType)
|
|
{
|
|
case CONTEXTHANDLE_LICENSE_ENUM_TYPE:
|
|
{
|
|
PTLSDbWorkSpace pDbWkSpace = (PTLSDbWorkSpace)lpClientContext->m_ContextHandle;
|
|
|
|
if( IsValidAllocatedWorkspace(pDbWkSpace) == TRUE )
|
|
{
|
|
ReleaseWorkSpace(&pDbWkSpace);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CONTEXTHANDLE_KEYPACK_ENUM_TYPE:
|
|
{
|
|
LPENUMHANDLE hEnum=(LPENUMHANDLE)lpClientContext->m_ContextHandle;
|
|
|
|
if( IsValidAllocatedWorkspace(hEnum->pbWorkSpace) == TRUE )
|
|
{
|
|
TLSDBLicenseKeyPackEnumEnd(hEnum);
|
|
}
|
|
|
|
lpClientContext->m_ContextType = CONTEXTHANDLE_EMPTY_TYPE;
|
|
lpClientContext->m_ContextHandle=NULL;
|
|
}
|
|
break;
|
|
|
|
case CONTEXTHANDLE_HYDRA_REQUESTCERT_TYPE:
|
|
{
|
|
LPTERMSERVCERTREQHANDLE lpHandle=(LPTERMSERVCERTREQHANDLE)lpClientContext->m_ContextHandle;
|
|
midl_user_free(lpHandle->pCertRequest);
|
|
midl_user_free(lpHandle->pbChallengeData);
|
|
FreeMemory(lpHandle);
|
|
}
|
|
break;
|
|
|
|
case CONTEXTHANDLE_CHALLENGE_SERVER_TYPE:
|
|
case CONTEXTHANDLE_CHALLENGE_LRWIZ_TYPE:
|
|
case CONTEXTHANDLE_CHALLENGE_TERMSRV_TYPE:
|
|
{
|
|
PTLSCHALLENGEDATA pChallengeData = (PTLSCHALLENGEDATA) lpClientContext->m_ContextHandle;
|
|
if(pChallengeData)
|
|
{
|
|
FreeMemory(pChallengeData->pbChallengeData);
|
|
FreeMemory(pChallengeData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("PCONTEXT_HANDLE_rundown while shutting down...\n")
|
|
);
|
|
}
|
|
|
|
if( lpClientContext->m_Client )
|
|
{
|
|
FreeMemory(lpClientContext->m_Client);
|
|
}
|
|
|
|
midl_user_free(lpClientContext);
|
|
}
|
|
}
|
|
catch(...) {
|
|
SetLastError(TLS_E_INTERNAL);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
DWORD
|
|
GetClientPrivilege(
|
|
IN handle_t hRpcBinding
|
|
)
|
|
|
|
/*++
|
|
Description:
|
|
|
|
Return client's privilege level
|
|
|
|
Arguments:
|
|
|
|
hRpcBinding - Client's RPC binding handle.
|
|
|
|
Return:
|
|
|
|
Client's privilege level
|
|
|
|
++*/
|
|
{
|
|
DWORD dwStatus = CLIENT_ACCESS_USER;
|
|
BOOL bAdmin=FALSE;
|
|
RPC_STATUS rpc_status;
|
|
|
|
// If a value of zero is specified, the server impersonates the client that
|
|
// is being served by this server thread
|
|
rpc_status = RpcImpersonateClient(hRpcBinding);
|
|
if(rpc_status == RPC_S_OK)
|
|
{
|
|
IsAdmin(&bAdmin);
|
|
dwStatus = (bAdmin) ? CLIENT_ACCESS_ADMIN : CLIENT_ACCESS_USER;
|
|
|
|
RpcRevertToSelfEx(hRpcBinding);
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcConnect(
|
|
/* [in] */ handle_t binding,
|
|
/* [out] */ PCONTEXT_HANDLE __RPC_FAR *pphContext
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Connect client and allocate/return client context handle.
|
|
|
|
Arguments:
|
|
|
|
hRPCBinding - RPC binding handle
|
|
pphContext - client context handle.
|
|
|
|
Returns via dwErrCode.
|
|
|
|
RPC_S_ACCESS_DENIED or LSERVER_S_SUCCESS.
|
|
|
|
++*/
|
|
{
|
|
DWORD status=ERROR_SUCCESS;
|
|
DWORD dwPriv;
|
|
|
|
RPC_BINDING_HANDLE hClient=NULL;
|
|
WCHAR * pszRpcStrBinding=NULL;
|
|
LPTSTR pszClient=NULL;
|
|
|
|
if(RpcBindingServerFromClient(binding, &hClient) == RPC_S_OK)
|
|
{
|
|
status = RpcBindingToStringBinding( hClient, &pszRpcStrBinding );
|
|
RpcBindingFree(&hClient);
|
|
|
|
if (status != RPC_S_OK)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
//
|
|
// need to load from resource file
|
|
//
|
|
pszClient = (LPTSTR)AllocateMemory(
|
|
(_tcslen((pszRpcStrBinding) ? pszRpcStrBinding : _TEXT("Unknown")) + 1) * sizeof(TCHAR)
|
|
);
|
|
|
|
if(pszClient == NULL)
|
|
{
|
|
status = ERROR_OUTOFMEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
_tcscpy(pszClient,
|
|
(pszRpcStrBinding) ? pszRpcStrBinding : _TEXT("Unknown")
|
|
);
|
|
|
|
if(pszRpcStrBinding)
|
|
{
|
|
RpcStringFree(&pszRpcStrBinding);
|
|
}
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("Connect from client %s\n"),
|
|
pszClient
|
|
);
|
|
|
|
dwPriv=GetClientPrivilege(binding);
|
|
|
|
LPCLIENTCONTEXT lpContext;
|
|
|
|
lpContext=(LPCLIENTCONTEXT)midl_user_allocate(sizeof(CLIENTCONTEXT));
|
|
if(lpContext == NULL)
|
|
{
|
|
status = ERROR_OUTOFMEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_CONNECT;
|
|
lpContext->m_PreDbg[0] = 0xcdcdcdcd;
|
|
lpContext->m_PreDbg[1] = 0xcdcdcdcd;
|
|
lpContext->m_PostDbg[0] = 0xcdcdcdcd;
|
|
lpContext->m_PostDbg[1] = 0xcdcdcdcd;
|
|
#endif
|
|
|
|
lpContext->m_Client = pszClient;
|
|
|
|
lpContext->m_RefCount = 0;
|
|
*pphContext=lpContext;
|
|
lpContext->m_ContextType = CONTEXTHANDLE_EMPTY_TYPE;
|
|
lpContext->m_ClientFlags = dwPriv;
|
|
|
|
cleanup:
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
FreeMemory(pszClient);
|
|
}
|
|
|
|
return TLSMapReturnCode(status);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcDisconnect(
|
|
/* [out][in] */ PPCONTEXT_HANDLE pphContext
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Disconnect client and FreeMemory all memory allocated on the behalf of client
|
|
|
|
Arguments:
|
|
|
|
pphContext - pointer to client context handle
|
|
|
|
Returns:
|
|
|
|
LSERVER_S_SUCCESS or ERROR_INVALID_HANDLE
|
|
|
|
++*/
|
|
{
|
|
DWORD Status=ERROR_SUCCESS;
|
|
|
|
try {
|
|
|
|
if(!ValidContextHandle(*pphContext) || *pphContext == NULL)
|
|
{
|
|
Status = ERROR_INVALID_HANDLE;
|
|
}
|
|
else
|
|
{
|
|
PCONTEXT_HANDLE_rundown(*pphContext);
|
|
*pphContext = NULL;
|
|
}
|
|
|
|
}
|
|
catch(...) {
|
|
Status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
return TLSMapReturnCode(Status);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
error_status_t
|
|
TLSRpcGetVersion(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [ref][out][in] */ PDWORD pdwVersion
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcGetVersion\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
if(TLSIsBetaNTServer() == TRUE)
|
|
{
|
|
*pdwVersion = TLS_CURRENT_VERSION;
|
|
}
|
|
else
|
|
{
|
|
*pdwVersion = TLS_CURRENT_VERSION_RTM;
|
|
}
|
|
|
|
if(g_SrvRole & TLSERVER_ENTERPRISE_SERVER)
|
|
{
|
|
*pdwVersion |= TLS_VERSION_ENTERPRISE_BIT;
|
|
}
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
_TEXT("%s : TLSRpcGetVersion return 0x%08x\n"),
|
|
lpContext->m_Client,
|
|
*pdwVersion
|
|
);
|
|
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcGetSupportFlags(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [ref][out] */ DWORD *pdwSupportFlags
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
error_status_t status = RPC_S_OK;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcGetSupportFlags\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
if (NULL != pdwSupportFlags)
|
|
{
|
|
*pdwSupportFlags = ALL_KNOWN_SUPPORT_FLAGS;
|
|
}
|
|
else
|
|
{
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
return status;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
error_status_t
|
|
TLSRpcSendServerCertificate(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD cbCert,
|
|
/* [size_is][in] */ PBYTE pbCert,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
This routine is for License Server to identify hydra server, hydra server
|
|
need to send its certificate in order to gain certificate request privilege.
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle.
|
|
cbCert - size of hydra server certificate.
|
|
pbCert - hydra server's self-created certificate.
|
|
dwErrCode - return code.
|
|
|
|
Returns via dwErrCode
|
|
|
|
LSERVER_E_INVALID_DATA.
|
|
|
|
++*/
|
|
{
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcSendServerCertificate\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
try {
|
|
|
|
if(pbCert == NULL || cbCert == 0 ||
|
|
TLSVerifyHydraCertificate(pbCert, cbCert) != LICENSE_STATUS_OK)
|
|
{
|
|
DBGPrintf(
|
|
DBG_WARNING,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
_TEXT("TLSRpcSendServerCertificate : client %s send invalid certificate\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
status = TLS_E_INVALID_DATA;
|
|
}
|
|
else
|
|
{
|
|
lpContext->m_ClientFlags |= CLIENT_ACCESS_REQUEST;
|
|
}
|
|
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INVALID_DATA;
|
|
}
|
|
|
|
// midl_user_free(pbCert);
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_SEND_CERTIFICATE;
|
|
#endif
|
|
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcGetServerName(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [size_is][string][out][in] */ LPTSTR szMachineName,
|
|
/* [out][in] */ PDWORD cbSize,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Return server's machine name.
|
|
|
|
Arguments:
|
|
|
|
phContext - Client context handle
|
|
szMachineName - return server's machine name, must be at least
|
|
MAX_COMPUTERNAME_LENGTH + 1 in length
|
|
|
|
Return:
|
|
|
|
TLS_E_INVALID_DATA - buffer size too small.
|
|
|
|
++*/
|
|
{
|
|
// TODO: no need for this buffer - use caller's buffer instead
|
|
|
|
TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+2];
|
|
DWORD dwBufferSize=MAX_COMPUTERNAME_LENGTH+1;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcGetServerName\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
if(lpContext->m_ContextType != CONTEXTHANDLE_CHALLENGE_SERVER_TYPE)
|
|
{
|
|
*dwErrCode = TLSMapReturnCode(TLS_E_INVALID_DATA);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
*dwErrCode = ERROR_SUCCESS;
|
|
if(!GetComputerName(szComputerName, &dwBufferSize))
|
|
{
|
|
*dwErrCode = GetLastError();
|
|
}
|
|
|
|
//
|
|
// return buffer must be big enough for NULL,
|
|
// dwBufferSize return does not include NULL.
|
|
//
|
|
if(*cbSize <= dwBufferSize)
|
|
{
|
|
DBGPrintf(
|
|
DBG_WARNING,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
_TEXT("TLSRpcGetServerName : Client %s invalid parameter\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
*dwErrCode = TLSMapReturnCode(TLS_E_INVALID_DATA);
|
|
}
|
|
else
|
|
{
|
|
_tcsncpy(szMachineName, szComputerName, min(_tcslen(szComputerName), *cbSize));
|
|
szMachineName[min(_tcslen(szComputerName), *cbSize - 1)] = _TEXT('\0');
|
|
}
|
|
|
|
*cbSize = _tcslen(szComputerName) + 1; // include NULL terminate string
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_GET_SERVERNAME;
|
|
#endif
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcGetServerNameEx(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [size_is][string][out][in] */ LPTSTR szMachineName,
|
|
/* [out][in] */ PDWORD cbSize,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Return server's machine name.
|
|
|
|
Arguments:
|
|
|
|
phContext - Client context handle
|
|
szMachineName - return server's machine name, must be at least
|
|
MAX_COMPUTERNAME_LENGTH + 1 in length
|
|
|
|
Return:
|
|
|
|
TLS_E_INVALID_DATA - buffer size too small.
|
|
|
|
++*/
|
|
{
|
|
// TODO: no need for this buffer - use caller's buffer instead
|
|
|
|
TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+2];
|
|
DWORD dwBufferSize=MAX_COMPUTERNAME_LENGTH+1;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcGetServerNameEx\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
*dwErrCode = ERROR_SUCCESS;
|
|
if(!GetComputerName(szComputerName, &dwBufferSize))
|
|
{
|
|
*dwErrCode = GetLastError();
|
|
}
|
|
|
|
//
|
|
// return buffer must be big enough for NULL,
|
|
// dwBufferSize return does not include NULL.
|
|
//
|
|
if(*cbSize <= dwBufferSize)
|
|
{
|
|
DBGPrintf(
|
|
DBG_WARNING,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
_TEXT("TLSRpcGetServerNameEx : Client %s invalid parameter\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
*dwErrCode = TLSMapReturnCode(TLS_E_INVALID_DATA);
|
|
}
|
|
else
|
|
{
|
|
_tcsncpy(szMachineName, szComputerName, min(_tcslen(szComputerName), *cbSize));
|
|
szMachineName[min(_tcslen(szComputerName), *cbSize - 1)] = _TEXT('\0');
|
|
}
|
|
|
|
*cbSize = _tcslen(szComputerName) + 1; // include NULL terminate string
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_GET_SERVERNAME;
|
|
#endif
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcGetServerScope(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [size_is][string][out][in] */ LPTSTR szScopeName,
|
|
/* [out][in] */ PDWORD cbSize,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Return License Server's scope
|
|
|
|
Arguments:
|
|
|
|
phContext - Client context
|
|
szScopeName - return server's scope, must be at least
|
|
MAX_COMPUTERNAME_LENGTH in length
|
|
|
|
Return:
|
|
|
|
LSERVER_S_SUCCESS or error code from WideCharToMultiByte()
|
|
TLS_E_INVALID_DATA - buffer size too small.
|
|
|
|
++*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcGetServerScope\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
*dwErrCode = ERROR_SUCCESS;
|
|
if(*cbSize <= _tcslen(g_pszScope))
|
|
{
|
|
*dwErrCode = TLSMapReturnCode(TLS_E_INVALID_DATA);
|
|
}
|
|
else
|
|
{
|
|
_tcsncpy(szScopeName, g_pszScope, min(_tcslen(g_pszScope), *cbSize));
|
|
szScopeName[min(_tcslen(g_pszScope), *cbSize-1)] = _TEXT('\0');
|
|
}
|
|
|
|
*cbSize = _tcslen(g_pszScope) + 1; // include NULL terminate string
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_GET_SERVERSCOPE;
|
|
#endif
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcGetInfo(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD cbHSCert,
|
|
/* [size_is][in] */ PBYTE pHSCert,
|
|
/* [ref][out] */ DWORD __RPC_FAR *pcbLSCert,
|
|
/* [size_is][size_is][out] */ BYTE __RPC_FAR *__RPC_FAR *pLSCert,
|
|
/* [ref][out] */ DWORD __RPC_FAR *pcbLSSecretKey,
|
|
/* [size_is][size_is][out] */ BYTE __RPC_FAR *__RPC_FAR *pLSSecretKey,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Routine to exchange Hydra server's certificate and License server's
|
|
certificate/private key for signing client machine's hardware ID.
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle
|
|
cbHSCert - size of Hydra Server's certificate
|
|
pHSCert - Hydra Server's certificate
|
|
pcbLSCert - return size of License Server's certificate
|
|
pLSCert - return License Server's certificate
|
|
pcbLSSecretKey - return size of License Server's private key.
|
|
pLSSecretKey - retrun License Server's private key
|
|
|
|
Return Value:
|
|
|
|
LSERVER_S_SUCCESS success
|
|
LSERVER_E_INVALID_DATA Invalid hydra server certificate
|
|
LSERVER_E_OUTOFMEMORY Can't allocate required memory
|
|
TLS_E_INTERNAL Internal error occurred in License Server
|
|
|
|
++*/
|
|
{
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcGetInfo\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
try {
|
|
do {
|
|
if( pHSCert == NULL || cbHSCert == 0 ||
|
|
TLSVerifyHydraCertificate(pHSCert, cbHSCert) != LICENSE_STATUS_OK)
|
|
{
|
|
status= TLS_E_INVALID_DATA;
|
|
break;
|
|
}
|
|
|
|
*pcbLSCert = g_cbSignatureEncodedCert;
|
|
*pLSCert = (PBYTE)midl_user_allocate(*pcbLSCert);
|
|
if(!*pLSCert)
|
|
{
|
|
status = ERROR_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
memcpy(*pLSCert, (PBYTE)g_pbSignatureEncodedCert, *pcbLSCert);
|
|
|
|
*pcbLSSecretKey=0;
|
|
*pLSSecretKey=NULL;
|
|
} while(FALSE);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
if(*pLSCert)
|
|
midl_user_free(*pLSCert);
|
|
|
|
if(*pLSSecretKey)
|
|
midl_user_free(*pLSSecretKey);
|
|
|
|
*pcbLSCert=0;
|
|
*pcbLSSecretKey=0;
|
|
*pLSCert=NULL;
|
|
*pLSSecretKey=NULL;
|
|
}
|
|
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
// midl_user_free(pHSCert);
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_GETINFO;
|
|
#endif
|
|
|
|
lpContext->m_LastError = status;
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
#define RANDOM_CHALLENGE_DATA _TEXT("TEST")
|
|
|
|
DWORD
|
|
TLSGenerateChallengeData(
|
|
IN DWORD ClientInfo,
|
|
OUT PDWORD pcbChallengeData,
|
|
IN OUT PBYTE* pChallengeData
|
|
)
|
|
{
|
|
DWORD hr=ERROR_SUCCESS;
|
|
|
|
*pcbChallengeData = (_tcslen(RANDOM_CHALLENGE_DATA) + 1) * sizeof(WCHAR);
|
|
*pChallengeData=(PBYTE)midl_user_allocate(*pcbChallengeData);
|
|
|
|
if(*pChallengeData)
|
|
{
|
|
memcpy(*pChallengeData, RANDOM_CHALLENGE_DATA, *pcbChallengeData);
|
|
}
|
|
else
|
|
{
|
|
SetLastError(hr=ERROR_OUTOFMEMORY);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//++----------------------------------------------------------------------------
|
|
DWORD
|
|
TLSVerifyChallengeDataGetWantedLicenseLevel(
|
|
IN const CHALLENGE_CONTEXT ChallengeContext,
|
|
IN const DWORD cbChallengeData,
|
|
IN const PBYTE pbChallengeData,
|
|
OUT WORD* pwLicenseDetail
|
|
)
|
|
/*++
|
|
|
|
--*/
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
|
|
DWORD dwChallengeDataSize = (_tcslen(RANDOM_CHALLENGE_DATA) + 1) * sizeof(WCHAR);
|
|
PPlatformChallengeResponseData pChallengeResponse;
|
|
|
|
if( cbChallengeData < dwChallengeDataSize || pbChallengeData == NULL )
|
|
{
|
|
//
|
|
// Assume old client, new client always send back our challenge data
|
|
//
|
|
*pwLicenseDetail = LICENSE_DETAIL_SIMPLE;
|
|
}
|
|
else if( cbChallengeData == dwChallengeDataSize &&
|
|
_tcsicmp( (LPCTSTR)pbChallengeData, RANDOM_CHALLENGE_DATA ) == 0 )
|
|
{
|
|
//
|
|
// old client, set license chain to LICENSE_DETAIL_SIMPLE
|
|
//
|
|
*pwLicenseDetail = LICENSE_DETAIL_SIMPLE;
|
|
}
|
|
else
|
|
{
|
|
BOOL bValidStruct = TRUE;
|
|
|
|
//
|
|
// we still don't have a good challenge so ignore actual verification
|
|
//
|
|
pChallengeResponse = (PPlatformChallengeResponseData) pbChallengeData;
|
|
|
|
bValidStruct = (pChallengeResponse->wVersion == CURRENT_PLATFORMCHALLENGE_VERSION);
|
|
if( bValidStruct == TRUE )
|
|
{
|
|
bValidStruct = (pChallengeResponse->cbChallenge + offsetof(PlatformChallengeResponseData, pbChallenge) == cbChallengeData);
|
|
}
|
|
|
|
if (bValidStruct == TRUE )
|
|
{
|
|
if( pChallengeResponse->wClientType == WIN32_PLATFORMCHALLENGE_TYPE ||
|
|
pChallengeResponse->wClientType == WIN16_PLATFORMCHALLENGE_TYPE ||
|
|
pChallengeResponse->wClientType == WINCE_PLATFORMCHALLENGE_TYPE ||
|
|
pChallengeResponse->wClientType == OTHER_PLATFORMCHALLENGE_TYPE )
|
|
{
|
|
bValidStruct = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bValidStruct = FALSE;
|
|
}
|
|
}
|
|
|
|
if( bValidStruct == TRUE )
|
|
{
|
|
if( pChallengeResponse->wLicenseDetailLevel == LICENSE_DETAIL_SIMPLE ||
|
|
pChallengeResponse->wLicenseDetailLevel == LICENSE_DETAIL_MODERATE ||
|
|
pChallengeResponse->wLicenseDetailLevel == LICENSE_DETAIL_DETAIL )
|
|
{
|
|
bValidStruct = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bValidStruct = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// For now, we simply let it go thru, assert or deny request once
|
|
// we settle down of challenge
|
|
//
|
|
if( bValidStruct == FALSE )
|
|
{
|
|
// bad data, assume old client
|
|
*pwLicenseDetail = LICENSE_DETAIL_SIMPLE;
|
|
}
|
|
//else if( pChallengeResponse->wClientType == WINCE_PLATFORMCHALLENGE_TYPE )
|
|
//{
|
|
//
|
|
// UN-comment this to limit WINCE to get a self-signed certificate
|
|
//
|
|
// *pwLicenseDetail = LICENSE_DETAIL_SIMPLE;
|
|
//}
|
|
else
|
|
{
|
|
*pwLicenseDetail = pChallengeResponse->wLicenseDetailLevel;
|
|
}
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
|
|
//++----------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcIssuePlatformChallenge(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwClientInfo,
|
|
/* [ref][out] */ PCHALLENGE_CONTEXT pChallengeContext,
|
|
/* [out] */ PDWORD pcbChallengeData,
|
|
/* [size_is][size_is][out] */ BYTE __RPC_FAR *__RPC_FAR *pChallengeData,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Issue a platform challenge to hydra client.
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle
|
|
dwClientInfo - client info.
|
|
pChallengeContext - pointer to client challenge context.
|
|
pcbChallengeData - size of challenge data.
|
|
pChallengeData - random client challenge data.
|
|
|
|
Returns via dwErrCode:
|
|
|
|
LSERVER_S_SUCCESS
|
|
LSERVER_E_OUTOFMEMORY Out of memory
|
|
LSERVER_E_INVALID_DATA Invalid client info.
|
|
LSERVER_E_SERVER_BUSY Server is busy
|
|
|
|
++*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
LPCLIENTCHALLENGECONTEXT lpChallenge=NULL;
|
|
DWORD status=ERROR_SUCCESS;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcIssuePlatformChallenge\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
try {
|
|
|
|
do {
|
|
status=TLSGenerateChallengeData(
|
|
dwClientInfo,
|
|
pcbChallengeData,
|
|
pChallengeData
|
|
);
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
|
|
*pChallengeContext = dwClientInfo;
|
|
} while (FALSE);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
if(*pChallengeData)
|
|
{
|
|
midl_user_free(*pChallengeData);
|
|
*pChallengeData = NULL;
|
|
}
|
|
|
|
*pcbChallengeData=0;
|
|
}
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
lpContext->m_LastError=status;
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_ISSUEPLATFORMCHLLENGE;
|
|
#endif
|
|
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcRequestNewLicense(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ const CHALLENGE_CONTEXT ChallengeContext,
|
|
/* [in] */ TLSLICENSEREQUEST __RPC_FAR *pRequest,
|
|
/* [string][in] */ LPTSTR szMachineName,
|
|
/* [string][in] */ LPTSTR szUserName,
|
|
/* [in] */ const DWORD cbChallengeResponse,
|
|
/* [size_is][in] */ const PBYTE pbChallenge,
|
|
/* [in] */ BOOL bAcceptTemporaryLicense,
|
|
/* [out] */ PDWORD pcbLicense,
|
|
/* [size_is][size_is][out] */ BYTE __RPC_FAR *__RPC_FAR *ppbLicense,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Routine to issue new license to hydra client based on product requested,
|
|
it returns existing license if client already has a license and the
|
|
license is not expired/returned/revoked, if request product has not been
|
|
installed, it will issue a temporary license, if license found is temporary
|
|
or expired, it will tried to upgrade/re-issue a new license with latest
|
|
version of requested product, if the existing license is temporary and
|
|
no license can be issued, it returns LSERVER_E_LICENSE_EXPIRED
|
|
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle.
|
|
ChallengeContext - client challenge context handle, return from
|
|
call TLSRpcIssuePlatformChallenge()
|
|
pRequest - product license request.
|
|
pMachineName - client's machine name.
|
|
pUserName - client user name.
|
|
cbChallengeResponse - size of the client's response to license server's
|
|
platform challenge.
|
|
pbChallenge - client's response to license server's platform challenge
|
|
bAcceptTemporaryLicense - TRUE if client wants temp. license FALSE otherwise.
|
|
pcbLicense - size of return license.
|
|
ppLicense - return license, could be old license
|
|
|
|
Return Value:
|
|
|
|
LSERVER_S_SUCCESS
|
|
LSERVER_E_OUTOFMEMORY
|
|
LSERVER_E_SERVER_BUSY Server is busy to process request.
|
|
LSERVER_E_INVALID_DATA Invalid platform challenge response.
|
|
LSERVER_E_NO_LICENSE No license available.
|
|
LSERVER_E_NO_PRODUCT Request product is not installed on server.
|
|
LSERVER_E_LICENSE_REJECTED License request is rejected by cert. server
|
|
LSERVER_E_LICENSE_REVOKED Old license found and has been revoked
|
|
LSERVER_E_LICENSE_EXPIRED Request product's license has expired
|
|
LSERVER_E_CORRUPT_DATABASE Corrupted database.
|
|
LSERVER_E_INTERNAL_ERROR Internal error in license server
|
|
LSERVER_I_PROXIMATE_LICENSE Closest match license returned.
|
|
LSERVER_I_TEMPORARY_LICENSE Temporary license has been issued
|
|
LSERVER_I_LICENSE_UPGRADED Old license has been upgraded.
|
|
++*/
|
|
{
|
|
DWORD dwSupportFlags = 0;
|
|
|
|
return TLSRpcRequestNewLicenseEx(
|
|
phContext,
|
|
&dwSupportFlags,
|
|
ChallengeContext,
|
|
pRequest,
|
|
szMachineName,
|
|
szUserName,
|
|
cbChallengeResponse,
|
|
pbChallenge,
|
|
bAcceptTemporaryLicense,
|
|
1, // dwQuantity
|
|
pcbLicense,
|
|
ppbLicense,
|
|
pdwErrCode
|
|
);
|
|
}
|
|
|
|
error_status_t
|
|
TLSRpcRequestNewLicenseEx(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in, out] */ DWORD *pdwSupportFlags,
|
|
/* [in] */ const CHALLENGE_CONTEXT ChallengeContext,
|
|
/* [in] */ TLSLICENSEREQUEST __RPC_FAR *pRequest,
|
|
/* [string][in] */ LPTSTR szMachineName,
|
|
/* [string][in] */ LPTSTR szUserName,
|
|
/* [in] */ const DWORD cbChallengeResponse,
|
|
/* [size_is][in] */ const PBYTE pbChallenge,
|
|
/* [in] */ BOOL bAcceptTemporaryLicense,
|
|
/* [in] */ DWORD dwQuantity,
|
|
/* [out] */ PDWORD pcbLicense,
|
|
/* [size_is][size_is][out] */ BYTE __RPC_FAR *__RPC_FAR *ppbLicense,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Routine to issue new license to hydra client based on product requested
|
|
and input support flags.
|
|
|
|
*pdwSupportFlags == 0:
|
|
it returns existing license if client already has a license and the
|
|
license is not expired/returned/revoked, if request product has not
|
|
been installed, it will issue a temporary license, if license found is
|
|
temporary or expired, it will tried to upgrade/re-issue a new license
|
|
with latest version of requested product, if the existing license is
|
|
temporary and no license can be issued, it returns
|
|
LSERVER_E_LICENSE_EXPIRED
|
|
|
|
*pdwSupportFlags & SUPPORT_PER_SEAT_POST_LOGON:
|
|
For non-per-seat licenses, it behaves as if the flag wasn't set.
|
|
For per-seat licenses, if bAcceptTemporaryLicense is TRUE, it always
|
|
returns a temporary license. If bAcceptTemporaryLicense if FALSE, it
|
|
returns LSERVER_E_NO_LICENSE.
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle.
|
|
pdwSupportFlags - on input, abilities supported by TS. on output,
|
|
abilities supported by both TS and LS
|
|
ChallengeContext - client challenge context handle, return from
|
|
call TLSRpcIssuePlatformChallenge()
|
|
pRequest - product license request.
|
|
pMachineName - client's machine name.
|
|
pUserName - client user name.
|
|
cbChallengeResponse - size of the client's response to license server's
|
|
platform challenge.
|
|
pbChallenge - client's response to license server's platform challenge
|
|
bAcceptTemporaryLicense - TRUE if client wants temp. license FALSE
|
|
otherwise.
|
|
dwQuantity - number of licenses to allocate
|
|
pcbLicense - size of return license.
|
|
ppLicense - return license, could be old license
|
|
|
|
Return Value:
|
|
|
|
LSERVER_S_SUCCESS
|
|
LSERVER_E_OUTOFMEMORY
|
|
LSERVER_E_SERVER_BUSY Server is busy to process request.
|
|
LSERVER_E_INVALID_DATA Invalid platform challenge response.
|
|
LSERVER_E_NO_LICENSE No license available.
|
|
LSERVER_E_NO_PRODUCT Request product is not installed on server.
|
|
LSERVER_E_LICENSE_REJECTED License request is rejected by cert. server
|
|
LSERVER_E_LICENSE_REVOKED Old license found and has been revoked
|
|
LSERVER_E_LICENSE_EXPIRED Request product's license has expired
|
|
LSERVER_E_CORRUPT_DATABASE Corrupted database.
|
|
LSERVER_E_INTERNAL_ERROR Internal error in license server
|
|
LSERVER_I_PROXIMATE_LICENSE Closest match license returned.
|
|
LSERVER_I_TEMPORARY_LICENSE Temporary license has been issued
|
|
LSERVER_I_LICENSE_UPGRADED Old license has been upgraded.
|
|
++*/
|
|
{
|
|
return TLSRpcRequestNewLicenseExEx(
|
|
phContext,
|
|
pdwSupportFlags,
|
|
ChallengeContext,
|
|
pRequest,
|
|
szMachineName,
|
|
szUserName,
|
|
cbChallengeResponse,
|
|
pbChallenge,
|
|
bAcceptTemporaryLicense,
|
|
FALSE, // bAcceptFewerLicense
|
|
&dwQuantity,
|
|
pcbLicense,
|
|
ppbLicense,
|
|
pdwErrCode
|
|
);
|
|
}
|
|
|
|
error_status_t
|
|
TLSRpcRequestNewLicenseExEx(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in, out] */ DWORD *pdwSupportFlags,
|
|
/* [in] */ const CHALLENGE_CONTEXT ChallengeContext,
|
|
/* [in] */ TLSLICENSEREQUEST __RPC_FAR *pRequest,
|
|
/* [string][in] */ LPTSTR szMachineName,
|
|
/* [string][in] */ LPTSTR szUserName,
|
|
/* [in] */ const DWORD cbChallengeResponse,
|
|
/* [size_is][in] */ const PBYTE pbChallenge,
|
|
/* [in] */ BOOL bAcceptTemporaryLicense,
|
|
/* [in] */ BOOL bAcceptFewerLicenses,
|
|
/* [in,out] */ DWORD *pdwQuantity,
|
|
/* [out] */ PDWORD pcbLicense,
|
|
/* [size_is][size_is][out] */ BYTE __RPC_FAR *__RPC_FAR *ppbLicense,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Routine to issue new license to hydra client based on product requested
|
|
and input support flags.
|
|
|
|
*pdwSupportFlags == 0:
|
|
it returns existing license if client already has a license and the
|
|
license is not expired/returned/revoked, if request product has not
|
|
been installed, it will issue a temporary license, if license found is
|
|
temporary or expired, it will tried to upgrade/re-issue a new license
|
|
with latest version of requested product, if the existing license is
|
|
temporary and no license can be issued, it returns
|
|
LSERVER_E_LICENSE_EXPIRED
|
|
|
|
*pdwSupportFlags & SUPPORT_PER_SEAT_POST_LOGON:
|
|
For non-per-seat licenses, it behaves as if the flag wasn't set.
|
|
For per-seat licenses, if bAcceptTemporaryLicense is TRUE, it always
|
|
returns a temporary license. If bAcceptTemporaryLicense if FALSE, it
|
|
returns LSERVER_E_NO_LICENSE.
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle.
|
|
pdwSupportFlags - on input, abilities supported by TS. on output,
|
|
abilities supported by both TS and LS
|
|
ChallengeContext - client challenge context handle, return from
|
|
call TLSRpcIssuePlatformChallenge()
|
|
pRequest - product license request.
|
|
pMachineName - client's machine name.
|
|
pUserName - client user name.
|
|
cbChallengeResponse - size of the client's response to license server's
|
|
platform challenge.
|
|
pbChallenge - client's response to license server's platform challenge
|
|
bAcceptTemporaryLicense - TRUE if client wants temp. license FALSE
|
|
otherwise.
|
|
bAcceptFewerLicenses - TRUE if succeeding with fewer licenses than
|
|
requested is acceptable
|
|
pdwQuantity - on input, number of licenses to allocate. on output,
|
|
number of licenses actually allocated
|
|
pcbLicense - size of return license.
|
|
ppLicense - return license, could be old license
|
|
|
|
Return Value:
|
|
|
|
LSERVER_S_SUCCESS
|
|
LSERVER_E_OUTOFMEMORY
|
|
LSERVER_E_SERVER_BUSY Server is busy to process request.
|
|
LSERVER_E_INVALID_DATA Invalid platform challenge response.
|
|
LSERVER_E_NO_LICENSE No license available.
|
|
LSERVER_E_NO_PRODUCT Request product is not installed on server.
|
|
LSERVER_E_LICENSE_REJECTED License request is rejected by cert. server
|
|
LSERVER_E_LICENSE_REVOKED Old license found and has been revoked
|
|
LSERVER_E_LICENSE_EXPIRED Request product's license has expired
|
|
LSERVER_E_CORRUPT_DATABASE Corrupted database.
|
|
LSERVER_E_INTERNAL_ERROR Internal error in license server
|
|
LSERVER_I_PROXIMATE_LICENSE Closest match license returned.
|
|
LSERVER_I_TEMPORARY_LICENSE Temporary license has been issued
|
|
LSERVER_I_LICENSE_UPGRADED Old license has been upgraded.
|
|
++*/
|
|
{
|
|
PMHANDLE hClient;
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
TCHAR szUnknown[LSERVER_MAX_STRING_SIZE+1];
|
|
TCHAR szClientMachineName[LSERVER_MAX_STRING_SIZE];
|
|
TCHAR szClientUserName[LSERVER_MAX_STRING_SIZE];
|
|
TCHAR szCompanyName[LSERVER_MAX_STRING_SIZE+1];
|
|
TCHAR szProductId[LSERVER_MAX_STRING_SIZE+1];
|
|
|
|
TLSForwardNewLicenseRequest Forward;
|
|
TLSDBLICENSEREQUEST LsLicenseRequest;
|
|
CTLSPolicy* pPolicy=NULL;
|
|
|
|
PMLICENSEREQUEST PMLicenseRequest;
|
|
PPMLICENSEREQUEST pAdjustedRequest;
|
|
BOOL bForwardRequest = TRUE;
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
#ifdef DBG
|
|
DWORD dwStartTime=GetTickCount();
|
|
#endif
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcRequestNewLicense\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
if ((NULL == pdwQuantity) || (0 == *pdwQuantity))
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(VerifyLicenseRequest(pRequest) == FALSE)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(NULL == pdwSupportFlags)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
*pdwSupportFlags &= ALL_KNOWN_SUPPORT_FLAGS;
|
|
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_REQUEST))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(lpContext->m_ClientFlags == CLIENT_ACCESS_LSERVER)
|
|
{
|
|
//
|
|
// do not forward any request or infinite loop might
|
|
// occur.
|
|
//
|
|
bForwardRequest = FALSE;
|
|
}
|
|
|
|
Forward.m_ChallengeContext = ChallengeContext;
|
|
Forward.m_pRequest = pRequest;
|
|
Forward.m_szMachineName = szMachineName;
|
|
Forward.m_szUserName = szUserName;
|
|
Forward.m_cbChallengeResponse = cbChallengeResponse;
|
|
Forward.m_pbChallengeResponse = pbChallenge;
|
|
|
|
memset(szCompanyName, 0, sizeof(szCompanyName));
|
|
memset(szProductId, 0, sizeof(szProductId));
|
|
|
|
memcpy(
|
|
szCompanyName,
|
|
pRequest->ProductInfo.pbCompanyName,
|
|
min(pRequest->ProductInfo.cbCompanyName, sizeof(szCompanyName)-sizeof(TCHAR))
|
|
);
|
|
|
|
memcpy(
|
|
szProductId,
|
|
pRequest->ProductInfo.pbProductID,
|
|
min(pRequest->ProductInfo.cbProductID, sizeof(szProductId)-sizeof(TCHAR))
|
|
);
|
|
|
|
//
|
|
// Acquire policy module, a default policy module will
|
|
// be returned.
|
|
//
|
|
pPolicy = AcquirePolicyModule(
|
|
szCompanyName, //(LPCTSTR)pRequest->ProductInfo.pbCompanyName,
|
|
szProductId, //(LPCTSTR)pRequest->ProductInfo.pbProductID
|
|
FALSE
|
|
);
|
|
|
|
if(pPolicy == NULL)
|
|
{
|
|
status = TLS_E_INTERNAL;
|
|
goto cleanup;
|
|
}
|
|
|
|
hClient = GenerateClientId();
|
|
|
|
//
|
|
// return error if string is too big.
|
|
//
|
|
LoadResourceString(
|
|
IDS_UNKNOWN_STRING,
|
|
szUnknown,
|
|
sizeof(szUnknown)/sizeof(szUnknown[0])
|
|
);
|
|
|
|
_tcsncpy(szClientMachineName,
|
|
(szMachineName) ? szMachineName : szUnknown,
|
|
LSERVER_MAX_STRING_SIZE
|
|
);
|
|
|
|
szClientMachineName[LSERVER_MAX_STRING_SIZE-1] = 0;
|
|
|
|
_tcsncpy(szClientUserName,
|
|
(szUserName) ? szUserName : szUnknown,
|
|
LSERVER_MAX_STRING_SIZE
|
|
);
|
|
|
|
szClientUserName[LSERVER_MAX_STRING_SIZE-1] = 0;
|
|
|
|
//
|
|
// Convert request to PMLICENSEREQUEST
|
|
//
|
|
TlsLicenseRequestToPMLicenseRequest(
|
|
LICENSETYPE_LICENSE,
|
|
pRequest,
|
|
szClientMachineName,
|
|
szClientUserName,
|
|
*pdwSupportFlags,
|
|
&PMLicenseRequest
|
|
);
|
|
|
|
//
|
|
// Inform Policy module start of new license request
|
|
//
|
|
status = pPolicy->PMLicenseRequest(
|
|
hClient,
|
|
REQUEST_NEW,
|
|
(PVOID) &PMLicenseRequest,
|
|
(PVOID *) &pAdjustedRequest
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
if(pAdjustedRequest != NULL)
|
|
{
|
|
if(_tcsicmp(PMLicenseRequest.pszCompanyName,pAdjustedRequest->pszCompanyName) != 0)
|
|
{
|
|
// try to steal license from other company???
|
|
TLSLogEvent(
|
|
EVENTLOG_ERROR_TYPE,
|
|
TLS_E_POLICYERROR,
|
|
status = TLS_E_POLICYMODULEERROR,
|
|
pPolicy->GetCompanyName(),
|
|
pPolicy->GetProductId()
|
|
);
|
|
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pAdjustedRequest = &PMLicenseRequest;
|
|
}
|
|
|
|
//
|
|
// form DB request structure
|
|
//
|
|
status = TLSFormDBRequest(
|
|
pRequest->pbEncryptedHwid,
|
|
pRequest->cbEncryptedHwid,
|
|
pAdjustedRequest->dwProductVersion,
|
|
pAdjustedRequest->pszCompanyName,
|
|
pAdjustedRequest->pszProductId,
|
|
pAdjustedRequest->dwLanguageId,
|
|
pAdjustedRequest->dwPlatformId,
|
|
pAdjustedRequest->pszMachineName,
|
|
pAdjustedRequest->pszUserName,
|
|
&LsLicenseRequest
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
LsLicenseRequest.pPolicy = pPolicy;
|
|
LsLicenseRequest.hClient = hClient;
|
|
LsLicenseRequest.pPolicyLicenseRequest = pAdjustedRequest;
|
|
LsLicenseRequest.pClientLicenseRequest = &PMLicenseRequest;
|
|
|
|
try {
|
|
status = TLSVerifyChallengeDataGetWantedLicenseLevel(
|
|
ChallengeContext,
|
|
cbChallengeResponse,
|
|
pbChallenge,
|
|
&LsLicenseRequest.wLicenseDetail
|
|
);
|
|
|
|
if( status == ERROR_SUCCESS )
|
|
{
|
|
status = TLSNewLicenseRequest(
|
|
bForwardRequest,
|
|
pdwSupportFlags,
|
|
&Forward,
|
|
&LsLicenseRequest,
|
|
bAcceptTemporaryLicense,
|
|
pAdjustedRequest->fTemporary,
|
|
TRUE, // bFindLostLicense
|
|
bAcceptFewerLicenses,
|
|
pdwQuantity,
|
|
pcbLicense,
|
|
ppbLicense
|
|
);
|
|
}
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
cleanup:
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_ISSUENEWLICENSE;
|
|
#endif
|
|
|
|
#ifdef DBG
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
_TEXT("\t%s : TLSRpcRequestNewLicense() takes %dms\n"),
|
|
lpContext->m_Client,
|
|
GetTickCount() - dwStartTime
|
|
);
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(status);
|
|
|
|
if(pPolicy)
|
|
{
|
|
pPolicy->PMLicenseRequest(
|
|
hClient,
|
|
REQUEST_COMPLETE,
|
|
UlongToPtr(status),
|
|
NULL
|
|
);
|
|
|
|
ReleasePolicyModule(pPolicy);
|
|
}
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcUpgradeLicense(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ TLSLICENSEREQUEST __RPC_FAR *pRequest,
|
|
/* [in] */ const CHALLENGE_CONTEXT ChallengeContext,
|
|
/* [in] */ const DWORD cbChallengeResponse,
|
|
/* [size_is][in] */ const PBYTE pbChallenge,
|
|
/* [in] */ DWORD cbOldLicense,
|
|
/* [size_is][in] */ PBYTE pbOldLicense,
|
|
/* [out] */ PDWORD pcbNewLicense,
|
|
/* [size_is][size_is][out] */ PBYTE __RPC_FAR *ppbNewLicense,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Update an old license.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
LSERVER_S_SUCCESS
|
|
TLS_E_INTERNAL
|
|
LSERVER_E_INTERNAL_ERROR
|
|
LSERVER_E_INVALID_DATA old license is invalid.
|
|
LSERVER_E_NO_LICENSE no available license
|
|
LSERVER_E_NO_PRODUCT request product not install in current server.
|
|
LSERVER_E_CORRUPT_DATABASE Corrupted database.
|
|
LSERVER_E_LICENSE_REJECTED License request rejected by cert. server.
|
|
LSERVER_E_SERVER_BUSY
|
|
|
|
++*/
|
|
{
|
|
DWORD dwSupportFlags = 0;
|
|
|
|
return TLSRpcUpgradeLicenseEx(
|
|
phContext,
|
|
&dwSupportFlags,
|
|
pRequest,
|
|
ChallengeContext,
|
|
cbChallengeResponse,
|
|
pbChallenge,
|
|
cbOldLicense,
|
|
pbOldLicense,
|
|
1, // dwQuantity
|
|
pcbNewLicense,
|
|
ppbNewLicense,
|
|
dwErrCode
|
|
);
|
|
|
|
}
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcUpgradeLicenseEx(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in,out] */ DWORD *pdwSupportFlags,
|
|
/* [in] */ TLSLICENSEREQUEST __RPC_FAR *pRequest,
|
|
/* [in] */ const CHALLENGE_CONTEXT ChallengeContext,
|
|
/* [in] */ const DWORD cbChallengeResponse,
|
|
/* [size_is][in] */ const PBYTE pbChallenge,
|
|
/* [in] */ DWORD cbOldLicense,
|
|
/* [size_is][in] */ PBYTE pbOldLicense,
|
|
/* [in] */ DWORD dwQuantity,
|
|
/* [out] */ PDWORD pcbNewLicense,
|
|
/* [size_is][size_is][out] */ PBYTE __RPC_FAR *ppbNewLicense,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Update an old license. Behavior varies depending on product requested,
|
|
the old license, and input support flags.
|
|
|
|
*pdwSupportFlags == 0:
|
|
it returns existing license if client already has a current-version
|
|
license and the license is not expired/returned/revoked. if requested
|
|
product has not been installed, it will issue a temporary license (if
|
|
the client doesn't already have one). if old license is temporary
|
|
or expired, it will try to upgrade/re-issue a new license
|
|
with latest version of requested product. if the existing license is
|
|
temporary and no license can be issued, it returns
|
|
LSERVER_E_LICENSE_EXPIRED
|
|
|
|
*pdwSupportFlags & SUPPORT_PER_SEAT_POST_LOGON:
|
|
For non-per-seat licenses, it behaves as if the flag wasn't set.
|
|
For per-seat licenses, if the old license isn't current-version
|
|
temporary, it also behaves as if the flag wasn't set.
|
|
Otherwise, it checks that the temporary license was marked as having
|
|
been authenticated. If so, it tries to issue a permanent license.
|
|
If a license can't be issued, or if he temporary license wasn't marked,
|
|
it returns the old license.
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle.
|
|
pdwSupportFlags - on input, abilities supported by TS. on output,
|
|
abilities supported by both TS and LS
|
|
pRequest - product license request.
|
|
ChallengeContext - client challenge context handle, return from
|
|
call TLSRpcIssuePlatformChallenge()
|
|
cbChallengeResponse - size of the client's response to license server's
|
|
platform challenge.
|
|
pbChallenge - client's response to license server's platform challenge
|
|
cbOldLicense - size of old license.
|
|
pbOldLicense - old license
|
|
dwQuantity - number of licenses to allocate
|
|
pcbNewLicense - size of return license.
|
|
ppbNewLicense - return license, could be old license
|
|
|
|
Return Value:
|
|
|
|
LSERVER_S_SUCCESS
|
|
TLS_E_INTERNAL
|
|
LSERVER_E_INTERNAL_ERROR
|
|
LSERVER_E_INVALID_DATA old license is invalid.
|
|
LSERVER_E_NO_LICENSE no available license
|
|
LSERVER_E_NO_PRODUCT request product not install in current server.
|
|
LSERVER_E_CORRUPT_DATABASE Corrupted database.
|
|
LSERVER_E_LICENSE_REJECTED License request rejected by cert. server.
|
|
LSERVER_E_SERVER_BUSY
|
|
|
|
++*/
|
|
{
|
|
DWORD status = ERROR_SUCCESS;
|
|
BOOL bTemporaryLicense;
|
|
PMUPGRADEREQUEST pmRequestUpgrade;
|
|
PMLICENSEREQUEST pmLicenseRequest;
|
|
PPMLICENSEREQUEST pmAdjustedRequest;
|
|
PPMLICENSEDPRODUCT ppmLicensedProduct=NULL;
|
|
DWORD dwNumLicensedProduct=0;
|
|
PLICENSEDPRODUCT pLicensedProduct=NULL;
|
|
TLSDBLICENSEREQUEST LsLicenseRequest;
|
|
PMHANDLE hClient;
|
|
CTLSPolicy* pPolicy=NULL;
|
|
DWORD dwNumPermLicense;
|
|
DWORD dwNumTempLicense;
|
|
TLSForwardUpgradeLicenseRequest Forward;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
LICENSEDCLIENT license;
|
|
LICENSEPACK keypack;
|
|
DWORD index;
|
|
BOOL bForwardRequest = TRUE;
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcUpgradeLicense\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
if (1 != dwQuantity)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(VerifyLicenseRequest(pRequest) == FALSE)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(NULL == pdwSupportFlags)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
*pdwSupportFlags &= ALL_KNOWN_SUPPORT_FLAGS;
|
|
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_REQUEST))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(lpContext->m_ClientFlags == CLIENT_ACCESS_LSERVER)
|
|
{
|
|
//
|
|
// do not forward any request or infinite loop might
|
|
// occur.
|
|
//
|
|
bForwardRequest = FALSE;
|
|
}
|
|
|
|
//
|
|
// Convert blob to licensed product structure
|
|
//
|
|
status = LSVerifyDecodeClientLicense(
|
|
pbOldLicense,
|
|
cbOldLicense,
|
|
g_pbSecretKey,
|
|
g_cbSecretKey,
|
|
&dwNumLicensedProduct,
|
|
NULL
|
|
);
|
|
|
|
if(status != LICENSE_STATUS_OK || dwNumLicensedProduct == 0)
|
|
{
|
|
status = TLS_E_INVALID_LICENSE;
|
|
goto cleanup;
|
|
}
|
|
|
|
pLicensedProduct = (PLICENSEDPRODUCT)AllocateMemory(
|
|
dwNumLicensedProduct * sizeof(LICENSEDPRODUCT)
|
|
);
|
|
if(pLicensedProduct == NULL)
|
|
{
|
|
status = TLS_E_ALLOCATE_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
status = LSVerifyDecodeClientLicense(
|
|
pbOldLicense,
|
|
cbOldLicense,
|
|
g_pbSecretKey,
|
|
g_cbSecretKey,
|
|
&dwNumLicensedProduct,
|
|
pLicensedProduct
|
|
);
|
|
|
|
if(status != LICENSE_STATUS_OK)
|
|
{
|
|
status = TLS_E_INVALID_LICENSE;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Verify licensed product array.
|
|
//
|
|
for(index = 1; index < dwNumLicensedProduct; index++)
|
|
{
|
|
//
|
|
// licensed product array always sorted in decending order
|
|
//
|
|
|
|
//
|
|
// Product ID in original request in licensed product must
|
|
// be the same otherwise invalid license.
|
|
//
|
|
if(pLicensedProduct->cbOrgProductID != (pLicensedProduct-1)->cbOrgProductID)
|
|
{
|
|
status = TLS_E_INVALID_LICENSE;
|
|
break;
|
|
}
|
|
|
|
if( memcmp(
|
|
pLicensedProduct->pbOrgProductID,
|
|
(pLicensedProduct-1)->pbOrgProductID,
|
|
pLicensedProduct->cbOrgProductID) != 0 )
|
|
{
|
|
status = TLS_E_INVALID_LICENSE;
|
|
goto cleanup;
|
|
}
|
|
|
|
if( (pLicensedProduct->pLicensedVersion->dwFlags & LICENSED_VERSION_TEMPORARY) )
|
|
{
|
|
//
|
|
// only latest licensed version can be temporary
|
|
//
|
|
status = TLS_E_INVALID_LICENSE;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Find the policy module
|
|
//
|
|
hClient = GenerateClientId();
|
|
|
|
TCHAR szCompanyName[LSERVER_MAX_STRING_SIZE+1];
|
|
TCHAR szProductId[LSERVER_MAX_STRING_SIZE+1];
|
|
|
|
memset(szCompanyName, 0, sizeof(szCompanyName));
|
|
memset(szProductId, 0, sizeof(szProductId));
|
|
|
|
memcpy(
|
|
szCompanyName,
|
|
pRequest->ProductInfo.pbCompanyName,
|
|
min(pRequest->ProductInfo.cbCompanyName, sizeof(szCompanyName)-sizeof(TCHAR))
|
|
);
|
|
|
|
memcpy(
|
|
szProductId,
|
|
pRequest->ProductInfo.pbProductID,
|
|
min(pRequest->ProductInfo.cbProductID, sizeof(szProductId)-sizeof(TCHAR))
|
|
);
|
|
|
|
//
|
|
// Acquire policy module, a default policy module will
|
|
// be returned.
|
|
//
|
|
pPolicy = AcquirePolicyModule(
|
|
szCompanyName, // (LPCTSTR) pLicensedProduct->LicensedProduct.pProductInfo->pbCompanyName,
|
|
szProductId, // (LPCTSTR) pLicensedProduct->pbOrgProductID
|
|
FALSE
|
|
);
|
|
|
|
if(pPolicy == NULL)
|
|
{
|
|
//
|
|
// Must have a policy module, default policy module always there
|
|
//
|
|
status = TLS_E_INTERNAL;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Convert request to PMLICENSEREQUEST
|
|
//
|
|
TlsLicenseRequestToPMLicenseRequest(
|
|
LICENSETYPE_LICENSE,
|
|
pRequest,
|
|
pLicensedProduct->szLicensedClient,
|
|
pLicensedProduct->szLicensedUser,
|
|
*pdwSupportFlags,
|
|
&pmLicenseRequest
|
|
);
|
|
|
|
//
|
|
// generate PMUPGRADEREQUEST and pass it to Policy Module
|
|
//
|
|
memset(&pmRequestUpgrade, 0, sizeof(pmRequestUpgrade));
|
|
|
|
ppmLicensedProduct = (PPMLICENSEDPRODUCT)AllocateMemory(sizeof(PMLICENSEDPRODUCT)*dwNumLicensedProduct);
|
|
if(ppmLicensedProduct == NULL)
|
|
{
|
|
status = TLS_E_ALLOCATE_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
for(index=0; index < dwNumLicensedProduct; index++)
|
|
{
|
|
ppmLicensedProduct[index].pbData =
|
|
pLicensedProduct[index].pbPolicyData;
|
|
|
|
ppmLicensedProduct[index].cbData =
|
|
pLicensedProduct[index].cbPolicyData;
|
|
|
|
ppmLicensedProduct[index].bTemporary =
|
|
((pLicensedProduct[index].pLicensedVersion->dwFlags & LICENSED_VERSION_TEMPORARY) != 0);
|
|
|
|
// treat license issued from beta server as temporary
|
|
if(ppmLicensedProduct[index].bTemporary == FALSE && TLSIsBetaNTServer() == FALSE)
|
|
{
|
|
if(IS_LICENSE_ISSUER_RTM(pLicensedProduct[index].pLicensedVersion->dwFlags) == FALSE)
|
|
{
|
|
ppmLicensedProduct[index].bTemporary = TRUE;
|
|
}
|
|
}
|
|
|
|
ppmLicensedProduct[index].ucMarked = 0;
|
|
|
|
if (0 == index)
|
|
{
|
|
// for first license, check markings on license
|
|
status = TLSCheckLicenseMarkRequest(
|
|
TRUE, // forward request if necessary
|
|
pLicensedProduct,
|
|
cbOldLicense,
|
|
pbOldLicense,
|
|
&(ppmLicensedProduct[index].ucMarked)
|
|
);
|
|
}
|
|
|
|
ppmLicensedProduct[index].LicensedProduct.dwProductVersion =
|
|
pLicensedProduct[index].LicensedProduct.pProductInfo->dwVersion;
|
|
|
|
ppmLicensedProduct[index].LicensedProduct.pszProductId =
|
|
(LPTSTR)(pLicensedProduct[index].LicensedProduct.pProductInfo->pbProductID);
|
|
|
|
ppmLicensedProduct[index].LicensedProduct.pszCompanyName =
|
|
(LPTSTR)(pLicensedProduct[index].LicensedProduct.pProductInfo->pbCompanyName);
|
|
|
|
ppmLicensedProduct[index].LicensedProduct.dwLanguageId =
|
|
pLicensedProduct[index].LicensedProduct.dwLanguageID;
|
|
|
|
ppmLicensedProduct[index].LicensedProduct.dwPlatformId =
|
|
pLicensedProduct[index].LicensedProduct.dwPlatformID;
|
|
|
|
ppmLicensedProduct[index].LicensedProduct.pszMachineName =
|
|
pLicensedProduct[index].szLicensedClient;
|
|
|
|
ppmLicensedProduct[index].LicensedProduct.pszUserName =
|
|
pLicensedProduct[index].szLicensedUser;
|
|
}
|
|
|
|
pmRequestUpgrade.pbOldLicense = pbOldLicense;
|
|
pmRequestUpgrade.cbOldLicense = cbOldLicense;
|
|
pmRequestUpgrade.pUpgradeRequest = &pmLicenseRequest;
|
|
|
|
pmRequestUpgrade.dwNumProduct = dwNumLicensedProduct;
|
|
pmRequestUpgrade.pProduct = ppmLicensedProduct;
|
|
|
|
status = pPolicy->PMLicenseUpgrade(
|
|
hClient,
|
|
REQUEST_UPGRADE,
|
|
(PVOID)&pmRequestUpgrade,
|
|
(PVOID *) &pmAdjustedRequest
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
if(pmAdjustedRequest != NULL)
|
|
{
|
|
if(_tcsicmp(
|
|
pmLicenseRequest.pszCompanyName,
|
|
pmAdjustedRequest->pszCompanyName
|
|
) != 0)
|
|
{
|
|
//
|
|
// Try to steal license from other company???
|
|
//
|
|
TLSLogEvent(
|
|
EVENTLOG_ERROR_TYPE,
|
|
TLS_E_POLICYERROR,
|
|
status = TLS_E_POLICYMODULEERROR,
|
|
pPolicy->GetCompanyName(),
|
|
pPolicy->GetProductId()
|
|
);
|
|
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pmAdjustedRequest = &pmLicenseRequest;
|
|
}
|
|
|
|
for(index =0; index < dwNumLicensedProduct; index++)
|
|
{
|
|
DWORD tExpireDate;
|
|
|
|
FileTimeToLicenseDate(&(pLicensedProduct[index].NotAfter),
|
|
&tExpireDate);
|
|
|
|
if( CompareTLSVersions(pmAdjustedRequest->dwProductVersion, pLicensedProduct[index].LicensedProduct.pProductInfo->dwVersion) <= 0 &&
|
|
!(pLicensedProduct[index].pLicensedVersion->dwFlags & LICENSED_VERSION_TEMPORARY) &&
|
|
_tcscmp(pmAdjustedRequest->pszProductId, (LPTSTR)(pLicensedProduct[index].LicensedProduct.pProductInfo->pbProductID)) == 0 &&
|
|
tExpireDate-g_dwReissueLeaseLeeway >= ((DWORD)time(NULL)) )
|
|
{
|
|
if( TLSIsBetaNTServer() == TRUE ||
|
|
IS_LICENSE_ISSUER_RTM(pLicensedProduct[index].pLicensedVersion->dwFlags) == TRUE )
|
|
{
|
|
//
|
|
// Blob already contain perm. license that is >= version
|
|
// requested.
|
|
//
|
|
*ppbNewLicense = (PBYTE)midl_user_allocate(cbOldLicense);
|
|
if(*ppbNewLicense != NULL)
|
|
{
|
|
memcpy(*ppbNewLicense, pbOldLicense, cbOldLicense);
|
|
*pcbNewLicense = cbOldLicense;
|
|
status = ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
status = TLS_E_ALLOCATE_MEMORY;
|
|
}
|
|
|
|
goto cleanup;
|
|
}
|
|
}
|
|
}
|
|
|
|
memset(&LsLicenseRequest, 0, sizeof(TLSDBLICENSEREQUEST));
|
|
|
|
status = TLSFormDBRequest(
|
|
pRequest->pbEncryptedHwid,
|
|
pRequest->cbEncryptedHwid,
|
|
pmAdjustedRequest->dwProductVersion,
|
|
pmAdjustedRequest->pszCompanyName,
|
|
pmAdjustedRequest->pszProductId,
|
|
pmAdjustedRequest->dwLanguageId,
|
|
pmAdjustedRequest->dwPlatformId,
|
|
pmAdjustedRequest->pszMachineName,
|
|
pmAdjustedRequest->pszUserName,
|
|
&LsLicenseRequest
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
LsLicenseRequest.pPolicy = pPolicy;
|
|
LsLicenseRequest.hClient = hClient;
|
|
LsLicenseRequest.pPolicyLicenseRequest = pmAdjustedRequest;
|
|
LsLicenseRequest.pClientLicenseRequest = &pmLicenseRequest;
|
|
|
|
memset(&keypack, 0, sizeof(keypack));
|
|
|
|
try {
|
|
|
|
status = TLSVerifyChallengeDataGetWantedLicenseLevel(
|
|
ChallengeContext,
|
|
cbChallengeResponse,
|
|
pbChallenge,
|
|
&LsLicenseRequest.wLicenseDetail
|
|
);
|
|
|
|
if( status == ERROR_SUCCESS )
|
|
{
|
|
|
|
//
|
|
// if client challenge context handle is 0xFFFFFFFF,
|
|
// cbChallenge = 0 and pbChallenge is NULL.
|
|
// client is old version, don't verify challenge
|
|
//
|
|
Forward.m_pRequest = pRequest;
|
|
Forward.m_ChallengeContext = ChallengeContext;
|
|
Forward.m_cbChallengeResponse = cbChallengeResponse;
|
|
Forward.m_pbChallengeResponse = pbChallenge;
|
|
Forward.m_cbOldLicense = cbOldLicense;
|
|
Forward.m_pbOldLicense = pbOldLicense;
|
|
|
|
status = TLSUpgradeLicenseRequest(
|
|
bForwardRequest,
|
|
&Forward,
|
|
pdwSupportFlags,
|
|
&LsLicenseRequest,
|
|
pbOldLicense,
|
|
cbOldLicense,
|
|
dwNumLicensedProduct,
|
|
pLicensedProduct,
|
|
pmAdjustedRequest->fTemporary,
|
|
pcbNewLicense,
|
|
ppbNewLicense
|
|
);
|
|
}
|
|
|
|
} // end try
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...)
|
|
{
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
cleanup:
|
|
|
|
FreeMemory(ppmLicensedProduct);
|
|
|
|
for(index =0; index < dwNumLicensedProduct; index++)
|
|
{
|
|
LSFreeLicensedProduct(pLicensedProduct+index);
|
|
}
|
|
|
|
FreeMemory(pLicensedProduct);
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_UPGRADELICENSE;
|
|
#endif
|
|
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
|
|
if(pPolicy)
|
|
{
|
|
pPolicy->PMLicenseRequest(
|
|
hClient,
|
|
REQUEST_COMPLETE,
|
|
UlongToPtr (status),
|
|
NULL
|
|
);
|
|
|
|
ReleasePolicyModule(pPolicy);
|
|
}
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcCheckLicenseMark(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ const DWORD cbLicense,
|
|
/* [in, size_is(cbLicense)] */ PBYTE pbLicense,
|
|
/* [out] */ UCHAR *pucMarkFlags,
|
|
/* [in, out, ref] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Check markings on the passed in license
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle
|
|
cbLicense - size of license to be checked
|
|
pbLicense - license to be checked
|
|
pucMarkFlags - markings on license
|
|
|
|
Return via pdwErrCode:
|
|
LSERVER_S_SUCCESS
|
|
LSERVER_E_INVALID_DATA Invalid parameter.
|
|
LSERVER_E_INVALID_LICENSE License passed in is bad
|
|
LSERVER_E_DATANOTFOUND license not found in database
|
|
LSERVER_E_CORRUPT_DATABASE Corrupt database
|
|
LSERVER_E_INTERNAL_ERROR Internal error in license server
|
|
|
|
Note:
|
|
This function forwards the request to the issuing license server. If
|
|
the issuer isn't available, or doesn't have the license in the database,
|
|
it searches in the local database for a license with the same HWID.
|
|
|
|
++*/
|
|
{
|
|
DWORD status = ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD dwNumLicensedProduct = 0;
|
|
PLICENSEDPRODUCT pLicensedProduct=NULL;
|
|
DWORD index;
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcCheckLicenseMark\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_LSERVER))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
if (NULL == pucMarkFlags)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Convert blob to licensed product structure
|
|
//
|
|
status=LSVerifyDecodeClientLicense(
|
|
pbLicense,
|
|
cbLicense,
|
|
g_pbSecretKey,
|
|
g_cbSecretKey,
|
|
&dwNumLicensedProduct,
|
|
NULL // find size to allocate
|
|
);
|
|
|
|
if(status != LICENSE_STATUS_OK || dwNumLicensedProduct == 0)
|
|
{
|
|
status = TLS_E_INVALID_LICENSE;
|
|
goto cleanup;
|
|
}
|
|
|
|
pLicensedProduct = (PLICENSEDPRODUCT)AllocateMemory(
|
|
dwNumLicensedProduct * sizeof(LICENSEDPRODUCT)
|
|
);
|
|
|
|
if(pLicensedProduct == NULL)
|
|
{
|
|
status = TLS_E_ALLOCATE_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
status=LSVerifyDecodeClientLicense(
|
|
pbLicense,
|
|
cbLicense,
|
|
g_pbSecretKey,
|
|
g_cbSecretKey,
|
|
&dwNumLicensedProduct,
|
|
pLicensedProduct
|
|
);
|
|
|
|
if(status != LICENSE_STATUS_OK)
|
|
{
|
|
status = TLS_E_INVALID_LICENSE;
|
|
goto cleanup;
|
|
}
|
|
|
|
try {
|
|
|
|
status = TLSCheckLicenseMarkRequest(
|
|
FALSE, // don't forward the request
|
|
pLicensedProduct,
|
|
cbLicense,
|
|
pbLicense,
|
|
pucMarkFlags
|
|
);
|
|
} // end try
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...)
|
|
{
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
|
|
cleanup:
|
|
|
|
for(index =0; index < dwNumLicensedProduct; index++)
|
|
{
|
|
LSFreeLicensedProduct(pLicensedProduct+index);
|
|
}
|
|
|
|
FreeMemory(pLicensedProduct);
|
|
|
|
lpContext->m_LastError=status;
|
|
|
|
*pdwErrCode = TLSMapReturnCode(status);
|
|
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcMarkLicense(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ UCHAR ucMarkFlags,
|
|
/* [in] */ const DWORD cbLicense,
|
|
/* [in, size_is(cbLicense)] */ PBYTE pbLicense,
|
|
/* [in, out, ref] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Set markings on the passed in license
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle
|
|
ucMarkFlags - markings on license
|
|
cbLicense - size of license to be checked
|
|
pbLicense - license to be checked
|
|
|
|
Return via pdwErrCode:
|
|
LSERVER_S_SUCCESS
|
|
LSERVER_E_INVALID_DATA Invalid parameter.
|
|
LSERVER_E_INVALID_LICENSE License passed in is bad
|
|
LSERVER_E_DATANOTFOUND license not found in database
|
|
LSERVER_E_CORRUPT_DATABASE Corrupt database
|
|
LSERVER_E_INTERNAL_ERROR Internal error in license server
|
|
|
|
Note:
|
|
This function forwards the request to the issuing license server. The
|
|
issuer modifies the database entry of the license to set the markings.
|
|
|
|
++*/
|
|
{
|
|
DWORD status = ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
BOOL bForwardRequest = TRUE;
|
|
DWORD dwNumLicensedProduct = 0;
|
|
PLICENSEDPRODUCT pLicensedProduct=NULL;
|
|
DWORD index;
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcMarkLicense\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_REQUEST))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(lpContext->m_ClientFlags == CLIENT_ACCESS_LSERVER)
|
|
{
|
|
//
|
|
// do not forward any request or infinite loop might
|
|
// occur.
|
|
//
|
|
bForwardRequest = FALSE;
|
|
}
|
|
|
|
//
|
|
// Convert blob to licensed product structure
|
|
//
|
|
status=LSVerifyDecodeClientLicense(
|
|
pbLicense,
|
|
cbLicense,
|
|
g_pbSecretKey,
|
|
g_cbSecretKey,
|
|
&dwNumLicensedProduct,
|
|
NULL // find size to allocate
|
|
);
|
|
|
|
if(status != LICENSE_STATUS_OK || dwNumLicensedProduct == 0)
|
|
{
|
|
status = TLS_E_INVALID_LICENSE;
|
|
goto cleanup;
|
|
}
|
|
|
|
pLicensedProduct = (PLICENSEDPRODUCT)AllocateMemory(
|
|
dwNumLicensedProduct * sizeof(LICENSEDPRODUCT)
|
|
);
|
|
|
|
if(pLicensedProduct == NULL)
|
|
{
|
|
status = TLS_E_ALLOCATE_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
status=LSVerifyDecodeClientLicense(
|
|
pbLicense,
|
|
cbLicense,
|
|
g_pbSecretKey,
|
|
g_cbSecretKey,
|
|
&dwNumLicensedProduct,
|
|
pLicensedProduct
|
|
);
|
|
|
|
if(status != LICENSE_STATUS_OK)
|
|
{
|
|
status = TLS_E_INVALID_LICENSE;
|
|
goto cleanup;
|
|
}
|
|
|
|
try {
|
|
|
|
status = TLSMarkLicenseRequest(
|
|
bForwardRequest,
|
|
ucMarkFlags,
|
|
pLicensedProduct,
|
|
cbLicense,
|
|
pbLicense
|
|
);
|
|
} // end try
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...)
|
|
{
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
|
|
cleanup:
|
|
|
|
for(index =0; index < dwNumLicensedProduct; index++)
|
|
{
|
|
LSFreeLicensedProduct(pLicensedProduct+index);
|
|
}
|
|
|
|
FreeMemory(pLicensedProduct);
|
|
|
|
lpContext->m_LastError=status;
|
|
|
|
*pdwErrCode = TLSMapReturnCode(status);
|
|
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcAllocateConcurrentLicense(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [string][in] */ LPTSTR szHydraServer,
|
|
/* [in] */ TLSLICENSEREQUEST __RPC_FAR *pRequest,
|
|
/* [ref][out][in] */ LONG __RPC_FAR *pdwQuantity,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Allocate concurrent licenses base on product.
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle
|
|
szHydraServer - name of hydra server requesting concurrent licenses
|
|
pRequest - product to request for concurrent license.
|
|
dwQuantity - See note
|
|
|
|
Return via dwErrCode:
|
|
LSERVER_S_SUCCESS
|
|
LSERVER_E_INVALID_DATA Invalid parameter.
|
|
LSERVER_E_NO_PRODUCT request product not installed
|
|
LSERVER_E_NO_LICNESE no available license for request product
|
|
LSERVER_E_LICENSE_REVOKED Request license has been revoked
|
|
LSERVER_E_LICENSE_EXPIRED Request license has expired
|
|
LSERVER_E_CORRUPT_DATABASE Corrupt database
|
|
LSERVER_E_INTERNAL_ERROR Internal error in license server
|
|
|
|
Note:
|
|
dwQuantity
|
|
Input Output
|
|
------------------------- -----------------------------------------
|
|
0 Total number of concurrent license
|
|
issued to hydra server.
|
|
> 0, number of license Actual number of license allocated
|
|
requested
|
|
< 0, number of license Actual number of license returned, always
|
|
to return positive value.
|
|
|
|
++*/
|
|
{
|
|
#if 1
|
|
|
|
*pdwErrCode = TLSMapReturnCode(TLS_E_NOTSUPPORTED);
|
|
return RPC_S_OK;
|
|
|
|
#else
|
|
|
|
PMHANDLE hClient;
|
|
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
PTLSDbWorkSpace pDbWorkSpace;
|
|
|
|
TLSDBLICENSEREQUEST LsLicenseRequest;
|
|
TCHAR szUnknown[LSERVER_MAX_STRING_SIZE+1];
|
|
TCHAR szClientMachineName[LSERVER_MAX_STRING_SIZE];
|
|
TCHAR szClientUserName[LSERVER_MAX_STRING_SIZE];
|
|
TCHAR szCompanyName[LSERVER_MAX_STRING_SIZE+1];
|
|
TCHAR szProductId[LSERVER_MAX_STRING_SIZE+1];
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
CTLSPolicy* pPolicy = NULL;
|
|
BOOL bAllocateLicense = TRUE;
|
|
|
|
PMLICENSEREQUEST PMLicenseRequest;
|
|
PPMLICENSEREQUEST pAdjustedRequest;
|
|
|
|
#ifdef DBG
|
|
DWORD dwStartTime=GetTickCount();
|
|
#endif
|
|
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcAllocateConcurrentLicense\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
if(*pdwQuantity > 1)
|
|
{
|
|
TLSASSERT(*pdwQuantity > 1);
|
|
}
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_REQUEST))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
memset(szCompanyName, 0, sizeof(szCompanyName));
|
|
memset(szProductId, 0, sizeof(szProductId));
|
|
|
|
memcpy(
|
|
szCompanyName,
|
|
pRequest->ProductInfo.pbCompanyName,
|
|
min(pRequest->ProductInfo.cbCompanyName, sizeof(szCompanyName)-sizeof(TCHAR))
|
|
);
|
|
|
|
memcpy(
|
|
szProductId,
|
|
pRequest->ProductInfo.pbProductID,
|
|
min(pRequest->ProductInfo.cbProductID, sizeof(szProductId)-sizeof(TCHAR))
|
|
);
|
|
|
|
//
|
|
// Acquire policy module, a default policy module will
|
|
// be returned.
|
|
//
|
|
pPolicy = AcquirePolicyModule(
|
|
szCompanyName, //(LPCTSTR)pRequest->ProductInfo.pbCompanyName,
|
|
szProductId, //(LPCTSTR)pRequest->ProductInfo.pbProductID
|
|
TRUE
|
|
);
|
|
|
|
if(pPolicy == NULL)
|
|
{
|
|
status = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
hClient = GenerateClientId();
|
|
|
|
//
|
|
// return error if string is too big.
|
|
//
|
|
LoadResourceString(
|
|
IDS_UNKNOWN_STRING,
|
|
szUnknown,
|
|
sizeof(szUnknown)/sizeof(szUnknown[0])
|
|
);
|
|
|
|
_tcsncpy(
|
|
szClientMachineName,
|
|
(szHydraServer) ? szHydraServer : szUnknown,
|
|
LSERVER_MAX_STRING_SIZE
|
|
);
|
|
|
|
_tcsncpy(
|
|
szClientUserName,
|
|
(szHydraServer) ? szHydraServer : szUnknown,
|
|
LSERVER_MAX_STRING_SIZE
|
|
);
|
|
|
|
//
|
|
// Convert request to PMLICENSEREQUEST
|
|
//
|
|
TlsLicenseRequestToPMLicenseRequest(
|
|
LICENSETYPE_LICENSE,
|
|
pRequest,
|
|
szClientMachineName,
|
|
szClientUserName,
|
|
0,
|
|
&PMLicenseRequest
|
|
);
|
|
|
|
//
|
|
// Inform Policy module start of new license request
|
|
//
|
|
status = pPolicy->PMLicenseRequest(
|
|
hClient,
|
|
REQUEST_NEW,
|
|
(PVOID) &PMLicenseRequest,
|
|
(PVOID *) &pAdjustedRequest
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
if(pAdjustedRequest != NULL)
|
|
{
|
|
if(_tcsicmp(PMLicenseRequest.pszCompanyName,pAdjustedRequest->pszCompanyName) != 0)
|
|
{
|
|
// try to steal license from other company???
|
|
TLSLogEvent(
|
|
EVENTLOG_ERROR_TYPE,
|
|
TLS_E_POLICYERROR,
|
|
status = TLS_E_POLICYMODULEERROR,
|
|
pPolicy->GetCompanyName(),
|
|
pPolicy->GetProductId()
|
|
);
|
|
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pAdjustedRequest = &PMLicenseRequest;
|
|
}
|
|
|
|
|
|
//
|
|
// form DB request structure
|
|
//
|
|
status = TLSFormDBRequest(
|
|
pRequest->pbEncryptedHwid,
|
|
pRequest->cbEncryptedHwid,
|
|
pAdjustedRequest->dwProductVersion,
|
|
pAdjustedRequest->pszCompanyName,
|
|
pAdjustedRequest->pszProductId,
|
|
pAdjustedRequest->dwLanguageId,
|
|
pAdjustedRequest->dwPlatformId,
|
|
pAdjustedRequest->pszMachineName,
|
|
pAdjustedRequest->pszUserName,
|
|
&LsLicenseRequest
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
LsLicenseRequest.pPolicy = pPolicy;
|
|
LsLicenseRequest.hClient = hClient;
|
|
LsLicenseRequest.pPolicyLicenseRequest = pAdjustedRequest;
|
|
LsLicenseRequest.pClientLicenseRequest = &PMLicenseRequest;
|
|
|
|
if(!ALLOCATEDBHANDLE(pDbWkSpace, g_GeneralDbTimeout))
|
|
{
|
|
status=TLS_E_ALLOCATE_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
bAllocateLicense = (*pdwQuantity) > 0;
|
|
|
|
CLEANUPSTMT;
|
|
|
|
BEGIN_TRANSACTION(pDbWorkSpace);
|
|
|
|
try {
|
|
status = TLSDBAllocateConcurrentLicense(
|
|
USEHANDLE(pDbWorkSpace),
|
|
szHydraServer,
|
|
&LsLicenseRequest,
|
|
pdwQuantity
|
|
);
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
SetLastError(status = TLS_E_INTERNAL);
|
|
}
|
|
|
|
if(TLS_ERROR(status))
|
|
{
|
|
ROLLBACK_TRANSACTION(pDbWorkSpace);
|
|
}
|
|
else
|
|
{
|
|
COMMIT_TRANSACTION(pDbWorkSpace);
|
|
}
|
|
|
|
FREEDBHANDLE(pDbWorkSpace);
|
|
|
|
|
|
cleanup:
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_ALLOCATECONCURRENT;
|
|
#endif
|
|
|
|
#ifdef DBG
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
_TEXT("\t%s : TLSRpcRequestNewLicense() takes %dms\n"),
|
|
lpContext->m_Client,
|
|
GetTickCount() - dwStartTime
|
|
);
|
|
#endif
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
|
|
if(pPolicy)
|
|
{
|
|
pPolicy->PMLicenseRequest(
|
|
hClient,
|
|
REQUEST_COMPLETE,
|
|
(PVOID) status,
|
|
NULL
|
|
);
|
|
|
|
ReleasePolicyModule(pPolicy);
|
|
}
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
return RPC_S_OK;
|
|
|
|
#endif
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcGetLastError(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [ref][out][in] */ PDWORD cbBufferSize,
|
|
/* [size_is][string][out][in] */ LPTSTR szBuffer,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Return error description text for client's last LSXXX call
|
|
|
|
Arguments:
|
|
|
|
IN phContext - Client context
|
|
IN cbBufferSize - max. size of szBuffer
|
|
IN OUT szBuffer - Pointer to a buffer to receive the
|
|
null-terminated character string containing
|
|
error description
|
|
|
|
Returns via dwErrCode:
|
|
LSERVER_S_SUCCESS
|
|
|
|
TLS_E_INTERNAL No error or can't find corresponding error
|
|
description.
|
|
|
|
Error code from WideCharToMultiByte().
|
|
|
|
++*/
|
|
{
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPTSTR lpMsgBuf=NULL;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcGetLastError\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
try {
|
|
DWORD dwRet;
|
|
dwRet=FormatMessage(
|
|
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
|
NULL,
|
|
lpContext->m_LastError,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(LPTSTR) &lpMsgBuf,
|
|
0,
|
|
NULL
|
|
);
|
|
if(dwRet == 0)
|
|
{
|
|
status = GetLastError();
|
|
}
|
|
else
|
|
{
|
|
_tcsncpy(
|
|
szBuffer,
|
|
(LPTSTR)lpMsgBuf,
|
|
min(_tcslen((LPTSTR)lpMsgBuf), *cbBufferSize-1)
|
|
);
|
|
szBuffer[min(_tcslen((LPTSTR)lpMsgBuf), *cbBufferSize-1)] = _TEXT('\0');
|
|
*cbBufferSize = _tcslen(szBuffer) + 1;
|
|
}
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
if(lpMsgBuf)
|
|
LocalFree(lpMsgBuf);
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_GET_LASTERROR;
|
|
#endif
|
|
|
|
lpContext->m_LastError=status;
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcKeyPackEnumBegin(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwSearchParm,
|
|
/* [in] */ BOOL bMatchAll,
|
|
/* [ref][in] */ LPLSKeyPackSearchParm lpSearchParm,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Function to begin enumerate through all key pack installed on server
|
|
based on search criterial.
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle.
|
|
dwSearchParm - search criterial.
|
|
bMatchAll - match all search criterial.
|
|
lpSearchParm - search parameter.
|
|
|
|
Return Value:
|
|
|
|
LSERVER_S_SUCCESS
|
|
LSERVER_E_SERVER_BUSY Server is too busy to process request
|
|
LSERVER_E_OUTOFMEMORY
|
|
TLS_E_INTERNAL
|
|
LSERVER_E_INTERNAL_ERROR
|
|
LSERVER_E_INVALID_DATA Invalid data in search parameter
|
|
LSERVER_E_INVALID_SEQUENCE Invalid calling sequence, likely, previous
|
|
enumeration has not ended.
|
|
++*/
|
|
{
|
|
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcKeyPackEnumBegin\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
//
|
|
// This will use cached db connection, in-consistency may occurred,
|
|
// visibility of changes in one connection may not appear right away
|
|
// on another connection handle, this is expected behavoir for Jet and
|
|
// so are we, user can always re-fresh.
|
|
//
|
|
do {
|
|
if(lpContext->m_ContextType != CONTEXTHANDLE_EMPTY_TYPE)
|
|
{
|
|
SetLastError(status=TLS_E_INVALID_SEQUENCE);
|
|
break;
|
|
}
|
|
|
|
try {
|
|
|
|
LPENUMHANDLE hEnum;
|
|
|
|
hEnum = TLSDBLicenseKeyPackEnumBegin(
|
|
bMatchAll,
|
|
dwSearchParm,
|
|
lpSearchParm
|
|
);
|
|
if(hEnum)
|
|
{
|
|
lpContext->m_ContextType = CONTEXTHANDLE_KEYPACK_ENUM_TYPE;
|
|
lpContext->m_ContextHandle = (PVOID)hEnum;
|
|
}
|
|
else
|
|
{
|
|
status = GetLastError();
|
|
}
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
} while(FALSE);
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_KEYPACKENUMBEGIN;
|
|
#endif
|
|
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcKeyPackEnumNext(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [ref][out] */ LPLSKeyPack lpKeyPack,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Return next key pack that match search criterial
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle
|
|
lpKeyPack - key pack that match search criterial
|
|
|
|
Return Value:
|
|
|
|
LSERVER_S_SUCCESS
|
|
LSERVER_I_NO_MORE_DATA No more keypack match search criterial
|
|
TLS_E_INTERNAL General error in license server
|
|
LSERVER_E_INTERNAL_ERROR Internal error in license server
|
|
LSERVER_E_SERVER_BUSY License server is too busy to process request
|
|
LSERVER_E_OUTOFMEMORY Can't process request due to insufficient memory
|
|
LSERVER_E_INVALID_SEQUENCE Invalid calling sequence, must call
|
|
LSKeyPackEnumBegin().
|
|
|
|
++*/
|
|
{
|
|
DWORD status = ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
BOOL bShowAll = FALSE;
|
|
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcKeyPackEnumNext\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
if(lpContext->m_ClientFlags == CLIENT_ACCESS_LSERVER)
|
|
{
|
|
bShowAll = TRUE;
|
|
}
|
|
|
|
// this one might cause access violation
|
|
memset(lpKeyPack, 0, sizeof(LSKeyPack));
|
|
|
|
if(lpContext->m_ContextType != CONTEXTHANDLE_KEYPACK_ENUM_TYPE)
|
|
{
|
|
SetLastError(status=TLS_E_INVALID_SEQUENCE);
|
|
}
|
|
else
|
|
{
|
|
do {
|
|
try {
|
|
LPENUMHANDLE hEnum=(LPENUMHANDLE)lpContext->m_ContextHandle;
|
|
status=TLSDBLicenseKeyPackEnumNext(
|
|
hEnum,
|
|
lpKeyPack,
|
|
bShowAll
|
|
);
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
} while(status == TLS_I_MORE_DATA);
|
|
}
|
|
|
|
lpContext->m_LastError=GetLastError();
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_KEYPACKENUMNEXT;
|
|
#endif
|
|
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcKeyPackEnumEnd(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcKeyPackEnumEnd\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
try {
|
|
if(lpContext->m_ContextType != CONTEXTHANDLE_KEYPACK_ENUM_TYPE)
|
|
{
|
|
SetLastError(status=ERROR_INVALID_HANDLE);
|
|
}
|
|
else
|
|
{
|
|
LPENUMHANDLE hEnum=(LPENUMHANDLE)lpContext->m_ContextHandle;
|
|
|
|
TLSDBLicenseKeyPackEnumEnd(hEnum);
|
|
lpContext->m_ContextType = CONTEXTHANDLE_EMPTY_TYPE;
|
|
lpContext->m_ContextHandle=NULL;
|
|
}
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
lpContext->m_LastError=GetLastError();
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_KEYPACKENUMEND;
|
|
#endif
|
|
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcKeyPackAdd(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [ref][out][in] */ LPLSKeyPack lpKeypack,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Add a license key pack.
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle.
|
|
lpKeyPack - key pack to be added.
|
|
|
|
Return Value:
|
|
|
|
LSERVER_S_SUCCESS
|
|
LSERVER_E_INTERNAL_ERROR
|
|
TLS_E_INTERNAL
|
|
LSERVER_E_SERVER_BUSY
|
|
LSERVER_E_DUPLICATE Product already installed.
|
|
LSERVER_E_INVALID_DATA
|
|
LSERVER_E_CORRUPT_DATABASE
|
|
|
|
Note:
|
|
|
|
Application must call LSKeyPackSetStatus() to activate keypack
|
|
|
|
++*/
|
|
{
|
|
PTLSDbWorkSpace pDbWkSpace=NULL;
|
|
DWORD status=ERROR_SUCCESS;
|
|
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcKeyPackAdd\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_ADMIN))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
}
|
|
else
|
|
{
|
|
if(!ALLOCATEDBHANDLE(pDbWkSpace, g_GeneralDbTimeout))
|
|
{
|
|
status=TLS_E_ALLOCATE_HANDLE;
|
|
}
|
|
else
|
|
{
|
|
CLEANUPSTMT;
|
|
|
|
BEGIN_TRANSACTION(pDbWkSpace);
|
|
|
|
try {
|
|
if(lpKeypack->ucKeyPackStatus == LSKEYPACKSTATUS_ADD_LICENSE ||
|
|
lpKeypack->ucKeyPackStatus == LSKEYPACKSTATUS_REMOVE_LICENSE)
|
|
{
|
|
status = TLSDBLicenseKeyPackUpdateLicenses(
|
|
USEHANDLE(pDbWkSpace),
|
|
lpKeypack->ucKeyPackStatus == LSKEYPACKSTATUS_ADD_LICENSE,
|
|
lpKeypack
|
|
);
|
|
}
|
|
else
|
|
{
|
|
status = TLSDBLicenseKeyPackAdd(
|
|
USEHANDLE(pDbWkSpace),
|
|
lpKeypack
|
|
);
|
|
}
|
|
|
|
if(status == ERROR_SUCCESS)
|
|
{
|
|
if( _tcsicmp( lpKeypack->szCompanyName, PRODUCT_INFO_COMPANY_NAME ) == 0 )
|
|
{
|
|
//
|
|
// check with known termsrv product ID.
|
|
//
|
|
if( _tcsnicmp( lpKeypack->szProductId,
|
|
TERMSERV_PRODUCTID_SKU,
|
|
_tcslen(TERMSERV_PRODUCTID_SKU)) == 0 )
|
|
{
|
|
TLSResetLogLowLicenseWarning(
|
|
lpKeypack->szCompanyName,
|
|
TERMSERV_PRODUCTID_SKU,
|
|
MAKELONG(lpKeypack->wMinorVersion, lpKeypack->wMajorVersion),
|
|
FALSE
|
|
);
|
|
}
|
|
else if(_tcsnicmp( lpKeypack->szProductId,
|
|
TERMSERV_PRODUCTID_INTERNET_SKU,
|
|
_tcslen(TERMSERV_PRODUCTID_INTERNET_SKU)) == 0 )
|
|
{
|
|
TLSResetLogLowLicenseWarning(
|
|
lpKeypack->szCompanyName,
|
|
TERMSERV_PRODUCTID_INTERNET_SKU,
|
|
MAKELONG(lpKeypack->wMinorVersion, lpKeypack->wMajorVersion),
|
|
FALSE
|
|
);
|
|
}
|
|
else
|
|
{
|
|
TLSResetLogLowLicenseWarning(
|
|
lpKeypack->szCompanyName,
|
|
lpKeypack->szProductId,
|
|
MAKELONG(lpKeypack->wMinorVersion, lpKeypack->wMajorVersion),
|
|
FALSE
|
|
);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TLSResetLogLowLicenseWarning(
|
|
lpKeypack->szCompanyName,
|
|
lpKeypack->szProductId,
|
|
MAKELONG(lpKeypack->wMinorVersion, lpKeypack->wMajorVersion),
|
|
FALSE
|
|
);
|
|
}
|
|
}
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
if(TLS_ERROR(status))
|
|
{
|
|
ROLLBACK_TRANSACTION(pDbWkSpace);
|
|
}
|
|
else
|
|
{
|
|
COMMIT_TRANSACTION(pDbWkSpace);
|
|
}
|
|
|
|
FREEDBHANDLE(pDbWkSpace);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Post a sync work object
|
|
//
|
|
if( status == ERROR_SUCCESS )
|
|
{
|
|
if( lpKeypack->ucKeyPackType != LSKEYPACKTYPE_FREE )
|
|
{
|
|
if(TLSAnnounceLKPToAllRemoteServer(
|
|
lpKeypack->dwKeyPackId,
|
|
0
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
TLSLogWarningEvent(TLS_W_ANNOUNCELKP_FAILED);
|
|
}
|
|
}
|
|
}
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_KEYPACKADD;
|
|
#endif
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcKeyPackSetStatus(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwSetParm,
|
|
/* [ref][in] */ LPLSKeyPack lpKeyPack,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Routine to activate/deactivated a key pack.
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle
|
|
dwSetParam - type of key pack status to be set.
|
|
lpKeyPack - new key pack status.
|
|
|
|
Return Value:
|
|
|
|
LSERVER_S_SUCCESS
|
|
LSERVER_E_INTERNAL_ERROR
|
|
TLS_E_INTERNAL
|
|
LSERVER_E_INVALID_DATA
|
|
LSERVER_E_SERVER_BUSY
|
|
LSERVER_E_DATANOTFOUND Key pack is not in server
|
|
LSERVER_E_CORRUPT_DATABASE
|
|
|
|
++*/
|
|
{
|
|
PTLSDbWorkSpace pDbWkSpace=NULL;
|
|
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcKeyPackSetStatus\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_ADMIN))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
}
|
|
else if( (dwSetParm & ~(LSKEYPACK_SET_KEYPACKSTATUS | LSKEYPACK_SET_ACTIVATEDATE | LSKEYPACK_SET_EXPIREDATE)) &&
|
|
!(lpContext->m_ClientFlags & CLIENT_ACCESS_LRWIZ) )
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
}
|
|
else
|
|
{
|
|
if(!ALLOCATEDBHANDLE(pDbWkSpace, g_GeneralDbTimeout))
|
|
{
|
|
status=TLS_E_ALLOCATE_HANDLE;
|
|
}
|
|
else
|
|
{
|
|
CLEANUPSTMT;
|
|
|
|
BEGIN_TRANSACTION(pDbWkSpace);
|
|
|
|
try {
|
|
status=TLSDBLicenseKeyPackSetStatus(
|
|
USEHANDLE(pDbWkSpace),
|
|
dwSetParm,
|
|
lpKeyPack
|
|
);
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
if(TLS_ERROR(status))
|
|
{
|
|
ROLLBACK_TRANSACTION(pDbWkSpace);
|
|
}
|
|
else
|
|
{
|
|
COMMIT_TRANSACTION(pDbWkSpace);
|
|
}
|
|
|
|
FREEDBHANDLE(pDbWkSpace);
|
|
}
|
|
}
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_KEYPACKSETSTATUS;
|
|
#endif
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcLicenseEnumBegin(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwSearchParm,
|
|
/* [in] */ BOOL bMatchAll,
|
|
/* [ref][in] */ LPLSLicenseSearchParm lpSearchParm,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Description:
|
|
|
|
Begin enumeration of license issued based on search criterial
|
|
|
|
Arguments:
|
|
|
|
phContext - client context handle
|
|
dwSearchParm - license search criterial.
|
|
bMatchAll - match all search criterial
|
|
lpSearchParm - license(s) to be enumerated.
|
|
|
|
Return Value:
|
|
|
|
Same as LSKeyPackEnumBegin().
|
|
|
|
++*/
|
|
{
|
|
PTLSDbWorkSpace pDbWkSpace = NULL;
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcLicenseEnumBegin\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
//
|
|
// This will use cached db connection, in-consistency may occurred,
|
|
// visibility of changes in one connection may not appear right away
|
|
// on another connection handle, this is expected behavoir for Jet and
|
|
// so are we, user can always re-fresh.
|
|
//
|
|
|
|
do {
|
|
if(lpContext->m_ContextType != CONTEXTHANDLE_EMPTY_TYPE)
|
|
{
|
|
SetLastError(status=TLS_E_INVALID_SEQUENCE);
|
|
break;
|
|
}
|
|
|
|
pDbWkSpace = AllocateWorkSpace(g_EnumDbTimeout);
|
|
|
|
// allocate ODBC connections
|
|
if(pDbWkSpace == NULL)
|
|
{
|
|
status=TLS_E_ALLOCATE_HANDLE;
|
|
break;
|
|
}
|
|
|
|
try {
|
|
LICENSEDCLIENT license;
|
|
|
|
ConvertLSLicenseToLicense(lpSearchParm, &license);
|
|
status = TLSDBLicenseEnumBegin(
|
|
pDbWkSpace,
|
|
bMatchAll,
|
|
dwSearchParm & LICENSE_TABLE_EXTERN_SEARCH_MASK,
|
|
&license
|
|
);
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
if(status == ERROR_SUCCESS)
|
|
{
|
|
lpContext->m_ContextType = CONTEXTHANDLE_LICENSE_ENUM_TYPE;
|
|
lpContext->m_ContextHandle = (PVOID)pDbWkSpace;
|
|
}
|
|
} while(FALSE);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
if(pDbWkSpace)
|
|
{
|
|
ReleaseWorkSpace(&pDbWkSpace);
|
|
}
|
|
}
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_LICENSEENUMBEGIN;
|
|
#endif
|
|
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
lpContext->m_LastError=status;
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcLicenseEnumNext(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [ref][out] */ LPLSLicense lpLicense,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Fetch next record match enumeration criterial.
|
|
|
|
Parameters:
|
|
|
|
phContext : Client context handle.
|
|
lpLicense : return next record that match enumeration criterial.
|
|
dwErrCode : error code.
|
|
|
|
Returns:
|
|
|
|
Function returns RPC status, dwErrCode return error code.
|
|
|
|
Note:
|
|
|
|
Must have call TLSRpcLicenseEnumBegin().
|
|
|
|
++*/
|
|
{
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcLicenseEnumNext\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
if(lpContext->m_ContextType != CONTEXTHANDLE_LICENSE_ENUM_TYPE)
|
|
{
|
|
SetLastError(status=TLS_E_INVALID_SEQUENCE);
|
|
}
|
|
else
|
|
{
|
|
PTLSDbWorkSpace pDbWkSpace=(PTLSDbWorkSpace)lpContext->m_ContextHandle;
|
|
try {
|
|
LICENSEDCLIENT license;
|
|
|
|
memset(lpLicense, 0, sizeof(LSLicense));
|
|
|
|
status=TLSDBLicenseEnumNext(
|
|
pDbWkSpace,
|
|
&license
|
|
);
|
|
if(status == ERROR_SUCCESS)
|
|
{
|
|
ConvertLicenseToLSLicense(&license, lpLicense);
|
|
}
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
}
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_LICENSEENUMNEXT;
|
|
#endif
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcLicenseEnumNextEx(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [ref][out] */ LPLSLicenseEx lpLicense,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Fetch next record match enumeration criterial.
|
|
|
|
Parameters:
|
|
|
|
phContext : Client context handle.
|
|
lpLicense : return next record that match enumeration criterial.
|
|
dwErrCode : error code.
|
|
|
|
Returns:
|
|
|
|
Function returns RPC status, dwErrCode return error code.
|
|
|
|
Note:
|
|
|
|
Must have call TLSRpcLicenseEnumBegin().
|
|
|
|
++*/
|
|
{
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcLicenseEnumNextEx\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
if(lpContext->m_ContextType != CONTEXTHANDLE_LICENSE_ENUM_TYPE)
|
|
{
|
|
SetLastError(status=TLS_E_INVALID_SEQUENCE);
|
|
}
|
|
else
|
|
{
|
|
PTLSDbWorkSpace pDbWkSpace=(PTLSDbWorkSpace)lpContext->m_ContextHandle;
|
|
try {
|
|
LICENSEDCLIENT license;
|
|
|
|
memset(lpLicense, 0, sizeof(LSLicenseEx));
|
|
|
|
status=TLSDBLicenseEnumNext(
|
|
pDbWkSpace,
|
|
&license
|
|
);
|
|
if(status == ERROR_SUCCESS)
|
|
{
|
|
ConvertLicenseToLSLicenseEx(&license, lpLicense);
|
|
}
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
}
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_LICENSEENUMNEXT;
|
|
#endif
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcLicenseEnumEnd(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Terminate a enumeration.
|
|
|
|
Parameters:
|
|
|
|
phContext :
|
|
dwErrCode :
|
|
|
|
Returns:
|
|
|
|
|
|
Note
|
|
|
|
++*/
|
|
{
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcLicenseEnumEnd\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
try {
|
|
if(lpContext->m_ContextType != CONTEXTHANDLE_LICENSE_ENUM_TYPE)
|
|
{
|
|
SetLastError(status=ERROR_INVALID_HANDLE);
|
|
}
|
|
else
|
|
{
|
|
PTLSDbWorkSpace pDbWkSpace = (PTLSDbWorkSpace)lpContext->m_ContextHandle;
|
|
|
|
TLSDBLicenseEnumEnd(pDbWkSpace);
|
|
ReleaseWorkSpace(&pDbWkSpace);
|
|
lpContext->m_ContextType = CONTEXTHANDLE_EMPTY_TYPE;
|
|
}
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_LICENSEENUMEND;
|
|
#endif
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcLicenseSetStatus(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwSetParam,
|
|
/* [in] */ LPLSLicense lpLicense,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
PTLSDbWorkSpace pDbWkSpace=NULL;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcLicenseSetStatus\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_ADMIN))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
}
|
|
else if(dwSetParam != LSLICENSE_EXSEARCH_LICENSESTATUS)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
}
|
|
else
|
|
{
|
|
if(!ALLOCATEDBHANDLE(pDbWkSpace, g_GeneralDbTimeout))
|
|
{
|
|
status=TLS_E_ALLOCATE_HANDLE;
|
|
}
|
|
else
|
|
{
|
|
CLEANUPSTMT;
|
|
|
|
BEGIN_TRANSACTION(pDbWkSpace);
|
|
|
|
try {
|
|
LICENSEDCLIENT license;
|
|
|
|
ConvertLSLicenseToLicense(lpLicense, &license);
|
|
status=TLSDBLicenseSetValue(
|
|
USEHANDLE(pDbWkSpace),
|
|
dwSetParam,
|
|
&license,
|
|
FALSE
|
|
);
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
if(TLS_ERROR(status))
|
|
{
|
|
ROLLBACK_TRANSACTION(pDbWkSpace);
|
|
}
|
|
else
|
|
{
|
|
COMMIT_TRANSACTION(pDbWkSpace);
|
|
}
|
|
|
|
FREEDBHANDLE(pDbWkSpace);
|
|
}
|
|
}
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_LICENSESETSTATUS;
|
|
#endif
|
|
|
|
lpContext->m_LastError = status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcGetAvailableLicenses(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwSearchParm,
|
|
/* [ref][in] */ LPLSKeyPack lplsKeyPack,
|
|
/* [ref][out] */ LPDWORD lpdwAvail,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
PTLSDbWorkSpace pDbWkSpace=NULL;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcGetAvailableLicenses\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
//
|
|
// Don't use global cached DB connection handle, it is possible
|
|
// to get in-consistent value using other DB handle, however, it is
|
|
// also possible that during the time that this function return and
|
|
// the time that client actually make the call to allocate license,
|
|
// all available licenses were allocated by other client.
|
|
//
|
|
pDbWkSpace = AllocateWorkSpace(g_GeneralDbTimeout);
|
|
if(pDbWkSpace == NULL)
|
|
{
|
|
status=TLS_E_ALLOCATE_HANDLE;
|
|
}
|
|
else
|
|
{
|
|
try {
|
|
LICENSEPACK keypack;
|
|
|
|
memset(&keypack, 0, sizeof(keypack));
|
|
|
|
ConvertLsKeyPackToKeyPack(
|
|
lplsKeyPack,
|
|
&keypack,
|
|
NULL
|
|
);
|
|
|
|
status = TLSDBKeyPackGetAvailableLicenses(
|
|
pDbWkSpace,
|
|
dwSearchParm,
|
|
&keypack,
|
|
lpdwAvail
|
|
);
|
|
|
|
//FreeTlsLicensePack(&keypack);
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
ReleaseWorkSpace(&pDbWkSpace);
|
|
}
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcGetRevokeKeyPackList(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [out][in] */ PDWORD pcbNumberOfRange,
|
|
/* [size_is][out] */ LPLSRange __RPC_FAR *ppRevokeRange,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
*pdwErrCode = TLSMapReturnCode(TLS_E_NOTSUPPORTED);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcGetRevokeLicenseList(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [out][in] */ PDWORD pcbNumberOfRange,
|
|
/* [size_is][out] */ LPLSRange __RPC_FAR *ppRevokeRange,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
*pdwErrCode = TLSMapReturnCode(TLS_E_NOTSUPPORTED);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcReturnKeyPack(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwKeyPackId,
|
|
/* [in] */ DWORD dwReturnReason,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
*pdwErrCode = TLSMapReturnCode(TLS_E_NOTSUPPORTED);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcReturnLicense(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwKeyPackId,
|
|
/* [in] */ DWORD dwLicenseId,
|
|
/* [in] */ DWORD dwReturnReason,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
*pdwErrCode = TLSMapReturnCode(TLS_E_NOTSUPPORTED);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcInstallCertificate(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwCertType,
|
|
/* [in] */ DWORD dwCertLevel,
|
|
/* [in] */ DWORD cbSignCert,
|
|
/* [size_is][in] */ PBYTE pbSignCert,
|
|
/* [in] */ DWORD cbExchCert,
|
|
/* [size_is][in] */ PBYTE pbExchCert,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcInstallCertificate\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
DWORD cbLsSignCert=0;
|
|
PBYTE pbLsSignCert=NULL;
|
|
|
|
DWORD cbLsExchCert=0;
|
|
PBYTE pbLsExchCert=NULL;
|
|
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_ADMIN))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(pbSignCert == NULL || pbExchCert == NULL)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
#if DBG
|
|
//
|
|
// Verify input data
|
|
//
|
|
status = TLSVerifyCertChainInMomory(
|
|
g_hCryptProv,
|
|
pbSignCert,
|
|
cbSignCert
|
|
);
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
}
|
|
|
|
//
|
|
// Verify input data
|
|
//
|
|
status = TLSVerifyCertChainInMomory(
|
|
g_hCryptProv,
|
|
pbExchCert,
|
|
cbExchCert
|
|
);
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Block RPC call to serialize install certificate
|
|
//
|
|
if(AcquireRPCExclusiveLock(INFINITE) == FALSE)
|
|
{
|
|
status=TLS_E_ALLOCATE_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(AcquireAdministrativeLock(INFINITE) == TRUE)
|
|
{
|
|
try {
|
|
if(dwCertLevel == 0)
|
|
{
|
|
status = TLSSaveRootCertificatesToStore(
|
|
g_hCryptProv,
|
|
cbSignCert,
|
|
pbSignCert,
|
|
cbExchCert,
|
|
pbExchCert
|
|
);
|
|
}
|
|
else
|
|
{
|
|
status = TLSSaveCertificatesToStore(
|
|
g_hCryptProv,
|
|
dwCertType,
|
|
dwCertLevel,
|
|
cbSignCert,
|
|
pbSignCert,
|
|
cbExchCert,
|
|
pbExchCert
|
|
);
|
|
|
|
if(status == ERROR_SUCCESS && dwCertType == CERTIFICATE_CA_TYPE)
|
|
{
|
|
if(cbSignCert)
|
|
{
|
|
status = IsCertificateLicenseServerCertificate(
|
|
g_hCryptProv,
|
|
AT_SIGNATURE,
|
|
cbSignCert,
|
|
pbSignCert,
|
|
&cbLsSignCert,
|
|
&pbLsSignCert
|
|
);
|
|
}
|
|
|
|
if(status == ERROR_SUCCESS && cbExchCert)
|
|
{
|
|
status = IsCertificateLicenseServerCertificate(
|
|
g_hCryptProv,
|
|
AT_KEYEXCHANGE,
|
|
cbExchCert,
|
|
pbExchCert,
|
|
&cbLsExchCert,
|
|
&pbLsExchCert
|
|
);
|
|
|
|
}
|
|
|
|
//
|
|
// Install what we have here.
|
|
//
|
|
if(status == ERROR_SUCCESS && (cbLsExchCert || pbLsExchCert))
|
|
{
|
|
status = TLSInstallLsCertificate(
|
|
cbLsSignCert,
|
|
pbLsSignCert,
|
|
cbLsExchCert,
|
|
pbLsExchCert
|
|
);
|
|
}
|
|
|
|
#ifdef ENFORCE_LICENSING
|
|
|
|
// enforce version, check what's installed and restore backup if necessary
|
|
// non-enforce, just install, we won't use it anyway.
|
|
if(status == ERROR_SUCCESS && (cbLsExchCert || pbLsExchCert))
|
|
{
|
|
// reload certificate
|
|
if(TLSLoadVerifyLicenseServerCertificates() != ERROR_SUCCESS)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
|
|
// delete the primary certificate registry key
|
|
TLSRegDeleteKey(
|
|
HKEY_LOCAL_MACHINE,
|
|
LSERVER_SERVER_CERTIFICATE_REGKEY
|
|
);
|
|
|
|
//
|
|
// reload certificate, if anything goes wrong, we will goes
|
|
// back to unregister mode.
|
|
//
|
|
if(TLSLoadServerCertificate() == FALSE)
|
|
{
|
|
// critical error occurred
|
|
TLSLogErrorEvent(TLS_E_LOAD_CERTIFICATE);
|
|
|
|
// initiate self-shutdown
|
|
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD dwStatus;
|
|
|
|
// make sure our backup is up to date.
|
|
dwStatus = TLSRestoreLicenseServerCertificate(
|
|
LSERVER_SERVER_CERTIFICATE_REGKEY,
|
|
LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1
|
|
);
|
|
if(dwStatus != ERROR_SUCCESS)
|
|
{
|
|
TLSLogWarningEvent(TLS_W_BACKUPCERTIFICATE);
|
|
|
|
TLSRegDeleteKey(
|
|
HKEY_LOCAL_MACHINE,
|
|
LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1
|
|
);
|
|
}
|
|
|
|
dwStatus = TLSRestoreLicenseServerCertificate(
|
|
LSERVER_SERVER_CERTIFICATE_REGKEY,
|
|
LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2
|
|
);
|
|
if(dwStatus != ERROR_SUCCESS)
|
|
{
|
|
TLSLogWarningEvent(TLS_W_BACKUPCERTIFICATE);
|
|
|
|
TLSRegDeleteKey(
|
|
HKEY_LOCAL_MACHINE,
|
|
LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2
|
|
);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if(pbLsSignCert)
|
|
{
|
|
FreeMemory(pbLsSignCert);
|
|
}
|
|
|
|
if(pbLsExchCert)
|
|
{
|
|
FreeMemory(pbLsExchCert);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
ReleaseAdministrativeLock();
|
|
}
|
|
else
|
|
{
|
|
status=TLS_E_ALLOCATE_HANDLE;
|
|
}
|
|
|
|
ReleaseRPCExclusiveLock();
|
|
|
|
cleanup:
|
|
|
|
lpContext->m_LastError=status;
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_INSTALL_SERV_CERT;
|
|
#endif
|
|
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcGetServerCertificate(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ BOOL bSignCert,
|
|
/* [size_is][size_is][out] */ LPBYTE __RPC_FAR *ppCertBlob,
|
|
/* [ref][out] */ LPDWORD lpdwCertBlobLen,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcGetServerCertificate\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_ADMIN))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
}
|
|
else if(!g_pbExchangeEncodedCert || !g_cbExchangeEncodedCert ||
|
|
!g_pbSignatureEncodedCert || !g_cbSignatureEncodedCert)
|
|
{
|
|
status = TLS_E_NO_CERTIFICATE;
|
|
}
|
|
else
|
|
{
|
|
if(AcquireAdministrativeLock(INFINITE) == TRUE)
|
|
{
|
|
try{
|
|
status = TLSSaveCertAsPKCS7(
|
|
(bSignCert) ? g_pbSignatureEncodedCert : g_pbExchangeEncodedCert,
|
|
(bSignCert) ? g_cbSignatureEncodedCert : g_cbExchangeEncodedCert,
|
|
ppCertBlob,
|
|
lpdwCertBlobLen
|
|
);
|
|
|
|
// hack so that we can continue testing...
|
|
if(g_bHasHydraCert == FALSE)
|
|
{
|
|
if(g_pbServerSPK != NULL && g_cbServerSPK != 0)
|
|
{
|
|
status = TLS_W_SELFSIGN_CERTIFICATE;
|
|
}
|
|
else
|
|
{
|
|
status = TLS_W_TEMP_SELFSIGN_CERT;
|
|
}
|
|
}
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...)
|
|
{
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
ReleaseAdministrativeLock();
|
|
}
|
|
else
|
|
{
|
|
status = TLS_E_ALLOCATE_HANDLE;
|
|
}
|
|
}
|
|
|
|
lpContext->m_LastError=status;
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_GETSERV_CERT;
|
|
#endif
|
|
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
void
|
|
MyFreeLicenseKeyPack(
|
|
PLicense_KeyPack pLicenseKeyPack
|
|
)
|
|
/*
|
|
*/
|
|
{
|
|
DWORD i;
|
|
|
|
PKeyPack_Description pKpDesc;
|
|
|
|
if( pLicenseKeyPack->pDescription )
|
|
{
|
|
for( i = 0, pKpDesc = pLicenseKeyPack->pDescription;
|
|
i < pLicenseKeyPack->dwDescriptionCount;
|
|
i++, pKpDesc++ )
|
|
{
|
|
if(pKpDesc->pDescription)
|
|
LocalFree( pKpDesc->pDescription );
|
|
|
|
if(pKpDesc->pbProductName)
|
|
LocalFree( pKpDesc->pbProductName );
|
|
}
|
|
}
|
|
|
|
if(pLicenseKeyPack->pDescription)
|
|
LocalFree( pLicenseKeyPack->pDescription );
|
|
|
|
if(pLicenseKeyPack->pbManufacturer && pLicenseKeyPack->cbManufacturer != 0)
|
|
LocalFree( pLicenseKeyPack->pbManufacturer );
|
|
|
|
if(pLicenseKeyPack->pbManufacturerData && pLicenseKeyPack->cbManufacturerData != 0)
|
|
LocalFree( pLicenseKeyPack->pbManufacturerData );
|
|
|
|
if(pLicenseKeyPack->pbProductId && pLicenseKeyPack->cbProductId != 0)
|
|
LocalFree( pLicenseKeyPack->pbProductId );
|
|
return;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
error_status_t
|
|
TLSRpcRegisterLicenseKeyPack(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [size_is][in] */ LPBYTE pbCHCertBlob,
|
|
/* [in] */ DWORD cbCHCertBlobSize,
|
|
/* [size_is][in] */ LPBYTE pbRootCertBlob,
|
|
/* [in] */ DWORD cbRootCertBlob,
|
|
/* [size_is][in] */ LPBYTE lpKeyPackBlob,
|
|
/* [in] */ DWORD dwKeyPackBlobLen,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
LSKeyPack keypack;
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcRegisterLicenseKeyPack\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
PTLSDbWorkSpace pDbWkSpace;
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_ADMIN))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
|
|
if(!ALLOCATEDBHANDLE(pDbWkSpace, g_GeneralDbTimeout))
|
|
{
|
|
status=TLS_E_ALLOCATE_HANDLE;
|
|
}
|
|
else
|
|
{
|
|
License_KeyPack pLicenseKeyPack;
|
|
LicensePackDecodeParm LkpDecodeParm;
|
|
|
|
memset(
|
|
&LkpDecodeParm,
|
|
0,
|
|
sizeof(LicensePackDecodeParm)
|
|
);
|
|
|
|
LkpDecodeParm.hCryptProv = g_hCryptProv;
|
|
LkpDecodeParm.pbDecryptParm = (PBYTE)g_pszServerPid;
|
|
LkpDecodeParm.cbDecryptParm = (lstrlen(g_pszServerPid) * sizeof(TCHAR));
|
|
LkpDecodeParm.cbClearingHouseCert = cbCHCertBlobSize;
|
|
LkpDecodeParm.pbClearingHouseCert = pbCHCertBlob;
|
|
LkpDecodeParm.pbRootCertificate = pbRootCertBlob;
|
|
LkpDecodeParm.cbRootCertificate = cbRootCertBlob;
|
|
|
|
//
|
|
// make code clean, always start a transaction
|
|
//
|
|
CLEANUPSTMT;
|
|
BEGIN_TRANSACTION(pDbWkSpace);
|
|
|
|
try {
|
|
status = DecodeLicenseKeyPackEx(
|
|
&pLicenseKeyPack,
|
|
&LkpDecodeParm,
|
|
dwKeyPackBlobLen,
|
|
lpKeyPackBlob
|
|
);
|
|
|
|
if(status != LICENSE_STATUS_OK)
|
|
{
|
|
status = TLS_E_DECODE_KEYPACKBLOB;
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
_TEXT("Can't decode key pack blob - %d...\n"),
|
|
status);
|
|
}
|
|
else
|
|
{
|
|
status=TLSDBRegisterLicenseKeyPack(
|
|
USEHANDLE(pDbWkSpace),
|
|
&pLicenseKeyPack,
|
|
&keypack
|
|
);
|
|
|
|
MyFreeLicenseKeyPack(&pLicenseKeyPack);
|
|
}
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
if(TLS_ERROR(status))
|
|
{
|
|
ROLLBACK_TRANSACTION(pDbWkSpace);
|
|
}
|
|
else
|
|
{
|
|
COMMIT_TRANSACTION(pDbWkSpace);
|
|
}
|
|
|
|
FREEDBHANDLE(pDbWkSpace);
|
|
}
|
|
|
|
//
|
|
// Post a sync work object
|
|
//
|
|
if(status == ERROR_SUCCESS)
|
|
{
|
|
if(TLSAnnounceLKPToAllRemoteServer(
|
|
keypack.dwKeyPackId,
|
|
0
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
TLSLogWarningEvent(TLS_W_ANNOUNCELKP_FAILED);
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
|
|
lpContext->m_LastError=status;
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_REGISTER_LICENSE_PACK;
|
|
#endif
|
|
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
error_status_t
|
|
TLSRpcRequestTermServCert(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ LPTLSHYDRACERTREQUEST pRequest,
|
|
/* [ref][out][in] */ PDWORD pcbChallengeData,
|
|
/* [size_is][out] */ PBYTE* ppbChallengeData,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Private routine to issue certificate to Terminal Server.
|
|
|
|
Parameter:
|
|
|
|
phContext : Client context handle.
|
|
pRequest : Terminal Server specific certificate request.
|
|
pcbChallengeData : size of Server randomly generated challenge data
|
|
to Terminal Server.
|
|
ppbChallengeData : Server randomly generated challenge data to Terminal
|
|
server.
|
|
|
|
pdwErrCode : Error code.
|
|
|
|
Returns:
|
|
|
|
Function always return RPC_S_OK, actual error code is returned in
|
|
pdwErrCode.
|
|
|
|
Note:
|
|
|
|
Routine does not actually issue a license to Terminal Server, Terminal
|
|
Server must call TLSRpcRetrieveTermServCert() to retrieve its own
|
|
license.
|
|
|
|
--*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPTERMSERVCERTREQHANDLE lpHandle=NULL;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcRequestTermServCert\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
*ppbChallengeData = NULL;
|
|
*pcbChallengeData = 0;
|
|
|
|
// verify client handle
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
if(lpContext->m_ContextType != CONTEXTHANDLE_EMPTY_TYPE)
|
|
{
|
|
SetLastError(status=TLS_E_INVALID_SEQUENCE);
|
|
goto cleanup;
|
|
}
|
|
|
|
lpHandle = (LPTERMSERVCERTREQHANDLE)AllocateMemory(
|
|
sizeof(TERMSERVCERTREQHANDLE)
|
|
);
|
|
if(lpHandle == NULL)
|
|
{
|
|
SetLastError(status = ERROR_OUTOFMEMORY);
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Generate Challenge Data
|
|
//
|
|
lpHandle->pCertRequest = pRequest;
|
|
status = TLSGenerateChallengeData(
|
|
CLIENT_INFO_HYDRA_SERVER,
|
|
&lpHandle->cbChallengeData,
|
|
&lpHandle->pbChallengeData
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
// return challenge data
|
|
*pcbChallengeData = lpHandle->cbChallengeData;
|
|
*ppbChallengeData = (PBYTE)midl_user_allocate(*pcbChallengeData);
|
|
if(*ppbChallengeData == NULL)
|
|
{
|
|
SetLastError(status = ERROR_OUTOFMEMORY);
|
|
goto cleanup;
|
|
}
|
|
|
|
memcpy( *ppbChallengeData,
|
|
lpHandle->pbChallengeData,
|
|
lpHandle->cbChallengeData);
|
|
|
|
lpContext->m_ContextHandle = (HANDLE)lpHandle;
|
|
lpContext->m_ContextType = CONTEXTHANDLE_HYDRA_REQUESTCERT_TYPE;
|
|
|
|
cleanup:
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
// frees up memory.
|
|
// Can't overwrite context type.
|
|
//lpContext->m_ContextType = CONTEXTHANDLE_EMPTY_TYPE;
|
|
|
|
if(lpHandle != NULL)
|
|
{
|
|
FreeMemory(lpHandle->pbChallengeData);
|
|
FreeMemory(lpHandle);
|
|
}
|
|
|
|
if(*ppbChallengeData != NULL)
|
|
{
|
|
midl_user_free(*ppbChallengeData);
|
|
}
|
|
|
|
if(pRequest != NULL)
|
|
{
|
|
midl_user_free(pRequest);
|
|
}
|
|
|
|
*ppbChallengeData = NULL;
|
|
*pcbChallengeData = 0;
|
|
}
|
|
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
lpContext->m_LastError=status;
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_REQUEST_TERMSRV_CERT;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(status);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
error_status_t
|
|
TLSRpcRetrieveTermServCert(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD cbResponseData,
|
|
/* [size_is][in] */ PBYTE pbResponseData,
|
|
/* [ref][out][in] */ PDWORD pcbCert,
|
|
/* [size_is][out] */ PBYTE* ppbCert,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Private routine to retrieve Terminal Server's license.
|
|
|
|
Parameters:
|
|
|
|
phContext : client context handle.
|
|
cbResponseData : size of Terminal Server responses data to
|
|
license server's challenge.
|
|
pbResponseData : Terminal Server responses data to license
|
|
server's challenge.
|
|
pcbCert : Size of Terminal Server's license in bytes.
|
|
ppbCert : Terminal Server's license.
|
|
pdwErrCode : error code if fail.
|
|
|
|
Returns:
|
|
|
|
Function returns RPC_S_OK, actual error code returns in
|
|
pdwErrCode.
|
|
|
|
Note:
|
|
|
|
Must have call TLSRpcRequestTermServCert().
|
|
|
|
|
|
--*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPTERMSERVCERTREQHANDLE lpHandle=NULL;
|
|
CTLSPolicy* pPolicy=NULL;
|
|
PMHANDLE hClient;
|
|
|
|
PBYTE pbPkcs7=NULL;
|
|
DWORD cbPkcs7=0;
|
|
TLSDBLICENSEREQUEST LicenseRequest;
|
|
DWORD dwQuantity = 1;
|
|
TLSPRODUCTINFO ProductInfo;
|
|
|
|
TCHAR szCompanyName[LSERVER_MAX_STRING_SIZE];
|
|
TCHAR szMachineName[MAXCOMPUTERNAMELENGTH];
|
|
TCHAR szUserName[MAXUSERNAMELENGTH];
|
|
|
|
PTLSDbWorkSpace pDbWkSpace;
|
|
|
|
PMLICENSEREQUEST PMLicenseRequest;
|
|
PPMLICENSEREQUEST pAdjustedRequest;
|
|
|
|
TLSDBLICENSEDPRODUCT LicensedProduct;
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcRetrieveTermServCert\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
|
|
// verify client handle
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
if(lpContext->m_ContextType != CONTEXTHANDLE_HYDRA_REQUESTCERT_TYPE)
|
|
{
|
|
SetLastError(status = TLS_E_INVALID_SEQUENCE);
|
|
goto cleanup;
|
|
}
|
|
|
|
lpHandle = (LPTERMSERVCERTREQHANDLE)lpContext->m_ContextHandle;
|
|
if( lpHandle == NULL || lpHandle->pCertRequest == NULL ||
|
|
lpHandle->pCertRequest->pbEncryptedHwid == NULL ||
|
|
lpHandle->pCertRequest->cbEncryptedHwid == 0 )
|
|
{
|
|
SetLastError(status = TLS_E_INVALID_SEQUENCE);
|
|
goto cleanup;
|
|
}
|
|
|
|
|
|
//
|
|
// Verify challenge response data
|
|
//
|
|
|
|
|
|
//
|
|
// Request a license from specific key pack
|
|
//
|
|
|
|
memset(&LicenseRequest, 0, sizeof(TLSDBLICENSEREQUEST));
|
|
|
|
if(!LoadResourceString(
|
|
IDS_HS_COMPANYNAME,
|
|
szCompanyName,
|
|
sizeof(szCompanyName) / sizeof(szCompanyName[0])))
|
|
{
|
|
SetLastError(status = TLS_E_INTERNAL);
|
|
goto cleanup;
|
|
}
|
|
|
|
if(lpContext->m_Client == NULL)
|
|
{
|
|
if(!LoadResourceString(
|
|
IDS_HS_MACHINENAME,
|
|
LicenseRequest.szMachineName,
|
|
sizeof(LicenseRequest.szMachineName)/sizeof(LicenseRequest.szMachineName[0])))
|
|
{
|
|
SetLastError(status = TLS_E_INTERNAL);
|
|
goto cleanup;
|
|
}
|
|
|
|
if(!LoadResourceString(
|
|
IDS_HS_USERNAME,
|
|
LicenseRequest.szUserName,
|
|
sizeof(LicenseRequest.szUserName)/sizeof(LicenseRequest.szUserName[0])))
|
|
{
|
|
SetLastError(status = TLS_E_INTERNAL);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SAFESTRCPY(LicenseRequest.szMachineName, lpContext->m_Client);
|
|
SAFESTRCPY(LicenseRequest.szUserName, lpContext->m_Client);
|
|
}
|
|
|
|
LicenseRequest.dwProductVersion = HYDRACERT_PRODUCT_VERSION;
|
|
LicenseRequest.pszProductId = HYDRAPRODUCT_HS_CERTIFICATE_SKU;
|
|
LicenseRequest.pszCompanyName = szCompanyName;
|
|
|
|
LicenseRequest.dwLanguageID = GetSystemDefaultLangID(); // ignore
|
|
LicenseRequest.dwPlatformID = CLIENT_PLATFORMID_WINDOWS_NT_FREE; // WINDOWS
|
|
LicenseRequest.pbEncryptedHwid = lpHandle->pCertRequest->pbEncryptedHwid;
|
|
LicenseRequest.cbEncryptedHwid = lpHandle->pCertRequest->cbEncryptedHwid;
|
|
|
|
status=LicenseDecryptHwid(
|
|
&LicenseRequest.hWid,
|
|
LicenseRequest.cbEncryptedHwid,
|
|
LicenseRequest.pbEncryptedHwid,
|
|
g_cbSecretKey,
|
|
g_pbSecretKey
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
status = ERROR_INVALID_PARAMETER;
|
|
goto cleanup;
|
|
}
|
|
|
|
LicenseRequest.pClientPublicKey = (PCERT_PUBLIC_KEY_INFO)lpHandle->pCertRequest->pSubjectPublicKeyInfo;
|
|
LicenseRequest.clientCertRdn.type = LSCERT_RDN_STRING_TYPE;
|
|
LicenseRequest.clientCertRdn.szRdn = lpHandle->pCertRequest->szSubjectRdn;
|
|
LicenseRequest.dwNumExtensions = lpHandle->pCertRequest->dwNumCertExtension;
|
|
LicenseRequest.pExtensions = (PCERT_EXTENSION)lpHandle->pCertRequest->pCertExtensions;
|
|
|
|
hClient = GenerateClientId();
|
|
pPolicy = AcquirePolicyModule(NULL, NULL, FALSE);
|
|
if(pPolicy == NULL)
|
|
{
|
|
SetLastError(status = TLS_E_INTERNAL);
|
|
goto cleanup;
|
|
}
|
|
|
|
PMLicenseRequest.dwProductVersion = LicenseRequest.dwProductVersion;
|
|
PMLicenseRequest.pszProductId = LicenseRequest.pszProductId;
|
|
PMLicenseRequest.pszCompanyName = LicenseRequest.pszCompanyName;
|
|
PMLicenseRequest.dwLanguageId = LicenseRequest.dwLanguageID;
|
|
PMLicenseRequest.dwPlatformId = LicenseRequest.dwPlatformID;
|
|
PMLicenseRequest.pszMachineName = LicenseRequest.szMachineName;
|
|
PMLicenseRequest.pszUserName = LicenseRequest.szUserName;
|
|
PMLicenseRequest.dwLicenseType = LICENSETYPE_LICENSE;
|
|
|
|
//
|
|
// Inform Policy module start of new license request
|
|
//
|
|
status = pPolicy->PMLicenseRequest(
|
|
hClient,
|
|
REQUEST_NEW,
|
|
(PVOID) &PMLicenseRequest,
|
|
(PVOID *) &pAdjustedRequest
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
LicenseRequest.pPolicy = pPolicy;
|
|
LicenseRequest.hClient = hClient;
|
|
|
|
LicenseRequest.pPolicyLicenseRequest = pAdjustedRequest;
|
|
LicenseRequest.pClientLicenseRequest = &PMLicenseRequest;
|
|
|
|
|
|
// Call issue new license from sepcific keypack
|
|
if(!ALLOCATEDBHANDLE(pDbWkSpace, g_GeneralDbTimeout))
|
|
{
|
|
status = TLS_E_ALLOCATE_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
CLEANUPSTMT;
|
|
BEGIN_TRANSACTION(pDbWkSpace);
|
|
|
|
try {
|
|
status = TLSDBIssuePermanentLicense(
|
|
USEHANDLE(pDbWkSpace),
|
|
&LicenseRequest,
|
|
FALSE, // bLatestVersion
|
|
FALSE, // bAcceptFewerLicenses
|
|
&dwQuantity,
|
|
&LicensedProduct,
|
|
0
|
|
);
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
if(TLS_ERROR(status))
|
|
{
|
|
ROLLBACK_TRANSACTION(pDbWkSpace);
|
|
}
|
|
else
|
|
{
|
|
COMMIT_TRANSACTION(pDbWkSpace);
|
|
}
|
|
|
|
FREEDBHANDLE(pDbWkSpace);
|
|
|
|
if(status == ERROR_SUCCESS)
|
|
{
|
|
LicensedProduct.pSubjectPublicKeyInfo = (PCERT_PUBLIC_KEY_INFO)lpHandle->pCertRequest->pSubjectPublicKeyInfo;
|
|
|
|
//
|
|
// Generate client certificate
|
|
//
|
|
status = TLSGenerateClientCertificate(
|
|
g_hCryptProv,
|
|
1,
|
|
&LicensedProduct,
|
|
LICENSE_DETAIL_DETAIL,
|
|
&pbPkcs7,
|
|
&cbPkcs7
|
|
);
|
|
|
|
if(TLS_ERROR(status) == TRUE)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
status = TLSChainProprietyCertificate(
|
|
g_hCryptProv,
|
|
(CanIssuePermLicense() == FALSE),
|
|
pbPkcs7,
|
|
cbPkcs7,
|
|
ppbCert,
|
|
pcbCert
|
|
);
|
|
|
|
if(status == ERROR_SUCCESS)
|
|
{
|
|
if(CanIssuePermLicense() == FALSE)
|
|
{
|
|
status = TLS_W_SELFSIGN_CERTIFICATE;
|
|
}
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
|
|
FreeMemory(pbPkcs7);
|
|
|
|
if(pPolicy)
|
|
{
|
|
ReleasePolicyModule(pPolicy);
|
|
}
|
|
|
|
|
|
//
|
|
// Free up Hydra Certificate Request handle,
|
|
// all_nodes attribute so single free.
|
|
//
|
|
if(lpHandle)
|
|
{
|
|
if(lpHandle->pCertRequest)
|
|
{
|
|
midl_user_free(lpHandle->pCertRequest);
|
|
}
|
|
|
|
if(lpHandle->pbChallengeData)
|
|
{
|
|
midl_user_free(lpHandle->pbChallengeData);
|
|
}
|
|
|
|
FreeMemory(lpHandle);
|
|
}
|
|
|
|
if(lpContext->m_ContextType == CONTEXTHANDLE_HYDRA_REQUESTCERT_TYPE)
|
|
{
|
|
//
|
|
// force calling TLSRpcRequestTermServCert() again
|
|
//
|
|
lpContext->m_ContextType = CONTEXTHANDLE_EMPTY_TYPE;
|
|
lpContext->m_ContextHandle = NULL;
|
|
}
|
|
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
lpContext->m_LastError=status;
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_RETRIEVE_TERMSRV_CERT;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(status);
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
error_status_t
|
|
TLSRpcAuditLicenseKeyPack(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwKeyPackId,
|
|
/* [in] */ FILETIME ftStartTime,
|
|
/* [in] */ FILETIME ftEndTime,
|
|
/* [in] */ BOOL bResetCounter,
|
|
/* [ref][out][in] */ LPTLSKeyPackAudit lplsAudit,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Not implemented yet!.
|
|
|
|
--*/
|
|
{
|
|
*pdwErrCode = TLSMapReturnCode(TLS_E_NOTSUPPORTED);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcGetLSPKCS10CertRequest(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwCertType,
|
|
/* [ref][out][in] */ PDWORD pcbData,
|
|
/* [size_is][size_is][out] */ PBYTE __RPC_FAR *ppbData,
|
|
/* [ref][out][in] */ PDWORD dwErrCode
|
|
)
|
|
/*
|
|
|
|
Abstract:
|
|
|
|
|
|
Note:
|
|
|
|
Only return our key at this time, not a PKCS10 request
|
|
|
|
*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcGetLSPKCS10CertRequest\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_ADMIN))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(AcquireAdministrativeLock(INFINITE) == TRUE)
|
|
{
|
|
status = RetrieveKey(
|
|
(dwCertType == TLSCERT_TYPE_EXCHANGE) ?
|
|
LSERVER_LSA_PRIVATEKEY_EXCHANGE :
|
|
LSERVER_LSA_PRIVATEKEY_SIGNATURE,
|
|
ppbData,
|
|
pcbData
|
|
);
|
|
|
|
ReleaseAdministrativeLock();
|
|
}
|
|
else
|
|
{
|
|
status = TLS_E_ALLOCATE_HANDLE;
|
|
}
|
|
|
|
cleanup:
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_GETPKCS10CERT_REQUEST;
|
|
#endif
|
|
|
|
*dwErrCode = TLSMapReturnCode(status);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Replication function
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
error_status_t
|
|
TLSRpcBeginReplication(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [string][in] */ LPTSTR pszLsSetupId,
|
|
/* [string][in] */ LPTSTR pszLsServerName,
|
|
/* [in] */ DWORD cbDomainSid,
|
|
/* [size_is][in] */ PBYTE pbDomainSid,
|
|
/* [ref][out][in] */ FILETIME __RPC_FAR *pftLastBackupTime,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
*pdwErrCode = TLSMapReturnCode(TLS_E_NOTSUPPORTED);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcEndReplication(
|
|
/* [in] */ PCONTEXT_HANDLE phContext
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcReplicateRecord(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [ref][in] */ PTLSReplRecord pReplRecord,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
*pdwErrCode = TLSMapReturnCode(TLS_E_NOTSUPPORTED);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcTableEnumBegin(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwSearchParam,
|
|
/* [ref][in] */ PTLSReplRecord pRecord,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
*pdwErrCode = TLSMapReturnCode(TLS_E_NOTSUPPORTED);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcTableEnumNext(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [ref][out][in] */ PTLSReplRecord pRecord,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
*pdwErrCode = TLSMapReturnCode(TLS_E_NOTSUPPORTED);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcTableEnumEnd(
|
|
/* [in] */ PCONTEXT_HANDLE phContext
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcInstallPolicyModule(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [string][in] */ LPTSTR pszCompanyName,
|
|
/* [string][in] */ LPTSTR pszProductId,
|
|
/* [string][in] */ LPTSTR pszPolicyDllName,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
++*/
|
|
{
|
|
*pdwErrCode = TLSMapReturnCode(TLS_E_NOTSUPPORTED);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcAnnounceServer(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwAnnounceType,
|
|
/* [in] */ FILETIME __RPC_FAR *pLastStartupTime,
|
|
/* [string][in] */ LPTSTR pszSetupId,
|
|
/* [string][in] */ LPTSTR pszDomainName,
|
|
/* [string][in] */ LPTSTR pszLserverName,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Private routine for other license server to announce presence of
|
|
itself.
|
|
|
|
Parameters:
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Note:
|
|
|
|
|
|
++*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status = ERROR_SUCCESS;
|
|
BOOL bSuccess = TRUE;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcAnnounceServer\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
__try {
|
|
//
|
|
// Verify it is a license server
|
|
//
|
|
if(lpContext->m_ClientFlags != CLIENT_ACCESS_LSERVER)
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
}
|
|
|
|
if( status == ERROR_SUCCESS &&
|
|
(dwAnnounceType == TLSANNOUNCE_TYPE_STARTUP || dwAnnounceType == TLSANNOUNCE_TYPE_RESPONSE) )
|
|
{
|
|
status = TLSRegisterServerWithName(
|
|
pszSetupId,
|
|
pszDomainName,
|
|
pszLserverName
|
|
);
|
|
if(status == TLS_E_DUPLICATE_RECORD)
|
|
{
|
|
status = ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if(status == ERROR_SUCCESS)
|
|
{
|
|
if(dwAnnounceType == TLSANNOUNCE_TYPE_STARTUP)
|
|
{
|
|
//
|
|
// Prevent loop back, use job to response announce
|
|
//
|
|
status = TLSStartAnnounceResponseJob(
|
|
pszSetupId,
|
|
pszDomainName,
|
|
pszLserverName,
|
|
&g_ftLastShutdownTime
|
|
);
|
|
}
|
|
|
|
if(status == ERROR_SUCCESS)
|
|
{
|
|
// Create a CSSync workobject to sync. local LKP
|
|
status = TLSPushSyncLocalLkpToServer(
|
|
pszSetupId,
|
|
pszDomainName,
|
|
pszLserverName,
|
|
pLastStartupTime
|
|
);
|
|
}
|
|
else
|
|
{
|
|
// reset error code, can't connect back to server -
|
|
// server might be available anymore.
|
|
status = ERROR_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
status = GetExceptionCode();
|
|
}
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_ANNOUNCE_SERVER;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(status);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcLookupServer(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [string][in] */ LPTSTR pszLookupSetupId,
|
|
/* [size_is][string][out][in] */ LPTSTR pszLsSetupId,
|
|
/* [out][in] */ PDWORD pcbSetupId,
|
|
/* [size_is][string][out][in] */ LPTSTR pszDomainName,
|
|
/* [ref][out][in] */ PDWORD pcbDomainName,
|
|
/* [size_is][string][out][in] */ LPTSTR pszMachineName,
|
|
/* [ref][out][in] */ PDWORD pcbMachineName,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Look up a license server via a license server's setupId.
|
|
|
|
|
|
Parameters:
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Note:
|
|
|
|
|
|
++*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcLookupServer\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
TLServerInfo ServerInfo;
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
|
|
__try {
|
|
|
|
if(_tcsicmp(pszLookupSetupId, g_pszServerPid) == 0)
|
|
{
|
|
_tcsncpy(
|
|
pszLsSetupId,
|
|
g_pszServerPid,
|
|
min(_tcslen(g_pszServerPid), *pcbSetupId)
|
|
);
|
|
|
|
if(*pcbSetupId <= _tcslen(g_pszServerPid))
|
|
{
|
|
dwStatus = TLS_E_INVALID_DATA;
|
|
}
|
|
else
|
|
{
|
|
pszLsSetupId[min(_tcslen(g_pszServerPid), *pcbSetupId - 1)] = _TEXT('\0');
|
|
}
|
|
*pcbSetupId = _tcslen(g_pszServerPid) + 1;
|
|
|
|
//--------------------------------------------------------------
|
|
_tcsncpy(
|
|
pszDomainName,
|
|
g_szScope,
|
|
min(_tcslen(g_szScope), *pcbDomainName)
|
|
);
|
|
|
|
if(*pcbDomainName <= _tcslen(g_szScope))
|
|
{
|
|
dwStatus = TLS_E_INVALID_DATA;
|
|
}
|
|
else
|
|
{
|
|
pszDomainName[min(_tcslen(g_szScope), *pcbDomainName - 1)] = _TEXT('\0');
|
|
}
|
|
*pcbDomainName = _tcslen(g_szScope) + 1;
|
|
|
|
//--------------------------------------------------------------
|
|
_tcsncpy(
|
|
pszMachineName,
|
|
g_szComputerName,
|
|
min(_tcslen(g_szComputerName), *pcbMachineName)
|
|
);
|
|
|
|
if(*pcbMachineName <= _tcslen(g_szComputerName))
|
|
{
|
|
dwStatus = TLS_E_INVALID_DATA;
|
|
}
|
|
else
|
|
{
|
|
pszMachineName[min(_tcslen(g_szComputerName), *pcbMachineName - 1)] = _TEXT('\0');
|
|
}
|
|
*pcbMachineName = _tcslen(g_szComputerName) + 1;
|
|
|
|
}
|
|
else
|
|
{
|
|
dwStatus = TLSLookupRegisteredServer(
|
|
pszLookupSetupId,
|
|
NULL,
|
|
pszMachineName,
|
|
&ServerInfo
|
|
);
|
|
if(dwStatus == ERROR_SUCCESS)
|
|
{
|
|
_tcsncpy(
|
|
pszLsSetupId,
|
|
ServerInfo.GetServerId(),
|
|
min(_tcslen(ServerInfo.GetServerId()), *pcbSetupId)
|
|
);
|
|
|
|
if(*pcbSetupId <= _tcslen(ServerInfo.GetServerId()))
|
|
{
|
|
dwStatus = TLS_E_INVALID_DATA;
|
|
}
|
|
else
|
|
{
|
|
pszLsSetupId[min(_tcslen(ServerInfo.GetServerId()), *pcbSetupId - 1)] = _TEXT('\0');
|
|
}
|
|
|
|
*pcbSetupId = _tcslen(ServerInfo.GetServerId()) + 1;
|
|
|
|
//--------------------------------------------------------------
|
|
_tcsncpy(
|
|
pszDomainName,
|
|
ServerInfo.GetServerDomain(),
|
|
min(_tcslen(ServerInfo.GetServerDomain()), *pcbDomainName)
|
|
);
|
|
if(*pcbDomainName <= _tcslen(ServerInfo.GetServerDomain()))
|
|
{
|
|
dwStatus = TLS_E_INVALID_DATA;
|
|
}
|
|
else
|
|
{
|
|
pszDomainName[min(_tcslen(ServerInfo.GetServerDomain()), *pcbDomainName - 1)] = _TEXT('\0');
|
|
}
|
|
*pcbDomainName = _tcslen(ServerInfo.GetServerDomain()) + 1;
|
|
|
|
//--------------------------------------------------------------
|
|
_tcsncpy(
|
|
pszMachineName,
|
|
ServerInfo.GetServerName(),
|
|
min(_tcslen(ServerInfo.GetServerName()), *pcbMachineName)
|
|
);
|
|
|
|
if(*pcbMachineName <= _tcslen(ServerInfo.GetServerName()))
|
|
{
|
|
dwStatus = TLS_E_INVALID_DATA;
|
|
}
|
|
else
|
|
{
|
|
pszMachineName[min(_tcslen(ServerInfo.GetServerName()), *pcbMachineName - 1)] = _TEXT('\0');
|
|
}
|
|
*pcbMachineName = _tcslen(ServerInfo.GetServerName()) + 1;
|
|
}
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
dwStatus = GetExceptionCode();
|
|
}
|
|
|
|
lpContext->m_LastError=dwStatus;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_SERVERLOOKUP;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(dwStatus);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcAnnounceLicensePack(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ PTLSReplRecord pReplRecord,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Private routine for one license server to announce it has particular
|
|
License Pack.
|
|
|
|
Parameters:
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
++*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD dwStatus=ERROR_SUCCESS;
|
|
PTLSDbWorkSpace pDbWkSpace=NULL;
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcAnnounceLicensePack\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
if(lpContext->m_ClientFlags != CLIENT_ACCESS_LSERVER)
|
|
{
|
|
dwStatus = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(pReplRecord->dwUnionType != UNION_TYPE_LICENSEPACK)
|
|
{
|
|
dwStatus = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(!ALLOCATEDBHANDLE(pDbWkSpace, g_GeneralDbTimeout))
|
|
{
|
|
dwStatus = TLS_E_ALLOCATE_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
CLEANUPSTMT;
|
|
BEGIN_TRANSACTION(pDbWkSpace);
|
|
|
|
try {
|
|
TLSLICENSEPACK LicPack;
|
|
LicPack = pReplRecord->w.ReplLicPack;
|
|
//
|
|
// TODO - verify input parameters
|
|
//
|
|
dwStatus = TLSDBRemoteKeyPackAdd(
|
|
USEHANDLE(pDbWkSpace),
|
|
&LicPack
|
|
);
|
|
}
|
|
catch( SE_Exception e ) {
|
|
dwStatus = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
dwStatus = TLS_E_INTERNAL;
|
|
}
|
|
|
|
if(TLS_ERROR(dwStatus) && dwStatus != TLS_E_DUPLICATE_RECORD)
|
|
{
|
|
ROLLBACK_TRANSACTION(pDbWkSpace);
|
|
}
|
|
else
|
|
{
|
|
COMMIT_TRANSACTION(pDbWkSpace);
|
|
}
|
|
|
|
FREEDBHANDLE(pDbWkSpace);
|
|
|
|
cleanup:
|
|
|
|
lpContext->m_LastError=dwStatus;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_ANNOUNCELICENSEPACK;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(dwStatus);
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcReturnLicensedProduct(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ PTLSLicenseToBeReturn pClientLicense,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
|
|
++*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD dwStatus=ERROR_SUCCESS;
|
|
CTLSPolicy* pPolicy=NULL;
|
|
PTLSDbWorkSpace pDbWorkSpace;
|
|
PMHANDLE hClient;
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcReturnLicensedProduct\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
if(lpContext->m_ClientFlags != CLIENT_ACCESS_LSERVER)
|
|
{
|
|
dwStatus = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
|
|
pPolicy = AcquirePolicyModule(
|
|
pClientLicense->pszCompanyName,
|
|
pClientLicense->pszOrgProductId,
|
|
FALSE
|
|
);
|
|
|
|
if(pPolicy == NULL)
|
|
{
|
|
dwStatus = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
hClient = GenerateClientId();
|
|
|
|
if(!ALLOCATEDBHANDLE(pDbWkSpace, g_GeneralDbTimeout))
|
|
{
|
|
dwStatus=TLS_E_ALLOCATE_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
CLEANUPSTMT;
|
|
BEGIN_TRANSACTION(pDbWorkSpace);
|
|
|
|
try {
|
|
dwStatus = TLSReturnClientLicensedProduct(
|
|
USEHANDLE(pDbWkSpace),
|
|
hClient,
|
|
pPolicy,
|
|
pClientLicense
|
|
);
|
|
}
|
|
catch( SE_Exception e ) {
|
|
dwStatus = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
SetLastError(dwStatus = TLS_E_INTERNAL);
|
|
}
|
|
|
|
if(TLS_ERROR(dwStatus))
|
|
{
|
|
ROLLBACK_TRANSACTION(pDbWorkSpace);
|
|
}
|
|
else
|
|
{
|
|
COMMIT_TRANSACTION(pDbWorkSpace);
|
|
}
|
|
|
|
FREEDBHANDLE(pDbWorkSpace);
|
|
|
|
|
|
cleanup:
|
|
|
|
lpContext->m_LastError=dwStatus;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_RETURNLICENSE;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(dwStatus);
|
|
|
|
if(pPolicy)
|
|
{
|
|
pPolicy->PMLicenseRequest(
|
|
hClient,
|
|
REQUEST_COMPLETE,
|
|
UlongToPtr (dwStatus),
|
|
NULL
|
|
);
|
|
|
|
ReleasePolicyModule(pPolicy);
|
|
}
|
|
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcChallengeServer(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwClientType,
|
|
/* [in] */ PTLSCHALLENGEDATA pClientChallenge,
|
|
/* [out][in] */ PTLSCHALLENGERESPONSEDATA* pServerResponse,
|
|
/* [out][in] */ PTLSCHALLENGEDATA* pServerChallenge,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Private routine for client to challenge server in order for client
|
|
confirm server's identity. License Server, in addition to response to
|
|
client's challenge, also generate random challenge data based on
|
|
client's self-declare type back to client.
|
|
|
|
Parameter:
|
|
|
|
phContext : Client's context handle.
|
|
dwClientType : Client self-pronounce type, valid values are ...
|
|
pClientChallenge : Client challenge data.
|
|
pServerResponse : Server's responses to client's challenge.
|
|
pServerChallenge : Server's challenge to client.
|
|
pdwErrCode : Error code if failed.
|
|
|
|
Returns:
|
|
|
|
|
|
Notes:
|
|
|
|
Private routine for LrWiz and License Server to identify itself.
|
|
|
|
--*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
|
|
PTLSCHALLENGEDATA pChallenge=NULL;
|
|
PTLSCHALLENGERESPONSEDATA pResponse = NULL;
|
|
HCRYPTPROV hProv = NULL;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcChallengeServer\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
//if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_ADMIN))
|
|
//{
|
|
// status = TLS_E_ACCESS_DENIED;
|
|
// goto cleanup;
|
|
//}
|
|
|
|
if(lpContext->m_ContextType != CONTEXTHANDLE_EMPTY_TYPE)
|
|
{
|
|
status = TLS_E_INVALID_SEQUENCE;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Input parameters...
|
|
//
|
|
if( pClientChallenge == NULL ||
|
|
pServerResponse == NULL ||
|
|
pServerChallenge == NULL )
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Verify Data send by client
|
|
//
|
|
if( pClientChallenge->dwVersion != TLS_CURRENT_CHALLENGE_VERSION ||
|
|
pClientChallenge->cbChallengeData == 0 ||
|
|
pClientChallenge->pbChallengeData == NULL )
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
pResponse = (PTLSCHALLENGERESPONSEDATA)midl_user_allocate(sizeof(TLSCHALLENGERESPONSEDATA));
|
|
if(pResponse == NULL)
|
|
{
|
|
status = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
pChallenge = (PTLSCHALLENGEDATA)AllocateMemory(sizeof(TLSCHALLENGEDATA));
|
|
if(pChallenge == NULL)
|
|
{
|
|
status = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
*pServerChallenge = (PTLSCHALLENGEDATA)midl_user_allocate(sizeof(TLSCHALLENGEDATA));
|
|
if(*pServerChallenge == NULL)
|
|
{
|
|
status = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Generate Challenge response data
|
|
//
|
|
status = TLSGenerateChallengeResponseData(
|
|
g_hCryptProv,
|
|
dwClientType,
|
|
pClientChallenge,
|
|
&(pResponse->pbResponseData),
|
|
&(pResponse->cbResponseData)
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Generate Server side challenge data
|
|
//
|
|
pChallenge->dwVersion = TLS_CURRENT_CHALLENGE_VERSION;
|
|
|
|
if (CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT)) {
|
|
if (!CryptGenRandom(hProv,sizeof(pChallenge->dwRandom), (BYTE *) &pChallenge->dwRandom)) {
|
|
status = TLS_E_INTERNAL;
|
|
goto cleanup;
|
|
}
|
|
} else {
|
|
status = TLS_E_INTERNAL;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// This must range from 1 to 128, as it's used as an offset into the
|
|
// challenge data buffer
|
|
//
|
|
|
|
pChallenge->dwRandom %= RANDOM_CHALLENGE_DATASIZE;
|
|
pChallenge->dwRandom++;
|
|
|
|
status = TLSGenerateRandomChallengeData(
|
|
g_hCryptProv,
|
|
&(pChallenge->pbChallengeData),
|
|
&(pChallenge->cbChallengeData)
|
|
);
|
|
|
|
// base on type, mark this handle...
|
|
if(dwClientType == CLIENT_TYPE_LRWIZ)
|
|
{
|
|
lpContext->m_ContextType = CONTEXTHANDLE_CHALLENGE_LRWIZ_TYPE;
|
|
}
|
|
else
|
|
{
|
|
lpContext->m_ContextType = CONTEXTHANDLE_CHALLENGE_SERVER_TYPE;
|
|
}
|
|
|
|
(*pServerChallenge)->pbChallengeData = (PBYTE)midl_user_allocate(pChallenge->cbChallengeData);
|
|
if((*pServerChallenge)->pbChallengeData == NULL)
|
|
{
|
|
status = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
(*pServerChallenge)->dwVersion = TLS_CURRENT_CHALLENGE_VERSION;
|
|
(*pServerChallenge)->dwRandom = pChallenge->dwRandom;
|
|
(*pServerChallenge)->cbChallengeData = pChallenge->cbChallengeData;
|
|
memcpy(
|
|
(*pServerChallenge)->pbChallengeData,
|
|
pChallenge->pbChallengeData,
|
|
pChallenge->cbChallengeData
|
|
);
|
|
|
|
lpContext->m_ContextHandle = (HANDLE)(pChallenge);
|
|
*pServerResponse = pResponse;
|
|
|
|
cleanup:
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
if(pChallenge)
|
|
{
|
|
if(pChallenge->pbChallengeData)
|
|
{
|
|
FreeMemory(pChallenge->pbChallengeData);
|
|
}
|
|
|
|
if(pChallenge->pbReservedData)
|
|
{
|
|
FreeMemory(pChallenge->pbReservedData);
|
|
}
|
|
|
|
FreeMemory(pChallenge);
|
|
}
|
|
|
|
if(pResponse)
|
|
{
|
|
if(pResponse->pbResponseData)
|
|
{
|
|
FreeMemory(pResponse->pbResponseData);
|
|
}
|
|
|
|
if(pResponse->pbReservedData)
|
|
{
|
|
FreeMemory(pResponse->pbReservedData);
|
|
}
|
|
|
|
midl_user_free(pResponse);
|
|
}
|
|
}
|
|
|
|
if (hProv)
|
|
CryptReleaseContext(hProv,0);
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_CHALLENGESERVER;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(status);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcResponseServerChallenge(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ PTLSCHALLENGERESPONSEDATA pClientResponse,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Client's responses to Server challenge returned TLSRpcChallengeServer(),
|
|
must have call TLSRpcChallengeServer().
|
|
|
|
Parameter:
|
|
|
|
phContext:
|
|
pClientResponses: Client's response to server's challenge.
|
|
pdwErrCode : Return error code.
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Note:
|
|
|
|
--*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
DWORD dwClientType;
|
|
PTLSCHALLENGEDATA pServerToClientChallenge;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcResponseServerChallenge\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
//if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_ADMIN))
|
|
//{
|
|
// status = TLS_E_ACCESS_DENIED;
|
|
// goto cleanup;
|
|
//}
|
|
|
|
if( pClientResponse == NULL ||
|
|
pClientResponse->pbResponseData == NULL ||
|
|
pClientResponse->cbResponseData == 0 )
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(lpContext->m_ContextType != CONTEXTHANDLE_CHALLENGE_SERVER_TYPE &&
|
|
lpContext->m_ContextType != CONTEXTHANDLE_CHALLENGE_LRWIZ_TYPE)
|
|
{
|
|
status = TLS_E_INVALID_SEQUENCE;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(lpContext->m_ContextHandle == NULL)
|
|
{
|
|
status = TLS_E_INTERNAL;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(lpContext->m_ContextType == CONTEXTHANDLE_CHALLENGE_LRWIZ_TYPE)
|
|
{
|
|
dwClientType = CLIENT_TYPE_LRWIZ;
|
|
}
|
|
else
|
|
{
|
|
dwClientType = CLIENT_TYPE_TLSERVER;
|
|
}
|
|
|
|
pServerToClientChallenge = (PTLSCHALLENGEDATA)lpContext->m_ContextHandle;
|
|
|
|
//
|
|
// base on client type, verify challenge response data
|
|
//
|
|
status = TLSVerifyChallengeResponse(
|
|
g_hCryptProv,
|
|
dwClientType,
|
|
pServerToClientChallenge,
|
|
pClientResponse
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
}
|
|
else
|
|
{
|
|
if(dwClientType == CLIENT_TYPE_LRWIZ)
|
|
{
|
|
lpContext->m_ClientFlags |= CLIENT_ACCESS_LRWIZ;
|
|
}
|
|
else
|
|
{
|
|
lpContext->m_ClientFlags |= CLIENT_ACCESS_LSERVER;
|
|
}
|
|
}
|
|
|
|
if(pServerToClientChallenge != NULL)
|
|
{
|
|
FreeMemory(pServerToClientChallenge->pbChallengeData);
|
|
FreeMemory(pServerToClientChallenge);
|
|
}
|
|
|
|
lpContext->m_ContextHandle = NULL;
|
|
lpContext->m_ContextType = CONTEXTHANDLE_EMPTY_TYPE;
|
|
|
|
cleanup:
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_RESPONSESERVERCHALLENGE;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(status);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcGetTlsPrivateData(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwPrivateDataType,
|
|
/* [switch_is][in] */ PTLSPrivateDataUnion pSearchData,
|
|
/* [ref][out][in] */ PDWORD pdwRetDataType,
|
|
/* [switch_is][out] */ PTLSPrivateDataUnion __RPC_FAR *ppPrivateData,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Retrieve license server's private data, this include Server's
|
|
unique ID, PID, and registered SPK if any.
|
|
|
|
Parameters:
|
|
|
|
phContext : Client's context handle.
|
|
dwPrivateDataType : Type of private data interested.
|
|
pSearchData : Type of data to search, currently ignore.
|
|
pdwRetDataType : Return data type.
|
|
ppPrivateData : License Server's private data.
|
|
pdwErrCode : Error Code.
|
|
|
|
Returns:
|
|
|
|
|
|
Note:
|
|
|
|
Only LrWiz and License Server can invoke this RPC call.
|
|
|
|
--*/
|
|
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
DWORD cbSource=0;
|
|
PBYTE pbSource=NULL;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcGetTlsPrivateData\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
//
|
|
// relax restriction on who can get private data
|
|
//
|
|
if( dwPrivateDataType != TLS_PRIVATEDATA_PID &&
|
|
dwPrivateDataType != TLS_PRIVATEDATA_UNIQUEID )
|
|
{
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_LRWIZ))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
if( dwPrivateDataType < TLS_PRIVATEDATA_MIN ||
|
|
dwPrivateDataType > TLS_PRIVATEDATA_MAX )
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Not supported yet...
|
|
//
|
|
if(dwPrivateDataType == TLS_PRIVATEDATA_INSTALLED_CERT)
|
|
{
|
|
status = TLS_E_NOTSUPPORTED;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Don't really need this but we might need to support
|
|
// re-generate of License Server ID
|
|
//
|
|
if(!AcquireAdministrativeLock(INFINITE))
|
|
{
|
|
status = TLS_E_ALLOCATE_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
switch(dwPrivateDataType)
|
|
{
|
|
case TLS_PRIVATEDATA_UNIQUEID:
|
|
pbSource = (PBYTE)g_pszServerUniqueId;
|
|
cbSource = g_cbServerUniqueId;
|
|
break;
|
|
|
|
case TLS_PRIVATEDATA_PID:
|
|
pbSource = (PBYTE)g_pszServerPid;
|
|
cbSource = g_cbServerPid;
|
|
break;
|
|
|
|
case TLS_PRIVATEDATA_SPK:
|
|
pbSource = g_pbServerSPK;
|
|
cbSource = g_cbServerSPK;
|
|
}
|
|
|
|
//
|
|
// Currently, what you ask is what you get.
|
|
//
|
|
*pdwRetDataType = dwPrivateDataType;
|
|
|
|
if( (dwPrivateDataType != TLS_PRIVATEDATA_SYSTEMLANGID) &&
|
|
(pbSource == NULL || cbSource == 0) )
|
|
{
|
|
status = TLS_E_RECORD_NOTFOUND;
|
|
}
|
|
else
|
|
{
|
|
*ppPrivateData = (PTLSPrivateDataUnion)midl_user_allocate(sizeof(TLSPrivateDataUnion));
|
|
if(*ppPrivateData != NULL)
|
|
{
|
|
memset(
|
|
*ppPrivateData,
|
|
0,
|
|
sizeof(TLSPrivateDataUnion)
|
|
);
|
|
|
|
if(*pdwRetDataType == TLS_PRIVATEDATA_SYSTEMLANGID)
|
|
{
|
|
(*ppPrivateData)->systemLangId = GetSystemDefaultLangID();
|
|
}
|
|
else if(*pdwRetDataType == TLS_PRIVATEDATA_SPK)
|
|
{
|
|
(*ppPrivateData)->SPK.cbSPK = cbSource;
|
|
(*ppPrivateData)->SPK.pbSPK = pbSource;
|
|
(*ppPrivateData)->SPK.pCertExtensions = g_pCertExtensions;
|
|
|
|
//(*ppPrivateData)->SPK.pCertExtensions = (PTLSCERT_EXTENSIONS)midl_user_allocate(g_cbCertExtensions);
|
|
//memcpy(
|
|
// (*ppPrivateData)->SPK.pCertExtensions,
|
|
// g_pCertExtensions,
|
|
// g_cbCertExtensions
|
|
// );
|
|
}
|
|
else
|
|
{
|
|
(*ppPrivateData)->BinaryData.cbData = cbSource;
|
|
(*ppPrivateData)->BinaryData.pbData = pbSource;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = ERROR_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
ReleaseAdministrativeLock();
|
|
|
|
cleanup:
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_GETPRIVATEDATA;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(status);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcSetTlsPrivateData(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD dwPrivateDataType,
|
|
/* [switch_is][in] */ PTLSPrivateDataUnion pPrivateData,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Private routine for LrWiz to set license server's private data.
|
|
|
|
Parameter:
|
|
|
|
phContext: Client context handle.
|
|
dwPrivateDataType : Type of private data to set.
|
|
pPrivateData : Private data to set/install.
|
|
pdwErrCode : Server return code.
|
|
|
|
Returns:
|
|
|
|
|
|
Note:
|
|
|
|
Only support installing of SPK/Extension at this time.
|
|
|
|
--*/
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
DWORD dwSpkVerifyResult;
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcDepositeSPK\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_LRWIZ))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Only support SPK at this time
|
|
//
|
|
if(dwPrivateDataType != TLS_PRIVATEDATA_SPK)
|
|
{
|
|
status = TLS_E_INVALID_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Lock all RPC calls related to issuing certificate
|
|
//
|
|
if(!AcquireRPCExclusiveLock(INFINITE))
|
|
{
|
|
status = TLS_E_ALLOCATE_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
do {
|
|
//if(g_pbServerSPK != NULL && g_cbServerSPK != 0)
|
|
//{
|
|
// status = TLS_E_SPKALREADYEXIST;
|
|
// break;
|
|
//}
|
|
|
|
if(AcquireAdministrativeLock(INFINITE))
|
|
{
|
|
try {
|
|
status = TLSReGenSelfSignCert(
|
|
g_hCryptProv,
|
|
pPrivateData->SPK.pbSPK,
|
|
pPrivateData->SPK.cbSPK,
|
|
pPrivateData->SPK.pCertExtensions->cExtension,
|
|
pPrivateData->SPK.pCertExtensions->rgExtension
|
|
);
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
ReleaseAdministrativeLock();
|
|
}
|
|
else
|
|
{
|
|
status = TLS_E_ALLOCATE_HANDLE;
|
|
}
|
|
} while(FALSE);
|
|
|
|
ReleaseRPCExclusiveLock();
|
|
|
|
cleanup:
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_SETPRIVATEDATA;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(status);
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcTriggerReGenKey(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ BOOL bRegenKey,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Private routine to force license server to re-generate its
|
|
public/private key pair, all installed certificates/SPK are
|
|
deleted, User are required to re-register license server.
|
|
|
|
Parameters:
|
|
|
|
phContext : Client context handle.
|
|
bKeepSPKAndExtension : For future use only.
|
|
pdwErrCode : Return error code.
|
|
|
|
Returns:
|
|
|
|
|
|
++*/
|
|
|
|
{
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
DWORD status=ERROR_SUCCESS;
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcTriggerReGenKey\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_LRWIZ))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
LPCTSTR pString[1];
|
|
|
|
pString[0] = lpContext->m_Client;
|
|
|
|
TLSLogEventString(
|
|
EVENTLOG_INFORMATION_TYPE,
|
|
TLS_I_TRIGGER_REGENKEY,
|
|
1,
|
|
pString
|
|
);
|
|
|
|
//
|
|
// Block ALL RPC calls
|
|
//
|
|
if(!AcquireRPCExclusiveLock(INFINITE))
|
|
{
|
|
status=TLS_E_ALLOCATE_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
do {
|
|
if(!AcquireAdministrativeLock(INFINITE))
|
|
{
|
|
status = TLS_E_ALLOCATE_HANDLE;
|
|
break;
|
|
}
|
|
|
|
try {
|
|
status = TLSReGenKeysAndReloadServerCert(
|
|
bRegenKey
|
|
);
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
ReleaseAdministrativeLock();
|
|
|
|
} while(FALSE);
|
|
|
|
ReleaseRPCExclusiveLock();
|
|
|
|
cleanup:
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_TRIGGERREGENKEY;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(status);
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcTelephoneRegisterLKP(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD cbData,
|
|
/* [size_is][in] */ PBYTE pbData,
|
|
/* [ref][out] */ PDWORD pdwErrCode
|
|
)
|
|
|
|
/*++
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD status=ERROR_SUCCESS;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
PTLSDbWorkSpace pDbWkSpace;
|
|
LSKeyPack keypack;
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcTelephoneRegisterLKP\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_LRWIZ))
|
|
{
|
|
status = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
if(!ALLOCATEDBHANDLE(pDbWkSpace, g_GeneralDbTimeout))
|
|
{
|
|
status=TLS_E_ALLOCATE_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
CLEANUPSTMT;
|
|
BEGIN_TRANSACTION(pDbWkSpace);
|
|
|
|
try {
|
|
status = TLSDBTelephoneRegisterLicenseKeyPack(
|
|
USEHANDLE(pDbWkSpace),
|
|
g_pszServerPid,
|
|
pbData,
|
|
cbData,
|
|
&keypack
|
|
);
|
|
}
|
|
catch( SE_Exception e ) {
|
|
status = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
status = TLS_E_INTERNAL;
|
|
}
|
|
|
|
if(TLS_ERROR(status))
|
|
{
|
|
ROLLBACK_TRANSACTION(pDbWkSpace);
|
|
}
|
|
else
|
|
{
|
|
COMMIT_TRANSACTION(pDbWkSpace);
|
|
}
|
|
|
|
FREEDBHANDLE(pDbWkSpace);
|
|
|
|
//
|
|
// Post a sync work object
|
|
//
|
|
if(status == ERROR_SUCCESS)
|
|
{
|
|
if(TLSAnnounceLKPToAllRemoteServer(
|
|
keypack.dwKeyPackId,
|
|
0
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
TLSLogWarningEvent(TLS_W_ANNOUNCELKP_FAILED);
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
|
|
|
|
lpContext->m_LastError=status;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_TELEPHONEREGISTERLKP;
|
|
#endif
|
|
|
|
|
|
*pdwErrCode = TLSMapReturnCode(status);
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcAllocateInternetLicense(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ const CHALLENGE_CONTEXT ChallengeContext,
|
|
/* [in] */ const PTLSLICENSEREQUEST pRequest,
|
|
/* [string][in] */ LPTSTR pMachineName,
|
|
/* [string][in] */ LPTSTR pUserName,
|
|
/* [in] */ const DWORD cbChallengeResponse,
|
|
/* [size_is][in] */ const PBYTE pbChallengeResponse,
|
|
/* [out] */ PDWORD pcbLicense,
|
|
/* [size_is][size_is][out] */ BYTE __RPC_FAR *__RPC_FAR *pbLicense,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
|
|
|
|
--*/
|
|
{
|
|
return TLSRpcRequestNewLicense(
|
|
phContext,
|
|
ChallengeContext,
|
|
pRequest,
|
|
pMachineName,
|
|
pUserName,
|
|
cbChallengeResponse,
|
|
pbChallengeResponse,
|
|
FALSE,
|
|
pcbLicense,
|
|
pbLicense,
|
|
pdwErrCode
|
|
);
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcAllocateInternetLicenseEx(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ const CHALLENGE_CONTEXT ChallengeContext,
|
|
/* [in] */ const PTLSLICENSEREQUEST pRequest,
|
|
/* [string][in] */ LPTSTR pMachineName,
|
|
/* [string][in] */ LPTSTR pUserName,
|
|
/* [in] */ const DWORD cbChallengeResponse,
|
|
/* [size_is][in] */ const PBYTE pbChallengeResponse,
|
|
/* [ref][out] */ PTLSInternetLicense pInternetLicense,
|
|
/* [ref][out] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
--*/
|
|
{
|
|
PBYTE pbLicense = NULL;
|
|
DWORD cbLicense = 0;
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
DWORD index = 0;
|
|
PLICENSEDPRODUCT pLicensedProduct = NULL;
|
|
DWORD dwNumLicensedProduct = 0;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
|
|
if(lpContext == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
goto cleanup;
|
|
}
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcAllocateInternetLicenseEx\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
//
|
|
// Internally forward the request.
|
|
//
|
|
dwStatus = TLSRpcAllocateInternetLicense(
|
|
phContext,
|
|
ChallengeContext,
|
|
pRequest,
|
|
pMachineName,
|
|
pUserName,
|
|
cbChallengeResponse,
|
|
pbChallengeResponse,
|
|
&cbLicense,
|
|
&pbLicense,
|
|
pdwErrCode
|
|
);
|
|
|
|
if(*pdwErrCode >= LSERVER_ERROR_BASE)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// decode the license.
|
|
//
|
|
dwStatus = LSVerifyDecodeClientLicense(
|
|
pbLicense,
|
|
cbLicense,
|
|
g_pbSecretKey,
|
|
g_cbSecretKey,
|
|
&dwNumLicensedProduct,
|
|
pLicensedProduct
|
|
);
|
|
|
|
//
|
|
// Internet license can only have one licensed product
|
|
//
|
|
if(dwStatus != LICENSE_STATUS_OK || dwNumLicensedProduct == 0 || dwNumLicensedProduct > 1)
|
|
{
|
|
dwStatus = TLS_E_INTERNAL;
|
|
goto cleanup;
|
|
}
|
|
|
|
pLicensedProduct = (PLICENSEDPRODUCT)AllocateMemory(
|
|
dwNumLicensedProduct * sizeof(LICENSEDPRODUCT)
|
|
);
|
|
if(pLicensedProduct == NULL)
|
|
{
|
|
dwStatus = TLS_E_ALLOCATE_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
dwStatus = LSVerifyDecodeClientLicense(
|
|
pbLicense,
|
|
cbLicense,
|
|
g_pbSecretKey,
|
|
g_cbSecretKey,
|
|
&dwNumLicensedProduct,
|
|
pLicensedProduct
|
|
);
|
|
|
|
if(dwStatus != LICENSE_STATUS_OK)
|
|
{
|
|
dwStatus = TLS_E_INTERNAL;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Sets up returns.
|
|
//
|
|
SAFESTRCPY(pInternetLicense->szServerId, pLicensedProduct->szIssuerId);
|
|
SAFESTRCPY(pInternetLicense->szServerName, pLicensedProduct->szIssuer);
|
|
pInternetLicense->ulSerialNumber = pLicensedProduct->ulSerialNumber;
|
|
pInternetLicense->dwQuantity = pLicensedProduct->dwQuantity;
|
|
|
|
cleanup:
|
|
|
|
lpContext->m_LastError=dwStatus;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_ALLOCATEINTERNETLICNESEEX;
|
|
#endif
|
|
|
|
if(*pdwErrCode == ERROR_SUCCESS)
|
|
{
|
|
*pdwErrCode = TLSMapReturnCode(dwStatus);
|
|
}
|
|
|
|
if(pLicensedProduct != NULL)
|
|
{
|
|
for(index =0; index < dwNumLicensedProduct; index++)
|
|
{
|
|
LSFreeLicensedProduct(pLicensedProduct+index);
|
|
}
|
|
|
|
FreeMemory(pLicensedProduct);
|
|
}
|
|
|
|
if(pbLicense != NULL)
|
|
{
|
|
midl_user_free(pbLicense);
|
|
}
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcReturnInternetLicenseEx(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ const PTLSLICENSEREQUEST pRequest,
|
|
/* [in] */ const ULARGE_INTEGER __RPC_FAR *pulSerialNumber,
|
|
/* [in] */ DWORD dwQuantity,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
--*/
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
TLSLicenseToBeReturn TobeReturn;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
PTLSDbWorkSpace pDbWorkSpace = NULL;
|
|
CTLSPolicy* pPolicy = NULL;
|
|
PMHANDLE hClient;
|
|
|
|
PMLICENSEREQUEST PMLicenseRequest;
|
|
PPMLICENSEREQUEST pAdjustedRequest;
|
|
|
|
TCHAR szCompanyName[LSERVER_MAX_STRING_SIZE+2];
|
|
TCHAR szProductId[LSERVER_MAX_STRING_SIZE+2];
|
|
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
|
|
if(VerifyLicenseRequest(pRequest) == FALSE)
|
|
{
|
|
SetLastError(dwStatus = TLS_E_INVALID_DATA);
|
|
goto cleanup;
|
|
}
|
|
|
|
if(lpContext == NULL)
|
|
{
|
|
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
|
|
goto cleanup;
|
|
}
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcReturnInternetLicenseEx\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_REQUEST))
|
|
{
|
|
dwStatus = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
memset(szCompanyName, 0, sizeof(szCompanyName));
|
|
memset(szProductId, 0, sizeof(szProductId));
|
|
|
|
memcpy(
|
|
szCompanyName,
|
|
pRequest->ProductInfo.pbCompanyName,
|
|
min(pRequest->ProductInfo.cbCompanyName, sizeof(szCompanyName)-sizeof(TCHAR))
|
|
);
|
|
|
|
memcpy(
|
|
szProductId,
|
|
pRequest->ProductInfo.pbProductID,
|
|
min(pRequest->ProductInfo.cbProductID, sizeof(szProductId)-sizeof(TCHAR))
|
|
);
|
|
|
|
//
|
|
// Allocate policy module, must have the right policy module to
|
|
// return license.
|
|
//
|
|
pPolicy = AcquirePolicyModule(
|
|
szCompanyName,
|
|
szProductId,
|
|
TRUE
|
|
);
|
|
|
|
if(pPolicy == NULL)
|
|
{
|
|
dwStatus = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
hClient = GenerateClientId();
|
|
|
|
|
|
//
|
|
// Convert request to PMLICENSEREQUEST
|
|
//
|
|
TlsLicenseRequestToPMLicenseRequest(
|
|
LICENSETYPE_LICENSE,
|
|
pRequest,
|
|
_TEXT(""),
|
|
_TEXT(""),
|
|
0,
|
|
&PMLicenseRequest
|
|
);
|
|
|
|
//
|
|
// Ask policy module the actual product ID
|
|
//
|
|
dwStatus = pPolicy->PMLicenseRequest(
|
|
hClient,
|
|
REQUEST_NEW,
|
|
(PVOID) &PMLicenseRequest,
|
|
(PVOID *) &pAdjustedRequest
|
|
);
|
|
|
|
memset(&TobeReturn, 0, sizeof(TobeReturn));
|
|
|
|
TobeReturn.dwQuantity = dwQuantity;
|
|
TobeReturn.dwKeyPackId = pulSerialNumber->HighPart;
|
|
TobeReturn.dwLicenseId = pulSerialNumber->LowPart;
|
|
TobeReturn.dwPlatformID = pAdjustedRequest->dwPlatformId;
|
|
TobeReturn.cbEncryptedHwid = pRequest->cbEncryptedHwid;
|
|
TobeReturn.pbEncryptedHwid = pRequest->pbEncryptedHwid;
|
|
TobeReturn.dwProductVersion = pAdjustedRequest->dwProductVersion;
|
|
TobeReturn.pszOrgProductId = szProductId;
|
|
TobeReturn.pszCompanyName = szCompanyName;
|
|
TobeReturn.pszProductId = pAdjustedRequest->pszProductId;
|
|
|
|
//
|
|
// Allocate DB handle
|
|
//
|
|
if(!ALLOCATEDBHANDLE(pDbWkSpace, g_GeneralDbTimeout))
|
|
{
|
|
dwStatus = TLS_E_ALLOCATE_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
CLEANUPSTMT;
|
|
BEGIN_TRANSACTION(pDbWorkSpace);
|
|
|
|
try {
|
|
dwStatus = TLSReturnClientLicensedProduct(
|
|
USEHANDLE(pDbWkSpace),
|
|
hClient,
|
|
pPolicy,
|
|
&TobeReturn
|
|
);
|
|
}
|
|
catch( SE_Exception e ) {
|
|
dwStatus = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
SetLastError(dwStatus = TLS_E_INTERNAL);
|
|
}
|
|
|
|
if(TLS_ERROR(dwStatus))
|
|
{
|
|
ROLLBACK_TRANSACTION(pDbWorkSpace);
|
|
}
|
|
else
|
|
{
|
|
COMMIT_TRANSACTION(pDbWorkSpace);
|
|
}
|
|
|
|
FREEDBHANDLE(pDbWorkSpace);
|
|
|
|
cleanup:
|
|
|
|
lpContext->m_LastError=dwStatus;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_RETURNINTERNETLICENSEEX;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(dwStatus);
|
|
|
|
if(pPolicy)
|
|
{
|
|
pPolicy->PMLicenseRequest(
|
|
hClient,
|
|
REQUEST_COMPLETE,
|
|
UlongToPtr (dwStatus),
|
|
NULL
|
|
);
|
|
|
|
ReleasePolicyModule(pPolicy);
|
|
}
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
error_status_t
|
|
TLSRpcReturnInternetLicense(
|
|
/* [in] */ PCONTEXT_HANDLE phContext,
|
|
/* [in] */ DWORD cbLicense,
|
|
/* [size_is][in] */ PBYTE pbLicense,
|
|
/* [ref][out][in] */ PDWORD pdwErrCode
|
|
)
|
|
/*++
|
|
|
|
--*/
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
DWORD index = 0;
|
|
PLICENSEDPRODUCT pLicensedProduct = NULL;
|
|
DWORD dwNumLicensedProduct = 0;
|
|
TLSLicenseToBeReturn TobeReturn;
|
|
LPCLIENTCONTEXT lpContext = (LPCLIENTCONTEXT)phContext;
|
|
PTLSDbWorkSpace pDbWorkSpace = NULL;
|
|
CTLSPolicy* pPolicy = NULL;
|
|
PMHANDLE hClient;
|
|
|
|
|
|
_se_translator_function old_trans_se_func = NULL;
|
|
old_trans_se_func = _set_se_translator( trans_se_func );
|
|
|
|
|
|
|
|
if(lpContext == NULL)
|
|
{
|
|
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
|
|
goto cleanup;
|
|
}
|
|
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RPC,
|
|
DBGLEVEL_FUNCTION_TRACE,
|
|
_TEXT("%s : TLSRpcReturnInternetLicense\n"),
|
|
lpContext->m_Client
|
|
);
|
|
|
|
InterlockedIncrement( &lpContext->m_RefCount );
|
|
if(!(lpContext->m_ClientFlags & CLIENT_ACCESS_REQUEST))
|
|
{
|
|
dwStatus = TLS_E_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
// decode the license.
|
|
// -------------------------------------------------------
|
|
dwStatus = LSVerifyDecodeClientLicense(
|
|
pbLicense,
|
|
cbLicense,
|
|
g_pbSecretKey,
|
|
g_cbSecretKey,
|
|
&dwNumLicensedProduct,
|
|
pLicensedProduct
|
|
);
|
|
|
|
// -------------------------------------------------------
|
|
// Internet license can only have one licensed product
|
|
// -------------------------------------------------------
|
|
if(dwStatus != LICENSE_STATUS_OK || dwNumLicensedProduct == 0 || dwNumLicensedProduct > 1)
|
|
{
|
|
dwStatus = TLS_E_INVALID_LICENSE;
|
|
goto cleanup;
|
|
}
|
|
|
|
pLicensedProduct = (PLICENSEDPRODUCT)AllocateMemory(
|
|
dwNumLicensedProduct * sizeof(LICENSEDPRODUCT)
|
|
);
|
|
if(pLicensedProduct == NULL)
|
|
{
|
|
dwStatus = TLS_E_ALLOCATE_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
dwStatus = LSVerifyDecodeClientLicense(
|
|
pbLicense,
|
|
cbLicense,
|
|
g_pbSecretKey,
|
|
g_cbSecretKey,
|
|
&dwNumLicensedProduct,
|
|
pLicensedProduct
|
|
);
|
|
|
|
if(dwStatus != LICENSE_STATUS_OK)
|
|
{
|
|
dwStatus = TLS_E_INVALID_LICENSE;
|
|
goto cleanup;
|
|
}
|
|
|
|
|
|
TobeReturn.dwQuantity = pLicensedProduct->dwQuantity;
|
|
TobeReturn.dwKeyPackId = pLicensedProduct->ulSerialNumber.HighPart;
|
|
TobeReturn.dwLicenseId = pLicensedProduct->ulSerialNumber.LowPart;
|
|
TobeReturn.dwPlatformID = pLicensedProduct->LicensedProduct.dwPlatformID;
|
|
TobeReturn.cbEncryptedHwid = pLicensedProduct->LicensedProduct.cbEncryptedHwid;
|
|
TobeReturn.pbEncryptedHwid = pLicensedProduct->LicensedProduct.pbEncryptedHwid;
|
|
TobeReturn.dwProductVersion = MAKELONG(
|
|
pLicensedProduct->pLicensedVersion->wMinorVersion,
|
|
pLicensedProduct->pLicensedVersion->wMajorVersion
|
|
);
|
|
|
|
TobeReturn.pszOrgProductId = (LPTSTR) pLicensedProduct->pbOrgProductID;
|
|
TobeReturn.pszCompanyName = (LPTSTR) pLicensedProduct->LicensedProduct.pProductInfo->pbCompanyName;
|
|
TobeReturn.pszProductId = (LPTSTR) pLicensedProduct->LicensedProduct.pProductInfo->pbProductID;
|
|
TobeReturn.pszUserName = (LPTSTR) pLicensedProduct->szLicensedUser;
|
|
TobeReturn.pszMachineName = pLicensedProduct->szLicensedClient;
|
|
|
|
|
|
//
|
|
// Allocate policy module, must have the right policy module to
|
|
// return license.
|
|
//
|
|
pPolicy = AcquirePolicyModule(
|
|
TobeReturn.pszCompanyName,
|
|
TobeReturn.pszOrgProductId,
|
|
TRUE
|
|
);
|
|
|
|
if(pPolicy == NULL)
|
|
{
|
|
dwStatus = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
hClient = GenerateClientId();
|
|
|
|
//
|
|
// Allocate DB handle
|
|
//
|
|
if(!ALLOCATEDBHANDLE(pDbWkSpace, g_GeneralDbTimeout))
|
|
{
|
|
dwStatus = TLS_E_ALLOCATE_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
CLEANUPSTMT;
|
|
BEGIN_TRANSACTION(pDbWorkSpace);
|
|
|
|
try {
|
|
dwStatus = TLSReturnClientLicensedProduct(
|
|
USEHANDLE(pDbWkSpace),
|
|
hClient,
|
|
pPolicy,
|
|
&TobeReturn
|
|
);
|
|
}
|
|
catch( SE_Exception e ) {
|
|
dwStatus = e.getSeNumber();
|
|
}
|
|
catch(...) {
|
|
SetLastError(dwStatus = TLS_E_INTERNAL);
|
|
}
|
|
|
|
if(TLS_ERROR(dwStatus))
|
|
{
|
|
ROLLBACK_TRANSACTION(pDbWorkSpace);
|
|
}
|
|
else
|
|
{
|
|
COMMIT_TRANSACTION(pDbWorkSpace);
|
|
}
|
|
|
|
FREEDBHANDLE(pDbWorkSpace);
|
|
|
|
cleanup:
|
|
|
|
lpContext->m_LastError=dwStatus;
|
|
InterlockedDecrement( &lpContext->m_RefCount );
|
|
|
|
#if DBG
|
|
lpContext->m_LastCall = RPC_CALL_RETURNINTERNETLICENSE;
|
|
#endif
|
|
|
|
*pdwErrCode = TLSMapReturnCode(dwStatus);
|
|
|
|
if(pLicensedProduct != NULL)
|
|
{
|
|
for(index =0; index < dwNumLicensedProduct; index++)
|
|
{
|
|
LSFreeLicensedProduct(pLicensedProduct+index);
|
|
}
|
|
|
|
FreeMemory(pLicensedProduct);
|
|
}
|
|
|
|
if(pPolicy)
|
|
{
|
|
pPolicy->PMLicenseRequest(
|
|
hClient,
|
|
REQUEST_COMPLETE,
|
|
UlongToPtr (dwStatus),
|
|
NULL
|
|
);
|
|
|
|
ReleasePolicyModule(pPolicy);
|
|
}
|
|
|
|
//
|
|
// Reset SE translator
|
|
//
|
|
_set_se_translator(old_trans_se_func);
|
|
return RPC_S_OK;
|
|
}
|