SNF_CS_Developer_Package of all files except SNF2Check, SNFClient, CodeDweller, and SNFMulti. git-svn-id: https://svn.microneil.com/svn/PKG-SNF-CS-NIX/trunk@28 233e721a-07f6-49eb-a7da-05e0e16828fcmaster
@@ -0,0 +1,171 @@ | |||
Artistic License 2.0 | |||
Copyright (c) 2000-2006, The Perl Foundation. | |||
Everyone is permitted to copy and distribute verbatim copies of this | |||
license document, but changing it is not allowed. Preamble | |||
This license establishes the terms under which a given free software | |||
Package may be copied, modified, distributed, and/or | |||
redistributed. The intent is that the Copyright Holder maintains some | |||
artistic control over the development of that Package while still | |||
keeping the Package available as open source and free software. | |||
You are always permitted to make arrangements wholly outside of this | |||
license directly with the Copyright Holder of a given Package. If the | |||
terms of this license do not permit the full use that you propose to | |||
make of the Package, you should contact the Copyright Holder and seek | |||
a different licensing arrangement. Definitions | |||
"Copyright Holder" means the individual(s) or organization(s) named in | |||
the copyright notice for the entire Package. | |||
"Contributor" means any party that has contributed code or other | |||
material to the Package, in accordance with the Copyright Holder's | |||
procedures. | |||
"You" and "your" means any person who would like to copy, distribute, | |||
or modify the Package. | |||
"Package" means the collection of files distributed by the Copyright | |||
Holder, and derivatives of that collection and/or of those files. A | |||
given Package may consist of either the Standard Version, or a | |||
Modified Version. | |||
"Distribute" means providing a copy of the Package or making it | |||
accessible to anyone else, or in the case of a company or | |||
organization, to others outside of your company or organization. | |||
"Distributor Fee" means any fee that you charge for Distributing this | |||
Package or providing support for this Package to another party. It | |||
does not mean licensing fees. | |||
"Standard Version" refers to the Package if it has not been modified, | |||
or has been modified only in ways explicitly requested by the | |||
Copyright Holder. | |||
"Modified Version" means the Package, if it has been changed, and such | |||
changes were not explicitly requested by the Copyright Holder. | |||
"Original License" means this Artistic License as Distributed with the | |||
Standard Version of the Package, in its current version or as it may | |||
be modified by The Perl Foundation in the future. | |||
"Source" form means the source code, documentation source, and | |||
configuration files for the Package. | |||
"Compiled" form means the compiled bytecode, object code, binary, or | |||
any other form resulting from mechanical transformation or translation | |||
of the Source form. Permission for Use and Modification Without | |||
Distribution | |||
(1) You are permitted to use the Standard Version and create and use | |||
Modified Versions for any purpose without restriction, provided that | |||
you do not Distribute the Modified Version. Permissions for | |||
Redistribution of the Standard Version | |||
(2) You may Distribute verbatim copies of the Source form of the | |||
Standard Version of this Package in any medium without restriction, | |||
either gratis or for a Distributor Fee, provided that you duplicate | |||
all of the original copyright notices and associated disclaimers. At | |||
your discretion, such verbatim copies may or may not include a | |||
Compiled form of the Package. | |||
(3) You may apply any bug fixes, portability changes, and other | |||
modifications made available from the Copyright Holder. The resulting | |||
Package will still be considered the Standard Version, and as such | |||
will be subject to the Original License. Distribution of Modified | |||
Versions of the Package as Source | |||
(4) You may Distribute your Modified Version as Source (either gratis | |||
or for a Distributor Fee, and with or without a Compiled form of the | |||
Modified Version) provided that you clearly document how it differs | |||
from the Standard Version, including, but not limited to, documenting | |||
any non-standard features, executables, or modules, and provided that | |||
you do at least ONE of the following: | |||
(a) make the Modified Version available to the Copyright Holder of the | |||
Standard Version, under the Original License, so that the Copyright | |||
Holder may include your modifications in the Standard Version. (b) | |||
ensure that installation of your Modified Version does not prevent the | |||
user installing or running the Standard Version. In addition, the | |||
Modified Version must bear a name that is different from the name of | |||
the Standard Version. (c) allow anyone who receives a copy of the | |||
Modified Version to make the Source form of the Modified Version | |||
available to others under (i) the Original License or (ii) a license | |||
that permits the licensee to freely copy, modify and redistribute the | |||
Modified Version using the same licensing terms that apply to the copy | |||
that the licensee received, and requires that the Source form of the | |||
Modified Version, and of any works derived from it, be made freely | |||
available in that license fees are prohibited but Distributor Fees are | |||
allowed. Distribution of Compiled Forms of the Standard Version or | |||
Modified Versions without the Source | |||
(5) You may Distribute Compiled forms of the Standard Version without | |||
the Source, provided that you include complete instructions on how to | |||
get the Source of the Standard Version. Such instructions must be | |||
valid at the time of your distribution. If these instructions, at any | |||
time while you are carrying out such distribution, become invalid, you | |||
must provide new instructions on demand or cease further | |||
distribution. If you provide valid instructions or cease distribution | |||
within thirty days after you become aware that the instructions are | |||
invalid, then you do not forfeit any of your rights under this | |||
license. | |||
(6) You may Distribute a Modified Version in Compiled form without the | |||
Source, provided that you comply with Section 4 with respect to the | |||
Source of the Modified Version. Aggregating or Linking the Package | |||
(7) You may aggregate the Package (either the Standard Version or | |||
Modified Version) with other packages and Distribute the resulting | |||
aggregation provided that you do not charge a licensing fee for the | |||
Package. Distributor Fees are permitted, and licensing fees for other | |||
components in the aggregation are permitted. The terms of this license | |||
apply to the use and Distribution of the Standard or Modified Versions | |||
as included in the aggregation. | |||
(8) You are permitted to link Modified and Standard Versions with | |||
other works, to embed the Package in a larger work of your own, or to | |||
build stand-alone binary or bytecode versions of applications that | |||
include the Package, and Distribute the result without restriction, | |||
provided the result does not expose a direct interface to the Package. | |||
Items That are Not Considered Part of a Modified Version | |||
(9) Works (including, but not limited to, modules and scripts) that | |||
merely extend or make use of the Package, do not, by themselves, cause | |||
the Package to be a Modified Version. In addition, such works are not | |||
considered parts of the Package itself, and are not subject to the | |||
terms of this license. General Provisions | |||
(10) Any use, modification, and distribution of the Standard or | |||
Modified Versions is governed by this Artistic License. By using, | |||
modifying or distributing the Package, you accept this license. Do not | |||
use, modify, or distribute the Package, if you do not accept this | |||
license. | |||
(11) If your Modified Version has been derived from a Modified Version | |||
made by someone other than you, you are nevertheless required to | |||
ensure that your Modified Version complies with the requirements of | |||
this license. | |||
(12) This license does not grant you the right to use any trademark, | |||
service mark, tradename, or logo of the Copyright Holder. | |||
(13) This license includes the non-exclusive, worldwide, | |||
free-of-charge patent license to make, have made, use, offer to sell, | |||
sell, import and otherwise transfer the Package with respect to any | |||
patent claims licensable by the Copyright Holder that are necessarily | |||
infringed by the Package. If you institute patent litigation | |||
(including a cross-claim or counterclaim) against any party alleging | |||
that the Package constitutes direct or contributory patent | |||
infringement, then this Artistic License to you shall terminate on the | |||
date that such litigation is filed. | |||
(14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT | |||
HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED | |||
WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |||
PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT | |||
PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT | |||
HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, | |||
INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE | |||
OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@@ -0,0 +1,375 @@ | |||
SNF Command Line & SNFMulti Engine / Client Change Log | |||
------------------------------------------------------------------------------ | |||
20080710 - Version 3.0.1 | |||
Minor change to SNFServer main.cpp:59 - removed cast to (int) which caused | |||
a precision loss error when compiling on 64 bit systems. This changes the | |||
thread pointer info in debug mode slightly (better). | |||
20080626 - Version 3.0, It's official. | |||
Changed build information. | |||
Removed extraneous comments from configuration file. | |||
20080524 - Version V2-9rc2.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-9rc2.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. | |||
20080416 - Version V2-9rc2.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-9rc2.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-9rc2.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-9rc2.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-9rc2.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 RulebaseHandler 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-9rc2.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-9rc2.17.6 | |||
Enhanced exception reporting in snfXCImrg | |||
20080405 - SNFServer V2-9rc2.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 - SNFServer V2-9rc2.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 - SNFServer V2-9rc2.15.4 | |||
Refactored snfNETmgr::sync() to consolidate non-blocking io routines. | |||
Added detailed thread status data to XCI listener thread. | |||
Fixed minor bug in main (not changing revision), Debug flag for internal use | |||
was left on in the last build cycle. It is commented out now. | |||
20080325 - SNFServer V2-9rc2.14.4 | |||
Updated snfNETmgr with comprehensive thread status data. | |||
Refactored snfNETmgr::sync() to check a Timeout, removed TCPWatchdog. | |||
20080325 - SNFServer V2-9rc2.13.4 | |||
Upgraded TCPWatcher code to use new threading features (type, status). | |||
20080324 - SNFServer v2-9rc2.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. | |||
Built thread monitoring function for SNFServer.exe (Full status report / sec). | |||
The thread monitoring report is turned on when the program is renamed to | |||
SNFDebugServer.exe or if "debug" appears in the file path to the program. | |||
Refactored XCI channels to leverage new thread monitoring. | |||
Refactored Threading to eliminate inline code. | |||
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 Threading library to include high level thread state tracking and | |||
naming. Also creates a global Threads object that can produce a real-time | |||
status report on all threads. | |||
Updated Networking library to use SO_REUSEADDR by default on listeners. | |||
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. | |||
Added BIG-ENDIAN Conversion - When the SNFServer program is compiled on a | |||
system that uses a BIG-ENDIAN processor (such as a power-mac) the rulebase | |||
load process now includes a routine to convert the token matrix from it's | |||
native LITTLE-ENDIAN format to a BIG-ENDIAN format. This solves a bug where | |||
Power-Mac (and presumably other BIG-ENDIAN systems) could compile and run | |||
the SNF* software but were unable to capture spam because the token matrix | |||
in the rulebase file was misinterpreted. | |||
Note: The BIG-ENDIAN Conversion feature is still considered experimental | |||
because it has not yet been thoroughly tested. | |||
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 - SNF2-9b1.5.exe | |||
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 - SNF2-9b1.4.exe | |||
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. | |||
20071008 - SNF2-9b1.2.exe | |||
Added support for passing Communigate Message Files directly. Communigate adds | |||
data to the top of the message file. That data stops at the first blank line and | |||
the rfc822 message begins. The SNFServer engine can now be told to ignore this | |||
extra data using the following option: | |||
<msg-file type='cgp'/> <!-- type='cgp' for communigate message files --> | |||
If the msg-file type is anything other than 'cgp' then it will treat the message | |||
file as a standard rfc822 message in the usual way. The default setting is | |||
<msg-file type='rfc822'/> | |||
@@ -0,0 +1,219 @@ | |||
Developer notes for the SNFServer developer distribution | |||
27 January 2009 | |||
Scope | |||
----- | |||
This file contains information for software developers. Ths | |||
information includes the prerequisite software for building, a | |||
description of the build system, and procedures for creating binary | |||
packages. | |||
Software prerequisites | |||
---------------------- | |||
The build system uses GNU software development system. The following | |||
software is needed for building: | |||
1) automake | |||
2) autoconf | |||
3) libtool | |||
4) make | |||
5) g++ | |||
6) tar | |||
7) curl | |||
8) pthread development. | |||
These tools are normally available on a Linux system that is | |||
configured as a software development system. The Linux system | |||
installation process usually gives the user a choice of installing a | |||
workstation, server, or software development system. However, not all | |||
Linux distributions give these choices. | |||
If these tools are not installed, they may be installed (or upgraded) | |||
at any time. The commands vary from distribution to distribution. | |||
For Ubuntu, the apt-get command can be used: | |||
1) 'apt-get install automake'. | |||
2) 'apt-get install autoconf'. | |||
3) 'apt-get install libtool'. | |||
4) 'apt-get install make'. | |||
5) 'apt-get install g++'. | |||
6) 'apt-get install tar'. | |||
7) 'apt-get install curl'. | |||
8) 'apt-get install libc6-dev' (to install the pthread library). | |||
Structure of the build system | |||
----------------------------- | |||
The following files comprise the build system: | |||
1) configure.ac. This is the main configuration file. It specifies | |||
the distribution name, version, which libraries are needed, etc. | |||
2) Makefile.am. This is used to create the top-level Makefile. It | |||
lists which directories are part of the build system | |||
(e.g. SNFServer), and which extra files are to be part of the | |||
distribution (e.g. BUGS, README, etc). | |||
3) CodeDweller/Makefile.am. This is used to create the Makefile for | |||
the CodeDweller library. It lists which source files are to be used | |||
for building. | |||
3) SNFMulti/Makefile.am. This is used to create the Makefile for | |||
the SNFMulti library. It lists which source files are to be used | |||
for building. | |||
4) SNFClient/Makefile.am. This is used to create the Makefile for | |||
SNFClient. | |||
5) SNF2Check/Makefile.am. This is used to create the Makefile for | |||
SNF2Check. | |||
6) Scripts/Makefile.am. This is used to create the Makefile for | |||
scripts (getRulebase, OS startup/shutdown, snfSniffer, etc). | |||
During the build process, the files in SNFMulti and CodeDweller are | |||
compiled into a static library. The applications SNFServer, | |||
SNFClient, and SNF2Check link with these libraries. This library is | |||
not installed. The system checks the dates of the files, and | |||
recompiles and relinks as necessary. | |||
To add an additional source file , edit the appropriate Makefile.am. | |||
Add the source file to the appropriate variable. For example, in | |||
SNFServer/Makefile.am: | |||
1) SNFServer_SOURCES for the cpp files for SNFServer. | |||
2) noinst_HEADERS for the header files for SNFServer. These are | |||
part of the user tarball, but aren't installed into the user system. | |||
Note that files that are not listed will not be included in the | |||
distribution tarball. This allows you to have additional files in | |||
directories (used, for example, for other projects) without | |||
unnecessarily increasing the size of the SNFServer application or | |||
tarball. | |||
Using the build system | |||
---------------------- | |||
Issue the following command to prepare system newly checked out for | |||
building: | |||
1) autoreconf --install | |||
Issue the following commands for building (the ./configure command | |||
needs options; see the INSTALL file or run './configure --help' for | |||
more info): | |||
1) ./configure --enable-os-type=Ubuntu --sysconfdir=/etc | |||
--prefix=/usr | |||
2) make | |||
The "./configure" command configures the system for installation into | |||
the default directory. The default directory '/usr/local', but can be | |||
specified to be '/var/spool/snfilter' by adding the following line in | |||
configure.ac: | |||
AC_PREFIX_DEFAULT([/var/spool/snfilter]) | |||
This can be overridden when running configure: | |||
./configure --prefix=installation_directory | |||
where installation_directory is the directory to install the software. | |||
Other commands: | |||
"make dist" creates a tarball of the form snf-server-X.Y.Z.tar.gz. | |||
X, Y, and Z, as well as SNFServer, are specified by the following | |||
line in configure.ac: | |||
AC_INIT(snf-server, X.Y.Z) | |||
"make install" installs the software (currently copies SNFServer to | |||
the bin subdirectory of the installation directory. I expect it | |||
will be modified to install other files (configuration files, | |||
scripts, etc). | |||
"make uninstall" removes the software from the installation | |||
directory. | |||
"make clean", "make distclean", "make maintainer-clean" remove files | |||
that can be recreated. After running "make clean", you'd need to | |||
run "make" to rebuild the system. After running "make distclean" or | |||
"make maintainer-clean", you'd need to run ./configure to build the | |||
system. | |||
"make dist" creates a tarball for the user. The name is | |||
snf-server-X.Y.Z.tar.gz, and the files are extracted into the | |||
directory snf-server-X.Y.Z. | |||
"make distcheck" tests a user tarball. This command extracts, | |||
configures, builds, and installs in temporary directories. After | |||
verifying that each operation was successful, the command removes | |||
the temporary directories. | |||
"make maintainer-clean" removes many of the files that can be | |||
created. After running this, you would need to run ./configure. | |||
Note: The script 'cleanForDist' cleans the developer distribution. It | |||
removes any user tarballs that might have been created, files created | |||
by 'autoreconf --install', and files ending in "~". After running | |||
this command, the directory tree can be imported into a version | |||
control system, or tarred and gzipped. | |||
Changing the version number or package name | |||
------------------------------------------- | |||
To change the version number or package name, do the following: | |||
1) Update configure.ac: | |||
a) Change the version number and/or package name for the build | |||
system. Do this by modifying the argument to the AC_INIT line in | |||
configure.ac. For example, to change the package name to FOO and | |||
the version to 8.0.2, modify the line to be: | |||
AC_INIT(FOO, 8.0.2) | |||
Build-time configuration parameters | |||
----------------------------------- | |||
The configure script accepts the following command-line parameters in | |||
addition to the standard parameters; | |||
--enable-os-type=TYPE | |||
where TYPE specifies the operating system for which SNFServer is to | |||
be configured. | |||
Generation of sample configuration files and scripts | |||
---------------------------------------------------- | |||
The build system generates sample configuration files and scripts that | |||
take into account where the SNFServer distribution is installed. For | |||
example, if the distribution is built as follows: | |||
./configure --prefix=/home/temp --enable-os-type=OpenBSD | |||
then the sample rulebase download script getRulebase.sample would | |||
download the rulebase to /home/temp/share/snf-server. The other files | |||
(SNFServer.xml.sample, and SNFServer) would also be generated to take | |||
the specified prefix into account. |
@@ -0,0 +1,48 @@ | |||
Both SNFServer.exe and SNFClient.exe can be run in a debugging mode which | |||
produces additional output. In order to run these programs in debug mode | |||
you can rename them so that "debug" or "Debug" is in their name, or you | |||
can call them in a sub directory so that the path to the program conains | |||
"debug" or "Debug". | |||
SNFDebugClient.exe -- | |||
The SNFClient.exe debug mode will display the entire XCI session for each | |||
call. This is a good way to see how XCI is used if you want to explore | |||
communicating with the SNFServer directly from your programs. | |||
SNFDebugServer.exe -- | |||
The SNFServer.exe debug mode will display a thread status report each | |||
second along with the usual running statistics line. The thread status | |||
report will show all active theads, what they are doing (generally), and | |||
whether they are running or have stopped. If a thread stops due to an | |||
unhandeled exception then information about that exception will be | |||
displayed in the status report. | |||
There is a special version of the control script that will run the server | |||
in debug mode and capture it's output in a file called debuglog. | |||
20080325 -- At this time there are a few systems that are reporting an | |||
intermittent bug where SNFServer will either stop answering requests or | |||
it will stop reporting telemetry. When this happens there are no errors | |||
reported in logs, no exceptions thrown, no corrupted programs, nothing | |||
unusual at all --which is, of course, the most unusual thing of all. The | |||
program continues to run -- it's just not listening (or talking). | |||
On all but a handfull of systems SNFServer runs reliably for hundreds of | |||
days at a time without stopping until told to do so... This includes our | |||
lab computers... We hate mysteries -- the thread status report is designed | |||
to help us learn something about this bug since we are not yet able to | |||
reproduce it. | |||
To run SNFServer in debug mode, create a copy of SNFServer.exe named | |||
SNFDebugServer.exe and use the debugsnfctrl script to launch it (or you | |||
can launch it your own way -- the goal is to capture stdout and errout to | |||
a file called debuglog so that we can, hopefully, learn something). | |||
If you are not experiencing the bug then please run SNFServer.exe in the | |||
normal way. | |||
Thanks | |||
_M |
@@ -0,0 +1,23 @@ | |||
## Process this file with automake to produce Makefile.in | |||
## | |||
## $Id: Makefile.am,v 1.2 2007/05/29 19:06:09 adeniz Exp $ | |||
## | |||
## automake input for the ARM Research SNFServer documentation. | |||
## | |||
## Author: Alban Deniz | |||
## | |||
## Copyright (C) 2008 ARM Research Labs, LLC. | |||
## See www.armresearch.com for the copyright terms. | |||
## | |||
doc_DATA = \ | |||
README \ | |||
SNFServer_readme.txt \ | |||
SNFClient_readme.txt \ | |||
DebugMode_readme.txt \ | |||
snf_xci.xml | |||
EXTRA_DIST = \ | |||
$(doc_DATA) \ | |||
Makefile.am |
@@ -0,0 +1,8 @@ | |||
This files in this directory contain additional information. The | |||
files are: | |||
SNFServer_readme.txt: Information about the SNFServer application. | |||
SNFClient_readme.txt: Information about the SNFClient application. | |||
snf_xci.xml: Sample XCI messages. |
@@ -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. | |||
@@ -0,0 +1,203 @@ | |||
SNF_Server V3.0 installation brief | |||
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 | |||
SNFServer.xml 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 SNFServer.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 SNFServer.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 | |||
SNFServer.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 SNFServer.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 (Microsoft Windows example): | |||
c:\SNF\SNFServer.exe c:\SNF\SNFServer.xml | |||
or | |||
/usr/sbin/SNFServer /etc/SNFServer/SNFServer.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,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,489 @@ | |||
SNFServer Installation and Configuration | |||
Copyright (C) 2008 ARM Research Labs, LLC. | |||
See www.armresearch.com for the copyright terms. | |||
Installing SNFServer to filter email involves the following steps: | |||
1) Check prerequisites. | |||
2) Create the snfilter user and group. | |||
3) Build and install the SNFServer package (using a tarball or a | |||
package). | |||
4) Configure the SNFServer package. | |||
5) Interface with the MTA (postfix or sendmail). | |||
6) Configure the OS to start and stop SNFServer on bootup and | |||
shutdown. | |||
The following sections describes each of these steps for a default | |||
installation. Any OS-specific issues are described at the end of each | |||
section. | |||
Prerequisites | |||
************* | |||
Before installing SNFServer, make sure that: | |||
1) The program curl must be installed. | |||
Creating the snfilter user and group | |||
************************************ | |||
Before installing, the snfilter user and group must be created. For | |||
increased security, snfilter user has no shell. | |||
OS-specific issues-- | |||
The commands to create the snfilter user and group are OS dependent. | |||
For your convenience, the commands for creating the user and group for | |||
varous OSes are listed here. However, no guarantee is made that these | |||
commands will work on your system; please refer to your system | |||
documentation. | |||
1) OpenBSD: | |||
a) 'useradd -g =uid -m -c "SNFServer Account" -s /bin/false snfilter'. | |||
2) Ubuntu: | |||
a) 'adduser --gecos "SNFServer Account" --no-create-home --shell /bin/false snfilter'. | |||
3) RedHat (and variants such as Fedora and CentOS): | |||
a) 'adduser --comment "SNFServer Account" -M --shell /bin/false snfilter' | |||
4) Suse: | |||
a) 'groupadd snfilter' | |||
b) 'useradd -c "SNFServer Account" -s /bin/false -g snfilter snfilter' | |||
5) FreeBSD: | |||
a) 'pw user add -c "SNFServer Account" -n snfilter -w no -s /bin/false' | |||
Building and installing SNFServer | |||
********************************* | |||
For some operating systems, configuration files are normally installed | |||
in /etc, and the installation of the remaining files are in /usr | |||
(i.e. /usr/sbin, /usr/share/snf-server, etc). In other operating | |||
systems, the files are installed in /usr/local/etc or /usr/local. | |||
The directories to install are specified by the '--prefix' and | |||
'--sysconfdir' options to the configure script (see below). | |||
To build and install from the tarball-- | |||
1) Extract the distribution from the tarball: 'tar xvzf | |||
snf-server-X.Y.Z.tar.gz', where X.Y.Z is the version of the | |||
distribution. | |||
1) 'cd' to the source directory. | |||
2) Run the configure script. See the section on OS-specific issues | |||
for the options to specify. This configures the package. | |||
3) Type 'make'. This builds the package. | |||
4) Type 'make install'. This installs the package in the default | |||
directories. | |||
The following files are installed: | |||
Executables and scripts in sbin: | |||
SNFServer | |||
SNFClient | |||
SNF2Check | |||
getRulebase.sample | |||
snfSniffer.sample | |||
snfSnifferFilter.sample | |||
snfscan-standalone.sample | |||
snfServerControl.sample | |||
Sample configuration files in etc/snf-server: | |||
SNFServer.xml.sample | |||
identity.xml.sample | |||
In share/snf-server | |||
GBUdbIgnoreList.txt.sample | |||
During operation of SNFServer, the following files are created: | |||
In share/snf-server: | |||
*.snf | |||
Log files | |||
UpdateReady.txt | |||
Temporary files | |||
OS-specific options for ./configure: | |||
1) OpenBSD: | |||
./configure --enable-os-type=OpenBSD --sysconfdir=/etc | |||
2) FreeBSD: | |||
./configure --enable-os-type=FreeBSD | |||
3) Ubuntu: | |||
./configure --enable-os-type=Ubuntu --sysconfdir=/etc --prefix=/usr | |||
4) RedHat (and variants such as Fedora and CentOS): | |||
./configure --enable-os-type=RedHat --sysconfdir=/etc --prefix=/usr | |||
5) Suse: | |||
./configure --enable-os-type=Suse --sysconfdir=/etc --prefix=/usr | |||
Configuration | |||
************* | |||
Configuration consists of creating the configuration files used by | |||
SNFServer from the sample configuration files of the distribution. | |||
There are three configuration files. The location of the files | |||
described in this section are for the installation in /usr and /etc. | |||
Two of the files are in /etc/snf-server: | |||
1) SNFServer.xml (sample configuration file is | |||
SNFServer.xml.sample). | |||
2) identity.xml (sample configuration file is identity.xml.sample). | |||
and one in /usr/share/snf-server: | |||
1) GBUdbIngoreList.txt (sample configuration file is | |||
GBUdbIgnoreList.txt.sample). | |||
To configure SNFServer, do the following: | |||
1) Copy SNFServer.xml.sample to SNFServer.xml, and edit as follows: | |||
a) Specify the directories. The default directories are: | |||
<node identity='/etc/snf-server/identity.xml'> | |||
<log path='/usr/share/snf-server/'/> | |||
<rulebase path='/usr/share/snf-server/'/> | |||
<workspace path='/usr/share/snf-server/'/> | |||
<update-script on-off='on' call='/usr/sbin/getRulebase' | |||
guard-time='180'/> | |||
The paths need to be changed only if the default directories are | |||
not used. | |||
If desired for security purposes, restrict the permissions of | |||
SNFServer.xml. For example, to make SNFServer.xml readonly by | |||
only the snfilter user and snfilter group, enter the following: | |||
chmod 440 SNFServer.xml | |||
2) Copy identity.xml.sample to identity.xml, and edit to include the | |||
license ID and authentication attributes of the <identity> element. | |||
If desired for security purposes, restrict the permissions of | |||
identity.xml. For example, to make identity.xml readonly by only | |||
snfilter, enter the following: | |||
chmod 400 identity.xml | |||
3) Copy GBUdbIngoreList.txt.sample to GBUdbIgnoreList.txt, and edit | |||
as appropriate (the file format is described in the comments in the | |||
file). See README for more information on this file. | |||
4) In the directory for the update script specified in the | |||
configuration file (default: /usr/sbin): | |||
a) Copy getRulebase.sample to getRulebase, and edit as follows: | |||
i) In the line | |||
AUTHENTICATION=authenticationxx | |||
replace authenticationxx with the authentication for the | |||
SNFServer license. | |||
ii) In the line | |||
LICENSE_ID=licenseid | |||
replace licenseid with the license ID of the SNFServer | |||
license. | |||
iii) Any other changes as necessary if the default directories | |||
are not used. | |||
b) Ensure that getRulebase is executable by the snfilter user. | |||
This can be done with the command: | |||
chmod +x getRulebase | |||
5) Ensure that the snfilter user has read/write access to the files | |||
in workspace (default: /usr/share/snf-server or | |||
/usr/local/share/snf-server) and configuration directory (default: | |||
/etc/snf-server). To grant this access, enter the following command, | |||
as the root user: | |||
chown -R snfilter:snfilter /usr/share/snf-server | |||
chown -R snfilter:snfilter /etc/snf-server | |||
As you modify files in these directories, please ensure that the | |||
read/write permissions for snfilter is maintained. | |||
4) Download the rulebase file: | |||
a) 'cd /usr/share/snf-server'. If the workspace specified in the | |||
configuration file is not the default, this command should be | |||
changed accordingly. | |||
b) 'touch UpdateReady.txt'. | |||
c) 'chown snfilter UpdateReady.txt'. | |||
d) 'su -m snfilter -c "/usr/sbin/getRulebase"'. If getRulebase | |||
is in a different directory, this command should be changed | |||
accordingly. | |||
OS-specific issues-- | |||
None. | |||
Configuring the OS | |||
****************** | |||
The OS can be configured to automatically start and stop SNFServer on | |||
system startup and shutdown. The following gives the procedure for | |||
each OS: | |||
OpenBSD: | |||
1) Add the following line to /etc/rc.local: | |||
/usr/local/sbin/snf-server start | |||
2) Add the following line to /etc/rc.shutdown: | |||
/usr/local/sbin/snf-server stop | |||
3) Run '/usr/local/sbin/snf-server start' to start the server. | |||
FreeBSD: | |||
1) Create the directory /etc/rc.conf.d (if it doesn't exist). | |||
2) Create the file /etc/rc.conf.d/snfsrver with the contents: | |||
snfserver_enable="YES" | |||
3) Run '/usr/local/etc/rc.d/snf-server start' to start the server. | |||
Ubuntu: | |||
1) Set the VERBOSE variable in /etc/default/rcS to control the | |||
script output. | |||
2) Configure the system to run the script using the appropriate | |||
procedure. | |||
3) Run '/etc/init.d/snf-server start' to start the server. | |||
RedHat (and variants such as Fedora) and Suse: | |||
1) Run 'chkconfig --add snf-server'. This sonfigures the system to | |||
run the script on startup and shutdown. | |||
2) Run 'chkconfig --list snf-server' to display the runlevels | |||
3) Run 'service snf-server start' to start the SNFServer. | |||
Integration with MTAs | |||
********************* | |||
The section assumes you will be using SNFServer with an MTA and simply | |||
injecting headers that will be used later to remove, quarantine, or | |||
otherwise redirect messages detected as spam. There are as many ways | |||
to use SNFServer as there are systems using it -- so the following is | |||
just a good starting point. | |||
It is presumed that SNFServer is configured with x-header injection | |||
turned on and that the x-headers have been customized to suit your | |||
needs. Check the <xheaders/> section of your | |||
/etc/snf-server/SNFServer.xml file to verify that SNFServer is | |||
configured to do what you want. | |||
Integration with postfix | |||
------------------------ | |||
One way to integrate with postfix is to configure postfix to use the | |||
snfSniffer script (described below) as a content filter. The | |||
snfSniffer script passes the message through SNFServer, and then | |||
reinjects the message into the mail system. | |||
1) In /usr/sbin (or /usr/local/sbin), copy the script | |||
snfSniffer.sample to snfSniffer set the correct access rights: | |||
cp snfSniffer.sample snfSniffer | |||
chown snfilter snfSniffer | |||
chmod 550 snfSniffer | |||
The default snfSniffer script creates a temporary copy of the message, | |||
scans it with SNFServer, and then reinjects the message. | |||
2) Change /etc/postfix/master.cf as follows (LEADING WHITE SPACES | |||
ARE IMPORTANT WHEN MAKING THIS CHANGE): | |||
change (each line is enclosed in single quotes; add only the text | |||
between the single quotes): | |||
'smtp inet n - n - - smtpd' | |||
to: | |||
'smtp inet n - n - - smtpd' | |||
' -o content_filter=snfilter:dummy' | |||
also add: | |||
'snfilter unix - n n - 10 pipe' | |||
' flags=Rq user=snfilter argv=/usr/sbin/snfSniffer' | |||
' -f ${sender} -- ${recipient}' | |||
to master.cf. Specify the directory snfSniffer is in if not | |||
/usr/sbin. | |||
At this point you could just restart postfix, and hope nothing goes | |||
wrong. Instead, it would be smarter to first test the installation | |||
from the command line by injecting a message directly into the filter | |||
script "snfSniffer". We can issue a command like (in directory | |||
/usr/share/snf-server): | |||
/usr/sbin/snfSniffer -f sender recipient < junkmsg.txt | |||
Where junkmsg.txt is a spam test message. We should also test | |||
a clean message to make sure that this script is working as we | |||
expect it to. In this case we would issue a command like | |||
/usr/sbin/snfSniffer -f sender recipient < cleanmsg.txt | |||
If you've done everything correctly then all you have to do is reload | |||
postfix to start the content_filter working. | |||
4) 'postfix reload'. Restart postfix. | |||
5) To stop using the snfSniffer filter: | |||
i) Comment out or remove the '-o content_filter=snfilter:dummy' | |||
line in the /etc/postfix/master.cf file. | |||
ii) 'postsuper -r ALL' to remove content filter request records | |||
from existing queue files. | |||
iii) 'postfix reload' to reload the postfix configuration. | |||
OS-specific issues-- | |||
1) OpenBSD: In the default postfix configuration for OpenBSD, the | |||
postfix programs run chrooted in /var/spool/postfix. For that | |||
configuration, the /etc/pwd.db file needs to be made available to | |||
the postfix programs. This can be done by copying pwd.db: | |||
cp /etc/pwd.db /var/spool/postfix/etc | |||
If the /etc/pwd.db file is modified after copying, the postfix | |||
system issues a warning. To avoid this warning, copy the | |||
/etc/pwd.db file to /var/spool/postfix/etc directory whenever | |||
/etc/pwd.db is modified. | |||
Integration with sendmail | |||
------------------------- | |||
One way to integrate with send is to configure sendmail to use the | |||
snfSnifferFilter script (described below) as a filter. The snfSniffer | |||
script passes the message through SNFServer, and then sends the | |||
message to stdout. The integration is done by having sendmail use | |||
procmail to filter all mail (which is normally the default), and | |||
configuring procmail to use snfSnifferFilter as a filter. | |||
1) In /usr/sbin (or /usr/local/sbin), copy the script | |||
snfSnifferFilter.sample to snfSnifferFilter set the correct access | |||
rights: | |||
cp snfSnifferFilter.sample snfSnifferFilter | |||
chown snfilter snfSnifferFilter | |||
chmod 550 snfSnifferFilter | |||
The default snfSnifferFilter script creates a temporary copy of the | |||
message, scans it with SNFServer, and then send the message to | |||
stdout. | |||
2) Verify that sendmail is configured to use procmail to deliver | |||
mail. Please see the sendmail and procmail documentation for how | |||
to do this. | |||
3) Create the file /etc/procmailrc (or whatever the system procmail | |||
rcfile is; see the procmail documentation for the path on your | |||
system) to contain the following lines: | |||
':0 fw' | |||
'| /usr/sbin/snfSnifferFilter' | |||
where the single quotes are not to be included. | |||
At this point mail should be filtered by SNFServer. To check this, | |||
issue a command like (in directory /usr/share/snf-server): | |||
/usr/sbin/snfSnifferFilter < junkmsg.txt | |||
Where junkmsg.txt is a spam test message. We should also test a clean | |||
message to make sure that this script is working as we expect it to. | |||
In this case we would issue a command like | |||
/usr/sbin/snfSnifferFilter < cleanmsg.txt | |||
In either case you should see the message with the headers added by | |||
SNFServer. | |||
4) To stop using the snfSnifferFilter: | |||
i) Comment out or remove the two lines you added to /etc/procmailrc. | |||
OS-specific issues-- | |||
1) OpenBSD: The default sendmail confiugration might not use | |||
procmail. To configure sendmail to use procmail, please ensure that | |||
procmail is installed and see the procmail documentation | |||
(/usr/local/share/examples/procmail/advanced) for the procedure to | |||
integrate procmail as an integrated local mail delivery agent. | |||
By default, procmail is installed in /usr/local/bin, and the system | |||
procmail rcfile is /etc/procmailrc. | |||
After you make the changes, stop sendmail with 'pkill sendmail', and | |||
start it with 'sendmail -bd'. | |||
2) FreeBSD: The default sendmail confiugration might not use | |||
procmail. To configure sendmail to use procmail, please ensure that | |||
procmail is installed and see the procmail documentation | |||
(/usr/local/share/examples/procmail/advanced) for the procedure to | |||
integrate procmail as an integrated local mail delivery agent. | |||
By default, procmail is installed in /usr/local/bin, and the system | |||
procmail rcfile is /usr/local/etc/procmailrc. | |||
After you make the changes, restart sendmail with | |||
'/etc/rc.d/sendmail restart'. | |||
3) RedHat, Fedora, Centos, Suse, and Ubuntu: Restart sendmail with | |||
'/etc/init.d/sendmail restart'. |
@@ -0,0 +1,42 @@ | |||
## Process this file with automake to produce Makefile.in | |||
## | |||
## $Id: Makefile.am,v 1.2 2007/05/29 19:06:09 adeniz Exp $ | |||
## | |||
## automake input for the ARM Research Labs SNFServer distribution | |||
## (top directory). | |||
## | |||
## Author: Alban Deniz | |||
## | |||
## Copyright (C) 2008 ARM Research Labs, LLC. | |||
## See www.armresearch.com for the copyright terms. | |||
## | |||
SUBDIRS = \ | |||
CodeDweller \ | |||
SNFMulti \ | |||
SNFServer \ | |||
SNFClient \ | |||
SNF2Check \ | |||
Scripts \ | |||
config_files \ | |||
Docs | |||
doc_DATA = \ | |||
BUGS \ | |||
ChangeLog \ | |||
README \ | |||
TODO \ | |||
INSTALL \ | |||
COPYING | |||
EXTRA_DIST = \ | |||
$(doc_DATA) \ | |||
Makefile.am \ | |||
configure.ac \ | |||
SNF4SA/INSTALL \ | |||
SNF4SA/README \ | |||
SNF4SA/snf4sa.cf \ | |||
SNF4SA/snf4sa.pm | |||
DISTCHECK_CONFIGURE_FLAGS=--enable-os-type=OpenBSD |
@@ -0,0 +1,9 @@ | |||
This is the README file for SNFServer, an anti-spam server daemon. | |||
Copyright (C) 2008 ARM Research Labs, LLC. | |||
See the file COPYING or www.armresearch.com for the copyright terms. | |||
Please see the docs directory for additional information. | |||
Please see the INSTALL file for installation and configuration | |||
directions. |
@@ -0,0 +1,674 @@ | |||
GNU GENERAL PUBLIC LICENSE | |||
Version 3, 29 June 2007 | |||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> | |||
Everyone is permitted to copy and distribute verbatim copies | |||
of this license document, but changing it is not allowed. | |||
Preamble | |||
The GNU General Public License is a free, copyleft license for | |||
software and other kinds of works. | |||
The licenses for most software and other practical works are designed | |||
to take away your freedom to share and change the works. By contrast, | |||
the GNU General Public License is intended to guarantee your freedom to | |||
share and change all versions of a program--to make sure it remains free | |||
software for all its users. We, the Free Software Foundation, use the | |||
GNU General Public License for most of our software; it applies also to | |||
any other work released this way by its authors. You can apply it to | |||
your programs, too. | |||
When we speak of free software, we are referring to freedom, not | |||
price. Our General Public Licenses are designed to make sure that you | |||
have the freedom to distribute copies of free software (and charge for | |||
them if you wish), that you receive source code or can get it if you | |||
want it, that you can change the software or use pieces of it in new | |||
free programs, and that you know you can do these things. | |||
To protect your rights, we need to prevent others from denying you | |||
these rights or asking you to surrender the rights. Therefore, you have | |||
certain responsibilities if you distribute copies of the software, or if | |||
you modify it: responsibilities to respect the freedom of others. | |||
For example, if you distribute copies of such a program, whether | |||
gratis or for a fee, you must pass on to the recipients the same | |||
freedoms that you received. You must make sure that they, too, receive | |||
or can get the source code. And you must show them these terms so they | |||
know their rights. | |||
Developers that use the GNU GPL protect your rights with two steps: | |||
(1) assert copyright on the software, and (2) offer you this License | |||
giving you legal permission to copy, distribute and/or modify it. | |||
For the developers' and authors' protection, the GPL clearly explains | |||
that there is no warranty for this free software. For both users' and | |||
authors' sake, the GPL requires that modified versions be marked as | |||
changed, so that their problems will not be attributed erroneously to | |||
authors of previous versions. | |||
Some devices are designed to deny users access to install or run | |||
modified versions of the software inside them, although the manufacturer | |||
can do so. This is fundamentally incompatible with the aim of | |||
protecting users' freedom to change the software. The systematic | |||
pattern of such abuse occurs in the area of products for individuals to | |||
use, which is precisely where it is most unacceptable. Therefore, we | |||
have designed this version of the GPL to prohibit the practice for those | |||
products. If such problems arise substantially in other domains, we | |||
stand ready to extend this provision to those domains in future versions | |||
of the GPL, as needed to protect the freedom of users. | |||
Finally, every program is threatened constantly by software patents. | |||
States should not allow patents to restrict development and use of | |||
software on general-purpose computers, but in those that do, we wish to | |||
avoid the special danger that patents applied to a free program could | |||
make it effectively proprietary. To prevent this, the GPL assures that | |||
patents cannot be used to render the program non-free. | |||
The precise terms and conditions for copying, distribution and | |||
modification follow. | |||
TERMS AND CONDITIONS | |||
0. Definitions. | |||
"This License" refers to version 3 of the GNU General Public License. | |||
"Copyright" also means copyright-like laws that apply to other kinds of | |||
works, such as semiconductor masks. | |||
"The Program" refers to any copyrightable work licensed under this | |||
License. Each licensee is addressed as "you". "Licensees" and | |||
"recipients" may be individuals or organizations. | |||
To "modify" a work means to copy from or adapt all or part of the work | |||
in a fashion requiring copyright permission, other than the making of an | |||
exact copy. The resulting work is called a "modified version" of the | |||
earlier work or a work "based on" the earlier work. | |||
A "covered work" means either the unmodified Program or a work based | |||
on the Program. | |||
To "propagate" a work means to do anything with it that, without | |||
permission, would make you directly or secondarily liable for | |||
infringement under applicable copyright law, except executing it on a | |||
computer or modifying a private copy. Propagation includes copying, | |||
distribution (with or without modification), making available to the | |||
public, and in some countries other activities as well. | |||
To "convey" a work means any kind of propagation that enables other | |||
parties to make or receive copies. Mere interaction with a user through | |||
a computer network, with no transfer of a copy, is not conveying. | |||
An interactive user interface displays "Appropriate Legal Notices" | |||
to the extent that it includes a convenient and prominently visible | |||
feature that (1) displays an appropriate copyright notice, and (2) | |||
tells the user that there is no warranty for the work (except to the | |||
extent that warranties are provided), that licensees may convey the | |||
work under this License, and how to view a copy of this License. If | |||
the interface presents a list of user commands or options, such as a | |||
menu, a prominent item in the list meets this criterion. | |||
1. Source Code. | |||
The "source code" for a work means the preferred form of the work | |||
for making modifications to it. "Object code" means any non-source | |||
form of a work. | |||
A "Standard Interface" means an interface that either is an official | |||
standard defined by a recognized standards body, or, in the case of | |||
interfaces specified for a particular programming language, one that | |||
is widely used among developers working in that language. | |||
The "System Libraries" of an executable work include anything, other | |||
than the work as a whole, that (a) is included in the normal form of | |||
packaging a Major Component, but which is not part of that Major | |||
Component, and (b) serves only to enable use of the work with that | |||
Major Component, or to implement a Standard Interface for which an | |||
implementation is available to the public in source code form. A | |||
"Major Component", in this context, means a major essential component | |||
(kernel, window system, and so on) of the specific operating system | |||
(if any) on which the executable work runs, or a compiler used to | |||
produce the work, or an object code interpreter used to run it. | |||
The "Corresponding Source" for a work in object code form means all | |||
the source code needed to generate, install, and (for an executable | |||
work) run the object code and to modify the work, including scripts to | |||
control those activities. However, it does not include the work's | |||
System Libraries, or general-purpose tools or generally available free | |||
programs which are used unmodified in performing those activities but | |||
which are not part of the work. For example, Corresponding Source | |||
includes interface definition files associated with source files for | |||
the work, and the source code for shared libraries and dynamically | |||
linked subprograms that the work is specifically designed to require, | |||
such as by intimate data communication or control flow between those | |||
subprograms and other parts of the work. | |||
The Corresponding Source need not include anything that users | |||
can regenerate automatically from other parts of the Corresponding | |||
Source. | |||
The Corresponding Source for a work in source code form is that | |||
same work. | |||
2. Basic Permissions. | |||
All rights granted under this License are granted for the term of | |||
copyright on the Program, and are irrevocable provided the stated | |||
conditions are met. This License explicitly affirms your unlimited | |||
permission to run the unmodified Program. The output from running a | |||
covered work is covered by this License only if the output, given its | |||
content, constitutes a covered work. This License acknowledges your | |||
rights of fair use or other equivalent, as provided by copyright law. | |||
You may make, run and propagate covered works that you do not | |||
convey, without conditions so long as your license otherwise remains | |||
in force. You may convey covered works to others for the sole purpose | |||
of having them make modifications exclusively for you, or provide you | |||
with facilities for running those works, provided that you comply with | |||
the terms of this License in conveying all material for which you do | |||
not control copyright. Those thus making or running the covered works | |||
for you must do so exclusively on your behalf, under your direction | |||
and control, on terms that prohibit them from making any copies of | |||
your copyrighted material outside their relationship with you. | |||
Conveying under any other circumstances is permitted solely under | |||
the conditions stated below. Sublicensing is not allowed; section 10 | |||
makes it unnecessary. | |||
3. Protecting Users' Legal Rights From Anti-Circumvention Law. | |||
No covered work shall be deemed part of an effective technological | |||
measure under any applicable law fulfilling obligations under article | |||
11 of the WIPO copyright treaty adopted on 20 December 1996, or | |||
similar laws prohibiting or restricting circumvention of such | |||
measures. | |||
When you convey a covered work, you waive any legal power to forbid | |||
circumvention of technological measures to the extent such circumvention | |||
is effected by exercising rights under this License with respect to | |||
the covered work, and you disclaim any intention to limit operation or | |||
modification of the work as a means of enforcing, against the work's | |||
users, your or third parties' legal rights to forbid circumvention of | |||
technological measures. | |||
4. Conveying Verbatim Copies. | |||
You may convey verbatim copies of the Program's source code as you | |||
receive it, in any medium, provided that you conspicuously and | |||
appropriately publish on each copy an appropriate copyright notice; | |||
keep intact all notices stating that this License and any | |||
non-permissive terms added in accord with section 7 apply to the code; | |||
keep intact all notices of the absence of any warranty; and give all | |||
recipients a copy of this License along with the Program. | |||
You may charge any price or no price for each copy that you convey, | |||
and you may offer support or warranty protection for a fee. | |||
5. Conveying Modified Source Versions. | |||
You may convey a work based on the Program, or the modifications to | |||
produce it from the Program, in the form of source code under the | |||
terms of section 4, provided that you also meet all of these conditions: | |||
a) The work must carry prominent notices stating that you modified | |||
it, and giving a relevant date. | |||
b) The work must carry prominent notices stating that it is | |||
released under this License and any conditions added under section | |||
7. This requirement modifies the requirement in section 4 to | |||
"keep intact all notices". | |||
c) You must license the entire work, as a whole, under this | |||
License to anyone who comes into possession of a copy. This | |||
License will therefore apply, along with any applicable section 7 | |||
additional terms, to the whole of the work, and all its parts, | |||
regardless of how they are packaged. This License gives no | |||
permission to license the work in any other way, but it does not | |||
invalidate such permission if you have separately received it. | |||
d) If the work has interactive user interfaces, each must display | |||
Appropriate Legal Notices; however, if the Program has interactive | |||
interfaces that do not display Appropriate Legal Notices, your | |||
work need not make them do so. | |||
A compilation of a covered work with other separate and independent | |||
works, which are not by their nature extensions of the covered work, | |||
and which are not combined with it such as to form a larger program, | |||
in or on a volume of a storage or distribution medium, is called an | |||
"aggregate" if the compilation and its resulting copyright are not | |||
used to limit the access or legal rights of the compilation's users | |||
beyond what the individual works permit. Inclusion of a covered work | |||
in an aggregate does not cause this License to apply to the other | |||
parts of the aggregate. | |||
6. Conveying Non-Source Forms. | |||
You may convey a covered work in object code form under the terms | |||
of sections 4 and 5, provided that you also convey the | |||
machine-readable Corresponding Source under the terms of this License, | |||
in one of these ways: | |||
a) Convey the object code in, or embodied in, a physical product | |||
(including a physical distribution medium), accompanied by the | |||
Corresponding Source fixed on a durable physical medium | |||
customarily used for software interchange. | |||
b) Convey the object code in, or embodied in, a physical product | |||
(including a physical distribution medium), accompanied by a | |||
written offer, valid for at least three years and valid for as | |||
long as you offer spare parts or customer support for that product | |||
model, to give anyone who possesses the object code either (1) a | |||
copy of the Corresponding Source for all the software in the | |||
product that is covered by this License, on a durable physical | |||
medium customarily used for software interchange, for a price no | |||
more than your reasonable cost of physically performing this | |||
conveying of source, or (2) access to copy the | |||
Corresponding Source from a network server at no charge. | |||
c) Convey individual copies of the object code with a copy of the | |||
written offer to provide the Corresponding Source. This | |||
alternative is allowed only occasionally and noncommercially, and | |||
only if you received the object code with such an offer, in accord | |||
with subsection 6b. | |||
d) Convey the object code by offering access from a designated | |||
place (gratis or for a charge), and offer equivalent access to the | |||
Corresponding Source in the same way through the same place at no | |||
further charge. You need not require recipients to copy the | |||
Corresponding Source along with the object code. If the place to | |||
copy the object code is a network server, the Corresponding Source | |||
may be on a different server (operated by you or a third party) | |||
that supports equivalent copying facilities, provided you maintain | |||
clear directions next to the object code saying where to find the | |||
Corresponding Source. Regardless of what server hosts the | |||
Corresponding Source, you remain obligated to ensure that it is | |||
available for as long as needed to satisfy these requirements. | |||
e) Convey the object code using peer-to-peer transmission, provided | |||
you inform other peers where the object code and Corresponding | |||
Source of the work are being offered to the general public at no | |||
charge under subsection 6d. | |||
A separable portion of the object code, whose source code is excluded | |||
from the Corresponding Source as a System Library, need not be | |||
included in conveying the object code work. | |||
A "User Product" is either (1) a "consumer product", which means any | |||
tangible personal property which is normally used for personal, family, | |||
or household purposes, or (2) anything designed or sold for incorporation | |||
into a dwelling. In determining whether a product is a consumer product, | |||
doubtful cases shall be resolved in favor of coverage. For a particular | |||
product received by a particular user, "normally used" refers to a | |||
typical or common use of that class of product, regardless of the status | |||
of the particular user or of the way in which the particular user | |||
actually uses, or expects or is expected to use, the product. A product | |||
is a consumer product regardless of whether the product has substantial | |||
commercial, industrial or non-consumer uses, unless such uses represent | |||
the only significant mode of use of the product. | |||
"Installation Information" for a User Product means any methods, | |||
procedures, authorization keys, or other information required to install | |||
and execute modified versions of a covered work in that User Product from | |||
a modified version of its Corresponding Source. The information must | |||
suffice to ensure that the continued functioning of the modified object | |||
code is in no case prevented or interfered with solely because | |||
modification has been made. | |||
If you convey an object code work under this section in, or with, or | |||
specifically for use in, a User Product, and the conveying occurs as | |||
part of a transaction in which the right of possession and use of the | |||
User Product is transferred to the recipient in perpetuity or for a | |||
fixed term (regardless of how the transaction is characterized), the | |||
Corresponding Source conveyed under this section must be accompanied | |||
by the Installation Information. But this requirement does not apply | |||
if neither you nor any third party retains the ability to install | |||
modified object code on the User Product (for example, the work has | |||
been installed in ROM). | |||
The requirement to provide Installation Information does not include a | |||
requirement to continue to provide support service, warranty, or updates | |||
for a work that has been modified or installed by the recipient, or for | |||
the User Product in which it has been modified or installed. Access to a | |||
network may be denied when the modification itself materially and | |||
adversely affects the operation of the network or violates the rules and | |||
protocols for communication across the network. | |||
Corresponding Source conveyed, and Installation Information provided, | |||
in accord with this section must be in a format that is publicly | |||
documented (and with an implementation available to the public in | |||
source code form), and must require no special password or key for | |||
unpacking, reading or copying. | |||
7. Additional Terms. | |||
"Additional permissions" are terms that supplement the terms of this | |||
License by making exceptions from one or more of its conditions. | |||
Additional permissions that are applicable to the entire Program shall | |||
be treated as though they were included in this License, to the extent | |||
that they are valid under applicable law. If additional permissions | |||
apply only to part of the Program, that part may be used separately | |||
under those permissions, but the entire Program remains governed by | |||
this License without regard to the additional permissions. | |||
When you convey a copy of a covered work, you may at your option | |||
remove any additional permissions from that copy, or from any part of | |||
it. (Additional permissions may be written to require their own | |||
removal in certain cases when you modify the work.) You may place | |||
additional permissions on material, added by you to a covered work, | |||
for which you have or can give appropriate copyright permission. | |||
Notwithstanding any other provision of this License, for material you | |||
add to a covered work, you may (if authorized by the copyright holders of | |||
that material) supplement the terms of this License with terms: | |||
a) Disclaiming warranty or limiting liability differently from the | |||
terms of sections 15 and 16 of this License; or | |||
b) Requiring preservation of specified reasonable legal notices or | |||
author attributions in that material or in the Appropriate Legal | |||
Notices displayed by works containing it; or | |||
c) Prohibiting misrepresentation of the origin of that material, or | |||
requiring that modified versions of such material be marked in | |||
reasonable ways as different from the original version; or | |||
d) Limiting the use for publicity purposes of names of licensors or | |||
authors of the material; or | |||
e) Declining to grant rights under trademark law for use of some | |||
trade names, trademarks, or service marks; or | |||
f) Requiring indemnification of licensors and authors of that | |||
material by anyone who conveys the material (or modified versions of | |||
it) with contractual assumptions of liability to the recipient, for | |||
any liability that these contractual assumptions directly impose on | |||
those licensors and authors. | |||
All other non-permissive additional terms are considered "further | |||
restrictions" within the meaning of section 10. If the Program as you | |||
received it, or any part of it, contains a notice stating that it is | |||
governed by this License along with a term that is a further | |||
restriction, you may remove that term. If a license document contains | |||
a further restriction but permits relicensing or conveying under this | |||
License, you may add to a covered work material governed by the terms | |||
of that license document, provided that the further restriction does | |||
not survive such relicensing or conveying. | |||
If you add terms to a covered work in accord with this section, you | |||
must place, in the relevant source files, a statement of the | |||
additional terms that apply to those files, or a notice indicating | |||
where to find the applicable terms. | |||
Additional terms, permissive or non-permissive, may be stated in the | |||
form of a separately written license, or stated as exceptions; | |||
the above requirements apply either way. | |||
8. Termination. | |||
You may not propagate or modify a covered work except as expressly | |||
provided under this License. Any attempt otherwise to propagate or | |||
modify it is void, and will automatically terminate your rights under | |||
this License (including any patent licenses granted under the third | |||
paragraph of section 11). | |||
However, if you cease all violation of this License, then your | |||
license from a particular copyright holder is reinstated (a) | |||
provisionally, unless and until the copyright holder explicitly and | |||
finally terminates your license, and (b) permanently, if the copyright | |||
holder fails to notify you of the violation by some reasonable means | |||
prior to 60 days after the cessation. | |||
Moreover, your license from a particular copyright holder is | |||
reinstated permanently if the copyright holder notifies you of the | |||
violation by some reasonable means, this is the first time you have | |||
received notice of violation of this License (for any work) from that | |||
copyright holder, and you cure the violation prior to 30 days after | |||
your receipt of the notice. | |||
Termination of your rights under this section does not terminate the | |||
licenses of parties who have received copies or rights from you under | |||
this License. If your rights have been terminated and not permanently | |||
reinstated, you do not qualify to receive new licenses for the same | |||
material under section 10. | |||
9. Acceptance Not Required for Having Copies. | |||
You are not required to accept this License in order to receive or | |||
run a copy of the Program. Ancillary propagation of a covered work | |||
occurring solely as a consequence of using peer-to-peer transmission | |||
to receive a copy likewise does not require acceptance. However, | |||
nothing other than this License grants you permission to propagate or | |||
modify any covered work. These actions infringe copyright if you do | |||
not accept this License. Therefore, by modifying or propagating a | |||
covered work, you indicate your acceptance of this License to do so. | |||
10. Automatic Licensing of Downstream Recipients. | |||
Each time you convey a covered work, the recipient automatically | |||
receives a license from the original licensors, to run, modify and | |||
propagate that work, subject to this License. You are not responsible | |||
for enforcing compliance by third parties with this License. | |||
An "entity transaction" is a transaction transferring control of an | |||
organization, or substantially all assets of one, or subdividing an | |||
organization, or merging organizations. If propagation of a covered | |||
work results from an entity transaction, each party to that | |||
transaction who receives a copy of the work also receives whatever | |||
licenses to the work the party's predecessor in interest had or could | |||
give under the previous paragraph, plus a right to possession of the | |||
Corresponding Source of the work from the predecessor in interest, if | |||
the predecessor has it or can get it with reasonable efforts. | |||
You may not impose any further restrictions on the exercise of the | |||
rights granted or affirmed under this License. For example, you may | |||
not impose a license fee, royalty, or other charge for exercise of | |||
rights granted under this License, and you may not initiate litigation | |||
(including a cross-claim or counterclaim in a lawsuit) alleging that | |||
any patent claim is infringed by making, using, selling, offering for | |||
sale, or importing the Program or any portion of it. | |||
11. Patents. | |||
A "contributor" is a copyright holder who authorizes use under this | |||
License of the Program or a work on which the Program is based. The | |||
work thus licensed is called the contributor's "contributor version". | |||
A contributor's "essential patent claims" are all patent claims | |||
owned or controlled by the contributor, whether already acquired or | |||
hereafter acquired, that would be infringed by some manner, permitted | |||
by this License, of making, using, or selling its contributor version, | |||
but do not include claims that would be infringed only as a | |||
consequence of further modification of the contributor version. For | |||
purposes of this definition, "control" includes the right to grant | |||
patent sublicenses in a manner consistent with the requirements of | |||
this License. | |||
Each contributor grants you a non-exclusive, worldwide, royalty-free | |||
patent license under the contributor's essential patent claims, to | |||
make, use, sell, offer for sale, import and otherwise run, modify and | |||
propagate the contents of its contributor version. | |||
In the following three paragraphs, a "patent license" is any express | |||
agreement or commitment, however denominated, not to enforce a patent | |||
(such as an express permission to practice a patent or covenant not to | |||
sue for patent infringement). To "grant" such a patent license to a | |||
party means to make such an agreement or commitment not to enforce a | |||
patent against the party. | |||
If you convey a covered work, knowingly relying on a patent license, | |||
and the Corresponding Source of the work is not available for anyone | |||
to copy, free of charge and under the terms of this License, through a | |||
publicly available network server or other readily accessible means, | |||
then you must either (1) cause the Corresponding Source to be so | |||
available, or (2) arrange to deprive yourself of the benefit of the | |||
patent license for this particular work, or (3) arrange, in a manner | |||
consistent with the requirements of this License, to extend the patent | |||
license to downstream recipients. "Knowingly relying" means you have | |||
actual knowledge that, but for the patent license, your conveying the | |||
covered work in a country, or your recipient's use of the covered work | |||
in a country, would infringe one or more identifiable patents in that | |||
country that you have reason to believe are valid. | |||
If, pursuant to or in connection with a single transaction or | |||
arrangement, you convey, or propagate by procuring conveyance of, a | |||
covered work, and grant a patent license to some of the parties | |||
receiving the covered work authorizing them to use, propagate, modify | |||
or convey a specific copy of the covered work, then the patent license | |||
you grant is automatically extended to all recipients of the covered | |||
work and works based on it. | |||
A patent license is "discriminatory" if it does not include within | |||
the scope of its coverage, prohibits the exercise of, or is | |||
conditioned on the non-exercise of one or more of the rights that are | |||
specifically granted under this License. You may not convey a covered | |||
work if you are a party to an arrangement with a third party that is | |||
in the business of distributing software, under which you make payment | |||
to the third party based on the extent of your activity of conveying | |||
the work, and under which the third party grants, to any of the | |||
parties who would receive the covered work from you, a discriminatory | |||
patent license (a) in connection with copies of the covered work | |||
conveyed by you (or copies made from those copies), or (b) primarily | |||
for and in connection with specific products or compilations that | |||
contain the covered work, unless you entered into that arrangement, | |||
or that patent license was granted, prior to 28 March 2007. | |||
Nothing in this License shall be construed as excluding or limiting | |||
any implied license or other defenses to infringement that may | |||
otherwise be available to you under applicable patent law. | |||
12. No Surrender of Others' Freedom. | |||
If conditions are imposed on you (whether by court order, agreement or | |||
otherwise) that contradict the conditions of this License, they do not | |||
excuse you from the conditions of this License. If you cannot convey a | |||
covered work so as to satisfy simultaneously your obligations under this | |||
License and any other pertinent obligations, then as a consequence you may | |||
not convey it at all. For example, if you agree to terms that obligate you | |||
to collect a royalty for further conveying from those to whom you convey | |||
the Program, the only way you could satisfy both those terms and this | |||
License would be to refrain entirely from conveying the Program. | |||
13. Use with the GNU Affero General Public License. | |||
Notwithstanding any other provision of this License, you have | |||
permission to link or combine any covered work with a work licensed | |||
under version 3 of the GNU Affero General Public License into a single | |||
combined work, and to convey the resulting work. The terms of this | |||
License will continue to apply to the part which is the covered work, | |||
but the special requirements of the GNU Affero General Public License, | |||
section 13, concerning interaction through a network will apply to the | |||
combination as such. | |||
14. Revised Versions of this License. | |||
The Free Software Foundation may publish revised and/or new versions of | |||
the GNU General Public License from time to time. Such new versions will | |||
be similar in spirit to the present version, but may differ in detail to | |||
address new problems or concerns. | |||
Each version is given a distinguishing version number. If the | |||
Program specifies that a certain numbered version of the GNU General | |||
Public License "or any later version" applies to it, you have the | |||
option of following the terms and conditions either of that numbered | |||
version or of any later version published by the Free Software | |||
Foundation. If the Program does not specify a version number of the | |||
GNU General Public License, you may choose any version ever published | |||
by the Free Software Foundation. | |||
If the Program specifies that a proxy can decide which future | |||
versions of the GNU General Public License can be used, that proxy's | |||
public statement of acceptance of a version permanently authorizes you | |||
to choose that version for the Program. | |||
Later license versions may give you additional or different | |||
permissions. However, no additional obligations are imposed on any | |||
author or copyright holder as a result of your choosing to follow a | |||
later version. | |||
15. Disclaimer of Warranty. | |||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY | |||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT | |||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY | |||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, | |||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM | |||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF | |||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | |||
16. Limitation of Liability. | |||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS | |||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY | |||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE | |||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF | |||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD | |||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), | |||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF | |||
SUCH DAMAGES. | |||
17. Interpretation of Sections 15 and 16. | |||
If the disclaimer of warranty and limitation of liability provided | |||
above cannot be given local legal effect according to their terms, | |||
reviewing courts shall apply local law that most closely approximates | |||
an absolute waiver of all civil liability in connection with the | |||
Program, unless a warranty or assumption of liability accompanies a | |||
copy of the Program in return for a fee. | |||
END OF TERMS AND CONDITIONS | |||
How to Apply These Terms to Your New Programs | |||
If you develop a new program, and you want it to be of the greatest | |||
possible use to the public, the best way to achieve this is to make it | |||
free software which everyone can redistribute and change under these terms. | |||
To do so, attach the following notices to the program. It is safest | |||
to attach them to the start of each source file to most effectively | |||
state the exclusion of warranty; and each file should have at least | |||
the "copyright" line and a pointer to where the full notice is found. | |||
<one line to give the program's name and a brief idea of what it does.> | |||
Copyright (C) <year> <name of author> | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 3 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
Also add information on how to contact you by electronic and paper mail. | |||
If the program does terminal interaction, make it output a short | |||
notice like this when it starts in an interactive mode: | |||
<program> Copyright (C) <year> <name of author> | |||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |||
This is free software, and you are welcome to redistribute it | |||
under certain conditions; type `show c' for details. | |||
The hypothetical commands `show w' and `show c' should show the appropriate | |||
parts of the General Public License. Of course, your program's commands | |||
might be different; for a GUI interface, you would use an "about box". | |||
You should also get your employer (if you work as a programmer) or school, | |||
if any, to sign a "copyright disclaimer" for the program, if necessary. | |||
For more information on this, and how to apply and follow the GNU GPL, see | |||
<http://www.gnu.org/licenses/>. | |||
The GNU General Public License does not permit incorporating your program | |||
into proprietary programs. If your program is a subroutine library, you | |||
may consider it more useful to permit linking proprietary applications with | |||
the library. If this is what you want to do, use the GNU Lesser General | |||
Public License instead of this License. But first, please read | |||
<http://www.gnu.org/philosophy/why-not-lgpl.html>. |
@@ -0,0 +1,11 @@ | |||
2009-05-16 Alban Deniz <adeniz@skidmark.localdomain> | |||
* snf4sa.pm (snf4sa_sacheck): Submit the contribution to the score | |||
using $permsgstatus->{conf}->{scoreset} rather than | |||
$permsgstatus->{scoreset}. This addresses the problem with | |||
amavisd-new always having a score of 1. | |||
2009-05-13 Alban Deniz <adeniz@skidmark.localdomain> | |||
* snf4sa.pm (snf4sa_sacheck): Corrected calculation of GBUdb | |||
contribution to SA score: sqrt(abs(p * c)) * weight. |
@@ -0,0 +1,120 @@ | |||
Developer notes for the SNF4SA developer distribution | |||
30 April 2009 | |||
Scope | |||
----- | |||
This file contains information for software developers. Ths | |||
information includes the prerequisite software for building, and a | |||
description of the build system. | |||
Introduction | |||
------------ | |||
The purpose of the build system is to create a user tarball. The | |||
files don't need to be compiled or linked, and the user is responsible | |||
for intalling and removing the files. Therefore, the build system | |||
doesn't include any functionality for building, installing, or | |||
uninstalling; the "make install" command does nothing. | |||
See the section "Using the build system" for commands to initialize | |||
the build system and create a user tarball. | |||
Software prerequisites | |||
---------------------- | |||
The build system uses GNU software development system. The following | |||
software is needed for building: | |||
1) automake | |||
2) autoconf | |||
3) make | |||
4) tar | |||
These tools are normally available on a Linux system that is | |||
configured as a software development system. The Linux system | |||
installation process usually gives the user a choice of installing a | |||
workstation, server, or software development system. However, not all | |||
Linux distributions give these choices. | |||
If these tools are not installed, they may be installed (or upgraded) | |||
at any time. The commands vary from distribution to distribution. | |||
For Ubuntu, the apt-get command can be used: | |||
1) 'apt-get install automake'. | |||
2) 'apt-get install autoconf'. | |||
3) 'apt-get install make'. | |||
4) 'apt-get install tar'. | |||
Structure of the build system | |||
----------------------------- | |||
The following files comprise the build system: | |||
1) configure.ac. This is the main configuration file. It specifies | |||
the distribution name, version, which libraries are needed, etc. | |||
2) Makefile.am. This is used to create the top-level Makefile. It | |||
lists which files and directories are part of the build system | |||
(e.g. snf4sa.cf), and which extra files are to be part of the | |||
distribution (e.g. README, etc). | |||
To add an additional file , edit Makefile.am. Add the file to the | |||
appropriate variable (for example, to EXTRA_DIST). | |||
Note that files that are not listed will not be included in the | |||
distribution tarball. This allows you to have additional files in | |||
directories (used, for example, for other projects) without | |||
unnecessarily increasing the size of the SNFServer application or | |||
tarball. | |||
Using the build system | |||
---------------------- | |||
Issue the following command to prepare system newly checked out for | |||
building: | |||
autoreconf --install | |||
Then issue the following command for configuring the build system: | |||
./configure | |||
To create a user tarball: | |||
make dist | |||
This creates a tarball with the name snf4sa-X.Y.Z.tar.gz. X, Y, and Z, as well as "snf4sa" are specified by the following line in configure.ac: | |||
AC_INIT(snf4sa, X.Y.Z) | |||
Other commands: | |||
"make maintainer-clean" removes many of the files that can be | |||
created. After running this, you would need to run ./configure. | |||
Note: The script 'cleanForDist' cleans the developer distribution. It | |||
removes any user tarballs that might have been created, files created | |||
by 'autoreconf --install', and files ending in "~". After running | |||
this command, the directory tree can be imported into a version | |||
control system, or tarred and gzipped. | |||
Changing the version number or package name | |||
------------------------------------------- | |||
To change the version number or package name, edit configure.ac as | |||
follows: | |||
Change the version number and/or package name for the build system. | |||
Do this by modifying the argument to the AC_INIT line in | |||
configure.ac. For example, to change the package name to FOO and | |||
the version to 8.0.2, modify the line to be: | |||
AC_INIT(FOO, 8.0.2) |
@@ -0,0 +1,134 @@ | |||
SpamAssassin SNF4SA Plugin for SNFServer | |||
Installation and Configuration | |||
Copyright (C) 2009 ARM Research Labs, LLC. | |||
See www.armresearch.com for the copyright terms. | |||
Installing SpamAssassin SNF4SA plugin for SNFServer involves the | |||
following steps: | |||
1) Copy snf4sa.pm and snf4sa.cf to /etc/mail/spamassassin . | |||
2) Edit /etc/mail/spamassassin/snf4sa.cf plugin configuration file | |||
to meet your needs. See below for a description of the | |||
configuration settings. | |||
The module writes the email message to a temporary file in | |||
/tmp/snf4sa. If this directory doesn't exist, the script creates it | |||
with permission 777. This allows both the script and SNFServer to | |||
write to that directory. If that directory already exists, ensure | |||
that it has a permission of 777. | |||
Plugin Configuation Settings | |||
---------------------------- | |||
The plugin file (snf4sa.cf) contains required lines that: | |||
1) Configures SpamAssassin to load the plugin. | |||
2) Describes the plugin. | |||
3) Configures SpamAssassin to add the X-Spam-SNF-Result header to | |||
the email. This header contains the results of the SNF scan. | |||
In addition, there are lines that can be configured by the user that | |||
specifies: | |||
1) Which emails to process through SNFServer. | |||
2) The relationship between SNFServer results and the SpamAssassin | |||
score. You can specify the value added to or subtracted from the | |||
SpamAssasin score for each SNFServer result. You can also specify | |||
whether SpamAssasin should abort further processing for eacn | |||
SNFServer result. | |||
3) The relationship between the GBUdb results and the SpamAssassin | |||
score. The GBUdb probability p and confidence c add the following | |||
value to the SpamAssasin score: | |||
abs(p * c) ^ 0.5 * sign(p) * MaxWeight | |||
where sign(p) is -1 if p < 0, and +1 otherwise, and MaxWeight is | |||
specified in a configuration line. MaxWeight is greater than or | |||
equal to zero. If MaxWeight isn't specified in the configuration | |||
file, then the GBUdb results don't affect the SpamAssassin score. | |||
To specify which emails to process, use a line similar to: | |||
full SNF4SA eval:snf4sa_sacheck() | |||
The above line specifies that all emails be processed. Please see the | |||
SpamAssassin documentation for other options. | |||
To specify the relationship between the SNFServer results and the | |||
SpamAssassin score, enter zero or more lines with the format: | |||
snf_result NN sa_score S short_circuit_[yes|no] | |||
where NN specifies the SNFServer result, and S is the SpamAssassin | |||
score for that SNFServer result. [yes|no] is "yes" if further | |||
scanning should be skipped if SNFServer returns the result specified | |||
by NN, or "no" if further scanning should not be skipped. NN can be a | |||
combination of a series of one or more integers, and a range of | |||
integers specified by N-M, where N and M are integers. The | |||
"short_circuit_[yes|no]" is optional, and the default value for | |||
[yes|no] is "no" (which specifies that SpamAssasin continue scanning). | |||
NOTE: There must not be any space when specifying a range of integers. | |||
For example, specify "34-43" rather than the incorrect "34 - 43". | |||
For example: | |||
snf_result 63 sa_score 2.5 short_circuit_no | |||
causes the plugin to add 2.5 to the SpamAssassin score if SNFServer | |||
returns 63 (which in the default SNFServer configuration corresponds | |||
to "caution"). | |||
Another example: | |||
snf_result 45 47-62 sa_score 5.0 short_circuit_yes | |||
causes the plugin to add 5.0 to the SpamAssassin score and stop | |||
further processing if SNFServer returns 45 or 47 thru 62. | |||
Final example: | |||
snf_result 1 sa_score -5.0 | |||
causes the plugin to subtract 5.0 from the SpamAssassin score. | |||
SpamAssassin continues to process the email. | |||
If SNFServer returns a result that isn't specified, then the plugin | |||
adds zero to the SpamAssassin score. | |||
The following line specifies the MaxWeight parameter: | |||
GBUdb_max_weight MaxWeight | |||
where MaxWeight is the value to specify. For example, | |||
GBUdb_max_weight 3.0 | |||
specifies a MaxWeight value of 3.0. | |||
Debugging the configuration | |||
--------------------------- | |||
The configuration can be tested by running | |||
spamassassin --lint | |||
This outputs a message if any line in in the configuration file cannot | |||
be parsed, along with the offending line. | |||
In order to obtain more detailed information, run | |||
spamassassin -D --lint | |||
This command outputs information about why a line could not be parsed. | |||
The output includes a great deal of other debugging information; you | |||
can filter the information relevant to this plugin like this: | |||
spamassassin -D --lint 2>&1 | grep snf4sa |
@@ -0,0 +1,20 @@ | |||
## Process this file with automake to produce Makefile.in | |||
## | |||
## $Id: Makefile.am,v 1.2 2007/05/29 19:06:09 adeniz Exp $ | |||
## | |||
## automake input for the ARM Research Labs SNF4SA distribution | |||
## (top directory). | |||
## | |||
## Author: Alban Deniz | |||
## | |||
## Copyright (C) 2009 ARM Research Labs, LLC. | |||
## See www.armresearch.com for the copyright terms. | |||
## | |||
EXTRA_DIST = \ | |||
Makefile.am \ | |||
configure.ac \ | |||
README \ | |||
INSTALL \ | |||
snf4sa.cf \ | |||
snf4sa.pm |
@@ -0,0 +1,43 @@ | |||
SpamAssassin SNF4SA Plugin for SNFServer | |||
README file | |||
Copyright (C) 2009 ARM Research Labs, LLC. | |||
See www.armresearch.com for the copyright terms. | |||
This directory contains the SpamAssassin plugin for SNFServer. | |||
The plugin implements a rule that checks the email message with | |||
SNFServer. | |||
If SNFServer determines that the email message is spam, then | |||
SpamAssassin increments the score by an amount that depends on the | |||
SNFServer result. The amount to add for each SNFServer result is | |||
specified in the configuration file. | |||
The GBUdb scan result also changes the score by: | |||
abs(p * c) ^ 0.5 * sign(p) * MaxWeight | |||
where p is the probability and c is the confidence returned by the | |||
GBUdb scan, sign(p) is -1 if p < 0 and +1 otherwise, and MaxWeight is | |||
specified in the configuration file. If SNFServer is not configured | |||
to insert the GBUdb scan results into a header in the message, or | |||
MaxWeight is not specified in the configuration file, then the | |||
SpamAssassin score is not affected by the GBUdb scan results. | |||
In addition to scanning the message, the plugin inserts headers into | |||
the email. The SNFServer must be configured to insert the headers | |||
into the email message. The following headers are copied by the | |||
plugin into the message if SNFServer is configured to generate them: | |||
1) 'X-SPAM-MessageSniffer-Scan-Result' contains the body of the | |||
X-MessageSniffer-Scan-Result header inserted by SNFServer. | |||
2) 'X-SPAM-MessageSniffer-Rules' contains the body of the | |||
X-MessageSniffer-Rules header inserted by SNFServer. | |||
3) 'X-SPAM-GBUdb-Analysis' contains the body of the X-GBUdb-Analysis | |||
header inserted by SNFServer. | |||
Please see the INSTALL file for installation and configuration. |
@@ -0,0 +1,15 @@ | |||
#!/bin/sh | |||
# | |||
# Script to clean the developer distribution. | |||
# | |||
# This script removes all files that can be created. After running | |||
# this script, you'd need to run 'autoreconf --install' before | |||
# running './configure'. | |||
# | |||
# Copyright (C) 2009 ARM Research Labs, LLC | |||
# | |||
############################################################################## | |||
make distclean | |||
find . -name '*~' -exec rm {} \; | |||
find . -name Makefile.in -exec rm {} \; | |||
rm -rf config autom4te.cache configure config.h* install-sh missing aclocal.m4 snf4sa-*gz |
@@ -0,0 +1,20 @@ | |||
dnl | |||
dnl Process this file with autoconf to produce a configure script. | |||
dnl | |||
dnl $Id: configure.in,v 1.33 2008/02/08 15:10:17 adeniz Exp $ | |||
dnl | |||
dnl autoconf input for the MicroNeil SNF4SA distribution. | |||
dnl | |||
dnl Author: Alban Deniz | |||
dnl | |||
dnl Copyright (C) 2009 by MicroNeil Corporation. All rights reserved. | |||
dnl See www.armresearch.com for the copyright terms. | |||
dnl | |||
dnl | |||
AC_PREREQ(2.52) | |||
AC_INIT(snf4sa, 0.9.2) | |||
AC_CONFIG_SRCDIR(snf4sa.cf) | |||
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) | |||
AC_OUTPUT([Makefile]) |
@@ -0,0 +1,40 @@ | |||
# | |||
# SpamAssassin SNF4SA Plugin for SNFServer configuration. | |||
# | |||
# Copyright (C) 2009 ARM Research Labs, LLC. | |||
# | |||
# snf4sa.cf | |||
# | |||
#snf4sa.cf | |||
# Name of plugin. | |||
loadplugin Snf4sa snf4sa.pm | |||
#################################################################### | |||
# Modify the following to suit your installation. | |||
#################################################################### | |||
describe SNF4SA Message Sniffer | |||
# Default configuration. | |||
GBUdb_max_weight 3.0 | |||
snf_result 1 sa_score -5.0 short_circuit_no | |||
snf_result 20 sa_score 6.0 short_circuit_yes | |||
snf_result 40 sa_score 2.5 short_circuit_no | |||
snf_result 47-62 sa_score 4.0 short_circuit_no | |||
snf_result 63 sa_score 3.5 short_circuit_no | |||
#################################################################### | |||
# Do not modify anything below this line. | |||
#################################################################### | |||
# Name of rule. | |||
full SNF4SA eval:snf4sa_sacheck() | |||
# Header line containing the results from SNFServer. | |||
add_header all SNF-Result _SNFRESULTTAG_ | |||
add_header all MessageSniffer-Scan-Result _SNFMESSAGESNIFFERSCANRESULT_ | |||
add_header all MessageSniffer-Rules _SNFMESSAGESNIFFERRULES_ | |||
add_header all GBUdb-Analysis _SNFGBUDBANALYSIS_ |
@@ -0,0 +1,726 @@ | |||
# | |||
# SpamAssassin SNF4SA Plugin for SNFServer. | |||
# | |||
# This plugin implements a SpamAssassin rule to use SNFServer to test | |||
# whether an email is spam. | |||
# | |||
# Copyright (C) 2009 ARM Research Labs, LLC. | |||
# | |||
# snf4sa.pm | |||
# | |||
# The plugin implements a single evaluation rule, which passes the | |||
# email message through SNFServer. The communication with SNFServer | |||
# is through XCI and a temporary file on disk which contains the email | |||
# message truncated to the frist 64K bytes. | |||
# | |||
package Snf4sa; | |||
use strict; | |||
use Mail::SpamAssassin; | |||
use Mail::SpamAssassin::Plugin; | |||
use Mail::SpamAssassin::PerMsgStatus; | |||
use Mail::SpamAssassin::Logger; | |||
use IO::Socket; | |||
use IO::File; | |||
use File::Temp qw/ tempfile tempdir /; | |||
our @ISA = qw(Mail::SpamAssassin::Plugin); | |||
# Convenience variables and pseudo-constants | |||
my $CRLF = "\x0d\x0a"; | |||
# translation table for SNF rule codes | |||
my $rule_code_xlat = { | |||
0 => 'Standard White Rules', | |||
20 => 'GBUdb Truncate (superblack)', | |||
40 => 'GBUdb Caution (suspicious)', | |||
47 => 'Travel', | |||
48 => 'Insurance', | |||
49 => 'Antivirus Push', | |||
50 => 'Media Theft', | |||
51 => 'Spamware', | |||
52 => 'Snake Oil', | |||
53 => 'Scam Patterns', | |||
54 => 'Porn/Adult', | |||
55 => 'Malware & Scumware Greetings', | |||
56 => 'Ink & Toner', | |||
57 => 'Get Rich', | |||
58 => 'Debt & Credit', | |||
59 => 'Casinos & Gambling', | |||
60 => 'Ungrouped Black Rules', | |||
61 => 'Experimental Abstract', | |||
62 => 'Obfuscation Techniques', | |||
63 => 'Experimental Received [ip]', | |||
}; | |||
sub new { | |||
my ($class, $mailsa) = @_; | |||
$class = ref($class) || $class; | |||
my $self = $class->SUPER::new($mailsa); | |||
bless ($self, $class); | |||
# Name of evaluation rule. | |||
$self->register_eval_rule ("snf4sa_sacheck"); | |||
# Use localhost. | |||
$self->{SNF_Host} = "localhost"; | |||
# Use default port. | |||
$self->{SNF_Port} = 9001; | |||
# Timeout. | |||
$self->{SNF_Timeout} = 1; | |||
# Directory for files containing emails read by SNFServer. | |||
$self->{Temp_Dir} = '/tmp/snf4sa'; | |||
# Maximum email message size (including headers). | |||
$self->{SNF_MaxTempFileSize} = 64 * 1024; | |||
# Key for confidence in mail header inserted by SNFServer. | |||
$self->{GBUdb_ConfidenceKey} = "c="; | |||
# Key for probability in mail header inserted by SNFServer. | |||
$self->{GBUdb_ProbabilityKey} = "p="; | |||
# Key for GBUdb maximum weight in the configuration file. | |||
$self->{GBUdb_MaxWeightKey} = "gbudb_max_weight"; | |||
# Key for SNFServer code in configuration file. | |||
$self->{SNF_CodeKey} = "snf_result"; | |||
# Key for SA score increment in configuration file. | |||
$self->{SA_DeltaScoreKey} = "sa_score"; | |||
# Key for short circuit in configuration file. | |||
$self->{SA_ShortCircuitYesKey} = "short_circuit_yes"; | |||
# Key for no short circuit in configuration file. | |||
$self->{SA_ShortCircuitNoKey} = "short_circuit_no"; | |||
return $self; | |||
} | |||
# DEBUG/TEST. | |||
#sub extract_metadata { | |||
# | |||
# my ($self, $opts) = @_; | |||
# | |||
# print "***********************\n"; | |||
# print "extract_metadata called\n"; | |||
# print "***********************\n"; | |||
# | |||
# $opts->{msg}->put_metadata("X-Extract-Metadata:", "Test header"); | |||
# | |||
#} | |||
# END OF DEBUG/TEST. | |||
sub have_shortcircuited { | |||
my ($self, $options) = @_; | |||
if (defined($options->{permsgstatus}->{shortCircuit})) { | |||
return $options->{permsgstatus}->{shortCircuit}; | |||
} | |||
return 0; | |||
} | |||
sub parse_config { | |||
my ($self, $options) = @_; | |||
# DEBUG. | |||
#print "parse_confg. key: $options->{key}\n"; | |||
#print "parse_config. line: $options->{line}\n"; | |||
#print "parse_config. value: $options->{value}\n"; | |||
#END OF DEBUG. | |||
# Process GBUdb_max_weight. | |||
if (lc($options->{key}) eq $self->{GBUdb_MaxWeightKey}) { | |||
# GBUdb maximum weight. | |||
my $tempValue = $options->{value}; | |||
# Test that the value was a number. | |||
#$self->log_debug("Found $self->{GBUdb_MaxWeightKey} . " value: $options->{value}, tempValue: $tempValue\n"; # DEBUG. | |||
if ($tempValue =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/) { | |||
# Value was a number. Load and return success. | |||
$options->{conf}->{gbuDbMaxWeight} = $tempValue; | |||
$self->inhibit_further_callbacks(); | |||
return 1; | |||
} else { | |||
$self->log_debug("Invalid value for $self->{GBUdb_MaxWeightKey} " . | |||
$tempValue); | |||
} | |||
} elsif (lc($options->{key}) eq $self->{SNF_CodeKey}) { | |||
# Relationship between SNFServer code and SA score delta. | |||
my $snf = $self->parse_snf_sa_mapping($options); | |||
if (defined($snf)) { | |||
my @snfCode = @{$snf->{snfCode}}; | |||
#print "snf->{snfCode}: @snfCode\n"; # DEBUG. | |||
#print "snf->{deltaScore}: $snf->{deltaScore}\n"; # DEBUG. | |||
#print "snf->{shortCircuit}: $snf->{shortCircuit}\n"; # DEBUG. | |||
# Save configuration. | |||
foreach my $i (@{$snf->{snfCode}}) { | |||
# Create (or update) an element in the mapping array | |||
# that snfSaMapping is a reference to. | |||
$options->{conf}->{snfSaMapping}->[$i] = { | |||
deltaScore => $snf->{deltaScore}, | |||
shortCircuit => $snf->{shortCircuit} | |||
}; | |||
} | |||
# DEBUG. | |||
#for (my $i = 0; $i < @{$options->{conf}->{snfSaMapping}}; $i++) { | |||
# if (! defined($options->{conf}->{snfSaMapping}->[$i])) { | |||
# print "No configuration for SNFServer code $i\n"; | |||
# next; | |||
# } | |||
# print "SNFServer code: $i, " . | |||
# "deltaScore: " . | |||
# "$options->{conf}->{snfSaMapping}->[$i]->{deltaScore}, " . | |||
# "shortCircuit: " . | |||
# "$options->{conf}->{snfSaMapping}->[$i]->{shortCircuit}\n"; | |||
#} | |||
# END OF DEBUG. | |||
# Successfully parsed. | |||
$self->inhibit_further_callbacks(); | |||
return 1; | |||
} | |||
} | |||
# Wasn't handled. | |||
return 0; | |||
} | |||
# Parse a snf_result configuration line. | |||
# | |||
# Input-- | |||
# | |||
# $line--String containing the snf_result line without the first word. | |||
# | |||
# Returns a reference with the following fields (if no error)-- | |||
# | |||
# snfCode--Array of SNFServer result codes that this configuration | |||
# line specifies. | |||
# | |||
# deltaScore--SA score increment for the codes in @snfCode. | |||
# | |||
# shortCircuit--True if a SNFServer code in @snfCode is to | |||
# short-circuit the message scan, false otherwise. | |||
# | |||
# If the line cannot be parsed, the return value is undef. | |||
# | |||
sub parse_snf_sa_mapping | |||
{ | |||
my ($self, $options) = @_; | |||
my $value = $options->{value}; | |||
my $ret_hash = { | |||
snfCode => undef, | |||
deltaScore => undef, | |||
shortCircuit => undef | |||
}; | |||
# SNFServer codes found. | |||
my @snfCode = (); | |||
# Remove leading and trailing whitespace. | |||
$value =~ s/^\s+//; | |||
$value =~ s/\s+$//; | |||
# Convert to lower case. | |||
$value = lc($value); | |||
# Split up by white space. | |||
my @specVal = split(/\s+/, $value); | |||
if (0 == @specVal) { | |||
# No separate words. | |||
$self->log_debug("No separate words found in configuration line '" . | |||
$options->{line} . "'"); | |||
return undef; | |||
} | |||
# Convert each SNFServer result specification into an integer. | |||
my $lastSpec; | |||
for ($lastSpec = 0; $lastSpec < @specVal; $lastSpec++) { | |||
# Check for next keyword. | |||
if ($specVal[$lastSpec] eq $self->{SA_DeltaScoreKey}) { | |||
# We've completed the processing of the SNFServer result | |||
# codes. | |||
last; | |||
} | |||
# Get the code values. | |||
my @codeVal = $self->get_code_values($specVal[$lastSpec]); | |||
if (0 == @codeVal) { | |||
# No code values were obtained. | |||
$self->log_debug("Couldn't parse all the SNFServer code values " . | |||
"in configuration line '" . | |||
$options->{line} . "'"); | |||
return undef; | |||
} | |||
# Add to the list of codes. | |||
@snfCode = (@snfCode, @codeVal); | |||
} | |||
# Sort the SNFServer result codes and remove duplicates. | |||
@snfCode = sort { $a <=> $b } @snfCode; | |||
my $prev = -1; | |||
my @temp = grep($_ != $prev && ($prev = $_), @snfCode); | |||
$ret_hash->{snfCode} = \@temp; | |||
# The $specVal[$lastSpec] is $self->{SA_DeltaScoreKey}. Return if | |||
# there aren't enough parameters. | |||
$lastSpec++; | |||
if ($lastSpec >= @specVal) { | |||
# Not enough parameters. | |||
$self->log_debug("Not enough parameters in configuration line '" . | |||
$options->{line} . "'"); | |||
return undef; | |||
} | |||
# Extract the SA delta score. | |||
$ret_hash->{deltaScore} = $specVal[$lastSpec]; | |||
if (!($ret_hash->{deltaScore} =~ | |||
/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)) { | |||
# SA delta score isn't a number. | |||
$self->log_debug("Value after '" . $self->{SA_DeltaScoreKey} . | |||
"' ($specVal[$lastSpec]) must be a number " . | |||
"in configuration line '" . | |||
$options->{line} . "'"); | |||
return undef; | |||
} | |||
# Get short circuit spec. | |||
$lastSpec++; | |||
$ret_hash->{shortCircuit} = 0; | |||
if ( ($lastSpec + 1) == @specVal) { | |||
# A parameter was specified. | |||
my $shortCircuitSpec = $specVal[$lastSpec]; | |||
if ($self->{SA_ShortCircuitYesKey} eq $shortCircuitSpec) { | |||
# Specified short-circuit evaluation. | |||
$ret_hash->{shortCircuit} = 1; | |||
} elsif ($self->{SA_ShortCircuitNoKey} ne $shortCircuitSpec) { | |||
# Invalid short-circuit specification. | |||
$self->log_debug("Invalid short-circuit specification: '" . | |||
$specVal[$lastSpec] . | |||
"' in configuration line '" . $options->{line} . | |||
"'. Must be '$self->{SA_ShortCircuitYesKey}' " . | |||
" or '$self->{SA_ShortCircuitNoKey}'."); | |||
return undef; | |||
} | |||
} elsif ($lastSpec != @specVal) { | |||
# Too many parameters were specified. | |||
$self->log_debug("Too many parameters were specified in " . | |||
"configuration line '" . $options->{line} . "'"); | |||
return undef; | |||
} | |||
return $ret_hash; | |||
} | |||
sub get_code_values | |||
{ | |||
my ($self, $specElement) = @_; | |||
my @snfCode = (); | |||
# Split the specification. | |||
my @codeVal = split(/-/, $specElement); | |||
#$self->log_debug("snf4sa: get_code_values. specElement: $specElement. codeVal: @codeVal"); # DEBUG | |||
if (1 == @codeVal) { | |||
if ($specElement =~ /^\d+$/) { | |||
# Found a single code. | |||
$snfCode[0] = 1 * $specElement; | |||
} | |||
} elsif (2 == @codeVal) { | |||
# Check range. | |||
if ( ($codeVal[0] =~ /^\d+$/) && ($codeVal[1] =~ /^\d+$/) ) { | |||
# Found a range of codes. | |||
$codeVal[0] = 1 * $codeVal[0]; | |||
$codeVal[1] = 1 * $codeVal[1]; | |||
if ($codeVal[0] <= $codeVal[1]) { | |||
# Add these SNF codes. | |||
for (my $i = $codeVal[0]; $i <= $codeVal[1]; $i++) { | |||
push(@snfCode, $i); | |||
} | |||
} | |||
} | |||
} | |||
return @snfCode; | |||
} | |||
# Output a debug message. | |||
# | |||
# Input-- | |||
# | |||
# $message--String containing the message to output. | |||
# | |||
sub log_debug | |||
{ | |||
my ($self, $message) = @_; | |||
dbg("snf4sa: $message"); | |||
} | |||
# Check the message with SNFServer. | |||
sub snf4sa_sacheck { | |||
my ($self, $permsgstatus, $fulltext) = @_; | |||
my $response =''; | |||
my $exitvalue; | |||
# Make sure we have a temp dir | |||
unless(-d $self->{Temp_Dir}) { | |||
mkdir($self->{Temp_Dir}); | |||
chmod(0777, $self->{Temp_Dir}); | |||
}; | |||
# Truncate the message. | |||
my $mailtext = substr( ${$fulltext}, 0, $self->{SNF_MaxTempFileSize}); | |||
# create our temp file, $filename will contain the full path | |||
my ($fh, $filename) = tempfile( DIR => $self->{Temp_Dir} ); | |||
# spew our mail into the temp file | |||
my $SNF_fh = IO::File->new( $filename, "w" ) || | |||
die(__PACKAGE__ . ": Unable to create temporary file '" . $filename . "'"); | |||
$SNF_fh->print($mailtext) || | |||
$self->cleanup_die($filename, | |||
__PACKAGE__ . ": Unable to write to temporary file '" . | |||
$filename . "'"); | |||
$SNF_fh->close || | |||
$self->cleanup_die($filename, | |||
__PACKAGE__ . ": Unable to close temporary file '" . | |||
$filename . "'"); | |||
# Change permissions. | |||
my $cnt = chmod(0666, $filename) || | |||
$self->cleanup_die($filename, __PACKAGE__ . | |||
": Unable to change permissions of temporary file '" . | |||
$filename . "'"); | |||
# xci_scan connects to SNFServer with XCI to scan the message | |||
my $SNF_XCI_Return = $self->xci_scan( $filename ); | |||
#print "header:\n\n$SNF_XCI_Return->{header}\n\n"; # DEBUG | |||
# Remove the temp file, we are done with it. | |||
unlink($filename); | |||
# Check response from SNFServer. | |||
if (! $SNF_XCI_Return ) { | |||
die(__PACKAGE__ . ": Internal error"); | |||
} | |||
# Check for success. | |||
if (! $SNF_XCI_Return->{"success"}) { | |||
die(__PACKAGE__ . ": Error from SNFServer: " . | |||
$SNF_XCI_Return->{"message"}); | |||
} | |||
# get the return code and translation | |||
my ( $rc, $rcx ) = ( $SNF_XCI_Return->{"code"}, | |||
$rule_code_xlat->{ $SNF_XCI_Return->{"code"} } ); | |||
$rc = -1 unless defined $rc; # default values | |||
$rcx = 'Unknown' unless $rcx; | |||
my $rch = $SNF_XCI_Return->{"header"}; # the SNF header(s) | |||
# Initialize the change in the SA score. | |||
my $deltaScore = 0.0; | |||
# Add the score from the SNFServer return. | |||
if (defined($permsgstatus->{main}->{conf}->{snfSaMapping}->[$rc])) { | |||
$deltaScore += | |||
$permsgstatus->{main}->{conf}->{snfSaMapping}->[$rc]->{deltaScore}; | |||
$permsgstatus->{shortCircuit} = | |||
$permsgstatus->{main}->{conf}->{snfSaMapping}->[$rc]->{shortCircuit}; | |||
} | |||
# Perform GBUdb processing. | |||
if (defined($permsgstatus->{main}->{conf}->{gbuDbMaxWeight})) { | |||
#print "gbudbMaxWeight: $permsgstatus->{main}->{conf}->{gbuDbMaxWeight}\n\n"; # DEBUG. | |||
# Calculate the contribution to the scrore from the GBUdb results. | |||
$deltaScore += | |||
$self->calc_GBUdb($SNF_XCI_Return->{header}, | |||
$permsgstatus->{main}->{conf}->{gbuDbMaxWeight}); | |||
} | |||
# Add the headers. | |||
$permsgstatus->set_tag("SNFRESULTTAG", "$rc ($rcx)"); | |||
$permsgstatus->set_tag("SNFMESSAGESNIFFERSCANRESULT", | |||
$self->extract_header_body($SNF_XCI_Return->{header}, | |||
"X-MessageSniffer-Scan-Result")); | |||
$permsgstatus->set_tag("SNFMESSAGESNIFFERRULES", | |||
$self->extract_header_body($SNF_XCI_Return->{header}, | |||
"X-MessageSniffer-Rules")); | |||
$permsgstatus->set_tag("SNFGBUDBANALYSIS", | |||
$self->extract_header_body($SNF_XCI_Return->{header}, | |||
"X-GBUdb-Analysis")); | |||
# Submit the score. | |||
if ($deltaScore) { | |||
$permsgstatus->got_hit("SNF4SA", "", score => $deltaScore); | |||
for my $set (0..3) { | |||
$permsgstatus->{conf}->{scoreset}->[$set]->{"SNF4SA"} = | |||
sprintf("%0.3f", $deltaScore); | |||
} | |||
} | |||
# Always return zero, since the score was submitted via got_hit() | |||
# above. | |||
return 0; | |||
} | |||
# Calculate the contribution of the GBUdb scan to the SA score. | |||
# | |||
# Input-- | |||
# | |||
# $headers--String containing the headers. | |||
# | |||
# $weight--Weight used to calculate the contribution. | |||
# | |||
# Returns the contribution to the SA score (float). | |||
# | |||
sub calc_GBUdb | |||
{ | |||
my ( $self, $headers, $weight ) = @_; | |||
# Split the header into lines. | |||
my @headerLine = split(/\n/, $headers); | |||
# Find the line containing the GBUdb results. | |||
my $line; | |||
foreach $line (@headerLine) { | |||
# Search for the tag. | |||
if ($line =~ /^X-GBUdb-Analysis:/) { | |||
# GBUdb analysis was done. Extract the values. | |||
my $ind0 = index($line, $self->{GBUdb_ConfidenceKey}); | |||
my $ind1 = index($line, " ", $ind0 + 2); | |||
if (-1 == $ind0) { | |||
return 0.0; | |||
} | |||
my $c = 1.0 * substr($line, $ind0 + 2, $ind1 - $ind0 - 2); | |||
#print "calc_GBUdb. line: $line\n"; # DEBUG | |||
#print "calc_GBUdb. c: $c, ind0: $ind0, ind1: $ind1\n"; # DEBUG | |||
$ind0 = index($line, $self->{GBUdb_ProbabilityKey}); | |||
$ind1 = index($line, " ", $ind0 + 2); | |||
if (-1 == $ind0) { | |||
return 0.0; | |||
} | |||
my $p = 1.0 * substr($line, $ind0 + 2, $ind1 - $ind0 - 2); | |||
#print "calc_GBUdb. p: $p, ind0: $ind0, ind1: $ind1\n"; # DEBUG | |||
# Calculate and return the score. | |||
my $score = abs($p * $c) ** 0.5; | |||
$score *= $weight; | |||
if ($p < 0.0) { | |||
$score *= -1.0; | |||
} | |||
# DEBUG. | |||
#print "calc_GBUdb. p: $p, c: $c, weight: $weight\n"; | |||
#print "calc_GBUdb. score: $score\n"; | |||
# END OF DEBUG. | |||
return $score; | |||
} | |||
} | |||
} | |||
# Extract the specified header body from a string containing all the | |||
# headers. | |||
# | |||
# Input-- | |||
# | |||
# $headers--String containing the headers. | |||
# | |||
# $head--String containing the head of the header to extract. | |||
# | |||
# Returns the body of the header. | |||
# | |||
sub extract_header_body | |||
{ | |||
my ( $self, $headers, $head ) = @_; | |||
my $body = ""; | |||
if ($headers =~ /$head:(.*)/s) { | |||
my $temp = $1; | |||
$temp =~ /(.*)\nX-(.*)/s; | |||
$body = $1; | |||
} | |||
return $body; | |||
} | |||
# xci_scan( $file ) | |||
# returns hashref: | |||
# success : true/false | |||
# code : response code from SNF | |||
# message : scalar message (if any) | |||
sub xci_scan | |||
{ | |||
my ( $self, $file ) = @_; | |||
return undef unless $self and $file; | |||
my $ret_hash = { | |||
success => undef, | |||
code => undef, | |||
message => undef, | |||
header => undef, | |||
xml => undef | |||
}; | |||
my $xci = $self->connect_socket( $self->{SNF_Host}, $self->{SNF_Port} ) | |||
or return $self->err_hash("cannot connect to socket ($!)"); | |||
$xci->print("<snf><xci><scanner><scan file='$file' xhdr='yes' /></scanner></xci></snf>\n"); | |||
my $rc = $ret_hash->{xml} = $self->socket_response($xci, $file); | |||
$xci->close; | |||
if ( $rc =~ /^<snf><xci><scanner><result code='(\d*)'>/ ) { | |||
$ret_hash->{success} = 1; | |||
$ret_hash->{code} = $1; | |||
$rc =~ /<xhdr>(.*)<\/xhdr>/s and $ret_hash->{header} = $1; | |||
} elsif ( $rc =~ /^<snf><xci><error message='(.*)'/ ) { | |||
$ret_hash->{message} = $1; | |||
} else { | |||
$ret_hash->{message} = "unknown XCI response: $rc"; | |||
} | |||
return $ret_hash; | |||
} | |||
# connect_socket( $host, $port ) | |||
# returns IO::Socket handle | |||
sub connect_socket | |||
{ | |||
my ( $self, $host, $port ) = @_; | |||
return undef unless $self and $host and $port; | |||
my $protoname = 'tcp'; # Proto should default to tcp but it's not expensive to specify | |||
$self->{XCI_Socket} = IO::Socket::INET->new( | |||
PeerAddr => $host, | |||
PeerPort => $port, | |||
Proto => $protoname, | |||
Timeout => $self->{SNF_Timeout} ) or return undef; | |||
$self->{XCI_Socket}->autoflush(1); # make sure autoflush is on -- legacy | |||
return $self->{XCI_Socket}; # return the socket handle | |||
} | |||
# socket_response( $socket_handle ) | |||
# returns scalar string | |||
sub socket_response | |||
{ | |||
my ( $self, $rs, $file ) = @_; | |||
my $buf = ''; # buffer for response | |||
# blocking timeout for servers who accept but don't answer | |||
eval { | |||
local $SIG{ALRM} = sub { die "timeout\n" }; # set up the interrupt | |||
alarm $self->{SNF_Timeout}; # set up the alarm | |||
while (<$rs>) { # read the socket | |||
$buf .= $_; | |||
} | |||
alarm 0; # reset the alarm | |||
}; | |||
# report a blocking timeout | |||
if ( $@ eq "timeout\n" ) { | |||
$self->cleanup_die($file, | |||
__PACKAGE__ . ": Timeout waiting for response from SNFServer"); | |||
} elsif ( $@ =~ /alarm.*unimplemented/ ) { # no signals on Win32 | |||
while (<$rs>) { # get whatever's left | |||
# in the socket. | |||
$buf .= $_; | |||
} | |||
} | |||
return $buf; | |||
} | |||
# return an error message for xci_scan | |||
sub err_hash | |||
{ | |||
my ( $self, $message ) = @_; | |||
return { | |||
success => undef, | |||
code => undef, | |||
message => $message | |||
}; | |||
} | |||
sub cleanup_die | |||
{ | |||
my ( $self, $file, $message ) = @_; | |||
unlink($file); | |||
die($message); | |||
} | |||
1; |
@@ -0,0 +1,27 @@ | |||
## Process this file with automake to produce Makefile.in | |||
## | |||
## $Id$ | |||
## | |||
## automake input for the MicroNeil SNFServer application (SNFServer directory). | |||
## | |||
## Author: Alban Deniz | |||
## | |||
## Copyright (C) 2008 ARM Research Labs, LLC. | |||
## See www.armresearch.com for the copyright terms. | |||
## | |||
## | |||
LIBS = @SNF_LIBS@ -L../SNFMulti -L../CodeDweller -lSNFMulti -lCodeDweller @LIBS@ | |||
CXXFLAGS = $(SNF_CXXFLAGS) -I@top_srcdir@/SNFMulti -I@top_srcdir@/CodeDweller | |||
sbin_PROGRAMS = \ | |||
SNFServer | |||
SNFServer_SOURCES = \ | |||
@top_srcdir@/SNFServer/main.cpp | |||
EXTRA_DIST = \ | |||
Makefile.am | |||
clean-local: | |||
rm -f *.gcno *.gcov *.gcda *~ $(CONFDATA) |
@@ -0,0 +1,192 @@ | |||
#include <sys/types.h> | |||
#include <sys/stat.h> | |||
#include <ctime> | |||
#include <cstring> | |||
#include <iostream> | |||
#include <iomanip> | |||
#include <fstream> | |||
#include <sstream> | |||
#include <string> | |||
#include <queue> | |||
#include <cmath> | |||
#include <exception> | |||
#include <stdexcept> | |||
#include "unistd.h" | |||
#include "timing.hpp" | |||
#include "threading.hpp" | |||
#include "networking.hpp" | |||
#include "SNFMulti.hpp" | |||
#include "snf_xci.hpp" | |||
#include "snf_sync.hpp" | |||
#include "config.h" | |||
// temporary - proving base64codec | |||
#include "base64codec.hpp" | |||
//#include "../nvwa-0.6/nvwa/debug_new.h" | |||
using namespace std; // Introduce standard namespace. | |||
const char* SERVER_VERSION_INFO = "SNF Server Version " PACKAGE_VERSION " Build: " __DATE__ " " __TIME__; | |||
static const string XCIShutdownResponse = | |||
"<snf><xci><server><response message=\'shutdown in progress\' code=\'0\'/></server></xci></snf>\n"; | |||
class XCIShutdownWatcher : public snfXCIServerCommandHandler { // Shutdown watcher. | |||
public: | |||
XCIShutdownWatcher():TimeToStop(false){} // Construct with shutdown flag false. | |||
bool TimeToStop; // Here is the flag. | |||
string processXCIRequest(snf_xci& X) { // Here is how we process requests. | |||
if(0 == X.xci_server_command.find("shutdown")) { // If we find shutdown then | |||
TimeToStop = true; // set the shutdown flag | |||
return XCIShutdownResponse; // and let them know we got it. | |||
} // If we get some other request | |||
return XCIErrorResponse; // return the error response. | |||
} | |||
}; | |||
// Thread Status Analysis For Debugging. | |||
void ThreadStatusToCout() { // Produce a thread status list. | |||
ThreadStatusReport R = Threads.StatusReport(); // Get a report from Threads. | |||
cout << endl; // Break the line. | |||
for( | |||
ThreadStatusReport::iterator iR = R.begin(); // Loop through the report. | |||
iR != R.end(); iR++ | |||
) { | |||
ThreadStatusRecord& S = (*iR); // Take each status report and | |||
cout // send it to cout on it's own line. | |||
<< S.getName() << " (" << S.getPointer() << "), " | |||
<< S.getType().Name << ", " | |||
<< S.getState().Name << ", " | |||
<< ((S.getRunning()) ? "Running, " : "Not Running, ") | |||
<< ((S.getBad()) ? "Broken, " : "Ok, ") | |||
<< S.getFault() | |||
<< endl; | |||
} | |||
cout << endl; // Leave a blank line at the end. | |||
} | |||
// Here in the main thread is where we get executive tasks done. | |||
int go(int argc, char* argv[]) { //// go() stands in for main(). main() catches any unhandled exceptions. | |||
// Check for debug mode. | |||
bool DebugMode = false; // This will be our debug mode. | |||
string argv0(argv[0]); // Capture how we were called. | |||
if( | |||
string::npos != argv0.find("Debug") || // If we find "Debug" or | |||
string::npos != argv0.find("debug") // "debug" in our command path | |||
) { // then we are in DebugMode. | |||
DebugMode = true; // Set the flag and tell the | |||
cout << "Debug Mode" << endl; // watchers. | |||
} | |||
// DebugMode = true; // Force it when needed. | |||
// Announce Version / Build Info. | |||
cout << SERVER_VERSION_INFO << endl; // Shout out our version. | |||
cout << SNF_ENGINE_VERSION << endl; // Shout out the engine version. | |||
// Sanity checks before we get going. | |||
if(2 != argc) { // Check the command line args. | |||
cout << "Use: SNFServer <path-to-config-file>" << endl; // If wrong, say how we work. | |||
return 0; | |||
} | |||
if(0 != access(argv[1], R_OK)) { // Check the config file path. | |||
cout << "Can't read " << argv[1] << endl; // If it's not accessible, punt. | |||
return 0; | |||
} | |||
cout << "Launching with " << argv[1] << endl; // Tell them we're going. | |||
snf_RulebaseHandler MyRulebase; // Create a rulebase manager. | |||
MyRulebase.PlatformVersion(SERVER_VERSION_INFO); // Set the Platform version string. | |||
XCIShutdownWatcher ShutdownWatcher; // Make a server shutdown processor | |||
MyRulebase.XCIServerCommandHandler(ShutdownWatcher); // and register it with the engine. | |||
MyRulebase.open(argv[1], "", ""); // Open a configured rulebase. | |||
Sleeper WaitATic(1000); // Learn to wait a second. | |||
cout << "Running." << endl << endl; // Tell them we're running. | |||
char Tic = '\\'; // Tic/Toc indicator. | |||
while(false == ShutdownWatcher.TimeToStop) { // While running, update the screen. | |||
WaitATic(); // One second between updates. | |||
// Animate the Tick/Toc Indicator | |||
switch(Tic) { | |||
case '\\': Tic = '|'; break; | |||
case '|': Tic = '/'; break; | |||
case '/': Tic = '-'; break; | |||
default: Tic = '\\'; break; | |||
} | |||
// Format and output the screen update. At the end post a \r so that | |||
// the line appears to update in place. | |||
cout | |||
<< "M/min: " << setw(4) << (int) MyRulebase.MyLOGmgr.MessagesPerMinute() << " " | |||
<< "SP: " << setw(6) << setprecision(2) << setiosflags(ios::fixed) << | |||
((0 < MyRulebase.MyLOGmgr.MessagesPerMinute()) ? | |||
(100 * MyRulebase.MyLOGmgr.SpamPerMinute() / MyRulebase.MyLOGmgr.MessagesPerMinute()) : 0.0) << "% " | |||
<< "LR:" << setw(7) << MyRulebase.MyLOGmgr.LatestRuleID() | |||
<< " [" | |||
<< MyRulebase.MyXCImgr.pollClientCount() << "/" | |||
<< MyRulebase.MyXCImgr.pollLoopCount() << " " | |||
<< Tic << " " << (int) MyRulebase.MyXCImgr.TotalQueue() << "] " | |||
<< "W:" << (int) MyRulebase.MyLOGmgr.WhitePerMinute() << " " | |||
<< "C:" << (int) MyRulebase.MyLOGmgr.CautionPerMinute() << " " | |||
<< "B:" << (int) MyRulebase.MyLOGmgr.BlackPerMinute() << " " | |||
<< "T:" << (int) MyRulebase.MyLOGmgr.TruncatePerMinute() << " " | |||
<< "S:" << (int) MyRulebase.MyLOGmgr.SamplePerMinute() | |||
<< " \r" << flush; | |||
if(DebugMode) ThreadStatusToCout(); // Debug? Show Thread Status Report. | |||
} | |||
cout << endl << endl << "Shutdown Received." << endl; | |||
// When this loop fails it is time to shut down. | |||
// All the rest happens via XCI now. | |||
cout << "Closing Rulebase Handler..." << endl; | |||
MyRulebase.close(); | |||
// All done... | |||
cout << "Bye bye." << endl; | |||
return 0; | |||
} | |||
/* | |||
class DebugExceptionHandler { // Hand wrapper for exception handler. | |||
public: | |||
DebugExceptionHandler() { | |||
LoadLibrary("exchndl.dll"); | |||
} | |||
}; | |||
static DebugExceptionHandler TheDebugExceptionHandler; // Global exception handler. | |||
*/ | |||
int main(int argc, char* argv[]) { | |||
try { | |||
go(argc, argv); | |||
} | |||
catch(exception& e) { | |||
cout << "Unhandled Exception: " << e.what() << " Thrown!" << endl; | |||
} | |||
catch(...) { | |||
cout << "Unknown, Unhandled Exception Discovered!" << endl; | |||
} | |||
return 0; | |||
} | |||
@@ -0,0 +1,97 @@ | |||
## Process this file with automake to produce Makefile.in | |||
## | |||
## $Id: Makefile.am,v 1.30 2007/10/26 17:50:49 adeniz Exp $ | |||
## | |||
## automake input for the ARM Research SNFServer scripts. | |||
## | |||
## Author: Alban Deniz | |||
## | |||
## Copyright (C) 2008 ARM Research Labs, LLC. | |||
## See www.armresearch.com for the copyright terms. | |||
## | |||
sbin_SCRIPTS = \ | |||
getRulebase.sample \ | |||
snfSniffer.sample \ | |||
snfSnifferFilter.sample \ | |||
snfscan-standalone.sample | |||
rcexec_SCRIPTS = \ | |||
snf-server | |||
if OpenBSD | |||
snf-server.in: snf-server.openbsd Makefile | |||
cp @top_srcdir@/Scripts/snf-server.openbsd snf-server.in | |||
chmod +x $@ | |||
rcexecdir = @sbindir@ | |||
else | |||
if FreeBSD | |||
snf-server.in: snf-server.freebsd Makefile | |||
cp @top_srcdir@/Scripts/snf-server.freebsd snf-server.in | |||
chmod +x $@ | |||
rcexecdir = @sysconfdir@/rc.d | |||
else | |||
rcexecdir = @sysconfdir@/init.d | |||
endif | |||
endif | |||
if Ubuntu | |||
snf-server.in: snf-server.ubuntu Makefile | |||
cp @top_srcdir@/Scripts/snf-server.ubuntu snf-server.in | |||
chmod +x $@ | |||
endif | |||
if RedHat | |||
snf-server.in: snf-server.redhat Makefile | |||
cp @top_srcdir@/Scripts/snf-server.redhat snf-server.in | |||
chmod +x $@ | |||
endif | |||
if Suse | |||
snf-server.in: snf-server.suse Makefile | |||
cp @top_srcdir@/Scripts/snf-server.suse snf-server.in | |||
chmod +x $@ | |||
endif | |||
getRulebase.sample: getRulebase.in Makefile | |||
cat @top_srcdir@/Scripts/getRulebase.in | sed -e s+PREFIX+@prefix@+ -e s+PACKAGE_NAME+@PACKAGE_NAME@+ > $@ | |||
chmod +x $@ | |||
snf-server: snf-server.in Makefile | |||
cat @top_srcdir@/Scripts/snf-server.in | sed -e s+PREFIX+@prefix@+ -e s+CONFFILE+@sysconfdir@/@PACKAGE_NAME@/SNFServer.xml+ > $@ | |||
chmod +x $@ | |||
snfSniffer.sample: snfSniffer.in Makefile | |||
cat @top_srcdir@/Scripts/snfSniffer.in | sed -e s+DATADIR+@datadir@+ -e s+PREFIX+@prefix@+ -e s+PACKAGE_NAME+@PACKAGE_NAME@+ > $@ | |||
chmod +x $@ | |||
snfSnifferFilter.sample: snfSnifferFilter.in Makefile | |||
cat @top_srcdir@/Scripts/snfSnifferFilter.in | sed -e s+DATADIR+@datadir@+ -e s+PREFIX+@prefix@+ -e s+PACKAGE_NAME+@PACKAGE_NAME@+ > $@ | |||
chmod +x $@ | |||
snfscan-standalone.sample: snfscan-standalone.in Makefile | |||
cat @top_srcdir@/Scripts/snfscan-standalone.in | sed -e s+DATADIR+@datadir@+ -e s+PREFIX+@prefix@+ -e s+PACKAGE_NAME+@PACKAGE_NAME@+ > $@ | |||
chmod +x $@ | |||
pkgdata_DATA = \ | |||
junkmsg.txt \ | |||
cleanmsg.txt | |||
EXTRA_DIST = \ | |||
getRulebase.in \ | |||
snfSniffer.in \ | |||
snfSnifferFilter.in \ | |||
snfscan-standalone.in \ | |||
snf-server.openbsd \ | |||
snf-server.freebsd \ | |||
snf-server.redhat \ | |||
snf-server.ubuntu \ | |||
snf-server.suse \ | |||
$(pkgdata_DATA) | |||
clean-local: | |||
rm -f *.gcno *.gcov *.gcda *~ $(sbin_SCRIPTS) $(rcexec_SCRIPTS) snf-server.in |
@@ -0,0 +1,8 @@ | |||
From: test@domain.com | |||
To: test@domain.com | |||
Subject: This is a test message | |||
This is a plain message for testing the | |||
content_filter. | |||
@@ -0,0 +1,51 @@ | |||
#!/bin/sh | |||
# | |||
# Script to download a rulebase for SNFServer. | |||
# | |||
# Copyright (C) 2008 by MicroNeil Corporation. All rights reserved. | |||
## See www.armresearch.com for the copyright terms. | |||
# | |||
# | |||
# Replace authenticationxx and licensid with your license info. | |||
# | |||
SNIFFER_PATH=PREFIX/share/PACKAGE_NAME | |||
SNF2CHECK=PREFIX/sbin/SNF2Check | |||
AUTHENTICATION=authenticationxx | |||
LICENSE_ID=licenseid | |||
# | |||
# Do not modify anything below this line. | |||
# | |||
cd $SNIFFER_PATH | |||
if [ -e UpdateReady.txt ] && [ ! -e UpdateReady.lck ]; then | |||
# Uncomment the following line if more than one process might | |||
# launch this script. Leave it commented out if this script will | |||
# normally be run by the <update-script/> mechanism in SNFServer. | |||
# touch UpdateReady.lck | |||
curl http://www.sortmonster.net/Sniffer/Updates/$LICENSE_ID.snf --output $LICENSE_ID.new --compressed --user sniffer:ki11sp8m --remote-time --fail | |||
$SNF2CHECK $LICENSE_ID.new $AUTHENTICATION | |||
RETVAL=$? | |||
if [ $RETVAL -eq 0 ]; then | |||
if [ -e $LICENSE_ID.old ]; then rm -f $LICENSE_ID.old; fi | |||
if [ -e $LICENSE_ID.snf ]; then mv $LICENSE_ID.snf $LICENSE_ID.old; fi | |||
mv $LICENSE_ID.new $LICENSE_ID.snf | |||
if [ -e UpdateReady.txt ]; then rm -f UpdateReady.txt; fi | |||
if [ -e UpdateReady.lck ]; then rm -f UpdateReady.lck; fi | |||
else | |||
if [ -e $LICENSE_ID.new ]; then rm -f $LICENSE_ID.new; fi | |||
if [ -e UpdateReady.lck ]; then rm -f UpdateReady.lck; fi | |||
fi | |||
fi | |||
@@ -0,0 +1,51 @@ | |||
Received: from c-69-251-204-89.hsd1.md.comcast.net [69.251.204.89] (HELO c-69-251-204-89.hsd1.md.comcast.net) | |||
by inbound.appriver.com (CommuniGate Pro SMTP 5.1.5) | |||
with ESMTP id 488834279 for timarsh1@example.com; Mon, 17 Mar 2008 19:46:13 -0400 | |||
Message-ID: <000601c88888$04d58eff$9bb664a3@xytlg> | |||
From: =?koi8-r?B?8MnXztHL?= <jsanghvi@peoplepc.com> | |||
To: <timarsh1@example.com> | |||
Subject: =?koi8-r?B?Rnc6INzUzyDNz9bF1CDQ0snHz8TJ1NjT0Q==?Date: Mon, 17 Mar 2008 21:56:52 +0000 | |||
MIME-Version: 1.0 | |||
Content-Type: text/plain; | |||
charset="koi8-r" | |||
Content-Transfer-Encoding: 8bit | |||
X-Priority: 3 | |||
X-MSMail-Priority: Normal | |||
X-Mailer: Microsoft Outlook Express 6.00.2900.3138 | |||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3198 | |||
X-RCPT-TO: <timarsh1@example.com> | |||
Status: U | |||
X-UIDL: 493986027 | |||
<HTML> | |||
<HEAD> | |||
<TITLE>Bondage Bulletin</TITLE> | |||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> | |||
</HEAD> | |||
<BODY BGCOLOR=#000000 LEFTMARGIN=0 TOPMARGIN=0 MARGINWIDTH=0 MARGINHEIGHT=0> | |||
<center> | |||
<TABLE WIDTH=500 BORDER=0 CELLPADDING=0 CELLSPACING=0> | |||
<TR> | |||
<TD COLSPAN=3><A HREF="http://pillagemypussy.com/"><IMG SRC="http://sex-mails.com/bb/im/bb_logo.gif" WIDTH=500 HEIGHT=35 BORDER=0></A></TD> | |||
</TR> | |||
<TR> | |||
<TD COLSPAN=2><A HREF="http://pillagemypussy.com/"><IMG SRC="http://sex-mails.com/bb/im/bb_2.jpg" WIDTH=369 HEIGHT=194 BORDER=0></A></TD> | |||
<TD ROWSPAN=2><A HREF="http://pillagemypussy.com/"><IMG SRC="http://sex-mails.com/bb/im/bb_3.jpg" WIDTH=131 HEIGHT=343 BORDER=0></A></TD> | |||
</TR> | |||
<TR> | |||
<TD><A HREF="http://pillagemypussy.com/"><IMG SRC="http://sex-mails.com/bb/im/bb_4.jpg" WIDTH=122 HEIGHT=149 BORDER=0></A></TD> | |||
<TD><A HREF="http://pillagemypussy.com/"><IMG SRC="http://sex-mails.com/bb/im/bb_5.gif" WIDTH=247 HEIGHT=149 BORDER=0></A></TD> | |||
</TR> | |||
<TR> | |||
<TD COLSPAN=3><IMG SRC="http://sex-mails.com/bb/im/bb_6.gif" WIDTH=500 HEIGHT=74 BORDER=0 USEMAP="#bb_6_Map"></TD> | |||
</TR> | |||
</TABLE> | |||
<MAP NAME="bb_6_Map"> | |||
<AREA SHAPE="rect" COORDS="303,54,484,73" HREF="http://shavekitty.com/"> | |||
<AREA SHAPE="rect" COORDS="149,56,288,73" HREF="http://mygyno.com/"> | |||
<AREA SHAPE="rect" COORDS="13,55,143,73" HREF="http://scatattack.com/"> | |||
<AREA SHAPE="rect" COORDS="315,31,487,51" HREF="http://peepersxxx.com/"> | |||
<AREA SHAPE="rect" COORDS="169,31,308,52" HREF="http://fuckmyfist.com/"> | |||
<AREA SHAPE="rect" COORDS="22,33,162,51" HREF="http://weeonme.com/"> | |||
</MAP> | |||
</center> |
@@ -0,0 +1,73 @@ | |||
#!/bin/sh | |||
# | |||
# SNFServer This shell script takes care of starting and stopping | |||
# the ARM Research SNFServer daemon for FreeBSD systems. | |||
# | |||
# Author-- Alban Deniz | |||
# | |||
# Copyright (C) 2008 ARM Research Labs, LLC. | |||
# See www.armresearch.com for the copyright terms. | |||
# | |||
# PROVIDE: SNFServer | |||
# REQUIRE: FILESYSTEMS | |||
# KEYWORD: shutdown | |||
. /etc/rc.subr | |||
# Location of programs. | |||
installedDir="PREFIX" | |||
# Location of programs. | |||
dir="$installedDir/sbin" | |||
# Name of config file. | |||
configFile="CONFFILE" | |||
# Name of daemon. | |||
prog="SNFServer" | |||
# Name of client. | |||
clientProg="SNFClient" | |||
name="snfserver" | |||
rcvar=`set_rcvar` | |||
command=$dir/$prog | |||
command_args="$configFile > /dev/null 2>&1 &" | |||
required_dirs=$dir | |||
required_files="$dir/$prog $dir/$clientProg $configFile" | |||
snf_user=snfilter | |||
snf_group=snfilter | |||
start_postcmd="${name}_poststart" | |||
snfserver_poststart() | |||
{ | |||
$dir/$clientProg -status.second > /dev/null 2>&1 | |||
return $? | |||
} | |||
stop_cmd="${name}_stop" | |||
snfserver_stop() | |||
{ | |||
echo "Stopping $name." | |||
$dir/$clientProg -shutdown > /dev/null 2>&1 | |||
sleep 10 | |||
} | |||
stop_postcmd="${name}_poststop" | |||
snfserver_poststop() | |||
{ | |||
SNFPID=$(check_process $dir/$prog) | |||
if [ -n "$SNFPID" ]; then | |||
kill $SNFPID | |||
RETVAL=$? | |||
else | |||
RETVAL=0 | |||
fi | |||
return $RETVAL | |||
} | |||
load_rc_config $name | |||
run_rc_command "$1" |
@@ -0,0 +1,111 @@ | |||
#!/bin/sh | |||
# | |||
# SNFServer This shell script takes care of starting and stopping | |||
# the MicroNeil SNFServer daemon for OpenBSD systems. | |||
# Author: Alban Deniz | |||
# | |||
# Copyright (C) 2008 ARM Research Labs, LLC. | |||
# See www.armresearch.com for the copyright terms. | |||
# | |||
# Location of installation. | |||
installedDir="PREFIX" | |||
# Location of programs. | |||
dir="$installedDir/sbin" | |||
# Name of config file. | |||
configFile="CONFFILE" | |||
# Name of daemon. | |||
prog="SNFServer" | |||
# Name of client. | |||
clientProg="SNFClient" | |||
# Name of user to run as. | |||
userName="snfilter" | |||
# Start command. | |||
snfStartCmd="$dir/$prog $configFile > /dev/null 2>&1 &" | |||
start(){ | |||
SNFPID=`ps -axww | grep $dir/$prog | grep -v grep | awk '{print $1}'` | |||
echo -n " $prog " | |||
if [ -n "$SNFPID" ] ; then | |||
echo "already running" | |||
return 1 | |||
else | |||
su -m $userName -c "$snfStartCmd" > /dev/null 2>&1 | |||
RETVAL=$? | |||
if [ $RETVAL -eq 0 ]; then | |||
$dir/$clientProg -status.second > /dev/null 2>&1 | |||
RETVAL=$? | |||
fi | |||
fi | |||
if [ $RETVAL -eq 0 ]; then | |||
echo "started " | |||
else | |||
echo "failed " | |||
fi | |||
return $RETVAL | |||
} | |||
stopFunction(){ | |||
echo -n " $prog " | |||
SNFPID=`ps -axww | grep $dir/$prog | grep -v grep | awk '{print $1}'` | |||
if [ -n "$SNFPID" ]; then | |||
$dir/$clientProg -shutdown > /dev/null 2>&1 | |||
sleep 10 | |||
SNFPID=`ps -axww | grep $dir/$prog | grep -v grep | awk '{print $1}'` | |||
if [ -n "$SNFPID" ]; then | |||
kill $SNFPID | |||
RETVAL=$? | |||
else | |||
RETVAL=0 | |||
fi | |||
echo -n "stopped" | |||
else | |||
echo -n "not running" | |||
RETVAL=1 | |||
fi | |||
echo "" | |||
return $RETVAL | |||
} | |||
restart(){ | |||
stopFunction | |||
start | |||
} | |||
status(){ | |||
SNFPID=`ps -axww | grep $dir/$prog | grep -v grep | awk '{print $1}'` | |||
if [ -n "$SNFPID" ] ; then | |||
echo "$prog (pid $SNFPID) is running" | |||
return 0 | |||
else | |||
echo "$prog is not running" | |||
return 0 | |||
fi | |||
} | |||
# See how we were called. | |||
case "$1" in | |||
start) | |||
start | |||
;; | |||
stop) | |||
stopFunction | |||
;; | |||
status) | |||
status $prog | |||
;; | |||
restart) | |||
restart | |||
;; | |||
*) | |||
echo "Usage: $0 {start|stop|status|restart}" | |||
exit 1 | |||
esac | |||
exit $? |
@@ -0,0 +1,125 @@ | |||
#!/bin/bash | |||
# | |||
# SNFServer This shell script takes care of starting and stopping | |||
# the MicroNeil SNFServer daemon for RedHat systems. | |||
# | |||
# Author-- Alban Deniz | |||
# | |||
# Copyright (C) 2008 ARM Research Labs, LLC. | |||
# See www.armresearch.com for the copyright terms. | |||
# | |||
# chkconfig: 345 80 30 | |||
# description: SNFServer provides email filtering (anti-spam) services \ | |||
# See www.armresearch.com for details. | |||
# processname: SNFServer | |||
# Source function library. | |||
. /etc/rc.d/init.d/functions | |||
# Source networking configuration. | |||
. /etc/sysconfig/network | |||
# Location of programs. | |||
installedDir="PREFIX" | |||
# Location of programs. | |||
dir="$installedDir/sbin" | |||
# Name of config file. | |||
configFile="CONFFILE" | |||
# Name of daemon. | |||
prog="SNFServer" | |||
# Name of client. | |||
clientProg="SNFClient" | |||
# Name of user to run as. | |||
userName="snfilter" | |||
# Name of lockfile. | |||
lockFile="/var/lock/subsys/$prog" | |||
# Start command. | |||
snfStartCmd="$dir/$prog $configFile > /dev/null 2>&1 &" | |||
start(){ | |||
SNFPID=$(pidof -s $dir/$prog) | |||
echo -n $"Starting $prog: " | |||
if [ -n "$SNFPID" ] ; then | |||
echo -n $"$prog is already running" | |||
failure | |||
echo | |||
return 1 | |||
else | |||
su $userName -c "$snfStartCmd" -s /bin/sh > /dev/null 2>&1 | |||
RETVAL=$? | |||
if [ $RETVAL -eq 0 ]; then | |||
$dir/$clientProg -status.second > /dev/null 2>&1 | |||
RETVAL=$? | |||
fi | |||
fi | |||
if [ $RETVAL -eq 0 ]; then | |||
touch $lockFile | |||
success | |||
echo | |||
else | |||
failure | |||
echo | |||
fi | |||
return $RETVAL | |||
} | |||
stop(){ | |||
echo -n $"Stopping $prog: " | |||
SNFPID=$(pidof -s $dir/$prog) | |||
if [ -n "$SNFPID" ]; then | |||
$dir/$clientProg -shutdown > /dev/null 2>&1 | |||
sleep 10 | |||
SNFPID=$(pidof -s $dir/$prog) | |||
if [ -n "$SNFPID" ]; then | |||
kill $SNFPID | |||
RETVAL=$? | |||
else | |||
RETVAL=0 | |||
fi | |||
else | |||
echo -n $"$prog is not running" | |||
RETVAL=1 | |||
failure | |||
echo | |||
fi | |||
if [ $RETVAL -eq 0 ]; then | |||
success | |||
echo | |||
rm -f $lockFile | |||
fi | |||
return $RETVAL | |||
} | |||
restart(){ | |||
stop | |||
start | |||
} | |||
# See how we were called. | |||
case "$1" in | |||
start) | |||
start | |||
;; | |||
stop) | |||
stop | |||
;; | |||
status) | |||
status $prog | |||
;; | |||
restart) | |||
restart | |||
;; | |||
*) | |||
echo $"Usage: $0 {start|stop|status|restart}" | |||
exit 1 | |||
esac | |||
exit $? |
@@ -0,0 +1,252 @@ | |||
#!/bin/bash | |||
# | |||
# SNFServer This shell script takes care of starting and stopping | |||
# the MicroNeil SNFServer daemon for SUSE systems. | |||
# | |||
# Author-- Alban Deniz | |||
# | |||
# Copyright (C) 2008 ARM Research Labs, LLC. | |||
# See www.armresearch.com for the copyright terms. | |||
# | |||
# chkconfig: 345 80 30 | |||
# description: SNFServer providing email filtering. | |||
# | |||
### BEGIN INIT INFO | |||
# Provides: SNFServer | |||
# Required-Start: $syslog $remote_fs $network $named | |||
# Should-Start: $time ypbind smtp | |||
# Required-Stop: $syslog $remote_fs | |||
# Should-Stop: $time ypbind smtp | |||
# Default-Start: 3 4 5 | |||
# Default-Stop: 0 1 2 6 | |||
# Short-Description: SNFServer providing email filtering. | |||
# Description: Start SNFServer to filter email for spam, | |||
# blacklist IP addresses, etc. | |||
### END INIT INFO | |||
# Location of programs. | |||
installedDir="PREFIX" | |||
# Location of programs. | |||
dir="$installedDir/sbin" | |||
# Name of config file. | |||
configFile="CONFFILE" | |||
# Name of daemon. | |||
prog="SNFServer" | |||
# Name of client. | |||
clientProg="SNFClient" | |||
# Name of user to run as. | |||
userName="snfilter" | |||
# Name of lockfile. | |||
lockFile="/var/lock/subsys/$prog" | |||
# Start command. | |||
snfStartCmd="$dir/$prog $configFile > /dev/null 2>&1 &" | |||
# Check for missing binaries (stale symlinks should not happen) | |||
# Note: Special treatment of stop for LSB conformance | |||
SNFServer_BIN=$dir/$prog | |||
test -x $SNFServer_BIN || { echo "$SNFServer_BIN not installed"; | |||
if [ "$1" = "stop" ]; then exit 0; | |||
else exit 5; fi; } | |||
# Use the SUSE rc_ init script functions; | |||
# emulate them on LSB, RH and other systems | |||
# Default: Assume sysvinit binaries exist | |||
start_daemon() { /sbin/start_daemon ${1+"$@"}; } | |||
killproc() { /sbin/killproc ${1+"$@"}; } | |||
pidofproc() { /sbin/pidofproc ${1+"$@"}; } | |||
checkproc() { /sbin/checkproc ${1+"$@"}; } | |||
if test -e /etc/rc.status; then | |||
# SUSE rc script library | |||
. /etc/rc.status | |||
else | |||
export LC_ALL=POSIX | |||
_cmd=$1 | |||
declare -a _SMSG | |||
if test "${_cmd}" = "status"; then | |||
_SMSG=(running dead dead unused unknown reserved) | |||
_RC_UNUSED=3 | |||
else | |||
_SMSG=(done failed failed missed failed skipped unused failed failed reserved) | |||
_RC_UNUSED=6 | |||
fi | |||
if test -e /lib/lsb/init-functions; then | |||
# LSB | |||
. /lib/lsb/init-functions | |||
echo_rc() | |||
{ | |||
if test ${_RC_RV} = 0; then | |||
log_success_msg " [${_SMSG[${_RC_RV}]}] " | |||
else | |||
log_failure_msg " [${_SMSG[${_RC_RV}]}] " | |||
fi | |||
} | |||
# TODO: Add checking for lockfiles | |||
checkproc() { return pidofproc ${1+"$@"} >/dev/null 2>&1; } | |||
elif test -e /etc/init.d/functions; then | |||
# RHAT | |||
. /etc/init.d/functions | |||
echo_rc() | |||
{ | |||
#echo -n " [${_SMSG[${_RC_RV}]}] " | |||
if test ${_RC_RV} = 0; then | |||
success " [${_SMSG[${_RC_RV}]}] " | |||
else | |||
failure " [${_SMSG[${_RC_RV}]}] " | |||
fi | |||
} | |||
checkproc() { return status ${1+"$@"}; } | |||
start_daemon() { return daemon ${1+"$@"}; } | |||
else | |||
# emulate it | |||
echo_rc() { echo " [${_SMSG[${_RC_RV}]}] "; } | |||
fi | |||
rc_reset() { _RC_RV=0; } | |||
rc_failed() | |||
{ | |||
if test -z "$1"; then | |||
_RC_RV=1; | |||
elif test "$1" != "0"; then | |||
_RC_RV=$1; | |||
fi | |||
return ${_RC_RV} | |||
} | |||
rc_check() | |||
{ | |||
return rc_failed $? | |||
} | |||
rc_status() | |||
{ | |||
rc_failed $? | |||
if test "$1" = "-r"; then _RC_RV=0; shift; fi | |||
if test "$1" = "-s"; then rc_failed 5; echo_rc; rc_failed 3; shift; fi | |||
if test "$1" = "-u"; then rc_failed ${_RC_UNUSED}; echo_rc; rc_failed 3; shift; fi | |||
if test "$1" = "-v"; then echo_rc; shift; fi | |||
if test "$1" = "-r"; then _RC_RV=0; shift; fi | |||
return ${_RC_RV} | |||
} | |||
rc_exit() { exit ${_RC_RV}; } | |||
rc_active() | |||
{ | |||
if test -z "$RUNLEVEL"; then read RUNLEVEL REST < <(/sbin/runlevel); fi | |||
if test -e /etc/init.d/S[0-9][0-9]${1}; then return 0; fi | |||
return 1 | |||
} | |||
fi | |||
# Reset status of this service | |||
rc_reset | |||
# Return values acc. to LSB for all commands but status: | |||
# 0 - success | |||
# 1 - generic or unspecified error | |||
# 2 - invalid or excess argument(s) | |||
# 3 - unimplemented feature (e.g. "reload") | |||
# 4 - user had insufficient privileges | |||
# 5 - program is not installed | |||
# 6 - program is not configured | |||
# 7 - program is not running | |||
# 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl) | |||
# | |||
# Note that starting an already running service, stopping | |||
# or restarting a not-running service as well as the restart | |||
# with force-reload (in case signaling is not supported) are | |||
# considered a success. | |||
start(){ | |||
SNFPID=$(pidof -s $dir/$prog) | |||
echo -n $"Starting $prog " | |||
if [ -n "$SNFPID" ] ; then | |||
return 0 | |||
else | |||
su $userName -c "$snfStartCmd" -s /bin/sh | |||
RETVAL=$? | |||
if [ $RETVAL -eq 0 ]; then | |||
$dir/$clientProg -status.second > /dev/null 2>&1 | |||
RETVAL=$? | |||
fi | |||
fi | |||
if [ $RETVAL -eq 0 ]; then | |||
touch $lockFile | |||
else | |||
rc_failed 1 | |||
fi | |||
return $RETVAL | |||
} | |||
stop(){ | |||
echo -n $"Stopping $prog " | |||
SNFPID=$(pidof -s $dir/$prog) | |||
if [ -n "$SNFPID" ]; then | |||
$dir/$clientProg -shutdown > /dev/null 2>&1 | |||
sleep 10 | |||
SNFPID=$(pidof -s $dir/$prog) | |||
if [ -n "$SNFPID" ]; then | |||
kill $SNFPID | |||
RETVAL=$? | |||
else | |||
RETVAL=0 | |||
fi | |||
else | |||
# Process is not running. | |||
RETVAL=0 | |||
fi | |||
if [ $RETVAL -eq 0 ]; then | |||
rm -f $lockFile | |||
else | |||
rc_failed 1 | |||
fi | |||
return $RETVAL | |||
} | |||
restart(){ | |||
stop | |||
start | |||
} | |||
case "$1" in | |||
start) | |||
start | |||
# Remember status and be verbose | |||
rc_status -v | |||
;; | |||
stop) | |||
stop | |||
# Remember status and be verbose | |||
rc_status -v | |||
;; | |||
restart) | |||
## Stop the service and regardless of whether it was | |||
## running or not, start it again. | |||
$0 stop | |||
$0 start | |||
# Remember status and be quiet | |||
rc_status | |||
;; | |||
status) | |||
echo -n "Checking for service SNFServer " | |||
checkproc $SNFServer_BIN | |||
rc_status -v | |||
;; | |||
try-restart|condrestart|force-reload|reload|probe) | |||
# Not supported. | |||
echo -n "$0 $1 " | |||
rc_failed 3 | |||
rc_status -v | |||
;; | |||
*) | |||
echo "Usage: $0 {start|stop|status|restart}" | |||
exit 1 | |||
;; | |||
esac | |||
rc_exit |
@@ -0,0 +1,194 @@ | |||
#! /bin/sh | |||
# | |||
# snfServer. This shell script takes care of starting and stopping | |||
# the ARM Research SNFServer daemon for Ubuntu systems. | |||
# | |||
# Author: Alban Deniz | |||
# | |||
# Copyright (C) 2008 ARM Research Labs, LLC. | |||
# See www.armresearch.com for the copyright terms. | |||
# | |||
### BEGIN INIT INFO | |||
# Provides: SNFServer | |||
# Required-Start: $syslog $remote_fs $network $named | |||
# Should-Start: $time ypbind smtp | |||
# Required-Stop: $syslog $remote_fs | |||
# Should-Stop: $time ypbind smtp | |||
# Default-Start: 3 4 5 | |||
# Default-Stop: 0 1 2 6 | |||
# Short-Description: SNFServer providing email filtering. | |||
# Description: Start SNFServer to filter email for spam, | |||
# blacklist IP addresses, etc. | |||
### END INIT INFO | |||
# Location of installation. | |||
installedDir="PREFIX" | |||
# Location of programs. | |||
dir="$installedDir/sbin" | |||
# Name of config file. | |||
configFile="CONFFILE" | |||
# Name of daemon. | |||
prog="SNFServer" | |||
# Name of client. | |||
clientProg="SNFClient" | |||
# Name of user to run as. | |||
userName="snfilter" | |||
# Name of lockfile. | |||
lockFile="/var/lock/subsys/$prog" | |||
# Name of client. | |||
clientProg="SNFClient" | |||
# Start command. | |||
snfStartCmd="$dir/$prog $configFile > /dev/null 2>&1 &" | |||
# Do NOT "set -e" | |||
# PATH should only include /usr/* if it runs after the mountnfs.sh script | |||
PATH=/usr/sbin:/usr/bin:/sbin:/bin | |||
DESC="SNFServer providing email filtering" | |||
NAME="snfServer" | |||
DAEMON=$dir/$prog | |||
DAEMON_ARGS="$configFile" | |||
SCRIPTNAME=/etc/init.d/$NAME | |||
# Exit if the package is not installed | |||
[ -x "$DAEMON" ] || exit 0 | |||
# Read configuration variable file if it is present | |||
[ -r /etc/default/$NAME ] && . /etc/default/$NAME | |||
# Load the VERBOSE setting and other rcS variables | |||
[ -f /etc/default/rcS ] && . /etc/default/rcS | |||
# Define LSB log_* functions. | |||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. | |||
. /lib/lsb/init-functions | |||
# | |||
# Function that starts the daemon/service | |||
# | |||
do_start() | |||
{ | |||
# Return | |||
# 0 if daemon has been started | |||
# 1 if daemon was already running | |||
# 2 if daemon could not be started | |||
start-stop-daemon --chuid $userName --start --quiet \ | |||
--exec $DAEMON --test > /dev/null 2>&1 \ | |||
|| return 1 | |||
start-stop-daemon --chuid $userName --start --quiet \ | |||
--background --exec $DAEMON -- $DAEMON_ARGS > /dev/null 2>&1 \ | |||
|| return 2 | |||
# Check that process started. | |||
$dir/$clientProg -status.second > /dev/null 2>&1 | |||
RETVAL=$? | |||
if [ $RETVAL -ne 0 ]; then | |||
RETVAL=2 | |||
fi | |||
return $RETVAL | |||
} | |||
# | |||
# Function that stops the daemon/service | |||
# | |||
do_stop() | |||
{ | |||
# Return | |||
# 0 if daemon has been stopped | |||
# 1 if daemon was already stopped | |||
# 2 if daemon could not be stopped | |||
# other if a failure occurred | |||
# Check whether SNFServer is running. | |||
start-stop-daemon --chuid $userName --start --quiet \ | |||
--exec $DAEMON --test > /dev/null | |||
RETVAL=$? | |||
if [ $RETVAL -ne 1 ]; then | |||
return 1 | |||
fi | |||
# Issue shutdown command | |||
$dir/$clientProg -shutdown > /dev/null 2>&1 | |||
sleep 10 | |||
# Check again whether SNFServer is running. | |||
start-stop-daemon --chuid $userName --start --quiet \ | |||
--exec $DAEMON --test > /dev/null | |||
RETVAL=$? | |||
if [ $RETVAL -eq 1 ] ; then | |||
# Send TERM signal to stop SNFServer. | |||
start-stop-daemon --stop --quiet --retry=TERM/5 --exec $DAEMON | |||
RETVAL="$?" | |||
[ "$RETVAL" = 2 ] && return 2 | |||
return "$RETVAL" | |||
fi | |||
# SNFServer isn't running. | |||
return 0 | |||
} | |||
case "$1" in | |||
start) | |||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" | |||
do_start | |||
case "$?" in | |||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; | |||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; | |||
esac | |||
;; | |||
stop) | |||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" | |||
do_stop | |||
case "$?" in | |||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; | |||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; | |||
esac | |||
;; | |||
status) | |||
start-stop-daemon --chuid $userName --start --quiet \ | |||
--exec $DAEMON --test > /dev/null | |||
RETVAL=$? | |||
if [ $RETVAL -eq 0 ]; then | |||
# Stopped | |||
echo "$prog is stopped" | |||
else | |||
# Running | |||
echo "$prog (pid $(pidof $dir/$prog)) is running" | |||
fi | |||
;; | |||
restart|force-reload) | |||
# | |||
# If the "reload" option is implemented then remove the | |||
# 'force-reload' alias | |||
# | |||
log_daemon_msg "Restarting $DESC" "$NAME" | |||
do_stop | |||
case "$?" in | |||
0|1) | |||
do_start | |||
case "$?" in | |||
0) log_end_msg 0 ;; | |||
1) log_end_msg 1 ;; # Old process is still running | |||
*) log_end_msg 1 ;; # Failed to start | |||
esac | |||
;; | |||
*) | |||
# Failed to stop | |||
log_end_msg 1 | |||
;; | |||
esac | |||
;; | |||
*) | |||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 | |||
exit 3 | |||
;; | |||
esac |
@@ -0,0 +1,121 @@ | |||
#!/bin/sh | |||
# 20040508 _M Modified for snfrv2r3 release. | |||
# 20040102 _M Modified for snfrv2r2 release. | |||
# Also improved file collision avoidance using DATE functions. | |||
# 20021204 _M Modified for sniffer2 release. No other changes. | |||
# sniffer - 20021106 _M ############################################## | |||
# | |||
# This script is a template for using SortMonster's Message Sniffer | |||
# on Postfix systems. It is derived from the FILTER_README distributed | |||
# with Postfix. | |||
# | |||
# This script accepts the message, writes it to a file, scans it with | |||
# the sniffer utility, and then delivers the message if there is no | |||
# pattern match. If a pattern match is found then there are a number | |||
# of options included in this script. | |||
# | |||
# The default action is to write a header to the message indicating | |||
# the symbol for the pattern match. | |||
# | |||
# In practice, the system administrator should adjust this script to | |||
# interpret the response from sniffer and take some appropriate action. | |||
# In that respect, this script is only a good starting point. | |||
# | |||
# | |||
###################################################################### | |||
# Localize the inspection directory, sniffer installation, and | |||
# sendmail command. It is VITAL that the sniffer utility is named with | |||
# a .exe extension so that it can rewrite it's file name to produce it's | |||
# log file and to read it's rule file. Both of those must be in the same | |||
# directory along with the binary. | |||
INSPECT_DIR=DATADIR/PACKAGE_NAME | |||
SNIFFER_EXE=PREFIX/sbin/SNFClient | |||
SENDMAIL="/usr/sbin/sendmail -G -i" | |||
MSGFILE=$INSPECT_DIR/`date +%Y%m%d%H%M%S`_$$_$RANDOM.msg | |||
# Define Exit codes from <sysexits.h> | |||
EX_OK=0 | |||
EX_TEMPFAIL=75 | |||
EX_UNAVAILABLE=69 | |||
# Clean up when when aborting. | |||
trap "rm -f $MSGFILE*" 1 2 3 15 | |||
# Move to our filter directory where we perform our inspections. | |||
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; } | |||
# Copy the message to a temp file for processing. | |||
cat > $MSGFILE || { echo Cannot save mail to file; exit $EX_TEMPFAIL; } | |||
# Now that we have the message as a file we can process it with | |||
# Message Sniffer. The sniffer utility will return a nonzero value if | |||
# it finds a pattern match. | |||
$SNIFFER_EXE $MSGFILE || { | |||
# If we're here, we know sniffer found a match. So, what do we do? | |||
################################################################## | |||
# # | |||
# *ONE* OF THE FOLLOWING BLOCKS MUST BE UNCOMMENTED. THE DEFAULT # | |||
# IS THE MESSAGE HEADER BLOCK. # | |||
# # | |||
################################################################## | |||
#### Uncomment this section to reject (bounce) the message. | |||
# | |||
# echo Message content rejected, symbol = $?; | |||
# rm -f $MSGFILE*; | |||
# exit $EX_UNAVAILABLE; | |||
#### Uncomment this section to eat the message. | |||
# | |||
# echo Message content destroyed, symbol = $?; | |||
# rm -f $MSGFILE* | |||
# exit $EX_OK; | |||
#### Uncomment this section to hold the message for review. | |||
# | |||
# echo Message Content Held For Review, symbol = $?; | |||
# exit $EX_OK; | |||
#### Uncomment this section to add a header to the message. | |||
echo X-SortMonster-Msg-Sniffer-Match: Symbol-$? > $MSGFILE.x; | |||
cat $MSGFILE.x $MSGFILE > $MSGFILE.y; | |||
$SENDMAIL "$@" < $MSGFILE.y; | |||
rm -f $MSGFILE*; | |||
exit $EX_OK; | |||
# NOTE: The value returned by the sniffer program is an integer | |||
# representing the rule/group that was matched. That value may be | |||
# any integer from 1 through 64. The value is derived from the | |||
# matching rule's symbol (mod 64)+1. The actual symbol will be | |||
# accurately recorded in the log file. This is a correction from | |||
# the demo version which uses an older code base. | |||
} | |||
# At this point we want to deliver the message as-is. We reinject | |||
# the message with our sendmail command and then clean up our temp | |||
# file(s). | |||
$SENDMAIL "$@" < $MSGFILE | |||
rm -f $MSGFILE* | |||
exit $? | |||
@@ -0,0 +1,118 @@ | |||
#!/bin/sh | |||
# 20081216 AVD Modified for use with procmail as a filter. | |||
# 20040508 _M Modified for snfrv2r3 release. | |||
# 20040102 _M Modified for snfrv2r2 release. | |||
# Also improved file collision avoidance using DATE functions. | |||
# 20021204 _M Modified for sniffer2 release. No other changes. | |||
# sniffer - 20021106 _M ############################################## | |||
# | |||
# This script is a template for using SortMonster's Message Sniffer | |||
# with procmail. It is derived from the FILTER_README distributed with | |||
# Postfix. | |||
# | |||
# This script accepts the message from standard input, writes it to a | |||
# file, scans it with the sniffer utility, and then sends the message | |||
# to standard output if there is no pattern match. If a pattern match | |||
# is found then there are a number of options included in this script. | |||
# | |||
# The default action is to write a header to the message indicating | |||
# the symbol for the pattern match, and send the result to standard | |||
# output. | |||
# | |||
# In practice, the system administrator should adjust this script to | |||
# interpret the response from sniffer and take some appropriate action. | |||
# In that respect, this script is only a good starting point. | |||
# | |||
# | |||
###################################################################### | |||
# Localize the inspection directory, sniffer installation, and | |||
# sendmail command. | |||
INSPECT_DIR=DATADIR/PACKAGE_NAME | |||
SNIFFER_EXE=PREFIX/sbin/SNFClient | |||
MSGFILE=$INSPECT_DIR/`date +%Y%m%d%H%M%S`_$$_$RANDOM.msg | |||
# Define Exit codes from <sysexits.h> | |||
EX_OK=0 | |||
EX_TEMPFAIL=75 | |||
EX_UNAVAILABLE=69 | |||
# Clean up when when aborting. | |||
trap "rm -f $MSGFILE*" 1 2 3 15 | |||
# Move to our filter directory where we perform our inspections. | |||
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; } | |||
# Copy the message to a temp file for processing. | |||
cat > $MSGFILE || { echo Cannot save mail to file; exit $EX_TEMPFAIL; } | |||
chmod 444 $MSGFILE | |||
# Now that we have the message as a file we can process it with | |||
# Message Sniffer. The sniffer utility will return a nonzero value if | |||
# it finds a pattern match. | |||
$SNIFFER_EXE $MSGFILE || { | |||
# If we're here, we know sniffer found a match. So, what do we do? | |||
################################################################## | |||
# # | |||
# *ONE* OF THE FOLLOWING BLOCKS MUST BE UNCOMMENTED. THE DEFAULT # | |||
# IS THE MESSAGE HEADER BLOCK. # | |||
# # | |||
################################################################## | |||
#### Uncomment this section to reject (bounce) the message. | |||
# | |||
# echo Message content rejected, symbol = $?; | |||
# rm -f $MSGFILE*; | |||
# exit $EX_UNAVAILABLE; | |||
#### Uncomment this section to eat the message. | |||
# | |||
# echo Message content destroyed, symbol = $?; | |||
# rm -f $MSGFILE* | |||
# exit $EX_OK; | |||
#### Uncomment this section to hold the message for review. | |||
# | |||
# echo Message Content Held For Review, symbol = $?; | |||
# exit $EX_OK; | |||
#### Uncomment this section to add a header to the message. | |||
echo X-SortMonster-Msg-Sniffer-Match: Symbol-$? > $MSGFILE.x; | |||
cat $MSGFILE.x $MSGFILE > $MSGFILE.y; | |||
cat $MSGFILE.y; | |||
rm -f $MSGFILE*; | |||
exit $EX_OK; | |||
# NOTE: The value returned by the sniffer program is an integer | |||
# representing the rule/group that was matched. That value may be | |||
# any integer from 1 through 64. The value is derived from the | |||
# matching rule's symbol (mod 64)+1. The actual symbol will be | |||
# accurately recorded in the log file. This is a correction from | |||
# the demo version which uses an older code base. | |||
} | |||
# At this point we want to deliver the message as-is. We send the | |||
# message to stdout and then clean up our temp file(s). | |||
cat $MSGFILE | |||
rm -f $MSGFILE* | |||
exit $? | |||
@@ -0,0 +1,41 @@ | |||
#!/bin/sh | |||
# 20080314 _M Simplified from sniffer script. | |||
# This version simply creates a temp file, scans it w/ SNFClient and | |||
# sends it on it's way - presumably with headers injected. | |||
# Setup These Variable. The rest of the script should be fine as is. | |||
INSPECT_DIR=DATADIR/PACKAGE_NAME | |||
SNIFFER_EXE=PREFIX/sbin/SNFClient | |||
SENDMAIL="/usr/sbin/sendmail -G -i" | |||
MSGFILE=$INSPECT_DIR/`date +%Y%m%d%H%M%S`_$$_$RANDOM.msg | |||
# Define Exit codes from <sysexits.h> | |||
EX_OK=0 | |||
EX_TEMPFAIL=75 | |||
EX_UNAVAILABLE=69 | |||
# Clean up when when aborting. | |||
trap "rm -f *$MSGFILE" 1 2 3 15 | |||
# Move to our filter directory where we perform our inspections. | |||
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; } | |||
# Copy the message to a temp file for processing. | |||
cat > $MSGFILE || { echo Cannot save mail to file; exit $EX_TEMPFAIL; } | |||
# Scan the mesage w/ SNF. SNFServer will inject headers. | |||
$SNIFFER_EXE $MSGFILE # Scan the message | |||
$SENDMAIL "$@" < $MSGFILE # Reinject the message | |||
rm -f $MSGFILE # Remove the temp file | |||
# All done. | |||
exit $EX_OK; | |||
@@ -0,0 +1,15 @@ | |||
#!/bin/sh | |||
# | |||
# Script to clean the developer distribution. | |||
# | |||
# This script removes all files that can be created. After running | |||
# this script, you'd need to run 'autoreconf --install' before | |||
# running './configure'. | |||
# | |||
# Copyright (C) 2009 ARM Research Labs, LLC | |||
# | |||
############################################################################## | |||
make distclean | |||
find . -name '*~' -exec rm {} \; | |||
find . -name Makefile.in -exec rm {} \; | |||
rm -rf config autom4te.cache configure config.h* aclocal.m4 snf-server-* |
@@ -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,51 @@ | |||
## Process this file with automake to produce Makefile.in | |||
## | |||
## $Id$ | |||
## | |||
## automake input for the MicroNeil SNFServer config files. | |||
## | |||
## Author: Alban Deniz | |||
## | |||
## Copyright (C) 2008 ARM Research Labs, LLC. | |||
## See www.armresearch.com for the copyright terms. | |||
## | |||
## | |||
CONFDATA = \ | |||
SNFServer.xml.sample \ | |||
identity.xml.sample | |||
if OpenBSD | |||
if ForPackage | |||
sampleconfdir = @datadir@/examples/@PACKAGE_NAME@ | |||
sampleconf_DATA = $(CONFDATA) | |||
else | |||
sampleconfdir = @sysconfdir@/@PACKAGE_NAME@ | |||
sampleconf_DATA = $(CONFDATA) | |||
endif | |||
else | |||
sampleconfdir = @sysconfdir@/@PACKAGE_NAME@ | |||
sampleconf_DATA = $(CONFDATA) | |||
endif | |||
SNFServer.xml.sample: SNFServer.xml.sample.in Makefile | |||
cat @top_srcdir@/config_files/SNFServer.xml.sample.in | sed -e s+SYSCONFDIR+@sysconfdir@+ -e s+PREFIX+@prefix@+ -e s+PACKAGE_NAME+@PACKAGE_NAME@+ > $@ | |||
identity.xml.sample: identity.xml.sample.in | |||
cp @top_srcdir@/config_files/identity.xml.sample.in $@ | |||
pkgdata_DATA = \ | |||
GBUdbIgnoreList.txt.sample | |||
EXTRA_DIST = \ | |||
SNFServer.xml.sample.in \ | |||
identity.xml.sample.in \ | |||
GBUdbIgnoreList.txt.sample \ | |||
Makefile.am | |||
clean-local: | |||
rm -f *.gcno *.gcov *.gcda *~ $(CONFDATA) |
@@ -0,0 +1,150 @@ | |||
<!-- SNFMulti V3.0 Configuration File, Setup: Typical of *nix Client / Server --> | |||
<!-- http://www.armresearch.com/support/articles/software/snfServer/config/snfEngine.jsp --> | |||
<snf> | |||
<node identity='SYSCONFDIR/PACKAGE_NAME/identity.xml'> | |||
<paths> | |||
<log path='PREFIX/share/PACKAGE_NAME/'/> | |||
<rulebase path='PREFIX/share/PACKAGE_NAME/'/> | |||
<workspace path='PREFIX/share/PACKAGE_NAME/'/> | |||
</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'/> | |||
<classic 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-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='PREFIX/sbin/getRulebase' 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,4 @@ | |||
<!-- Change 'licenseid' and 'xxxxxxxxxxxxxxxx' to match your license info --> | |||
<snf><identity licenseid='licenseid' authentication='xxxxxxxxxxxxxxxx'/></snf> | |||
@@ -0,0 +1,119 @@ | |||
dnl | |||
dnl Process this file with autoconf to produce a configure script. | |||
dnl | |||
dnl $Id: configure.in,v 1.33 2008/02/08 15:10:17 adeniz Exp $ | |||
dnl | |||
dnl autoconf input for the MicroNeil SNFServer distribution. | |||
dnl | |||
dnl Author: Alban Deniz | |||
dnl | |||
dnl Copyright (C) 2008 by MicroNeil Corporation. All rights reserved. | |||
dnl See www.armresearch.com for the copyright terms. | |||
dnl | |||
dnl | |||
AC_PREREQ(2.52) | |||
AC_INIT(snf-server, 3.0.5) | |||
AC_CONFIG_SRCDIR(SNFMulti/snfCFGmgr.cpp) | |||
AC_CONFIG_AUX_DIR(config) | |||
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) | |||
AM_CONFIG_HEADER(config.h) | |||
AC_LANG(C++) | |||
AC_PROG_LIBTOOL | |||
AC_PROG_CXX | |||
AC_PROG_CC | |||
AC_PROG_INSTALL | |||
AC_PROG_MAKE_SET | |||
dnl | |||
dnl Check for programs. | |||
dnl | |||
AC_CHECK_PROG(haveCURL, curl, true, false) | |||
if [[ $haveCURL == "false" ]] | |||
then | |||
AC_MSG_ERROR([The CURL program was not found]); | |||
fi | |||
dnl | |||
dnl Load the user-specified OS. | |||
dnl | |||
AC_ARG_ENABLE(os-type, | |||
[AS_HELP_STRING([--enable-os-type=TYPE], | |||
[where TYPE is OpenBSD, FreeBSD, RedHat, Suse, or Ubuntu])], | |||
[SNF_OSTYPE="${enableval}" ]) | |||
case "$SNF_OSTYPE" in | |||
OpenBSD|OpenBSD|FreeBSD|RedHat|Suse|Ubuntu) | |||
: | |||
;; | |||
*) | |||
AC_MSG_ERROR([Invalid OS type: "$SNF_OSTYPE". | |||
You must specify a valid OS type with --enable-os-type=TYPE, where TYPE is one of: | |||
OpenBSD | |||
FreeBSD | |||
Suse | |||
RedHat | |||
Ubuntu]) | |||
;; | |||
esac | |||
AM_CONDITIONAL([OpenBSD], [test x$SNF_OSTYPE = xOpenBSD]) | |||
AM_CONDITIONAL([FreeBSD], [test x$SNF_OSTYPE = xFreeBSD]) | |||
AM_CONDITIONAL([Suse], [test x$SNF_OSTYPE = xSuse]) | |||
AM_CONDITIONAL([RedHat], [test x$SNF_OSTYPE = xRedHat]) | |||
AM_CONDITIONAL([Ubuntu], [test x$SNF_OSTYPE = xUbuntu]) | |||
dnl | |||
dnl Load whether this is for a package. | |||
dnl | |||
AC_ARG_ENABLE(for-package, | |||
[AS_HELP_STRING([--enable-for-package], | |||
[enable if building for a package])], | |||
[FOR_PACKAGE="${enableval}" ]) | |||
AM_CONDITIONAL([ForPackage], [test x$FOR_PACKAGE = xyes]) | |||
dnl | |||
dnl Check libraries. | |||
dnl | |||
dnl | |||
dnl pthread library. | |||
dnl | |||
AC_CHECK_LIB(pthread, pthread_create,, | |||
AC_MSG_ERROR([libpthread is required to build AC_PACKAGE_NAME])) | |||
dnl | |||
dnl Additional compile-time and link-time flags. | |||
dnl | |||
SNF_CXXFLAGS='-O3 -pthread' | |||
SNF_LIBS='' | |||
AC_SUBST(SNF_CXXFLAGS) | |||
AC_SUBST(SNF_LIBS) | |||
dnl | |||
dnl Output the makefiles. | |||
dnl | |||
AC_OUTPUT([Makefile | |||
CodeDweller/Makefile | |||
SNFMulti/Makefile | |||
SNFServer/Makefile | |||
SNFClient/Makefile | |||
SNF2Check/Makefile | |||
Scripts/Makefile | |||
config_files/Makefile | |||
Docs/Makefile]) | |||
echo " | |||
Type "make" to build the system using the default (optimized) parameters. | |||
Type "make SNF_CXXFLAGS='-g -pthread'" to build the system for debugging. | |||
OS type: $SNF_OSTYPE | |||
The software will be installed in $prefix. | |||
Done | |||
" |
@@ -0,0 +1,85 @@ | |||
SNF V2.x to V3.x Source Distribution Readme | |||
Version 3.x of SNF is a departure from previous versions of Message | |||
Sniffer on many levels. Though the core scanning engine and rulebase | |||
files are the same, the new version uses a client/server model. | |||
The client and server programs connect via TCP/Localhost port 9001. | |||
If this is your first experience with SNF in a *nix environment then | |||
please use the snfv2-3.5-PostfixExample as a guied. | |||
The new SNF engine and client are designed to work in parallel | |||
with prior versions of SNF so that it is easy to switch back if | |||
neede. In general all you need to do to switch between versions is | |||
to swap out the client executable in your scripts that scan messages | |||
with SNF. Be careful to read and understand your configuration! | |||
The SNFClient program is compatible with the old snf program when | |||
used as a scanner. | |||
The SNFServer program takes the place of a persistent instance of SNF | |||
and is required for the new version. | |||
The old program will generally ignore the new program and the new | |||
program will generally ignore the old program. | |||
The easiest way to convert a system from the previous (2-3) version | |||
of SNF to the new version is: | |||
* Copy the source distribution to it's own directory. | |||
* Run . compile in each of the client and source directories. | |||
* Copy the working files to your /var/spool/snfilter directory. | |||
cp SNF_Service/SNFServer.exe /var/spool/snfilter | |||
cp SNF_Client/SNFClient.exe /var/spool/snfilter | |||
cp identity.xml /var/spool/snfilter | |||
cp snf_engine.xml /var/spool/snfilter | |||
cp GBUdbIgnoreList.txt /var/spool/snfilter | |||
* Follow the SNFServer_readme.txt instructions and carefully | |||
configure your snf_engine.xml, identity.xml, and GBUdbIgnoreList.txt | |||
files. | |||
When you are ready to go, launch the SNFServer.exe program with | |||
the full path to the configuration file. | |||
/var/spool/snfilter/SNFServer.exe /var/spool/snfilter/snf_engine.xml | |||
If you run this from the console you will see a handy real-time | |||
monitor. | |||
To cleanly shut down the SNFServer use: | |||
SNFClient.exe -shutdown | |||
__________________________________________________________ | |||
IF YOU ARE USING THE snfilter SCRIPT or something similar: | |||
* Modify your snfilter script to call the new SNFClient.exe | |||
SNIFFER_EXE=/var/spool/snfilter/SNFClient.exe | |||
* If your script is designed to inject headers then you could use | |||
the new xheader feature in the new engine. To do this: | |||
** Comment out the section of your script which modifies the message. | |||
** Turn on xheader injection in the snf_engine.xml file | |||
<xheaders> | |||
<!-- X-Header formatting and output options --> | |||
<output mode='inject'/> | |||
_________________________________________ | |||
IF YOU ARE USING THE SpamAssassin Plugin: | |||
Adjust your snfilter.pm to point to the new SNFClient.exe | |||
my $sniffer='SNFClient.exe'; | |||
Note: The SNFClient.exe program will accept and ignore the | |||
authentication string so there is no reason to change your | |||
$key. | |||
@@ -0,0 +1,175 @@ | |||
# Setting up Message Sniffer with Postfix | |||
# You should already have an SNF license ID and authentication string. If | |||
# you don't then sign up for a free trial first and they will be provided: | |||
# http://www.armresearch.com/products/trial.jsp | |||
# This procedure assumes you're running Linux. | |||
# If you are using BSD please substitue the correct distribution directory. | |||
# Follow this procedure logged in as root! | |||
# Download and unpack the distribution files. | |||
wget http://www.armresearch.com/message-sniffer/download/SNFSourceClientServer.3.0.1.zip | |||
unzip SNFSourceClientServer.3.0.1.zip | |||
# Compile the SNFServer.exe, SNFClient.exe and snf2check.exe programs. | |||
cd SNF_Source_Distribution/SNF_Service | |||
. compile | |||
cd ../SNF_Client | |||
. compile | |||
cd ../SNF2Check | |||
. compile | |||
cd .. | |||
# Create the /var/spool/snfilter directory. | |||
# Copy the necessary files to the snfilter directory. | |||
# The Linux distribution is assumed below. | |||
mkdir /var/spool/snfilter | |||
mkdir /var/spool/snfilter/msg | |||
cp SNF_Service/SNFServer.exe /var/spool/snfilter | |||
cp SNF_Client/SNFClient.exe /var/spool/snfilter | |||
cp SNF2Check/SNF2Check.exe /var/spool/snfilter | |||
cp GBUdbIgnoreList.txt /var/spool/snfilter | |||
cp snf_engine.xml /var/spool/snfilter | |||
cp identity.xml /var/spool/snfilter | |||
# Copy the control and update scripts to the snfilter directory. | |||
cp scripts/* /var/spool/snfilter | |||
# Copy a couple of test files to the snfilter directory. | |||
cp cleanmsg.txt /var/spool/snfilter | |||
cp junkmsg.txt /var/spool/snfilter | |||
# Create an unprivleged user with no shell or home directory. | |||
# Set Permissions and ownership of the files and directory. | |||
groupadd -g 93 snfilter | |||
useradd -g 93 -u 93 -c "Spam Filter" -d /bin/false snfilter | |||
chown snfilter /var/spool/snfilter /var/spool/snfilter/msg | |||
cd /var/spool/snfilter | |||
chown snfilter * | |||
chmod 460 * | |||
chmod 770 msg | |||
chmod 500 SNFServer.exe | |||
chmod 570 SNFClient.exe SNF2Check.exe | |||
chmod 570 getRulebase snfscan-spamassasin snfscan-standalone | |||
chmod 070 snfctrl | |||
# Modify your getRulebase script (input your license information) | |||
# Simulate a ready rulebase update and download your .snf file. | |||
touch UpdateReady.txt | |||
chown snfilter UpdateReady.txt | |||
su snfilter -c "/var/spool/snfilter/getRulebase" | |||
ls *.snf | |||
# SNFServer_readme.txt will guide you through the next step: | |||
# Make the appropriate adjustments to your GBUdbIgnoreList.txt, | |||
# identity.xml, and snf_engine.xml files. | |||
# Test your SNFServer installation | |||
./snfctrl start | |||
./SNFClient.exe -status.second | |||
# If successful you should see XML data. If not, an error. | |||
# Upon success, set up SNFServer to run on startup. We will | |||
# test the link by shutting down snf from init.d. | |||
ln -s /var/spool/snfilter/snfctrl /etc/init.d/snf | |||
/etc/init.d/snf stop | |||
# Tell chkconfig that we want SNFServer turned on. | |||
chkconfig snf on | |||
chkconfig --list | grep snf | |||
# Congratulations!! | |||
# If you've gotten to this point then you have successfully installed | |||
# SNF on your server! The next set of instructions assumes you will | |||
# be using SNF with postfix and simply injecting headers that will be | |||
# used later to remove, quarantine, or otherwise redirect messages | |||
# detected as spam. There are as many ways to use SNF as there are | |||
# systems using it -- so the following is just a good starting place | |||
# for postfix users. | |||
# Be sure to restar SNFServer before trying to use it ;-) | |||
service snf start | |||
#------------------------------------------------------------------ | |||
# Copy the snfscan-standalone script to sniffer and set the correct | |||
# access rights. | |||
cp snfscan-standalone sniffer | |||
chown snfilter sniffer | |||
chmod 570 sniffer | |||
# The snfscan-standalone version of the sniffer script creates a | |||
# temporary copy of the message, scans it with SNF, and then reinjects | |||
# the message. It is presumed that SNF is configured with x-header | |||
# injection turned on and that the x-headers have been customized | |||
# to suit your needs. Check the <xheaders/> section of your snf_engine.xml | |||
# file to verify that SNF is configured to do what you want. | |||
# Edit the sniffer shell script, and uncomment the action you want | |||
# the script to take. The default action will only to add a | |||
# "X-SortMonster-Msg-Sniffer-Match:" header to messages that | |||
# match the filter. This default action will not stop spam from | |||
# getting through. | |||
# Changes to /etc/postfix/master.cf | |||
# LEADING WHITE SPACES ARE IMPORTANT WHEN MAKING THIS CHANGE | |||
change: | |||
smtp inet n - n - - smtpd | |||
to: | |||
smtp inet n - y - - smtpd | |||
-o content_filter=snfilter | |||
also add: | |||
snfilter unix - n n - 10 pipe | |||
flags=q user=snfilter argv=/var/spool/snfilter/sniffer | |||
-f ${sender} ${recipient} | |||
to master.cf | |||
# At this point You could just restart postfix, and hope nothing | |||
# goes wrong. Instead, it would be smarter to first test the | |||
# installation from the command line by injecting a message directly | |||
# into the filter script "sniffer". We can issue a command like | |||
./sniffer -f sender recipient <junkmsg.txt | |||
# Where junkmsg.txt is a spam test message. We should also test | |||
# a clean message to make sure that this script is working as we | |||
# expect it to. In this case we would issue a command like | |||
./sniffer -f sender recipient <cleanmsg.txt | |||
# If you've done everything correctly then all you have to do | |||
# is reload postfix to start the content_filter working. | |||
postfix reload | |||
# If something goes wrong you need only comment out, or remove | |||
# the line | |||
-o content_filter=snfilter | |||
# in /etc/postfix/master.cf, then reload postfix as shown above. |
@@ -0,0 +1,42 @@ | |||
#!/bin/sh | |||
# 20080314 _M Simplified from sniffer script. | |||
# This version simply creates a temp file, scans it w/ SNFClient and | |||
# sends it on it's way - presumably with headers injected. | |||
# Setup These Variable. The rest of the script should be fine as is. | |||
INSPECT_DIR=/var/spool/snfilter/msg | |||
SNIFFER_EXE=/var/spool/snfilter/SNFClient.exe | |||
SENDMAIL="/usr/sbin/sendmail -i" | |||
SPAMC="/usr/bin/spamc" | |||
MSGFILE=$INSPECT_DIR/`date +%Y%m%d%H%M%S`_$$_$RANDOM.msg | |||
# Define Exit codes from <sysexits.h> | |||
EX_OK=0 | |||
EX_TEMPFAIL=75 | |||
EX_UNAVAILABLE=69 | |||
# Clean up when when aborting. | |||
trap "rm -f *$MSGFILE" 1 2 3 15 | |||
# Move to our filter directory where we perform our inspections. | |||
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; } | |||
# Copy the message to a temp file for processing. | |||
cat > $MSGFILE || { echo Cannot save mail to file; exit $EX_TEMPFAIL; } | |||
# Scan the mesage w/ SNF. SNFServer will inject headers. | |||
$SNIFFER_EXE $MSGFILE # Scan the message | |||
$SPAMC < $MSGFILE -e $SENDMAIL "$@" # Reinject the message through SpamAssasin | |||
rm -f $MSGFILE # Remove the temp file | |||
# All done. | |||
exit $EX_OK; | |||