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

📄 pgpike.c

📁 pgp soucecode pgp soucecode
💻 C
📖 第 1 页 / 共 5 页
字号:
			err = kPGPError_NoErr;
		else
		{
#if PGPIKE_DEBUG
			pgpIKEDebugLog( ike, "pgpIKE PGPError: %ld\n", err );
#endif
		}
	}
	return err;
}

	PGPError
pgpIKEFindSAPartner(
	PGPikeContextPriv *		ike,
	PGPikeSA *				sa,
	PGPBoolean				mustBeReady,
	PGPikePartner **		partnerP )
{
	PGPError				err = kPGPError_NoErr;
	PGPikePartner *			partner;
	
	*partnerP = NULL;
	for( partner = ike->partner; IsntNull( partner );
			partner = partner->nextPartner )
	{
		if( ( sa->ipAddress == partner->ipAddress ) &&
			( partner->ready || !mustBeReady ) &&
			( sa->ipAddrStart == partner->ipsecOpts.ipAddrStart ) &&
			( sa->ipMaskEnd == partner->ipsecOpts.ipMaskEnd ) &&
			( sa->destIsRange == partner->ipsecOpts.destIsRange ) )
		{
			*partnerP = partner;
			goto done;
		}
	}
	err = kPGPError_ItemNotFound;
done:
	return err;
}

	PGPError
pgpIKEFreeSA(
	PGPikeContextPriv *		ike,
	PGPikeSA *				sa )
{	
	PGPError				err = kPGPError_NoErr;
	
	err = pgpIKELocalAlert( ike, sa->ipAddress,
			kPGPike_AL_None, kPGPike_IA_DeadPhase2SA, FALSE );
	if( IsntNull( sa->prevSA ) )
		sa->prevSA->nextSA = sa->nextSA;
	else
		ike->sa = sa->nextSA;
	if( IsntNull( sa->nextSA ) )
		sa->nextSA->prevSA = sa->prevSA;
	(void)PGPFreeData( sa );
	return err;
}

	PGPError
pgpIKEHandleSAEvent(
	PGPikeContextPriv *		ike,
	PGPBoolean				death,
	PGPikeSA *				sa )
{
	PGPError				err = kPGPError_NoErr;
	PGPikePartner *			partner;
	PGPikeExchange *		exchange;
	
	if( IsntPGPError( pgpIKEFindSAPartner( ike, sa, TRUE, &partner ) ) )
	{
		if( death )
		{
			err = pgpIKEKillSA( &partner, sa );	CKERR;
		}
		else if( IsNull( partner->exchanges ) )
		{
			PGPikeSA *		oSA;
			PGPBoolean		found = FALSE;
			
			for( oSA = ike->sa; IsntNull( oSA ); oSA = oSA->nextSA )
			{
				if( ( oSA->ipAddress == sa->ipAddress ) && ( sa != oSA ) &&
					( oSA->ipAddrStart == sa->ipAddrStart ) &&
					( oSA->ipMaskEnd == sa->ipMaskEnd ) &&
					( oSA->destIsRange == sa->destIsRange ) )
				{
					found = TRUE;
					break;
				}
			}
			if( !found )
			{
				err = pgpIKEStartQMExchange( partner, &exchange );	CKERR;
			}
		}
	}
done:
	return err;
}

	PGPError
pgpIKESetPref(
	PGPikeContextPriv *		ike,
	PGPikeMTPref *			pref )
{
	PGPError				err = kPGPError_NoErr;
	
	switch( pref->pref )
	{
		case kPGPike_PF_Expiration:
			ike->secLifeTimeIKE			= pref->u.expiration.secLifeTimeIKE;
			if( ike->secLifeTimeIKE && ( ike->secLifeTimeIKE < 60 ) )
				ike->secLifeTimeIKE = 60;
			ike->kbLifeTimeIKE			= pref->u.expiration.kbLifeTimeIKE;
			if( ike->kbLifeTimeIKE && ( ike->kbLifeTimeIKE < kPGPike_KBLifeMinimum ) )
				ike->kbLifeTimeIKE = kPGPike_KBLifeMinimum;
			ike->secLifeTimeIPSEC		= pref->u.expiration.secLifeTimeIPSEC;
			if( ike->secLifeTimeIPSEC && ( ike->secLifeTimeIPSEC < 60 ) )
				ike->secLifeTimeIPSEC = 60;
			ike->kbLifeTimeIPSEC		= pref->u.expiration.kbLifeTimeIPSEC;
			if( ike->kbLifeTimeIPSEC && ( ike->kbLifeTimeIPSEC < kPGPike_KBLifeMinimum ) )
				ike->kbLifeTimeIPSEC = kPGPike_KBLifeMinimum;
			break;
		case kPGPike_PF_IKEProposals:
			if( IsntNull( ike->defaultIKEProps ) )
			{
				err = pgpContextMemFree( ike->pgpContext,
										ike->defaultIKEProps );CKERR;
			}
			ike->defaultIKEProps = (PGPikeTransform *)
				pgpContextMemAlloc( ike->pgpContext,
				sizeof(PGPikeTransform) * pref->u.ikeProposals.numTransforms,
				kPGPMemoryMgrFlags_Clear );
			if( IsNull( ike->defaultIKEProps ) )
			{
				err = kPGPError_OutOfMemory;
				goto done;
			}
			ike->numIKEProps = pref->u.ikeProposals.numTransforms;
			pgpCopyMemory( pref->u.ikeProposals.t, ike->defaultIKEProps,
							ike->numIKEProps * sizeof(PGPikeTransform) );
			break;
		case kPGPike_PF_IPSECProposals:
			if( IsntNull( ike->defaultIPSECProps ) )
			{
				err = pgpContextMemFree( ike->pgpContext,
										ike->defaultIPSECProps );CKERR;
			}
			ike->defaultIPSECProps = (PGPipsecTransform *)
				pgpContextMemAlloc( ike->pgpContext,
				sizeof(PGPipsecTransform) * pref->u.ipsecProposals.numTransforms,
				kPGPMemoryMgrFlags_Clear );
			if( IsNull( ike->defaultIPSECProps ) )
			{
				err = kPGPError_OutOfMemory;
				goto done;
			}
			ike->numIPSECProps = pref->u.ipsecProposals.numTransforms;
			pgpCopyMemory( pref->u.ipsecProposals.t, ike->defaultIPSECProps,
							ike->numIPSECProps * sizeof(PGPipsecTransform) );
			break;
		case kPGPike_PF_AllowedAlgorithms:
			pgpCopyMemory( &pref->u.allowedAlgorithms, &ike->allowedAlgorithms,
							sizeof(PGPikeAllowedAlgorithms) );
			break;
		default:
			err = kPGPError_FeatureNotAvailable;
			break;
	}
done:
	return err;
}

	PGPError
pgpIKEAddPending(
	PGPikeContextPriv *		ike,
	PGPUInt32				ipAddress,
	PGPUInt32				ipAddrStart,
	PGPUInt32				ipMaskEnd,
	PGPBoolean				destIsRange )
{
	PGPikeDestination *		dest;
	PGPError				err = kPGPError_NoErr;
	
	/* The pending list is really just for debugging purposes */
	dest = (PGPikeDestination *)PGPNewData( ike->memMgr, sizeof(PGPikeDestination), 0 );
	if( IsntNull( dest ) )
	{
		dest->ipAddress		= ipAddress;
		dest->ipAddrStart	= ipAddrStart;
		dest->ipMaskEnd		= ipMaskEnd;
		dest->destIsRange	= destIsRange;
		dest->nextD			= ike->pending;
		ike->pending		= dest;
	}
	else
		err = kPGPError_OutOfMemory;
	return err;
}

	PGPBoolean
pgpIKEFindPending(
	PGPikeContextPriv *		ike,
	PGPUInt32				ipAddress,
	PGPUInt32				ipAddrStart,
	PGPUInt32				ipMaskEnd,
	PGPBoolean				destIsRange )
{
	PGPBoolean				found = FALSE;
	PGPikeDestination *		dest;
	
	for( dest = ike->pending; IsntNull( dest ); dest = dest->nextD )
	{
		if( ( dest->ipAddress == ipAddress ) &&
			( dest->ipAddrStart == ipAddrStart ) &&
			( dest->ipMaskEnd == ipMaskEnd ) &&
			( dest->destIsRange == destIsRange ) )
		{
			found = TRUE;
			break;
		}
	}
	return found;
}

	PGPError
pgpIKERemovePending(
	PGPikeContextPriv *		ike,
	PGPUInt32				ipAddress,
	PGPUInt32				ipAddrStart,
	PGPUInt32				ipMaskEnd,
	PGPBoolean				destIsRange )
{
	PGPikeDestination *		dest;
	PGPikeDestination *		lastDest = NULL;
	PGPError				err = kPGPError_NoErr;
	
	for( dest = ike->pending; IsntNull( dest ); dest = dest->nextD )
	{
		if( ( dest->ipAddress == ipAddress ) &&
			( dest->ipAddrStart == ipAddrStart ) &&
			( dest->ipMaskEnd == ipMaskEnd ) &&
			( dest->destIsRange == destIsRange ) )
		{
			if( IsNull( lastDest ) )
				ike->pending = dest->nextD;
			else
				lastDest->nextD = dest->nextD;
			(void)PGPFreeData( dest );
			break;
		}
		lastDest = dest;
	}
	return err;
}

	PGPError
pgpIKEHandleSARequest(
	PGPikeContextPriv *		ike,
	PGPikeMTSASetup *		saReq )
{
	PGPError				err = kPGPError_NoErr;
	PGPikePartner *			partner = NULL;

	if( IsNull( saReq ) )
		return kPGPError_BadParams;
	if( saReq->doi != kPGPike_DOI_IPSEC )
		return kPGPError_FeatureNotAvailable;
	
	/* currently, if a P2 Tunnel Mode SA exists, and we want to communicate with
		a different destination inside the Tunnel, we establish another P1 and P2
		SA for that.  This is unnecessary, and a good optimization here would be
		to only establish the P2 SA using the existing P1 SA if there is one. */
	
#if PGPIKE_DEBUG
	pgpIKEDebugLog( ike, "SARequest: %u.%u.%u.%u (%u.%u.%u.%u/%u.%u.%u.%u)\n",
		( saReq->ipAddress >> 24 ), ( saReq->ipAddress >> 16 ) & 0xFF,
		( saReq->ipAddress >> 8 ) & 0xFF, ( saReq->ipAddress & 0xFF ),
		( saReq->u.ipsec.ipAddrStart >> 24 ), ( saReq->u.ipsec.ipAddrStart >> 16 ) & 0xFF,
		( saReq->u.ipsec.ipAddrStart >> 8 ) & 0xFF, ( saReq->u.ipsec.ipAddrStart & 0xFF ),
		( saReq->u.ipsec.ipMaskEnd >> 24 ), ( saReq->u.ipsec.ipMaskEnd >> 16 ) & 0xFF,
		( saReq->u.ipsec.ipMaskEnd >> 8 ) & 0xFF, ( saReq->u.ipsec.ipMaskEnd & 0xFF ) );
#endif
	if( pgpIKEFindPending(  ike, saReq->ipAddress, saReq->u.ipsec.ipAddrStart,
			saReq->u.ipsec.ipMaskEnd, saReq->u.ipsec.destIsRange ) )
	{
#if PGPIKE_DEBUG
		pgpIKEDebugLog( ike, "IGNORED: Already in progress\n" );
#endif
		goto done;
	}
	err = pgpIKEAddPending( ike, saReq->ipAddress, saReq->u.ipsec.ipAddrStart,
			saReq->u.ipsec.ipMaskEnd, saReq->u.ipsec.destIsRange );	CKERR;
	err = pgpIKEStartIdentityExchange( ike, saReq->ipAddress, saReq, FALSE, 0, 0 );	CKERR;
done:
	return err;
}

	PGPError
pgpIKECreateProposals(
	PGPikeExchange *		exchange )
{
	PGPError				err = kPGPError_NoErr;
	PGPikeProposal *		proposal = NULL;
	PGPUInt16				transIndex,
							numTransforms;

	proposal = PGPNewData( exchange->ike->memMgr, sizeof(PGPikeProposal),
								kPGPMemoryMgrFlags_Clear );
	if( IsNull( proposal ) )
	{
		err = kPGPError_OutOfMemory;
		goto done;
	}
	switch( exchange->exchangeT )
	{
		case kPGPike_EX_Identity:
			proposal->number				= 1;
			proposal->protocol				= kPGPike_PR_IKE;
			numTransforms = exchange->ike->numIKEProps;
			if( numTransforms > kPGPike_MaxPropTransforms )
				numTransforms = kPGPike_MaxPropTransforms;
			for( transIndex = 0; transIndex < numTransforms; transIndex++ )
				if( pgpIKEIsTransformValid( exchange->partner, kPGPike_PR_IKE,
					(PGPikeGenericTransform *)
					&exchange->ike->defaultIKEProps[transIndex] ) )
				{
					pgpCopyMemory(	&exchange->ike->defaultIKEProps[transIndex],
									&proposal->t[proposal->numTransforms].u.ike,
									sizeof( PGPikeTransform ) );
					proposal->numTransforms++;
				}
			proposal->secLifeTime			= exchange->ike->secLifeTimeIKE;
			proposal->kbLifeTime			= exchange->ike->kbLifeTimeIKE;
			break;
		case kPGPike_EX_IPSEC_Quick:
		{
			PGPikeProposal	*	nproposal = NULL;
			PGPUInt32			propType,
								propIndex;
			PGPBoolean			useProtocol;
			PGPipsecTransform *	curp;
			
			for( propIndex = exchange->ike->numIPSECProps; propIndex > 0; propIndex-- )
			{
				curp = &exchange->ike->defaultIPSECProps[propIndex - 1];
				for( propType = 0; propType < 3; propType++ )
				{
					useProtocol = FALSE;
					if( IsNull( nproposal ) )
						nproposal = proposal;
					else
					{
						nproposal = PGPNewData( exchange->ike->memMgr,
							sizeof(PGPikeProposal), kPGPMemoryMgrFlags_Clear );
						if( IsNull( nproposal ) )
						{
							err = kPGPError_OutOfMemory;
							goto done;
						}
						nproposal->nextProposal = proposal;
						proposal = nproposal;
					}
					switch( propType )	// in reverse order
					{
						case 0:			// IPCOMP
							if( curp->useIPCOMP )
							{
								useProtocol = TRUE;
								proposal->protocol	= kPGPike_PR_IPCOMP;
								pgpCopyMemory( &curp->ipcomp,
												&proposal->t[0].u.ipsec.ipcomp,
												sizeof(PGPipsecIPCOMPTransform) );
							}
							break;
						case 1:			// ESP
							if( curp->useESP )
							{
								useProtocol = TRUE;
								proposal->protocol	= kPGPike_PR_ESP;
								pgpCopyMemory( &curp->esp, &proposal->t[0].u.ipsec.esp,
												sizeof(PGPipsecESPTransform) );
								proposal->t[0].u.ipsec.esp.mode =
									exchange->partner->ipsecOpts.packetMode;
							}
							break;
						case 2:			// AH
							if( curp->useAH )
							{
								useProtocol = TRUE;
								proposal->protocol	= kPGPike_PR_AH;
								pgpCopyMemory( &curp->ah, &proposal->t[0].u.ipsec.ah,
												sizeof(PGPipsecAHTransform) );
								proposal->t[0].u.ipsec.ah.mode =
									exchange->partner->ipsecOpts.packetMode;
							}
							break;
					}
					if( useProtocol )
					{
						proposal->number		= propIndex;
						proposal->numTransforms	= 1;
						proposal->t[0].u.ipsec.groupID	= curp->groupID;
						proposal->secLifeTime	= exchange->ike->secLifeTimeIPSEC;
						proposal->kbLifeTime	= exchange->ike->kbLifeTimeIPSEC;
						err = PGPContextGetRandomBytes( exchange->ike->pgpContext,
									&proposal->initSPI, sizeof(PGPipsecSPI) ); CKERR;
					}
					else
					{
						nproposal = proposal;
						proposal = proposal->nextProposal;
						err = PGPFreeData( nproposal );	CKERR;
					}
				}
			}
			break;
		}
		default:
			break;
	}
	pgpAssert( IsNull( exchange->proposals ) );
	exchange->proposals = proposal;
	proposal = NULL;
done:
	if( IsntNull( proposal ) )
		(void) PGPFreeData( proposal );
	return err;
}

	PGPError
pgpIKECreateExchange(
	PGPikePartner *			partner,
	PGPikeExchangeT			exchangeT,
	PGPikeMessageID *		messageID,
	PGPikeState				state,
	PGPBoolean				initiator,
	PGPikeExchange **		exchangeP )
{
	PGPError				err = kPGPError_NoErr;
	PGPikeExchange *		exchange = NULL;
	PGPHashContextRef		hash = kInvalidPGPHashContextRef;

	*exchangeP = NULL;
	pgpAssertAddrValid( partner, PGPikePartner );
	
	exchange = PGPNewData( partner->ike->memMgr, sizeof(PGPikeExchange),
							kPGPMemoryMgrFlags_Clear );

⌨️ 快捷键说明

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