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

📄 pgpnetpolicymanager.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 1998, Network Associates, Inc.
 * All rights reserved.
 *
 * $Id: pgpNetPolicyManager.c,v 1.63.4.2 1999/06/17 21:15:20 elowe Exp $
 *
 */
#include <ndis.h>

#include "ipdef.h"
#include "vpn.h"
#include "vpndbg.h"

#include "pgpMem.h"
#include "pgpNetKernel.h"
#include "pgpNetKernelXChng.h"
#include "pgpNetPMConfig.h"
#include "pgpNetPMHost.h"
#include "pgpNetPMSA.h"
#include "pgpNetPMEvents.h"

/* some IPSEC helper functions */
#include "pgpIPsecBuffer.h"
#include "pgpIPsecESP.h"
#include "pgpIPsecAH.h"
#include "pgpIPheader.h"

#define ESP_HEADERSIZE	8
#define AH_HEADERSIZE	12

#ifndef PM_EMULATION

static void sCheckRekey(PVPN_ADAPTER adapter, PGPnetKernelSA *pSA);
static void sCopySrcToxForm(PGPNDIS_PACKET *start);
static void sCopyPacketXformToSrc(const PGPNDIS_PACKET *source, PGPNDIS_PACKET *dest,PVPN_ADAPTER adapter);
static PGPBoolean sCheckExpiration(PVPN_ADAPTER	adapter,
								   PGPnetKernelSA *pSA);
static PGPnetPMStatus sDoTransformOutgoing(PGPnetPMContext *pContext,
										   PGPNDIS_PACKET *packet,
										   PVPN_ADAPTER adapter);
static PGPnetPMStatus sDoTransformIncoming(PGPnetPMContext *pContext,
										   PGPNDIS_PACKET *packet,
										   PVPN_ADAPTER adapter);
static PGPnetPMStatus sAcquireSA(PGPnetPMContext *pContext,
								 PGPUInt32 ipAddress,
								 PGPUInt32 ipAddrStart,
								 PGPUInt32 ipMaskEnd,
								 PGPBoolean incoming,
								 void * ipBuffer,
								 PGPUInt32 ipBufferSize,
								 PVPN_ADAPTER adapter,
								 PGPnetKernelSA **pSA);
static PGPnetPMStatus sLookHardForSA(PGPnetPMContext *pContext, 
			   PVPN_ADAPTER adapter,
			   PGPNetHostEntry *host,
			   PGPUInt32 ipAddress,
			   PGPUInt16 port,
			   void *ipBuffer,
			   PGPUInt32 ipBufferSize,
			   PGPnetKernelSA **ppTransport,
			   PGPnetKernelSA **ppTunnel,
			   PGPBoolean incoming);



void
PGPnetRASdisconnect(PVPN_ADAPTER adapter)
{
	/* fire event */
	DBG_FUNC("PGPnetRASdisconnect")

	PGPMESSAGE_CONTEXT	*	kernelMessageContext;
	PGPnetMessageHeader *	kernelMessageHeader;
	PGPUInt32				head = 0;

	DBG_ENTER();

	if ((adapter != NULL) && (adapter->pgpMessage != NULL)) {
		kernelMessageContext = (PGPMESSAGE_CONTEXT*)(adapter->pgpMessage);
		kernelMessageHeader = &kernelMessageContext->header;
		
		NdisAcquireSpinLock(&adapter->general_lock);

		head = kernelMessageHeader->head + 1;

		if (head > kernelMessageHeader->maxSlots)
			head = 1;

		kernelMessageContext = &kernelMessageContext[head];
		kernelMessageContext->messageType = PGPnetMessageRASdisconnect;

		kernelMessageHeader->head = head;

		NdisReleaseSpinLock(&adapter->general_lock);

		PgpEventSet(&adapter->pgpEvent);
	}

	DBG_LEAVE(0);
}

void
PGPnetRASconnect(PVPN_ADAPTER adaptor, ULONG ipAddress)
{
	DBG_FUNC("PGPnetRASconnect")

	DBG_ENTER();

	DBG_PRINT(("New IP address Report, ipAddress: %xh\n", ipAddress););
	DBG_LEAVE(0);

}

/*
 * This is the Heavy (or default) NeedTransform. It starts
 * the SA acquisition process.
 */
PGPnetPMStatus
PGPnetPMNeedTransform(PGPnetPMContext *pContext, 
					  PGPUInt32 ipAddress, 
					  PGPUInt16 port,
					  PGPBoolean incoming,
					  void * ipBuffer,
					  PGPUInt32 ipBufferSize,
					  void * reserved)
{
	PGPNetHostEntry *	host 		= PMFindHost(pContext, ipAddress);
	PVPN_ADAPTER		adapter		= (PVPN_ADAPTER) reserved;
	PGPnetPMStatus		ret;
	PGPnetKernelSA *	pSA;
	
    DBG_FUNC("PGPnetPMNeedTransform")

	DBG_ENTER();

	ret = PGPnetPMNeedTransformLight(pContext, ipAddress, incoming, adapter);

	if (ret == kPGPNetPMPacketEncrypt) {
		ret = sLookHardForSA(pContext, 
			adapter,
			host,
			ipAddress,
			port,
			ipBuffer,
			ipBufferSize,
			&pSA,
			&pSA,
			incoming);

		if (ret != kPGPNetPMPacketEncrypt && port == UDP_PORT_IKE_NET)
			ret = kPGPNetPMPacketClear;

		DBG_LEAVE(ret);
		return ret;
	}

	DBG_LEAVE(ret);

	return ret;
}

/*
 * This is the lightweight version of NeedTransform. It does not
 * start the SA acquisition process.
 */
PGPnetPMStatus
PGPnetPMNeedTransformLight(PGPnetPMContext *pContext, 
					  PGPUInt32 ipAddress, 
					  PGPBoolean incoming,
					  void * reserved)
{
	PGPNetHostEntry *	host 		= PMFindHost(pContext, ipAddress);
	PGPNetHostEntry *	secureGW	= 0;
	PVPN_ADAPTER		adapter		= (PVPN_ADAPTER) reserved;
	
    DBG_FUNC("PGPnetPMNeedTransformLight")

	DBG_ENTER();
	/* configuration not here yet, default to clear */
	if (!pContext->pConfig) {
		DBG_PRINT(("kPGPNetPMPacketClear because no config yet\n"););
		DBG_LEAVE(kPGPNetPMPacketClear);
		return kPGPNetPMPacketClear;
	}

	if (!pContext->pConfig->bPGPnetEnabled){
		DBG_PRINT(("kPGPNetPMPacketClear because PGPnet disabled by user\n"););
		DBG_LEAVE(kPGPNetPMPacketClear);
		return kPGPNetPMPacketClear;
	}
	
	if (host) {
		/* Check for insecure host and no gateway */
		if (host->hostType == kPGPnetInsecureHost && host->childOf == -1) {
			DBG_PRINT(("kPGPNetPMPacketClear because host is insecure\n"););
			DBG_LEAVE(kPGPNetPMPacketClear);
			return kPGPNetPMPacketClear;
		}

		DBG_PRINT(("kPGPNetPMPacketEncrypt\n"););
		DBG_LEAVE(kPGPNetPMPacketEncrypt);
		return kPGPNetPMPacketEncrypt;
	}

	if (pContext->pConfig->bAllowUnconfigHost && 
		pContext->pConfig->bAttemptUnconfigHost) {
		DBG_PRINT(("kPGPNetPMPacketEncrypt\n"););
		DBG_LEAVE(kPGPNetPMPacketEncrypt);
		return kPGPNetPMPacketEncrypt;
	}

	if (pContext->pConfig->bAllowUnconfigHost && 
		!pContext->pConfig->bAttemptUnconfigHost) {
		/* 
		 * There may be an SA for this host that was initiated by the peer.
		 * So we need to look for an SA, before sending it in the clear
		 */
		if (PMFindSA(pContext, ipAddress, 0, incoming)) {
			DBG_PRINT(("kPGPNetPMPacketEncrypt because SA exists\n"););
			DBG_LEAVE(kPGPNetPMPacketEncrypt);
			return kPGPNetPMPacketEncrypt;
		} else {
			DBG_PRINT(("kPGPNetPMPacketClear because bAllow && !bAttempt\n"););
			DBG_LEAVE(kPGPNetPMPacketClear);
			return kPGPNetPMPacketClear;
		}
	}

	if (!pContext->pConfig->bAllowUnconfigHost) {
		DBG_PRINT(("kPGPNetPMPacketDrop because !bAllow\n"););
		DBG_LEAVE(kPGPNetPMPacketDrop);
		return kPGPNetPMPacketDrop;
	}

	DBG_PRINT(("kPGPNetPMPacketDrop because default\n"););
	DBG_LEAVE(kPGPNetPMPacketDrop);

	return kPGPNetPMPacketDrop;
}

PGPnetPMStatus
PGPnetPMDoTransform(PGPnetPMContext *pContext, 
					PGPNDIS_PACKET *packet,
					PGPBoolean incoming,
					PVPN_ADAPTER adapter)
{
	PGPnetPMStatus retCode;
	PGPUInt32 i = 0;

    DBG_FUNC("PGPnetPMDoTransform")

    DBG_ENTER();

	packet->xformBlockLen = 0;
	if (!incoming) {
		retCode = sDoTransformOutgoing(pContext, packet, adapter);
	} else {
		retCode = sDoTransformIncoming(pContext, packet, adapter);
	}

#if/*def*/ 0 /*DBG*/
	/* write out packet src info */
	DBG_PRINT(("Incoming: %s\n", incoming ? "TRUE" : "FALSE"););
	DBG_PRINT(("packet->srcBlockLen: %d\n", packet->srcBlockLen););
	DBG_PRINT(("packet->srcBlock: %X\n", packet->srcBlock););
	for (i = 0; i<packet->srcBlockLen; i++) {
		DbgPrint("%X ", packet->srcBlock[i]);
		if (((i+1) % 16) == 0) {
			DbgPrint("\n");
		}
	}
	DbgPrint("\n");

	/* write out packet xform info */
	DBG_PRINT(("packet->xformBlockLen: %d\n", packet->xformBlockLen););
	DBG_PRINT(("packet->xformBlock: %X\n", packet->xformBlock););
	for (i = 0; i<packet->xformBlockLen; i++) {
		DbgPrint("%X ", packet->xformBlock[i]);
		if (((i+1) % 16) == 0) {
			DbgPrint("\n");
		}
	}
	DbgPrint("\n");
#endif

	return retCode;
}

#endif // !PM_EMULATION

PGPnetPMStatus
sAcquireSA(PGPnetPMContext *pContext, 
		   PGPUInt32 ipAddress,
		   PGPUInt32 ipAddrStart,
		   PGPUInt32 ipMaskEnd,
		   PGPBoolean incoming,
		   void *ipBuffer,
		   PGPUInt32 ipBufferSize,
		   PVPN_ADAPTER adapter,
		   PGPnetKernelSA **pSA)
{
	PGPnetPMStatus		ret;
	PGPUInt32 spi = 0;
	PGPError err = kPGPError_NoErr;
	PGPIPsecBuffer inPacket;

	DBG_FUNC("sAcquireSA")

	DBG_ENTER();

	if (incoming) {
		
		PGPUInt32 unused;

		if (ipBufferSize == 0) {
			/* assume ipBuffer is an PGPNDIS_PACKET */
			/* Bad Assumption? XXX */
			PGPNDIS_PACKET *packet = (PGPNDIS_PACKET*)ipBuffer;

			packet->xformBlockLen = 0;
			err = PGPnetIPsecGetAddrAndSPI(pContext, 
				packet,
				&unused,
				&spi);
		} else {
			// look for spi in the ipBuffer, hopefully we have
			// read in enough data. If not, then say we will encrypt
			// and deal with any problems later

			if (ipBufferSize < (sizeof(IP_HEADER) + ESP_HEADERSIZE) ) {
				DBG_LEAVE(kPGPNetPMPacketEncrypt);
				return kPGPNetPMPacketEncrypt;
			}	

			inPacket.data = ipBuffer;
			inPacket.dataSize = ipBufferSize;
			inPacket.allocatedSize = ipBufferSize;
			inPacket.next = NULL;

			pgpIPsecESPGetSPI(&inPacket, &spi);

			if (!spi) {
				if (ipBufferSize < (sizeof(IP_HEADER) + AH_HEADERSIZE) ) {
					DBG_LEAVE(kPGPNetPMPacketEncrypt);
					return kPGPNetPMPacketEncrypt;
				}
				pgpIPsecAHGetSPI(&inPacket, &spi);
			}
		}
	}
	
	/* try to find existing SA */
	if (IsntPGPError(err) && spi) {
		*pSA = PMFindSAspi(pContext, ipAddress, spi);
		if (!*pSA) {
			/* Ok, this is odd, the packet had an SPI, but we can't
			 * find a matching SA. So we check to see if we have a
			 * different SA with this machine. If so, we don't ask
			 * for a new one. In any event, we must drop the packet
			 * since we can't process it.
			 */
			/* generate error for now */
			PMfireErrorEvent(adapter, ipAddress, kPGPIPsecError_NoSAFound);
			if (PMFindSA(pContext, ipAddress, ipAddrStart, incoming)) {
				DBG_PRINT(("kPGPNetPMPacketDrop because we could not find SA\n"););
				return kPGPNetPMPacketDrop;
			}
		}
	} else 
		*pSA = PMFindSA(pContext, ipAddress, ipAddrStart, incoming);

	if (*pSA && !(*pSA)->pending) {
		/* An SA is ready to go */
		DBG_PRINT(("kPGPNetPMPacketEncrypt because host is secure\n"););
		ret = kPGPNetPMPacketEncrypt;
	} else if (*pSA && (*pSA)->pending) {
		/* already waiting for one */
		DBG_PRINT(("kPGPNetPMPacketWaiting because no SA yet\n"););
		ret = kPGPNetPMPacketWaiting;
	} else {
		/* no SA */
		DBG_PRINT(("Asking for SA\n"););
		/* fire kernel event and ask service for SA */
		ret = PMfireSARequestEvent(adapter, ipAddress, ipAddrStart, ipMaskEnd);
		if (ret == kPGPNetPMPacketDrop) {
			DBG_LEAVE(kPGPNetPMPacketDrop);
			return kPGPNetPMPacketDrop;
		}

		if (!PMAddPendingSA(pContext, ipAddress, ipAddrStart, ipMaskEnd)) {
			DBG_LEAVE(kPGPNetPMPacketDrop);
			return kPGPNetPMPacketDrop;
		}
	}

	DBG_LEAVE(ret);
	return ret;
}

PGPBoolean
sCheckExpiration(PVPN_ADAPTER adapter, PGPnetKernelSA *pSA)
{
	DBG_FUNC("sCheckExpiration")
	if (!pSA)
		return FALSE;
	/* check for expiration */
	if ((pSA->ikeSA.kbLifeTime != 0 && 
			pSA->bytesSent >= (pSA->ikeSA.kbLifeTime * 1024)) || 
		(pSA->packetsSent >= (MAX_PGPUInt32-1))) {
		/*(pSA->packetsSent == 8)) {*/
		/* SA expired so generate SADied */
		PMfireSADiedEvent(adapter, pSA->ikeSA.transform[0].u.ipsec.inSPI);
		DBG_LEAVE(TRUE);
		return TRUE;
	}
	return FALSE;
}

void
sCheckRekey(PVPN_ADAPTER adapter, PGPnetKernelSA *pSA)
{
	DBG_FUNC("sCheckRekey")

	PGPBoolean	bRekey = FALSE;
	PGPUInt32	kbSent = 1;
	
	if (!pSA)
		return;
	
	/* OK, this is a little verbose, but I can understand it */

	/* 1st: already rekeying */
	if (pSA->reKeyInProgress)
		return;

	/* 2nd: packet count overload */
	if (pSA->packetsSent >= 0xFFFF7FFF) {
		bRekey = TRUE;
		goto rekey;
	}

	/* 3rd: no rekey timeout or only a few bytes sent */
	if ((pSA->ikeSA.kbLifeTime == 0) || (pSA->bytesSent < 1024)) 
		return;

	/* Ok calculating whether or not we should rekey */
	kbSent = pSA->bytesSent / 1024;

#ifdef CHICAGO

	//NdisGetCurrentSystemTime(&nowLarge);
//	KeQuerySystemTime(&nowLarge);
/*
VxDCall( Get_Last_Updated_System_Time );     //puts return value in eax
_asm mov timeVal, eax     ;get return value into variable
*/
#if 0
	pgpCopyMemory(&(nowLarge.HighPart) /*src*/,
		&now64 /*dest*/,
		4);
	pgpCopyMemory(&(nowLarge.LowPart) /*src*/,
		(&now64) + 4 /*dest*/,
		4);

	avgkb = kbSent / ((now64 - pSA->birthTime) / 10000000);
#endif

#else
	{
		PGPInt64	avgkb = 0;
		LARGE_INTEGER nowLarge;
		PGPInt64 now64 = 0, t1 = 0;

		KeQuerySystemTime(&nowLarge);
		now64 = nowLarge.QuadPart;
		t1 = (now64 - pSA->birthTime) / 10000000;

		if (t1 != 0)
			avgkb = kbSent / t1;

#define kPGPnetRekeyKBSeconds		30

		/* 4th: going to hit the limit in 30 seconds, better rekey */
		if ((avgkb != 0) && 
			(((pSA->ikeSA.kbLifeTime - kbSent) / avgkb) 
			<= kPGPnetRekeyKBSeconds)) { 
			bRekey = TRUE;
			goto rekey;
		}
	}
#endif

	/* 5th: only 1 meg left, better rekey */
	if (kbSent >= (pSA->ikeSA.kbLifeTime - 2048)) { 
		bRekey = TRUE;
		goto rekey;
	}

rekey:
	if (bRekey) {
		DBG_PRINT(("Firing Rekey event\n"););
		PMfireSARekeyEvent(adapter, pSA->ikeSA.transform[0].u.ipsec.inSPI);

⌨️ 快捷键说明

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