📄 pgpnetattack.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: pgpNetAttack.c,v 1.22 2002/08/06 20:10:25 dallen Exp $
____________________________________________________________________________*/
#include "pgpErrors.h"
#include "pgpNetAttackPriv.h"
#include "pgpMem.h"
#if PGP_WIN32
#include "pgpNetDebug.h"
#include "pgpIKE.h"
#include "pgpNetPacket.h"
#include "pgpNetPM.h"
#include "pgpNetPMEvents.h"
#if (defined(DBG) && (DBG != 0))
extern void PMfireDebugEvent(PGPUInt32 dbgBits,
const char* format,
...);
#define sDriverDebugMsg(msg) \
PMfireDebugEvent(DBG_FIREWALL_ON, "%s", msg)
#else
#define sDriverDebugMsg(msg)
#endif /* (defined(DBG) && (DBG != 0)) */
#endif /* PGP_WIN32 */
#if defined(_WIN32) && defined(_MSC_VER)
#define PGP_INLINE __inline
#elif defined(__GNUC__)
#define PGP_INLINE __inline__
#else
#define PGP_INLINE
#endif
/* Generic functions */
static PGPError sAddAttackerG(PGPMemoryMgrRef memoryMgr,
PGPnetAttacker **listStart, PGPnetAttacker **listEnd,
PGPUInt32 ipAddress, PGPUInt32 timeNow,
PGPnetAttacker **attacker);
static void sRemoveAttackerG(PGPnetAttacker *attacker,
PGPnetAttacker **listStart, PGPnetAttacker **listEnd);
static PGPnetAttacker * sFindAttackerG(PGPnetAttacker **listStart,
PGPnetAttacker **listEnd, PGPUInt32 ipAddress,
PGPUInt32 timeNow);
/* Tracked functions */
static PGP_INLINE PGPError sAddTrackedAttacker(PGPnetAttackContextRef attack,
PGPUInt32 ipAddress, PGPUInt32 timeNow,
PGPnetAttacker **attacker);
static PGP_INLINE void sRemoveTrackedAttacker(PGPnetAttackContextRef attack,
PGPnetAttacker *attacker);
static PGP_INLINE PGPnetAttacker * sFindTrackedAttacker(PGPnetAttackContextRef attack,
PGPUInt32 ipAddress, PGPUInt32 timeNow);
/* Blocked functions */
static PGP_INLINE PGPError sAddBlockedAttacker(PGPnetAttackContextRef attack,
PGPUInt32 ipAddress, PGPUInt32 timeNow,
PGPnetAttacker **attacker);
static PGP_INLINE void sRemoveBlockedAttacker(PGPnetAttackContextRef attack,
PGPnetAttacker *attacker);
static PGP_INLINE PGPnetAttacker * sFindBlockedAttacker(PGPnetAttackContextRef attack,
PGPUInt32 ipAddress, PGPUInt32 timeNow);
PGPError PGPNewNetAttackContext(PGPnetAttackContextRef *attack)
{
PGPError err = kPGPError_NoErr;
PGPMemoryMgrRef memoryMgr = NULL;
PGPnetAttackContextRef newAttack = NULL;
if (IsNull(attack))
return kPGPError_BadParams;
*attack = NULL;
err = PGPNewMemoryMgr(0, &memoryMgr);
if (IsPGPError(err))
return err;
newAttack = (PGPnetAttackContextRef) PGPNewData(memoryMgr,
sizeof(PGPnetAttackContext),
kPGPMemoryMgrFlags_Clear);
if (IsNull(newAttack))
{
PGPFreeMemoryMgr(memoryMgr);
return kPGPError_OutOfMemory;
}
newAttack->memoryMgr = memoryMgr;
*attack = newAttack;
return kPGPError_NoErr;;
}
PGPError PGPFreeNetAttackContext(PGPnetAttackContextRef attack)
{
PGPMemoryMgrRef memoryMgr;
PGPnetAttacker *freeAttacker;
if (IsNull(attack))
return kPGPError_BadParams;
memoryMgr = attack->memoryMgr;
while (IsntNull(attack->blockListStart))
{
freeAttacker = attack->blockListStart;
attack->blockListStart = attack->blockListStart->next;
PGPFreeData(freeAttacker);
}
while (IsntNull(attack->trackListStart))
{
freeAttacker = attack->trackListStart;
attack->trackListStart = attack->trackListStart->next;
PGPFreeData(freeAttacker);
}
PGPFreeData(attack);
PGPFreeMemoryMgr(memoryMgr);
return kPGPError_NoErr;
}
PGPError PGPSetAttackContextUserValue(PGPnetAttackContextRef attack,
PGPUserValue userValue)
{
if (IsNull(attack))
return kPGPError_BadParams;
attack->userValue = userValue;
return kPGPError_NoErr;
}
PGPError PGPnetAddBlockedAttacker(PGPnetAttackContextRef attack,
PGPUInt32 nboIpAddress)
{
PGPError err;
PGPnetAttacker *attacker;
if (IsNull(attack))
return kPGPError_BadParams;
err = sAddBlockedAttacker(attack, nboIpAddress, 0, NULL);
/* No need to track this blocked attacker */
if (IsntPGPError(err))
{
attacker = sFindTrackedAttacker(attack, nboIpAddress, 0);
if (IsntNull(attacker))
sRemoveTrackedAttacker(attack, attacker);
}
return err;
}
PGPError PGPnetRemoveBlockedAttacker(PGPnetAttackContextRef attack,
PGPUInt32 ipAddress)
{
PGPnetAttacker *attacker;
if (IsNull(attack))
return kPGPError_BadParams;
attacker = sFindBlockedAttacker(attack, ipAddress, 0);
if (IsntNull(attacker))
sRemoveBlockedAttacker(attack, attacker);
return kPGPError_NoErr;
}
PGPError PGPnetRemoveAllAttackers(PGPnetAttackContextRef attack)
{
PGPnetAttacker *freeAttacker;
if (IsNull(attack))
return kPGPError_BadParams;
while (IsntNull(attack->blockListStart))
{
freeAttacker = attack->blockListStart;
attack->blockListStart = attack->blockListStart->next;
PGPFreeData(freeAttacker);
}
attack->blockListEnd = NULL;
return kPGPError_NoErr;
}
PGPBoolean PGPnetIsAddressBlocked(PGPnetAttackContextRef attack,
PGPUInt32 ipAddress)
{
PGPBoolean foundAddress = FALSE;
PGPnetAttacker *attacker;
if (IsNull(attack))
return FALSE;
attacker = sFindBlockedAttacker(attack, ipAddress, 0);
if (IsntNull(attacker))
foundAddress = TRUE;
return foundAddress;
}
/* Generic List functions */
static PGPError sAddAttackerG(PGPMemoryMgrRef memoryMgr,
PGPnetAttacker **listStart, PGPnetAttacker **listEnd,
PGPUInt32 ipAddress, PGPUInt32 timeNow,
PGPnetAttacker **attacker)
{
PGPnetAttacker *newAttacker;
if (IsntNull(attacker))
*attacker = NULL;
newAttacker = (PGPnetAttacker *) PGPNewData(memoryMgr,
sizeof(PGPnetAttacker),
kPGPMemoryMgrFlags_Clear);
if (IsNull(newAttacker))
return kPGPError_OutOfMemory;
if (IsntNull(*listStart))
{
(*listEnd)->next = newAttacker;
newAttacker->prev = *listEnd;
}
else
*listStart = newAttacker;
newAttacker->ipAddress = ipAddress;
newAttacker->lastCheck = timeNow;
*listEnd = newAttacker;
if (IsntNull(attacker))
*attacker = newAttacker;
return kPGPError_NoErr;
}
static void sRemoveAttackerG(PGPnetAttacker *attacker,
PGPnetAttacker **listStart, PGPnetAttacker **listEnd)
{
if (attacker == *listStart)
*listStart = attacker->next;
if (attacker == *listEnd)
*listEnd = attacker->prev;
if (IsntNull(attacker->prev))
attacker->prev->next = attacker->next;
if (IsntNull(attacker->next))
attacker->next->prev = attacker->prev;
PGPFreeData(attacker);
return;
}
static PGPnetAttacker * sFindAttackerG(PGPnetAttacker **listStart,
PGPnetAttacker **listEnd, PGPUInt32 ipAddress,
PGPUInt32 timeNow)
{
PGPnetAttacker *listPtr;
PGPnetAttacker *tempPtr;
listPtr = *listStart;
while (IsntNull(listPtr))
{
if (listPtr->ipAddress == ipAddress)
{
listPtr->lastCheck = timeNow;
return listPtr;
}
if (timeNow && listPtr->lastCheck)
{
tempPtr = listPtr;
listPtr = listPtr->next;
if ((timeNow - tempPtr->lastCheck) > TRACK_LIFETIME)
sRemoveAttackerG(tempPtr, listStart, listEnd);
}
else
listPtr = listPtr->next;
}
return NULL;
}
/* Tracked list functions */
static PGPUInt16 sNumTrackedAttackers = 0;
static PGP_INLINE PGPError sAddTrackedAttacker(PGPnetAttackContextRef attack,
PGPUInt32 ipAddress, PGPUInt32 timeNow,
PGPnetAttacker **attacker)
{
PGPError err = sAddAttackerG(attack->memoryMgr,
&(attack->trackListStart),
&(attack->trackListEnd),
ipAddress,
timeNow,
attacker);
if (IsntPGPError(err) && sNumTrackedAttackers++ >= 512) {
sRemoveTrackedAttacker(attack, attack->trackListStart);
}
return err;
}
static PGP_INLINE void sRemoveTrackedAttacker(PGPnetAttackContextRef attack,
PGPnetAttacker *attacker)
{
sRemoveAttackerG(attacker, &(attack->trackListStart), &(attack->trackListEnd));
sNumTrackedAttackers--;
}
static PGP_INLINE PGPnetAttacker * sFindTrackedAttacker(PGPnetAttackContextRef attack,
PGPUInt32 ipAddress, PGPUInt32 timeNow)
{
return sFindAttackerG(&(attack->trackListStart), &(attack->trackListEnd), ipAddress, timeNow);
}
/* Blocked list functions */
static PGP_INLINE PGPError sAddBlockedAttacker(PGPnetAttackContextRef attack,
PGPUInt32 ipAddress, PGPUInt32 timeNow,
PGPnetAttacker **attacker)
{
PGPError err = sAddAttackerG(attack->memoryMgr,
&(attack->blockListStart),
&(attack->blockListEnd),
ipAddress,
timeNow,
attacker);
return err;
}
static PGP_INLINE void sRemoveBlockedAttacker(PGPnetAttackContextRef attack,
PGPnetAttacker *attacker)
{
sRemoveAttackerG(attacker, &(attack->blockListStart), &(attack->blockListEnd));
}
static PGP_INLINE PGPnetAttacker * sFindBlockedAttacker(PGPnetAttackContextRef attack,
PGPUInt32 ipAddress, PGPUInt32 timeNow)
{
return sFindAttackerG(&(attack->blockListStart), &(attack->blockListEnd), ipAddress, timeNow);
}
PGPBoolean pgpPortScanAttack(PGPnetAttackContextRef attack, PGPUInt32 timeNow,
PGPUInt32 ipAddress, PGPUInt16 port, PGPBoolean tcp)
{
PGPUInt32 index;
PGPPortScanRecord * record;
PGPUInt32 count;
PGPBoolean recorded;
PGPnetAttacker * attacker;
PGPByte * ipAddressByte;
PGPByte counter;
PGPError err;
ipAddressByte = (PGPByte *) &ipAddress;
attacker = sFindTrackedAttacker(attack, ipAddress, timeNow);
if (IsNull(attacker))
{
err = sAddTrackedAttacker(attack, ipAddress, timeNow, &attacker);
if (IsPGPError(err))
return FALSE;
}
count = attacker->portScan.numTCPScans + attacker->portScan.numUDPScans;
recorded = FALSE;
for (index=0; index<MAX_PORT_SCANS; index++)
{
record = &(attacker->portScan.scanRecord[index]);
if (!record->port)
{
if (!recorded)
{
recorded = TRUE;
if (port >= MIN_HIGH_PORT)
{
if (tcp)
{
attacker->portScan.tcpCounter++;
counter = attacker->portScan.tcpCounter;
}
else
{
attacker->portScan.udpCounter++;
counter = attacker->portScan.udpCounter;
}
}
if ((port < MIN_HIGH_PORT) ||
(counter >= HIGH_PORT_DIVIDER))
{
record->port = port;
record->time = timeNow;
record->tcp = tcp;
if (tcp)
{
attacker->portScan.numTCPScans++;
if (port >= MIN_HIGH_PORT)
attacker->portScan.tcpCounter = 0;
}
else
{
attacker->portScan.numUDPScans++;
if (port >= MIN_HIGH_PORT)
attacker->portScan.udpCounter = 0;
}
pgpDebugFmtMsg((pgpaFmtPrefix,
"Possible port scan attack from %d.%d.%d.%d on port %d.\n"
"%d TCP scans, %d UDP scans",
ipAddressByte[0], ipAddressByte[1], ipAddressByte[2],
ipAddressByte[3], port, attacker->portScan.numTCPScans,
attacker->portScan.numUDPScans));
}
}
}
else
{
count--;
if (record->tcp)
{
if ((timeNow - record->time) > TCP_SCAN_LIFETIME)
{
pgpDebugFmtMsg((pgpaFmtPrefix,
"TCP port scan from %d.%d.%d.%d port %d has expired. "
"%d TCP scans and %d UDP scans remaining",
ipAddressByte[0], ipAddressByte[1], ipAddressByte[2],
ipAddressByte[3], record->port,
attacker->portScan.numTCPScans-1,
attacker->portScan.numUDPScans));
record->port = 0;
attacker->portScan.numTCPScans--;
}
}
else
{
if ((timeNow - record->time) > UDP_SCAN_LIFETIME)
{
pgpDebugFmtMsg((pgpaFmtPrefix,
"UDP port scan from %d.%d.%d.%d port %d has expired. "
"%d TCP scans and %d UDP scans remaining",
ipAddressByte[0], ipAddressByte[1], ipAddressByte[2],
ipAddressByte[3], record->port,
attacker->portScan.numTCPScans,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -