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

📄 asyncgsssocketlayer.cpp

📁 一个支持FTP,SFTP的客户端程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{
	if (m_gotAuth == GSSAPI_AUTHENTICATION_SUCCEEDED && m_bUseGSS)
	{
		if (m_nShutDown)
		{
			if (m_nSendBufferLen)
				return FALSE;
			else
				return TRUE;
		}
		m_nShutDown = 1;

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

		encBufferLen = pFzGss_EncryptData(m_pData, encBuffer, 0, sendme);
		if (!encBufferLen)
		{
			WSASetLastError(WSAENETDOWN);
			return FALSE;
		}
		
		encBuffer[encBufferLen++] = '\r';
		encBuffer[encBufferLen++] = '\n';

		if (m_nSendBufferLen)
		{
			ASSERT(m_pSendBuffer);
			int numsent = SendNext(m_pSendBuffer, m_nSendBufferLen, 0);
			if (!numsent)
				return TRUE;
			else if (numsent == SOCKET_ERROR && GetLastError()!=WSAEWOULDBLOCK)
				return TRUE;
			else if (numsent != m_nSendBufferLen)
			{
				if (numsent == SOCKET_ERROR)
					numsent = 0;
				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;

				WSASetLastError(WSAEWOULDBLOCK);
				return FALSE;
			}
			else
				m_nSendBufferLen = 0;
		}

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

				memcpy(m_pSendBuffer, encBuffer, encBufferLen);
				m_nSendBufferLen = encBufferLen;
				return FALSE;
			}
			return TRUE;
		}

		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 (m_nSendBufferLen)
		{
			WSASetLastError(WSAEWOULDBLOCK);
			return FALSE;
		}
		else
			return TRUE;
	}
	else
		return ShutDownNext();
}

BOOL CAsyncGssSocketLayer::ShutDownComplete()
{
	//If a ShutDown was issued, has the connection already been shut down?
	if (!m_nShutDown)
		return FALSE;
	else if (m_gotAuth != GSSAPI_AUTHENTICATION_SUCCEEDED || !m_bUseGSS)
		return FALSE;
	else if (m_nSendBufferLen)
		return FALSE;
	else
		return TRUE;
}

int CAsyncGssSocketLayer::ProcessCommand(const char *command, const char *args, char *sendme)
{
	ASSERT(command);
	ASSERT(sendme);

	if (!m_bUseGSS)
	{
		strcpy(sendme, "501 GSSAPI not initialized");
		return -1;
	}
	
	char *argBuffer = m_tmpBuffer;
	if ((strlen(args) + 1000) >= (1024*32))
		argBuffer = new char[strlen(args) + 1000];
	
	if (!strcmp(command, "ADAT"))
	{
		SOCKADDR_IN his_addr;
		SOCKADDR_IN ctrl_addr;
		
		int addrlen = sizeof (his_addr);
		if (!GetPeerName((SOCKADDR*)&his_addr, &addrlen))
		{
			if (argBuffer != m_tmpBuffer)
				delete [] argBuffer;
			sprintf(sendme, "501 unable to getpeername");
			return -1;
		}
		
		addrlen = sizeof (ctrl_addr);
		if (!GetSockName((SOCKADDR*)&ctrl_addr, &addrlen))
		{
			if (argBuffer != m_tmpBuffer)
				delete [] argBuffer;
			sprintf(sendme, "501 unable to getsockname");
			return -1;
		}
		
		char localname[513];
		struct hostent *hp;

		if (gethostname(localname, 512))
		{
			if (argBuffer != m_tmpBuffer)
				delete [] argBuffer;
			sprintf(sendme, "501 couldn't get local hostname (%d)", errno);
			return -1;
		}
		
		hp = gethostbyname(localname);
		if (!hp) 
		{
			if (argBuffer != m_tmpBuffer)
				delete [] argBuffer;
			sprintf(sendme, "501 couldn't canonicalize local hostname");
			return -1;
		}
		strncpy(localname, hp->h_name, sizeof(localname) - 1);
		localname[sizeof(localname) - 1] = '\0';
		
		memcpy(argBuffer, &his_addr.sin_addr.s_addr, 4);
		memcpy(argBuffer+4, &ctrl_addr.sin_addr.s_addr, 4);
		strcpy(argBuffer + 8, localname);
		strcpy(argBuffer + 8 + strlen(localname) + 1, args);
	}
	else
		strcpy(argBuffer, args);

	int res = pFzGss_ProcessCommand(m_pData, command, argBuffer, sendme);

	if (!strcmp(command, "ADAT") && res != -1)
	{
		m_nAwaitingReply = 3;
		m_gotAuth = GSSAPI_AUTHENTICATION_SUCCEEDED;
	}
	
	if (argBuffer != m_tmpBuffer)
		delete [] argBuffer;

	return res;
}

BOOL CAsyncGssSocketLayer::AuthSuccessful() const
{
	return m_gotAuth == GSSAPI_AUTHENTICATION_SUCCEEDED;
}

int CAsyncGssSocketLayer::ProcessCommand(const char *command, const char *args1, const char *args2, char *sendme)
{
	ASSERT(command);
	ASSERT(sendme);

	if (!m_bUseGSS)
	{
		strcpy(sendme, "501 GSSAPI not initialized");
		return -1;
	}
	
	char *argBuffer = m_tmpBuffer;
	if ((strlen(args1) + strlen(args2) + 10) >= (1024*32))
		argBuffer = new char[strlen(args1) + strlen(args2) + 10];
	
	strcpy(argBuffer, args1);
	strcpy(argBuffer + strlen(args1) + 1, args2);

	int res = pFzGss_ProcessCommand(m_pData, command, argBuffer, sendme);

	if (!strcmp(command, "ADAT") && res != -1)
		m_gotAuth = GSSAPI_AUTHENTICATION_SUCCEEDED;
	
	if (argBuffer != m_tmpBuffer)
		delete [] argBuffer;

	return res;
}

int CAsyncGssSocketLayer::GetClientAuth(const char* pHost)
{
	if (m_hGSS_API)
	{
		char *hostname;
		int res;
		
		hostname = new char[strlen(pHost)+1];
		strcpy(hostname, pHost);
	
		memset(&m_myAddr, 0, sizeof(m_myAddr));
		int SockAddrLen = sizeof(m_myAddr);
		if (!GetPeerName(&m_myAddr, &SockAddrLen))
		{
			DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_ERROR, (int)"GetAuth() GetPeerName() failed");
			return FALSE;
		}
				
		memset(&m_hisAddr, 0, sizeof(m_hisAddr));
		if (!GetSockName(&m_hisAddr, &SockAddrLen))
		{
			DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_ERROR, (int)"GetAuth() GetSockName() failed");
			return FALSE;
		}
				
		res = pFzGss_DoClientAuth(m_pData, hostname,
			&m_myAddr,
			&m_hisAddr,
			'P', 0);
		
		m_gotAuth = res;
		if (m_gotAuth == -1)
			m_gotAuth = 1;
		delete [] hostname;
		return res;
	}
	else
	{
		DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_ERROR, (int)"GetClientAuth(933): GSS api not initialized!");
		m_gotAuth = 0;//SEND_DATA_IN_THE_CLEAR;
	}
	return m_gotAuth;
}

void CAsyncGssSocketLayer::OnClose(int nErrorCode)
{
	if (!m_nGssNetworkError)
		m_nGssNetworkError = -1;
	if (!nErrorCode)
		OnReceive(0);
	if (!m_nDecryptedReceiveBufferLen)
		TriggerEvent(FD_CLOSE, nErrorCode, TRUE);
}

int CALLBACK CAsyncGssSocketLayer::Callback(void *pData, int nParam1, int nParam2, int nParam3)
{
	CAsyncGssSocketLayer *pLayer = reinterpret_cast<CAsyncGssSocketLayer *>(pData);
	switch (nParam1)
	{
	case 0:
		pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_INFO, nParam2);
		break;
	case 1:
		{
			char *buffer = (char *)nParam2;
			int len = strlen(buffer);
			if (nParam3)
			{
				pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_COMMAND, nParam3);
				char *str = new char[strlen((char *)nParam2)+25];
				sprintf(str, "Encrypted command: %s", (char *)nParam2);
				pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_INFO, (int)str);
				delete [] str;
			}
			else
				pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_COMMAND, nParam2);
			pLayer->m_nAwaitingReply = nParam3 ? 2:1;
	
			if (!pLayer->m_pSendBuffer)
			{
				pLayer->m_pSendBuffer = new char[len + 4096];
				pLayer->m_nSendBufferSize = len + 4096;
			}
			else if (pLayer->m_nSendBufferSize < (pLayer->m_nSendBufferLen + len + 2))
			{
				char *tmp = pLayer->m_pSendBuffer;
				pLayer->m_pSendBuffer = new char[pLayer->m_nSendBufferLen + len + 4096];
				pLayer->m_nSendBufferSize = pLayer->m_nSendBufferLen + len + 4096;
				memcpy(pLayer->m_pSendBuffer, tmp, pLayer->m_nSendBufferLen);
				delete [] tmp;
			}

			memcpy(pLayer->m_pSendBuffer+pLayer->m_nSendBufferLen, (char *)nParam2, len);
			pLayer->m_pSendBuffer[pLayer->m_nSendBufferLen+len] = '\r';
			pLayer->m_pSendBuffer[pLayer->m_nSendBufferLen+len+1] = '\n';
			pLayer->m_nSendBufferLen += len + 2;
			pLayer->TriggerEvent(FD_WRITE, 0);
			break;
		}
	}
	return 0;
}

void CAsyncGssSocketLayer::ReceiveReply()
{
	if (m_nReceiveBufferSize < 4096)
	{
		delete [] m_pReceiveBuffer;
		m_pReceiveBuffer = new char[4096];
		m_nReceiveBufferSize = 4096;
	}

	char buffer;
	int numread = ReceiveNext(&buffer, 1);
	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 (buffer == 0 || buffer=='\r' || buffer=='\n')
	{
		if (!m_nReceiveBufferLen)
			return;
		m_nAwaitingReply = 0;
		m_pReceiveBuffer[m_nReceiveBufferLen] = 0;	
		DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_REPLY, (int)m_pReceiveBuffer);
		int res = pFzGss_ProcessReply(m_pData, m_pReceiveBuffer);
		m_nReceiveBufferLen = 0;
		if (res == 1)
			DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_AUTHCOMPLETE, 0);
		else if (res==-1)
			return;
		else
		{
			m_gotAuth = 0;
			DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, GSS_AUTHFAILED, 0);
		}
	}
	else if (m_nReceiveBufferLen < 4095)
		m_pReceiveBuffer[m_nReceiveBufferLen++] = buffer;
}

BOOL CAsyncGssSocketLayer::GetUserFromKrbTicket(char *buffer)
{
	if (!m_gotAuth || !m_bUseGSS || !m_pData || !pFzGss_GetUserFromKrbTicket)
		return FALSE;

	return pFzGss_GetUserFromKrbTicket(m_pData, buffer);
}

⌨️ 快捷键说明

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