📄 xtunnelsfamilydata.cpp
字号:
/* File: XTunnelsFamilyData.cp Contains: X-Tunnels data members shared between parent and children Copyright: (c) 2003 by Xten Networks, Inc., all rights reserved.*/#if DEBUG#include <iostream>// for packet type readout#include "XTunnelsXCipher.h"#endif // DEBUG#include <strstream>#include <cerrno>#include <algorithm>#include <stdio.h>#include "restart.h"#include "md5.h"#include "XTunnelsFamilyData.h"#include "XTunnelsParentData.h"#include "XTunnelsCVsSHA1.h"#include "XTunnelsCVsDES.h"#include "XTunnelsCVsAES.h"#if DEBUGusing std::cout;using std::endl;// for packet type readoutusing namespace XCipher;#endif // DEBUGusing std::istrstream;using std::ostrstream;using std::min;namespace {void MakeMD5SessionKeyColonPasswordDigest( unsigned long ulSessionKeySize, const char* szSessionKey, const char* szPassword, unsigned long& ulOutDigestSize, char* pOutDigest ) { struct MD5Context md5c; MD5Init(&md5c); u_char colon = ':'; MD5Update(&md5c, (u_char*)szSessionKey, ulSessionKeySize); MD5Update(&md5c, &colon, 1); MD5Update(&md5c, (u_char*)szPassword, strlen(szPassword)); MD5Final((u_char*)pOutDigest, &md5c); ulOutDigestSize = 16; }} // end anonymous namespacenamespace XTunnels {// used with SIGUSR2 from child to pipe to parent // -- deathwatch info// -- host1/host2/password XCipher triplets// -- user/host XCipher conversation ID requestsint g_pChild2ParentInfoPipe[2] = { 0 };// -- user/host XCipher conversation ID repliesint g_pParent2ChildInfoPipe[2] = { 0 };// common buffer for constructing messages and sending if no encryption/packing requiredTXTunnelsPacket g_tSendingPacket; // = { 0 }; // for g_tSendingPacket to be encrypted/packed into if necessaryTXTunnelsPacket g_tTransmitPacket; // = { 0 }; // to read from remote into before checking encryption/packingTXTunnelsPacket g_tReceivedPacket; // = { 0 }; // for g_tReceivedPacket to be unencrypted/unpacked into if necessaryTXTunnelsPacket g_tParsedPacket; // = { 0 };// sets magic number and autoincrements packet index; encrypts if necessary// returns &g_tTransmitPacket or NULL if encryption failsTXTunnelsPacket* PreparePacketForTransmit( TXTunnelsPacket* pSourcePacket, ssize_t tUnencryptedSize, long lEncryptionType, unsigned long& ulInOutPacketIndex, const char* szPassword ) { // note that the intention is for packet to always be &g_tSendingPacket // but some packet type handlers might still be reusing the &g_tReceivedPacket/&g_tParsedPacket they were passed // // HandleRemoteClient() -- check TXTunnelsPacket* pTransmissionData = pSourcePacket; // magic number is always sent unencrypted, and will be first part of encrypted data pSourcePacket->m_tData.m_ulPacketMagicNumber = HOST2XT32(EPacketMagicNumber); tUnencryptedSize += sizeof(pSourcePacket->m_tData.m_ulPacketMagicNumber); // and packet index follows pSourcePacket->m_tData.m_ulPacketIndex = HOST2XT32(ulInOutPacketIndex++); tUnencryptedSize += sizeof(pSourcePacket->m_tData.m_ulPacketIndex); unsigned long ulEncryptedSize = 0; // with the magic number and packet index fields, we always have encryptable data now bool isEncrypted = (lEncryptionType != EAlgorithm_None); if (isEncrypted) { g_tTransmitPacket.m_tHeaderBasic = pSourcePacket->m_tHeaderBasic; g_tTransmitPacket.m_tEncrypt.m_tSpecs.m_ulAlgorithm = HOST2XT32(lEncryptionType); g_tTransmitPacket.m_tEncrypt.m_tSpecs.decryptsize = HOST2XT32(tUnencryptedSize); int encryptErr = 0; ulEncryptedSize = EMaxPacketSize; char* pUnencryptedSource = reinterpret_cast<char*>(&pSourcePacket->m_tData); char* pEncryptDestination = g_tTransmitPacket.m_tEncrypt.m_pEncryptedData; switch (lEncryptionType) { case EAlgorithm_Triple_DES: encryptErr = EncryptTripleDES(pEncryptDestination, ulEncryptedSize, pUnencryptedSource, tUnencryptedSize, szPassword);#if DEBUG#define CHECK_TRIPLEDES_DECOMPRESS 0#endif // DEBUG#if CHECK_TRIPLEDES_DECOMPRESS { // to check whether it looks the same... char szDecompressedTripleDES[EMaxPacketDataSize] = { 0 }; std::istrstream cDESInput(reinterpret_cast<char*>(pEncryptDestination), ulEncryptedSize); CVsDES decryptDES; decryptDES.OpenRead(szPassword, &cDESInput); unsigned long dwActualRead = tUnencryptedSize; decryptDES.Read(szDecompressedTripleDES, tUnencryptedSize, &dwActualRead); bool bAreEqual = 0 == memcmp(szDecompressedTripleDES, pUnencryptedSource, tUnencryptedSize); cout << "TripleDES decryption check " << (bAreEqual ? "succeeded!" : "FAILED!!") << endl; decryptDES.Close(); }#endif // CHECK_TRIPLEDES_DECOMPRESS break; case EAlgorithm_AES_128_Bits: encryptErr = EncryptAES128(pEncryptDestination, ulEncryptedSize, pUnencryptedSource, tUnencryptedSize, szPassword);#if DEBUG#define CHECK_AES_DECOMPRESS 0#endif // DEBUG#if CHECK_AES_DECOMPRESS { // to check whether it looks the same... char szDecompressedAES128[EMaxPacketDataSize] = { 0 }; std::istrstream cAES128Input(reinterpret_cast<char*>(pEncryptDestination), ulEncryptedSize); CVsAES decryptAES128; decryptAES128.OpenRead(szPassword, &cAES128Input, CVsAES::E128bits); unsigned long dwActualRead = tUnencryptedSize; decryptAES128.Read(szDecompressedAES128, tUnencryptedSize, &dwActualRead); bool bAreEqual = 0 == memcmp(szDecompressedAES128, pUnencryptedSource, tUnencryptedSize); cout << "AES128 decryption check " << (bAreEqual ? "succeeded!" : "FAILED!!") << endl; decryptAES128.Close(); }#endif // CHECK_AES_DECOMPRESS break; case EAlgorithm_AES_192_Bits: encryptErr = EncryptAES192(pEncryptDestination, ulEncryptedSize, pUnencryptedSource, tUnencryptedSize, szPassword);#if CHECK_AES_DECOMPRESS { // to check whether it looks the same... char szDecompressedAES192[EMaxPacketDataSize] = { 0 }; std::istrstream cAES192Input(reinterpret_cast<char*>(pEncryptDestination), ulEncryptedSize); CVsAES decryptAES192; decryptAES192.OpenRead(szPassword, &cAES192Input, CVsAES::E192bits); unsigned long dwActualRead = tUnencryptedSize; decryptAES192.Read(szDecompressedAES192, tUnencryptedSize, &dwActualRead); bool bAreEqual = 0 == memcmp(szDecompressedAES192, pUnencryptedSource, tUnencryptedSize); cout << "AES192 decryption check " << (bAreEqual ? "succeeded!" : "FAILED!!") << endl; decryptAES192.Close(); }#endif // CHECK_AES_DECOMPRESS break; case EAlgorithm_AES_256_Bits: encryptErr = EncryptAES256(pEncryptDestination, ulEncryptedSize, pUnencryptedSource, tUnencryptedSize, szPassword);#if CHECK_AES_DECOMPRESS { // to check whether it looks the same... char szDecompressedAES256[EMaxPacketDataSize] = { 0 }; std::istrstream cAES256Input(reinterpret_cast<char*>(pEncryptDestination), ulEncryptedSize); CVsAES decryptAES256; decryptAES256.OpenRead(szPassword, &cAES256Input, CVsAES::E256bits); unsigned long dwActualRead = tUnencryptedSize; decryptAES256.Read(szDecompressedAES256, tUnencryptedSize, &dwActualRead); bool bAreEqual = 0 == memcmp(szDecompressedAES256, pUnencryptedSource, tUnencryptedSize); cout << "AES256 decryption check " << (bAreEqual ? "succeeded!" : "FAILED!!") << endl; decryptAES256.Close(); }#endif // CHECK_AES_DECOMPRESS break; case EAlgorithm_MD5: case EAlgorithm_SHA1: default:#if DEBUG cout << "WARNING: PreparePacketForTransmit got unknown encryption method " << lEncryptionType << endl;#endif //DEBUG encryptErr = 1; break; } if (encryptErr) {#if DEBUG cout << "X-Tunnels: PreparePacketForTransmit FAILED encrypting " << lEncryptionType << ", disconnecting!" << endl;#endif //DEBUG return NULL; } else ulEncryptedSize += sizeof(TXTunnelsPacketHeaderEncrypt); unsigned long encryptcommandID = XT2HOST32(g_tTransmitPacket.m_tHeaderBasic.commandid); encryptcommandID = encryptcommandID | kIsEncryptedPacket; g_tTransmitPacket.m_tHeaderBasic.commandid = HOST2XT32(encryptcommandID); pTransmissionData = &g_tTransmitPacket; g_tTransmitPacket.m_tHeaderBasic.payloadsize = HOST2XT32(ulEncryptedSize); } else { ulEncryptedSize = tUnencryptedSize; pSourcePacket->m_tHeaderBasic.payloadsize = HOST2XT32(tUnencryptedSize); } return pTransmissionData; }int TransmitPreparedPacket( TXTunnelsPacket* pTransmissionData, int iTransmitTCPSocket, int iTransmitUDPSocket, u_buf_t* pUDPDestination ) { unsigned long ulEncryptedSize = XT2HOST32(pTransmissionData->m_tHeaderBasic.payloadsize); ssize_t towrite = sizeof(TXTunnelsPacketHeader) + ulEncryptedSize; ssize_t wrote = 0; if (iTransmitUDPSocket) { wrote = u_sendto(iTransmitUDPSocket, pTransmissionData, towrite, pUDPDestination); } else { wrote = r_write(iTransmitTCPSocket, pTransmissionData, towrite); } if (wrote != towrite) {#if DEBUG bool isEncrypted = kIsEncryptedPacket == (kIsEncryptedPacket & XT2HOST32(pTransmissionData->m_tHeaderBasic.commandid)); cout << "X-Tunnels: SendPacketToClient failed writing " << (iTransmitUDPSocket ? "UDP" : "TCP") << (isEncrypted ? " encrypted " : " unencrypted ") << "packet { " << XT2HOST32(pTransmissionData->m_tHeaderBasic.commandid) << ", " << XT2HOST32(pTransmissionData->m_tHeaderBasic.payloadsize) << " } "; if (isEncrypted) cout << " { " << XT2HOST32(g_tTransmitPacket.m_tEncrypt.m_tSpecs.m_ulAlgorithm) << ", " << XT2HOST32(g_tTransmitPacket.m_tEncrypt.m_tSpecs.decryptsize) << " } "; cout << endl;#endif //DEBUG return 1; }/*#if DEBUG cout << "X-Tunnels: SendPacketToClient succeeded writing " << (iTransmitUDPSocket ? "UDP" : "TCP") << (isEncrypted ? " encrypted " : " unencrypted ") << "packet { " << XT2HOST32(packet->m_tHeaderBasic.commandid) << ", " << XT2HOST32(packet->m_tHeaderBasic.payloadsize) << " } "; if (isEncrypted) cout << " { " << XT2HOST32(g_tTransmitPacket.m_tEncrypt.m_tSpecs.algorithm) << ", " << XT2HOST32(g_tTransmitPacket.m_tEncrypt.m_tSpecs.decryptsize) << " } "; cout << endl;#endif //DEBUG*/ return 0; }// returns nil for protocol failureTXTunnelsPacket* ReceivePacket( long& lInOutEncryptionType, int iReceiveTCPSocket, int iReceiveUDPSocket, u_buf_t* pUDPDestination, unsigned long ulBoundUDPRedirectAddress, u_port_t tBoundUDPRedirectPort, double dTimeoutSeconds, const char* szPassword ) {#if DEBUG bzero(&g_tReceivedPacket, sizeof(g_tReceivedPacket)); bzero(&g_tParsedPacket, sizeof(g_tParsedPacket)); char szWhoWeIs[1024] = { 0 }; if (ThisIsParent()) strcpy(szWhoWeIs, "parent"); else sprintf(szWhoWeIs, "child %d", getpid());#else g_tReceivedPacket.m_tHeaderBasic.commandid = 0; g_tReceivedPacket.m_tHeaderBasic.payloadsize = 0;#endif //DEBUG TXTunnelsPacket* pUnencryptedPacket = NULL; ssize_t toread = sizeof(TXTunnelsPacketHeader); ssize_t tDidReadSize = -1; ssize_t udpPacketTotal = 0; unsigned long sourceip = 0; unsigned short sourceport = 0; //int packetresult = 0; unsigned long ulPacketEncryption = EAlgorithm_None; if (iReceiveUDPSocket) { // read entire datagram //bzero(pUDPDestination, sizeof(*pUDPDestination)); size_t nbyte = EMaxPacketDataSize; udpPacketTotal = u_recvfrom(iReceiveUDPSocket, &g_tReceivedPacket, nbyte, pUDPDestination); sourceip = pUDPDestination->sin_addr.s_addr; sourceport = pUDPDestination->sin_port; // check against bound address if appropriate if ( (ulBoundUDPRedirectAddress && (ulBoundUDPRedirectAddress != sourceip)) || (tBoundUDPRedirectPort && (tBoundUDPRedirectPort != sourceport))) return NULL; // attempt to mark header bytes read tDidReadSize = min<int>(toread, udpPacketTotal); udpPacketTotal -= tDidReadSize; } else { // attempt to read header -- optional timeout in case it's a nonblocking socket if (dTimeoutSeconds) tDidReadSize = readtimed(iReceiveTCPSocket, &g_tReceivedPacket, toread, dTimeoutSeconds); else tDidReadSize = readblock(iReceiveTCPSocket, &g_tReceivedPacket, toread); } if (tDidReadSize != toread) {#if DEBUG if (!tDidReadSize) cout << "X-Tunnels: " << szWhoWeIs << " found EOF reading basic header, client has apparently disconnected" << endl; else cout << "X-Tunnels: " << szWhoWeIs << " received " << tDidReadSize << " not " << toread << " packet basic header bytes" << endl;#endif //DEBUG return NULL; } g_tReceivedPacket.m_tHeaderBasic.commandid = XT2HOST32(g_tReceivedPacket.m_tHeaderBasic.commandid); bool encrypted = (0 != (g_tReceivedPacket.m_tHeaderBasic.commandid & kIsEncryptedPacket)); g_tReceivedPacket.m_tHeaderBasic.commandid = g_tReceivedPacket.m_tHeaderBasic.commandid & ~kIsEncryptedPacket; g_tReceivedPacket.m_tHeaderBasic.payloadsize = XT2HOST32(g_tReceivedPacket.m_tHeaderBasic.payloadsize);#if DEBUG bool bAnnouncePacket = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -