📄 xtunnelsxcipher.cpp
字号:
{#if DEBUG cout << "PROTOCOL ERROR: GetGlobalOrMasterServerPacket() failed to get XCipher::EMessageGlobalServerCommunication_Ready!!" << endl;#endif // DEBUG iResult = XCipher::EErrorProtocolGlobalServer; goto bail; }bail: return iResult; }int DisconnectPolitely( int iConnectedSocket, unsigned long& ulPacketIndex, long& lEncryptionType, const char* szMasterToGlobalEncryptionKey, const char* /*szGlobalToMasterDecryptionKey*/ ) { int iResult = 0; unsigned long ulPacketsize = 0; TXTunnelsPacket* pReceivedPacket = NULL; // --> EMessageDisconnect#if DEBUG TimeCheck("sending disconnect packet");#endif // DEBUG { g_tSendingPacket.m_tHeaderBasic.commandid = HOST2XT32(EMessageDisconnect); const char* szPoliteGoodbye = "Thank you ever so much"; ulPacketsize = sizeof(unsigned long) + sizeof(unsigned short) + strlen(szPoliteGoodbye); g_tSendingPacket.m_tHeaderBasic.payloadsize = HOST2XT32(ulPacketsize); g_tSendingPacket.m_tData.disconnect.reason = HOST2XT32(kDisconnectReasonNormal); g_tSendingPacket.m_tData.disconnect.messagesize = HOST2XT16(strlen(szPoliteGoodbye)); strcpy(g_tSendingPacket.m_tData.disconnect.message, szPoliteGoodbye); if (SendPacketToGlobalOrMasterServer(&g_tSendingPacket, ulPacketsize, ulPacketIndex, lEncryptionType, iConnectedSocket, szMasterToGlobalEncryptionKey)) return 1; } #if DEBUG TimeCheck("sent disconnect packet");#endif // DEBUG/* Apparently global server does not actually send a reply packet // <-- EMessageDisconnect pReceivedPacket = GetGlobalOrMasterServerPacket(lEncryptionType, iConnectedSocket, EMessageDisconnect, szGlobalToMasterDecryptionKey); if (!pReceivedPacket) {#if DEBUG TimeCheck("gave up on disconnect message");#endif // DEBUG // whatever, we don't really care now } else {#if DEBUG TimeCheck("got disconnect message");#endif // DEBUG // or about this for that matter //pReceivedPacket->m_tData.disconnect.messagesize = HOST2XT16(pReceivedPacket->m_tData.disconnect.messagesize); // no trailing NUL //pReceivedPacket->m_tData.disconnect.message[pReceivedPacket->m_tData.disconnect.messagesize] = 0; }*/ return iResult; } int SendToMasterServer( int iMasterServerSocket, const char* szGlobalServerPassword, uuid_t& tGlobalServerSequence, TConversationInfoParam& tConversation ) { unsigned long ulPacketIndex = 1; long lEncryptionType = EAlgorithm_None; char szMasterToGlobalEncryptionKey[EMaxSmallBufferSize] = { 0 }; char szGlobalToMasterDecryptionKey[EMaxSmallBufferSize] = { 0 }; #if DEBUG cout << "X-Cipher: SendToMasterServer with password " << szGlobalServerPassword << endl;#endif // DEBUG int iResult = DoGlobalOrMasterServerLogin( iMasterServerSocket, ulPacketIndex, lEncryptionType, tConversation.m_szLocalHost, tGlobalServerSequence, szGlobalServerPassword, szMasterToGlobalEncryptionKey, szGlobalToMasterDecryptionKey ); if (iResult) return iResult; g_tSendingPacket.m_tHeaderBasic.commandid = HOST2XT32(XCipher::EMessageMasterServerToMasterServer_SendConversationInfo); unsigned long ulPacketsize = sizeof(tConversation); g_tSendingPacket.m_tHeaderBasic.payloadsize = HOST2XT32(ulPacketsize); memcpy(&g_tSendingPacket.m_tData.m_tXCipherConversation, &tConversation, sizeof(tConversation)); g_tSendingPacket.m_tData.m_tXCipherConversation.m_tExpires = HOST2XT32(tConversation.m_tExpires); if (SendPacketToGlobalOrMasterServer(&g_tSendingPacket, ulPacketsize, ulPacketIndex, lEncryptionType, iMasterServerSocket, szGlobalServerPassword)) { iResult = XCipher::EErrorCommunicationGlobalServer; goto bail; } DisconnectPolitely( iMasterServerSocket, ulPacketIndex, lEncryptionType, szMasterToGlobalEncryptionKey, szGlobalToMasterDecryptionKey ); bail: r_close(iMasterServerSocket); return iResult; }int SendToMasterServers( const char* szGlobalServerPassword, uuid_t& tGlobalServerSequence, TConversationInfoParam& tConversation ) { int iResult = 0; // get list of master servers using SRV lookup char szSRVRequest[EMaxSmallBufferSize] = { 0 }; sprintf(szSRVRequest, "_xtunnels._tcp.%s", tConversation.m_szRemoteHost); unsigned char pSRVReply[1500] = { 0 }; HEADER* hdr = (HEADER*)pSRVReply; int iResultLength = res_query(szSRVRequest, C_ANY, /* SRV */ 33, pSRVReply, sizeof(pSRVReply)); if (iResultLength < (int)sizeof(HEADER)) {#if DEBUG cout << "res_query() FAILED!" << endl;#endif // DEBUG return -1; } // need to swap these from big endian hdr->qdcount = ntohs(hdr->qdcount); hdr->ancount = ntohs(hdr->ancount); hdr->nscount = ntohs(hdr->nscount); hdr->arcount = ntohs(hdr->arcount); u_char *ptr = pSRVReply + sizeof(HEADER); u_int16_t port = 0; u_int i = 0; char target[1024] = { 0 }; for (i = 0; i < hdr->qdcount; i++) { if (skip_question((char**)&ptr, (char*)pSRVReply, iResultLength) != 0) {#if DEBUG cout << "X-Cipher: SendToMasterServers error parsing SRV question " << i << " of " << hdr->qdcount << endl;#endif // DEBUG return -1; } } for (i = 0; i < hdr->ancount; i++) { int iMasterServerSocket = -1; if (decode_srv((char**)&ptr, (char*)pSRVReply, iResultLength, target, &port) != 0) {#if DEBUG cout << "X-Cipher: SendToMasterServers error parsing SRV record " << i << " of " << hdr->ancount << endl;#endif // DEBUG return -1; } // cut the dot off the end to get a valid address? if (target[strlen(target) - 1] == '.') target[strlen(target) - 1] = 0;#if DEBUG cout << "X-Cipher: SendToMasterServers connecting to " << target << " port " << XCipher::EDefaultXCipherListenPort << endl;#endif // DEBUG iMasterServerSocket = u_connect( XCipher::EDefaultXCipherListenPort, target ); if (iMasterServerSocket > -1) SendToMasterServer( iMasterServerSocket, szGlobalServerPassword, tGlobalServerSequence, tConversation ); } return iResult; }} // end anonymous namespacenamespace XCipher {CXCipher* CXCipher::g_pXCipher = NULL;bool CXCipher::g_bXCipherEnabled = false;// set in config filechar g_szXCipherGlobalServerSRVRequest[EMaxSmallBufferSize] = { 0 };char g_szLocalXCipherHost[EMaxSmallBufferSize] = { 0 };char g_szLocalXCipherPassword[EMaxSmallBufferSize] = { 0 };bool InitializeXCipher(bool bForceEnabled) { if (bForceEnabled) CXCipher::g_bXCipherEnabled = true; if (CXCipher::g_bXCipherEnabled) CXCipher::g_pXCipher = new CXCipher; if (!CXCipher::g_bXCipherEnabled) CXCipher::g_bXCipherEnabled = false; return NULL != CXCipher::g_pXCipher; } CXCipher::CXCipher() { }void CXCipher::DestroyXCipher() { delete g_pXCipher; g_pXCipher = NULL; g_bXCipherEnabled = false; }void CXCipher::EmptyHostPairCache() { m_cHostPairKeyCache.erase(m_cHostPairKeyCache.begin(), m_cHostPairKeyCache.end()); }void CXCipher::CleanCaches() { time_t tNow = time(NULL); list<XTunnels::THostPairPasswordInfo>::iterator cIterPairCache = m_cHostPairKeyCache.begin(); while (cIterPairCache != m_cHostPairKeyCache.end()) { if (cIterPairCache->m_tExpires < tNow) { m_cHostPairKeyCache.erase(cIterPairCache); cIterPairCache = m_cHostPairKeyCache.begin(); continue; } cIterPairCache++; } list<TConversationInfoParam>::iterator cIterConversationCache = m_cConversationCache.begin(); while (cIterConversationCache != m_cConversationCache.end()) { if (cIterConversationCache->m_tExpires < tNow) { m_cConversationCache.erase(cIterConversationCache); cIterConversationCache = m_cConversationCache.begin(); continue; } cIterConversationCache++; } }void CXCipher::CleanHostPairCache(const char* szOutOfSyncHost) { time_t tNow = time(NULL); list<XTunnels::THostPairPasswordInfo>::iterator cIterPairCache = m_cHostPairKeyCache.begin(); while (cIterPairCache != m_cHostPairKeyCache.end()) { bool bTooOld = cIterPairCache->m_tExpires < tNow; bool bNeedsCleaning = (0 == strcmp(cIterPairCache->m_szHostOne, szOutOfSyncHost)) || (0 == strcmp(cIterPairCache->m_szHostTwo, szOutOfSyncHost)); if (bTooOld || bNeedsCleaning) { m_cHostPairKeyCache.erase(cIterPairCache); cIterPairCache = m_cHostPairKeyCache.begin(); continue; } cIterPairCache++; } } bool CXCipher::GetCipherkeyFromCache( const char* szLocalHost, const char* szRemoteHost, const char* szUsername, char m_pOutCipherkeyBytes[32] ) { time_t tNow = time(NULL); list<TConversationInfoParam>::iterator cIterCache = m_cConversationCache.begin(); while (cIterCache != m_cConversationCache.end()) { if (cIterCache->m_tExpires < tNow) { m_cConversationCache.erase(cIterCache); cIterCache = m_cConversationCache.begin(); continue; } if (strcmp(szUsername, cIterCache->m_szRemoteUsername)) continue; if (!strcmp(szLocalHost, cIterCache->m_szLocalHost) && !strcmp(szRemoteHost, cIterCache->m_szRemoteHost)) { memcpy(m_pOutCipherkeyBytes, cIterCache->m_pCipherkeyBytes, 32); return true; } if (!strcmp(szLocalHost, cIterCache->m_szRemoteHost) && !strcmp(szRemoteHost, cIterCache->m_szLocalHost)) { memcpy(m_pOutCipherkeyBytes, cIterCache->m_pCipherkeyBytes, 32); return true; } cIterCache++; } return false; }void CXCipher::GetHostPairPasswordFromCache( const char* szRemote, const char* szLocal, char* szOutHostPairPassword, uuid_t& tOutSequenceNumber ) { time_t tNow = time(NULL); list<XTunnels::THostPairPasswordInfo>::iterator cIterCache = m_cHostPairKeyCache.begin(); while (cIterCache != m_cHostPairKeyCache.end()) { if (cIterCache->m_tExpires < tNow) { m_cHostPairKeyCache.erase(cIterCache); cIterCache = m_cHostPairKeyCache.begin(); continue; } if (!strcmp(szRemote, cIterCache->m_szHostOne) && !strcmp(szLocal, cIterCache->m_szHostTwo)) { strcpy(szOutHostPairPassword, cIterCache->m_szPairPassword); tOutSequenceNumber = cIterCache->m_tSequenceNumber; return; } if (!strcmp(szRemote, cIterCache->m_szHostTwo) && !strcmp(szLocal, cIterCache->m_szHostOne)) { strcpy(szOutHostPairPassword, cIterCache->m_szPairPassword); tOutSequenceNumber = cIterCache->m_tSequenceNumber; return; } cIterCache++; } }void CXCipher::UpdateHostPairCache(XTunnels::THostPairPasswordInfo& tNewPair) { CleanCaches(); m_cHostPairKeyCache.push_back(tNewPair);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -