Browse Source

finish up namespace tidy to get a clean build

master
Pete McNeil 4 years ago
parent
commit
43d297c8bd
6 changed files with 606 additions and 595 deletions
  1. 118
    114
      SNFMulti.cpp
  2. 190
    191
      SNFMulti.hpp
  3. 225
    221
      snfLOGmgr.cpp
  4. 48
    44
      snfNETmgr.cpp
  5. 16
    16
      snfNETmgr.hpp
  6. 9
    9
      snf_HeaderFinder.cpp

+ 118
- 114
SNFMulti.cpp View File

// SNFMulti.cpp // SNFMulti.cpp
// //
// (C) Copyright 2006 - 2009 ARM Research Labs, LLC
// (C) Copyright 2006 - 2020 ARM Research Labs, LLC
// See www.armresearch.com for the copyright terms. // See www.armresearch.com for the copyright terms.
// //
// 20060121_M // 20060121_M


//// Script Caller Methods //// Script Caller Methods


const ThreadType ScriptCaller::Type("Script Caller"); // Script caller thread type mnemonic.
const cd::ThreadType ScriptCaller::Type("Script Caller"); // Script caller thread type mnemonic.


const ThreadState ScriptCaller::CallingSystem("In system()"); // Script caller "CallingSystem" state.
const ThreadState ScriptCaller::PendingGuardTime("Guard Time"); // Script caller "GuardTime" state.
const ThreadState ScriptCaller::StandingBy("Standby"); // Script caller "Standby" state.
const ThreadState ScriptCaller::Disabled("Disabled"); // State when unable to run.
const cd::ThreadState ScriptCaller::CallingSystem("In system()"); // Script caller "CallingSystem" state.
const cd::ThreadState ScriptCaller::PendingGuardTime("Guard Time"); // Script caller "GuardTime" state.
const cd::ThreadState ScriptCaller::StandingBy("Standby"); // Script caller "Standby" state.
const cd::ThreadState ScriptCaller::Disabled("Disabled"); // State when unable to run.




const int ScriptGuardDefault = 180000; // 3 Minute Default Guard Time. const int ScriptGuardDefault = 180000; // 3 Minute Default Guard Time.


ScriptCaller::ScriptCaller(string S) : // Script caller constructor (with name).
ScriptCaller::ScriptCaller(std::string S) : // Script caller constructor (with name).
Thread(ScriptCaller::Type, S), // Set up the thread type and name. Thread(ScriptCaller::Type, S), // Set up the thread type and name.
GuardTimer(ScriptGuardDefault), // Initialize the guard time. GuardTimer(ScriptGuardDefault), // Initialize the guard time.
GoFlag(false), // Not ready to go yet. GoFlag(false), // Not ready to go yet.


ScriptCaller::~ScriptCaller() { // Destructor. ScriptCaller::~ScriptCaller() { // Destructor.
DieFlag = true; // Set the die flag. DieFlag = true; // Set the die flag.
Sleeper WaitATic(1000); // One second sleeper.
cd::Sleeper WaitATic(1000); // One second sleeper.
for(int x = 10; x > 0; x--) { // We don't join, we might get stuck. for(int x = 10; x > 0; x--) { // We don't join, we might get stuck.
if(false == isRunning()) break; // If we're still running then wait if(false == isRunning()) break; // If we're still running then wait
WaitATic(); // up to 10 seconds, then just exit. WaitATic(); // up to 10 seconds, then just exit.
} // If the thread is stuck it will } // If the thread is stuck it will
} // just get closed. } // just get closed.


string ScriptCaller::ScriptToRun() { // Safely grab the SystemCallText.
ScopeMutex Freeze(MyMutex); // Protect the string.
std::string ScriptCaller::ScriptToRun() { // Safely grab the SystemCallText.
cd::ScopeMutex Freeze(MyMutex); // Protect the string.
return SystemCallText; // Grab a copy of the text. return SystemCallText; // Grab a copy of the text.
} }


bool ScriptCaller::hasGuardExpired() { // True if guard time has expired. bool ScriptCaller::hasGuardExpired() { // True if guard time has expired.
ScopeMutex Freeze(MyMutex); // Protect the timer.
cd::ScopeMutex Freeze(MyMutex); // Protect the timer.
return GuardTimer.isExpired(); // If it has expired we're true. return GuardTimer.isExpired(); // If it has expired we're true.
} }


void ScriptCaller::SystemCall(string S) { // Set the SystemCall text.
ScopeMutex Freeze(MyMutex); // Protect the string object.
void ScriptCaller::SystemCall(std::string S) { // Set the SystemCall text.
cd::ScopeMutex Freeze(MyMutex); // Protect the string object.
SystemCallText = S; // Set it's data. SystemCallText = S; // Set it's data.
} }


const int MinimumGuardTime = 60000; // Minimum Guard Time 1 minute. const int MinimumGuardTime = 60000; // Minimum Guard Time 1 minute.
void ScriptCaller::GuardTime(int T) { // Set the Guard Time. void ScriptCaller::GuardTime(int T) { // Set the Guard Time.
if(MinimumGuardTime > T) T = MinimumGuardTime; // Enforce our lower limit. if(MinimumGuardTime > T) T = MinimumGuardTime; // Enforce our lower limit.
ScopeMutex Freeze(MyMutex); // Protect the Guard Timer.
cd::ScopeMutex Freeze(MyMutex); // Protect the Guard Timer.
GuardTimer.setDuration(T); // Set the duration. GuardTimer.setDuration(T); // Set the duration.
GuardTimer.restart(); // Restart the timer. GuardTimer.restart(); // Restart the timer.
} }
} }


void ScriptCaller::myTask() { // Safely call system() when triggered. void ScriptCaller::myTask() { // Safely call system() when triggered.
Sleeper WaitATic(1000); // One second sleeper.
cd::Sleeper WaitATic(1000); // One second sleeper.
while(false == DieFlag) { // While it's not time to die: while(false == DieFlag) { // While it's not time to die:
WaitATic(); // Pause for 1 sec each round. WaitATic(); // Pause for 1 sec each round.
string ScriptThisRound = ScriptToRun(); // Grab the current script.
std::string ScriptThisRound = ScriptToRun(); // Grab the current script.
if(0 < ScriptToRun().length()) { // If script text is defined and if(0 < ScriptToRun().length()) { // If script text is defined and
if(true == GoFlag) { // If GoFlag is triggered and if(true == GoFlag) { // If GoFlag is triggered and
if(hasGuardExpired()) { // Guard time is expired: if(hasGuardExpired()) { // Guard time is expired:


// How to get timestamps on critical files. // How to get timestamps on critical files.


time_t getFileTimestamp(string FileName) {
time_t getFileTimestamp(std::string FileName) {
struct stat FileNameStat; // First we need a stat buffer. struct stat FileNameStat; // First we need a stat buffer.
if(0 != stat(FileName.c_str(), &FileNameStat)) { // If we can't get the stat we if(0 != stat(FileName.c_str(), &FileNameStat)) { // If we can't get the stat we
return 0; // will return 0; return 0; // will return 0;
} }
} }


const string snfReloadContext = "--RELOADING--"; // Context for info and error logs.
const std::string snfReloadContext = "--RELOADING--"; // Context for info and error logs.


void snf_Reloader::myTask() { // How do we do this refresh thing? void snf_Reloader::myTask() { // How do we do this refresh thing?
Sleeper WaitATic(1000); // Wait a second between checks.
cd::Sleeper WaitATic(1000); // Wait a second between checks.
while(!TimeToStop) { // While it's not time to stop: while(!TimeToStop) { // While it's not time to stop:


if( if(
} }
} }


const ThreadType snf_Reloader::Type("snf_Reloader"); // The thread's type.
const cd::ThreadType snf_Reloader::Type("snf_Reloader"); // The thread's type.


snf_Reloader::snf_Reloader(snf_RulebaseHandler& R) : // When we are created, we snf_Reloader::snf_Reloader(snf_RulebaseHandler& R) : // When we are created, we
Thread(snf_Reloader::Type, "Reloader"), // brand and name our thread. Thread(snf_Reloader::Type, "Reloader"), // brand and name our thread.


cd::RuntimeCheck FileUTCGoodTimestampLength("SNFMulti.cpp:FileUTC snprintf(...) == CorrectTimestampLength"); cd::RuntimeCheck FileUTCGoodTimestampLength("SNFMulti.cpp:FileUTC snprintf(...) == CorrectTimestampLength");


string FileUTC(string FileName) { // Gets a files UTC.
std::string FileUTC(std::string FileName) { // Gets a files UTC.
struct stat FileNameStat; // First we need a stat buffer. struct stat FileNameStat; // First we need a stat buffer.
string t; // We also need a Timestamp holder.
std::string t; // We also need a Timestamp holder.
if(0 != stat(FileName.c_str(), &FileNameStat)) { // If we can't get the stat we if(0 != stat(FileName.c_str(), &FileNameStat)) { // If we can't get the stat we
t.append("00000000000000"); return t; // will return all zeroz to t.append("00000000000000"); return t; // will return all zeroz to
} // make sure we should get the file. } // make sure we should get the file.
RefreshInProgress = false; // we are no longer "in refresh" RefreshInProgress = false; // we are no longer "in refresh"
throw ConfigurationError("_snf_LoadNewRulebase() MyCFGmgr.load() failed"); // throw the Configuration exception. throw ConfigurationError("_snf_LoadNewRulebase() MyCFGmgr.load() failed"); // throw the Configuration exception.
} }
string RuleFilePath = MyCFGmgr.RuleFilePath(); // Get our rulebase file path and our
string SecurityKey = MyCFGmgr.SecurityKey(); // security key from the CFG manager.
std::string RuleFilePath = MyCFGmgr.RuleFilePath(); // Get our rulebase file path and our
std::string SecurityKey = MyCFGmgr.SecurityKey(); // security key from the CFG manager.
if(0>=RuleFilePath.length()) { // If we don't have a path, we're hosed. if(0>=RuleFilePath.length()) { // If we don't have a path, we're hosed.
RefreshInProgress = false; // We are no longer "in refresh" RefreshInProgress = false; // We are no longer "in refresh"
throw FileError("_snf_LoadNewRulebase() Zero length RuleFilePath"); // Can't load a RB file with no path! throw FileError("_snf_LoadNewRulebase() Zero length RuleFilePath"); // Can't load a RB file with no path!


/**** This section needs work ****/ /**** This section needs work ****/
try { try {
string IgnoreListPath = CFGData.paths_workspace_path;
std::string IgnoreListPath = CFGData.paths_workspace_path;
IgnoreListPath.append("GBUdbIgnoreList.txt"); IgnoreListPath.append("GBUdbIgnoreList.txt");
if(0 == MyGBUdb.readIgnoreList(IgnoreListPath.c_str())) // We must have at least 1 IP listed. if(0 == MyGBUdb.readIgnoreList(IgnoreListPath.c_str())) // We must have at least 1 IP listed.
throw ConfigurationError( throw ConfigurationError(
try { try {
AutoRefresh(false); // Stop AutoRefresh if it's on. AutoRefresh(false); // Stop AutoRefresh if it's on.
} }
catch(exception& e) { throw; } // Rethrow good exceptions.
catch(const std::exception& e) { throw e; } // Rethrow good exceptions.
catch(...) { throw Panic("snf_RulebaseHandler::close() AutoRefresh(false) panic!"); } // Panic blank exceptions. catch(...) { throw Panic("snf_RulebaseHandler::close() AutoRefresh(false) panic!"); } // Panic blank exceptions.


try { try {
MyXCImgr.stop(); // Stop the XCI manager. MyXCImgr.stop(); // Stop the XCI manager.
} }
catch(exception& e) { throw; } // Rethrow good exceptions.
catch(const std::exception& e) { throw e; } // Rethrow good exceptions.
catch(...) { throw Panic("snf_RulebaseHandler::close() MyXCImgr.stop() panic!"); } // Panic blank exceptions. catch(...) { throw Panic("snf_RulebaseHandler::close() MyXCImgr.stop() panic!"); } // Panic blank exceptions.


if(isBusy() || 0<CurrentCount || 0<ReferenceCount) { // Check that there is no activity. if(isBusy() || 0<CurrentCount || 0<ReferenceCount) { // Check that there is no activity.
try { try {
MyLOGmgr.stop(); // Stop the LOG manager. MyLOGmgr.stop(); // Stop the LOG manager.
} }
catch(exception& e) { throw; } // Rethrow good exceptions.
catch(const std::exception& e) { throw e; } // Rethrow good exceptions.
catch(...) { throw Panic("snf_RulebaseHandler::close() MyLOGmgr.stop() panic!"); } // Panic blank exceptions. catch(...) { throw Panic("snf_RulebaseHandler::close() MyLOGmgr.stop() panic!"); } // Panic blank exceptions.


try { try {
MyNETmgr.stop(); // Stop the NET manager. MyNETmgr.stop(); // Stop the NET manager.
} }
catch(exception& e) { throw; } // Rethrow good exceptions.
catch(const std::exception& e) { throw e; } // Rethrow good exceptions.
catch(...) { throw Panic("snf_RulebaseHandler::close() MyNETmgr.stop() panic!"); } // Panic blank exceptions. catch(...) { throw Panic("snf_RulebaseHandler::close() MyNETmgr.stop() panic!"); } // Panic blank exceptions.


try { try {
MyGBUdbmgr.stop(); // Stop the GBUdb manager. MyGBUdbmgr.stop(); // Stop the GBUdb manager.
} }
catch(exception& e) { throw; } // Rethrow good exceptions.
catch(const std::exception& e) { throw e; } // Rethrow good exceptions.
catch(...) { throw Panic("snf_RulebaseHandler::close() MyGBUdbmgr.stop() panic!"); } // Panic blank exceptions. catch(...) { throw Panic("snf_RulebaseHandler::close() MyGBUdbmgr.stop() panic!"); } // Panic blank exceptions.


try { try {
if(NULL!=Rulebase) {delete Rulebase; Rulebase=NULL;} // If we have a Rulebase destroy it. if(NULL!=Rulebase) {delete Rulebase; Rulebase=NULL;} // If we have a Rulebase destroy it.
} }
catch(exception& e) { throw; } // Rethrow good exceptions.
catch(const std::exception& e) { throw e; } // Rethrow good exceptions.
catch(...) { throw Panic("snf_RulebaseHandler::close() delete Rulebase panic!"); } // Panic blank exceptions. catch(...) { throw Panic("snf_RulebaseHandler::close() delete Rulebase panic!"); } // Panic blank exceptions.


try { try {
if(NULL!=OldRulebase) {delete OldRulebase; OldRulebase=NULL;} // Shouldn't happen, but just in case. if(NULL!=OldRulebase) {delete OldRulebase; OldRulebase=NULL;} // Shouldn't happen, but just in case.
} }
catch(exception& e) { throw; } // Rethrow good exceptions.
catch(const std::exception& e) { throw e; } // Rethrow good exceptions.
catch(...) { throw Panic("snf_RulebaseHandler::close() delete OldRulebase panic!"); } // Panic blank exceptions. catch(...) { throw Panic("snf_RulebaseHandler::close() delete OldRulebase panic!"); } // Panic blank exceptions.
} }


// the operation goes out of scope the configuration packet drop()s with it. // the operation goes out of scope the configuration packet drop()s with it.


void snf_RulebaseHandler::grab(snfCFGPacket& CP) { // Activate this Rulebase. void snf_RulebaseHandler::grab(snfCFGPacket& CP) { // Activate this Rulebase.
ScopeMutex HoldStillPlease(MyMutex); // Lock the rulebase until we're done.
cd::ScopeMutex HoldStillPlease(MyMutex); // Lock the rulebase until we're done.
CurrentCount++; // Boost the count for myself. CurrentCount++; // Boost the count for myself.
CP.MyTokenMatrix = Rulebase; // Grab the current rulebase. CP.MyTokenMatrix = Rulebase; // Grab the current rulebase.
CP.MyCFGData = MyCFGmgr.ActiveConfiguration(); // Grab the active configuration. CP.MyCFGData = MyCFGmgr.ActiveConfiguration(); // Grab the active configuration.
void snf_RulebaseHandler::drop(snfCFGPacket& CP) { // Deactiveate this Rulebase. void snf_RulebaseHandler::drop(snfCFGPacket& CP) { // Deactiveate this Rulebase.
const TokenMatrix* t = CP.MyTokenMatrix; // Grab the token matrix pointer. const TokenMatrix* t = CP.MyTokenMatrix; // Grab the token matrix pointer.
CP.MyCFGData = NULL; // Null the configuration pointer. CP.MyCFGData = NULL; // Null the configuration pointer.
ScopeMutex HoldStillPlease(MyMutex); // Lock the rulebase until we're done.
cd::ScopeMutex HoldStillPlease(MyMutex); // Lock the rulebase until we're done.
if(t==Rulebase) { // If we're dropping the current rulebase if(t==Rulebase) { // If we're dropping the current rulebase
CurrentCount--; // then reduce the current count. CurrentCount--; // then reduce the current count.
} else // If not that then... } else // If not that then...
// will have a consistent result based on their last grab(). // will have a consistent result based on their last grab().


void snf_RulebaseHandler::addRulePanic(int RuleID) { // Add a rule panic id dynamically. void snf_RulebaseHandler::addRulePanic(int RuleID) { // Add a rule panic id dynamically.
ScopeMutex JustMe(MyMutex); // Freeze the rulebase while we adjust
cd::ScopeMutex JustMe(MyMutex); // Freeze the rulebase while we adjust
MyCFGmgr.ActiveConfiguration() // the active configuration to MyCFGmgr.ActiveConfiguration() // the active configuration to
->RulePanicHandler.IntegerSet.insert(RuleID); // insert the new rule panic ruleid. ->RulePanicHandler.IntegerSet.insert(RuleID); // insert the new rule panic ruleid.
} // When we're done, unlock and move on. } // When we're done, unlock and move on.
return I; // Return the processed record. return I; // Return the processed record.
} }


void snf_RulebaseHandler::logThisIPTest(IPTestRecord& I, string Action) { // Log an IP test result & action.
void snf_RulebaseHandler::logThisIPTest(IPTestRecord& I, std::string Action) { // Log an IP test result & action.
MyLOGmgr.logThisIPTest(I, Action); MyLOGmgr.logThisIPTest(I, Action);
} }


void snf_RulebaseHandler::logThisError( // Log an error message. void snf_RulebaseHandler::logThisError( // Log an error message.
string ContextName, int Code, string Text
std::string ContextName, int Code, std::string Text
) { ) {
MyLOGmgr.logThisError(ContextName, Code, Text); MyLOGmgr.logThisError(ContextName, Code, Text);
} }


void snf_RulebaseHandler::logThisInfo( // Log an informational message. void snf_RulebaseHandler::logThisInfo( // Log an informational message.
string ContextName, int Code, string Text
std::string ContextName, int Code, std::string Text
) { ) {
MyLOGmgr.logThisInfo(ContextName, Code, Text); MyLOGmgr.logThisInfo(ContextName, Code, Text);
} }


string snf_RulebaseHandler::PlatformVersion(string NewPlatformVersion) { // Set platform version info.
std::string snf_RulebaseHandler::PlatformVersion(std::string NewPlatformVersion) { // Set platform version info.
return MyLOGmgr.PlatformVersion(NewPlatformVersion); return MyLOGmgr.PlatformVersion(NewPlatformVersion);
} }


string snf_RulebaseHandler::PlatformVersion() { // Get platform version info.
std::string snf_RulebaseHandler::PlatformVersion() { // Get platform version info.
return MyLOGmgr.PlatformVersion(); return MyLOGmgr.PlatformVersion();
} }


string snf_RulebaseHandler::PlatformConfiguration() { // Get platform configuration.
ScopeMutex LockAndGrab(MyMutex); // Freeze things for a moment and
std::string snf_RulebaseHandler::PlatformConfiguration() { // Get platform configuration.
cd::ScopeMutex LockAndGrab(MyMutex); // Freeze things for a moment and
return MyCFGmgr.ActiveConfiguration()->PlatformElementContents; // copy the platform configuration. return MyCFGmgr.ActiveConfiguration()->PlatformElementContents; // copy the platform configuration.
} }


string snf_RulebaseHandler::EngineVersion() { // Get engine version info.
std::string snf_RulebaseHandler::EngineVersion() { // Get engine version info.
return MyLOGmgr.EngineVersion(); return MyLOGmgr.EngineVersion();
} }


void snf_RulebaseHandler:: void snf_RulebaseHandler::
XCIServerCommandHandler(snfXCIServerCommandHandler& XCH) { // Registers a new XCI Srvr Cmd handler. XCIServerCommandHandler(snfXCIServerCommandHandler& XCH) { // Registers a new XCI Srvr Cmd handler.
ScopeMutex ThereCanBeOnlyOne(XCIServerCommandMutex); // Serialize access to this resource.
cd::ScopeMutex ThereCanBeOnlyOne(XCIServerCommandMutex); // Serialize access to this resource.
myXCIServerCommandHandler = &XCH; // Assign the new handler as provided. myXCIServerCommandHandler = &XCH; // Assign the new handler as provided.
} }


string snf_RulebaseHandler::processXCIServerCommandRequest(snf_xci& X) { // Handle a parsed XCI Srvr Cmd request.
ScopeMutex ThereCanBeOnlyOne(XCIServerCommandMutex); // Serialize access to this resource.
std::string snf_RulebaseHandler::processXCIServerCommandRequest(snf_xci& X) { // Handle a parsed XCI Srvr Cmd request.
cd::ScopeMutex ThereCanBeOnlyOne(XCIServerCommandMutex); // Serialize access to this resource.
if(0 == myXCIServerCommandHandler) { // If we don't have a handler then if(0 == myXCIServerCommandHandler) { // If we don't have a handler then
snfXCIServerCommandHandler H; // create a base handler and snfXCIServerCommandHandler H; // create a base handler and
return H.processXCIRequest(X); // return it's default response. return H.processXCIRequest(X); // return it's default response.
// always considered the source and second if they are in the GBUdb ignore list // always considered the source and second if they are in the GBUdb ignore list
// then GBUdb training bypass is established. // then GBUdb training bypass is established.


string& snf_IPTestEngine::test(string& input, string& output) { // Perform IP lookups and put IPs into ScanData.
std::string& snf_IPTestEngine::test(std::string& input, std::string& output) { // Perform IP lookups and put IPs into ScanData.


if(NULL == Lookup || NULL == ScanData) { // If we are not set up properly then we if(NULL == Lookup || NULL == ScanData) { // If we are not set up properly then we
output = "{IPTest Config Error}"; // will return an error string. output = "{IPTest Config Error}"; // will return an error string.


try { // If we're out of IP records, no analysis. try { // If we're out of IP records, no analysis.
IPScanRecord& I = ScanData->newIPScanRecord(); // Grab a new IP scan record and IPScanRecord& I = ScanData->newIPScanRecord(); // Grab a new IP scan record and
IP4Address IP = input; // Convert the string to an IP.
cd::IP4Address IP = input; // Convert the string to an IP.


// Identify forced Source IP addresses // Identify forced Source IP addresses






output = "{"; // Next we start to build our IP data insert. output = "{"; // Next we start to build our IP data insert.
ostringstream S; // We will use a string stream for formatting.
std::ostringstream S; // We will use a string stream for formatting.
switch(R.Flag()) { // Identify the flag data for this IP. switch(R.Flag()) { // Identify the flag data for this IP.
case Good: S << "Good "; break; case Good: S << "Good "; break;
case Bad: S << "Bad "; break; case Bad: S << "Bad "; break;
// a bad outcome. // a bad outcome.


bool snf_RulebaseHandler::testXHDRInjectOn() { bool snf_RulebaseHandler::testXHDRInjectOn() {
ScopeMutex HoldStillPlease(MyMutex); // Lock the rulebase until we're done.
cd::ScopeMutex HoldStillPlease(MyMutex); // Lock the rulebase until we're done.
snfCFGData* myCFG = MyCFGmgr.ActiveConfiguration(); // Grab the active configuration. snfCFGData* myCFG = MyCFGmgr.ActiveConfiguration(); // Grab the active configuration.
bool myXHDRInjectOnFlag = (LogOutputMode_Inject == myCFG->XHDROutput_Mode); // True if output mode is inject. bool myXHDRInjectOnFlag = (LogOutputMode_Inject == myCFG->XHDROutput_Mode); // True if output mode is inject.
return myXHDRInjectOnFlag; // return the result. return myXHDRInjectOnFlag; // return the result.
} }


int snf_EngineHandler::scanMessageFile( // Scan this message file. int snf_EngineHandler::scanMessageFile( // Scan this message file.
const string MessageFilePath, // -- this is the file path (and id)
const std::string MessageFilePath, // -- this is the file path (and id)
const int MessageSetupTime, // -- setup time already used. const int MessageSetupTime, // -- setup time already used.
const IP4Address MessageSource // -- message source IP (for injection).
const cd::IP4Address MessageSource // -- message source IP (for injection).
) { ) {


Timer AdditionalSetupTime;
ScopeMutex DoingAFileScan(FileScan); // Protect MyScanData @ this entry.
cd::Timer AdditionalSetupTime;
cd::ScopeMutex DoingAFileScan(FileScan); // Protect MyScanData @ this entry.


// Preliminary setup. Clearing the ScanData resets the ReadyToClear flag // Preliminary setup. Clearing the ScanData resets the ReadyToClear flag
// and allows us to set some data for more accurate tracking and so that if // and allows us to set some data for more accurate tracking and so that if
// Now that the preliminaries are established we can begin our work. // Now that the preliminaries are established we can begin our work.


int MessageFileSize = 0; // Here will be the size of it. int MessageFileSize = 0; // Here will be the size of it.
ifstream MessageFile; // Here will be our input file.
std::ifstream MessageFile; // Here will be our input file.
MessageFile.exceptions( // It will throw exceptions for MessageFile.exceptions( // It will throw exceptions for
ifstream::eofbit | ifstream::failbit | ifstream::badbit // these unwanted events.
std::ifstream::eofbit | std::ifstream::failbit | std::ifstream::badbit // these unwanted events.
); );


try { // Try opening the message file. try { // Try opening the message file.
MessageFile.open(MessageFilePath.c_str(), ios::in | ios::binary); // Open the file, binary mode.
MessageFile.seekg(0, ios::end); // Find the end of the file,
MessageFile.open(MessageFilePath.c_str(),
std::ios::in | std::ios::binary); // Open the file, binary mode.

MessageFile.seekg(0, std::ios::end); // Find the end of the file,
MessageFileSize = MessageFile.tellg(); // read that position as the size, MessageFileSize = MessageFile.tellg(); // read that position as the size,
MessageFile.seekg(0, ios::beg); // then go back to the beginning.
MessageFile.seekg(0, std::ios::beg); // then go back to the beginning.
MyScanData.ScanSize = MessageFileSize; // Capture the message file size. MyScanData.ScanSize = MessageFileSize; // Capture the message file size.
} }
catch(...) { // Trouble? Throw FileError. catch(...) { // Trouble? Throw FileError.
bool isXHeaderInjectionOn = MyRulebase->testXHDRInjectOn(); bool isXHeaderInjectionOn = MyRulebase->testXHDRInjectOn();
bool noNeedToReadFullFile = (false == isXHeaderInjectionOn); bool noNeedToReadFullFile = (false == isXHeaderInjectionOn);
if(noNeedToReadFullFile) { if(noNeedToReadFullFile) {
MessageFileSize = min(MessageFileSize, snf_ScanHorizon);
MessageFileSize = std::min(MessageFileSize, snf_ScanHorizon);
} }


vector<unsigned char> MessageBuffer; // Allocate a buffer and size
std::vector<unsigned char> MessageBuffer; // Allocate a buffer and size
try { MessageBuffer.resize(MessageFileSize, 0); } // it to fit the message. try { MessageBuffer.resize(MessageFileSize, 0); } // it to fit the message.
catch(...) { // Trouble? Throw AllocationError. catch(...) { // Trouble? Throw AllocationError.
MyRulebase->MyLOGmgr.logThisError( // Log the error. MyRulebase->MyLOGmgr.logThisError( // Log the error.


XHDRInjStage = "Open Temp File"; // Update our process monitor. XHDRInjStage = "Open Temp File"; // Update our process monitor.


string TempFileName = MessageFilePath; // Prepare a temp file name
std::string TempFileName = MessageFilePath; // Prepare a temp file name
TempFileName.append(".tmp"); // based on the message file. TempFileName.append(".tmp"); // based on the message file.


ofstream TempFile; // Here will be our temp file.
TempFile.exceptions(ofstream::failbit | ofstream::badbit); // It will throw these exceptions.
TempFile.open(TempFileName.c_str(), ios::binary | ios::trunc); // Open and truncate the file.
std::ofstream TempFile; // Here will be our temp file.
TempFile.exceptions(std::ofstream::failbit | std::ofstream::badbit); // It will throw these exceptions.
TempFile.open(TempFileName.c_str(),
std::ios::binary | std::ios::trunc); // Open and truncate the file.


// If our insert point is the top of the message we'll skip this. // If our insert point is the top of the message we'll skip this.


XHDRInjStage = "XHDR <CR><LF> to <LF>"; XHDRInjStage = "XHDR <CR><LF> to <LF>";


if(true == UseLFOnly) { // If we are using <LF> only: if(true == UseLFOnly) { // If we are using <LF> only:
string ReworkedHeaders = ""; // Make a new string and rework
std::string ReworkedHeaders = ""; // Make a new string and rework
for( // our headers. for( // our headers.
string::iterator iS = MyScanData.XHDRsText.begin(); // Run through the headers one
std::string::iterator iS = MyScanData.XHDRsText.begin(); // Run through the headers one
iS != MyScanData.XHDRsText.end(); iS++ // byte at a time. iS != MyScanData.XHDRsText.end(); iS++ // byte at a time.
) { ) {
if('\r' != (*iS)) ReworkedHeaders.push_back(*iS); // Strip out any <CR> chars. if('\r' != (*iS)) ReworkedHeaders.push_back(*iS); // Strip out any <CR> chars.


TempFile.close(); // Close the file (flushing it). TempFile.close(); // Close the file (flushing it).


Sleeper PauseBeforeRetry(300); // Delay to use between retries.
cd::Sleeper PauseBeforeRetry(300); // Delay to use between retries.


XHDRInjStage = "Drop Msg"; // Update our process monitor. XHDRInjStage = "Drop Msg"; // Update our process monitor.


} }
} }
catch(XHDRError& e) { // For full XHDRError exceptions. catch(XHDRError& e) { // For full XHDRError exceptions.
string ERROR_MSG_XHDRi = "ERROR_MSG_XHDRi: "; // Format the XHDRInj error msg.
std::string ERROR_MSG_XHDRi = "ERROR_MSG_XHDRi: "; // Format the XHDRInj error msg.
ERROR_MSG_XHDRi.append(XHDRInjStage); ERROR_MSG_XHDRi.append(XHDRInjStage);
ERROR_MSG_XHDRi.append(" "); ERROR_MSG_XHDRi.append(" ");
ERROR_MSG_XHDRi.append(e.what()); ERROR_MSG_XHDRi.append(e.what());
); );
throw; // Rethrow any XHDRError exceptions. throw; // Rethrow any XHDRError exceptions.
} }
catch(exception& e) { // For ordinary runtime exceptions.
string ERROR_MSG_XHDRi = "ERROR_MSG_XHDRi: "; // Format the XHDRInj error msg.
catch(const std::exception& e) { // For ordinary runtime exceptions.
std::string ERROR_MSG_XHDRi = "ERROR_MSG_XHDRi: "; // Format the XHDRInj error msg.
ERROR_MSG_XHDRi.append(XHDRInjStage); ERROR_MSG_XHDRi.append(XHDRInjStage);
ERROR_MSG_XHDRi.append(" "); ERROR_MSG_XHDRi.append(" ");
ERROR_MSG_XHDRi.append(e.what()); ERROR_MSG_XHDRi.append(e.what());
throw XHDRError(ERROR_MSG_XHDRi); // Rethrow as XHDRError exceptions. throw XHDRError(ERROR_MSG_XHDRi); // Rethrow as XHDRError exceptions.
} }
catch(...) { // If we encounter a problem then catch(...) { // If we encounter a problem then
string ERROR_MSG_XHDRi = "ERROR_MSG_XHDRi: "; // Format the XHDRInj error msg.
std::string ERROR_MSG_XHDRi = "ERROR_MSG_XHDRi: "; // Format the XHDRInj error msg.
ERROR_MSG_XHDRi.append(XHDRInjStage); ERROR_MSG_XHDRi.append(XHDRInjStage);
MyRulebase->MyLOGmgr.logThisError( // Log the error. MyRulebase->MyLOGmgr.logThisError( // Log the error.
MyScanData, "scanMessageFile().xhdr.inject", MyScanData, "scanMessageFile().xhdr.inject",
snf_ERROR_MSG_FILE, ERROR_MSG_XHDRi snf_ERROR_MSG_FILE, ERROR_MSG_XHDRi
); );
string XHDRError_msg = "Message Rewrite Failed: "; // Format our throw message with
std::string XHDRError_msg = "Message Rewrite Failed: "; // Format our throw message with
XHDRError_msg.append(XHDRInjStage); // our detailed stage data and XHDRError_msg.append(XHDRInjStage); // our detailed stage data and
throw XHDRError(XHDRError_msg); // throw our special exception. throw XHDRError(XHDRError_msg); // throw our special exception.
} }


if(MyScanData.XHeaderFileOn) { if(MyScanData.XHeaderFileOn) {
try { try {
ofstream XHDRFile; // Output file will be XHDRFile.
XHDRFile.exceptions(ofstream::failbit | ofstream::badbit); // These events will throw exceptions.
string XHDRFileName = MessageFilePath; // Build the XHDR file name by adding
XHDRFileName.append(".xhdr"); // .xhdr to the message file name.
XHDRFile.open(XHDRFileName.c_str(), ios::binary | ios::trunc); // Open (and truncate) the file.
std::ofstream XHDRFile; // Output file will be XHDRFile.
XHDRFile.exceptions(std::ofstream::failbit | std::ofstream::badbit); // These events will throw exceptions.
std::string XHDRFileName = MessageFilePath; // Build the XHDR file name by adding
XHDRFileName.append(".xhdr"); // .xhdr to the message file name.
XHDRFile.open(XHDRFileName.c_str(),
std::ios::binary | std::ios::trunc); // Open (and truncate) the file.
XHDRFile << MyScanData.XHDRsText; // Spit out the XHDRs. XHDRFile << MyScanData.XHDRsText; // Spit out the XHDRs.
XHDRFile.close(); // All done. XHDRFile.close(); // All done.
} }
return ScanResultCode; // Return the actual result, of course. return ScanResultCode; // Return the actual result, of course.
} }


string snf_EngineHandler::extractMessageID( // Find and return the first Message-ID
std::string snf_EngineHandler::extractMessageID( // Find and return the first Message-ID
const unsigned char* Msg, // Input the Message buffer to search const unsigned char* Msg, // Input the Message buffer to search
const int Len // and the length of the buffer. const int Len // and the length of the buffer.
) { ) {
string ExtractedID = ""; // Start with an empty string.
std::string ExtractedID = ""; // Start with an empty string.
bool FoundID = false; // Haven't found it yet. bool FoundID = false; // Haven't found it yet.
int C = 0; // Cursor position. int C = 0; // Cursor position.
while(!FoundID && (C < (Len - 12))) { // Loop through the Msg looking for while(!FoundID && (C < (Len - 12))) { // Loop through the Msg looking for
M.endex = R->MatchEndPosition; M.endex = R->MatchEndPosition;
} }


void snf_SaccadesHandler::applySaccades(EvaluationMatrix* Scanner, vector<unsigned char>& Data) {
void snf_SaccadesHandler::applySaccades(EvaluationMatrix* Scanner, std::vector<unsigned char>& Data) {
if(NULL == Scanner) return; if(NULL == Scanner) return;


bool isTimeToPeek = (0 >= TimeToPeekCounter); bool isTimeToPeek = (0 >= TimeToPeekCounter);
--TimeToPeekCounter; --TimeToPeekCounter;
} }


vector<saccade> Saccades = grabSaccades();
for(vector<saccade>::iterator i = Saccades.begin(); i != Saccades.end(); i++) {
std::vector<saccade> Saccades = grabSaccades();
for(std::vector<saccade>::iterator i = Saccades.begin(); i != Saccades.end(); i++) {
const saccade& s = (*i); const saccade& s = (*i);
if(s.start >= Data.size()) break; if(s.start >= Data.size()) break;
Scanner->evaluateSegment(Data, s.start, s.finish); Scanner->evaluateSegment(Data, s.start, s.finish);
void snf_SaccadesHandler::learnMatches(MatchRecord* Matches) { void snf_SaccadesHandler::learnMatches(MatchRecord* Matches) {
if(NULL == Matches) return; if(NULL == Matches) return;


vector<saccade> MatchesToLearn;
std::vector<saccade> MatchesToLearn;
saccade WatchForHeaderWhiteRules(0, AlwaysScanLength); saccade WatchForHeaderWhiteRules(0, AlwaysScanLength);
MatchesToLearn.push_back(WatchForHeaderWhiteRules); MatchesToLearn.push_back(WatchForHeaderWhiteRules);


int snf_EngineHandler::scanMessage( // Scan this message (in buffer). int snf_EngineHandler::scanMessage( // Scan this message (in buffer).
const unsigned char* inputMessageBuffer, // -- this is the message buffer. const unsigned char* inputMessageBuffer, // -- this is the message buffer.
const int inputMessageLength, // -- this is the length of the buffer. const int inputMessageLength, // -- this is the length of the buffer.
const string MessageName, // -- this is the message identifier.
const std::string MessageName, // -- this is the message identifier.
const int MessageSetupTime, // -- setup time used (for logging). const int MessageSetupTime, // -- setup time used (for logging).
const IP4Address MessageSource // -- message source IP (for injection).
const cd::IP4Address MessageSource // -- message source IP (for injection).
) { ) {


ScopeTimer ScanTimeCapture(MyScanData.ScanTime); // Start the scan time clock.
cd::ScopeTimer ScanTimeCapture(MyScanData.ScanTime); // Start the scan time clock.


unsigned char* MessageBuffer = NULL; // Explicitly initialize these two unsigned char* MessageBuffer = NULL; // Explicitly initialize these two
int MessageLength = 0; // so the compiler will be happy. int MessageLength = 0; // so the compiler will be happy.


// Protect this engine - only one scan at a time per EngineHandler ;-) // Protect this engine - only one scan at a time per EngineHandler ;-)


ScopeMutex ScannerIsBusy(MyMutex); // Serialize this...
cd::ScopeMutex ScannerIsBusy(MyMutex); // Serialize this...


// Preliminary job setup. // Preliminary job setup.




// Set up our filter chain. // Set up our filter chain.


stringstream PrependedHeaders; // Use this to prepend X-Headers.
std::stringstream PrependedHeaders; // Use this to prepend X-Headers.
FilterChainCBFR IU(MessageBuffer, MessageLength, PrependedHeaders); // Set up the filter chain. FilterChainCBFR IU(MessageBuffer, MessageLength, PrependedHeaders); // Set up the filter chain.
FilterChainHeaderAnalysis IV(&IU, MyIPTestEngine); // Include header analysis. FilterChainHeaderAnalysis IV(&IU, MyIPTestEngine); // Include header analysis.
FilterChainBase64 IW(&IV); // Include Base64 decoding. FilterChainBase64 IW(&IV); // Include Base64 decoding.
if(0UL != MyScanData.CallerForcedSourceIP()) { // If the caller forced the source IP: if(0UL != MyScanData.CallerForcedSourceIP()) { // If the caller forced the source IP:
PrependedHeaders // Make a phantom Received header PrependedHeaders // Make a phantom Received header
<< "Received: Caller.Forced.Source.IP [" // showing that the caller forced << "Received: Caller.Forced.Source.IP [" // showing that the caller forced
<< (string) MyScanData.CallerForcedSourceIP() << "]\n"; // the source IP.
<< (std::string) MyScanData.CallerForcedSourceIP() << "]\n"; // the source IP.
} else } else
// If not forced by the caller but a // If not forced by the caller but a
if(0UL != MyScanData.HeaderDirectiveSourceIP()) { // header directive forced the source IP: if(0UL != MyScanData.HeaderDirectiveSourceIP()) { // header directive forced the source IP:
PrependedHeaders // Make a phantom Received header PrependedHeaders // Make a phantom Received header
<< "Received: Header.Directive.Source.IP [" // showing that a header directive << "Received: Header.Directive.Source.IP [" // showing that a header directive
<< (string) MyScanData.HeaderDirectiveSourceIP() << "]\n"; // established the source IP.
<< (std::string) MyScanData.HeaderDirectiveSourceIP() << "]\n"; // established the source IP.
} }


// Most of the time we will extract the source IP the normal way. // Most of the time we will extract the source IP the normal way.
); );
throw; throw;
} }
catch(exception& e) { // Other exceptions.
catch(const std::exception& e) { // Other exceptions.
MyRulebase->MyLOGmgr.logThisError( // Log the error. MyRulebase->MyLOGmgr.logThisError( // Log the error.
MyScanData, "scanMessage()", MyScanData, "scanMessage()",
snf_ERROR_UNKNOWN, "ERROR_EXCEPTION" snf_ERROR_UNKNOWN, "ERROR_EXCEPTION"
// GBUdb training is enabled. // GBUdb training is enabled.


bool discoveredNewIP = false; bool discoveredNewIP = false;
IP4Address theSourceIP = MyScanData.SourceIPRecord().IP;
cd::IP4Address theSourceIP = MyScanData.SourceIPRecord().IP;


switch(ScanResultType) { // Evaluate the scan result. switch(ScanResultType) { // Evaluate the scan result.
case NoPattern: // On no pattern (benefit of doubt) or case NoPattern: // On no pattern (benefit of doubt) or




int snf_EngineHandler::getResults(snf_match* MatchBuffer){ // Get the next match buffer. int snf_EngineHandler::getResults(snf_match* MatchBuffer){ // Get the next match buffer.
ScopeMutex SerializeThis(MyMutex); // Serialize this...
cd::ScopeMutex SerializeThis(MyMutex); // Serialize this...
if(NULL == MatchBuffer) { // If we were given the reset signal if(NULL == MatchBuffer) { // If we were given the reset signal
MyScanData.MatchRecordsCursor = MyScanData.MatchRecords.begin(); // Move the cursor to the beginning MyScanData.MatchRecordsCursor = MyScanData.MatchRecords.begin(); // Move the cursor to the beginning
MyScanData.MatchRecordsDelivered = 0; // and reset the delivered count. MyScanData.MatchRecordsDelivered = 0; // and reset the delivered count.
} }


int snf_EngineHandler::getDepth(){ // Get the scan depth. int snf_EngineHandler::getDepth(){ // Get the scan depth.
ScopeMutex SerializeThis(MyMutex); // Protect our reading.
cd::ScopeMutex SerializeThis(MyMutex); // Protect our reading.
return MyScanData.ScanDepth; // Return the latest scan depth. return MyScanData.ScanDepth; // Return the latest scan depth.
} }


const string snf_EngineHandler::getClassicLog() { // Get classic log entries for last scan.
ScopeMutex SerializeThis(MyMutex); // Serialize this...
const std::string snf_EngineHandler::getClassicLog() { // Get classic log entries for last scan.
cd::ScopeMutex SerializeThis(MyMutex); // Serialize this...
return MyScanData.ClassicLogText; // Return the log text. return MyScanData.ClassicLogText; // Return the log text.
} }


const string snf_EngineHandler::getXMLLog() { // Get XML log entries or last scan.
ScopeMutex SerializeThis(MyMutex); // Serialize this...
const std::string snf_EngineHandler::getXMLLog() { // Get XML log entries or last scan.
cd::ScopeMutex SerializeThis(MyMutex); // Serialize this...
return MyScanData.XMLLogText; // Return the log text. return MyScanData.XMLLogText; // Return the log text.
} }


const string snf_EngineHandler::getXHDRs() { // Get XHDRs for last scan.
ScopeMutex SerializeThis(MyMutex); // Serialize this...
const std::string snf_EngineHandler::getXHDRs() { // Get XHDRs for last scan.
cd::ScopeMutex SerializeThis(MyMutex); // Serialize this...
return MyScanData.XHDRsText; // Return the XHeaders text. return MyScanData.XHDRsText; // Return the XHeaders text.
} }


{ RulebaseScan.unlock(); throw FileError(e.what()); } { RulebaseScan.unlock(); throw FileError(e.what()); }
catch(snf_RulebaseHandler::Busy& e) catch(snf_RulebaseHandler::Busy& e)
{ RulebaseScan.unlock(); throw Panic(e.what()); } // Wasn't busy above!! Shoudn't be here!!! { RulebaseScan.unlock(); throw Panic(e.what()); } // Wasn't busy above!! Shoudn't be here!!!
catch(exception& e)
{ RulebaseScan.unlock(); throw; }
catch(const std::exception& e)
{ RulebaseScan.unlock(); throw e; }
catch(...) { catch(...) {
RulebaseScan.unlock(); RulebaseScan.unlock();
throw Panic("snf_MultiEngineHandler::OpenRulebase() ???"); throw Panic("snf_MultiEngineHandler::OpenRulebase() ???");
catch(snf_RulebaseHandler::Busy& e) { catch(snf_RulebaseHandler::Busy& e) {
throw Busy(e.what()); throw Busy(e.what());
} }
catch(exception& e) {
throw;
catch(const std::exception& e) {
throw e;
} }
catch(...) { catch(...) {
throw Panic("snf_MultiEngineHandler::RefreshRulebase() ???"); throw Panic("snf_MultiEngineHandler::RefreshRulebase() ???");
catch(snf_RulebaseHandler::Busy& e) { // A busy throw we can understand. catch(snf_RulebaseHandler::Busy& e) { // A busy throw we can understand.
RulebaseScan.unlock(); throw Busy(e.what()); RulebaseScan.unlock(); throw Busy(e.what());
} }
catch(exception& e) { // Other exceptions? rethrow.
RulebaseScan.unlock(); throw;
catch(const std::exception& e) { // Other exceptions? rethrow.
RulebaseScan.unlock(); throw e;
} }
catch(...) { // Any other throw is big trouble. catch(...) { // Any other throw is big trouble.
RulebaseScan.unlock(); RulebaseScan.unlock();
{ EngineScan.unlock(); throw AllocationError(e.what()); } { EngineScan.unlock(); throw AllocationError(e.what()); }
catch(snf_EngineHandler::Busy& e) catch(snf_EngineHandler::Busy& e)
{ EngineScan.unlock(); throw Panic(e.what()); } // Not busy above should not be busy now!!! { EngineScan.unlock(); throw Panic(e.what()); } // Not busy above should not be busy now!!!
catch(exception& e) {
catch(const std::exception& e) {
EngineScan.unlock(); EngineScan.unlock();
throw;
throw e;
} }
catch(...) { catch(...) {
EngineScan.unlock(); EngineScan.unlock();
{ EngineScan.unlock(); throw AllocationError(e.what()); } { EngineScan.unlock(); throw AllocationError(e.what()); }
catch(snf_EngineHandler::Busy& e) catch(snf_EngineHandler::Busy& e)
{ EngineScan.unlock(); throw Busy(e.what()); } { EngineScan.unlock(); throw Busy(e.what()); }
catch(exception& e) {
catch(const std::exception& e) {
EngineScan.unlock(); EngineScan.unlock();
throw;
throw e;
} }
catch(...) { catch(...) {
EngineScan.unlock(); EngineScan.unlock();
throw AllocationError(e.what()); throw AllocationError(e.what());
} }
catch(snf_EngineHandler::Busy& e) { throw Busy(e.what()); } catch(snf_EngineHandler::Busy& e) { throw Busy(e.what()); }
catch(exception& e) { throw; }
catch(const std::exception& e) { throw e; }
catch(...) { throw Panic("snf_MultiEngineHandler::Scan() ???"); } catch(...) { throw Panic("snf_MultiEngineHandler::Scan() ???"); }
return ScanResult; // Return the results. return ScanResult; // Return the results.
} }
throw AllocationError(e.what()); throw AllocationError(e.what());
} }
catch(snf_EngineHandler::Busy& e) { throw Busy(e.what()); } catch(snf_EngineHandler::Busy& e) { throw Busy(e.what()); }
catch(exception& e) { throw; }
catch(const std::exception& e) { throw e; }
catch(...) { throw Panic("snf_MultiEngineHandler::getResults() ???"); } catch(...) { throw Panic("snf_MultiEngineHandler::getResults() ???"); }


return ResultCount; // Return the results. return ResultCount; // Return the results.
throw AllocationError(e.what()); throw AllocationError(e.what());
} }
catch(snf_EngineHandler::Busy& e) { throw Busy(e.what()); } catch(snf_EngineHandler::Busy& e) { throw Busy(e.what()); }
catch(exception& e) { throw; }
catch(const std::exception& e) { throw e; }
catch(...) { throw Panic("snf_MultiEngineHandler::getDepth() ???"); } catch(...) { throw Panic("snf_MultiEngineHandler::getDepth() ???"); }


return DepthResult; // Return the results. return DepthResult; // Return the results.

+ 190
- 191
SNFMulti.hpp View File

// SNFMulti.hpp // SNFMulti.hpp
// //
// (C) Copyright 2006 - 2009 ARM Research Labs, LLC.
// (C) Copyright 2006 - 2020 ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms. // See www.armresearch.com for the copyright terms.
// //
// 20060121_M // 20060121_M
// rulebase each time they restart. The grabbing and swapping in of new rulebases is // rulebase each time they restart. The grabbing and swapping in of new rulebases is
// a very short critical section. // a very short critical section.


#ifndef _ARM_SNFMulti
#define _ARM_SNFMulti
#pragma once


#include <stdexcept> #include <stdexcept>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <ctime> #include <ctime>
#include <string>
#include <string>
#include "../CodeDweller/faults.hpp" #include "../CodeDweller/faults.hpp"
#include "../CodeDweller/threading.hpp" #include "../CodeDweller/threading.hpp"
#include "GBUdb.hpp" #include "GBUdb.hpp"
#include "snfLOGmgr.hpp" #include "snfLOGmgr.hpp"
#include "snfNETmgr.hpp" #include "snfNETmgr.hpp"
#include "snfGBUdbmgr.hpp" #include "snfGBUdbmgr.hpp"
#include "snfXCImgr.hpp"
#include "snf_saccades.hpp"
#include "snfXCImgr.hpp"
#include "snf_saccades.hpp"
#include <cassert> #include <cassert>


namespace cd = codedweller;

extern const char* SNF_ENGINE_VERSION; extern const char* SNF_ENGINE_VERSION;


// snf Result Code Constants // snf Result Code Constants
TokenMatrix* MyTokenMatrix; // We combine the current token matrix TokenMatrix* MyTokenMatrix; // We combine the current token matrix
snfCFGData* MyCFGData; // and the current cfg data for each scan. snfCFGData* MyCFGData; // and the current cfg data for each scan.


set<int> RulePanics; // Set of known rule panic IDs.
std::set<int> RulePanics; // Set of known rule panic IDs.


public: public:
snfCFGPacket(snf_RulebaseHandler* R); // Constructor grab()s the Rulebase. snfCFGPacket(snf_RulebaseHandler* R); // Constructor grab()s the Rulebase.
bool isRulePanic(int R); // Test for a rule panic. bool isRulePanic(int R); // Test for a rule panic.
}; };


class ScriptCaller : private Thread { // Calls system() in separate thread.
class ScriptCaller : private cd::Thread { // Calls system() in separate thread.
private: private:
Mutex MyMutex; // Protects internal data.
string SystemCallText; // Text to send to system().
Timeout GuardTimer; // Guard time between triggers.
cd::Mutex MyMutex; // Protects internal data.
std::string SystemCallText; // Text to send to system().
cd::Timeout GuardTimer; // Guard time between triggers.
volatile bool GoFlag; // Go flag true when triggered. volatile bool GoFlag; // Go flag true when triggered.
volatile bool DieFlag; // Die flag when it's time to leave. volatile bool DieFlag; // Die flag when it's time to leave.


string ScriptToRun(); // Safely grab the script.
std::string ScriptToRun(); // Safely grab the script.
bool hasGuardExpired(); // True if guard time has expired. bool hasGuardExpired(); // True if guard time has expired.
void myTask(); // Thread task overload. void myTask(); // Thread task overload.


volatile int myLastResult; // Last result of system() call. volatile int myLastResult; // Last result of system() call.


public: public:
ScriptCaller(string Name); // Constructor.
ScriptCaller(std::string Name); // Constructor.
~ScriptCaller(); // Destructor. ~ScriptCaller(); // Destructor.


void SystemCall(string S); // Set system call text.
void SystemCall(std::string S); // Set system call text.
void GuardTime(int T); // Change guard time. void GuardTime(int T); // Change guard time.
void trigger(); // Trigger if possible. void trigger(); // Trigger if possible.
int LastResult(); // Return myLastResult. int LastResult(); // Return myLastResult.


const static ThreadType Type; // The thread's type.
const static cd::ThreadType Type; // The thread's type.


const static ThreadState CallingSystem; // State when in system() call.
const static ThreadState PendingGuardTime; // State when waiting for guard time.
const static ThreadState StandingBy; // State when waiting around.
const static ThreadState Disabled; // State when unable to run.
const static cd::ThreadState CallingSystem; // State when in system() call.
const static cd::ThreadState PendingGuardTime; // State when waiting for guard time.
const static cd::ThreadState StandingBy; // State when waiting around.
const static cd::ThreadState Disabled; // State when unable to run.
}; };


class snf_Reloader : private Thread { // Rulebase maintenance thread.
class snf_Reloader : private cd::Thread { // Rulebase maintenance thread.
private: private:


snf_RulebaseHandler& MyRulebase; // We know our rulebase. snf_RulebaseHandler& MyRulebase; // We know our rulebase.
bool TimeToStop; // We know if it's time to stop. bool TimeToStop; // We know if it's time to stop.


string RulebaseFileCheckName; // We keep track of these files.
string ConfigFileCheckName;
string IgnoreListCheckFileName;
std::string RulebaseFileCheckName; // We keep track of these files.
std::string ConfigFileCheckName;
std::string IgnoreListCheckFileName;
time_t RulebaseFileTimestamp; // We watch their timestamps. time_t RulebaseFileTimestamp; // We watch their timestamps.
time_t ConfigurationTimestamp; time_t ConfigurationTimestamp;
time_t IgnoreListTimestamp; time_t IgnoreListTimestamp;
snf_Reloader(snf_RulebaseHandler& R); // Setup takes some work. snf_Reloader(snf_RulebaseHandler& R); // Setup takes some work.
~snf_Reloader(); // Tear down takes some work. ~snf_Reloader(); // Tear down takes some work.


const static ThreadType Type; // The thread's type.
const static cd::ThreadType Type; // The thread's type.


}; };




private: private:


Mutex MyMutex; // This handler's mutex.
cd::Mutex MyMutex; // This handler's mutex.


snf_Reloader* MyReloader; // Reloader engine (when in use). snf_Reloader* MyReloader; // Reloader engine (when in use).


int volatile ReferenceCount; // Associated scanners count. int volatile ReferenceCount; // Associated scanners count.


snfCFGData* volatile Configuration; // Configuration for this handler. snfCFGData* volatile Configuration; // Configuration for this handler.
TokenMatrix* volatile Rulebase; // Rulebase for this handler.
int volatile CurrentCount; // Active current scanners count.
TokenMatrix* volatile Rulebase; // Rulebase for this handler.
int volatile CurrentCount; // Active current scanners count.


TokenMatrix* volatile OldRulebase; // Retiring rulebase holder.
int volatile RetiringCount; // Active retiring scanners count.
TokenMatrix* volatile OldRulebase; // Retiring rulebase holder.
int volatile RetiringCount; // Active retiring scanners count.


bool volatile RefreshInProgress; // Flag for locking the refresh process.
bool volatile RefreshInProgress; // Flag for locking the refresh process.


int volatile MyGeneration; // Generation (reload) number.
int volatile MyGeneration; // Generation (reload) number.


void _snf_LoadNewRulebase(); // Internal function to load new rulebase.
void _snf_LoadNewRulebase(); // Internal function to load new rulebase.


Mutex XCIServerCommandMutex; // XCI Server Command Serializer.
cd::Mutex XCIServerCommandMutex; // XCI Server Command Serializer.
snfXCIServerCommandHandler* myXCIServerCommandHandler; // ptr to Installed Srv Cmd Handler. snfXCIServerCommandHandler* myXCIServerCommandHandler; // ptr to Installed Srv Cmd Handler.


void grab(snfCFGPacket& CP); // Activate this Rulebase for a scan. void grab(snfCFGPacket& CP); // Activate this Rulebase for a scan.
void drop(snfCFGPacket& CP); // Deactiveate this Rulebase after it.
void drop(snfCFGPacket& CP); // Deactiveate this Rulebase after it.
public: public:


class ConfigurationError : public runtime_error { // When the configuration won't load.
public: ConfigurationError(const string& w):runtime_error(w) {}
class ConfigurationError : public std::runtime_error { // When the configuration won't load.
public: ConfigurationError(const std::string& w):runtime_error(w) {}
}; };
class FileError : public runtime_error { // Exception: rulebase file won't load.
public: FileError(const string& w):runtime_error(w) {}
class FileError : public std::runtime_error { // Exception: rulebase file won't load.
public: FileError(const std::string& w):runtime_error(w) {}
}; };
class AuthenticationError : public runtime_error { // Exception when authentication fails.
public: AuthenticationError(const string& w):runtime_error(w) {}
class AuthenticationError : public std::runtime_error { // Exception when authentication fails.
public: AuthenticationError(const std::string& w):runtime_error(w) {}
}; };
class IgnoreListError : public runtime_error { // When the ignore list won't load.
public: IgnoreListError(const string& w):runtime_error(w) {}
class IgnoreListError : public std::runtime_error { // When the ignore list won't load.
public: IgnoreListError(const std::string& w):runtime_error(w) {}
}; };
class AllocationError : public runtime_error { // Exception when we can't allocate something.
public: AllocationError(const string& w):runtime_error(w) {}
class AllocationError : public std::runtime_error { // Exception when we can't allocate something.
public: AllocationError(const std::string& w):runtime_error(w) {}
}; };
class Busy : public runtime_error { // Exception when there is a collision.
public: Busy(const string& w):runtime_error(w) {}
class Busy : public std::runtime_error { // Exception when there is a collision.
public: Busy(const std::string& w):runtime_error(w) {}
}; };
class Panic : public runtime_error { // Exception when something else happens.
public: Panic(const string& w):runtime_error(w) {}
class Panic : public std::runtime_error { // Exception when something else happens.
public: Panic(const std::string& w):runtime_error(w) {}
}; };


//// Plugin Components. //// Plugin Components.
OldRulebase(NULL), OldRulebase(NULL),
RetiringCount(0), RetiringCount(0),
RefreshInProgress(false), RefreshInProgress(false),
MyGeneration(0),
MyGeneration(0),
myXCIServerCommandHandler(0){ myXCIServerCommandHandler(0){
MyNETmgr.linkLOGmgr(MyLOGmgr); // Link the NET manager to the LOGmgr. MyNETmgr.linkLOGmgr(MyLOGmgr); // Link the NET manager to the LOGmgr.
MyNETmgr.linkGBUdbmgr(MyGBUdbmgr); // Link the NET manager to the GBUdbmgr. MyNETmgr.linkGBUdbmgr(MyGBUdbmgr); // Link the NET manager to the GBUdbmgr.


int Generation(); // Returns the generation number. int Generation(); // Returns the generation number.


void addRulePanic(int RuleID); // Synchronously add a RulePanic.
void addRulePanic(int RuleID); // Synchronously add a RulePanic.
bool testXHDRInjectOn(); // Safely look ahead at XHDRInjectOn. bool testXHDRInjectOn(); // Safely look ahead at XHDRInjectOn.


IPTestRecord& performIPTest(IPTestRecord& I); // Perform an IP test. IPTestRecord& performIPTest(IPTestRecord& I); // Perform an IP test.
void logThisIPTest(IPTestRecord& I, string Action); // Log an IP test result & action.
void logThisIPTest(IPTestRecord& I, std::string Action); // Log an IP test result & action.


void logThisError(string ContextName, int Code, string Text); // Log an error message.
void logThisInfo(string ContextName, int Code, string Text); // Log an informational message.
string PlatformVersion(string NewPlatformVersion); // Set platform version info.
string PlatformVersion(); // Get platform version info.
string PlatformConfiguration(); // Get platform configuration.
string EngineVersion(); // Get engine version info.
void logThisError(std::string ContextName, int Code, std::string Text); // Log an error message.
void logThisInfo(std::string ContextName, int Code, std::string Text); // Log an informational message.
std::string PlatformVersion(std::string NewPlatformVersion); // Set platform version info.
std::string PlatformVersion(); // Get platform version info.
std::string PlatformConfiguration(); // Get platform configuration.
std::string EngineVersion(); // Get engine version info.


void XCIServerCommandHandler(snfXCIServerCommandHandler& XCH); // Registers a new XCI Srvr Cmd handler. void XCIServerCommandHandler(snfXCIServerCommandHandler& XCH); // Registers a new XCI Srvr Cmd handler.
string processXCIServerCommandRequest(snf_xci& X); // Handle a parsed XCI Srvr Cmd request.
std::string processXCIServerCommandRequest(snf_xci& X); // Handle a parsed XCI Srvr Cmd request.
}; };


// IPTestEngine w/ GBUdb interface. // IPTestEngine w/ GBUdb interface.
void setCFGData(snfCFGData& C); // (Re)Set the config data to use. void setCFGData(snfCFGData& C); // (Re)Set the config data to use.
void setLOGmgr(snfLOGmgr& L); // Setup the LOGmgr to use. void setLOGmgr(snfLOGmgr& L); // Setup the LOGmgr to use.


string& test(string& input, string& output); // Our obligatory test function.
std::string& test(std::string& input, std::string& output); // Our obligatory test function.
};


class snf_SaccadesHandler {
private:
cd::Mutex MyMutex;
saccades_engine MyEngine;

void lockAndLearn(std::vector<saccade>& Matches) {
cd::ScopeMutex SafetyFirst(MyMutex);
MyEngine.learn(Matches);
}

std::vector<saccade> grabSaccades() {
cd::ScopeMutex SafetyFirst(MyMutex);
return MyEngine.recall();
}

int TimeToPeekCounter;
static const int TimeToPeekReset = 32;

public:

static const int AlwaysScanLength = 2048;

snf_SaccadesHandler() :
MyEngine(128),
TimeToPeekCounter(0) {}

void applySaccades(EvaluationMatrix* Scanner, std::vector<unsigned char>& Data);
void learnMatches(MatchRecord* Matches);
};

// How to spot strangers in the IP reputations.

class snf_IPStrangerList {
private:
cd::Mutex myMutex;
std::set<cd::IP4Address> listA;
std::set<cd::IP4Address> listB;
bool usingANotB;
cd::Timeout listExpiration;

std::set<cd::IP4Address>& myActiveList() {
if(usingANotB) return listA;
else return listB;
}

void swapOutOldLists() {
if(listExpiration.isExpired()) {
usingANotB = !usingANotB;
myActiveList().clear();
listExpiration.restart();
}
}

std::set<cd::IP4Address>& myCurrentList() {
swapOutOldLists();
return myActiveList();
}

public:
static const int TwoHours = (2 * (60 * (60 * 1000)));
snf_IPStrangerList() : usingANotB(true), listExpiration(TwoHours) {}

bool isStranger(cd::IP4Address a) {
cd::ScopeMutex JustMe(myMutex);
swapOutOldLists();
bool foundStranger = (0 < listA.count(a)) || (0 < listB.count(a));
return foundStranger;
}

void addStranger(cd::IP4Address a) {
cd::ScopeMutex JustMe(myMutex);
myCurrentList().insert(a);
}
}; };
class snf_SaccadesHandler {
private:
Mutex MyMutex;
saccades_engine MyEngine;
void lockAndLearn(vector<saccade>& Matches) {
ScopeMutex SafetyFirst(MyMutex);
MyEngine.learn(Matches);
}
vector<saccade> grabSaccades() {
ScopeMutex SafetyFirst(MyMutex);
return MyEngine.recall();
}
int TimeToPeekCounter;
static const int TimeToPeekReset = 32;
public:
static const int AlwaysScanLength = 2048;
snf_SaccadesHandler() :
MyEngine(128),
TimeToPeekCounter(0) {}
void applySaccades(EvaluationMatrix* Scanner, vector<unsigned char>& Data);
void learnMatches(MatchRecord* Matches);
};
// How to spot strangers in the IP reputations.

class snf_IPStrangerList {
private:
Mutex myMutex;
set<IP4Address> listA;
set<IP4Address> listB;
bool usingANotB;
Timeout listExpiration;
set<IP4Address>& myActiveList() {
if(usingANotB) return listA;
else return listB;
}
void swapOutOldLists() {
if(listExpiration.isExpired()) {
usingANotB = !usingANotB;
myActiveList().clear();
listExpiration.restart();
}
}
set<IP4Address>& myCurrentList() {
swapOutOldLists();
return myActiveList();
}
public:
static const int TwoHours = (2 * (60 * (60 * 1000)));
snf_IPStrangerList() : usingANotB(true), listExpiration(TwoHours) {}
bool isStranger(IP4Address a) {
ScopeMutex JustMe(myMutex);
swapOutOldLists();
bool foundStranger = (0 < listA.count(a)) || (0 < listB.count(a));
return foundStranger;
}
void addStranger(IP4Address a) {
ScopeMutex JustMe(myMutex);
myCurrentList().insert(a);
}
};

// Here's where we pull it all together. // Here's where we pull it all together.


class snf_EngineHandler { class snf_EngineHandler {


private: private:


Mutex MyMutex; // This handler's mutex.
Mutex FileScan; // File scan entry mutex.
cd::Mutex MyMutex; // This handler's mutex.
cd::Mutex FileScan; // File scan entry mutex.


EvaluationMatrix* volatile CurrentMatrix; // Matrix for the latest scan.
snf_RulebaseHandler* volatile MyRulebase; // My RulebaseHandler.
EvaluationMatrix* volatile CurrentMatrix; // Matrix for the latest scan.
snf_RulebaseHandler* volatile MyRulebase; // My RulebaseHandler.


snfScanData MyScanData; // Local snfScanData record.
snf_IPTestEngine MyIPTestEngine; // Local IP Test Engine.
snfScanData MyScanData; // Local snfScanData record.
snf_IPTestEngine MyIPTestEngine; // Local IP Test Engine.


int ResultsCount; // Count of Match Records for getResults
int ResultsRemaining; // Count of Match Records ahead of cursor.
MatchRecord* FinalResult; // Final (winning) result of the scan.
MatchRecord* ResultCursor; // Current Match Record for getResults.
int ResultsCount; // Count of Match Records for getResults
int ResultsRemaining; // Count of Match Records ahead of cursor.
MatchRecord* FinalResult; // Final (winning) result of the scan.
MatchRecord* ResultCursor; // Current Match Record for getResults.


string extractMessageID(const unsigned char* Msg, const int Len); // Get log safe Message-ID or substitute.
std::string extractMessageID(const unsigned char* Msg, const int Len); // Get log safe Message-ID or substitute.


public: public:


class FileError : public runtime_error { // Exception when a file won't open.
public: FileError(const string& w):runtime_error(w) {}
class FileError : public std::runtime_error { // Exception when a file won't open.
public: FileError(const std::string& w):runtime_error(w) {}
}; };
class XHDRError : public runtime_error { // Exception when XHDR Inject/File fails.
public: XHDRError(const string& w):runtime_error(w) {}
class XHDRError : public std::runtime_error { // Exception when XHDR Inject/File fails.
public: XHDRError(const std::string& w):runtime_error(w) {}
}; };
class BadMatrix : public runtime_error { // Exception out of bounds of matrix.
public: BadMatrix(const string& w):runtime_error(w) {}
class BadMatrix : public std::runtime_error { // Exception out of bounds of matrix.
public: BadMatrix(const std::string& w):runtime_error(w) {}
}; };
class MaxEvals : public runtime_error { // Exception too many evaluators.
public: MaxEvals(const string& w):runtime_error(w) {}
class MaxEvals : public std::runtime_error { // Exception too many evaluators.
public: MaxEvals(const std::string& w):runtime_error(w) {}
}; };
class AllocationError : public runtime_error { // Exception when we can't allocate something.
public: AllocationError(const string& w):runtime_error(w) {}
class AllocationError : public std::runtime_error { // Exception when we can't allocate something.
public: AllocationError(const std::string& w):runtime_error(w) {}
}; };
class Busy : public runtime_error { // Exception when there is a collision.
public: Busy(const string& w):runtime_error(w) {}
class Busy : public std::runtime_error { // Exception when there is a collision.
public: Busy(const std::string& w):runtime_error(w) {}
}; };
class Panic : public runtime_error { // Exception when something else happens.
public: Panic(const string& w):runtime_error(w) {}
class Panic : public std::runtime_error { // Exception when something else happens.
public: Panic(const std::string& w):runtime_error(w) {}
}; };


snf_EngineHandler(): // Initialization is simple. snf_EngineHandler(): // Initialization is simple.
void close(); // Close down the engine. void close(); // Close down the engine.


int scanMessageFile( // Scan this message file. int scanMessageFile( // Scan this message file.
const string MessageFilePath, // -- this is the file (and id)
const std::string MessageFilePath, // -- this is the file (and id)
const int MessageSetupTime = 0, // -- setup time already used. const int MessageSetupTime = 0, // -- setup time already used.
const IP4Address MessageSource = 0UL // -- message source IP (for injection).
const cd::IP4Address MessageSource = 0UL // -- message source IP (for injection).
); );


int scanMessage( // Scan this message.
const unsigned char* MessageBuffer, // -- this is the message buffer.
const int MessageLength, // -- this is the length of the buffer.
const string MessageName = "", // -- this is the message identifier.
int scanMessage( // Scan this message.
const unsigned char* MessageBuffer, // -- this is the message buffer.
const int MessageLength, // -- this is the length of the buffer.
const std::string MessageName = "", // -- this is the message identifier.
const int MessageSetupTime = 0, // -- setup time used (for logging). const int MessageSetupTime = 0, // -- setup time used (for logging).
const IP4Address MessageSource = 0UL // -- message source IP (for injection).
const cd::IP4Address MessageSource = 0UL // -- message source IP (for injection).
); );


int getResults(snf_match* MatchBuffer); // Get the next match buffer.
int getDepth(); // Get the scan depth.
int getResults(snf_match* MatchBuffer); // Get the next match buffer.
int getDepth(); // Get the scan depth.


const string getClassicLog(); // Get classic log entries for last scan.
const string getXMLLog(); // Get XML log entries or last scan.
const string getXHDRs(); // Get XHDRs for last scan.
const std::string getClassicLog(); // Get classic log entries for last scan.
const std::string getXMLLog(); // Get XML log entries or last scan.
const std::string getXHDRs(); // Get XHDRs for last scan.
}; };


// Here's the class that pulls it all together. // Here's the class that pulls it all together.


private: private:


Mutex RulebaseScan; // This handler's mutex.
cd::Mutex RulebaseScan; // This handler's mutex.
int RulebaseCursor; // Next Rulebase to search. int RulebaseCursor; // Next Rulebase to search.
snf_RulebaseHandler RulebaseHandlers[snf_MAX_RULEBASES]; // Array of Rulebase Handlers snf_RulebaseHandler RulebaseHandlers[snf_MAX_RULEBASES]; // Array of Rulebase Handlers


int RoundRulebaseCursor(); // Gets round robin Rulebase handle candidates. int RoundRulebaseCursor(); // Gets round robin Rulebase handle candidates.


Mutex EngineScan; // Serializes searching the Engine list.
cd::Mutex EngineScan; // Serializes searching the Engine list.
int EngineCursor; // Next Engine to search. int EngineCursor; // Next Engine to search.
snf_EngineHandler EngineHandlers[snf_MAX_SCANNERS]; // Array of Engine Handlers snf_EngineHandler EngineHandlers[snf_MAX_SCANNERS]; // Array of Engine Handlers




public: public:


class TooMany : public runtime_error { // Exception when no more handle slots.
public: TooMany(const string& w):runtime_error(w) {}
class TooMany : public std::runtime_error { // Exception when no more handle slots.
public: TooMany(const std::string& w):runtime_error(w) {}
}; };
class FileError : public runtime_error { // Exception when a file won't open.
public: FileError(const string& w):runtime_error(w) {}
class FileError : public std::runtime_error { // Exception when a file won't open.
public: FileError(const std::string& w):runtime_error(w) {}
}; };
class AuthenticationError : public runtime_error { // Exception when authentication fails.
public: AuthenticationError(const string& w):runtime_error(w) {}
class AuthenticationError : public std::runtime_error { // Exception when authentication fails.
public: AuthenticationError(const std::string& w):runtime_error(w) {}
}; };
class AllocationError : public runtime_error { // Exception when we can't allocate something.
public: AllocationError(const string& w):runtime_error(w) {}
class AllocationError : public std::runtime_error { // Exception when we can't allocate something.
public: AllocationError(const std::string& w):runtime_error(w) {}
}; };
class Busy : public runtime_error { // Exception when there is a collision.
public: Busy(const string& w):runtime_error(w) {}
class Busy : public std::runtime_error { // Exception when there is a collision.
public: Busy(const std::string& w):runtime_error(w) {}
}; };
class Panic : public runtime_error { // Exception when something else happens.
public: Panic(const string& w):runtime_error(w) {}
class Panic : public std::runtime_error { // Exception when something else happens.
public: Panic(const std::string& w):runtime_error(w) {}
}; };


snf_MultiEngineHandler(): snf_MultiEngineHandler():
int getDepth(int EngineHandle); int getDepth(int EngineHandle);


}; };

#endif

+ 225
- 221
snfLOGmgr.cpp
File diff suppressed because it is too large
View File


+ 48
- 44
snfNETmgr.cpp View File

const unsigned char* MessageBuffer, // This is the message itself const unsigned char* MessageBuffer, // This is the message itself
int MessageLength // and it is this size. int MessageLength // and it is this size.
) { ) {
string TimeStamp; (*myLOGmgr).Timestamp(TimeStamp); // Grab a timestamp.
ostringstream XML; // Make formatting easier with this.
std::string TimeStamp; (*myLOGmgr).Timestamp(TimeStamp); // Grab a timestamp.
std::ostringstream XML; // Make formatting easier with this.


//-- <sample...> //-- <sample...>


XML << "<sample node=\'" << CFGData.node_licenseid << "\' " XML << "<sample node=\'" << CFGData.node_licenseid << "\' "
<< "time=\'" << TimeStamp << "\' " << "time=\'" << TimeStamp << "\' "
<< "result=\'" << ScanData.CompositeFinalResult << "\'>" << endl;
<< "result=\'" << ScanData.CompositeFinalResult << "\'>" << std::endl;


//-- <ip...> //-- <ip...>


XML << "<ip range=\'"; XML << "<ip range=\'";
string IPRange;
std::string IPRange;
switch(ScanData.SourceIPRange()) { switch(ScanData.SourceIPRange()) {
case Unknown: { IPRange = "Unknown"; break; } // Unknown - not defined. case Unknown: { IPRange = "Unknown"; break; } // Unknown - not defined.
case White: { IPRange = "White"; break; } // This is a good guy. case White: { IPRange = "White"; break; } // This is a good guy.


XML << IPRange << "\' ip=\'" << (std::string) cd::IP4Address(IP.getAddress()) << "\' t=\'"; XML << IPRange << "\' ip=\'" << (std::string) cd::IP4Address(IP.getAddress()) << "\' t=\'";


string IPType;
std::string IPType;
switch(ScanData.SourceIPRecord().GBUdbData.Flag()) { switch(ScanData.SourceIPRecord().GBUdbData.Flag()) {
case Good: { IPType = "Good"; break; } case Good: { IPType = "Good"; break; }
case Bad: { IPType = "Bad"; break; } case Bad: { IPType = "Bad"; break; }


XML << IPType << "\' b=\'" << ScanData.SourceIPRecord().GBUdbData.Bad() XML << IPType << "\' b=\'" << ScanData.SourceIPRecord().GBUdbData.Bad()
<< "\' g=\'" << ScanData.SourceIPRecord().GBUdbData.Good() << "\' g=\'" << ScanData.SourceIPRecord().GBUdbData.Good()
<< "\'/>" << endl;
<< "\'/>" << std::endl;


//-- <match...> as many as needed //-- <match...> as many as needed


if(0 < ScanData.MatchRecords.size()) { // If we have match records - emit them. if(0 < ScanData.MatchRecords.size()) { // If we have match records - emit them.
list<snf_match>::iterator iM; // Grab an iterator.
std::list<snf_match>::iterator iM; // Grab an iterator.
for( // Emit each snf_match entry. for( // Emit each snf_match entry.
iM = ScanData.MatchRecords.begin(); iM = ScanData.MatchRecords.begin();
iM != ScanData.MatchRecords.end(); iM != ScanData.MatchRecords.end();


//-- <msg...> //-- <msg...>


XML << "<msg size=\'" << ScanData.ScanSize << "'>" << endl; // Starting with the msg element.
XML << "<msg size=\'" << ScanData.ScanSize << "'>" << std::endl; // Starting with the msg element.
cd::to_base64 EncodedMessageData( cd::to_base64 EncodedMessageData(
reinterpret_cast<const char*>(MessageBuffer), MessageLength); // Encode the message to base64. reinterpret_cast<const char*>(MessageBuffer), MessageLength); // Encode the message to base64.


for(int l = 0; l < SampleLineLength && i < MessageLength; l++, i++) { // that are a reasonable length. for(int l = 0; l < SampleLineLength && i < MessageLength; l++, i++) { // that are a reasonable length.
XML << EncodedMessageData.at(i); // Emit one character at a time... XML << EncodedMessageData.at(i); // Emit one character at a time...
} // At the end of a reasonable } // At the end of a reasonable
XML << endl; // length we terminate the line.
XML << std::endl; // length we terminate the line.
} }
XML << "</msg>" << endl; // End of the <msg> element.
XML << "</msg>" << std::endl; // End of the <msg> element.


//-- done with the sample! //-- done with the sample!


XML << "</sample>" << endl;
XML << "</sample>" << std::endl;


// Last thing we do is post the formatted string to the buffer. // Last thing we do is post the formatted string to the buffer.
const unsigned int SampleSafetyLimit = 100000; // 100 Kbyte limit on samples. const unsigned int SampleSafetyLimit = 100000; // 100 Kbyte limit on samples.
SamplesBuffer.append(XML.str()); // Append the XML to the buffer. SamplesBuffer.append(XML.str()); // Append the XML to the buffer.
} }


string snfNETmgr::getSamples() { // Synchronized way to get Samples.
std::string snfNETmgr::getSamples() { // Synchronized way to get Samples.
cd::ScopeMutex DoNotDisturb(myMutex); // Lock the mutex to protect our work. cd::ScopeMutex DoNotDisturb(myMutex); // Lock the mutex to protect our work.
string SamplesBatch = SamplesBuffer; // Copy the samples to a new string.
std::string SamplesBatch = SamplesBuffer; // Copy the samples to a new string.
SamplesBuffer.clear(); // Clear the samples buffer. SamplesBuffer.clear(); // Clear the samples buffer.
return SamplesBatch; // Return a batch of Samples. return SamplesBatch; // Return a batch of Samples.
} }


void snfNETmgr::sendReport(const string& S) { // How to send a status report.
void snfNETmgr::sendReport(const std::string& S) { // How to send a status report.
const unsigned int ReportSafetyLimit = 100000; // 100 Kbytes limit on reports. const unsigned int ReportSafetyLimit = 100000; // 100 Kbytes limit on reports.
cd::ScopeMutex DoNotDisturb(myMutex); // Lock the mutex for a moment. cd::ScopeMutex DoNotDisturb(myMutex); // Lock the mutex for a moment.
if(ReportSafetyLimit < ReportsBuffer.length()) // If the reports buffer is full if(ReportSafetyLimit < ReportsBuffer.length()) // If the reports buffer is full
ReportsBuffer.append(S); // Append the report. ReportsBuffer.append(S); // Append the report.
} }


string snfNETmgr::getReports() { // Synchronized way to get Reports.
std::string snfNETmgr::getReports() { // Synchronized way to get Reports.
cd::ScopeMutex DoNotDisturb(myMutex); // Lock the mutex to protect our work. cd::ScopeMutex DoNotDisturb(myMutex); // Lock the mutex to protect our work.
string ReportsBatch = ReportsBuffer; // Copy the reports to a new string.
std::string ReportsBatch = ReportsBuffer; // Copy the reports to a new string.
ReportsBuffer.clear(); // Clear the reports buffer. ReportsBuffer.clear(); // Clear the reports buffer.
return ReportsBatch; // Return a batch of Reports. return ReportsBatch; // Return a batch of Reports.
} }


cd::RuntimeCheck RulebaseUTCGoodTimestampLength("SNFNetmgr.cpp:RulebaseUTC snprintf(...) == CorrectTimestampLength"); cd::RuntimeCheck RulebaseUTCGoodTimestampLength("SNFNetmgr.cpp:RulebaseUTC snprintf(...) == CorrectTimestampLength");


string& snfNETmgr::RulebaseUTC(string& t) { // Gets local rulebase file UTC.
std::string& snfNETmgr::RulebaseUTC(std::string& t) { // Gets local rulebase file UTC.
struct stat RulebaseStat; // First we need a stat buffer. struct stat RulebaseStat; // First we need a stat buffer.
if(0 != stat(RulebaseFilePath.c_str(), &RulebaseStat)) { // If we can't get the stat we if(0 != stat(RulebaseFilePath.c_str(), &RulebaseStat)) { // If we can't get the stat we
t.append("000000000000"); return t; // will return 000000000000 to t.append("000000000000"); return t; // will return 000000000000 to
return t; // and return it to the caller. return t; // and return it to the caller.
} }


unsigned long snfNETmgr::ResolveHostIPFromName(const string& N) { // Host name resolution tool.
unsigned long snfNETmgr::ResolveHostIPFromName(const std::string& N) { // Host name resolution tool.
cd::ScopeMutex OneAtATimePlease(ResolverMutex); // Resolve only one at a time. cd::ScopeMutex OneAtATimePlease(ResolverMutex); // Resolve only one at a time.
unsigned long IP = inet_addr(N.c_str()); // See if it's an IP. unsigned long IP = inet_addr(N.c_str()); // See if it's an IP.
if (INADDR_NONE == IP) { // If it's not an IP resolve it. if (INADDR_NONE == IP) { // If it's not an IP resolve it.
// Sensitivity to this entropy has millisecond resolution. This is a cross- // Sensitivity to this entropy has millisecond resolution. This is a cross-
// platform solution that depends only on our own code ;-) // platform solution that depends only on our own code ;-)


void snfNETmgr::evolvePad(string Entropy) { // Add entropy and evolve.
void snfNETmgr::evolvePad(std::string Entropy) { // Add entropy and evolve.
cd::ScopeMutex OneAtATimePlease(PadMutex); // Protect the one time pad. cd::ScopeMutex OneAtATimePlease(PadMutex); // Protect the one time pad.
myLOGmgr->Timestamp(Entropy); // Time matters ;-) myLOGmgr->Timestamp(Entropy); // Time matters ;-)
for(unsigned int a = 0; a < Entropy.length(); a++) { // Add the entropy to our generator. for(unsigned int a = 0; a < Entropy.length(); a++) { // Add the entropy to our generator.
if(CurrentHandshake.size() != SNFHandshakeSize) { // If we don't have one make one! if(CurrentHandshake.size() != SNFHandshakeSize) { // If we don't have one make one!
CurrentHandshake = OneTimePad(SNFHandshakeSize); // Set up a default handshake to use CurrentHandshake = OneTimePad(SNFHandshakeSize); // Set up a default handshake to use
try { // if we can't remember the real one. try { // if we can't remember the real one.
ifstream HSF(HandshakeFilePath.c_str(), ios::binary); // Open the handshake file.
std::ifstream HSF(HandshakeFilePath.c_str(), std::ios::binary); // Open the handshake file.
char* bfr = reinterpret_cast<char*>(&CurrentHandshake[0]); // Manufacture a proper pointer. char* bfr = reinterpret_cast<char*>(&CurrentHandshake[0]); // Manufacture a proper pointer.
HSF.read(bfr, SNFHandshakeSize); // Read the data (overwrite the HSB). HSF.read(bfr, SNFHandshakeSize); // Read the data (overwrite the HSB).
HSF.close(); // Close the file. HSF.close(); // Close the file.
PadBuffer& snfNETmgr::Handshake(PadBuffer& NewHandshake) { // Store a new handshake. PadBuffer& snfNETmgr::Handshake(PadBuffer& NewHandshake) { // Store a new handshake.
CurrentHandshake = NewHandshake; // Grab the new handshake CurrentHandshake = NewHandshake; // Grab the new handshake
try { // then try to store it... try { // then try to store it...
ofstream HSF(HandshakeFilePath.c_str(), ios::binary | ios::trunc); // Open the handshake file.
std::ofstream HSF(
HandshakeFilePath.c_str(), std::ios::binary | std::ios::trunc); // Open the handshake file.

char* bfr = reinterpret_cast<char*>(&NewHandshake[0]); // Access the raw buffer. char* bfr = reinterpret_cast<char*>(&NewHandshake[0]); // Access the raw buffer.
HSF.write(bfr, NewHandshake.size()); // Replace the old handshake HSF.write(bfr, NewHandshake.size()); // Replace the old handshake
HSF.close(); // close the file. HSF.close(); // close the file.
return NewHandshake; // Return what we were given. return NewHandshake; // Return what we were given.
} }


void snfNETmgr::postUpdateTrigger(string& updateUTC) { // Post an update trigger file.
void snfNETmgr::postUpdateTrigger(std::string& updateUTC) { // Post an update trigger file.
try { // Safely post an update trigger. try { // Safely post an update trigger.
ofstream HSF(UpdateReadyFilePath.c_str(), ios::binary | ios::trunc); // Open/create the trigger file.
std::ofstream HSF(
UpdateReadyFilePath.c_str(), std::ios::binary | std::ios::trunc); // Open/create the trigger file.

char* bfr = reinterpret_cast<char*>(&updateUTC[0]); // Access the raw UTC buffer. char* bfr = reinterpret_cast<char*>(&updateUTC[0]); // Access the raw UTC buffer.
HSF.write(bfr, updateUTC.size()); // Write the update timestamp. HSF.write(bfr, updateUTC.size()); // Write the update timestamp.
HSF.close(); // close the file. HSF.close(); // close the file.
// Utility to read a line from a non-blocking TCPHost & check the timeout. // Utility to read a line from a non-blocking TCPHost & check the timeout.


const unsigned int MaxReadLineLength = 1024; // How long a line can be. const unsigned int MaxReadLineLength = 1024; // How long a line can be.
string readLineTimeout(cd::TCPHost& S, cd::Timeout& T) { // Read a line from S until T.
std::string readLineTimeout(cd::TCPHost& S, cd::Timeout& T) { // Read a line from S until T.
cd::Sleeper WaitForMoreData(50); // How long to wait when no data. cd::Sleeper WaitForMoreData(50); // How long to wait when no data.
string LineBuffer = ""; // Buffer for the line.
std::string LineBuffer = ""; // Buffer for the line.
while( // Keep going as long as: while( // Keep going as long as:
false == T.isExpired() && // our timeout has not expired AND false == T.isExpired() && // our timeout has not expired AND
MaxReadLineLength > LineBuffer.length() // we haven't reached our limit. MaxReadLineLength > LineBuffer.length() // we haven't reached our limit.


// Keep these things in scope. This is how we roll. // Keep these things in scope. This is how we roll.


string HostName;
std::string HostName;
int HostPort; int HostPort;
string Secret;
string Node;
std::string Secret;
std::string Node;


// Grab our configuration data (marchng orders). // Grab our configuration data (marchng orders).


cd::PollTimer WaitForOpen(10, 340); // Expand 10ms to 340ms between tries. cd::PollTimer WaitForOpen(10, 340); // Expand 10ms to 340ms between tries.
while(!SessionDog.isExpired()) { // Wait & Watch for a good connection. while(!SessionDog.isExpired()) { // Wait & Watch for a good connection.
try { SyncServer.open(); } // Try opening the connection. try { SyncServer.open(); } // Try opening the connection.
catch(exception& e) { // If we get an exception then
string ConnectFailMessage = "snfNETmgr::sync().open() "; // format a useful message about
catch(const std::exception& e) { // If we get an exception then
std::string ConnectFailMessage = "snfNETmgr::sync().open() "; // format a useful message about
ConnectFailMessage.append(e.what()); // the error and then throw ConnectFailMessage.append(e.what()); // the error and then throw
throw SyncFailed(ConnectFailMessage); // a SyncFailed exception. throw SyncFailed(ConnectFailMessage); // a SyncFailed exception.
} }


// Start communicating. // Start communicating.


string LineBuffer = ""; // Input Line Buffer.
std::string LineBuffer = ""; // Input Line Buffer.


// Read challenge // Read challenge


//--- Encode our response as base64 and send it. //--- Encode our response as base64 and send it.


cd::to_base64 ResponseTxt(ResponseBin); // Encode the cyphertext as base64. cd::to_base64 ResponseTxt(ResponseBin); // Encode the cyphertext as base64.
string ResponseTxtString; // Create a handy string and place
std::string ResponseTxtString; // Create a handy string and place
ResponseTxtString.assign(ResponseTxt.begin(), ResponseTxt.end()); // the base 64 text into it. ResponseTxtString.assign(ResponseTxt.begin(), ResponseTxt.end()); // the base 64 text into it.


string ResponseMsg; // Build an appropriate response
std::string ResponseMsg; // Build an appropriate response
ResponseMsg.append("<snf><sync><response nodeid=\'"); // identifying this node ResponseMsg.append("<snf><sync><response nodeid=\'"); // identifying this node
ResponseMsg.append(Node); // with the license id ResponseMsg.append(Node); // with the license id
ResponseMsg.append("\' text=\'"); // and providing an appropriately ResponseMsg.append("\' text=\'"); // and providing an appropriately


CurrentThreadState(SYNC_Send_GBUdb_Alerts); CurrentThreadState(SYNC_Send_GBUdb_Alerts);


string ClientReport;
std::string ClientReport;
ClientReport.append("<snf><sync><client>\n"); ClientReport.append("<snf><sync><client>\n");
sendDataTimeout(SyncServer, SessionDog, ClientReport); sendDataTimeout(SyncServer, SessionDog, ClientReport);
ClientReport = ""; ClientReport = "";


// Insert our GBUdb Alerts. // Insert our GBUdb Alerts.


list<GBUdbAlert> Alerts; // Make a list of GBUdb Alerts.
std::list<GBUdbAlert> Alerts; // Make a list of GBUdb Alerts.
myGBUdbmgr->GetAlertsForSync(Alerts); // Get them from our GBUdb. myGBUdbmgr->GetAlertsForSync(Alerts); // Get them from our GBUdb.
list<GBUdbAlert>::iterator iA;
std::list<GBUdbAlert>::iterator iA;
for(iA = Alerts.begin(); iA != Alerts.end(); iA++) { // Convert each alert in our list for(iA = Alerts.begin(); iA != Alerts.end(); iA++) { // Convert each alert in our list
ClientReport.append((*iA).toXML()); // into XML, follow it up ClientReport.append((*iA).toXML()); // into XML, follow it up
ClientReport.append("\n"); // with a new line, and send it ClientReport.append("\n"); // with a new line, and send it
**/ **/


if(0 < ReportsBuffer.length()) { // If we have reports to send if(0 < ReportsBuffer.length()) { // If we have reports to send
string DataToSend = getReports(); // get (and clear) the reports and
std::string DataToSend = getReports(); // get (and clear) the reports and
sendDataTimeout(SyncServer, SessionDog, DataToSend); // send them (mindful of timeout). sendDataTimeout(SyncServer, SessionDog, DataToSend); // send them (mindful of timeout).
} }
if(SessionDog.isExpired()) throw SyncFailed("Out Of Time"); // Check our session time. if(SessionDog.isExpired()) throw SyncFailed("Out Of Time"); // Check our session time.
***/ ***/


if(0 < SamplesBuffer.length()) { // If we have samples to send if(0 < SamplesBuffer.length()) { // If we have samples to send
string DataToSend = getSamples(); // get (and clear) the samples and
std::string DataToSend = getSamples(); // get (and clear) the samples and
sendDataTimeout(SyncServer, SessionDog, DataToSend); // send them (mindful of timeout). sendDataTimeout(SyncServer, SessionDog, DataToSend); // send them (mindful of timeout).
} }
if(SessionDog.isExpired()) throw SyncFailed("Out Of Time"); // Check our session time. if(SessionDog.isExpired()) throw SyncFailed("Out Of Time"); // Check our session time.


CurrentThreadState(SYNC_Read_Server_Response); CurrentThreadState(SYNC_Read_Server_Response);


string ServerResponse;
string ResponseLine;
while(string::npos == ResponseLine.find("</snf>\n")) { // Until we find the ending...
std::string ServerResponse;
std::string ResponseLine;
while(std::string::npos == ResponseLine.find("</snf>\n")) { // Until we find the ending...
ResponseLine = readLineTimeout(SyncServer, SessionDog); // Read a line. ResponseLine = readLineTimeout(SyncServer, SessionDog); // Read a line.
if(0 >= ResponseLine.length()) { // If we get an empty line if(0 >= ResponseLine.length()) { // If we get an empty line
throw SyncFailed("sync() server response empty line"); // then it's an error. throw SyncFailed("sync() server response empty line"); // then it's an error.
(*myLOGmgr).RecordSyncEvent(); // Finished that -- so log the event. (*myLOGmgr).RecordSyncEvent(); // Finished that -- so log the event.


} }
catch (exception& e) { // SYNC Failed and we know more.
catch (const std::exception& e) { // SYNC Failed and we know more.
const int snf_UNKNOWN_ERROR = 99; // Report an error (unknown code) const int snf_UNKNOWN_ERROR = 99; // Report an error (unknown code)
string ERROR_SYNC_FAILEDmsg = CurrentThreadState().Name; // Format a useful state message.
std::string ERROR_SYNC_FAILEDmsg = CurrentThreadState().Name; // Format a useful state message.
ERROR_SYNC_FAILEDmsg.append(": "); ERROR_SYNC_FAILEDmsg.append(": ");
ERROR_SYNC_FAILEDmsg.append(e.what()); ERROR_SYNC_FAILEDmsg.append(e.what());
(*myLOGmgr).logThisError( // Log the error (if possible) (*myLOGmgr).logThisError( // Log the error (if possible)
} }
catch (...) { // SYNC Failed if we're here. catch (...) { // SYNC Failed if we're here.
const int snf_UNKNOWN_ERROR = 99; // Report an error (unknown code) const int snf_UNKNOWN_ERROR = 99; // Report an error (unknown code)
string ERROR_SYNC_FAILEDmsg = CurrentThreadState().Name; // Format a useful state message.
std::string ERROR_SYNC_FAILEDmsg = CurrentThreadState().Name; // Format a useful state message.
ERROR_SYNC_FAILEDmsg.append(": Panic!"); ERROR_SYNC_FAILEDmsg.append(": Panic!");
(*myLOGmgr).logThisError( // Log the error (if possible) (*myLOGmgr).logThisError( // Log the error (if possible)
"SNF_NETWORK", snf_UNKNOWN_ERROR, ERROR_SYNC_FAILEDmsg "SNF_NETWORK", snf_UNKNOWN_ERROR, ERROR_SYNC_FAILEDmsg

+ 16
- 16
snfNETmgr.hpp View File



// Configuration data // Configuration data


string License; // Node (license) Id?
string SecurityKey; // Security key for this rulebase?
string RulebaseFilePath; // Where we can find our rulebase?
string HandshakeFilePath; // Where do we keep our handshake?
string UpdateReadyFilePath; // Where do I put update trigger files?
string SyncHostName; // Where do we connect to sync?
std::string License; // Node (license) Id?
std::string SecurityKey; // Security key for this rulebase?
std::string RulebaseFilePath; // Where we can find our rulebase?
std::string HandshakeFilePath; // Where do we keep our handshake?
std::string UpdateReadyFilePath; // Where do I put update trigger files?
std::string SyncHostName; // Where do we connect to sync?
int SyncHostPort; // What port do we use to sync? int SyncHostPort; // What port do we use to sync?
int SyncSecsOverride; // How may secs between sync (override)? int SyncSecsOverride; // How may secs between sync (override)?
int SyncSecsConfigured; // How many secs to sync (nominally)? int SyncSecsConfigured; // How many secs to sync (nominally)?
PadBuffer& Handshake(PadBuffer& NewHandshake); // Store a new handshake. PadBuffer& Handshake(PadBuffer& NewHandshake); // Store a new handshake.
PadBuffer CurrentHandshake; // Where we keep our current handshake. PadBuffer CurrentHandshake; // Where we keep our current handshake.


void postUpdateTrigger(string& updateUTC); // Post an update trigger file.
void postUpdateTrigger(std::string& updateUTC); // Post an update trigger file.


string SamplesBuffer; // Message Samples Appended Together.
string getSamples(); // Syncrhonized way to get Samples.
string ReportsBuffer; // Status Reports Appended Together.
string getReports(); // Synchronized way to get Reports.
std::string SamplesBuffer; // Message Samples Appended Together.
std::string getSamples(); // Syncrhonized way to get Samples.
std::string ReportsBuffer; // Status Reports Appended Together.
std::string getReports(); // Synchronized way to get Reports.


public: public:


void linkGBUdbmgr(snfGBUdbmgr& G); // Set the GBUdbmgr. void linkGBUdbmgr(snfGBUdbmgr& G); // Set the GBUdbmgr.
void configure(snfCFGData& CFGData); // Update the configuration. void configure(snfCFGData& CFGData); // Update the configuration.


class SyncFailed : public runtime_error { // Thrown if sync doesn't work.
public: SyncFailed(const string& w):runtime_error(w) {}
class SyncFailed : public std::runtime_error { // Thrown if sync doesn't work.
public: SyncFailed(const std::string& w):runtime_error(w) {}
}; };


// Operations // Operations
int MessageLength // and it is this size. int MessageLength // and it is this size.
); );


void sendReport(const string& StatusReportText); // Send a status report...
void sendReport(const std::string& StatusReportText); // Send a status report...


void sync(); // Do the whole "sync" thing. void sync(); // Do the whole "sync" thing.


// Utility Functions // Utility Functions


unsigned long ResolveHostIPFromName(const string& N); // Find the IP.
string& RulebaseUTC(string& t); // Gets local rulebase file UTC.
unsigned long ResolveHostIPFromName(const std::string& N); // Find the IP.
std::string& RulebaseUTC(std::string& t); // Gets local rulebase file UTC.


const static cd::ThreadType Type; // The thread's type. const static cd::ThreadType Type; // The thread's type.



+ 9
- 9
snf_HeaderFinder.cpp View File

UnfoldHeaders(); // Unfold the headers. UnfoldHeaders(); // Unfold the headers.
} }


cd::IP4Address extractIPFromSourceHeader(string& Header) { // Return first IP found in header.
const string Digits = "0123456789";
cd::IP4Address extractIPFromSourceHeader(std::string& Header) { // Return first IP found in header.
const std::string Digits = "0123456789";
unsigned int EndOfName = Header.find_first_of(":"); unsigned int EndOfName = Header.find_first_of(":");


unsigned int StartOfIP = Header.find_first_of(Digits, EndOfName); unsigned int StartOfIP = Header.find_first_of(Digits, EndOfName);
const string IPCharacters = ".0123456789";
const std::string IPCharacters = ".0123456789";
unsigned int EndOfIP = Header.find_first_not_of(IPCharacters, StartOfIP); unsigned int EndOfIP = Header.find_first_not_of(IPCharacters, StartOfIP);
bool NoExtraCharactersAfterIP = (string::npos == EndOfIP);
bool NoExtraCharactersAfterIP = (std::string::npos == EndOfIP);
if(NoExtraCharactersAfterIP) EndOfIP = Header.length(); if(NoExtraCharactersAfterIP) EndOfIP = Header.length();
unsigned int IPLength = EndOfIP - StartOfIP; unsigned int IPLength = EndOfIP - StartOfIP;
cd::IP4Address ExtractedIP = Header.substr(StartOfIP, IPLength); cd::IP4Address ExtractedIP = Header.substr(StartOfIP, IPLength);
return ExtractedIP; return ExtractedIP;
} }


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


if(HeaderContainsFinderPattern) { if(HeaderContainsFinderPattern) {
} }




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


void captureThisHeader( // Capture the header and move pos. void captureThisHeader( // Capture the header and move pos.
string& Output, // Here is the output string.
std::string& Output, // Here is the output string.
int& Pos, // Here is the current position. int& Pos, // Here is the current position.
const unsigned char* Bfr, // Here is the buffer pointer. const unsigned char* Bfr, // Here is the buffer pointer.
const int Len // Here is the length of the buffer. const int Len // Here is the length of the buffer.
void HeaderFinder::UnfoldHeaders() { // Unfold and check headers. void HeaderFinder::UnfoldHeaders() { // Unfold and check headers.
if(0 >= HeaderDirectives.size()) return; // Skip this if we have no patterns. if(0 >= HeaderDirectives.size()) return; // Skip this if we have no patterns.
if(0 >= Len) return; // Skip if we have no message. if(0 >= Len) return; // Skip if we have no message.
string TestHeader; // The header under test.
std::string TestHeader; // The header under test.


int Position = 0; // Position in Bfr. int Position = 0; // Position in Bfr.
for(;;) { // Scan through all of the headers. for(;;) { // Scan through all of the headers.

Loading…
Cancel
Save