ClientComm.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. #include "StdAfx.h"
  2. #if defined(_MSC_VER)
  3. #include <WTypes.h>
  4. #else
  5. #include <winpr/wtypes.h>
  6. #endif //_MSC_VER
  7. #include "ErrorCode.h"
  8. #ifdef _INCLUDE_SPBASE_
  9. #include "SpBase.h"
  10. #else
  11. #define Dbg
  12. #endif
  13. #include "ClientComm.h"
  14. #include "Package.h"
  15. #if defined(_MSC_VER)
  16. #include <process.h>
  17. #else
  18. #include <chrono>
  19. #include <iomanip>
  20. #include <ctime>
  21. #include <iostream>
  22. #endif //_MSC_VER
  23. #include <winpr/crt.h>
  24. #include <winpr/thread.h>
  25. #include "dbgutil.h"
  26. #include <winpr/wlog.h>
  27. #include <assert.h>
  28. #include <string.h>
  29. #define TAG RVCCOMM_TAG("clientcomm")
  30. DWORD CClientComm::s_dwSessionID =0;
  31. DWORD CClientComm::s_dwTokenHash =0;
  32. BYTE CClientComm::s_arrSessionKey[16] = {0};
  33. //////////////////////////////////////////////////////////////////////
  34. // Construction/Destruction
  35. //////////////////////////////////////////////////////////////////////
  36. #define SafeCallbackOnSocketError() \
  37. try \
  38. { \
  39. int nErrCode = WSAGetLastError(); \
  40. string errMsg = GetSysErrorMsg(nErrCode); \
  41. if (m_pCallback != NULL)\
  42. m_pCallback->OnError(Error_IO, 0, errMsg.c_str()); \
  43. } \
  44. catch(...) {}
  45. #define SafeCallbackOnError(dwSysCode, dwUserCode, pErrMsg) \
  46. try \
  47. { \
  48. if (m_pCallback != NULL)\
  49. m_pCallback->OnError(dwSysCode, dwUserCode, pErrMsg); \
  50. } \
  51. catch(...) {}
  52. #define SafeCallbackOnClose() \
  53. try \
  54. { \
  55. if (m_pCallback != NULL)\
  56. m_pCallback->OnClose();\
  57. } \
  58. catch (...) {}
  59. CClientComm::CClientComm(CSecureClientBase *pCallback)
  60. :SOCKET_RECV_BUF_LEN(8096)
  61. {
  62. TOOLKIT_ASSERT(pCallback != NULL);
  63. m_pCallback = pCallback;
  64. m_hSocket = INVALID_SOCKET;
  65. m_hWorkThread = 0;
  66. m_eState = State_None;
  67. m_bNeedAuth = true;
  68. m_hRecvEvent = ::CreateEventA(NULL, FALSE, FALSE, NULL);
  69. m_nSyncWaitResult = 0;
  70. m_nRecvBufLen = SOCKET_RECV_BUF_LEN * 100; //800K
  71. m_pRecvBuf = new BYTE[m_nRecvBufLen];
  72. memset(m_pRecvBuf, 0, m_nRecvBufLen);
  73. m_nHasRecvLen =0;
  74. m_dwSessionID =0;
  75. m_dwTokenHash =0;
  76. memset(m_arrSessionKey, 0, 16);
  77. }
  78. CClientComm::~CClientComm()
  79. {
  80. Close();
  81. if (m_hRecvEvent != 0)
  82. {
  83. CloseHandle(m_hRecvEvent);
  84. m_hRecvEvent = 0;
  85. }
  86. delete[] m_pRecvBuf;
  87. m_pRecvBuf = NULL;
  88. m_nRecvBufLen = 0;
  89. }
  90. // 创建连接,@option:1、重新鉴权新建会话密钥;2、通过握手使用缓存会话密钥;
  91. // 3、不使用会话密钥,即非安全通道 4、不协商,直接使用共享会话密钥
  92. bool CClientComm::Connect(const char *pServerAddr, int nPort, int nOption)
  93. {
  94. m_eState = State_Connecting;
  95. m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  96. if (m_hSocket == INVALID_SOCKET)
  97. {
  98. m_eState = State_Error;
  99. WLog_ERR(TAG, "socket create failed.");
  100. SafeCallbackOnSocketError();
  101. return false;
  102. }
  103. //SetSocketOption();
  104. sockaddr_in addr;
  105. ZeroMemory(&addr, sizeof(sockaddr_in));
  106. addr.sin_family = AF_INET;
  107. addr.sin_addr.s_addr = inet_addr(pServerAddr);
  108. addr.sin_port = htons(nPort);
  109. if (connect(m_hSocket, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR)
  110. {
  111. m_eState = State_Error;
  112. WLog_ERR(TAG, "socket connect failed.");
  113. SafeCallbackOnSocketError();
  114. return false;
  115. }
  116. m_bNeedAuth = (nOption != 3);
  117. WLog_DBG(TAG, "Is need Auth: %d", m_bNeedAuth);
  118. // 创建接收线程,支持异步模式
  119. #if defined(_MSC_VER)
  120. UINT nThreadID;
  121. m_hWorkThread = (HANDLE)_beginthreadex(NULL, 0, &RecvThreadFunc, this, 0, &nThreadID);
  122. #else
  123. DWORD nThreadID;
  124. m_hWorkThread = (HANDLE)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&RecvThreadFunc, this, 0, &nThreadID);
  125. #endif //_MSC_VER
  126. if (m_hWorkThread == 0)
  127. {
  128. Close();
  129. SafeCallbackOnError(Error_Unexpect, 0, "_beginthreadex() error");
  130. WLog_ERR(TAG, "beginthreadex() error.");
  131. m_eState = State_Error;
  132. return false;
  133. }
  134. bool bSendSuc = false;
  135. WLog_DBG(TAG, "to send shakehand pacakge...");
  136. if (nOption == CONN_OPT_NAKED)
  137. {
  138. // 非鉴权握手
  139. bSendSuc = SendHelloReqPackage();
  140. }
  141. else if (nOption == CONN_OPT_SHARED_SESSION)
  142. {
  143. bSendSuc = SendUseSharedSKPackage();
  144. }
  145. else if (nOption == CONN_OPT_CACHED_SESSION && s_dwSessionID !=0) // 连接成功,如果要重用会话密钥,则发送握手请求
  146. {
  147. bSendSuc = SendShakeReqPackage();
  148. }
  149. else
  150. {
  151. // 重新鉴权
  152. bSendSuc = SendAuthReqPackage();
  153. }
  154. WLog_DBG(TAG, "to wait ret pkg....");
  155. // 同步等待返回
  156. WaitRetPkg:
  157. if (!bSendSuc)
  158. {
  159. SafeCallbackOnError(Error_Unexpect, 0, "send auth pkg fail");
  160. WLog_ERR(TAG, "send auth pkg failed.");
  161. Close();
  162. m_eState = State_Error;
  163. return false;
  164. }
  165. auto pkg = ReceivePackage(10);
  166. if (pkg == NULL)
  167. {
  168. if (m_eState == State_Connecting) {
  169. WLog_ERR(TAG, "connect timeout.");
  170. SafeCallbackOnError(Error_TimeOut, 0, "connect timeout");
  171. }
  172. m_eState = State_Error;
  173. Close();
  174. WLog_ERR(TAG, "pkg is empty, out!");
  175. return false;
  176. }
  177. bool bAuthSuc = false;
  178. if (strcmp(pkg->GetServiceCode().c_str(), "_AUTHSM_") ==0)
  179. {
  180. bAuthSuc = HandleAuthRetPackage(pkg);
  181. }
  182. else if (strcmp(pkg->GetServiceCode().c_str(), "_SHAKE_") == 0)
  183. {
  184. bAuthSuc = HandleShakeRetPackage(pkg);
  185. if (!bAuthSuc) // 握手失败,重新鉴权
  186. {
  187. bSendSuc = SendAuthReqPackage();
  188. goto WaitRetPkg;
  189. }
  190. }
  191. else if (strcmp(pkg->GetServiceCode().c_str(), "_USESSK_") == 0)
  192. {
  193. bAuthSuc = HandleUseSharedSKRetPackage(pkg);
  194. if (!bAuthSuc) // 使用共享密钥请求失败,重新鉴权
  195. {
  196. bSendSuc = SendAuthReqPackage();
  197. goto WaitRetPkg;
  198. }
  199. }
  200. else if (strcmp(pkg->GetServiceCode().c_str(), "_HELLO_") == 0)
  201. {
  202. bAuthSuc = HandleHelloRetPackage(pkg);
  203. }
  204. else
  205. {
  206. // 继续等待
  207. goto WaitRetPkg;
  208. }
  209. if (bAuthSuc)
  210. {
  211. m_eState = State_OK;
  212. // 回调OnAuthPass事件
  213. try
  214. {
  215. if (m_pCallback) {
  216. m_pCallback->OnAuthPass();
  217. }
  218. }
  219. catch(...)
  220. {
  221. SafeCallbackOnError(Error_Exception, 0, "OnAuthPass exception");
  222. }
  223. }
  224. else
  225. {
  226. m_eState = State_Error;
  227. }
  228. return bAuthSuc;
  229. }
  230. CSmartPointer<IPackage> CClientComm::CreateNewPackage(const char *pServiceCode)
  231. {
  232. WLog_DBG(TAG, "to create package: %s", pServiceCode);
  233. CSmartPointer<IPackage> ptr;
  234. ptr.Attach(new CCommPackage(m_bNeedAuth && m_eState == State_OK ? m_arrSessionKey : NULL, pServiceCode));
  235. WLog_DBG(TAG, "create package: %s finished!", pServiceCode);
  236. return ptr;
  237. }
  238. CSmartPointer<IPackage> CClientComm::CreateReplyPackage(const CSmartPointer<IPackage>& pRecvPkg)
  239. {
  240. CCommPackage* p = dynamic_cast<CCommPackage*>(pRecvPkg.GetRawPointer());
  241. CSmartPointer<IPackage> ptr;
  242. ptr.Attach(new CCommPackage(p));
  243. return ptr;
  244. }
  245. // socket接收线程
  246. #if defined(_MSC_VER)
  247. UINT CClientComm::RecvThreadFunc(void* pArg)
  248. #else
  249. DWORD CClientComm::RecvThreadFunc(void* pArg)
  250. #endif //_MSC_VER
  251. {
  252. CClientComm *pThis = (CClientComm*) pArg;
  253. TOOLKIT_ASSERT(pThis != NULL);
  254. WLog_DBG(TAG, "Enter recv thread function.");
  255. while(pThis->m_eState == State_OK || pThis->m_eState == State_Connecting)
  256. {
  257. pThis->RecvThreadProcess();
  258. }
  259. // 清空接收缓存
  260. pThis->m_nHasRecvLen = 0;
  261. // 退出线程
  262. #if defined(_MSC_VER)
  263. _endthreadex(0);
  264. #endif //_MSC_VER
  265. WLog_DBG(TAG, "Leave recv thread function.");
  266. return 0;
  267. }
  268. bool CClientComm::IsConnectionOK()
  269. {
  270. return m_eState == State_OK ;
  271. }
  272. bool CClientComm::IsSecureConnection()
  273. {
  274. return m_bNeedAuth;
  275. }
  276. void CClientComm::RecvThreadProcess()
  277. {
  278. // 查询状态
  279. fd_set fdsRead;
  280. FD_ZERO(&fdsRead);
  281. FD_SET(m_hSocket, &fdsRead);
  282. timeval waitTime;
  283. waitTime.tv_sec = 0;
  284. waitTime.tv_usec = 100 * 1000;
  285. #if defined(_MSC_VER)
  286. int rc = select(0, &fdsRead, NULL, NULL, &waitTime);
  287. #else
  288. int rc = select(m_hSocket + 1, &fdsRead, NULL, NULL, &waitTime);
  289. #endif //_MSC_VER
  290. if (rc >0) // 有数据到达
  291. {
  292. int nLen = recv(m_hSocket, (char *)m_pRecvBuf + m_nHasRecvLen, m_nRecvBufLen - m_nHasRecvLen, 0);
  293. if (nLen ==0)
  294. {
  295. // 连接已中断
  296. if (m_eState == State_OK)
  297. {
  298. m_eState = State_Disconnected;
  299. WLog_WARN(TAG, "socket disconnected.");
  300. SafeCallbackOnError(Error_NetBroken, 0, "socket disconnected");
  301. SafeCallbackOnClose();
  302. }
  303. return;
  304. }
  305. else if (nLen <0)
  306. {
  307. bool bCallback = m_eState == State_OK;
  308. m_eState = State_Error;
  309. WLog_WARN(TAG, "receive len is less than zero: %d.", nLen);
  310. if (bCallback)
  311. {
  312. SafeCallbackOnSocketError();
  313. SafeCallbackOnClose();
  314. }
  315. m_eState = State_Error;
  316. return;
  317. }
  318. else
  319. {
  320. m_nHasRecvLen += nLen;
  321. // 可能一次收到多个包
  322. while(true)
  323. {
  324. // 检查包头是否完整
  325. if (m_nHasRecvLen < sizeof(CPackageHeader))
  326. return;
  327. // 提取整包长度
  328. int nPackageLen = GetPackageLenFromRecvBuf();
  329. // 重新分配接收缓冲区
  330. if (nPackageLen > m_nRecvBufLen)
  331. {
  332. WLog_DBG(TAG, "the recv len is longer than package len.");
  333. BYTE *pNewBuf = new BYTE[nPackageLen];
  334. memset(pNewBuf, 0, nPackageLen);
  335. m_nRecvBufLen = nPackageLen;
  336. memcpy(pNewBuf, m_pRecvBuf, m_nHasRecvLen);
  337. delete[] m_pRecvBuf;
  338. m_pRecvBuf = pNewBuf;
  339. return;
  340. }
  341. if (m_nHasRecvLen < nPackageLen) {
  342. WLog_DBG(TAG, "the recv len is less than package len.");
  343. return;
  344. }
  345. // 解析整包长度
  346. CCommPackage *p = new CCommPackage(m_bNeedAuth && m_eState==State_OK ? m_arrSessionKey : NULL, NULL);
  347. CSmartPointer<IPackage> ppkg;
  348. ppkg.Attach(p);
  349. string strErrMsg;
  350. WLog_DBG(TAG, "to parse recv data...");
  351. if (p->ParseRecvData(m_pRecvBuf, &nPackageLen, strErrMsg))
  352. {
  353. WLog_DBG(TAG, "parse recv data finished.");
  354. // 从缓冲区删除完整包数据
  355. memmove(m_pRecvBuf, m_pRecvBuf + nPackageLen, m_nHasRecvLen - nPackageLen);
  356. m_nHasRecvLen -= nPackageLen;
  357. // 检查是否底层错误包
  358. if (strcmp(ppkg->GetServiceCode().c_str(), "__ERROR_") ==0)
  359. {
  360. WLog_DBG(TAG, "receive error flag recv package.");
  361. DWORD dwSysCode(0), dwUserCode(0);
  362. if (!ppkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg))
  363. {
  364. dwSysCode = Error_Bug;
  365. strErrMsg = "get comm package error msg fail";
  366. WLog_DBG(TAG, "get comm package error msg fail");
  367. }
  368. SafeCallbackOnError(dwSysCode, dwUserCode, strErrMsg.c_str());
  369. m_eState = State_Error;
  370. if (::InterlockedCompareExchange(&m_nSyncWaitResult, 0, 1) == 1)
  371. {
  372. ::SetEvent(m_hRecvEvent);
  373. WLog_DBG(TAG, "setEvent 1");
  374. }
  375. return;
  376. }
  377. // 回调应用处理
  378. if (::InterlockedCompareExchange(&m_nSyncWaitResult, 0, 1) == 1) {
  379. CAutoLock Lock(&m_LockObject, 1000);
  380. m_RecvPackages.push_back(ppkg.Detach());
  381. ::SetEvent(m_hRecvEvent);
  382. WLog_DBG(TAG, "setEvent 2");
  383. } else {
  384. WLog_DBG(TAG, "to rely on callback");
  385. // 回调
  386. if (m_pCallback != NULL) {
  387. try {
  388. m_pCallback->OnReceivePackage(ppkg);
  389. } catch (...) {}
  390. }
  391. }
  392. }
  393. else
  394. {
  395. // 丢弃全部接收数据
  396. m_nHasRecvLen = 0;
  397. WLog_ERR(TAG, "parse received package failed: %s", strErrMsg.c_str());
  398. SafeCallbackOnError(Error_Bug, 0, strErrMsg.c_str());
  399. SafeCallbackOnClose();
  400. m_eState = State_Error;
  401. }
  402. }
  403. }
  404. }
  405. else if (rc ==0) {// 超时
  406. //WLog_ERR(TAG, "parse received package timeout!");
  407. } else if (rc == SOCKET_ERROR) { // 错误
  408. WLog_ERR(TAG, "parse received package failed!");
  409. if (m_eState == State_OK)
  410. {
  411. SafeCallbackOnSocketError();
  412. SafeCallbackOnClose();
  413. m_eState = State_Error;
  414. }
  415. }
  416. }
  417. bool CClientComm::SendUseSharedSKPackage()
  418. {
  419. WLog_DBG(TAG, "to send use shared sk package...");
  420. CUseSharedSKReq req;
  421. memset(&req, 0, sizeof(req));
  422. int nSKLen = 16;
  423. int nTNLen = 16;
  424. if (!m_pCallback->OnGetSharedSK(req.m_arrTerminalNo, &nTNLen, m_arrSessionKey, &nSKLen))
  425. {
  426. WLog_ERR(TAG, "get shared seesion key fail");
  427. SafeCallbackOnError(Error_Unexpect, 0, "get shared seesion key fail");
  428. return false;
  429. }
  430. // 生成Hash
  431. BYTE md5[16];
  432. memset(md5, 0, 16);
  433. WLog_DBG(TAG, "to get md5 hash...");
  434. MD5Hash(m_arrSessionKey, 16, md5);
  435. DWORD dwHash = ((DWORD)md5[0]) << 24 | ((DWORD)md5[1]) << 16 | ((DWORD)md5[2]) << 8 | ((DWORD)md5[3]);
  436. WLog_DBG(TAG, "get md5 hash: 0x%X", dwHash);
  437. req.m_dwSharedSKHash = dwHash;
  438. CSmartPointer<IPackage> pkg = CreateNewPackage("_USESSK_");
  439. pkg->AddStruct("USESKREQ", false, false, (BYTE*)&req, sizeof(req));
  440. return SendPackage(pkg) != "";
  441. }
  442. bool CClientComm::SendShakeReqPackage()
  443. {
  444. WLog_DBG(TAG, "to send shake reques package...");
  445. CSessionShakeReq req;
  446. memset(&req, 0, sizeof(req));
  447. //ASSERT(pTerminalNo != NULL);
  448. req.m_dwTokenHash = s_dwTokenHash;
  449. req.m_dwSessionID = s_dwSessionID;
  450. CSmartPointer<IPackage> pkg = CreateNewPackage("_SHAKE_");
  451. pkg->AddStruct("SHAKEREQ", false, false, (BYTE*)&req, sizeof(req));
  452. return SendPackage(pkg) != "";
  453. }
  454. bool CClientComm::SendHelloReqPackage()
  455. {
  456. CSmartPointer<IPackage> pkg = CreateNewPackage("_HELLO_");
  457. return SendPackage(pkg) != "";
  458. }
  459. bool CClientComm::SendAuthReqPackage()
  460. {
  461. WLog_DBG(TAG, "to send auth request pacakge...");
  462. CConnAuthSMReq authReq;
  463. memset(&authReq, 0, sizeof(authReq));
  464. try
  465. {
  466. WLog_DBG(TAG, "on auth request sm...");
  467. if (!m_pCallback->OnAuthRequestSM(&authReq))
  468. {
  469. WLog_DBG(TAG, "callback OnAuthRequestSM() error.");
  470. SafeCallbackOnError(Error_Unexpect, 0, "callback OnAuthRequestSM() error");
  471. return false;
  472. }
  473. WLog_DBG(TAG, "on auth request sm finished.");
  474. }
  475. catch(...)
  476. {
  477. WLog_DBG(TAG, "callback OnAuthRequestSM() exception.");
  478. SafeCallbackOnError(Error_Exception, 0, "callback OnAuthRequestSM() exception");
  479. return false;
  480. }
  481. // 保存TokenHash
  482. BYTE t_sm3Hash[32];
  483. memset(t_sm3Hash, 0, 32);
  484. WLog_DBG(TAG, "to sm3 hash...");
  485. SM3Hash(authReq.m_arrVerifyToken, sizeof(authReq.m_arrVerifyToken), t_sm3Hash);
  486. WLog_DBG(TAG, "sm3 hash done.");
  487. m_dwTokenHash = ((DWORD)t_sm3Hash[0]) << 24 | ((DWORD)t_sm3Hash[1]) << 16 | ((DWORD)t_sm3Hash[2]) << 8 | ((DWORD)t_sm3Hash[3]);
  488. WLog_DBG(TAG, "sm token hash: 0x%X", m_dwTokenHash);
  489. {
  490. CAutoLock lock(&m_LockObject);
  491. s_dwTokenHash = m_dwTokenHash;
  492. }
  493. CSmartPointer<IPackage> ppkg = CreateNewPackage("_AUTHSM_");
  494. ppkg->AddStruct("AUTHSM_R", false, false, (BYTE*)&authReq, sizeof(authReq));
  495. return SendPackage(ppkg) != "";
  496. }
  497. bool CClientComm::HandleHelloRetPackage(const CSmartPointer<IPackage> &pRetPkg)
  498. {
  499. DWORD dwSysCode(0), dwUserCode(0);
  500. string errMsg;
  501. if (pRetPkg->GetErrMsg(dwSysCode, dwUserCode, errMsg))
  502. {
  503. SafeCallbackOnError(dwSysCode, dwUserCode, errMsg.c_str());
  504. return false;
  505. }
  506. return true;
  507. }
  508. bool CClientComm::HandleShakeRetPackage(const CSmartPointer<IPackage> &pRetPkg)
  509. {
  510. WLog_ERR(TAG, "handle shake returned package...");
  511. DWORD dwSysCode(0), dwUserCode(0);
  512. string errMsg;
  513. if (!pRetPkg->GetErrMsg(dwSysCode, dwUserCode, errMsg))
  514. {
  515. // 将缓存的Session信息恢复
  516. {
  517. CAutoLock lock(&m_LockObject);
  518. m_dwSessionID = s_dwSessionID;
  519. m_dwTokenHash = s_dwTokenHash;
  520. memcpy(m_arrSessionKey, s_arrSessionKey, 16);
  521. }
  522. return true;
  523. }
  524. // 握手失败,重新鉴权
  525. SafeCallbackOnError(dwSysCode, dwUserCode, errMsg.c_str());
  526. return false;
  527. }
  528. bool CClientComm::HandleUseSharedSKRetPackage(const CSmartPointer<IPackage> &pRetPkg)
  529. {
  530. // 握手通过
  531. DWORD dwSysCode(0), dwUserCode(0);
  532. string errMsg;
  533. if (pRetPkg->GetErrMsg(dwSysCode, dwUserCode, errMsg))
  534. {
  535. SafeCallbackOnError(dwSysCode, dwUserCode, errMsg.c_str());
  536. return false;
  537. }
  538. return true;
  539. }
  540. bool CClientComm::HandleAuthRetPackage(const CSmartPointer<IPackage> &pRetPkg)
  541. {
  542. WLog_DBG(TAG, "handle auth ret package...");
  543. DWORD dwSysCode(0), dwUserCode(0);
  544. string errMsg;
  545. if (pRetPkg->GetErrMsg(dwSysCode, dwUserCode, errMsg))
  546. {
  547. SafeCallbackOnError(dwSysCode, dwUserCode, errMsg.c_str());
  548. return false;
  549. }
  550. int nBufLen = pRetPkg->GetStructLen("AUTHSM_A");
  551. if (nBufLen != sizeof(CConnAuthSMRet))
  552. {
  553. char buf[64];
  554. sprintf(buf, "struct length of [AUTHSM_A] is invalid: %d", nBufLen);
  555. SafeCallbackOnError(Error_Bug, 0, buf);
  556. return false;
  557. }
  558. CConnAuthSMRet authRet;
  559. memset(&authRet, 0, sizeof(authRet));
  560. int nArrayNum(0);
  561. bool bRet = pRetPkg->GetStructData("AUTHSM_A", (BYTE*)&authRet, &nBufLen, &nArrayNum);
  562. if (!bRet)
  563. {
  564. SafeCallbackOnError(Error_Bug, 0, "get struct data of [AUTHSM_A] fail");
  565. return false;
  566. }
  567. // 解密并保存会话密钥
  568. int nLen = 256;
  569. BYTE buf[256];
  570. memset(buf, 0, 256);
  571. try
  572. {
  573. if (!m_pCallback->OnSessionKeySMRet(&authRet, buf, &nLen))
  574. {
  575. SafeCallbackOnError(Error_Unexpect, 0, "callback OnSessionKeySMRet() error");
  576. return false;
  577. }
  578. }
  579. catch(...)
  580. {
  581. SafeCallbackOnError(Error_Exception, 0, "decrypt return session key exception");
  582. return false;
  583. }
  584. if (nLen == 16)
  585. {
  586. memcpy(m_arrSessionKey, buf, 16);
  587. // 缓存SessionKey
  588. {
  589. CAutoLock lock(&m_LockObject);
  590. memcpy(s_arrSessionKey, m_arrSessionKey, 16);
  591. }
  592. BYTE t_sm3Hash[32];
  593. memset(t_sm3Hash, 0, 32);
  594. SM3Hash(m_arrSessionKey, 16, t_sm3Hash);
  595. m_dwSessionID = ((DWORD)t_sm3Hash[0]) << 24 | ((DWORD)t_sm3Hash[1]) << 16 | ((DWORD)t_sm3Hash[2]) << 8 | ((DWORD)t_sm3Hash[3]);
  596. {
  597. CAutoLock lock(&m_LockObject);
  598. s_dwSessionID = m_dwSessionID;
  599. }
  600. return true;
  601. }
  602. else
  603. {
  604. SafeCallbackOnError(Error_Bug, 0, "decrypted sesseion key length invalid");
  605. return false;
  606. }
  607. }
  608. int CClientComm::GetPackageLenFromRecvBuf()
  609. {
  610. if (m_pRecvBuf == NULL || m_nRecvBufLen < sizeof(CPackageHeader) || m_nHasRecvLen < sizeof(CPackageHeader))
  611. return 0;
  612. CPackageHeader *pHead = (CPackageHeader*) m_pRecvBuf;
  613. return pHead->m_nPackageLen;
  614. }
  615. void CClientComm::SetSocketOption()
  616. {
  617. /*
  618. //Send time out
  619. int timeout = SOCKET_SENDTIMEOUT * 1000;
  620. int rc = setsockopt(nSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
  621. //recieve time out
  622. setsockopt(nSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
  623. // Send keepalives
  624. nSockOptVal = 1;
  625. setsockopt(nSocket, SOL_SOCKET, SO_KEEPALIVE, (const char FAR *)&nSockOptVal, sizeof(nSockOptVal));
  626. //Reuse Port
  627. BOOL bOptVal = TRUE;
  628. setsockopt(nSocket, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bOptVal, sizeof(bOptVal));
  629. */
  630. // Enable "hard" close
  631. LINGER LingerOpt;
  632. LingerOpt.l_onoff = 0;
  633. LingerOpt.l_linger = 0;
  634. setsockopt(m_hSocket, SOL_SOCKET, SO_LINGER, (const char FAR *)&LingerOpt, sizeof(LingerOpt));
  635. // set recv buf lenght
  636. setsockopt(m_hSocket, SOL_SOCKET, SO_RCVBUF, (const char *) SOCKET_RECV_BUF_LEN, sizeof(int));
  637. }
  638. // 返回序列号
  639. string CClientComm::SendPackage(const CSmartPointer<IPackage>& pSendPkg)
  640. {
  641. CCommPackage *pkg = dynamic_cast<CCommPackage*>(pSendPkg.GetRawPointer());
  642. TOOLKIT_ASSERT(pkg != NULL);
  643. if (m_bNeedAuth && m_eState != State_OK
  644. && pkg->GetServiceCode().compare("_AUTHSM_") != 0
  645. && pkg->GetServiceCode().compare("_HELLO_") != 0
  646. && pkg->GetServiceCode().compare("_USESSK_") != 0
  647. && pkg->GetServiceCode().compare("_SHAKE_") != 0)
  648. {
  649. SafeCallbackOnError(Error_Bug, 0, "conn auth first");
  650. return "";
  651. }
  652. WLog_DBG(TAG, "begin send package: [%s]", pSendPkg->GetServiceCode().c_str());
  653. int nBufLen = pkg->GetPackageLen();
  654. BYTE *pBuf = new BYTE[nBufLen];
  655. memset(pBuf, 0, nBufLen);
  656. if (!pkg->GenerateSendData(pBuf, &nBufLen)) {
  657. SafeCallbackOnError(Error_Bug, 0, "generate send data failed!");
  658. WLog_ERR(TAG, "generate send data failed!");
  659. delete[] pBuf;
  660. return "";
  661. }
  662. int nTotalSend =0;
  663. while (nTotalSend < nBufLen)
  664. {
  665. int nSendLen = send(m_hSocket, (const char *)pBuf + nTotalSend, nBufLen - nTotalSend, 0);
  666. if (nSendLen == SOCKET_ERROR)
  667. break;
  668. nTotalSend += nSendLen;
  669. }
  670. delete[] pBuf;
  671. #ifdef _INCLUDE_SPBASE_
  672. if (nTotalSend < nBufLen)
  673. LogError(Severity_Low, Error_NetBroken, 0, (const char*)CSimpleStringA::Format("send package [%s] fail, socket error: [%d]",
  674. pSendPkg->GetServiceCode().c_str(), WSAGetLastError()));
  675. else
  676. WLog_DBG(TAG, "send package [%s] succeed, total [%d] bytes", pSendPkg->GetServiceCode().c_str(), nTotalSend);
  677. #endif
  678. return nTotalSend == nBufLen ? pkg->GetPackageReqID() : "";
  679. }
  680. CSmartPointer<IPackage> CClientComm::ReceivePackage(int nWaitSecond)
  681. {
  682. WLog_DBG(TAG, "to receive package, max timeout: %d", nWaitSecond);
  683. if (m_eState != State_OK && m_eState != State_Connecting)
  684. {
  685. SafeCallbackOnError(Error_Bug, 0, "connection not ok!");
  686. return NULL;
  687. }
  688. DWORD dwWaitResult = WAIT_OBJECT_0;
  689. ResetEvent(m_hRecvEvent);
  690. ::InterlockedExchange(&m_nSyncWaitResult, 1);
  691. if (m_RecvPackages.size() == 0)
  692. {
  693. dwWaitResult = WaitForSingleObject(m_hRecvEvent, nWaitSecond * 1000);
  694. }
  695. if (dwWaitResult == WAIT_OBJECT_0 && (m_eState == State_OK || m_eState == State_Connecting))
  696. {
  697. TOOLKIT_ASSERT(m_RecvPackages.size() >0);
  698. CAutoLock lock(&m_LockObject, 1000);
  699. CSmartPointer<IPackage> ptr;
  700. ptr.Attach(m_RecvPackages.back());
  701. m_RecvPackages.pop_back();
  702. return ptr;
  703. }
  704. return NULL;
  705. }
  706. void CClientComm::Close()
  707. {
  708. if (m_eState == State_OK)
  709. m_eState = State_Closed;
  710. if (m_hWorkThread != 0)
  711. {
  712. CloseHandle(m_hWorkThread);
  713. m_hWorkThread = 0;
  714. }
  715. if (m_hSocket != INVALID_SOCKET)
  716. {
  717. shutdown(m_hSocket, SD_BOTH);
  718. closesocket(m_hSocket);
  719. m_hSocket = INVALID_SOCKET;
  720. }
  721. }