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.

755 lines
34 KiB

  1. /****************************************************************************/
  2. /* asmcpp.cpp */
  3. /* */
  4. /* Security Manager C++ functions */
  5. /* */
  6. /* Copyright (C) 1997-1999 Microsoft Corporation */
  7. /****************************************************************************/
  8. #include <precomp.h>
  9. #pragma hdrstop
  10. #define TRC_FILE "asmcpp"
  11. #define pTRCWd (pRealSMHandle->pWDHandle)
  12. #include <adcg.h>
  13. #include <as_conf.hpp>
  14. extern "C"
  15. {
  16. #include <asmint.h>
  17. #include <slicense.h>
  18. }
  19. #define DC_INCLUDE_DATA
  20. #include <asmdata.c>
  21. #undef DC_INCLUDE_DATA
  22. /****************************************************************************/
  23. /* Name: SM_Register */
  24. /* */
  25. /* Purpose: Register with SM */
  26. /* */
  27. /* Returns: TRUE - registered OK */
  28. /* FALSE - register failed */
  29. /* */
  30. /* Params: pSMHandle - SM handle */
  31. /* pMaxPDUSize - max PDU size supported (returned) */
  32. /* pUserID - this person's user ID (returned) */
  33. /* */
  34. /* Operation: This function enables the Share Class to register with SM. */
  35. /* This allows */
  36. /* - the Share Class to call SM */
  37. /* - SM to issue callbacks to the Share Class (SC_SMCallback). */
  38. /****************************************************************************/
  39. BOOL RDPCALL SM_Register(
  40. PVOID pSMHandle,
  41. PUINT32 pMaxPDUSize,
  42. PUINT32 pUserID)
  43. {
  44. PSM_HANDLE_DATA pRealSMHandle = (PSM_HANDLE_DATA)pSMHandle;
  45. BOOL rc = FALSE;
  46. DC_BEGIN_FN("SM_Register");
  47. // Console stacks do not go through the typical key negotiation, so update
  48. // the state appropriately
  49. if (pRealSMHandle->pWDHandle->StackClass == Stack_Console)
  50. {
  51. TRC_ALT((TB, "Console security state to SM_STATE_SM_CONNECTED"));
  52. SM_SET_STATE(SM_STATE_CONNECTED);
  53. }
  54. //Skip the following CHECK_STATE. For the console reconnect,
  55. // this is a legal transition.
  56. //SM_CHECK_STATE(SM_EVT_REGISTER);
  57. /************************************************************************/
  58. /* Calculate max PDU size allowed to caller */
  59. /************************************************************************/
  60. *pMaxPDUSize = pRealSMHandle->maxPDUSize -
  61. pRealSMHandle->encryptHeaderLen;
  62. TRC_NRM((TB, "Max PDU size allowed to core is %d", *pMaxPDUSize));
  63. /************************************************************************/
  64. /* Return the user ID */
  65. /************************************************************************/
  66. *pUserID = pRealSMHandle->userID;
  67. TRC_NRM((TB, "Returning user id %d", *pUserID));
  68. SM_SET_STATE(SM_STATE_SC_REGISTERED);
  69. pRealSMHandle->bForwardDataToSC = TRUE;
  70. rc = TRUE;
  71. //DC_EXIT_POINT:
  72. DC_END_FN();
  73. return rc;
  74. } /* SM_Register */
  75. /****************************************************************************/
  76. /* Name: SM_OnConnected */
  77. /* */
  78. /* Purpose: Handle connection state change callbacks from NM */
  79. /* */
  80. /* Returns: none */
  81. /* */
  82. /* Params: pRealSMHandle - SM Handle */
  83. /* userID - userID of the node causing the callback */
  84. /* result - result of connection attempt */
  85. /* pUserData - Network (Server-Client) user data */
  86. /* maxPDUSize - max size of PDUs that can be sent */
  87. /****************************************************************************/
  88. void RDPCALL SM_OnConnected(
  89. PVOID pSMHandle,
  90. UINT32 userID,
  91. UINT32 result,
  92. PRNS_UD_SC_NET pUserData,
  93. UINT32 maxPDUSize)
  94. {
  95. PSM_HANDLE_DATA pRealSMHandle = (PSM_HANDLE_DATA)pSMHandle;
  96. DC_BEGIN_FN("SM_OnConnected");
  97. if (result == NM_CB_CONN_OK)
  98. {
  99. TRC_NRM((TB, "Connected OK as user %x", userID));
  100. SM_CHECK_STATE(SM_EVT_CONNECTED);
  101. /********************************************************************/
  102. /* Store useful stuff in SM Handle */
  103. /********************************************************************/
  104. pRealSMHandle->userID = userID;
  105. pRealSMHandle->maxPDUSize = maxPDUSize;
  106. pRealSMHandle->channelID = pUserData->MCSChannelID;
  107. /********************************************************************/
  108. // Pass the result to WDW. For WDW this is the start of the
  109. // connection sequence.
  110. /********************************************************************/
  111. SM_SET_STATE(SM_STATE_SM_CONNECTING);
  112. WDW_OnSMConnecting(pRealSMHandle->pWDHandle, pRealSMHandle->pUserData,
  113. pUserData);
  114. /********************************************************************/
  115. // Free the reply user data once we've passed it to WDW.
  116. /********************************************************************/
  117. if (pRealSMHandle->pUserData != NULL)
  118. {
  119. TRC_NRM((TB, "Free user data"));
  120. COM_Free(pRealSMHandle->pUserData);
  121. pRealSMHandle->pUserData = NULL;
  122. }
  123. }
  124. else
  125. {
  126. TRC_NRM((TB, "Failed to connect, reason %d", result));
  127. /********************************************************************/
  128. // Tell WDW
  129. /********************************************************************/
  130. WDW_OnSMConnected(pRealSMHandle->pWDHandle, result);
  131. /********************************************************************/
  132. /* Clean up */
  133. /********************************************************************/
  134. SM_SET_STATE(SM_STATE_SM_CONNECTING);
  135. SM_Disconnect(pRealSMHandle);
  136. }
  137. DC_EXIT_POINT:
  138. DC_END_FN();
  139. } /* SM_OnConnected */
  140. /****************************************************************************/
  141. /* Name: SM_OnDisconnected */
  142. /* */
  143. /* Purpose: Handle disconnection state change callback from NM */
  144. /* */
  145. /* Params: pRealSMHandle - SM Handle */
  146. /* userID - userID of the node causing the callback */
  147. /* result - reason for the disconnection */
  148. /****************************************************************************/
  149. void RDPCALL SM_OnDisconnected(
  150. PVOID pSMHandle,
  151. UINT32 userID,
  152. UINT32 result)
  153. {
  154. ShareClass *pSC;
  155. PSM_HANDLE_DATA pRealSMHandle = (PSM_HANDLE_DATA)pSMHandle;
  156. DC_BEGIN_FN("SM_OnDisconnected");
  157. SM_CHECK_STATE(SM_EVT_DISCONNECTED);
  158. TRC_NRM((TB, "Disconnected, reason %d", result));
  159. /************************************************************************/
  160. /* First, clear up connection resources */
  161. /************************************************************************/
  162. SMFreeConnectResources(pRealSMHandle);
  163. SM_SET_STATE(SM_STATE_INITIALIZED);
  164. /************************************************************************/
  165. // Tell SC. Don't call if SC is not registered.
  166. /************************************************************************/
  167. if (pRealSMHandle->state == SM_STATE_SC_REGISTERED) {
  168. // Check that the Share Class exists.
  169. pSC = (ShareClass *)(pRealSMHandle->pWDHandle->dcShare);
  170. if (pSC != NULL) {
  171. // Call SC's callback.
  172. pSC->SC_OnDisconnected((UINT16)userID);
  173. }
  174. else {
  175. TRC_ERR((TB, "No Share Class"));
  176. }
  177. }
  178. else {
  179. TRC_ERR((TB, "SC Not registered"));
  180. }
  181. /************************************************************************/
  182. /* Then tell WDW */
  183. /************************************************************************/
  184. WDW_OnSMDisconnected(pRealSMHandle->pWDHandle);
  185. DC_EXIT_POINT:
  186. DC_END_FN();
  187. } /* SM_OnDisconnected */
  188. /****************************************************************************/
  189. // SM_DecodeFastPathInput
  190. //
  191. // Handles decryption of fast-path input data if it's an encrypted packet.
  192. // Then passes directly to IM for bytestream decoding and injection.
  193. /****************************************************************************/
  194. void RDPCALL SM_DecodeFastPathInput(
  195. void *pSM,
  196. BYTE *pData,
  197. unsigned DataLength,
  198. BOOL bEncrypted,
  199. unsigned NumEvents,
  200. BOOL fSafeChecksum)
  201. {
  202. BOOL rc;
  203. PSM_HANDLE_DATA pRealSMHandle = (PSM_HANDLE_DATA)pSM;
  204. ShareClass *pShareClass;
  205. // Used if encypted using FIPS
  206. BYTE *pEncData, *pSigData;
  207. DWORD EncDataLen, dwPadLen;
  208. DC_BEGIN_FN("SM_FastPathInputDecode");
  209. // If we are being attacked or have a bad client, we may receive data
  210. // here before we are really in a conference. If so, ignore it.
  211. // We can't disconnect here because the code to do so requires pWDHandle
  212. // to be valid. If the protocol stream is messed up, the connection will
  213. // be dropped later by other decoding code.
  214. if (pRealSMHandle->pWDHandle != NULL) {
  215. pShareClass = (ShareClass *)pRealSMHandle->pWDHandle->dcShare;
  216. if (pRealSMHandle->encrypting) {
  217. if (bEncrypted) {
  218. //
  219. // Debug verification, we always go with what the protocol header
  220. // says but verify it's consistent with the capabilities
  221. //
  222. if (pRealSMHandle->useSafeChecksumMethod != (fSafeChecksum != 0)) {
  223. TRC_ERR((TB,
  224. "fastpath: fSecureChecksum: 0x%x setting"
  225. "does not match protocol: 0x%x",
  226. pRealSMHandle->useSafeChecksumMethod,
  227. fSafeChecksum));
  228. }
  229. // Make sure we have at least the size of the security context.
  230. if (DataLength >= DATA_SIGNATURE_SIZE) {
  231. // Check to see if we need to update the session key.
  232. if (pRealSMHandle->decryptCount == UPDATE_SESSION_KEY_COUNT) {
  233. rc = TRUE;
  234. // Don't need to update the session key if using FIPS
  235. if (pRealSMHandle->encryptionMethodSelected != SM_FIPS_ENCRYPTION_FLAG) {
  236. rc = UpdateSessionKey(
  237. pRealSMHandle->startDecryptKey,
  238. pRealSMHandle->currentDecryptKey,
  239. pRealSMHandle->encryptionMethodSelected,
  240. pRealSMHandle->keyLength,
  241. &pRealSMHandle->rc4DecryptKey,
  242. pRealSMHandle->encryptionLevel);
  243. }
  244. if (rc) {
  245. // Reset counter.
  246. pRealSMHandle->decryptCount = 0;
  247. }
  248. else {
  249. TRC_ERR((TB,"SM failed to update session key"));
  250. goto FailedKey;
  251. }
  252. }
  253. if (pRealSMHandle->encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  254. if (DataLength < (sizeof(RNS_SECURITY_HEADER2) - sizeof(RNS_SECURITY_HEADER))) {
  255. TRC_ERR((TB,"PDU len %u too short for security context in FIPS decryption",
  256. DataLength));
  257. goto ShortData;
  258. }
  259. pEncData = pData + sizeof(RNS_SECURITY_HEADER2) - sizeof(RNS_SECURITY_HEADER);
  260. pSigData = pEncData - MAX_SIGN_SIZE;
  261. EncDataLen = DataLength - (sizeof(RNS_SECURITY_HEADER2) - sizeof(RNS_SECURITY_HEADER));
  262. dwPadLen = *((TSUINT8 *)(pSigData - sizeof(TSUINT8)));
  263. rc = TSFIPS_DecryptData(
  264. &(pRealSMHandle->FIPSData),
  265. pEncData,
  266. EncDataLen,
  267. dwPadLen,
  268. pSigData,
  269. pRealSMHandle->totalDecryptCount);
  270. }
  271. else {
  272. // Encryption signature sits in first DATA_SIGNATURE_SIZE
  273. // bytes of the provided packet data.
  274. rc = DecryptData(
  275. pRealSMHandle->encryptionLevel,
  276. pRealSMHandle->currentDecryptKey,
  277. &pRealSMHandle->rc4DecryptKey,
  278. pRealSMHandle->keyLength,
  279. pData + DATA_SIGNATURE_SIZE,
  280. DataLength - DATA_SIGNATURE_SIZE,
  281. pRealSMHandle->macSaltKey,
  282. pData,
  283. fSafeChecksum,
  284. pRealSMHandle->totalDecryptCount);
  285. }
  286. if (rc) {
  287. TRC_DBG((TB, "Data decrypted: %u",
  288. DataLength - DATA_SIGNATURE_SIZE));
  289. // Increment decryption counter.
  290. pRealSMHandle->decryptCount++;
  291. pRealSMHandle->totalDecryptCount++;
  292. // Skip past the encryption signature for passing to IM.
  293. if (pRealSMHandle->encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  294. pData = pEncData;
  295. DataLength = EncDataLen - *((TSUINT8 *)(pSigData - sizeof(TSUINT8)));
  296. }
  297. else {
  298. pData += DATA_SIGNATURE_SIZE;
  299. DataLength -= DATA_SIGNATURE_SIZE;
  300. }
  301. }
  302. else {
  303. TRC_ERR((TB, "SM failed to decrypt data: len=%u",
  304. DataLength - DATA_SIGNATURE_SIZE));
  305. goto FailedDecrypt;
  306. }
  307. }
  308. else {
  309. TRC_ERR((TB,"PDU len %u too short for security context",
  310. DataLength));
  311. goto ShortData;
  312. }
  313. }
  314. else {
  315. // Need to disconnect if client only sends encrypted data
  316. if (pRealSMHandle->pWDHandle->bForceEncryptedCSPDU) {
  317. TRC_ASSERT((FALSE), (TB, "unencrypted data in encrypted protocol"));
  318. goto FailedDecrypt;
  319. }
  320. }
  321. }
  322. // Be sure to decrypt before checking the dead and other state to
  323. // maintain the correct context between the client and server.
  324. if (!pRealSMHandle->dead && SM_CHECK_STATE_Q(SM_EVT_DATA_PACKET)) {
  325. // We directly inject into the mouse and keyboard streams if we
  326. // are a primary stack. We cannot receive fast-path data on a
  327. // passthru stack since it does not get RawInput calls. Fast-path
  328. // input cannot be received by a shadow stack since the passthru-
  329. // to-shadow stack data format is always the non-fast-path
  330. // format, munged from the fast-path format by
  331. // IM_ConvertFastPathToShadow().
  332. TRC_ASSERT((pRealSMHandle->pWDHandle->StackClass == Stack_Primary),
  333. (TB,"Somehow we received fast-path input on a %s stack!",
  334. (pRealSMHandle->pWDHandle->StackClass == Stack_Passthru ?
  335. "passthru" :
  336. pRealSMHandle->pWDHandle->StackClass == Stack_Shadow ?
  337. "shadow" : "console")));
  338. pShareClass->IM_DecodeFastPathInput(pData, DataLength, NumEvents);
  339. if (pRealSMHandle->pWDHandle->shadowState == SHADOW_CLIENT)
  340. pShareClass->IM_ConvertFastPathToShadow(pData, DataLength, NumEvents);
  341. }
  342. else {
  343. TRC_ALT((TB,"Ignoring fast-path input PDU on dead or bad state"));
  344. }
  345. }
  346. else {
  347. TRC_ERR((TB,"Received fast-path input data before SM initialized, "
  348. "ignoring"));
  349. goto DataTooSoon;
  350. }
  351. DC_END_FN();
  352. return;
  353. // Error handling, segregate to keep out of performance path
  354. // instruction cache.
  355. FailedKey:
  356. WDW_LogAndDisconnect(pRealSMHandle->pWDHandle, TRUE,
  357. Log_RDP_ENC_UpdateSessionKeyFailed, NULL, 0);
  358. return;
  359. FailedDecrypt:
  360. WDW_LogAndDisconnect(pRealSMHandle->pWDHandle, TRUE, Log_RDP_ENC_DecryptFailed,
  361. NULL, 0);
  362. return;
  363. ShortData:
  364. WDW_LogAndDisconnect(pRealSMHandle->pWDHandle, TRUE,
  365. Log_RDP_SecurityDataTooShort, pData, DataLength);
  366. return;
  367. DataTooSoon:
  368. // TODO: Combine the SM, NM, and TSWd state into one single struct
  369. // containing everything we need, then fix this code to disconnect
  370. // by using the pContext we need.
  371. ;
  372. }
  373. /****************************************************************************/
  374. /* Name: SM_MCSSendDataCallback */
  375. /* */
  376. /* Purpose: Handle SendData callback from MCS */
  377. /* */
  378. /* Returns: TRUE if successful, FALSE otherwise. */
  379. /* */
  380. /* Params: hUser - MCS user handle for our user attachment */
  381. /* UserDefined - our NM handle */
  382. /* bUniform - Data received is from an MCS uniform-send-data */
  383. /* hChannel - Handle of the receive channel */
  384. /* Priority - MCS priority for the data */
  385. /* SenderID - MCS UserID of the sender */
  386. /* Segmentation - MCS segmentation flags for the data */
  387. /* DataLength - Length of the incoming data */
  388. /* pData - Pointer to (DataLength) sized memory block */
  389. /****************************************************************************/
  390. BOOLEAN __fastcall SM_MCSSendDataCallback(BYTE *pData,
  391. unsigned DataLength,
  392. void *UserDefined,
  393. UserHandle hUser,
  394. BOOLEAN bUniform,
  395. ChannelHandle hChannel,
  396. MCSPriority Priority,
  397. UserID SenderID,
  398. Segmentation Segmentation)
  399. {
  400. BOOLEAN result = TRUE;
  401. PSM_HANDLE_DATA pRealSMHandle;
  402. BOOL dataPkt;
  403. BOOL licPkt;
  404. UINT16 channelID;
  405. ShareClass *dcShare;
  406. DC_BEGIN_FN("SM_MCSSendDataCallback");
  407. /************************************************************************/
  408. /* SMHandle is assumed to be the first member in the NM struct pointed */
  409. /* to by UserDefined. */
  410. /************************************************************************/
  411. pRealSMHandle = *((PSM_HANDLE_DATA *)UserDefined);
  412. dcShare = (ShareClass*)pRealSMHandle->pWDHandle->dcShare;
  413. /************************************************************************/
  414. /* Check MCS segmentation. */
  415. /************************************************************************/
  416. TRC_ASSERT((Segmentation == (SEGMENTATION_BEGIN | SEGMENTATION_END)),
  417. (TB,"Segmented packet received"));
  418. /************************************************************************/
  419. /* Decide what type of packet it is. This is a bit hokey. */
  420. /* - If we are encrypting, the security header always tells us the type */
  421. /* of packet. */
  422. /* - If we are not encrypting */
  423. /* - assume packets received in state SM_STATE_SC_REGISTERED are data */
  424. /* packets */
  425. /* - assume packets received in other states are not data packets. */
  426. /************************************************************************/
  427. if (pRealSMHandle->encrypting)
  428. {
  429. if (DataLength >= sizeof(RNS_SECURITY_HEADER)) {
  430. dataPkt = !(((PRNS_SECURITY_HEADER_UA)pData)->flags &
  431. RNS_SEC_NONDATA_PKT);
  432. }
  433. else {
  434. TRC_ERR((TB,"Received pkt len %u too short for security header",
  435. DataLength));
  436. WDW_LogAndDisconnect(pRealSMHandle->pWDHandle, TRUE,
  437. Log_RDP_SecurityDataTooShort, pData, DataLength);
  438. result = FALSE;
  439. DC_QUIT;
  440. }
  441. }
  442. else
  443. {
  444. dataPkt = (pRealSMHandle->state == SM_STATE_SC_REGISTERED);
  445. }
  446. TRC_DBG((TB, "Encrypting=%d: %s packet",
  447. pRealSMHandle->encrypting, dataPkt ? "data" : "security"));
  448. /************************************************************************/
  449. /* Handle data packets (perf path). */
  450. /************************************************************************/
  451. if (dataPkt)
  452. {
  453. /********************************************************************/
  454. /* Decrypt the packet if necessary */
  455. /********************************************************************/
  456. if (pRealSMHandle->encrypting)
  457. {
  458. if (((PRNS_SECURITY_HEADER_UA)pData)->flags & RNS_SEC_ENCRYPT)
  459. {
  460. TRC_DBG((TB, "Decrypt the packet"));
  461. if (SMDecryptPacket(pRealSMHandle, pData, DataLength,
  462. pRealSMHandle->useSafeChecksumMethod))
  463. {
  464. TRC_NRM((TB,"Decrypted packet at %p", pData));
  465. }
  466. else
  467. {
  468. TRC_ERR((TB, "Failed to decrypt packet: %ld", DataLength));
  469. DC_QUIT;
  470. }
  471. if (pRealSMHandle->encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  472. DataLength -= (sizeof(RNS_SECURITY_HEADER2) + ((PRNS_SECURITY_HEADER2_UA)pData)->padlen);
  473. pData += sizeof(RNS_SECURITY_HEADER2);
  474. }
  475. else {
  476. pData += sizeof(RNS_SECURITY_HEADER1);
  477. DataLength -= sizeof(RNS_SECURITY_HEADER1);
  478. }
  479. }
  480. else
  481. {
  482. /************************************************************/
  483. /* Adjust pointer and length */
  484. /************************************************************/
  485. if (pRealSMHandle->pWDHandle->bForceEncryptedCSPDU) {
  486. TRC_ASSERT((FALSE), (TB, "unencrypted data in encrypted protocol"));
  487. WDW_LogAndDisconnect(
  488. pRealSMHandle->pWDHandle, TRUE,
  489. Log_RDP_ENC_DecryptFailed, NULL, 0);
  490. result = FALSE;
  491. DC_QUIT;
  492. }
  493. else {
  494. TRC_NRM((TB, "Pass packet to SC"));
  495. pData += sizeof(RNS_SECURITY_HEADER);
  496. DataLength -= sizeof(RNS_SECURITY_HEADER);
  497. }
  498. }
  499. }
  500. /********************************************************************/
  501. /* Don't do anything if we're dead */
  502. /********************************************************************/
  503. if (!pRealSMHandle->dead)
  504. {
  505. if (SM_CHECK_STATE_Q(SM_EVT_DATA_PACKET)) {
  506. // Decide where to send the packet based on the channel ID.
  507. channelID = (UINT16)MCSGetChannelIDFromHandle(hChannel);
  508. if (channelID == pRealSMHandle->channelID) {
  509. // Pass packet to SC. Don't do it if the ShareClass
  510. // doesn't exist.
  511. TRC_NRM((TB, "Share channel %x", channelID));
  512. if (pRealSMHandle->pWDHandle->dcShare != NULL) {
  513. // Only a non-shadowing primary stack, or a shadow
  514. // stack should process the full set of PDUs
  515. if (((pRealSMHandle->pWDHandle->StackClass == Stack_Primary) &&
  516. (pRealSMHandle->pWDHandle->shadowState != SHADOW_CLIENT))) {
  517. ((ShareClass*)(pRealSMHandle->pWDHandle->dcShare))->
  518. SC_OnDataReceived(pData, SenderID, DataLength,
  519. Priority);
  520. }
  521. else if ((pRealSMHandle->pWDHandle->StackClass == Stack_Shadow)) {
  522. UINT16 pduType = ((PTS_SHARECONTROLHEADER)pData)->pduType
  523. & TS_MASK_PDUTYPE;
  524. // Unless it's CLIENTRANDOM PDU, we can only forward
  525. // data to Share Class if Share Class is ready.
  526. // We could be in a racing condition that Share class
  527. // hasn't finished initialization, but we have received
  528. // shadow data.
  529. if (pRealSMHandle->bForwardDataToSC == TRUE ||
  530. pduType == TS_PDUTYPE_CLIENTRANDOMPDU) {
  531. ((ShareClass*)(pRealSMHandle->pWDHandle->dcShare))->
  532. SC_OnDataReceived(pData, SenderID, DataLength,
  533. Priority);
  534. }
  535. }
  536. // Else send to SC for shadow hotkey processing or
  537. // passthru from the shadow target to the shadow
  538. // client.
  539. else {
  540. ((ShareClass*)(pRealSMHandle->pWDHandle->dcShare))->
  541. SC_OnShadowDataReceived(pData, SenderID, DataLength,
  542. Priority);
  543. }
  544. }
  545. else {
  546. TRC_ERR((TB, "Tried to call non-existent Share Class"));
  547. }
  548. }
  549. else
  550. {
  551. /************************************************************/
  552. /* Virtual Channel */
  553. /************************************************************/
  554. TRC_NRM((TB, "Virtual channel %x", channelID));
  555. WDW_OnDataReceived(pRealSMHandle->pWDHandle,
  556. pData,
  557. DataLength,
  558. channelID);
  559. }
  560. }
  561. else {
  562. TRC_ALT((TB,"Ignoring PDU because of bad state"));
  563. #ifdef INSTRUM_TRACK_DISCARDED
  564. pRealSMHandle->nDiscardPDUBadState++;
  565. #endif
  566. DC_QUIT;
  567. }
  568. }
  569. else
  570. {
  571. TRC_ERR((TB, "Recvd PDU when we're dead"));
  572. //
  573. // To help track down the VC decompression bug
  574. // track if we dropped any VC packets
  575. //
  576. channelID = (UINT16)MCSGetChannelIDFromHandle(hChannel);
  577. if (channelID != pRealSMHandle->channelID) {
  578. //
  579. // If this is VC data then we must hand it off
  580. // to be decompressed otherwise the server's context
  581. // will get out of sync with the client's
  582. //
  583. TRC_NRM((TB, "Virtual channel %x", channelID));
  584. WDW_OnDataReceived(pRealSMHandle->pWDHandle,
  585. pData,
  586. DataLength,
  587. channelID);
  588. #ifdef INSTRUM_TRACK_DISCARDED
  589. pRealSMHandle->nDiscardVCDataWhenDead++;
  590. #endif
  591. }
  592. else
  593. {
  594. #ifdef INSTRUM_TRACK_DISCARDED
  595. pRealSMHandle->nDiscardNonVCPDUWhenDead++;
  596. #endif
  597. }
  598. DC_QUIT;
  599. }
  600. }
  601. else
  602. {
  603. /********************************************************************/
  604. /* If we're encrypting, the security header tells us the packet */
  605. /* type. If we're not encrypting, we need to use our state to */
  606. /* decide whether this is a licensing or security packet. */
  607. /********************************************************************/
  608. if (pRealSMHandle->encrypting)
  609. {
  610. licPkt = (((PRNS_SECURITY_HEADER_UA)pData)->flags &
  611. RNS_SEC_LICENSE_PKT);
  612. }
  613. else
  614. {
  615. licPkt = (pRealSMHandle->state == SM_STATE_LICENSING);
  616. }
  617. if (licPkt)
  618. {
  619. #ifdef USE_LICENSE
  620. /****************************************************************/
  621. /* License packet */
  622. /****************************************************************/
  623. TRC_NRM((TB, "Licensing packet"));
  624. SM_CHECK_STATE(SM_EVT_LIC_PACKET);
  625. if (((PRNS_SECURITY_HEADER_UA)pData)->flags & RNS_SEC_ENCRYPT)
  626. {
  627. TRC_DBG((TB, "Decrypt the licensing packet"));
  628. if (SMDecryptPacket(pRealSMHandle, pData, DataLength,
  629. pRealSMHandle->useSafeChecksumMethod))
  630. {
  631. TRC_NRM((TB,"Decrypted packet at %p", pData));
  632. }
  633. else
  634. {
  635. TRC_ERR((TB, "Failed to decrypt packet: %ld", DataLength));
  636. DC_QUIT;
  637. }
  638. if (pRealSMHandle->encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  639. DataLength -= (sizeof(RNS_SECURITY_HEADER2) + ((PRNS_SECURITY_HEADER2_UA)pData)->padlen);
  640. pData += sizeof(RNS_SECURITY_HEADER2);
  641. }
  642. else {
  643. pData += sizeof(RNS_SECURITY_HEADER1);
  644. DataLength -= sizeof(RNS_SECURITY_HEADER1);
  645. }
  646. }
  647. else
  648. {
  649. TRC_NRM((TB, "Licensing packet not encrypted"));
  650. pData += sizeof(RNS_SECURITY_HEADER);
  651. DataLength -= sizeof(RNS_SECURITY_HEADER);
  652. }
  653. SLicenseData(pRealSMHandle->pLicenseHandle,
  654. pRealSMHandle,
  655. pData,
  656. DataLength);
  657. #else /* USE_LICENSE */
  658. TRC_ABORT((TB,"Licensing not implemented yet"));
  659. #endif /* USE_LICENSE */
  660. }
  661. else
  662. {
  663. /****************************************************************/
  664. /* Security packet */
  665. /****************************************************************/
  666. TRC_NRM((TB, "Security packet"));
  667. SM_CHECK_STATE(SM_EVT_SEC_PACKET);
  668. result = SMContinueSecurityExchange(pRealSMHandle, pData, DataLength);
  669. }
  670. }
  671. DC_EXIT_POINT:
  672. DC_END_FN();
  673. return (result);
  674. } /* SM_MCSSendDataCallback */