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.

1209 lines
30 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. //
  5. // File:
  6. //
  7. // Contents:
  8. //
  9. // History:
  10. //
  11. //---------------------------------------------------------------------------
  12. #include "precomp.h"
  13. #define EXTENDED_ERROR_CAPABILITY 0x80
  14. ///////////////////////////////////////////////////////////////////////////////
  15. VOID
  16. CopyBinaryBlob(
  17. PBYTE pbBuffer,
  18. PBinary_Blob pbbBlob,
  19. DWORD * pdwCount )
  20. {
  21. *pdwCount = 0;
  22. //
  23. // First copy the wBlobType data;
  24. //
  25. memcpy( pbBuffer, &pbbBlob->wBlobType, sizeof( WORD ) );
  26. pbBuffer += sizeof( WORD );
  27. *pdwCount += sizeof( WORD );
  28. //
  29. // Copy the wBlobLen data
  30. //
  31. memcpy( pbBuffer, &pbbBlob->wBlobLen, sizeof( WORD ) );
  32. pbBuffer += sizeof( WORD );
  33. *pdwCount += sizeof( WORD );
  34. if( 0 == pbbBlob->wBlobLen )
  35. {
  36. return;
  37. }
  38. //
  39. // Copy the actual data
  40. //
  41. memcpy( pbBuffer, pbbBlob->pBlob, pbbBlob->wBlobLen );
  42. *pdwCount += pbbBlob->wBlobLen;
  43. }
  44. ///////////////////////////////////////////////////////////////////////////////
  45. LICENSE_STATUS
  46. GetBinaryBlob(
  47. PBinary_Blob pBBlob,
  48. DWORD dwMsgSize,
  49. PBYTE pMessage,
  50. PDWORD pcbProcessed )
  51. {
  52. PBinary_Blob pBB;
  53. LICENSE_STATUS Status;
  54. if(dwMsgSize < 2 * sizeof(WORD))
  55. {
  56. return( LICENSE_STATUS_INVALID_INPUT );
  57. }
  58. pBB = ( PBinary_Blob )pMessage;
  59. pBBlob->wBlobType = pBB->wBlobType;
  60. pBBlob->wBlobLen = pBB->wBlobLen;
  61. pBBlob->pBlob = NULL;
  62. *pcbProcessed = 2 * ( sizeof( WORD ) );
  63. if( 0 == pBBlob->wBlobLen )
  64. {
  65. return( LICENSE_STATUS_OK );
  66. }
  67. if(dwMsgSize < (2 * sizeof(WORD)) + pBB->wBlobLen)
  68. {
  69. return( LICENSE_STATUS_INVALID_INPUT );
  70. }
  71. //
  72. // Check that strings are NULL terminated
  73. //
  74. switch (pBB->wBlobType)
  75. {
  76. case BB_CLIENT_USER_NAME_BLOB:
  77. case BB_CLIENT_MACHINE_NAME_BLOB:
  78. if ('\0' != pMessage[(2 * sizeof(WORD)) + (pBB->wBlobLen) - 1])
  79. {
  80. __try
  81. {
  82. //
  83. // Handle bug in old client, where length is off by one
  84. //
  85. if ('\0' == pMessage[(2 * sizeof(WORD)) + pBB->wBlobLen])
  86. {
  87. pBBlob->wBlobLen++;
  88. break;
  89. }
  90. }
  91. __except( EXCEPTION_EXECUTE_HANDLER )
  92. {
  93. return( LICENSE_STATUS_INVALID_INPUT );
  94. }
  95. //
  96. // Handle WTB client bug - send wrong data size.
  97. // At this stage of licensing, we don't really care about
  98. // client's machine and user name
  99. //
  100. pMessage[(2 * sizeof(WORD)) + (pBB->wBlobLen) - 1] = '\0';
  101. if(!(pBB->wBlobLen & 0x01))
  102. {
  103. //
  104. // Even length, assuming UNICODE, wBlobLen must > 1 to
  105. // come to here
  106. //
  107. pMessage[(2 * sizeof(WORD)) + (pBB->wBlobLen) - 2] = '\0';
  108. }
  109. //return( LICENSE_STATUS_INVALID_INPUT );
  110. }
  111. break;
  112. }
  113. //
  114. // allocate memory for and copy the actual data
  115. //
  116. if( BB_CLIENT_USER_NAME_BLOB == pBB->wBlobType ||
  117. BB_CLIENT_MACHINE_NAME_BLOB == pBB->wBlobType )
  118. {
  119. // WINCE client sends UNICODE, add extra NULL at the end
  120. Status = LicenseMemoryAllocate( ( DWORD )pBBlob->wBlobLen + sizeof(WCHAR), &(pBBlob->pBlob) );
  121. }
  122. else
  123. {
  124. Status = LicenseMemoryAllocate( ( DWORD )pBBlob->wBlobLen, &(pBBlob->pBlob) );
  125. }
  126. if( LICENSE_STATUS_OK != Status )
  127. {
  128. return( Status );
  129. }
  130. __try
  131. {
  132. memcpy( pBBlob->pBlob, pMessage + ( 2 * sizeof( WORD ) ), pBBlob->wBlobLen );
  133. }
  134. __except( EXCEPTION_EXECUTE_HANDLER )
  135. {
  136. LicenseMemoryFree( &pBBlob->pBlob );
  137. return( LICENSE_STATUS_INVALID_INPUT );
  138. }
  139. *pcbProcessed += ( DWORD )pBBlob->wBlobLen;
  140. return( LICENSE_STATUS_OK );
  141. }
  142. ///////////////////////////////////////////////////////////////////////////////
  143. VOID
  144. FreeBinaryBlob(
  145. PBinary_Blob pBlob )
  146. {
  147. if( pBlob->pBlob )
  148. {
  149. LicenseMemoryFree( &pBlob->pBlob );
  150. pBlob->wBlobLen = 0;
  151. }
  152. return;
  153. }
  154. ///////////////////////////////////////////////////////////////////////////////
  155. LICENSE_STATUS
  156. PackHydraServerLicenseRequest(
  157. DWORD dwProtocolVersion,
  158. PHydra_Server_License_Request pCanonical,
  159. PBYTE* ppNetwork,
  160. DWORD* pcbNetwork )
  161. {
  162. Preamble Header;
  163. DWORD i, cbCopied;
  164. PBinary_Blob pBlob;
  165. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  166. PBYTE pNetworkBuf;
  167. ASSERT( pCanonical );
  168. if( ( NULL == pCanonical ) ||
  169. ( NULL == pcbNetwork ) ||
  170. ( NULL == ppNetwork ) )
  171. {
  172. return( LICENSE_STATUS_INVALID_INPUT );
  173. }
  174. //
  175. // calculate the size needed for network format
  176. //
  177. Header.wMsgSize = (WORD)(sizeof( Preamble ) +
  178. LICENSE_RANDOM +
  179. sizeof( DWORD ) +
  180. sizeof( DWORD ) + pCanonical->ProductInfo.cbCompanyName +
  181. sizeof( DWORD ) + pCanonical->ProductInfo.cbProductID +
  182. GetBinaryBlobSize( pCanonical->KeyExchngList ) +
  183. GetBinaryBlobSize( pCanonical->ServerCert ) +
  184. sizeof( DWORD ) +
  185. ( pCanonical->ScopeList.dwScopeCount * ( sizeof( WORD ) + sizeof( WORD ) ) ) );
  186. for( i = 0, pBlob = pCanonical->ScopeList.Scopes;
  187. i < pCanonical->ScopeList.dwScopeCount;
  188. i++ )
  189. {
  190. Header.wMsgSize += pBlob->wBlobLen;
  191. pBlob++;
  192. }
  193. //
  194. // allocate the output buffer
  195. //
  196. Status = LicenseMemoryAllocate( Header.wMsgSize, ppNetwork );
  197. if( LICENSE_STATUS_OK != Status )
  198. {
  199. goto PackError;
  200. }
  201. *pcbNetwork = Header.wMsgSize;
  202. pNetworkBuf = *ppNetwork;
  203. //
  204. // copy the header
  205. //
  206. Header.bMsgType = HS_LICENSE_REQUEST;
  207. Header.bVersion = GET_PREAMBLE_VERSION( dwProtocolVersion );
  208. memcpy( pNetworkBuf, &Header, sizeof( Preamble ) );
  209. pNetworkBuf += sizeof( Preamble );
  210. //
  211. // copy the server random number
  212. //
  213. memcpy( pNetworkBuf, pCanonical->ServerRandom, LICENSE_RANDOM );
  214. pNetworkBuf += LICENSE_RANDOM;
  215. //
  216. // copy the product info
  217. //
  218. memcpy( pNetworkBuf, &pCanonical->ProductInfo.dwVersion, sizeof( DWORD ) );
  219. pNetworkBuf += sizeof( DWORD );
  220. memcpy( pNetworkBuf, &pCanonical->ProductInfo.cbCompanyName, sizeof( DWORD ) );
  221. pNetworkBuf += sizeof( DWORD );
  222. memcpy( pNetworkBuf, pCanonical->ProductInfo.pbCompanyName,
  223. pCanonical->ProductInfo.cbCompanyName );
  224. pNetworkBuf += pCanonical->ProductInfo.cbCompanyName;
  225. memcpy( pNetworkBuf, &pCanonical->ProductInfo.cbProductID, sizeof( DWORD ) );
  226. pNetworkBuf += sizeof( DWORD );
  227. memcpy( pNetworkBuf, pCanonical->ProductInfo.pbProductID,
  228. pCanonical->ProductInfo.cbProductID );
  229. pNetworkBuf += pCanonical->ProductInfo.cbProductID;
  230. //
  231. // copy the key exchange list
  232. //
  233. CopyBinaryBlob( pNetworkBuf, &pCanonical->KeyExchngList, &cbCopied );
  234. pNetworkBuf += cbCopied;
  235. //
  236. // copy the hydra server certificate
  237. //
  238. CopyBinaryBlob( pNetworkBuf, &pCanonical->ServerCert, &cbCopied );
  239. pNetworkBuf += cbCopied;
  240. //
  241. // copy the scope list
  242. //
  243. memcpy( pNetworkBuf, &pCanonical->ScopeList.dwScopeCount, sizeof( DWORD ) );
  244. pNetworkBuf += sizeof( DWORD );
  245. for( i = 0, pBlob = pCanonical->ScopeList.Scopes;
  246. i < pCanonical->ScopeList.dwScopeCount;
  247. i++ )
  248. {
  249. CopyBinaryBlob( pNetworkBuf, pBlob, &cbCopied );
  250. pNetworkBuf += cbCopied;
  251. pBlob++;
  252. }
  253. PackError:
  254. return( Status );
  255. }
  256. ///////////////////////////////////////////////////////////////////////////////
  257. LICENSE_STATUS
  258. PackHydraServerPlatformChallenge(
  259. DWORD dwProtocolVersion,
  260. PHydra_Server_Platform_Challenge pCanonical,
  261. PBYTE* ppNetwork,
  262. DWORD* pcbNetwork )
  263. {
  264. Preamble Header;
  265. DWORD cbCopied;
  266. PBinary_Blob pBlob;
  267. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  268. PBYTE pNetworkBuf;
  269. ASSERT( pCanonical );
  270. ASSERT( pcbNetwork );
  271. ASSERT( ppNetwork );
  272. if( ( NULL == pCanonical ) ||
  273. ( NULL == pcbNetwork ) ||
  274. ( NULL == ppNetwork ) )
  275. {
  276. return( LICENSE_STATUS_INVALID_INPUT );
  277. }
  278. //
  279. // calculate the buffer size needed
  280. //
  281. Header.wMsgSize = sizeof( Preamble ) +
  282. sizeof( DWORD ) +
  283. GetBinaryBlobSize( pCanonical->EncryptedPlatformChallenge ) +
  284. LICENSE_MAC_DATA;
  285. //
  286. // allocate the output buffer
  287. //
  288. Status = LicenseMemoryAllocate( Header.wMsgSize, ppNetwork );
  289. if( LICENSE_STATUS_OK != Status )
  290. {
  291. goto PackError;
  292. }
  293. *pcbNetwork = Header.wMsgSize;
  294. pNetworkBuf = *ppNetwork;
  295. //
  296. // copy the header
  297. //
  298. Header.bMsgType = HS_PLATFORM_CHALLENGE;
  299. Header.bVersion = GET_PREAMBLE_VERSION( dwProtocolVersion );
  300. memcpy( pNetworkBuf, &Header, sizeof( Preamble ) );
  301. pNetworkBuf += sizeof( Preamble );
  302. //
  303. // copy the connect flag
  304. //
  305. memcpy( pNetworkBuf, &pCanonical->dwConnectFlags, sizeof( DWORD ) );
  306. pNetworkBuf += sizeof( DWORD );
  307. //
  308. // copy the encrypted platform challenge
  309. //
  310. CopyBinaryBlob( pNetworkBuf, &pCanonical->EncryptedPlatformChallenge, &cbCopied );
  311. pNetworkBuf += cbCopied;
  312. //
  313. // copy the MAC
  314. //
  315. memcpy( pNetworkBuf, pCanonical->MACData, LICENSE_MAC_DATA );
  316. PackError:
  317. return( Status );
  318. }
  319. ///////////////////////////////////////////////////////////////////////////////
  320. LICENSE_STATUS
  321. PackHydraServerNewLicense(
  322. DWORD dwProtocolVersion,
  323. PHydra_Server_New_License pCanonical,
  324. PBYTE* ppNetwork,
  325. DWORD* pcbNetwork )
  326. {
  327. Preamble Header;
  328. DWORD cbCopied;
  329. PBinary_Blob pBlob;
  330. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  331. PBYTE pNetworkBuf;
  332. ASSERT( pCanonical );
  333. ASSERT( pcbNetwork );
  334. ASSERT( ppNetwork );
  335. if( ( NULL == pCanonical ) ||
  336. ( NULL == pcbNetwork ) ||
  337. ( NULL == ppNetwork ) )
  338. {
  339. return( LICENSE_STATUS_INVALID_INPUT );
  340. }
  341. //
  342. // calculate the buffer size needed
  343. //
  344. Header.wMsgSize = sizeof( Preamble ) +
  345. GetBinaryBlobSize( pCanonical->EncryptedNewLicenseInfo ) +
  346. LICENSE_MAC_DATA;
  347. //
  348. // allocate the output buffer
  349. //
  350. Status = LicenseMemoryAllocate( Header.wMsgSize, ppNetwork );
  351. if( LICENSE_STATUS_OK != Status )
  352. {
  353. goto PackError;
  354. }
  355. *pcbNetwork = Header.wMsgSize;
  356. pNetworkBuf = *ppNetwork;
  357. //
  358. // copy the header
  359. //
  360. Header.bMsgType = HS_NEW_LICENSE;
  361. Header.bVersion = GET_PREAMBLE_VERSION( dwProtocolVersion );
  362. memcpy( pNetworkBuf, &Header, sizeof( Preamble ) );
  363. pNetworkBuf += sizeof( Preamble );
  364. //
  365. // copy the encrypted new license info
  366. //
  367. CopyBinaryBlob( pNetworkBuf, &pCanonical->EncryptedNewLicenseInfo, &cbCopied );
  368. pNetworkBuf += cbCopied;
  369. //
  370. // copy the MAC
  371. //
  372. memcpy( pNetworkBuf, pCanonical->MACData, LICENSE_MAC_DATA );
  373. PackError:
  374. return( Status );
  375. }
  376. ///////////////////////////////////////////////////////////////////////////////
  377. LICENSE_STATUS
  378. PackHydraServerUpgradeLicense(
  379. DWORD dwProtocolVersion,
  380. PHydra_Server_Upgrade_License pCanonical,
  381. PBYTE* ppNetwork,
  382. DWORD* pcbNetwork )
  383. {
  384. LICENSE_STATUS Status;
  385. PPreamble pHeader;
  386. Status = PackHydraServerNewLicense( dwProtocolVersion, pCanonical, ppNetwork, pcbNetwork );
  387. if( LICENSE_STATUS_OK == Status )
  388. {
  389. //
  390. // make this an upgrade license message
  391. //
  392. pHeader = ( PPreamble )*ppNetwork;
  393. pHeader->bMsgType = HS_UPGRADE_LICENSE;
  394. }
  395. return( Status );
  396. }
  397. ///////////////////////////////////////////////////////////////////////////////
  398. LICENSE_STATUS
  399. PackHydraServerErrorMessage(
  400. DWORD dwProtocolVersion,
  401. PLicense_Error_Message pCanonical,
  402. PBYTE* ppNetwork,
  403. DWORD* pcbNetwork )
  404. {
  405. Preamble Header;
  406. DWORD cbCopied;
  407. PBinary_Blob pBlob;
  408. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  409. PBYTE pNetworkBuf;
  410. ASSERT( pCanonical );
  411. ASSERT( pcbNetwork );
  412. ASSERT( ppNetwork );
  413. if( ( NULL == pCanonical ) ||
  414. ( NULL == pcbNetwork ) ||
  415. ( NULL == ppNetwork ) )
  416. {
  417. return( LICENSE_STATUS_INVALID_INPUT );
  418. }
  419. //
  420. // calculate the buffer size needed
  421. //
  422. Header.wMsgSize = sizeof( Preamble ) +
  423. sizeof( DWORD ) +
  424. sizeof( DWORD ) +
  425. GetBinaryBlobSize( pCanonical->bbErrorInfo );
  426. //
  427. // allocate the output buffer
  428. //
  429. Status = LicenseMemoryAllocate( Header.wMsgSize, ppNetwork );
  430. if( LICENSE_STATUS_OK != Status )
  431. {
  432. goto PackError;
  433. }
  434. *pcbNetwork = Header.wMsgSize;
  435. pNetworkBuf = *ppNetwork;
  436. //
  437. // set up preamble
  438. //
  439. Header.bMsgType = GM_ERROR_ALERT;
  440. Header.bVersion = GET_PREAMBLE_VERSION( dwProtocolVersion );
  441. memcpy( pNetworkBuf, &Header, sizeof( Preamble ) );
  442. pNetworkBuf += sizeof( Preamble );
  443. //
  444. // copy the error code, state transition and error info
  445. //
  446. memcpy( pNetworkBuf, &pCanonical->dwErrorCode, sizeof( DWORD ) );
  447. pNetworkBuf += sizeof( DWORD );
  448. memcpy( pNetworkBuf, &pCanonical->dwStateTransition, sizeof( DWORD ) );
  449. pNetworkBuf += sizeof( DWORD );
  450. CopyBinaryBlob( pNetworkBuf, &pCanonical->bbErrorInfo, &cbCopied );
  451. PackError:
  452. return( Status );
  453. }
  454. ///////////////////////////////////////////////////////////////////////////////
  455. LICENSE_STATUS
  456. PackNewLicenseInfo(
  457. PNew_License_Info pCanonical,
  458. PBYTE* ppNetwork,
  459. DWORD* pcbNetwork )
  460. {
  461. DWORD cbBufNeeded;
  462. PBYTE pNetworkBuf;
  463. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  464. ASSERT( pCanonical );
  465. ASSERT( pcbNetwork );
  466. ASSERT( ppNetwork );
  467. if( ( NULL == pCanonical ) ||
  468. ( NULL == pcbNetwork ) ||
  469. ( NULL == ppNetwork ) )
  470. {
  471. return( LICENSE_STATUS_INVALID_INPUT );
  472. }
  473. //
  474. // calculate the buffer size needed and check that the output
  475. // buffer is large enough
  476. //
  477. cbBufNeeded = 5 * sizeof( DWORD ) +
  478. pCanonical->cbScope +
  479. pCanonical->cbCompanyName +
  480. pCanonical->cbProductID +
  481. pCanonical->cbLicenseInfo;
  482. //
  483. // allocate the output buffer
  484. //
  485. Status = LicenseMemoryAllocate( cbBufNeeded, ppNetwork );
  486. if( LICENSE_STATUS_OK != Status )
  487. {
  488. goto done;
  489. }
  490. *pcbNetwork = cbBufNeeded;
  491. pNetworkBuf = *ppNetwork;
  492. //
  493. // start copying the data
  494. //
  495. memcpy( pNetworkBuf, &pCanonical->dwVersion, sizeof( DWORD ) );
  496. pNetworkBuf += sizeof( DWORD );
  497. memcpy( pNetworkBuf, &pCanonical->cbScope, sizeof( DWORD ) );
  498. pNetworkBuf += sizeof( DWORD );
  499. memcpy( pNetworkBuf, pCanonical->pbScope, pCanonical->cbScope );
  500. pNetworkBuf += pCanonical->cbScope;
  501. memcpy( pNetworkBuf, &pCanonical->cbCompanyName, sizeof( DWORD ) );
  502. pNetworkBuf += sizeof( DWORD );
  503. memcpy( pNetworkBuf, pCanonical->pbCompanyName, pCanonical->cbCompanyName );
  504. pNetworkBuf += pCanonical->cbCompanyName;
  505. memcpy( pNetworkBuf, &pCanonical->cbProductID, sizeof( DWORD ) );
  506. pNetworkBuf += sizeof( DWORD );
  507. memcpy( pNetworkBuf, pCanonical->pbProductID, pCanonical->cbProductID );
  508. pNetworkBuf += pCanonical->cbProductID;
  509. memcpy( pNetworkBuf, &pCanonical->cbLicenseInfo, sizeof( DWORD ) );
  510. pNetworkBuf += sizeof( DWORD );
  511. memcpy( pNetworkBuf, pCanonical->pbLicenseInfo, pCanonical->cbLicenseInfo );
  512. pNetworkBuf += pCanonical->cbLicenseInfo;
  513. done:
  514. return( Status );
  515. }
  516. ///////////////////////////////////////////////////////////////////////////////
  517. LICENSE_STATUS
  518. PackExtendedErrorInfo(
  519. UINT32 uiExtendedErrorInfo,
  520. Binary_Blob *pbbErrorInfo)
  521. {
  522. WORD cbBufNeeded;
  523. PBYTE pbNetworkBuf;
  524. WORD wBlobVersion = BB_ERROR_BLOB_VERSION;
  525. WORD wBlobReserved = 0;
  526. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  527. if (NULL == pbbErrorInfo)
  528. {
  529. return( LICENSE_STATUS_INVALID_INPUT );
  530. }
  531. //
  532. // Initialize in case of errors
  533. //
  534. pbbErrorInfo->wBlobLen = 0;
  535. //
  536. // calculate the buffer size needed
  537. //
  538. cbBufNeeded = sizeof(WORD) + sizeof(WORD) + sizeof(UINT32);
  539. //
  540. // allocate the output buffer
  541. //
  542. Status = LicenseMemoryAllocate( cbBufNeeded, &(pbbErrorInfo->pBlob) );
  543. if( LICENSE_STATUS_OK != Status )
  544. {
  545. goto done;
  546. }
  547. pbbErrorInfo->wBlobLen = cbBufNeeded;
  548. pbNetworkBuf = pbbErrorInfo->pBlob;
  549. //
  550. // start copying the data
  551. //
  552. memcpy( pbNetworkBuf, &wBlobVersion, sizeof( WORD ) );
  553. pbNetworkBuf += sizeof( WORD );
  554. memcpy( pbNetworkBuf, &wBlobReserved, sizeof( WORD ) );
  555. pbNetworkBuf += sizeof( WORD );
  556. memcpy( pbNetworkBuf, &uiExtendedErrorInfo, sizeof( UINT32 ) );
  557. done:
  558. return ( Status );
  559. }
  560. ///////////////////////////////////////////////////////////////////////////////
  561. // Functions for unpacking different Hydra Client Messages from
  562. // simple binary blobs to corresponding structure
  563. //
  564. ///////////////////////////////////////////////////////////////////////////////
  565. LICENSE_STATUS
  566. UnPackHydraClientErrorMessage(
  567. PBYTE pbMessage,
  568. DWORD cbMessage,
  569. PLicense_Error_Message pCanonical,
  570. BOOL* pfExtendedError)
  571. {
  572. DWORD cbUnpacked = 0;
  573. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  574. PPreamble pHeader;
  575. PBYTE pNetwork;
  576. DWORD cbProcessed = 0, cbRemainder;
  577. //
  578. // check the input parameters
  579. //
  580. ASSERT( NULL != pbMessage );
  581. ASSERT( 0 < cbMessage );
  582. ASSERT( NULL != pCanonical );
  583. ASSERT( NULL != pfExtendedError );
  584. if( ( NULL == pbMessage ) ||
  585. ( 0 >= cbMessage ) ||
  586. ( NULL == pCanonical ) ||
  587. ( pfExtendedError == NULL))
  588. {
  589. return( LICENSE_STATUS_INVALID_INPUT );
  590. }
  591. *pfExtendedError = FALSE;
  592. //
  593. // check the preamble
  594. //
  595. pHeader = ( PPreamble )pbMessage;
  596. if( GM_ERROR_ALERT != pHeader->bMsgType )
  597. {
  598. #if DBG
  599. DbgPrint( "UnPackHydraClientErrorMessage: received unexpected message type %c\n", pHeader->bMsgType );
  600. #endif
  601. return( LICENSE_STATUS_INVALID_RESPONSE );
  602. }
  603. if(pHeader->bVersion & EXTENDED_ERROR_CAPABILITY)
  604. {
  605. *pfExtendedError = TRUE;
  606. }
  607. //
  608. // do a calculation of the fixed field length
  609. //
  610. cbUnpacked = sizeof( Preamble ) + 2 * sizeof( DWORD );
  611. if( cbMessage < ( WORD )cbUnpacked )
  612. {
  613. return( LICENSE_STATUS_INVALID_INPUT );
  614. }
  615. cbRemainder = cbMessage - cbUnpacked;
  616. //
  617. // get the license error structure
  618. //
  619. pNetwork = pbMessage + sizeof( Preamble );
  620. memcpy( &pCanonical->dwErrorCode, pNetwork, sizeof( DWORD ) );
  621. pNetwork += sizeof( DWORD );
  622. memcpy( &pCanonical->dwStateTransition, pNetwork, sizeof( DWORD ) );
  623. pNetwork += sizeof( DWORD );
  624. Status = GetBinaryBlob( &( pCanonical->bbErrorInfo ), cbRemainder, pNetwork, &cbProcessed );
  625. if( LICENSE_STATUS_OK != Status )
  626. {
  627. return( Status );
  628. }
  629. cbUnpacked += cbProcessed;
  630. ASSERT( pHeader->wMsgSize == ( WORD )cbUnpacked );
  631. return( Status );
  632. }
  633. ///////////////////////////////////////////////////////////////////////////////
  634. LICENSE_STATUS
  635. UnPackHydraClientLicenseInfo(
  636. PBYTE pbMessage,
  637. DWORD cbMessage,
  638. PHydra_Client_License_Info pCanonical,
  639. BOOL* pfExtendedError)
  640. {
  641. DWORD cbUnpacked = 0;
  642. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  643. PPreamble pHeader;
  644. PBYTE pNetwork;
  645. DWORD cbProcessed = 0, cbRemainder = 0;
  646. //
  647. // check the input parameters
  648. //
  649. ASSERT( NULL != pbMessage );
  650. ASSERT( 0 < cbMessage );
  651. ASSERT( NULL != pCanonical );
  652. ASSERT( NULL != pfExtendedError );
  653. if( ( NULL == pbMessage ) ||
  654. ( 0 >= cbMessage ) ||
  655. ( NULL == pCanonical ) ||
  656. ( NULL == pfExtendedError))
  657. {
  658. return( LICENSE_STATUS_INVALID_INPUT );
  659. }
  660. *pfExtendedError = FALSE;
  661. //
  662. // check the preamble
  663. //
  664. pHeader = ( PPreamble )pbMessage;
  665. if( HC_LICENSE_INFO != pHeader->bMsgType )
  666. {
  667. #if DBG
  668. DbgPrint( "UnPackHydraClientLicenseInfo: received unexpected message type %c\n", pHeader->bMsgType );
  669. #endif
  670. return( LICENSE_STATUS_INVALID_RESPONSE );
  671. }
  672. if(pHeader->bVersion & EXTENDED_ERROR_CAPABILITY)
  673. {
  674. *pfExtendedError = TRUE;
  675. }
  676. //
  677. // do a calculation of the fixed field length
  678. //
  679. cbUnpacked = sizeof( Preamble ) +
  680. 2 * sizeof( DWORD ) +
  681. LICENSE_RANDOM +
  682. LICENSE_MAC_DATA;
  683. cbRemainder = cbMessage - cbUnpacked;
  684. if( cbMessage < ( WORD )cbUnpacked )
  685. {
  686. return( LICENSE_STATUS_INVALID_INPUT );
  687. }
  688. //
  689. // get the license info structure
  690. //
  691. pNetwork = pbMessage + sizeof( Preamble );
  692. memcpy( &pCanonical->dwPrefKeyExchangeAlg, pNetwork, sizeof( DWORD ) );
  693. pNetwork += sizeof( DWORD );
  694. memcpy( &pCanonical->dwPlatformID, pNetwork, sizeof( DWORD ) );
  695. pNetwork += sizeof( DWORD );
  696. memcpy( &pCanonical->ClientRandom, pNetwork, LICENSE_RANDOM );
  697. pNetwork += LICENSE_RANDOM;
  698. Status = GetBinaryBlob( &pCanonical->EncryptedPreMasterSecret, cbRemainder, pNetwork, &cbProcessed );
  699. if( LICENSE_STATUS_OK != Status )
  700. {
  701. if (Status == LICENSE_STATUS_INVALID_INPUT)
  702. {
  703. Status = LICENSE_STATUS_INVALID_RESPONSE;
  704. }
  705. return( Status );
  706. }
  707. pNetwork += cbProcessed;
  708. cbUnpacked += cbProcessed;
  709. cbRemainder = cbMessage - cbUnpacked;
  710. Status = GetBinaryBlob( &pCanonical->LicenseInfo, cbRemainder, pNetwork, &cbProcessed );
  711. if( LICENSE_STATUS_OK != Status )
  712. {
  713. if (Status == LICENSE_STATUS_INVALID_INPUT)
  714. {
  715. Status = LICENSE_STATUS_INVALID_RESPONSE;
  716. }
  717. return( Status );
  718. }
  719. pNetwork += cbProcessed;
  720. cbUnpacked += cbProcessed;
  721. cbRemainder = cbMessage- cbUnpacked;
  722. Status = GetBinaryBlob( &pCanonical->EncryptedHWID, cbRemainder, pNetwork, &cbProcessed );
  723. if( LICENSE_STATUS_OK != Status )
  724. {
  725. if (Status == LICENSE_STATUS_INVALID_INPUT)
  726. {
  727. Status = LICENSE_STATUS_INVALID_RESPONSE;
  728. }
  729. return( Status );
  730. }
  731. pNetwork += cbProcessed;
  732. cbUnpacked += cbProcessed;
  733. memcpy( pCanonical->MACData, pNetwork, LICENSE_MAC_DATA );
  734. ASSERT( pHeader->wMsgSize == ( WORD )cbUnpacked );
  735. return( Status );
  736. }
  737. ///////////////////////////////////////////////////////////////////////////////
  738. LICENSE_STATUS
  739. UnPackHydraClientNewLicenseRequest(
  740. PBYTE pbMessage,
  741. DWORD cbMessage,
  742. PHydra_Client_New_License_Request pCanonical,
  743. BOOL* pfExtendedError)
  744. {
  745. DWORD cbUnpacked = 0;
  746. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  747. PPreamble pHeader;
  748. PBYTE pNetwork;
  749. DWORD cbProcessed = 0, cbRemainder = 0;
  750. //
  751. // check the input parameters
  752. //
  753. ASSERT( NULL != pbMessage );
  754. ASSERT( 0 < cbMessage );
  755. ASSERT( NULL != pCanonical );
  756. ASSERT( NULL != pfExtendedError );
  757. if( ( NULL == pbMessage ) ||
  758. ( 0 >= cbMessage ) ||
  759. ( NULL == pCanonical ) ||
  760. ( NULL == pfExtendedError))
  761. {
  762. return( LICENSE_STATUS_INVALID_INPUT );
  763. }
  764. *pfExtendedError = FALSE;
  765. //
  766. // check the preamble
  767. //
  768. pHeader = ( PPreamble )pbMessage;
  769. if( HC_NEW_LICENSE_REQUEST != pHeader->bMsgType )
  770. {
  771. #if DBG
  772. DbgPrint( "UnPackHydraClientNewLicenseRequest: received unexpected message type %c\n", pHeader->bMsgType );
  773. #endif
  774. return( LICENSE_STATUS_INVALID_RESPONSE );
  775. }
  776. if(pHeader->bVersion & EXTENDED_ERROR_CAPABILITY)
  777. {
  778. *pfExtendedError = TRUE;
  779. }
  780. //
  781. // do a calculation of the fixed field length
  782. //
  783. cbUnpacked = sizeof( Preamble ) +
  784. 2 * sizeof( DWORD ) +
  785. LICENSE_RANDOM;
  786. cbRemainder = cbMessage - cbUnpacked;
  787. if( cbMessage < ( WORD )cbUnpacked )
  788. {
  789. return( LICENSE_STATUS_INVALID_INPUT );
  790. }
  791. //
  792. // get the new license request structure
  793. //
  794. pNetwork = pbMessage + sizeof( Preamble );
  795. memcpy( &pCanonical->dwPrefKeyExchangeAlg, pNetwork, sizeof( DWORD ) );
  796. pNetwork += sizeof( DWORD );
  797. memcpy( &pCanonical->dwPlatformID, pNetwork, sizeof( DWORD ) );
  798. pNetwork += sizeof( DWORD );
  799. memcpy( &pCanonical->ClientRandom, pNetwork, LICENSE_RANDOM );
  800. pNetwork += LICENSE_RANDOM;
  801. Status = GetBinaryBlob( &pCanonical->EncryptedPreMasterSecret, cbRemainder, pNetwork, &cbProcessed );
  802. if( LICENSE_STATUS_OK != Status )
  803. {
  804. return( Status );
  805. }
  806. cbUnpacked += cbProcessed;
  807. pNetwork += cbProcessed;
  808. cbRemainder = cbMessage - cbUnpacked;
  809. //
  810. // we changed the licensing protocol to include the client user and machine
  811. // name. So to prevent an older client that does not have the user and machine
  812. // name binary blobs from crashing the server, we add this check for the
  813. // message length.
  814. //
  815. if( pHeader->wMsgSize <= cbUnpacked )
  816. {
  817. #if DBG
  818. DbgPrint( "UnPackHydraClientNewLicenseRequest: old licensing protocol\n" );
  819. #endif
  820. pCanonical->ClientUserName.pBlob = NULL;
  821. pCanonical->ClientMachineName.pBlob = NULL;
  822. //
  823. // make these 2 fields optional for now.
  824. //
  825. return( Status );
  826. }
  827. Status = GetBinaryBlob( &pCanonical->ClientUserName, cbRemainder, pNetwork, &cbProcessed );
  828. if( LICENSE_STATUS_OK != Status )
  829. {
  830. return( Status );
  831. }
  832. cbUnpacked += cbProcessed;
  833. pNetwork += cbProcessed;
  834. cbRemainder = cbMessage - cbUnpacked;
  835. Status = GetBinaryBlob( &pCanonical->ClientMachineName, cbRemainder, pNetwork, &cbProcessed );
  836. if( LICENSE_STATUS_OK != Status )
  837. {
  838. return( Status );
  839. }
  840. cbUnpacked += cbProcessed;
  841. ASSERT( pHeader->wMsgSize == ( WORD )cbUnpacked );
  842. return( Status );
  843. }
  844. ///////////////////////////////////////////////////////////////////////////////
  845. LICENSE_STATUS
  846. UnPackHydraClientPlatformChallengeResponse(
  847. PBYTE pbMessage,
  848. DWORD cbMessage,
  849. PHydra_Client_Platform_Challenge_Response pCanonical,
  850. BOOL* pfExtendedError)
  851. {
  852. DWORD cbUnpacked = 0;
  853. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  854. PPreamble pHeader;
  855. PBYTE pNetwork;
  856. DWORD cbProcessed = 0, cbRemainder = 0;
  857. //
  858. // check the input parameters
  859. //
  860. ASSERT( NULL != pbMessage );
  861. ASSERT( 0 < cbMessage );
  862. ASSERT( NULL != pCanonical );
  863. ASSERT( NULL != pfExtendedError );
  864. if( ( NULL == pbMessage ) ||
  865. ( 0 >= cbMessage ) ||
  866. ( NULL == pCanonical ) ||
  867. ( NULL == pfExtendedError ))
  868. {
  869. return( LICENSE_STATUS_INVALID_INPUT );
  870. }
  871. *pfExtendedError = FALSE;
  872. //
  873. // check the preamble
  874. //
  875. pHeader = ( PPreamble )pbMessage;
  876. if( HC_PLATFORM_CHALENGE_RESPONSE != pHeader->bMsgType )
  877. {
  878. #if DBG
  879. DbgPrint( "UnPackHydraClientPlatformChallengeResponse: received unexpected message type %c\n", pHeader->bMsgType );
  880. #endif
  881. return( LICENSE_STATUS_INVALID_RESPONSE );
  882. }
  883. if(pHeader->bVersion & EXTENDED_ERROR_CAPABILITY)
  884. {
  885. *pfExtendedError = TRUE;
  886. }
  887. //
  888. // do a calculation of the fixed field length
  889. //
  890. cbUnpacked = sizeof( Preamble ) +
  891. LICENSE_MAC_DATA;
  892. cbRemainder = cbMessage - cbUnpacked;
  893. if( cbMessage < ( WORD )cbUnpacked )
  894. {
  895. return( LICENSE_STATUS_INVALID_INPUT );
  896. }
  897. //
  898. // get the platform challenge response structure
  899. //
  900. pNetwork = pbMessage + sizeof( Preamble );
  901. Status = GetBinaryBlob( &pCanonical->EncryptedChallengeResponse, cbRemainder, pNetwork, &cbProcessed );
  902. if( LICENSE_STATUS_OK != Status )
  903. {
  904. return( Status );
  905. }
  906. pNetwork += cbProcessed;
  907. cbUnpacked += cbProcessed;
  908. cbRemainder = cbMessage - cbUnpacked;
  909. Status = GetBinaryBlob( &pCanonical->EncryptedHWID, cbRemainder, pNetwork, &cbProcessed );
  910. if( LICENSE_STATUS_OK != Status )
  911. {
  912. return( Status );
  913. }
  914. pNetwork += cbProcessed;
  915. cbUnpacked += cbProcessed;
  916. memcpy( pCanonical->MACData, pNetwork, LICENSE_MAC_DATA );
  917. ASSERT( pHeader->wMsgSize == ( WORD )cbUnpacked );
  918. return( Status );
  919. }