AccessAuthFSM.cpp 39 KB

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