You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
353 lines
14 KiB
353 lines
14 KiB
/**MOD+**********************************************************************/
|
|
/* Header: CLicense.cpp */
|
|
/* */
|
|
/* Purpose: Client License Manager implementation */
|
|
/* */
|
|
/* Copyright(C) Microsoft Corporation 1997-1999 */
|
|
/* */
|
|
/****************************************************************************/
|
|
|
|
#include <adcg.h>
|
|
|
|
extern "C" {
|
|
#include <clicense.h>
|
|
#define TRC_GROUP TRC_GROUP_SECURITY
|
|
#define TRC_FILE "clicense"
|
|
#include <atrcapi.h>
|
|
|
|
#ifdef ENFORCE_LICENSE
|
|
|
|
#include "license.h"
|
|
#include "cryptkey.h"
|
|
#include "hccontxt.h"
|
|
#endif //ENFORCE_LICENSE
|
|
}
|
|
|
|
#include "clicense.h"
|
|
#include "autil.h"
|
|
#include "wui.h"
|
|
#include "sl.h"
|
|
|
|
/****************************************************************************/
|
|
/* License Handle Data */
|
|
/****************************************************************************/
|
|
typedef struct tagCLICENSE_DATA
|
|
{
|
|
int ANumber;
|
|
|
|
} CLICENSE_DATA, * PCLICENSE_DATA;
|
|
|
|
/****************************************************************************/
|
|
/* Define our memory alloc function */
|
|
/****************************************************************************/
|
|
|
|
#define MemoryAlloc(x) LocalAlloc(LMEM_FIXED, x)
|
|
#define MemoryFree(x) LocalFree(x)
|
|
|
|
CLic::CLic(CObjs* objs)
|
|
{
|
|
_pClientObjects = objs;
|
|
}
|
|
|
|
|
|
CLic::~CLic()
|
|
{
|
|
}
|
|
|
|
|
|
/**PROC+*********************************************************************/
|
|
/* Name: CLicenseInit */
|
|
/* */
|
|
/* Purpose: Initialize ClientLicense Manager */
|
|
/* */
|
|
/* Returns: Handle to be passed to subsequent License Manager functions */
|
|
/* */
|
|
/* Params: None */
|
|
/* */
|
|
/* Operation: LicenseInit is called during Client initialization. Its */
|
|
/* purpose is to allow one-time initialization. It returns a */
|
|
/* handle which is subsequently passed to all License Manager */
|
|
/* functions. A typical use for this handle is as a pointer to */
|
|
/* memory containing per-instance data. */
|
|
/* */
|
|
/**PROC-*********************************************************************/
|
|
int CALL_TYPE CLic::CLicenseInit(
|
|
HANDLE FAR * phContext
|
|
)
|
|
{
|
|
int
|
|
nResult = LICENSE_OK;
|
|
LICENSE_STATUS
|
|
Status;
|
|
|
|
DC_BEGIN_FN( "CLicenseInit" );
|
|
|
|
_pUt = _pClientObjects->_pUtObject;
|
|
_pSl = _pClientObjects->_pSlObject;
|
|
_pMcs = _pClientObjects->_pMCSObject;
|
|
_pUi = _pClientObjects->_pUiObject;
|
|
|
|
//Set only if server capability specifies it
|
|
_fEncryptLicensePackets = FALSE;
|
|
|
|
TRC_NRM( ( TB, _T("ClicenseInit Called\n") ) );
|
|
|
|
if( _pSl->_SL.encrypting )
|
|
{
|
|
//
|
|
// Security exchange has already taken place, so we do not
|
|
// have to do the server authentication again.
|
|
//
|
|
|
|
Status = LicenseInitializeContext(
|
|
phContext,
|
|
LICENSE_CONTEXT_NO_SERVER_AUTHENTICATION );
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
TRC_ERR( ( TB, _T("Error Initializing License Context: %d\n"), Status ) );
|
|
nResult = LICENSE_ERROR;
|
|
}
|
|
|
|
//
|
|
// Keep track of the proprietory certificate or the public key that the
|
|
// server has sent to us.
|
|
//
|
|
|
|
if( _pSl->_SL.pServerCert )
|
|
{
|
|
Status = LicenseSetCertificate( *phContext, _pSl->_SL.pServerCert );
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
TRC_ERR( ( TB, _T("Error setting server certificate: %d\n"), Status ) );
|
|
nResult = LICENSE_ERROR;
|
|
}
|
|
}
|
|
else if( _pSl->_SL.pbServerPubKey )
|
|
{
|
|
Status = LicenseSetPublicKey( *phContext, _pSl->_SL.cbServerPubKey, _pSl->_SL.pbServerPubKey );
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
TRC_ERR( ( TB, _T("Error setting server public key: %d\n"), Status ) );
|
|
nResult = LICENSE_ERROR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRC_ERR( ( TB, _T("Error: no server certificate or public key after security exchange\n") ) );
|
|
nResult = LICENSE_ERROR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Status = LicenseInitializeContext( phContext, 0 );
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
TRC_ERR( ( TB, _T("Error Initializing License Context: %d\n"), Status ) );
|
|
nResult = LICENSE_ERROR;
|
|
}
|
|
|
|
}
|
|
|
|
DC_END_FN();
|
|
return( nResult );
|
|
}
|
|
|
|
|
|
/**PROC+*********************************************************************/
|
|
/* Name: CLicenseData */
|
|
/* */
|
|
/* Purpose: Handle license data received from the Server */
|
|
/* */
|
|
/* Returns: LICENSE_OK - License negotiation is complete */
|
|
/* LICENSE_CONTINUE - License negotiation will continue */
|
|
/* */
|
|
/* Params: pHandle - handle returned by LicenseInit */
|
|
/* pData - data received from Server */
|
|
/* dataLen - length of data received */
|
|
/* */
|
|
/* Operation: This function is passed all license packets received from the */
|
|
/* Server. It should parse the packet and respond (by calling */
|
|
/* suitable SL functions - see aslapi.h) as required. */
|
|
/* */
|
|
/* If license negotiation is complete, this function must return */
|
|
/* LICENSE_OK */
|
|
/* If license negotiation is not yet complete, return */
|
|
/* LICENSE_CONTINUE */
|
|
/* */
|
|
/* Incoming packets from the Client will continue to be */
|
|
/* interpreted as license packets until this function returns */
|
|
/* LICENSE_OK. */
|
|
/* */
|
|
/**PROC-*********************************************************************/
|
|
int CALL_TYPE CLic::CLicenseData(
|
|
HANDLE hContext,
|
|
LPVOID pData,
|
|
DWORD dwDataLen,
|
|
UINT32 *puiExtendedErrorInfo)
|
|
{
|
|
SL_BUFHND bufHandle;
|
|
DWORD dwBufLen;
|
|
DWORD dwHeaderLen, dwTotalLen, newDataLen;
|
|
BYTE FAR * pbBuffer;
|
|
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
|
|
PRNS_SECURITY_HEADER2 pSecHeader2;
|
|
|
|
DC_BEGIN_FN("CLicenseData");
|
|
|
|
TRC_NRM((TB, _T("CLicenseData Called\n")));
|
|
TRC_NRM((TB, _T("CLicenseData called, length = %ld"), dwDataLen));
|
|
|
|
lsReturn = LicenseAcceptContext( hContext,
|
|
puiExtendedErrorInfo,
|
|
(BYTE FAR *)pData,
|
|
dwDataLen,
|
|
NULL,
|
|
&dwBufLen);
|
|
|
|
if( lsReturn == LICENSE_STATUS_OK)
|
|
{
|
|
TRC_NRM((TB, _T("License verification succeeded\n")));
|
|
DC_END_FN();
|
|
return LICENSE_OK;
|
|
}
|
|
|
|
if(lsReturn != LICENSE_STATUS_CONTINUE)
|
|
{
|
|
TRC_ERR((TB, _T("Error %d during license verification.\n"), lsReturn));
|
|
DC_END_FN();
|
|
return LICENSE_ERROR;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* Adjust requested length to account for SL header and */
|
|
/* get the buffer from NL */
|
|
/************************************************************************/
|
|
|
|
if (_pSl->_SL.encrypting)
|
|
{
|
|
if (_pSl->_SL.encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
|
|
// If FIPS is used,
|
|
// it must have room for an extra block
|
|
dwHeaderLen = sizeof(RNS_SECURITY_HEADER2);
|
|
newDataLen = TSCAPI_AdjustDataLen(dwBufLen);
|
|
dwTotalLen = newDataLen + dwHeaderLen;
|
|
}
|
|
else {
|
|
dwHeaderLen = sizeof(RNS_SECURITY_HEADER1);
|
|
dwTotalLen = dwBufLen + dwHeaderLen;
|
|
}
|
|
TRC_DBG((TB, _T("Ask NL for %d (was %d) bytes"), dwTotalLen, dwBufLen));
|
|
}
|
|
else
|
|
{
|
|
dwHeaderLen = sizeof(RNS_SECURITY_HEADER);
|
|
dwTotalLen = dwBufLen + dwHeaderLen;
|
|
TRC_DBG((TB, _T("Not encrypting, ask NL for %d bytes"), dwTotalLen));
|
|
}
|
|
|
|
if( !_pMcs->NL_GetBuffer((DCUINT)(dwTotalLen),
|
|
(PPDCUINT8)&pbBuffer,
|
|
&bufHandle) )
|
|
{
|
|
/********************************************************************/
|
|
/* Buffer not available so can't send, try later. */
|
|
/********************************************************************/
|
|
|
|
TRC_ALT((TB, _T("Failed to get buffer for licensing data\n")));
|
|
DC_END_FN();
|
|
return LICENSE_ERROR;
|
|
}
|
|
|
|
// Since FIPS need extra block, fill in the padding size
|
|
if (_pSl->_SL.encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
|
|
pSecHeader2 = (PRNS_SECURITY_HEADER2)pbBuffer;
|
|
pSecHeader2->padlen = (TSUINT8)(newDataLen - dwBufLen);
|
|
}
|
|
|
|
/********************************************************************/
|
|
/* Adjust buffer pointer to account for SL header */
|
|
/********************************************************************/
|
|
|
|
pbBuffer += dwHeaderLen;
|
|
|
|
lsReturn = LicenseAcceptContext(hContext,
|
|
0,
|
|
(BYTE FAR *)pData,
|
|
dwDataLen,
|
|
pbBuffer,
|
|
&dwBufLen);
|
|
|
|
if( lsReturn != LICENSE_STATUS_CONTINUE )
|
|
{
|
|
TRC_ERR((TB, _T("Error %d during license verification.\n"), lsReturn));
|
|
DC_END_FN();
|
|
return LICENSE_ERROR;
|
|
}
|
|
|
|
if(dwBufLen >0)
|
|
{
|
|
//
|
|
// Now send the data
|
|
//
|
|
|
|
_pSl->SL_SendPacket( pbBuffer,
|
|
(DCUINT)(dwBufLen),
|
|
RNS_SEC_LICENSE_PKT |
|
|
(_fEncryptLicensePackets ? RNS_SEC_ENCRYPT : 0 ),
|
|
bufHandle,
|
|
_pUi->UI_GetClientMCSID(),
|
|
_pUi->UI_GetChannelID(),
|
|
TS_LOWPRIORITY );
|
|
|
|
TRC_NRM((TB, _T("Sending license verification data, length = %ld"),
|
|
dwBufLen));
|
|
TRC_NRM((TB, _T("Send License Verification data.\n")));
|
|
DC_END_FN();
|
|
DC_END_FN();
|
|
return LICENSE_CONTINUE;
|
|
}
|
|
|
|
DC_END_FN();
|
|
return(LICENSE_OK);
|
|
}
|
|
|
|
/**PROC+*********************************************************************/
|
|
/* Name: CLicenseTerm */
|
|
/* */
|
|
/* Purpose: Terminate Client License Manager */
|
|
/* */
|
|
/* Returns: None */
|
|
/* */
|
|
/* Params: pHandle - handle returned from LicenseInit */
|
|
/* */
|
|
/* Operation: This function is provided to do one-time termination of the */
|
|
/* License Manager. For example, if pHandle points to per- */
|
|
/* instance memory, this would be a good place to free it. */
|
|
/* */
|
|
/* Note that CLicenseTerm is called if CLicenseInit fails, hence */
|
|
/* it can be called with a NULL pHandle. */
|
|
/* */
|
|
/**PROC-*********************************************************************/
|
|
|
|
int CALL_TYPE CLic::CLicenseTerm(
|
|
HANDLE hContext )
|
|
{
|
|
LICENSE_STATUS lsReturn = LICENSE_STATUS_OK;
|
|
DC_BEGIN_FN("CLicenseTerm");
|
|
TRC_NRM((TB, _T("CLicenseTerm called.\n")));
|
|
|
|
if( LICENSE_STATUS_OK != ( lsReturn = LicenseDeleteContext(hContext) ) )
|
|
{
|
|
TRC_ERR((TB, _T("Error %d while deleting license context.\n"), lsReturn));
|
|
DC_END_FN();
|
|
return LICENSE_ERROR;
|
|
}
|
|
|
|
DC_END_FN();
|
|
return LICENSE_OK;
|
|
}
|
|
|