12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079 |
- // snfCFGmgr.cpp
- // Copyright (C) 2006 - 2020 Arm Research Labs, LLC
- // See www.armresearch.com for the copyright terms.
- //
-
- // See snfCFGmgr.hpp for details.
-
- #include "snfCFGmgr.hpp"
- #include <iostream>
-
- namespace cd = codedweller;
-
- //// IntegerSetHandler /////////////////////////////////////////////////////////
-
- bool IntegerSetHandler::isListed(int x) { // How to check if an int is listed.
- return (IntegerSet.end() != IntegerSet.find(x));
- }
-
-
- //// snfCFGmgr /////////////////////////////////////////////////////////////////
-
- snfCFGmgr::snfCFGmgr() : // We construct a CFGmgr this way...
- AisActive(false), // So that A is active after 1st load()
- InitFileName(""), // and all of the Init strings are
- InitLicenseId(""), // empty.
- InitAuthentication(""),
- ConfigurationPath("") {
- }
-
- void snfCFGmgr::swapCFGData() { // This swaps the active dataset.
- AisActive = (AisActive)?false:true;
- }
-
- snfCFGData& snfCFGmgr::ActiveData() { // This returns the active dataset.
- return (AisActive) ? A : B;
- }
-
- snfCFGData& snfCFGmgr::InactiveData() { // This returns the inactive dataset.
- return (AisActive) ? B : A;
- }
-
- std::string snfCFGmgr::RuleFilePath() { // Rulebase file path
- return ActiveData().RuleFilePath;
- }
-
- std::string snfCFGmgr::SecurityKey() { // Security key for rulebase
- return ActiveData().SecurityKey;
- }
-
- snfCFGData* snfCFGmgr::ActiveConfiguration() { // Pointer to active configuration
- return &(ActiveData());
- }
-
- //// RangeHandler //////////////////////////////////////////////////////////////
-
- bool RangeHandler::isInBlack(RangePoint& x) { // Find if x is on the black side.
- if(EdgeMap.empty()) { // If there are no points then
- return false; // there is no map so there is
- } // no side to be on.
- // If there are points we will need
- std::set<RangePoint>::iterator iRangePoint; // to examine them.
- iRangePoint = EdgeMap.begin(); // What is the first point.
-
- if(x < (*iRangePoint)) { // If x is below that then
- return false; // x is out of range -- false.
- }
- iRangePoint = EdgeMap.end();--iRangePoint; // What is the last range point.
- if(x > (*iRangePoint)) { // If x is beyond that then
- return false; // x is out of range -- false.
- }
-
- // At this point we know our point is in the range of the edge map.
- // So our next task is to find the two points between which we will
- // interpolate our comparative result.
-
- iRangePoint = EdgeMap.lower_bound(x); // Find the lower point.
- if(x < (*iRangePoint)) --iRangePoint; // If we've overshot, then move back.
- RangePoint LowerBound = (*iRangePoint); // Grab the value at that point.
- iRangePoint = EdgeMap.upper_bound(x); // Find the upper point.
- if(iRangePoint == EdgeMap.end()) --iRangePoint; // If we've overshot, then move back.
- RangePoint UpperBound = (*iRangePoint); // Grab the value at that point.
-
- // So then, where is x in [Lower, Upper]
- // First we check the obvious matching values. Then if those fail we will
- // interpolate between the two points.
- double ComparativeProbability; // This value will map the edge.
-
- if(x == LowerBound) { // If we match the lower bound then
- ComparativeProbability = LowerBound.Probability; // that is the Probability we compare.
- } else
- if(x == UpperBound) { // If we match the upper bound then
- ComparativeProbability = UpperBound.Probability; // that is the Probability we compare.
- } else { // For in-between we interpolate.
- double ULDifference = UpperBound.Confidence - LowerBound.Confidence; // First, find the difference.
- double Incursion = x.Confidence - LowerBound.Confidence; // How far does x go past L to U?
- double Ratio = Incursion / ULDifference; // Express that as a ratio.
- ComparativeProbability = // Interpolate the Probability using
- (((1-Ratio) * LowerBound.Probability) + // a weighted average of the lower and
- (Ratio * UpperBound.Probability)); // upper bound values using the Ratio
- }
-
- // Now compare x to the interpolated edge.
-
- return (x.Probability >= ComparativeProbability); // True if on or right of the edge.
- }
-
- bool RangeHandler::isInWhite(RangePoint& x) {
- if(EdgeMap.empty()) { // If there are no points then
- return false; // there is no map so there is
- } // no side to be on.
- // If ther are points then we
- std::set<RangePoint>::iterator iRangePoint; // need to examine them.
- iRangePoint = EdgeMap.begin(); // What is the first point.
-
- if(x < (*iRangePoint)) { // If x is below that then
- return false; // x is out of range -- false.
- }
- iRangePoint = EdgeMap.end();--iRangePoint; // What is the last range point.
- if(x > (*iRangePoint)) { // If x is beyond that then
- return false; // x is out of range -- false.
- }
-
- // At this point we know our point is in the range of the edge map.
- // So our next task is to find the two points between which we will
- // interpolate our comparative result.
-
- iRangePoint = EdgeMap.lower_bound(x); // Find the lower point.
- if(x < (*iRangePoint)) --iRangePoint; // If we've overshot, then move back.
- RangePoint LowerBound = (*iRangePoint); // Grab the value at that point.
- iRangePoint = EdgeMap.upper_bound(x); // Find the upper point.
- if(iRangePoint == EdgeMap.end()) --iRangePoint; // If we've overshot, then move back.
- RangePoint UpperBound = (*iRangePoint); // Grab the value at that point.
-
- // So then, where is x in [Lower, Upper]
- // First we check the obvious matching values. Then if those fail we will
- // interpolate between the two points.
- double ComparativeProbability; // This value will map the edge.
-
- if(x == LowerBound) { // If we match the lower bound then
- ComparativeProbability = LowerBound.Probability; // that is the Probability we compare.
- } else
- if(x == UpperBound) { // If we match the upper bound then
- ComparativeProbability = UpperBound.Probability; // that is the Probability we compare.
- } else { // For in-between we interpolate.
- double ULDifference = UpperBound.Confidence - LowerBound.Confidence; // First, find the difference.
- double Incursion = x.Confidence - LowerBound.Confidence; // How far does x go past L to U?
- double Ratio = Incursion / ULDifference; // Express that as a ratio.
- ComparativeProbability = // Interpolate the Probability using
- (((1-Ratio) * LowerBound.Probability) + // a weighted average of the lower and
- (Ratio * UpperBound.Probability)); // upper bound values using the Ratio
- }
-
- // Now compare x to the interpolated edge.
-
- return (x.Probability <= ComparativeProbability); // True if on or left of the edge.
- }
-
- //// snfCFGData ////////////////////////////////////////////////////////////////
-
- snfCFGData::snfCFGData() : // Constructor. No init list because the
- MyCFGReader("snf") { // interpreter will set the defaults.
-
- WhiteRangeInitializer.setTarget(WhiteRangeHandler); // However, we do need to link up our
- BlackRangeInitializer.setTarget(BlackRangeHandler); // Initialization configurators with our
- CautionRangeInitializer.setTarget(CautionRangeHandler); // Handlers.
- RulePanicInitializer.setTarget(RulePanicHandler);
- XHDRSymbolHeadersInitializer.setTarget(XHDRSymbolHeaders);
- HeaderDirectivesInitializer.setTarget(HeaderDirectivesHandler);
- HDSourceHeaderInitializer.setTarget(HeaderDirectivesHandler);
- HDDrilldownInitializer.setTarget(HeaderDirectivesHandler);
- HDBypassHeaderInitializer.setTarget(HeaderDirectivesHandler);
- HDWhiteHeaderInitializer.setTarget(HeaderDirectivesHandler);
- TrainingBypassRuleInitializer.setTarget(TrainingBypassRuleHandler);
- TrainingWhiteRuleInitializer.setTarget(TrainingWhiteRuleHandler);
-
- MyCFGReader // Building our interpreter.
- .Element("node")
- .Attribute("identity", node_identity)
- .Attribute("licenseid", node_licenseid)
- .Attribute("authentication", node_authentication)
- .Element("paths")
- .Element("workspace")
- .Attribute("path", paths_workspace_path)
- .End("workspace")
- .Element("rulebase")
- .Attribute("path", paths_rulebase_path)
- .End("rulebase")
- .Element("log")
- .Attribute("path", paths_log_path)
- .End("log")
- .End("paths")
- .Element("logs")
- .Element("rotation")
- .Attribute("localtime", Logs_Rotation_LocalTime_OnOff, false)
- .Mnemonic("yes", "true")
- .Mnemonic("no", "false")
- .End("rotation")
- .Element("status")
- .Element("second")
- .Attribute("log", Status_SecondReport_Log_OnOff, false)
- .Mnemonic("yes", "true")
- .Mnemonic("no", "false")
- .Attribute("append", Status_SecondReport_Append_OnOff, false)
- .Mnemonic("yes", "true")
- .Mnemonic("no", "false")
- .End("second")
- .Element("minute")
- .Attribute("log", Status_MinuteReport_Log_OnOff, false)
- .Mnemonic("yes", "true")
- .Mnemonic("no", "false")
- .Attribute("append", Status_MinuteReport_Append_OnOff, false)
- .Mnemonic("yes", "true")
- .Mnemonic("no", "false")
- .End("minute")
- .Element("hour")
- .Attribute("log", Status_HourReport_Log_OnOff, false)
- .Mnemonic("yes", "true")
- .Mnemonic("no", "false")
- .Attribute("append", Status_HourReport_Append_OnOff, false)
- .Mnemonic("yes", "true")
- .Mnemonic("no", "false")
- .End("hour")
- .End("status")
- .Element("scan")
- .Element("identifier")
- .Attribute("force-message-id", Scan_Identifier_Force_Message_Id, false)
- .End("identifier")
- .Element("classic")
- .Attribute("mode", Scan_Classic_Mode, LogOutputMode_None)
- .Mnemonic("none", "0")
- .Mnemonic("api", "1")
- .Mnemonic("file", "2")
- .Attribute("rotate", Scan_Classic_Rotate, false)
- .Attribute("matches", Scan_Classic_Matches, ScanLogMatches_None)
- .Mnemonic("none", "0")
- .Mnemonic("unique", "1")
- .Mnemonic("all","2")
- .End("classic")
- .Element("xml")
- .Attribute("mode", Scan_XML_Mode, LogOutputMode_None)
- .Mnemonic("none", "0")
- .Mnemonic("api", "1")
- .Mnemonic("file", "2")
- .Attribute("rotate", Scan_XML_Rotate, false)
- .Attribute("matches", Scan_XML_Matches, ScanLogMatches_None)
- .Mnemonic("none", "0")
- .Mnemonic("unique", "1")
- .Mnemonic("all","2")
- .Attribute("performance", Scan_XML_Performance, false)
- .Attribute("gbudb", Scan_XML_GBUdb, false)
- .End("xml")
- .Element("xheaders")
- .atStartCall(XHDRSymbolHeadersInitializer)
- .Element("output")
- .Attribute("mode", XHDROutput_Mode, LogOutputMode_None)
- .Mnemonic("none", "0")
- .Mnemonic("api", "1")
- .Mnemonic("file", "2")
- .Mnemonic("inject", "3")
- .End("output")
- .Element("symbol", XHDRSymbolHeaders.Header, "")
- .atEndCall(XHDRSymbolHeaders)
- .Attribute("on-off", XHDRSymbolHeaders.OnOff, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("n", XHDRSymbolHeaders.Symbol, -1)
- .End("symbol")
- .Element("version", XHDRVersion_Header, "")
- .Attribute("on-off", XHDRVersion_OnOff, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .End("version")
- .Element("license", XHDRLicense_Header, "")
- .Attribute("on-off", XHDRLicense_OnOff, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .End("license")
- .Element("rulebase", XHDRRulebase_Header, "")
- .Attribute("on-off", XHDRRulebase_OnOff, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .End("rulebase")
- .Element("identifier", XHDRIdentifier_Header, "")
- .Attribute("on-off", XHDRIdentifier_OnOff, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .End("identifier")
- .Element("gbudb", XHDRGBUdb_Header, "")
- .Attribute("on-off", XHDRGBUdb_OnOff, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .End("gbudb")
- .Element("result", XHDRResult_Header, "")
- .Attribute("on-off", XHDRResult_OnOff, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .End("result")
- .Element("matches", XHDRMatches_Header, "")
- .Attribute("on-off", XHDRMatches_OnOff, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .End("matches")
- .Element("black", XHDRBlack_Header, "")
- .Attribute("on-off", XHDRBlack_OnOff, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .End("black")
- .Element("white", XHDRWhite_Header, "")
- .Attribute("on-off", XHDRWhite_OnOff, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .End("white")
- .Element("clean", XHDRClean_Header, "")
- .Attribute("on-off", XHDRClean_OnOff, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .End("clean")
- .End("xheaders")
- .End("scan")
- .End("logs")
- .Element("network")
- .Element("sync")
- .Attribute("secs", network_sync_secs, 30)
- .Attribute("host", network_sync_host, "sync.messagesniffer.net")
- .Attribute("port", network_sync_port, 25)
- .End("sync")
- .Element("update-script")
- .Attribute("on-off", update_script_on_off, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("call", update_script_call, "")
- .Attribute("guard-time", update_script_guard_time, 180)
- .End("update-script")
- .End("network")
- .Element("xci")
- .Attribute("on-off", XCI_OnOff, true)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("port", XCI_Port, 9001)
- .End("xci")
- .Element("gbudb")
- .Element("database")
- .Element("condense")
- .Attribute("minimum-seconds-between", gbudb_database_condense_minimum_seconds_between, 600)
- .Element("time-trigger")
- .Attribute("on-off", gbudb_database_condense_time_trigger_on_off, true)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("seconds", gbudb_database_condense_time_trigger_seconds, 84600)
- .End("time-trigger")
- .Element("posts-trigger")
- .Attribute("on-off", gbudb_database_condense_posts_trigger_on_off, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("posts", gbudb_database_condense_posts_trigger_posts, 32768)
- .End("posts-trigger")
- .Element("records-trigger")
- .Attribute("on-off", gbudb_database_condense_records_trigger_on_off, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("records", gbudb_database_condense_records_trigger_records, 150000)
- .End("records-trigger")
- .Element("size-trigger")
- .Attribute("on-off", gbudb_database_condense_size_trigger_on_off, false)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("megabytes", gbudb_database_condense_size_trigger_megabytes, 150)
- .End("size-trigger")
- .End("condense")
- .Element("checkpoint")
- .Attribute("on-off", gbudb_database_checkpoint_on_off, true)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("secs", gbudb_database_checkpoint_secs, 3600)
- .End("checkpoint")
- .End("database")
- .Element("regions")
- .Element("white")
- .atStartCall(WhiteRangeInitializer)
- .Attribute("on-off", WhiteRangeHandler.On_Off, true)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("symbol", WhiteRangeHandler.Symbol, 0)
- .Attribute("priority", WhiteRangeHandler.Priority, 1)
- .Element("edge")
- .atEndCall(WhiteRangeHandler)
- .Attribute("probability", WhiteRangeHandler.EdgeInput.Probability, 0.0)
- .Attribute("confidence", WhiteRangeHandler.EdgeInput.Confidence, 0.0)
- .End("edge")
- .Element("panic")
- .Attribute("on-off", gbudb_regions_white_panic_on_off, true)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("rule-range", gbudb_regions_white_panic_rule_range, 1000)
- .End("panic")
- .End("white")
- .Element("black")
- .atStartCall(BlackRangeInitializer)
- .Attribute("on-off", BlackRangeHandler.On_Off, true)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("symbol", BlackRangeHandler.Symbol, 63)
- .mapTo(gbudb_regions_black_truncate_symbol, 63)
- .Attribute("priority", BlackRangeHandler.Priority, 2)
- .Element("edge")
- .atEndCall(BlackRangeHandler)
- .Attribute("probability", BlackRangeHandler.EdgeInput.Probability, 0.0)
- .Attribute("confidence", BlackRangeHandler.EdgeInput.Confidence, 0.0)
- .End("edge")
- .Element("truncate")
- .Attribute("on-off", gbudb_regions_black_truncate_on_off, true)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("probability", gbudb_regions_black_truncate_probability, 0.5)
- .Attribute("peek-one-in", gbudb_regions_black_truncate_peek_one_in, 3)
- .Attribute("symbol", gbudb_regions_black_truncate_symbol, 63)
- .End("truncate")
- .Element("sample")
- .Attribute("on-off", gbudb_regions_black_sample_on_off, true)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("probability", gbudb_regions_black_sample_probability, 0.5)
- .Attribute("grab-one-in", gbudb_regions_black_sample_grab_one_in, 10)
- .Attribute("passthrough", gbudb_regions_black_sample_passthrough, false)
- .Attribute("passthrough-symbol", gbudb_regions_black_sample_passthrough_symbol, 0)
- .End("sample")
- .End("black")
- .Element("caution")
- .atStartCall(CautionRangeInitializer)
- .Attribute("on-off", CautionRangeHandler.On_Off, true)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Attribute("symbol", CautionRangeHandler.Symbol, 30)
- .Attribute("priority", CautionRangeHandler.Priority, 3)
- .Element("edge")
- .atEndCall(CautionRangeHandler)
- .Attribute("probability", CautionRangeHandler.EdgeInput.Probability, 0.0)
- .Attribute("confidence", CautionRangeHandler.EdgeInput.Confidence, 0.0)
- .End("edge")
- .End("caution")
- .End("regions")
- .Element("training")
- .atStartCall(HeaderDirectivesInitializer)
- .Attribute("on-off", GBUdbTrainingOn_Off, true)
- .Mnemonic("on", "true")
- .Mnemonic("off", "false")
- .Element("source")
- .Element("header")
- .atStartCall(HDSourceHeaderInitializer)
- .atEndCall(HeaderDirectivesHandler)
- .Attribute("name", HeaderDirectivesHandler.DirectiveInput.Header, "\n\n")
- .Attribute("received", HeaderDirectivesHandler.ContextInput.Contains, "\n\n")
- .Attribute("ordinal", HeaderDirectivesHandler.ContextInput.Ordinal, 0)
- .End("header")
- .End("source")
- .Element("drilldown")
- .Element("received")
- .atStartCall(HDDrilldownInitializer)
- .atEndCall(HeaderDirectivesHandler)
- .Attribute("ordinal", HeaderDirectivesHandler.DirectiveInput.Ordinal, 0)
- .Attribute("find", HeaderDirectivesHandler.DirectiveInput.Contains, "\n\n")
- .End("received")
- .End("drilldown")
- .Element("bypass")
- .atStartCall(TrainingBypassRuleInitializer)
- .Element("result")
- .atEndCall(TrainingBypassRuleHandler)
- .Attribute("code", TrainingBypassRuleHandler.IntegerInput,-1)
- .End("result")
- .Element("header")
- .atStartCall(HDBypassHeaderInitializer)
- .atEndCall(HeaderDirectivesHandler)
- .Attribute("name", HeaderDirectivesHandler.DirectiveInput.Header, "\n\n")
- .Attribute("ordinal", HeaderDirectivesHandler.DirectiveInput.Ordinal, 0)
- .Attribute("find", HeaderDirectivesHandler.DirectiveInput.Contains, "\n\n")
- .End("header")
- .End("bypass")
- .Element("white")
- .atStartCall(TrainingWhiteRuleInitializer)
- .Element("result")
- .atEndCall(TrainingWhiteRuleHandler)
- .Attribute("code", TrainingWhiteRuleHandler.IntegerInput,-1)
- .End("result")
- .Element("header")
- .atStartCall(HDWhiteHeaderInitializer)
- .atEndCall(HeaderDirectivesHandler)
- .Attribute("name", HeaderDirectivesHandler.DirectiveInput.Header, "\n\n")
- .Attribute("ordinal", HeaderDirectivesHandler.DirectiveInput.Ordinal, 0)
- .Attribute("find", HeaderDirectivesHandler.DirectiveInput.Contains, "\n\n")
- .End("header")
- .End("white")
- .End("training")
- .End("gbudb")
- .Element("rule-panics")
- .atStartCall(RulePanicInitializer)
- .Element("rule")
- .atEndCall(RulePanicHandler)
- .Attribute("id", RulePanicHandler.IntegerInput, -1)
- .End("rule")
- .End("rule-panics")
- .Element("platform", PlatformElementContents, "")
- .End("platform")
- .Element("msg-file")
- .Attribute("type", MessageFileTypeCGP_on_off, false)
- .Mnemonic("cgp", "true")
- .End("msg-file")
- .End("node")
- .End("snf");
- }
-
- void fixPathTermination(std::string& s) { // Ensure s ends in a / or a \ as needed.
-
- if(0 == s.length()) return; // If the string is empty we do nothing.
-
- // Determine what our path terminator should be by looking to
- // see what separator has already been used.
-
- char Terminator; // This will be our terminator.
- if(std::string::npos == s.find('\\')) { // If we're not using a backslash then
- Terminator = '/'; // we will use the forward slash.
- } else { // If we are using the backslash then
- Terminator = '\\'; // we will remain consistent and terminate
- } // with a backslash.
-
- // If the path that's given doesn't have a terminator then we will add
- // the appropriate separator to the end.
-
- if( // If the string is
- '\\' != s.at(s.length()-1) && // not terminated by a backslash nor
- '/' != s.at(s.length()-1) // by a forward slash then
- ) { // we will append an appropriate
- s.append(1,Terminator); // terminator. Otherwise we will
- } // leave it as it is.
- }
-
- void snfCFGData::initializeFromFile(const char* FileName) { // Initialize from the provided file.
- cd::ConfigurationData MyCFGData(FileName); // Create a cfg data object from the file.
- if(0 == MyCFGData.Data(0)) throw false; // If we didn't read a config file throw!
- MyCFGReader.initialize(); // Initialize to defaults.
- MyCFGReader.interpret(MyCFGData); // Interpret the data.
- fixPathTermination(paths_log_path); // Automagically fix / or \ termination
- fixPathTermination(paths_rulebase_path); // for the paths provided in the
- fixPathTermination(paths_workspace_path); // configuration <path/> section.
- ConfigFilePath = FileName; // Set the ConfigFilePath for what we read.
- }
-
- snfIPRange snfCFGData::RangeEvaluation(GBUdbRecord& R) { // Returns the range for a GBUdbRecord.
-
- if(Good == R.Flag()) { // If the flag on the IP is Good
- return White; // then this IP is automatically white.
- } else
- if(Bad == R.Flag()) { // If the flag on this IP is Bad
- if(true == gbudb_regions_black_truncate_on_off) { // and truncate is turned on then
- return Truncate; // the IP is automatically in the
- } else { // truncate range. If truncate is off
- return Black; // then this IP is automatically black.
- }
- }
- // If it's not so simple then get a
- RangePoint P(R.Confidence(), R.Probability()); // range point and evaluate it that way.
- return RangeEvaluation(P);
- }
-
- snfIPRange snfCFGData::RangeEvaluation(RangePoint& p) { // Returns the range for a RangePoint.
- if( // If the IP is unknown, indicated
- 0.0 == p.Confidence && // by a zero confidence and
- 0.0 == p.Probability // a zero probability, then
- ) { // the range point cannot be "in"
- return New; // any range.
- }
-
- if(WhiteRangeHandler.isInWhite(p)) { // If it's in the white range,
- return White; // return White.
- } else // White has priority over all others.
- if(BlackRangeHandler.isInBlack(p)) { // If it's in the black range then
- if(p.Probability >= gbudb_regions_black_truncate_probability) { // determine if it's also in the truncate
- return Truncate; // range, and if so - send back Truncate.
- } else { // If not then we can send back a
- return Black; // normal black result.
- }
- } else // Black takes precedence over caution.
- if(CautionRangeHandler.isInBlack(p)) { // If we're in the caution range
- return Caution; // then return caution.
- } // If none of those ranges matched then
- return Normal; // the IP is in the normal range.
- }
-
- //// snfCFGmgr /////////////////////////////////////////////////////////////////
-
- void snfCFGmgr::initialize( // Initialize our configuration data.
- const char* FileName,
- const char* LicenseId,
- const char* Authentication) {
-
- // Check for NULLs and assign Init parameters
-
- InitFileName = (NULL==FileName)?"":FileName; // Initilization parameters are reused
- InitLicenseId = (NULL==LicenseId)?"":LicenseId; // any time load() is called.
- InitAuthentication = (NULL==Authentication)?"":Authentication;
- }
-
- //*****************************************************************************
- //// IMPORTANT: If the authentication string is provided in the initialize() it
- //// MUST NOT be put into D.node_authentication.
- //*****************************************************************************
-
- //// When the license ID and security string come from an OEM application they
- //// may not appear in the configuration files. If that is the case we will assume
- //// that they developer wants to keep the security string secret by encrypting it
- //// in their application and providing it to SNF at runtime. In that case we will
- //// not display the security key in the configuration log.
- ////
- //// To prevent hacking attempts, if the authentication information appears to be
- //// provided by configuration data then we will build the string from that data.
- //// that way an attacker can't trick the application into disclosing the true
- //// authentication string -- they will only get out what they put in.
-
- std::string SecurityKeyDisplayString(snfCFGData& D) { // Returns appropriate SecurityKey: data
- std::string ConfigLogSecurityKey = "************************"; // Start with a masked display.
- if(0 < D.node_authentication.length()) { // If auth info is in the config files then
- ConfigLogSecurityKey = D.node_licenseid + D.node_authentication; // build up the key from that data so it
- } // can be displayed in the config log.
- return ConfigLogSecurityKey;
- }
-
- void logCFGData(snfCFGData& D) { // Log interpreted cfg data (debug aid).
-
- try {
- std::string CFGLogPath; // Build the snf_cfg log path.
- CFGLogPath = D.paths_log_path +
- D.node_licenseid + "_snf_engine_cfg.log";
-
- std::ofstream cfgl(CFGLogPath.c_str(), std::ios::trunc); // Open and truncate the cfg log file.
- cfgl // Report important cfg information.
- << "SNF Engine Configuration" << std::endl
- << "____________" << std::endl
- << "Fundamentals" << std::endl
- << " License: " << D.node_licenseid << std::endl
- << " ConfigFilePath: " << D.ConfigFilePath << std::endl
- << " IdentityFilePath: " << D.node_identity << std::endl
- << " SecurityKey: " << SecurityKeyDisplayString(D) << std::endl
- << "_____" << std::endl
- << "Paths" << std::endl
- << " Log Path: " << D.paths_log_path << std::endl
- << " Rulebase Path: " << D.paths_rulebase_path << std::endl
- << " Workspace Path: " << D.paths_workspace_path << std::endl
- << " RuleFilePath: " << D.RuleFilePath << std::endl
- << "____" << std::endl
- << "Logs" << std::endl
- << std::endl
- << " Rotation-Midnight: " << ((D.Logs_Rotation_LocalTime_OnOff)? "Local" : "UTC") << std::endl
- << " ______" << std::endl
- << " Status" << std::endl
- << " PerSecond: "
- << ((D.Status_SecondReport_Log_OnOff)? "yes, " : "no, ")
- << "Append: "
- << ((D.Status_SecondReport_Append_OnOff)? "yes" : "no")
- << std::endl
- << " PerMinute: "
- << ((D.Status_MinuteReport_Log_OnOff)? "yes, " : "no, ")
- << "Append: "
- << ((D.Status_MinuteReport_Append_OnOff)? "yes" : "no")
- << std::endl
- << " PerHour: "
- << ((D.Status_HourReport_Log_OnOff)? "yes, " : "no, ")
- << "Append: "
- << ((D.Status_HourReport_Append_OnOff)? "yes" : "no")
- << std::endl
- << " ____" << std::endl
- << " Scan" << std::endl
- << " Identifier: "
- << ((D.Scan_Identifier_Force_Message_Id)? "Force RFC822 Message-ID" : "Use Provided Identifier")
- << std::endl
- << " Classic: Output-"
- << ((LogOutputMode_None == D.Scan_Classic_Mode)? "None, " :
- ((LogOutputMode_API == D.Scan_Classic_Mode)? "API, " :
- ((LogOutputMode_File == D.Scan_Classic_Mode)? "File, " : "Error!")))
- << ((D.Scan_Classic_Rotate)? "Rotating, ": "Non-Rotating, ")
- << ((D.Scan_Classic_Matches == ScanLogMatches_None) ? "No Mathes":
- ((D.Scan_Classic_Matches == ScanLogMatches_Unique) ? "Unique Matches":
- ((D.Scan_Classic_Matches == ScanLogMatches_All) ? "All Matches" : "Error!")))
- << std::endl
- << " XML: Output-"
- << ((LogOutputMode_None == D.Scan_XML_Mode)? "None, " :
- ((LogOutputMode_API == D.Scan_XML_Mode)? "API, " :
- ((LogOutputMode_File == D.Scan_XML_Mode)? "File, " : "Error!")))
- << ((D.Scan_XML_Rotate)? "Rotating, ": "Non-Rotating, ")
- << ((D.Scan_XML_Matches == ScanLogMatches_None) ? "No Mathes, ":
- ((D.Scan_XML_Matches == ScanLogMatches_Unique) ? "Unique Matches, ":
- ((D.Scan_XML_Matches == ScanLogMatches_All) ? "All Matches, " : "Match Error! ")))
- << ((D.Scan_XML_Performance)? "Performance Metrics, " : "No Performance Metrics, ")
- << ((D.Scan_XML_GBUdb)? "GBUdb Data" : "No GBUdb Data")
- << std::endl
- << " XHeaders:" << std::endl
- << " Output: "
- << ((LogOutputMode_None == D.XHDROutput_Mode) ? "None" :
- ((LogOutputMode_API == D.XHDROutput_Mode) ? "API" :
- ((LogOutputMode_File == D.XHDROutput_Mode) ? "File" :
- ((LogOutputMode_Inject == D.XHDROutput_Mode)? "Inject" : "Error!"))))
- << std::endl
- << " Version: "
- << ((D.XHDRVersion_OnOff)? "On, " : "Off, ")
- << D.XHDRVersion_Header
- << std::endl
- << " License: "
- << ((D.XHDRLicense_OnOff)? "On, " : "Off, ")
- << D.XHDRLicense_Header
- << std::endl
- << " Rulebase: "
- << ((D.XHDRRulebase_OnOff)? "On, " : "Off, ")
- << D.XHDRRulebase_Header
- << std::endl
- << " Identifier: "
- << ((D.XHDRIdentifier_OnOff)? "On, " : "Off, ")
- << D.XHDRIdentifier_Header
- << std::endl
- << " GBUdb: "
- << ((D.XHDRGBUdb_OnOff)? "On, " : "Off, ")
- << D.XHDRGBUdb_Header
- << std::endl
- << " Result: "
- << ((D.XHDRResult_OnOff)? "On, " : "Off, ")
- << D.XHDRResult_Header
- << std::endl
- << " Matches: "
- << ((D.XHDRMatches_OnOff)? "On, " : "Off, ")
- << D.XHDRMatches_Header
- << std::endl
- << " Black: "
- << ((D.XHDRBlack_OnOff)? "On, " : "Off, ")
- << D.XHDRBlack_Header
- << std::endl
- << " White: "
- << ((D.XHDRWhite_OnOff)? "On, " : "Off, ")
- << D.XHDRWhite_Header
- << std::endl
- << " Clean: "
- << ((D.XHDRClean_OnOff)? "On, " : "Off, ")
- << D.XHDRClean_Header
- << std::endl;
-
- for(
- std::set<XHDRSymbol>::iterator iH = D.XHDRSymbolHeaders.SymbolHeaders.begin();
- iH != D.XHDRSymbolHeaders.SymbolHeaders.end(); iH++
- ) {
- cfgl
- << " Symbol: "
- << (*iH).Symbol << ", "
- << (*iH).Header
- << std::endl;
- }
-
- cfgl
- << "_______" << std::endl
- << "Network" << std::endl
- << " Sync Host: " << D.network_sync_host << std::endl
- << " Sync Port: " << D.network_sync_port << std::endl
- << " Sync Secs: " << D.network_sync_secs << std::endl
- << " _____________" << std::endl
- << " Update-Script" << std::endl
- << " On-Off: " << ((D.update_script_on_off) ? "On" : "Off") << std::endl
- << " Script: " << D.update_script_call << std::endl
- << " Guard-Time: " << D.update_script_guard_time << " seconds" << std::endl
- << "___" << std::endl
- << "XCI" << std::endl
- << " " << ((D.XCI_OnOff)? "Enabled" : "Disabled") << std::endl
- << " Port: " << D.XCI_Port << std::endl
- << "_____" << std::endl
- << "GBUdb" << std::endl
- << " ____________" << std::endl
- << " Condensation" << std::endl
- << " Minimum-Seconds-Between = " << D.gbudb_database_condense_minimum_seconds_between << std::endl
- << " Time-Trigger: "
- << ((D.gbudb_database_condense_time_trigger_on_off)? "on, " : "off, ")
- << D.gbudb_database_condense_time_trigger_seconds << " seconds" << std::endl
- << " Posts-Trigger: "
- << ((D.gbudb_database_condense_posts_trigger_on_off)? "on, " : "off, ")
- << D.gbudb_database_condense_posts_trigger_posts << " posts" << std::endl
- << " Records-Trigger: "
- << ((D.gbudb_database_condense_records_trigger_on_off) ? "on, " : "off, ")
- << D.gbudb_database_condense_records_trigger_records << " records" << std::endl
- << " Size-Trigger: "
- << ((D.gbudb_database_condense_size_trigger_on_off) ? "on, " : "off, ")
- << D.gbudb_database_condense_size_trigger_megabytes << " megabytes" << std::endl
- << " __________" << std::endl
- << " Checkpoint" << std::endl
- << " Checkpoint: "
- << ((D.gbudb_database_checkpoint_on_off) ? "on, " : "off, ")
- << D.gbudb_database_checkpoint_secs << " seconds" << std::endl
- << " ______" << std::endl
- << " Ranges" << std::endl
- << " White: "
- << ((D.WhiteRangeHandler.On_Off) ? "on, " : "off, ")
- << "Symbol " << D.WhiteRangeHandler.Symbol << std::endl
- << " Auto-Panic: "
- << ((D.gbudb_regions_white_panic_on_off) ? "on, " : "off, ")
- << "Range " << D.gbudb_regions_white_panic_rule_range << std::endl
- << std::endl
- << " Caution: "
- << ((D.CautionRangeHandler.On_Off) ? "on, " : "off, ")
- << "Symbol " << D.CautionRangeHandler.Symbol << std::endl
- << std::endl
- << " Black: "
- << ((D.BlackRangeHandler.On_Off) ? "on, " : "off, ")
- << "Symbol " << D.BlackRangeHandler.Symbol << std::endl
- << " Truncate: "
- << ((D.gbudb_regions_black_truncate_on_off) ? "on, " : "off, ")
- << "Probability " << D.gbudb_regions_black_truncate_probability << ", "
- << "Peek-One-In " << D.gbudb_regions_black_truncate_peek_one_in << ", "
- << "Symbol " << D.gbudb_regions_black_truncate_symbol << std::endl
- << " Sample: "
- << ((D.gbudb_regions_black_sample_on_off) ? "on, " : "off, ")
- << "Probability: " << D.gbudb_regions_black_sample_probability << ", "
- << "Grab-One-In: " << D.gbudb_regions_black_sample_grab_one_in << ", " << std::endl
- << " Passthrough: "
- << ((D.gbudb_regions_black_sample_passthrough) ? "yes, " : "no, ")
- << "Passthrough Symbol " << D.gbudb_regions_black_sample_passthrough_symbol << std::endl
- << std::endl
- << " Range Map - [W]hite [B]lack [C]aution [ ]undefined" << std::endl << std::endl
- << " |-9876543210123456789+|" << std::endl;
-
- // Output GBUdb Range Map
-
- for(double c = 0; c < 1.01; c+=0.1) { // Run through the confidence
- cfgl << " |";
- for(double p = -1.0; p < 1.01; p+=0.1) { // and probability ranges.
- RangePoint t(c,p); // Test the range point w/ c & p
- if(D.WhiteRangeHandler.isInWhite(t)) { // If it's in the white range
- cfgl << "W"; // put in a W.
- } else
- if(D.BlackRangeHandler.isInBlack(t)) { // If it's in the black range
- cfgl << "B"; // put in a B.
- } else
- if(D.CautionRangeHandler.isInBlack(t)) { // If it's in the caution range
- cfgl << "C"; // put in a C.
- } else {
- cfgl << " "; // Otherwise put in a space.
- }
- }
- cfgl << "|" << c << std::endl;
- }
- cfgl << " |---------------------|" << std::endl;
-
- cfgl
- << std::endl
- << " ________" << std::endl
- << " Training" << std::endl
- << " GBUdb Updates: "
- << ((D.GBUdbTrainingOn_Off)? "Enabled" : "Disabled") << std::endl
- << std::endl;
-
- cfgl
- << " Source Header Directives: " << std::endl;
- for(
- HeaderDirectiveSet::iterator iD = D.HeaderDirectivesHandler.HeaderDirectives.begin();
- iD != D.HeaderDirectivesHandler.HeaderDirectives.end(); iD++
- ) {
- const HeaderFinderPattern& Dx = *iD;
- if(HeaderDirectiveContext == Dx.Directive) {
- cfgl
- << " "
- << "Context " << Dx.Context << " is a "
- << Dx.Header << " header at"
- << " Ordinal " << Dx.Ordinal
- << " that Contains " << Dx.Contains << std::endl;
- } else
- if(HeaderDirectiveSource == Dx.Directive) {
- cfgl
- << " "
- << "Context " << Dx.Context << " Source ip is in "
- << Dx.Header << " header at"
- << " Ordinal " << Dx.Ordinal << std::endl;
- }
- }
- cfgl << std::endl;
-
- cfgl
- << " Drilldown Header Directives: " << std::endl;
- for(
- HeaderDirectiveSet::iterator iD = D.HeaderDirectivesHandler.HeaderDirectives.begin();
- iD != D.HeaderDirectivesHandler.HeaderDirectives.end(); iD++
- ) {
- const HeaderFinderPattern& Dx = *iD;
- if(HeaderDirectiveDrillDown == Dx.Directive) {
- cfgl
- << " "
- << Dx.Header << " header at"
- << " Ordinal " << Dx.Ordinal
- << " Contains " << Dx.Contains << std::endl;
- }
- }
- cfgl << std::endl;
-
- cfgl
- << " Bypass Header Directives: " << std::endl;
- for(
- HeaderDirectiveSet::iterator iD = D.HeaderDirectivesHandler.HeaderDirectives.begin();
- iD != D.HeaderDirectivesHandler.HeaderDirectives.end(); iD++
- ) {
- const HeaderFinderPattern& Dx = *iD;
- if(HeaderDirectiveBypass == Dx.Directive) {
- cfgl
- << " "
- << Dx.Header << " header at"
- << " Ordinal " << Dx.Ordinal
- << " Contains " << Dx.Contains << std::endl;
- }
- }
- cfgl << std::endl;
-
- cfgl
- << " White Rule Header Directives: " << std::endl;
- for(
- HeaderDirectiveSet::iterator iD = D.HeaderDirectivesHandler.HeaderDirectives.begin();
- iD != D.HeaderDirectivesHandler.HeaderDirectives.end(); iD++
- ) {
- const HeaderFinderPattern& Dx = *iD;
- if(HeaderDirectiveWhite == Dx.Directive) {
- cfgl
- << " "
- << Dx.Header << " header at"
- << " Ordinal " << Dx.Ordinal
- << " Contains " << Dx.Contains << std::endl;
- }
- }
- cfgl << std::endl;
-
- cfgl
- << " White Rule Symbols: ";
-
- // Output white rule symbols
-
- for(
- std::set<int>::iterator ix = D.TrainingWhiteRuleHandler.IntegerSet.begin();
- ix != D.TrainingWhiteRuleHandler.IntegerSet.end();
- ix ++) {
- if(D.TrainingWhiteRuleHandler.IntegerSet.begin() != ix) {
- cfgl << ", ";
- }
- cfgl << (*ix);
- }
- cfgl << std::endl;
-
- // Rule Panics
-
- cfgl
- << "___________" << std::endl
- << "Rule-Panics" << std::endl;
-
- for(
- std::set<int>::iterator ix = D.RulePanicHandler.IntegerSet.begin();
- ix != D.RulePanicHandler.IntegerSet.end();
- ix ++) {
- cfgl << " Rule ID: " << (*ix) << std::endl;
- }
- cfgl << std::endl;
-
- cfgl
- << "___________" << std::endl
- << "Integration" << std::endl
- << std::endl
- << " Message Format: "
- << ((D.MessageFileTypeCGP_on_off)? "CGP" : "RFC822")
- << std::endl;
-
- #ifdef __BIG_ENDIAN__
-
- cfgl << " Rulebase Conversion: BIG ENDIAN" << std::endl;
-
- #else
-
- cfgl << " Rulebase Conversion: LITTLE ENDIAN" << std::endl;
-
- #endif
-
- cfgl
- << "________" << std::endl
- << "Platform" << std::endl
- << D.PlatformElementContents
- << std::endl;
-
- cfgl << std::endl; // End with a new line.
- cfgl.close(); // Close the cfg log file.
- } catch (...) {} // Ignore any errors.
- }
-
- void snfCFGmgr::load() {
-
- // What shall we configure -- the inactive snfCFGData.
-
- snfCFGData& CFGData = InactiveData();
-
- // How shall we configure?
- // If FileName ends in .snf then find the .cfg file for details.
- // If the FileName ends some other way it _should_ be our cfg file.
-
- int PathLength = InitFileName.length(); // How long is the path?
- const int MinimumPathLength = 12; // Must be at least licensid.snf long.
- if(MinimumPathLength > PathLength) throw LoadFailure(); // Path length is impossible? throw!
- const std::string SNFExt = ".snf"; // The extension we are looking for.
- const std::string CFGExt = ".xml"; // The default cfg extension.
- const int SNFExtLength = SNFExt.length(); // The length of the extension.
- int SNFExtPosition = InitFileName.rfind(SNFExt,PathLength); // Find the extension at the end.
-
- bool InitPathIsRulebase = false; // Was the init FileName the Rulebase?
- bool InitLicenseIdIsProvided = (0 < InitLicenseId.length()); // Was the init LicenseId provided?
- bool InitAuthenticationIsProvided = (0 < InitAuthentication.length()); // Was the authentication provided?
-
- if((PathLength - SNFExtLength) == SNFExtPosition) { // If path ends in .snf then
- InitPathIsRulebase = true; // set our flag to keep track then set
- ConfigurationPath = InitFileName.substr(0,SNFExtPosition); // our configuration path as the init
- ConfigurationPath.append(CFGExt); // file name with the config extension.
- } else { // If the init file is not a rulebase
- ConfigurationPath = InitFileName; // then it is the config file name.
- }
-
- // At this point we know where to read our configuration from.
-
- try { CFGData.initializeFromFile(ConfigurationPath.c_str()); } // Initialize the inactive config.
- catch(...) { // If that failed then throw.
- throw LoadFailure();
- }
-
- // Now that the main config has been read we create the derived cfg data.
- // Anything that was provided in Init takes precedence over the config.
-
- //// SecurityKey
- //// If an identity path has been provided we must load that data.
-
- if(0 < CFGData.node_identity.length()) { // If an identity path was provided
- cd::ConfigurationData Identity(CFGData.node_identity.c_str()); // then get the data from that file.
- cd::ConfigurationElement IdentityReader("snf"); // Create an Identity reader and
- IdentityReader // configure it.
- .Element("identity")
- .Attribute("licenseid", CFGData.node_licenseid)
- .Attribute("authentication", CFGData.node_authentication)
- .End("identity")
- .End("snf");
- IdentityReader.interpret(Identity); // Then read the data.
- }
-
- //// The SecurityKey is built from the licenseID and the Authentication
-
- if(InitLicenseIdIsProvided) { // If the LicenseID is OEM provided then
- CFGData.SecurityKey = InitLicenseId; // the first part of our security key is that.
- CFGData.node_licenseid = InitLicenseId; // Also override any file-loaded license ID.
- } else { // If it was not provided then we will get
- CFGData.SecurityKey = CFGData.node_licenseid; // the LicenseID from our config file.
- }
-
- std::string LicenseIDToUse = CFGData.SecurityKey; // Grab the License ID we want to use.
-
- if(InitAuthenticationIsProvided) { // If the Authentication has been provided then
- CFGData.SecurityKey += InitAuthentication; // we use it for the second part of our
- } else { // security key. Otherwise we will get the
- CFGData.SecurityKey += CFGData.node_authentication; // Authentication from the config file.
- }
-
- //// RuleFilePath
-
- if(InitPathIsRulebase) { // If the Rulebase path was provided
- CFGData.RuleFilePath = InitFileName; // then we have our rulebase path.
- } else { // If not then we must figure it out...
- CFGData.RuleFilePath = // We build the path from the base
- CFGData.paths_rulebase_path + // rulebase path concattonated with
- LicenseIDToUse + // the license id concattonated with
- SNFExt; // the rulebase extension.
- }
-
- // Once all of the configuration data is correct we make it active.
-
- swapCFGData(); // Then swap it into the active state.
-
- // Log the configuration data as it was interpreted.
-
- logCFGData(ActiveData());
-
- }
|