///////////////////////////////////////////////////
// Acl.cpp文件
#define UNICODE
#define _UNICODE
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "../common/debug.h"
#include "Acl.h"
///////////////////////////////////////
// 共享内存
// 所有使用Winsock访问网络的应用程序都共享initdata和uinitdata段的变量
#pragma data_seg(".initdata")
HWND g_hPhoenixWnd = NULL; // 主窗口句柄
UCHAR g_ucWorkMode = PF_PASS_ALL; // 工作模式
#pragma data_seg()
#pragma bss_seg(".uinitdata")
RULE_ITEM g_Rule[MAX_RULE_COUNT]; // 应用层规则
ULONG g_RuleCount;
QUERY_SESSION g_QuerySession[MAX_QUERY_SESSION]; // 向主程序发送会话询问时使用
SESSION g_SessionBuffer[MAX_SESSION_BUFFER]; // 向主程序发送会话信息时使用
TCHAR g_szPhoenixFW[MAX_PATH]; // 记录主程序路径
#pragma bss_seg()
extern TCHAR g_szCurrentApp[MAX_PATH];
CRITICAL_SECTION g_csGetAccess;
CAcl::CAcl()
{
m_nSessionCount = 0;
// 为会话结构预申请内存空间
m_nSessionMaxCount = INIT_SESSION_BUFFER;
m_pSession = new SESSION[m_nSessionMaxCount];
::InitializeCriticalSection(&g_csGetAccess);
}
CAcl::~CAcl()
{
ODS(L" CAcl::~CAcl send CODE_APP_EXIT ... ");
// 通知主模块,当前应用程序正在退出
int nIndex = CreateSession(0, 0);
NotifySession(&m_pSession[nIndex], CODE_APP_EXIT);
delete[] m_pSession;
::DeleteCriticalSection(&g_csGetAccess);
}
/////////////////////////////////////////////////////////
// 检查函数
void CAcl::CheckSocket(SOCKET s, int af, int type, int protocol)
{
if (af != AF_INET) // 仅支持IPv4
return;
// 先判断基本协议类型
int nProtocol = RULE_SERVICE_TYPE_ALL;
if(protocol == 0)
{
if(type == SOCK_STREAM)
nProtocol = RULE_SERVICE_TYPE_TCP;
else if(type == SOCK_DGRAM)
nProtocol = RULE_SERVICE_TYPE_UDP;
}
else if(protocol == IPPROTO_TCP)
nProtocol = RULE_SERVICE_TYPE_TCP;
else if(protocol == IPPROTO_UDP)
nProtocol = RULE_SERVICE_TYPE_UDP;
// 为新套节字创建会话,指明协议类型
CreateSession(s, nProtocol);
}
void CAcl::CheckCloseSocket(SOCKET s)
{
// 删除会话
DeleteSession(s);
}
void CAcl::CheckBind(SOCKET s, const struct sockaddr *addr)
{
int nIndex;
if((nIndex = FindSession(s)) >= m_nSessionCount)
return;
// 设置会话
sockaddr_in *pLocal = (sockaddr_in *)addr;
m_pSession[nIndex].usLocalPort = ntohs(pLocal->sin_port);
if(pLocal->sin_addr.S_un.S_addr != ADDR_ANY)
m_pSession[nIndex].ulLocalIP = *((DWORD*)&pLocal->sin_addr);
}
int CAcl::CheckAccept(SOCKET s, SOCKET sNew, sockaddr FAR *addr)
{
int nIndex;
if((nIndex = FindSession(s)) >= m_nSessionCount)
return PF_PASS;
nIndex = CreateSession(sNew, RULE_SERVICE_TYPE_TCP);
// 设置会话
if(addr != NULL)
{
sockaddr_in *pRemote = (sockaddr_in *)addr;
USHORT usPort = ntohs(pRemote->sin_port);
DWORD dwIP = *((DWORD*)&pRemote->sin_addr);
SetSession(&m_pSession[nIndex], usPort, dwIP, RULE_DIRECTION_IN_OUT);
}
return GetAccessInfo(&m_pSession[nIndex]);
}
int CAcl::CheckConnect(SOCKET s, const struct sockaddr FAR *addr)
{
int nIndex;
if((nIndex = FindSession(s)) >= m_nSessionCount)
return PF_PASS;
// 设置会话远程地址
sockaddr_in *pRemote = (sockaddr_in *)addr;
USHORT usPort = ntohs(pRemote->sin_port);
DWORD dwIP = *((DWORD*)&pRemote->sin_addr);
SetSession(&m_pSession[nIndex], usPort, dwIP, RULE_DIRECTION_IN_OUT);
return GetAccessInfo(&m_pSession[nIndex]);
}
int CAcl::CheckSendTo(SOCKET s, const SOCKADDR *pTo)
{
int nIndex;
if((nIndex = FindSession(s)) >= m_nSessionCount)
return PF_PASS;
if(pTo != NULL)
{
// 设置会话远程地址
sockaddr_in *pRemote = (sockaddr_in *)pTo;
USHORT usPort = ntohs(pRemote->sin_port);
DWORD dwIP = *((DWORD*)&pRemote->sin_addr);
SetSession(&m_pSession[nIndex], usPort, dwIP, RULE_DIRECTION_OUT);
}
return GetAccessInfo(&m_pSession[nIndex]);
}
int CAcl::CheckRecvFrom(SOCKET s, SOCKADDR *pFrom)
{
int nIndex;
if((nIndex = FindSession(s)) >= m_nSessionCount)
return PF_PASS;
if(pFrom != NULL)
{
// 设置会话远程地址
sockaddr_in *pRemote = (sockaddr_in *)pFrom;
USHORT usPort = ntohs(pRemote->sin_port);
DWORD dwIP = *((DWORD*)&pRemote->sin_addr);
SetSession(&m_pSession[nIndex], usPort, dwIP, RULE_DIRECTION_IN);
}
return GetAccessInfo(&m_pSession[nIndex]);
}
/////////////////////////////////////////////////////////////
// 查看访问权限
int CAcl::GetAccessInfo(SESSION *pSession)
{
// 如果是主模块访问网络,放行
if(wcsicmp(g_szCurrentApp, g_szPhoenixFW) == 0)
{
return PF_PASS;
}
// 先查看工作模式
int nRet;
if((nRet = GetAccessFromWorkMode(pSession)) != PF_FILTER)
{
ODS(L" GetAccessInfo return from WorkMode \n");
return nRet;
}
// 工作模式为过滤,则按照文件中记录的规则过滤之
::EnterCriticalSection(&g_csGetAccess);
RULE_ITEM *pItem = NULL;
int nIndex = 0;
nRet = PF_PASS;
while(TRUE)
{
// 如果不是第一次查询,则加1,避免查找相同的规则
if(nIndex > 0)
nIndex++;
nIndex = FindRule(g_szCurrentApp, nIndex);
if(nIndex >= (int)g_RuleCount)
{
if(pItem == NULL) // 一个记录项也没有,则查询
{
// 询问主模块怎么办
if(!QueryAccess())
{
nRet = PF_DENY;
}
break;
}
else // 按照上一个记录项处理
{
if(pItem->ucAction != RULE_ACTION_PASS)
{
nRet = PF_DENY;
}
break;
}
}
ODS(L" Find a rule in GetAccessInfo ");
// 查看规则和会话的属性是否一致
pItem = &g_Rule[nIndex];
// 方向
if(pItem->ucDirection != RULE_DIRECTION_IN_OUT &&
pItem->ucDirection != pSession->ucDirection)
continue;
// 服务类型
if(pItem->ucServiceType != RULE_SERVICE_TYPE_ALL &&
pItem->ucServiceType != pSession->nProtocol)
continue;
// 服务端口
if(pItem->usServicePort != RULE_SERVICE_PORT_ALL &&
pItem->usServicePort != pSession->usRemotePort)
continue;
// 程序运行到这里,说明找到了一个和会话属性完全相同的规则
if(pItem->ucAction != RULE_ACTION_PASS)
{
nRet = PF_DENY;
}
break;
}
::LeaveCriticalSection(&g_csGetAccess);
if(nRet == PF_PASS)
pSession->ucAction = RULE_ACTION_PASS;
else
pSession->ucAction = RULE_ACTION_DENY;
return nRet;
}
int CAcl::GetAccessFromWorkMode(SESSION *pSession)
{
if(g_ucWorkMode == PF_PASS_ALL)
return PF_PASS;
if(g_ucWorkMode == PF_DENY_ALL)
return PF_DENY;
if(g_ucWorkMode == PF_QUERY_ALL)
return PF_FILTER;
return PF_UNKNOWN;
}
int CAcl::FindRule(TCHAR *szAppName, int nStart)
{
// 从指定位置开始查找,返回规则的索引
for(int nIndex = nStart; nIndex < (int)g_RuleCount; nIndex++)
{
if(wcsicmp(szAppName, g_Rule[nIndex].szApplication) == 0)
break;
}
return nIndex;
}
BOOL CAcl::QueryAccess()
{
ODS(L" QueryAccess ... ");
// 发送消息
for(int i=0; i<MAX_QUERY_SESSION; i++)
{
if(!g_QuerySession[i].bUsed) // 找到一个没有使用的QuerySession,发出询问
{
g_QuerySession[i].bUsed = TRUE;
wcscpy(g_QuerySession[i].szPathName, g_szCurrentApp);
if(!::PostMessage(g_hPhoenixWnd, PM_QUERY_ACL_NOTIFY, i, 0))
{
g_QuerySession[i].bUsed = FALSE;
return TRUE;
}
// 询问发送成功,等待
ODS(L"询问发送成功,等待... ");
int n=0;
while(g_QuerySession[i].bUsed)
{
if(n++ > 3000) // 等5分钟,如果用户还不决定,就禁止
return FALSE;
::Sleep(100);
}
if(g_QuerySession[i].nReturnValue == 0)
return FALSE;
return TRUE;
}
}
// 用完了
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////////////
// 会话操作
int CAcl::CreateSession(SOCKET s, int nProtocol)
{
for(int i=0; i<m_nSessionCount; i++)
{
if(m_pSession[i].s == s)
return i;
}
// 确保有足够的内存空间
if(m_nSessionCount >= m_nSessionMaxCount) // 已经达到最大数量
{
SESSION *pTmp = new SESSION[m_nSessionMaxCount];
memcpy(pTmp,
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
PhoenixFW.rar (58个子文件)
PhoenixFW
PhoenixLSP
PhoenixLSP.cpp 13KB
Acl.cpp 13KB
Debug
PhoenixLSP.dll 220KB
PhoenixLSP.h 2KB
Release
PhoenixLSP.dll 40KB
Acl.h 1KB
PhoenixLSP.dsp 5KB
PhoenixLSP.dsw 543B
PhoenixLSP.def 199B
common
IOCOMMON.H 3KB
PMacRes.h 3KB
initsock.h 461B
Debug.h 453B
TypeStruct.h 2KB
PhoenixFW
RuleDlg.h 2KB
ptutils.h 1KB
prule.fnk 2KB
StdAfx.cpp 863B
PIOControl.cpp 2KB
KerRulePage.h 1KB
resource.h 3KB
PhoenixFW.dsw 541B
KerRuleDlg.h 1KB
PhoenixLSP.dll 220KB
PhoenixFW.dsp 6KB
IOCOMMON.H 3KB
PRuleFile.h 1KB
PRuleFile.cpp 6KB
RulePage.h 2KB
PhoenixFWDlg.cpp 7KB
MonitorPage.cpp 6KB
Debug
PhoenixLSP.dll 220KB
PhoenixFW.exe 164KB
ptutils.cpp 5KB
PhoenixFWDlg.h 2KB
StdAfx.h 2KB
PIOControl.h 861B
SyssetPage.cpp 4KB
SyssetPage.h 1KB
PhoenixFW.h 1KB
IMIoControl.h 108B
KerRuleDlg.cpp 4KB
Provider.cpp 7KB
IMIoControl.cpp 86B
MonitorPage.h 2KB
Release
prule.fnk 2KB
PhoenixLSP.dll 40KB
PhoenixFW.exe 244KB
KerRulePage.cpp 5KB
RuleDlg.cpp 6KB
PhoenixFW.rc 12KB
PhoenixFW.suo 8KB
res
PhoenixFW.rc2 401B
PhoenixFW.ico 1KB
bitmap1.bmp 3KB
Thumbs.db 5KB
PhoenixFW.cpp 4KB
RulePage.cpp 8KB
共 58 条
- 1
资源评论
- DF2019-07-22真的好用,之前防火墙一直开不了,一用可以了
- shanqln2020-07-02下载的时候没有看日期,原来是这么旧的东西,怪不得我运行了没成功。
stargate2008
- 粉丝: 1
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功