AccessAuthFSM.cpp 42 KB

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