AccessAuthFSM.cpp 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438
  1. #include "stdafx.h"
  2. #include "AccessAuthFSM.h"
  3. #include "mod_AccessAuth.h"
  4. #include "Event.h"
  5. #include "access_basefun.h"
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include "fileutil.h"
  9. #include "iniutil.h"
  10. #include "CommEntityUtil.hpp"
  11. #include "CommEntityRestful.hpp"
  12. #include "SpUtility.h"
  13. #include "comm.h"
  14. #include "PinPad_client_g.h"
  15. #include <codecvt>
  16. using namespace PinPad;
  17. #ifdef RVC_OS_WIN
  18. #include <io.h>
  19. #include <stdint.h>"
  20. #include "MyBase64.h"
  21. #include <TlHelp32.h>
  22. #include <iphlpapi.h>
  23. #include <ws2tcpip.h>
  24. #include <Winsock2.h>
  25. #include <algorithm>
  26. #include "WMIDeviceQuery.h"
  27. #include <WinCrypt.h>
  28. #include <Strsafe.h>
  29. #include "DeviceBaseClass.h"
  30. #pragma comment(lib, "IPHLPAPI.lib")
  31. #define ALLOW_MULTI_NETWORKD_CARDS
  32. #endif // RVC_OS_WIN
  33. int HexBuf2StrBuf(PBYTE hexBuf, char** strBuf, DWORD len)
  34. {
  35. char* tmpStr = *strBuf;
  36. int count = 0;
  37. for (int i = 0; i < len; ++i) {
  38. sprintf(tmpStr + count, "%0.2X", hexBuf[i]);
  39. count += 2;
  40. }
  41. return 0;
  42. }
  43. int StrBuf2HexBuf(LPCTSTR strBuf, PBYTE* hexBuf)
  44. {
  45. int len = strlen(strBuf);
  46. if (len == 0 || len % 2 != 0)
  47. return 0;
  48. BYTE* buf = new BYTE[len / 2];
  49. if (buf == NULL)
  50. return 0;
  51. int j = 0;
  52. for (int i = 0; i < len;) {
  53. int tmpVal;
  54. sscanf(strBuf + i, "%2X", &tmpVal);
  55. buf[j] = tmpVal;
  56. i += 2;
  57. j++;
  58. }
  59. *hexBuf = buf;
  60. return j;
  61. }
  62. CAccessAuthFSM::CAccessAuthFSM()
  63. :m_finishAccess(0), m_nAccessFailedCount(0)
  64. , m_accessAuthHost(true), m_initDeviceHost(true)
  65. , m_torelateDiffSyncTimeSecs(180)
  66. {
  67. }
  68. CAccessAuthFSM::~CAccessAuthFSM()
  69. {
  70. m_iState = FSM_STATE_EXIT; // 屏蔽退出ASSERT错误
  71. }
  72. void CAccessAuthFSM::OnStateTrans(int iSrcState, int iDstState)
  73. {
  74. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("trans from %s to %s", GetStateName(iSrcState), GetStateName(iDstState));
  75. }
  76. ErrorCodeEnum CAccessAuthFSM::OnInit()
  77. {
  78. LOG_FUNCTION();
  79. AddStateHooker(this);
  80. m_finishAccess = 0;
  81. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Complied at: %s %s", __DATE__, __TIME__);
  82. //设置初始锁定状态,0
  83. CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();
  84. spFunction->SetSysVar("LockState", "0", true);
  85. ErrorCodeEnum Error = LoadCenterConfig();
  86. if (Error != Error_Succeed)
  87. {
  88. LOG_TRACE("load CenterSetting.ini failed!");
  89. }
  90. GetDiffSyncTimeFromCenterSettings();
  91. return Error_Succeed;
  92. }
  93. ErrorCodeEnum CAccessAuthFSM::OnExit()
  94. {
  95. RemoveStateHooker(this);
  96. return Error_Succeed;
  97. }
  98. void CAccessAuthFSM::HttpsLogCallBack(const char* logtxt)
  99. {
  100. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI("HttpsLogCallBack")("%s", logtxt);
  101. }
  102. struct TimeSynTask : ITaskSp
  103. {
  104. CAccessAuthFSM* m_fsm;
  105. TimeSynTask(CAccessAuthFSM* fsm) :m_fsm(fsm) {}
  106. void Process()
  107. {
  108. if (m_fsm->GetmAccessAuthHost().IsNullOrEmpty())
  109. {
  110. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_AccessAuth_NULL, "准入Url为空");
  111. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenCancel);
  112. pEvent->param1 = AccessAuthorization_UserErrorCode_AccessAuth_NULL;
  113. m_fsm->PostEventFIFO(pEvent);
  114. CSimpleStringA strMsg(true);
  115. strMsg = CSimpleStringA::Format("准入服务地址为空,请下载集中配置或重启应用");
  116. m_fsm->doWarnMsg(AccessAuthorization_UserErrorCode_AccessAuth_NULL, strMsg.GetData(), true);
  117. return;
  118. }
  119. CSystemStaticInfo si;
  120. m_fsm->GetEntityBase()->GetFunction()->GetSystemStaticInfo(si);
  121. struct TimeSynReqStructJson
  122. {
  123. std::string terminalNo;
  124. int curTime;
  125. JSONCONVERT2OBJECT_MEMEBER_REGISTER(terminalNo, curTime)
  126. } timeSyncReq;
  127. struct TimeSyncAnsStructJson
  128. {
  129. int timeDiff;
  130. int authVersion;
  131. std::string sessionKey;
  132. std::string reserved;
  133. JSONCONVERT2OBJECT_MEMEBER_REGISTER(timeDiff, authVersion, sessionKey, reserved)
  134. }timeSyncAns;
  135. timeSyncReq.terminalNo = si.strTerminalID.GetData();
  136. timeSyncReq.curTime = CSmallDateTime::GetNow().GetTime64();
  137. HttpClientResponseResult result;
  138. HttpClientRequestConfig config(HttpRequestMethod::POST, m_fsm->GetmAccessAuthHost().GetData(), &SpGetToken);
  139. config.SetChildUri("/api/v3/sessionkey");
  140. SP::Module::Restful::FulfillRequestJsonBody(&config, timeSyncReq);
  141. RestfulClient client = RestfulClient::getInstance();
  142. if (m_fsm->containsChinese(m_fsm->GetmAccessAuthHost().GetData()))
  143. {
  144. result.statusCode = 6;
  145. m_fsm->AuthLogWarn(result, m_fsm->GetmAccessAuthHost().GetData(), "获取会话密钥");
  146. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("TimeSynTask Connect Failed.");
  147. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenCancel);
  148. pEvent->param1 = AccessAuthorization_UserErrorCode_ACS_FAIL;
  149. m_fsm->PostEventFIFO(pEvent);
  150. return;
  151. }
  152. std::string test;
  153. test = config.GetRequestUri();
  154. config.PreDo();
  155. client.Do(&config, &result);
  156. if (result.ResponseOK()) {
  157. SP::Module::Restful::CommResponseJson responseStatus;
  158. SP::Module::Restful::GetStatusFromDebranchResponse(result.content, responseStatus);
  159. if (!responseStatus.IsOperatedOK()) {
  160. m_fsm->AuthLogWarn(result, config.GetRequestUri(), "获取会话密钥");
  161. return;
  162. }
  163. SP::Module::Restful::ExtractDataFromDebranchResponse(result.content, timeSyncAns);
  164. auto printFunc = [&timeSyncAns]() {
  165. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("timeDiff: %d", timeSyncAns.timeDiff);
  166. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("authVersion: %d", timeSyncAns.authVersion);
  167. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("sessionKey: %s", timeSyncAns.sessionKey.c_str());
  168. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("reserved: %s", timeSyncAns.reserved.c_str());
  169. };
  170. printFunc();
  171. int decodedSessionKeyLen = 0;
  172. char* decodedSessionKey = Hex2Str(timeSyncAns.sessionKey.c_str(), decodedSessionKeyLen);
  173. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("decodedSessionKey=%s,%d", decodedSessionKey, decodedSessionKeyLen);
  174. DWORD rc = Error_InvalidState;
  175. rc = m_fsm->HandleTimeSyn(timeSyncAns.timeDiff, (BYTE*)decodedSessionKey);
  176. delete decodedSessionKey;
  177. if (rc == Error_Succeed) {
  178. auto pEvent = new FSMEvent(CAccessAuthFSM::Event_EndSyncTime);
  179. m_fsm->PostEventFIFO(pEvent);
  180. }
  181. else {
  182. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("TimeSynTask HandleTimeSyn error = %08X", rc);
  183. }
  184. }
  185. else {
  186. std::string errDetail(result.WhatError());
  187. if (errDetail.find("Error resolving address") != std::string::npos) {
  188. std::string tmpDetail = SP::Module::Net::GetWWWInfoThroughDig(config.GetBaseUri());
  189. if (!tmpDetail.empty()) {
  190. SP::Utility::replaceInPlace(tmpDetail, "\n", "$$");
  191. const int len = tmpDetail.length();
  192. int pos = 0, times = 0;
  193. const int each_size = 450;
  194. std::vector<std::string> contents;
  195. while (pos < len) {
  196. const std::string elem = tmpDetail.substr(pos, (len - pos) > each_size ? each_size : std::string::npos);
  197. pos = (++times) * each_size;
  198. contents.push_back(elem);
  199. LogWarn(Severity_Low, Error_Debug, ERROR_ACCESSAUTH_ACS_DIGINFO,
  200. CSimpleStringA::Format("[%d]%s", times, elem.c_str()));
  201. }
  202. }
  203. else {
  204. LogWarn(Severity_Low, Error_Debug, ERROR_ACCESSAUTH_ACS_DIGINFO, errDetail.c_str());
  205. }
  206. }
  207. m_fsm->AuthLogWarn(result, config.GetRequestUri(), "获取会话密钥");
  208. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("TimeSynTask Connect Failed.");
  209. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenCancel);
  210. pEvent->param1 = AccessAuthorization_UserErrorCode_ACS_FAIL;
  211. m_fsm->PostEventFIFO(pEvent);
  212. }
  213. }
  214. };
  215. struct UpdateWKTask : ITaskSp
  216. {
  217. CAccessAuthFSM* m_fsm;
  218. CAccessAuthEntity* m_entity;
  219. UpdateWKTask(CAccessAuthFSM* fsm, CAccessAuthEntity* entity) :m_fsm(fsm), m_entity(entity) {}
  220. void Process()
  221. {
  222. if (m_fsm->GetmAccessAuthHost().IsNullOrEmpty())
  223. {
  224. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_AccessAuth_NULL, "准入Url为空");
  225. return;
  226. }
  227. CSystemStaticInfo si;
  228. m_fsm->GetEntityBase()->GetFunction()->GetSystemStaticInfo(si);
  229. if (m_fsm->containsChinese(m_fsm->GetmAccessAuthHost().GetData()))
  230. {
  231. m_fsm->doWarnMsg(ERROR_ACCESSAUTH_CONNECT_ACS,
  232. GetOutPutStr("%s", "连接总行ACS准入服务失败(UpdateWKTask).").c_str(), true);
  233. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5212")("UpdateWKTask Connect Failed.");
  234. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenCancel);
  235. m_fsm->PostEventFIFO(pEvent);
  236. return;
  237. }
  238. struct UpdateWKReq
  239. {
  240. std::string terminalNo;
  241. std::string encRandom;
  242. string tpkKeyCheck; //tpk密钥校验值
  243. string edkKeyCheck; //edk密钥校验值
  244. string keyIndex; //密钥序号
  245. JSONCONVERT2OBJECT_MEMEBER_REGISTER(terminalNo, encRandom, tpkKeyCheck, edkKeyCheck, keyIndex)
  246. } updateWKReq;
  247. struct UpdateWKAns
  248. {
  249. string tmk;
  250. string tpk;
  251. string edk;
  252. string tpkKeyCheck; //密钥校验值
  253. string edkKeyCheck; //edk密钥校验值
  254. string keyIndex; //密钥序号
  255. JSONCONVERT2OBJECT_MEMEBER_REGISTER(tmk, tpk, edk, tpkKeyCheck, edkKeyCheck, keyIndex)
  256. } updateWKAns;
  257. updateWKReq.terminalNo = si.strTerminalID.GetData();
  258. auto tmkpair = m_entity->GenerateTmkToKMC();//first是加密的,seconde是没加密的
  259. updateWKReq.encRandom = tmkpair.first;
  260. PinPadService_ClientBase* pPinPad = new PinPadService_ClientBase(this->m_entity);
  261. auto errRc = pPinPad->Connect();
  262. if (errRc == Error_Succeed)
  263. {
  264. PinPadService_GetCheckCode_Req req = {};
  265. PinPadService_GetCheckCode_Ans ans = {};
  266. req.mSN.Init(1);
  267. req.wSN.Init(1);
  268. req.mSN[0] = 1;
  269. req.wSN[0] = 0;
  270. errRc = (*pPinPad)(EntityResource::getLink().upgradeLink())->GetCheckCode(req, ans, 10000);
  271. if (errRc == Error_Succeed)
  272. {
  273. updateWKReq.tpkKeyCheck = ans.checkcode[0].GetData();
  274. updateWKReq.keyIndex = ans.index[0].GetData();
  275. }
  276. else
  277. {
  278. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Get keyChek && keyIndex failed.");
  279. }
  280. pPinPad->GetFunction()->CloseSession();
  281. }
  282. else
  283. {
  284. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("connect to pinpad failed.error code:%d", errRc);
  285. }
  286. HttpClientResponseResult result;
  287. HttpClientRequestConfig config(HttpRequestMethod::POST, m_fsm->GetmAccessAuthHost().GetData(), &SpGetToken);
  288. config.SetChildUri("/api/v5/wkupdate");
  289. SP::Module::Restful::FulfillRequestJsonBody(&config, updateWKReq);
  290. std::string test;
  291. test = config.GetRequestUri();
  292. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("请求地址:%s.", test.c_str());
  293. RestfulClient client = RestfulClient::getInstance();
  294. config.PreDo();
  295. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to Post with new restful....");
  296. client.Do(&config, &result);
  297. if (result.ResponseOK()) {
  298. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("UpdateWKTask Connect With Restful Success.");
  299. SP::Module::Restful::CommResponseJson responseStatus;
  300. SP::Module::Restful::GetStatusFromDebranchResponse(result.content, responseStatus);
  301. if (!responseStatus.IsOperatedOK()) {
  302. m_fsm->doWarnMsg(ERR_ACCESSAUTH_UPDATE_WK,
  303. GetOutPutStr("%s%s%s%s", "UpdateWKTask", responseStatus.errorCode.c_str(), "message", responseStatus.errorMsg.c_str()).c_str(), true);
  304. return;
  305. }
  306. SP::Module::Restful::ExtractDataFromDebranchResponse(result.content, updateWKAns);
  307. DWORD rc = m_entity->LoadKeysToPinPadACS(tmkpair.second, updateWKAns.tpk, updateWKAns.edk, updateWKAns.keyIndex, updateWKAns.tpkKeyCheck, updateWKAns.edkKeyCheck);
  308. if (rc == Error_Succeed) {
  309. return;
  310. }
  311. else {
  312. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("UpdateWKTask 密钥加载失败,请检查密码键盘连接。 error = %08X", rc);
  313. }
  314. }
  315. else {
  316. m_fsm->doWarnMsg(ERROR_ACCESSAUTH_CONNECT_ACS,
  317. GetOutPutStr("%s%s", "连接总行ACS准入服务失败(UpdateWKTask).", result.WhatError().c_str()).c_str(), true);
  318. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5212")("UpdateWKTask Connect Failed.");
  319. }
  320. UpdateWKRetError:
  321. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenCancel);
  322. m_fsm->PostEventFIFO(pEvent);
  323. }
  324. };
  325. struct GetTokenTask : ITaskSp
  326. {
  327. CAccessAuthFSM* m_fsm;
  328. CAccessAuthEntity* m_entity;
  329. GetTokenTask(CAccessAuthFSM* fsm, CAccessAuthEntity* entity) :m_fsm(fsm), m_entity(entity) {}
  330. void Process()
  331. {
  332. if (m_fsm->GetmAccessAuthHost().IsNullOrEmpty()) {
  333. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_AccessAuth_NULL, "准入Url为空");
  334. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenCancel);
  335. pEvent->param1 = AccessAuthorization_UserErrorCode_AccessAuth_NULL;
  336. m_fsm->PostEventFIFO(pEvent);
  337. CSimpleStringA strMsg(true);
  338. strMsg = CSimpleStringA::Format("准入服务地址为空,请下载集中配置或尝试重启应用");
  339. m_fsm->doWarnMsg(AccessAuthorization_UserErrorCode_AccessAuth_NULL, strMsg.GetData(), true);
  340. return;
  341. }
  342. ///**TODO(Gifur@3/11/2022): 诗友确定是否还需要连分行!!!!! */
  343. CAccessAuthGetTokenReq getTokenReq;
  344. if (m_fsm->GetTokenReq(&getTokenReq) != Error_Succeed)
  345. {
  346. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenFail);
  347. m_fsm->PostEventFIFO(pEvent);
  348. return;
  349. }
  350. struct GetTokenReq
  351. {
  352. string installVersion;//终端版本(新加字段)
  353. string terminalCharacter;
  354. string terminalNo;
  355. string sessionTempPubKey;
  356. string encTerminalInfo;
  357. string publicKeySM;
  358. string pinPadID;
  359. string existPinPad;
  360. JSONCONVERT2OBJECT_MEMEBER_REGISTER(installVersion, terminalCharacter, terminalNo,
  361. sessionTempPubKey, encTerminalInfo, publicKeySM, pinPadID, existPinPad)
  362. } getTokenReqJson;
  363. struct AccessTokenJson
  364. {
  365. string enToken;
  366. string retHash;
  367. JSONCONVERT2OBJECT_MEMEBER_REGISTER(enToken, retHash)
  368. };
  369. struct SharedKeyJson
  370. {
  371. string enToken;
  372. string sharedSK;
  373. string retHash;
  374. JSONCONVERT2OBJECT_MEMEBER_REGISTER(enToken, sharedSK, retHash)
  375. };
  376. struct GetTokenAns
  377. {
  378. AccessTokenJson accessToken;
  379. SharedKeyJson sharedKey;
  380. bool flag;
  381. string warnMessage;
  382. JSONCONVERT2OBJECT_MEMEBER_REGISTER(accessToken, sharedKey, flag, warnMessage)
  383. } getTokenAns;
  384. HttpClientResponseResult result;
  385. HttpClientRequestConfig config(HttpRequestMethod::POST, m_fsm->GetmAccessAuthHost().GetData(), &SpGetToken);
  386. config.SetChildUri("/api/v3/access");
  387. if (m_fsm->containsChinese(m_fsm->GetmAccessAuthHost().GetData()))
  388. {
  389. result.statusCode = 6;
  390. m_fsm->AuthLogWarn(result, m_fsm->GetmAccessAuthHost().GetData(), "获取准入token");
  391. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetTokenTask Connect Failed.");
  392. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenFail);
  393. m_fsm->PostEventFIFO(pEvent);
  394. return;
  395. }
  396. getTokenReqJson.installVersion = getTokenReq.installVersion;
  397. getTokenReqJson.terminalCharacter = getTokenReq.terminalCharacter;
  398. getTokenReqJson.terminalNo = getTokenReq.terminalNo;
  399. getTokenReqJson.sessionTempPubKey = getTokenReq.sessionTempPubKey;
  400. getTokenReqJson.encTerminalInfo = getTokenReq.encTerminalInfo;
  401. getTokenReqJson.publicKeySM = getTokenReq.publicKeySM;
  402. getTokenReqJson.pinPadID = getTokenReq.pinPadID;
  403. getTokenReqJson.existPinPad = getTokenReq.existPinPad;
  404. SP::Module::Restful::FulfillRequestJsonBody(&config, getTokenReqJson);
  405. std::string test;
  406. test = config.GetRequestUri();
  407. RestfulClient client = RestfulClient::getInstance();
  408. config.PreDo();
  409. client.Do(&config, &result);
  410. if (result.ResponseOK()) {
  411. SP::Module::Restful::CommResponseJson responseStatus;
  412. SP::Module::Restful::GetStatusFromDebranchResponse(result.content, responseStatus);
  413. if (!responseStatus.IsOperatedOK()) {
  414. m_fsm->AuthLogWarn(result, config.GetRequestUri(), "获取准入token");
  415. return;
  416. }
  417. SP::Module::Restful::ExtractDataFromDebranchResponse(result.content, getTokenAns);
  418. if (getTokenAns.flag != false/*&& flag?*/) //判断是否需要告警,通过标志位,标志位待确定
  419. {
  420. CSimpleStringA tmsg = CSimpleStringA::Format("{\"errcode\": \"%s\", \"message\": %s}",
  421. responseStatus.errorCode.c_str(), getTokenAns.warnMessage.c_str());
  422. m_fsm->GetEntityBase()->GetFunction()->SetSysVar("AuthErrMsg", tmsg.GetData(), true);
  423. }
  424. else
  425. {
  426. m_fsm->GetEntityBase()->GetFunction()->SetSysVar("AuthErrMsg", "", true);
  427. }
  428. DWORD rc = m_fsm->HandleGetToken((BYTE*)getTokenAns.sharedKey.enToken.c_str(), (BYTE*)getTokenAns.sharedKey.sharedSK.c_str(),
  429. (BYTE*)getTokenAns.accessToken.enToken.c_str(), (BYTE*)getTokenAns.accessToken.retHash.c_str());
  430. if (rc == Error_Succeed) {
  431. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenSucc);
  432. m_fsm->PostEventFIFO(pEvent);
  433. return;
  434. }
  435. else {
  436. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetTokenTask HandleGetToken error = %08X", rc);
  437. }
  438. }
  439. else {
  440. std::string errDetail(result.WhatError());
  441. if (errDetail.find("Error resolving address") != std::string::npos) {
  442. std::string tmpDetail = SP::Module::Net::GetWWWInfoThroughDig(config.GetBaseUri());
  443. if (!tmpDetail.empty()) {
  444. SP::Utility::replaceInPlace(tmpDetail, "\n", "$$");
  445. const int len = tmpDetail.length();
  446. int pos = 0, times = 0;
  447. const int each_size = 450;
  448. std::vector<std::string> contents;
  449. while (pos < len) {
  450. const std::string elem = tmpDetail.substr(pos, (len - pos) > each_size ? each_size : std::string::npos);
  451. pos = (++times) * each_size;
  452. contents.push_back(elem);
  453. LogWarn(Severity_Low, Error_Debug, ERROR_ACCESSAUTH_ACS_DIGINFO,
  454. CSimpleStringA::Format("[%d]%s", times, elem.c_str()));
  455. }
  456. }
  457. else {
  458. LogWarn(Severity_Low, Error_Debug, ERROR_ACCESSAUTH_ACS_DIGINFO, errDetail.c_str());
  459. }
  460. }
  461. m_fsm->AuthLogWarn(result, config.GetRequestUri(), "获取准入token");
  462. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetTokenTask Connect Failed.");
  463. }
  464. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenFail);
  465. m_fsm->PostEventFIFO(pEvent);
  466. }
  467. };
  468. struct InitDeviceTask :public ITaskSp
  469. {
  470. CAccessAuthFSM* m_fsm;
  471. InitDeviceReq m_req;
  472. InitDeviceTask(CAccessAuthFSM* fsm, InitDeviceReq req) :m_fsm(fsm), m_req(req) {}
  473. void Process()
  474. {
  475. return;
  476. }
  477. };
  478. #ifdef RVC_OS_LINUX
  479. bool isChineseChar(const char* p) {
  480. if (*p >= 0x80) { // ASCII字符的最高位是0,非ASCII字符的最高位是1
  481. char firstByte = *p;
  482. if ((firstByte & 0xE0) == 0xE0) { // 3字节的UTF-8字符
  483. return (*++p >= 0x80) && (*++p >= 0x80) && // 第二、三个字节都是10xxxxxx
  484. ((firstByte & 0xFE) != 0xFE) && // 排除0xFE00~0xFEFF的特殊区域
  485. ((*(unsigned char*)p - 0x80) <= 0xBF);
  486. }
  487. else if ((firstByte & 0xC0) == 0xC0) { // 2字节的UTF-8字符
  488. return (*++p >= 0x80) && // 第二个字节是10xxxxxx
  489. ((firstByte & 0xFE) != 0xFE);
  490. }
  491. }
  492. return false;
  493. }
  494. bool CAccessAuthFSM::containsChinese(const std::string& str) {
  495. for (size_t i = 0; i < str.size(); i++) {
  496. if (isChineseChar(str.c_str() + i)) {
  497. return true;
  498. }
  499. }
  500. return false;
  501. }
  502. #else
  503. bool CAccessAuthFSM::containsChinese(const std::string& str) {
  504. int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
  505. wchar_t* wideStr = new wchar_t[len];
  506. MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, wideStr, len);
  507. for (int i = 0; i < len; i++) {
  508. if (wideStr[i] >= 0x4E00 && wideStr[i] <= 0x9FFF) {
  509. delete[] wideStr;
  510. return true;
  511. }
  512. }
  513. delete[] wideStr;
  514. return false;
  515. }
  516. #endif // RVC_OS_WIN
  517. void CAccessAuthFSM::doWarnMsg(int errReason, std::string errMsg, bool bNeedEvent, string varMsg)
  518. {
  519. #ifdef RVC_OS_WIN
  520. auto fullErrMsg = varMsg.length() > 0 ? varMsg : errMsg;
  521. #else
  522. const std::string errMsgStr = SP::Utility::GBK2UTF8(errMsg);
  523. const std::string varMsgStr = SP::Utility::GBK2UTF8(varMsg);
  524. auto fullErrMsg = varMsgStr.length() > 0 ? varMsgStr : errMsgStr;
  525. #endif // RVC_OS_WIN
  526. if (bNeedEvent)
  527. {
  528. const ErrorCodeEnum ec = m_pEntity->GetFunction()->SetSysVar("AuthErrMsg", fullErrMsg.c_str(), true);
  529. if (ec != Error_Succeed) {
  530. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Update SysVar failed: 0x%X", ec);
  531. }
  532. if (errReason == ERR_ACCESSAUTH_SERVICE_FAILED)
  533. {
  534. m_pEntity->GetFunction()->SetSysVar("AuthErrMsg", errMsg.c_str(), true);
  535. LogEvent(Severity_Middle, ERR_ACCESSAUTH_SERVICE_FAILED, errMsg.c_str());
  536. }
  537. else
  538. {
  539. LogEvent(Severity_Middle, checkErrType(errReason), errMsg.c_str());
  540. }
  541. }
  542. LogWarn(Severity_Middle, Error_Unexpect, errReason, errMsg.c_str());
  543. }
  544. void CAccessAuthFSM::s1_on_entry()
  545. {
  546. CSimpleStringA strEntryStatus = GetEntryPermitSysVar();
  547. if (strEntryStatus.Compare("L") == 0) {
  548. PostEventFIFO(new FSMEvent(Event_AccessAuthSucc));
  549. }
  550. else {
  551. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("EntryStatus: %s", strEntryStatus.GetData());
  552. SetEntryPermitSysVar("I");
  553. }
  554. GetEntityBase()->GetFunction()->SetSysVar("AccessHavePath", "Y");//oiltmp to delete
  555. }
  556. void CAccessAuthFSM::s1_on_exit()
  557. {
  558. }
  559. unsigned int CAccessAuthFSM::s1_on_event(FSMEvent* pEvent)
  560. {
  561. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("s1_on_event: %d", pEvent->iEvt);
  562. return 0;
  563. }
  564. void CAccessAuthFSM::s2_on_entry()
  565. {
  566. LOG_FUNCTION();
  567. m_finishAccess = 0;
  568. SetEntryPermitSysVar("C");
  569. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("开始第%d次准入", m_nAccessFailedCount);
  570. CSmartPointer<TimeSynTask> timeSynTask = new TimeSynTask(this);
  571. GetEntityBase()->GetFunction()->PostThreadPoolTask(timeSynTask.GetRawPointer());
  572. }
  573. void CAccessAuthFSM::s2_on_exit()
  574. {
  575. }
  576. unsigned int CAccessAuthFSM::s2_on_event(FSMEvent* pEvent)
  577. {
  578. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("s2 receives event id: %d", pEvent->iEvt);
  579. if (pEvent->iEvt == Event_EndSyncTime)
  580. {
  581. pEvent->SetHandled();
  582. CSmartPointer<GetTokenTask> getTokenTask = new GetTokenTask(this, (CAccessAuthEntity*)m_pEntity);
  583. GetEntityBase()->GetFunction()->PostThreadPoolTask(getTokenTask.GetRawPointer());
  584. return 0;
  585. }
  586. else if (pEvent->iEvt == Event_ReqTokenCancel)
  587. { //这里貌似会触发健康发起重试
  588. auto pEntity = (CAccessAuthEntity*)m_pEntity;
  589. if (pEvent->param1 == AccessAuthorization_UserErrorCode_AccessAuth_NULL)
  590. {
  591. CSimpleStringA strMsg = CSimpleStringA::Format("准入Url为空");
  592. pEntity->SetAuthErrMsg(strMsg);
  593. }
  594. else if (pEvent->param1 == AccessAuthorization_UserErrorCode_ACS_FAIL)
  595. {
  596. pEntity->SetAuthErrMsg("访问总行ACS失败");
  597. }
  598. else
  599. {
  600. CSimpleStringA strErrMsg = CSimpleStringA::Format("准入超时(%d)", m_finishAccess);
  601. pEntity->GetFunction()->ShowFatalError(strErrMsg);
  602. }
  603. SetEntryPermitSysVar("A");
  604. m_nAccessFailedCount++;
  605. pEvent->SetHandled();
  606. }
  607. else if (pEvent->iEvt == Event_ReqTokenFail)
  608. { //而这里不会触发健康发起重试
  609. SetEntryPermitSysVar("F");
  610. pEvent->SetHandled();
  611. auto pEntity = (CAccessAuthEntity*)m_pEntity;
  612. CSimpleStringA strErrMsg = CSimpleStringA::Format("%s", (const char*)pEntity->GetAuthErrMsg());
  613. // 发送准入失败事件,暂时不发送事件进去关门界面,原因关门界面显示中文乱码
  614. doWarnMsg(EVENT_ACCESSAUTH_FAILED, strErrMsg.GetData(), true);
  615. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA520B")("准入失败");
  616. pEntity->GetFunction()->ShowFatalError(strErrMsg);
  617. m_nAccessFailedCount = 0;
  618. }
  619. else if (pEvent->iEvt == Event_ReqTokenSucc)
  620. {
  621. SetEntryPermitSysVar("L");
  622. LogEvent(Severity_Middle, EVENT_ACCESSAUTH_SUCCEED, "终端准入成功");
  623. m_pEntity->GetFunction()->ShowStartupInfo("准入成功");
  624. m_nAccessFailedCount = 0;
  625. pEvent->SetHandled();
  626. PostEventFIFO(new FSMEvent(Event_AccessAuthSucc));
  627. }
  628. return 0;
  629. }
  630. void CAccessAuthFSM::s3_on_entry()
  631. {
  632. LOG_FUNCTION();
  633. CSystemStaticInfo si;
  634. m_pEntity->GetFunction()->GetSystemStaticInfo(si);
  635. if (si.InstallVersion.ToString().IsNullOrEmpty()) {
  636. LogWarn(Severity_Low, Error_Debug, AccessAuthorization_UserErrorCode_Start, "终端准入成功");
  637. }
  638. else {
  639. LogWarn(Severity_Low, Error_Debug, AccessAuthorization_UserErrorCode_Start, CSimpleStringA::Format("终端准入成功,版本: %s", si.InstallVersion.ToString().GetData()));
  640. }
  641. }
  642. unsigned int CAccessAuthFSM::s3_on_event(FSMEvent* event)
  643. {
  644. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("s3 receives event id: %d", event->iEvt);
  645. return 0;
  646. }
  647. CSimpleStringA CAccessAuthFSM::GetEntryPermitSysVar()
  648. {
  649. CSimpleStringA strValue(true);
  650. CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();
  651. spFunction->GetSysVar("EntryPermit", strValue);
  652. return strValue;
  653. }
  654. ErrorCodeEnum CAccessAuthFSM::SetEntryPermitSysVar(const CSimpleStringA& newVal)
  655. {
  656. CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();
  657. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Set EntryPermit with %s", newVal.GetData());
  658. return spFunction->SetSysVar("EntryPermit", (const char*)newVal);
  659. }
  660. ErrorCodeEnum CAccessAuthFSM::LoadCenterConfig()
  661. {
  662. CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();
  663. CSmartPointer<IConfigInfo> spConfig;
  664. ErrorCodeEnum Error = spFunction->OpenConfig(Config_CenterSetting, spConfig);
  665. if (Error_Succeed == Error)
  666. {
  667. spConfig->ReadConfigValue("AccessAuthorization", "HostUrl", m_accessAuthHost);
  668. spConfig->ReadConfigValue("AccessAuthorization", "HostInitDeviceUrl", m_initDeviceHost);
  669. }
  670. return Error;
  671. }
  672. bool CAccessAuthFSM::DecryptWithSessionKey(BYTE* encText, int encTextLen, BYTE* decTest, int& decTestLen)
  673. {
  674. BYTE key[16] = { 0 };
  675. memcpy(key, ((CAccessAuthEntity*)m_pEntity)->m_AuthSessionKey, 16);
  676. char* keyTmp = Str2Hex((char*)key, 16);
  677. delete keyTmp;
  678. if (!DecWithSM4_ECB(key, encText, encTextLen, decTest, &decTestLen)) {
  679. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("DecryptWithSessionKey ECB error.");
  680. return false;
  681. }
  682. keyTmp = Str2Hex((char*)decTest, decTestLen);
  683. delete keyTmp;
  684. return true;
  685. }
  686. DWORD CAccessAuthFSM::HandleTimeSyn(long nTimeDiff, BYTE* nSessionKey)
  687. {
  688. // 比较终端和服务器时间, 时差小于3分钟(默认,可通过集中配置配置)不纠正
  689. const long dwTimeDiff = nTimeDiff > 0 ? nTimeDiff : 0 - nTimeDiff;
  690. const long torelateTime = m_torelateDiffSyncTimeSecs > 0 ? m_torelateDiffSyncTimeSecs : 0 - m_torelateDiffSyncTimeSecs;
  691. if (torelateTime < dwTimeDiff) {
  692. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("HandleTimeSyn")
  693. ("time diff is too large (%ds), sync time now", nTimeDiff);
  694. CSmallDateTime dtServerTime((DWORD)(CSmallDateTime::GetNow()) + nTimeDiff);
  695. SYSTEMTIME stServerTime = dtServerTime.ToSystemTime();
  696. #ifdef RVC_OS_WIN
  697. if (SetLocalTime(&stServerTime)) {
  698. #else
  699. if (set_system_time_by_sec(nTimeDiff)) {
  700. #endif // RVC_OS_WIN
  701. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("sync time with server succeed, server time: [%s]", dtServerTime.ToTimeString().GetData());
  702. LogWarn(Severity_Low, Error_Debug, AccessAuthorization_UserErrorCode_Sync_Time_Succ,
  703. CSimpleStringA::Format("sync time succ: server time: [%s],diff[%ld],threshold:[%d]",
  704. dtServerTime.ToTimeString().GetData(), nTimeDiff, m_torelateDiffSyncTimeSecs));
  705. }
  706. else {
  707. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_Sync_Time_Failed,
  708. CSimpleStringA::Format("sync time failed: server time: [%s],diff[%ld],threshold:[%d](GLE=%u)",
  709. dtServerTime.ToTimeString().GetData(), nTimeDiff, m_torelateDiffSyncTimeSecs, GetLastError()));
  710. return ERR_ACCESSAUTH_SET_LOCALE_TIME;
  711. }
  712. }
  713. else {
  714. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("HandleTimeSyn")
  715. ("time diff is acceptable (%lds), threshold(%d),", nTimeDiff, m_torelateDiffSyncTimeSecs);
  716. }
  717. //会话密钥缓存
  718. if (((CAccessAuthEntity*)m_pEntity)->SaveAuthKey(nSessionKey))
  719. return Error_Succeed;
  720. return Error_Unexpect;
  721. }
  722. DWORD CAccessAuthFSM::HandleGetToken(BYTE* enToken1, BYTE* sharedKey, BYTE* enToken2, BYTE* retHash)
  723. {
  724. DWORD rc = Error_Succeed;
  725. auto pEntity = (CAccessAuthEntity*)m_pEntity;
  726. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI("HandleGetToken")("retHash=%s", (char*)retHash);
  727. char* enToken1_acs, * sharedKey_acs, * enToken2_acs, * hash_acs;
  728. int enToken1_acs_len = 0, sharedKey_acs_len = 0, enToken2_acs_len = 0, hash_acs_len = 0;
  729. enToken1_acs = Hex2Str((char*)enToken1, enToken1_acs_len);
  730. sharedKey_acs = Hex2Str((char*)sharedKey, sharedKey_acs_len);
  731. enToken2_acs = Hex2Str((char*)enToken2, enToken2_acs_len);
  732. hash_acs = Hex2Str((char*)retHash, hash_acs_len);
  733. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI("HandleGetToken")("enToken1_acs_len=%d", enToken1_acs_len);
  734. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI("HandleGetToken")("sharedKey_acs_len=%d", sharedKey_acs_len);
  735. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI("HandleGetToken")("enToken2_acs_len=%d", enToken2_acs_len);
  736. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI("HandleGetToken")("hash_acs_len=%d", hash_acs_len);
  737. memset(enToken1, 0, strlen((char*)enToken1));
  738. memset(sharedKey, 0, strlen((char*)sharedKey));
  739. memset(enToken2, 0, strlen((char*)enToken2));
  740. memset(retHash, 0, strlen((char*)retHash));
  741. memcpy(enToken1, enToken1_acs, enToken1_acs_len);
  742. memcpy(sharedKey, sharedKey_acs, sharedKey_acs_len);
  743. memcpy(enToken2, enToken2_acs, enToken2_acs_len);
  744. memcpy(retHash, hash_acs, hash_acs_len);
  745. delete enToken1_acs;
  746. delete sharedKey_acs;
  747. delete enToken2_acs;
  748. delete hash_acs;
  749. BYTE enToken[512 + 16] = { 0 };
  750. memcpy(enToken, enToken1, 256);
  751. memcpy(enToken + 256, enToken2, 256);
  752. memcpy(enToken + 512, sharedKey, 16);
  753. BYTE sm3[32] = { 0 };
  754. if (!SM3Hash(enToken, 512 + 16, sm3)) {
  755. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("SM3 Hash error at Token Ret.");
  756. }
  757. if (memcmp(sm3, retHash, 32) != 0)
  758. {
  759. rc = Error_Bug;
  760. pEntity->SetAuthErrMsg("返回令牌校验不通过");
  761. pEntity->GetFunction()->SetSysVar("AuthErrMsg", "返回令牌校验不通过", true);
  762. char* sm3Ret = Str2Hex((char*)sm3, 32);
  763. delete sm3Ret;
  764. doWarnMsg(ERR_ACCESSAUTH_TOKEN_HASH, "返回令牌校验不通过", true);
  765. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)(GetOutPutStr("%s%s", "Hash", "返回令牌校验不通过").c_str());
  766. }
  767. else
  768. {
  769. CBlob token;
  770. token.Alloc(512);
  771. memcpy(token.m_pData, enToken, 512);
  772. CBlob sharedSK;
  773. sharedSK.Alloc(16);
  774. memcpy(sharedSK.m_pData, sharedKey, 16);
  775. rc = pEntity->SaveTokenAndSharedSK(token, sharedSK);
  776. if (rc != Error_Succeed)
  777. {
  778. pEntity->SetAuthErrMsg("保存令牌失败");
  779. pEntity->GetFunction()->SetSysVar("AuthErrMsg", "保存令牌失败", true);
  780. pEntity->SetAuthErrMsg("保存令牌失败");
  781. doWarnMsg(ERR_ACCESSAUTH_SAVE_TOKEN, "保存令牌失败", true);
  782. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5208")(GetOutPutStr("%s%08X", "SaveTokenAndSharedSK", rc).c_str());
  783. }
  784. }
  785. return rc;
  786. }
  787. DWORD CAccessAuthFSM::GetEncTerminalInfo(CBlob& encInfo)
  788. {
  789. LOG_FUNCTION();
  790. RequestTokenReq1 req1;
  791. memset(&req1, 0, sizeof(req1));
  792. BYTE* pBuf = (BYTE*)&req1.encTerminalInfo;
  793. // 设置长度
  794. sprintf((char*)pBuf, "%.4d", sizeof(RequestTokenInfo));
  795. RequestTokenInfo* pInfo = (RequestTokenInfo*)(pBuf + 4);
  796. CSystemStaticInfo si;
  797. m_pEntity->GetFunction()->GetSystemStaticInfo(si);
  798. strncpy(pInfo->szTerminalNo, (const char*)si.strTerminalID, sizeof(pInfo->szTerminalNo) - 1);
  799. CSimpleStringA strPinPadID = "", strDeviceID = "";
  800. bool isPinPadMac = false, bPinPadOnline = false;
  801. int nRet = ((CAccessAuthEntity*)m_pEntity)->GetPinPadIDAndDeviceID(strPinPadID, strDeviceID, isPinPadMac, bPinPadOnline);
  802. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("GetPinPadIDAndDeviceID ret: %d, PinPadID: %s, DeviceID: %s", nRet, strPinPadID.GetData(), strDeviceID.GetData());
  803. if (nRet == 2 || nRet == 3) {
  804. strncpy(pInfo->szPadDeviceID, (const char*)strDeviceID, sizeof(pInfo->szPadDeviceID) - 1);
  805. }
  806. strncpy(pInfo->szMachineType, (const char*)si.strMachineType, sizeof(pInfo->szMachineType) - 1);
  807. // 设备版本,低两位为小版本号,高两位为大版本号 Binary 4
  808. DWORD ver32 = si.MachineVersion.GetVersion32();
  809. for (int i = 0; i < 4; i++) {
  810. pInfo->machineVersion[3 - i] = ((BYTE*)&ver32)[i];
  811. }
  812. // 安装版本,其中包含软件框架版本 binary 8
  813. __int64 ver64 = si.InstallVersion.GetVersion64();
  814. for (int i = 0; i < 8; i++) {
  815. pInfo->installVersion[7 - i] = ((BYTE*)&ver64)[i];
  816. }
  817. #ifdef RVC_OS_WIN
  818. hostent* ent = gethostbyname(NULL);
  819. if (ent && ent->h_addr_list[0] != NULL) {
  820. int i = 0;
  821. for (; ent->h_addr_list[i] != NULL; ++i) {
  822. struct in_addr* in = (struct in_addr*)ent->h_addr_list[i];
  823. //99开头行内办公网,10开头行内业务网。规范出自《招商银行总行网络规范汇编(2017年版).pdf》
  824. if (in->S_un.S_un_b.s_b1 == 99 || in->S_un.S_un_b.s_b1 == 10)
  825. break;
  826. }
  827. if (ent->h_addr_list[i] == NULL)
  828. i = 0;
  829. auto in = (struct in_addr*)ent->h_addr_list[i];
  830. pInfo->ip[0] = in->S_un.S_un_b.s_b1;
  831. pInfo->ip[1] = in->S_un.S_un_b.s_b2;
  832. pInfo->ip[2] = in->S_un.S_un_b.s_b3;
  833. pInfo->ip[3] = in->S_un.S_un_b.s_b4;
  834. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("ip:%d.%d.%d.%d", pInfo->ip[0], pInfo->ip[1], pInfo->ip[2], pInfo->ip[3]);
  835. }
  836. #else
  837. char ip[32] = { 0 };
  838. if (getIPFromLinux(ip)) DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Get IP From Linux Error ex.");
  839. else {
  840. if (ip2byte(ip, pInfo->ip)) DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Ip 2 Byte Error");
  841. else {
  842. for (int i = 0; i < 4; i++) {
  843. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("ip[%d]=%d", i, (int)pInfo->ip[i]);
  844. }
  845. }
  846. }
  847. #endif //#ifdef RVC_OS_WIN
  848. strncpy(pInfo->szSites, si.strSite, sizeof(pInfo->szSites) - 1);
  849. si.EnrolGPS.GetBinaryLongitude(&pInfo->currentGPS[0]);
  850. si.EnrolGPS.GetBinaryLatitude(&pInfo->currentGPS[4]);
  851. CSimpleStringA ts;
  852. DWORD rc = m_pEntity->GetFunction()->GetSysVar("TerminalStage", ts);
  853. if (rc != Error_Succeed)
  854. {
  855. string outStr = GetOutPutStr("%s%08X%s%s", "GetSysVar", rc, "TerminalStage", ts.GetData());
  856. doWarnMsg(ERR_ACCESSAUTH_GET_SYS_VAR, outStr.c_str());
  857. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)(outStr.c_str());
  858. return ERR_ACCESSAUTH_GET_SYS_VAR;
  859. }
  860. assert(ts.GetLength() >= 1);
  861. pInfo->chTerminalState = ts[0];
  862. CSimpleStringA rs;
  863. rc = m_pEntity->GetFunction()->GetSysVar("RunState", rs);
  864. if (rc != Error_Succeed)
  865. {
  866. string outStr = GetOutPutStr("%s%08X%s%s", "GetSysVar", rc, "RunState", rs.GetData());
  867. doWarnMsg(ERR_ACCESSAUTH_GET_SYS_VAR, outStr.c_str());
  868. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)(outStr.c_str());
  869. return ERR_ACCESSAUTH_GET_SYS_VAR;
  870. }
  871. assert(rs.GetLength() >= 1);
  872. pInfo->chRunState = rs[0];
  873. CBlob raw;
  874. auto pEntity = ((CAccessAuthEntity*)m_pEntity);
  875. // 使用会话密钥加密
  876. raw.Refer(pBuf, sizeof(RequestTokenInfo) + 4);
  877. rc = pEntity->EncryptDataWithSessionKey(raw, encInfo);
  878. if (rc != Error_Succeed)
  879. {
  880. doWarnMsg(ERR_ACCESSAUTH_ENCRYPT_KEY,
  881. GetOutPutStr("%s%08X", "CryptEncrypt", rc).c_str());
  882. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)(GetOutPutStr("%s%08X", "CryptEncrypt", rc).c_str());
  883. return ERR_ACCESSAUTH_ENCRYPT_KEY;
  884. }
  885. return Error_Succeed;
  886. }
  887. //密钥加密并转成可见字符
  888. DWORD CAccessAuthFSM::GetTmk(string& tmk)
  889. {
  890. BYTE tmp[140];
  891. CBlob pubKey;
  892. CBlob priKey;
  893. DWORD rc = ((CAccessAuthEntity*)m_pEntity)->CreateSM2KeyPair(pubKey, priKey);
  894. if (rc != Error_Succeed) return rc;
  895. rc = ((CAccessAuthEntity*)m_pEntity)->SaveSM2KeyPair(pubKey, priKey);
  896. if (rc != Error_Succeed) return rc;
  897. memset(tmp, 0, sizeof(tmp));
  898. if (pubKey.m_iLength > 70) {
  899. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("临时公钥长度(%d)大于70。。。", pubKey.m_iLength);
  900. return Error_TooSmallBuffer;
  901. }
  902. memcpy_s(tmp, sizeof(tmp) - 70, pubKey.m_pData, pubKey.m_iLength);
  903. if (priKey.m_iLength > 70) {
  904. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("临时私钥长度(%d)大于70。。。", priKey.m_iLength);
  905. return Error_TooSmallBuffer;
  906. }
  907. memcpy_s(&tmp[70], sizeof(tmp) - 70, priKey.m_pData, priKey.m_iLength);
  908. char* pRet = new char[512];
  909. HexBuf2StrBuf(tmp, &pRet, 140);
  910. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("data=%s,%d", pRet, strlen(pRet));
  911. tmk.assign(pRet);
  912. delete[] pRet;
  913. return Error_Succeed;
  914. }
  915. DWORD CAccessAuthFSM::GetTokenReq(CAccessAuthGetTokenReq* getTokenReq)
  916. {
  917. DWORD rc;
  918. auto pEntity = (CAccessAuthEntity*)m_pEntity;
  919. CSystemStaticInfo si;
  920. pEntity->GetFunction()->GetSystemStaticInfo(si);
  921. getTokenReq->installVersion = si.InstallVersion.ToString();
  922. BYTE fingerPrint[32] = { 0 };
  923. int nBufLen = sizeof(fingerPrint);
  924. if (!pEntity->GetTerminalFingerPrint(fingerPrint, nBufLen))
  925. {
  926. doWarnMsg(ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT,
  927. GetOutPutStr("%s%s", "GetTerminalFingerPrint", "False").c_str());
  928. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5203")
  929. (GetOutPutStr("%s%s", "GetTerminalFingerPrint", "False").c_str());
  930. return ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT;
  931. }
  932. char tmp[256] = { 0 };
  933. char* fingerPrintHex = Str2Hex((char*)fingerPrint, 64);
  934. memcpy(tmp, fingerPrintHex, 64);
  935. getTokenReq->terminalCharacter = tmp;
  936. delete fingerPrintHex;
  937. CBlob encInfo;
  938. if ((rc = GetEncTerminalInfo(encInfo)) != Error_Succeed)
  939. {
  940. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetEncTerminalInfo failed:%d", rc);
  941. return rc;
  942. }
  943. char* pTmp = Str2Hex((char*)encInfo.m_pData, encInfo.m_iLength);
  944. getTokenReq->encTerminalInfo = pTmp;
  945. delete pTmp;
  946. getTokenReq->terminalNo = si.strTerminalID.GetData();
  947. string tmpStr = "";
  948. if ((rc = GetTmk(tmpStr)) != Error_Succeed) return rc;
  949. getTokenReq->sessionTempPubKey = tmpStr;
  950. CSimpleStringA strPinPadID = "", strDeviceID = "";
  951. bool isPinPadMac = false, bPinPadOnline = false;
  952. int nRet = ((CAccessAuthEntity*)m_pEntity)->GetPinPadIDAndDeviceID(strPinPadID, strDeviceID, isPinPadMac, bPinPadOnline);
  953. getTokenReq->pinPadID = strPinPadID.GetData();
  954. if (pEntity->HasPinPad())
  955. {
  956. getTokenReq->existPinPad = "1";
  957. }
  958. else
  959. {
  960. getTokenReq->existPinPad = "0";
  961. }
  962. return rc;
  963. }
  964. void CAccessAuthFSM::UpdateWK()
  965. {
  966. LOG_FUNCTION();
  967. auto pEntity = ((CAccessAuthEntity*)m_pEntity);
  968. CSimpleStringA strPinPadID = "", strDeviceID = "";
  969. bool isPinPadMac = false, bPinPadOnline = false;
  970. pEntity->GetPinPadIDAndDeviceID(strPinPadID, strDeviceID, isPinPadMac, bPinPadOnline);
  971. if (bPinPadOnline) {
  972. CSmartPointer<UpdateWKTask> updateWKTask = new UpdateWKTask(this, pEntity);
  973. GetEntityBase()->GetFunction()->PostThreadPoolTask(updateWKTask.GetRawPointer());
  974. }
  975. }
  976. DWORD CAccessAuthFSM::InitDevice(SpReqAnsContext<AccessAuthService_InitDev_Req, AccessAuthService_InitDev_Ans>::Pointer& ctx)
  977. {
  978. return Error_Succeed;
  979. }
  980. void CAccessAuthFSM::GetDiffSyncTimeFromCenterSettings()
  981. {
  982. CSmartPointer<IConfigInfo> spConfig;
  983. GetEntityBase()->GetFunction()->OpenConfig(Config_CenterSetting, spConfig);
  984. int nValue(0);
  985. spConfig->ReadConfigValueInt(GetEntityBase()->GetEntityName(), "SyncTimeThreshold", nValue);
  986. if (nValue != 0) {
  987. m_torelateDiffSyncTimeSecs = nValue;
  988. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_BUSINESS_SYSTEM)("Fetch SyncTimeThreshold from CS returns: %d", m_torelateDiffSyncTimeSecs);
  989. }
  990. }
  991. template<class T>
  992. void CAccessAuthFSM::AuthLogWarn(const T& ret, const string& url, const string& method, bool bNeedEvent)
  993. {
  994. CSimpleStringA msg;
  995. if (!ret.ResponseOK())
  996. {
  997. int acsErrCode = ERROR_ACCESSAUTH_CONNECT_ACS_x;
  998. if (ret.statusCode == 6) {
  999. acsErrCode = ERROR_ACCESSAUTH_CONNECT_ACS_6;
  1000. msg = CSimpleStringA::Format("%s失败:域名解析失败,请尝试重启应用", method.c_str());
  1001. }
  1002. else if (ret.statusCode == 28) {
  1003. acsErrCode = ERROR_ACCESSAUTH_CONNECT_ACS_28;
  1004. msg = CSimpleStringA::Format("%s失败:连接总行服务超时,请尝试重启应用", method.c_str());
  1005. }
  1006. else {
  1007. msg = CSimpleStringA::Format("%s失败,请尝试重启应用", method.c_str());
  1008. }
  1009. doWarnMsg(acsErrCode, msg.GetData(), bNeedEvent);
  1010. }
  1011. else {
  1012. SP::Module::Restful::CommResponseJson responseStatus;
  1013. SP::Module::Restful::GetStatusFromDebranchResponse(ret.content, responseStatus);
  1014. msg = CSimpleStringA::Format("{\"errcode\": \"%s\", \"message\": %s}",
  1015. responseStatus.errorCode.c_str(), responseStatus.errorMsg.c_str());
  1016. doWarnMsg(ERR_ACCESSAUTH_SERVICE_FAILED, msg.GetData(), bNeedEvent);
  1017. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA520A")("准入服务端报错");
  1018. }
  1019. }
  1020. void CAccessAuthFSM::GetNetMsg(SpReqAnsContext<AccessAuthService_GetNetMsg_Req, AccessAuthService_GetNetMsg_Ans>::Pointer& ctx)
  1021. {
  1022. CSimpleStringA tmp;
  1023. ctx->Ans.netStatus = 1; //成功
  1024. ctx->Answer(Error_Succeed);
  1025. }
  1026. CSimpleStringA CAccessAuthFSM::GetOsVersion()
  1027. {
  1028. #if defined(RVC_OS_WIN)
  1029. CSimpleStringA runInfoPath;
  1030. ErrorCodeEnum eErr = GetEntityBase()->GetFunction()->GetPath("runinfo", runInfoPath);
  1031. if (eErr != Error_Succeed) {
  1032. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("GetPath runinfo error=%s.", SpStrError(eErr));
  1033. return "";
  1034. }
  1035. runInfoPath += "\\runcfg\\osverion";
  1036. ifstream is;
  1037. is.open(runInfoPath.GetData(), ios::binary);
  1038. if (!is.is_open())
  1039. {
  1040. DWORD dwErr = GetLastError();
  1041. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open runcfg\\osverion file failed. [%d]", dwErr);
  1042. return "";
  1043. }
  1044. string line;
  1045. while (!is.eof()) {
  1046. getline(is, line);
  1047. int start = line.find("版本");
  1048. if (start != string::npos)
  1049. //return CSimpleStringA(line.substr(start + 5, line.length() - start - 7).c_str());
  1050. return CSimpleStringA(line.c_str());
  1051. else
  1052. continue;
  1053. }
  1054. return "";
  1055. #else
  1056. std::map<std::string, std::string> osInfo;
  1057. const char filePath[] = "/etc/os-version";
  1058. char tmp[33];
  1059. memset(tmp, 0, 33);
  1060. inifile_read_str_s("Version", "SystemName", "unknown", tmp, 32, filePath);
  1061. osInfo["SystemName"] = tmp;
  1062. memset(tmp, 0, 33);
  1063. inifile_read_str_s("Version", "ProductType", "unknown", tmp, 32, filePath);
  1064. osInfo["ProductType"] = tmp;
  1065. memset(tmp, 0, 33);
  1066. inifile_read_str_s("Version", "MajorVersion", "unknown", tmp, 32, filePath);
  1067. osInfo["MajorVersion"] = tmp;
  1068. memset(tmp, 0, 33);
  1069. inifile_read_str_s("Version", "MinorVersion", "unknown", tmp, 32, filePath);
  1070. osInfo["MinorVersion"] = tmp;
  1071. memset(tmp, 0, 33);
  1072. inifile_read_str_s("Version", "OsBuild", "unknown", tmp, 32, filePath);
  1073. osInfo["OsBuild"] = tmp;
  1074. return generateJsonStr(osInfo).second.c_str();
  1075. #endif
  1076. }
  1077. void CAccessAuthFSM::GetIPandMac(CSimpleStringA& ip, CSimpleStringA& mac)
  1078. {
  1079. CAutoArray<SP::Module::Net::NetworkAdapterItem> netList;
  1080. ErrorCodeEnum rc = SP::Module::Net::GetINETMacAddresses(netList);
  1081. if (rc != Error_Succeed)
  1082. {
  1083. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Get sys netinfo failed!. rc=%d.", rc);
  1084. return;
  1085. }
  1086. CSimpleStringA csMac(""), csIP(""), csDNS("");
  1087. for (int i = 0; i < netList.GetCount(); i++) {
  1088. if (!csMac.IsNullOrEmpty()) {
  1089. csMac += ";";
  1090. }
  1091. csMac += netList[i].mac.c_str();
  1092. }
  1093. mac = csMac;
  1094. for (int i = 0; i < netList.GetCount(); i++) {
  1095. if (!csIP.IsNullOrEmpty()) {
  1096. csIP += ";";
  1097. }
  1098. csIP += netList[i].ip.c_str();
  1099. }
  1100. ip = csIP;
  1101. return;
  1102. }
  1103. void CAccessAuthFSM::GetHardWareInfo(CSimpleStringA & cpu, CSimpleStringA & mainBoard, CSimpleStringA & disk)
  1104. {
  1105. auto pEntity = (CAccessAuthEntity*)m_pEntity;
  1106. #ifdef RVC_OS_LINUX
  1107. char szTmp[1024] = {};
  1108. string strTmp;
  1109. int nTmpBufLen = 1024;
  1110. CSimpleStringA strErrMsg;
  1111. CSmartPointer<IEntityFunction> spFunction = GetEntityBase()->GetFunction();
  1112. CSimpleStringA strRet;
  1113. CSimpleStringA runInfoPath;
  1114. auto rc = GetEntityBase()->GetFunction()->GetPath("runinfo", runInfoPath);
  1115. if (rc != Error_Succeed) {
  1116. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("GetPath runinfo error=%d.", rc);
  1117. return;
  1118. }
  1119. runInfoPath += SPLIT_SLASH_STR "runcfg";
  1120. if (!get_cpu_id_by_system(strTmp, runInfoPath.GetData()))
  1121. {
  1122. strErrMsg = CSimpleStringA::Format("查询CPU ID失败,请重启机器并重新初始化");
  1123. pEntity->SetAuthErrMsg((const char*)strErrMsg);
  1124. doWarnMsg(ERROR_ACCESSAUTH_GETCPUID,
  1125. GetOutPutStr("%s%s", "Processor", "False").c_str());
  1126. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5213")
  1127. (GetOutPutStr("%s%s", "Processor", "False").c_str());
  1128. return;
  1129. }
  1130. cpu = strTmp.c_str();
  1131. strRet = strTmp.c_str();
  1132. strTmp.clear();
  1133. if (!get_board_serial_by_system(strTmp, runInfoPath.GetData()))
  1134. {
  1135. strErrMsg = CSimpleStringA::Format("查询主板序列号失败, 请重启机器并重新初始化");
  1136. pEntity->SetAuthErrMsg((const char*)strErrMsg);
  1137. doWarnMsg(ERROR_ACCESSAUTH_GETBASEBOARDSN,
  1138. GetOutPutStr("%s%s", "BaseBoard", "False").c_str());
  1139. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5214")
  1140. (GetOutPutStr("%s%s", "BaseBoard", "False").c_str());
  1141. return;
  1142. }
  1143. strRet += "|";
  1144. mainBoard = strTmp.c_str();
  1145. strRet += strTmp.c_str();
  1146. vector<string> diskArr;
  1147. int errCode = 0;
  1148. if (!get_disk_serial_by_system(diskArr, errCode, runInfoPath.GetData()))
  1149. {
  1150. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get_disk_serial_by_system errCode:%d", errCode);
  1151. strErrMsg = CSimpleStringA::Format("查询磁盘序列号失败, 请重启机器并重新初始化");
  1152. pEntity->SetAuthErrMsg((const char*)strErrMsg);
  1153. doWarnMsg(ERROR_ACCESSAUTH_DISKDRIVESN,
  1154. GetOutPutStr("%s%s", "DiskDrive", "False").c_str());
  1155. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5215")
  1156. (GetOutPutStr("%s%s", "DiskDrive", "False").c_str());
  1157. return;
  1158. }
  1159. strRet += "|";
  1160. strTmp = "";
  1161. vector<string>::iterator it = diskArr.begin();
  1162. while (it != diskArr.end()) {
  1163. strTmp += *it;
  1164. it++;
  1165. }
  1166. strRet += strTmp.c_str();
  1167. disk = strTmp.c_str();
  1168. BYTE m_btTermSysInfoSM3[32] = { 0 };
  1169. if (!SM3Hash(reinterpret_cast<BYTE*>(const_cast<char*>(strRet.GetData())), strRet.GetLength(), m_btTermSysInfoSM3))
  1170. {
  1171. strErrMsg = "get sm3 hash as fingerprint fail";
  1172. pEntity->SetAuthErrMsg((const char*)strErrMsg);
  1173. spFunction->SetSysVar("AuthErrMsg", (const char*)strErrMsg, true);
  1174. doWarnMsg(ERROR_ACCESSAUTH_GETSM3HASH, (const char*)strErrMsg);
  1175. return;
  1176. }
  1177. #else
  1178. //oilyang@20231008 to get system info from runcfg first
  1179. //no matter calculating from runcfg succeed or not,we also get system info from system api for update runcfg
  1180. bool bCalcFromRunCfg = false;
  1181. CSimpleString csInfo, strErrMsg, strRet;
  1182. CSmartPointer<IConfigInfo> pConfigRun;
  1183. ErrorCodeEnum eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, pConfigRun);
  1184. if (eErr == Error_Succeed && pConfigRun->ReadConfigValue("system", "info", csInfo) == Error_Succeed && !csInfo.IsNullOrEmpty()) {
  1185. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("read device info from runcfg: [%s]", csInfo.GetData());
  1186. CAutoArray<CSimpleStringA> sysInfo = csInfo.Split('|');
  1187. if (sysInfo.GetCount() == 3)
  1188. {
  1189. cpu = sysInfo[0];
  1190. mainBoard = sysInfo[1];
  1191. disk = sysInfo[2];
  1192. }
  1193. }
  1194. else
  1195. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetTermSysInfo, OpenConfig Config_Run error=%d.", eErr);
  1196. ULONGLONG ullStart = GetTickCount64();
  1197. char szTmp[1024] = {};
  1198. int nTmpBufLen = 1024;
  1199. CSmartPointer<IEntityFunction> spFunction = GetEntityBase()->GetFunction();
  1200. if (!QueryWMIDevice(Processor, "ProcessorId", szTmp, &nTmpBufLen))
  1201. {
  1202. strErrMsg = CSimpleStringA::Format("查询 cpu id 失败: %d, 请尝试重启应用", GetLastError());
  1203. pEntity->SetAuthErrMsg((const char*)strErrMsg);
  1204. LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT,
  1205. GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "Processor", GetLastError()).c_str());
  1206. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5203")
  1207. (GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "Processor", GetLastError()).c_str());
  1208. return;
  1209. }
  1210. strRet = szTmp;
  1211. cpu = szTmp;
  1212. nTmpBufLen = 1024;
  1213. memset(szTmp, 0, sizeof(szTmp));
  1214. if (!QueryWMIDevice(BaseBoard, "SerialNumber", szTmp, &nTmpBufLen))
  1215. {
  1216. strErrMsg = CSimpleStringA::Format("查询 baseboard sn 失败: %d, 请尝试重启应用", GetLastError());
  1217. pEntity->SetAuthErrMsg((const char*)strErrMsg);
  1218. LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT,
  1219. GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "BaseBoard", GetLastError()).c_str());
  1220. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5203")
  1221. (GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "BaseBoard", GetLastError()).c_str());
  1222. return;
  1223. }
  1224. strRet += "|";
  1225. strRet += szTmp;
  1226. mainBoard = szTmp;
  1227. nTmpBufLen = 1024;
  1228. memset(szTmp, 0, sizeof(szTmp));
  1229. if (!QueryWMIDevice(DiskDrive, "SerialNumber", szTmp, &nTmpBufLen))
  1230. {
  1231. strErrMsg = CSimpleStringA::Format("查询 harddisk sn 失败: %d, 请尝试重启应用", GetLastError());
  1232. pEntity->SetAuthErrMsg((const char*)strErrMsg);
  1233. LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT,
  1234. GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "DiskDrive", GetLastError()).c_str());
  1235. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)(GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "DiskDrive", GetLastError()).c_str());
  1236. return;
  1237. }
  1238. strRet += "|";
  1239. strRet += szTmp;
  1240. disk = szTmp;
  1241. if (!bCalcFromRunCfg || csInfo.Compare(strRet) != 0)
  1242. {
  1243. eErr = pConfigRun->WriteConfigValue("system", "info", strRet.GetData());
  1244. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("device info changed,before[%s],current[%s],write to runcfg:%d"
  1245. , csInfo.GetData(), strRet.GetData(), eErr);
  1246. }
  1247. else
  1248. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("device info: [%s]", strRet.GetData());
  1249. ULONGLONG ullEnd = GetTickCount64();
  1250. if (ullEnd - ullStart > 5000)
  1251. {
  1252. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5201")
  1253. ("获取系统信息耗时过长:%d秒", (ullEnd - ullStart) / 1000);
  1254. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_GetTermCostTooLong,
  1255. CSimpleStringA::Format("获取系统信息耗时过长:%d秒", (ullEnd - ullStart) / 1000));
  1256. }
  1257. return;
  1258. #endif // RVC_OS_LINUX
  1259. }