📄 pgpnetpolicymanager.c
字号:
pSA->reKeyInProgress = TRUE;
}
}
PGPnetPMStatus
sDoTransformOutgoing(PGPnetPMContext *pContext,
PGPNDIS_PACKET *packet,
PVPN_ADAPTER adapter)
{
PGPUInt32 ipAddress = htonl(packet->ipAddress);
PGPUInt32 i = 0;
PGPNetHostEntry *host = PMFindHost(pContext, ipAddress);
PGPnetKernelSA *transportSA = 0, *tunnelSA = 0;
PGPError err = kPGPError_NoErr;
PGPBoolean bRet = FALSE;
PGPnetPMStatus ret;
DBG_FUNC("sDoTransformOutgoing")
DBG_ENTER();
retry:
ret = sLookHardForSA(pContext,
adapter,
host,
ipAddress,
packet->port,
packet,
0,
&transportSA,
&tunnelSA,
FALSE);
if (ret != kPGPNetPMPacketEncrypt && ret != kPGPNetPMPacketClear) {
DBG_PRINT(("Could not find SA\n"););
DBG_PRINT(("Happens w/ fragmented packets and other cases\n"););
goto end;
}
bRet = sCheckExpiration(adapter, transportSA);
if (bRet) {
/* now set activeOut to false */
transportSA->ikeSA.activeOut = FALSE;
goto retry;
}
bRet = sCheckExpiration(adapter, tunnelSA);
if (bRet) {
/* now set activeOut to false */
transportSA->ikeSA.activeOut = FALSE;
goto retry;
}
sCheckRekey(adapter, transportSA);
sCheckRekey(adapter, tunnelSA);
if (transportSA && packet->port != UDP_PORT_IKE_NET) {
err = PGPnetIPsecApplySA(adapter, pContext, packet, transportSA, FALSE, FALSE);
if (IsntPGPError(err)) {
transportSA->packetsSent++;
DBG_PRINT(("Packets sent: %d\n", transportSA->packetsSent););
/* XXX Is BlockLen the right thing to add? */
transportSA->bytesSent += packet->srcBlockLen /* - header size */;
} else {
goto fail;
}
#if/*def*/ 0 /*DBG*/
/* write out SA info */
DBG_PRINT(("inESPKey\n"););
for (i = 0; i< kPGPike_ESPMaximumKeySize; i++) {
DbgPrint("%X ", transportSA->ikeSA.transform[0].u.ipsec.u.esp.inESPKey[i]);
}
DBG_PRINT(("\noutESPKey\n"););
for (i = 0; i< kPGPike_ESPMaximumKeySize; i++) {
DbgPrint("%X ", transportSA->ikeSA.transform[0].u.ipsec.u.esp.outESPKey[i]);
}
DBG_PRINT(("\ninAuthKey\n"););
for (i = 0; i< kPGPike_AuthMaximumKeySize; i++) {
DbgPrint("%X ", transportSA->ikeSA.transform[0].u.ipsec.u.esp.inAuthKey[i]);
}
DBG_PRINT(("\noutAuthKey\n"););
for (i = 0; i< kPGPike_AuthMaximumKeySize; i++) {
DbgPrint("%X ", transportSA->ikeSA.transform[0].u.ipsec.u.esp.outAuthKey[i]);
}
DBG_PRINT(("\nESP Cipher: %d\n", transportSA->ikeSA.transform[0].u.ipsec.u.esp.t.cipher););
DBG_PRINT(("ESP Auth Attr: %d\n", transportSA->ikeSA.transform[0].u.ipsec.u.esp.t.authAttr););
#endif
} else if (packet->port == UDP_PORT_IKE_NET && !tunnelSA) {
// copy the chained buffer
sCopySrcToxForm(packet);
}
if (tunnelSA) {
err = PGPnetIPsecApplySA(adapter, pContext, packet, tunnelSA, FALSE, TRUE);
if (IsntPGPError(err)) {
/* XXX this doesn't seem right */
tunnelSA->packetsSent++;
DBG_PRINT(("Packets sent: %d\n", tunnelSA->packetsSent););
tunnelSA->bytesSent += packet->srcBlockLen /* - something */;
} else {
goto fail;
}
}
if (!tunnelSA && !transportSA && packet->port != UDP_PORT_IKE_NET) {
err = kPGPIPsecError_NoSAFound;
goto fail;
}
DBG_LEAVE(kPGPNetPMPacketSent);
return kPGPNetPMPacketSent;
fail:
PMfireErrorEvent(adapter, ipAddress, err);
DBG_LEAVE(kPGPNetPMPacketDrop);
return kPGPNetPMPacketDrop;
end:
DBG_LEAVE(ret);
return ret;
}
PGPnetPMStatus
sDoTransformIncoming(PGPnetPMContext *pContext, PGPNDIS_PACKET *packet, PVPN_ADAPTER adapter)
{
PGPUInt32 ipAddress = htonl(packet->ipAddress);
PGPUInt32 i = 0;
PGPUInt32 spi = 0;
PGPUInt32 tunnelIPsrc = 0;
PGPNetHostEntry *host = PMFindHost(pContext, ipAddress);
PGPnetKernelSA *pSA = 0;
PGPnetKernelSA *unused = 0;
PGPError err = kPGPError_NoErr;
PGPBoolean tunnelMode = FALSE;
PGPNDIS_PACKET *pgpPacket = 0;
NDIS_STATUS status;
DBG_FUNC("sDoTransformIncoming")
DBG_ENTER();
/* retrieve the outermost spi (tunnelIPsrc ignored) */
err = PGPnetIPsecGetAddrAndSPI(pContext, packet, &tunnelIPsrc, &spi);
if (IsPGPError(err))
goto fail;
if (spi) {
/* try to find SA */
if (!(pSA = PMFindSAspi(pContext, ipAddress, spi))) {
/* No SA found with this SPI
* Try to find another SA, and possibly
* acquire a new SA. Must drop this packet,
* since there isn't anyway I can decrypt it.
*/
sLookHardForSA(pContext,
adapter,
host,
ipAddress,
packet->port,
packet,
0,
&pSA,
&unused,
TRUE);
/* silent drop */
DBG_LEAVE(kPGPNetPMPacketDrop);
return kPGPNetPMPacketDrop;
}
if (host && host->hostType == kPGPnetSecureGateway) {
/* tunnels require phaseII */
tunnelMode = TRUE;
} else {
tunnelMode = FALSE;
}
/* Ok, time to apply SA */
err = PGPnetIPsecApplySA(adapter, pContext, packet, pSA, TRUE, tunnelMode);
if (IsPGPError(err)) {
DBG_PRINT(("Returning Drop: PGPnetIPsecApplySA error: %d\n", err););
goto fail;
}
} else {
if (packet->port == UDP_PORT_IKE_NET) {
sCopySrcToxForm(packet);
} else {
/* Ok the packet did not have an SPI. But it should, since we can't get here unless we
* have an SA for the machine. Although it may have been deleted in the meantime
so check again. Should it? only if it came from a configured host. If it did, then we start an SA acquisition.
if we already have an SA, which is the most likely case, then what?
*/
if (!(pSA = PMFindSAspi(pContext, ipAddress, spi))) {
/* No SA found with this SPI
* Try to find another SA, and possibly
* acquire a new SA. Must drop this packet,
* since there isn't anyway I can decrypt it.
*/
sLookHardForSA(pContext,
adapter,
host,
ipAddress,
packet->port,
packet,
0,
&pSA,
&unused,
TRUE);
/* silent drop */
DBG_LEAVE(kPGPNetPMPacketDrop);
return kPGPNetPMPacketDrop;
} else {
err = kPGPIPsecError_NoSPIFound;
goto fail;
}
}
}
/* phase II */
if (tunnelMode) {
DBG_PRINT(("Entering Phase II\n"););
#define ETHERNET_HDRLENGTH 14
if (pgpIsFragmented(packet->xformBlock + ETHERNET_HDRLENGTH)) {
// Allocate the pgpPacket
pgpPacket = PGPNdisPacketAllocWithSrcPacket(&status, adapter);
if (status != NDIS_STATUS_SUCCESS)
{
DBG_LEAVE(kPGPNetPMPacketDrop);
return kPGPNetPMPacketDrop;
}
sCopyPacketXformToSrc(packet /*src*/, pgpPacket, adapter);
status = TransformAndIndicate(adapter, pgpPacket);
if (status == NDIS_STATUS_SUCCESS)
{
PGPNdisPacketFreeSrcPacket(adapter, pgpPacket);
}
return kPGPNetPMPacketDrop;
}
err = PGPnetIPsecGetAddrAndSPI(pContext, packet, &tunnelIPsrc, &spi);
if (IsPGPError(err)) {
goto fail;
}
/*
* If we don't find an SPI, that's fine. It just means that
* was a normal IP packet within the tunnel, rather than
* an IPSEC packet
*/
if (spi) {
if (!(pSA = PMFindSAspi(pContext, tunnelIPsrc, spi))) {
err = kPGPIPsecError_NoSAFound;
goto fail;
}
tunnelMode = FALSE;
err = PGPnetIPsecApplySA(adapter, pContext, packet, pSA, TRUE, tunnelMode);
if (IsPGPError(err)) {
DBG_PRINT(("Returning Drop: PGPnetIPsecApplySA error: %d\n", err););
goto fail;
}
}
}
#if/*def*/ 0 /*DBG*/
/* write out SA info */
DBG_PRINT(("inESPKey\n"););
for (i = 0; i< kPGPike_ESPMaximumKeySize; i++) {
DbgPrint("%X ", pSA->ikeSA.transform[0].u.ipsec.u.esp.inESPKey[i]);
}
DBG_PRINT(("\noutESPKey\n"););
for (i = 0; i< kPGPike_ESPMaximumKeySize; i++) {
DbgPrint("%X ", pSA->ikeSA.transform[0].u.ipsec.u.esp.outESPKey[i]);
}
DBG_PRINT(("\ninAuthKey\n"););
for (i = 0; i< kPGPike_AuthMaximumKeySize; i++) {
DbgPrint("%X ", pSA->ikeSA.transform[0].u.ipsec.u.esp.inAuthKey[i]);
}
DBG_PRINT(("\noutAuthKey\n"););
for (i = 0; i< kPGPike_AuthMaximumKeySize; i++) {
DbgPrint("%X ", pSA->ikeSA.transform[0].u.ipsec.u.esp.outAuthKey[i]);
}
DBG_PRINT(("\nESP Cipher: %d\n", pSA->ikeSA.transform[0].u.ipsec.u.esp.t.cipher););
DBG_PRINT(("ESP Auth Attr: %d\n", pSA->ikeSA.transform[0].u.ipsec.u.esp.t.authAttr););
#endif
DBG_LEAVE(kPGPNetPMPacketSent);
return kPGPNetPMPacketSent;
fail:
PMfireErrorEvent(adapter, ipAddress, err);
DBG_LEAVE(kPGPNetPMPacketDrop);
return kPGPNetPMPacketDrop;
}
void
sCopySrcToxForm(PGPNDIS_PACKET *start)
{
PGPNDIS_PACKET *current = start;
PGPBoolean moreLinks = TRUE;
DBG_FUNC("sCopySrcToxForm")
DBG_ENTER();
if (!current->firstSrcBlock)
return;
do {
DBG_PRINT(("current->srcBlockLen: %d\n", current->srcBlockLen););
pgpCopyMemory(current->srcBlock /*src*/, current->xformBlock, current->srcBlockLen);
current->xformBlockLen = current->srcBlockLen;
current->firstXformBlock = current->firstSrcBlock;
current->lastXformBlock = current->lastSrcBlock;
if (current->lastSrcBlock)
moreLinks = FALSE;
current = current->link;
} while (moreLinks);
DBG_LEAVE(0);
}
void
sCopyPacketXformToSrc(const PGPNDIS_PACKET *source, PGPNDIS_PACKET *dest, PVPN_ADAPTER adapter)
{
DBG_FUNC("sCopyPacketXformToSrc")
DBG_ENTER();
if (!source->firstXformBlock)
return;
if (!source->lastXformBlock) {
DBG_BREAK();
}
DBG_PRINT(("source->xformBlockLen: %d\n", source->xformBlockLen););
pgpCopyMemory(source->xformBlock /*src*/, dest->srcBlock, source->xformBlockLen);
dest->srcBlockLen = source->xformBlockLen;
dest->firstSrcBlock = TRUE;
dest->lastSrcBlock = FALSE;
DBG_LEAVE(0);
}
PGPnetPMStatus
sLookHardForSA(PGPnetPMContext *pContext,
PVPN_ADAPTER adapter,
PGPNetHostEntry *host,
PGPUInt32 ipAddress,
PGPUInt16 port,
void * ipBuffer,
PGPUInt32 ipBufferSize,
PGPnetKernelSA **ppTransport,
PGPnetKernelSA **ppTunnel,
PGPBoolean incoming)
{
PGPnetPMStatus ret = kPGPNetPMPacketDrop;
PGPnetPMStatus tunnelRet, transportRet;
PGPNetHostEntry *secureGW = 0;
if (host) {
if (host->hostType == kPGPnetSecureGateway &&
port != UDP_PORT_IKE_NET &&
!incoming) {
/* we always talk to Gateways in Tunnel mode */
/* this should be right, but doesn't work with GVPN NT */
ret = sAcquireSA(pContext,
host->ipAddress,
host->ipAddress,
host->ipMask,
incoming,
ipBuffer,
ipBufferSize,
adapter,
ppTunnel);
return ret;
}
if (host->hostType == kPGPnetSecureHost &&
host->childOf == -1 &&
port != UDP_PORT_IKE_NET) {
/* we need only the transport SA */
ret = sAcquireSA(pContext,
ipAddress,
0,
0,
incoming,
ipBuffer,
ipBufferSize,
adapter,
ppTransport);
return ret;
}
if (host->hostType == kPGPnetInsecureHost && host->childOf != -1) {
/* we need only the tunnel SA */
secureGW = &(pContext->pKernelHostList[host->childOf]);
ret = sAcquireSA(pContext,
secureGW->ipAddress,
host->ipAddress,
host->ipMask,
incoming,
ipBuffer,
ipBufferSize,
adapter,
ppTunnel);
return ret;
}
if (host->hostType == kPGPnetSecureHost && host->childOf != -1) {
/* we need transport SA and tunnel SA */
/* first get tunnel SA */
secureGW = &(pContext->pKernelHostList[host->childOf]);
tunnelRet = sAcquireSA(pContext,
secureGW->ipAddress,
host->ipAddress,
host->ipMask,
incoming,
ipBuffer,
ipBufferSize,
adapter,
ppTunnel);
if (port == UDP_PORT_IKE_NET) {
return tunnelRet;
}
/* next get the transport SA */
transportRet = sAcquireSA(pContext,
ipAddress,
0,
0,
incoming,
ipBuffer,
ipBufferSize,
adapter,
ppTransport);
if (tunnelRet == kPGPNetPMPacketEncrypt &&
transportRet == kPGPNetPMPacketEncrypt) {
/* both SAs are ready to go */
ret = kPGPNetPMPacketEncrypt;
} else {
/* something isn't ready yet */
ret = kPGPNetPMPacketWaiting;
}
return ret;
}
}
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 ((*ppTransport = PMFindSA(pContext, ipAddress, 0, incoming))) {
return kPGPNetPMPacketEncrypt;
} else {
return kPGPNetPMPacketClear;
}
}
if (pContext->pConfig->bAllowUnconfigHost &&
pContext->pConfig->bAttemptUnconfigHost &&
port != UDP_PORT_IKE_NET) {
ret = sAcquireSA(pContext,
ipAddress,
0,
0,
incoming,
ipBuffer,
ipBufferSize,
adapter,
ppTransport);
return ret;
}
if (ret != kPGPNetPMPacketEncrypt && port == UDP_PORT_IKE_NET)
ret = kPGPNetPMPacketClear;
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -