|
|
@@ -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. |