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

📄 asyncgsssocketlayer.cpp

📁 一个支持FTP,SFTP的客户端程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// GSSAsyncSocksifiedSocket.cpp: implementation of the CAsyncGssSocketLayer class.
//
//////////////////////////////////////////////////////////////////////
// Part of this code is copyright 2001 Massachusetts Institute of Technology

#include "stdafx.h"
#include "resource.h"
#include "AsyncGssSocketLayer.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

#define BUFSIZE (1024*8)

CAsyncGssSocketLayer::CAsyncGssSocketLayer()
{
	m_hGSS_API = NULL;
	m_transfer = FALSE;
	m_bInitialized=FALSE;
	m_bUseGSS=FALSE;
	m_nGssNetworkError=0;
	m_gotAuth=0;
	m_nShutDown = 0;

	pFzGss_ProcessCommand = NULL;
	pFzGss_InitGSS = NULL;
	pFzGss_KillGSS = NULL;
	pFzGss_DecryptMessage = NULL;
	pFzGss_EncryptMessage = NULL;
	pFzGss_EncryptData = NULL;
	pFzGss_DecryptData = NULL;

	m_pSendBuffer = NULL;
	m_nSendBufferLen = 0;
	m_nSendBufferSize = 0;

	m_pReceiveBuffer = NULL;
	m_nReceiveBufferLen = 0;
	m_nReceiveBufferSize = 0;

	m_pDecryptedReceiveBuffer = NULL;
	m_nDecryptedReceiveBufferLen = 0;
	m_nDecryptedReceiveBufferSize = 0;

	m_nAwaitingReply = 0;
}

CAsyncGssSocketLayer::~CAsyncGssSocketLayer()
{
	delete [] m_pSendBuffer;
	delete [] m_pReceiveBuffer;
	delete [] m_pDecryptedReceiveBuffer;
	
	KillGSSData();
}

int CAsyncGssSocketLayer::Send(const void* lpBuf, int nBufLen, int nFlags)
{
	if (m_gotAuth == GSSAPI_AUTHENTICATION_SUCCEEDED && m_bUseGSS)
	{
		if (m_nAwaitingReply == 3)
		{
			m_nAwaitingReply = 0;
			int res = SendNext(lpBuf, nBufLen, nFlags);
			if (res == nBufLen)
				m_nAwaitingReply = 0;
			return res;
		}
		if (m_nShutDown)
		{
			SetLastError(WSAESHUTDOWN);
			return SOCKET_ERROR;
		}
		
		if (!nBufLen)
			return 0;

		if (m_nSendBufferLen > BUFSIZE)
		{
			SetLastError(WSAEWOULDBLOCK);
			return SOCKET_ERROR;
		}

		char sendme[4096];
		char *encBuffer = m_tmpBuffer;
		int encBufferLen = 0;

		if ((nBufLen*1.5) > (1024*32))
			encBuffer = new char[(int)(nBufLen * 1.5)];
		memcpy(encBuffer, (char*)lpBuf, nBufLen);

		if (m_transfer)
		{
			if (nBufLen>4000)
				nBufLen=4000;
			
			encBuffer[nBufLen] = '\0';
			encBufferLen = pFzGss_EncryptData(m_pData, encBuffer, nBufLen, sendme);
		
			if (!encBufferLen)
			{
				if (encBuffer != m_tmpBuffer)
					delete [] encBuffer;
				return 0;
			}
		}
		else
		{
			encBuffer[nBufLen]='\0';
			int len = pFzGss_EncryptMessage(m_pData, encBuffer, sendme);
			if (!len) 
			{
				if (encBuffer != m_tmpBuffer)
					delete [] encBuffer;
				return 0;
			}

			char *str = new char[strlen(encBuffer) + 30];
			sprintf(str, "Encrypted command: %s", encBuffer);
			DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_INFO, (int)str);
			delete [] str;
			strcat(encBuffer, "\r\n");
			encBufferLen = strlen(encBuffer);
		}

		if (m_nSendBufferLen)
		{
			ASSERT(m_nSendBufferLen <= m_nSendBufferSize);
			ASSERT(m_pSendBuffer);
			int numsent = SendNext(m_pSendBuffer, m_nSendBufferLen, 0);
			if (!numsent)
			{
				if (encBuffer != m_tmpBuffer)
					delete [] encBuffer;
				return 0;
			}
			else if (numsent == SOCKET_ERROR && GetLastError()!=WSAEWOULDBLOCK)
			{
				if (encBuffer != m_tmpBuffer)
					delete [] encBuffer;
				return SOCKET_ERROR;
			}
			else if (numsent != m_nSendBufferLen)
			{
				if (numsent == SOCKET_ERROR)
					numsent = 0;
				if (!m_pSendBuffer)
				{
					m_pSendBuffer = new char[encBufferLen * 2];
					m_nSendBufferSize = encBufferLen * 2;
				}
				else if (m_nSendBufferSize < (m_nSendBufferLen + encBufferLen))
				{
					char *tmp = m_pSendBuffer;
					m_pSendBuffer = new char[m_nSendBufferSize + encBufferLen + 4096];
					m_nSendBufferSize = m_nSendBufferSize + encBufferLen + 4096;
					memcpy(m_pSendBuffer, tmp+numsent, m_nSendBufferLen-numsent);
					delete [] tmp;
				}
				else
					memmove(m_pSendBuffer, m_pSendBuffer + numsent, m_nSendBufferLen - numsent);
				memcpy(m_pSendBuffer + m_nSendBufferLen - numsent, encBuffer, encBufferLen);
				m_nSendBufferLen += encBufferLen-numsent;

				if (encBuffer != m_tmpBuffer)
					delete [] encBuffer;

				return nBufLen;
			}
			else
				m_nSendBufferLen = 0;
		}

		int numsent = SendNext(encBuffer, encBufferLen, 0);
		if (!numsent)
		{
			if (encBuffer != m_tmpBuffer)
				delete [] encBuffer;
			return 0;
		}
		if (numsent == SOCKET_ERROR)
		{
			if (GetLastError() != WSAEWOULDBLOCK)
			{
				if (encBuffer != m_tmpBuffer)
					delete [] encBuffer;
				return SOCKET_ERROR;
			}
			else
			{
				if (m_nSendBufferSize < encBufferLen)
				{
					delete [] m_pSendBuffer;
					m_pSendBuffer = new char[encBufferLen * 2];
					m_nSendBufferSize = encBufferLen * 2;
				}

				memcpy(m_pSendBuffer, encBuffer, encBufferLen);
				m_nSendBufferLen = encBufferLen;
			}
		}
		else if (numsent != encBufferLen)
		{
			if (m_nSendBufferSize < encBufferLen)
			{
				delete [] m_pSendBuffer;
				m_pSendBuffer = new char[encBufferLen * 2];
				m_nSendBufferSize = encBufferLen * 2;
			}
			memcpy(m_pSendBuffer, encBuffer+numsent, encBufferLen-numsent);
			m_nSendBufferLen = encBufferLen-numsent;
		}

		if (encBuffer != m_tmpBuffer)
			delete [] encBuffer;
		
		return nBufLen;
	}
	else
		return SendNext(lpBuf, nBufLen, nFlags);
}
/*
This method calls its super method to receive data.
If authentication succeeded at some point, then it tries to decrypt the data.
After decryption, it adds \r\n to the end of the buffer.
This method currently does not handle the MSG_PEEK flag, it also ignores nBufLen.
*/
int CAsyncGssSocketLayer::Receive(void *lpBuf, int nBufLen, int nFlags)
{
	if (m_gotAuth == GSSAPI_AUTHENTICATION_SUCCEEDED && m_bUseGSS)
	{
		if (m_nShutDown)
		{
			SetLastError(WSAESHUTDOWN);
			return SOCKET_ERROR;
		}

		if (!nBufLen)
			return 0;
	
		BOOL bTriggerRead = TRUE;
		if (!m_nDecryptedReceiveBufferLen)
		{
			bTriggerRead = FALSE;
			OnReceive(0);
		}
		
		if (m_nDecryptedReceiveBufferLen)
		{
			ASSERT(m_pDecryptedReceiveBuffer && m_nDecryptedReceiveBufferLen<=m_nDecryptedReceiveBufferSize);
			if (m_nDecryptedReceiveBufferLen > nBufLen)
			{
				memcpy(lpBuf, m_pDecryptedReceiveBuffer, nBufLen);
				memmove(m_pDecryptedReceiveBuffer, m_pDecryptedReceiveBuffer + nBufLen, m_nDecryptedReceiveBufferLen-nBufLen);
				m_nDecryptedReceiveBufferLen -= nBufLen;
				ASSERT(nBufLen>0);

				if (bTriggerRead)
					TriggerEvent(FD_READ, 0);

				return nBufLen;
			}
			else if (m_nDecryptedReceiveBufferLen == nBufLen)
			{
				memcpy(lpBuf, m_pDecryptedReceiveBuffer, nBufLen);
				m_nDecryptedReceiveBufferLen = 0;

				if (m_nGssNetworkError == -1)
				{
					//Trigger OnClose()
					TriggerEvent(FD_CLOSE, 0, TRUE);
				}
				else if (bTriggerRead)
					TriggerEvent(FD_READ, 0);

				return nBufLen;
			}
			else
			{
				memcpy(lpBuf, m_pDecryptedReceiveBuffer, m_nDecryptedReceiveBufferLen);
				int res = m_nDecryptedReceiveBufferLen;
				m_nDecryptedReceiveBufferLen = 0;

				if (m_nGssNetworkError == -1)
				{
					//Trigger OnClose()
					TriggerEvent(FD_CLOSE, 0, TRUE);
				}
				else if (bTriggerRead)
					TriggerEvent(FD_READ, 0);
				
				return res;
			}
		}
		else
		{
			if (m_nGssNetworkError==-1)
				return 0;
			else if (m_nGssNetworkError)
			{
				WSASetLastError(m_nGssNetworkError);
				return SOCKET_ERROR;
			}
			else
			{
				WSASetLastError(WSAEWOULDBLOCK);
				return SOCKET_ERROR;
			}
		}
	}
	else
		return ReceiveNext(lpBuf, nBufLen, nFlags);
}

void CAsyncGssSocketLayer::OnReceive(int nErrorCode) 
{
	if (!m_bUseGSS || m_gotAuth != GSSAPI_AUTHENTICATION_SUCCEEDED)
	{
		TriggerEvent(FD_READ, nErrorCode, TRUE);
		return;
	}

	//Don't decrypt additional data if buffer for decrypted data is not empty
	if (m_nDecryptedReceiveBufferLen && (GetLayerState()==attached || GetLayerState()==connected))
	{
		TriggerEvent(FD_READ, nErrorCode, TRUE);
		return;
	}

	char sendme[4096];
	//TRACE(m_transfer?"GSS OnReceive: called, transfer mode\n":"GSS OnReceive: called\n");
	int count = 10;
	while(count--)
	{
		if (m_transfer)
		{
			if (m_nReceiveBufferLen < 4)
			{
				if (!m_pReceiveBuffer)
				{
					ASSERT(!m_nReceiveBufferLen);
					ASSERT(!m_nReceiveBufferSize);
					m_pReceiveBuffer = new char[4096];
					m_nReceiveBufferSize = 4096;
					m_nReceiveBufferLen = 0;
				}
				int numread = ReceiveNext(m_pReceiveBuffer+m_nReceiveBufferLen, 4 - m_nReceiveBufferLen);
				if (!numread)
				{
					m_nGssNetworkError = -1;
					if (!m_nDecryptedReceiveBufferLen)
						TriggerEvent(FD_CLOSE, 0, TRUE);
					return;
				}
				else if (numread == SOCKET_ERROR)
				{
					if (GetLastError() != WSAEWOULDBLOCK)
					{
						TriggerEvent(FD_CLOSE, 0, TRUE);
						m_nGssNetworkError = GetLastError();
					}
					else
						if (m_nDecryptedReceiveBufferLen)
							TriggerEvent(FD_READ, nErrorCode, TRUE);
					return;
				}
				m_nReceiveBufferLen += numread;
				
				if (m_nReceiveBufferLen != 4)
				{
					if (m_nDecryptedReceiveBufferLen)
						TriggerEvent(FD_READ, nErrorCode, TRUE);
					return;
				}

				char tmp = m_pReceiveBuffer[0];
				m_pReceiveBuffer[0] = m_pReceiveBuffer[3];
				m_pReceiveBuffer[3] = tmp;
				tmp = m_pReceiveBuffer[1];
				m_pReceiveBuffer[1] = m_pReceiveBuffer[2];
				m_pReceiveBuffer[2] = tmp;
				unsigned int len = *(unsigned int*)m_pReceiveBuffer;
				if (len<4 || len > (1024*1024*4))
				{
					m_nGssNetworkError = WSAEMSGSIZE;
					TriggerEvent(FD_CLOSE, 0, TRUE);
					return;
				}
					
				if (m_nReceiveBufferSize < (len+4))
				{
					delete [] m_pReceiveBuffer;
					m_pReceiveBuffer = new char[len * 2 + 4];
					m_nReceiveBufferSize = len * 2 + 4;
				}
				memcpy(m_pReceiveBuffer, &len, 4);

⌨️ 快捷键说明

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