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

📄 pgpnetikeworker.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (c) 1998 Network Associates, Inc. and its Affiliated Companies
	All rights reserved.

	$Id: pgpNetIKEWorker.cpp,v 1.54.4.2 1999/06/16 04:52:08 elowe Exp $
____________________________________________________________________________*/

#include <windows.h>
#include <assert.h>
#include <queue>

// PGP includes
#include "pgpRMWOLock.h"
#include "pgpMem.h"
#include "pgpErrors.h"
#include "pgpEndianConversion.h"

// PGPnet includes
#include "pgpNetAppLog.h"
#include "pgpNetDebugLog.h"
#include "pgpIKE.h"
#include "pgpNetKernelXChng.h"
#include "pgpRWLockSignal.h"
#include "pgpNetQueueElement.h"
#include "pgpNetDSAarray.h"
#include "pgpNetCConfig.h"
#include "pgpNetIPC.h"

#include "pgpNetIKEWorker.h"

// external globals
extern CPGPrwLockSignal< std::queue<CPGPnetQueueElement> >	g_IKEQueue;
extern CPGPrwLockSignal< std::queue<CPGPnetQueueElement> >	g_UDPQueue;
extern CPGPrwLockSignal< std::queue<CPGPnetQueueElement> >	g_KernelQueue;
extern CPGPrwLockSignal< std::queue<CPGPnetQueueElement> >	g_GUIQueue;
extern CPGPrwLockSignal<CPGPnetDSAarray>					g_SAarray;
extern CPGPrwLockSignal<CPGPnetCConfig>	*					g_pConfig;

extern PGPUInt32		g_localIP;
extern PGPCond_t		g_localIPEvent;
extern PGPCond_t		g_ExitEvent;
extern PGPCond_t		g_ShutdownRequest;
extern PGPCond_t		g_SuspendEvent;
extern PGPContextRef	g_Context;

CPGPnetIKEWorker::CPGPnetIKEWorker()
: m_pIdData(0), m_pSharedKey(0), m_exitPending(FALSE)
{
	// Initialize IKE
	PGPError err = PGPNewIKEContext(g_Context, 
		CPGPnetIKEWorker::IKEMessageProc, 
		static_cast<void*>(this), 
		&m_ikeRef);

	if (IsPGPError(err)) {
		CPGPnetAppLog::instance()->logPGPEvent(err,
			0,
			__FILE__, 
			__LINE__);
		m_ikeRef = kInvalidPGPikeContextRef;
	}
}

CPGPnetIKEWorker::~CPGPnetIKEWorker()
{
	if (m_pIdData) {
		PGPFreeData(m_pIdData);
		m_pIdData = NULL;
	}
	delete [] m_pSharedKey;
	PGPFreeIKEContext(m_ikeRef);
}

PGPError
CPGPnetIKEWorker::IKEMessageProc(PGPikeContextRef ike,
		void * inUserData,
		PGPikeMessageType msg,
		void * data)
{
	CPGPnetIKEWorker *pMyself = static_cast<CPGPnetIKEWorker*>(inUserData);

	switch (msg) {
		case kPGPike_MT_SARequestFailed:
				CPGPnetDebugLog::instance()->dbgOut("Got SARequestFailed");

				// put onto the kernel queue
				g_KernelQueue.startWriting();

				g_KernelQueue.data().push(
					CPGPnetQueueElement(
						sizeof(PGPikeMTSAFailed),
						data, 
						OID_PGP_SAFAILED,
						0));

				g_KernelQueue.stopWriting();
				g_KernelQueue.setEvent();
				
				CPGPnetAppLog::instance()->logServiceEvent(
					kPGPnetSrvcError_SAFailed,
					static_cast<PGPikeMTSAFailed*>(data)->ipAddress,
					0,
					__FILE__,
					__LINE__);
			break;
		case kPGPike_MT_SAEstablished:
			{
				CPGPnetDebugLog::instance()->dbgOut(
					"Got SAEstablished");
				
				// we store the *pointer*
				CPGPnetQueueElement tElem(sizeof(PGPikeSA*),	
					&data,
					OID_PGP_NEWSA,
					static_cast<PGPikeSA*>(data)->ipAddress);

				// put onto kernel Queue
				g_KernelQueue.startWriting();
				g_KernelQueue.data().push(tElem);
				g_KernelQueue.stopWriting();
				g_KernelQueue.setEvent();

				// put onto GUI Queue
				g_GUIQueue.startWriting();
				g_GUIQueue.data().push(tElem);
				g_GUIQueue.stopWriting();
				g_GUIQueue.setEvent();
			}
			break;
		case kPGPike_MT_SADied:
			{
				CPGPnetDebugLog::instance()->dbgOut("Got SADied");

				// we store a copy of the spi, since IKE will 
				// free this SA after this function returns
				CPGPnetQueueElement tElem(sizeof(PGPipsecSPI),	
					static_cast<PGPikeSA*>(data)->transform[0].u.ipsec.inSPI,
					OID_PGP_SADIED,
					static_cast<PGPikeSA*>(data)->ipAddress);

				g_SAarray.startWriting();
				g_SAarray.data().removeSA(data, sizeof(PGPikeSA));
				g_SAarray.stopWriting();

				// put onto kernel queue
				g_KernelQueue.startWriting();
				g_KernelQueue.data().push(tElem);
				g_KernelQueue.stopWriting();
				g_KernelQueue.setEvent();
	
				// put onto GUI Queue
				g_GUIQueue.startWriting();
				g_GUIQueue.data().push(tElem);
				g_GUIQueue.stopWriting();
				g_GUIQueue.setEvent();
	
				break;
			}
		case kPGPike_MT_PolicyCheck:
			CPGPnetDebugLog::instance()->dbgOut("Got PolicyCheck");
			pMyself->doPolicyCheck(static_cast<PGPikeMTSASetup*>(data));
			break;
		case kPGPike_MT_LocalPGPCert:
			CPGPnetDebugLog::instance()->dbgOut("Got LocalPGPCert");
			pMyself->doLocalPGPCert(static_cast<PGPikeMTCert*>(data));
			break;
		case kPGPike_MT_LocalX509Cert:
			CPGPnetDebugLog::instance()->dbgOut("Got LocalX509Cert");
			pMyself->doLocalX509Cert(static_cast<PGPikeMTCert*>(data));
			break;
		case kPGPike_MT_RemoteCert:
			CPGPnetDebugLog::instance()->dbgOut("Got RemoteCert");
			pMyself->doRemoteCert(static_cast<PGPikeMTRemoteCert*>(data));
			break;
		case kPGPike_MT_Packet:
			CPGPnetDebugLog::instance()->dbgOut("Got MT_Packet");
			pMyself->doPacket(static_cast<PGPikeMTPacket*>(data));
			break;
		case kPGPike_MT_ClientIDCheck:
			CPGPnetDebugLog::instance()->dbgOut("Got MTAlert");
			pMyself->doClientIDCheck(static_cast<PGPikeMTClientIDCheck*>(data));
			break;
		case kPGPike_MT_SAUpdate:
			{
				CPGPnetDebugLog::instance()->dbgOut("Got SAUpdate");

				// we store a copy of the spi, since IKE will 
				// free this SA sometime soon
				CPGPnetQueueElement tElem(sizeof(PGPipsecSPI),	
					static_cast<PGPikeSA*>(data)->transform[0].u.ipsec.inSPI,
					OID_PGP_SAUPDATE,
					static_cast<PGPikeSA*>(data)->ipAddress);

				// put onto kernel queue
				g_KernelQueue.startWriting();
				g_KernelQueue.data().push(tElem);
				g_KernelQueue.stopWriting();
				g_KernelQueue.setEvent();
	
				break;
			}
		case kPGPike_MT_Alert:
			CPGPnetDebugLog::instance()->dbgOut("Got MTAlert");
			CPGPnetAppLog::instance()->logIKEAlert(
				static_cast<PGPikeMTAlert*>(data));
			break;
		case kPGPike_MT_DebugLog:
			CPGPnetDebugLog::instance()->dbgOut("%s", static_cast<char*>(data));
			break;
		default:
			break;
	}

	return kPGPError_NoErr;
}

unsigned int
CPGPnetIKEWorker::Run()
{
	PGPUInt32		ret = 0;
	const PGPInt16	numHandles = 4;
	HANDLE			lpHandles[numHandles];

	lpHandles[0] = g_ShutdownRequest;
	lpHandles[1] = g_ExitEvent;
	lpHandles[2] = g_IKEQueue.event();
	lpHandles[3] = g_SuspendEvent;

	PGPBoolean running = TRUE;
	while (running) {
		ret = WaitForMultipleObjects(numHandles,
									 lpHandles, 
									 FALSE, 
									 500);
		if (ret == WAIT_TIMEOUT) {
			PGPError err = PGPikeProcessMessage(m_ikeRef, 
				kPGPike_MT_Idle,
				NULL);

			if (IsPGPError(err)) {
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: PGPError processing MT_Idle: %d",
					err);

				CPGPnetAppLog::instance()->logPGPEvent(
					err,
					0,
					__FILE__,
					__LINE__);
			}
		} else if (ret >= WAIT_ABANDONED_0) {
			CPGPnetDebugLog::instance()->dbgOut(
				"IKEWorker: something abandoned");
			running = FALSE;
			goto end;
		} else if (ret >= WAIT_OBJECT_0) {
			switch (ret - WAIT_OBJECT_0) {
			case 0:
			{
				if (m_exitPending)
					break;

				m_exitPending = TRUE;
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: ShutdownRequest signaled");

				PGPError err = PGPikeProcessMessage(m_ikeRef, 
					kPGPike_MT_SAKillAll, 
					0);

				if (IsPGPError(err)) {
					CPGPnetDebugLog::instance()->dbgOut(
						"IKEWorker: PGPError processing kPGPike_MT_SAKillAll: %d",
						err);

					CPGPnetAppLog::instance()->logPGPEvent(
						err,
						0,
						__FILE__,
						__LINE__);
				}

	
				if (g_SAarray.data().numSAs() == 0) {
					PGPCondSignal(&g_ExitEvent);
					return kPGPError_NoErr;
				}
				break;
			}
			case 1:
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: ExitEvent signaled");
				running = FALSE;
				goto end;
				break;
			case 2:
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: IKEQueue event signaled");
				processQueue();
				break;
			case 3:
			{
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: SuspendEvent signaled");
				
				PGPError err = PGPikeProcessMessage(m_ikeRef, 
					kPGPike_MT_SAKillAll, 
					0);

				if (IsPGPError(err)) {
					CPGPnetDebugLog::instance()->dbgOut(
						"IKEWorker: PGPError processing kPGPike_MT_SAKillAll: %d",
						err);

					CPGPnetAppLog::instance()->logPGPEvent(
						err,
						0,
						__FILE__,
						__LINE__);
				}
	
				if (g_SAarray.data().numSAs() == 0) {
					return kPGPError_NoErr;
				}
				break;
			}
			default:
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: something signaled");
				break;
			}
		}
	}

end:
	return kPGPError_NoErr;
}

void
CPGPnetIKEWorker::processQueue()
{
	PGPError err = kPGPError_NoErr;

	while (!g_IKEQueue.data().empty()) {
		g_IKEQueue.startReading();
		// pull one thing off;
		CPGPnetQueueElement queueElem = g_IKEQueue.data().front();
		g_IKEQueue.stopReading();

		g_IKEQueue.startWriting();
		g_IKEQueue.data().pop();
		g_IKEQueue.stopWriting();

		switch (queueElem.type()) {
		case kPGPike_MT_Packet:
		{
			// MTPackets are stored as flat buffers
			// in the queue, so we need to unflatten it
			// into a PGPikeMTPacket structure.
			const PGPByte *buf = static_cast<const PGPByte*>(queueElem.data());
			PGPikeMTPacket packetHolder;
			
			packetHolder.ipAddress = queueElem.ipAddress();
			packetHolder.packetSize = queueElem.size();
			// create some memory for the packet info
			packetHolder.packet = new PGPByte[queueElem.size()];
			if (packetHolder.packet) {
				// copy from the flat buffer to the new pointer
				pgpCopyMemory(buf, 
					packetHolder.packet, 
					packetHolder.packetSize);

				struct in_addr foo;
				foo.S_un.S_addr = packetHolder.ipAddress;

				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: Processing MT_Packet (size: %d, from %s)",
					packetHolder.packetSize,
					inet_ntoa(foo));

				err = PGPikeProcessMessage(m_ikeRef, 
					kPGPike_MT_Packet, 
					&packetHolder);

				if (IsPGPError(err)) {
					CPGPnetDebugLog::instance()->dbgOut(
						"IKEWorker: PGPError processing MT_Packet: %d",
						err);

					CPGPnetAppLog::instance()->logPGPEvent(
						err,
						packetHolder.ipAddress,
						__FILE__,
						__LINE__);
				}
			} else {
				CPGPnetAppLog::instance()->logPGPEvent(
					kPGPError_OutOfMemory,
					packetHolder.ipAddress,
					__FILE__,
					__LINE__);
			}

			delete [] packetHolder.packet; // IKE makes a copy, so delete
			break;

		}
		case kPGPike_MT_SADied:
		{
			if (queueElem.size() != sizeof(PGPikeSA*)) {
				CPGPnetDebugLog::instance()->dbgOut("Bad SADIED size!");
				pgpAssert(TRUE);
				return;
			}
			// the queueElem contains a copy of the *pointer*
			PGPikeSA *pSA = 0;
			pgpCopyMemory(queueElem.data(), &pSA, sizeof(pSA));
			err = PGPikeProcessMessage(m_ikeRef, kPGPike_MT_SADied, pSA);
			if (IsPGPError(err)) {
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: PGPError processing MT_SADied: %d",
					err);

				CPGPnetAppLog::instance()->logPGPEvent(
					err,
					pSA->ipAddress,
					__FILE__,
					__LINE__);
			}
			break;
		}
		case kPGPike_MT_SARekey:
		{
			if (queueElem.size() != sizeof(PGPikeSA*)) {
				CPGPnetDebugLog::instance()->dbgOut("Bad SARekey size!");
				pgpAssert(TRUE);
				return;
			}
			// the queueElem contains a copy of the *pointer*
			PGPikeSA *pSA = 0;
			pgpCopyMemory(queueElem.data(), &pSA, sizeof(pSA));
			err = PGPikeProcessMessage(m_ikeRef, kPGPike_MT_SARekey, pSA);
			if (IsPGPError(err)) {
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: PGPError processing MT_SARekey: %d",
					err);

				CPGPnetAppLog::instance()->logPGPEvent(
					err,
					pSA->ipAddress,
					__FILE__,
					__LINE__);
			}
			break;
		}
		case kPGPike_MT_SARequest:
		{
			const PGPikeMTSASetup *pSAsetup = 
				static_cast<const PGPikeMTSASetup*>(queueElem.data());

			err = PGPikeProcessMessage(m_ikeRef,
				kPGPike_MT_SARequest,
				const_cast<PGPikeMTSASetup*>(pSAsetup));
			
			if (IsPGPError(err)) {
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: PGPError processing MT_SARequest: %d",
					err);

				CPGPnetAppLog::instance()->logPGPEvent(
					err,
					pSAsetup->ipAddress,
					__FILE__,
					__LINE__);
			}
			delete [] pSAsetup->sharedKey;
			if (pSAsetup->u.ipsec.idData) {
				PGPFreeData(pSAsetup->u.ipsec.idData);
			//	pSAsetup->u.ipsec.idData = NULL;
			}
			break;
		}
		case kPGPike_MT_Pref:
			// send Prefs from global config data
			g_pConfig->startReading();
			err = PGPikeProcessMessage(m_ikeRef,
				kPGPike_MT_Pref,
				const_cast<PGPikeMTPref *>
				(&(g_pConfig->data().config()->IkeExpirationPrefs)));
			
			if (IsPGPError(err)) {
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: PGPError processing MT_Pref: %d",
					err);

				CPGPnetAppLog::instance()->logPGPEvent(
					err,
					0,
					__FILE__,
					__LINE__);
			}

			err = PGPikeProcessMessage(m_ikeRef,
				kPGPike_MT_Pref,
				const_cast<PGPikeMTPref *>
				(&(g_pConfig->data().config()->IkeIkeProposalPrefs)));

			if (IsPGPError(err)) {
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: PGPError processing MT_Pref: %d",
					err);

				CPGPnetAppLog::instance()->logPGPEvent(
					err,
					0,
					__FILE__,
					__LINE__);
			}
			
			err = PGPikeProcessMessage(m_ikeRef,
				kPGPike_MT_Pref,
				const_cast<PGPikeMTPref *>
				(&(g_pConfig->data().config()->IkeIpsecProposalPrefs)));
			
			if (IsPGPError(err)) {
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: PGPError processing MT_Pref: %d",
					err);

				CPGPnetAppLog::instance()->logPGPEvent(
					err,
					0,
					__FILE__,
					__LINE__);
			}
			
			err = PGPikeProcessMessage(m_ikeRef,
				kPGPike_MT_Pref,
				const_cast<PGPikeMTPref *>
				(&(g_pConfig->data().config()->IkeAlgorithmPrefs)));
			
			if (IsPGPError(err)) {
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: PGPError processing MT_Pref: %d",
					err);

				CPGPnetAppLog::instance()->logPGPEvent(
					err,
					0,
					__FILE__,
					__LINE__);
			}
			g_pConfig->stopReading();

			break;
		default:
			// all other IKE messages do not require any processing
			err = PGPikeProcessMessage(m_ikeRef,
				static_cast<PGPikeMessageType>(queueElem.type()),
				const_cast<void*>(queueElem.data()));
			if (IsPGPError(err)) {
				CPGPnetDebugLog::instance()->dbgOut(
					"IKEWorker: PGPError processing %d: %d",
					queueElem.type(),
					err);

				CPGPnetAppLog::instance()->logPGPEvent(
					err,
					0,
					__FILE__,
					__LINE__);
			}
		}
	}
	g_IKEQueue.resetEvent();
}

void
CPGPnetIKEWorker::doPolicyCheck(PGPikeMTSASetup *tS)
{
	PGPBoolean found = FALSE;
	PGPInt32 i = 0;
	PGPNetHostEntry *host = 0;

	// fill in the values that I can right now
	tS->approved = FALSE;
	tS->doi = kPGPike_DOI_IPSEC;

	// put localIP request onto kernel queue
	g_KernelQueue.startWriting();
	g_KernelQueue.data().push(CPGPnetQueueElement(0,0,OID_PGP_LOCALIP,0));
	g_KernelQueue.stopWriting();
	g_KernelQueue.setEvent();	
	
	// wait for kernel queue to process request
	WaitForSingleObject(g_localIPEvent, INFINITE);

⌨️ 快捷键说明

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