Leaked source code of windows server 2003
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.

4181 lines
111 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File: licprot.c
  7. //
  8. // Contents: Implementation of Hydra Server License Protocol API
  9. //
  10. // History: 02-08-00 RobLeit Created
  11. //
  12. //-----------------------------------------------------------------------------
  13. #include "precomp.h"
  14. #include <rpcnterr.h>
  15. #include <lmapibuf.h>
  16. #include "licemem.inc"
  17. #include <srvdef.h>
  18. #include <tserrs.h>
  19. #include <locale.h>
  20. BOOL g_fSetLocale = FALSE;
  21. VOID
  22. LogLicensingTimeBombExpirationEvent();
  23. void
  24. ThrottleLicenseLogEvent(
  25. WORD wEventType,
  26. DWORD dwEventId,
  27. WORD cStrings,
  28. PWCHAR * apwszStrings );
  29. LICENSE_STATUS
  30. LsStatusToLicenseStatus(
  31. DWORD LsStatus,
  32. DWORD LsStatusDefault
  33. );
  34. #define LS_DISCOVERY_TIMEOUT (1*1000)
  35. // Copied from tlserver\server\srvdef.h
  36. #define PERMANENT_LICENSE_EXPIRE_DATE INT_MAX
  37. #define SECONDS_IN_A_DAY 86400 // number of seconds in a day
  38. #define TERMINAL_SERVICE_EVENT_LOG L"TermService"
  39. #define HARDCODED_CHALLENGE_DATA _TEXT("TEST")
  40. ///////////////////////////////////////////////////////////////////////////////
  41. //
  42. // Global variables
  43. //
  44. HANDLE g_hEventLog = NULL;
  45. BOOL g_fEventLogOpen = FALSE;
  46. CRITICAL_SECTION g_EventLogCritSec;
  47. DWORD g_dwLicenseExpirationLeeway = PERMANENT_LICENSE_LEASE_EXPIRE_LEEWAY;
  48. DWORD g_dwTerminalServerVersion;
  49. ///////////////////////////////////////////////////////////////////////////////
  50. LICENSE_STATUS
  51. InitializeProtocolLib()
  52. {
  53. LICENSE_STATUS lsStatus;
  54. //
  55. // initialize the cert util library
  56. //
  57. if (LSInitCertutilLib( 0 ))
  58. {
  59. __try
  60. {
  61. INITLOCK( &g_EventLogCritSec );
  62. }
  63. __except( EXCEPTION_EXECUTE_HANDLER )
  64. {
  65. return LICENSE_STATUS_OUT_OF_MEMORY;
  66. }
  67. g_hEventLog = RegisterEventSource( NULL, TERMINAL_SERVICE_EVENT_LOG );
  68. if (NULL != g_hEventLog)
  69. {
  70. g_fEventLogOpen = TRUE;
  71. }
  72. }
  73. else
  74. {
  75. return LICENSE_STATUS_SERVER_ABORT;
  76. }
  77. lsStatus = InitializeLicensingTimeBomb();
  78. if (lsStatus == LICENSE_STATUS_OK)
  79. {
  80. DWORD dwStatus;
  81. HKEY hKey = NULL;
  82. DWORD dwOSVersion = GetVersion();
  83. g_dwTerminalServerVersion = (DWORD)(HIBYTE(LOWORD(dwOSVersion)));
  84. g_dwTerminalServerVersion |= (DWORD)(LOBYTE(LOWORD(dwOSVersion)) << 16);
  85. dwStatus = RegCreateKeyEx(HKEY_LOCAL_MACHINE, HYDRA_SERVER_PARAM, 0,
  86. NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey,
  87. NULL);
  88. if (dwStatus == ERROR_SUCCESS)
  89. {
  90. DWORD dwBuffer;
  91. DWORD cbBuffer = sizeof(DWORD);
  92. dwStatus = RegQueryValueEx(hKey, PERSEAT_LEEWAY_VALUE, NULL, NULL,
  93. (LPBYTE)&dwBuffer, &cbBuffer);
  94. if (dwStatus == ERROR_SUCCESS)
  95. {
  96. g_dwLicenseExpirationLeeway = min(dwBuffer,
  97. PERMANENT_LICENSE_LEASE_EXPIRE_LEEWAY);
  98. }
  99. }
  100. TSRNG_Initialize();
  101. if(hKey)
  102. RegCloseKey(hKey);
  103. }
  104. return lsStatus;
  105. }
  106. ///////////////////////////////////////////////////////////////////////////////
  107. LICENSE_STATUS
  108. ShutdownProtocolLib()
  109. {
  110. //
  111. // shut down cert util library
  112. //
  113. g_fEventLogOpen = FALSE;
  114. DeregisterEventSource( g_hEventLog );
  115. g_hEventLog = NULL;
  116. DELETELOCK(&g_EventLogCritSec);
  117. LSShutdownCertutilLib();
  118. TSRNG_Shutdown();
  119. return( LICENSE_STATUS_OK );
  120. }
  121. ///////////////////////////////////////////////////////////////////////////////
  122. LICENSE_STATUS
  123. CreateProtocolContext(
  124. IN LPLICENSE_CAPABILITIES pLicenseCap,
  125. OUT HANDLE * phContext)
  126. {
  127. LICENSE_STATUS Status;
  128. PHS_Protocol_Context pLicenseContext = NULL;
  129. //
  130. // allocate the protocol context
  131. //
  132. Status = LicenseMemoryAllocate( sizeof( HS_Protocol_Context ), &pLicenseContext );
  133. if( LICENSE_STATUS_OK != Status )
  134. {
  135. return( Status );
  136. }
  137. //
  138. // Note: InitializeCriticalSection could throw an exception during
  139. // low memory conditions.
  140. //
  141. __try
  142. {
  143. INITLOCK( &pLicenseContext->CritSec );
  144. }
  145. __except( EXCEPTION_EXECUTE_HANDLER )
  146. {
  147. #if DBG
  148. DbgPrint( "LICPROT: CreateLicenseContext: InitializeCriticalSection exception: 0x%x\n",
  149. GetExceptionCode() );
  150. #endif
  151. Status = LICENSE_STATUS_OUT_OF_MEMORY;
  152. if( pLicenseContext )
  153. {
  154. LicenseMemoryFree( &pLicenseContext );
  155. }
  156. return( Status );
  157. }
  158. pLicenseContext->hLSHandle = NULL;
  159. pLicenseContext->State = INIT;
  160. pLicenseContext->dwProtocolVersion = LICENSE_HIGHEST_PROTOCOL_VERSION;
  161. pLicenseContext->fAuthenticateServer = TRUE;
  162. pLicenseContext->CertTypeUsed = CERT_TYPE_INVALID;
  163. pLicenseContext->dwKeyExchangeAlg = KEY_EXCHANGE_ALG_RSA;
  164. pLicenseContext->fLoggedProtocolError = FALSE;
  165. //
  166. // Initialize the crypto context parameters
  167. //
  168. pLicenseContext->CryptoContext.dwCryptState = CRYPT_SYSTEM_STATE_INITIALIZED;
  169. pLicenseContext->CryptoContext.dwSessKeyAlg = BASIC_RC4_128;
  170. pLicenseContext->CryptoContext.dwMACAlg = MAC_MD5_SHA;
  171. if (NULL != pLicenseCap)
  172. {
  173. //
  174. // initialize the license context with the incoming data.
  175. //
  176. pLicenseContext->fAuthenticateServer = pLicenseCap->fAuthenticateServer;
  177. pLicenseContext->dwProtocolVersion = pLicenseCap->ProtocolVer;
  178. //
  179. // If the client is not authenticating the server, this means that
  180. // the client already has our certificate. But we need to know which
  181. // certificate the client has.
  182. //
  183. if( FALSE == pLicenseContext->fAuthenticateServer )
  184. {
  185. pLicenseContext->CertTypeUsed = pLicenseCap->CertType;
  186. }
  187. //
  188. // remember the client's machine name
  189. //
  190. if( pLicenseCap->pbClientName )
  191. {
  192. Status = LicenseMemoryAllocate(
  193. pLicenseCap->cbClientName,
  194. &pLicenseContext->ptszClientMachineName );
  195. if( LICENSE_STATUS_OK == Status )
  196. {
  197. //
  198. // copy the client machine name
  199. //
  200. memcpy( pLicenseContext->ptszClientMachineName,
  201. pLicenseCap->pbClientName,
  202. pLicenseCap->cbClientName );
  203. }
  204. else
  205. {
  206. goto error;
  207. }
  208. }
  209. }
  210. else
  211. {
  212. pLicenseContext->ptszClientMachineName = NULL;
  213. }
  214. *phContext = ( HANDLE )pLicenseContext;
  215. return( Status );
  216. error:
  217. //
  218. // encountered error creating context, free allocated memory before
  219. // returning
  220. //
  221. if( pLicenseContext )
  222. {
  223. DELETELOCK( &pLicenseContext->CritSec );
  224. if (pLicenseContext->ptszClientMachineName)
  225. {
  226. LicenseMemoryFree(&pLicenseContext->ptszClientMachineName);
  227. }
  228. LicenseMemoryFree( &pLicenseContext );
  229. }
  230. return( Status );
  231. }
  232. ///////////////////////////////////////////////////////////////////////////////
  233. LICENSE_STATUS
  234. DeleteProtocolContext(
  235. HANDLE hContext )
  236. {
  237. PHS_Protocol_Context pLicenseContext = ( PHS_Protocol_Context )hContext;
  238. if( NULL == pLicenseContext )
  239. {
  240. return( LICENSE_STATUS_INVALID_SERVER_CONTEXT );
  241. }
  242. LOCK( &pLicenseContext->CritSec );
  243. if (pLicenseContext->hLSHandle != NULL)
  244. {
  245. TLSDisconnectFromServer(pLicenseContext->hLSHandle);
  246. pLicenseContext->hLSHandle = NULL;
  247. }
  248. if( pLicenseContext->ProductInfo.pbCompanyName )
  249. {
  250. LicenseMemoryFree( &pLicenseContext->ProductInfo.pbCompanyName );
  251. }
  252. if( pLicenseContext->ProductInfo.pbProductID )
  253. {
  254. LicenseMemoryFree( &pLicenseContext->ProductInfo.pbProductID );
  255. }
  256. if( pLicenseContext->ptszClientUserName )
  257. {
  258. LicenseMemoryFree( &pLicenseContext->ptszClientUserName );
  259. }
  260. if( pLicenseContext->ptszClientMachineName )
  261. {
  262. LicenseMemoryFree( &pLicenseContext->ptszClientMachineName );
  263. }
  264. if( pLicenseContext->pbOldLicense )
  265. {
  266. LicenseMemoryFree( &pLicenseContext->pbOldLicense );
  267. }
  268. //
  269. // Free the license info that's being cached
  270. //
  271. if( pLicenseContext->pTsLicenseInfo )
  272. {
  273. FreeLicenseInfo( pLicenseContext->pTsLicenseInfo );
  274. LicenseMemoryFree( &pLicenseContext->pTsLicenseInfo );
  275. }
  276. UNLOCK( &pLicenseContext->CritSec );
  277. DELETELOCK( &pLicenseContext->CritSec );
  278. LicenseMemoryFree( &pLicenseContext );
  279. return( LICENSE_STATUS_OK );
  280. }
  281. ///////////////////////////////////////////////////////////////////////////////
  282. void
  283. HandleErrorCondition(
  284. PHS_Protocol_Context pLicenseContext,
  285. PDWORD pcbOutBuf,
  286. PBYTE * ppOutBuf,
  287. LICENSE_STATUS * pStatus )
  288. {
  289. License_Error_Message ErrorMsg;
  290. LICENSE_STATUS licenseStatus;
  291. //
  292. // returns the correct error code based on the error condition
  293. //
  294. switch( *pStatus )
  295. {
  296. case( LICENSE_STATUS_NO_LICENSE_SERVER ):
  297. ErrorMsg.dwErrorCode = GM_HS_ERR_NO_LICENSE_SERVER;
  298. ErrorMsg.dwStateTransition = ST_NO_TRANSITION;
  299. break;
  300. case( LICENSE_STATUS_INVALID_MAC_DATA ):
  301. ErrorMsg.dwErrorCode = GM_HC_ERR_INVALID_MAC;
  302. ErrorMsg.dwStateTransition = ST_TOTAL_ABORT;
  303. break;
  304. //
  305. // Handle all other error conditions as invalid client
  306. //
  307. case( LICENSE_STATUS_INVALID_RESPONSE ):
  308. default:
  309. ErrorMsg.dwErrorCode = GM_HS_ERR_INVALID_CLIENT;
  310. ErrorMsg.dwStateTransition = ST_TOTAL_ABORT;
  311. break;
  312. }
  313. //
  314. // for now, we are not sending any error string
  315. //
  316. ErrorMsg.bbErrorInfo.wBlobType = BB_ERROR_BLOB;
  317. ErrorMsg.bbErrorInfo.wBlobLen = 0;
  318. ErrorMsg.bbErrorInfo.pBlob = NULL;
  319. //
  320. // pack the error message
  321. //
  322. licenseStatus = PackHydraServerErrorMessage(
  323. pLicenseContext->dwProtocolVersion,
  324. &ErrorMsg,
  325. ppOutBuf,
  326. pcbOutBuf );
  327. if( LICENSE_STATUS_OK != licenseStatus )
  328. {
  329. #if DBG
  330. DbgPrint( "HandleErrorConditions: cannot pack error message: 0x%x\n", *pStatus );
  331. #endif
  332. *pStatus = LICENSE_STATUS_SERVER_ABORT;
  333. }
  334. return;
  335. }
  336. ///////////////////////////////////////////////////////////////////////////////
  337. LICENSE_STATUS
  338. CreateHydraServerHello(
  339. PHS_Protocol_Context pLicenseContext,
  340. DWORD cbInBuf,
  341. PBYTE pInBuf,
  342. DWORD * pcbOutBuf,
  343. PBYTE * ppOutBuf )
  344. {
  345. Hydra_Server_License_Request LicenseRequest;
  346. LICENSE_STATUS Status;
  347. Binary_Blob ScopeBlob;
  348. CHAR szScope[] = SCOPE_NAME;
  349. DWORD dwCertSize;
  350. //
  351. // generate a server random number
  352. //
  353. if(!TSRNG_GenerateRandomBits( LicenseRequest.ServerRandom, LICENSE_RANDOM ))
  354. {
  355. Status = LICENSE_STATUS_OUT_OF_MEMORY;
  356. goto no_request;
  357. }
  358. memcpy( pLicenseContext->CryptoContext.rgbServerRandom,
  359. LicenseRequest.ServerRandom,
  360. LICENSE_RANDOM );
  361. //
  362. // fill in the product info. Allocate memory for and initialize the
  363. // license context copy of the product info and then just copy the
  364. // same product info to the license request.
  365. // NOTE: This info should probably be passed in in the future
  366. //
  367. Status = InitProductInfo(
  368. &( pLicenseContext->ProductInfo ),
  369. PRODUCT_INFO_SKU_PRODUCT_ID );
  370. if( LICENSE_STATUS_OK != Status )
  371. {
  372. #if DBG
  373. DbgPrint( "CreateHydraServerHello: cannot init product info: 0x%x\n", Status );
  374. #endif
  375. goto no_request;
  376. }
  377. memcpy( &LicenseRequest.ProductInfo,
  378. &pLicenseContext->ProductInfo,
  379. sizeof( Product_Info ) );
  380. //
  381. // get the hydra server certificate and fill in the key exchange list
  382. //
  383. LicenseRequest.KeyExchngList.wBlobType = BB_KEY_EXCHG_ALG_BLOB;
  384. LicenseRequest.KeyExchngList.wBlobLen = sizeof( DWORD );
  385. LicenseRequest.KeyExchngList.pBlob = ( PBYTE )&pLicenseContext->dwKeyExchangeAlg;
  386. LicenseRequest.ServerCert.pBlob = NULL;
  387. LicenseRequest.ServerCert.wBlobLen = 0;
  388. //
  389. // We may or may not have to send the client the certificate depending on whether the
  390. // client is authenticating the server.
  391. //
  392. if( TRUE == pLicenseContext->fAuthenticateServer )
  393. {
  394. //
  395. // decide on what kind of certificate to get depending on the client's version.
  396. // Pre-Hydra 5.0 clients only knows how to decode proprietory certificate.
  397. // Use X509 certificate for all other clients.
  398. //
  399. if( CERT_TYPE_INVALID == pLicenseContext->CertTypeUsed )
  400. {
  401. if( PREAMBLE_VERSION_3_0 > GET_PREAMBLE_VERSION( pLicenseContext->dwProtocolVersion ) )
  402. {
  403. pLicenseContext->CertTypeUsed = CERT_TYPE_PROPRIETORY;
  404. }
  405. else
  406. {
  407. pLicenseContext->CertTypeUsed = CERT_TYPE_X509;
  408. }
  409. }
  410. Status = TLSGetTSCertificate(
  411. pLicenseContext->CertTypeUsed,
  412. &LicenseRequest.ServerCert.pBlob,
  413. &dwCertSize);
  414. LicenseRequest.ServerCert.wBlobLen = LOWORD(dwCertSize);
  415. LicenseRequest.ServerCert.wBlobType = BB_CERTIFICATE_BLOB;
  416. if( ( LICENSE_STATUS_OK != Status ) &&
  417. ( CERT_TYPE_X509 == pLicenseContext->CertTypeUsed ) )
  418. {
  419. //
  420. // if we cannot get the X509 certificate chain, use the proprietory
  421. // certificate.
  422. //
  423. pLicenseContext->CertTypeUsed = CERT_TYPE_PROPRIETORY;
  424. Status = TLSGetTSCertificate(
  425. pLicenseContext->CertTypeUsed,
  426. &LicenseRequest.ServerCert.pBlob,
  427. &dwCertSize);
  428. LicenseRequest.ServerCert.wBlobLen = LOWORD(dwCertSize);
  429. LicenseRequest.ServerCert.wBlobType = BB_CERTIFICATE_BLOB;
  430. }
  431. if( LICENSE_STATUS_OK != Status )
  432. {
  433. #if DBG
  434. DbgPrint( "LICPROT: cannot get server certificate: %x\n", Status );
  435. #endif
  436. goto no_request;
  437. }
  438. }
  439. //
  440. // fill in the scope info. This info may be passed in in the future.
  441. //
  442. LicenseRequest.ScopeList.dwScopeCount = 1;
  443. LicenseRequest.ScopeList.Scopes = &ScopeBlob;
  444. ScopeBlob.wBlobType = BB_SCOPE_BLOB;
  445. ScopeBlob.pBlob = szScope;
  446. ScopeBlob.wBlobLen = strlen( ScopeBlob.pBlob ) + 1;
  447. strcpy( pLicenseContext->Scope, ScopeBlob.pBlob );
  448. //
  449. // Pack the server hello message into network format
  450. //
  451. Status = PackHydraServerLicenseRequest(
  452. pLicenseContext->dwProtocolVersion,
  453. &LicenseRequest,
  454. ppOutBuf,
  455. pcbOutBuf );
  456. //
  457. // free the memory containing the server certificate
  458. //
  459. if( LicenseRequest.ServerCert.pBlob )
  460. {
  461. TLSFreeTSCertificate( LicenseRequest.ServerCert.pBlob );
  462. LicenseRequest.ServerCert.pBlob = NULL;
  463. }
  464. if( LICENSE_STATUS_OK != Status )
  465. {
  466. goto no_request;
  467. }
  468. Status = LICENSE_STATUS_CONTINUE;
  469. //
  470. // change the state of the context
  471. //
  472. pLicenseContext->State = SENT_SERVER_HELLO;
  473. return( Status );
  474. //=========================================================================
  475. // Error return
  476. //=========================================================================
  477. no_request:
  478. //
  479. // free memory and handles
  480. //
  481. if( pLicenseContext->ProductInfo.pbCompanyName )
  482. {
  483. LicenseMemoryFree( &pLicenseContext->ProductInfo.pbCompanyName );
  484. }
  485. if( pLicenseContext->ProductInfo.pbProductID )
  486. {
  487. LicenseMemoryFree( &pLicenseContext->ProductInfo.pbProductID );
  488. }
  489. return( Status );
  490. }
  491. ///////////////////////////////////////////////////////////////////////////////
  492. LICENSE_STATUS
  493. HandleHelloResponse(
  494. PHS_Protocol_Context pLicenseContext,
  495. DWORD cbInBuf,
  496. PBYTE pInBuf,
  497. DWORD * pcbOutBuf,
  498. PBYTE * ppOutBuf,
  499. BOOL* pfExtendedError)
  500. {
  501. PPreamble pPreamble;
  502. ASSERT( NULL != pInBuf );
  503. ASSERT( cbInBuf > sizeof( Preamble ) );
  504. if( ( NULL == pInBuf ) || ( sizeof( Preamble ) > cbInBuf ) )
  505. {
  506. return( LICENSE_STATUS_INVALID_INPUT );
  507. }
  508. //
  509. // check the message preamble to determine how to unpack the message
  510. //
  511. pPreamble = ( PPreamble )pInBuf;
  512. if( HC_LICENSE_INFO == pPreamble->bMsgType )
  513. {
  514. //
  515. // Client has sent us its license
  516. //
  517. return( HandleClientLicense( pLicenseContext, cbInBuf, pInBuf, pcbOutBuf, ppOutBuf, pfExtendedError ) );
  518. }
  519. else if( HC_NEW_LICENSE_REQUEST == pPreamble->bMsgType )
  520. {
  521. //
  522. // Client has requested for a new license
  523. //
  524. return( HandleNewLicenseRequest( pLicenseContext, cbInBuf, pInBuf, pcbOutBuf, ppOutBuf, pfExtendedError ) );
  525. }
  526. else if( GM_ERROR_ALERT == pPreamble->bMsgType )
  527. {
  528. //
  529. // Client has encountered an error
  530. //
  531. return( HandleClientError( pLicenseContext, cbInBuf, pInBuf, pcbOutBuf, ppOutBuf, pfExtendedError ) );
  532. }
  533. //
  534. // The client response is invalid for the current server state
  535. //
  536. return( LICENSE_STATUS_INVALID_RESPONSE );
  537. }
  538. ///////////////////////////////////////////////////////////////////////////////
  539. LICENSE_STATUS
  540. ChooseLicense(
  541. PValidation_Info pValidationInfo,
  542. DWORD dwNumLicenses,
  543. LICENSEDPRODUCT * pLicenseInfo,
  544. LPDWORD pdwLicenseIndex,
  545. BOOL fMatchingVersion )
  546. {
  547. DWORD
  548. dwCurrentLicense,
  549. dwProductVersion;
  550. LICENSEDPRODUCT *
  551. pCurrentLicense = pLicenseInfo;
  552. BOOL
  553. fFoundLicense = FALSE;
  554. if( ( 0 >= dwNumLicenses ) || ( NULL == pLicenseInfo ) || ( NULL == pdwLicenseIndex ) )
  555. {
  556. return( LICENSE_STATUS_INVALID_INPUT );
  557. }
  558. //
  559. // Find a license with the license array that matches the criteria.
  560. // The caller may be looking for a license that matches the current product
  561. // version, or for a license that is later than the current product version.
  562. //
  563. for( dwCurrentLicense = 0; dwCurrentLicense < dwNumLicenses; dwCurrentLicense++ )
  564. {
  565. if( TERMSERV_CERT_VERSION_BETA == pCurrentLicense->dwLicenseVersion )
  566. {
  567. continue;
  568. }
  569. dwProductVersion = pCurrentLicense->pLicensedVersion->wMajorVersion;
  570. dwProductVersion <<= 16;
  571. dwProductVersion |= pCurrentLicense->pLicensedVersion->wMinorVersion;
  572. if( fMatchingVersion )
  573. {
  574. //
  575. // we should be looking for a license with a matching version
  576. //
  577. if( dwProductVersion == pValidationInfo->pProductInfo->dwVersion )
  578. {
  579. fFoundLicense = TRUE;
  580. break;
  581. }
  582. }
  583. else
  584. {
  585. //
  586. // Looking for a license that is later than the current product
  587. // version.
  588. //
  589. if( dwProductVersion > pValidationInfo->pProductInfo->dwVersion )
  590. {
  591. fFoundLicense = TRUE;
  592. break;
  593. }
  594. }
  595. //
  596. // continue looking for the license
  597. //
  598. pCurrentLicense++;
  599. }
  600. if( FALSE == fFoundLicense )
  601. {
  602. return( LICENSE_STATUS_NO_LICENSE_ERROR );
  603. }
  604. *pdwLicenseIndex = dwCurrentLicense;
  605. return( LICENSE_STATUS_OK );
  606. }
  607. ///////////////////////////////////////////////////////////////////////////////
  608. VOID
  609. UpdateVerifyResult(
  610. LICENSE_STATUS * pCurrentStatus,
  611. LICENSE_STATUS NewStatus )
  612. {
  613. //
  614. // Update the current status with the best result so far.
  615. // The ratings of the license verification result are as follows:
  616. //
  617. // (1) LICENSE_STATUS_OK
  618. // (2) LICENSE_STATUS_SHOULD_UPGRADE_LICENSE
  619. // (3) LICENSE_STATUS_MUST_UPGRADE_LICENSE
  620. // (4) Other LICENSE_STATUS_xxx
  621. //
  622. if( LICENSE_STATUS_OK == *pCurrentStatus )
  623. {
  624. return;
  625. }
  626. else if( LICENSE_STATUS_OK == NewStatus )
  627. {
  628. *pCurrentStatus = NewStatus;
  629. return;
  630. }
  631. if( LICENSE_STATUS_SHOULD_UPGRADE_LICENSE == *pCurrentStatus )
  632. {
  633. return;
  634. }
  635. else if( LICENSE_STATUS_SHOULD_UPGRADE_LICENSE == NewStatus )
  636. {
  637. *pCurrentStatus = NewStatus;
  638. return;
  639. }
  640. if( LICENSE_STATUS_MUST_UPGRADE_LICENSE == *pCurrentStatus )
  641. {
  642. return;
  643. }
  644. else if( LICENSE_STATUS_MUST_UPGRADE_LICENSE == NewStatus )
  645. {
  646. *pCurrentStatus = NewStatus;
  647. return;
  648. }
  649. *pCurrentStatus = NewStatus;
  650. return;
  651. }
  652. /*++
  653. Function:
  654. FreeTsLicenseInfo
  655. Description:
  656. Release all the memory used in the given TS_LICENSE_INFO structure
  657. Parameter:
  658. pTsLicenseInfo - Pointer to a TS_LICENSE_INFO structure
  659. Return:
  660. Nothing.
  661. --*/
  662. VOID
  663. FreeTsLicenseInfo(
  664. PTS_LICENSE_INFO pTsLicenseInfo )
  665. {
  666. if( NULL == pTsLicenseInfo )
  667. {
  668. return;
  669. }
  670. if( pTsLicenseInfo->pbRawLicense )
  671. {
  672. LicenseMemoryFree( &pTsLicenseInfo->pbRawLicense );
  673. }
  674. //
  675. // release all memory within the structure
  676. //
  677. memset( pTsLicenseInfo, 0, sizeof( TS_LICENSE_INFO ) );
  678. return;
  679. }
  680. /*++
  681. Function:
  682. CacheLicenseInfo
  683. Description:
  684. Cache the client licensing info
  685. Parameters:
  686. pLicenseContext - Pointer to license protocol context
  687. pCurrentLicense - Pointer to the license info to cache
  688. Returns:
  689. nothing.
  690. --*/
  691. VOID
  692. CacheLicenseInfo(
  693. PHS_Protocol_Context pLicenseContext,
  694. PLICENSEDPRODUCT pCurrentLicense )
  695. {
  696. LICENSE_STATUS
  697. Status;
  698. //
  699. // free the old information in the cache
  700. //
  701. if( pLicenseContext->pTsLicenseInfo )
  702. {
  703. FreeTsLicenseInfo( pLicenseContext->pTsLicenseInfo );
  704. }
  705. else
  706. {
  707. Status = LicenseMemoryAllocate( sizeof( TS_LICENSE_INFO ), &pLicenseContext->pTsLicenseInfo );
  708. if( LICENSE_STATUS_OK != Status )
  709. {
  710. #if DBG
  711. DbgPrint( "LICEMGR: CacheLicenseInfo: cannot allocate memory for license info cache\n" );
  712. #endif
  713. return;
  714. }
  715. }
  716. //
  717. // decide if the license is temporary
  718. //
  719. if( pCurrentLicense->pLicensedVersion->dwFlags & 0x80000000 )
  720. {
  721. pLicenseContext->pTsLicenseInfo->fTempLicense = TRUE;
  722. }
  723. else
  724. {
  725. pLicenseContext->pTsLicenseInfo->fTempLicense = FALSE;
  726. }
  727. //
  728. // cache license validity dates
  729. //
  730. pLicenseContext->pTsLicenseInfo->NotAfter = pCurrentLicense->NotAfter;
  731. return;
  732. }
  733. ///////////////////////////////////////////////////////////////////////////////
  734. LICENSE_STATUS
  735. ValidateHydraLicense(
  736. PHS_Protocol_Context pLicenseContext,
  737. PValidation_Info pValidationInfo,
  738. DWORD dwNumLicenses,
  739. PLICENSEDPRODUCT pLicenseInfo,
  740. PDWORD pdwLicenseState )
  741. {
  742. LICENSE_STATUS
  743. Status = LICENSE_STATUS_INVALID_LICENSE,
  744. CurrentStatus;
  745. DWORD
  746. dwLicenseIndex = 0,
  747. dwCurrentLicense = 0;
  748. PLICENSEDPRODUCT
  749. pCurrentLicense;
  750. BOOL
  751. fFoundMatchingVersion = FALSE;
  752. //
  753. // The client could have given us multiple licenses. Pick the right
  754. // license from the array of licenses to validate. Always try to pick
  755. // the license that matches the current product version before looking
  756. // for a license that is for a later version.
  757. //
  758. CurrentStatus = ChooseLicense(
  759. pValidationInfo,
  760. dwNumLicenses,
  761. pLicenseInfo,
  762. &dwLicenseIndex,
  763. TRUE );
  764. if( LICENSE_STATUS_OK == CurrentStatus )
  765. {
  766. //
  767. // Verify the license that is the same version as the current product
  768. // version
  769. // initialize the license state
  770. //
  771. LicenseInitState( *pdwLicenseState );
  772. pCurrentLicense = pLicenseInfo + dwLicenseIndex;
  773. fFoundMatchingVersion = TRUE;
  774. //
  775. // verify HWID
  776. //
  777. CurrentStatus = VerifyClientHwid( pLicenseContext, pValidationInfo, pCurrentLicense );
  778. if( LICENSE_STATUS_OK != CurrentStatus )
  779. {
  780. UpdateVerifyResult( &Status, CurrentStatus );
  781. goto verify_later_license;
  782. }
  783. //
  784. // verify product info. Also verifies the product version.
  785. // The product version determines if the license needs to be
  786. // upgraded or not.
  787. //
  788. CurrentStatus = VerifyLicenseProductInfo(
  789. pLicenseContext,
  790. pValidationInfo,
  791. pCurrentLicense,
  792. pdwLicenseState );
  793. if( LICENSE_STATUS_OK != CurrentStatus )
  794. {
  795. UpdateVerifyResult( &Status, CurrentStatus );
  796. goto verify_later_license;
  797. }
  798. //
  799. // verify license valid date and time.
  800. //
  801. CurrentStatus = VerifyLicenseDateAndTime( pCurrentLicense, pdwLicenseState );
  802. if( LICENSE_STATUS_OK != CurrentStatus )
  803. {
  804. UpdateVerifyResult( &Status, CurrentStatus );
  805. goto verify_later_license;
  806. }
  807. CurrentStatus = GetVerifyResult( *pdwLicenseState );
  808. UpdateVerifyResult( &Status, CurrentStatus );
  809. //
  810. // cache the license we tried to validate
  811. //
  812. CacheLicenseInfo( pLicenseContext, pCurrentLicense );
  813. //
  814. // If the current license is OK, then we're done verifying
  815. //
  816. if( LICENSE_STATUS_OK == Status )
  817. {
  818. return( Status );
  819. }
  820. }
  821. verify_later_license:
  822. //
  823. // Cannot find or did not sucessfully verify a license that matches the
  824. // current product version. The following code finds and verifies
  825. // licenses that are later than the current product version.
  826. //
  827. CurrentStatus = ChooseLicense(
  828. pValidationInfo,
  829. dwNumLicenses,
  830. pLicenseInfo,
  831. &dwLicenseIndex,
  832. FALSE );
  833. if( LICENSE_STATUS_OK != CurrentStatus )
  834. {
  835. if( FALSE == fFoundMatchingVersion )
  836. {
  837. //
  838. // cannot find a license that is the same or later than the current
  839. // product version ==> this license must be upgraded.
  840. //
  841. LicenseSetState( *pdwLicenseState, LICENSE_STATE_OLD_VERSION );
  842. //
  843. // Cache the existing license regardless, so we know what type
  844. // it is
  845. //
  846. CacheLicenseInfo( pLicenseContext, pLicenseInfo );
  847. return( GetVerifyResult( *pdwLicenseState ) );
  848. }
  849. else
  850. {
  851. return( Status );
  852. }
  853. }
  854. pCurrentLicense = pLicenseInfo + dwLicenseIndex;
  855. dwCurrentLicense = dwLicenseIndex;
  856. while( dwCurrentLicense < dwNumLicenses )
  857. {
  858. //
  859. // initialize the license state
  860. //
  861. LicenseInitState( *pdwLicenseState );
  862. //
  863. // verify HWID
  864. //
  865. CurrentStatus = VerifyClientHwid( pLicenseContext, pValidationInfo, pCurrentLicense );
  866. if( LICENSE_STATUS_OK != CurrentStatus )
  867. {
  868. UpdateVerifyResult( &Status, CurrentStatus );
  869. goto next_license;
  870. }
  871. //
  872. // verify product info. Also verifies the product version.
  873. // The product version determines if the license needs to be
  874. // upgraded or not.
  875. //
  876. CurrentStatus = VerifyLicenseProductInfo(
  877. pLicenseContext,
  878. pValidationInfo,
  879. pCurrentLicense,
  880. pdwLicenseState );
  881. if( LICENSE_STATUS_OK != CurrentStatus )
  882. {
  883. UpdateVerifyResult( &Status, CurrentStatus );
  884. goto next_license;
  885. }
  886. //
  887. // verify license valid date and time.
  888. //
  889. CurrentStatus = VerifyLicenseDateAndTime( pCurrentLicense, pdwLicenseState );
  890. if( LICENSE_STATUS_OK != CurrentStatus )
  891. {
  892. UpdateVerifyResult( &Status, CurrentStatus );
  893. goto next_license;
  894. }
  895. CurrentStatus = GetVerifyResult( *pdwLicenseState );
  896. UpdateVerifyResult( &Status, CurrentStatus );
  897. //
  898. // cache the info of the license we had just try to validate
  899. //
  900. CacheLicenseInfo( pLicenseContext, pCurrentLicense );
  901. if( LICENSE_STATUS_OK == Status )
  902. {
  903. //
  904. // if the license is OK, then we can stop the verification process
  905. //
  906. break;
  907. }
  908. next_license:
  909. //
  910. // Get the next license that is later than the current product version.
  911. //
  912. if( dwNumLicenses <= ++dwCurrentLicense )
  913. {
  914. break;
  915. }
  916. pCurrentLicense++;
  917. CurrentStatus = ChooseLicense(
  918. pValidationInfo,
  919. dwNumLicenses - dwCurrentLicense,
  920. pCurrentLicense,
  921. &dwLicenseIndex,
  922. FALSE );
  923. if( LICENSE_STATUS_OK != CurrentStatus )
  924. {
  925. break;
  926. }
  927. pCurrentLicense += dwLicenseIndex;
  928. dwCurrentLicense += dwLicenseIndex;
  929. }
  930. return( Status );
  931. }
  932. ///////////////////////////////////////////////////////////////////////////////
  933. LICENSE_STATUS
  934. ValidateLicense(
  935. PHS_Protocol_Context pLicenseContext,
  936. PValidation_Info pValidationInfo,
  937. PDWORD pdwLicenseState,
  938. BOOL fCheckForPermanent )
  939. {
  940. LICENSE_STATUS Status;
  941. DWORD dwNumLicenseInfo = 0;
  942. LICENSEDPRODUCT * pLicenseInfo = NULL;
  943. static DWORD cchComputerName;
  944. static TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  945. DWORD cbSecretKey = 0;
  946. PBYTE pbSecretKey = NULL;
  947. BOOL fDifferent = FALSE;
  948. if( NULL == pLicenseContext )
  949. {
  950. return( LICENSE_STATUS_INVALID_INPUT );
  951. }
  952. //
  953. // Get the secret key that is used to encrypt the HWID
  954. //
  955. LicenseGetSecretKey( &cbSecretKey, NULL );
  956. Status = LicenseMemoryAllocate( cbSecretKey, &pbSecretKey );
  957. if( LICENSE_STATUS_OK != Status )
  958. {
  959. goto done;
  960. }
  961. Status = LicenseGetSecretKey( &cbSecretKey, pbSecretKey );
  962. if( LICENSE_STATUS_OK != Status )
  963. {
  964. goto done;
  965. }
  966. //
  967. // decode license issued by hydra license server certificate engine.
  968. // Decoding the license will also get us back the decrypted HWID.
  969. //
  970. __try
  971. {
  972. Status = LSVerifyDecodeClientLicense(
  973. pValidationInfo->pLicense,
  974. pValidationInfo->cbLicense,
  975. pbSecretKey,
  976. cbSecretKey,
  977. &dwNumLicenseInfo,
  978. NULL );
  979. if( LICENSE_STATUS_OK != Status )
  980. {
  981. goto done;
  982. }
  983. Status = LicenseMemoryAllocate(
  984. sizeof( LICENSEDPRODUCT ) * dwNumLicenseInfo,
  985. &pLicenseInfo );
  986. if( LICENSE_STATUS_OK != Status )
  987. {
  988. goto done;
  989. }
  990. Status = LSVerifyDecodeClientLicense(
  991. pValidationInfo->pLicense,
  992. pValidationInfo->cbLicense,
  993. pbSecretKey,
  994. cbSecretKey,
  995. &dwNumLicenseInfo,
  996. pLicenseInfo );
  997. }
  998. __except( EXCEPTION_EXECUTE_HANDLER )
  999. {
  1000. DWORD dwExceptionCode = GetExceptionCode();
  1001. Status = LICENSE_STATUS_CANNOT_DECODE_LICENSE;
  1002. }
  1003. if( LICENSE_STATUS_OK != Status )
  1004. {
  1005. #if DBG
  1006. DbgPrint( "LICEMGR: cannot decode license: 0x%x\n", Status );
  1007. #endif
  1008. goto done;
  1009. }
  1010. //
  1011. // now validate the license
  1012. //
  1013. Status = ValidateHydraLicense(
  1014. pLicenseContext,
  1015. pValidationInfo,
  1016. dwNumLicenseInfo,
  1017. pLicenseInfo,
  1018. pdwLicenseState );
  1019. if (fCheckForPermanent
  1020. && LICENSE_STATUS_OK == Status
  1021. && !pLicenseContext->pTsLicenseInfo->fTempLicense
  1022. && pLicenseContext->ProductInfo.cbProductID >= sizeof(TERMSERV_FREE_TYPE))
  1023. {
  1024. int i;
  1025. TCHAR *pszT;
  1026. for (i = 0, pszT = (TCHAR *)(pLicenseContext->ProductInfo.pbProductID + pLicenseContext->ProductInfo.cbProductID - sizeof(TERMSERV_FREE_TYPE)); i < sizeof(TERMSERV_FREE_TYPE); i++)
  1027. {
  1028. if (TERMSERV_FREE_TYPE[i] != pszT[i])
  1029. {
  1030. fDifferent = TRUE;
  1031. break;
  1032. }
  1033. }
  1034. if (fDifferent)
  1035. ReceivedPermanentLicense();
  1036. }
  1037. done:
  1038. if( pbSecretKey )
  1039. {
  1040. LicenseMemoryFree( &pbSecretKey );
  1041. }
  1042. //
  1043. // Free the array of licensed product info
  1044. //
  1045. if( pLicenseInfo )
  1046. {
  1047. while( dwNumLicenseInfo-- )
  1048. {
  1049. LSFreeLicensedProduct( pLicenseInfo + dwNumLicenseInfo );
  1050. }
  1051. LicenseMemoryFree( &pLicenseInfo );
  1052. }
  1053. return( Status );
  1054. }
  1055. ///////////////////////////////////////////////////////////////////////////////
  1056. LICENSE_STATUS
  1057. HandleClientLicense(
  1058. PHS_Protocol_Context pLicenseContext,
  1059. DWORD cbInBuf,
  1060. PBYTE pInBuf,
  1061. DWORD * pcbOutBuf,
  1062. PBYTE * ppOutBuf,
  1063. PBOOL pfExtendedError)
  1064. {
  1065. LICENSE_STATUS Status, UpgradeStatus;
  1066. Hydra_Client_License_Info LicenseInfo;
  1067. PBYTE pPreMasterSecret = NULL;
  1068. DWORD dwPreMasterSecretLen = 0;
  1069. HWID Hwid;
  1070. Validation_Info ValidationInfo;
  1071. License_Error_Message ErrorMsg;
  1072. DWORD dwLicenseState = 0;
  1073. BYTE MacData[LICENSE_MAC_DATA];
  1074. DWORD CertType;
  1075. ASSERT( NULL != pInBuf );
  1076. ASSERT( cbInBuf > 0 );
  1077. if( ( NULL == pInBuf ) || ( 0 >= cbInBuf ) )
  1078. {
  1079. return( LICENSE_STATUS_INVALID_INPUT );
  1080. }
  1081. //
  1082. // Unpack the client license info message
  1083. //
  1084. InitBinaryBlob( &LicenseInfo.EncryptedPreMasterSecret );
  1085. InitBinaryBlob( &LicenseInfo.LicenseInfo );
  1086. InitBinaryBlob( &LicenseInfo.EncryptedHWID );
  1087. Status = UnPackHydraClientLicenseInfo( pInBuf, cbInBuf, &LicenseInfo, pfExtendedError );
  1088. if( LICENSE_STATUS_CANNOT_DECODE_LICENSE == Status ||
  1089. LICENSE_STATUS_INVALID_LICENSE == Status )
  1090. {
  1091. goto license_bad;
  1092. }
  1093. if( LICENSE_STATUS_OK != Status )
  1094. {
  1095. goto construct_return_msg;
  1096. }
  1097. //
  1098. // Initialize the crypto context with the key exchange info and build the pre-master
  1099. // secret. We need the server and client random numbers and the pre-master secret
  1100. // to build the pre-master secret.
  1101. //
  1102. memcpy( pLicenseContext->CryptoContext.rgbClientRandom,
  1103. LicenseInfo.ClientRandom,
  1104. LICENSE_RANDOM );
  1105. pLicenseContext->CryptoContext.dwKeyExchAlg = LicenseInfo.dwPrefKeyExchangeAlg;
  1106. dwPreMasterSecretLen = LICENSE_PRE_MASTER_SECRET;
  1107. Status = GetEnvelopedData( pLicenseContext->CertTypeUsed,
  1108. LicenseInfo.EncryptedPreMasterSecret.pBlob,
  1109. ( DWORD )LicenseInfo.EncryptedPreMasterSecret.wBlobLen,
  1110. &pPreMasterSecret,
  1111. &dwPreMasterSecretLen );
  1112. if( LICENSE_STATUS_OK != Status )
  1113. {
  1114. if (Status == LICENSE_STATUS_INVALID_INPUT)
  1115. {
  1116. Status = LICENSE_STATUS_INVALID_RESPONSE;
  1117. }
  1118. goto construct_return_msg;
  1119. }
  1120. //
  1121. // Set the pre-master secret and generate the master secret
  1122. //
  1123. Status = LicenseSetPreMasterSecret( &pLicenseContext->CryptoContext, pPreMasterSecret );
  1124. if( LICENSE_STATUS_OK != Status )
  1125. {
  1126. goto construct_return_msg;
  1127. }
  1128. Status = LicenseBuildMasterSecret( &pLicenseContext->CryptoContext );
  1129. if( LICENSE_STATUS_OK != Status )
  1130. {
  1131. goto construct_return_msg;
  1132. }
  1133. //
  1134. // Derive the session key from the key exchange info
  1135. //
  1136. Status = LicenseMakeSessionKeys( &pLicenseContext->CryptoContext, 0 );
  1137. if( LICENSE_STATUS_OK != Status )
  1138. {
  1139. goto construct_return_msg;
  1140. }
  1141. //
  1142. // Use the session key to decrypt the HWID
  1143. //
  1144. if( LicenseInfo.EncryptedHWID.wBlobLen > sizeof(Hwid) )
  1145. {
  1146. Status = LICENSE_STATUS_INVALID_MAC_DATA;
  1147. goto construct_return_msg;
  1148. }
  1149. memcpy( &Hwid,
  1150. LicenseInfo.EncryptedHWID.pBlob,
  1151. LicenseInfo.EncryptedHWID.wBlobLen );
  1152. Status = LicenseDecryptSessionData( &pLicenseContext->CryptoContext,
  1153. ( PBYTE )&Hwid,
  1154. ( DWORD )LicenseInfo.EncryptedHWID.wBlobLen );
  1155. if( LICENSE_STATUS_OK != Status )
  1156. {
  1157. goto construct_return_msg;
  1158. }
  1159. //
  1160. // Calculate the MAC on the HWID.
  1161. //
  1162. Status = LicenseGenerateMAC( &pLicenseContext->CryptoContext,
  1163. ( PBYTE )&Hwid,
  1164. sizeof( HWID ),
  1165. MacData);
  1166. if( LICENSE_STATUS_OK != Status )
  1167. {
  1168. Status = LICENSE_STATUS_INVALID_MAC_DATA;
  1169. goto construct_return_msg;
  1170. }
  1171. //
  1172. // now verify the MAC data
  1173. //
  1174. if( 0 != memcmp( MacData, LicenseInfo.MACData, LICENSE_MAC_DATA ) )
  1175. {
  1176. Status = LICENSE_STATUS_INVALID_LICENSE;
  1177. goto license_bad;
  1178. }
  1179. //
  1180. // keep track of the client platform ID
  1181. //
  1182. pLicenseContext->dwClientPlatformID = LicenseInfo.dwPlatformID;
  1183. //
  1184. // call the license manager to validate the license.
  1185. // For now, we don't have to fill in the product info fields
  1186. //
  1187. ValidationInfo.pValidationData = ( PBYTE )&Hwid;
  1188. ValidationInfo.cbValidationData = LICENSE_HWID_LENGTH;
  1189. ValidationInfo.pProductInfo = &pLicenseContext->ProductInfo;
  1190. ValidationInfo.pLicense = LicenseInfo.LicenseInfo.pBlob;
  1191. ValidationInfo.cbLicense = ( DWORD )LicenseInfo.LicenseInfo.wBlobLen;
  1192. Status = ValidateLicense( pLicenseContext,
  1193. &ValidationInfo,
  1194. &dwLicenseState,
  1195. FALSE // fCheckForPermanent
  1196. );
  1197. license_bad:
  1198. //
  1199. // If the license cannot be decoded, then it is time to issue a new license
  1200. // for the client.
  1201. //
  1202. if( LICENSE_STATUS_CANNOT_DECODE_LICENSE == Status ||
  1203. LICENSE_STATUS_INVALID_LICENSE == Status )
  1204. {
  1205. LICENSE_STATUS StatusT = IssuePlatformChallenge( pLicenseContext, pcbOutBuf, ppOutBuf );
  1206. if( LICENSE_STATUS_OK != StatusT )
  1207. {
  1208. //
  1209. // cannot obtain a platform challenge for the client
  1210. //
  1211. #if DBG
  1212. DbgPrint( "LICPROT: cannot issue platform challenge: 0x%x\n", Status );
  1213. #endif
  1214. goto construct_return_msg;
  1215. }
  1216. pLicenseContext->State = ISSUED_PLATFORM_CHALLENGE;
  1217. Status = LICENSE_STATUS_CONTINUE;
  1218. goto done;
  1219. }
  1220. #ifdef UPGRADE_LICENSE
  1221. //
  1222. // check if the license needs to be upgraded.
  1223. //
  1224. if( ( LICENSE_STATUS_MUST_UPGRADE_LICENSE == Status ) ||
  1225. ( LICENSE_STATUS_SHOULD_UPGRADE_LICENSE == Status ) )
  1226. {
  1227. //
  1228. // issue the platform challenge for upgrading a license
  1229. //
  1230. UpgradeStatus = IssuePlatformChallenge(
  1231. pLicenseContext,
  1232. pcbOutBuf,
  1233. ppOutBuf );
  1234. if( LICENSE_STATUS_OK == UpgradeStatus )
  1235. {
  1236. //
  1237. // keep track of the old license and continue with the licensing
  1238. // protocol. We will upgrade the old license when the client
  1239. // returns with the platform challenge.
  1240. //
  1241. if( pLicenseContext->pbOldLicense )
  1242. {
  1243. LicenseMemoryFree( &pLicenseContext->pbOldLicense );
  1244. }
  1245. pLicenseContext->pbOldLicense = LicenseInfo.LicenseInfo.pBlob;
  1246. pLicenseContext->cbOldLicense = LicenseInfo.LicenseInfo.wBlobLen;
  1247. pLicenseContext->State = ISSUED_PLATFORM_CHALLENGE;
  1248. Status = LICENSE_STATUS_CONTINUE;
  1249. goto done;
  1250. }
  1251. else if( LICENSE_STATUS_SHOULD_UPGRADE_LICENSE == Status )
  1252. {
  1253. //
  1254. // Let the client go through if we cannot issue a platform
  1255. // challenge to upgrade a valid license now.
  1256. //
  1257. Status = LICENSE_STATUS_OK;
  1258. goto construct_return_msg;
  1259. }
  1260. else
  1261. {
  1262. // LICENSE_STATUS_MUST_UPGRADE_LICENSE: send back the real error
  1263. Status = UpgradeStatus;
  1264. }
  1265. //
  1266. // cannot issue platform challenge to upgrade a license that is
  1267. // not good any more.
  1268. //
  1269. #if DBG
  1270. DbgPrint( "LICPROT: cannot issue platform challenge to upgrade license: 0x%x\n", Status );
  1271. #endif
  1272. }
  1273. #else
  1274. //
  1275. // we are ignoring license upgrade
  1276. //
  1277. if( LICENSE_STATUS_SHOULD_UPGRADE_LICENSE == Status )
  1278. {
  1279. //
  1280. // change the status to OK
  1281. //
  1282. Status = LICENSE_STATUS_OK;
  1283. }
  1284. #endif
  1285. //
  1286. // now construct the message to return to the client, based on the current
  1287. // status code
  1288. //
  1289. construct_return_msg:
  1290. if( LICENSE_STATUS_OK != Status )
  1291. {
  1292. //
  1293. // The current status states that the client could not be validated
  1294. // due to some error
  1295. //
  1296. #if DBG
  1297. DbgPrint( "HandleClientLicense: constructing error message: 0x%x\n", Status );
  1298. #endif
  1299. //
  1300. // handle the error condition and update our state
  1301. //
  1302. HandleErrorCondition( pLicenseContext, pcbOutBuf, ppOutBuf, &Status );
  1303. pLicenseContext->State = VALIDATION_ERROR;
  1304. if( (LICENSE_STATUS_INVALID_RESPONSE == Status)
  1305. || (LICENSE_STATUS_INVALID_MAC_DATA == Status)
  1306. || (LICENSE_STATUS_CANNOT_DECODE_LICENSE == Status)
  1307. || (LICENSE_STATUS_INVALID_LICENSE == Status) )
  1308. {
  1309. WORD wLogString = 0;
  1310. LPTSTR ptszLogString[1] = { NULL };
  1311. //
  1312. // Log the failure
  1313. //
  1314. if( pLicenseContext->ptszClientMachineName )
  1315. {
  1316. wLogString = 1;
  1317. ptszLogString[0] = pLicenseContext->ptszClientMachineName;
  1318. }
  1319. LicenseLogEvent( EVENTLOG_INFORMATION_TYPE,
  1320. EVENT_INVALID_LICENSE,
  1321. wLogString, ptszLogString );
  1322. pLicenseContext->fLoggedProtocolError = TRUE;
  1323. }
  1324. else if ((NULL != pLicenseContext->pTsLicenseInfo)
  1325. && (!pLicenseContext->fLoggedProtocolError))
  1326. {
  1327. LPTSTR ptszLogString[1] = { NULL };
  1328. if( pLicenseContext->ptszClientMachineName )
  1329. {
  1330. ptszLogString[0] = pLicenseContext->ptszClientMachineName;
  1331. }
  1332. // Couldn't renew/upgrade license
  1333. pLicenseContext->fLoggedProtocolError = TRUE;
  1334. if(IsLicensingTimeBombExpired())
  1335. {
  1336. if (pLicenseContext->pTsLicenseInfo->fTempLicense)
  1337. {
  1338. // The expired temporary license could not be upgraded
  1339. LicenseLogEvent(
  1340. EVENTLOG_INFORMATION_TYPE,
  1341. EVENT_EXPIRED_TEMPORARY_LICENSE,
  1342. 1,
  1343. ptszLogString
  1344. );
  1345. }
  1346. else
  1347. {
  1348. // The expired permanent license could not be renewed
  1349. LicenseLogEvent(
  1350. EVENTLOG_INFORMATION_TYPE,
  1351. EVENT_EXPIRED_PERMANENT_LICENSE,
  1352. 1,
  1353. ptszLogString
  1354. );
  1355. }
  1356. }
  1357. }
  1358. goto done;
  1359. }
  1360. //
  1361. // The license has been validated successfully, generate the message to
  1362. // return to the client
  1363. //
  1364. Status = ConstructServerResponse( pLicenseContext->dwProtocolVersion,
  1365. LICENSE_RESPONSE_VALID_CLIENT,
  1366. TS_ERRINFO_NOERROR,
  1367. pcbOutBuf,
  1368. ppOutBuf,
  1369. *pfExtendedError);
  1370. if( LICENSE_STATUS_OK != Status )
  1371. {
  1372. #if DBG
  1373. DbgPrint( "HandleClientLicense: cannot pack error message: 0x%x\n", Status );
  1374. #endif
  1375. pLicenseContext->State = ABORTED;
  1376. Status = LICENSE_STATUS_SERVER_ABORT;
  1377. }
  1378. else
  1379. {
  1380. pLicenseContext->State = VALIDATED_LICENSE_COMPLETE;
  1381. }
  1382. done:
  1383. //
  1384. // free the memory used in the license info structure
  1385. //
  1386. FreeBinaryBlob( &LicenseInfo.EncryptedPreMasterSecret );
  1387. FreeBinaryBlob( &LicenseInfo.EncryptedHWID );
  1388. if( pLicenseContext->pbOldLicense != LicenseInfo.LicenseInfo.pBlob )
  1389. {
  1390. FreeBinaryBlob( &LicenseInfo.LicenseInfo );
  1391. }
  1392. if( pPreMasterSecret )
  1393. {
  1394. LicenseMemoryFree( &pPreMasterSecret );
  1395. }
  1396. return( Status);
  1397. }
  1398. ///////////////////////////////////////////////////////////////////////////////
  1399. LICENSE_STATUS
  1400. HandleNewLicenseRequest(
  1401. PHS_Protocol_Context pLicenseContext,
  1402. DWORD cbInBuf,
  1403. PBYTE pInBuf,
  1404. DWORD * pcbOutBuf,
  1405. PBYTE * ppOutBuf,
  1406. PBOOL pfExtendedError)
  1407. {
  1408. LICENSE_STATUS Status;
  1409. Hydra_Client_New_License_Request NewLicenseRequest;
  1410. PBYTE pPreMasterSecret = NULL;
  1411. DWORD dwPreMasterSecretLen = 0;
  1412. DWORD dwChallengeLen = 0;
  1413. DWORD CertType;
  1414. ASSERT( NULL != pInBuf );
  1415. ASSERT( cbInBuf > 0 );
  1416. if( ( NULL == pInBuf ) || ( 0 >= cbInBuf ) )
  1417. {
  1418. return( LICENSE_STATUS_INVALID_INPUT );
  1419. }
  1420. InitBinaryBlob( &NewLicenseRequest.EncryptedPreMasterSecret );
  1421. //
  1422. // Unpack the new license request
  1423. //
  1424. Status = UnPackHydraClientNewLicenseRequest( pInBuf, cbInBuf, &NewLicenseRequest, pfExtendedError );
  1425. if( LICENSE_STATUS_OK != Status )
  1426. {
  1427. #if DBG
  1428. DbgPrint( "LICPROT: HandleNewLicenseRequest: cannot unpack client request: 0x%x\n", Status );
  1429. #endif
  1430. return( Status );
  1431. }
  1432. //
  1433. // save the client user and machine name
  1434. //
  1435. #ifdef UNICODE
  1436. //
  1437. // convert the client's user and machine name to unicode
  1438. //
  1439. if( ( NewLicenseRequest.ClientUserName.pBlob ) &&
  1440. ( NULL == pLicenseContext->ptszClientUserName ) )
  1441. {
  1442. Status = Ascii2Wchar( NewLicenseRequest.ClientUserName.pBlob,
  1443. &pLicenseContext->ptszClientUserName );
  1444. if( LICENSE_STATUS_OK != Status )
  1445. {
  1446. #if DBG
  1447. DbgPrint( "LICPROT: HandleNewLicenseRequest: cannot convert client user name: %s to wide char: 0x%x\n",
  1448. NewLicenseRequest.ClientUserName.pBlob, Status );
  1449. #endif
  1450. }
  1451. }
  1452. if( ( NewLicenseRequest.ClientMachineName.pBlob ) &&
  1453. ( NULL == pLicenseContext->ptszClientMachineName ) )
  1454. {
  1455. Status = Ascii2Wchar( NewLicenseRequest.ClientMachineName.pBlob,
  1456. &pLicenseContext->ptszClientMachineName );
  1457. if( LICENSE_STATUS_OK != Status )
  1458. {
  1459. #if DBG
  1460. DbgPrint( "LICPROT: HandleNewLicenseRequest: cannot convert client machine name %s to wide char: 0x%x\n",
  1461. NewLicenseRequest.ClientMachineName.pBlob, Status );
  1462. #endif
  1463. }
  1464. }
  1465. #else // non-UNICODE
  1466. //
  1467. // save the client's user and machine name
  1468. //
  1469. if( ( NewLicenseRequest.ClientUserName.pBlob ) &&
  1470. ( NULL == pLicenseContext->ptszClientUserName ) )
  1471. {
  1472. Status = LicenseMemoryAllocate(
  1473. NewLicenseRequest.ClientUserName.wBlobLen,
  1474. &pLicenseContext->ptszClientUserName );
  1475. if( LICENSE_STATUS_OK != Status )
  1476. {
  1477. #if DBG
  1478. DbgPrint( "LICPROT: HandleNewLicenseRequest: cannot allocate memory for client's user name: 0x%x\n",
  1479. Status );
  1480. #endif
  1481. }
  1482. else
  1483. {
  1484. memcpy( pLicenseContext->ptszClientUserName,
  1485. NewLicenseRequest.ClientUserName.pBlob,
  1486. NewLicenseRequest.ClientUserName.wBlobLen );
  1487. }
  1488. }
  1489. if( ( NewLicenseRequest.ClientMachineName.pBlob ) &&
  1490. ( NULL == pLicenseContext->ptszClientMachineName ) )
  1491. {
  1492. Status = LicenseMemoryAllocate(
  1493. NewLicenseRequest.ClientMachineName.wBlobLen,
  1494. &pLicenseContext->ptszClientMachineName );
  1495. if( LICENSE_STATUS_OK != Status )
  1496. {
  1497. #if DBG
  1498. DbgPrint( "LICPROT: HandleNewLicenseRequest: cannot allocate memory for client's machine name: 0x%x\n",
  1499. Status );
  1500. #endif
  1501. }
  1502. else
  1503. {
  1504. memcpy( pLicenseContext->ptszClientMachineName,
  1505. NewLicenseRequest.ClientMachineName.pBlob,
  1506. NewLicenseRequest.ClientMachineName.wBlobLen );
  1507. }
  1508. }
  1509. #endif // UNICODE
  1510. //
  1511. // Initialize the crypto context with the key exchange info and build the pre-master
  1512. // secret. We need the server and client random numbers and the pre-master secret
  1513. // to build the pre-master secret.
  1514. //
  1515. memcpy( pLicenseContext->CryptoContext.rgbClientRandom,
  1516. NewLicenseRequest.ClientRandom,
  1517. LICENSE_RANDOM );
  1518. pLicenseContext->CryptoContext.dwKeyExchAlg = NewLicenseRequest.dwPrefKeyExchangeAlg;
  1519. //
  1520. // Get the pre-master secret from the enveloped data
  1521. //
  1522. Status = GetEnvelopedData( pLicenseContext->CertTypeUsed,
  1523. NewLicenseRequest.EncryptedPreMasterSecret.pBlob,
  1524. ( DWORD )NewLicenseRequest.EncryptedPreMasterSecret.wBlobLen,
  1525. &pPreMasterSecret,
  1526. &dwPreMasterSecretLen );
  1527. if( LICENSE_STATUS_OK != Status )
  1528. {
  1529. #if DBG
  1530. DbgPrint( "LICPROT: HandleNewLicenseRequest: cannot get enveloped data: 0x%x", Status );
  1531. #endif
  1532. goto done;
  1533. }
  1534. //
  1535. // set the premaster secret and generate the master secret
  1536. //
  1537. Status = LicenseSetPreMasterSecret( &pLicenseContext->CryptoContext, pPreMasterSecret );
  1538. if( LICENSE_STATUS_OK != Status )
  1539. {
  1540. goto done;
  1541. }
  1542. Status = LicenseBuildMasterSecret( &pLicenseContext->CryptoContext );
  1543. if( LICENSE_STATUS_OK != Status )
  1544. {
  1545. goto done;
  1546. }
  1547. //
  1548. // Derive the session key from the key exchange info
  1549. //
  1550. Status = LicenseMakeSessionKeys( &pLicenseContext->CryptoContext, 0 );
  1551. if( LICENSE_STATUS_OK != Status )
  1552. {
  1553. goto done;
  1554. }
  1555. //
  1556. // record the client platform ID and issue the platform challenge
  1557. //
  1558. pLicenseContext->dwClientPlatformID = NewLicenseRequest.dwPlatformID;
  1559. Status = IssuePlatformChallenge( pLicenseContext, pcbOutBuf, ppOutBuf );
  1560. if( LICENSE_STATUS_OK != Status )
  1561. {
  1562. goto done;
  1563. }
  1564. //
  1565. // update our state
  1566. //
  1567. pLicenseContext->State = ISSUED_PLATFORM_CHALLENGE;
  1568. Status = LICENSE_STATUS_CONTINUE;
  1569. done:
  1570. FreeBinaryBlob( &NewLicenseRequest.EncryptedPreMasterSecret );
  1571. FreeBinaryBlob( &NewLicenseRequest.ClientUserName );
  1572. FreeBinaryBlob( &NewLicenseRequest.ClientMachineName );
  1573. if( pPreMasterSecret )
  1574. {
  1575. LicenseMemoryFree( &pPreMasterSecret );
  1576. }
  1577. return( Status );
  1578. }
  1579. ///////////////////////////////////////////////////////////////////////////////
  1580. LICENSE_STATUS
  1581. HandleClientError(
  1582. PHS_Protocol_Context pLicenseContext,
  1583. DWORD cbInBuf,
  1584. PBYTE pInBuf,
  1585. DWORD * pcbOutBuf,
  1586. PBYTE * ppOutBuf,
  1587. PBOOL pfExtendedError )
  1588. {
  1589. LICENSE_STATUS Status;
  1590. License_Error_Message ClientError;
  1591. ASSERT( NULL != pInBuf );
  1592. ASSERT( cbInBuf > 0 );
  1593. ASSERT( NULL != pfExtendedError);
  1594. if( ( NULL == pInBuf ) || ( 0 >= cbInBuf ) )
  1595. {
  1596. return( LICENSE_STATUS_INVALID_INPUT );
  1597. }
  1598. InitBinaryBlob( &ClientError.bbErrorInfo );
  1599. //
  1600. // unpack the client error
  1601. //
  1602. Status = UnPackHydraClientErrorMessage( pInBuf, cbInBuf, &ClientError, pfExtendedError );
  1603. if( LICENSE_STATUS_OK != Status )
  1604. {
  1605. return( Status );
  1606. }
  1607. //
  1608. // Process the client error code, the possible errors are:
  1609. // (1) Error processing the hydra server certificate
  1610. // (2) Client has no license and does not want one
  1611. //
  1612. // For now, just record the client error and abort the operation
  1613. //
  1614. pLicenseContext->dwClientError = ClientError.dwErrorCode;
  1615. pLicenseContext->State = ABORTED;
  1616. FreeBinaryBlob( &ClientError.bbErrorInfo );
  1617. return( LICENSE_STATUS_CLIENT_ABORT );
  1618. }
  1619. LICENSE_STATUS
  1620. AuthWithLicenseServer(
  1621. PHS_Protocol_Context pLicenseContext )
  1622. {
  1623. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  1624. LPBYTE lpCert = NULL;
  1625. DWORD dwResult, RpcStatus;
  1626. DWORD dwSize;
  1627. if (pLicenseContext->hLSHandle == NULL)
  1628. {
  1629. return LICENSE_STATUS_INVALID_SERVER_CONTEXT;
  1630. }
  1631. Status = TLSGetTSCertificate(CERT_TYPE_X509, &lpCert, &dwSize);
  1632. if (Status != LICENSE_STATUS_OK)
  1633. {
  1634. Status = TLSGetTSCertificate(CERT_TYPE_PROPRIETORY, &lpCert, &dwSize);
  1635. }
  1636. if (Status != LICENSE_STATUS_OK)
  1637. {
  1638. goto done;
  1639. }
  1640. RpcStatus = TLSSendServerCertificate(
  1641. pLicenseContext->hLSHandle,
  1642. dwSize,
  1643. lpCert,
  1644. &dwResult
  1645. );
  1646. if( ( RPC_S_OK != RpcStatus ) || ( LSERVER_S_SUCCESS != dwResult ) )
  1647. {
  1648. Status = LICENSE_STATUS_AUTHENTICATION_ERROR;
  1649. goto done;
  1650. }
  1651. done:
  1652. if (lpCert)
  1653. TLSFreeTSCertificate(lpCert);
  1654. return Status;
  1655. }
  1656. ///////////////////////////////////////////////////////////////////////////////
  1657. LICENSE_STATUS
  1658. CheckConnectLicenseServer(
  1659. PHS_Protocol_Context pLicenseContext )
  1660. {
  1661. LICENSE_STATUS Status = LICENSE_STATUS_NO_LICENSE_SERVER;
  1662. if (pLicenseContext->hLSHandle != NULL)
  1663. return LICENSE_STATUS_OK;
  1664. pLicenseContext->hLSHandle = TLSConnectToAnyLsServer(LS_DISCOVERY_TIMEOUT);
  1665. if (NULL != pLicenseContext->hLSHandle)
  1666. {
  1667. Status = AuthWithLicenseServer(pLicenseContext);
  1668. if (Status == LICENSE_STATUS_OK)
  1669. {
  1670. goto done;
  1671. }
  1672. else if(Status == LICENSE_STATUS_AUTHENTICATION_ERROR)
  1673. {
  1674. BOOL fInDomain;
  1675. LPWSTR szLSName = NULL;
  1676. DWORD dwErr;
  1677. dwErr = TLSInDomain(&fInDomain, NULL);
  1678. if( (ERROR_SUCCESS == dwErr) && (fInDomain == TRUE))
  1679. {
  1680. DWORD dwErrCode = ERROR_SUCCESS;
  1681. dwErr = TLSGetServerNameFixed(pLicenseContext->hLSHandle,&szLSName,&dwErrCode);
  1682. if(dwErr == RPC_S_OK && dwErrCode == ERROR_SUCCESS && NULL != szLSName)
  1683. {
  1684. LicenseLogEvent( EVENTLOG_WARNING_TYPE,
  1685. EVENT_LICENSE_SERVER_AUTHENTICATION_FAILED,
  1686. 1, &szLSName );
  1687. }
  1688. if(NULL != szLSName)
  1689. {
  1690. MIDL_user_free(szLSName);
  1691. }
  1692. }
  1693. }
  1694. }
  1695. else
  1696. {
  1697. BOOL fInDomain;
  1698. LPWSTR szDomain = NULL;
  1699. DWORD dwErr;
  1700. dwErr = TLSInDomain(&fInDomain,&szDomain);
  1701. if ((ERROR_SUCCESS == dwErr) && (NULL != szDomain))
  1702. {
  1703. ThrottleLicenseLogEvent(
  1704. EVENTLOG_WARNING_TYPE,
  1705. fInDomain
  1706. ? EVENT_NO_LICENSE_SERVER_DOMAIN
  1707. : EVENT_NO_LICENSE_SERVER_WORKGROUP,
  1708. 1,
  1709. &szDomain );
  1710. }
  1711. else
  1712. {
  1713. ThrottleLicenseLogEvent(
  1714. EVENTLOG_WARNING_TYPE,
  1715. EVENT_NO_LICENSE_SERVER,
  1716. 0,
  1717. NULL );
  1718. }
  1719. if (NULL != szDomain)
  1720. {
  1721. NetApiBufferFree(szDomain);
  1722. }
  1723. }
  1724. // error case
  1725. if (NULL != pLicenseContext->hLSHandle)
  1726. {
  1727. TLSDisconnectFromServer(pLicenseContext->hLSHandle);
  1728. pLicenseContext->hLSHandle = NULL;
  1729. }
  1730. done:
  1731. return Status;
  1732. }
  1733. ///////////////////////////////////////////////////////////////////////////////
  1734. LICENSE_STATUS
  1735. CheckConnectNamedLicenseServer(
  1736. PHS_Protocol_Context pLicenseContext,
  1737. TCHAR *tszComputerName)
  1738. {
  1739. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  1740. if (pLicenseContext->hLSHandle != NULL)
  1741. return LICENSE_STATUS_OK;
  1742. pLicenseContext->hLSHandle = TLSConnectToLsServer(tszComputerName);
  1743. if (NULL == pLicenseContext->hLSHandle)
  1744. {
  1745. Status = LICENSE_STATUS_NO_LICENSE_SERVER;
  1746. goto done;
  1747. }
  1748. Status = AuthWithLicenseServer(pLicenseContext);
  1749. if (Status != LICENSE_STATUS_OK)
  1750. {
  1751. TLSDisconnectFromServer(pLicenseContext->hLSHandle);
  1752. pLicenseContext->hLSHandle = NULL;
  1753. }
  1754. done:
  1755. return Status;
  1756. }
  1757. ///////////////////////////////////////////////////////////////////////////////
  1758. LICENSE_STATUS
  1759. CheckUpgradeLicense(
  1760. PHS_Protocol_Context pLicenseContext,
  1761. PDWORD pSupportFlags,
  1762. PLicense_Request pLicenseRequest,
  1763. DWORD cbChallengeResponse,
  1764. PBYTE pbChallengeResponse,
  1765. PHWID pHwid,
  1766. PDWORD pcbOutBuf,
  1767. PBYTE * ppOutBuf )
  1768. {
  1769. LICENSE_STATUS
  1770. Status = LICENSE_STATUS_OK;
  1771. DWORD
  1772. cbLicense = 0;
  1773. PBYTE
  1774. pbLicense = NULL;
  1775. Validation_Info
  1776. ValidationInfo;
  1777. DWORD
  1778. dwLicenseState = 0;
  1779. DWORD
  1780. RpcStatus, LsStatus;
  1781. BOOL
  1782. fRetried = FALSE;
  1783. reconnect:
  1784. Status = CheckConnectLicenseServer(pLicenseContext);
  1785. if( LICENSE_STATUS_OK != Status )
  1786. {
  1787. goto validate_old_one;
  1788. }
  1789. RpcStatus = TLSUpgradeLicenseEx(pLicenseContext->hLSHandle,
  1790. pSupportFlags,
  1791. pLicenseRequest,
  1792. 0, // ChallengeContext unused
  1793. cbChallengeResponse,
  1794. pbChallengeResponse,
  1795. pLicenseContext->cbOldLicense,
  1796. pLicenseContext->pbOldLicense,
  1797. 1, // dwQuantity
  1798. &cbLicense,
  1799. &pbLicense,
  1800. &LsStatus
  1801. );
  1802. if ( RPC_S_OK != RpcStatus )
  1803. {
  1804. if (!fRetried)
  1805. {
  1806. fRetried = TRUE;
  1807. pLicenseContext->hLSHandle = NULL;
  1808. goto reconnect;
  1809. }
  1810. else
  1811. {
  1812. Status = LICENSE_STATUS_NO_LICENSE_SERVER;
  1813. }
  1814. }
  1815. else if ( LSERVER_ERROR_BASE <= LsStatus )
  1816. {
  1817. Status = LsStatusToLicenseStatus(LsStatus,
  1818. LICENSE_STATUS_CANNOT_UPGRADE_LICENSE);
  1819. }
  1820. validate_old_one:
  1821. ValidationInfo.pValidationData = ( PBYTE )pHwid;
  1822. ValidationInfo.cbValidationData = LICENSE_HWID_LENGTH;
  1823. ValidationInfo.pProductInfo = &pLicenseContext->ProductInfo;
  1824. //
  1825. // if we cannot upgrade the license, check if the current license is
  1826. // still good. If it is, return it to the client.
  1827. //
  1828. if( LICENSE_STATUS_OK != Status )
  1829. {
  1830. LICENSE_STATUS
  1831. LicenseStatus;
  1832. ValidationInfo.pLicense = pLicenseContext->pbOldLicense;
  1833. ValidationInfo.cbLicense = pLicenseContext->cbOldLicense;
  1834. LicenseStatus = ValidateLicense(
  1835. pLicenseContext,
  1836. &ValidationInfo,
  1837. &dwLicenseState,
  1838. FALSE // fCheckForPermanent
  1839. );
  1840. if( ( LICENSE_STATUS_OK == LicenseStatus ) ||
  1841. ( LICENSE_STATUS_SHOULD_UPGRADE_LICENSE == LicenseStatus ) )
  1842. {
  1843. //
  1844. // Store the raw license bits for later use. Ignore failure;
  1845. // that only means that if this is a license that should be
  1846. // marked, termsrv won't be able to.
  1847. //
  1848. CacheRawLicenseData(pLicenseContext,
  1849. pLicenseContext->pbOldLicense,
  1850. pLicenseContext->cbOldLicense);
  1851. //
  1852. // The current license is still OK, send it back to the client.
  1853. //
  1854. Status = PackageLicense(
  1855. pLicenseContext,
  1856. pLicenseContext->cbOldLicense,
  1857. pLicenseContext->pbOldLicense,
  1858. pcbOutBuf,
  1859. ppOutBuf,
  1860. FALSE );
  1861. }
  1862. else
  1863. {
  1864. //
  1865. // The current license is not good any more
  1866. //
  1867. #if DBG
  1868. DbgPrint( "UpgradeLicense: cannot upgrade license 0x%x\n", Status );
  1869. #endif
  1870. }
  1871. goto done;
  1872. }
  1873. //
  1874. // the license upgrade was successful. Now validate the new license so
  1875. // that the new license info will be cached.
  1876. //
  1877. ValidationInfo.pLicense = pbLicense;
  1878. ValidationInfo.cbLicense = cbLicense;
  1879. ValidateLicense(
  1880. pLicenseContext,
  1881. &ValidationInfo,
  1882. &dwLicenseState,
  1883. TRUE // fCheckForPermanent
  1884. );
  1885. //
  1886. // Store the raw license bits for later use. Ignore failure; that only
  1887. // means that if this is a license that should be marked, termsrv won't be
  1888. // able to.
  1889. //
  1890. CacheRawLicenseData(pLicenseContext,
  1891. pbLicense,
  1892. cbLicense);
  1893. //
  1894. // pack up the upgraded license
  1895. //
  1896. Status = PackageLicense( pLicenseContext,
  1897. cbLicense,
  1898. pbLicense,
  1899. pcbOutBuf,
  1900. ppOutBuf,
  1901. FALSE );
  1902. done:
  1903. if( pbLicense )
  1904. {
  1905. LicenseMemoryFree( &pbLicense );
  1906. }
  1907. return( Status );
  1908. }
  1909. ///////////////////////////////////////////////////////////////////////////////
  1910. LICENSE_STATUS
  1911. HandlePlatformChallengeResponse(
  1912. PHS_Protocol_Context pLicenseContext,
  1913. DWORD cbInBuf,
  1914. PBYTE pInBuf,
  1915. DWORD * pcbOutBuf,
  1916. PBYTE * ppOutBuf,
  1917. PBOOL pfExtendedError)
  1918. {
  1919. LICENSE_STATUS Status;
  1920. Hydra_Client_Platform_Challenge_Response PlatformChallengeResponse;
  1921. BYTE ChallengeResponse[PLATFORM_CHALLENGE_LENGTH];
  1922. PBYTE pLicense = NULL;
  1923. DWORD cbLicenseSize = 0;
  1924. License_Request LicenseRequest;
  1925. HS_LICENSE_STATE HsState = ABORTED;
  1926. License_Requester_Info RequesterInfo;
  1927. BYTE bEncryptedHwid[ sizeof( HWID ) ];
  1928. PBYTE pbSecretKey = NULL;
  1929. DWORD cbMacData = 0, cbSecretKey = 0, cbEncryptedHwid = sizeof( HWID );
  1930. BYTE MacData[ sizeof( HWID ) + PLATFORM_CHALLENGE_LENGTH ];
  1931. BYTE ComputedMac[LICENSE_MAC_DATA];
  1932. HWID Hwid;
  1933. DWORD RpcStatus,LsStatus;
  1934. TCHAR tszComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  1935. TCHAR tszUserName[UNLEN + 1];
  1936. DWORD dwComputerName = MAX_COMPUTERNAME_LENGTH + 1;
  1937. DWORD dwUserName = UNLEN + 1;
  1938. DWORD dwSupportFlags = ALL_KNOWN_SUPPORT_FLAGS;
  1939. BOOL fRetried = FALSE;
  1940. ASSERT( NULL != pInBuf );
  1941. ASSERT( cbInBuf > 0 );
  1942. if( ( NULL == pInBuf ) || ( 0 >= cbInBuf ) )
  1943. {
  1944. return( LICENSE_STATUS_INVALID_INPUT );
  1945. }
  1946. //
  1947. // unpack the platform challenge response
  1948. //
  1949. InitBinaryBlob( &PlatformChallengeResponse.EncryptedChallengeResponse );
  1950. InitBinaryBlob( &PlatformChallengeResponse.EncryptedHWID );
  1951. Status = UnPackHydraClientPlatformChallengeResponse( pInBuf, cbInBuf, &PlatformChallengeResponse, pfExtendedError );
  1952. if( LICENSE_STATUS_OK != Status )
  1953. {
  1954. goto done;
  1955. }
  1956. //
  1957. // decrypt the encrypted challenge response and HWID
  1958. //
  1959. ASSERT(PlatformChallengeResponse.EncryptedChallengeResponse.wBlobLen
  1960. <= PLATFORM_CHALLENGE_LENGTH);
  1961. if(PlatformChallengeResponse.EncryptedChallengeResponse.wBlobLen > PLATFORM_CHALLENGE_LENGTH)
  1962. {
  1963. Status = LICENSE_STATUS_INVALID_INPUT;
  1964. goto done;
  1965. }
  1966. memcpy( ChallengeResponse,
  1967. PlatformChallengeResponse.EncryptedChallengeResponse.pBlob,
  1968. PlatformChallengeResponse.EncryptedChallengeResponse.wBlobLen );
  1969. Status = LicenseDecryptSessionData( &pLicenseContext->CryptoContext,
  1970. ChallengeResponse,
  1971. ( DWORD )PlatformChallengeResponse.EncryptedChallengeResponse.wBlobLen );
  1972. if( LICENSE_STATUS_OK != Status )
  1973. {
  1974. goto done;
  1975. }
  1976. //
  1977. // decrypt the client's HWID
  1978. //
  1979. if( PlatformChallengeResponse.EncryptedHWID.wBlobLen > sizeof(Hwid) )
  1980. {
  1981. Status = LICENSE_STATUS_INVALID_MAC_DATA;
  1982. goto done;
  1983. }
  1984. memcpy( &Hwid,
  1985. PlatformChallengeResponse.EncryptedHWID.pBlob,
  1986. PlatformChallengeResponse.EncryptedHWID.wBlobLen );
  1987. Status = LicenseDecryptSessionData( &pLicenseContext->CryptoContext,
  1988. ( PBYTE )&Hwid,
  1989. ( DWORD )PlatformChallengeResponse.EncryptedHWID.wBlobLen );
  1990. if( LICENSE_STATUS_OK != Status )
  1991. {
  1992. goto done;
  1993. }
  1994. //
  1995. // Verify the MAC data on the decrypted challenge response and the HWID
  1996. //
  1997. cbMacData += ( DWORD )PlatformChallengeResponse.EncryptedChallengeResponse.wBlobLen;
  1998. memcpy( MacData,
  1999. ChallengeResponse,
  2000. ( DWORD )PlatformChallengeResponse.EncryptedChallengeResponse.wBlobLen );
  2001. cbMacData += ( DWORD )PlatformChallengeResponse.EncryptedHWID.wBlobLen;
  2002. memcpy( MacData + ( DWORD )PlatformChallengeResponse.EncryptedChallengeResponse.wBlobLen,
  2003. &Hwid,
  2004. ( DWORD )PlatformChallengeResponse.EncryptedHWID.wBlobLen );
  2005. Status = LicenseGenerateMAC( &pLicenseContext->CryptoContext,
  2006. MacData,
  2007. cbMacData,
  2008. ComputedMac );
  2009. if( LICENSE_STATUS_OK != Status )
  2010. {
  2011. Status = LICENSE_STATUS_INVALID_MAC_DATA;
  2012. goto done;
  2013. }
  2014. if( 0 != memcmp( ComputedMac,
  2015. PlatformChallengeResponse.MACData,
  2016. LICENSE_MAC_DATA ) )
  2017. {
  2018. Status = LICENSE_STATUS_INVALID_MAC_DATA;
  2019. goto done;
  2020. }
  2021. //
  2022. // now get the license server's secret key and encrypt the HWID before transmitting it.
  2023. //
  2024. LicenseGetSecretKey( &cbSecretKey, NULL );
  2025. Status = LicenseMemoryAllocate( cbSecretKey, &pbSecretKey );
  2026. if( LICENSE_STATUS_OK != Status )
  2027. {
  2028. goto done;
  2029. }
  2030. Status = LicenseGetSecretKey( &cbSecretKey, pbSecretKey );
  2031. if( LICENSE_STATUS_OK != Status )
  2032. {
  2033. goto done;
  2034. }
  2035. Status = LicenseEncryptHwid( &Hwid, &cbEncryptedHwid, bEncryptedHwid,
  2036. cbSecretKey, pbSecretKey );
  2037. if( LICENSE_STATUS_OK != Status )
  2038. {
  2039. goto done;
  2040. }
  2041. LicenseRequest.cbEncryptedHwid = cbEncryptedHwid;
  2042. LicenseRequest.pbEncryptedHwid = bEncryptedHwid;
  2043. //
  2044. // send the platform challenge response to the license manager and wait for it
  2045. // to issue a new license.
  2046. //
  2047. LicenseRequest.pProductInfo = &pLicenseContext->ProductInfo;
  2048. LicenseRequest.dwPlatformID = pLicenseContext->dwClientPlatformID;
  2049. LicenseRequest.dwLanguageID = GetSystemDefaultLCID();
  2050. //
  2051. // if we don't have the client's user and machine name, get it now.
  2052. //
  2053. if( NULL == pLicenseContext->ptszClientMachineName )
  2054. {
  2055. //
  2056. // if we don't have the client machine name, just use the
  2057. // hydra server machine name
  2058. //
  2059. if( !GetComputerName( tszComputerName, &dwComputerName ) )
  2060. {
  2061. #if DBG
  2062. DbgPrint( "HandlePlatformChallengeResponse: cannot get computer name: 0x%x\n", GetLastError() );
  2063. #endif
  2064. memset( tszComputerName, 0, ( MAX_COMPUTERNAME_LENGTH + 1 ) * sizeof( TCHAR ) );
  2065. }
  2066. RequesterInfo.ptszMachineName = tszComputerName;
  2067. }
  2068. else
  2069. {
  2070. RequesterInfo.ptszMachineName = pLicenseContext->ptszClientMachineName;
  2071. }
  2072. if( NULL == pLicenseContext->ptszClientUserName )
  2073. {
  2074. //
  2075. // if we don't have the client's user name, just use the
  2076. // hydra server logged on user name.
  2077. //
  2078. if( !GetUserName( tszUserName, &dwUserName ) )
  2079. {
  2080. #if DBG
  2081. DbgPrint( "HandlePlatformChallengeResponse: cannot get user name: 0x%x\n", GetLastError() );
  2082. #endif
  2083. memset( tszUserName, 0, ( UNLEN + 1 ) * sizeof( TCHAR ) );
  2084. }
  2085. RequesterInfo.ptszUserName = tszUserName;
  2086. }
  2087. else
  2088. {
  2089. RequesterInfo.ptszUserName = pLicenseContext->ptszClientUserName;
  2090. }
  2091. if( pLicenseContext->pbOldLicense )
  2092. {
  2093. //
  2094. // attempt to upgrade an old license
  2095. //
  2096. Status = CheckUpgradeLicense(
  2097. pLicenseContext,
  2098. &dwSupportFlags,
  2099. &LicenseRequest,
  2100. ( DWORD )PlatformChallengeResponse.EncryptedChallengeResponse.wBlobLen,
  2101. ChallengeResponse,
  2102. &Hwid,
  2103. pcbOutBuf,
  2104. ppOutBuf );
  2105. if (LICENSE_STATUS_OK != Status)
  2106. {
  2107. if (NULL != pLicenseContext->pTsLicenseInfo)
  2108. {
  2109. pLicenseContext->fLoggedProtocolError = TRUE;
  2110. if(IsLicensingTimeBombExpired())
  2111. {
  2112. if (pLicenseContext->pTsLicenseInfo->fTempLicense)
  2113. {
  2114. // The expired temporary license could not be upgraded
  2115. LicenseLogEvent(
  2116. EVENTLOG_INFORMATION_TYPE,
  2117. EVENT_EXPIRED_TEMPORARY_LICENSE,
  2118. 1,
  2119. &(RequesterInfo.ptszMachineName)
  2120. );
  2121. }
  2122. else
  2123. {
  2124. // The expired permanent license could not be renewed
  2125. LicenseLogEvent(
  2126. EVENTLOG_INFORMATION_TYPE,
  2127. EVENT_EXPIRED_PERMANENT_LICENSE,
  2128. 1,
  2129. &(RequesterInfo.ptszMachineName)
  2130. );
  2131. }
  2132. }
  2133. }
  2134. }
  2135. if( LICENSE_STATUS_OK != Status )
  2136. {
  2137. goto done;
  2138. }
  2139. }
  2140. else
  2141. {
  2142. reconnect:
  2143. Status = CheckConnectLicenseServer(pLicenseContext);
  2144. if( LICENSE_STATUS_OK != Status )
  2145. {
  2146. goto done;
  2147. }
  2148. RpcStatus = TLSIssueNewLicenseEx(
  2149. pLicenseContext->hLSHandle,
  2150. &dwSupportFlags,
  2151. 0, // ChallengeContext unused
  2152. &LicenseRequest,
  2153. RequesterInfo.ptszMachineName,
  2154. RequesterInfo.ptszUserName,
  2155. ( DWORD )PlatformChallengeResponse.EncryptedChallengeResponse.wBlobLen,
  2156. ChallengeResponse,
  2157. TRUE,
  2158. 1, // dwQuantity
  2159. &cbLicenseSize,
  2160. &pLicense,
  2161. &LsStatus );
  2162. if ( RPC_S_OK != RpcStatus )
  2163. {
  2164. if (!fRetried)
  2165. {
  2166. fRetried = TRUE;
  2167. pLicenseContext->hLSHandle = NULL;
  2168. goto reconnect;
  2169. }
  2170. else
  2171. {
  2172. Status = LICENSE_STATUS_NO_LICENSE_SERVER;
  2173. }
  2174. }
  2175. else if ( LSERVER_ERROR_BASE <= LsStatus )
  2176. {
  2177. Status = LsStatusToLicenseStatus(LsStatus,
  2178. LICENSE_STATUS_NO_LICENSE_ERROR);
  2179. }
  2180. else
  2181. {
  2182. DWORD dwLicenseState;
  2183. Validation_Info ValidationInfo;
  2184. //
  2185. // Validate the license for the sole purpose of caching the
  2186. // information.
  2187. //
  2188. ValidationInfo.pValidationData = ( PBYTE )&Hwid;
  2189. ValidationInfo.cbValidationData = LICENSE_HWID_LENGTH;
  2190. ValidationInfo.pProductInfo = &pLicenseContext->ProductInfo;
  2191. ValidationInfo.pLicense = pLicense;
  2192. ValidationInfo.cbLicense = cbLicenseSize;
  2193. ValidateLicense(pLicenseContext,
  2194. &ValidationInfo,
  2195. &dwLicenseState,
  2196. TRUE // fCheckForPermanent
  2197. );
  2198. //
  2199. // Store the raw license bits for later use. Ignore failure;
  2200. // that only means that if this is a license that should be
  2201. // marked, termsrv won't be able to.
  2202. //
  2203. CacheRawLicenseData(pLicenseContext, pLicense, cbLicenseSize);
  2204. //
  2205. // package up the new license
  2206. //
  2207. Status = PackageLicense( pLicenseContext,
  2208. cbLicenseSize,
  2209. pLicense,
  2210. pcbOutBuf,
  2211. ppOutBuf,
  2212. TRUE );
  2213. }
  2214. }
  2215. SetExtendedData(pLicenseContext, dwSupportFlags);
  2216. if( LICENSE_STATUS_OK != Status )
  2217. {
  2218. goto done;
  2219. }
  2220. //
  2221. // done with the protocol
  2222. //
  2223. HsState = ISSUED_LICENSE_COMPLETE;
  2224. Status = LICENSE_STATUS_ISSUED_LICENSE;
  2225. done:
  2226. //
  2227. // log all issue license failures
  2228. //
  2229. if( (LICENSE_STATUS_ISSUED_LICENSE != Status)
  2230. && (pLicenseContext != NULL)
  2231. && (!pLicenseContext->fLoggedProtocolError) )
  2232. {
  2233. pLicenseContext->fLoggedProtocolError = TRUE;
  2234. LicenseLogEvent( EVENTLOG_INFORMATION_TYPE,
  2235. EVENT_CANNOT_ISSUE_LICENSE,
  2236. 0, NULL );
  2237. }
  2238. if( pLicense )
  2239. {
  2240. LicenseMemoryFree( &pLicense );
  2241. }
  2242. if( pbSecretKey )
  2243. {
  2244. LicenseMemoryFree( &pbSecretKey );
  2245. }
  2246. if( pLicenseContext->pbOldLicense )
  2247. {
  2248. //
  2249. // free the old license
  2250. //
  2251. LicenseMemoryFree( &pLicenseContext->pbOldLicense );
  2252. pLicenseContext->cbOldLicense = 0;
  2253. }
  2254. FreeBinaryBlob( &PlatformChallengeResponse.EncryptedChallengeResponse );
  2255. FreeBinaryBlob( &PlatformChallengeResponse.EncryptedHWID );
  2256. pLicenseContext->State = HsState;
  2257. return( Status );
  2258. }
  2259. ///////////////////////////////////////////////////////////////////////////////
  2260. LICENSE_STATUS
  2261. IssuePlatformChallenge(
  2262. PHS_Protocol_Context pLicenseContext,
  2263. PDWORD pcbOutBuf,
  2264. PBYTE * ppOutBuf )
  2265. {
  2266. Hydra_Server_Platform_Challenge
  2267. PlatformChallenge;
  2268. LICENSE_STATUS
  2269. Status = LICENSE_STATUS_OK;
  2270. CHALLENGE_CONTEXT
  2271. ChallengeContext;
  2272. //
  2273. // generate the platform challenge
  2274. //
  2275. ASSERT( pLicenseContext );
  2276. //
  2277. // Form the platform challenge message
  2278. //
  2279. PlatformChallenge.EncryptedPlatformChallenge.wBlobLen = ( WORD )sizeof(HARDCODED_CHALLENGE_DATA);
  2280. Status = LicenseMemoryAllocate(sizeof(HARDCODED_CHALLENGE_DATA), &(PlatformChallenge.EncryptedPlatformChallenge.pBlob));
  2281. if (LICENSE_STATUS_OK != Status)
  2282. {
  2283. #if DBG
  2284. DbgPrint( "LICPROT: cannot generate MAC data for challenge platform: 0x%x\n", Status );
  2285. #endif
  2286. goto done;
  2287. }
  2288. memcpy(PlatformChallenge.EncryptedPlatformChallenge.pBlob, HARDCODED_CHALLENGE_DATA, sizeof(HARDCODED_CHALLENGE_DATA));
  2289. //
  2290. // calculate the MAC for the unencrypted platform challenge
  2291. //
  2292. Status = LicenseGenerateMAC( &pLicenseContext->CryptoContext,
  2293. PlatformChallenge.EncryptedPlatformChallenge.pBlob,
  2294. ( DWORD )PlatformChallenge.EncryptedPlatformChallenge.wBlobLen,
  2295. PlatformChallenge.MACData );
  2296. if( LICENSE_STATUS_OK != Status )
  2297. {
  2298. #if DBG
  2299. DbgPrint( "LICPROT: cannot generate MAC data for challenge platform: 0x%x\n", Status );
  2300. #endif
  2301. goto done;
  2302. }
  2303. //
  2304. // encrypt the platform challenge
  2305. //
  2306. Status = LicenseEncryptSessionData( &pLicenseContext->CryptoContext,
  2307. PlatformChallenge.EncryptedPlatformChallenge.pBlob,
  2308. PlatformChallenge.EncryptedPlatformChallenge.wBlobLen );
  2309. if( LICENSE_STATUS_OK != Status )
  2310. {
  2311. #if DBG
  2312. DbgPrint( "LICPROT: cannot encrypt platform challenge data: 0x%x\n", Status );
  2313. #endif
  2314. goto done;
  2315. }
  2316. //
  2317. // pack the platform challenge
  2318. //
  2319. Status = PackHydraServerPlatformChallenge(
  2320. pLicenseContext->dwProtocolVersion,
  2321. &PlatformChallenge,
  2322. ppOutBuf,
  2323. pcbOutBuf );
  2324. if( LICENSE_STATUS_OK != Status )
  2325. {
  2326. #if DBG
  2327. DbgPrint( "LICPROT: cannot pack platform challenge data: 0x%x\n", Status );
  2328. #endif
  2329. goto done;
  2330. }
  2331. done:
  2332. if (NULL != PlatformChallenge.EncryptedPlatformChallenge.pBlob)
  2333. {
  2334. LicenseMemoryFree(&PlatformChallenge.EncryptedPlatformChallenge.pBlob);
  2335. }
  2336. return( Status );
  2337. }
  2338. ///////////////////////////////////////////////////////////////////////////////
  2339. LICENSE_STATUS
  2340. PackageLicense(
  2341. PHS_Protocol_Context pLicenseContext,
  2342. DWORD cbLicense,
  2343. PBYTE pLicense,
  2344. PDWORD pcbOutBuf,
  2345. PBYTE * ppOutBuf,
  2346. BOOL fNewLicense )
  2347. {
  2348. LICENSE_STATUS Status;
  2349. New_License_Info NewLicenseInfo;
  2350. Hydra_Server_New_License NewLicense;
  2351. DWORD cbEncryptedLicenseInfo = 0;
  2352. if( ( 0 == cbLicense ) || ( NULL == pLicense ) )
  2353. {
  2354. return( LICENSE_STATUS_INVALID_INPUT );
  2355. }
  2356. //
  2357. // Initialize the new license information
  2358. //
  2359. NewLicenseInfo.dwVersion = pLicenseContext->ProductInfo.dwVersion;
  2360. NewLicenseInfo.cbScope = strlen( pLicenseContext->Scope ) + 1;
  2361. NewLicenseInfo.pbScope = pLicenseContext->Scope;
  2362. NewLicenseInfo.cbCompanyName = pLicenseContext->ProductInfo.cbCompanyName;
  2363. NewLicenseInfo.pbCompanyName = pLicenseContext->ProductInfo.pbCompanyName;
  2364. NewLicenseInfo.cbProductID = pLicenseContext->ProductInfo.cbProductID;
  2365. NewLicenseInfo.pbProductID = pLicenseContext->ProductInfo.pbProductID;
  2366. NewLicenseInfo.cbLicenseInfo = cbLicense;
  2367. NewLicenseInfo.pbLicenseInfo = pLicense;
  2368. //
  2369. // initialize the blob that will contain the encrypted new license
  2370. // information
  2371. //
  2372. NewLicense.EncryptedNewLicenseInfo.wBlobLen = 0;
  2373. NewLicense.EncryptedNewLicenseInfo.pBlob = NULL;
  2374. //
  2375. // pack the new license information
  2376. //
  2377. Status = PackNewLicenseInfo( &NewLicenseInfo,
  2378. &NewLicense.EncryptedNewLicenseInfo.pBlob,
  2379. &cbEncryptedLicenseInfo );
  2380. NewLicense.EncryptedNewLicenseInfo.wBlobLen = ( WORD )cbEncryptedLicenseInfo;
  2381. if( LICENSE_STATUS_OK != Status )
  2382. {
  2383. goto done;
  2384. }
  2385. //
  2386. // calculate the mac data
  2387. //
  2388. Status = LicenseGenerateMAC( &pLicenseContext->CryptoContext,
  2389. NewLicense.EncryptedNewLicenseInfo.pBlob,
  2390. ( DWORD )NewLicense.EncryptedNewLicenseInfo.wBlobLen,
  2391. NewLicense.MACData );
  2392. if( LICENSE_STATUS_OK != Status )
  2393. {
  2394. goto done;
  2395. }
  2396. //
  2397. // Encrypt the new license info
  2398. //
  2399. Status = LicenseEncryptSessionData( &pLicenseContext->CryptoContext,
  2400. NewLicense.EncryptedNewLicenseInfo.pBlob,
  2401. cbEncryptedLicenseInfo );
  2402. if( LICENSE_STATUS_OK != Status )
  2403. {
  2404. goto done;
  2405. }
  2406. //
  2407. // package up the license for the client
  2408. //
  2409. if( fNewLicense )
  2410. {
  2411. Status = PackHydraServerNewLicense(
  2412. pLicenseContext->dwProtocolVersion,
  2413. &NewLicense,
  2414. ppOutBuf,
  2415. pcbOutBuf );
  2416. }
  2417. else
  2418. {
  2419. Status = PackHydraServerUpgradeLicense(
  2420. pLicenseContext->dwProtocolVersion,
  2421. &NewLicense,
  2422. ppOutBuf,
  2423. pcbOutBuf );
  2424. }
  2425. done:
  2426. if( NewLicense.EncryptedNewLicenseInfo.pBlob )
  2427. {
  2428. LicenseMemoryFree( &NewLicense.EncryptedNewLicenseInfo.pBlob );
  2429. }
  2430. return( Status );
  2431. }
  2432. ///////////////////////////////////////////////////////////////////////////////
  2433. LICENSE_STATUS
  2434. ConstructProtocolResponse(
  2435. HANDLE hLicense,
  2436. DWORD dwResponse,
  2437. UINT32 uiExtendedErrorInfo,
  2438. PDWORD pcbOutBuf,
  2439. PBYTE * ppOutBuf,
  2440. BOOL fExtendedError)
  2441. {
  2442. PHS_Protocol_Context
  2443. pLicenseContext;
  2444. LICENSE_STATUS
  2445. Status;
  2446. pLicenseContext = ( PHS_Protocol_Context )hLicense;
  2447. if (pLicenseContext == NULL)
  2448. {
  2449. return( LICENSE_STATUS_INVALID_INPUT );
  2450. }
  2451. LOCK( &pLicenseContext->CritSec );
  2452. //
  2453. // construct the server response. If this is a per seat license context, use the
  2454. // licensing protocol version specified in the context. Otherwise, use the
  2455. // protocol version that is compatible with Terminal server 4.0.
  2456. //
  2457. Status = ConstructServerResponse(
  2458. pLicenseContext->dwProtocolVersion,
  2459. dwResponse,
  2460. uiExtendedErrorInfo,
  2461. pcbOutBuf,
  2462. ppOutBuf,
  2463. fExtendedError);
  2464. UNLOCK( &pLicenseContext->CritSec );
  2465. return( Status );
  2466. }
  2467. ///////////////////////////////////////////////////////////////////////////////
  2468. LICENSE_STATUS
  2469. ConstructServerResponse(
  2470. DWORD dwProtocolVersion,
  2471. DWORD dwResponse,
  2472. UINT32 uiExtendedErrorInfo,
  2473. PDWORD pcbOutBuf,
  2474. PBYTE * ppOutBuf,
  2475. BOOL fExtendedError)
  2476. {
  2477. License_Error_Message ErrorMsg;
  2478. LICENSE_STATUS Status;
  2479. if( ( NULL == pcbOutBuf ) || ( NULL == ppOutBuf ))
  2480. {
  2481. return( LICENSE_STATUS_INVALID_INPUT );
  2482. }
  2483. if( LICENSE_RESPONSE_VALID_CLIENT == dwResponse )
  2484. {
  2485. ErrorMsg.dwErrorCode = GM_HS_ERR_VALID_CLIENT;
  2486. ErrorMsg.dwStateTransition = ST_NO_TRANSITION;
  2487. }
  2488. else if( LICENSE_RESPONSE_INVALID_CLIENT == dwResponse )
  2489. {
  2490. ErrorMsg.dwErrorCode = GM_HS_ERR_INVALID_CLIENT;
  2491. ErrorMsg.dwStateTransition = ST_TOTAL_ABORT;
  2492. }
  2493. else
  2494. {
  2495. return( LICENSE_STATUS_INVALID_INPUT );
  2496. }
  2497. ErrorMsg.bbErrorInfo.wBlobType = BB_ERROR_BLOB;
  2498. if (uiExtendedErrorInfo == TS_ERRINFO_NOERROR || !(fExtendedError) )
  2499. {
  2500. ErrorMsg.bbErrorInfo.wBlobLen = 0;
  2501. ErrorMsg.bbErrorInfo.pBlob = NULL;
  2502. }
  2503. else
  2504. {
  2505. PackExtendedErrorInfo(uiExtendedErrorInfo,&(ErrorMsg.bbErrorInfo));
  2506. }
  2507. Status = PackHydraServerErrorMessage(
  2508. dwProtocolVersion,
  2509. &ErrorMsg,
  2510. ppOutBuf,
  2511. pcbOutBuf );
  2512. return( Status );
  2513. }
  2514. ///////////////////////////////////////////////////////////////////////////////
  2515. LICENSE_STATUS
  2516. GetEnvelopedData(
  2517. CERT_TYPE CertType,
  2518. PBYTE pEnvelopedData,
  2519. DWORD dwEnvelopedDataLen,
  2520. PBYTE * ppData,
  2521. PDWORD pdwDataLen )
  2522. {
  2523. LICENSE_STATUS
  2524. Status;
  2525. LsCsp_DecryptEnvelopedData(
  2526. CertType,
  2527. pEnvelopedData,
  2528. dwEnvelopedDataLen,
  2529. NULL,
  2530. pdwDataLen );
  2531. Status = LicenseMemoryAllocate( *pdwDataLen, ppData );
  2532. if( LICENSE_STATUS_OK != Status )
  2533. {
  2534. goto done;
  2535. }
  2536. if( !LsCsp_DecryptEnvelopedData(
  2537. CertType,
  2538. pEnvelopedData,
  2539. dwEnvelopedDataLen,
  2540. *ppData,
  2541. pdwDataLen ) )
  2542. {
  2543. Status = LICENSE_STATUS_INVALID_INPUT;
  2544. }
  2545. done:
  2546. return( Status );
  2547. }
  2548. ///////////////////////////////////////////////////////////////////////////////
  2549. LICENSE_STATUS
  2550. InitProductInfo(
  2551. PProduct_Info pProductInfo,
  2552. LPTSTR lptszProductSku )
  2553. {
  2554. LICENSE_STATUS Status;
  2555. pProductInfo->pbCompanyName = NULL;
  2556. pProductInfo->pbProductID = NULL;
  2557. pProductInfo->dwVersion = g_dwTerminalServerVersion;
  2558. pProductInfo->cbCompanyName = wcslen( PRODUCT_INFO_COMPANY_NAME ) * sizeof( WCHAR )
  2559. + sizeof( WCHAR );
  2560. Status = LicenseMemoryAllocate( pProductInfo->cbCompanyName,
  2561. &pProductInfo->pbCompanyName );
  2562. if( LICENSE_STATUS_OK != Status )
  2563. {
  2564. #if DBG
  2565. DbgPrint( "InitProductInfo: cannot allocate memory: 0x%x\n", Status );
  2566. #endif
  2567. goto error;
  2568. }
  2569. wcscpy( ( PWCHAR )pProductInfo->pbCompanyName, PRODUCT_INFO_COMPANY_NAME );
  2570. pProductInfo->cbProductID = _tcslen( lptszProductSku ) * sizeof( TCHAR )
  2571. + sizeof( TCHAR );
  2572. Status = LicenseMemoryAllocate( pProductInfo->cbProductID,
  2573. &pProductInfo->pbProductID );
  2574. if( LICENSE_STATUS_OK != Status )
  2575. {
  2576. #if DBG
  2577. DbgPrint( "InitProductInfo: cannot allocate memory: 0x%x\n", Status );
  2578. #endif
  2579. goto error;
  2580. }
  2581. _tcscpy( ( PTCHAR )pProductInfo->pbProductID, lptszProductSku );
  2582. return( Status );
  2583. error:
  2584. //
  2585. // error return, free allocated resources
  2586. //
  2587. if( pProductInfo->pbCompanyName )
  2588. {
  2589. LicenseMemoryFree( &pProductInfo->pbCompanyName );
  2590. }
  2591. if( pProductInfo->pbProductID )
  2592. {
  2593. LicenseMemoryFree( &pProductInfo->pbProductID );
  2594. }
  2595. return( Status );
  2596. }
  2597. #define THROTTLE_WRAPAROUND 100
  2598. //
  2599. // Reduce the frequency of logging
  2600. // No need to strictly limit it to once every 100 calls
  2601. //
  2602. void
  2603. ThrottleLicenseLogEvent(
  2604. WORD wEventType,
  2605. DWORD dwEventId,
  2606. WORD cStrings,
  2607. PWCHAR * apwszStrings )
  2608. {
  2609. static LONG lLogged = THROTTLE_WRAPAROUND;
  2610. LONG lResult;
  2611. lResult = InterlockedIncrement(&lLogged);
  2612. if (THROTTLE_WRAPAROUND <= lResult)
  2613. {
  2614. LicenseLogEvent(
  2615. wEventType,
  2616. dwEventId,
  2617. cStrings,
  2618. apwszStrings );
  2619. lLogged = 0;
  2620. }
  2621. }
  2622. ///////////////////////////////////////////////////////////////////////////////
  2623. void
  2624. LicenseLogEvent(
  2625. WORD wEventType,
  2626. DWORD dwEventId,
  2627. WORD cStrings,
  2628. PWCHAR * apwszStrings )
  2629. {
  2630. if (!g_fEventLogOpen)
  2631. {
  2632. LOCK(&g_EventLogCritSec);
  2633. if (!g_fEventLogOpen)
  2634. {
  2635. g_hEventLog = RegisterEventSource( NULL,
  2636. TERMINAL_SERVICE_EVENT_LOG );
  2637. if (NULL != g_hEventLog)
  2638. {
  2639. g_fEventLogOpen = TRUE;
  2640. }
  2641. }
  2642. UNLOCK(&g_EventLogCritSec);
  2643. }
  2644. if( g_hEventLog )
  2645. {
  2646. WCHAR *wszStringEmpty = L"";
  2647. if (NULL == apwszStrings)
  2648. apwszStrings = &wszStringEmpty;
  2649. if ( !ReportEvent( g_hEventLog,
  2650. wEventType,
  2651. 0,
  2652. dwEventId,
  2653. NULL,
  2654. cStrings,
  2655. 0,
  2656. apwszStrings,
  2657. NULL ) )
  2658. {
  2659. #if DBG
  2660. DbgPrint( "LogEvent: could not log event: 0x%x\n", GetLastError() );
  2661. #endif
  2662. }
  2663. }
  2664. return;
  2665. }
  2666. #ifdef UNICODE
  2667. /*++
  2668. Function:
  2669. Ascii2Wchar
  2670. Description:
  2671. Convert an ascii string to a wide character string. This function is only
  2672. defined if UNICODE is defined. This function allocates memory for the
  2673. return value of the wide character string.
  2674. Arguments:
  2675. lpszAsciiStr - Points to the ascii string
  2676. ppwszWideStr - Points to the pointer to the wide character string.
  2677. Return:
  2678. LICENSE_STATUS_OK if successful or a LICENSE_STATUS error code otherwise.
  2679. --*/
  2680. LICENSE_STATUS
  2681. Ascii2Wchar
  2682. (
  2683. LPSTR lpszAsciiStr,
  2684. LPWSTR * ppwszWideStr )
  2685. {
  2686. LICENSE_STATUS
  2687. Status;
  2688. if( ( NULL == lpszAsciiStr ) || ( NULL == ppwszWideStr ) )
  2689. {
  2690. return( LICENSE_STATUS_INVALID_INPUT );
  2691. }
  2692. if( !g_fSetLocale )
  2693. {
  2694. setlocale( LC_ALL, "" );
  2695. g_fSetLocale = TRUE;
  2696. }
  2697. //
  2698. // allocate memory for the wide string
  2699. //
  2700. //
  2701. // Allocate extra space for NULL, mbstowcs() does not NULL terminate string
  2702. //
  2703. Status = LicenseMemoryAllocate(
  2704. ( _mbslen( lpszAsciiStr ) + 2 ) * sizeof( WCHAR ),
  2705. ppwszWideStr );
  2706. if( LICENSE_STATUS_OK != Status )
  2707. {
  2708. return( Status );
  2709. }
  2710. if( 0 >= mbstowcs( *ppwszWideStr, lpszAsciiStr, _mbslen( lpszAsciiStr ) + 1 ) )
  2711. {
  2712. #if DBG
  2713. DbgPrint( "LICPROT: Ascii2Wchar: cannot convert ascii string to wide char\n" );
  2714. #endif
  2715. Status = LICENSE_STATUS_INVALID_INPUT;
  2716. }
  2717. return( Status );
  2718. }
  2719. #endif
  2720. /*++
  2721. Function:
  2722. QueryLicenseInfo
  2723. Description:
  2724. Query the license information provided by the client
  2725. Parameters:
  2726. pLicenseContext - License protocol context
  2727. pTsLicenseInfo - Pointer to license information
  2728. Return:
  2729. If successful, pTsLicenseInfo will contain the license info and this
  2730. function returns LICENSE_STATUS_SUCCESS. Otherwise, returns a
  2731. LICENSE_STATUS error.
  2732. --*/
  2733. LICENSE_STATUS
  2734. QueryLicenseInfo(
  2735. HANDLE hContext,
  2736. PTS_LICENSE_INFO pTsLicenseInfo )
  2737. {
  2738. PHS_Protocol_Context
  2739. pLicenseContext = (PHS_Protocol_Context) hContext;
  2740. LICENSE_STATUS
  2741. Status;
  2742. if( ( NULL == hContext ) || ( NULL == pTsLicenseInfo ) )
  2743. {
  2744. return( LICENSE_STATUS_INVALID_INPUT );
  2745. }
  2746. if( NULL == pLicenseContext->pTsLicenseInfo )
  2747. {
  2748. return( LICENSE_STATUS_NO_LICENSE_ERROR );
  2749. }
  2750. //
  2751. // indicate if the license is temporary
  2752. //
  2753. pTsLicenseInfo->fTempLicense = pLicenseContext->pTsLicenseInfo->fTempLicense;
  2754. //
  2755. // license validity dates
  2756. //
  2757. pTsLicenseInfo->NotAfter = pLicenseContext->pTsLicenseInfo->NotAfter;
  2758. //
  2759. // raw license data
  2760. //
  2761. if (NULL != pTsLicenseInfo->pbRawLicense)
  2762. {
  2763. LicenseMemoryFree( &pTsLicenseInfo->pbRawLicense );
  2764. }
  2765. Status = LicenseMemoryAllocate(
  2766. pLicenseContext->pTsLicenseInfo->cbRawLicense,
  2767. &(pTsLicenseInfo->pbRawLicense));
  2768. if (Status != LICENSE_STATUS_OK)
  2769. {
  2770. return Status;
  2771. }
  2772. memcpy(pTsLicenseInfo->pbRawLicense,
  2773. pLicenseContext->pTsLicenseInfo->pbRawLicense,
  2774. pLicenseContext->pTsLicenseInfo->cbRawLicense);
  2775. pTsLicenseInfo->cbRawLicense
  2776. = pLicenseContext->pTsLicenseInfo->cbRawLicense;
  2777. //
  2778. // flags
  2779. //
  2780. pTsLicenseInfo->dwSupportFlags
  2781. = pLicenseContext->pTsLicenseInfo->dwSupportFlags;
  2782. return( LICENSE_STATUS_OK );
  2783. }
  2784. /*++
  2785. Function:
  2786. FreeLicenseInfo
  2787. Description:
  2788. Free the memory allocated for the elements in the TS_LICENSE_INFO structure.
  2789. Parameters:
  2790. pTsLicenseInfo - Pointer to a TS_LICENSE_INFO structure
  2791. Returns:
  2792. Nothing.
  2793. --*/
  2794. VOID
  2795. FreeLicenseInfo(
  2796. PTS_LICENSE_INFO pTsLicenseInfo )
  2797. {
  2798. FreeTsLicenseInfo( pTsLicenseInfo );
  2799. return;
  2800. }
  2801. ///////////////////////////////////////////////////////////////////////////////
  2802. LICENSE_STATUS
  2803. AcceptProtocolContext(
  2804. IN HANDLE hContext,
  2805. IN DWORD cbInBuf,
  2806. IN PBYTE pInBuf,
  2807. IN OUT DWORD * pcbOutBuf,
  2808. IN OUT PBYTE * ppOutBuf,
  2809. IN OUT PBOOL pfExtendedError)
  2810. {
  2811. PHS_Protocol_Context pLicenseContext;
  2812. LICENSE_STATUS Status;
  2813. pLicenseContext = ( PHS_Protocol_Context )hContext;
  2814. if (NULL == pLicenseContext)
  2815. {
  2816. return LICENSE_STATUS_INVALID_SERVER_CONTEXT;
  2817. }
  2818. LOCK( &pLicenseContext->CritSec );
  2819. if( INIT == pLicenseContext->State )
  2820. {
  2821. //
  2822. // Generate a hydra server hello message to request for client
  2823. // license
  2824. //
  2825. Status = CreateHydraServerHello(pLicenseContext,
  2826. cbInBuf,
  2827. pInBuf,
  2828. pcbOutBuf,
  2829. ppOutBuf);
  2830. goto done;
  2831. }
  2832. else if( SENT_SERVER_HELLO == pLicenseContext->State )
  2833. {
  2834. //
  2835. // Hello response from the client
  2836. //
  2837. Status = HandleHelloResponse(pLicenseContext,
  2838. cbInBuf,
  2839. pInBuf,
  2840. pcbOutBuf,
  2841. ppOutBuf,
  2842. pfExtendedError);
  2843. goto done;
  2844. }
  2845. else if( ISSUED_PLATFORM_CHALLENGE == pLicenseContext->State )
  2846. {
  2847. //
  2848. // Handle the platform challenge response
  2849. //
  2850. Status = HandlePlatformChallengeResponse(pLicenseContext,
  2851. cbInBuf,
  2852. pInBuf,
  2853. pcbOutBuf,
  2854. ppOutBuf,
  2855. pfExtendedError);
  2856. goto done;
  2857. }
  2858. else
  2859. {
  2860. Status = LICENSE_STATUS_INVALID_SERVER_CONTEXT;
  2861. }
  2862. //
  2863. // check other states to create other messages as required...
  2864. //
  2865. done:
  2866. //
  2867. // handle any error before returning.
  2868. //
  2869. // If the current status is LICENSE_STATUS_SERVER_ABORT, it means
  2870. // that we have already tried to handle the error conditions
  2871. // with no success and the only option is to abort without
  2872. // informing the client licensing protocol.
  2873. //
  2874. if( ( LICENSE_STATUS_OK != Status ) &&
  2875. ( LICENSE_STATUS_CONTINUE != Status ) &&
  2876. ( LICENSE_STATUS_ISSUED_LICENSE != Status ) &&
  2877. ( LICENSE_STATUS_SEND_ERROR != Status ) &&
  2878. ( LICENSE_STATUS_SERVER_ABORT != Status ) &&
  2879. ( LICENSE_STATUS_INVALID_SERVER_CONTEXT != Status ) )
  2880. {
  2881. HandleErrorCondition( pLicenseContext, pcbOutBuf, ppOutBuf, &Status );
  2882. }
  2883. UNLOCK( &pLicenseContext->CritSec );
  2884. return( Status );
  2885. }
  2886. LICENSE_STATUS
  2887. RequestNewLicense(
  2888. IN HANDLE hContext,
  2889. IN TCHAR *tszLicenseServerName,
  2890. IN LICENSEREQUEST *pLicenseRequest,
  2891. IN TCHAR *tszComputerName,
  2892. IN TCHAR *tszUserName,
  2893. IN BOOL fAcceptTempLicense,
  2894. IN BOOL fAcceptFewerLicenses,
  2895. IN DWORD *pdwQuantity,
  2896. OUT DWORD *pcbLicense,
  2897. OUT PBYTE *ppbLicense
  2898. )
  2899. {
  2900. PHS_Protocol_Context pLicenseContext;
  2901. LICENSE_STATUS LsStatus;
  2902. DWORD dwChallengeResponse = 0;
  2903. DWORD RpcStatus;
  2904. DWORD dwSupportFlags = SUPPORT_PER_SEAT_REISSUANCE;
  2905. BOOL fRetried = FALSE;
  2906. pLicenseContext = ( PHS_Protocol_Context )hContext;
  2907. LOCK( &pLicenseContext->CritSec );
  2908. reconnect:
  2909. if (NULL != tszLicenseServerName)
  2910. {
  2911. LsStatus = CheckConnectNamedLicenseServer(pLicenseContext,
  2912. tszLicenseServerName);
  2913. }
  2914. else
  2915. {
  2916. LsStatus = CheckConnectLicenseServer(pLicenseContext);
  2917. }
  2918. if( LICENSE_STATUS_OK != LsStatus )
  2919. {
  2920. goto done;
  2921. }
  2922. RpcStatus = TLSIssueNewLicenseExEx(
  2923. pLicenseContext->hLSHandle,
  2924. &dwSupportFlags,
  2925. 0, // Challenge Context
  2926. pLicenseRequest,
  2927. tszComputerName,
  2928. tszUserName,
  2929. sizeof(DWORD), // cbChallengeResponse
  2930. (PBYTE) &dwChallengeResponse,
  2931. fAcceptTempLicense,
  2932. fAcceptFewerLicenses,
  2933. pdwQuantity,
  2934. pcbLicense,
  2935. ppbLicense,
  2936. &LsStatus );
  2937. if ( RPC_S_OK != RpcStatus )
  2938. {
  2939. if (!fRetried)
  2940. {
  2941. fRetried = TRUE;
  2942. pLicenseContext->hLSHandle = NULL;
  2943. goto reconnect;
  2944. }
  2945. else
  2946. {
  2947. LsStatus = LICENSE_STATUS_NO_LICENSE_SERVER;
  2948. }
  2949. }
  2950. else if ( LSERVER_ERROR_BASE <= LsStatus )
  2951. {
  2952. LsStatus = LsStatusToLicenseStatus(LsStatus,
  2953. LICENSE_STATUS_NO_LICENSE_ERROR);
  2954. }
  2955. else
  2956. {
  2957. LsStatus = LICENSE_STATUS_OK;
  2958. }
  2959. done:
  2960. UNLOCK( &pLicenseContext->CritSec );
  2961. return LsStatus;
  2962. }
  2963. // TODO: Generalize this for all license types
  2964. LICENSE_STATUS
  2965. ReturnInternetLicense(
  2966. IN HANDLE hContext,
  2967. IN TCHAR *tszLicenseServer,
  2968. IN LICENSEREQUEST *pLicenseRequest,
  2969. IN ULARGE_INTEGER ulSerialNumber,
  2970. IN DWORD dwQuantity
  2971. )
  2972. {
  2973. PHS_Protocol_Context pLicenseContext;
  2974. LICENSE_STATUS LsStatus;
  2975. DWORD RpcStatus;
  2976. BOOL fRetried = FALSE;
  2977. pLicenseContext = ( PHS_Protocol_Context )hContext;
  2978. LOCK( &pLicenseContext->CritSec );
  2979. reconnect:
  2980. if (NULL != tszLicenseServer)
  2981. {
  2982. LsStatus = CheckConnectNamedLicenseServer(pLicenseContext,
  2983. tszLicenseServer);
  2984. }
  2985. else
  2986. {
  2987. LsStatus = CheckConnectLicenseServer(pLicenseContext);
  2988. }
  2989. if (LICENSE_STATUS_OK != LsStatus)
  2990. {
  2991. goto done;
  2992. }
  2993. RpcStatus = TLSReturnInternetLicenseEx(
  2994. pLicenseContext->hLSHandle,
  2995. pLicenseRequest,
  2996. &ulSerialNumber,
  2997. dwQuantity,
  2998. &LsStatus );
  2999. if ( RPC_S_OK != RpcStatus )
  3000. {
  3001. if (!fRetried)
  3002. {
  3003. fRetried = TRUE;
  3004. pLicenseContext->hLSHandle = NULL;
  3005. goto reconnect;
  3006. }
  3007. else
  3008. {
  3009. LsStatus = LICENSE_STATUS_NO_LICENSE_SERVER;
  3010. }
  3011. }
  3012. else if ( LSERVER_ERROR_BASE <= LsStatus )
  3013. {
  3014. LsStatus = LsStatusToLicenseStatus(LsStatus,
  3015. LICENSE_STATUS_NOT_SUPPORTED);
  3016. }
  3017. else
  3018. {
  3019. LsStatus = LICENSE_STATUS_OK;
  3020. }
  3021. done:
  3022. UNLOCK( &pLicenseContext->CritSec );
  3023. return( LsStatus );
  3024. }
  3025. /****************************************************************************
  3026. *
  3027. * FileTimeToUnixTime
  3028. *
  3029. * Convert FILETIME to UNIX time (time_t)
  3030. *
  3031. * ENTRY:
  3032. * pft (input)
  3033. * pointer FILETIME structure
  3034. * t (input/output)
  3035. * pointer to UNIX time
  3036. *
  3037. * EXIT:
  3038. * TRUE - Success
  3039. * FALSE - Failure
  3040. *
  3041. ****************************************************************************/
  3042. BOOL
  3043. FileTimeToUnixTime(
  3044. LPFILETIME pft,
  3045. time_t * t
  3046. )
  3047. {
  3048. SYSTEMTIME sysTime;
  3049. struct tm gmTime;
  3050. if( FileTimeToSystemTime( pft, &sysTime ) == FALSE )
  3051. {
  3052. return( FALSE );
  3053. }
  3054. if( sysTime.wYear >= 2038 )
  3055. {
  3056. *t = INT_MAX;
  3057. }
  3058. else
  3059. {
  3060. //
  3061. // Unix time support up to 2038/1/18
  3062. // restrict any expiration data
  3063. //
  3064. memset( &gmTime, 0, sizeof( gmTime ) );
  3065. gmTime.tm_sec = sysTime.wSecond;
  3066. gmTime.tm_min = sysTime.wMinute;
  3067. gmTime.tm_hour = sysTime.wHour;
  3068. gmTime.tm_year = sysTime.wYear - 1900;
  3069. gmTime.tm_mon = sysTime.wMonth - 1;
  3070. gmTime.tm_mday = sysTime.wDay;
  3071. *t = mktime( &gmTime );
  3072. }
  3073. return( *t != ( time_t )-1 );
  3074. }
  3075. /*++
  3076. Function:
  3077. DaysToExpiration
  3078. Description:
  3079. Return expiration info from the client license
  3080. Parameters:
  3081. hContext - License protocol context
  3082. pdwDaysLeft - Number of days to expiration is returned here. If the
  3083. license has already expired, this is 0. If the
  3084. license has no expiration date, this is 0xFFFFFFFF
  3085. pfTemporary - Whether the license is temporary is returned here
  3086. Return:
  3087. If successful, the output parameters are filled in, and this
  3088. function returns LICENSE_STATUS_SUCCESS. Otherwise, returns a
  3089. LICENSE_STATUS error.
  3090. --*/
  3091. LICENSE_STATUS
  3092. DaysToExpiration(
  3093. HANDLE hContext,
  3094. DWORD *pdwDaysLeft,
  3095. BOOL *pfTemporary
  3096. )
  3097. {
  3098. PHS_Protocol_Context
  3099. pLicenseContext = (PHS_Protocol_Context) hContext;
  3100. time_t
  3101. Expiration,
  3102. CurrentTime;
  3103. if ( NULL == hContext )
  3104. {
  3105. return( LICENSE_STATUS_INVALID_INPUT );
  3106. }
  3107. if( NULL == pLicenseContext->pTsLicenseInfo )
  3108. {
  3109. return( LICENSE_STATUS_NO_LICENSE_ERROR );
  3110. }
  3111. //
  3112. // indicate if the license is temporary
  3113. //
  3114. if (NULL != pfTemporary)
  3115. {
  3116. *pfTemporary = pLicenseContext->pTsLicenseInfo->fTempLicense;
  3117. }
  3118. //
  3119. // license validity dates
  3120. //
  3121. if (NULL != pdwDaysLeft)
  3122. {
  3123. if ( FALSE == FileTimeToUnixTime( &pLicenseContext->pTsLicenseInfo->NotAfter, &Expiration ) )
  3124. {
  3125. return (LICENSE_STATUS_INVALID_CLIENT_CONTEXT);
  3126. }
  3127. if (PERMANENT_LICENSE_EXPIRE_DATE == Expiration)
  3128. {
  3129. *pdwDaysLeft = 0xFFFFFFFF;
  3130. }
  3131. else
  3132. {
  3133. time( &CurrentTime );
  3134. if( CurrentTime >= Expiration )
  3135. {
  3136. //
  3137. // license already expired
  3138. //
  3139. *pdwDaysLeft = 0;
  3140. }
  3141. //
  3142. // figure out how many more days to go before license expires
  3143. //
  3144. *pdwDaysLeft = (DWORD)(( Expiration - CurrentTime ) / SECONDS_IN_A_DAY);
  3145. }
  3146. }
  3147. return( LICENSE_STATUS_OK );
  3148. }
  3149. /*++
  3150. Function:
  3151. MarkLicenseFlags
  3152. Description:
  3153. Marks the license at the license server as being used in a valid logon.
  3154. --*/
  3155. LICENSE_STATUS
  3156. MarkLicenseFlags(
  3157. HANDLE hContext,
  3158. UCHAR ucFlags
  3159. )
  3160. {
  3161. PHS_Protocol_Context pLicenseContext;
  3162. LICENSE_STATUS LsStatus;
  3163. DWORD RpcStatus;
  3164. BOOL fRetried = FALSE;
  3165. pLicenseContext = ( PHS_Protocol_Context )hContext;
  3166. if( NULL == pLicenseContext->pTsLicenseInfo )
  3167. {
  3168. return( LICENSE_STATUS_NO_LICENSE_ERROR );
  3169. }
  3170. if (!pLicenseContext->pTsLicenseInfo->fTempLicense)
  3171. {
  3172. return LICENSE_STATUS_OK;
  3173. }
  3174. // TODO: This can be done on a background thread, so that it doesn't
  3175. // block logon
  3176. LOCK( &pLicenseContext->CritSec );
  3177. reconnect:
  3178. LsStatus = CheckConnectLicenseServer(pLicenseContext);
  3179. if( LICENSE_STATUS_OK != LsStatus )
  3180. {
  3181. goto done;
  3182. }
  3183. RpcStatus = TLSMarkLicense(
  3184. pLicenseContext->hLSHandle,
  3185. ucFlags,
  3186. pLicenseContext->pTsLicenseInfo->cbRawLicense,
  3187. pLicenseContext->pTsLicenseInfo->pbRawLicense,
  3188. &LsStatus );
  3189. if ( RPC_S_OK != RpcStatus )
  3190. {
  3191. if (!fRetried)
  3192. {
  3193. fRetried = TRUE;
  3194. pLicenseContext->hLSHandle = NULL;
  3195. goto reconnect;
  3196. }
  3197. else
  3198. {
  3199. LsStatus = LICENSE_STATUS_NO_LICENSE_SERVER;
  3200. }
  3201. }
  3202. else if ( LSERVER_ERROR_BASE <= LsStatus )
  3203. {
  3204. LsStatus = LsStatusToLicenseStatus(LsStatus,
  3205. LICENSE_STATUS_NOT_SUPPORTED);
  3206. }
  3207. else
  3208. {
  3209. LsStatus = LICENSE_STATUS_OK;
  3210. }
  3211. done:
  3212. UNLOCK( &pLicenseContext->CritSec );
  3213. return LsStatus;
  3214. }
  3215. /*++
  3216. Function:
  3217. CacheRawLicenseData
  3218. Description:
  3219. Caches the unpacked license bits in the TS_LICENSE_INFO for later use.
  3220. The TS_LICENSE_INFO struct should already be created.
  3221. --*/
  3222. LICENSE_STATUS
  3223. CacheRawLicenseData(
  3224. PHS_Protocol_Context pLicenseContext,
  3225. PBYTE pbRawLicense,
  3226. DWORD cbRawLicense
  3227. )
  3228. {
  3229. LICENSE_STATUS Status;
  3230. if ((pLicenseContext == NULL) || (pLicenseContext->pTsLicenseInfo == NULL))
  3231. {
  3232. return(LICENSE_STATUS_INVALID_INPUT);
  3233. }
  3234. if (pLicenseContext->pTsLicenseInfo->pbRawLicense != NULL)
  3235. {
  3236. LicenseMemoryFree(&(pLicenseContext->pTsLicenseInfo->pbRawLicense));
  3237. }
  3238. Status = LicenseMemoryAllocate(cbRawLicense,
  3239. &(pLicenseContext->pTsLicenseInfo->pbRawLicense));
  3240. if (Status == LICENSE_STATUS_OK)
  3241. {
  3242. memcpy(pLicenseContext->pTsLicenseInfo->pbRawLicense, pbRawLicense,
  3243. cbRawLicense);
  3244. pLicenseContext->pTsLicenseInfo->cbRawLicense = cbRawLicense;
  3245. }
  3246. return(Status);
  3247. }
  3248. /*++
  3249. Function:
  3250. SetExtendedData
  3251. Description:
  3252. Sets the new fields in the TsLicenseInfo.
  3253. --*/
  3254. LICENSE_STATUS
  3255. SetExtendedData(
  3256. PHS_Protocol_Context pLicenseContext,
  3257. DWORD dwSupportFlags
  3258. )
  3259. {
  3260. if ((pLicenseContext == NULL) || (pLicenseContext->pTsLicenseInfo == NULL))
  3261. {
  3262. return(LICENSE_STATUS_INVALID_INPUT);
  3263. }
  3264. pLicenseContext->pTsLicenseInfo->dwSupportFlags = dwSupportFlags;
  3265. return(LICENSE_STATUS_OK);
  3266. }
  3267. /*++
  3268. Function:
  3269. LsStatusToLicenseStatus
  3270. Description:
  3271. Map a license server error code to a LICENSE_STATUS
  3272. --*/
  3273. LICENSE_STATUS
  3274. LsStatusToLicenseStatus(
  3275. DWORD LsStatus,
  3276. DWORD LsStatusDefault
  3277. )
  3278. {
  3279. LICENSE_STATUS LicenseStatus;
  3280. switch (LsStatus)
  3281. {
  3282. case LSERVER_S_SUCCESS:
  3283. LicenseStatus = LICENSE_STATUS_OK;
  3284. break;
  3285. case LSERVER_E_OUTOFMEMORY:
  3286. LicenseStatus = LICENSE_STATUS_OUT_OF_MEMORY;
  3287. break;
  3288. case LSERVER_E_INVALID_DATA:
  3289. LicenseStatus = LICENSE_STATUS_INVALID_INPUT;
  3290. break;
  3291. case LSERVER_E_LS_NOTPRESENT:
  3292. case LSERVER_E_LS_NOTRUNNING:
  3293. LicenseStatus = LICENSE_STATUS_NO_LICENSE_SERVER;
  3294. break;
  3295. case LSERVER_E_NO_LICENSE:
  3296. case LSERVER_E_NO_PRODUCT:
  3297. case LSERVER_E_NO_CERTIFICATE: // not activated
  3298. LicenseStatus = LICENSE_STATUS_NO_LICENSE_ERROR;
  3299. break;
  3300. case LSERVER_E_INTERNAL_ERROR:
  3301. LicenseStatus = LICENSE_STATUS_UNSPECIFIED_ERROR;
  3302. break;
  3303. default:
  3304. LicenseStatus = LsStatusDefault;
  3305. break;
  3306. }
  3307. return LicenseStatus;
  3308. }