00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Security.h"
00026 #include "Network.h"
00027 #include "Buffer.h"
00028 #include "XML.h"
00029
00030 #ifdef _DEBUG
00031 #undef THIS_FILE
00032 static char THIS_FILE[]=__FILE__;
00033 #define new DEBUG_NEW
00034 #endif
00035
00036 CSecurity Security;
00037 CAdultFilter AdultFilter;
00038 CMessageFilter MessageFilter;
00039
00040
00042
00043
00044 CSecurity::CSecurity()
00045 {
00046 m_bDenyPolicy = FALSE;
00047 }
00048
00049 CSecurity::~CSecurity()
00050 {
00051 Clear();
00052 }
00053
00055
00056
00057 POSITION CSecurity::GetIterator() const
00058 {
00059 return m_pRules.GetHeadPosition();
00060 }
00061
00062 CSecureRule* CSecurity::GetNext(POSITION& pos) const
00063 {
00064 return (CSecureRule*)m_pRules.GetNext( pos );
00065 }
00066
00067 int CSecurity::GetCount()
00068 {
00069 return m_pRules.GetCount();
00070 }
00071
00072 BOOL CSecurity::Check(CSecureRule* pRule) const
00073 {
00074 return pRule && ( m_pRules.Find( pRule ) != NULL );
00075 }
00076
00077 CSecureRule* CSecurity::GetGUID(const GUID& pGUID) const
00078 {
00079 for ( POSITION pos = m_pRules.GetHeadPosition() ; pos ; )
00080 {
00081 CSecureRule* pRule = (CSecureRule*)m_pRules.GetNext( pos );
00082 if ( pRule->m_pGUID == pGUID ) return pRule;
00083 }
00084
00085 return NULL;
00086 }
00087
00089
00090
00091 void CSecurity::Add(CSecureRule* pRule)
00092 {
00093 pRule->MaskFix();
00094
00095 POSITION pos = m_pRules.Find( pRule );
00096 if ( pos == NULL ) m_pRules.AddHead( pRule );
00097 }
00098
00099 void CSecurity::Remove(CSecureRule* pRule)
00100 {
00101 POSITION pos = m_pRules.Find( pRule );
00102 if ( pos ) m_pRules.RemoveAt( pos );
00103 delete pRule;
00104 }
00105
00106 void CSecurity::MoveUp(CSecureRule* pRule)
00107 {
00108 POSITION posMe = m_pRules.Find( pRule );
00109 if ( posMe == NULL ) return;
00110
00111 POSITION posOther = posMe;
00112 m_pRules.GetPrev( posOther );
00113
00114 if ( posOther )
00115 {
00116 m_pRules.InsertBefore( posOther, pRule );
00117 m_pRules.RemoveAt( posMe );
00118 }
00119 }
00120
00121 void CSecurity::MoveDown(CSecureRule* pRule)
00122 {
00123 POSITION posMe = m_pRules.Find( pRule );
00124 if ( posMe == NULL ) return;
00125
00126 POSITION posOther = posMe;
00127 m_pRules.GetNext( posOther );
00128
00129 if ( posOther )
00130 {
00131 m_pRules.InsertAfter( posOther, pRule );
00132 m_pRules.RemoveAt( posMe );
00133 }
00134 }
00135
00136 void CSecurity::Clear()
00137 {
00138 for ( POSITION pos = GetIterator() ; pos ; )
00139 {
00140 delete GetNext( pos );
00141 }
00142
00143 m_pRules.RemoveAll();
00144 }
00146
00147
00148 void CSecurity::Ban(IN_ADDR* pAddress, int nBanLength, BOOL bMessage)
00149 {
00150 CSingleLock pLock( &Network.m_pSection );
00151 if ( ! pLock.Lock( 250 ) ) return;
00152
00153 DWORD tNow = time( NULL );
00154 CString strAddress = inet_ntoa( *pAddress );
00155
00156 for ( POSITION pos = GetIterator() ; pos ; )
00157 {
00158 CSecureRule* pRule = GetNext( pos );
00159
00160 if ( pRule->Match( pAddress ) )
00161 {
00162 if ( pRule->m_nAction == CSecureRule::srDeny )
00163 {
00164 if ( ( nBanLength == banWeek ) && ( pRule->m_nExpire < tNow + 604000 ) )
00165 {
00166 pRule->m_nExpire = time( NULL ) + 604800;
00167 }
00168 else if ( ( nBanLength == banForever ) && ( pRule->m_nExpire != CSecureRule::srIndefinite ) )
00169 {
00170 pRule->m_nExpire = CSecureRule::srIndefinite;
00171 }
00172 else if ( bMessage )
00173 {
00174 theApp.Message( MSG_SYSTEM, IDS_NETWORK_SECURITY_ALREADY_BLOCKED,
00175 (LPCTSTR)strAddress );
00176 }
00177
00178 return;
00179 }
00180 }
00181 }
00182
00183 CSecureRule* pRule = new CSecureRule();
00184 pRule->m_nAction = CSecureRule::srDeny;
00185
00186 switch ( nBanLength )
00187 {
00188 case banSession:
00189 pRule->m_nExpire = CSecureRule::srSession;
00190 pRule->m_sComment = _T("Quick Ban");
00191 break;
00192 case ban5Mins:
00193 pRule->m_nExpire = time( NULL ) + 300;
00194 pRule->m_sComment = _T("Temp Ignore");
00195 break;
00196 case ban30Mins:
00197 pRule->m_nExpire = time( NULL ) + 1800;
00198 pRule->m_sComment = _T("Temp Ignore");
00199 break;
00200 case ban2Hours:
00201 pRule->m_nExpire = time( NULL ) + 7200;
00202 pRule->m_sComment = _T("Temp Ignore");
00203 break;
00204 case banWeek:
00205 pRule->m_nExpire = time( NULL ) + 604800;
00206 pRule->m_sComment = _T("Client Block");
00207 break;
00208 case banForever:
00209 pRule->m_nExpire = CSecureRule::srIndefinite;
00210 pRule->m_sComment = _T("Ban");
00211 break;
00212 default:
00213 pRule->m_nExpire = CSecureRule::srSession;
00214 pRule->m_sComment = _T("Quick Ban");
00215 }
00216
00217 CopyMemory( pRule->m_nIP, pAddress, 4 );
00218 Add( pRule );
00219
00220 if ( bMessage )
00221 {
00222 theApp.Message( MSG_SYSTEM, IDS_NETWORK_SECURITY_BLOCKED,
00223 (LPCTSTR)strAddress );
00224 }
00225 }
00226
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00302
00303
00304 BOOL CSecurity::IsDenied(IN_ADDR* pAddress, LPCTSTR pszContent)
00305 {
00306 CSingleLock pLock( &Network.m_pSection );
00307 if ( ! pLock.Lock( 50 ) ) return FALSE;
00308
00309 DWORD nNow = time( NULL );
00310
00311 for ( POSITION pos = GetIterator() ; pos ; )
00312 {
00313 POSITION posLast = pos;
00314 CSecureRule* pRule = GetNext( pos );
00315
00316 if ( pRule->m_nExpire && pRule->IsExpired( nNow ) )
00317 {
00318 m_pRules.RemoveAt( posLast );
00319 delete pRule;
00320 }
00321 else if ( pRule->Match( pAddress, pszContent ) )
00322 {
00323 pRule->m_nToday ++;
00324 pRule->m_nEver ++;
00325
00326 if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE;
00327 else if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE;
00328 }
00329 }
00330
00331 return m_bDenyPolicy;
00332 }
00333
00334 BOOL CSecurity::IsAccepted(IN_ADDR* pAddress, LPCTSTR pszContent)
00335 {
00336 return ! IsDenied( pAddress, pszContent );
00337 }
00338
00340
00341
00342 void CSecurity::Expire()
00343 {
00344 DWORD nNow = time( NULL );
00345
00346 for ( POSITION pos = GetIterator() ; pos ; )
00347 {
00348 POSITION posLast = pos;
00349 CSecureRule* pRule = GetNext( pos );
00350
00351 if ( pRule->m_nExpire && pRule->IsExpired( nNow ) )
00352 {
00353 m_pRules.RemoveAt( posLast );
00354 delete pRule;
00355 }
00356 }
00357 }
00358
00360
00361
00362 BOOL CSecurity::Load()
00363 {
00364 CFile pFile;
00365
00366 CString strFile = Settings.General.UserPath + _T("\\Data\\Security.dat");
00367
00368 if ( ! pFile.Open( strFile, CFile::modeRead ) ) return FALSE;
00369
00370 try
00371 {
00372 CArchive ar( &pFile, CArchive::load );
00373 Serialize( ar );
00374 ar.Close();
00375 }
00376 catch ( CException* pException )
00377 {
00378 pException->Delete();
00379 }
00380
00381 pFile.Close();
00382
00383 return TRUE;
00384 }
00385
00386 BOOL CSecurity::Save(BOOL bLock)
00387 {
00388 if ( bLock ) bLock = Network.m_pSection.Lock( 250 );
00389
00390 CFile pFile;
00391
00392 CString strFile = Settings.General.UserPath + _T("\\Data\\Security.dat");
00393
00394 if ( pFile.Open( strFile, CFile::modeWrite|CFile::modeCreate ) )
00395 {
00396 CArchive ar( &pFile, CArchive::store );
00397 Serialize( ar );
00398 ar.Close();
00399 }
00400
00401 if ( bLock ) Network.m_pSection.Unlock();
00402
00403 return TRUE;
00404 }
00405
00407
00408
00409 void CSecurity::Serialize(CArchive& ar)
00410 {
00411 int nVersion = 4;
00412
00413 if ( ar.IsStoring() )
00414 {
00415 ar << nVersion;
00416 ar << m_bDenyPolicy;
00417
00418 ar.WriteCount( GetCount() );
00419
00420 for ( POSITION pos = GetIterator() ; pos ; )
00421 {
00422 CSecureRule* pRule = GetNext( pos );
00423 pRule->Serialize( ar, nVersion );
00424 }
00425 }
00426 else
00427 {
00428 Clear();
00429
00430 ar >> nVersion;
00431 ar >> m_bDenyPolicy;
00432
00433 DWORD nNow = time( NULL );
00434
00435 for ( int nCount = ar.ReadCount() ; nCount > 0 ; nCount-- )
00436 {
00437 CSecureRule* pRule = new CSecureRule( FALSE );
00438 pRule->Serialize( ar, nVersion );
00439
00440 if ( pRule->IsExpired( nNow, TRUE ) )
00441 delete pRule;
00442 else
00443 m_pRules.AddTail( pRule );
00444 }
00445 }
00446 }
00447
00449
00450
00451 LPCTSTR CSecurity::xmlns = _T("http://www.shareaza.com/schemas/Security.xsd");
00452
00453 CXMLElement* CSecurity::ToXML(BOOL bRules)
00454 {
00455 CXMLElement* pXML = new CXMLElement( NULL, _T("security") );
00456 pXML->AddAttribute( _T("xmlns"), CSecurity::xmlns );
00457
00458 if ( bRules )
00459 {
00460 for ( POSITION pos = GetIterator() ; pos ; )
00461 {
00462 pXML->AddElement( GetNext( pos )->ToXML() );
00463 }
00464 }
00465
00466 return pXML;
00467 }
00468
00469 BOOL CSecurity::FromXML(CXMLElement* pXML)
00470 {
00471 if ( ! pXML->IsNamed( _T("security") ) ) return FALSE;
00472
00473 int nCount = 0;
00474
00475 for ( POSITION pos = pXML->GetElementIterator() ; pos ; )
00476 {
00477 CXMLElement* pElement = pXML->GetNextElement( pos );
00478
00479 if ( pElement->IsNamed( _T("rule") ) )
00480 {
00481 CSecureRule* pRule = NULL;
00482 CString strGUID = pElement->GetAttributeValue( _T("guid") );
00483 BOOL bExisting = FALSE;
00484 GUID pGUID;
00485
00486 if ( GUIDX::Decode( strGUID, &pGUID ) )
00487 {
00488 if ( pRule = GetGUID( pGUID ) ) bExisting = TRUE;
00489
00490 if ( pRule == NULL )
00491 {
00492 pRule = new CSecureRule( FALSE );
00493 pRule->m_pGUID = pGUID;
00494 }
00495 }
00496 else
00497 {
00498 pRule = new CSecureRule();
00499 }
00500
00501 if ( pRule->FromXML( pElement ) )
00502 {
00503 if ( ! bExisting ) m_pRules.AddTail( pRule );
00504 nCount++;
00505 }
00506 else
00507 {
00508 if ( ! bExisting ) delete pRule;
00509 }
00510 }
00511 }
00512
00513 return nCount > 0;
00514 }
00515
00517
00518
00519 BOOL CSecurity::Import(LPCTSTR pszFile)
00520 {
00521 CSingleLock pLock( &Network.m_pSection );
00522 if ( ! pLock.Lock( 250 ) ) return FALSE;
00523
00524 CString strText;
00525 CBuffer pBuffer;
00526 CFile pFile;
00527
00528 if ( ! pFile.Open( pszFile, CFile::modeRead ) ) return FALSE;
00529 pBuffer.EnsureBuffer( (DWORD)pFile.GetLength() );
00530 pBuffer.m_nLength = (DWORD)pFile.GetLength();
00531 pFile.Read( pBuffer.m_pBuffer, pBuffer.m_nLength );
00532 pFile.Close();
00533
00534 CXMLElement* pXML = CXMLElement::FromBytes( pBuffer.m_pBuffer, pBuffer.m_nLength, TRUE );
00535 BOOL bResult = FALSE;
00536
00537 if ( pXML != NULL )
00538 {
00539 bResult = FromXML( pXML );
00540 delete pXML;
00541 }
00542 else
00543 {
00544 CString strLine;
00545
00546 while ( pBuffer.ReadLine( strLine ) )
00547 {
00548 strLine.TrimLeft();
00549 strLine.TrimRight();
00550 if ( strLine.IsEmpty() ) continue;
00551 if ( strLine.GetAt( 0 ) == ';' ) continue;
00552
00553 CSecureRule* pRule = new CSecureRule();
00554
00555 if ( pRule->FromGnucleusString( strLine ) )
00556 {
00557 m_pRules.AddTail( pRule );
00558 bResult = TRUE;
00559 }
00560 else
00561 {
00562 delete pRule;
00563 }
00564 }
00565 }
00566
00567 return bResult;
00568 }
00569
00571
00572
00573 CSecureRule::CSecureRule(BOOL bCreate)
00574 {
00575 m_nType = srAddress;
00576 m_nAction = ( Security.m_bDenyPolicy ? srAccept : srDeny );
00577 m_nExpire = srIndefinite;
00578 m_nToday = 0;
00579 m_nEver = 0;
00580
00581 m_nIP[0] = m_nIP[1] = m_nIP[2] = m_nIP[3] = 0;
00582 m_nMask[0] = m_nMask[1] = m_nMask[2] = m_nMask[3] = 255;
00583 m_pContent = NULL;
00584
00585 if ( bCreate ) CoCreateGuid( &m_pGUID );
00586 }
00587
00588 CSecureRule::~CSecureRule()
00589 {
00590 if ( m_pContent ) delete [] m_pContent;
00591 }
00592
00594
00595
00596 void CSecureRule::Remove()
00597 {
00598 Security.Remove( this );
00599 }
00600
00601 void CSecureRule::Reset()
00602 {
00603 m_nToday = m_nEver = 0;
00604 }
00605
00607
00608
00609 BOOL CSecureRule::IsExpired(DWORD nNow, BOOL bSession)
00610 {
00611 if ( m_nExpire == srIndefinite ) return FALSE;
00612 if ( m_nExpire == srSession ) return bSession;
00613 return m_nExpire < nNow;
00614 }
00615
00617
00618
00619 BOOL CSecureRule::Match(IN_ADDR* pAddress, LPCTSTR pszContent)
00620 {
00621 if ( m_nExpire > srSession )
00622 {
00623 if ( m_nExpire <= (DWORD)time( NULL ) ) return FALSE;
00624 }
00625
00626 if ( m_nType == srAddress && pAddress != NULL )
00627 {
00628 DWORD* pBase = (DWORD*)m_nIP;
00629 DWORD* pMask = (DWORD*)m_nMask;
00630 DWORD* pTest = (DWORD*)pAddress;
00631
00632
00633 if ( ( ( *pTest ) & ( *pMask ) ) == ( *pBase ) )
00634 {
00635 return TRUE;
00636 }
00637 }
00638 else if ( m_nType == srContent && pszContent != NULL && m_pContent != NULL )
00639 {
00640 for ( LPCTSTR pszFilter = m_pContent ; *pszFilter ; )
00641 {
00642 BOOL bFound = _tcsistr( pszContent, pszFilter ) != NULL;
00643
00644 if ( bFound && m_nIP[0] == 0 )
00645 {
00646 return TRUE;
00647 }
00648 else if ( ! bFound && m_nIP[0] == 1 )
00649 {
00650 return FALSE;
00651 }
00652
00653 pszFilter += _tcslen( pszFilter ) + 1;
00654 }
00655
00656 if ( m_nIP[0] == 1 ) return TRUE;
00657 }
00658
00659 return FALSE;
00660 }
00661
00663
00664
00665 void CSecureRule::SetContentWords(const CString& strContent)
00666 {
00667 LPTSTR pszContent = (LPTSTR)(LPCTSTR)strContent;
00668 int nTotalLength = 3;
00669 CStringList pWords;
00670
00671 int nStart = 0, nPos = 0;
00672 for ( ; *pszContent ; nPos++, pszContent++ )
00673 {
00674 if ( *pszContent == ' ' || *pszContent == '\t' )
00675 {
00676 if ( nStart < nPos )
00677 {
00678 pWords.AddTail( strContent.Mid( nStart, nPos - nStart ) );
00679 nTotalLength += nPos - nStart + 1;
00680 }
00681 nStart = nPos + 1;
00682 }
00683 }
00684
00685 if ( nStart < nPos )
00686 {
00687 pWords.AddTail( strContent.Mid( nStart, nPos - nStart ) );
00688 nTotalLength += nPos - nStart + 1;
00689 }
00690
00691 if ( m_pContent )
00692 {
00693 delete [] m_pContent;
00694 m_pContent = NULL;
00695 }
00696
00697 if ( pWords.IsEmpty() ) return;
00698
00699 m_pContent = new TCHAR[ nTotalLength ];
00700 pszContent = m_pContent;
00701
00702 for ( POSITION pos = pWords.GetHeadPosition() ; pos ; )
00703 {
00704 CString strWord = pWords.GetNext( pos );
00705 CopyMemory( pszContent, (LPCTSTR)strWord, ( strWord.GetLength() + 1 ) * sizeof(TCHAR) );
00706 pszContent += strWord.GetLength() + 1;
00707 }
00708
00709 *pszContent++ = 0;
00710 *pszContent++ = 0;
00711 }
00712
00713 CString CSecureRule::GetContentWords()
00714 {
00715 CString strWords;
00716
00717 if ( m_pContent == NULL ) return strWords;
00718
00719 for ( LPCTSTR pszFilter = m_pContent ; *pszFilter ; )
00720 {
00721 if ( strWords.GetLength() ) strWords += ' ';
00722 strWords += pszFilter;
00723
00724 pszFilter += _tcslen( pszFilter ) + 1;
00725 }
00726
00727 return strWords;
00728 }
00729
00731
00732
00733 void CSecureRule::Serialize(CArchive& ar, int nVersion)
00734 {
00735 CString strTemp;
00736
00737 if ( ar.IsStoring() )
00738 {
00739 ar << m_nType;
00740 ar << m_nAction;
00741 ar << m_sComment;
00742
00743 ar.Write( &m_pGUID, sizeof(GUID) );
00744
00745 ar << m_nExpire;
00746 ar << m_nEver;
00747
00748 switch ( m_nType )
00749 {
00750 case srAddress:
00751 ar.Write( m_nIP, 4 );
00752 ar.Write( m_nMask, 4 );
00753 break;
00754 case srContent:
00755 ar << m_nIP[0];
00756 strTemp = GetContentWords();
00757 ar << strTemp;
00758 break;
00759 }
00760 }
00761 else
00762 {
00763 ar >> m_nType;
00764 ar >> m_nAction;
00765
00766 if ( nVersion >= 2 ) ar >> m_sComment;
00767
00768 if ( nVersion >= 4 )
00769 ar.Read( &m_pGUID, sizeof(GUID) );
00770 else
00771 CoCreateGuid( &m_pGUID );
00772
00773 ar >> m_nExpire;
00774 ar >> m_nEver;
00775
00776 switch ( m_nType )
00777 {
00778 case srAddress:
00779 ar.Read( m_nIP, 4 );
00780 ar.Read( m_nMask, 4 );
00781 MaskFix();
00782 break;
00783 case srContent:
00784 ar >> m_nIP[0];
00785
00786 if ( nVersion < 3 )
00787 {
00788 for ( int nCount = ar.ReadCount() ; nCount > 0 ; nCount-- )
00789 {
00790 CString strWord;
00791 ar >> strWord;
00792
00793 strTemp += ' ';
00794 strTemp += strWord;
00795 }
00796 }
00797 else
00798 {
00799 ar >> strTemp;
00800 }
00801 SetContentWords( strTemp );
00802 break;
00803 }
00804 }
00805 }
00806
00808
00809
00810 CXMLElement* CSecureRule::ToXML()
00811 {
00812 CXMLElement* pXML = new CXMLElement( NULL, _T("rule") );
00813 CString strValue;
00814
00815 if ( m_sComment.GetLength() )
00816 {
00817 pXML->AddAttribute( _T("comment"), m_sComment );
00818 }
00819
00820 switch ( m_nType )
00821 {
00822 case srAddress:
00823 pXML->AddAttribute( _T("type"), _T("address") );
00824 strValue.Format( _T("%lu.%lu.%lu.%lu"),
00825 m_nIP[0], m_nIP[1], m_nIP[2], m_nIP[3] );
00826 pXML->AddAttribute( _T("address"), strValue );
00827 if ( *(DWORD*)m_nMask != 0xFFFFFFFF )
00828 {
00829 strValue.Format( _T("%lu.%lu.%lu.%lu"),
00830 m_nMask[0], m_nMask[1], m_nMask[2], m_nMask[3] );
00831 pXML->AddAttribute( _T("mask"), strValue );
00832 }
00833 break;
00834 case srContent:
00835 pXML->AddAttribute( _T("type"), _T("content") );
00836 pXML->AddAttribute( _T("content"), GetContentWords() );
00837 pXML->AddAttribute( _T("match"), m_nIP[0] != 1 ? _T("any") : _T("all") );
00838 break;
00839 }
00840
00841 switch ( m_nAction )
00842 {
00843 case srNull:
00844 pXML->AddAttribute( _T("action"), _T("null") );
00845 break;
00846 case srAccept:
00847 pXML->AddAttribute( _T("action"), _T("accept") );
00848 break;
00849 case srDeny:
00850 pXML->AddAttribute( _T("action"), _T("deny") );
00851 break;
00852 }
00853
00854 if ( m_nExpire == srSession )
00855 {
00856 pXML->AddAttribute( _T("expire"), _T("session") );
00857 }
00858 else if ( m_nExpire > srSession )
00859 {
00860 strValue.Format( _T("%lu"), m_nExpire );
00861 pXML->AddAttribute( _T("expire"), strValue );
00862 }
00863
00864 wchar_t szGUID[39];
00865 szGUID[ StringFromGUID2( *(GUID*)&m_pGUID, szGUID, 39 ) - 2 ] = 0;
00866 pXML->AddAttribute( _T("guid"), (CString)&szGUID[1] );
00867
00868 return pXML;
00869 }
00870
00871 BOOL CSecureRule::FromXML(CXMLElement* pXML)
00872 {
00873 CString strValue;
00874
00875 m_sComment = pXML->GetAttributeValue( _T("comment") );
00876
00877 strValue = pXML->GetAttributeValue( _T("type") );
00878
00879 if ( strValue.CompareNoCase( _T("address") ) == 0 )
00880 {
00881 int x[4];
00882
00883 m_nType = srAddress;
00884
00885 strValue = pXML->GetAttributeValue( _T("address") );
00886 if ( _stscanf( strValue, _T("%lu.%lu.%lu.%lu"), &x[0], &x[1], &x[2], &x[3] ) == 4 )
00887 {
00888 m_nIP[0] = (BYTE)x[0]; m_nIP[1] = (BYTE)x[1];
00889 m_nIP[2] = (BYTE)x[2]; m_nIP[3] = (BYTE)x[3];
00890 }
00891
00892 strValue = pXML->GetAttributeValue( _T("mask") );
00893 if ( _stscanf( strValue, _T("%lu.%lu.%lu.%lu"), &x[0], &x[1], &x[2], &x[3] ) == 4 )
00894 {
00895 m_nMask[0] = (BYTE)x[0]; m_nMask[1] = (BYTE)x[1];
00896 m_nMask[2] = (BYTE)x[2]; m_nMask[3] = (BYTE)x[3];
00897 }
00898 }
00899 else if ( strValue.CompareNoCase( _T("content") ) == 0 )
00900 {
00901 m_nType = srContent;
00902 SetContentWords( pXML->GetAttributeValue( _T("content") ) );
00903 m_nIP[0] = pXML->GetAttributeValue( _T("match") ).CompareNoCase( _T("all") ) == 0;
00904 if ( m_pContent == NULL ) return FALSE;
00905 }
00906 else
00907 {
00908 return FALSE;
00909 }
00910
00911 strValue = pXML->GetAttributeValue( _T("action") );
00912
00913 if ( strValue.CompareNoCase( _T("null") ) == 0 )
00914 {
00915 m_nAction = srNull;
00916 }
00917 else if ( strValue.CompareNoCase( _T("accept") ) == 0 )
00918 {
00919 m_nAction = srAccept;
00920 }
00921 else if ( strValue.CompareNoCase( _T("deny") ) == 0 || strValue.IsEmpty() )
00922 {
00923 m_nAction = srDeny;
00924 }
00925 else
00926 {
00927 return FALSE;
00928 }
00929
00930 strValue = pXML->GetAttributeValue( _T("expire") );
00931 m_nExpire = srIndefinite;
00932
00933 if ( strValue.CompareNoCase( _T("session") ) == 0 )
00934 {
00935 m_nExpire = srSession;
00936 }
00937 else if ( strValue.CompareNoCase( _T("indefinite") ) != 0 )
00938 {
00939 _stscanf( strValue, _T("%lu"), &m_nExpire );
00940 }
00941
00942 MaskFix();
00943
00944 return TRUE;
00945 }
00946
00948
00949
00950 CString CSecureRule::ToGnucleusString()
00951 {
00952 CString strRule;
00953
00954 if ( m_nType != srAddress ) return strRule;
00955 if ( m_nAction != srDeny ) return strRule;
00956
00957 if ( *(DWORD*)m_nMask == 0xFFFFFFFF )
00958 {
00959 strRule.Format( _T("%lu.%lu.%lu.%lu"),
00960 m_nIP[0], m_nIP[1], m_nIP[2], m_nIP[3] );
00961 }
00962 else
00963 {
00964 int nFrom[4], nTo[4];
00965
00966 for ( int nByte = 0 ; nByte < 4 ; nByte++ )
00967 {
00968 nFrom[ nByte ] = m_nIP[ nByte ] & m_nMask[ nByte ];
00969 nTo[ nByte ] = m_nIP[ nByte ] | ( ~m_nMask[ nByte ] );
00970 }
00971
00972 strRule.Format( _T("%lu.%lu.%lu.%lu-%lu.%lu.%lu.%lu"),
00973 nFrom[0], nFrom[1], nFrom[2], nFrom[3],
00974 nTo[0], nTo[1], nTo[2], nTo[3] );
00975 }
00976
00977 strRule += ':';
00978 strRule += m_sComment;
00979 strRule += ':';
00980
00981 return strRule;
00982 }
00983
00984 BOOL CSecureRule::FromGnucleusString(CString& str)
00985 {
00986 int nPos, x[4];
00987
00988 nPos = str.Find( ':' );
00989 if ( nPos < 1 ) return FALSE;
00990
00991 CString strAddress = str.Left( nPos );
00992 str = str.Mid( nPos + 1 );
00993
00994 if ( _stscanf( strAddress, _T("%lu.%lu.%lu.%lu"), &x[0], &x[1], &x[2], &x[3] ) != 4 )
00995 return FALSE;
00996
00997 m_nIP[0] = (BYTE)x[0]; m_nIP[1] = (BYTE)x[1];
00998 m_nIP[2] = (BYTE)x[2]; m_nIP[3] = (BYTE)x[3];
00999
01000 nPos = strAddress.Find( '-' );
01001
01002 if ( nPos >= 0 )
01003 {
01004 strAddress = strAddress.Mid( nPos + 1 );
01005
01006 if ( _stscanf( strAddress, _T("%lu.%lu.%lu.%lu"), &x[0], &x[1], &x[2], &x[3] ) != 4 )
01007 return FALSE;
01008
01009 for ( int nByte = 0 ; nByte < 4 ; nByte++ )
01010 {
01011 BYTE nTop = (BYTE)x[ nByte ], nBase = (BYTE)x[ nByte ];
01012
01013 for ( BYTE nValue = m_nIP[ nByte ] ; nValue < nTop ; nValue++ )
01014 {
01015 m_nMask[ nByte ] &= ~( nValue ^ nBase );
01016 }
01017 }
01018 }
01019
01020 m_nType = srAddress;
01021 m_nAction = srDeny;
01022 m_nExpire = srIndefinite;
01023 m_sComment = str.SpanExcluding( _T(":") );
01024
01025 MaskFix();
01026
01027 return TRUE;
01028 }
01030
01031 void CSecureRule::MaskFix()
01032 {
01033 DWORD nNetwork = 0 , nOldMask = 0 , nNewMask = 0;
01034
01035 for ( int nByte = 0 ; nByte < 4 ; nByte++ )
01036 {
01037 BYTE nMaskByte = 0;
01038 BYTE nNetByte = 0;
01039 nNetByte = m_nIP[ nByte ];
01040 nMaskByte = m_nMask[ nByte ];
01041 for ( int nBits = 0 ; nBits < 8 ; nBits++ )
01042 {
01043 nNetwork <<= 1;
01044 if( nNetByte & 0x80 )
01045 {
01046 nNetwork |= 1;
01047 }
01048 nNetByte <<= 1;
01049
01050 nOldMask <<= 1;
01051 if( nMaskByte & 0x80 )
01052 {
01053 nOldMask |= 1;
01054 }
01055 nMaskByte <<= 1;
01056 }
01057 }
01058
01059 DWORD nTempMask = nOldMask;
01060
01061 for ( int nBits = 0 ; nBits < 32 ; nBits++ )
01062 {
01063 if( nTempMask & 0x80000000 )
01064 {
01065 nNewMask >>= 1;
01066 nNewMask |= 0x80000000;
01067 }
01068 else
01069 {
01070 break;
01071 }
01072 nTempMask <<= 1;
01073 }
01074
01075 if ( nNewMask != nOldMask )
01076 {
01077 m_nExpire = srSession;
01078 return;
01079 }
01080
01081 nNetwork &= nNewMask;
01082
01083 for ( int nByte = 0 ; nByte < 4 ; nByte++ )
01084 {
01085 BYTE nNetByte = 0;
01086 for ( int nBits = 0 ; nBits < 8 ; nBits++ )
01087 {
01088 nNetByte <<= 1;
01089 if( nNetwork & 0x80000000 )
01090 {
01091 nNetByte |= 1;
01092 }
01093 nNetwork <<= 1;
01094 }
01095 m_nIP[ nByte ] = nNetByte;
01096 }
01097 }
01098
01100
01101
01102 CAdultFilter::CAdultFilter()
01103 {
01104 m_pszBlockedWords = NULL;
01105 m_pszDubiousWords = NULL;
01106 }
01107
01108 CAdultFilter::~CAdultFilter()
01109 {
01110 if ( m_pszBlockedWords ) delete [] m_pszBlockedWords;
01111 m_pszBlockedWords = NULL;
01112
01113 if ( m_pszDubiousWords ) delete [] m_pszDubiousWords;
01114 m_pszDubiousWords = NULL;
01115 }
01116
01117 void CAdultFilter::Load()
01118 {
01119 CFile pFile;
01120 CString strFile = Settings.General.Path + _T("\\Data\\AdultFilter.dat");
01121 CString strBlockedWords, strDubiousWords;
01122
01123
01124 if ( m_pszBlockedWords ) delete [] m_pszBlockedWords;
01125 m_pszBlockedWords = NULL;
01126
01127 if ( m_pszDubiousWords ) delete [] m_pszDubiousWords;
01128 m_pszDubiousWords = NULL;
01129
01130
01131 if ( pFile.Open( strFile, CFile::modeRead ) )
01132 {
01133
01134 try
01135 {
01136 CBuffer pBuffer;
01137
01138 pBuffer.EnsureBuffer( (DWORD)pFile.GetLength() );
01139 pBuffer.m_nLength = (DWORD)pFile.GetLength();
01140 pFile.Read( pBuffer.m_pBuffer, pBuffer.m_nLength );
01141 pFile.Close();
01142
01143 pBuffer.ReadLine( strBlockedWords );
01144 pBuffer.ReadLine( strDubiousWords );
01145 }
01146 catch ( CException* pException )
01147 {
01148 if (pFile.m_hFile != CFile::hFileNull) pFile.Close();
01149 pException->Delete();
01150 }
01151 }
01152
01153
01154 if ( strBlockedWords.IsEmpty() )
01155 strBlockedWords = _T("xxx porn fuck cock cunt vagina pussy nude naked hentai lesbian whore shit rape preteen hardcore lolita playboy penthouse dildo upskirt beastiality bestiality pedofil necrofil");
01156 if ( strDubiousWords.IsEmpty() )
01157 strDubiousWords = _T("ass sex anal gay teen thong babe bikini viagra dick");
01158
01159
01160 if ( strBlockedWords.GetLength() > 3 )
01161 {
01162 LPCTSTR pszPtr = strBlockedWords;
01163 int nWordLen = 3;
01164 CStringList pWords;
01165
01166 int nStart = 0, nPos = 0;
01167 for ( ; *pszPtr ; nPos++, pszPtr++ )
01168 {
01169 if ( *pszPtr == ' ' )
01170 {
01171 if ( nStart < nPos )
01172 {
01173 pWords.AddTail( strBlockedWords.Mid( nStart, nPos - nStart ) );
01174 nWordLen += ( nPos - nStart ) + 1;
01175 }
01176 nStart = nPos + 1;
01177 }
01178 }
01179
01180
01181 if ( nStart < nPos )
01182 {
01183 pWords.AddTail( strBlockedWords.Mid( nStart, nPos - nStart ) );
01184 nWordLen += ( nPos - nStart ) + 1;
01185 }
01186
01187 m_pszBlockedWords = new TCHAR[ nWordLen ];
01188 LPTSTR pszFilter = m_pszBlockedWords;
01189
01190 for ( POSITION pos = pWords.GetHeadPosition() ; pos ; )
01191 {
01192 CString strWord = pWords.GetNext( pos );
01193 CharLower( strWord.GetBuffer() );
01194 strWord.ReleaseBuffer();
01195 CopyMemory( pszFilter, (LPCTSTR)strWord, sizeof(TCHAR) * ( strWord.GetLength() + 1 ) );
01196 pszFilter += strWord.GetLength() + 1;
01197 }
01198
01199 *pszFilter++ = 0;
01200 *pszFilter++ = 0;
01201 }
01202
01203
01204 if ( strDubiousWords.GetLength() > 3 )
01205 {
01206 LPCTSTR pszPtr = strDubiousWords;
01207 int nWordLen = 3;
01208 CStringList pWords;
01209
01210 int nStart = 0, nPos = 0;
01211 for ( ; *pszPtr ; nPos++, pszPtr++ )
01212 {
01213 if ( *pszPtr == ' ' )
01214 {
01215 if ( nStart < nPos )
01216 {
01217 pWords.AddTail( strDubiousWords.Mid( nStart, nPos - nStart ) );
01218 nWordLen += ( nPos - nStart ) + 1;
01219 }
01220 nStart = nPos + 1;
01221 }
01222 }
01223
01224 if ( nStart < nPos )
01225 {
01226 pWords.AddTail( strDubiousWords.Mid( nStart, nPos - nStart ) );
01227 nWordLen += ( nPos - nStart ) + 1;
01228 }
01229
01230 m_pszDubiousWords = new TCHAR[ nWordLen ];
01231 LPTSTR pszFilter = m_pszDubiousWords;
01232
01233 for ( POSITION pos = pWords.GetHeadPosition() ; pos ; )
01234 {
01235 CString strWord = pWords.GetNext( pos );
01236 CharLower( strWord.GetBuffer() );
01237 strWord.ReleaseBuffer();
01238 CopyMemory( pszFilter, (LPCTSTR)strWord, sizeof(TCHAR) * ( strWord.GetLength() + 1 ) );
01239 pszFilter += strWord.GetLength() + 1;
01240 }
01241
01242 *pszFilter++ = 0;
01243 *pszFilter++ = 0;
01244 }
01245
01246 }
01247
01248 BOOL CAdultFilter::IsHitAdult( LPCTSTR pszText )
01249 {
01250 if ( pszText )
01251 {
01252 return IsFiltered( pszText );
01253 }
01254 return FALSE;
01255 }
01256
01257 BOOL CAdultFilter::IsSearchFiltered( LPCTSTR pszText )
01258 {
01259 if ( Settings.Search.AdultFilter && pszText )
01260 {
01261 return IsFiltered( pszText );
01262 }
01263 return FALSE;
01264 }
01265
01266 BOOL CAdultFilter::IsChatFiltered( LPCTSTR pszText )
01267 {
01268 if ( Settings.Community.ChatCensor && pszText )
01269 {
01270 return IsFiltered( pszText );
01271 }
01272 return FALSE;
01273 }
01274
01275 BOOL CAdultFilter::Censor( TCHAR* pszText )
01276 {
01277 BOOL bModified = FALSE;
01278 if ( ! pszText ) return FALSE;
01279
01280 LPCTSTR pszWord;
01281
01282
01283 if ( m_pszBlockedWords )
01284 {
01285 for ( pszWord = m_pszBlockedWords ; *pszWord ; )
01286 {
01287 TCHAR* pReplace = (TCHAR*)_tcsistr( pszText, pszWord );
01288
01289 if ( pReplace != NULL )
01290 {
01291 TCHAR cExpletives[6] = {'#','@','$','%','&','*'};
01292
01293 for ( unsigned nLoop = 0 ; nLoop < _tcslen( pszWord ) ; nLoop++ )
01294 {
01295 *pReplace = cExpletives[ ( nLoop % 6 ) ];
01296 pReplace++;
01297 }
01298
01299 bModified = TRUE;
01300 }
01301
01302 pszWord += _tcslen( pszWord ) + 1;
01303 }
01304 }
01305
01306 return bModified;
01307 }
01308
01309 BOOL CAdultFilter::IsFiltered( LPCTSTR pszText )
01310 {
01311 if ( pszText )
01312 {
01313 LPCTSTR pszWord;
01314
01315
01316 if ( m_pszBlockedWords )
01317 {
01318 for ( pszWord = m_pszBlockedWords ; *pszWord ; )
01319 {
01320 if ( _tcsistr( pszText, pszWord ) != NULL ) return TRUE;
01321 pszWord += _tcslen( pszWord ) + 1;
01322 }
01323 }
01324
01325
01326 if ( m_pszDubiousWords )
01327 {
01328 int nDubiousWords = 0, nWordsPermitted = min( (_tcslen( pszText ) / 8 ), size_t(4) );
01329
01330 for ( pszWord = m_pszDubiousWords ; *pszWord ; )
01331 {
01332 if ( _tcsistr( pszText, pszWord ) != NULL ) nDubiousWords++;
01333 if ( nDubiousWords > nWordsPermitted ) return TRUE;
01334 pszWord += _tcslen( pszWord ) + 1;
01335 }
01336 }
01337 }
01338
01339 return FALSE;
01340 }
01341
01342
01344
01345
01346 CMessageFilter::CMessageFilter()
01347 {
01348 m_pszED2KSpam = NULL;
01349 m_pszFilteredPhrases = NULL;
01350 }
01351
01352 CMessageFilter::~CMessageFilter()
01353 {
01354 if ( m_pszED2KSpam ) delete [] m_pszED2KSpam;
01355 m_pszED2KSpam = NULL;
01356
01357 if ( m_pszFilteredPhrases ) delete [] m_pszFilteredPhrases;
01358 m_pszFilteredPhrases = NULL;
01359
01360 }
01361
01362 void CMessageFilter::Load()
01363 {
01364 CFile pFile;
01365 CString strFile = Settings.General.Path + _T("\\Data\\MessageFilter.dat");
01366 CString strFilteredPhrases, strED2KSpamPhrases;
01367
01368
01369 if ( m_pszFilteredPhrases ) delete [] m_pszFilteredPhrases;
01370 m_pszFilteredPhrases = NULL;
01371
01372
01373 if ( pFile.Open( strFile, CFile::modeRead ) )
01374 {
01375 try
01376 {
01377 CBuffer pBuffer;
01378
01379 pBuffer.EnsureBuffer( (DWORD)pFile.GetLength() );
01380 pBuffer.m_nLength = (DWORD)pFile.GetLength();
01381 pFile.Read( pBuffer.m_pBuffer, pBuffer.m_nLength );
01382 pFile.Close();
01383
01384 pBuffer.ReadLine( strED2KSpamPhrases );
01385 pBuffer.ReadLine( strFilteredPhrases );
01386 }
01387 catch ( CException* pException )
01388 {
01389 if (pFile.m_hFile != CFile::hFileNull) pFile.Close();
01390 pException->Delete();
01391 }
01392 }
01393
01394
01395
01396 if ( strED2KSpamPhrases.IsEmpty() )
01397 strED2KSpamPhrases = _T("Your client is connecting too fast|Join the L33cher Team|PeerFactor|Your client is making too many connections|AUTOMATED MESSAGE:");
01398
01399 if ( strFilteredPhrases.IsEmpty() )
01400 strFilteredPhrases = _T("");
01401
01402
01403
01404 if ( strED2KSpamPhrases.GetLength() > 3 )
01405 {
01406 LPCTSTR pszPtr = strED2KSpamPhrases;
01407 int nWordLen = 3;
01408 CStringList pWords;
01409
01410 int nStart = 0, nPos = 0;
01411 for ( ; *pszPtr ; nPos++, pszPtr++ )
01412 {
01413 if ( *pszPtr == '|' )
01414 {
01415 if ( nStart < nPos )
01416 {
01417 pWords.AddTail( strED2KSpamPhrases.Mid( nStart, nPos - nStart ) );
01418 nWordLen += ( nPos - nStart ) + 1;
01419 }
01420 nStart = nPos + 1;
01421 }
01422 }
01423
01424 if ( nStart < nPos )
01425 {
01426 pWords.AddTail( strED2KSpamPhrases.Mid( nStart, nPos - nStart ) );
01427 nWordLen += ( nPos - nStart ) + 1;
01428 }
01429
01430 m_pszED2KSpam = new TCHAR[ nWordLen ];
01431 LPTSTR pszFilter = m_pszED2KSpam;
01432
01433 for ( POSITION pos = pWords.GetHeadPosition() ; pos ; )
01434 {
01435 CString strWord = pWords.GetNext( pos );
01436 CharLower( strWord.GetBuffer() );
01437 strWord.ReleaseBuffer();
01438 CopyMemory( pszFilter, (LPCTSTR)strWord, sizeof(TCHAR) * ( strWord.GetLength() + 1 ) );
01439 pszFilter += strWord.GetLength() + 1;
01440 }
01441
01442 *pszFilter++ = 0;
01443 *pszFilter++ = 0;
01444 }
01445
01446
01447 if ( strFilteredPhrases.GetLength() > 3 )
01448 {
01449 LPCTSTR pszPtr = strFilteredPhrases;
01450 int nWordLen = 3;
01451 CStringList pWords;
01452
01453 int nStart = 0, nPos = 0;
01454 for ( ; *pszPtr ; nPos++, pszPtr++ )
01455 {
01456 if ( *pszPtr == '|' )
01457 {
01458 if ( nStart < nPos )
01459 {
01460 pWords.AddTail( strFilteredPhrases.Mid( nStart, nPos - nStart ) );
01461 nWordLen += ( nPos - nStart ) + 1;
01462 }
01463 nStart = nPos + 1;
01464 }
01465 }
01466
01467 if ( nStart < nPos )
01468 {
01469 pWords.AddTail( strFilteredPhrases.Mid( nStart, nPos - nStart ) );
01470 nWordLen += ( nPos - nStart ) + 1;
01471 }
01472
01473 m_pszFilteredPhrases = new TCHAR[ nWordLen ];
01474 LPTSTR pszFilter = m_pszFilteredPhrases;
01475
01476 for ( POSITION pos = pWords.GetHeadPosition() ; pos ; )
01477 {
01478 CString strWord = pWords.GetNext( pos );
01479 CharLower( strWord.GetBuffer() );
01480 strWord.ReleaseBuffer();
01481 CopyMemory( pszFilter, (LPCTSTR)strWord, sizeof(TCHAR) * ( strWord.GetLength() + 1 ) );
01482 pszFilter += strWord.GetLength() + 1;
01483 }
01484
01485 *pszFilter++ = 0;
01486 *pszFilter++ = 0;
01487 }
01488 }
01489
01490 BOOL CMessageFilter::IsED2KSpam( LPCTSTR pszText )
01491 {
01492 if ( Settings.Community.ChatFilterED2K && pszText )
01493 {
01494
01495 if ( m_pszED2KSpam )
01496 {
01497 LPCTSTR pszWord;
01498 for ( pszWord = m_pszED2KSpam ; *pszWord ; )
01499 {
01500 if ( _tcsistr( pszText, pszWord ) != NULL ) return TRUE;
01501 pszWord += _tcslen( pszWord ) + 1;
01502 }
01503 }
01504 }
01505
01506 return FALSE;
01507 }
01508
01509
01510 BOOL CMessageFilter::IsFiltered( LPCTSTR pszText )
01511 {
01512 if ( Settings.Community.ChatFilter && pszText )
01513 {
01514
01515 if ( m_pszFilteredPhrases )
01516 {
01517 LPCTSTR pszWord;
01518 for ( pszWord = m_pszFilteredPhrases ; *pszWord ; )
01519 {
01520 if ( _tcsistr( pszText, pszWord ) != NULL ) return TRUE;
01521 pszWord += _tcslen( pszWord ) + 1;
01522 }
01523 }
01524 }
01525
01526 return FALSE;
01527 }