Browse Source

Fixed bug where only one of multiple source header directives with the same source header definition would be recognized. The fix was to improve the comparator function for HeaderFinderPattern so that it included context. Prior to that only one source header definition would be recognized because the ordinal is always 0 for source headers. As a result, only the first context could be registered.

Refactored HeaderFinder::CheckContent() to improve the coding style and make use of a switch().

Corrected a bug in HeaderFinder::CheckContent that would allow a header forced source IP to be set multiple times. Now it will only be set when the first event where all of the conditions are satisfied. Bug was that the test that the source had already been set was looking at the source IP which is actually never set until the actual message scan begins (after header directives have already been evaluated).

Changed SNFMulti revision to 16.


git-svn-id: https://svn.microneil.com/svn/SNFMulti/trunk@34 dc71a809-1921-45c4-985c-09c81d0142d9
wx
madscientist 13 years ago
parent
commit
9c5d58d399
3 changed files with 67 additions and 44 deletions
  1. 1
    1
      SNFMulti.cpp
  2. 63
    43
      snf_HeaderFinder.cpp
  3. 3
    0
      snf_HeaderFinder.inline.hpp

+ 1
- 1
SNFMulti.cpp View File

@@ -23,7 +23,7 @@ using namespace std;

//// Version Info

const char* SNF_ENGINE_VERSION = "SNFMulti Engine Version 3.0.15 Build: " __DATE__ " " __TIME__;
const char* SNF_ENGINE_VERSION = "SNFMulti Engine Version 3.0.16 Build: " __DATE__ " " __TIME__;

//// Script Caller Methods


+ 63
- 43
snf_HeaderFinder.cpp View File

@@ -25,51 +25,71 @@ HeaderFinder::HeaderFinder(
Directives(0) { // Zero the composite result.
UnfoldHeaders(); // Unfold the headers.
}

void HeaderFinder::CheckContent(string& Header, const HeaderFinderPattern& P) { // Check for a match in the header.
if(string::npos != Header.find(P.Contains, P.Header.length())) { // If we find the required contents:

/*** if/else laddar - too complex for switch ***/

if(
HeaderDirectiveBypass == P.Directive || // If this is a bypass directive or
HeaderDirectiveWhite == P.Directive // a white header directive:
) {
Directives |= P.Directive; // Add the flags to our output.
} else

if(HeaderDirectiveDrillDown == P.Directive) { // If this is a DrillDown rule
ScanData->drillPastOrdinal(P.Ordinal); // mark the IP DrillDown flag.
Directives |= P.Directive; // Add the flags to our output.
} else

if(HeaderDirectiveContext == P.Directive) { // If this is a context activation
ActivatedContexts.insert(P.Context); // header then activate the context.
Directives |= P.Directive; // Add the flags to our output.
} else

if( // Are we forcing the message source?
HeaderDirectiveSource == P.Directive && // If we matched a source directive and
false == ScanData->FoundSourceIP() && // the source is not already set and
ActivatedContexts.end() != ActivatedContexts.find(P.Context) // and the source context is active then
) { // we set the source from this header.
// Extract the IP from the header.

const string digits = "0123456789"; // These are valid digits.
unsigned int IPStart =
Header.find_first_of(digits, P.Header.length()); // Find the first digit in the header.
if(string::npos == IPStart) return; // If we don't find it we're done.
const string ipchars = ".0123456789"; // These are valid IP characters.
unsigned int IPEnd = Header.find_first_not_of(ipchars, IPStart); // Find the end of the IP.
if(string::npos == IPEnd) IPEnd = Header.length(); // Correct for end of string cases.
ScanData->HeaderDirectiveSourceIP( // Extract the IP from the header and
Header.substr(IPStart, (IPEnd - IPStart)) // expose it to the calling scanner.
);
Directives |= P.Directive; // Add the flags to our output.
}
}
IP4Address extractIPFromSourceHeader(string& Header) { // Return first IP found in header.
const string Digits = "0123456789";
unsigned int EndOfName = Header.find_first_of(":");
unsigned int StartOfIP = Header.find_first_of(Digits, EndOfName);
const string IPCharacters = ".0123456789";
unsigned int EndOfIP = Header.find_first_not_of(IPCharacters, StartOfIP);
bool NoExtraCharactersAfterIP = (string::npos == EndOfIP);
if(NoExtraCharactersAfterIP) EndOfIP = Header.length();
unsigned int IPLength = EndOfIP - StartOfIP;
IP4Address ExtractedIP = Header.substr(StartOfIP, IPLength);
return ExtractedIP;
}

void HeaderFinder::CheckContent(string& Header, const HeaderFinderPattern& P) { // Check for a match in the header.
bool HeaderContainsFinderPattern = (
string::npos != Header.find(P.Contains, P.Header.length())
);
if(HeaderContainsFinderPattern) {

switch(P.Directive) {
case HeaderDirectiveBypass:
case HeaderDirectiveWhite: {
Directives |= P.Directive; // Add the flags to our output.
break;
}
case HeaderDirectiveDrillDown: {
ScanData->drillPastOrdinal(P.Ordinal); // Mark the IP DrillDown flag.
Directives |= P.Directive; // Add the flags to our output.
break;
}
case HeaderDirectiveContext: {
ActivatedContexts.insert(P.Context); // Activate the context.
Directives |= P.Directive; // Add the flags to our output.
break;
}
case HeaderDirectiveSource: {
bool HeaderDirectiveSourceIPNotSet = (
0UL == ScanData->HeaderDirectiveSourceIP()
);
bool SourceContextActive = (
ActivatedContexts.end() != ActivatedContexts.find(P.Context)
);
if(HeaderDirectiveSourceIPNotSet && SourceContextActive) {
ScanData->HeaderDirectiveSourceIP(
extractIPFromSourceHeader(Header)
);
Directives |= P.Directive; // Add the flags to our output.
}
break;
}
}
}
}


void HeaderFinder::MatchHeaders(string& Header) { // Check that the header matches.
if(0 >= Header.length()) return; // If there's nothing to look at, done!
HeaderFinderPattern Key; // We will need a handy key.

+ 3
- 0
snf_HeaderFinder.inline.hpp View File

@@ -14,6 +14,9 @@ inline const bool HeaderFinderPattern::operator<(const HeaderFinderPattern& R) c
if(Ordinal == R.Ordinal) { // If the Ordinal == then
if(Contains < R.Contains) { // check the Contains. If it is < then
return true; // true!
} else
if(Context < R.Context) {
return true;
}
}
}

Loading…
Cancel
Save