📄 pgpike.c
字号:
{
PGPError err = kPGPError_NoErr;
PGPikePartner * partner;
PGPikeExchange * exchange;
PGPHashContextRef hash = kInvalidPGPHashContextRef;
for( partner = ike->partner; IsntNull( partner ); partner = partner->nextPartner )
{
if( partner->ipAddress == authCheck->gatewayIP )
{
for( exchange = partner->exchanges; IsntNull( exchange );
exchange = exchange->nextExchange )
{
if( ( exchange->exchangeT == kPGPike_EX_Transaction ) &&
( exchange->numConfigs > 0 ) &&
( exchange->configs[0].transactionID == authCheck->transactionID ) )
{
pgpIKEFreeConfigs( exchange );
if( authCheck->success )
{
if( authCheck->includeType )
{
exchange->configs[0].configType = kPGPike_CT_Reply;
exchange->configs[0].transactionID = authCheck->transactionID;
exchange->configs[0].attribute = kPGPike_AT_XAuth_Type;
exchange->configs[0].value = authCheck->xauthType;
exchange->numConfigs++;
switch( authCheck->xauthType )
{
case kPGPike_XT_RADIUS_CHAP:
{
PGPUInt32 challengeSize = authCheck->challengeSize;
if( authCheck->useChallenge &&
( challengeSize % 2 == 0 ) &&
( challengeSize > 4 ) &&
( challengeSize < 66 ) )
{
PGPByte chapHash[16],
authID;
err = PGPContextGetRandomBytes( ike->pgpContext, &authID, 1); CKERR;
err = PGPNewHashContext( ike->pgpContext,
kPGPHashAlgorithm_MD5, &hash ); CKERR;
err = PGPContinueHash( hash, &authID, 1 ); CKERR;
err = PGPContinueHash( hash, authCheck->password,
strlen( authCheck->password ) ); CKERR;
err = PGPContinueHash( hash, authCheck->challenge,
challengeSize ); CKERR;
err = PGPFinalizeHash( hash, chapHash ); CKERR;
authCheck->challenge[0] = authID;
pgpCopyMemory( chapHash, &authCheck->challenge[1], challengeSize );
authCheck->challengeSize = challengeSize + 1;
}
else
{
#if PGPIKE_DEBUG
pgpIKEDebugLog( ike, TRUE, "\tBuggy gateway sent RADIUS_CHAP without Challenge\n" );
#endif
}
break;
}
case kPGPike_XT_OTP:
goto authCheckFailed;
case kPGPike_XT_SKEY: /* we really should fail here, but Altiga bug sends this */
default:
break;
}
}
if( authCheck->useUserName )
{
err = pgpIKESetConfigData( ike->memMgr, &exchange->configs[exchange->numConfigs],
kPGPike_CT_Reply, kPGPike_AT_XAuth_Username, authCheck->transactionID,
authCheck->userName ); CKERR;
exchange->numConfigs++;
}
if( authCheck->usePassword )
{
if( authCheck->useChallenge )
{
exchange->configs[exchange->numConfigs].configType = kPGPike_CT_Reply;
exchange->configs[exchange->numConfigs].transactionID = authCheck->transactionID;
exchange->configs[exchange->numConfigs].attribute = kPGPike_AT_XAuth_Password;
exchange->configs[exchange->numConfigs].valueP =
PGPNewSecureData( ike->memMgr, authCheck->challengeSize, 0 );
if( IsntNull( exchange->configs[exchange->numConfigs].valueP ) )
pgpCopyMemory( authCheck->challenge,
exchange->configs[exchange->numConfigs].valueP,
authCheck->challengeSize );
else
err = kPGPError_OutOfMemory;
exchange->configs[exchange->numConfigs].valueSize = authCheck->challengeSize;
exchange->numConfigs++;
}
else
{
err = pgpIKESetConfigData( ike->memMgr, &exchange->configs[exchange->numConfigs],
kPGPike_CT_Reply, kPGPike_AT_XAuth_Password, authCheck->transactionID,
authCheck->password ); CKERR;
exchange->numConfigs++;
}
}
if( authCheck->usePasscode )
{
err = pgpIKESetConfigData( ike->memMgr, &exchange->configs[exchange->numConfigs],
kPGPike_CT_Reply, kPGPike_AT_XAuth_Passcode, authCheck->transactionID,
authCheck->passcode ); CKERR;
exchange->numConfigs++;
}
if( authCheck->useDomain )
{
err = pgpIKESetConfigData( ike->memMgr, &exchange->configs[exchange->numConfigs],
kPGPike_CT_Reply, kPGPike_AT_XAuth_Domain, authCheck->transactionID,
authCheck->domain ); CKERR;
exchange->numConfigs++;
}
if( exchange->numConfigs )
{
err = pgpIKEDoPacket( &exchange,
kPGPike_PY_Attribute,
kPGPike_PY_None ); CKERR;
#if !PGPIKE_XAUTHCISCO
pgpIKEFreeExchange( exchange );
#endif
}
}
else
{
/*exchange->configs[0].configType = kPGPike_CT_Set;
exchange->configs[0].transactionID = authCheck->transactionID;
exchange->configs[0].attribute = kPGPike_AT_XAuth_Status;
exchange->configs[0].value = 0;
exchange->numConfigs = 1;*/
authCheckFailed:
exchange->partner->termSchedule = PGPGetTime();
err = pgpIKEAbortExchange( &exchange, kPGPike_AL_AuthenticationFailed );
goto done;
}
break;
}
}
if( IsNull( exchange ) )
err = kPGPError_ItemNotFound;
break;
}
}
if( IsNull( partner ) )
err = kPGPError_ItemNotFound;
done:
if( PGPHashContextRefIsValid( hash ) )
(void)PGPFreeHashContext( hash );
return err;
}
PGPError
pgpIKEHandleSAEvent(
PGPikeContextPriv * ike,
PGPBoolean death,
PGPipsecSA * sa )
{
PGPError err = kPGPError_NoErr;
PGPikePartner * partner;
PGPikeExchange * exchange;
if( pgpIKEFindSAPartner( ike, sa, TRUE, &partner ) )
{
if( death )
{
err = pgpIKEKillSA( &partner, sa ); CKERR;
}
else if( IsNull( partner->exchanges ) )
{
PGPipsecSA * oSA;
PGPBoolean found = FALSE;
/* Make sure there isn't already another one exactly like it */
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 ) &&
( oSA->ipPort == sa->ipPort ) &&
( oSA->ipProtocol == sa->ipProtocol ) )
{
found = TRUE;
break;
}
}
if( found )
{
#if PGPIKE_DEBUG
pgpIKEDebugLog( ike, TRUE, "Remote side is not rekeying correctly. Compensating.\n" );
#endif
}
{
PGPikePendingDest * rekeyDest;
rekeyDest = (PGPikePendingDest *)PGPNewData( ike->memMgr,
sizeof(PGPikePendingDest), kPGPMemoryMgrFlags_Clear );
if( IsNull( rekeyDest ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
rekeyDest->ipAddrStart = sa->ipAddrStart;
rekeyDest->ipMaskEnd = sa->ipMaskEnd;
rekeyDest->destIsRange = sa->destIsRange;
rekeyDest->ipPort = sa->ipPort;
rekeyDest->ipProtocol = sa->ipProtocol;
rekeyDest->nextDest = partner->pendList;
partner->pendList = rekeyDest;
err = pgpIKEStartQMExchange( partner, &exchange ); CKERR;
}
}
}
else if( death )
{
#if PGPIKE_DEBUG
pgpIKEDebugLog( ike, TRUE, "Kill P2 SA requested, no Phase 1 available!\n" );
#endif
err = (ike->msgProc)( (PGPikeContextRef)ike,
ike->userData, kPGPike_MT_SADied, sa ); CKERR;
err = pgpIKEFreeSA( ike, sa ); CKERR;
}
else
{
#if PGPIKE_DEBUG
pgpIKEDebugLog( ike, TRUE, "Rekey requested, but no Phase 1 available!\n" );
#endif
}
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) );
pgpAssert( ( ike->allowedAlgorithms.aes & ~( kPGPike_AESKeyLengthAll ) ) == 0 );
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;
PGPipsecSA * sa = NULL;
PGPBoolean found = FALSE,
foundSA = FALSE;
if( IsNull( saReq ) )
return kPGPError_BadParams;
#if PGPIKE_DEBUG
{
char ip1Str[20],
ip2Str[20],
ip3Str[20];
pgpIKEGetIPString( saReq->ipAddress, ip1Str );
pgpIKEGetIPString( saReq->ipAddrStart, ip2Str );
pgpIKEGetIPString( saReq->ipMaskEnd, ip3Str );
pgpIKEDebugLog( ike, TRUE, "SARequest: %s (%s/%s)\n", ip1Str, ip2Str, ip3Str );
}
#endif
if( pgpIKEFindPending( ike, saReq->ipAddress, saReq->ipAddrStart,
saReq->ipMaskEnd, saReq->destIsRange ) )
{
#if PGPIKE_DEBUG
pgpIKEDebugLog( ike, TRUE, "SARequest: IGNORED!! Already in progress.\n" );
#endif
goto done;
}
err = pgpIKEAddPending( ike, saReq->ipAddress, saReq->ipAddrStart,
saReq->ipMaskEnd, saReq->destIsRange ); CKERR;
for( partner = ike->partner; IsntNull( partner ); partner = partner->nextPartner )
{
if( ( partner->ipAddress == saReq->ipAddress ) && partner->ready )
{
/* We only re-use an existing P1 if it has SAs available */
for( sa = ike->sa; IsntNull( sa ); sa = sa->nextSA )
{
if( sa->ipAddress == saReq->ipAddress )
{
foundSA = TRUE;
break;
}
}
if( foundSA )
{
PGPikePendingDest * pendDest;
found = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -