#ifndef __ACCESSAUTHFSM_H #define __ACCESSAUTHFSM_H #include "SpBase.h" #include "SpFSM.h" #include "Blob.h" #include #include "EventCode.h" #include "AccessAuthConn.h" //#include "AccessAuthErrorCode.h" #include "IHttpFunc.h" #include "publicFunExport.h" #include static void GetLocalTimeRVC(SYSTEMTIME& stTime) { GetLocalTime(&stTime); } #define ACS_SUCCESS "0" #define REFLECTION(var) #var #define JUAGEHTTPS(ret) (ret.m_sysCode == 200 || ret.m_sysCode == 201) typedef struct CAccessAuthHttpsGateReq : public CHTTPReq { string terminal_no; string branch_no; string modular; CAccessAuthHttpsGateReq(string terminal, string branch, string module) : terminal_no(terminal), branch_no(branch), modular(module) { //m_url = "https://rvcgateway.paas.cmbchina.cn/api/gray/way"; } string ToJson() { Dbg("To Json"); map mapReq; mapReq[REFLECTION(terminal_no)] = terminal_no; Dbg("%s=%s", REFLECTION(terminal_no),terminal_no.c_str()); mapReq[REFLECTION(branch_no)] = branch_no; mapReq[REFLECTION(modular)] = modular; pair pairRet = generateJsonStr(mapReq); if (pairRet.first) return pairRet.second; else return ""; } } CAccessAuthHttpsGateReq; typedef struct CAccessAuthHttpsGateRet : public CHTTPRet { bool m_bACS; CAccessAuthHttpsGateRet(): m_bACS(false){} bool Parse(string strData) { Dbg("Parse Json"); Dbg("strData=%s", strData.c_str()); if (m_userCode.compare("10000")) return false; RVCJson rvcJson; rvcJson.SetJson((char*)strData.c_str()); m_bACS = rvcJson.GetBoolValue(REFLECTION(data)); rvcJson.Destory(); return true; } } CAccessAuthHttpsGateRet; /* typedef struct CAccessAuthBaseRet : CHTTPRet { string request; bool success; string code; string message; virtual void Parse(string strData) { RVCJson rvcJson; rvcJson.SetJson((char*)strData.c_str()); request = rvcJson.GetStringValue(REFLECTION(request)); success = rvcJson.GetBoolValue(REFLECTION(success)); code = rvcJson.GetStringValue(REFLECTION(code)); message = rvcJson.GetStringValue(REFLECTION(message)); } } CAccessAuthBaseRet; */ typedef struct CAccessAuthTimeSynReq : CHTTPReq { string terminalNo; long curTime; string reserved; CAccessAuthTimeSynReq(string terminalNo, long curTime, string reserved = "") : terminalNo(terminalNo), curTime(curTime) {} string ToJson() { RVCJson rvcJson(true); rvcJson.AddStringToObject(REFLECTION(terminalNo),(char*) terminalNo.c_str()); rvcJson.AddNumberToObject(REFLECTION(curTime), curTime); rvcJson.AddStringToObject(REFLECTION(reserved),(char*) reserved.c_str()); char* tmp = rvcJson.GetJsonStr(); rvcJson.Destory(); Dbg("req=%s at CAccessAuthTimeSynReq", tmp); string ret; ret.assign(tmp); delete tmp; return ret; } } CAccessAuthTimeSynReq; typedef struct CAccessAuthTimeSynRet : CHTTPRet { struct data { long timeDiff; int authVersion; string sessionKey; string reserved; } data; bool Parse(string strData) { Dbg("ret=%s at CAccessAuthTimeSynRet", strData.c_str()); if (m_userCode.compare(ACS_SUCCESS)) return true; RVCJson rvcJson; rvcJson.SetJson(strData.c_str()); auto retJson = rvcJson.GetJsonValue(REFLECTION(data)); data.timeDiff = retJson->GetNumberValue(REFLECTION(timeDiff)); data.authVersion = retJson->GetNumberIntValue(REFLECTION(authVersion)); data.sessionKey = retJson->GetStringValue(REFLECTION(sessionKey)); char * tmpReserved = retJson->GetStringValue(REFLECTION(reserved)); data.reserved = tmpReserved == NULL ? "" : tmpReserved; rvcJson.Destory(); retJson->Destory(); delete retJson; return true; } } CAccessAuthTimeSynRet; typedef struct CAccessAuthLockStateReq : CHTTPReq { string terminalNo; CAccessAuthLockStateReq(string terminalNo) : terminalNo(terminalNo) {} string ToJson() { RVCJson rvcJson(true); rvcJson.AddStringToObject(REFLECTION(terminalNo),(char*) terminalNo.c_str()); string ret; char* tmp = rvcJson.GetJsonStr(); ret.assign(tmp); delete tmp; rvcJson.Destory(); Dbg("req=%s at CAccessAuthLockStateReq", ret.c_str()); return ret; } } CAccessAuthLockStateReq; typedef struct CAccessAuthLockStateRet : CHTTPRet { struct data { string lockState; } data; bool Parse(string strData) { Dbg("ret=%s at CAccessAuthLockStateRet", strData.c_str()); if (m_userCode.compare(ACS_SUCCESS)) return true; RVCJson rvcJson; rvcJson.SetJson(strData.c_str()); auto retJson = rvcJson.GetJsonValue(REFLECTION(data)); data.lockState = retJson->GetStringValue(REFLECTION(lockState)); rvcJson.Destory(); retJson->Destory(); delete retJson; return true; } } CAccessAuthLockStateRet; typedef struct CAccessAuthUpdateWKReq : CHTTPReq { string terminalNo; CAccessAuthUpdateWKReq(string terminalNo) : terminalNo(terminalNo) {} string ToJson() { RVCJson rvcJson(true); rvcJson.AddStringToObject(REFLECTION(terminalNo),(char*) terminalNo.c_str()); string ret; char* tmp = rvcJson.GetJsonStr(); ret.assign(tmp); delete tmp; rvcJson.Destory(); Dbg("req=%s at CAccessAuthUpdateWKReq", ret.c_str()); return ret; } } CAccessAuthUpdateWKReq; typedef struct CAccessAuthUpdateWKRet : CHTTPRet { struct data { string TMK; string TPK; string EDK; string index; string reserved; } data; bool Parse(string strData) { Dbg("ret=%s at CAccessAuthUpdateWKRet", strData.c_str()); if (m_userCode.compare(ACS_SUCCESS)) return true; RVCJson rvcJson; rvcJson.SetJson((char*)strData.c_str()); auto retJson = rvcJson.GetJsonValue(REFLECTION(data)); data.TMK = retJson->GetStringValue(REFLECTION(TMK)); data.TPK = retJson->GetStringValue(REFLECTION(TPK)); data.EDK = retJson->GetStringValue(REFLECTION(EDK)); data.index = retJson->GetStringValue(REFLECTION(index)); rvcJson.Destory(); retJson->Destory(); delete retJson; return true; } } CAccessAuthUpdateWKRet; typedef struct CAccessAuthGetTokenReq :public CHTTPReq { public: struct TOKEN_R0 { int isSM; int isFirst; string fingerPrintSM; } TOKEN_R0; struct TOKEN_R1 { string terminalNo; string TPK; string encTerminalInfo; } TOKEN_R1; struct TOKEN_R2 { string type; string modal; string factory; string versoin; }**TOKEN_R2; struct TOKEN_R3 { string signCertHash; string uKeyRootHash; int authVersion; string fingerPrint; string publicKey; string kmcSyncFlag; string reserved; } TOKEN_R3; struct TOKEN_R4 { string pinPadID; string reserved; }TOKEN_R4; struct TOKEN_R5 { int existPinPad; } TOKEN_R5; int R2Count; CAccessAuthGetTokenReq(int R2Count) : R2Count(R2Count){ TOKEN_R2 = new struct TOKEN_R2 *[R2Count]; for (int i = 0; i < R2Count; i++) { TOKEN_R2[i] = new struct TOKEN_R2; } } string ToJson() { RVCJson rvcJson(true); RVCJson *tokenJson[6]; for (int i = 0; i < 6; i++){ if(i == 2) tokenJson[i] = new RVCJson(false); else tokenJson[i] = new RVCJson(true); } tokenJson[0]->AddStringToObject(REFLECTION(fingerPrintSM),(char*) TOKEN_R0.fingerPrintSM.c_str()); tokenJson[0]->AddNumberToObject(REFLECTION(isFirst), TOKEN_R0.isFirst); tokenJson[0]->AddNumberToObject(REFLECTION(isSM), TOKEN_R0.isSM); Dbg("R0=%s",tokenJson[0]->GetJsonStr()); tokenJson[1]->AddStringToObject(REFLECTION(terminalNo),(char*) TOKEN_R1.terminalNo.c_str()); tokenJson[1]->AddStringToObject(REFLECTION(TPK),(char*) TOKEN_R1.TPK.c_str()); tokenJson[1]->AddStringToObject(REFLECTION(encTerminalInfo),(char*) TOKEN_R1.encTerminalInfo.c_str()); Dbg("R1=%s", tokenJson[1]->GetJsonStr()); for (int i = 0; i < R2Count; i++) { RVCJson R2Json(true); R2Json.AddStringToObject(REFLECTION(type),(char*) TOKEN_R2[i]->type.c_str()); R2Json.AddStringToObject(REFLECTION(modal),(char*) TOKEN_R2[i]->modal.c_str()); R2Json.AddStringToObject(REFLECTION(factory),(char*) TOKEN_R2[i]->factory.c_str()); R2Json.AddStringToObject(REFLECTION(versoin),(char*) TOKEN_R2[i]->versoin.c_str()); Dbg("R_=%s", R2Json.GetJsonStr()); tokenJson[2]->AddItemToArray(&R2Json); R2Json.Destory(); } Dbg("R2=%s", tokenJson[2]->GetJsonStr()); tokenJson[3]->AddStringToObject(REFLECTION(signCertHash),(char*) TOKEN_R3.signCertHash.c_str()); tokenJson[3]->AddStringToObject(REFLECTION(uKeyRootHash),(char*) TOKEN_R3.uKeyRootHash.c_str()); tokenJson[3]->AddNumberToObject(REFLECTION(authVersion), TOKEN_R3.authVersion); tokenJson[3]->AddStringToObject(REFLECTION(fingerPrint),(char*) TOKEN_R3.fingerPrint.c_str()); tokenJson[3]->AddStringToObject(REFLECTION(publicKey),(char*) TOKEN_R3.publicKey.c_str()); tokenJson[3]->AddStringToObject(REFLECTION(kmcSyncFlag),(char*) TOKEN_R3.kmcSyncFlag.c_str()); tokenJson[3]->AddStringToObject(REFLECTION(reserved),(char*) TOKEN_R3.reserved.c_str()); Dbg("R3=%s", tokenJson[3]->GetJsonStr()); tokenJson[4]->AddStringToObject(REFLECTION(pinPadID),(char*) TOKEN_R4.pinPadID.c_str()); tokenJson[4]->AddStringToObject(REFLECTION(reserved),(char*) TOKEN_R4.reserved.c_str()); Dbg("R4=%s", tokenJson[4]->GetJsonStr()); tokenJson[5]->AddNumberToObject(REFLECTION(existPinPad),TOKEN_R5.existPinPad); Dbg("R5=%s", tokenJson[5]->GetJsonStr()); for (int i = 0; i < 6; i++) { string strTmp = int2str(i); strTmp = "TOKEN_R" + strTmp; rvcJson.AddItemToObject(strTmp.c_str(), tokenJson[i]); } char *tmp = rvcJson.GetJsonStr(); string ret(tmp); delete tmp; Dbg("req=%s at CAccessAuthGetTokenReq", ret.c_str()); for (int i = 0; i < 6; i++) { tokenJson[i]->Destory(); delete tokenJson[i]; } rvcJson.Destory(); return ret; } }CAccessAuthGetTokenReq; typedef struct CAccessAuthGetTokenRet : CHTTPRet { typedef struct AccessToken { string enToken; string retHash; } AccessToken; typedef struct SharedKey { string enToken; string sharedSK; string retHash; } ShareKey; struct data { AccessToken accessToken; SharedKey sharedKey; } data; bool Parse(string strData) { Dbg("ret=%s at CAccessAuthGetTokenRet", strData.c_str()); if (m_userCode.compare(ACS_SUCCESS)) return true; RVCJson rvcJson; rvcJson.SetJson(strData.c_str()); auto dataJson = rvcJson.GetJsonValue(REFLECTION(data)); auto tokenJson = dataJson->GetJsonValue(REFLECTION(accessToken)); data.accessToken.enToken = tokenJson->GetStringValue(REFLECTION(enToken)); data.accessToken.retHash = tokenJson->GetStringValue(REFLECTION(retHash)); tokenJson->Destory(); delete tokenJson; auto sharedJson = dataJson->GetJsonValue(REFLECTION(sharedKey)); data.sharedKey.enToken = sharedJson->GetStringValue(REFLECTION(enToken)); data.sharedKey.sharedSK = sharedJson->GetStringValue(REFLECTION(sharedSK)); char* tmp = sharedJson->GetStringValue(REFLECTION(retHash)); data.sharedKey.retHash = tmp == NULL?"":tmp; sharedJson->Destory(); delete sharedJson; dataJson->Destory(); delete dataJson; rvcJson.Destory(); Dbg("leave CAccessAuthGetTokenRet."); return true; } } CAccessAuthGetTokenRet; typedef struct CAccessAuthStageReportReq : CHTTPReq { string terminalNo; string newStage; string ip; string runState; string ToJson() { RVCJson rvcJson(true); rvcJson.AddStringToObject(REFLECTION(terminalNo),(char*) terminalNo.c_str()); rvcJson.AddStringToObject(REFLECTION(newStage),(char*) newStage.c_str()); rvcJson.AddStringToObject(REFLECTION(ip),(char*) ip.c_str()); rvcJson.AddStringToObject(REFLECTION(runState),(char*) runState.c_str()); string ret; char* tmp = rvcJson.GetJsonStr(); ret.assign(tmp); delete tmp; Dbg("req=%s at CAccessAuthStageReportReq", ret.c_str()); return ret; } } CAccessAuthStageReportReq; typedef struct CAccessAuthStageReportRet : CHTTPRet { bool Parse(string strData) { //if (m_userCode.compare(ACS_SUCCESS)) return false; return true; } } CAccessAuthStageReportRet; typedef struct CAccessAuthInitDeviceReq : CHTTPReq { string cr1; string cr3; string r2; string cDevPubKey; string vendor; string terminalNo; string ToJson() { RVCJson rvcJson(true); rvcJson.AddStringToObject(REFLECTION(cr1),(char*) cr1.c_str()); rvcJson.AddStringToObject(REFLECTION(cr3),(char*) cr3.c_str()); rvcJson.AddStringToObject(REFLECTION(r2),(char*) r2.c_str()); rvcJson.AddStringToObject(REFLECTION(cDevPubKey),(char*) cDevPubKey.c_str()); rvcJson.AddStringToObject(REFLECTION(vendor),(char*) vendor.c_str()); rvcJson.AddStringToObject(REFLECTION(terminalNo), (char*)terminalNo.c_str()); string ret; char* tmp = rvcJson.GetJsonStr(); ret.assign(tmp); delete tmp; Dbg("req=%s at CAccessAuthInitDeviceReq", ret.c_str()); rvcJson.Destory(); return ret; } } CAccessAuthInitDeviceReq; typedef struct CAccessAuthInitDeviceRet : CHTTPRet { struct data { string r3; string cr2; string r1; }data; bool Parse(string strData) { Dbg("ret=%s at CAccessAuthInitDeviceRet", strData.c_str()); if (m_userCode.compare(ACS_SUCCESS)) return true; RVCJson rvcJson; rvcJson.SetJson((char*)strData.c_str()); auto retJson = rvcJson.GetJsonValue(REFLECTION(data)); //data.r3 = retJson->GetNumberValue(REFLECTION(r3)); data.r3 = retJson->GetStringValue(REFLECTION(r3)); //data.cr2 = retJson->GetNumberValue(REFLECTION(cr2)); data.cr2 = retJson->GetStringValue(REFLECTION(cr2)); //data.r1 = retJson->GetNumberValue(REFLECTION(r1)); data.r1 = retJson->GetStringValue(REFLECTION(r1)); rvcJson.Destory(); return true; } } CAccessAuthInitDeviceRet; typedef struct CAccessAuthExitReq : CHTTPReq { string terminalNo; int triggerReason; int rebootWay; int terminalStage; string ToJson() { RVCJson rvcJson(true); rvcJson.AddStringToObject(REFLECTION(terminalNo),(char*) terminalNo.c_str()); rvcJson.AddNumberToObject(REFLECTION(triggerReason),triggerReason); rvcJson.AddNumberToObject(REFLECTION(rebootWay), rebootWay); rvcJson.AddNumberToObject(REFLECTION(terminalStage), terminalStage); string ret; char* tmp = rvcJson.GetJsonStr(); ret.assign(tmp); delete tmp; Dbg("req=%s at CAccessAuthExitReq", ret.c_str()); return ret; } } CAccessAuthExitReq; typedef struct CAccessAuthExitRet : CHTTPRet { bool Parse(string strData) { if (m_userCode.compare(ACS_SUCCESS)) return true; if (strData.empty()) Dbg("ret is NULL at CAccessAuthExitReq"); else { Dbg("ret=%s at CAccessAuthExitReq",strData.c_str()); } return true; } } CAccessAuthExitRet; class MyMutex; class CAccessAuthFSM : public FSMImpl, public IFSMStateHooker { public: struct ReportStateEvent : public FSMEvent { ReportStateEvent(char cNewStage, DWORD dwNewStageTime, char cOldStage, DWORD dwOldStageTime): FSMEvent(Event_ReportStage), cNewStage(cNewStage), dwNewStageTime(dwNewStageTime), cOldStage(cOldStage), dwOldStageTime(dwOldStageTime) {} char cNewStage; char cOldStage; DWORD dwNewStageTime; DWORD dwOldStageTime; }; CAccessAuthFSM(); virtual ~CAccessAuthFSM(); virtual void OnStateTrans(int iSrcState, int iDstState); virtual ErrorCodeEnum OnInit(); virtual ErrorCodeEnum OnExit(); enum{s1, s2, s3, s4, s5, s6, s7}; enum { Event_StartRegist = EVT_USER+1, Event_StartReregist, Event_ConnectionOK, Event_EndSyncTime, Event_UpdateWKSucc, Event_IgnoreUpdateWK, Event_UpdateWKFail, Event_ReqTokenSucc, Event_ReqTokenFail, Event_ReqTokenCancel, Event_StartUnregist, Event_LostTrust, Event_StateTimeout, // 临时状态超时 Event_ReportStage, Event_CheckMD5Succ, Event_CheckMD5Fail, Event_InitFinishOK, Event_GetHsotFailed, Event_NetworkIllegal, Event_SyncTimeFailed //同步时间失败 }; BEGIN_FSM_STATE(CAccessAuthFSM) FSM_STATE_ENTRY(s1, "Isolate",s1_on_entry,s1_on_exit,s1_on_event) FSM_STATE_ENTRY(s2, "Checking",s2_on_entry,s2_on_exit,s2_on_event) //开始准入 FSM_STATE_ENTRY(s3, "Failure",s3_on_entry,s3_on_exit,s3_on_event) //准入失败 FSM_STATE_ENTRY(s4, "Cancel", s4_on_entry, s4_on_exit, s4_on_event) //准入超时 FSM_STATE_ENTRY(s5, "Login", s5_on_entry, s5_on_exit, s5_on_event) //准入成功 FSM_STATE_ENTRY(s6, "Leaving", s6_on_entry, s6_on_exit, s6_on_event) FSM_STATE_ENTRY(s7, "LostTrust", s7_on_entry, s7_on_exit, s7_on_event) END_FSM_STATE() BEGIN_FSM_RULE(CAccessAuthFSM,s1) FSM_RULE_ENTRY_ANY(s1, s2, Event_StartRegist) FSM_RULE_ENTRY_ANY(s1, s3, Event_GetHsotFailed) //FSM_RULE_ENTRY_ANY(s2, s3, Event_UpdateWKFail) FSM_RULE_ENTRY_ANY(s2, s3, Event_ReqTokenFail) FSM_RULE_ENTRY_ANY(s2, s3, Event_CheckMD5Fail) FSM_RULE_ENTRY_ANY(s2, s3, Event_NetworkIllegal) FSM_RULE_ENTRY_ANY(s2, s4, Event_ReqTokenCancel) FSM_RULE_ENTRY_ANY(s2, s5, Event_ReqTokenSucc) FSM_RULE_ENTRY_ANY(s2, s3, Event_SyncTimeFailed) FSM_RULE_ENTRY_ANY(s3, s2, Event_StartRegist) FSM_RULE_ENTRY_ANY(s4, s1, Event_StateTimeout) FSM_RULE_ENTRY_ANY(s5, s6, Event_StartUnregist) FSM_RULE_ENTRY_ANY(s5, s2, Event_StartReregist) FSM_RULE_ENTRY_ANY(s5, s2, Event_StartRegist) FSM_RULE_ENTRY_ANY(s5, s7, Event_LostTrust) FSM_RULE_ENTRY_ANY(s6, s1, Event_StateTimeout) FSM_RULE_ENTRY_ANY(s7, s1, Event_StateTimeout) END_FSM_RULE() void s1_on_entry(); void s1_on_exit(); unsigned int s1_on_event(FSMEvent* event); void s2_on_entry(); void s2_on_exit(); unsigned int s2_on_event(FSMEvent* event); void s3_on_entry(); void s3_on_exit(); unsigned int s3_on_event(FSMEvent* event); void s4_on_entry(); void s4_on_exit(); unsigned int s4_on_event(FSMEvent* event); void s5_on_entry(); void s5_on_exit(); unsigned int s5_on_event(FSMEvent* event); void s6_on_entry(); void s6_on_exit(); unsigned int s6_on_event(FSMEvent* event); void s7_on_entry(); void s7_on_exit(); unsigned int s7_on_event(FSMEvent* event); public: DWORD InitDevice(SpReqAnsContext::Pointer &ctx); DWORD SyncTime(); int m_finishAccess; static void HttpsLogCallBack(const char *logtxt); bool m_bAccessACS; CAccessAuthConn* m_pConnection; CSimpleStringA GetmAccessAuthHost(); CSimpleStringA GetmInitDeviceHost() { return m_initDeviceHost; } CSimpleStringA GetmTerminalList() { return m_terminalList; } int GetmnExitReason() { return m_nExitReason; } int GetmnExitWay() { return m_nExitWay; } bool DecryptWithSessionKey(BYTE* encText, int encTextLen, BYTE* decTest, int& decTestLen); //oilyang@20210813 add bNeedEvent. //no need to throw event defaultly except the KEY error to call for Close Page void doWarnMsg(int errReason, std::string errMsg, bool bNeedEvent = false,string varMsg = ""); int RtsMapToUserCode(const char* pRtsCode,DWORD dwDefaultUserCode = ERR_ACCESSAUTH_UNKOWN); private: ErrorCodeEnum SetSysVar(const CSimpleStringA &newVal); ErrorCodeEnum SecureClientConnect(); ErrorCodeEnum SecureClientRelease(); ErrorCodeEnum LoadCenterConfig(); /*True: Legal; False: illegal*/ BOOL DetectNetworkLegality(); int m_nExitReason; int m_nExitWay; CSimpleStringA m_accessAuthHost; CSimpleStringA m_initDeviceHost; CSimpleStringA m_terminalList; ErrorCodeEnum GetIntFromCS(const char* pcSection, const char* pcKey, int &retInt); ErrorCodeEnum GetStrFromCS(const char* pcSection, const char* pcKey, CSimpleStringA& retStr); int m_nCheckMD5; //oilyang@20210813 实际上上次关门页改造应该把这个去掉,已经有了(不)重试(不)重启的模式组合 int m_nAccessFailedCount; }; class MyMutex { public: explicit MyMutex(std::mutex* pm):mut(pm) { mut->lock(); } ~MyMutex() { mut->unlock(); } private: std::mutex* mut; }; #endif // !__ACCESSAUTHFSM_H