📄 pgpnetikeworker.cpp
字号:
/*____________________________________________________________________________
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 + -