📄 authnull.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 + -