📄 asyncgsssocketlayer.cpp
字号:
m_nReceiveBufferLen = 4;
}
ASSERT(m_pReceiveBuffer);
int len = *(int*)m_pReceiveBuffer;
ASSERT(len>4 && len < (1024*1024*4));
int lenToReceive = len - m_nReceiveBufferLen + 4;
int numread = ReceiveNext(m_pReceiveBuffer + m_nReceiveBufferLen, lenToReceive);
if (!numread)
{
m_nGssNetworkError = -1;
if (!m_nDecryptedReceiveBufferLen)
TriggerEvent(FD_CLOSE, 0, TRUE);
return;
}
else if (numread == SOCKET_ERROR)
{
if (GetLastError() != WSAEWOULDBLOCK)
{
m_nGssNetworkError = GetLastError();
TriggerEvent(FD_CLOSE, 0, TRUE);
}
return;
}
m_nReceiveBufferLen += numread;
if (numread != lenToReceive)
{
if (m_nDecryptedReceiveBufferLen)
TriggerEvent(FD_READ, nErrorCode, TRUE);
return;
}
ASSERT(m_nReceiveBufferLen-4 == len);
char * decBuffer = m_tmpBuffer;
if ((len*1.5) > (1024*32))
decBuffer = new char[(int)(len * 1.5)];
memcpy(decBuffer, m_pReceiveBuffer+4, len);
m_nReceiveBufferLen = 0;
int nDecrypted = pFzGss_DecryptData(m_pData, decBuffer, len, sendme);
if (nDecrypted <= 0)
{
if (!m_nDecryptedReceiveBufferLen)
//Trigger OnClose()
TriggerEvent(FD_CLOSE, 0, TRUE);
if (decBuffer != m_tmpBuffer)
delete [] decBuffer;
return;
}
//Add line to decrypted buffer
if (!m_pDecryptedReceiveBuffer)
{
ASSERT(!m_nDecryptedReceiveBufferSize && !m_nDecryptedReceiveBufferLen);
m_pDecryptedReceiveBuffer = new char[nDecrypted * 2];
m_nDecryptedReceiveBufferSize = nDecrypted * 2;
m_nDecryptedReceiveBufferLen = 0;
}
else if (m_nDecryptedReceiveBufferSize < (m_nDecryptedReceiveBufferLen+nDecrypted))
{
char *tmp=m_pDecryptedReceiveBuffer;
m_pDecryptedReceiveBuffer = new char[m_nDecryptedReceiveBufferSize + nDecrypted + 4096];
m_nDecryptedReceiveBufferSize = m_nDecryptedReceiveBufferSize + nDecrypted + 4096;
memcpy(m_pDecryptedReceiveBuffer, tmp, m_nDecryptedReceiveBufferLen);
delete [] tmp;
}
memcpy(m_pDecryptedReceiveBuffer + m_nDecryptedReceiveBufferLen, decBuffer, nDecrypted);
m_nDecryptedReceiveBufferLen += nDecrypted;
if (decBuffer != m_tmpBuffer)
delete [] decBuffer;
}
else
{
if (m_nAwaitingReply == 1)
{
ReceiveReply();
return;
}
int numread = ReceiveNext(m_tmpBuffer, BUFSIZE);
if (!numread)
{
m_nGssNetworkError = -1;
//Trigger OnClose()
TriggerEvent(FD_CLOSE, 0, TRUE);
return;
}
else if ( numread == SOCKET_ERROR )
{
if ( WSAGetLastError() != WSAEWOULDBLOCK )
{
m_nGssNetworkError = GetLastError();
TriggerEvent(FD_CLOSE, 0, TRUE);
}
else if (m_nDecryptedReceiveBufferLen)
TriggerEvent(FD_READ, 0, TRUE);
return;
}
if (!m_pReceiveBuffer)
{
ASSERT(!m_nReceiveBufferLen && !m_nReceiveBufferSize);
m_pReceiveBuffer = new char[numread * 2];
m_nReceiveBufferSize = numread * 2;
}
else if (m_nReceiveBufferSize < (m_nReceiveBufferLen + numread))
{
char *tmp=m_pReceiveBuffer;
m_pReceiveBuffer = new char[m_nReceiveBufferLen + numread + 4096];
m_nReceiveBufferSize = m_nReceiveBufferLen + numread + 4096;
memcpy(m_pReceiveBuffer, tmp, m_nReceiveBufferLen);
delete [] tmp;
}
memcpy(m_pReceiveBuffer+m_nReceiveBufferLen, m_tmpBuffer, numread);
int nOldLen = m_nReceiveBufferLen;
m_nReceiveBufferLen += numread;
//Now search for complete lines and decrypt them
for (int i=nOldLen; i<m_nReceiveBufferLen; i++)
{
if (m_pReceiveBuffer[i]=='\n')
{
if (!i)
{
if (m_nReceiveBufferLen>1)
memmove(m_pReceiveBuffer, m_pReceiveBuffer+1, m_nReceiveBufferLen-1);
m_nReceiveBufferLen--;
i--;
continue;
}
if (m_pReceiveBuffer[i-1]=='\r')
{
//We've found a line
char *decBuffer = m_tmpBuffer;
if ((i*1.5) > (1024*32))
decBuffer = new char[(int)(i * 1.5)];
memcpy(decBuffer, m_pReceiveBuffer, i-2);
decBuffer[i-1] = '\0';
//Delete encrypted line from receive buffer
if (!(m_nReceiveBufferLen-i-1))
m_nReceiveBufferLen = 0;
else
{
memmove(m_pReceiveBuffer, m_pReceiveBuffer+i+1, m_nReceiveBufferLen - i - 1);
m_nReceiveBufferLen -= i + 1;
}
// Decrypt line
char *str = new char[strlen(decBuffer) + 30];
sprintf(str, "Encrypted reply: %s", decBuffer);
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_INFO, (int)str);
delete [] str;
int nDecrypted = pFzGss_DecryptMessage(m_pData, decBuffer, sendme);
if (!nDecrypted)
{
m_nGssNetworkError = -1;
//Trigger OnClose()
TriggerEvent(FD_CLOSE, 0, TRUE);
if (decBuffer != m_tmpBuffer)
delete [] decBuffer;
return;
}
nDecrypted = strlen(decBuffer);
if (m_nAwaitingReply && m_nAwaitingReply<3)
{
while (decBuffer[nDecrypted - 1]=='\n' || decBuffer[nDecrypted - 1]=='\r')
nDecrypted--;
decBuffer[nDecrypted] = 0;
m_nAwaitingReply = 0;
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_REPLY, (int)decBuffer);
if (decBuffer[nDecrypted - 1]!='\n')
{
decBuffer[nDecrypted++]='\r';
decBuffer[nDecrypted++]='\n';
decBuffer[nDecrypted] = 0;
}
int res = pFzGss_ProcessReply(m_pData, decBuffer);
if (res == 1)
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_AUTHCOMPLETE, 0);
else if (res!=-1)
{
m_gotAuth = 0;
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_AUTHFAILED, 0);
}
if (decBuffer != m_tmpBuffer)
delete [] decBuffer;
}
else
{
if (decBuffer[nDecrypted - 1]!='\n')
{
decBuffer[nDecrypted++]='\r';
decBuffer[nDecrypted++]='\n';
decBuffer[nDecrypted] = 0;
}
//Add line to decrypted buffer
if (!m_pDecryptedReceiveBuffer)
{
m_pDecryptedReceiveBuffer = new char[nDecrypted * 2];
m_nDecryptedReceiveBufferSize = nDecrypted * 2;
m_nDecryptedReceiveBufferLen=0;
}
else if (m_nDecryptedReceiveBufferSize < (m_nDecryptedReceiveBufferLen+nDecrypted))
{
char *tmp=m_pDecryptedReceiveBuffer;
m_pDecryptedReceiveBuffer = new char[m_nDecryptedReceiveBufferSize + nDecrypted + 4096];
m_nDecryptedReceiveBufferSize = m_nDecryptedReceiveBufferSize + nDecrypted + 4096;
memcpy(m_pDecryptedReceiveBuffer, tmp, m_nDecryptedReceiveBufferLen);
delete [] tmp;
}
memcpy(m_pDecryptedReceiveBuffer + m_nDecryptedReceiveBufferLen, decBuffer, nDecrypted);
m_nDecryptedReceiveBufferLen += nDecrypted;
if (decBuffer != m_tmpBuffer)
delete [] decBuffer;
}
//Try to decrypt any additional lines
i=-1;
}
}
}
}
}
}
void CAsyncGssSocketLayer::Close()
{
CloseNext();
m_nAwaitingReply = 0;
m_nGssNetworkError=0;
if (!m_transfer)
m_gotAuth = 0;
m_nSendBufferLen = 0;
m_nReceiveBufferLen = 0;
m_nDecryptedReceiveBufferLen = 0;
KillGSSData();
}
BOOL CAsyncGssSocketLayer::UnLoadGSSLibrary()
{
if (m_hGSS_API)
{
FreeLibrary(m_hGSS_API);
m_hGSS_API = NULL;
}
return TRUE;
}
BOOL CAsyncGssSocketLayer::LoadGSSLibrary()
{
if (m_hGSS_API)
return TRUE;
m_hGSS_API = LoadLibrary(GFTPDLL);
return !(m_hGSS_API==NULL);
}
BOOL CAsyncGssSocketLayer::InitGSS(BOOL bSpawned, BOOL promptPassword)
{
if (m_bUseGSS)
return TRUE;
if (m_bInitialized)
return TRUE;
if (!m_hGSS_API)
LoadGSSLibrary();
if (!m_hGSS_API)
return FALSE;
if (m_hGSS_API)
{
pFzGss_ProcessCommand = (t_FzGss_ProcessCommand)GetProcAddress(m_hGSS_API, "ProcessCommand");
pFzGss_DecryptMessage = (t_FzGss_DecryptMessage)GetProcAddress(m_hGSS_API, "DecryptMessage");
pFzGss_EncryptMessage = (t_FzGss_EncryptMessage)GetProcAddress(m_hGSS_API, "EncryptMessage");
pFzGss_EncryptData = (t_FzGss_EncryptData)GetProcAddress(m_hGSS_API , "EncryptData");
pFzGss_DecryptData = (t_FzGss_DecryptData)GetProcAddress(m_hGSS_API, "DecryptData");
pFzGss_InitGSS = (t_FzGss_InitGSS)GetProcAddress(m_hGSS_API, "InitGSS");
pFzGss_KillGSS = (t_FzGss_KillGSS)GetProcAddress(m_hGSS_API, "KillGSS");
pFzGss_DoClientAuth = (t_FzGss_DoClientAuth)GetProcAddress(m_hGSS_API, "DoClientAuth");
pFzGss_ProcessReply = (t_FzGss_ProcessReply)GetProcAddress(m_hGSS_API, "ProcessReply");
pFzGss_GetUserFromKrbTicket = (t_FzGss_GetUserFromKrbTicket)GetProcAddress(m_hGSS_API, "GetUserFromKrbTicket");
if (!pFzGss_ProcessCommand || !pFzGss_InitGSS || !pFzGss_KillGSS||
!pFzGss_DecryptMessage || !pFzGss_EncryptMessage || !pFzGss_EncryptData ||
!pFzGss_DecryptData ||
!pFzGss_DoClientAuth ||
!pFzGss_ProcessReply ||
!pFzGss_GetUserFromKrbTicket
)
{
return FALSE;
}
}
if (!bSpawned)
{
m_pData=new void*;
pFzGss_InitGSS(m_pData, Callback, this, promptPassword);
}
if (!bSpawned)
m_bInitialized = TRUE;
m_bUseGSS = TRUE;
return TRUE;
}
BOOL CAsyncGssSocketLayer::KillGSSData()
{
if (!m_bUseGSS)
return FALSE;
if (!m_bInitialized)
return TRUE;
m_bUseGSS = FALSE;
pFzGss_KillGSS(m_pData);
m_bInitialized = FALSE;
delete m_pData;
m_pData = NULL;
UnLoadGSSLibrary();
return TRUE;
}
BOOL CAsyncGssSocketLayer::InitTransferChannel(CAsyncGssSocketLayer *pSocket)
{
KillGSSData();
InitGSS(TRUE);
m_pData = pSocket->m_pData;
m_bUseGSS = pSocket->m_bUseGSS;
m_gotAuth = pSocket->m_gotAuth;
m_transfer = TRUE;
return TRUE;
}
void CAsyncGssSocketLayer::OnSend(int nErrorCode)
{
if (!m_nSendBufferLen)
TriggerEvent(FD_WRITE, nErrorCode, TRUE);
else
{
ASSERT(m_pSendBuffer);
int numsent = SendNext(m_pSendBuffer, m_nSendBufferLen, 0);
if (!numsent)
TriggerEvent(FD_CLOSE, nErrorCode, TRUE);
else if (numsent == SOCKET_ERROR)
{
if (GetLastError() != WSAEWOULDBLOCK)
TriggerEvent(FD_CLOSE, nErrorCode, TRUE);
}
else if (numsent != m_nSendBufferLen)
{
memmove(m_pSendBuffer, m_pSendBuffer + numsent, m_nSendBufferLen - numsent);
m_nSendBufferLen -= numsent;
}
else
{
m_nSendBufferLen = 0;
if (ShutDownComplete())
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_SHUTDOWN_COMPLETE, 0);
else
TriggerEvent(FD_WRITE, nErrorCode, TRUE);
}
}
}
BOOL CAsyncGssSocketLayer::ShutDown(int nHow /*=sends*/)
{
if (m_gotAuth == GSSAPI_AUTHENTICATION_SUCCEEDED && m_bUseGSS)
{
if (m_nShutDown)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -