📄 security.cpp
字号:
//////////////////////////////////////////////////////////////////////
// CSecureRule construction
CSecureRule::CSecureRule(BOOL bCreate)
{
m_nType = srAddress;
m_nAction = ( Security.m_bDenyPolicy ? srAccept : srDeny );
m_nExpire = srIndefinite;
m_nToday = 0;
m_nEver = 0;
m_nIP[0] = m_nIP[1] = m_nIP[2] = m_nIP[3] = 0;
m_nMask[0] = m_nMask[1] = m_nMask[2] = m_nMask[3] = 255;
m_pContent = NULL;
if ( bCreate ) CoCreateGuid( &m_pGUID );
}
CSecureRule::~CSecureRule()
{
if ( m_pContent ) delete [] m_pContent;
}
//////////////////////////////////////////////////////////////////////
// CSecureRule remove and reset
void CSecureRule::Remove()
{
Security.Remove( this );
}
void CSecureRule::Reset()
{
m_nToday = m_nEver = 0;
}
//////////////////////////////////////////////////////////////////////
// CSecureRule expiry check
BOOL CSecureRule::IsExpired(DWORD nNow, BOOL bSession)
{
if ( m_nExpire == srIndefinite ) return FALSE;
if ( m_nExpire == srSession ) return bSession;
return m_nExpire < nNow;
}
//////////////////////////////////////////////////////////////////////
// CSecureRule match
BOOL CSecureRule::Match(IN_ADDR* pAddress, LPCTSTR pszContent)
{
if ( m_nExpire > srSession )
{
if ( m_nExpire <= (DWORD)time( NULL ) ) return FALSE;
}
if ( m_nType == srAddress && pAddress != NULL )
{
DWORD* pBase = (DWORD*)m_nIP;
DWORD* pMask = (DWORD*)m_nMask;
DWORD* pTest = (DWORD*)pAddress;
if ( ( ( *pTest ) & ( *pMask ) ) == ( ( *pBase ) & ( *pMask ) ) )
{
return TRUE;
}
}
else if ( m_nType == srContent && pszContent != NULL && m_pContent != NULL )
{
for ( LPCTSTR pszFilter = m_pContent ; *pszFilter ; )
{
BOOL bFound = _tcsistr( pszContent, pszFilter ) != NULL;
if ( bFound && m_nIP[0] == 0 )
{
return TRUE;
}
else if ( ! bFound && m_nIP[0] == 1 )
{
return FALSE;
}
pszFilter += _tcslen( pszFilter ) + 1;
}
if ( m_nIP[0] == 1 ) return TRUE;
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CSecureRule content list helpers
void CSecureRule::SetContentWords(const CString& strContent)
{
LPTSTR pszContent = (LPTSTR)(LPCTSTR)strContent;
int nTotalLength = 3;
CStringList pWords;
for ( int nStart = 0, nPos = 0 ; *pszContent ; nPos++, pszContent++ )
{
if ( *pszContent == ' ' || *pszContent == '\t' )
{
if ( nStart < nPos )
{
pWords.AddTail( strContent.Mid( nStart, nPos - nStart ) );
nTotalLength += nPos - nStart + 1;
}
nStart = nPos + 1;
}
}
if ( nStart < nPos )
{
pWords.AddTail( strContent.Mid( nStart, nPos - nStart ) );
nTotalLength += nPos - nStart + 1;
}
if ( m_pContent )
{
delete [] m_pContent;
m_pContent = NULL;
}
if ( pWords.IsEmpty() ) return;
m_pContent = new TCHAR[ nTotalLength ];
pszContent = m_pContent;
for ( POSITION pos = pWords.GetHeadPosition() ; pos ; )
{
CString strWord = pWords.GetNext( pos );
CopyMemory( pszContent, (LPCTSTR)strWord, ( strWord.GetLength() + 1 ) * sizeof(TCHAR) );
pszContent += strWord.GetLength() + 1;
}
*pszContent++ = 0;
*pszContent++ = 0;
}
CString CSecureRule::GetContentWords()
{
CString strWords;
if ( m_pContent == NULL ) return strWords;
for ( LPCTSTR pszFilter = m_pContent ; *pszFilter ; )
{
if ( strWords.GetLength() ) strWords += ' ';
strWords += pszFilter;
pszFilter += _tcslen( pszFilter ) + 1;
}
return strWords;
}
//////////////////////////////////////////////////////////////////////
// CSecureRule serialize
void CSecureRule::Serialize(CArchive& ar, int nVersion)
{
CString strTemp;
if ( ar.IsStoring() )
{
ar << m_nType;
ar << m_nAction;
ar << m_sComment;
ar.Write( &m_pGUID, sizeof(GUID) );
ar << m_nExpire;
ar << m_nEver;
switch ( m_nType )
{
case srAddress:
ar.Write( m_nIP, 4 );
ar.Write( m_nMask, 4 );
break;
case srContent:
ar << m_nIP[0];
strTemp = GetContentWords();
ar << strTemp;
break;
}
}
else
{
ar >> m_nType;
ar >> m_nAction;
if ( nVersion >= 2 ) ar >> m_sComment;
if ( nVersion >= 4 )
ar.Read( &m_pGUID, sizeof(GUID) );
else
CoCreateGuid( &m_pGUID );
ar >> m_nExpire;
ar >> m_nEver;
switch ( m_nType )
{
case srAddress:
ar.Read( m_nIP, 4 );
ar.Read( m_nMask, 4 );
break;
case srContent:
ar >> m_nIP[0];
if ( nVersion < 3 )
{
for ( int nCount = ar.ReadCount() ; nCount > 0 ; nCount-- )
{
CString strWord;
ar >> strWord;
strTemp += ' ';
strTemp += strWord;
}
}
else
{
ar >> strTemp;
}
SetContentWords( strTemp );
break;
}
}
}
//////////////////////////////////////////////////////////////////////
// CSecureRule XML
CXMLElement* CSecureRule::ToXML()
{
CXMLElement* pXML = new CXMLElement( NULL, _T("rule") );
CString strValue;
if ( m_sComment.GetLength() )
{
pXML->AddAttribute( _T("comment"), m_sComment );
}
switch ( m_nType )
{
case srAddress:
pXML->AddAttribute( _T("type"), _T("address") );
strValue.Format( _T("%lu.%lu.%lu.%lu"),
m_nIP[0], m_nIP[1], m_nIP[2], m_nIP[3] );
pXML->AddAttribute( _T("address"), strValue );
if ( *(DWORD*)m_nMask != 0xFFFFFFFF )
{
strValue.Format( _T("%lu.%lu.%lu.%lu"),
m_nMask[0], m_nMask[1], m_nMask[2], m_nMask[3] );
pXML->AddAttribute( _T("mask"), strValue );
}
break;
case srContent:
pXML->AddAttribute( _T("type"), _T("content") );
pXML->AddAttribute( _T("content"), GetContentWords() );
pXML->AddAttribute( _T("match"), m_nIP[0] != 1 ? _T("any") : _T("all") );
break;
}
switch ( m_nAction )
{
case srNull:
pXML->AddAttribute( _T("action"), _T("null") );
break;
case srAccept:
pXML->AddAttribute( _T("action"), _T("accept") );
break;
case srDeny:
pXML->AddAttribute( _T("action"), _T("deny") );
break;
}
if ( m_nExpire == srSession )
{
pXML->AddAttribute( _T("expire"), _T("session") );
}
else if ( m_nExpire > srSession )
{
strValue.Format( _T("%lu"), m_nExpire );
pXML->AddAttribute( _T("expire"), strValue );
}
wchar_t szGUID[39];
szGUID[ StringFromGUID2( *(GUID*)&m_pGUID, szGUID, 39 ) - 2 ] = 0;
pXML->AddAttribute( _T("guid"), (CString)&szGUID[1] );
return pXML;
}
BOOL CSecureRule::FromXML(CXMLElement* pXML)
{
CString strValue;
m_sComment = pXML->GetAttributeValue( _T("comment") );
strValue = pXML->GetAttributeValue( _T("type") );
if ( strValue.CompareNoCase( _T("address") ) == 0 )
{
int x[4];
m_nType = srAddress;
strValue = pXML->GetAttributeValue( _T("address") );
if ( _stscanf( strValue, _T("%lu.%lu.%lu.%lu"), &x[0], &x[1], &x[2], &x[3] ) == 4 )
{
m_nIP[0] = (BYTE)x[0]; m_nIP[1] = (BYTE)x[1];
m_nIP[2] = (BYTE)x[2]; m_nIP[3] = (BYTE)x[3];
}
strValue = pXML->GetAttributeValue( _T("mask") );
if ( _stscanf( strValue, _T("%lu.%lu.%lu.%lu"), &x[0], &x[1], &x[2], &x[3] ) == 4 )
{
m_nMask[0] = (BYTE)x[0]; m_nMask[1] = (BYTE)x[1];
m_nMask[2] = (BYTE)x[2]; m_nMask[3] = (BYTE)x[3];
}
}
else if ( strValue.CompareNoCase( _T("content") ) == 0 )
{
m_nType = srContent;
SetContentWords( pXML->GetAttributeValue( _T("content") ) );
m_nIP[0] = pXML->GetAttributeValue( _T("match") ).CompareNoCase( _T("all") ) == 0;
if ( m_pContent == NULL ) return FALSE;
}
else
{
return FALSE;
}
strValue = pXML->GetAttributeValue( _T("action") );
if ( strValue.CompareNoCase( _T("null") ) == 0 )
{
m_nAction = srNull;
}
else if ( strValue.CompareNoCase( _T("accept") ) == 0 )
{
m_nAction = srAccept;
}
else if ( strValue.CompareNoCase( _T("deny") ) == 0 || strValue.IsEmpty() )
{
m_nAction = srDeny;
}
else
{
return FALSE;
}
strValue = pXML->GetAttributeValue( _T("expire") );
m_nExpire = srIndefinite;
if ( strValue.CompareNoCase( _T("session") ) == 0 )
{
m_nExpire = srSession;
}
else if ( strValue.CompareNoCase( _T("indefinite") ) != 0 )
{
_stscanf( strValue, _T("%lu"), &m_nExpire );
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CSecureRule Gnucelus strings
CString CSecureRule::ToGnucleusString()
{
CString strRule;
if ( m_nType != srAddress ) return strRule;
if ( m_nAction != srDeny ) return strRule;
if ( *(DWORD*)m_nMask == 0xFFFFFFFF )
{
strRule.Format( _T("%lu.%lu.%lu.%lu"),
m_nIP[0], m_nIP[1], m_nIP[2], m_nIP[3] );
}
else
{
int nFrom[4], nTo[4];
for ( int nByte = 0 ; nByte < 4 ; nByte++ )
{
nFrom[ nByte ] = m_nIP[ nByte ] & m_nMask[ nByte ];
nTo[ nByte ] = m_nIP[ nByte ] | ( ~m_nMask[ nByte ] );
}
strRule.Format( _T("%lu.%lu.%lu.%lu-%lu.%lu.%lu.%lu"),
nFrom[0], nFrom[1], nFrom[2], nFrom[3],
nTo[0], nTo[1], nTo[2], nTo[3] );
}
strRule += ':';
strRule += m_sComment;
strRule += ':';
return strRule;
}
BOOL CSecureRule::FromGnucleusString(CString& str)
{
int nPos, x[4];
nPos = str.Find( ':' );
if ( nPos < 1 ) return FALSE;
CString strAddress = str.Left( nPos );
str = str.Mid( nPos + 1 );
if ( _stscanf( strAddress, _T("%lu.%lu.%lu.%lu"), &x[0], &x[1], &x[2], &x[3] ) != 4 )
return FALSE;
m_nIP[0] = (BYTE)x[0]; m_nIP[1] = (BYTE)x[1];
m_nIP[2] = (BYTE)x[2]; m_nIP[3] = (BYTE)x[3];
nPos = strAddress.Find( '-' );
if ( nPos >= 0 )
{
strAddress = strAddress.Mid( nPos + 1 );
if ( _stscanf( strAddress, _T("%lu.%lu.%lu.%lu"), &x[0], &x[1], &x[2], &x[3] ) != 4 )
return FALSE;
for ( int nByte = 0 ; nByte < 4 ; nByte++ )
{
BYTE nTop = (BYTE)x[ nByte ], nBase = (BYTE)x[ nByte ];
for ( BYTE nValue = m_nIP[ nByte ] ; nValue < nTop ; nValue++ )
{
m_nMask[ nByte ] &= ~( nValue ^ nBase );
}
}
}
m_nType = srAddress;
m_nAction = srDeny;
m_nExpire = srIndefinite;
m_sComment = str.SpanExcluding( _T(":") );
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -