void CSecurity::Expire() { CQuickLock oLock( m_pSection ); const DWORD tNow = static_cast< DWORD >( time( NULL ) ); for ( POSITION pos = m_Complains.GetStartPosition() ; pos ; ) { DWORD pAddress; CComplain* pComplain; m_Complains.GetNextAssoc( pos, pAddress, pComplain ); if ( pComplain->m_nExpire < tNow ) { m_Complains.RemoveKey( pAddress ); delete pComplain; } } for ( POSITION pos = GetIterator() ; pos ; ) { POSITION posLast = pos; CSecureRule* pRule = GetNext( pos ); if ( pRule->IsExpired( tNow ) ) { m_pRules.RemoveAt( posLast ); delete pRule; } } }
BOOL CSecurity::IsDenied(const CQuerySearch* pQuery, const CString& strContent) { const DWORD tNow = static_cast< DWORD >( time( NULL ) ); CQuickLock oLock( m_pSection ); for ( POSITION pos = GetIterator() ; pos ; ) { POSITION posLast = pos; CSecureRule* pRule = GetNext( pos ); if ( pRule->IsExpired( tNow ) ) { m_pRules.RemoveAt( posLast ); delete pRule; } else if ( pRule->Match( pQuery, strContent ) ) { pRule->m_nToday ++; pRule->m_nEver ++; if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE; if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE; } } return m_bDenyPolicy; }
BOOL CSecurity::IsDenied(const IN_ADDR* pAddress) { if ( m_Cache.count( *(DWORD*)pAddress ) ) return m_bDenyPolicy; //theApp.Message( MSG_DEBUG, _T("Skipped Repeat IP Security Check (%i Cached)"), m_Cache.size() ); if ( BYTE nIndex = GetAddressMap( *(DWORD*)pAddress ) ) { if ( CSecureRule* pRule = m_pRuleIndexMap[ nIndex ] ) { pRule->m_nToday ++; pRule->m_nEver ++; if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE; if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE; } } const DWORD tNow = static_cast< DWORD >( time( NULL ) ); { CQuickLock oLock( m_pSection ); for ( POSITION pos = GetIterator() ; pos ; ) { POSITION posLast = pos; CSecureRule* pRule = GetNext( pos ); if ( pRule->IsExpired( tNow ) ) { m_pRules.RemoveAt( posLast ); delete pRule; continue; } if ( pRule->Match( pAddress ) ) { pRule->m_nToday ++; pRule->m_nEver ++; // Add 5 min penalty for early access if ( pRule->m_nExpire > CSecureRule::srSession && pRule->m_nExpire < tNow + 300 ) pRule->m_nExpire = tNow + 300; if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE; if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE; } } } m_Cache.insert( *(DWORD*)pAddress ); // Skip future lookups return m_bDenyPolicy; }
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") ) ) { CQuickLock oLock( m_pSection ); CSecureRule* pRule = NULL; CString strGUID = pElement->GetAttributeValue( _T("guid") ); BOOL bExisting = FALSE; GUID pGUID; if ( Hashes::fromGuid( strGUID, &pGUID ) ) { if ( ( pRule = GetGUID( pGUID ) ) != NULL ) 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; }
void CSecurity::Ban(const CPeerProjectFile* pFile, int nBanLength, BOOL bMessage) { CQuickLock oLock( m_pSection ); const DWORD tNow = static_cast< DWORD >( time( NULL ) ); for ( POSITION pos = GetIterator() ; pos ; ) { POSITION posCurrent = pos; CSecureRule* pRule = GetNext( pos ); if ( pRule->IsExpired( tNow ) ) { m_pRules.RemoveAt( posCurrent ); delete pRule; continue; } if ( pRule->Match( pFile ) ) // Non-regexp name, hash, or size:ext:0000 { if ( pRule->m_nAction == CSecureRule::srDeny ) { if ( nBanLength == banWeek && ( pRule->m_nExpire < tNow + 604000 ) ) pRule->m_nExpire = tNow + 604800; else if ( nBanLength == banCustom && ( pRule->m_nExpire < tNow + Settings.Security.DefaultBan + 3600 ) ) pRule->m_nExpire = tNow + Settings.Security.DefaultBan + 3600; else if ( nBanLength == banForever && ( pRule->m_nExpire != CSecureRule::srIndefinite ) ) pRule->m_nExpire = CSecureRule::srIndefinite; return; } } } CSecureRule* pRule = NewBanRule( nBanLength ); if ( pFile->m_oSHA1 || pFile->m_oTiger || pFile->m_oED2K || pFile->m_oBTH || pFile->m_oMD5 ) { pRule->m_nType = CSecureRule::srContentHash; pRule->SetContentWords( ( pFile->m_oSHA1 ? pFile->m_oSHA1.toUrn() + _T(" ") : CString() ) + ( pFile->m_oTiger ? pFile->m_oTiger.toUrn() + _T(" ") : CString() ) + ( pFile->m_oED2K ? pFile->m_oED2K.toUrn() + _T(" ") : CString() ) + ( pFile->m_oMD5 ? pFile->m_oMD5.toUrn() + _T(" ") : CString() ) + ( pFile->m_oBTH ? pFile->m_oBTH.toUrn() : CString() ) ); } Add( pRule ); if ( bMessage && pFile ) theApp.Message( MSG_NOTICE, IDS_NETWORK_SECURITY_BLOCKED, (LPCTSTR)pFile->m_sName ); }
BOOL CSecurity::Import(LPCTSTR pszFile) { 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.Trim(); if ( strLine.IsEmpty() ) continue; if ( strLine.GetAt( 0 ) == ';' ) continue; CSecureRule* pRule = new CSecureRule(); if ( pRule->FromGnucleusString( strLine ) ) { CQuickLock oLock( m_pSection ); m_pRules.AddTail( pRule ); bResult = TRUE; } else { delete pRule; } } } // Check all lists for newly denied hosts PostMainWndMessage( WM_SANITY_CHECK ); return bResult; }
BOOL CSecurity::IsDenied(LPCTSTR pszContent) { if ( CString(pszContent).GetLength() > 30 && StartsWith( pszContent, _PT("urn:") ) ) { if ( BYTE nIndex = GetHashMap( pszContent ) ) { if ( CSecureRule* pRule = GetRuleByIndex( nIndex ) ) { pRule->m_nToday ++; pRule->m_nEver ++; if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE; if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE; } } return m_bDenyPolicy; } const DWORD tNow = static_cast< DWORD >( time( NULL ) ); CQuickLock oLock( m_pSection ); for ( POSITION pos = GetIterator() ; pos ; ) { POSITION posLast = pos; CSecureRule* pRule = GetNext( pos ); if ( pRule->IsExpired( tNow ) ) { m_pRules.RemoveAt( posLast ); delete pRule; } else if ( pRule->Match( pszContent ) ) { pRule->m_nToday ++; pRule->m_nEver ++; // Add 5 min penalty for early access if ( pRule->m_nExpire > CSecureRule::srSession && pRule->m_nExpire < tNow + 300 ) pRule->m_nExpire = tNow + 300; if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE; if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE; } } return m_bDenyPolicy; }
// Contains default code for XML generation. void CSecureRule::toXML(const CSecureRule& oRule, QXmlStreamWriter& oXMLdocument) { QString sValue; // Write rule action to XML file. switch ( oRule.m_nAction ) { case RuleAction::None: sValue = "null"; break; case RuleAction::Accept: sValue = "accept"; break; case RuleAction::Deny: sValue = "deny"; break; default: Q_ASSERT( false ); } oXMLdocument.writeAttribute( "action", sValue ); if(oRule.m_bAutomatic) oXMLdocument.writeAttribute( "automatic", "true" ); else oXMLdocument.writeAttribute( "automatic", "false" ); // Write expiry date. if ( oRule.m_tExpire == RuleTime::Special ) { if ( oRule.m_bForever ) { sValue = "forever"; } else { sValue = "session"; } } else if ( oRule.m_tExpire > 0 ) { sValue = "%1"; sValue.arg( oRule.getExpiryTime() ); } oXMLdocument.writeAttribute( "expire", sValue ); // Write rule UUID. sValue = oRule.m_oUUID.toString(); oXMLdocument.writeAttribute( "uuid", sValue ); // Write user comment. if ( !( oRule.m_sComment.isEmpty() ) ) { oXMLdocument.writeAttribute( "comment", oRule.m_sComment ); } }
void CSecurity::Ban(const IN_ADDR* pAddress, int nBanLength, BOOL bMessage, LPCTSTR szComment) { CQuickLock oLock( m_pSection ); const DWORD tNow = static_cast< DWORD >( time( NULL ) ); for ( POSITION pos = GetIterator() ; pos ; ) { POSITION posCurrent = pos; CSecureRule* pRule = GetNext( pos ); if ( pRule->IsExpired( tNow ) ) { m_pRules.RemoveAt( posCurrent ); delete pRule; continue; } if ( pRule->Match( pAddress ) && pRule->m_nAction == CSecureRule::srDeny ) { if ( nBanLength == banWeek && ( pRule->m_nExpire < tNow + 604000 ) ) pRule->m_nExpire = tNow + 604800; else if ( nBanLength == banCustom && ( pRule->m_nExpire < tNow + Settings.Security.DefaultBan + 3600 ) ) pRule->m_nExpire = tNow + Settings.Security.DefaultBan + 3600; else if ( nBanLength == banForever && ( pRule->m_nExpire != CSecureRule::srIndefinite ) ) pRule->m_nExpire = CSecureRule::srIndefinite; else if ( bMessage && pAddress ) theApp.Message( MSG_NOTICE, IDS_NETWORK_SECURITY_ALREADY_BLOCKED, (LPCTSTR)CString( inet_ntoa( *pAddress ) ) ); return; } } CSecureRule* pRule = NewBanRule( nBanLength, szComment ); pRule->m_nType = CSecureRule::srAddress; CopyMemory( pRule->m_nIP, pAddress, sizeof pRule->m_nIP ); Add( pRule ); if ( bMessage ) theApp.Message( MSG_NOTICE, IDS_NETWORK_SECURITY_BLOCKED, (LPCTSTR)CString( inet_ntoa( *pAddress ) ) ); }
CSecureRule* CSecureRule::fromXML(QXmlStreamReader& oXMLdocument, float nVersion) { QXmlStreamAttributes attributes = oXMLdocument.attributes(); const QString sType = attributes.value( "type" ).toString(); if ( sType.isEmpty() ) return NULL; CSecureRule* pRule = NULL; if ( sType.compare( "address", Qt::CaseInsensitive ) == 0 ) { QString sAddress = attributes.value( "address" ).toString(); pRule = new CIPRule(); pRule->parseContent( sAddress ); } else if ( sType.compare( "addressrange", Qt::CaseInsensitive ) == 0 ) { QString sStartAddress = attributes.value( "startaddress" ).toString(); QString sEndAddress = attributes.value( "endaddress" ).toString(); pRule = new CIPRangeRule(); pRule->parseContent( QString("%1-%2").arg(sStartAddress).arg(sEndAddress) ); } else if ( sType.compare( "hash", Qt::CaseInsensitive ) == 0 ) { CHashRule* rule = new CHashRule(); if ( !rule->parseContent( attributes.value( "content" ).toString() ) ) { delete rule; return NULL; } pRule = rule; } else if ( sType.compare( "regexp", Qt::CaseInsensitive ) == 0 ) { CRegularExpressionRule* rule = new CRegularExpressionRule(); if ( !rule->parseContent( attributes.value( "content" ).toString() ) ) { delete rule; return NULL; } pRule = rule; } else if ( sType.compare( "content", Qt::CaseInsensitive ) == 0 ) { const QString sMatch = attributes.value( "match" ).toString(); const QString sContent = attributes.value( "content" ).toString(); const QString sUrn = sContent.left( 4 ); if ( nVersion < 2.0 ) { // This handles "old style" Shareaza RegExp rules. if ( sMatch.compare( "regexp", Qt::CaseInsensitive ) == 0 ) { CRegularExpressionRule* rule = new CRegularExpressionRule(); if ( !rule->parseContent( sContent ) ) { delete rule; return NULL; } pRule = rule; } // This handles "old style" Shareaza hash rules. else if ( sUrn.compare( "urn:", Qt::CaseInsensitive ) == 0 ) { CHashRule* rule = new CHashRule(); if ( !rule->parseContent( sContent ) ) { delete rule; return NULL; } pRule = rule; } } if ( !pRule ) { bool all = ( sMatch.compare( "all", Qt::CaseInsensitive ) == 0 ); if ( all || sMatch.compare( "any", Qt::CaseInsensitive ) == 0 ) { CContentRule* rule = new CContentRule(); if ( !rule->parseContent( sContent ) ) { delete rule; return NULL; } rule->setAll( all ); pRule = rule; } else { return NULL; } } } else { return NULL; } const QString sAction = attributes.value( "action" ).toString(); if ( sAction.compare( "deny", Qt::CaseInsensitive ) == 0 || sAction.isEmpty() ) { pRule->m_nAction = RuleAction::Deny; } else if ( sAction.compare( "accept", Qt::CaseInsensitive ) == 0 ) { pRule->m_nAction = RuleAction::Accept; } else if ( sAction.compare( "null", Qt::CaseInsensitive ) == 0 ) { pRule->m_nAction = RuleAction::None; } else { delete pRule; return NULL; } const QString sAutomatic = attributes.value( "automatic" ).toString(); if(sAutomatic == "true") pRule->m_bAutomatic = true; else pRule->m_bAutomatic = false; pRule->m_sComment = attributes.value( "comment" ).toString().trimmed(); QString sExpire = attributes.value( "expire" ).toString(); if ( sExpire.compare( "forever", Qt::CaseInsensitive ) == 0 ) { pRule->setForever(true); } else if ( sExpire.compare( "session", Qt::CaseInsensitive ) == 0 ) { pRule->setForever(false); pRule->m_tExpire = RuleTime::Special; } else { pRule->m_tExpire = sExpire.toUInt(); } QString sUUID = attributes.value( "uuid" ).toString(); if ( sUUID.isEmpty() ) sUUID = attributes.value( "guid" ).toString(); if ( sUUID.isEmpty() ) { pRule->m_oUUID = QUuid::createUuid(); } else { pRule->m_oUUID = QUuid( sUUID ); } return pRule; }
// TODO: change user interface for IP ranges and hashes. void DialogAddRule::on_pushButtonOK_clicked() { CSecureRule* pRule = NULL; QString sTmp; switch ( ui->comboBoxRuleType->currentIndex() ) { case 0: pRule = new CIPRule(); sTmp = ui->lineEditIP->text(); if ( !pRule->parseContent( sTmp ) ) { delete pRule; pRule = NULL; } break; case 1: pRule = new CIPRangeRule(); break; case 2: pRule = new CCountryRule(); sTmp = ui->lineEditCountry->text(); if ( !pRule->parseContent( sTmp ) ) { delete pRule; pRule = NULL; } break; case 3: pRule = new CHashRule(); sTmp = ui->lineEditURI->text(); if ( !pRule->parseContent( sTmp ) ) { delete pRule; pRule = NULL; } break; case 4: pRule = new CContentRule(); sTmp = ui->lineEditContent->text(); if ( !pRule->parseContent( sTmp ) ) { delete pRule; pRule = NULL; } ((CContentRule*)pRule)->setAll( ui->radioButtonMatchAll->isChecked() ); break; case 5: pRule = new CRegExpRule(); sTmp = ui->lineEditRegularExpression->text(); if ( !pRule->parseContent( sTmp ) ) { delete pRule; pRule = NULL; } break; case 6: pRule = new CUserAgentRule(); sTmp = ui->lineEditUserAgent->text(); if ( !pRule->parseContent( sTmp ) ) { delete pRule; pRule = NULL; } ((CUserAgentRule*)pRule)->setRegExp( ui->checkBoxUserAgent->isChecked() ); break; default: Q_ASSERT( false ); } if ( pRule ) { quint32 tExpire = ui->comboBoxExpire->currentIndex(); if ( tExpire == 2 ) { tExpire = 0; tExpire += ui->lineEditMinutes->text().toUShort() * 60; tExpire += ui->lineEditHours->text().toUShort() * 3600; tExpire += ui->lineEditDays->text().toUShort() * 216000; tExpire += static_cast< quint32 >( time( NULL ) ); } pRule->m_tExpire = tExpire; pRule->m_sComment = ui->lineEditComment->text(); pRule->m_oUUID = m_pRule->m_oUUID; if ( *pRule != *m_pRule ) { securityManager.remove( m_pRule ); securityManager.add( pRule ); } } emit dataUpdated(); emit closed(); close(); }
void CSecurity::Serialize(CArchive& ar) { int nVersion = SECURITY_SER_VERSION; if ( ar.IsStoring() ) { ar << nVersion; ar << m_bDenyPolicy; ar.WriteCount( GetCount() ); for ( POSITION pos = GetIterator() ; pos ; ) { GetNext( pos )->Serialize( ar, nVersion ); } // Unimplemented //for ( CAddressRuleMap::const_iterator i = m_pIPRules.begin() ; i != m_pIPRules.end() ; ++i ) //{ // (*i).second->Serialize( ar, nVersion ); //} } else // Loading { Clear(); ar >> nVersion; ar >> m_bDenyPolicy; const DWORD tNow = static_cast< DWORD >( time( NULL ) ); for ( DWORD_PTR nCount = ar.ReadCount() ; nCount > 0 ; nCount-- ) { CSecureRule* pRule = new CSecureRule( FALSE ); pRule->Serialize( ar, nVersion ); if ( pRule->IsExpired( tNow, TRUE ) ) { delete pRule; continue; } // Special handling for single-IP security rules if ( pRule->m_nType == CSecureRule::srAddress && pRule->m_nAction == CSecureRule::srDeny && *(DWORD*)pRule->m_nMask == 0xffffffff ) { SetAddressMap( *(DWORD*)pRule->m_nIP, SetRuleIndex( pRule ) ); continue; } if ( pRule->m_nType == CSecureRule::srContentHash && pRule->m_nAction == CSecureRule::srDeny ) { SetHashMap( pRule->GetContentWords(), SetRuleIndex( pRule ) ); continue; } if ( pRule->m_nType == CSecureRule::srExternal ) ListLoader.AddList( pRule ); m_pRules.AddTail( pRule ); } } }
BOOL CSecurity::IsDenied(const CPeerProjectFile* pFile) { if ( pFile->m_oSHA1 && ! m_HashMap[urnSHA].empty() ) if ( BYTE nIndex = GetHashMap( pFile->m_oSHA1.toUrn() ) ) { if ( CSecureRule* pRule = GetRuleByIndex( nIndex ) ) { pRule->m_nToday ++; pRule->m_nEver ++; if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE; if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE; } } if ( pFile->m_oTiger && ! m_HashMap[urnTiger].empty() ) if ( BYTE nIndex = GetHashMap( pFile->m_oTiger.toUrn() ) ) { if ( CSecureRule* pRule = GetRuleByIndex( nIndex ) ) { pRule->m_nToday ++; pRule->m_nEver ++; if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE; if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE; } } if ( pFile->m_oED2K && ! m_HashMap[urnED2K].empty() ) if ( BYTE nIndex = GetHashMap( pFile->m_oED2K.toUrn() ) ) { if ( CSecureRule* pRule = GetRuleByIndex( nIndex ) ) { pRule->m_nToday ++; pRule->m_nEver ++; if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE; if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE; } } if ( pFile->m_oBTH && ! m_HashMap[urnBTH].empty() ) if ( BYTE nIndex = GetHashMap( pFile->m_oBTH.toUrn() ) ) { if ( CSecureRule* pRule = GetRuleByIndex( nIndex ) ) { pRule->m_nToday ++; pRule->m_nEver ++; if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE; if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE; } } if ( pFile->m_oMD5 && ! m_HashMap[urnMD5].empty() ) if ( BYTE nIndex = GetHashMap( pFile->m_oMD5.toUrn() ) ) { if ( CSecureRule* pRule = GetRuleByIndex( nIndex ) ) { pRule->m_nToday ++; pRule->m_nEver ++; if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE; if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE; } } const DWORD tNow = static_cast< DWORD >( time( NULL ) ); CQuickLock oLock( m_pSection ); for ( POSITION pos = GetIterator() ; pos ; ) { POSITION posLast = pos; CSecureRule* pRule = GetNext( pos ); if ( pRule->IsExpired( tNow ) ) { m_pRules.RemoveAt( posLast ); delete pRule; } else if ( pRule->Match( pFile ) ) // Non-regexp name, hash, or size:ext:0000 { pRule->m_nToday ++; pRule->m_nEver ++; // Add 5 min penalty for early access if ( pRule->m_nExpire > CSecureRule::srSession && pRule->m_nExpire < tNow + 300 ) pRule->m_nExpire = tNow + 300; if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE; if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE; } } return m_bDenyPolicy; }
void CListLoader::OnRun() { while ( IsThreadEnabled() && m_pQueue.GetCount() ) { CSecureRule* pRule = m_pQueue.GetHead(); if ( ! pRule || ! pRule->m_pContent || pRule->m_nType != CSecureRule::srExternal ) { m_pQueue.RemoveHead(); continue; } CString strPath = pRule->GetContentWords(); if ( strPath.GetLength() < 6 ) { m_pQueue.RemoveHead(); continue; } CString strCommentBase = pRule->m_sComment; if ( strCommentBase.IsEmpty() ) strCommentBase = _T("• %u"); else if ( strCommentBase.ReverseFind( _T('•') ) >= 0 ) strCommentBase = strCommentBase.Left( strCommentBase.ReverseFind( _T('•') ) + 1 ) + _T(" %u"); else strCommentBase += _T(" • %u"); if ( strPath[1] != _T(':') ) strPath = Settings.General.DataPath + strPath; CFile pFile; if ( ! pFile.Open( (LPCTSTR)strPath.GetBuffer(), CFile::modeRead ) ) { m_pQueue.RemoveHead(); continue; } const BYTE nIndex = Security.SetRuleIndex( pRule ); try { CBuffer pBuffer; const DWORD nLength = pFile.GetLength(); pBuffer.EnsureBuffer( nLength ); pBuffer.m_nLength = nLength; pFile.Read( pBuffer.m_pBuffer, nLength ); pFile.Close(); // Format: Delineated Lists CString strLine, strURN; DWORD nCount = 0; int nPos; //TIMER_START while ( pBuffer.ReadLine( strLine ) && IsThreadEnabled() && pRule ) { strLine.TrimRight(); if ( strLine.GetLength() < 7 ) continue; // Blank/Invalid line if ( strLine[ 0 ] == '#' ) { if ( strLine[ strLine.GetLength() - 1 ] == _T(':') && strLine.Find( _T("urn:") ) > 0 ) strURN = strLine.Mid( strLine.Find( _T("urn:") ) ); // Default "# urn:type:" continue; // Comment line } if ( strLine[ 0 ] < '0' || strLine[ 0 ] > 'z' ) // Whitespace/Chars continue; // Invalid line if ( ++nCount % 10 == 0 ) { if ( pRule->m_sComment.IsEmpty() ) strCommentBase = _T("• %u"); else if ( pRule->m_sComment.ReverseFind( _T('•') ) < 0 ) strCommentBase = pRule->m_sComment + _T(" • %u"); pRule->m_sComment.Format( strCommentBase, nCount ); Sleep( 1 ); // Limit CPU } // Hashes: if ( ( ! strURN.IsEmpty() && strLine.Find( _T('.'), 5 ) < 0 ) || StartsWith( strLine, _PT("urn:") ) ) { nPos = strLine.FindOneOf( _T(" \t") ); if ( nPos > 0 ) strLine.Truncate( nPos ); // Trim at whitespace (remove any trailing comments) if ( ! strURN.IsEmpty() && ! StartsWith( strLine, _PT("urn:") ) ) strLine = strURN + strLine; // Default "urn:type:" prepended if ( strLine.GetLength() > 35 ) Security.SetHashMap( strLine, nIndex ); else nCount--; continue; } // IPs: nPos = strLine.ReverseFind( _T(':') ); if ( nPos > 0 ) strLine = strLine.Mid( nPos + 1 ); // Remove leading comment for some formats nPos = strLine.FindOneOf( _T(" \t") ); if ( nPos > 0 ) strLine.Truncate( nPos ); // Trim at whitespace (remove any trailing comments) if ( strLine.GetLength() < 7 || strLine.Find( _T('.') ) < 1 ) { nCount--; continue; } nPos = strLine.Find( _T('-') ); // Possible Range if ( nPos < 0 ) // Single IP { Security.SetAddressMap( IPStringToDWORD( strLine, TRUE ), nIndex ); continue; } CString strFirst = strLine.Left( nPos ); CString strLast = strLine.Mid( nPos + 1 ); if ( strFirst == strLast ) { Security.SetAddressMap( IPStringToDWORD( strLine, TRUE ), nIndex ); continue; } // inet_addr( CT2CA( (LPCTSTR)strLast ) DWORD nFirst = IPStringToDWORD( strFirst, FALSE ); DWORD nLast = IPStringToDWORD( strLast, FALSE ); if ( nFirst < 10 || nFirst >= 0xE0000000 ) // 0 or "0.0." or "224-255" continue; // Redundant/Invalid //if ( Network.IsReserved( (IN_ADDR*)nFirst ) ) // Crash //if ( StartsWith( strFirst, _PT("0.0") ) || // StartsWith( strFirst, _PT("6.0") ) || // StartsWith( strFirst, _PT("7.0") ) || // StartsWith( strFirst, _PT("11.0") ) || // StartsWith( strFirst, _PT("55.0") ) || // StartsWith( strFirst, _PT("127.0") ) ) // continue; // Redundant for ( DWORD nRange = Settings.Security.ListRangeLimit ; nFirst <= nLast && nRange ; nFirst++, nRange-- ) { Security.SetAddressMap( htonl( nFirst ), nIndex ); // Reverse host-byte order } } if ( pRule ) pRule->m_sComment.Format( strCommentBase, nCount ); // Final update PostMainWndMessage( WM_SANITY_CHECK ); //TIMER_STOP } catch ( CException* pException ) { if ( pFile.m_hFile != CFile::hFileNull ) pFile.Close(); // File is still open so close it pException->Delete(); } m_pQueue.RemoveHead(); // Done } Exit(); Wakeup(); Sleep( 5000 ); // Recheck if ( ! m_pQueue.GetCount() ) // && IsThreadEnabled() { CQuickLock oLock( Security.m_pSection ); Security.m_Cache.clear(); PostMainWndMessage( WM_SANITY_CHECK ); } }