AccessAuthFSM.cpp 43 KB

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