📄 security.cpp
字号:
//
// Security.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
#include "StdAfx.h"
#include "Shareaza.h"
#include "Settings.h"
#include "Security.h"
#include "Network.h"
#include "Buffer.h"
#include "XML.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CSecurity Security;
//////////////////////////////////////////////////////////////////////
// CSecurity construction
CSecurity::CSecurity()
{
m_bDenyPolicy = FALSE;
}
CSecurity::~CSecurity()
{
Clear();
}
//////////////////////////////////////////////////////////////////////
// CSecurity rule access
POSITION CSecurity::GetIterator() const
{
return m_pRules.GetHeadPosition();
}
CSecureRule* CSecurity::GetNext(POSITION& pos) const
{
return (CSecureRule*)m_pRules.GetNext( pos );
}
int CSecurity::GetCount()
{
return m_pRules.GetCount();
}
BOOL CSecurity::Check(CSecureRule* pRule) const
{
return pRule && ( m_pRules.Find( pRule ) != NULL );
}
CSecureRule* CSecurity::GetGUID(const GUID& pGUID) const
{
for ( POSITION pos = m_pRules.GetHeadPosition() ; pos ; )
{
CSecureRule* pRule = (CSecureRule*)m_pRules.GetNext( pos );
if ( pRule->m_pGUID == pGUID ) return pRule;
}
return NULL;
}
//////////////////////////////////////////////////////////////////////
// CSecurity rule modification
void CSecurity::Add(CSecureRule* pRule)
{
POSITION pos = m_pRules.Find( pRule );
if ( pos == NULL ) m_pRules.AddHead( pRule );
}
void CSecurity::Remove(CSecureRule* pRule)
{
POSITION pos = m_pRules.Find( pRule );
if ( pos ) m_pRules.RemoveAt( pos );
delete pRule;
}
void CSecurity::MoveUp(CSecureRule* pRule)
{
POSITION posMe = m_pRules.Find( pRule );
if ( posMe == NULL ) return;
POSITION posOther = posMe;
m_pRules.GetPrev( posOther );
if ( posOther )
{
m_pRules.InsertBefore( posOther, pRule );
m_pRules.RemoveAt( posMe );
}
}
void CSecurity::MoveDown(CSecureRule* pRule)
{
POSITION posMe = m_pRules.Find( pRule );
if ( posMe == NULL ) return;
POSITION posOther = posMe;
m_pRules.GetNext( posOther );
if ( posOther )
{
m_pRules.InsertAfter( posOther, pRule );
m_pRules.RemoveAt( posMe );
}
}
void CSecurity::Clear()
{
for ( POSITION pos = GetIterator() ; pos ; )
{
delete GetNext( pos );
}
m_pRules.RemoveAll();
}
//////////////////////////////////////////////////////////////////////
// CSecurity session ban
void CSecurity::SessionBan(IN_ADDR* pAddress, BOOL bMessage)
{
CSingleLock pLock( &Network.m_pSection );
if ( ! pLock.Lock( 250 ) ) return;
CString strAddress = inet_ntoa( *pAddress );
for ( POSITION pos = GetIterator() ; pos ; )
{
CSecureRule* pRule = GetNext( pos );
if ( pRule->Match( pAddress ) )
{
if ( pRule->m_nAction == CSecureRule::srDeny )
{
if ( bMessage )
{
theApp.Message( MSG_SYSTEM, IDS_NETWORK_SECURITY_ALREADY_BLOCKED,
(LPCTSTR)strAddress );
}
return;
}
}
}
CSecureRule* pRule = new CSecureRule();
pRule->m_nAction = CSecureRule::srDeny;
pRule->m_nExpire = CSecureRule::srSession;
pRule->m_sComment = _T("Quick Ban");
CopyMemory( pRule->m_nIP, pAddress, 4 );
Add( pRule );
if ( bMessage )
{
theApp.Message( MSG_SYSTEM, IDS_NETWORK_SECURITY_BLOCKED,
(LPCTSTR)strAddress );
}
}
//////////////////////////////////////////////////////////////////////
// CSecurity access check
BOOL CSecurity::IsDenied(IN_ADDR* pAddress, LPCTSTR pszContent)
{
CSingleLock pLock( &Network.m_pSection );
if ( ! pLock.Lock( 50 ) ) return FALSE;
DWORD nNow = time( NULL );
for ( POSITION pos = GetIterator() ; pos ; )
{
POSITION posLast = pos;
CSecureRule* pRule = GetNext( pos );
if ( pRule->m_nExpire && pRule->IsExpired( nNow ) )
{
m_pRules.RemoveAt( posLast );
delete pRule;
}
else if ( pRule->Match( pAddress, pszContent ) )
{
pRule->m_nToday ++;
pRule->m_nEver ++;
if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE;
else if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE;
}
}
return m_bDenyPolicy;
}
BOOL CSecurity::IsAccepted(IN_ADDR* pAddress, LPCTSTR pszContent)
{
return ! IsDenied( pAddress, pszContent );
}
//////////////////////////////////////////////////////////////////////
// CSecurity expire
void CSecurity::Expire()
{
DWORD nNow = time( NULL );
for ( POSITION pos = GetIterator() ; pos ; )
{
POSITION posLast = pos;
CSecureRule* pRule = GetNext( pos );
if ( pRule->m_nExpire && pRule->IsExpired( nNow ) )
{
m_pRules.RemoveAt( posLast );
delete pRule;
}
}
}
//////////////////////////////////////////////////////////////////////
// CSecurity load and save
BOOL CSecurity::Load()
{
CFile pFile;
CString strFile = Settings.General.Path + _T("\\Data\\Security.dat");
if ( ! pFile.Open( strFile, CFile::modeRead ) ) return FALSE;
try
{
CArchive ar( &pFile, CArchive::load );
Serialize( ar );
ar.Close();
}
catch ( CException* pException )
{
pException->Delete();
}
pFile.Close();
return TRUE;
}
BOOL CSecurity::Save(BOOL bLock)
{
if ( bLock ) bLock = Network.m_pSection.Lock( 250 );
CFile pFile;
CString strFile = Settings.General.Path + _T("\\Data\\Security.dat");
if ( pFile.Open( strFile, CFile::modeWrite|CFile::modeCreate ) )
{
CArchive ar( &pFile, CArchive::store );
Serialize( ar );
ar.Close();
}
if ( bLock ) Network.m_pSection.Unlock();
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CSecurity serialize
void CSecurity::Serialize(CArchive& ar)
{
int nVersion = 4;
if ( ar.IsStoring() )
{
ar << nVersion;
ar << m_bDenyPolicy;
ar.WriteCount( GetCount() );
for ( POSITION pos = GetIterator() ; pos ; )
{
CSecureRule* pRule = GetNext( pos );
pRule->Serialize( ar, nVersion );
}
}
else
{
Clear();
ar >> nVersion;
ar >> m_bDenyPolicy;
DWORD nNow = time( NULL );
for ( int nCount = ar.ReadCount() ; nCount > 0 ; nCount-- )
{
CSecureRule* pRule = new CSecureRule( FALSE );
pRule->Serialize( ar, nVersion );
if ( pRule->IsExpired( nNow, TRUE ) )
delete pRule;
else
m_pRules.AddTail( pRule );
}
}
}
//////////////////////////////////////////////////////////////////////
// CSecurity XML
LPCTSTR CSecurity::xmlns = _T("http://www.shareaza.com/schemas/Security.xsd");
CXMLElement* CSecurity::ToXML(BOOL bRules)
{
CXMLElement* pXML = new CXMLElement( NULL, _T("security") );
pXML->AddAttribute( _T("xmlns"), CSecurity::xmlns );
if ( bRules )
{
for ( POSITION pos = GetIterator() ; pos ; )
{
pXML->AddElement( GetNext( pos )->ToXML() );
}
}
return pXML;
}
BOOL CSecurity::FromXML(CXMLElement* pXML)
{
if ( ! pXML->IsNamed( _T("security") ) ) return FALSE;
int nCount = 0;
for ( POSITION pos = pXML->GetElementIterator() ; pos ; )
{
CXMLElement* pElement = pXML->GetNextElement( pos );
if ( pElement->IsNamed( _T("rule") ) )
{
CSecureRule* pRule = NULL;
CString strGUID = pElement->GetAttributeValue( _T("guid") );
BOOL bExisting = FALSE;
GUID pGUID;
if ( GUIDX::Decode( strGUID, &pGUID ) )
{
if ( pRule = GetGUID( pGUID ) ) bExisting = TRUE;
if ( pRule == NULL )
{
pRule = new CSecureRule( FALSE );
pRule->m_pGUID = pGUID;
}
}
else
{
pRule = new CSecureRule();
}
if ( pRule->FromXML( pElement ) )
{
if ( ! bExisting ) m_pRules.AddTail( pRule );
nCount++;
}
else
{
if ( ! bExisting ) delete pRule;
}
}
}
return nCount > 0;
}
//////////////////////////////////////////////////////////////////////
// CSecurity import
BOOL CSecurity::Import(LPCTSTR pszFile)
{
CSingleLock pLock( &Network.m_pSection );
if ( ! pLock.Lock( 250 ) ) return FALSE;
CString strText;
CBuffer pBuffer;
CFile pFile;
if ( ! pFile.Open( pszFile, CFile::modeRead ) ) return FALSE;
pBuffer.EnsureBuffer( (DWORD)pFile.GetLength() );
pBuffer.m_nLength = (DWORD)pFile.GetLength();
pFile.Read( pBuffer.m_pBuffer, pBuffer.m_nLength );
pFile.Close();
CXMLElement* pXML = CXMLElement::FromBytes( pBuffer.m_pBuffer, pBuffer.m_nLength, TRUE );
BOOL bResult = FALSE;
if ( pXML != NULL )
{
bResult = FromXML( pXML );
delete pXML;
}
else
{
CString strLine;
while ( pBuffer.ReadLine( strLine ) )
{
strLine.TrimLeft();
strLine.TrimRight();
if ( strLine.IsEmpty() ) continue;
if ( strLine.GetAt( 0 ) == ';' ) continue;
CSecureRule* pRule = new CSecureRule();
if ( pRule->FromGnucleusString( strLine ) )
{
m_pRules.AddTail( pRule );
bResult = TRUE;
}
else
{
delete pRule;
}
}
}
return bResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -