// snfCFGmgr.hpp // Copyright (C) 2006 - 2009 Arm Research Labs, LLC // See www.armresearch.com for the copyright terms. // // SNF Configuration manager. //// Begin include only once #ifndef included_snfCFGmgr_hpp #define included_snfCFGmgr_hpp #include "SNFMulti/GBUdb.hpp" #include "SNFMulti/snf_HeaderFinder.hpp" #include "CodeDweller/XMLReader.hpp" #include "CodeDweller/threading.hpp" #include #include namespace SNFMulti { const unsigned long int HeaderDirectiveBypass = 0x00000001; // Bypass hd rule flag. const unsigned long int HeaderDirectiveWhite = 0x00000002; // White hd rule flag. const unsigned long int HeaderDirectiveDrillDown = 0x00000004; // DrillDown rule flag. const unsigned long int HeaderDirectiveSource = 0x00000008; // Source rule flag. const unsigned long int HeaderDirectiveContext = 0x80000000; // Context activation flag. class HeaderDirectiveHandler : public CodeDweller::Configurator { // Handle inputs to header directives. public: HeaderDirectiveSet HeaderDirectives; // Managed set of Header Directives. void operator()(CodeDweller::ConfigurationElement& E, CodeDweller::ConfigurationData& D) { // The configurator call adds the Input. if(HeaderDirectiveContext == ContextInput.Directive) { // If a context has been established ContextInput.Context = HeaderDirectives.size() + 1; // then setup the context ID and DirectiveInput.Context = ContextInput.Context; // share it with the input. HeaderDirectives.insert(ContextInput); // Insert the context tester and ContextInput.clear(); // then clear it for future use. } HeaderDirectives.insert(DirectiveInput); // Insert the directive and then DirectiveInput.clear(); // clear the input for future use. } HeaderFinderPattern ContextInput; // The context can be set externally. HeaderFinderPattern DirectiveInput; // The Input can be set externally. void reset() { // Reset the handler like this: HeaderDirectives.clear(); // Clear the header directives. ContextInput.clear(); // Clear the Context Input. DirectiveInput.clear(); // Clear the Directive Input. } }; class HeaderDirectiveInitializer : public CodeDweller::Configurator { // Initializes Header Directives. private: HeaderDirectiveHandler* MyTarget; // Needs to know it's target. public: HeaderDirectiveInitializer() : MyTarget(NULL) {} // Constructor doesn't know it's target yet. void setTarget(HeaderDirectiveHandler& H) { MyTarget = &H; } // We have a way to set the target though ;-) void operator()(CodeDweller::ConfigurationElement& E, CodeDweller::ConfigurationData& D) { // The configurator() function goes to the if(NULL!=MyTarget) { // target (if it's set) and pushes the MyTarget->reset(); // reset button (empties the set). } } }; class HeaderDirectiveWhiteHeaderInitializer : public CodeDweller::Configurator {// Initializes White Header Directives. private: HeaderDirectiveHandler* MyTarget; // Needs to know it's target. public: HeaderDirectiveWhiteHeaderInitializer() : MyTarget(NULL) {} // Constructor doesn't know it's target yet. void setTarget(HeaderDirectiveHandler& H) { MyTarget = &H; } // We have a way to set the target though ;-) void operator()(CodeDweller::ConfigurationElement& E, CodeDweller::ConfigurationData& D) { // The configurator() function goes to the if(NULL!=MyTarget) { // target (if it's set) and sets it up MyTarget->ContextInput.clear(); // for a white header directive. MyTarget->DirectiveInput.clear(); MyTarget->DirectiveInput.Directive = HeaderDirectiveWhite; } } }; class HeaderDirectiveBypassHeaderInitializer : public CodeDweller::Configurator {// Initializes Bypass Header Directives. private: HeaderDirectiveHandler* MyTarget; // Needs to know it's target. public: HeaderDirectiveBypassHeaderInitializer() : MyTarget(NULL) {} // Constructor doesn't know it's target yet. void setTarget(HeaderDirectiveHandler& H) { MyTarget = &H; } // We have a way to set the target though ;-) void operator()(CodeDweller::ConfigurationElement& E, CodeDweller::ConfigurationData& D) { // The configurator() function goes to the if(NULL!=MyTarget) { // target (if it's set) and sets it up MyTarget->ContextInput.clear(); // for a bypass header directive. MyTarget->DirectiveInput.clear(); MyTarget->DirectiveInput.Directive = HeaderDirectiveBypass; } } }; class HeaderDirectiveDrilldownInitializer : public CodeDweller::Configurator { // Initializes Drilldown Header Directives. private: HeaderDirectiveHandler* MyTarget; // Needs to know it's target. public: HeaderDirectiveDrilldownInitializer() : MyTarget(NULL) {} // Constructor doesn't know it's target yet. void setTarget(HeaderDirectiveHandler& H) { MyTarget = &H; } // We have a way to set the target though ;-) void operator()(CodeDweller::ConfigurationElement& E, CodeDweller::ConfigurationData& D) { // The configurator() function goes to the if(NULL!=MyTarget) { // target (if it's set) and sets it up for MyTarget->ContextInput.clear(); // a drilldown header directive. MyTarget->DirectiveInput.clear(); MyTarget->DirectiveInput.Directive = HeaderDirectiveDrillDown; MyTarget->DirectiveInput.Header = "Received:"; } } }; class HeaderDirectiveSourceHeaderInitializer : public CodeDweller::Configurator {// Initializes Source Header Directives. private: HeaderDirectiveHandler* MyTarget; // Needs to know it's target. public: HeaderDirectiveSourceHeaderInitializer() : MyTarget(NULL) {} // Constructor doesn't know it's target yet. void setTarget(HeaderDirectiveHandler& H) { MyTarget = &H; } // We have a way to set the target though ;-) void operator()(CodeDweller::ConfigurationElement& E, CodeDweller::ConfigurationData& D) { // The configurator() function goes to the if(NULL!=MyTarget) { // target (if it's set) and sets it up MyTarget->ContextInput.clear(); // for a context sensitive source header MyTarget->DirectiveInput.clear(); // directive. Activation context as well MyTarget->ContextInput.Directive = HeaderDirectiveContext; // as source header data. MyTarget->ContextInput.Header = "Received:"; MyTarget->DirectiveInput.Directive = HeaderDirectiveSource; } } }; class RangePoint { // Range point x:Probability, y:Confidence public: RangePoint() : // The simple constructor sets all to zero. Probability(0.0), Confidence(0.0) {} RangePoint(double C, double P) : // This constructor sets the values. Probability(P), Confidence(C) {} double Probability; // Probability and Confidence are double Confidence; // freely accessible. bool operator<(const RangePoint& right) const { // Comparison of RangePoint objects depends return (Confidence < right.Confidence); // on the Confidence value. This is because } // Confidence is used as a "key" in the set. bool operator>(const RangePoint& right) const { return (Confidence > right.Confidence); } bool operator==(const RangePoint& right) const { return (Confidence == right.Confidence); } bool operator<=(const RangePoint& right) const { return (Confidence <= right.Confidence); } bool operator>=(const RangePoint& right) const { return (Confidence >= right.Confidence); } }; class RangeHandler : public CodeDweller::Configurator { // The handler adds edgepoints and holds and public: // tests the set that defines the region. void operator()(CodeDweller::ConfigurationElement& E, CodeDweller::ConfigurationData& D) { // The () operator adds EdgeInput to the list. EdgeMap.insert(EdgeInput); } bool On_Off; // Ranges can be turned on and off. int Symbol; // They have a symbol assigned to them. int Priority; // They have an evaluation priority. RangePoint EdgeInput; // This EdgePoint is set, and added using (). std::set EdgeMap; // This contains the set of EdgePoints. bool isInWhite(RangePoint& x); // True if x is inside the -P of the EdgeMap. bool isInBlack(RangePoint& x); // True if x is inside the +P of the EdgeMap. void reset() { EdgeMap.clear(); } // When we reset - we empty the EdgeMap. }; class RangeInitializer : public CodeDweller::Configurator { // The RangeInitializer Configurator. private: RangeHandler* MyTarget; // Needs to know it's target. public: RangeInitializer() : MyTarget(NULL) {} // Constructor doesn't know it's target yet. void setTarget(RangeHandler& H) { MyTarget = &H; } // We have a way to set the target though ;-) void operator()(CodeDweller::ConfigurationElement& E, CodeDweller::ConfigurationData& D) { // The configurator() function goes to the if(NULL!=MyTarget) { // target (if it's set) and pushes the MyTarget->reset(); // reset button. } } }; class IntegerSetHandler : public CodeDweller::Configurator { // Integer set handler for rule panics. public: void operator()(CodeDweller::ConfigurationElement& E, CodeDweller::ConfigurationData& D) { // The operator() inserts IntegerInput IntegerSet.insert(IntegerInput); // if it's not already a member. } int IntegerInput; // The input port. std::set IntegerSet; // The set itself. bool isListed(int x); // How to check if an int is listed. void reset() { IntegerSet.clear(); } // How to reset (clear) the list. }; class IntegerSetInitializer : public CodeDweller::Configurator { // The initializer resets the set. private: IntegerSetHandler* MyTarget; // It needs to know which set to init. public: IntegerSetInitializer() : MyTarget(NULL) {} // Start off not knowing where to go. void setTarget(IntegerSetHandler& H) { MyTarget = &H; } // Set a pointer to the handler. void operator()(CodeDweller::ConfigurationElement& E, CodeDweller::ConfigurationData& D) { // The operator() does the trick. if(NULL!=MyTarget) { MyTarget->reset(); } } }; class XHDRSymbol { // XHeader associated with a Symbol public: int Symbol; // The integer symbol. std::string Header; // The header to associate. XHDRSymbol(int FreshSymbol, std::string FreshHeader) : // Creating the object requires both. Symbol(FreshSymbol), Header(FreshHeader) {} bool operator<(const XHDRSymbol& right) const { // To live in a set we must have a < return (Symbol < right.Symbol); // operator. Only the symbol matters } // in this case. }; class XHDRSymbolsHandler : public CodeDweller::Configurator { // XHDRSymbol hander. public: std::set SymbolHeaders; // Carries a set of Symbol Headers. void reset() { SymbolHeaders.clear(); } // Is reset by clearing the set. std::string HeaderForSymbol(int S) { // Can return a Header for symbol. std::string MatchingHeader = ""; // Starting with an empty string, std::set::iterator iS = SymbolHeaders.find(XHDRSymbol(S,""));// we look up the symbol and if(SymbolHeaders.end() != iS) { // if we find it then we will MatchingHeader = (*iS).Header; // return the matching header } // string. If not then we return return MatchingHeader; // the empty string. } // Coded in-line on purpose. bool OnOff; // Input OnOff value. int Symbol; // Input Symbol value. std::string Header; // Input Header value. void operator()(CodeDweller::ConfigurationElement& E, CodeDweller::ConfigurationData& D) { // The operator() inserts an XHDRSymbol if(OnOff) { // if the header entry is turned on and SymbolHeaders.insert(XHDRSymbol(Symbol, Header)); // if it's not already a member. } } }; class XHDRSymbolsInitializer : public CodeDweller::Configurator { // The XHDRSymbols initializer. private: XHDRSymbolsHandler* MyTarget; // It needs to know which set to init. public: XHDRSymbolsInitializer() : MyTarget(NULL) {} // Start off not knowing where to go. void setTarget(XHDRSymbolsHandler& H) { MyTarget = &H; } // Set a pointer to the handler. void operator()(CodeDweller::ConfigurationElement& E, CodeDweller::ConfigurationData& D) { // The operator() does the trick. if(NULL!=MyTarget) { MyTarget->reset(); } } }; enum snfIPRange { // IP action ranges Unknown, // Unknown - not defined. White, // This is a good guy. Normal, // Benefit of the doubt. New, // It is new to us. Caution, // This is suspicious. Black, // This is bad. Truncate // Don't even bother looking. }; const int ScanLogMatches_All = 2; // Include all matches. const int ScanLogMatches_Unique = 1; // Include 1 match of each rule. const int ScanLogMatches_None = 0; // Include only the final result. const int LogOutputMode_None = 0; // No output (don't process). const int LogOutputMode_API = 1; // Make available to API. const int LogOutputMode_File = 2; // Output to msgfile.xhdr. const int LogOutputMode_Inject = 3; // Inject into msgfile. class snfCFGData { // Object that stores our config data. private: CodeDweller::ConfigurationElement MyCFGReader; // This is how we read our cfg data. public: snfCFGData(); // Constructor handled in .cpp void initializeFromFile(const char* FileName); // Initialize from the provided file. int Generation; // Generation tag. // Here are the derived data elements... std::string ConfigFilePath; // Configuration file path std::string RuleFilePath; // Rulebase file path std::string SecurityKey; // Security key for rulebase // Here are the basic data elements... std::string node_identity; std::string node_licenseid; std::string node_authentication; //// paths std::string paths_workspace_path; std::string paths_rulebase_path; std::string paths_log_path; //// logging bool Logs_Rotation_LocalTime_OnOff; bool Status_SecondReport_Log_OnOff; bool Status_SecondReport_Append_OnOff; bool Status_MinuteReport_Log_OnOff; bool Status_MinuteReport_Append_OnOff; bool Status_HourReport_Log_OnOff; bool Status_HourReport_Append_OnOff; bool Scan_Identifier_Force_Message_Id; int Scan_Classic_Mode; bool Scan_Classic_Rotate; int Scan_Classic_Matches; int Scan_XML_Mode; bool Scan_XML_Rotate; int Scan_XML_Matches; bool Scan_XML_Performance; bool Scan_XML_GBUdb; //// xheaders int XHDROutput_Mode; bool XHDRVersion_OnOff; std::string XHDRVersion_Header; bool XHDRLicense_OnOff; std::string XHDRLicense_Header; bool XHDRRulebase_OnOff; std::string XHDRRulebase_Header; bool XHDRIdentifier_OnOff; std::string XHDRIdentifier_Header; bool XHDRGBUdb_OnOff; std::string XHDRGBUdb_Header; bool XHDRResult_OnOff; std::string XHDRResult_Header; bool XHDRMatches_OnOff; std::string XHDRMatches_Header; bool XHDRBlack_OnOff; std::string XHDRBlack_Header; bool XHDRWhite_OnOff; std::string XHDRWhite_Header; bool XHDRClean_OnOff; std::string XHDRClean_Header; XHDRSymbolsHandler XHDRSymbolHeaders; XHDRSymbolsInitializer XHDRSymbolHeadersInitializer; //// platform std::string PlatformElementContents; //// network int network_sync_secs; std::string network_sync_host; int network_sync_port; bool update_script_on_off; std::string update_script_call; int update_script_guard_time; //// gbudb int gbudb_database_condense_minimum_seconds_between; bool gbudb_database_condense_time_trigger_on_off; int gbudb_database_condense_time_trigger_seconds; bool gbudb_database_condense_posts_trigger_on_off; int gbudb_database_condense_posts_trigger_posts; bool gbudb_database_condense_records_trigger_on_off; int gbudb_database_condense_records_trigger_records; bool gbudb_database_condense_size_trigger_on_off; int gbudb_database_condense_size_trigger_megabytes; bool gbudb_database_checkpoint_on_off; int gbudb_database_checkpoint_secs; RangeHandler WhiteRangeHandler; RangeInitializer WhiteRangeInitializer; bool gbudb_regions_white_panic_on_off; int gbudb_regions_white_panic_rule_range; RangeHandler BlackRangeHandler; RangeInitializer BlackRangeInitializer; bool gbudb_regions_black_sample_on_off; double gbudb_regions_black_sample_probability; int gbudb_regions_black_sample_grab_one_in; bool gbudb_regions_black_sample_passthrough; int gbudb_regions_black_sample_passthrough_symbol; int gbudb_regions_black_truncate_symbol; bool gbudb_regions_black_truncate_on_off; double gbudb_regions_black_truncate_probability; int gbudb_regions_black_truncate_peek_one_in; RangeHandler CautionRangeHandler; RangeInitializer CautionRangeInitializer; snfIPRange RangeEvaluation(GBUdbRecord& R); // Returns the range for a GBUdbRecord. snfIPRange RangeEvaluation(RangePoint& p); // Returns the range for a RangePoint. HeaderDirectiveHandler HeaderDirectivesHandler; //** Handles header directives. HeaderDirectiveInitializer HeaderDirectivesInitializer; //** Initializes header directives set. HeaderDirectiveSourceHeaderInitializer HDSourceHeaderInitializer; //**** For source header directives. HeaderDirectiveDrilldownInitializer HDDrilldownInitializer; //**** For drilldown header directives. HeaderDirectiveBypassHeaderInitializer HDBypassHeaderInitializer; //**** For bypass header directives. HeaderDirectiveWhiteHeaderInitializer HDWhiteHeaderInitializer; //**** For white header directives. IntegerSetHandler TrainingBypassRuleHandler; // Rules to NOT train GBUdb with source. IntegerSetInitializer TrainingBypassRuleInitializer; IntegerSetHandler TrainingWhiteRuleHandler; // Rules to train GBUdb as white source. IntegerSetInitializer TrainingWhiteRuleInitializer; bool GBUdbTrainingOn_Off; // True when GBUdb training is allowed. IntegerSetHandler RulePanicHandler; IntegerSetInitializer RulePanicInitializer; bool XCI_OnOff; // XML Command Interface ON or OFF. int XCI_Port; // XML Command Interface Port number. bool MessageFileTypeCGP_on_off; // True for scanning communigate msgs. }; class snfCFGmgr { // Object that manages our config data. private: CodeDweller::Mutex myMutex; // Serialize control during updates. snfCFGData A; // This is where we store one copy. snfCFGData B; // This is where we store the other. volatile bool AisActive; // This tells us which is active. void swapCFGData(); // This swaps the active dataset. snfCFGData& ActiveData(); // This returns the active dataset. snfCFGData& InactiveData(); // This returns the inactive dataset. std::string InitFileName; // Initilization parameters are reused std::string InitLicenseId; // any time load() is called. std::string InitAuthentication; std::string ConfigurationPath; // Path to active configuration file. public: snfCFGmgr(); // Constructor - to get things right void initialize( // In order to initialize we need to const char* FileName, // collect a path to our config or .snf const char* LicenseId, // our license id and our const char* Authentication // authentication. ); class LoadFailure {}; // What we throw if load fails. void load(); // Load the configuration data. //// Access methods for config data... std::string RuleFilePath(); // Rulebase file path std::string SecurityKey(); // Security key for rulebase snfCFGData* ActiveConfiguration(); // Pointer to active configuration }; #include "snfCFGmgr.inline.hpp" } // namespace SNFMulti #endif // End include only once