⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 authnull.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
字号:
// AuthNull.CC
/*/////////////////////////////////////////////////////////////////////////////

	李亦
	2006.06.20
/*//////////////////////////////////////////////////////////////////////////////

//#include <platforms.h>

#include "server/net/AuthSocket.h"
//#include "server/net/IOSocket.h"
#include "server/net/AuthNull.h"

namespace CS
{
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//CS_AUTHHANDLER AuthNull::m_authHandler;

static AuthNull	gs_nullAuth;

AuthNull::AuthNull()
{
	m_authHandler.pInsert	= Insert;
	m_authHandler.pRemove	= Remove;
	m_authHandler.pQuery		= Query;
	m_authHandler.pOnListen	= OnListen;
	m_authHandler.pOnConnect= OnConnect;
	m_authHandler.pOnAccept	= OnAccept;
	m_authHandler.pGetUserID= GetUserID;
	m_authHandler.pOnClose	= OnClose;
	m_authHandler.pOnRecv	= OnRecv;
	m_authHandler.pOnSend	= OnSend;
	m_authHandler.pFree		= Free;
	m_authHandler.pValidateCommand	= ValidateCommand;
}

AuthNull::~AuthNull()
{
}


CS_AUTHHANDLER *AuthNull::GetNullAuthHandler(void)
{	
	return &gs_nullAuth.m_authHandler;
	//return &m_authHandler;
}

int RPGAPI AuthNull::Insert(void)
{
	return E_IOOK;
}

int RPGAPI AuthNull::Remove(void)
{
	return E_IOOK;
}

char * RPGAPI AuthNull::Query(void)
{
	return "NULL: Single User / Encrypt Only";
}


void * RPGAPI AuthNull::OnListen(CIOSocket *pSock, CEncryptionEngine *pEnc, int nUserId)
{
	INTERNAL *pNAI = (INTERNAL*)dMalloc(sizeof(INTERNAL));
	if(pNAI == NULL) 
		return NULL;
	
	pNAI->nUserId		= nUserId;
	pNAI->dwSeq			= 0;
	pNAI->dwRemoteSeq	= 0;
	return pNAI;
}

int AuthNull::SequenceEncryptPacket(CEncryptionEngine *pEnc, BYTE *pIn, int nInLen, BYTE **ppOut, int *pnOutLen, SEQ_HDR *pSeq)
{
	// Create encrypt buffer
	int nSize	= nInLen + sizeof(SEQ_HDR);
	BYTE *pDum	= (BYTE *)dMalloc(nSize);
	if(pDum == NULL) 
	{
		*ppOut		= NULL;
		*pnOutLen	= 0;
		return E_IOFAILED;
	}
	
	// Copy data
	dMemcpy(pDum, pSeq, sizeof(SEQ_HDR));
	dMemcpy(pDum+sizeof(SEQ_HDR), pIn, nInLen);
	
	// Encrypt data
	BYTE	*pData;
	int	nDataLen;

	pData = pEnc->Encrypt(pDum, nSize, &nDataLen);
	dFree(pDum);
	if(pData == NULL) 
		return E_IOFAILED;

	// Create output buffer
	nSize = nDataLen;
	pDum	= (BYTE *)dMalloc(nSize);
	if(pDum == NULL) 
	{
		pEnc->Free(pData);
		*ppOut	= NULL;
		*pnOutLen= 0;
		return E_IOFAILED;
	}
	
	// Copy data
	dMemcpy(pDum, pData, nSize);
	pEnc->Free(pData);
	
	// Return data
	*ppOut		= pDum;
	*pnOutLen	= nSize;

	return E_IOOK;
}


int AuthNull::UnsequenceDecryptPacket(CEncryptionEngine *pEnc, BYTE *pIn, int nInLen, BYTE **ppOut, int *pnOutLen, SEQ_HDR *pSeq)
{
	// Decrypt data
	BYTE	*pDum;
	int	nSize;

	pDum = pEnc->Decrypt(pIn,nInLen,&nSize);
	if(pDum == NULL) 
	{
		*ppOut	= NULL;
		*pnOutLen= 0;
		return E_IOFAILED;
	}

	if(nSize < sizeof(SEQ_HDR) ) 
	{
		pEnc->Free(pDum);
		*ppOut	= NULL;
		*pnOutLen= 0;
		return E_IOFAILED;
	}
	
	// Create output buffer
	int	nDataLen	= nSize - sizeof(SEQ_HDR);
	BYTE	*pData	= (BYTE *)dMalloc(nDataLen);
	if(pData == NULL) 
	{
		pEnc->Free(pDum);
		*ppOut	= NULL;
		*pnOutLen= 0;
		return E_IOFAILED;
	}
	
	// Copy data
	dMemcpy(pSeq, pDum, sizeof(SEQ_HDR));
	dMemcpy(pData, pDum+sizeof(SEQ_HDR), nDataLen);
	pEnc->Free(pDum);

	// Return data
	*ppOut		= pData;
	*pnOutLen	= nDataLen;

	return E_IOOK;
}

void AuthNull::SequenceFreePacket(BYTE *pData)
{
	dFree(pData);
}	


void * RPGAPI AuthNull::OnConnect(CIOSocket *pSock, CEncryptionEngine *pEnc, int nUserId)
{	
	INTERNAL *pNAI = (INTERNAL *)dMalloc(sizeof(INTERNAL));
	if(pNAI == NULL)
		return NULL;

	// Set up internal data structure
	pNAI->nUserId	= nUserId;
	pNAI->dwSeq		= Platform::getRealMilliseconds(); // Should be a random number generator. Can be hijacked if the encryption key is known.
	
	// Prepare authentication packet
	SEQ_HDR hdr;
	hdr.dwTag	= AUTH_TAG;
	hdr.dwSeq	= (pNAI->dwSeq-1);
	
	int	nSize	= (Platform::getRealMilliseconds() & 0xFF);	// Attention would-be hackers: Initial packet size is somewhat related to initial sequence number.
	BYTE	*pDum	= (BYTE *)dMalloc(nSize);
	if(pDum == NULL)
	{
		dFree(pNAI);
		return NULL;
	}

	dMemset(pDum,69,nSize);

	// Sequence and encrypt packet	
	BYTE	*pOut;
	int	nOutLen;

	if(SequenceEncryptPacket(pEnc,pDum,nSize,&pOut,&nOutLen,&hdr)  != E_IOOK) 
	{
		dFree(pDum);
		dFree(pNAI);
		return NULL;
	}
	dFree(pDum);
	
	// Send initial packet
	if(pSock->SendEx(pOut,nOutLen) != E_IOOK)
	{
		SequenceFreePacket(pOut);
		dFree(pNAI);
		return NULL;
	}
	SequenceFreePacket(pOut);

	// Wait for authentication handshake
	DWORD dwTime = Platform::getRealMilliseconds();
	while( pSock->RecvEx(&pDum,&nSize)  != E_IOOK) 
	{
		// Check for operation timeout
		if((Platform::getRealMilliseconds() - dwTime) >= AUTH_TIMEOUT) 
		{
			dFree(pNAI);
			return NULL;
		}
	}		
	
	// Decrypt handshake packet
	if(UnsequenceDecryptPacket(pEnc, pDum, nSize, &pOut, &nOutLen, &hdr)  != E_IOOK)
	{
		pSock->Free(pDum);
		dFree(pNAI);
		return NULL;
	}
	pSock->Free(pDum);	
	SequenceFreePacket(pOut);

	// Verify tag and store remote sequence number
	if(hdr.dwTag != AUTH_TAG) 
	{
		dFree(pNAI);
		return NULL;
	}
	pNAI->dwRemoteSeq	= hdr.dwSeq + 1;
	
	return pNAI;
}


void * RPGAPI AuthNull::OnAccept(void *pInternal, CIOSocket *pSock, CEncryptionEngine *pEnc)
{
	BYTE		*pDum,
				*pOut;
	int		nSize,
				nOutLen;
	SEQ_HDR	hdr;

	INTERNAL *pNAI		= (INTERNAL *)pInternal;
	INTERNAL *pNewNAI	= (INTERNAL *)dMalloc(sizeof(INTERNAL));
	if(pNewNAI == NULL) 
		return NULL;

	// Set up internal data structure
	pNewNAI->nUserId	= pNAI->nUserId;
	pNewNAI->dwSeq		= Platform::getRealMilliseconds(); // Should be a random number generator. Can be hijacked if the encryption key is known.
	
	// Wait for initial packet
	DWORD dwTime	= Platform::getRealMilliseconds();
	while(pSock->RecvEx(&pDum,&nSize)  != E_IOOK) 
	{
		// Check for operation timeout
		if((Platform::getRealMilliseconds() - dwTime) >= AUTH_TIMEOUT) 
		{
			dFree(pNewNAI);
			return NULL;
		}
	}		
	
	// Decrypt handshake packet
	if(UnsequenceDecryptPacket(pEnc,pDum,nSize,&pOut,&nOutLen,&hdr)  != E_IOOK)
	{
		pSock->Free(pDum);
		dFree(pNewNAI);
		return NULL;
	}
	pSock->Free(pDum);	
	SequenceFreePacket(pOut);


	// Verify tag and store remote sequence number
	if(hdr.dwTag != AUTH_TAG) 
	{
		dFree(pNewNAI);
		return NULL;
	}
	pNewNAI->dwRemoteSeq	= hdr.dwSeq + 1;

	// Prepare handshake packet
	hdr.dwTag	= AUTH_TAG;
	hdr.dwSeq	= (pNewNAI->dwSeq - 1);
	
	nSize	= (Platform::getRealMilliseconds() & 0xFF);	// Attention would-be hackers: Initial packet size is somewhat related to initial sequence number.
	pDum	= (BYTE *)dMalloc(nSize);
	if(pDum == NULL) 
	{
		dFree(pNewNAI);
		return NULL;
	}

	// Sequence and encrypt packet	
	if(SequenceEncryptPacket(pEnc,pDum,nSize,&pOut,&nOutLen,&hdr)  != E_IOOK) 
	{
		dFree(pDum);
		dFree(pNewNAI);
		return NULL;
	}
	dFree(pDum);
	
	// Send initial packet
	if(pSock->SendEx(pOut,nOutLen)  != E_IOOK) 
	{
		SequenceFreePacket(pOut);
		dFree(pNewNAI);
		return NULL;
	}
	SequenceFreePacket(pOut);
	
	return pNewNAI;
}



int RPGAPI AuthNull::GetUserID(void *pInternal)
{
	if(pInternal == NULL) 
		return  E_IOFAILED;

	return ((INTERNAL *)pInternal)->nUserId;
}


int RPGAPI AuthNull::OnClose(void *pInternal)
{
	if(pInternal == NULL) 
		return E_IOFAILED;
	
	dFree(pInternal);
	
	return  E_IOOK;
}


int RPGAPI AuthNull::OnRecv(void *pInternal, CEncryptionEngine *pEnc, BYTE *pData, int nDataLen, BYTE **ppInData, int *pnInDataLen)
{
	BYTE		*pDum;
	int		nSize;
	SEQ_HDR	hdr;
	INTERNAL *pNAI	=	(INTERNAL *)pInternal;

	if(ppInData == NULL || pnInDataLen == NULL || pData == NULL) 
		return E_IOFAILED;
	
	// This part does decryption and unsequencing
	
	// Decrypt packet
	if(UnsequenceDecryptPacket(pEnc,pData,nDataLen,&pDum,&nSize,&hdr)  != E_IOOK)
	{
		*ppInData		= NULL;
		*pnInDataLen	= 0;
		return E_IOFAILED;
	}
	
	// Verify tag and remote sequence number
	if( ( hdr.dwTag != AUTH_TAG) || (hdr.dwSeq != pNAI->dwRemoteSeq))  
	{
		SequenceFreePacket(pDum);
		*ppInData		= NULL;
		*pnInDataLen	= 0;
		return E_IOFAILED;
	}

	// Increment expected sequence number
	pNAI->dwRemoteSeq++;

	// Return decrypted packet
	*ppInData	= pDum;
	*pnInDataLen= nSize;

	return E_IOOK;
}


int RPGAPI AuthNull::OnSend(void *pInternal, CEncryptionEngine *pEnc, BYTE *pData, int nDataLen, BYTE **ppOutData, int *pnOutDataLen)
{
	SEQ_HDR	hdr;
	BYTE		*pDum;
	int		nSize;
	INTERNAL *pNAI	= (INTERNAL *)pInternal;

	if(ppOutData == NULL || pnOutDataLen == NULL) 
		return E_IOFAILED;
	
	// This part does encryption and sequencing
	
	// Create sequence header
	hdr.dwSeq	= pNAI->dwSeq;
	hdr.dwTag	= AUTH_TAG;

	// Encrypt packet
	if(SequenceEncryptPacket(pEnc,pData,nDataLen,&pDum,&nSize,&hdr) != E_IOOK) 
	{
		*ppOutData		= NULL;
		*pnOutDataLen	= 0;
		return E_IOFAILED;
	}

	// Increment sequence number
	pNAI->dwSeq++;

	// Return encrypted packet
	*ppOutData		= pDum;
	*pnOutDataLen	= nSize;
	
	return E_IOOK;
}


void RPGAPI AuthNull::Free(void *pInternal, BYTE *pBuffer)
{	
	if(pBuffer == NULL) 
		return;
	
	SequenceFreePacket(pBuffer);
}



// Returns true if the user can execute said command.
// Returns false if the user doesn't have priveleges.
BOOL RPGAPI AuthNull::ValidateCommand(int nUserId, int nCommand)
{
	return TRUE;
}



};//namespace CS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -