#include "SpSecureClient.h" #include "sp_cfg.h" #include "sp_env.h" #include "spShareMemoryBase.h" #include "sp_checkEntity.h" #include "TokenKeeper_client_g.h" using namespace TokenKeeper; #include enum CommEventEnum { //连接主用地址 事件 1 0xNNN08001 连接配置文件定义的主用地址,需要记录地址信息。如果为短连接,记录首次连接事件。 CE_ConnectMasterServer = 0x00008001, //连接备用地址 事件 1 0xNNN08002 如果没有定义备用地址,就不会有这条信息 CE_ConnectSlaveServer = 0x00008002, //主动断开连接 事件 1 0xNNN08011 如果为短连接,无需记录此事件 CE_ActiveClose = 0x00008011, //读取配置失败 错误 3 0xNNN08021 不能读到需要配置项,代码或配置有误,可以切换备份区域,或需要人干预 CE_ReadCfgFail = 0x00008021, //连接地址无效 错误 2 0xNNN88031 对端不存在,配置错误,或当前服务器故障 CE_InvalidAddr = 0x00088031, //对端拒绝连接 错误 2 0xNNN88032 对端存在,但可能故障,导致服务器拒绝建立连接 CE_PeerReject = 0x00088032, //连接超时 错误 2 0xNNN88033 等待连接超时 CE_ConnectTimeout = 0x00088033, //容量拒绝 错误 2 0xNNN88034 由于达到后台的最大容量,连接拒绝,需要重试 CE_ReachMaxNum = 0x00088034, //服务暂停 错误 2 0xNNN88035 后台暂停服务,实体可以切换主备服务或抛出连接失败,切换备份区域 CE_OutOfService = 0x00088035, //失去连接 错误 2 0xNNN88036 由于对端或网络原因连接断开 CE_LostConnection = 0x00088036, //无效请求包 错误 3 0xNNN88041 实体或后台代码错误,需要进行人工修复。在描述中应该说明错误的原因。 CE_InvalidReqPack = 0x00088041, //鉴权不可识别 错误 3 0xNNN88051 由于服务准入服务证书不符,不能解开请求包,错误需要干预,不能自动修复。 CE_AuthFailed = 0x00088051, //鉴权信息不匹配 错误 2 0xNNN88052 请求时鉴权信息不匹配,需要重新进行准入。 CE_HashMismatch = 0x00088052, //当前区域连接失败 事件 2 0xNNN880F1 由于多次尝试失败,或发生不可尝试错误,实体放弃了当前区域连接尝试,用于驱动状态切换。记录区域代码。 CE_CurRegionDisabled = 0x000880F1, }; // 不应该直接delete,而用DecRef() SpSecureClient::~SpSecureClient() { } SpSecureClient::SpSecureClient(CEntityBase *pEntityBase) : m_pEntity(pEntityBase), m_bClosed(true) { //Dbg("SpSecureClient"); } bool SpSecureClient::Connect(const char *pServerAddr, int nPort, int nOption) // wait until all authentication operation has been finished { assert(m_pEntity != NULL); bool result = false; Dbg("connect to %s:%d, option=%d...", pServerAddr, nPort, nOption); if (GetFunction()->Connect(pServerAddr, nPort, nOption)) { m_bClosed = false; result = true; } Dbg("connect to %s:%d, option=%d, result:%s", pServerAddr, nPort, nOption, result ? "SUCCESS" : "FAIL"); return result; } // 使用配置项连接, 连接参数从实体配置文件中读取 [Main]/Server和[Main]/Server_Backup项 // @option:1、重新鉴权新建会话密钥;2、通过握手使用缓存会话密钥; // 3、不使用会话密钥,即非安全通道; 4、不协商,直接使用共享会话密钥 bool SpSecureClient::ConnectFromConfig(int nOption) { if (IsConnectionOK()) return true; const char* pEntityName = m_pEntity->GetEntityName(); ENTITY_CONNECT_INFO connectInfo; if (!readConnectInfoFromConfig(pEntityName, &connectInfo)) { Dbg("Read %s Info Failed", pEntityName); return false; } // 判断当前是否已经准入,已准入时强制使用加密通道 int nActOption = nOption; CSimpleStringA strVal; const ErrorCodeEnum result = m_pEntity->GetFunction()->GetSysVar("EntryPermit", strVal); if (Error_Succeed != result) { Dbg("Read SysVal '' failed, ec=%s", SpStrError(result)); return false; } if (strVal == "L" && stricmp(pEntityName, "AccessAuthorization") != 0 && stricmp(pEntityName, "Initializer") != 0) nActOption = 2; // 优先使用缓存密钥 if (1 == connectInfo.m_DualActive) return Connect_Dual(&connectInfo, nOption); else return Connect_Single(&connectInfo, nOption); } bool SpSecureClient::readConnectInfoFromConfig(const char *pEntityName, ENTITY_CONNECT_INFO *connectInfo) { if (NULL == pEntityName || NULL == connectInfo) return false; connectControl *entityConnect = connectControl::getInstance(); bool readSuccess = entityConnect->getEntityInfo(pEntityName, connectInfo); auto pFunc = m_pEntity->GetFunction(); CSmartPointer spConfig; if (Error_Succeed != pFunc->OpenConfig(Config_CenterSetting, spConfig)) { Dbg("open center setting config fail"); return false; } CSimpleStringA str; int readEach = 0; if (Error_Succeed == spConfig->ReadConfigValue("SpBase", "ReadEach", str) && !str.IsNullOrEmpty()) readEach = atoi(str); if (0 == readEach && readSuccess) return true;//不是每次都读取新的Entity的IP和Port,只在实体启动时读取一次 int dualActive = -1; if (Error_Succeed == spConfig->ReadConfigValue("SpBase", "DualActive", str) && !str.IsNullOrEmpty()) dualActive = atoi(str); if (Error_Succeed != pFunc->OpenConfig(Config_Software, spConfig)) { Dbg("open entity config fail"); return false; } if (Error_Succeed != spConfig->ReadConfigValue("Main", "Server", str) || str.IsNullOrEmpty()) { Dbg("read Main::Server config fail"); return false; } CSimpleStringA strServer1; int nServer1Port; if (Error_Succeed != ParseIPAddress(str, strServer1, nServer1Port)) { Dbg("parse ip addr fail: %s", (const char*)str); return false; } CSimpleStringA strServer2; int nServer2Port = 0; if (Error_Succeed == spConfig->ReadConfigValue("Main", "Server_Backup", str) && !str.IsNullOrEmpty()) ParseIPAddress(str, strServer2, nServer2Port); if (readSuccess) connectInfo->setParam(pEntityName, strServer1.GetData(), nServer1Port, strServer2.GetData(), nServer2Port, dualActive, connectInfo->m_currentLink); else { connectInfo->clear(); connectInfo->setParam(pEntityName, strServer1.GetData(), nServer1Port, strServer2.GetData(), nServer2Port, dualActive); } entityConnect->setEntityInfo(connectInfo); return true; } void SpSecureClient::connectClose(const char *pEntityName) { if (NULL == pEntityName) return; ENTITY_CONNECT_INFO connectInfo; if (!findConnectInfo(pEntityName, &connectInfo)) { m_log.LOGERROR("can note find %s in connection list.", pEntityName); return; } connectInfo.m_currentLink = -1; } bool SpSecureClient::findConnectInfo(const char *pEntityName, ENTITY_CONNECT_INFO *connectInfo) { if (NULL == pEntityName || NULL == connectInfo) return false; connectControl *entityConnect = connectControl::getInstance(); if (entityConnect->getEntityInfo(pEntityName, connectInfo)) return true; return false; } bool SpSecureClient::readConnectInfoFromCentralSetting(const char *pEntityName, ENTITY_CONNECT_INFO *connectInfo) { if (NULL == pEntityName || NULL == connectInfo) return false; connectControl *entityConnect = connectControl::getInstance(); bool readSuccess = entityConnect->getEntityInfo(pEntityName, connectInfo); //获得集中配置信息 auto pFunc = m_pEntity->GetFunction(); CSmartPointer spConfig; if (Error_Succeed != pFunc->OpenConfig(Config_CenterSetting, spConfig)) { Dbg("open center setting config fail"); return false; } CSimpleStringA str; int readEach = 1; if (Error_Succeed == spConfig->ReadConfigValue("SpBase", "ReadEach", str) && !str.IsNullOrEmpty()) readEach = atoi(str); if (0 == readEach && readSuccess) return true;//不是每次都读取新的Entity的IP和Port,只在实体启动时读取一次 if (Error_Succeed != spConfig->ReadConfigValue(pEntityName, "Server", str) || str.IsNullOrEmpty()) { Dbg("read Main::Server config fail"); return false; } CSimpleStringA strServer1; int nServer1Port; if (Error_Succeed != ParseIPAddress(str, strServer1, nServer1Port)) { Dbg("parse ip addr fail: %s", (const char*)str); return false; } CSimpleStringA strServer2 = ""; int nServer2Port = 0; if (Error_Succeed == spConfig->ReadConfigValue(pEntityName, "Server_Backup", str) && !str.IsNullOrEmpty()) ParseIPAddress(str, strServer2, nServer2Port); int dualActive = -1; if (Error_Succeed == spConfig->ReadConfigValue("SpBase", "DualActive", str) && !str.IsNullOrEmpty()) dualActive = atoi(str); if (readSuccess) connectInfo->setParam(pEntityName, strServer1.GetData(), nServer1Port, strServer2.GetData(), nServer2Port, dualActive, connectInfo->m_currentLink); else { //m_log.LOGERROR("call clear"); connectInfo->clear(); connectInfo->setParam(pEntityName, strServer1.GetData(), nServer1Port, strServer2.GetData(), nServer2Port, dualActive); } entityConnect->setEntityInfo(connectInfo); return true; } bool SpSecureClient::setConnectInfo(const ENTITY_CONNECT_INFO *connectInfo) { if (NULL == connectInfo) return false; connectControl *entityConnect = connectControl::getInstance(); entityConnect->setLastLink(connectInfo->m_currentLink); return entityConnect->setEntityInfo(connectInfo); } // 使用集中配置项连接 bool SpSecureClient::ConnectFromCentralSetting() { SetthreadGroup(GetCurrentThreadId(), m_pEntity->GetEntityName()); if (IsConnectionOK()) return true; const char* pEntityName = m_pEntity->GetEntityName(); ENTITY_CONNECT_INFO connectInfo; if (!readConnectInfoFromCentralSetting(pEntityName, &connectInfo)) { Dbg("Read %s Info Failed", pEntityName); m_log.LOGERROR("Read %s Info Failed", pEntityName); return false; } // 判断当前是否已经准入,已经准入则强制使用安全连接 int nOption = 3; CSimpleStringA strVal; m_pEntity->GetFunction()->GetSysVar("EntryPermit", strVal); if (strVal == "L" && stricmp(pEntityName, "AccessAuthorization") != 0 && stricmp(pEntityName, "Initializer") != 0) nOption = 2; // 优先使用缓存密钥 //Dbg("connect using center setting"); if (1 == connectInfo.m_DualActive) return Connect_Dual(&connectInfo, nOption); else return Connect_Single(&connectInfo, nOption); } int SpSecureClient::getCurrentLink() { if (!IsConnectionOK()) return -1; const char* pEntityName = m_pEntity->GetEntityName(); ENTITY_CONNECT_INFO connectInfo; if (!readConnectInfoFromCentralSetting(pEntityName, &connectInfo)) { Dbg("Read %s Info Failed", pEntityName); return -1; } return connectInfo.m_currentLink; } bool SpSecureClient::Connect_Single(ENTITY_CONNECT_INFO *connectInfo, int option) { if (NULL == connectInfo || 0 == strlen(connectInfo->m_EntityName)) return false; Dbg("single connect, entity %s using option %d", connectInfo->m_EntityName, option); if (Connect(connectInfo->m_ServerIP, connectInfo->m_ServerPort, option)) connectInfo->m_currentLink = 0; else if (0 != strlen(connectInfo->m_Server_BackupIP) && strcmp(connectInfo->m_ServerIP, connectInfo->m_Server_BackupIP) && Connect(connectInfo->m_Server_BackupIP, connectInfo->m_Server_BackupPort, option)) connectInfo->m_currentLink = 1; else connectInfo->m_currentLink = -1; setConnectInfo(connectInfo); m_log.LOGERROR("Single Connection: EntityName:%s, server:%s %d, serverBackup:%s %d, DualOpen: %d, currentLink:%d", connectInfo->m_EntityName, connectInfo->m_ServerIP, connectInfo->m_ServerPort, connectInfo->m_Server_BackupIP, connectInfo->m_Server_BackupPort, connectInfo->m_DualActive, connectInfo->m_currentLink); return -1 != connectInfo->m_currentLink; } bool SpSecureClient::Connect_Dual(ENTITY_CONNECT_INFO *connectInfo, int option) { if (NULL == connectInfo || 0 == strlen(connectInfo->m_EntityName)) return false; connectControl *entityConnect = connectControl::getInstance(); bool quickConnect = false; int priorLink = entityConnect->getPriorLink(connectInfo->m_lastLink); if (-1 != priorLink) { /* 根据上次双活成功时的server进行连接 */ m_log.LOGERROR("lastLink:%d", connectInfo->m_lastLink); if (0 == priorLink && 0 != strlen(connectInfo->m_ServerIP)) connectInfo->m_currentLink = (Connect(connectInfo->m_ServerIP, connectInfo->m_ServerPort, option) ? 0 : -1); else if (1 == priorLink && 0 != strlen(connectInfo->m_Server_BackupIP)) connectInfo->m_currentLink = (Connect(connectInfo->m_Server_BackupIP, connectInfo->m_Server_BackupPort, option) ? 1 : -1); quickConnect = (-1 == connectInfo->m_currentLink ? false : true); m_log.LOGERROR("lastLink:%d,currentLink:%d", connectInfo->m_lastLink, connectInfo->m_currentLink); } if (!IsConnectionOK()) { /* 根据终端号进行连接 */ //获取终端号,判断优先连接的IP和端口 auto pFunc = m_pEntity->GetFunction(); CSmartPointer spConfig; auto rc = pFunc->OpenConfig(Config_Root, spConfig); if (rc != Error_Succeed) { Dbg("read root.ini Fail\r\n"); return false; } CSimpleStringA strValue; spConfig->ReadConfigValue("Terminal", "TerminalNo", strValue); bool isMainServer = true; if (strValue.GetLength() > 0) { char str[20] = ""; sprintf(str, "%s", (const char*)strValue); isMainServer = (0 == ((str[strlen(str) - 1] - '0') % 2)); m_log.LOGERROR("lastByte:%s, %d, MainServer:%d", str, str[strlen(str) - 1] - '0', isMainServer); } Dbg("dual connection, entity %s using option %d", connectInfo->m_EntityName, option); if (0 == strlen(connectInfo->m_Server_BackupIP) && 0 == strlen(connectInfo->m_ServerIP)) connectInfo->m_currentLink = -1; else if (0 == strlen(connectInfo->m_Server_BackupIP)) {//serverBackup Ip and port error, link to server connectInfo->m_currentLink = (Connect(connectInfo->m_ServerIP, connectInfo->m_ServerPort, option) ? 0 : -1);//Link to first one m_log.LOGERROR("%s serverBackup param error", connectInfo->m_EntityName); } else { if (isMainServer) {//link to first server if (Connect(connectInfo->m_ServerIP, connectInfo->m_ServerPort, option)) connectInfo->m_currentLink = 0; else if (strcmp(connectInfo->m_ServerIP, connectInfo->m_Server_BackupIP) && Connect(connectInfo->m_Server_BackupIP, connectInfo->m_Server_BackupPort, option)) connectInfo->m_currentLink = 1; else connectInfo->m_currentLink = -1; } else {//link to second server m_log.LOGERROR("BackUp"); if (Connect(connectInfo->m_Server_BackupIP, connectInfo->m_Server_BackupPort, option)) connectInfo->m_currentLink = 1; else if (strcmp(connectInfo->m_ServerIP, connectInfo->m_Server_BackupIP) && Connect(connectInfo->m_ServerIP, connectInfo->m_ServerPort, option)) connectInfo->m_currentLink = 0; else connectInfo->m_currentLink = -1; } } } /* 连接结束 */ char msg[1024]; sprintf(msg, "%sDual Connection: EntityName:%s, server:%s %d, serverBackup:%s %d, DualOpen: %d, currentLink:%d, curEntityNum:%d", (quickConnect ? "quick " : ""), connectInfo->m_EntityName, connectInfo->m_ServerIP, connectInfo->m_ServerPort, connectInfo->m_Server_BackupIP, connectInfo->m_Server_BackupPort, connectInfo->m_DualActive, connectInfo->m_currentLink, entityConnect->getEntityNum()); m_log.LOGERROR(msg); setConnectInfo(connectInfo); return -1 != connectInfo->m_currentLink; } bool SpSecureClient::IsConnectionOK() { return GetFunction()->IsConnectionOK(); } bool SpSecureClient::IsSecureConn() { return GetFunction()->IsSecureConnection(); } void SpSecureClient::Close() { if (!m_bClosed) { m_bClosed = true; GetFunction()->Close(); //clear the connect Info connectClose(m_pEntity->GetEntityName()); m_log.LOGERROR("%s closed", m_pEntity->GetEntityName()); } } string SpSecureClient::SendPackage(const CSmartPointer& pSendPkg) { return GetFunction()->SendPackage(pSendPkg); } CSmartPointer SpSecureClient::ReceivePackage(int nWaitSecond) { return GetFunction()->ReceivePackage(nWaitSecond); } CSmartPointer SpSecureClient::CreateNewPackage(const char *pServiceCode) { return GetFunction()->CreateNewPackage(pServiceCode); } CSmartPointer SpSecureClient::CreateReplyPackage(const CSmartPointer& pRecvPkg) { return GetFunction()->CreateReplyPackage(pRecvPkg); } void SpSecureClient::OnErrorMsg(DWORD dwSysCode, DWORD dwUserCode, const CSimpleStringA &pErrMsg) { // 切换到实体线程执行 Dbg("SpSecureClient error: %s", (const char*)pErrMsg); } void SpSecureClient::OnDisconnect() { Dbg("SpSecureClient disconnect"); m_log.LOGERROR("Entity %s OnDisconnect", m_pEntity->GetEntityName()); } void SpSecureClient::OnReConnect() { if (!IsConnectionOK()) {//可能OnDisconnect被重载,已重新连接 m_log.LOGERROR("Entity %s disconnect, try to reconnect", m_pEntity->GetEntityName()); ConnectFromCentralSetting(); } } struct OnPackageTask : public ITaskSp { OnPackageTask(SpSecureClient *pClient, IPackage* pkg) :m_pSecureClient(pClient), m_pPackage(pkg) {} SpSecureClient *m_pSecureClient; IPackage * m_pPackage; virtual void Process() { assert(m_pPackage != NULL); CSmartPointer ptr; ptr.Attach(m_pPackage); m_pSecureClient->OnPkgAnswer(ptr); m_pSecureClient->DecRefCount(); } }; struct OnDisconnectTask : public ITaskSp { OnDisconnectTask(SpSecureClient *pClient) :m_pSecureClient(pClient) {} SpSecureClient *m_pSecureClient; virtual void Process() { m_pSecureClient->Close(); m_pSecureClient->OnDisconnect(); m_pSecureClient->DecRefCount(); m_pSecureClient->OnReConnect(); } }; struct OnErrorTask : public ITaskSp { OnErrorTask(SpSecureClient *pClient, DWORD dwSysCode, DWORD dwUserCode, const char *pMsg) :m_pSecureClient(pClient), m_dwSysCode(dwSysCode), m_dwUserCode(dwUserCode), m_strErrMsg(pMsg) {} SpSecureClient *m_pSecureClient; DWORD m_dwSysCode; DWORD m_dwUserCode; CSimpleStringA m_strErrMsg; virtual void Process() { m_pSecureClient->OnErrorMsg(m_dwSysCode, m_dwUserCode, m_strErrMsg); m_pSecureClient->DecRefCount(); } }; void SpSecureClient::OnReceivePackage(CSmartPointer &pRecvPkg) { // 切换到实体线程执行 OnPackageTask *pTask = new OnPackageTask(this, pRecvPkg.Detach()); IncRefCount(); m_pEntity->GetFunction()->PostEntityTaskFIFO(pTask); } void SpSecureClient::OnClose() { // 切换到实体线程执行 OnDisconnectTask *pTask = new OnDisconnectTask(this); IncRefCount(); m_pEntity->GetFunction()->PostEntityTaskFIFO(pTask); } void SpSecureClient::OnError(DWORD dwSysCode, DWORD dwUserCode, const char *pErrMsg) { // 切换到实体线程执行 OnErrorTask *pTask = new OnErrorTask(this, dwSysCode, dwUserCode, pErrMsg); IncRefCount(); m_pEntity->GetFunction()->PostEntityTaskFIFO(pTask); } void SpSecureClient::OnAuthPass() { Dbg("SpSecureClient AuthPass"); } bool SpSecureClient::OnAuthRequest(CConnAuthReq *pReq) { ErrorCodeEnum Error = Error_Unexpect; // prepare verify info CSystemStaticInfo si; { m_pEntity->GetFunction()->GetSystemStaticInfo(si); } CVerifyInfo info; memset(&info, 0, sizeof(info)); strncpy(info.m_arrTerminalNo, (LPCSTR)si.strTerminalID, sizeof(info.m_arrTerminalNo)-1); strcpy(info.m_arrServiceType, "CMBRVC"); { hostent *ent = _gethostbyname(NULL); if (ent && ent->h_addr_list[0] != NULL) { int i = 0; for (; ent->h_addr_list[i] != NULL; ++i) { struct in_addr *in = (struct in_addr*)ent->h_addr_list[i]; if (in->S_un.S_un_b.s_b1 == 99 || in->S_un.S_un_b.s_b1 == 10) break; } if (ent->h_addr_list[i] == NULL) i = 0; auto in = (struct in_addr*)ent->h_addr_list[i]; info.m_arrIP[0] = in->S_un.S_un_b.s_b1; info.m_arrIP[1] = in->S_un.S_un_b.s_b2; info.m_arrIP[2] = in->S_un.S_un_b.s_b3; info.m_arrIP[3] = in->S_un.S_un_b.s_b4; } } { // call token service to encrypt verify info int nDestLen = sizeof(pReq->m_arrVerifyInfo); TokenService_ClientBase *client = new TokenService_ClientBase(m_pEntity); Error = client->Connect(); if (Error == Error_Succeed) { TokenService_EncryptWithPriKey_Req Req; TokenService_EncryptWithPriKey_Ans Ans; Req.raw_data.m_pData = (char*)&info; Req.raw_data.m_iLength = sizeof(info); Error = client->EncryptWithPriKey(Req, Ans, -1); if (Error != Error_Succeed) { LOG_TRACE("EncryptWithPriKey for VerifyInfo failed! Error = %d", Error); } else { memcpy_s(pReq->m_arrVerifyInfo, sizeof(pReq->m_arrVerifyInfo), Ans.enc_data.m_pData, Ans.enc_data.m_iLength); // get token TokenService_GetToken_Req Req1; TokenService_GetToken_Ans Ans1; Error = client->GetToken(Req1, Ans1, -1); if (Error != Error_Succeed) { LOG_TRACE("GetToken for VerifyInfo failed! Error = %d", Error); } else { memcpy_s(pReq->m_arrVerifyToken, sizeof(pReq->m_arrVerifyToken), Ans1.token.m_pData, Ans1.token.m_iLength); } } client->GetFunction()->CloseSession(); } else { LOG_TRACE("connect to tokenservice failed! Error = %d", Error); } client->SafeDelete(); } return Error == Error_Succeed; } bool SpSecureClient::OnSessionKeyRet(CConnAuthRet *pRet, BYTE *pBuf, int *pBufLen) { memset(pBuf, 0, *pBufLen); TokenService_ClientBase *client = new TokenService_ClientBase(m_pEntity); ErrorCodeEnum Error = client->Connect(); if (Error == Error_Succeed) { TokenService_DecryptWithPriKey_Req Req; TokenService_DecryptWithPriKey_Ans Ans; Req.enc_data.m_pData = (char*)&pRet->m_arrEncSessionKey[0]; Req.enc_data.m_iLength = sizeof(pRet->m_arrEncSessionKey); Error = client->DecryptWithPriKey(Req, Ans, -1); if (Error == Error_Succeed) { memcpy_s(pBuf, *pBufLen, Ans.raw_data.m_pData, Ans.raw_data.m_iLength); *pBufLen = Ans.raw_data.m_iLength; } else { *pBufLen = 0; LOG_TRACE("OnSessionKey decrypt session key failed! Error = %d", Error); } client->GetFunction()->CloseSession(); } client->SafeDelete(); return Error == Error_Succeed; } bool SpSecureClient::OnGetSharedSK(char *pTerminalNo, int *pTerminalNoLen, BYTE *pBuf, int *pBufLen) { ErrorCodeEnum Error = Error_Unexpect; CSystemStaticInfo si; { m_pEntity->GetFunction()->GetSystemStaticInfo(si); } assert(si.strTerminalID.GetLength() <= *pTerminalNoLen); strcpy(pTerminalNo, (LPCSTR)si.strTerminalID); *pTerminalNoLen = strlen(pTerminalNo); { TokenService_ClientBase *client = new TokenService_ClientBase(m_pEntity); Error = client->Connect(); if (Error == Error_Succeed) { TokenService_GetSharedSK_Req Req; TokenService_GetSharedSK_Ans Ans; Error = client->GetSharedSK(Req, Ans, 10000); if (Error == Error_Succeed) { memcpy_s(pBuf, *pBufLen, Ans.ssk.m_pData, Ans.ssk.m_iLength); *pBufLen = Ans.ssk.m_iLength; } else { *pBufLen = 0; LOG_TRACE("OnSessionKey decrypt session key failed! Error = %d", Error); } client->GetFunction()->CloseSession(); } client->SafeDelete(); } return Error == Error_Succeed; } ErrorCodeEnum SpSecureClient::ParseIPAddress(const char *str, CSimpleStringA &ip, int &port) { ErrorCodeEnum Error = Error_Unexpect; if (str) { char tmp1[32] = {}; char tmp2[16] = {}; sscanf(str, "%s %s", tmp1, tmp2); if (tmp1[0] != 0 && tmp2[0] != 0) { ip = tmp1; port = atoi(tmp2); Error = Error_Succeed; } else return Error; } return Error; } DWORD SpSecureClient::GetEntityUserCode(DWORD code) { assert(m_pEntity != NULL); auto pEnv = sp_get_env(); assert(pEnv != NULL); auto pCfg = pEnv->cfg; assert(pCfg != NULL); auto pEntity = sp_cfg_get_entity_by_name(pCfg, m_pEntity->GetEntityName()); assert(pEntity != NULL); DWORD dwDevelopID = pEntity->devel_id; return (dwDevelopID << 20 | code); }