AccessAuthFSM.cpp 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384
  1. #include "stdafx.h"
  2. #include "AccessAuthFSM.h"
  3. #include "mod_AccessAuth.h"
  4. #include "Event.h"
  5. #include "access_basefun.h"
  6. #include "SpUtility.h"
  7. #ifdef RVC_OS_WIN
  8. #include <io.h>
  9. #endif
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include "comm.h"
  13. #define SAFE_DELETE_HTTPCLIENT(obj) \
  14. do{if(obj != NULL) { obj->Destory(); obj = NULL; }}while(false)
  15. CAccessAuthFSM::CAccessAuthFSM()
  16. :m_pConnection(NULL),m_bAccessACS(false)
  17. {
  18. m_nAccessFailedCount = 0;
  19. }
  20. CAccessAuthFSM::~CAccessAuthFSM()
  21. {
  22. m_iState = FSM_STATE_EXIT; // 屏蔽退出ASSERT错误
  23. }
  24. void CAccessAuthFSM::OnStateTrans(int iSrcState, int iDstState)
  25. {
  26. Dbg("trans from %s to %s", GetStateName(iSrcState), GetStateName(iDstState));
  27. }
  28. // 初始化PinPad及KMC
  29. ErrorCodeEnum CAccessAuthFSM::OnInit()
  30. {
  31. LOG_FUNCTION();
  32. AddStateHooker(this);
  33. m_finishAccess = 0;
  34. //设置初始锁定状态,0
  35. CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();
  36. spFunction->SetSysVar("LockState", "0", true);
  37. ErrorCodeEnum Error = LoadCenterConfig();
  38. if (Error != Error_Succeed)
  39. {
  40. LOG_TRACE("load CenterSetting.ini failed!");
  41. }
  42. m_pConnection = new CAccessAuthConn(m_pEntity, this);
  43. return Error_Succeed;
  44. }
  45. ErrorCodeEnum CAccessAuthFSM::OnExit()
  46. {
  47. RemoveStateHooker(this);
  48. return Error_Succeed;
  49. }
  50. ErrorCodeEnum CAccessAuthFSM::SecureClientConnect()
  51. {
  52. if (m_pConnection != NULL && m_pConnection->IsConnectionOK())
  53. return Error_Succeed;
  54. SecureClientRelease();
  55. m_pConnection = new CAccessAuthConn(m_pEntity, this);
  56. if (m_pConnection->ConnectFromCentralSetting() && m_pConnection->IsConnectionOK())
  57. return Error_Succeed;
  58. SecureClientRelease();
  59. return Error_PeerReject;
  60. }
  61. ErrorCodeEnum CAccessAuthFSM::SecureClientRelease()
  62. {
  63. if (m_pConnection != NULL)
  64. {
  65. m_pConnection->Close();
  66. m_pConnection->DecRefCount();
  67. m_pConnection = NULL;
  68. }
  69. return Error_Succeed;
  70. }
  71. std::mutex mut;
  72. struct TimeOutTask : public ITaskSp {
  73. CAccessAuthFSM* m_fsm;
  74. long m_timeOut;//毫秒级
  75. TimeOutTask(CAccessAuthFSM* fsm,long timeOut) :m_fsm(fsm),m_timeOut(timeOut) {}
  76. void Process()
  77. {
  78. Sleep(m_timeOut);
  79. MyMutex myMut(&mut);
  80. if (!m_fsm->m_finishAccess) {
  81. Dbg("准入超时[%d]",m_fsm->m_finishAccess);
  82. m_fsm->PostEventFIFO(new FSMEvent(m_fsm->Event_ReqTokenCancel));
  83. m_fsm->m_finishAccess = 1;
  84. }
  85. }
  86. };
  87. void CAccessAuthFSM::HttpsLogCallBack(const char* logtxt) {
  88. Dbg("%s",logtxt);
  89. }
  90. vector<string> CAccessAuthFSM::GetSplitByChar(const char* content, int len, char spl) {
  91. vector<string> vec;
  92. vec.clear();
  93. char* tmp = new char[len + 1];
  94. memset(tmp, 0, len + 1);
  95. memcpy(tmp, content, len);
  96. char *pos = strtok(tmp, &spl);
  97. while (pos) {
  98. vec.push_back(pos);
  99. pos = strtok(NULL, &spl);
  100. }
  101. delete[] tmp;
  102. return vec;
  103. }
  104. bool CAccessAuthFSM::ACSAccessControl() {
  105. if (m_gateHost.IsNullOrEmpty())
  106. {
  107. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_GateUrl_NULL, "灰度Url为空");
  108. return false;
  109. }
  110. bool bACS = false;
  111. CSystemStaticInfo si;
  112. GetEntityBase()->GetFunction()->GetSystemStaticInfo(si);
  113. //if (!m_terminalList.IsNullOrEmpty()) {
  114. // /*int pos = m_terminalList.IndexOf(si.strTerminalID.GetData());
  115. // if (pos == -1) {
  116. // bACS = false;
  117. // }*/
  118. // auto vec = std::move(GetSplitByChar(m_terminalList.GetData(),m_terminalList.GetLength(),';'));
  119. // int i;
  120. // for (i= 0; i < vec.size(); i++) {
  121. // if (vec[i].compare(si.strTerminalID.GetData()) == 0) {
  122. // bACS = true;
  123. // break;
  124. // }
  125. // }
  126. // if(i==vec.size()) bACS = false;
  127. //}
  128. //else {
  129. // bACS = true;
  130. //}
  131. //Dbg("m_bACS=%d", bACS);
  132. //if (bACS) {
  133. IHttpFunc* client;
  134. client = create_http(HttpsLogCallBack);
  135. CSimpleStringA branchNo = "";
  136. if (GetStrFromCS("Initializer", "SubBankNo", branchNo) != 0) {
  137. Dbg("get SubBankNO from CS error.");
  138. branchNo = 0755;
  139. }
  140. CAccessAuthHttpsGateReq gateReq(si.strTerminalID.GetData(), branchNo.GetData(), "AccessAuthorization2");
  141. CAccessAuthHttpsGateRet gateRet;
  142. gateReq.m_url = m_gateHost;
  143. //oiltest
  144. gateReq.m_printDbg = true;
  145. bool ret = client->Post(gateReq, gateRet);
  146. if (!ret)
  147. {
  148. doWarnMsg(ERROR_ACCESSAUTH_CONNECT_ACS, GetOutPutStr("%s%d%s", "访问灰度控制失败"
  149. ,gateRet.m_sysCode, gateRet.m_userCode.c_str()));
  150. gateRet.m_bACS = false;
  151. }
  152. SAFE_DELETE_HTTPCLIENT(client);
  153. Dbg("m_bACS=%d", gateRet.m_bACS);
  154. bACS = gateRet.m_bACS;
  155. if (bACS)
  156. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_ACS_TURE, "Gray say:come,come,come to ACS.");
  157. else
  158. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_ACS_FALSE, "Gray access failed or Gray say don't call for ACS.");
  159. //
  160. CSmartPointer<IConfigInfo> pConfigRun;
  161. m_pEntity->GetFunction()->OpenConfig(Config_Run, pConfigRun);
  162. int lastAuthPath;
  163. pConfigRun->ReadConfigValueInt("Main", "LastAuthPath", lastAuthPath);
  164. if ((bACS && lastAuthPath == 0) || (!bACS && lastAuthPath == 1))
  165. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_AuthPath_Change, "Auth path change.");
  166. int authPath = bACS ? 1 : 0;
  167. pConfigRun->WriteConfigValueInt("Main", "LastAuthPath", authPath);
  168. return bACS;
  169. }
  170. struct GateReqTask :public ITaskSp {
  171. CAccessAuthFSM* m_fsm;
  172. //string m_path;
  173. GateReqTask(CAccessAuthFSM* fsm) :m_fsm(fsm) {}
  174. void Process(){
  175. m_fsm->m_bAccessACS = m_fsm->ACSAccessControl();
  176. }
  177. };
  178. struct StageReportTask :public ITaskSp {
  179. CAccessAuthFSM* m_fsm;
  180. //string m_path;
  181. StageReportTask(CAccessAuthFSM* fsm) :m_fsm(fsm) {}
  182. void Process()
  183. {
  184. if (m_fsm->GetmAccessAuthHost().IsNullOrEmpty())
  185. {
  186. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_AccessAuth_NULL, "准入Url为空");
  187. return;
  188. }
  189. IHttpFunc* client;
  190. client = create_http(m_fsm->HttpsLogCallBack);
  191. CAccessAuthStageReportReq stageReportReq;
  192. CAccessAuthStageReportRet stageReportRet;
  193. stageReportReq.m_url = m_fsm->GetmAccessAuthHost();
  194. stageReportReq.m_url += "/api/terminal/stagereport";
  195. bool ret = client->Post(stageReportReq, stageReportRet);
  196. Dbg("code=%d", stageReportRet.m_sysCode);
  197. if (ret)
  198. {
  199. Dbg("StageReport Connect Success.");
  200. if (stageReportRet.m_userCode.compare(ACS_SUCCESS)) {
  201. std::string errStr = SP::Utility::GBK2UTF8(stageReportRet.m_errMsg);
  202. m_fsm->doWarnMsg(ERR_ACCESSAUTH_REPORT_STATE,
  203. GetOutPutStr("%s%s%s%s", "StageReportTask", stageReportRet.m_userCode.c_str(), "message", errStr.c_str()).c_str());
  204. SAFE_DELETE_HTTPCLIENT(client);
  205. return;
  206. }
  207. }
  208. else {
  209. Dbg("StageReport Connect Failed(%d).",stageReportRet.m_sysCode);
  210. m_fsm->doWarnMsg(ERROR_ACCESSAUTH_CONNECT_ACS, GetOutPutStr("%s%d","连接总行ACS准入服务失败(StageReport).", stageReportRet.m_sysCode).c_str());
  211. //m_fsm->doWarnMsg(stageReportRet.m_sysCode, "连接总行ACS准入服务失败(StageReport).");
  212. }
  213. SAFE_DELETE_HTTPCLIENT(client);
  214. }
  215. };
  216. struct TimeSynTask : ITaskSp {
  217. CAccessAuthFSM* m_fsm;
  218. TimeSynTask(CAccessAuthFSM* fsm) :m_fsm(fsm) {}
  219. void Process()
  220. {
  221. if (m_fsm->GetmAccessAuthHost().IsNullOrEmpty())
  222. {
  223. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_AccessAuth_NULL, "准入Url为空");
  224. return;
  225. }
  226. CSystemStaticInfo si;
  227. m_fsm->GetEntityBase()->GetFunction()->GetSystemStaticInfo(si);
  228. IHttpFunc* client;
  229. client = create_http(m_fsm->HttpsLogCallBack);
  230. CAccessAuthTimeSynReq timeSynReq(si.strTerminalID.GetData(), CSmallDateTime::GetNow().GetTime64());
  231. CAccessAuthTimeSynRet timeSynRet;
  232. timeSynReq.m_url = m_fsm->GetmAccessAuthHost();
  233. timeSynReq.m_url +="/api/sessionkey";
  234. bool ret = client->Post(timeSynReq, timeSynRet);
  235. Dbg("code=%d",timeSynRet.m_sysCode);
  236. if (ret)
  237. {
  238. Dbg("TimeSynTask Connect Success.");
  239. if (timeSynRet.m_userCode.compare(ACS_SUCCESS)) {
  240. std::string errStr = SP::Utility::GBK2UTF8(timeSynRet.m_errMsg);
  241. m_fsm->doWarnMsg(ERR_ACCESSAUTH_SYNC_TIME,
  242. GetOutPutStr("%s%s%s%s", "TimeSynTask", timeSynRet.m_userCode.c_str(), "message", errStr.c_str()).c_str(),true);
  243. SAFE_DELETE_HTTPCLIENT(client);
  244. return;
  245. }
  246. Dbg("sessionKey = %s", timeSynRet.data.sessionKey.c_str());
  247. int decodedSessionKeyLen = 0;
  248. char* decodedSessionKey = Hex2Str(timeSynRet.data.sessionKey.c_str(),decodedSessionKeyLen);
  249. Dbg("decodedSessionKey=%s,%d", decodedSessionKey, decodedSessionKeyLen);
  250. DWORD rc= m_fsm->m_pConnection->HandleTimeSyn(timeSynRet.data.timeDiff, timeSynRet.data.authVersion, (BYTE*)decodedSessionKey);
  251. delete decodedSessionKey;
  252. if (rc == Error_Succeed) {
  253. Dbg("TimeSynTask HandleTimeSyn Success");
  254. auto pEvent = new FSMEvent(CAccessAuthFSM::Event_EndSyncTime);
  255. m_fsm->PostEventFIFO(pEvent);
  256. }
  257. else {
  258. Dbg("TimeSynTask HandleTimeSyn error = %08X", rc);
  259. }
  260. }
  261. else {
  262. m_fsm->doWarnMsg(ERROR_ACCESSAUTH_CONNECT_ACS,
  263. GetOutPutStr("%s%d", "连接总行ACS准入服务失败(TimeSynTask).", timeSynRet.m_sysCode).c_str(),true);
  264. Dbg("TimeSynTask Connect Failed.");
  265. }
  266. //oiltest@20211117 temp comment the following line
  267. /** revert it [Gifur@2021128]*/
  268. SAFE_DELETE_HTTPCLIENT(client);
  269. }
  270. };
  271. struct LockStateTask : ITaskSp {
  272. CAccessAuthFSM* m_fsm;
  273. LockStateTask(CAccessAuthFSM* fsm) :m_fsm(fsm) {}
  274. void Process()
  275. {
  276. if (m_fsm->GetmAccessAuthHost().IsNullOrEmpty())
  277. {
  278. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_AccessAuth_NULL, "准入Url为空");
  279. return;
  280. }
  281. CSystemStaticInfo si;
  282. m_fsm->GetEntityBase()->GetFunction()->GetSystemStaticInfo(si);
  283. IHttpFunc* client;
  284. client = create_http(m_fsm->HttpsLogCallBack);
  285. CAccessAuthLockStateReq lockStateReq(si.strTerminalID.GetData());
  286. CAccessAuthLockStateRet lockStateRet;
  287. lockStateReq.m_url = m_fsm->GetmAccessAuthHost();
  288. lockStateReq.m_url += "/api/terminal/state";
  289. bool ret = client->Post(lockStateReq, lockStateRet);
  290. Dbg("code=%d", lockStateRet.m_sysCode);
  291. Dbg("code=%s", lockStateRet.m_userCode.c_str());
  292. if (ret)
  293. {
  294. Dbg("lockStateTask Connect Success.");
  295. if (lockStateRet.m_userCode.compare(ACS_SUCCESS)) {
  296. std::string errStr = SP::Utility::GBK2UTF8(lockStateRet.m_errMsg);
  297. m_fsm->doWarnMsg(ERR_ACCESSAUTH_SYNC_TIME,
  298. GetOutPutStr("%s%s%s%s", "LockStateTask", lockStateRet.m_userCode.c_str(), "message", errStr.c_str()).c_str());
  299. SAFE_DELETE_HTTPCLIENT(client);
  300. return;
  301. }
  302. Dbg("lock stat:%s", lockStateRet.data.lockState.c_str());
  303. DWORD rc = m_fsm->m_pConnection->HandleLockState(atoi(lockStateRet.data.lockState.c_str()));
  304. if (rc == Error_Succeed) {
  305. Dbg("lockStateTask HandleLockState Success");
  306. }
  307. else {
  308. Dbg("lockStateTask HandleLockState error = %08X", rc);
  309. }
  310. }
  311. else {
  312. m_fsm->doWarnMsg(ERROR_ACCESSAUTH_CONNECT_ACS,
  313. GetOutPutStr("%s%d", "连接总行ACS准入服务失败(lockStateTask).", lockStateRet.m_sysCode).c_str(),true);
  314. Dbg("lockStateTask Connect Failed.");
  315. }
  316. SAFE_DELETE_HTTPCLIENT(client);
  317. }
  318. };
  319. struct UpdateWKTask : ITaskSp {
  320. CAccessAuthFSM* m_fsm;
  321. CAccessAuthEntity* m_entity;
  322. UpdateWKTask(CAccessAuthFSM* fsm,CAccessAuthEntity *entity) :m_fsm(fsm), m_entity(entity) {}
  323. void Process()
  324. {
  325. if (m_fsm->GetmAccessAuthHost().IsNullOrEmpty())
  326. {
  327. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_AccessAuth_NULL, "准入Url为空");
  328. return;
  329. }
  330. CSystemStaticInfo si;
  331. m_fsm->GetEntityBase()->GetFunction()->GetSystemStaticInfo(si);
  332. IHttpFunc* client;
  333. client = create_http(m_fsm->HttpsLogCallBack);
  334. CAccessAuthUpdateWKReq updateWKReq(si.strTerminalID.GetData());
  335. CAccessAuthUpdateWKRet updateWKRet;
  336. updateWKReq.m_url = m_fsm->GetmAccessAuthHost();
  337. updateWKReq.m_url += "/api/wkupdate";
  338. bool ret = client->Post(updateWKReq, updateWKRet);
  339. Dbg("code=%d", updateWKRet.m_sysCode);
  340. if (ret)
  341. {
  342. Dbg("UpdateWKTask Connect Success.");
  343. if (updateWKRet.m_userCode.compare(ACS_SUCCESS)) {
  344. std::string errStr = SP::Utility::GBK2UTF8(updateWKRet.m_errMsg);
  345. m_fsm->doWarnMsg(ERR_ACCESSAUTH_UPDATE_WK,
  346. GetOutPutStr("%s%s%s%s", "UpdateWKTask", updateWKRet.m_userCode.c_str(), "message", errStr.c_str()).c_str());
  347. SAFE_DELETE_HTTPCLIENT(client);
  348. return;
  349. }
  350. int len = 0;
  351. char *tmp = Hex2Str(updateWKRet.data.TMK.c_str(),len);
  352. int textLen = 2 * len;
  353. BYTE* text = new BYTE[textLen];
  354. memset(text, 0, textLen);
  355. if (!m_fsm->DecryptWithSessionKey((BYTE*)tmp, len, text, textLen)) {
  356. delete[] tmp;
  357. delete[] text;
  358. goto UpdateWKRetError;
  359. }
  360. updateWKRet.data.TMK.assign((char*)text);
  361. delete[] text;
  362. delete tmp;
  363. Dbg("tmk=%s %d", updateWKRet.data.TMK.c_str(), updateWKRet.data.TMK.size());
  364. Dbg("tpk=%s %d", updateWKRet.data.TPK.c_str(), updateWKRet.data.TPK.size());
  365. Dbg("edk=%s %d", updateWKRet.data.EDK.c_str(), updateWKRet.data.EDK.size());
  366. Dbg("index=%s %d", updateWKRet.data.index.c_str(), updateWKRet.data.index.size());
  367. DWORD rc = m_entity->LoadKeysToPinPadNew(updateWKRet.data.TMK, updateWKRet.data.TPK,
  368. updateWKRet.data.EDK, updateWKRet.data.index);
  369. if (rc == Error_Succeed) {
  370. Dbg("UpdateWKTask LoadKeysToPinPadNew Success");
  371. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_UpdateWKSucc);
  372. m_fsm->PostEventFIFO(pEvent);
  373. SAFE_DELETE_HTTPCLIENT(client);
  374. return;
  375. }
  376. else {
  377. Dbg("UpdateWKTask LoadKeysToPinPadNew error = %08X", rc);
  378. }
  379. }
  380. else {
  381. m_fsm->doWarnMsg(ERROR_ACCESSAUTH_CONNECT_ACS,
  382. GetOutPutStr("%s%d", "连接总行ACS准入服务失败(StageReport).", updateWKRet.m_sysCode).c_str());
  383. Dbg("UpdateWKTask Connect Failed.");
  384. }
  385. UpdateWKRetError:
  386. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_UpdateWKFail);
  387. m_fsm->PostEventFIFO(pEvent);
  388. SAFE_DELETE_HTTPCLIENT(client);
  389. }
  390. };
  391. struct GetTokenTask : ITaskSp {
  392. CAccessAuthFSM* m_fsm;
  393. CAccessAuthEntity* m_entity;
  394. GetTokenTask(CAccessAuthFSM* fsm, CAccessAuthEntity* entity) :m_fsm(fsm), m_entity(entity) {}
  395. void Process()
  396. {
  397. if (m_fsm->GetmAccessAuthHost().IsNullOrEmpty())
  398. {
  399. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_AccessAuth_NULL, "准入Url为空");
  400. return;
  401. }
  402. CSystemStaticInfo si;
  403. m_fsm->GetEntityBase()->GetFunction()->GetSystemStaticInfo(si);
  404. CAutoArray<CSimpleStringA> devNames;
  405. DWORD rc = m_fsm->m_pConnection->GetAllDevices(m_entity, devNames);
  406. IHttpFunc* client;
  407. client = create_http(m_fsm->HttpsLogCallBack);
  408. CAccessAuthGetTokenReq getTokenReq(devNames.GetCount());
  409. if (m_fsm->m_pConnection->GetTokenReq(&getTokenReq) != Error_Succeed)
  410. {
  411. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenFail);
  412. m_fsm->PostEventFIFO(pEvent);
  413. SAFE_DELETE_HTTPCLIENT(client);
  414. return;
  415. }
  416. CAccessAuthGetTokenRet getTokenRet;
  417. getTokenReq.m_url = m_fsm->GetmAccessAuthHost();
  418. getTokenReq.m_url += "/api/access";
  419. bool ret = client->Post(getTokenReq, getTokenRet);
  420. Dbg("code=%d", getTokenRet.m_sysCode);
  421. if (ret)
  422. {
  423. Dbg("GetTokenTask userCode:%s,errMsg:%s", getTokenRet.m_userCode.c_str(), getTokenRet.m_errMsg.c_str());
  424. if (getTokenRet.m_userCode.compare(ACS_SUCCESS)) {
  425. std::string errStr = SP::Utility::GBK2UTF8(std::string(getTokenRet.m_errMsg));
  426. m_fsm->doWarnMsg(m_fsm->RtsMapToUserCode(getTokenRet.m_userCode.c_str(), ERR_ACCESSAUTH_TOKEN),
  427. GetOutPutStr("%s%s%s%s", "GetTokenTask", getTokenRet.m_userCode.c_str(), "message", errStr.c_str()).c_str(),true);
  428. SAFE_DELETE_HTTPCLIENT(client);
  429. return;
  430. }
  431. DWORD rc = m_fsm->m_pConnection->HandleGetToken((BYTE*)getTokenRet.data.sharedKey.enToken.c_str(), (BYTE*)getTokenRet.data.sharedKey.sharedSK.c_str(),
  432. (BYTE*)getTokenRet.data.accessToken.enToken.c_str() ,(BYTE*)getTokenRet.data.accessToken.retHash.c_str());
  433. if (rc == Error_Succeed) {
  434. Dbg("GetTokenTask HandleGetToken Success");
  435. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenSucc);
  436. m_fsm->PostEventFIFO(pEvent);
  437. SAFE_DELETE_HTTPCLIENT(client);
  438. return;
  439. }
  440. else {
  441. Dbg("GetTokenTask HandleGetToken error = %08X", rc);
  442. }
  443. }
  444. else {
  445. m_fsm->doWarnMsg(ERROR_ACCESSAUTH_CONNECT_ACS,
  446. GetOutPutStr("%s%d", "连接总行ACS准入服务失败(GetTokenTask).", getTokenRet.m_sysCode).c_str());
  447. Dbg("GetTokenTask Connect Failed.");
  448. }
  449. FSMEvent* pEvent = new FSMEvent(CAccessAuthFSM::Event_ReqTokenFail);
  450. m_fsm->PostEventFIFO(pEvent);
  451. SAFE_DELETE_HTTPCLIENT(client);
  452. }
  453. };
  454. struct InitDeviceTask :public ITaskSp {
  455. CAccessAuthFSM* m_fsm;
  456. InitDeviceReq m_req;
  457. //string m_path;
  458. InitDeviceTask(CAccessAuthFSM* fsm, InitDeviceReq req) :m_fsm(fsm), m_req(req) {}
  459. void Process()
  460. {
  461. if (m_fsm->GetmInitDeviceHost().IsNullOrEmpty())
  462. {
  463. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_InitDev_NULL, "加密通道Url为空");
  464. return;
  465. }
  466. IHttpFunc* client;
  467. client = create_http(m_fsm->HttpsLogCallBack);
  468. CAccessAuthInitDeviceReq initDeviceReq;
  469. initDeviceReq.cr1 = m_req.vtmCR1;
  470. initDeviceReq.cr3 = m_req.vtmCR3;
  471. initDeviceReq.cDevPubKey = m_req.CDevPubKey;
  472. initDeviceReq.r2 = m_req.R2;
  473. initDeviceReq.vendor = m_req.Verdor;
  474. CSystemStaticInfo si;
  475. m_fsm->GetEntityBase()->GetFunction()->GetSystemStaticInfo(si);
  476. initDeviceReq.terminalNo = si.strTerminalID;
  477. CAccessAuthInitDeviceRet initDeviceRet;
  478. initDeviceReq.m_url = m_fsm->GetmInitDeviceHost();
  479. initDeviceReq.m_url = initDeviceReq.m_url + "/api/initdevice";
  480. bool ret = client->Post(initDeviceReq, initDeviceRet);
  481. Dbg("code=%d,usercode:%s", initDeviceRet.m_sysCode, initDeviceRet.m_userCode.c_str());
  482. if (ret)
  483. {
  484. Dbg("InitDeviceTask Connect Success.");
  485. if (initDeviceRet.m_userCode.compare(ACS_SUCCESS)) {
  486. std::string errStr = SP::Utility::GBK2UTF8(initDeviceRet.m_errMsg);
  487. m_fsm->doWarnMsg(ERR_ACCESSAUTH_INIT_DEV,
  488. GetOutPutStr("%s%s%s%s", "InitDeviceTask", initDeviceRet.m_userCode.c_str(), "message", errStr.c_str()).c_str());
  489. }
  490. else {
  491. if (m_fsm->m_pConnection->m_ctxInitDev != NULL)
  492. {
  493. m_fsm->m_pConnection->m_ctxInitDev->Ans.R1 = initDeviceRet.data.r1.c_str();
  494. m_fsm->m_pConnection->m_ctxInitDev->Ans.EncR2 = initDeviceRet.data.cr2.c_str();
  495. m_fsm->m_pConnection->m_ctxInitDev->Ans.R3 = initDeviceRet.data.r3.c_str();
  496. m_fsm->m_pConnection->m_ctxInitDev->Answer(Error_Succeed);
  497. m_fsm->m_pConnection->m_ctxInitDev.Clear();
  498. Dbg("InitDeviceTask success.");
  499. }
  500. }
  501. }
  502. else {
  503. m_fsm->doWarnMsg(ERROR_ACCESSAUTH_CONNECT_ACS,
  504. GetOutPutStr("%s%d", "连接总行ACS准入服务失败(InitDeviceTask).", initDeviceRet.m_sysCode).c_str());
  505. Dbg("InitDeviceTask Connect Failed.");
  506. }
  507. SAFE_DELETE_HTTPCLIENT(client);
  508. }
  509. };
  510. struct TerminalExitTask :public ITaskSp {
  511. CAccessAuthFSM* m_fsm;
  512. //string m_path;
  513. TerminalExitTask(CAccessAuthFSM* fsm) :m_fsm(fsm) {}
  514. void Process()
  515. {
  516. if (m_fsm->GetmAccessAuthHost().IsNullOrEmpty())
  517. {
  518. LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_AccessAuth_NULL, "准入Url为空");
  519. return;
  520. }
  521. IHttpFunc* client;
  522. client = create_http(m_fsm->HttpsLogCallBack);
  523. CAccessAuthExitReq terminalExitReq;
  524. CSystemStaticInfo si;
  525. m_fsm->GetEntityBase()->GetFunction()->GetSystemStaticInfo(si);
  526. terminalExitReq.terminalNo = si.strTerminalID.GetData();
  527. terminalExitReq.rebootWay = m_fsm->GetmnExitWay();
  528. terminalExitReq.triggerReason = m_fsm->GetmnExitReason();
  529. terminalExitReq.terminalStage = 'T';
  530. CAccessAuthExitRet terminalExitRet;
  531. terminalExitReq.m_url = m_fsm->GetmAccessAuthHost();
  532. terminalExitReq.m_url += "/api/exitnotice";
  533. bool ret = client->Post(terminalExitReq, terminalExitRet);
  534. Dbg("code=%d", terminalExitRet.m_sysCode);
  535. if (ret)
  536. {
  537. Dbg("TerminalExitTask Connect Success.");
  538. if (terminalExitRet.m_userCode.compare(ACS_SUCCESS)) {
  539. std::string errStr = SP::Utility::GBK2UTF8(terminalExitRet.m_errMsg);
  540. m_fsm->doWarnMsg(ERR_ACCESSAUTH_TERM_EXIT,
  541. GetOutPutStr("%s%s%s%s", "InitDeviceTask", terminalExitRet.m_userCode.c_str(), "message", errStr.c_str()).c_str());
  542. }
  543. else {
  544. Dbg("TerminalExitTask Success.");
  545. }
  546. }
  547. else {
  548. m_fsm->doWarnMsg(ERROR_ACCESSAUTH_CONNECT_ACS,
  549. GetOutPutStr("%s%d", "连接总行ACS准入服务失败(InitDeviceTask).", terminalExitRet.m_sysCode).c_str());
  550. Dbg("TerminalExitTask Connect Failed.");
  551. }
  552. SAFE_DELETE_HTTPCLIENT(client);
  553. }
  554. };
  555. void CAccessAuthFSM::doWarnMsg(int errReason, std::string errMsg, bool bNeedEvent, string varMsg) {
  556. auto reasonStr = CSimpleString::Format("0x%X", errReason);
  557. const std::string errMsgStr = SP::Utility::GBK2UTF8(errMsg);
  558. const std::string varMsgStr = SP::Utility::GBK2UTF8(varMsg);
  559. Dbg("oiltest:%s,%s", errMsgStr.c_str(), varMsgStr.c_str());
  560. auto fullErrMsg = std::string(reasonStr.GetData()) + "|" + (varMsgStr.length() > 0 ? varMsgStr : errMsgStr);
  561. if (bNeedEvent)
  562. {
  563. m_pEntity->GetFunction()->SetSysVar("AuthErrMsg", fullErrMsg.c_str(), true);
  564. //oiltest@20211124
  565. LogEvent(Severity_Middle, checkErrType(errReason), errMsg.c_str());
  566. //LogEvent(Severity_Middle, CONTROL_ACCESSAUTH_NORETRY_NORESTART, errMsgStr.c_str());
  567. }
  568. LogWarn(Severity_Middle, Error_Unexpect, errReason, errMsgStr.c_str());
  569. }
  570. void CAccessAuthFSM::s1_on_entry()
  571. {
  572. SetSysVar("I");
  573. if (GetStrFromCS("Common","GrayLaunchUrl",m_gateHost) != 0) {
  574. ((CAccessAuthEntity*)m_pEntity)->SetAuthErrMsg("get GrayLaunchUrl error.");
  575. PostEventFIFO(new FSMEvent(Event_GetHsotFailed));
  576. return;
  577. }
  578. if (GetStrFromCS("AccessAuthorization", "HostUrl",m_accessAuthHost ) != 0) {
  579. ((CAccessAuthEntity*)m_pEntity)->SetAuthErrMsg("get Host error.");
  580. PostEventFIFO(new FSMEvent(Event_GetHsotFailed));
  581. return;
  582. }
  583. if (GetStrFromCS("AccessAuthorization", "HostInitDeviceUrl", m_initDeviceHost) != 0) {
  584. ((CAccessAuthEntity*)m_pEntity)->SetAuthErrMsg("get HostInitDevice error.");
  585. PostEventFIFO(new FSMEvent(Event_GetHsotFailed));
  586. return;
  587. }
  588. //oilyang@20210602 according to WangQiang,no need to use this list.It's only used in trial operation.
  589. //if (GetStrFromCS("AccessAuthorization", "TerminalList", m_terminalList) != 0) {
  590. // ((CAccessAuthEntity*)m_pEntity)->SetAuthErrMsg("get Terminals error.");
  591. // PostEventFIFO(new FSMEvent(Event_GetHsotFailed));
  592. // return;
  593. //}
  594. CSmartPointer<GateReqTask> gateReqTask = new GateReqTask(this);
  595. GetEntityBase()->GetFunction()->PostThreadPoolTask(gateReqTask.GetRawPointer());
  596. //m_bAccessACS = ACSAccessControl();
  597. }
  598. void CAccessAuthFSM::s1_on_exit()
  599. {
  600. }
  601. unsigned int CAccessAuthFSM::s1_on_event(FSMEvent* pEvent)
  602. {
  603. LOG_FUNCTION();
  604. Dbg("s1_on_event: %d", pEvent->iEvt);
  605. if (pEvent->iEvt == Event_ReportStage)
  606. {
  607. ReportStateEvent* pReportEvent = (ReportStateEvent*)pEvent;
  608. if (!m_bAccessACS) {
  609. if (SecureClientConnect() == Error_Succeed)
  610. {
  611. m_pConnection->SendTerminalStagePackage(pReportEvent->cNewStage, pReportEvent->dwNewStageTime,
  612. pReportEvent->cOldStage, pReportEvent->dwOldStageTime);
  613. }
  614. }
  615. else {
  616. CSmartPointer<StageReportTask> stageReport = new StageReportTask(this);
  617. GetEntityBase()->GetFunction()->PostThreadPoolTask(stageReport.GetRawPointer());
  618. }
  619. }
  620. return 0;
  621. }
  622. void CAccessAuthFSM::s2_on_entry()
  623. {
  624. LOG_FUNCTION();
  625. if(!DetectNetworkLegality()) {
  626. auto pAccessAuth = dynamic_cast<CAccessAuthEntity*>(GetEntityBase());
  627. LOG_ASSERT(pAccessAuth != NULL);
  628. pAccessAuth->SetAuthErrMsg("终端上网方式不符合规范要求");
  629. PostEventFIFO(new FSMEvent(Event_NetworkIllegal));
  630. return;
  631. }
  632. //[6/16/2020 9:51 @Gifur]
  633. m_finishAccess = 0;
  634. TimeOutTask* timeOutTask = new TimeOutTask(this,120 * 1000);// 设定 2 分钟准入超时
  635. GetEntityBase()->GetFunction()->PostThreadPoolTask(timeOutTask);
  636. Dbg("启动了准入超时定时器2分钟[%d]",m_finishAccess);
  637. GetEntityBase()->GetFunction()->ShowStartupInfo("正在进行准入...");
  638. auto pEntity = (CAccessAuthEntity*)m_pEntity;
  639. if (!m_bAccessACS) {
  640. auto rc = pEntity->InitKMC();
  641. if (rc != Error_Succeed)
  642. {
  643. doWarnMsg(ERR_ACCESSAUTH_INIT_KMC, GetOutPutStr("%s%08X", "调用KMC接口InitKMC错误", rc).c_str());
  644. FSMEvent *pEvent = new FSMEvent(Event_UpdateWKFail);
  645. PostEventFIFO(pEvent);
  646. return;
  647. }
  648. }
  649. SetSysVar("C");
  650. if (!m_bAccessACS) {
  651. ErrorCodeEnum rc;
  652. if ((rc = SecureClientConnect()) != Error_Succeed)
  653. {
  654. // 启动定时器尝试重试
  655. doWarnMsg(ERR_ACCESSAUTH_CONNECT_SERVER, GetOutPutStr("%s%08X", "请先检查网络是否连通,如果网络连通则检查集中配置是否正常。", rc).c_str(),true);
  656. ScheduleTimer(1, 8000);
  657. return;
  658. }
  659. }
  660. PostEventFIFO(new FSMEvent(Event_ConnectionOK));
  661. }
  662. void CAccessAuthFSM::s2_on_exit()
  663. {
  664. // 关闭连接
  665. auto pEntity = (CAccessAuthEntity*)m_pEntity;
  666. pEntity->ReleaseKMC();
  667. SecureClientRelease();
  668. CancelTimer(1);
  669. GetEntityBase()->GetFunction()->ShowStartupInfo("");
  670. }
  671. // 会收到Event_UpdateWKResult和Event_ReqTokenResult和EVT_TIMER
  672. unsigned int CAccessAuthFSM::s2_on_event(FSMEvent* pEvent)
  673. {
  674. Dbg("s2 pEvent:%d",pEvent->iEvt);
  675. if (pEvent->iEvt == EVT_TIMER)
  676. {
  677. if (pEvent->param1 == 2) // access timeout
  678. {
  679. // 重试超时
  680. Dbg("access authorize timeout");
  681. PostEventFIFO(new FSMEvent(Event_ReqTokenCancel));
  682. }
  683. else if (pEvent->param1 == 1 || pEvent->param1 == 3) // reconnect
  684. {
  685. if (!m_bAccessACS)
  686. {
  687. auto rc = SecureClientConnect();
  688. if (rc != Error_Succeed)
  689. {
  690. // 启动定时器尝试重试
  691. doWarnMsg(ERR_ACCESSAUTH_CONNECT_SERVER, GetOutPutStr("%s%08X", "请先检查网络是否连通,如果网络连通则检查集中配置是否正常。", rc).c_str(),true);
  692. ScheduleTimer(1, 8000);
  693. return 1;
  694. }
  695. }
  696. PostEventFIFO(new FSMEvent(Event_ConnectionOK));
  697. return 0;
  698. }
  699. }
  700. else if (pEvent->iEvt == Event_ConnectionOK)
  701. {
  702. Dbg("判断是否第一次准入!");
  703. auto pEntity = ((CAccessAuthEntity*)m_pEntity);
  704. int isFirstAccessAfterSM = pEntity->GetOrSetIsFirstSM(0);
  705. if (isFirstAccessAfterSM != 1) {
  706. Dbg("非首次准入");
  707. PostEventFIFO(new FSMEvent(Event_CheckMD5Succ));
  708. return 0;
  709. }
  710. Dbg("第一次准入 !!!");
  711. CSimpleStringA strInitState;
  712. pEntity->GetFunction()->GetSysVar("InitState", strInitState);
  713. if (strInitState == "1") {
  714. //2020/5/29 删除了各个文件MD5检验的代码
  715. PostEventFIFO(new FSMEvent(Event_CheckMD5Succ));
  716. } else {
  717. ScheduleTimer(3, 1500);
  718. }
  719. }
  720. else if (pEvent->iEvt == Event_CheckMD5Fail)
  721. {
  722. Dbg("Event_CheckMD5Fail");
  723. // 上报状态
  724. //m_pConnection->SendReportStatePackage("CheckMD5", Error_Unexpect, ((CAccessAuthEntity*)m_pEntity)->GetAuthErrMsg());
  725. return 0;
  726. }
  727. else if (pEvent->iEvt == Event_CheckMD5Succ)
  728. {
  729. Dbg("Event_CheckMD5Succ");
  730. if (!m_bAccessACS)
  731. {
  732. DWORD rc = m_pConnection->SendSyncTimePackage();
  733. if (rc != Error_Succeed)
  734. {
  735. FSMEvent* pEvent = new FSMEvent(Event_EndSyncTime);
  736. PostEventFIFO(pEvent);
  737. doWarnMsg(ERR_ACCESSAUTH_SYNC_TIME,
  738. GetOutPutStr("%s%08X", "SendSyncTimePackage", rc).c_str(),true);
  739. }
  740. //获取终端锁定状态
  741. rc = m_pConnection->SendLockStatePackage();
  742. if (rc != Error_Succeed)
  743. {
  744. doWarnMsg(rc,
  745. GetOutPutStr("%s%08X", "SendLockStatePackage", rc).c_str(),true);
  746. }
  747. }
  748. else {
  749. CSmartPointer<TimeSynTask> timeSynTask = new TimeSynTask(this);
  750. GetEntityBase()->GetFunction()->PostThreadPoolTask(timeSynTask.GetRawPointer());
  751. CSmartPointer<LockStateTask> lockStateTask = new LockStateTask(this);
  752. GetEntityBase()->GetFunction()->PostThreadPoolTask(lockStateTask.GetRawPointer());
  753. }
  754. }
  755. else if (pEvent->iEvt == Event_EndSyncTime)
  756. {
  757. Dbg("Event_EndSyncTime");
  758. auto pEntity = ((CAccessAuthEntity*)m_pEntity);
  759. if (!pEntity->HasPinPad())
  760. {
  761. // 没有密码键盘,直接准入
  762. Dbg("has no pinpad, ignore update wk");
  763. PostEventFIFO(new FSMEvent(CAccessAuthFSM::Event_IgnoreUpdateWK));
  764. return 0;
  765. }
  766. Dbg("to get last update time.");
  767. int nWKLastSyncTime(0);
  768. int nWKSyncFailCount(0);
  769. CSimpleStringA strWKSyncSuccTime = "";
  770. CSimpleStringA strWKSyncFailCount = "";
  771. // 检查上次密钥同步时间(一天只同步一次)
  772. CSmartPointer<IConfigInfo> pConfigRun;
  773. m_pEntity->GetFunction()->OpenConfig(Config_Run, pConfigRun);
  774. pConfigRun->ReadConfigValueInt("Main", "WKSyncSuccTime", nWKLastSyncTime);
  775. pConfigRun->ReadConfigValueInt("Main", "WKSyncFailCount", nWKSyncFailCount);
  776. SYSTEMTIME stSyncTime = CSmallDateTime(nWKLastSyncTime).ToSystemTime();
  777. Dbg("last WK sync time: %04d-%02d-%02d %02d:%02d:%02d",
  778. stSyncTime.wYear, stSyncTime.wMonth, stSyncTime.wDay,
  779. stSyncTime.wHour, stSyncTime.wMinute, stSyncTime.wSecond);
  780. SYSTEMTIME stNow = {};
  781. GetLocalTimeRVC(stNow);
  782. if (nWKLastSyncTime > 0 && stSyncTime.wYear == stNow.wYear
  783. && stSyncTime.wMonth == stNow.wMonth && stSyncTime.wDay == stNow.wDay
  784. && nWKSyncFailCount == 0) // 最近一次同步成功,才能跳过
  785. {
  786. Dbg("WK has been updated today");
  787. FSMEvent *pEvent = new FSMEvent(Event_IgnoreUpdateWK);
  788. PostEventFIFO(pEvent);
  789. }
  790. else
  791. {
  792. Dbg("begin update WK now");
  793. if (!m_bAccessACS) {
  794. // 请求WK
  795. DWORD rc = m_pConnection->SendWKUpdatePackage();
  796. if (rc != Error_Succeed)
  797. {
  798. doWarnMsg(ERR_ACCESSAUTH_UPDATE_WK,
  799. GetOutPutStr("%s%08X", "SendWKUpdatePackage", rc).c_str());
  800. FSMEvent* pEvent = new FSMEvent(Event_UpdateWKFail);
  801. PostEventFIFO(pEvent);
  802. }
  803. }
  804. else {
  805. if (pEntity->GetPinPadCapability() == 2 || pEntity->GetPinPadCapability() == 3)
  806. {
  807. CSmartPointer<UpdateWKTask> updateWKTask = new UpdateWKTask(this, pEntity);
  808. GetEntityBase()->GetFunction()->PostThreadPoolTask(updateWKTask.GetRawPointer());
  809. }
  810. else
  811. {
  812. PostEventFIFO(new FSMEvent(CAccessAuthFSM::Event_IgnoreUpdateWK));
  813. return 0;
  814. }
  815. }
  816. }
  817. #if defined(RVC_OS_LINUX)
  818. //if(lastTime != NULL) delete lastTime;
  819. //if(currentTime != NULL) delete currentTime;
  820. #endif
  821. return 0;
  822. }
  823. else if (pEvent->iEvt == Event_UpdateWKSucc)
  824. {
  825. Dbg("Event_UpdateWKSucc");
  826. // 上报状态
  827. //m_pConnection->SendReportStatePackage("UpdateWK", Error_Succeed, "更新工作密钥成功");
  828. // 保存WK同步时间
  829. #ifdef RVC_OS_WIN
  830. DWORD rc = m_pEntity->GetFunction()->SetSysVar("WKSyncSuccTime", (const char*)CSimpleStringA::Format("0x%08X", (DWORD)CSmallDateTime::GetNow()), true);
  831. #else
  832. TIME* tim = get_system_time();
  833. DWORD rc = m_pEntity->GetFunction()->SetSysVar("WKSyncSuccTime", time2str(tim).c_str(), true);
  834. delete tim;
  835. #endif
  836. assert(rc == Error_Succeed);
  837. rc = m_pEntity->GetFunction()->SetSysVar("WKSyncFailCount", "0", true);
  838. assert(rc == Error_Succeed);
  839. // 请求Token
  840. Dbg("begin get token now");
  841. if (!m_bAccessACS)
  842. {
  843. // 上报状态
  844. m_pConnection->SendReportStatePackage("UpdateWK", Error_Succeed, "更新工作密钥成功");
  845. rc = SecureClientConnect();
  846. if (rc == Error_Succeed)
  847. rc = m_pConnection->SendGetTokenPackage();
  848. if (rc != Error_Succeed)
  849. {
  850. FSMEvent* pEvent = new FSMEvent(Event_ReqTokenFail);
  851. PostEventFIFO(pEvent);
  852. }
  853. }
  854. else {
  855. CSmartPointer<GetTokenTask> getTokenTask = new GetTokenTask(this, (CAccessAuthEntity*) m_pEntity);
  856. GetEntityBase()->GetFunction()->PostThreadPoolTask(getTokenTask.GetRawPointer());
  857. }
  858. return 0;
  859. }
  860. else if (pEvent->iEvt == Event_IgnoreUpdateWK)
  861. {
  862. // 忽略同步WK,直接准入
  863. Dbg("ignore update wk, get token now");
  864. if (!m_bAccessACS)
  865. {
  866. DWORD rc = SecureClientConnect();
  867. if (rc == Error_Succeed)
  868. rc = m_pConnection->SendGetTokenPackage();
  869. if (rc != Error_Succeed)
  870. {
  871. FSMEvent* pEvent = new FSMEvent(Event_ReqTokenFail);
  872. PostEventFIFO(pEvent);
  873. }
  874. }
  875. else {
  876. CSmartPointer<GetTokenTask> getTokenTask = new GetTokenTask(this, (CAccessAuthEntity*)m_pEntity);
  877. GetEntityBase()->GetFunction()->PostThreadPoolTask(getTokenTask.GetRawPointer());
  878. }
  879. }
  880. else if (pEvent->iEvt == Event_UpdateWKFail)
  881. {
  882. Dbg("update pinpad WK fail");
  883. // 上报状态
  884. if (!m_bAccessACS) {
  885. m_pConnection->SendReportStatePackage("UpdateWK", Error_Unexpect, ((CAccessAuthEntity*)m_pEntity)->GetAuthErrMsg());
  886. }
  887. // zl@20190624 WKSyncFailCount迁移到系统变量
  888. CSimpleStringA strWKSyncFailCount = "";
  889. auto rc = m_pEntity->GetFunction()->GetSysVar("WKSyncFailCount", strWKSyncFailCount);
  890. assert(rc == Error_Succeed);
  891. int nWKSyncFailCount = atoi(strWKSyncFailCount);
  892. nWKSyncFailCount++;
  893. rc = m_pEntity->GetFunction()->SetSysVar("WKSyncFailCount", CSimpleStringA::Format("%d", nWKSyncFailCount), true);
  894. assert(rc == Error_Succeed);
  895. // xkm@20150702 启用新准入方案,密钥同步失败不得准入
  896. // xkm@20151116 失败3次以上应直接跳过同步,避免KMC故障时影响可视柜台准入
  897. // xkm@20161220 更新密钥失败直接准入
  898. PostEventFIFO(new FSMEvent(CAccessAuthFSM::Event_IgnoreUpdateWK));
  899. }
  900. else if (pEvent->iEvt == Event_ReqTokenFail)
  901. {
  902. Dbg("Event_ReqTokenFail");
  903. do {
  904. MyMutex myMut(&mut);
  905. if (m_finishAccess) return 0;
  906. m_finishAccess = 1;
  907. auto pEntity = (CAccessAuthEntity*)m_pEntity;
  908. CSimpleStringA strErrMsg = CSimpleStringA::Format("准入失败(%d)", m_finishAccess);
  909. pEntity->GetFunction()->ShowFatalError(strErrMsg);
  910. } while (0);
  911. // 上报状态
  912. if (!m_bAccessACS)
  913. {
  914. m_pConnection->SendReportStatePackage("AccessAuth", Error_Unexpect, ((CAccessAuthEntity*)m_pEntity)->GetAuthErrMsg());
  915. }
  916. return 0;
  917. }
  918. else if (pEvent->iEvt == Event_ReqTokenCancel)
  919. {
  920. auto pEntity = (CAccessAuthEntity*)m_pEntity;
  921. CSimpleStringA strErrMsg = CSimpleStringA::Format("准入超时(%d)", m_finishAccess);
  922. pEntity->GetFunction()->ShowFatalError(strErrMsg);
  923. // 上报状态
  924. if (!m_bAccessACS)
  925. {
  926. if (m_pConnection != NULL && m_pConnection->IsConnectionOK())
  927. {
  928. m_pConnection->SendReportStatePackage("AccessAuth", Error_TimeOut, "准入超时");
  929. }
  930. }
  931. return 0;
  932. }
  933. else if (pEvent->iEvt == Event_ReqTokenSucc)
  934. {
  935. Dbg("Event_ReqTokenSucc");
  936. do {
  937. MyMutex myMut(&mut);
  938. if (m_finishAccess) return 0;
  939. m_finishAccess = 1;
  940. } while (0);
  941. if (!m_bAccessACS)
  942. {
  943. m_pConnection->SendReportStatePackage("AccessAuth", Error_Succeed, "准入成功");
  944. }
  945. return 0;
  946. }
  947. else if (pEvent->iEvt == Event_NetworkIllegal)
  948. {
  949. pEvent->SetHandled();
  950. //禁止准入,如果关门有效,可以将上面这句显示在关门界面
  951. GetEntityBase()->GetFunction()->ShowFatalError("终端上网方式不符合规范要求,请整改后重试!");
  952. return 0;
  953. }
  954. return 0;
  955. }
  956. void CAccessAuthFSM::s3_on_entry()
  957. {
  958. SetSysVar("F");
  959. auto pEntity = (CAccessAuthEntity*)m_pEntity;
  960. CSimpleStringA strErrMsg = CSimpleStringA::Format("(%s)", (const char*)pEntity->GetAuthErrMsg());
  961. // 发送准入失败事件,暂时不发送事件进去关门界面,原因关门界面显示中文乱码
  962. //LogEvent(Severity_Middle, EVENT_ACCESSAUTH_FAILED, strErrMsg.GetData());
  963. doWarnMsg(EVENT_ACCESSAUTH_FAILED, strErrMsg.GetData(), true);
  964. pEntity->GetFunction()->ShowFatalError(strErrMsg);
  965. m_nAccessFailedCount = 0;
  966. }
  967. void CAccessAuthFSM::s3_on_exit()
  968. {
  969. }
  970. unsigned int CAccessAuthFSM::s3_on_event(FSMEvent* event)
  971. {
  972. return 0;
  973. }
  974. void CAccessAuthFSM::s4_on_entry()
  975. {
  976. SetSysVar("A");
  977. // 发送准入超时事件
  978. /*
  979. if (m_nAccessFailedCount >= 2)
  980. {
  981. LogEvent(Severity_Middle, EVENT_ACCESSAUTH_TIMEOUT,
  982. GetOutPutStr("%s%s", "准入", "超时").c_str());
  983. }
  984. */
  985. doWarnMsg(ERR_ACCESSAUTH_TIMEOUT, GetOutPutStr("%s%s", "准入", "超时").c_str(), true);
  986. LogEvent(Severity_Middle, EVENT_ACCESSAUTH_TIMEOUT,
  987. GetOutPutStr("%s%s", "准入", "超时").c_str());
  988. // 切换到s1
  989. PostEventFIFO(new FSMEvent(Event_StateTimeout));
  990. m_nAccessFailedCount++;
  991. }
  992. void CAccessAuthFSM::s4_on_exit()
  993. {
  994. }
  995. unsigned int CAccessAuthFSM::s4_on_event(FSMEvent* event)
  996. {
  997. return 0;
  998. }
  999. void CAccessAuthFSM::s5_on_entry()
  1000. {
  1001. SetSysVar("L");
  1002. LogEvent(Severity_Middle, EVENT_ACCESSAUTH_SUCCEED, "终端准入成功");
  1003. m_pEntity->GetFunction()->ShowStartupInfo("准入成功");
  1004. m_nAccessFailedCount = 0;
  1005. }
  1006. void CAccessAuthFSM::s5_on_exit()
  1007. {
  1008. }
  1009. unsigned int CAccessAuthFSM::s5_on_event(FSMEvent* pEvent)
  1010. {
  1011. if (pEvent->iEvt == Event_StartUnregist)
  1012. {
  1013. // 取出参数先保存
  1014. m_nExitReason = pEvent->param1;
  1015. m_nExitWay = pEvent->param2;
  1016. }
  1017. else if (pEvent->iEvt == Event_ReportStage)
  1018. {
  1019. // 上报状态
  1020. if (SecureClientConnect() == Error_Succeed)
  1021. {
  1022. ReportStateEvent *pReportEvent = (ReportStateEvent*)pEvent;
  1023. m_pConnection->SendTerminalStagePackage(pReportEvent->cNewStage, pReportEvent->dwNewStageTime,
  1024. pReportEvent->cOldStage, pReportEvent->dwOldStageTime);
  1025. }
  1026. }
  1027. return 0;
  1028. }
  1029. void CAccessAuthFSM::s6_on_entry()
  1030. {
  1031. SetSysVar("E");
  1032. if (SecureClientConnect() != Error_Succeed)
  1033. {
  1034. // 启动定时器尝试重试
  1035. Dbg("connect to AccessAuthorization service fail, start timer(30s) to retry");
  1036. ScheduleTimer(2, 30000);
  1037. return;
  1038. }
  1039. PostEventFIFO(new FSMEvent(Event_ConnectionOK));
  1040. }
  1041. void CAccessAuthFSM::s6_on_exit()
  1042. {
  1043. CancelTimer(2);
  1044. }
  1045. unsigned int CAccessAuthFSM::s6_on_event(FSMEvent* pEvent)
  1046. {
  1047. if (pEvent->iEvt == EVT_TIMER)
  1048. {
  1049. if (!m_bAccessACS) {
  1050. if (SecureClientConnect() != Error_Succeed)
  1051. {
  1052. // 启动定时器尝试重试
  1053. Dbg("connect to AccessAuthorization service fail, start timer to retry");
  1054. ScheduleTimer(2, 30000);
  1055. return 1;
  1056. }
  1057. }
  1058. PostEventFIFO(new FSMEvent(Event_ConnectionOK));
  1059. }
  1060. else if (pEvent->iEvt == Event_ConnectionOK)
  1061. {
  1062. // 请求退出
  1063. if (!m_bAccessACS) {
  1064. DWORD rc = m_pConnection->SendExitNoticePackage(m_nExitReason, m_nExitWay);
  1065. }
  1066. else {
  1067. CSmartPointer<TerminalExitTask> terminalExit = new TerminalExitTask(this);
  1068. GetEntityBase()->GetFunction()->PostThreadPoolTask(terminalExit.GetRawPointer());
  1069. }
  1070. // 切换到s1
  1071. PostEventFIFO(new FSMEvent(Event_StateTimeout));
  1072. }
  1073. return 0;
  1074. }
  1075. void CAccessAuthFSM::s7_on_entry()
  1076. {
  1077. SetSysVar("T");
  1078. // 过渡状态,立刻转入孤立状态
  1079. PostEventFIFO(new FSMEvent(Event_StateTimeout));
  1080. }
  1081. void CAccessAuthFSM::s7_on_exit()
  1082. {
  1083. }
  1084. unsigned int CAccessAuthFSM::s7_on_event(FSMEvent* event)
  1085. {
  1086. return 0;
  1087. }
  1088. /** 这样的函数命名也写得出来,表意不明并且跟框架的接口重复,谁知道要设置那个系统变量 [10/16/2021 Gifur] */
  1089. ErrorCodeEnum CAccessAuthFSM::SetSysVar(const CSimpleStringA &newVal)
  1090. {
  1091. CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();
  1092. return spFunction->SetSysVar("EntryPermit", (const char*)newVal);
  1093. }
  1094. DWORD CAccessAuthFSM::InitDevice(SpReqAnsContext<AccessAuthService_InitDev_Req, AccessAuthService_InitDev_Ans>::Pointer &ctx)
  1095. {
  1096. DWORD rc = 0;
  1097. if (!m_bAccessACS) {
  1098. rc = SecureClientConnect();
  1099. if (rc == Error_Succeed)
  1100. rc = m_pConnection->SendInitDevicePackage(ctx);
  1101. else
  1102. Dbg("secure connect fail");
  1103. if (rc != Error_Succeed)
  1104. {
  1105. ctx->Answer(rc ? Error_Unexpect : Error_Succeed);
  1106. return rc;
  1107. }
  1108. }
  1109. else{
  1110. InitDeviceReq req;
  1111. memset(&req, 0, sizeof(req));
  1112. strncpy(req.vtmCR1, (const char*)ctx->Req.EncR1, sizeof(req.vtmCR1));
  1113. strncpy(req.R2, (const char*)ctx->Req.R2, sizeof(req.R2));
  1114. strncpy(req.vtmCR3, (const char*)ctx->Req.EncR3, sizeof(req.vtmCR3));
  1115. strncpy(req.CDevPubKey, (const char*)ctx->Req.EncDevPubKey, sizeof(req.CDevPubKey));
  1116. strncpy(req.Verdor, (const char*)ctx->Req.Vendor, sizeof(req.Verdor));
  1117. m_pConnection->m_ctxInitDev = ctx;
  1118. CSmartPointer<InitDeviceTask> initDeviceTask = new InitDeviceTask(this, req);
  1119. GetEntityBase()->GetFunction()->PostThreadPoolTask(initDeviceTask.GetRawPointer());
  1120. }
  1121. return Error_Succeed;
  1122. }
  1123. DWORD CAccessAuthFSM::SyncTime()
  1124. {
  1125. auto rc = SecureClientConnect();
  1126. if (rc == Error_Succeed)
  1127. {
  1128. return m_pConnection->SendSyncTimePackageNew();
  1129. }
  1130. else
  1131. {
  1132. Dbg("secure connect fail");
  1133. return rc;
  1134. }
  1135. }
  1136. ErrorCodeEnum CAccessAuthFSM::LoadCenterConfig()
  1137. {
  1138. CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();
  1139. CSmartPointer<IConfigInfo> spConfig;
  1140. ErrorCodeEnum Error = spFunction->OpenConfig(Config_CenterSetting, spConfig);
  1141. if (Error_Succeed == Error)
  1142. {
  1143. Error = spConfig->ReadConfigValueInt("AccessAuthorization", "CheckMD5", m_nCheckMD5);
  1144. if (Error_Succeed == Error)
  1145. {
  1146. Dbg("get CheckMD5=%d from CenterSetting.ini", m_nCheckMD5);
  1147. }
  1148. else
  1149. {
  1150. Dbg("get CheckMD5 from CenterSetting.ini failed");
  1151. }
  1152. }
  1153. return Error;
  1154. }
  1155. BOOL CAccessAuthFSM::DetectNetworkLegality()
  1156. {
  1157. LOG_FUNCTION();
  1158. CSystemStaticInfo sysInfo;
  1159. CSmartPointer<IEntityFunction> spFunction = this->GetEntityBase()->GetFunction();
  1160. ErrorCodeEnum eErr = spFunction->GetSystemStaticInfo(sysInfo);
  1161. if(eErr != Error_Succeed) {
  1162. return TRUE;
  1163. }
  1164. //只针对行外PAD
  1165. if(0 != sysInfo.strMachineType.Compare("RVC.Pad", true) || 0 != sysInfo.strSite.Compare("cmb.FLB", true)) {
  1166. return TRUE;
  1167. }
  1168. CSimpleStringA csStatus;
  1169. unsigned int curTimes = 0;
  1170. const unsigned int maxTimes = 10;
  1171. do
  1172. {
  1173. csStatus.Clear();
  1174. eErr = spFunction->GetSysVar("NetState", csStatus);
  1175. if(eErr != Error_Succeed) {
  1176. return TRUE;
  1177. }
  1178. if(curTimes++ != 0) {
  1179. Sleep(300);
  1180. }
  1181. } while (csStatus.Compare("N") == 0 && curTimes <= maxTimes);
  1182. return (csStatus.Compare("F") != 0);
  1183. }
  1184. ErrorCodeEnum CAccessAuthFSM::GetIntFromCS(const char* pcSection, const char* pcKey, int& retInt) {
  1185. CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();
  1186. CSmartPointer<IConfigInfo> spConfig;
  1187. ErrorCodeEnum Error = spFunction->OpenConfig(Config_CenterSetting, spConfig);
  1188. if (Error_Succeed == Error)
  1189. {
  1190. Error = spConfig->ReadConfigValueInt(pcSection, pcKey, retInt);
  1191. if (Error_Succeed == Error)
  1192. {
  1193. Dbg("get retInt=%d from CenterSetting.ini", retInt);
  1194. }
  1195. else
  1196. {
  1197. Dbg("get retInt from CenterSetting.ini failed");
  1198. }
  1199. }
  1200. return Error;
  1201. }
  1202. ErrorCodeEnum CAccessAuthFSM::GetStrFromCS(const char* pcSection, const char* pcKey, CSimpleStringA& retStr) {
  1203. retStr = "";
  1204. CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();
  1205. CSmartPointer<IConfigInfo> spConfig;
  1206. ErrorCodeEnum Error = spFunction->OpenConfig(Config_CenterSetting, spConfig);
  1207. if (Error_Succeed == Error)
  1208. {
  1209. Error = spConfig->ReadConfigValue(pcSection, pcKey, retStr);
  1210. if (Error_Succeed == Error)
  1211. {
  1212. Dbg("get retStr=%s from CenterSetting.ini", retStr);
  1213. }
  1214. else
  1215. {
  1216. Dbg("get retStr from CenterSetting.ini failed");
  1217. }
  1218. }
  1219. return Error;
  1220. }
  1221. bool CAccessAuthFSM::DecryptWithSessionKey(BYTE* encText, int encTextLen, BYTE * decTest,int &decTestLen) {
  1222. BYTE key[16] = { 0 };
  1223. memcpy(key, ((CAccessAuthEntity*)m_pEntity)->m_AuthSessionKey,16);
  1224. char* keyTmp = Str2Hex((char *)key,16);
  1225. Dbg("keyTmp=%s",keyTmp);
  1226. delete keyTmp;
  1227. if (!DecWithSM4_ECB(key, encText, encTextLen, decTest, &decTestLen)) {
  1228. Dbg("DecryptWithSessionKey ECB error.");
  1229. return false;
  1230. }
  1231. keyTmp = Str2Hex((char*)decTest, decTestLen);
  1232. Dbg("keyTmp=%s", keyTmp);
  1233. delete keyTmp;
  1234. return true;
  1235. }
  1236. int CAccessAuthFSM::RtsMapToUserCode(const char* pRtsCode, DWORD dwDefaultUserCode)
  1237. {
  1238. LOG_FUNCTION();
  1239. Dbg("RtsCode:%s",pRtsCode);
  1240. CSmartPointer<IConfigInfo> pConfig;
  1241. m_pEntity->GetFunction()->OpenConfig(Config_Software, pConfig);
  1242. int tmpUserCode = 0;
  1243. pConfig->ReadConfigValueInt("RtsToUserCode", pRtsCode, tmpUserCode);
  1244. if (tmpUserCode > 0)
  1245. return tmpUserCode;
  1246. else
  1247. return dwDefaultUserCode;
  1248. }