Included with this distribution are the open-source "wget" and "gzip" files. They are | |||||
used in getRulebase.bat to download and decompress rulebase files. The "wget" and "gzip" | |||||
utilities included here came from http://unxutils.sourceforge.net/ and are included only | |||||
for your convenience. |
SNF MDaemon Plugin Change Log... | |||||
------------------------------------------------------------------------------ | |||||
20080626 - Version 3.0, It's official. | |||||
Changed build information. | |||||
Removed extraneous comments from configuration file. | |||||
20080524 - Version V2-9rc6.25.7 | |||||
Optimized networking library for additional speed & stability by moving | |||||
receive buffer allocation from heap to stack (automatic). | |||||
Optimized timing parameters in SNFClient for improved speed. Polling dealys | |||||
are now reduced to 10ms from 30ms. | |||||
Removed speed-bug in SNFClient, 100ms guard time between retries was always | |||||
executed after an attempt (even a successful attempt). The guard time is now | |||||
condition and only fires on unsuccessful attempts. | |||||
Updated XCI server logic to ensure non-blocking sockets for clients in all | |||||
socket implementations. | |||||
20080424 - Version V2-9rc6.24.6 | |||||
Refactored snfScanData.clear() to reduce heap work and fragments. | |||||
Added mutex to scanMessageFile() entry point just in case some app attempts to | |||||
put multiple threads through a single engine handler. scanMessage() is already | |||||
protected and fully wraped by the new scanMessageFile() mutex. | |||||
Added non-specific runtime exception handling to XHDR injection code. | |||||
Added 2 retries w/ 300ms delay to remove original message in XHDR inject code. | |||||
If remove fails after 3 attempts the injector throws. | |||||
Added 2 retries w/ 300ms delay to rename temp file to msg in XHDR inject code. | |||||
If rename fails after 3 attempts the injector throws. | |||||
Added IPTest logging. | |||||
20080416 - Version V2-9rc5.23.6 | |||||
Fixed bug where SNCY open() would fail on some Win* platforms with | |||||
WSAEINVAL instead of the standard EINPROGRESS or EALREADY which were expected. | |||||
Also added WSAEWOULDBLOCK to cover other "ambiguities" in windows sockets | |||||
implementations. InProgress() on Win* now test for any of: | |||||
WSAEINPROGRESS, WSAEALREADY, WSAEWOULDBLOCK, WSAEINVAL | |||||
20080413 - Version V2-9rc5.22.6 | |||||
Fixed bug in TCPHost.open() where EALREADY was not counted as a version of | |||||
EINPROGRESS. This would cause open() to throw an unnecessary exception when | |||||
an open() required extra time. | |||||
20080413 - Version V2-9rc5.21.6 | |||||
Extended timeout for SYNC session open() to the full session length. This way | |||||
if a session takes a long time to open it still has a shot at success. | |||||
20080411 - Version V2-9rc5.20.6 | |||||
Adjusted snfNETmgr to use non-blocking open in SYNC sessions. Open timeout | |||||
is 1/3 of the session timeout. Session timeout is 2 * Session pacing. Open | |||||
polling uses golden spiral delay from 10ms to 340ms. | |||||
20080410 - Version V2-9rc5.19.6 | |||||
Adjusted XCI manager to use new snfCFGPacket paradigm in checkCFG(). | |||||
Adjusted snf_RulebaseHandler::addRulePanic() to use MyMutex and eliminated | |||||
the AutoPanicMutex and waiting scheme. | |||||
Refactored scanMessage() to use a ScopeMutex() rather than lock()/unlock(). | |||||
Refactored scanMessage() to use MyCFGPacket.isRulePanic() test. | |||||
Redesigned snfCFGPacket handling to automate grab() / drop() functions. | |||||
Fixed lock-up bug: Redesigned AutoPanic posting and checking mechanisms to | |||||
eliminate potential dead-lock condition. Under some conditions a precisely | |||||
timed auto-panic posting could cause the RulebaesHandler mutex and the | |||||
AutoPanicMutex to become intertwined leading to a cascading deadlock. When | |||||
this occurred all XCI processing threads and eventually the XCI listener | |||||
thread would become blocked waiting to get the current configuration. | |||||
20080409 - Version V2-9rc5.18.6 | |||||
Enhanced XCI exception handling and logging to provide additional detail. | |||||
Added code to explicitely check for zero length files in scanMessagFile(). | |||||
Previously a zero length file would cause the CBFR module of the filter | |||||
chain to throw an invalid buffer exception. Now if the message file is empty | |||||
scanMessageFile() will throw a FileError stating FileEmpty!. | |||||
20080407 - Version V2-9rc5.17.6 | |||||
Enhanced exception reporting in snfXCImrg | |||||
20080405 - Version V2-9rc5.16.6 | |||||
Reduced safetly limits on status reports to 100K for status reports and 100K | |||||
for samples. Previous values were 10M. Most full sessions from the busiest | |||||
systems are < 50K total. | |||||
Recoded sendDataTimeout() to break uploads into 512 byte chunks and insert | |||||
delays only when a chunk is fragmented. This methodology improves reliability | |||||
on Win* systems without any significant penalty on systems that don't need | |||||
socket sends() to be in smaller chunks. | |||||
Fixed TCPClient::transmit() and TCPHost::transmit() bug where returned byte | |||||
count might be -1. Now returned byte counts can only be 0 or more. | |||||
20080403 - Version SNF2-9vr5.15.5 | |||||
Minor modifications to networking module to better support non-blocking open() | |||||
Updated SNFClient with new timing and non-blocking open(). Worst case return | |||||
time from SNFClient estimated at 200 seconds (theoretically impossible). No- | |||||
connection return time from SNFClient estimated at 20 seconds. | |||||
20080326 - Version SNF2-9rc4.15.4 | |||||
Refactored snfNETmgr::sync() to consolidate non-blocking io routines. | |||||
Added detailed thread status data to XCI listener thread. | |||||
Refactored snfNETmgr::sync() to check a Timeout, removed TCPWatchdog. | |||||
20080325 - Version SNF2-9rc4.12.4 | |||||
Added a "Rulebase Getter" feature as part of the snf_Reloader. When enabled | |||||
the Rulebase Getter will launch a user defineable system() call whenever a | |||||
new rulebase file is available. The call will be repeated until the condition | |||||
is cleared by a successful update of the rulebase file. The Rulebase Getter | |||||
will wait a configurable "guard time" between attempts. The default system() | |||||
call is "getRulebase" with a guard time of 3 minutes. In most cases this will | |||||
launch the provided getRulebase script which should be present in the start | |||||
location of SNFServer on most systems. Best practice is to configure the full | |||||
path to the update script. The system() call is made in a separate thread so | |||||
that if the system() call hangs for some reason only the Rulebase Getter is | |||||
stuck. | |||||
Improved exception handling/reporting in scanMessageFile(). | |||||
Updated scanMessagFile() header injection code to accommodate messages with | |||||
no body. Previous version would throw an exception when it could not find an | |||||
injection point. The new version makes the injection point byte 0 and puts | |||||
the injected headers at the top of the message using it's best guess about the | |||||
type of line endings (CRLF or LF) to use. | |||||
Updated Networking library to use SO_REUSEADDR by default on listeners. | |||||
20080319 - Version SNF2-9rc4.11 | |||||
Added IPScan on-off to snfmdplugin.xml. This allows users to turn off the | |||||
IPScan feature without editing the Plugins.dat file as was previously | |||||
required. The feature can now be enabled or disabled at will by editing the | |||||
configuration file. | |||||
Added Configuration editor options to snfmdplugin.xml. Previously the built- | |||||
in configuration function was hard coded to start notepad with the config | |||||
file. Now the system() call made by the ConfigFunc() can be edited in the | |||||
configuration file. The configuration file name can be appended to the | |||||
command optionally. The default is still to start notepad and append the | |||||
configuration file path so that it is loaded automatically. It is hoped that | |||||
GUI based configuration editors for the SNF plugin will be built by third | |||||
parties and in the mean time folks can now configure their favorite XML file | |||||
editor to modify their SNF plugin configuration. | |||||
Modified API use fixed shutdown bug - The plugin used to initialize the SNF | |||||
scanning engine when the DLL was loaded and would shut it down when the DLL | |||||
was unloaded. Now the Startup and Shutdown functions in the MDaemon plugin | |||||
API. This ensures that the engine components are started and shutdown in the | |||||
proper sequence. | |||||
Included new SNFEngine core (excerpts from that change log included). | |||||
20080318 - SNF2-9rc1.11.exe Consolidated several mods/fixes | |||||
Corrected scan error logging bug. Was posting <s/> now posts <e/>. | |||||
Updated scan error logging to be more uniform with non-scan errors. | |||||
Developed various script prototypes for postfix integration & automated | |||||
updates on win* systems using the new UpdateReady.txt file mechanism. | |||||
Fixed a bug in scanMessageFile() where an \n\n style insertion point | |||||
would never be detected. | |||||
Modified scanMessageFile() header injection to strip <CR> from line ends | |||||
when the message file provided does not use them. The line-end style of | |||||
the message file is detected while locating the insertion point. If the | |||||
insertion point (first blank line) does not use <CR><LF> then the SNF | |||||
generated X-Headers are stripped of <CR> in a tight loop before injection. | |||||
Enhanced error and exception reporting in SNFMulti.cpp scanMessageFile(). | |||||
Enhanced exception handling in networking module. All exceptions now | |||||
throw descriptive runtime_error exceptions. | |||||
20080306 - SNF2-9rc1.8.exe (FIRST RELEASE CANDIDATE for VERSION 3!) | |||||
Added Drilldown Header Directive Functions - When the candidate source IP | |||||
comes from a header matching a drilldown directive the IP is marked "Ignore" | |||||
in GBUdb and the candidate is no longer eligible to be the source for that | |||||
message. This allows SNF to follow the trusted chain of devices (by IP) down | |||||
to the actual source of the message. It is handy for ignoring net blocks | |||||
because it can match partial IPs but it is designed to allow SNF to learn | |||||
it's way through the servers at large ISPs so that the original source for | |||||
each message can be evaluated directly. | |||||
Added Source Header Directive Functions - This feature allows SNF to acquire | |||||
the source IP for a message from a specific header rather than searching | |||||
through the Received headers in the message. This is useful when the original | |||||
source for a message is not represented in Received headers. For example: | |||||
Hotmail places the originating source IP in a special header and does not | |||||
provide a Received header for that IP. This feature is protected from abuse | |||||
by a "Context" feature which only activates the source header directive when | |||||
specific content is found in a specific received header. Using the above | |||||
example, this feature can be configured so that a Hotmail source header would | |||||
only be read if the top Recieved header contained "hotmail.com [" indicating | |||||
that the ptr lookup for the header matched the hotmail domain. Note: When a | |||||
source is pulled from a header directive that source is put into a synthetic | |||||
Received header and injected into the scanning stream (not the message) as | |||||
the first Received header. | |||||
Added forced source IP to XCI - It is now possible to "inject" or "force" | |||||
the source IP for any message by providing that IP in the XCI request or | |||||
directly in a scan...() function call. This allows the calling application | |||||
to provide the source IP for a message ahead of any Received headers that | |||||
might be in the message. This is useful when the calling application knows | |||||
the original source IP for the message but that IP is not represented in | |||||
the Received headers and it is not desireable to use the Source Header | |||||
Directive mechanism. | |||||
Added forced source IP mode to SNFClient - It is now possible to call the | |||||
SNFClient utility with an IP4Address using the syntax: | |||||
SNFClient -source=12.34.56.78 | |||||
The -source mode of SNFClient exercises the forced source IP feature in | |||||
the XCI (see above) | |||||
Added Status Report features to SNFClient and XCI - It is now possible to | |||||
request the latest status.second, status.minute, or status.hour data via | |||||
the XCI and SNFClient. The syntax for requesting a status report using the | |||||
SNFClient is: | |||||
SNFClient -status.second | |||||
SNFClient -status.minute | |||||
SNFClient -status.hour | |||||
In addition to providing status reports the SNFClient in this mode will | |||||
return a nonzero value (usually 99) if it is unable to get a status report | |||||
from SNFServer. This feature can be used to verify that SNFServer is up | |||||
and responding. If SNFServer is OK then the result code returned is 0. | |||||
Added result codes to SNFClient -test and XCI IP test functions - The XCI | |||||
engine has been upgraded to provide the range value for the IP under test | |||||
as well as the symbolic result code associated with that range. This allows | |||||
the -test function to provide results that are consistent with the GBUdb | |||||
configuration without additional processing: For example, if the IP falls | |||||
in the Caution range then the Caution result code will be returned just | |||||
as if a message had been scanned with the same IP and no pattern match | |||||
occurred. The same is true for Truncate and Black range hits. | |||||
Added Timestamp and Command Line Parameter data to SNFClient.exe.err - When | |||||
an error occurs with SNFClient that may not appear in the SNFServer logs an | |||||
entry is appended to the SNFClient.exe.err file. That in itself is not new. | |||||
The new feature is that the entries added to the SNFClient.exe.err file now | |||||
include timestamp and command line data to aid in debugging. | |||||
Updated the Configuration Log to include all of the current configuration | |||||
features and to improve it's readability. | |||||
20080207 - SNF2-9b1.7.exe | |||||
SYNC Timeout now 2x SYNC Schedule | |||||
SNFServer now produces an UpdateReady.txt file when the UTC timestamp on | |||||
the SYNC server is newer than the UTC timestamp of the active rulebase. It | |||||
is presumed that a suitable update script or program will run periodically | |||||
and download a fresh rulebase file if the UpdateReady.txt file is present. | |||||
The update script should remove the UpdateReady.txt file when it completes | |||||
a successful download of the new rulebase file. | |||||
Added available rulebase UTC in status reports <udate utc.../> | |||||
Added Automatic path fixup for ending / or \ | |||||
Added option to use local time in log rotation <rotation localtime='no'/> | |||||
The default is still utc. | |||||
20071102 - SNF2-9b1.6.exe | |||||
Increased MAX_EVALS from 1024 to 2048. | |||||
Adjusted defult range envelopes in snf_engine.xml to be more conservative. | |||||
20071017 - Version SNF2-9b1.5 | |||||
Added a missing #include directive to the networking.hpp file. The | |||||
missing #include was not a factor on Linux and Windows systems but | |||||
caused compiler errors on BSD systems. | |||||
Corrected a bug in the GBUdb White Range code where any message with a | |||||
white range source IP was being forced to the white result code. The | |||||
engine now (correctly) only forces the result and records the event when | |||||
a black pattern rule was matched and the White Range IP causes that | |||||
scan result to be overturned. If the scan result was not a black pattern | |||||
match then the original scan result is allowed to pass through. | |||||
Corrected a bug in the Header Analysis filter chain module that would | |||||
cause the first header in the message to be ignored in some cases. | |||||
Corrected an XML log format problem so that <s/> elements are correctly | |||||
open ended <s ....> or closed (empty) <s..../> according to whether they | |||||
have subordinate elements. | |||||
Adjusted the GBUdb header info format. The order of the Confidence | |||||
figure and Probabilty figure is now the same as in the XML log files | |||||
(C then P). The confidence and probability figures are now preceeded | |||||
with c= and p= respectively so that it's easy to tell which is which. | |||||
20071009 Version 2-9b1.4 | |||||
Tightened up the XCI handler code and removed the watchdog. The watchdog | |||||
would restart the listener if there were no connections in 5 minutes. It | |||||
was originally added to provide additional stability, however in practice | |||||
there have been no "stalled listeners". Also, a stalled listener would | |||||
likely be a sign of a different problem that the watchdog would tend to | |||||
hide. | |||||
Modified and refactored the XCI configuration management code. All XCI config | |||||
changes and up-down operations are now handled in a single function except | |||||
upon exit from the main XCI thread where XCI_shutdown() is always called. | |||||
Added some more detailed exception handling code to the XCI component so that | |||||
more data will be logged in the event of an error. | |||||
Reviewed and modified the InstallInstructions.txt file. Removed this log | |||||
to this separate file. | |||||
Modified the snfmdplugin.xml file to properly configure the new features in | |||||
the engine. | |||||
* Header training directives and new <training/> section. | |||||
* XCI interface configuration. | |||||
* Tweaks to GBUdb ranges. | |||||
* msg-file type configuration (not used in MDaemon, but configured anyway) | |||||
---- | |||||
Version 2-9a11 (engine a53) | |||||
* Enhanced IP extraction from Received headers so that any unexpected bytes | |||||
between the [ and ] will force the attempt to be aborted. | |||||
* Fix the IP test code so that the IP 0.0.0.0 cannot be the source IP and | |||||
cannot be tested. | |||||
Version 2-9a11 (engine a52) | |||||
* Corrected plug-in log entry logic. Allowed/Rejected tag now comes directly | |||||
from the message rejection logic and is accurate in all cases. | |||||
Version 2-9a10 (engine a52) | |||||
* Corrected a bug in the MessageIPFunc where Ignore flagged IPs would still | |||||
cause rejected messages if the statistics were in the Truncate range. Now | |||||
messages are rejected in only two cases: | |||||
The Flag is _Ugly_ and the rating is _Truncate_ or, the Flag is _Bad_. | |||||
Version 2-9a9 (engine a52) | |||||
* Adjusted IPtest module in HeaderAnalysis to handle TooManyIPs exception | |||||
locally and silently. | |||||
* Increased HeaderAnalysis IP limit from 20 to 50. | |||||
Version 2-9a9 (engine a51) | |||||
* Corrected possible heap corruption bug in EvaulationMatrix Destructors. | |||||
* Added trace strings to scanMessage() for tighter panic reporting. | |||||
* Added caching to snf_engine Evaluator allocation scheme. | |||||
* Added optimizations to snf_engine Evaluator safety checks. | |||||
Version 2-9a8 | |||||
* Added deep exception handling to Token Matrix objects. | |||||
Version 2-9a7 | |||||
* Exception handling throughout the engine has been refactored to use std:exception | |||||
and to provide additional detail via e.what() | |||||
* The plug-in log will now show e.what() data as SNF Debug: whenever an exception | |||||
is thrown during a message scan. | |||||
Version 2-9a6 | |||||
* Adjusted .ctl file path converter to accept either .msg or .tmp paths. | |||||
Version 2-9a5 | |||||
A lot of new things were learned, updated, and corrected. | |||||
* Fixed the "lockup" when the plugin failed to start successfully. The cause of this | |||||
appears to be a threading issue associated with DLLs that are being initialized. | |||||
If threads are created during the initialization of a DLL, the DLL must succeed! | |||||
The threads that are created do not get any cycles until after the DLL is loaded | |||||
successfully. As a result, if the initialization process attempts to join() these | |||||
threads a deadlock is created. The fix was to allow the SNF plugin initialization | |||||
process to succeed in all cases while setting a flag that forces the engine to | |||||
be inert if the initialization was not successful. When the DLL is later unloaded | |||||
the threads are already running so the join() calls that are part of the engine | |||||
cleanup code are able to complete without incident. | |||||
* Installed detailed exception handling for the start-up sequence. The plugin can | |||||
now report on very specific reasons for failing to initialize properly. | |||||
* Fixed a bug in the GBUdbIgnoreList processor where long lines would cause the | |||||
remainder of the file not to be read. The line length limit still exists, but | |||||
it is now 255 characters which is unlikely to occur and would be considered | |||||
incorrect formatting. | |||||
* The threading library now includes top-level exception handling to trap any | |||||
exception that was not handled by myTask(). Along with this two flags were | |||||
added to thread objects: isRunning() and isBad(). isRunning() is true when a | |||||
thread object is still active. isBad() is true if the thread failed to start or | |||||
an exception escaped myTask(). | |||||
* At least one GBUdbIgnoreList entry is now REQUIRED. If the count of IPs from the | |||||
GBUdbIgnoreList.txt file is less than 1 (or the file is missing) then the plug-in | |||||
will complain and fail to start. | |||||
* snf2check.exe has been removed from the distribution for the time being since it | |||||
causes some systems to strip the attachment or block the email. This is the same | |||||
program that is already on existing SNF systems. |
# List of IPs to Ignore on startup | |||||
# Each IP in this list is set to Ignore in GBUdb when | |||||
# The configuration is loaded. | |||||
# Hash mark on the beginning of a line indicates a comment. | |||||
# Comments after an IP are also ignored. | |||||
# One line per IP. Sorry, no CIDR yet. | |||||
# Be sure to list ALL of your gateways :-) | |||||
127.0.0.1 # ignore localhost, of course. | |||||
MDaemon Plugin V2.9rc* (V3) installation instructions | |||||
------------------------------------------------------------------------------ | |||||
1. Locate your \MDaemon directory (Usually c:\MDaemon) | |||||
2. Create the directory \MDaemon\SNF | |||||
3. Copy the distribution files to \MDaemon\SNF | |||||
4. Edit identity.xml in notepad. | |||||
4.1. Replace licensid with your SNF license ID. | |||||
4.2. Replace authenticationxx with your SNF authentication code. | |||||
5. Adjust/Create your Plugins.dat file (\MDaemon\App\Plugins.dat) | |||||
5.1. If you already have a Plugins.dat file | |||||
5.1.1. Copy the contents of the Plugins.dat file in the distribution | |||||
to the Plugins.dat file you have. | |||||
5.1.2. If you have a [Message Sniffer] section in your Plugins.dat | |||||
file then make a copy of it (for backup) then remove that | |||||
section. (This will disable your previous Message Sniffer | |||||
installation) | |||||
5.2. If you do not already have a Plugins.dat file | |||||
5.2.1. Copy the Plugins.dat file from the distribution to your | |||||
\MDaemon\App directory. | |||||
6. Copy the snf-groups.cf into \MDaemon\SpamAssassin\rules | |||||
7. Download your SNF rulebase file and place it in your SNF directory. | |||||
7.1. Once you've signed up for a 30 Day free Trial or purchased a license for | |||||
SNF you will receive update notifications via email. These notifications | |||||
contain instructions on how to download your rulebase file. You can get | |||||
your 30 Day Free Trial started by visiting www.armresearch.com. | |||||
7.2. We have included an update script and utilities that you can use to | |||||
automate updates to your rulebase file. The SNFServer engine that runs | |||||
inside the plugin will produce an UpdateReady.txt file any time the local | |||||
rulbase file is older than the latest available update. The included | |||||
getRulebase.cmd script checks for this file and uses the open source | |||||
wget and gzip utilities to download, validate, and replace your rulebase | |||||
file automatically. | |||||
7.2.1. Edit the top of the getRulebase.cmd file to establish the correct | |||||
working directory, authentication string, and license ID for your | |||||
rulebase files. | |||||
7.2.2. Verify that the <update-script/> section of your snfmdplugin.xml file | |||||
points to the correct location of the getRulebase.cmd script. This new | |||||
feature will automatically run the getRulebase.cmd script whenever a | |||||
newer rulebase file is available on our servers. | |||||
8. Edit the GBUdbIgnoreList.txt file in notepad. | |||||
8.1 Add the IP of any gateways you have as well as any systems you | |||||
have that send mail through your mail server. | |||||
8.2 It is very important to populate your GBUdbIgnoreList if you have | |||||
gateways ahead of your mail server or else GBUdb will learn that | |||||
those systems are responsible for sending spam! The GBUdb engine | |||||
uses the ignore list to determine the actual source IP of the message. | |||||
The first IP it sees in the headers that is not on the ignore list | |||||
is determined to be the source IP for the message. Since most email | |||||
"in the wild" these days are spam, any gateways that are not listed | |||||
will be seen to be sending mostly spam - in error, of course. | |||||
8.3 You cannot enter network blocks in the GBUdbIgnoreList.txt file. If | |||||
you wish to ignore (mark as infrastructure) blocks of IPs then you should | |||||
use the <drilldown/> section of the snfmdplugin.xml file to enter | |||||
patterns that match the network blocks you want to ignore. For example, | |||||
if you want to ignore servers in the 12.34.56.0/24 network block then | |||||
you would enter a drilldown rule like: | |||||
<drilldown> | |||||
... | |||||
<received ordinal='0' find='[12.34.56.'/> | |||||
The rule tells GBUdb to learn to ignore any IP in the top (ordinal 0) | |||||
received header if that header contains the string '[12.34.56.'. Of | |||||
course that string will match every IP in the 12.34.56.0/24 class C | |||||
block so any servers in that block which deliver mail to the SNF equiped | |||||
server will be learned as infrastructure (ignore flag set). | |||||
9. Review and adjust your snfmdplugin.xml file | |||||
9.1. Check the paths at the top of the file and make sure they are complete and | |||||
correct. In most cases the defaults will work, but if you've installed | |||||
MDaemon & SNF on a different drive or in a different directory it would | |||||
be best to update these paths: | |||||
9.1.1. Find/Check <snf><node identity.../> | |||||
9.1.2. Find/Check <snf><node><paths><log path.../> | |||||
9.1.3. Find/Check <snf><node><paths><rulebase path.../> | |||||
9.1.4. Find/Check <snf><node><paths><workspace path.../> | |||||
9.2. If you have any addresses where people legitimately send spam such as an | |||||
abuse reporting address or support address then you should enter that | |||||
address into the <snf><node><gbudb><training><bypass/> section of the | |||||
snfmdplugin.xml file. For example an abuse reporting address might look | |||||
like this: | |||||
<bypass> | |||||
... | |||||
<header name='To:' find='spam@example.com'/> | |||||
The rule tells GBUdb to bypass it's training mechanism if it finds a | |||||
'To:' header in a message that contains 'spam@example.com'. This should | |||||
prevent customer's IPs from being learned as spam sources when they send | |||||
messages to spam@example.com. | |||||
9.3. Your system practices and policies may require additional rules in order | |||||
to get the best performance from the GBUdb system. For more information | |||||
please check out www.armresearch.com, support@armresearch.com, and our | |||||
community list sniffer@sortmonster.com. | |||||
10. Restart MDaemon. | |||||
11. Verify the SNF plugin is installed | |||||
11.1. In the plug-ins log tab you should see: | |||||
Attempting to load 'SNF' plugin | |||||
* ConfigFunc: ConfigFunc@4 (Ok, ready to use) | |||||
* StartupFunc: Startup@4 (Ok, ready to use) | |||||
* ShutdownFunc: Shutdown@4 (Ok, ready to use) | |||||
* PreMessageFunc: (NULL) | |||||
* PostMessageFunc: MessageFunc@8 (Ok, ready to use) | |||||
* SMTPMessageFunc: MessageIPFunc@8 (Ok, ready to use) | |||||
* SMTPMessageFunc2: (NULL) | |||||
* SMTPMessageFunc3: (NULL) | |||||
* DomainPOPMessageFunc: (NULL) | |||||
* MultiPOPMessageFunc: (NULL) | |||||
* Result: success (plugin DLL loaded in slot 0) | |||||
---------- | |||||
SNF plugin is starting up | |||||
SNFMulti Engine Version 2.9rc11 Build: Mar 20 2008 15:18:30 | |||||
SNF MDaemon Plugin Version 2-9rc4 Build: Mar 20 2008 15:17:20 | |||||
SNF Config: C:\MDaemon\SNF\SNFMDPlugin.xml | |||||
---------- | |||||
Note that the slot may be different if you have other plugins. | |||||
11.2. When your system processes a message you should see something like: | |||||
SNF MessageScan: c:\mdaemon\queues\local\md50000000039.msg, Result=0 | |||||
If you have a valid AntiVirus for MDaemon license you should also see | |||||
a line similar to this: | |||||
SNF IPScan: C:\MDaemon\Queues\Inbound\md50000000029.msg, 192.168.0.102, {Ugly, p=-1, c=0.303425, Normal} Allowed. | |||||
11.3. In your messages you should see some new headers similar to: | |||||
X-MessageSniffer-GBUdb-Result: 0, 192.168.0.102, Ugly -1 0.303425 Source Normal | |||||
X-MessageSniffer-Scan-Result: 0 | |||||
X-MessageSniffer-Patterns: | |||||
0-0-0-998-c |
[SNF] | |||||
MenuText=Configure SNF Plug-in | |||||
Enable=Yes | |||||
DllPath=c:\MDaemon\SNF\snfmdplugin.dll | |||||
StartupFuncName=Startup@4 | |||||
ConfigFuncName=ConfigFunc@4 | |||||
PostMessageFuncName=MessageFunc@8 | |||||
SMTPMessageFuncName=MessageIPFunc@8 | |||||
ShutdownFuncName=Shutdown@4 | |||||
PluginDoesAllLogging=No | |||||
NonAuthOnly=Yes |
SNFClient Readme | |||||
Command line client for SNF. This utility formats and processes SNF_XCI | |||||
requests through the SNF Engine working on the local machine. In general | |||||
this utility can be used as a replacement for the earlier SNF command | |||||
line scanner. It is also useful for other uses such as debugging and | |||||
communicating with GBUdb. | |||||
Note: Unlike prior versions of SNF, this command line utility does not | |||||
need to be "branded" (renamed for the SNF license id). | |||||
_________ | |||||
Help Mode | |||||
SNFClient.exe | |||||
When called with no command line parameters the utility produces | |||||
help and version information. | |||||
__________ | |||||
Debug Mode | |||||
SNFDebugClient.exe | |||||
When "debug" or "Debug" appears in the path to the program name | |||||
or if the program's name is altered to include the word "debug" or | |||||
"Debug" then the program will produce additional information about | |||||
it's operation to aid in debugging problems. This includes the | |||||
entire raw SNF_XCI request and response. | |||||
__________________ | |||||
Message Scan Modes | |||||
These modes are used to scan email message files (the data part of | |||||
smtp). This utility can be used as a drop-in replacement for previous | |||||
verions of SNF (Message Sniffer) for scanning messages. However, this | |||||
new version does not need to be "branded" (renamed for the license id) | |||||
and will ignore the authentication string if it is provided. Also, | |||||
since the newer version of SNF uses a client-server model and not a | |||||
peer-server model, there is no need for a "persistent" mode. | |||||
If "persistent" is passed to this utility on the command line as it | |||||
would be used in prior versions of SNF then it will be treated like | |||||
a file name and the scan will normally fail since a file named | |||||
"persistent" is not likely to exist. | |||||
SNFClient.exe <FileNameToScan> | |||||
Scan Mode: Scans <FileNameToScan> and returns a result code. | |||||
SNFClient.exe <authenticationxx> <FileNameToScan> | |||||
Compatibility Mode: Ignores <authenticationxx> then scans the | |||||
<FileNameToScan> and returns a result code. This mode provides | |||||
drop-in compatibility with previous versions of SNF. | |||||
SNFClient.exe -xhdr <FileNameToScan> | |||||
XHeader Mode: Scans <FileNameToScan> and returns the result. Also | |||||
outputs the contents of the X-Headers created by the SNF engine. If | |||||
the SNF engine is configured to inject these headers then they will | |||||
also have been injected into the <FileNameToScan>. | |||||
The SNF Engine can be configured to provide the X-Headers only to | |||||
the API without injecting them. In this case the XHeader Mode will | |||||
display the X-Headers that would be injected, but they will not | |||||
have been injected into the <FileNameToScan>. | |||||
If the SNF Engine is configured not to produce X-Headers (none) then | |||||
the XHeader Mode will not produce X-Headers because they will not | |||||
have been generated by the engine. | |||||
(note: -xhdr and -source options can be combined) | |||||
SNFClient.exe -source=<IP4Address> <FileNameToScan> | |||||
Source-IP Mode: Scans <FileNameToScan> and returns the result. The | |||||
provided source IP is injected into the scan as the first Received | |||||
header so that the scanning engine will presume the IP is the source | |||||
of the message. This allows you to pre-define the source IP for the | |||||
message when there is no other received header or when the received | |||||
headers may be incorrect or may not present the actual source of | |||||
the message. | |||||
(note: -xhdr and -source options can be combined) | |||||
_____________________________ | |||||
SNFServer Status Report Modes | |||||
SNFClient.exe -status.second | |||||
SNFClient.exe -status.minute | |||||
SNFClient.exe -status.hour | |||||
This mode returns the latest posted status report as indicated. | |||||
Normally these status reports are also posted to files in the | |||||
SNFServer workspace. | |||||
In this mode the SNFClient will return a result code (error level) | |||||
of 0 when the request is successful and 99 (or some nonzero value) | |||||
when the request is not successful. This allows the SNFClient to | |||||
be used to verify that the SNFServer is running. | |||||
Note: In most other modes the SNFClient returns a fail-safe 0 | |||||
result code to avoid tagging messages as spam when there are errors. | |||||
________________________ | |||||
XCI Server Command Modes | |||||
These features will expand as needed in later versions. | |||||
SNFClient.exe -shutdown | |||||
If the SNF Engine is running in an application that accepts SNF_XCI | |||||
server commands then this mode will send that command. The shutdown | |||||
command may have no effect if the application does not use the SNF_XCI | |||||
server commnand interface or does not recognize the command. | |||||
___________ | |||||
GBUdb Modes | |||||
These modes are used to communicate with the GBUdb system on the | |||||
local node. It is possible to test (read out) an IP record or make | |||||
any of a number of changes to IP data in the GBUdb. | |||||
SNFClient.exe -test <IP4Address> | |||||
Returns the current GBUdb statistics for the <IP4Address> | |||||
SNFClient also returns a result code that matches the GBUdb range | |||||
for the tested IP. These ranges are defined in the SNFServer | |||||
configuration file. By default they are: | |||||
20 - Truncate | |||||
63 - Black | |||||
40 - Caution | |||||
0 - Normal | |||||
SNFClient.exe -set <IP4Address> <flag> <bad> <good> | |||||
Creates or updates the data for <IP4Address> as provided. The | |||||
<IP4Address> must be provided as well as at least one of | |||||
<flag>, <bad>, and <good>. If <flag>, <bad>, or <good> are | |||||
to be left unchanged then they should be entered as a dash "-". | |||||
Examples: | |||||
Set all data for an IP. The flag will be "ugly", the bad count | |||||
will be 0 and the good count will be 1000. | |||||
SNFClient.exe -set 12.34.56.78 Ugly 0 1000 | |||||
Set the flag to "ignore" and do not change the counts. | |||||
SNFClient.exe -set 12.34.56.78 ignore - - | |||||
Set the good count to 400 and do not change anything else. | |||||
SNFClient.exe -set 12.34.56.78 - - 400 | |||||
SNFClient.exe -good <IP4Address> | |||||
Creates or updates statistics for the <IP4Address>. Increases the | |||||
good count by one. (Record a good event) | |||||
SNFClient.exe -bad <IP4Address> | |||||
Creates or updates statistics for the <IP4Address>. Increases the | |||||
bad count by one. (Record a bad event) | |||||
SNFClient.exe -drop <IP4Address> | |||||
Removes all local data for the <IP4Address>. Anything the local | |||||
system "knows" about the IP is forgotten. Next time the IP is | |||||
encountered it will be treated as new. | |||||
____________________ | |||||
For More Information | |||||
See www.armresearch.com | |||||
Copyright (C) 2007-2008 Arm Research Labs, LLC. | |||||
@ECHO OFF | |||||
SETLOCAL | |||||
REM ----- Edit This Section -------- | |||||
SET SNIFFER_PATH=\mdaemon\snf | |||||
SET AUTHENTICATION=authenticationxx | |||||
SET LICENSE_ID=licensid | |||||
REM -------------------------------- | |||||
CD /d %SNIFFER_PATH% | |||||
if not exist UpdateReady.txt GOTO DONE | |||||
if exist UpdateReady.lck GOTO DONE | |||||
:DOWNLOAD | |||||
COPY UpdateReady.txt UpdateReady.lck | |||||
wget http://www.sortmonster.net/Sniffer/Updates/%LICENSE_ID%.snf -O %LICENSE_ID%.new.gz --header=Accept-Encoding:gzip --http-user=sniffer --http-passwd=ki11sp8m | |||||
if exist %LICENSE_ID%.new.gz gzip -d -f %LICENSE_ID%.new.gz | |||||
snf2check.exe %LICENSE_ID%.new %AUTHENTICATION% | |||||
if errorlevel 1 goto CLEANUP | |||||
if exist %LICENSE_ID%.old del %LICENSE_ID%.old | |||||
rename %LICENSE_ID%.snf %LICENSE_ID%.old | |||||
rename %LICENSE_ID%.new %LICENSE_ID%.snf | |||||
if exist UpdateReady.txt del UpdateReady.txt | |||||
if exist UpdateReady.lck del UpdateReady.lck | |||||
:CLEANUP | |||||
if exist %LICENSE_ID%.new del %LICENSE_ID%.new | |||||
if exist UpdateReady.lck del UpdateReady.lck | |||||
:DONE | |||||
ENDLOCAL | |||||
<snf><identity licenseid='licensid' authentication='authenticationxx'/></snf> |
## Basic rules for detecting Message Sniffer header emissions | |||||
## so that they can be given scores in subsequent SpamAssassin | |||||
## scanning. Modify the scores and headers as needed for your | |||||
## system. | |||||
score SNF_IPTRUNCATE 10 | |||||
describe SNF_IPTRUNCATE IP Source consistently sends spam | |||||
header SNF_IPTRUNCATE X-MessageSniffer-Scan-Result =~ /20/ | |||||
score SNF_IPCAUTION 3 | |||||
describe SNF_IPCAUTION New IP source mixed scan results | |||||
header SNF_IPCAUTION X-MessageSniffer-Scan-Result =~ /40/ | |||||
score SNF_IPBLACK 4 | |||||
describe SNF_IPBLACK Static IP rules and GBUdb Black | |||||
header SNF_IPBLACK X-MessageSniffer-Scan-Result =~ /63/ | |||||
score SNF_OBFUSCATION 5 | |||||
describe SNF_OBFUSCATION Obfuscation detection | |||||
header SNF_OBFUSCATION X-MessageSniffer-Scan-Result =~ /62/ | |||||
score SNF_ABSTRACT 5 | |||||
describe SNF_ABSTRACT Abstracted spam patterns | |||||
header SNF_ABSTRACT X-MessageSniffer-Scan-Result =~ /61/ | |||||
score SNF_GENERAL 5 | |||||
describe SNF_GENERAL General spam content - unclassified | |||||
header SNF_GENERAL X-MessageSniffer-Scan-Result =~ /60/ | |||||
score SNF_GAMBLE 5 | |||||
describe SNF_GAMBLE Gambling and Casino spam patterns | |||||
header SNF_GAMBLE X-MessageSniffer-Scan-Result =~ /59/ | |||||
score SNF_DEBT 5 | |||||
describe SNF_DEBT Debt and Credit offer spam patterns | |||||
header SNF_DEBT X-MessageSniffer-Scan-Result =~ /58/ | |||||
score SNF_GETRICH 5 | |||||
describe SNF_GETRICH Home Biz, Stock Push, get rich quick | |||||
header SNF_GETRICH X-MessageSniffer-Scan-Result =~ /57/ | |||||
score SNF_TONER 5 | |||||
describe SNF_TONER Ink and Toner offer spam patterns | |||||
header SNF_TONER X-MessageSniffer-Scan-Result =~ /56/ | |||||
score SNF_MALWARE 5 | |||||
describe SNF_MALWARE Virus, worm, and exploit patterns | |||||
header SNF_MALWARE X-MessageSniffer-Scan-Result =~ /55/ | |||||
score SNF_ADULT 5 | |||||
describe SNF_ADULT Porn and Adult spam patterns | |||||
header SNF_ADULT X-MessageSniffer-Scan-Result =~ /54/ | |||||
score SNF_SCAM 5 | |||||
describe SNF_SCAM Phishing, 419, and other scam patterns | |||||
header SNF_SCAM X-MessageSniffer-Scan-Result =~ /53/ | |||||
score SNF_SNAKEOIL 5 | |||||
describe SNF_SNAKEOIL Drugs, diet aids, health scams | |||||
header SNF_SNAKEOIL X-MessageSniffer-Scan-Result =~ /52/ | |||||
score SNF_SPAMWARE 5 | |||||
describe SNF_SPAMWARE Spamming tools and spam hosting offers | |||||
header SNF_SPAMWARE X-MessageSniffer-Scan-Result =~ /51/ | |||||
score SNF_DATATHEFT 5 | |||||
describe SNF_DATATHEFT Movies, software, unlimited downloads | |||||
header SNF_DATATHEFT X-MessageSniffer-Scan-Result =~ /50/ | |||||
score SNF_AVPUSH 5 | |||||
describe SNF_AVPUSH Antivirus software push | |||||
header SNF_AVPUSH X-MessageSniffer-Scan-Result =~ /49/ | |||||
score SNF_INSURANCE 5 | |||||
describe SNF_INSURANCE Insurance offer patterns | |||||
header SNF_INSURANCE X-MessageSniffer-Scan-Result =~ /48/ | |||||
score SNF_TRAVEL 5 | |||||
describe SNF_TRAVEL Travel offer patterns | |||||
header SNF_TRAVEL X-MessageSniffer-Scan-Result =~ /47/ |
<!-- SNFMulti V3.0 Configuration File, Setup: Typical of MDaemon Plugin --> | |||||
<!-- http://www.armresearch.com/support/articles/software/snfServer/config/snfEngine.jsp --> | |||||
<snf> | |||||
<node identity='/MDaemon/SNF/identity.xml'> | |||||
<paths> | |||||
<log path='/MDaemon/SNF/'/> | |||||
<rulebase path='/MDaemon/SNF/'/> | |||||
<workspace path='/MDaemon/SNF/'/> | |||||
</paths> | |||||
<logs> | |||||
<rotation localtime='no'/> | |||||
<status> | |||||
<second log='yes' append='no'/> | |||||
<minute log='yes' append='no'/> | |||||
<hour log='no' append='no'/> | |||||
</status> | |||||
<scan> | |||||
<identifier force-message-id='no'/> | |||||
<classic mode='none' rotate='no' matches='none'/> | |||||
<xml mode='file' rotate='yes' matches='all' performance='yes' gbudb='yes'/> | |||||
<xheaders> | |||||
<output mode='inject'/> | |||||
<version on-off='off'>X-MessageSniffer-Version</version> | |||||
<license on-off='off'>X-MessageSniffer-License</license> | |||||
<rulebase on-off='off'>X-MessageSniffer-RulebaseUTC</rulebase> | |||||
<identifier on-off='off'>X-MessageSniffer-Identifier</identifier> | |||||
<gbudb on-off='on'>X-MessageSniffer-GBUdb-Result</gbudb> | |||||
<result on-off='on'>X-MessageSniffer-Scan-Result</result> | |||||
<matches on-off='on'>X-MessageSniffer-Patterns</matches> | |||||
<black on-off='off'>X-MessageSniffer-Spam: Yes</black> | |||||
<white on-off='off'>X-MessageSniffer-White: Yes</white> | |||||
<clean on-off='off'>X-MessageSniffer-Clean: Yes</clean> | |||||
<symbol on-off='off' n='0'>X-MessageSniffer-SNF-Group: OK</symbol> | |||||
<symbol on-off='off' n='20'>X-MessageSniffer-SNF-Group: Truncated</symbol> | |||||
<symbol on-off='off' n='40'>X-MessageSniffer-SNF-Group: Caution</symbol> | |||||
<symbol on-off='off' n='63'>X-MessageSniffer-SNF-Group: Black</symbol> | |||||
<symbol on-off='off' n='62'>X-MessageSniffer-SNF-Group: Obfuscation</symbol> | |||||
<symbol on-off='off' n='61'>X-MessageSniffer-SNF-Group: Abstract</symbol> | |||||
<symbol on-off='off' n='60'>X-MessageSniffer-SNF-Group: General</symbol> | |||||
<symbol on-off='off' n='59'>X-MessageSniffer-SNF-Group: Casinos-Gambling</symbol> | |||||
<symbol on-off='off' n='58'>X-MessageSniffer-SNF-Group: Debt-Credit</symbol> | |||||
<symbol on-off='off' n='57'>X-MessageSniffer-SNF-Group: Get-Rich</symbol> | |||||
<symbol on-off='off' n='56'>X-MessageSniffer-SNF-Group: Ink-Toner</symbol> | |||||
<symbol on-off='off' n='55'>X-MessageSniffer-SNF-Group: Malware</symbol> | |||||
<symbol on-off='off' n='54'>X-MessageSniffer-SNF-Group: Porn-Dating-Adult</symbol> | |||||
<symbol on-off='off' n='53'>X-MessageSniffer-SNF-Group: Scam-Phishing</symbol> | |||||
<symbol on-off='off' n='52'>X-MessageSniffer-SNF-Group: Snake-Oil</symbol> | |||||
<symbol on-off='off' n='51'>X-MessageSniffer-SNF-Group: Spamware</symbol> | |||||
<symbol on-off='off' n='50'>X-MessageSniffer-SNF-Group: Media-Theft</symbol> | |||||
<symbol on-off='off' n='49'>X-MessageSniffer-SNF-Group: AV-Push</symbol> | |||||
<symbol on-off='off' n='48'>X-MessageSniffer-SNF-Group: Insurance</symbol> | |||||
<symbol on-off='off' n='47'>X-MessageSniffer-SNF-Group: Travel</symbol> | |||||
</xheaders> | |||||
</scan> | |||||
</logs> | |||||
<network> | |||||
<sync secs='30' host='sync.messagesniffer.net' port='25'/> | |||||
<update-script on-off='on' call='/MDaemon/SNF/getRulebase.cmd' guard-time='180'/> | |||||
</network> | |||||
<xci on-off='on' port='9001'/> | |||||
<gbudb> | |||||
<database> | |||||
<condense minimum-seconds-between='600'> | |||||
<time-trigger on-off='on' seconds='86400'/> | |||||
<posts-trigger on-off='off' posts='1200000'/> | |||||
<records-trigger on-off='off' records='600000'/> | |||||
<size-trigger on-off='on' megabytes='150'/> | |||||
</condense> | |||||
<checkpoint on-off='on' secs='3600'/> | |||||
</database> | |||||
<regions> | |||||
<white on-off='on' symbol='0'> | |||||
<edge probability='-1.0' confidence='0.4'/> | |||||
<edge probability='-0.8' confidence='1.0'/> | |||||
<panic on-off='on' rule-range='1000'/> | |||||
</white> | |||||
<caution on-off='on' symbol='40'> | |||||
<edge probability='0.4' confidence='0.0'/> | |||||
<edge probability='0.8' confidence='0.5'/> | |||||
</caution> | |||||
<black on-off='on' symbol='63'> | |||||
<edge probability='0.8' confidence='0.2'/> | |||||
<edge probability='0.8' confidence='1.0'/> | |||||
<truncate on-off='on' probability='0.9' peek-one-in='5' symbol='20'/> | |||||
<sample on-off='on' probability='0.8' grab-one-in='5' passthrough='no' passthrough-symbol='0'/> | |||||
</black> | |||||
</regions> | |||||
<training on-off='on'> | |||||
<bypass> | |||||
<!-- <header name='To:' find='spam@example.com'/> --> | |||||
<!-- <header name='Received:' ordinal='1' find='friendlyhost.com'/> --> | |||||
</bypass> | |||||
<drilldown> | |||||
<!-- <received ordinal='0' find='[12.34.56.'/> where we want to ignore 12.34.56.0/24 --> | |||||
<!-- <received ordinal='0' find='mixed-source.com'/> --> | |||||
<!-- <received ordinal='1' find='mixed-source-internal.com'/> --> | |||||
</drilldown> | |||||
<source> | |||||
<!-- <header name='X-Use-This-Source:' received='mixedsource.com [' ordinal='0' /> --> | |||||
<!-- <header name='X-Originating-IP:' received='hotmail.com [' ordinal='0' /> --> | |||||
</source> | |||||
<white> | |||||
<result code='1'/> | |||||
<!-- <header name='Received:' ordinal='0' find='.friendlyhost.com'/> --> | |||||
</white> | |||||
</training> | |||||
</gbudb> | |||||
<rule-panics> | |||||
<!-- | |||||
<rule id='123456'/> | |||||
<rule id='123457'/> | |||||
--> | |||||
</rule-panics> | |||||
<!-- Platform Specific Configuration --> | |||||
<platform> | |||||
<mdaemon> | |||||
<ip-test on-off='on'/> | |||||
<configurator command='start notepad' append-path='yes'/> | |||||
</mdaemon> | |||||
</platform> | |||||
<msg-file type='rfc822'/> | |||||
</node> | |||||
</snf> | |||||
Included with this distribution are the open-source "wget" and "gzip" files. They are | |||||
used in getRulebase.bat to download and decompress rulebase files. The "wget" and "gzip" | |||||
utilities included here came from http://unxutils.sourceforge.net/ and are included only | |||||
for your convenience. |
SNF MDaemon Plugin Change Log... | |||||
------------------------------------------------------------------------------ | |||||
20080626 - Version 3.0, It's official. | |||||
Changed build information. | |||||
Removed extraneous comments from configuration file. | |||||
20080524 - Version V2-9rc6.25.7 | |||||
Optimized networking library for additional speed & stability by moving | |||||
receive buffer allocation from heap to stack (automatic). | |||||
Optimized timing parameters in SNFClient for improved speed. Polling dealys | |||||
are now reduced to 10ms from 30ms. | |||||
Removed speed-bug in SNFClient, 100ms guard time between retries was always | |||||
executed after an attempt (even a successful attempt). The guard time is now | |||||
condition and only fires on unsuccessful attempts. | |||||
Updated XCI server logic to ensure non-blocking sockets for clients in all | |||||
socket implementations. | |||||
20080424 - Version V2-9rc6.24.6 | |||||
Refactored snfScanData.clear() to reduce heap work and fragments. | |||||
Added mutex to scanMessageFile() entry point just in case some app attempts to | |||||
put multiple threads through a single engine handler. scanMessage() is already | |||||
protected and fully wraped by the new scanMessageFile() mutex. | |||||
Added non-specific runtime exception handling to XHDR injection code. | |||||
Added 2 retries w/ 300ms delay to remove original message in XHDR inject code. | |||||
If remove fails after 3 attempts the injector throws. | |||||
Added 2 retries w/ 300ms delay to rename temp file to msg in XHDR inject code. | |||||
If rename fails after 3 attempts the injector throws. | |||||
Added IPTest logging. | |||||
20080416 - Version V2-9rc5.23.6 | |||||
Fixed bug where SNCY open() would fail on some Win* platforms with | |||||
WSAEINVAL instead of the standard EINPROGRESS or EALREADY which were expected. | |||||
Also added WSAEWOULDBLOCK to cover other "ambiguities" in windows sockets | |||||
implementations. InProgress() on Win* now test for any of: | |||||
WSAEINPROGRESS, WSAEALREADY, WSAEWOULDBLOCK, WSAEINVAL | |||||
20080413 - Version V2-9rc5.22.6 | |||||
Fixed bug in TCPHost.open() where EALREADY was not counted as a version of | |||||
EINPROGRESS. This would cause open() to throw an unnecessary exception when | |||||
an open() required extra time. | |||||
20080413 - Version V2-9rc5.21.6 | |||||
Extended timeout for SYNC session open() to the full session length. This way | |||||
if a session takes a long time to open it still has a shot at success. | |||||
20080411 - Version V2-9rc5.20.6 | |||||
Adjusted snfNETmgr to use non-blocking open in SYNC sessions. Open timeout | |||||
is 1/3 of the session timeout. Session timeout is 2 * Session pacing. Open | |||||
polling uses golden spiral delay from 10ms to 340ms. | |||||
20080410 - Version V2-9rc5.19.6 | |||||
Adjusted XCI manager to use new snfCFGPacket paradigm in checkCFG(). | |||||
Adjusted snf_RulebaseHandler::addRulePanic() to use MyMutex and eliminated | |||||
the AutoPanicMutex and waiting scheme. | |||||
Refactored scanMessage() to use a ScopeMutex() rather than lock()/unlock(). | |||||
Refactored scanMessage() to use MyCFGPacket.isRulePanic() test. | |||||
Redesigned snfCFGPacket handling to automate grab() / drop() functions. | |||||
Fixed lock-up bug: Redesigned AutoPanic posting and checking mechanisms to | |||||
eliminate potential dead-lock condition. Under some conditions a precisely | |||||
timed auto-panic posting could cause the RulebaesHandler mutex and the | |||||
AutoPanicMutex to become intertwined leading to a cascading deadlock. When | |||||
this occurred all XCI processing threads and eventually the XCI listener | |||||
thread would become blocked waiting to get the current configuration. | |||||
20080409 - Version V2-9rc5.18.6 | |||||
Enhanced XCI exception handling and logging to provide additional detail. | |||||
Added code to explicitely check for zero length files in scanMessagFile(). | |||||
Previously a zero length file would cause the CBFR module of the filter | |||||
chain to throw an invalid buffer exception. Now if the message file is empty | |||||
scanMessageFile() will throw a FileError stating FileEmpty!. | |||||
20080407 - Version V2-9rc5.17.6 | |||||
Enhanced exception reporting in snfXCImrg | |||||
20080405 - Version V2-9rc5.16.6 | |||||
Reduced safetly limits on status reports to 100K for status reports and 100K | |||||
for samples. Previous values were 10M. Most full sessions from the busiest | |||||
systems are < 50K total. | |||||
Recoded sendDataTimeout() to break uploads into 512 byte chunks and insert | |||||
delays only when a chunk is fragmented. This methodology improves reliability | |||||
on Win* systems without any significant penalty on systems that don't need | |||||
socket sends() to be in smaller chunks. | |||||
Fixed TCPClient::transmit() and TCPHost::transmit() bug where returned byte | |||||
count might be -1. Now returned byte counts can only be 0 or more. | |||||
20080403 - Version SNF2-9vr5.15.5 | |||||
Minor modifications to networking module to better support non-blocking open() | |||||
Updated SNFClient with new timing and non-blocking open(). Worst case return | |||||
time from SNFClient estimated at 200 seconds (theoretically impossible). No- | |||||
connection return time from SNFClient estimated at 20 seconds. | |||||
20080326 - Version SNF2-9rc4.15.4 | |||||
Refactored snfNETmgr::sync() to consolidate non-blocking io routines. | |||||
Added detailed thread status data to XCI listener thread. | |||||
Refactored snfNETmgr::sync() to check a Timeout, removed TCPWatchdog. | |||||
20080325 - Version SNF2-9rc4.12.4 | |||||
Added a "Rulebase Getter" feature as part of the snf_Reloader. When enabled | |||||
the Rulebase Getter will launch a user defineable system() call whenever a | |||||
new rulebase file is available. The call will be repeated until the condition | |||||
is cleared by a successful update of the rulebase file. The Rulebase Getter | |||||
will wait a configurable "guard time" between attempts. The default system() | |||||
call is "getRulebase" with a guard time of 3 minutes. In most cases this will | |||||
launch the provided getRulebase script which should be present in the start | |||||
location of SNFServer on most systems. Best practice is to configure the full | |||||
path to the update script. The system() call is made in a separate thread so | |||||
that if the system() call hangs for some reason only the Rulebase Getter is | |||||
stuck. | |||||
Improved exception handling/reporting in scanMessageFile(). | |||||
Updated scanMessagFile() header injection code to accommodate messages with | |||||
no body. Previous version would throw an exception when it could not find an | |||||
injection point. The new version makes the injection point byte 0 and puts | |||||
the injected headers at the top of the message using it's best guess about the | |||||
type of line endings (CRLF or LF) to use. | |||||
Updated Networking library to use SO_REUSEADDR by default on listeners. | |||||
20080319 - Version SNF2-9rc4.11 | |||||
Added IPScan on-off to snfmdplugin.xml. This allows users to turn off the | |||||
IPScan feature without editing the Plugins.dat file as was previously | |||||
required. The feature can now be enabled or disabled at will by editing the | |||||
configuration file. | |||||
Added Configuration editor options to snfmdplugin.xml. Previously the built- | |||||
in configuration function was hard coded to start notepad with the config | |||||
file. Now the system() call made by the ConfigFunc() can be edited in the | |||||
configuration file. The configuration file name can be appended to the | |||||
command optionally. The default is still to start notepad and append the | |||||
configuration file path so that it is loaded automatically. It is hoped that | |||||
GUI based configuration editors for the SNF plugin will be built by third | |||||
parties and in the mean time folks can now configure their favorite XML file | |||||
editor to modify their SNF plugin configuration. | |||||
Modified API use fixed shutdown bug - The plugin used to initialize the SNF | |||||
scanning engine when the DLL was loaded and would shut it down when the DLL | |||||
was unloaded. Now the Startup and Shutdown functions in the MDaemon plugin | |||||
API. This ensures that the engine components are started and shutdown in the | |||||
proper sequence. | |||||
Included new SNFEngine core (excerpts from that change log included). | |||||
20080318 - SNF2-9rc1.11.exe Consolidated several mods/fixes | |||||
Corrected scan error logging bug. Was posting <s/> now posts <e/>. | |||||
Updated scan error logging to be more uniform with non-scan errors. | |||||
Developed various script prototypes for postfix integration & automated | |||||
updates on win* systems using the new UpdateReady.txt file mechanism. | |||||
Fixed a bug in scanMessageFile() where an \n\n style insertion point | |||||
would never be detected. | |||||
Modified scanMessageFile() header injection to strip <CR> from line ends | |||||
when the message file provided does not use them. The line-end style of | |||||
the message file is detected while locating the insertion point. If the | |||||
insertion point (first blank line) does not use <CR><LF> then the SNF | |||||
generated X-Headers are stripped of <CR> in a tight loop before injection. | |||||
Enhanced error and exception reporting in SNFMulti.cpp scanMessageFile(). | |||||
Enhanced exception handling in networking module. All exceptions now | |||||
throw descriptive runtime_error exceptions. | |||||
20080306 - SNF2-9rc1.8.exe (FIRST RELEASE CANDIDATE for VERSION 3!) | |||||
Added Drilldown Header Directive Functions - When the candidate source IP | |||||
comes from a header matching a drilldown directive the IP is marked "Ignore" | |||||
in GBUdb and the candidate is no longer eligible to be the source for that | |||||
message. This allows SNF to follow the trusted chain of devices (by IP) down | |||||
to the actual source of the message. It is handy for ignoring net blocks | |||||
because it can match partial IPs but it is designed to allow SNF to learn | |||||
it's way through the servers at large ISPs so that the original source for | |||||
each message can be evaluated directly. | |||||
Added Source Header Directive Functions - This feature allows SNF to acquire | |||||
the source IP for a message from a specific header rather than searching | |||||
through the Received headers in the message. This is useful when the original | |||||
source for a message is not represented in Received headers. For example: | |||||
Hotmail places the originating source IP in a special header and does not | |||||
provide a Received header for that IP. This feature is protected from abuse | |||||
by a "Context" feature which only activates the source header directive when | |||||
specific content is found in a specific received header. Using the above | |||||
example, this feature can be configured so that a Hotmail source header would | |||||
only be read if the top Recieved header contained "hotmail.com [" indicating | |||||
that the ptr lookup for the header matched the hotmail domain. Note: When a | |||||
source is pulled from a header directive that source is put into a synthetic | |||||
Received header and injected into the scanning stream (not the message) as | |||||
the first Received header. | |||||
Added forced source IP to XCI - It is now possible to "inject" or "force" | |||||
the source IP for any message by providing that IP in the XCI request or | |||||
directly in a scan...() function call. This allows the calling application | |||||
to provide the source IP for a message ahead of any Received headers that | |||||
might be in the message. This is useful when the calling application knows | |||||
the original source IP for the message but that IP is not represented in | |||||
the Received headers and it is not desireable to use the Source Header | |||||
Directive mechanism. | |||||
Added forced source IP mode to SNFClient - It is now possible to call the | |||||
SNFClient utility with an IP4Address using the syntax: | |||||
SNFClient -source=12.34.56.78 | |||||
The -source mode of SNFClient exercises the forced source IP feature in | |||||
the XCI (see above) | |||||
Added Status Report features to SNFClient and XCI - It is now possible to | |||||
request the latest status.second, status.minute, or status.hour data via | |||||
the XCI and SNFClient. The syntax for requesting a status report using the | |||||
SNFClient is: | |||||
SNFClient -status.second | |||||
SNFClient -status.minute | |||||
SNFClient -status.hour | |||||
In addition to providing status reports the SNFClient in this mode will | |||||
return a nonzero value (usually 99) if it is unable to get a status report | |||||
from SNFServer. This feature can be used to verify that SNFServer is up | |||||
and responding. If SNFServer is OK then the result code returned is 0. | |||||
Added result codes to SNFClient -test and XCI IP test functions - The XCI | |||||
engine has been upgraded to provide the range value for the IP under test | |||||
as well as the symbolic result code associated with that range. This allows | |||||
the -test function to provide results that are consistent with the GBUdb | |||||
configuration without additional processing: For example, if the IP falls | |||||
in the Caution range then the Caution result code will be returned just | |||||
as if a message had been scanned with the same IP and no pattern match | |||||
occurred. The same is true for Truncate and Black range hits. | |||||
Added Timestamp and Command Line Parameter data to SNFClient.exe.err - When | |||||
an error occurs with SNFClient that may not appear in the SNFServer logs an | |||||
entry is appended to the SNFClient.exe.err file. That in itself is not new. | |||||
The new feature is that the entries added to the SNFClient.exe.err file now | |||||
include timestamp and command line data to aid in debugging. | |||||
Updated the Configuration Log to include all of the current configuration | |||||
features and to improve it's readability. | |||||
20080207 - SNF2-9b1.7.exe | |||||
SYNC Timeout now 2x SYNC Schedule | |||||
SNFServer now produces an UpdateReady.txt file when the UTC timestamp on | |||||
the SYNC server is newer than the UTC timestamp of the active rulebase. It | |||||
is presumed that a suitable update script or program will run periodically | |||||
and download a fresh rulebase file if the UpdateReady.txt file is present. | |||||
The update script should remove the UpdateReady.txt file when it completes | |||||
a successful download of the new rulebase file. | |||||
Added available rulebase UTC in status reports <udate utc.../> | |||||
Added Automatic path fixup for ending / or \ | |||||
Added option to use local time in log rotation <rotation localtime='no'/> | |||||
The default is still utc. | |||||
20071102 - SNF2-9b1.6.exe | |||||
Increased MAX_EVALS from 1024 to 2048. | |||||
Adjusted defult range envelopes in snf_engine.xml to be more conservative. | |||||
20071017 - Version SNF2-9b1.5 | |||||
Added a missing #include directive to the networking.hpp file. The | |||||
missing #include was not a factor on Linux and Windows systems but | |||||
caused compiler errors on BSD systems. | |||||
Corrected a bug in the GBUdb White Range code where any message with a | |||||
white range source IP was being forced to the white result code. The | |||||
engine now (correctly) only forces the result and records the event when | |||||
a black pattern rule was matched and the White Range IP causes that | |||||
scan result to be overturned. If the scan result was not a black pattern | |||||
match then the original scan result is allowed to pass through. | |||||
Corrected a bug in the Header Analysis filter chain module that would | |||||
cause the first header in the message to be ignored in some cases. | |||||
Corrected an XML log format problem so that <s/> elements are correctly | |||||
open ended <s ....> or closed (empty) <s..../> according to whether they | |||||
have subordinate elements. | |||||
Adjusted the GBUdb header info format. The order of the Confidence | |||||
figure and Probabilty figure is now the same as in the XML log files | |||||
(C then P). The confidence and probability figures are now preceeded | |||||
with c= and p= respectively so that it's easy to tell which is which. | |||||
20071009 Version 2-9b1.4 | |||||
Tightened up the XCI handler code and removed the watchdog. The watchdog | |||||
would restart the listener if there were no connections in 5 minutes. It | |||||
was originally added to provide additional stability, however in practice | |||||
there have been no "stalled listeners". Also, a stalled listener would | |||||
likely be a sign of a different problem that the watchdog would tend to | |||||
hide. | |||||
Modified and refactored the XCI configuration management code. All XCI config | |||||
changes and up-down operations are now handled in a single function except | |||||
upon exit from the main XCI thread where XCI_shutdown() is always called. | |||||
Added some more detailed exception handling code to the XCI component so that | |||||
more data will be logged in the event of an error. | |||||
Reviewed and modified the InstallInstructions.txt file. Removed this log | |||||
to this separate file. | |||||
Modified the snfmdplugin.xml file to properly configure the new features in | |||||
the engine. | |||||
* Header training directives and new <training/> section. | |||||
* XCI interface configuration. | |||||
* Tweaks to GBUdb ranges. | |||||
* msg-file type configuration (not used in MDaemon, but configured anyway) | |||||
---- | |||||
Version 2-9a11 (engine a53) | |||||
* Enhanced IP extraction from Received headers so that any unexpected bytes | |||||
between the [ and ] will force the attempt to be aborted. | |||||
* Fix the IP test code so that the IP 0.0.0.0 cannot be the source IP and | |||||
cannot be tested. | |||||
Version 2-9a11 (engine a52) | |||||
* Corrected plug-in log entry logic. Allowed/Rejected tag now comes directly | |||||
from the message rejection logic and is accurate in all cases. | |||||
Version 2-9a10 (engine a52) | |||||
* Corrected a bug in the MessageIPFunc where Ignore flagged IPs would still | |||||
cause rejected messages if the statistics were in the Truncate range. Now | |||||
messages are rejected in only two cases: | |||||
The Flag is _Ugly_ and the rating is _Truncate_ or, the Flag is _Bad_. | |||||
Version 2-9a9 (engine a52) | |||||
* Adjusted IPtest module in HeaderAnalysis to handle TooManyIPs exception | |||||
locally and silently. | |||||
* Increased HeaderAnalysis IP limit from 20 to 50. | |||||
Version 2-9a9 (engine a51) | |||||
* Corrected possible heap corruption bug in EvaulationMatrix Destructors. | |||||
* Added trace strings to scanMessage() for tighter panic reporting. | |||||
* Added caching to snf_engine Evaluator allocation scheme. | |||||
* Added optimizations to snf_engine Evaluator safety checks. | |||||
Version 2-9a8 | |||||
* Added deep exception handling to Token Matrix objects. | |||||
Version 2-9a7 | |||||
* Exception handling throughout the engine has been refactored to use std:exception | |||||
and to provide additional detail via e.what() | |||||
* The plug-in log will now show e.what() data as SNF Debug: whenever an exception | |||||
is thrown during a message scan. | |||||
Version 2-9a6 | |||||
* Adjusted .ctl file path converter to accept either .msg or .tmp paths. | |||||
Version 2-9a5 | |||||
A lot of new things were learned, updated, and corrected. | |||||
* Fixed the "lockup" when the plugin failed to start successfully. The cause of this | |||||
appears to be a threading issue associated with DLLs that are being initialized. | |||||
If threads are created during the initialization of a DLL, the DLL must succeed! | |||||
The threads that are created do not get any cycles until after the DLL is loaded | |||||
successfully. As a result, if the initialization process attempts to join() these | |||||
threads a deadlock is created. The fix was to allow the SNF plugin initialization | |||||
process to succeed in all cases while setting a flag that forces the engine to | |||||
be inert if the initialization was not successful. When the DLL is later unloaded | |||||
the threads are already running so the join() calls that are part of the engine | |||||
cleanup code are able to complete without incident. | |||||
* Installed detailed exception handling for the start-up sequence. The plugin can | |||||
now report on very specific reasons for failing to initialize properly. | |||||
* Fixed a bug in the GBUdbIgnoreList processor where long lines would cause the | |||||
remainder of the file not to be read. The line length limit still exists, but | |||||
it is now 255 characters which is unlikely to occur and would be considered | |||||
incorrect formatting. | |||||
* The threading library now includes top-level exception handling to trap any | |||||
exception that was not handled by myTask(). Along with this two flags were | |||||
added to thread objects: isRunning() and isBad(). isRunning() is true when a | |||||
thread object is still active. isBad() is true if the thread failed to start or | |||||
an exception escaped myTask(). | |||||
* At least one GBUdbIgnoreList entry is now REQUIRED. If the count of IPs from the | |||||
GBUdbIgnoreList.txt file is less than 1 (or the file is missing) then the plug-in | |||||
will complain and fail to start. | |||||
* snf2check.exe has been removed from the distribution for the time being since it | |||||
causes some systems to strip the attachment or block the email. This is the same | |||||
program that is already on existing SNF systems. |
# List of IPs to Ignore on startup | |||||
# Each IP in this list is set to Ignore in GBUdb when | |||||
# The configuration is loaded. | |||||
# Hash mark on the beginning of a line indicates a comment. | |||||
# Comments after an IP are also ignored. | |||||
# One line per IP. Sorry, no CIDR yet. | |||||
# Be sure to list ALL of your gateways :-) | |||||
127.0.0.1 # ignore localhost, of course. | |||||
MDaemon Plugin V2.9rc* (V3) installation instructions | |||||
------------------------------------------------------------------------------ | |||||
1. Locate your \MDaemon directory (Usually c:\MDaemon) | |||||
2. Create the directory \MDaemon\SNF | |||||
3. Copy the distribution files to \MDaemon\SNF | |||||
4. Edit identity.xml in notepad. | |||||
4.1. Replace licensid with your SNF license ID. | |||||
4.2. Replace authenticationxx with your SNF authentication code. | |||||
5. Adjust/Create your Plugins.dat file (\MDaemon\App\Plugins.dat) | |||||
5.1. If you already have a Plugins.dat file | |||||
5.1.1. Copy the contents of the Plugins.dat file in the distribution | |||||
to the Plugins.dat file you have. | |||||
5.1.2. If you have a [Message Sniffer] section in your Plugins.dat | |||||
file then make a copy of it (for backup) then remove that | |||||
section. (This will disable your previous Message Sniffer | |||||
installation) | |||||
5.2. If you do not already have a Plugins.dat file | |||||
5.2.1. Copy the Plugins.dat file from the distribution to your | |||||
\MDaemon\App directory. | |||||
6. Copy the snf-groups.cf into \MDaemon\SpamAssassin\rules | |||||
7. Download your SNF rulebase file and place it in your SNF directory. | |||||
7.1. Once you've signed up for a 30 Day free Trial or purchased a license for | |||||
SNF you will receive update notifications via email. These notifications | |||||
contain instructions on how to download your rulebase file. You can get | |||||
your 30 Day Free Trial started by visiting www.armresearch.com. | |||||
7.2. We have included an update script and utilities that you can use to | |||||
automate updates to your rulebase file. The SNFServer engine that runs | |||||
inside the plugin will produce an UpdateReady.txt file any time the local | |||||
rulbase file is older than the latest available update. The included | |||||
getRulebase.cmd script checks for this file and uses the open source | |||||
wget and gzip utilities to download, validate, and replace your rulebase | |||||
file automatically. | |||||
7.2.1. Edit the top of the getRulebase.cmd file to establish the correct | |||||
working directory, authentication string, and license ID for your | |||||
rulebase files. | |||||
7.2.2. Verify that the <update-script/> section of your snfmdplugin.xml file | |||||
points to the correct location of the getRulebase.cmd script. This new | |||||
feature will automatically run the getRulebase.cmd script whenever a | |||||
newer rulebase file is available on our servers. | |||||
8. Edit the GBUdbIgnoreList.txt file in notepad. | |||||
8.1 Add the IP of any gateways you have as well as any systems you | |||||
have that send mail through your mail server. | |||||
8.2 It is very important to populate your GBUdbIgnoreList if you have | |||||
gateways ahead of your mail server or else GBUdb will learn that | |||||
those systems are responsible for sending spam! The GBUdb engine | |||||
uses the ignore list to determine the actual source IP of the message. | |||||
The first IP it sees in the headers that is not on the ignore list | |||||
is determined to be the source IP for the message. Since most email | |||||
"in the wild" these days are spam, any gateways that are not listed | |||||
will be seen to be sending mostly spam - in error, of course. | |||||
8.3 You cannot enter network blocks in the GBUdbIgnoreList.txt file. If | |||||
you wish to ignore (mark as infrastructure) blocks of IPs then you should | |||||
use the <drilldown/> section of the snfmdplugin.xml file to enter | |||||
patterns that match the network blocks you want to ignore. For example, | |||||
if you want to ignore servers in the 12.34.56.0/24 network block then | |||||
you would enter a drilldown rule like: | |||||
<drilldown> | |||||
... | |||||
<received ordinal='0' find='[12.34.56.'/> | |||||
The rule tells GBUdb to learn to ignore any IP in the top (ordinal 0) | |||||
received header if that header contains the string '[12.34.56.'. Of | |||||
course that string will match every IP in the 12.34.56.0/24 class C | |||||
block so any servers in that block which deliver mail to the SNF equiped | |||||
server will be learned as infrastructure (ignore flag set). | |||||
9. Review and adjust your snfmdplugin.xml file | |||||
9.1. Check the paths at the top of the file and make sure they are complete and | |||||
correct. In most cases the defaults will work, but if you've installed | |||||
MDaemon & SNF on a different drive or in a different directory it would | |||||
be best to update these paths: | |||||
9.1.1. Find/Check <snf><node identity.../> | |||||
9.1.2. Find/Check <snf><node><paths><log path.../> | |||||
9.1.3. Find/Check <snf><node><paths><rulebase path.../> | |||||
9.1.4. Find/Check <snf><node><paths><workspace path.../> | |||||
9.2. If you have any addresses where people legitimately send spam such as an | |||||
abuse reporting address or support address then you should enter that | |||||
address into the <snf><node><gbudb><training><bypass/> section of the | |||||
snfmdplugin.xml file. For example an abuse reporting address might look | |||||
like this: | |||||
<bypass> | |||||
... | |||||
<header name='To:' find='spam@example.com'/> | |||||
The rule tells GBUdb to bypass it's training mechanism if it finds a | |||||
'To:' header in a message that contains 'spam@example.com'. This should | |||||
prevent customer's IPs from being learned as spam sources when they send | |||||
messages to spam@example.com. | |||||
9.3. Your system practices and policies may require additional rules in order | |||||
to get the best performance from the GBUdb system. For more information | |||||
please check out www.armresearch.com, support@armresearch.com, and our | |||||
community list sniffer@sortmonster.com. | |||||
10. Restart MDaemon. | |||||
11. Verify the SNF plugin is installed | |||||
11.1. In the plug-ins log tab you should see: | |||||
Attempting to load 'SNF' plugin | |||||
* ConfigFunc: ConfigFunc@4 (Ok, ready to use) | |||||
* StartupFunc: Startup@4 (Ok, ready to use) | |||||
* ShutdownFunc: Shutdown@4 (Ok, ready to use) | |||||
* PreMessageFunc: (NULL) | |||||
* PostMessageFunc: MessageFunc@8 (Ok, ready to use) | |||||
* SMTPMessageFunc: MessageIPFunc@8 (Ok, ready to use) | |||||
* SMTPMessageFunc2: (NULL) | |||||
* SMTPMessageFunc3: (NULL) | |||||
* DomainPOPMessageFunc: (NULL) | |||||
* MultiPOPMessageFunc: (NULL) | |||||
* Result: success (plugin DLL loaded in slot 0) | |||||
---------- | |||||
SNF plugin is starting up | |||||
SNFMulti Engine Version 2.9rc11 Build: Mar 20 2008 15:18:30 | |||||
SNF MDaemon Plugin Version 2-9rc4 Build: Mar 20 2008 15:17:20 | |||||
SNF Config: C:\MDaemon\SNF\SNFMDPlugin.xml | |||||
---------- | |||||
Note that the slot may be different if you have other plugins. | |||||
11.2. When your system processes a message you should see something like: | |||||
SNF MessageScan: c:\mdaemon\queues\local\md50000000039.msg, Result=0 | |||||
If you have a valid AntiVirus for MDaemon license you should also see | |||||
a line similar to this: | |||||
SNF IPScan: C:\MDaemon\Queues\Inbound\md50000000029.msg, 192.168.0.102, {Ugly, p=-1, c=0.303425, Normal} Allowed. | |||||
11.3. In your messages you should see some new headers similar to: | |||||
X-MessageSniffer-GBUdb-Result: 0, 192.168.0.102, Ugly -1 0.303425 Source Normal | |||||
X-MessageSniffer-Scan-Result: 0 | |||||
X-MessageSniffer-Patterns: | |||||
0-0-0-998-c |
[SNF] | |||||
MenuText=Configure SNF Plug-in | |||||
Enable=Yes | |||||
DllPath=c:\MDaemon\SNF\snfmdplugin.dll | |||||
StartupFuncName=Startup@4 | |||||
ConfigFuncName=ConfigFunc@4 | |||||
PostMessageFuncName=MessageFunc@8 | |||||
SMTPMessageFuncName=MessageIPFunc@8 | |||||
ShutdownFuncName=Shutdown@4 | |||||
PluginDoesAllLogging=No | |||||
NonAuthOnly=Yes |
SNFClient Readme | |||||
Command line client for SNF. This utility formats and processes SNF_XCI | |||||
requests through the SNF Engine working on the local machine. In general | |||||
this utility can be used as a replacement for the earlier SNF command | |||||
line scanner. It is also useful for other uses such as debugging and | |||||
communicating with GBUdb. | |||||
Note: Unlike prior versions of SNF, this command line utility does not | |||||
need to be "branded" (renamed for the SNF license id). | |||||
_________ | |||||
Help Mode | |||||
SNFClient.exe | |||||
When called with no command line parameters the utility produces | |||||
help and version information. | |||||
__________ | |||||
Debug Mode | |||||
SNFDebugClient.exe | |||||
When "debug" or "Debug" appears in the path to the program name | |||||
or if the program's name is altered to include the word "debug" or | |||||
"Debug" then the program will produce additional information about | |||||
it's operation to aid in debugging problems. This includes the | |||||
entire raw SNF_XCI request and response. | |||||
__________________ | |||||
Message Scan Modes | |||||
These modes are used to scan email message files (the data part of | |||||
smtp). This utility can be used as a drop-in replacement for previous | |||||
verions of SNF (Message Sniffer) for scanning messages. However, this | |||||
new version does not need to be "branded" (renamed for the license id) | |||||
and will ignore the authentication string if it is provided. Also, | |||||
since the newer version of SNF uses a client-server model and not a | |||||
peer-server model, there is no need for a "persistent" mode. | |||||
If "persistent" is passed to this utility on the command line as it | |||||
would be used in prior versions of SNF then it will be treated like | |||||
a file name and the scan will normally fail since a file named | |||||
"persistent" is not likely to exist. | |||||
SNFClient.exe <FileNameToScan> | |||||
Scan Mode: Scans <FileNameToScan> and returns a result code. | |||||
SNFClient.exe <authenticationxx> <FileNameToScan> | |||||
Compatibility Mode: Ignores <authenticationxx> then scans the | |||||
<FileNameToScan> and returns a result code. This mode provides | |||||
drop-in compatibility with previous versions of SNF. | |||||
SNFClient.exe -xhdr <FileNameToScan> | |||||
XHeader Mode: Scans <FileNameToScan> and returns the result. Also | |||||
outputs the contents of the X-Headers created by the SNF engine. If | |||||
the SNF engine is configured to inject these headers then they will | |||||
also have been injected into the <FileNameToScan>. | |||||
The SNF Engine can be configured to provide the X-Headers only to | |||||
the API without injecting them. In this case the XHeader Mode will | |||||
display the X-Headers that would be injected, but they will not | |||||
have been injected into the <FileNameToScan>. | |||||
If the SNF Engine is configured not to produce X-Headers (none) then | |||||
the XHeader Mode will not produce X-Headers because they will not | |||||
have been generated by the engine. | |||||
(note: -xhdr and -source options can be combined) | |||||
SNFClient.exe -source=<IP4Address> <FileNameToScan> | |||||
Source-IP Mode: Scans <FileNameToScan> and returns the result. The | |||||
provided source IP is injected into the scan as the first Received | |||||
header so that the scanning engine will presume the IP is the source | |||||
of the message. This allows you to pre-define the source IP for the | |||||
message when there is no other received header or when the received | |||||
headers may be incorrect or may not present the actual source of | |||||
the message. | |||||
(note: -xhdr and -source options can be combined) | |||||
_____________________________ | |||||
SNFServer Status Report Modes | |||||
SNFClient.exe -status.second | |||||
SNFClient.exe -status.minute | |||||
SNFClient.exe -status.hour | |||||
This mode returns the latest posted status report as indicated. | |||||
Normally these status reports are also posted to files in the | |||||
SNFServer workspace. | |||||
In this mode the SNFClient will return a result code (error level) | |||||
of 0 when the request is successful and 99 (or some nonzero value) | |||||
when the request is not successful. This allows the SNFClient to | |||||
be used to verify that the SNFServer is running. | |||||
Note: In most other modes the SNFClient returns a fail-safe 0 | |||||
result code to avoid tagging messages as spam when there are errors. | |||||
________________________ | |||||
XCI Server Command Modes | |||||
These features will expand as needed in later versions. | |||||
SNFClient.exe -shutdown | |||||
If the SNF Engine is running in an application that accepts SNF_XCI | |||||
server commands then this mode will send that command. The shutdown | |||||
command may have no effect if the application does not use the SNF_XCI | |||||
server commnand interface or does not recognize the command. | |||||
___________ | |||||
GBUdb Modes | |||||
These modes are used to communicate with the GBUdb system on the | |||||
local node. It is possible to test (read out) an IP record or make | |||||
any of a number of changes to IP data in the GBUdb. | |||||
SNFClient.exe -test <IP4Address> | |||||
Returns the current GBUdb statistics for the <IP4Address> | |||||
SNFClient also returns a result code that matches the GBUdb range | |||||
for the tested IP. These ranges are defined in the SNFServer | |||||
configuration file. By default they are: | |||||
20 - Truncate | |||||
63 - Black | |||||
40 - Caution | |||||
0 - Normal | |||||
SNFClient.exe -set <IP4Address> <flag> <bad> <good> | |||||
Creates or updates the data for <IP4Address> as provided. The | |||||
<IP4Address> must be provided as well as at least one of | |||||
<flag>, <bad>, and <good>. If <flag>, <bad>, or <good> are | |||||
to be left unchanged then they should be entered as a dash "-". | |||||
Examples: | |||||
Set all data for an IP. The flag will be "ugly", the bad count | |||||
will be 0 and the good count will be 1000. | |||||
SNFClient.exe -set 12.34.56.78 Ugly 0 1000 | |||||
Set the flag to "ignore" and do not change the counts. | |||||
SNFClient.exe -set 12.34.56.78 ignore - - | |||||
Set the good count to 400 and do not change anything else. | |||||
SNFClient.exe -set 12.34.56.78 - - 400 | |||||
SNFClient.exe -good <IP4Address> | |||||
Creates or updates statistics for the <IP4Address>. Increases the | |||||
good count by one. (Record a good event) | |||||
SNFClient.exe -bad <IP4Address> | |||||
Creates or updates statistics for the <IP4Address>. Increases the | |||||
bad count by one. (Record a bad event) | |||||
SNFClient.exe -drop <IP4Address> | |||||
Removes all local data for the <IP4Address>. Anything the local | |||||
system "knows" about the IP is forgotten. Next time the IP is | |||||
encountered it will be treated as new. | |||||
____________________ | |||||
For More Information | |||||
See www.armresearch.com | |||||
Copyright (C) 2007-2008 Arm Research Labs, LLC. | |||||
@ECHO OFF | |||||
SETLOCAL | |||||
REM ----- Edit This Section -------- | |||||
SET SNIFFER_PATH=\mdaemon\snf | |||||
SET AUTHENTICATION=authenticationxx | |||||
SET LICENSE_ID=licensid | |||||
REM -------------------------------- | |||||
CD /d %SNIFFER_PATH% | |||||
if not exist UpdateReady.txt GOTO DONE | |||||
if exist UpdateReady.lck GOTO DONE | |||||
:DOWNLOAD | |||||
COPY UpdateReady.txt UpdateReady.lck | |||||
wget http://www.sortmonster.net/Sniffer/Updates/%LICENSE_ID%.snf -O %LICENSE_ID%.new.gz --header=Accept-Encoding:gzip --http-user=sniffer --http-passwd=ki11sp8m | |||||
if exist %LICENSE_ID%.new.gz gzip -d -f %LICENSE_ID%.new.gz | |||||
snf2check.exe %LICENSE_ID%.new %AUTHENTICATION% | |||||
if errorlevel 1 goto CLEANUP | |||||
if exist %LICENSE_ID%.old del %LICENSE_ID%.old | |||||
rename %LICENSE_ID%.snf %LICENSE_ID%.old | |||||
rename %LICENSE_ID%.new %LICENSE_ID%.snf | |||||
if exist UpdateReady.txt del UpdateReady.txt | |||||
if exist UpdateReady.lck del UpdateReady.lck | |||||
:CLEANUP | |||||
if exist %LICENSE_ID%.new del %LICENSE_ID%.new | |||||
if exist UpdateReady.lck del UpdateReady.lck | |||||
:DONE | |||||
ENDLOCAL | |||||
<snf><identity licenseid='licensid' authentication='authenticationxx'/></snf> |
## Basic rules for detecting Message Sniffer header emissions | |||||
## so that they can be given scores in subsequent SpamAssassin | |||||
## scanning. Modify the scores and headers as needed for your | |||||
## system. | |||||
score SNF_IPTRUNCATE 10 | |||||
describe SNF_IPTRUNCATE IP Source consistently sends spam | |||||
header SNF_IPTRUNCATE X-MessageSniffer-Scan-Result =~ /20/ | |||||
score SNF_IPCAUTION 3 | |||||
describe SNF_IPCAUTION New IP source mixed scan results | |||||
header SNF_IPCAUTION X-MessageSniffer-Scan-Result =~ /40/ | |||||
score SNF_IPBLACK 4 | |||||
describe SNF_IPBLACK Static IP rules and GBUdb Black | |||||
header SNF_IPBLACK X-MessageSniffer-Scan-Result =~ /63/ | |||||
score SNF_OBFUSCATION 5 | |||||
describe SNF_OBFUSCATION Obfuscation detection | |||||
header SNF_OBFUSCATION X-MessageSniffer-Scan-Result =~ /62/ | |||||
score SNF_ABSTRACT 5 | |||||
describe SNF_ABSTRACT Abstracted spam patterns | |||||
header SNF_ABSTRACT X-MessageSniffer-Scan-Result =~ /61/ | |||||
score SNF_GENERAL 5 | |||||
describe SNF_GENERAL General spam content - unclassified | |||||
header SNF_GENERAL X-MessageSniffer-Scan-Result =~ /60/ | |||||
score SNF_GAMBLE 5 | |||||
describe SNF_GAMBLE Gambling and Casino spam patterns | |||||
header SNF_GAMBLE X-MessageSniffer-Scan-Result =~ /59/ | |||||
score SNF_DEBT 5 | |||||
describe SNF_DEBT Debt and Credit offer spam patterns | |||||
header SNF_DEBT X-MessageSniffer-Scan-Result =~ /58/ | |||||
score SNF_GETRICH 5 | |||||
describe SNF_GETRICH Home Biz, Stock Push, get rich quick | |||||
header SNF_GETRICH X-MessageSniffer-Scan-Result =~ /57/ | |||||
score SNF_TONER 5 | |||||
describe SNF_TONER Ink and Toner offer spam patterns | |||||
header SNF_TONER X-MessageSniffer-Scan-Result =~ /56/ | |||||
score SNF_MALWARE 5 | |||||
describe SNF_MALWARE Virus, worm, and exploit patterns | |||||
header SNF_MALWARE X-MessageSniffer-Scan-Result =~ /55/ | |||||
score SNF_ADULT 5 | |||||
describe SNF_ADULT Porn and Adult spam patterns | |||||
header SNF_ADULT X-MessageSniffer-Scan-Result =~ /54/ | |||||
score SNF_SCAM 5 | |||||
describe SNF_SCAM Phishing, 419, and other scam patterns | |||||
header SNF_SCAM X-MessageSniffer-Scan-Result =~ /53/ | |||||
score SNF_SNAKEOIL 5 | |||||
describe SNF_SNAKEOIL Drugs, diet aids, health scams | |||||
header SNF_SNAKEOIL X-MessageSniffer-Scan-Result =~ /52/ | |||||
score SNF_SPAMWARE 5 | |||||
describe SNF_SPAMWARE Spamming tools and spam hosting offers | |||||
header SNF_SPAMWARE X-MessageSniffer-Scan-Result =~ /51/ | |||||
score SNF_DATATHEFT 5 | |||||
describe SNF_DATATHEFT Movies, software, unlimited downloads | |||||
header SNF_DATATHEFT X-MessageSniffer-Scan-Result =~ /50/ | |||||
score SNF_AVPUSH 5 | |||||
describe SNF_AVPUSH Antivirus software push | |||||
header SNF_AVPUSH X-MessageSniffer-Scan-Result =~ /49/ | |||||
score SNF_INSURANCE 5 | |||||
describe SNF_INSURANCE Insurance offer patterns | |||||
header SNF_INSURANCE X-MessageSniffer-Scan-Result =~ /48/ | |||||
score SNF_TRAVEL 5 | |||||
describe SNF_TRAVEL Travel offer patterns | |||||
header SNF_TRAVEL X-MessageSniffer-Scan-Result =~ /47/ |
<!-- SNFMulti V3.0 Configuration File, Setup: Typical of MDaemon Plugin --> | |||||
<!-- http://www.armresearch.com/support/articles/software/snfServer/config/snfEngine.jsp --> | |||||
<snf> | |||||
<node identity='/MDaemon/SNF/identity.xml'> | |||||
<paths> | |||||
<log path='/MDaemon/SNF/'/> | |||||
<rulebase path='/MDaemon/SNF/'/> | |||||
<workspace path='/MDaemon/SNF/'/> | |||||
</paths> | |||||
<logs> | |||||
<rotation localtime='no'/> | |||||
<status> | |||||
<second log='yes' append='no'/> | |||||
<minute log='yes' append='no'/> | |||||
<hour log='no' append='no'/> | |||||
</status> | |||||
<scan> | |||||
<identifier force-message-id='no'/> | |||||
<classic mode='none' rotate='no' matches='none'/> | |||||
<xml mode='file' rotate='yes' matches='all' performance='yes' gbudb='yes'/> | |||||
<xheaders> | |||||
<output mode='inject'/> | |||||
<version on-off='off'>X-MessageSniffer-Version</version> | |||||
<license on-off='off'>X-MessageSniffer-License</license> | |||||
<rulebase on-off='off'>X-MessageSniffer-RulebaseUTC</rulebase> | |||||
<identifier on-off='off'>X-MessageSniffer-Identifier</identifier> | |||||
<gbudb on-off='on'>X-MessageSniffer-GBUdb-Result</gbudb> | |||||
<result on-off='on'>X-MessageSniffer-Scan-Result</result> | |||||
<matches on-off='on'>X-MessageSniffer-Patterns</matches> | |||||
<black on-off='off'>X-MessageSniffer-Spam: Yes</black> | |||||
<white on-off='off'>X-MessageSniffer-White: Yes</white> | |||||
<clean on-off='off'>X-MessageSniffer-Clean: Yes</clean> | |||||
<symbol on-off='off' n='0'>X-MessageSniffer-SNF-Group: OK</symbol> | |||||
<symbol on-off='off' n='20'>X-MessageSniffer-SNF-Group: Truncated</symbol> | |||||
<symbol on-off='off' n='40'>X-MessageSniffer-SNF-Group: Caution</symbol> | |||||
<symbol on-off='off' n='63'>X-MessageSniffer-SNF-Group: Black</symbol> | |||||
<symbol on-off='off' n='62'>X-MessageSniffer-SNF-Group: Obfuscation</symbol> | |||||
<symbol on-off='off' n='61'>X-MessageSniffer-SNF-Group: Abstract</symbol> | |||||
<symbol on-off='off' n='60'>X-MessageSniffer-SNF-Group: General</symbol> | |||||
<symbol on-off='off' n='59'>X-MessageSniffer-SNF-Group: Casinos-Gambling</symbol> | |||||
<symbol on-off='off' n='58'>X-MessageSniffer-SNF-Group: Debt-Credit</symbol> | |||||
<symbol on-off='off' n='57'>X-MessageSniffer-SNF-Group: Get-Rich</symbol> | |||||
<symbol on-off='off' n='56'>X-MessageSniffer-SNF-Group: Ink-Toner</symbol> | |||||
<symbol on-off='off' n='55'>X-MessageSniffer-SNF-Group: Malware</symbol> | |||||
<symbol on-off='off' n='54'>X-MessageSniffer-SNF-Group: Porn-Dating-Adult</symbol> | |||||
<symbol on-off='off' n='53'>X-MessageSniffer-SNF-Group: Scam-Phishing</symbol> | |||||
<symbol on-off='off' n='52'>X-MessageSniffer-SNF-Group: Snake-Oil</symbol> | |||||
<symbol on-off='off' n='51'>X-MessageSniffer-SNF-Group: Spamware</symbol> | |||||
<symbol on-off='off' n='50'>X-MessageSniffer-SNF-Group: Media-Theft</symbol> | |||||
<symbol on-off='off' n='49'>X-MessageSniffer-SNF-Group: AV-Push</symbol> | |||||
<symbol on-off='off' n='48'>X-MessageSniffer-SNF-Group: Insurance</symbol> | |||||
<symbol on-off='off' n='47'>X-MessageSniffer-SNF-Group: Travel</symbol> | |||||
</xheaders> | |||||
</scan> | |||||
</logs> | |||||
<network> | |||||
<sync secs='30' host='sync.messagesniffer.net' port='25'/> | |||||
<update-script on-off='on' call='/MDaemon/SNF/getRulebase.cmd' guard-time='180'/> | |||||
</network> | |||||
<xci on-off='on' port='9001'/> | |||||
<gbudb> | |||||
<database> | |||||
<condense minimum-seconds-between='600'> | |||||
<time-trigger on-off='on' seconds='86400'/> | |||||
<posts-trigger on-off='off' posts='1200000'/> | |||||
<records-trigger on-off='off' records='600000'/> | |||||
<size-trigger on-off='on' megabytes='150'/> | |||||
</condense> | |||||
<checkpoint on-off='on' secs='3600'/> | |||||
</database> | |||||
<regions> | |||||
<white on-off='on' symbol='0'> | |||||
<edge probability='-1.0' confidence='0.4'/> | |||||
<edge probability='-0.8' confidence='1.0'/> | |||||
<panic on-off='on' rule-range='1000'/> | |||||
</white> | |||||
<caution on-off='on' symbol='40'> | |||||
<edge probability='0.4' confidence='0.0'/> | |||||
<edge probability='0.8' confidence='0.5'/> | |||||
</caution> | |||||
<black on-off='on' symbol='63'> | |||||
<edge probability='0.8' confidence='0.2'/> | |||||
<edge probability='0.8' confidence='1.0'/> | |||||
<truncate on-off='on' probability='0.9' peek-one-in='5' symbol='20'/> | |||||
<sample on-off='on' probability='0.8' grab-one-in='5' passthrough='no' passthrough-symbol='0'/> | |||||
</black> | |||||
</regions> | |||||
<training on-off='on'> | |||||
<bypass> | |||||
<!-- <header name='To:' find='spam@example.com'/> --> | |||||
<!-- <header name='Received:' ordinal='1' find='friendlyhost.com'/> --> | |||||
</bypass> | |||||
<drilldown> | |||||
<!-- <received ordinal='0' find='[12.34.56.'/> where we want to ignore 12.34.56.0/24 --> | |||||
<!-- <received ordinal='0' find='mixed-source.com'/> --> | |||||
<!-- <received ordinal='1' find='mixed-source-internal.com'/> --> | |||||
</drilldown> | |||||
<source> | |||||
<!-- <header name='X-Use-This-Source:' received='mixedsource.com [' ordinal='0' /> --> | |||||
<!-- <header name='X-Originating-IP:' received='hotmail.com [' ordinal='0' /> --> | |||||
</source> | |||||
<white> | |||||
<result code='1'/> | |||||
<!-- <header name='Received:' ordinal='0' find='.friendlyhost.com'/> --> | |||||
</white> | |||||
</training> | |||||
</gbudb> | |||||
<rule-panics> | |||||
<!-- | |||||
<rule id='123456'/> | |||||
<rule id='123457'/> | |||||
--> | |||||
</rule-panics> | |||||
<!-- Platform Specific Configuration --> | |||||
<platform> | |||||
<mdaemon> | |||||
<ip-test on-off='on'/> | |||||
<configurator command='start notepad' append-path='yes'/> | |||||
</mdaemon> | |||||
</platform> | |||||
<msg-file type='rfc822'/> | |||||
</node> | |||||
</snf> | |||||
EXPORTS | |||||
ConfigFunc@4 @1 | |||||
MessageFunc@8 @2 | |||||
MessageIPFunc@8 @3 | |||||
Shutdown@4 @4 | |||||
Startup@4 @5 |
// main.cpp | |||||
// SNF MDaemon Plugin | |||||
// Copyright (C) 2007-2008, ARM Research Labs, LLC. | |||||
#include <windows.h> | |||||
#include "mdconfiguration.hpp" | |||||
#include "../SNF_Service/SNFMulti.hpp" | |||||
#define DLL_EXPORT __declspec(dllexport) | |||||
//////////////////////////////////////////////////////////////////////////////// | |||||
// Constants And Tweaks | |||||
//////////////////////////////////////////////////////////////////////////////// | |||||
const int MDPLUGIN_MSG = 22000; | |||||
const int MDPLUGIN_DISPLAY = 22001; | |||||
const char* PLUGIN_VERSION_INFO = "SNF MDaemon Plugin Version 3.0 Build: " __DATE__ " " __TIME__; | |||||
//////////////////////////////////////////////////////////////////////////////// | |||||
// SNF MDaemon Plugin DLL Interface Setup. | |||||
//////////////////////////////////////////////////////////////////////////////// | |||||
extern "C" { // All of these "C" functions for export. | |||||
BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved ); // The DllMain starup/shutdown function. | |||||
DLL_EXPORT void _stdcall Startup(HWND Parent); // Startup Function. | |||||
DLL_EXPORT void _stdcall ConfigFunc(HWND Parent); // Configuration function. | |||||
DLL_EXPORT void _stdcall MessageFunc(HWND Parent, const char* File); // Message Scan Function. | |||||
DLL_EXPORT void _stdcall MessageIPFunc(HWND Parent, const char* File); // IP Scan Function. | |||||
DLL_EXPORT void _stdcall Shutdown(HWND Parent); // Shutdown Function. | |||||
} | |||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { // Thread attach/detach functions. | |||||
switch (fdwReason) { // Switch on the reason for the call. | |||||
case DLL_PROCESS_ATTACH: // Attach to process. | |||||
/*** Startup function moved to API ***/ | |||||
return true; // We will assume it worked. | |||||
break; | |||||
case DLL_PROCESS_DETACH: // Detach from process. | |||||
/*** Shutdown function moved to API ***/ | |||||
return true; // We will assume that worked. | |||||
break; | |||||
case DLL_THREAD_ATTACH: // Attach to thread | |||||
break; // Just be happy. | |||||
case DLL_THREAD_DETACH: // Detach from thread | |||||
break; // Just be happy. | |||||
} | |||||
return true; // Be happy by default. | |||||
} | |||||
//////////////////////////////////////////////////////////////////////////////// | |||||
// SNF MDaemon Plugin Engine Code | |||||
//////////////////////////////////////////////////////////////////////////////// | |||||
// Handy Debug Functions. This is how we can display critical events on screen | |||||
// and emit entries into the MDaemon logs. | |||||
HWND LatestParent = 0; // Handle MDaemon log operations. | |||||
void sayToScreen(const string StuffToSay) { // Display a modal system message. | |||||
MessageBox ( // Use a message box. | |||||
GetFocus(), // Take the user's focus. | |||||
StuffToSay.c_str(), // This is what to say. | |||||
"Message Sniffer Plug-In", // This is how to title the box. | |||||
MB_OK|MB_SYSTEMMODAL ); // This makes it modal with a button. | |||||
} | |||||
void sayToLog(const string Msg) { // Emit message into MDaemon log. | |||||
if(0 != LatestParent) { // If we have a handle: | |||||
COPYDATASTRUCT Packet; // Create a packet for the log. | |||||
Packet.dwData = MDPLUGIN_DISPLAY; | |||||
Packet.cbData = Msg.length(); | |||||
Packet.lpData = reinterpret_cast<void*>( | |||||
const_cast<char*>(Msg.c_str())); | |||||
SendMessage(LatestParent, MDPLUGIN_MSG, MDPLUGIN_DISPLAY, // Send the packet. | |||||
(LPARAM)(PCOPYDATASTRUCT)&Packet); | |||||
} | |||||
} | |||||
// The configuration file path is theoretically in a fixed location based on | |||||
// the installation directory of MDaemon. We read the installation directory | |||||
// from the registry and derive the path from that. If we get what we want | |||||
// then we return the full path to the SNFMDPlugin.xml file - which is derived | |||||
// from snf_engine.xml. If we don't get what we want then we return nothing. | |||||
string ConfigurationFilePath() { // Get the config file path. | |||||
char data[256]; // Create a buffer. | |||||
DWORD dwType = 0; // Type holder. | |||||
DWORD dwCount = sizeof(data); // Data counter. | |||||
HKEY rkey; // Key handle. | |||||
string KeyLocation("SOFTWARE\\Alt-N Technologies\\MDaemon"); // Key location. | |||||
string KeyValueName("AppPath"); // Value name. | |||||
// Open the key and if successful read it's value. | |||||
string ReadValue = ""; // We'll put the answer here. | |||||
if(ERROR_SUCCESS == // Try to open the registry | |||||
RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyLocation.c_str(), 0, KEY_READ, &rkey) | |||||
) { // If it opened successfully: | |||||
RegQueryValueEx( // Read the MDaemon AppPath key. | |||||
rkey, | |||||
KeyValueName.c_str(), | |||||
NULL, | |||||
&dwType, | |||||
(LPBYTE)&data, | |||||
&dwCount | |||||
); | |||||
ReadValue = data; // Convert the results to a string. | |||||
RegCloseKey(rkey); // Close the registry key. | |||||
// Now we must convert the APP path to our SNFMDPlugin path. | |||||
int PathEnd = ReadValue.length(); // Grab the length. | |||||
if(PathEnd > 0) { ReadValue.erase(PathEnd-1,1); } // Eat the stroke at the end. | |||||
PathEnd = ReadValue.find_last_of("\\"); // Find the next stroke in. | |||||
int PathLength = ReadValue.length(); // Grab the path length. | |||||
int EraseSpan = PathLength - (PathEnd+1); // Calculate the amount to erase. | |||||
ReadValue.erase(PathEnd+1,EraseSpan); // Erase it to get the root path. | |||||
ReadValue.append("SNF\\SNFMDPlugin.xml"); | |||||
} | |||||
// Return either the empty string or the configuration file path. | |||||
return ReadValue; // Return what we have. | |||||
} | |||||
// Here are out engine components, startup, and shutdown logic. The actual | |||||
// engine components are built as the DLL is loaded. They are "lit up" by the | |||||
// startup() function - which is called when an application attaches to this | |||||
// DLL; and they are closed down when an application detaches from this DLL. | |||||
// 20080311 _M Added configuration interpreter for <platform/> and linked it | |||||
// to the ConfigFunc() and MessageIPFunc() functions. | |||||
volatile bool EngineIsGood = false; // True when things are ready to go. | |||||
snf_RulebaseHandler* Rulebase = 0; // Our Rulebase Handler. | |||||
snf_EngineHandler* ScanEngine = 0; // Our Scan Engine. | |||||
int Generation = -1; // Configuration generation tag. | |||||
string Configuration; // Configuration file path. | |||||
MDConfiguration* PlatformConfig = 0; // Platform config interpreter. | |||||
DLL_EXPORT void _stdcall Startup(HWND Parent) { // How to get all this started. | |||||
LatestParent = Parent; | |||||
EngineIsGood = false; // Start off pessimistically. | |||||
try { // Be sure to catch any exceptions. | |||||
Rulebase = new snf_RulebaseHandler(); // Create our rulebase handler. | |||||
ScanEngine = new snf_EngineHandler(); // Create our engine scanner. | |||||
Configuration = ConfigurationFilePath(); // Get the configuration path. | |||||
PlatformConfig = new MDConfiguration(*Rulebase, Configuration); // Set up our configuration monitor. | |||||
Rulebase->open(Configuration.c_str(), "", ""); // Open a configured rulebase. | |||||
Rulebase->PlatformVersion(PLUGIN_VERSION_INFO); // Set the Platform version string. | |||||
ScanEngine->open(Rulebase); // Open the scanning engine. | |||||
EngineIsGood = true; // If all went well, we're up! | |||||
sayToLog(Rulebase->EngineVersion()); // version info to show we're ok. | |||||
sayToLog(Rulebase->PlatformVersion()); // Log our platform and engine | |||||
string ConfigInfo = "SNF Config: "; // Build a configuration info | |||||
ConfigInfo.append(Configuration); // message and display that | |||||
sayToLog(ConfigInfo); // too. | |||||
} | |||||
catch(snf_RulebaseHandler::ConfigurationError) { // Can't work with config file! | |||||
string ErrorMessage = "Unable to Configure with: "; // Tell them about it and give | |||||
ErrorMessage.append(Configuration); // them a hint where we looked. | |||||
sayToScreen(ErrorMessage); | |||||
} | |||||
catch(snf_RulebaseHandler::FileError) { // Can't load the rulebase file! | |||||
string ErrorMessage = "Unable to Load Rulebase in: "; // Tell them about it and give | |||||
ErrorMessage.append(Configuration); // them a hint where we looked. | |||||
sayToScreen(ErrorMessage); | |||||
} | |||||
catch(snf_RulebaseHandler::AllocationError) { // Can't allocate memory! | |||||
sayToScreen("Unable to Allocate Enough Memory!"); // Tell them about it. | |||||
} | |||||
catch(snf_RulebaseHandler::IgnoreListError) { // Can't load ignore list! | |||||
sayToScreen("Unable to Load Ingore List!"); // Tell them about it. | |||||
} | |||||
catch(snf_RulebaseHandler::AuthenticationError) { // Can't authenticate! | |||||
sayToScreen("Unable to Authenticate Rulebase!"); // Tell them about it. | |||||
} | |||||
catch(snf_RulebaseHandler::Busy) { // Busy?!! That's weird. | |||||
sayToScreen("Busy Exception?!!"); // Tell them about it. | |||||
} | |||||
catch(snf_RulebaseHandler::Panic) { // Panic?!! That's weird. | |||||
sayToScreen("Panic Exception?!!"); // Tell them about it. | |||||
} | |||||
catch(exception& e) { // Some other runtime error? | |||||
sayToScreen(e.what()); // Tell them what it was. | |||||
} | |||||
catch(...) { // Catch the unknown exception. | |||||
sayToScreen("Unexpected Exception!"); // Tell them things didn't work. | |||||
} | |||||
return; // All done. | |||||
} | |||||
/****** THE FOLLOWING IS DEFUNCT, BUT USEFUL INFO SO WE KEEP IT! ******/ | |||||
/**** *Note: Why do we always return true even when we fail??? | |||||
***** Because, in a DLL that is being loaded, none of the threads that | |||||
***** get created in the rulebase object will get any cycles until the | |||||
***** DLL load sequence is complete _AND_SUCCESSFUL_! | |||||
***** | |||||
***** The same is true when we return false -- because then the OS KNOWS | |||||
***** that it's not safe to run any of the threads we've created. | |||||
***** | |||||
***** As a result, if we try to destroy our rulebase manager after an | |||||
***** unsuccessful load then all of the stop() calls to our threads will | |||||
***** block waiting for the initialized threads to see their stop bits and | |||||
***** end. Since none of these threads actually get any love until the | |||||
***** DLL is successfully loaded, we end up waiting happily for ever! | |||||
***** | |||||
***** Instead of stepping into this world of hurt, we've decided to leave | |||||
***** the internal flag set to indicate that the engine is Not-Good so that | |||||
***** the scanning functions remain inert, and then we wait patiently for | |||||
***** the DLL to be unloaded. | |||||
***** | |||||
***** When that happens, since the OS KNOWS the DLL was loaded happily | |||||
***** before, the objects can go through their normal destruction without | |||||
***** deadlocking on their stop() functions (join()). | |||||
****/ | |||||
DLL_EXPORT void _stdcall Shutdown(HWND Parent) { // How to get all this stopped. | |||||
LatestParent = Parent; | |||||
if(EngineIsGood) { // If the engine is good: | |||||
try { | |||||
EngineIsGood = false; // Stop using the engine now. | |||||
LatestParent = 0; // No more logging calls. | |||||
if(ScanEngine) { // Close the scanner if it exists: | |||||
ScanEngine->close(); // Close it. | |||||
delete ScanEngine; // Delete it. | |||||
ScanEngine = 0; // Forget it. | |||||
} | |||||
if(Rulebase) { // Close the rulebase if it exists. | |||||
Rulebase->close(); // Close it. | |||||
delete Rulebase; // Delete it. | |||||
Rulebase = 0; // Forget it. | |||||
} | |||||
if(PlatformConfig) { // Drop the PlatformConfig if it be. | |||||
delete PlatformConfig; // Delete it. | |||||
PlatformConfig = 0; // Forget it. | |||||
} | |||||
Generation = -1; // Reset our config gen tag. | |||||
sayToLog("SNF: Plugin Shutdown."); // Tell them we're shut down. | |||||
} | |||||
catch(exception& e) { // If we have a runtime exception | |||||
string InShutdown = "SNF, Shutdown: "; // make a human friendly message | |||||
InShutdown.append(e.what()); // and package the exception for | |||||
sayToScreen(InShutdown); // a screen pop-up. | |||||
} | |||||
catch(...) { // If we see some other kind of | |||||
sayToScreen("SNF, Shutdown: Unknown Exception"); // exception then show that. | |||||
} | |||||
} | |||||
return; // All done. | |||||
} | |||||
// Now we get to the business end of the plugin. Three functions are exported. | |||||
// ConfigFunc() launches an editor for the configuration file. | |||||
// 20080311 _M Adjusted ConfigFunc to use Platform Configuration Parameters. | |||||
DLL_EXPORT void _stdcall ConfigFunc(HWND Parent) { // Configuration function. | |||||
LatestParent = Parent; // Capture the parent for logging. | |||||
string ConfiguratorString = PlatformConfig->ConfiguratorCommand(); // Get Configurator launch command. | |||||
if(0 < ConfiguratorString.length()) system(ConfiguratorString.c_str()); // If we have a launch command use it. | |||||
} | |||||
// MessageFunc() scans a message file and injects headers. | |||||
DLL_EXPORT void _stdcall MessageFunc(HWND Parent, const char* File) { // Message Scan Function. | |||||
LatestParent = Parent; // Capture the parent for logging. | |||||
string LogMessage = "SNF MessageScan: "; // Start a plugin log entry. | |||||
LogMessage.append(File); // add the file name. | |||||
if(false == EngineIsGood) { // If the engine is not up then | |||||
LogMessage.append(", Engine Not Ready!"); // report that in the plug-in log. | |||||
sayToLog(LogMessage); // Post our entry to the plug-in log. | |||||
return; // We're done. | |||||
} | |||||
// We are ready to begin our scan. | |||||
int ResultCode = 0; // Keep track of the scan result. | |||||
try { // Be sure to catch any exceptions. | |||||
ResultCode = ScanEngine->scanMessageFile(File); | |||||
} | |||||
catch(snf_EngineHandler::FileError& e) { // Exception when a file won't open. | |||||
LogMessage.append(", File Error!"); | |||||
sayToLog(LogMessage); | |||||
string DebugData = "SNF Debug: "; | |||||
DebugData.append(e.what()); | |||||
sayToLog(DebugData); | |||||
return; | |||||
} | |||||
catch(snf_EngineHandler::XHDRError& e) { // Exception when XHDR Inject/File fails. | |||||
LogMessage.append(", X-Header Error!"); | |||||
sayToLog(LogMessage); | |||||
string DebugData = "SNF Debug: "; | |||||
DebugData.append(e.what()); | |||||
sayToLog(DebugData); | |||||
return; | |||||
} | |||||
catch(snf_EngineHandler::BadMatrix& e) { // Exception out of bounds of matrix. | |||||
LogMessage.append(", Bad Matrix!"); | |||||
sayToLog(LogMessage); | |||||
string DebugData = "SNF Debug: "; | |||||
DebugData.append(e.what()); | |||||
sayToLog(DebugData); | |||||
return; | |||||
} | |||||
catch(snf_EngineHandler::MaxEvals& e) { // Exception too many evaluators. | |||||
LogMessage.append(", Too Many Evaluators!"); | |||||
sayToLog(LogMessage); | |||||
string DebugData = "SNF Debug: "; | |||||
DebugData.append(e.what()); | |||||
sayToLog(DebugData); | |||||
return; | |||||
} | |||||
catch(snf_EngineHandler::AllocationError& e) { // Exception when we can't allocate something. | |||||
LogMessage.append(", Allocation Error!"); | |||||
sayToLog(LogMessage); | |||||
string DebugData = "SNF Debug: "; | |||||
DebugData.append(e.what()); | |||||
sayToLog(DebugData); | |||||
return; | |||||
} | |||||
catch(snf_EngineHandler::Busy& e) { // Exception when there is a collision. | |||||
LogMessage.append(", Engine Busy!"); | |||||
sayToLog(LogMessage); | |||||
string DebugData = "SNF Debug: "; | |||||
DebugData.append(e.what()); | |||||
sayToLog(DebugData); | |||||
return; | |||||
} | |||||
catch(snf_EngineHandler::Panic& e) { // Exception when something else happens. | |||||
LogMessage.append(", Engine Panic!"); | |||||
sayToLog(LogMessage); | |||||
string DebugData = "SNF Debug: "; | |||||
DebugData.append(e.what()); | |||||
sayToLog(DebugData); | |||||
return; | |||||
} | |||||
catch(exception& e) { // Some unexpected exception. | |||||
LogMessage.append(", Unexpected Exception!"); | |||||
sayToLog(LogMessage); | |||||
string DebugData = "SNF Debug: "; | |||||
DebugData.append(e.what()); | |||||
sayToLog(DebugData); | |||||
return; | |||||
} | |||||
catch(...) { // We should never get one of these, but | |||||
LogMessage.append(", Non-Std Exception!"); // if we do we have something to say. | |||||
sayToLog(LogMessage); | |||||
return; | |||||
} | |||||
// At this point we know our scan worked ok. So, let's post the result. | |||||
ostringstream O; // A stringstream makes it easy to | |||||
O << LogMessage << ", Result=" << ResultCode; // format our plug-in log entry. | |||||
sayToLog(O.str()); // Then we post it to the plug-in log. | |||||
} | |||||
// ControlFilePath(MessageFilePath) Converts .msg path to .ctl path. | |||||
string ControlFilePath(string MessageFilePath) { // Convert .msg/.tmp to .ctl path. | |||||
const string ControlFileExt(".ctl"); // Control file extension. | |||||
const string EmptyString(""); // The empty string. | |||||
string ControlFilePath(MessageFilePath); // Start with the message path. | |||||
string::size_type CFExtPosition = ControlFilePath.find_last_of('.'); // Find the extension. | |||||
if(string::npos == CFExtPosition) return EmptyString; // If we didn't find it return "" | |||||
ControlFilePath.replace( // Replace the message file | |||||
CFExtPosition, ControlFileExt.length(), // extension with the control | |||||
ControlFileExt // file extension. | |||||
); | |||||
return ControlFilePath; | |||||
} | |||||
// MessageIPFunc() looks at the control file for a message, extracts the | |||||
// source IP, and deletes the message if the IP is in the truncate range. | |||||
DLL_EXPORT void _stdcall MessageIPFunc(HWND Parent, const char* File) { // IP Scan Function. | |||||
LatestParent = Parent; // Capture the parent for logging. | |||||
if(false == PlatformConfig->MessageIPFuncOn()) { // If the IP func is off: | |||||
return; // We're done. | |||||
} | |||||
string LogMessage = "SNF IPScan: "; // Start a plugin log entry. | |||||
LogMessage.append(File); // add the file name. | |||||
if(false == EngineIsGood) { // If the engine is not up then | |||||
LogMessage.append(", Engine Not Ready!"); // report that in the plug-in log. | |||||
sayToLog(LogMessage); // Post our entry to the plug-in log. | |||||
return; // We're done. | |||||
} | |||||
// Open the control file and find the RemoteIP | |||||
const string CtlRemoteIP("RemoteIP="); // This is what we're looking for. | |||||
string RemoteIP = ""; // This is where it will go. | |||||
try { // Do this safely. | |||||
ifstream ControlFile(ControlFilePath(File).c_str()); // Open the control file. | |||||
while(ControlFile) { // While the file is good... | |||||
string Line; // Read one line at a time | |||||
getline(ControlFile, Line); // into a string. | |||||
string::size_type TagPos = Line.find(CtlRemoteIP); // Look for the RemoteIP tag. | |||||
if(string::npos != TagPos) { // If we find the RemoteIP tag: | |||||
RemoteIP = Line.substr(TagPos + CtlRemoteIP.length()); // Get the string after the tag | |||||
break; // We're done with the ctl file! | |||||
} | |||||
} | |||||
ControlFile.close(); // Be nice and close our file. | |||||
} | |||||
catch(...) {} // Eat any exceptions. | |||||
if(0 == RemoteIP.length()) { // If we didn't get the IP then | |||||
LogMessage.append(", Didn't Get Remote IP!"); // make that the rest of our log | |||||
sayToLog(LogMessage); // entry and post it. | |||||
return; // We're done. | |||||
} | |||||
// At this point we have the remote IP to check. | |||||
LogMessage.append(", "); LogMessage.append(RemoteIP); // Add the IP to the log entry. | |||||
IPTestRecord IPAnalysis(RemoteIP); // Set up a test record. | |||||
try { // Safely, | |||||
Rulebase->performIPTest(IPAnalysis); // check the IP w/ GBUdb. | |||||
} | |||||
catch(...) { // If we encountered a problem | |||||
LogMessage.append(", Analysis Failed!"); // then we need to report that | |||||
sayToLog(LogMessage); // our analysis failed. | |||||
return; // We're done. | |||||
} | |||||
// At this point we've got a good analysis, so we take action (if needed) | |||||
// and produce a helpful log entry. | |||||
ostringstream Happy; // A stringstream for easy formatting. | |||||
Happy << LogMessage << ", {"; // Start the analysis report. | |||||
switch(IPAnalysis.G.Flag()) { // Identify the flag data for this IP. | |||||
case Good: Happy << "Good, "; break; | |||||
case Bad: Happy << "Bad, "; break; | |||||
case Ugly: Happy << "Ugly, "; break; | |||||
case Ignore: Happy << "Ignore, "; break; | |||||
} | |||||
Happy << "p=" << IPAnalysis.G.Probability() << ", " // Probability and Confidence. | |||||
<< "c=" << IPAnalysis.G.Confidence() << ", "; | |||||
switch(IPAnalysis.R) { // The Range analysis. | |||||
case Unknown: { Happy << " Unknown}"; break; } // Unknown - not defined. | |||||
case White: { Happy << " White}"; break; } // This is a good guy. | |||||
case Normal: { Happy << " Normal}"; break; } // Benefit of the doubt. | |||||
case New: { Happy << " New}"; break; } // It is new to us. | |||||
case Caution: { Happy << " Caution}"; break; } // This is suspicious. | |||||
case Black: { Happy << " Black}"; break; } // This is bad. | |||||
case Truncate: { Happy << " Truncate}"; break; } // This is bad unless we ignore it. | |||||
} | |||||
string WhatWeDid; // So, what do we do? | |||||
if( // Are we in Truncate land? | |||||
(Truncate == IPAnalysis.R && Ugly == IPAnalysis.G.Flag()) || // If the IP is Truncate & Ugly, or | |||||
Bad == IPAnalysis.G.Flag() // If the IP is just plain bad then | |||||
) { // we are in truncate land so we | |||||
Happy << " Rejected!"; WhatWeDid = "Rejected"; // mark the message Rejected! and | |||||
remove(File); // remove the file to reject it! | |||||
} else { // If we are not rejecting the | |||||
Happy << " Allowed."; WhatWeDid = "Allowed"; // message tell them it's allowed. | |||||
} | |||||
Rulebase->logThisIPTest(IPAnalysis, WhatWeDid); // Log the event. | |||||
sayToLog(Happy.str()); // Post to the plug-in log. | |||||
} |
// mdconfiguration.cpp | |||||
// SNF MDaemon Plugin: Platform Configuration Module | |||||
// Copyright (C) 2007-2008, ARM Research Labs, LLC. | |||||
#include "mdconfiguration.hpp" | |||||
MDConfiguration::MDConfiguration(snf_RulebaseHandler& R, string& C) : // Default constructor. | |||||
MyCFGReader("mdaemon"), // The top element is "mdaemon" | |||||
MyGeneration(-1), // Our first real gen will be 0. | |||||
MyMessageIPFuncOn(true), // By default the IP func is on. | |||||
MyConfiguratorCommand("start notepad"), // By default we start notepad to | |||||
MyAppendConfigurationFileOn(true), // edit our config and pass it the path. | |||||
MyConfigurationPath(C), // This is the config file path. | |||||
MyRulebase(R) { // This is the rulebase manager. | |||||
// Here we construct the configuration elements that will parse the platform | |||||
// configuration data from our rulebase manager. | |||||
MyCFGReader | |||||
.Element("ip-test") | |||||
.Attribute("on-off", MyMessageIPFuncOn, false) | |||||
.End("ip-test") | |||||
.Element("configurator") | |||||
.Attribute("command", MyConfiguratorCommand, "") | |||||
.Attribute("append-path", MyAppendConfigurationFileOn, true) | |||||
.End("configurator") | |||||
.End("mdaemon"); | |||||
} | |||||
int MDConfiguration::Generation() { // When checking our generation we | |||||
return MyGeneration; // need only return what we have. | |||||
} | |||||
bool MDConfiguration::MessageIPFuncOn() { // Are we using the MessageIP function? | |||||
ScopeMutex EverybodyFreeze(MyMutex); // Freeze the mutex. | |||||
updateConfig(); // Update the configuration if needed. | |||||
return MyMessageIPFuncOn; // Return the IP Func On/Off value. | |||||
} | |||||
string MDConfiguration::ConfiguratorCommand() { // Return proper configurator command. | |||||
ScopeMutex EverybodyFreeze(MyMutex); // Freeze the mutex. | |||||
updateConfig(); // Update the configuration. | |||||
string ConfiguratorCommandString = ""; // Keep this in scope. | |||||
if(0 < MyConfiguratorCommand.length()) { // If we have a command configured: | |||||
ConfiguratorCommandString = MyConfiguratorCommand; // capture that command. | |||||
if(MyAppendConfigurationFileOn) { // If we are supposed to append the | |||||
ConfiguratorCommandString.append(" "); // configuration file path then | |||||
ConfiguratorCommandString.append(MyConfigurationPath); // tack that on the end. | |||||
} // If the configure command string was | |||||
} // configured empty we will return "". | |||||
return ConfiguratorCommandString; // Send back what we got. | |||||
} | |||||
void MDConfiguration::updateConfig() { // Parse & update the config if needed. | |||||
if(MyGeneration != MyRulebase.Generation()) { // If our config is out of sync: | |||||
try { // Catch any parsing errors. | |||||
string NewConfiguration = MyRulebase.PlatformConfiguration(); // Grab the configuration string. | |||||
ConfigurationData MyConfigData( // Load the configuration string | |||||
NewConfiguration.c_str(), NewConfiguration.length()); // into a configuration data object. | |||||
MyCFGReader.initialize(); // Initialize the parser and | |||||
MyCFGReader.interpret(MyConfigData); // feed it the object. | |||||
MyGeneration = MyRulebase.Generation(); // Grab the new generation tag. | |||||
} | |||||
catch(...) { } // Eat any thrown exceptions. | |||||
} // If we're in sync we don't budge. | |||||
} | |||||
// mdconfiguration.hpp | |||||
// SNF MDaemon Plugin: Platform Configuration Module | |||||
// Copyright (C) 2007-2008, ARM Research Labs, LLC. | |||||
// This module handles the platform specific configuration for the MDaemon | |||||
// plugin. The rulebase is passed to the object when constructed. Each call to | |||||
// get a parameter from the object causes a quick check to the generation data. | |||||
// If the generation is still valid then the data is provided as is. If not then | |||||
// the configuration is updated before it is returned. All of this is protected | |||||
// by a mutex. | |||||
#ifndef included_mdconfiguration_hpp | |||||
#define included_mdconfiguration_hpp | |||||
#include <windows.h> | |||||
#include "../SNF_Service/SNFMulti.hpp" | |||||
#include "../SNF_Service/configuration.hpp" | |||||
#include "../SNF_Service/threading.hpp" | |||||
class MDConfiguration { | |||||
private: | |||||
Mutex MyMutex; // Protects configuration. | |||||
ConfigurationElement MyCFGReader; // This is how we read our cfg data. | |||||
string& MyConfigurationPath; // Configuration file path. | |||||
snf_RulebaseHandler& MyRulebase; // Rulebase manager at startup. | |||||
volatile int MyGeneration; // Numeric Generation Tag. | |||||
bool MyMessageIPFuncOn; // Message IP test on/off switch. | |||||
string MyConfiguratorCommand; // Config editor command string. | |||||
bool MyAppendConfigurationFileOn; // Append config file path to command? | |||||
void updateConfig(); // Update config if needed. | |||||
public: | |||||
MDConfiguration(snf_RulebaseHandler& R, string& C); // Default constructor. | |||||
int Generation(); // Numeric generation tag. | |||||
bool MessageIPFuncOn(); // Message IP test on/off switch. | |||||
string ConfiguratorCommand(); // Configure function command string. | |||||
}; | |||||
#endif | |||||