Updated all README files.master
@@ -0,0 +1,68 @@ | |||
20090707 Upgraded Engine to SNFMulti V3.0.8 (contains minor bug fixes). | |||
20090704 Getting closer - new DLL, new features, a little polish. | |||
NOTE: Beginning with this update this ChangeLog will only list hilights. | |||
For more details check the logs at https://svn.microneil.com/websvn/ | |||
* snfmulti.dll is now at version 3.0, engine 3.0.7 | |||
* Used newer MinGW with improved optimizations | |||
* Using newest SNF engine with several minor bug fixes | |||
* Added startupSNFAuthenticated() so OEMs can protect SNF license info | |||
* Added getIPReputation() to aid in converting GBUdb stats to weights | |||
* Added C++ sample code | |||
* Reorganized SNFMulti code base. | |||
20090317 Work in progess toward SDK release. | |||
* Included latest getRulebase.cmd and curl.exe | |||
* Included SNFClient_readme.txt and SNFServer_readme.txt | |||
* Included / updated SNFClient, and snf_engine.xml | |||
* Added ReadMe.html - includes API documentation | |||
* Added missing snf_ERROR_EXCEPTION to snfmultidll.h file | |||
* Removed redundant #define EXP __declspec(dllexport) from snfmultidll.cpp | |||
20080723 Version 2.9r3 - Engine 3.0 | |||
* Compiled DLL using new SNF engine V3.0. | |||
* Added snf_ERROR_EXCEPTION result (-3) to show when an exception occurred | |||
during a call that could not be expressed with one of the normal SNF result | |||
codes. | |||
* Wraped DLLMain() functions in a try/catch to eat any exceptions. If an | |||
exception occurs the function will return false; | |||
* Added pre-allocation to result cache buffers to minimize heap allocation | |||
during operations. The pre-allocated amount should be sufficient for all | |||
cases. If it is not then the string objects will allocate more as needed. | |||
* Changed snf_ERROR_UNKNOWN to snf_ERROR_EXCEPTION for startupSNF() and | |||
shutdownSNF(). | |||
* Wrapped testIP() in try/catch - now returns snf_ERROR_EXCEPTION if an | |||
exception occurs. | |||
* Wrapped getScanXHeaders() in try/catch - now returns snf_ERROR_EXCEPTION | |||
if an exception occurs. | |||
* Wrapped getScanXMLLog() in try/catch - now returns snf_ERROR_EXCEPTION | |||
if an exception occurs. | |||
* Wrapped getScanClassicLog() in try/catch - now returns snf_ERROR_EXCEPTION | |||
if an exception occurs. | |||
* Wrapped closeScan() in try/catch - now returns snf_ERROR_EXCEPTION | |||
if an exception occurs. | |||
@@ -0,0 +1,9 @@ | |||
# 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. |
@@ -0,0 +1,562 @@ | |||
<!-- Copyright 2009, ARM Research Labs, LLC --> | |||
<html> | |||
<body> | |||
<font face="sans-serif"> | |||
<h1>Message Sniffer SDK for Win* V3.1</h1> | |||
<h2>Contents</h2> | |||
</font><h3><ol> | |||
<p><font face="sans-serif">Introduction</font></p> | |||
<li><font face="sans-serif"><a href="#Begin">Before you begin!</a></font></li> | |||
<li><font face="sans-serif"><a href="#Contents">Contents of the SDK</a></font></li> | |||
<li><font face="sans-serif"><a href="#Description">SNFMulti DLL Description</a></font></li> | |||
<li><font face="sans-serif"><a href="ChangeLog.txt">Change Log</a></font></li> | |||
<p><font face="sans-serif">Setup notes and important instructions</font></p> | |||
<li><font face="sans-serif"><a href="SNFServer_readme.txt">SNFServer Setup Readme</a></font></li> | |||
<li><font face="sans-serif"><a href="SNFClient_readme.txt">SNFClient Setup Readme</a></font></li> | |||
<p><font face="sans-serif">Code Samples</font></p> | |||
<li><font face="sans-serif"><a href="32bitDll/snfmultidll.h">C Header File (snfmultidll.h></a></font></li> | |||
<li><font face="sans-serif"><a href="32bitDll/libsnfmulti.def">Module Definition File (libsnfmulti.def)</a></font></li> | |||
<li><font face="sans-serif"><a href="C++/main.cpp">C++ Sample Code</a></font></li> | |||
<li><font face="sans-serif"><a href="VB/SNFMulti_in_VB.Net.txt">VB.Net Sample Code</a></font></li> | |||
<p><font face="sans-serif">API Reference - Functions listed in the order they should be used</font></p> | |||
<li><font face="sans-serif"><a href="#startupSNF">startupSNF()</a> - Initializes the SNF engine and loads the rule base</font></li> | |||
<li><font face="sans-serif"><a href="#startupSNFAuthenticated">startupSNFAuthenticated()</a> - Initializes SNF with license info</font></li> | |||
<li><font face="sans-serif"><a href="#setThrottle">setThrottle()</a> - Sets a concurrent thread limit (if desired)</font></li> | |||
<li><font face="sans-serif"><a href="#testIP">testIP()</a> - Returns the GBUdb reputation range for an IP</font></li> | |||
<li><font face="sans-serif"><a href="#getIPReputation">getIPReputation()</a> - Returns IP Reputation Figure for an IP</font></li> | |||
<li><font face="sans-serif"><a href="#scanBuffer">scanBuffer()</a> - Scans a message buffer</font></li> | |||
<li><font face="sans-serif"><a href="#scanFile">scanFile()</a> - Scans a message file</font></li> | |||
<li><font face="sans-serif"><a href="#getScanXHeaders">getScanXHeaders()</a> - Returns the scan result and XHeaders</font></li> | |||
<li><font face="sans-serif"><a href="#getScanXMLLog">getScanXMLLog()</a> - Returns the scan result and XML Log data</font></li> | |||
<li><font face="sans-serif"><a href="#getScanClassicLog">getScanClassicLog()</a> - Returns the scan result and Classic Log Data</font></li> | |||
<li><font face="sans-serif"><a href="#getScanResult">getScanResult()</a> - Returns the scan result (nothing else)</font></li> | |||
<li><font face="sans-serif"><a href="#closeScan">closeScan()</a> - Closes the scan and releases resources</font></li> | |||
<li><font face="sans-serif"><a href="#shutdownSNF">shutdownSNF()</a> - Shuts down the SNF engine</font></li> | |||
<p><font face="sans-serif">Miscellaneous</font></p> | |||
<li><font face="sans-serif"><a href="#ResultCodes">Result Codes</a> - Error and Scan Result Mnemonics</font></li> | |||
</ol></h3><font face="sans-serif"> | |||
<hr/> | |||
<a name="Begin"><h3>Before you begin!</h3></a> | |||
<p>This SDK contains a complete Message Sniffer engine. You MUST be familiar with that engine | |||
before you can effectively use this SDK. If you do not already have an OEM license or trial | |||
SNF rule base license then please <a href="http://www.armresearch.com/">visit our web site first | |||
and get one!</a> The engine won't run without it.</p> | |||
<p>We highly recommend that you have some experience with our SNFServer and SNFClient applications | |||
before you begin writing your own or begin integrating the SNF engine into your own software.</p> | |||
<p>We're not saying it's hard to do -- quite the opposite actually, BUT SNF is a sophisticated | |||
piece of software with a lot of capabilities and options. You will have much better results | |||
if you are familiar with these before you begin ;-)</p> | |||
<hr/> | |||
<a name="Contents"><h3>Contents of the SDK</h3></a> | |||
<p>This SDK contains the following: | |||
<ol> | |||
<li><font face="sans-serif">Documentation files, including | |||
this file.</font></li> | |||
<li><font face="sans-serif">DLLs (both 32 bit and 64 bit | |||
versions) and the required header files (in | |||
directory <b>include</b>).</font></li> | |||
<li><font face="sans-serif">Sample programs in C++ (in | |||
directory <b>CPPSample</b>), C# (<b>CSSample</b>), and Visual | |||
Basic (<b>VBSample</b>).</font></li> | |||
<li><font face="sans-serif">VS 2008 Solution files to build | |||
the sample program in C++ (in | |||
directory <b>VS2008CPPSample</b>), in C# | |||
(<b>VS2008CSSample</b>), and Visual Basic | |||
(<b>VS2008VBSample</b>).<br> | |||
The <b>VS2008CPPSample\README</b> contains instructions for | |||
creating the SNFMulti import libraries for use with VS 2008. | |||
</font></li> | |||
<li><font face="sans-serif">Other applications | |||
(<b>curl</b>, <b>SNFClient</b>, and <b>getRulebase</b>) and | |||
configuration files needed to support SNF | |||
operation.</font></li> | |||
</ol> | |||
There are also directions for building VS 2008 import libraries in <b>VS2008CPPSample\README</b>. | |||
</p> | |||
<hr/> | |||
<a name="Description"><h3>SNFMulti DLL Description</h3></a> | |||
<p>The SNF SDK for Win* is based on a DLL. The DLLs for both the 32 bit | |||
and 64 bit versions are included here. | |||
</p> | |||
<p>The DLL contains the entire SNFServer engine and provides a simple API for starting the | |||
engine, scanning messages, and retrieving the results. Since the entire SNFServer engine is | |||
included you also have the option of using the SNFClient utility once your application has | |||
started the SNF engine. You can also make calls to the engine using the XCI protocol (which | |||
is how SNFClient does it's work)</p> | |||
<p>Of course the best way to use the DLL is to perform scans directly through the API. The | |||
best performance can be achieved by scanning a message in memory via the scanBuffer() function | |||
since this can be done at the full speed of the processor without waiting for IO operations.</p> | |||
<p>The DLL is fully thread-safe so you can perform as many concurrent scans as you wish. Also, | |||
just in case it will make things easier for you, the DLL provides a throttling function which | |||
can limit the number of concurrent scans. (It won't unless you ask it to.)</p> | |||
<p>The general form of an application using the DLL will first start the engine, then | |||
optionally set the throttle, then perform scans (perform a scan, get results, close the scan, repeat), | |||
and finally it will shutdown the engine.</p> | |||
<p>Since the DLL contains the entire SNFServer engine, it can (and must) be configured in | |||
exactly the same way as SNFServer. <a href="http://www.armresearch.com/support/articles/software/snfServer/config/index.jsp"> | |||
Documentation for configuring SNFServer can be found on our web site.</a></p> | |||
<p>New in snfmulti.dll V3.0!</p> | |||
<p>OEM developers can now protect their licenseID and Authentication string by providing it directly to the SNF engine at run-time. When combined with an internal mechanism for downloading rule base files this makes it practical to control SNF license information entirely within the OEM's application. <a href="#startupSNFAuthenticated">See startupSNFAuthenticated() for details.</a></p> | |||
<hr/> | |||
<a name="startupSNF"><h3>int startupSNF(char* path);</h3></a> | |||
<p>This function initializes the SNF scanning engine using the configuration file provided. | |||
The configuration file identifies all of the operational parameters for the SNF engine including | |||
the location of the working directories and rule base file, SNF license information, and | |||
much more. <a href="http://www.armresearch.com/support/articles/software/snfServer/config/index.jsp"> | |||
See our web site for details on configuring the SNF engine.</a></p> | |||
<dl> | |||
<dd><b>path</b> = The full path to the snf_engine.xml file as a null terminated string.</dd> | |||
<dd><b>returns</b> snf_SUCCESS when successful, otherwise see <a href="#ResultCodes">Error Codes</a>.</dd> | |||
</dl> | |||
<hr/> | |||
<a name="startupSNFAuthenticated"><h3>int startupSNFAuthenticated(char* path, char* lic, char* auth);</h3></a> | |||
<p>This function initializes the SNF scanning engine using the configuration file and authentication | |||
information provided. When SNF is started with this function the identity.xml file can be omitted and | |||
the identity= attribute of the <node/> element in snf_engine.xml can be omitted. This allows OEM | |||
developers to protect their authentication string by retrieving it from an encrypted source at run-time | |||
and providing it directly to the SNF engine.</p> | |||
<p>In all other ways the SNF engine is configured in the same as when using <a href="#startupSNF">startupSNF() (see above)</a></p> | |||
<p>Note that if you intend to use this mechanism to protect your SNF license information you will also need to | |||
address the mechanism you use to download and verify rule base files. Either build a mechanism to download and | |||
authenticate your rule base file without exposing your authentication string or you might modify the existing | |||
getRulebase script to remove the snf2check operation and the associated authentication string. The SNF engine will | |||
check all rule base files before they are loaded for scanning and will refuse to load a rule base file that does | |||
not authenticate properly.</p> | |||
<dl> | |||
<dd><b>path</b> = The full path to the snf_engine.xml file as a null terminated string.</dd> | |||
<dd><b>lic</b> = The 8 character license id as a null terminated string.</dd> | |||
<dd><b>auth</b> = The 16 character authentication string as a null terminated string.</dd> | |||
<dd><b>returns</b> snf_SUCCESS when successful, otherwise see <a href="#ResultCodes">Error Codes</a>.</dd> | |||
</dl> | |||
<hr/> | |||
<a name="setThrottle"><h3>int setThrottle(int Threads);</h3></a> | |||
<p>This function establishes a limit on the number of concurrent scans that can run. Any additional | |||
threads will block until at least one of the active scans is completed.</p> | |||
<p>The default value for the throttle setting is zero. When the throttle is set to zero then no limits | |||
are placed on the number of concurrent scans. In this mode the application must limit the number of | |||
concurrent scans.</p> | |||
<dl> | |||
<dd><b>Threads</b> = The number of concurrent scans allowed.</dd> | |||
<dd><b>returns</b> the number of Threads if successful otherwise snf_ERROR_EXCEPTION.</dd> | |||
</dl> | |||
<hr/> | |||
<a name="testIP"><h3>int testIP(unsigned long int IPToCheck);</h3></a> | |||
<p>This function tests an IP against the GBUdb. This function returns very quickly and can be called | |||
as often as required without any follow-up actions as long as the SNF Engine is active (between startupSNF() | |||
and shutdownSNF()). This function is thread-safe and does not interfere with other scanning functions.</p> | |||
<p>GBUdb gathers it's statistics based on the message scans that are performed. Information about those | |||
scans is also shared with other SNF nodes approximately once every minute. No external queries are | |||
performed to gather GBUdb data. As a result GBUdb can only provide an IP reputation for IPs that sourced | |||
messages scanned by this SNF node.</p> | |||
<p>Put another way - GBUdb does not work like a conventional real-time black list. Message scans must | |||
be performed in order for GBUdb to provide IP reputation information.</p> | |||
<p>For more information on how GBUdb works visit the | |||
<a href="http://www.armresearch.com/support/articles/technology/GBUdb/index.jsp"> | |||
GBUdb Technology section of our web site.</a></p> | |||
<dl> | |||
<dd><b>IPToCheck</b> = The IP to test.</dd> | |||
<dd><b>returns</b> an integer representing the GBUdb Range associated with the IP if successful | |||
otherwise snf_ERROR_EXCEPTION.</dd> | |||
</dl> | |||
<h4>GBUdb Range MNemonics from enum snfIPRange</h4> | |||
<dl> | |||
<dd>Unknown, snf_IP_Unknown = 0</dd> | |||
<dd>White, snf_IP_White = 1</dd> | |||
<dd>Normal, snf_IP_Normal = 2</dd> | |||
<dd>New, snf_IP_New = 3</dd> | |||
<dd>Caution, snf_IP_Caution = 4</dd> | |||
<dd>Black, snf_IP_Black = 5</dd> | |||
<dd>Truncate, snf_IP_Truncate = 6</dd> | |||
</dl> | |||
<hr/> | |||
<a name="getIPReputation"><h3>double getIPReputation(unsigned long int IPToCheck);</h3></a> | |||
<p>This function returns a number representing the overall reputation of the IP based on local GBUdb statistics. | |||
This number (Reputation Figure) can be easily manipulated to provide additional weight values in systems that combine | |||
multiple tests using a weight based scoring system. The Reputation Figure is calculated by combining the Probability figure and the Confidence figure using the formula:</p> | |||
<pre>R = sign(P) * sqrt(abs(P * C))</pre> | |||
<p>This function returns very quickly and can be called as often as required without any follow-up actions as long | |||
as the SNF Engine is active (between startupSNF...() and shutdownSNF()). This function is thread-safe and does not interfere with other scanning functions.</p> | |||
<dl> | |||
<dd><b>IPToCheck</b> = The IP to test.</dd> | |||
<dd><b>returns</b> a number between -1.0 and +1.0 representing the combined probability that the IP will produce spam.</dd> | |||
</dl> | |||
<h4>Converting IP Reputation Figures To Weights</h4> | |||
<p>There are a number of ways to convert a Reputation figure to a weight value. The simplest is to simply multiply | |||
the Reputation figure by the maximum weight you wish to give to this test.</p> | |||
<pre>SimpleWeight = R * MaxReputationWeight</pre> | |||
<p>Since many legitimate ISPs also produce a lot of spam it might be useful to apply a bias to this weight so that | |||
these systems appear closer to zero. For example if you applied a maximum weight of 10 and found that many ISPs | |||
regularly scored 5 or more then you might add a Bias of -5 to bring those systems toward zero.</p> | |||
<pre>BiasedWeight = (R * MaxReputationWeight) + Bias</pre> | |||
<p>A more sophisticated system might allow for different weights on the positive and negative going Reputation | |||
figures so that the amount of negative or positive weight that can be applied can be adjusted independently. Such | |||
a system might also wish to apply a bias directly to the reputation figure before doing that calculation so that | |||
the zero point can be adjusted to compensate for averages.</p> | |||
<p>In a system like this if legitimate ISPs tended to get a Reputation Figure of 0.5 then the bias might be -0.5 | |||
so that this would become the zero point. Then the positive and negative weight factors could be adjusted so that | |||
the desired maximum and minimum weights can be achieved... Note that in this scenario the positive and negative | |||
weight settings are not maximum values. | |||
<pre>SplitWeight = (0 > (R + Bias)) ? ((R + Bias) * NegativeWeightFactor) : ((R + Bias) * PositiveWeightFactor) | |||
MaximumNegativeWeight is given by (-1.0 + Bias) * NegativeWeightFactor | |||
MaximumPositiveWeight is given by (+1.0 + Bias) * PositiveWeightFactor | |||
When R + Bias == 0.0, the weight will be 0.</pre> | |||
<p>The most sophisticated system might provide a graphic interface that maps the reputation figure directly | |||
to a desired weight. This would allow the user to shape the effect of the Reputation figure any way they wish in | |||
order to gain very tight control over their systems accuracy.</p> | |||
<hr/> | |||
<a name="scanBuffer"><h3>int scanBuffer(unsigned char* Bfr, int Length, char* Name, int Setup);</h3></a> | |||
<p>This function scans an SMTP message from a buffer. A scan result block is allocated for the scan | |||
and a handle representing the scan result block is returned. The application can then use this handle to retrieve | |||
the scan results using the get...() functions. When the application is finished it MUST release the | |||
scan result block with a call to closeScan().</p> | |||
<p>The message buffer is expected to contain the raw SMTP data for the message with the local Received: | |||
header at the top. The message should not be broken into MIME segments before it is scanned by SNFMulti. | |||
This is important because Message Sniffer examines the entire message as well as how the message was | |||
assembled by the originating system. Any additional processing is both unnecessary and may remove subtle | |||
defects and artifacts that will help Message Sniffer classify the message.</p> | |||
<p>If the message is particularly large it is acceptable to scan only the first 32K bytes of the message. | |||
This means that if the calling application wants to scan a large incoming message before it has received | |||
all of the DATA during the SMTP connection then it can scan the first 32K of the message and potentially | |||
reject the remainder based on the scan result.</p> | |||
<p>When the application is finished with the results from this scan it must release the scan result block | |||
with a call to closeScan(). Scan result blocks are allocated as needed and then recycled in order to improve | |||
performance. If the application fails to close the scan result blocks then the DLL will continue to | |||
allocate additional blocks until there is no more RAM.</p> | |||
<p>The entire scan is performed before this function returns. After that the scanning thread is no longer | |||
considered to be active. The resulting scan result buffer may be accessed as often as needed to gather | |||
results data from this scan without impacting any other scan operations.</p> | |||
<p>Any number of scan...() operations may be active concurrently up to the limits of the platform.</p> | |||
<p>The scanBuffer() function accepts two additional parameters that are passed on to the logging system | |||
to aid in debugging.</p> | |||
<p>The Name parameter is a null terminated string containing an identifier for the | |||
message being scanned. This can be any name that can be used later to identify this particular message | |||
in the log files such as a serial number, unique hash, or the message-id. For example, when the | |||
scanFile() function is called this parameter is filled in with the path to the file that was scanned.</p> | |||
<p>The Setup parameter is an integer representing the number of milliseconds spent so far setting up | |||
the message to be scanned. This can be any useful metric - but generally it should represent how much | |||
time the system has spent working on preparing and evaluating the message so far. For example, when the | |||
scanFile() function is called this value is automatically established with the amount of time spent | |||
opening and reading the message file.</p> | |||
<p><b>IMPORTANT:</b> SNF expects to identify the source IP for the message by searching Received: headers | |||
in the message. The application must ensure that the local Received: header is present as the first | |||
Received: header in the message in order for this search to be accurate. If necessary the calling application can | |||
simulate the local received header using the following minimal form:</p> | |||
<p><pre>Received: from connecting.mta.example.com [12.34.56.78] by this.scanning.system</pre></p> | |||
<p>where <b><i>connecting.mta.example.com</i></b> is the optional reverse DNS resolved for the connecting MTA; | |||
<b><i>12.34.56.78</i></b> is the IP of the connecting MTA; and <b><i>by this.scanning.system</i></b> is an optional | |||
reference to the calling application.</p> | |||
</font><dl> | |||
<dd><font face="sans-serif"><b>Bfr</b> = a pointer to the buffer that is to be scanned.</font></dd> | |||
<dd><font face="sans-serif"><b>Length</b> = the length of the message buffer in bytes.</font></dd> | |||
<dd><font face="sans-serif"><b>Name</b> = a message identifier as a null terminated string.</font></dd> | |||
<dd><font face="sans-serif"><b>Setup</b> = the time in milliseconds already spent setting up this message for scanning.</font></dd> | |||
<dd><font face="sans-serif"><b>returns</b> a handle to the scan result block upon success otherwise an error code: | |||
</font><dl> | |||
<dd><font face="sans-serif">snf_ERROR_NO_HANDLE - There was a problem allocating a scan result block.</font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_SCAN_FAILED - There was a problem performing the scan.</font></dd> | |||
</dl> | |||
<p><font face="sans-serif">In general a result > 0 indicates a valid scan handle and a result <= 0 indicates an error. | |||
NOTE that the scan may have failed even if you get a valid handle. The scan result code you retrieve | |||
from get...() may indicate an error. <a href="#ResultCodes">See Result Codes</a> for details.</font></p> | |||
</dd> | |||
</dl><font face="sans-serif"> | |||
<hr/> | |||
<a name="scanFile"><h3>int scanFile(char* FilePath, int Setup);</h3></a> | |||
<p>This function scans an SMTP message from a file. A scan result block is allocated for the scan | |||
and a handle representing the results is returned. The application can then use this handle to retrieve | |||
the scan results using the get...() functions. When the application is finished it MUST release the | |||
scan result block with a call to closeScan().</p> | |||
<p>The scanFile() function is nearly identical to the <a href="#scanBuffer">scanBuffer() function (see above)</a> | |||
except that this function accepts the path to a file (null terminated string) instead of a pointer to a message | |||
buffer.</p> | |||
<p>One other key difference with between scanBuffer() and scanFile() is that the SNF engine can be configured | |||
to inject it's X- headers when scanFile() is used. These same X- headers are available to the calling application | |||
when using scanBuffer(), however if the application wishes to pass the message file on to other additional | |||
scanners and external processes then scanFile() might be more convenient.</p> | |||
<p>NOTE: There are significant performance implications to scanning files and injecting headers. Each time | |||
headers are injected into a message the message file must be rewritten. For optimal performance it is best | |||
to collect headers from scanning tools before writing the message to disk so that the message only needs to | |||
be written once. Extra file IO is the cost of the convenience of passing a message file to external processes.</p> | |||
<p>The Setup time passed to scanFile() will be added to the time required to open and read the message file | |||
prior to scanning. This value will be passed on to the logging system. For example, the calling application | |||
might include the number of milliseconds required to perform any previous message testing and the time it | |||
has taken to create a temporary message file for scanning. The log will then reflect the complete setup time | |||
separately from the time required to perform the SNF message scan.</p> | |||
<p>The FilePath will be passed on to the logging system to identify this message scan in the logs.</p> | |||
</font><dl> | |||
<dd><font face="sans-serif"><b>FilePath</b> = The full path (a null terminated string) to the message file to be scanned.</font></dd> | |||
<dd><font face="sans-serif"><b>Setup</b> = The time in milliseconds spent so far preparing this message to be scanned.</font></dd> | |||
<dd><font face="sans-serif"><b>returns</b> a handle to the scan result block upon success otherwise an error code: | |||
</font><dl> | |||
<dd><font face="sans-serif">snf_ERROR_NO_HANDLE - There was a problem allocating a scan result block.</font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_SCAN_FAILED - There was a problem performing the scan.</font></dd> | |||
</dl> | |||
<p><font face="sans-serif">In general a result > 0 indicates a valid scan handle and a result <= 0 indicates an error. | |||
NOTE that the scan may have failed even if you get a valid handle. The scan result code you retrieve | |||
from get...() may indicate an error. <a href="#ResultCodes">See Result Codes</a> for details.</font></p> | |||
</dd> | |||
</dl><font face="sans-serif"> | |||
<hr/> | |||
<a name="getScanXHeaders"><h3>int getScanXHeaders(int ScanHandle, char** Bfr, int* Length);</h3></a> | |||
<p>This function returns the scan result code <a href="#ResultCodes">(see Result Codes)</a> and a pointer | |||
to a buffer containing any X- headers that were produced for the scan associated with the ScanHandle.</p> | |||
<p>The function is passed a valid ScanHandle which identifies the scan result block to query; the address of | |||
a char* which will be changed to point to a buffer containing any X- headers that | |||
were produced; and the address of an integer which will be changed to the length of the | |||
X- headers buffer.</p> | |||
<p>If no X- headers were produced for the scan then the pointer Bfr will point to a safe empty string | |||
and Length will be set to zero. Put another way, Bfr and Length will be consistent with an empty null terminated | |||
string.</p> | |||
<p>The char* Bfr and the int Length will remain valid until closeScan() is called for this ScanHandle.</p> | |||
<p>In order for X- headers to be produced the engine must be configured properly. For details visit the | |||
<a href="http://www.armresearch.com/support/articles/software/snfServer/config/node/logs/scan/xheaders/index.jsp"> | |||
XHeader configuration documentation</a> on our web site.</p> | |||
<dl> | |||
<dd><b>ScanHandle</b> = a valid scan handle from scanBuffer() or scanFile().</dd> | |||
<dd><b>Bfr</b> = a pointer to a char* where the char* will be changed to point to the XHeaders.</dd> | |||
<dd><b>Length</b> = a pointer to an int where the int will be changed to the length of the XHeaders.</dd> | |||
<dd><b>returns</b> the scan result code upon success otherwise an error code: | |||
<dl> | |||
<dd>snf_ERROR_NO_HANDLE - The ScanHandle is not valid.</dd> | |||
<dd>snf_ERROR_EXCEPTION - There was a problem retrieving the data.</dd> | |||
<dd><a href="#ResultCodes">See Result Codes</a> for other possible return values.</dd> | |||
</dl> | |||
</dd> | |||
</dl> | |||
<hr/> | |||
<a name="getScanXMLLog"><h3>int getScanXMLLog(int ScanHandle, char** Bfr, int* Length);</h3></a> | |||
<p>This function returns the scan result code <a href="#ResultCodes">(see Result Codes)</a> and a pointer | |||
to a buffer containing any XML Log Data that was produced for the scan associated with the ScanHandle.</p> | |||
<p>The function is passed a valid ScanHandle which identifies the scan result block to query; the address of | |||
a char* which will be changed to point to a buffer containing any XML Log Data that | |||
was produced; and the address of an integer which will be changed to the length of the | |||
XML Log Data buffer.</p> | |||
<p>If no XML Log Data was produced for the scan then the pointer Bfr will point to a safe empty string | |||
and Length will be set to zero. Put another way, Bfr and Length will be consistent with an empty null terminated | |||
string.</p> | |||
<p>The char* Bfr and the int Length will remain valid until closeScan() is called for this ScanHandle.</p> | |||
<p>In order for XML Log Data to be produced the engine must be configured properly. For details visit the | |||
<a href="http://www.armresearch.com/support/articles/software/snfServer/config/node/logs/scan/xml.jsp"> | |||
XML Log configuration documentation</a> on our web site.</p> | |||
<dl> | |||
<dd><b>ScanHandle</b> = a valid scan handle from scanBuffer() or scanFile().</dd> | |||
<dd><b>Bfr</b> = a pointer to a char* where the char* will be changed to point to the XML Log Data.</dd> | |||
<dd><b>Length</b> = a pointer to an int where the int will be changed to the length of the XML Log Data.</dd> | |||
<dd><b>returns</b> the scan result code upon success otherwise an error code: | |||
<dl> | |||
<dd>snf_ERROR_NO_HANDLE - The ScanHandle is not valid.</dd> | |||
<dd>snf_ERROR_EXCEPTION - There was a problem retrieving the data.</dd> | |||
<dd><a href="#ResultCodes">See Result Codes</a> for other possible return values.</dd> | |||
</dl> | |||
</dd> | |||
</dl> | |||
<hr/> | |||
<a name="getScanClassicLog"><h3>int getScanClassicLog(int ScanHandle, char** Bfr, int* Length);</h3></a> | |||
<p>This function returns the scan result code <a href="#ResultCodes">(see Result Codes)</a> and a pointer | |||
to a buffer containing any Classic Log Data that was produced for the scan associated with the ScanHandle.</p> | |||
<p>The function is passed a valid ScanHandle which identifies the scan result block to query; the address of | |||
a char* which will be changed to point to a buffer containing any Classic Log Data that | |||
was produced; and the address of an integer which will be changed to the length of the | |||
Classic Log Data buffer.</p> | |||
<p>If no Classic Log Data was produced for the scan then the pointer Bfr will point to a safe empty string | |||
and Length will be set to zero. Put another way, Bfr and Length will be consistent with an empty null terminated | |||
string.</p> | |||
<p>The char* Bfr and the int Length will remain valid until closeScan() is called for this ScanHandle.</p> | |||
<p>In order for XML Log Data to be produced the engine must be configured properly. For details visit the | |||
<a href="http://www.armresearch.com/support/articles/software/snfServer/config/node/logs/scan/classic.jsp"> | |||
Classic Log configuration documentation</a> on our web site.</p> | |||
<dl> | |||
<dd><b>ScanHandle</b> = a valid scan handle from scanBuffer() or scanFile().</dd> | |||
<dd><b>Bfr</b> = a pointer to a char* where the char* will be changed to point to the Classic Log Data.</dd> | |||
<dd><b>Length</b> = a pointer to an int where the int will be changed to the length of the Classic Log Data.</dd> | |||
<dd><b>returns</b> the scan result code upon success otherwise an error code: | |||
<dl> | |||
<dd>snf_ERROR_NO_HANDLE - The ScanHandle is not valid.</dd> | |||
<dd>snf_ERROR_EXCEPTION - There was a problem retrieving the data.</dd> | |||
<dd><a href="#ResultCodes">See Result Codes</a> for other possible return values.</dd> | |||
</dl> | |||
</dd> | |||
</dl> | |||
<hr/> | |||
<a name="getScanResult"><h3>int getScanResult(int ScanHandle);</h3></a> | |||
<p>This function returns the scan result code <a href="#ResultCodes">(see Result Codes)</a> | |||
for the scan associated with the ScanHandle.</p> | |||
<dl> | |||
<dd><b>ScanHandle</b> = a valid scan handle from scanBuffer() or scanFile().</dd> | |||
<dd><b>returns</b> the scan result code upon success otherwise an error code: | |||
<dl> | |||
<dd>snf_ERROR_NO_HANDLE - The ScanHandle is not valid.</dd> | |||
<dd><a href="#ResultCodes">See Result Codes</a> for other possible return values.</dd> | |||
</dl> | |||
</dd> | |||
</dl> | |||
<hr/> | |||
<a name="closeScan"><h3>int closeScan(int ScanHandle);</h3></a> | |||
<p>This function closes a ScanHandle and releases the associated Scan Result Block to the pool. This | |||
function MUST be called once for each ScanHandle produced in a scan...() function. Once this function | |||
is called the ScanHandle is no longer valid and any pointers returned by previous | |||
calls to get...() functions should be discarded (forgotten, not freed!)</p> | |||
<dl> | |||
<dd><b>ScanHandle</b> = a valid scan handle from scanBuffer() or scanFile().</dd> | |||
<dd><b>returns:</b> | |||
<dl> | |||
<dd>snf_SUCCESS - The ScanHandle was closed successfully.</dd> | |||
<dd>snf_ERROR_NO_HANDLE - The ScanHandle is not valid.</dd> | |||
<dd>snf_ERROR_EXCEPTION - There was a problem closing the ScanHandle.</dd> | |||
</dl> | |||
</dd> | |||
</dl> | |||
<hr/> | |||
<a name="shutdownSNF"><h3>int shutdownSNF();</h3></a> | |||
<p>This function shuts down the SNFMulti engine. All previously allocated ScanHandles MUST be closed | |||
before this function is called. This should be the last function in the DLL that is called by your | |||
application (call no other SNFMultiDLL functions after this).</p> | |||
<dl> | |||
<dd><b>returns:</b> | |||
<dl> | |||
<dd>snf_SUCCESS - The shutdown was successful.</dd> | |||
<dd>snf_ERROR_EXCEPTION - An error occurred during shutdown.</dd> | |||
</dl> | |||
</dd> | |||
</dl> | |||
<hr/> | |||
<a name="ResultCodes"><h3>Result Codes</h3></a> | |||
<h4>Error Codes</h4> | |||
</font><dl> | |||
<dd><font face="sans-serif">snf_SUCCESS = 0</font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_CMD_LINE = 65</font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_LOG_FILE = 66</font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_RULE_FILE = 67</font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_RULE_DATA = 68</font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_RULE_AUTH = 73</font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_MSG_FILE = 69</font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_ALLOCATION = 70</font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_BAD_MATRIX = 71</font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_MAX_EVALS = 72</font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_UNKNOWN = 99</font></dd> | |||
<font face="sans-serif"><br/> | |||
<dd>snf_ERROR_NO_HANDLE = -1, Invalid scan handle used or created.</dd></font> | |||
<dd><font face="sans-serif">snf_ERROR_SCAN_FAILED = -2, An unexpected exception during a scan. </font></dd> | |||
<dd><font face="sans-serif">snf_ERROR_EXCEPTION = -3, An unexpected exception occurred.</font></dd> | |||
</dl><font face="sans-serif"> | |||
<p> | |||
<a href="http://www.armresearch.com/support/articles/software/snfServer/errors.jsp"> | |||
See our web site for more detailed descriptions of these error codes.</a></p> | |||
<h4>Scan Result Codes</h4> | |||
<p>Scan results codes 0 through 63 represent normal scan results. By convention a result of | |||
0 indicates ham (not spam); a result of 1 indicates a white-ruled message; and other non-zero | |||
result values that are less than 64 indicate some kind of spam or malware was detected. | |||
<a href="http://www.armresearch.com/support/articles/software/snfServer/core.jsp"> | |||
For more details on message scan result codes please see our web site.</a></p> | |||
<hr/> | |||
<div align="right"><font size="-3">Copyright (C) 2009 ARM Research Labs, LLC</font></div> | |||
</font> | |||
</body> | |||
</html> |
@@ -0,0 +1,184 @@ | |||
SNFClient Readme | |||
Copyright (c) 2010 ARM Research Laboratories | |||
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. | |||
@@ -0,0 +1,200 @@ | |||
SNF_Server V3.0 installation brief | |||
Copyright (c) 2010 ARM Research Laboratories | |||
This is a generalized guide. For specific platform guides see: | |||
http://www.armresearch.com/support/articles/installation/index.jsp | |||
Create a directory for SNF_Server. ( c:\SNF or /var/spool/snfilter ) | |||
Copy all of the files to that directory. | |||
Make a copy of the SNFServer<version>.exe file and give it the name | |||
SNFServer.exe. Later on if newer versions are provided you will | |||
be able to keep track of them by name and swap newer versions into | |||
place by copying them over your SNFServer.exe file. If you decide | |||
you have to go back to a previous version then you will be able to | |||
do that easily by deleting your SNFServer.exe file and copying the | |||
version you wish to use into place. | |||
Modify the identity.xml file to match your SNF license ID and your | |||
authentication string. | |||
Download your .snf file and place that in the SNF_Server working | |||
directory. | |||
RULEBASE UPDATES (NEW!): The latest version of the SNFServer engine | |||
includes a mechanism that will run an a script when the rulebase file | |||
on our server is newer than the active file in SNF. By default this | |||
feature is configured to run the included getRulebase script. If | |||
the script is not successful it will be launched again every 3 minutes | |||
until the rulebase file is successfully updated. | |||
Be sure to modify the top of the getRulebase script to include | |||
your correct license ID, authentication string, and working directory. | |||
Be sure to verify that the <update-script/> section of your snf_engine | |||
file is correct (points to the correct location of getRulebase). | |||
getRulebase uses wget and gzip (included for your convenience in | |||
the Win* distribution. See About-Wget-and-Gzip.txt.). These are open | |||
source utilities for downloading files from web servers and unzipping | |||
those files -- in this case, SNF rulebase files. | |||
If you have any gateways or other internal systems that will relay | |||
mail to SNF then include their IPs in GBUdbIgnoreList.txt. The GBUdb | |||
component of SNF uses the IPs in this list to determine the actual | |||
source IP for a message by reviewing the Received headers. Each | |||
Received header is evaluated in turn. If the source (connect) IP is | |||
found in the Ignore list then that Received IP is considered to be | |||
part of your infrastructure and is ignored. The first Received IP | |||
found that is NOT in the Ignore list is selected as the source IP. | |||
The GBUdbIgnoreList is a "safety net" that ensures the listed IPs are | |||
present in your GBUdb with their Ignore flag set. It is loaded every | |||
time the configuration is changed, SNFServer is started, or a new | |||
rulebase is loaded. This way if your GBUdb database is lost then your | |||
critical infrastructure will be re-listed in the new .gbx file that | |||
is created. | |||
The ignore list allows only SINGLE IP ENTRIES. This can be a problem | |||
in some cases - such as when you want to ignore large blocks of network | |||
addresses. | |||
SNF can learn to Ignore large blocks of IPs using the <drilldown/> | |||
feature. For example if you want to ignore all of 12.34.56.0/24 then | |||
you can make an entry in the <drilldown/> training section like this: | |||
<training on-off='on'> | |||
... | |||
<drilldown> | |||
<received ordinal='0' find='[12.34.56.'/> | |||
</drilldown> | |||
... | |||
</training> | |||
GBUdb learns the behavior of source IPs so it is important that GBUdb | |||
knows any friendly sources that might send spammy messages to your | |||
server or else it will learn that those sources are not to be trusted. | |||
Since not all friendly spam sources can be identified by IP ahead of | |||
time, there are features in the <training/> section of snf_engine.xml | |||
that allow you to adjust the training scenarios to compensate. The | |||
most likely of these is that you may wish to bypass training for | |||
messages that are to your support addresses or spam submission | |||
addresses. For example: | |||
<training on-off='on'> | |||
... | |||
<bypass> | |||
<header name='To:' find='support@example.com'/> | |||
<header name='To:' find='spam@example.com'/> | |||
</bypass> | |||
... | |||
</training> | |||
Evaluate the snf_engine.xml file carefully. In most cases the | |||
default settings are appropriate, however you may want to alter | |||
some of the settings to match your system policies or particular | |||
installation. | |||
IMPORTANT: Be sure that any file paths / directories referenced in | |||
the configuration file exist on your system and that SNF has full | |||
access rights to these - especially the SNF working directory. | |||
** If you selected a working directory for SNF other than c:\SNF\ | |||
then be sure you have changed these paths in the top of your | |||
snf_engine.xml file. Pay close attentiont to these 5 elements: | |||
<node identity='c:/SNF/identity.xml'> | |||
<log path='c:/SNF/'/> | |||
<rulebase path='c:/SNF/'/> | |||
<workspace path='c:/SNF/'/> | |||
<update-script ... call='c:/SNF/getRulebase.cmd' ... /> | |||
Once you are happy with your configuration and you have all of your | |||
files and directories in place (including your .snf file) then you | |||
can start SNF_Server. | |||
The command line (from inside the SNF workspace) is: | |||
SNFServer.exe snf_engine.xml | |||
That is: SNFServer <configuration> | |||
If you want to lauch SNFServer from some other location it would be | |||
best to use the entire path for both the SNFServer engine and the | |||
configuration file: | |||
c:\SNF\SNFServer.exe c:\SNF\snf_engine.xml | |||
You should begin by testing SNFServer by running it in a command line | |||
window where you can watch it's output. | |||
Once you are happy with it then you will probably want to run it as | |||
a service using a utility such as the srvany utility from the win2k | |||
toolkit, or detached as a daemon on *nix systems (snfctrl file example | |||
included). | |||
This section of our site might be helpful: | |||
http://www.armresearch.com/support/articles/installation/serviceSetup/index.jsp | |||
SNFServer is the server side of a client/server system. In order to | |||
scan messages you will need to use the client utility (SNFClient.exe | |||
or SNFIMailShim.exe) to scan messages. | |||
SNFClient.exe is a drop-in replacement for the production (2-3.x) | |||
SNF program when it is called from Declude or mxGuard or other similar | |||
software. There is no need to "brand" the SNFClient.exe | |||
program and it is not necessary to include the authentication string | |||
on the command line -- however, if you do it will be accepted and | |||
ignored without an error. | |||
SNFServer MUST be running for SNFClient to work. If SNFClient cannot | |||
reach SNFServer then it will wait for quite a while as it attempts to | |||
make contact. | |||
Here are a few ways to call SNFClient.exe: | |||
SNFClient.exe -shutdown | |||
Sends the Shutdown command to the SNF_Server. | |||
SNFClient.exe authenticationxx filetoscan | |||
Compatibility mode - ignores authenticationxx and scans filetoscan. | |||
SNFClient.exe filetoscan | |||
Normal scan mode - scans filetoscan. | |||
SNFClient.exe -xhdr filetoscan | |||
XHDR scan mode - scans filetoscan and returns X Headers. | |||
See the SNFClient_Readme.txt file for details. | |||
The SNF Client/Server pair communicate using short XML messages via a local | |||
TCP connection (typically to port 9001). Examples of SNF_XCI messages are | |||
included in snf_xci.xml (not a well formed xml file! - just some examples). | |||
It is possible to communicate directly with the SNF_Server engine via TCP | |||
from your software using the SNF_XCI (SNF XML Command Interface) protocol. The | |||
server expects to see one connection per request. The client sends an SNF_XCI | |||
request to the server. The server responds with an appropriate SNF_XCI | |||
formatted response and terminates the connection. | |||
Requests and responses are expected to terminate with a newline character. | |||
You can see the XCI protocol at work by running the SNFClient in debug mode | |||
(SNFdebugClient). | |||
If you run into trouble check out our web site: www.armresearch.com and/or | |||
contact us by email: support@armresearch.com | |||
____________________ | |||
For More Information | |||
See www.armresearch.com | |||
Copyright (C) 2007-2008 Arm Research Labs, LLC. |
@@ -0,0 +1,70 @@ | |||
@ECHO OFF | |||
SETLOCAL | |||
REM ----- Edit This Section -------- | |||
SET SNIFFER_PATH=c:\SNF | |||
SET AUTHENTICATION=authenticationxx | |||
SET LICENSE_ID=licensid | |||
REM -------------------------------- | |||
CD /d %SNIFFER_PATH% | |||
echo Running SNF getRulebase.cmd > getRulebase.txt | |||
if not exist UpdateReady.txt echo No UpdateReady.txt >> getRulebase.txt | |||
if not exist UpdateReady.txt goto DONE | |||
REM The next line may cause trouble if your system stops while this | |||
REM script is running. It is not needed when this script is run | |||
REM from SNF's <update-script/> feature since only one copy will run | |||
REM at a time. However, if you are going to run a version of this | |||
REM script as a scheduled task you will want to uncomment the next | |||
REM line to make sure only one copy runs at a time-- just be sure to | |||
REM clean out any stale .lck files after a restart. | |||
REM if exist UpdateReady.lck echo getRulebase.cmd locked/running >> getRulebase.txt | |||
REM if exist UpdateReady.lck goto DONE | |||
:DOWNLOAD | |||
copy UpdateReady.txt UpdateReady.lck > nul | |||
if exist %LICENSE_ID%.new del %LICENSE_ID%.new | |||
echo. | |||
curl -v "http://www.sortmonster.net/Sniffer/Updates/%LICENSE_ID%.snf" -o %LICENSE_ID%.new -s -S -R -z %LICENSE_ID%.snf -H "Accept-Encoding:gzip" --compressed -u sniffer:ki11sp8m 2>> getRulebase.txt | |||
if %ERRORLEVEL% NEQ 0 del %LICENSE_ID%.new 2> nul | |||
if not exist %LICENSE_ID%.new echo New rulebase file NOT downloaded >> getRulebase.txt | |||
if not exist %LICENSE_ID%.new goto CLEANUP | |||
snf2check.exe %LICENSE_ID%.new %AUTHENTICATION% 2>> getRulebase.txt | |||
if errorlevel 1 goto CLEANUP | |||
echo New rulebase file tested OK >> getRulebase.txt | |||
if exist %LICENSE_ID%.old del %LICENSE_ID%.old | |||
if exist %LICENSE_ID%.snf 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 | |||
echo Done >> getRulebase.txt | |||
REM This is a good place to add a line that will email getrulebase.txt to | |||
REM yourself so that you know what just happened. | |||
ENDLOCAL |
@@ -0,0 +1,4 @@ | |||
<!-- Change 'licenseid' and 'xxxxxxxxxxxxxxxx' to match your license info --> | |||
<snf><identity licenseid='licensid' authentication='authenticationxx'/></snf> | |||
@@ -0,0 +1,150 @@ | |||
<!-- SNFMulti V3.0 Configuration File, Setup: Typical of Win* Client / Server --> | |||
<!-- http://www.armresearch.com/support/articles/software/snfServer/config/snfEngine.jsp --> | |||
<snf> | |||
<node identity='c:/SNF/identity.xml'> | |||
<paths> | |||
<log path='c:/SNF/'/> | |||
<rulebase path='c:/SNF/'/> | |||
<workspace path='c:/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='yes' matches='unique'/> | |||
<xml mode='file' rotate='yes' matches='all' performance='yes' gbudb='yes'/> | |||
<xheaders> | |||
<output mode='none'/> | |||
<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-GBUdb-Analysis</gbudb> | |||
<result on-off='off'>X-MessageSniffer-Scan-Result</result> | |||
<matches on-off='on'>X-MessageSniffer-Rules</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='c:/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/> | |||
<msg-file type='rfc822'/> | |||
</node> | |||
</snf> | |||
@@ -0,0 +1,52 @@ | |||
<!-- SNF Xml Command Interface Examples --> | |||
<!-- Scanner --> | |||
<snf><xci><scanner><scan file='filepath'/></scanner></xci></snf> | |||
<snf><xci><scanner><result code='63'/></scanner></xci></snf> | |||
<snf><xci><scanner><scan file='filepath' xhdr='yes' log='no' ip='12.34.56.78'/></scanner></xci></snf> | |||
<snf><xci><scanner><result code='63'><xhdr> | |||
X-Signature-Violations: | |||
57-1404199-965-976-m | |||
57-1404199-1352-1363-m | |||
57-1404199-965-976-f | |||
</xhdr></result></scanner></xci></snf> | |||
<!-- GBUdb --> | |||
<snf><xci><gbudb><set ip='12.34.56.78' type='good'/></gbudb></xci></snf> <!-- Set flag to good on ip --> | |||
<snf><xci><gbudb><set ip='12.34.56.78' type='bad'/></gbudb></xci></snf> <!-- Set flag to bad on ip --> | |||
<snf><xci><gbudb><set ip='12.34.56.78' type='ugly'/></gbudb></xci></snf> <!-- Set flag to ugly on ip --> | |||
<snf><xci><gbudb><set ip='12.34.56.78' type='ignore'/></gbudb></xci></snf> <!-- Set flag to ignore on ip --> | |||
<snf><xci><gbudb><set ip='12.34.56.78' type='ugly' b='1' g='0'/></gbudb></xci></snf> <!-- Set flag and counts on ip --> | |||
<snf><xci><gbudb><good ip='12.34.56.78'/></gbudb></xci></snf> <!-- Record a "good" event on ip --> | |||
<snf><xci><gbudb><bad ip='12.34.56.78'/></gbudb></xci></snf> <!-- Record a "bad" event on ip --> | |||
<snf><xci><gbudb><test ip='12.34.56.78'/></gbudb></xci></snf> <!-- Return the state of ip --> | |||
<snf><xci><gbudb><drop ip='12.34.56.78'/></gbudb></xci></snf> <!-- Forget the IP --> | |||
<!-- GBUdb Result, always --> | |||
<snf><xci><gbudb><result ip='12.34.56.78' type='ugly' p='1.0' c='0.001' b='1' g='0' range='caution' code='40'/></gbudb></xci></snf> | |||
<!-- status report request --> | |||
<snf><xci><report><request><status class='second'/></request></report></xci></snf> | |||
<!-- status report result --> | |||
<snf><xci><report><response><!-- actual status report --></response></report></xcl></snf> | |||
<!-- Server --> | |||
<snf><xci><server><command command='shutdown'/></server></xci></snf> | |||
<snf><xci><server><response message='shutdown in progress' code='0'/></server></xci></snf> | |||
<!-- Specialized Server Requests --> | |||
<snf><xci><server><command command='systemdefinedcommand'> | |||
<system-defined/><command/><elements/> | |||
</command></server></xci></snf> | |||
<snf><xci><server><response message='shutdown in progress' code='0'> | |||
<system-defined/><response/><elements/> | |||
</response></server></xci></snf> | |||
<!-- XCI Error Response --> | |||
<snf><xci><error message="What was that?"/></xci></snf> | |||
@@ -0,0 +1,80 @@ | |||
#!/usr/bin/bash | |||
# | |||
# This scripts copies the files for a distribution to a zipfile. | |||
# | |||
# Usage: createDistribution VERSION | |||
# | |||
# where VERSION is the version of the distribution. | |||
# | |||
# The files are copied to a new directory named SNFMultiSDK_Windows, | |||
# which is zipped to create the zipfile. | |||
# | |||
############################################################################ | |||
# Name of the directory. | |||
DirName=SNFMultiSDK_Windows | |||
# Get the version. | |||
if [ "$#" -ne 1 ] | |||
then | |||
echo Usage: $0 VERSION | |||
echo where VERSION is the version of the distribution to create | |||
exit -1 | |||
fi | |||
VERSION=$1 | |||
ZipFile="$DirName"_$VERSION.zip | |||
# Create the directory. | |||
rm -rf $DirName | |||
cp --archive SNFMultiSDK_Windows_Base $DirName | |||
for dir in 32bitDll 64bitDLL CPPSample include VS2019CPPSample VS2019CSSample VS2019VBSample | |||
do | |||
mkdir $DirName/$dir | |||
done | |||
# Copy 32-bit DLL files | |||
for file in IMPORTANT.txt libgcc_s_sjlj-1.dll libstdc++-6.dll libwinpthread-1.dll snfmulti.def snfmulti.dll vs2019_snfmulti.exp vs2019_snfmulti.lib | |||
do | |||
cp 32bitDLL/$file $DirName/32bitDLL | |||
done | |||
# Copy 64-bit DLL files | |||
for file in IMPORTANT.txt libgcc_s_seh-1.dll libstdc++-6.dll libwinpthread-1.dll snfmulti.def snfmulti.dll vs2019_snfmulti.exp vs2019_snfmulti.lib | |||
do | |||
cp 64bitDLL/$file $DirName/64bitDLL | |||
done | |||
# Copy CPP sample files. | |||
for file in main.cpp main.cpp.html README.txt | |||
do | |||
cp CPPSample/$file $DirName/CPPSample | |||
done | |||
for file in README VS2019CPPSample.sln VS2019CPPSample.vcxproj VS2019CPPSample.vcxproj.filters VS2019CPPSample.vcxproj.user | |||
do | |||
cp VS2019CPPSample/$file $DirName/VS2019CPPSample | |||
done | |||
# Copy C# sample files. | |||
for file in main.cs README VS2019CSSample.csproj VS2019CSSample.csproj.user VS2019CSSample.sln | |||
do | |||
cp VS2019CSSample/$file $DirName/VS2019CSSample | |||
done | |||
# Copy VB sample files. | |||
for file in main.vb README VS2019VBSample.sln VS2019VBSample.vbproj VS2019VBSample.vbproj.user | |||
do | |||
cp VS2019VBSample/$file $DirName/VS2019VBSample | |||
done | |||
# Copy include file. | |||
cp include/snfmultidll.h include/snfmultidll.h.html $DirName/include | |||
# Create the zipfile. | |||
jzip -p -r $ZipFile $DirName | |||
echo Created zipfile $ZipFile |
@@ -50,24 +50,25 @@ file with further information): | |||
Studio files for building the C# and VB example applications, and | |||
the C++ test. | |||
To build the applications in the MinGW-64, MinGW-32, CodeBlocks, and | |||
VS2008 directories: | |||
To build the applications in the MinGW-64, MinGW-32, and VS2019 | |||
directories: | |||
1) Ensure that the SNFMultiTest, SNFMulti, and CodeDweller | |||
directories are present. | |||
2) Install the 64-bit MinGW toolchain. Unpack the 64-bit toolchain | |||
(e.g. mingw-w64-bin_i686-mingw_20090220.zip) into c:\MinGW-64. If | |||
done correctly, c:\MinGW-64 should have the directories bin, | |||
include, x86_64-pc-mingw32, and other directories. The MinGW .CMD | |||
files and the Code::Blocks project files are configured to use the | |||
64-bit toolchain in c:\MinGW-64. | |||
2) Install the 64-bit MinGW toolchain. The scripts in MinGW-64 are | |||
for MinGW-W64 version 8.1.0, posix threads, and seh exception. | |||
If a different version is installed, the scripts would need to be | |||
modified. | |||
3) Install the 32-bit MinGW toolchain to C:\MinGW. | |||
3) Install the 32-bit MinGW toolchain (i686 architecture), version | |||
8.1.0, posix threads, and sjlj exception. If a different version | |||
is installed, the scripts would need to be modified. | |||
4) Install VS 2008. | |||
4) Install VS 2019. and the .NET runtime. | |||
5) Follow the directions in each directorie's README file. | |||
5) Follow the directions in README file in MinGW-32, MinGW-64, and | |||
VS2019 directories. | |||
To build and test the SDK: | |||
@@ -79,7 +80,7 @@ To build and test the SDK: | |||
c) buildSNFMultiTestDLL.cmd. | |||
d) buildvs2008SNFMultiImportLib.cmd (in vs2008 command prompt). | |||
d) buildvs2019SNFMultiImportLib.cmd (in vs2019 command prompt). | |||
e) SNFMultiTest.exe. | |||
@@ -87,34 +88,25 @@ To build and test the SDK: | |||
2) Repeat in MinGW-64. | |||
3) Build and run VS2008CPPSample, x32 and x64. First copy | |||
snf_engine.xml to VS2008CPPSample. For x32, copy *.dll from | |||
32bitDll to VS2008CPPSample. For x64, copy *.dll from 64bitDll | |||
to VS2008CPPSample. | |||
3) Build and run VS2019CPPSample, x32 and x64, following the | |||
instructions in the README file. | |||
4) Build and run VS2008CSSample, any, x32, and x64. Copy | |||
snf_engine.xml to VS2008CSSample. Modify main.cs to specify | |||
the location of snf_engine.xml and snfmulti.dll, which is | |||
different for any, x32, and x64. | |||
4) Build and run VS2019CSSample, any, x32, and x64, following the | |||
instructions in the README file. | |||
5) Build and run VS2008VBSample, any, x32, and x64. Copy | |||
snf_engine.xml to VS2008VBSample. Modify main.vb to specify | |||
the location of snf_engine.xml and snfmulti.dll, which is | |||
different for any, x32, and x64. | |||
5) Build and run VS2019VBSample, any, x32, and x64, following the | |||
instructions in the README file. | |||
To create a zipfile distribution: | |||
1) Install jZip. | |||
2) Edit BuildDistribution.cmd to specify the DISTDIR variable, and | |||
optionally the TEMPDIR variable. | |||
2) Add jZip to the path for the MinGW-W64 bash command line. | |||
3) Run BuildDistribution. This creates a zip file in the current | |||
directory with the name %DISTDIR%.zip. | |||
3) At a MinGW bash prompt, run | |||
Note: When you run BuildDistribution, you will get a message saying | |||
that %DISTDIR%.zip could not be found. This message can be ignored. | |||
./createDistribution VERSION | |||
Note: For more information on the procedure for creating a zipfile | |||
distribution, see the BuildDistribution.cmd file and the | |||
BuildDistribution\README file. | |||
where VERSION is the version to create. This creates a | |||
distribution in SNFMultiSDK_Windows, and zips the distribution | |||
into SNFMultiSDK_Windows_VERSION.zip. |