Browse Source

git-svn-id: https://svn.microneil.com/svn/SNFMDaemon/trunk@1 13d20bd5-6e17-40a7-8d3d-b09f2b4ffc6d

master
madscientist 14 years ago
commit
d73de20c85
36 changed files with 2780 additions and 0 deletions
  1. 4
    0
      Distribution_20090514/About-Wget-and-Gzip.txt
  2. 449
    0
      Distribution_20090514/ChangeLog.txt
  3. 10
    0
      Distribution_20090514/GBUdbIgnoreList.txt
  4. 146
    0
      Distribution_20090514/InstallInstructions.txt
  5. 11
    0
      Distribution_20090514/Plugins.dat
  6. BIN
      Distribution_20090514/SNFClient.exe
  7. 182
    0
      Distribution_20090514/SNFClient_readme.txt
  8. 47
    0
      Distribution_20090514/getRulebase.cmd
  9. BIN
      Distribution_20090514/gzip.exe
  10. 1
    0
      Distribution_20090514/identity.xml
  11. BIN
      Distribution_20090514/mingwm10.dll
  12. 80
    0
      Distribution_20090514/snf-groups.cf
  13. BIN
      Distribution_20090514/snf2check.exe
  14. BIN
      Distribution_20090514/snfmdplugin.dll
  15. 156
    0
      Distribution_20090514/snfmdplugin.xml
  16. BIN
      Distribution_20090514/wget.exe
  17. 4
    0
      Distribution_20101124/About-Wget-and-Gzip.txt
  18. 449
    0
      Distribution_20101124/ChangeLog.txt
  19. 10
    0
      Distribution_20101124/GBUdbIgnoreList.txt
  20. 146
    0
      Distribution_20101124/InstallInstructions.txt
  21. 11
    0
      Distribution_20101124/Plugins.dat
  22. BIN
      Distribution_20101124/SNFClient.exe
  23. 182
    0
      Distribution_20101124/SNFClient_readme.txt
  24. 47
    0
      Distribution_20101124/getRulebase.cmd
  25. BIN
      Distribution_20101124/gzip.exe
  26. 1
    0
      Distribution_20101124/identity.xml
  27. BIN
      Distribution_20101124/mingwm10.dll
  28. 80
    0
      Distribution_20101124/snf-groups.cf
  29. BIN
      Distribution_20101124/snf2check.exe
  30. BIN
      Distribution_20101124/snfmdplugin.dll
  31. 156
    0
      Distribution_20101124/snfmdplugin.xml
  32. BIN
      Distribution_20101124/wget.exe
  33. 6
    0
      SNFMDaemonDLL/libsnfmdplugin.def
  34. 487
    0
      SNFMDaemonDLL/main.cpp
  35. 68
    0
      SNFMDaemonDLL/mdconfiguration.cpp
  36. 47
    0
      SNFMDaemonDLL/mdconfiguration.hpp

+ 4
- 0
Distribution_20090514/About-Wget-and-Gzip.txt View File

@@ -0,0 +1,4 @@
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.

+ 449
- 0
Distribution_20090514/ChangeLog.txt View File

@@ -0,0 +1,449 @@
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.

+ 10
- 0
Distribution_20090514/GBUdbIgnoreList.txt View File

@@ -0,0 +1,10 @@
# 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.

+ 146
- 0
Distribution_20090514/InstallInstructions.txt View File

@@ -0,0 +1,146 @@
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

+ 11
- 0
Distribution_20090514/Plugins.dat View File

@@ -0,0 +1,11 @@
[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

BIN
Distribution_20090514/SNFClient.exe View File


+ 182
- 0
Distribution_20090514/SNFClient_readme.txt View File

@@ -0,0 +1,182 @@
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.

+ 47
- 0
Distribution_20090514/getRulebase.cmd View File

@@ -0,0 +1,47 @@
@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

BIN
Distribution_20090514/gzip.exe View File


+ 1
- 0
Distribution_20090514/identity.xml View File

@@ -0,0 +1 @@
<snf><identity licenseid='licensid' authentication='authenticationxx'/></snf>

BIN
Distribution_20090514/mingwm10.dll View File


+ 80
- 0
Distribution_20090514/snf-groups.cf View File

@@ -0,0 +1,80 @@
## 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/

BIN
Distribution_20090514/snf2check.exe View File


BIN
Distribution_20090514/snfmdplugin.dll View File


+ 156
- 0
Distribution_20090514/snfmdplugin.xml View File

@@ -0,0 +1,156 @@
<!-- 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>

BIN
Distribution_20090514/wget.exe View File


+ 4
- 0
Distribution_20101124/About-Wget-and-Gzip.txt View File

@@ -0,0 +1,4 @@
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.

+ 449
- 0
Distribution_20101124/ChangeLog.txt View File

@@ -0,0 +1,449 @@
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.

+ 10
- 0
Distribution_20101124/GBUdbIgnoreList.txt View File

@@ -0,0 +1,10 @@
# 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.

+ 146
- 0
Distribution_20101124/InstallInstructions.txt View File

@@ -0,0 +1,146 @@
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

+ 11
- 0
Distribution_20101124/Plugins.dat View File

@@ -0,0 +1,11 @@
[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

BIN
Distribution_20101124/SNFClient.exe View File


+ 182
- 0
Distribution_20101124/SNFClient_readme.txt View File

@@ -0,0 +1,182 @@
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.

+ 47
- 0
Distribution_20101124/getRulebase.cmd View File

@@ -0,0 +1,47 @@
@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

BIN
Distribution_20101124/gzip.exe View File


+ 1
- 0
Distribution_20101124/identity.xml View File

@@ -0,0 +1 @@
<snf><identity licenseid='licensid' authentication='authenticationxx'/></snf>

BIN
Distribution_20101124/mingwm10.dll View File


+ 80
- 0
Distribution_20101124/snf-groups.cf View File

@@ -0,0 +1,80 @@
## 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/

BIN
Distribution_20101124/snf2check.exe View File


BIN
Distribution_20101124/snfmdplugin.dll View File


+ 156
- 0
Distribution_20101124/snfmdplugin.xml View File

@@ -0,0 +1,156 @@
<!-- 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>

BIN
Distribution_20101124/wget.exe View File


+ 6
- 0
SNFMDaemonDLL/libsnfmdplugin.def View File

@@ -0,0 +1,6 @@
EXPORTS
ConfigFunc@4 @1
MessageFunc@8 @2
MessageIPFunc@8 @3
Shutdown@4 @4
Startup@4 @5

+ 487
- 0
SNFMDaemonDLL/main.cpp View File

@@ -0,0 +1,487 @@
// 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.
}

+ 68
- 0
SNFMDaemonDLL/mdconfiguration.cpp View File

@@ -0,0 +1,68 @@
// 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.
}

+ 47
- 0
SNFMDaemonDLL/mdconfiguration.hpp View File

@@ -0,0 +1,47 @@
// 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

Loading…
Cancel
Save