For example, if you want to delete all messages from uglymail.com, you would create a UBE filter that identifies any email message from uglymail.com. You would designate "delete" as the action to be performed by the filter.
You can create a variety of types of UBE filters, store them, and activate or deactivate them from the UBE Filters form.
Action | Argument | Desciption |
COPY | List of addresses seperated by commas | Adds this list to the original list and sends it off |
DROP | One address | Replaces original list of recipients with this one and then sends it |
EXIT | NONE | Stop processing the script file completely |
HOLDCOPY | List of addresses | Message (example: tuser, tuser2 | "I don't like your mail" | Puts the message into a hold mode and sends a notification including the message to the list of addresses asking for instructions on dealing with the mail (including submit it, delete it, or return it) |
HOLDONLY | List of addresses | Message (example: tuser, tuser2 | "I don't like your mail" | Same as HOLDCOPY but the notification doesn't include the original message |
JUMP | Label (name) | Moves the scripts execution to the specified Name. For example:
Channel-To tuser JUMP "PastReject" Channel-To tuser REJECT "Bad Mail" :PastReject Channel-To tuser REJECT "Really Bad Mail" Would skip the REJECT bad mail and start at the PastReject label and thus apply the REJECT "Really Bad Mail" filter. |
REJECT | Reject Reason (example: This mail sucks) | The mail is returned to the sender with the reject reason included in the message |
RUN | External program | Runs the given program and pipes the message header and body to the program. The program must be in the post office (spool) directory. |
To activate or deactive filters:
To change the order of UBE filters:
This section describes the functionality of the General Scriptable Plugin, and how it interacts with the Netscape Messaging Server. This section assumes that you are using the Messaging Server Plugin API 2.x or 3.0. This API is available on the Solaris, HP-UX, and Windows NT platforms only.
One subsystem is implemented using this facility - the Unsolicited Bulk Email (UBE) filter.
The General Scriptable Plugin and its subsystems are designed for ISP
administrators who want to extend the functionality of the Netscape Messaging
Server for site-specific reasons.
Where to Find the General Scriptable
Plugin
The General Scriptable Plugin is installed when you run a regular install of the Messaging Server. To use the General Scriptable Plugin, go to Plugins|Plugin Config and enable the plugin.
For Netscape developer information, see the Netscape DevEdge site.
For more information about server Plugin APIs, see these Netscape documents:
Messaging Server Plugin API Guide
This section describes the General Scriptable Plugin and how to install it.
Overview
Installation
The General Scriptable Plugin is a dynamically loaded module designed to interact with Netscape Messaging Server 2.x and 3.x. It uses the existing Plugin API to hook into the "PostSmtpAccept" and "PreSmtpDelivery" stages of the MTA (Message Transfer Agent) operation, and contains a simple scripting language useful for processing and directing the flow of messages.
The General Scriptable Plugin is installed when you run a regular install of the Messaging Server. To use the General Scriptable Plugin, go to the Plugin Configuration menu and enable it.
This section describes how the filtering functionality of the General
Scriptable Plugin works.
What is UBE?
Unsolicited Bulk Email (UBE) is email sent to large numbers of recipients without their knowledge or consent, often advertising commercial products or services. It is the electronic equivalent of paper "junk mail".
For a full definition see
http://www.imc.org/uce-def.html
Unsolicited Bulk Email: Definitions and Problems.
What is the UBE filter?
The UBE filter is a plugin for Netscape Messaging Server (version
3.0 and above). It works by examining all incoming mail before it
is routed throughout the system (to users mailboxes or to other
email servers). The UBE filter uses a set of rules (also known as
filters) to decide what
to do with each piece of mail. Any mail not handled by one
of these filters continues on its normal course, untouched by the filter.
How do I use the UBE filter?
To use the filters in Messaging Server 3.5 simply turn on the nsfilter.dll (or nsfilter.so for UNIX) line from the Plugin Config screen in the admin server interface. Once turned on you can then go the Unsolicited Bulk Email page and use the UI to create filters. For Messaging Server 3.0, please see the documentation for instructions on how to install a plugin for your operating system. In 3.0 you must manually create the filters you wish to use. For 3.5 you can use the UI or manually create them. This document describes how to manually create rules. The online help for the UI describes how to use the UI method.
The Messaging Server looks at the file plugin.conf to determine how the UBE filter is configured. A typical line for an NT install would look like this:
PostSmtpAccept i:\Netscape\SuiteSpot\bin\mail\Server\etc\NSfilter.dll
funcs=filter_msg_plugin config=i:\Netscape\SuiteSpot\bin\mail\Server\etc\filter.cfg
option=i:\Netscape\SuiteSpot\bin\mail\Server\etc\filter.opt
This command line tells the server to:
For Unix, the command line would be very similar except that it would use the shared object NSfilter.so and the paths would be in a Unix format.
The important part of this statement is the config and option definitions. These two files drive the UBE filter. The config file (filter.cfg by default) contains the list of filters to apply to any incoming mail. The option file (filter.opt) tells the UBE filter how to behave. It describes such things as whether or not to parse the message header file and which file to use a template reply message.
Once you have the UBE filter installed and the line entered in the plugin.conf file, you can start creating filters. To write filters you can use any text editor (notepad for NT or vi for Unix, for example) and edit the file listed in the config line from the last section.
Enter your filters one per line in the file. To enter a comment use the '#' symbol at the beginning of the line. The UBE filter will then check these filters in order from the top to the bottom (see the JUMP action for exceptions) and will apply the first rule that matches.
Filters contain from 3 to 5 parts depending on type. These parts are described below using the following example:
filter.cfg
:Testlabel Subject "Bad mail" REJECT "Do not send mail"
Subject:case "test" REJECT "Hit rule 1" Subject "test" REJECT "Hit rule 2"
Now if a message arrives with a header of "Subject: Test" it won't be caught by the first rule since it's been modified to be case sensitive. The second rule, however, is not case sensitive and thus will catch this message and reject it with a reason of "Hit rule 2".
The envonly tag tells the filter to only look at the envelope information for this field. This can prevent fake envelope information. Auth-Sender is a good example. If a user sends mail via authenticated SMTP, then the envelope will contain an Auth-Sender field you could use to assure yourself that only authenticated mail gets through. A tricky user could, however, add an Auth-Sender to the header information (remember that header information can be any field name) and then your filter would become confused. By using the envonly flag you can tell the filter that you want to consider only those fields in the envelope that is created by the server and thus cannot be tampered with.
:Label "X-Accept#" "Free stuff" REJECT "Please don't send this mail"
The following example is invalid:
:Label X-Accept# "Free stuff" REJECT "Please don't
send this mail"
This tells the UBE filter to look at both the control and header fields.
The control fields include:
Subject "This is ." REJECT "This is bad mail"
The following is a list of all the possible actions and how to use them:
COPY
Argument: a comma separated list of recipients.
Description: Copy adds its argument to the existing list of
recipients for the incoming message and then sends the list on its way.
Example: Channel-To "user1@domain\.com" COPY "postmaster,
user2"
Any mail sent to user1@domain.com is also
sent to the postmaster
and user2.
DROP
Argument: one address.
Description: sends this mail to the address in the argument
only.
Example:
User-From ".*@bulk\.com"
DROP "postmaster"
Any mail from any account at bulk.com will be dropped in the postmasters inbox but nowhere else.
DROPRCPTAny mail containing the subject "Free hamburgers!" will not be sent to
any account starting with vegetarian or green.
EXIT
Argument: No argument.
Description: This action tells the UBE filter to stop looking
at this mail and just let it through. This prevents any filters further
down the file from trapping a message though any actions already taken
still take effect.
Example: User-From "CEO@.*" EXIT
If the mail is from the CEO send it through all the time.
HOLDCOPYAny mail with the subject "Free Stuff" will be given to the postmaster.
HOLDONLY
Argument: Comma separated list of recipients followed by | followed
by a text description.
Description: This is the same as HOLDCOPY except that a copy
of the original message is not included in the notification.
Example: See HOLDCOPY
JUMP
Argument: A label that exists somewhere else in the filter config
file.
Description: When a JUMP action is initiated the flow of control
in the list of filters is changed so that the next line interpreted is
the one that starts with the given label. Using !JUMP can be
very helpful, allowing the script to skip lines if criteria isn't met.
Example:
Subject "Test" JUMP "JumpHere" Subject "Test" REJECT "This is line 2" :JumpHere Subject "Test" REJECT "This is line 3"
If a message with the subject "Test" arrives, it will cause the filter
to skip the second rule and start at the line beginning with :JumpHere
and thus the message will be rejected with the following reason: "This is line
3"
REJECT
Argument: A message that will be included in the rejected mail.
Description: This action will send the mail back to its recipient
as if it had bounced but the reason for the bounced mail will be the given
argument.
Example:
User-From "annoying@domain\.com" REJECT "Your mail is annoying; nobody wants it"
Any mail from annoying@domain.com will automatically be sent back to
annoying@domain.com with the following reason: "Your mail is
annoying; nobody
wants it".
RUN
Argument: A command line to execute.
Description: You can extend the actions by having the filter
run another program. This program must exist in the postoffice (spool)
directory for security reasons. Once the program is started the UBE
filter will pipe the header and body of the message so that you can do
whatever you want to it. You can use the special field name $&
in the next filter to match the return value of your program.
Example:
Subject "May contain a virus" RUN "VirusScan.exe" $& "1" REJECT "This had a virus"
If mail arrives with the subject "May contain a virus" then run the program VirusScan.exe. If the return value is 1, reject the message with the reason "This had a virus".
Example Script:
Following is a sample script to show the interactions that the filters can have. Following the sample script is a description of how several kinds of mail would be handled by this script.
Channel-To "monitor@domain\.com" COPY "watcher@domain.com" Subject "weapons for sale" DROP "weap@xxx.gov" Channel-To "CEO.*" JUMP "HandleCEO" :DoneCEO $# "50" REJECT "Don't send mail 50 or more" Subject "May contain a virus" RUN "VirusScan.exe" $& "1" REJECT "This had a virus" Content-Type "multipart/mixed" JUMP "HandleMime" Client "Netscape.*" !JUMP "TestClient" :DoneClient Subject ".*" EXIT :HandleCEO Subject "Postmaster Eval" HOLDCOPY "postmaster | This is your eval" $ANY ".*" JUMP "DoneCEO" :HandleMime Channel-To "nomime@domain\.com" REJECT "Can't read mime messages" $ANY ".*" EXIT :TestClient Host-From "local\.domain\.com" COPY "IS_department" $ANY ".*" JUMP "DoneClient"
Case 1:
Message for the CEO about the postmasters evaluation:
Channel-To: CEO@domain.com"
Subject "Postmaster Eval"
This message will be caught by the Channel-To "CEO.*" message which will then jump to the label :HandleCEO. The lines rule will also match because of the subject and so this message will be copied to the postmaster who can decide whether or not the CEO should see it.
Case 2:
Message for the CEO about the shareholders meeting:
Channel-To: CEO@domain.com
Subject "Shareholders meeting"
This message will be caught by the Channel-To "CEO.*" rule but won't match the first line (Subject "Postmaster Eval") but will match the next line since .* means match anything. Thus, the script will jump back up to the line starting with :DoneCEO so that the rest of the filters can still be applied to the message.
Case 3:
Message sent to an account being monitored for some reason:
Channel-To "monitor@domain.com"
Subject "illegal stock trade"
A copy of this message will be mailed to the watcher account.
Case 4:
A message arrives with all 3000 employees listed:
This will be caught by the 4th line which says that any message with 50 or more recipients regardless of any other criteria will be reject automatically.
Case 5:
The IS department has said that all mail sent from local.domain.com
must be sent using a Netscape client:
If the client doesn't start with Netscape, the filter will jump to TestClient and then check if the host the message was sent from is local.domain.com. If it is, they didn't use a Netscape product to send mail from local.domain.com so the script sends a copy to the IS department so they can handle it. Otherwise, the script jumps back up and continues.
Case 6:
The account nomime can't read mime messages:
The filter will look at the content-type; if it is a
mime message, the script jumps to :HandleMime, which checks the account--if
it is nomime, the script rejects the mail.
Using Regular Expressions
The UBE filter supports extended regular expressions compliant with POSIX 1003.2. There are several good sources of information on regular expressions, a simple internet search will provide you with all the detail you could want.
Regular Expression | Description |
. | Any single character. |
[] | Any one of the characters contained in the brackets, or any of an ASCII range of characters separated by a hyphen (-). For example, b[aeiou]d matches bad, bed, bid, bod, and bud, and r[eo]+d matches red, rod, reed, and rood, but not reod or roed. x[0-9] matches x0, x1, x2, and so on. If the first character in the brackets is a caret (^), then the regular expression matches any characters except those in the brackets. |
^ | The beginning of a line. |
$ | The end of a line |
\~ | Not the following character. For example, b\~ad matches bbd, bcd, bdd, and so on, but not bad. |
\{c\!c\} | Any one of the characters separated by the alternation symbol (\!). For example, \{j\!u\}+fruit finds jfruit, jjfruit, ufruit, ujfruit, uufruit, and so on. |
* | None or more of the preceding characters or expressions. For example, ba*c matches bc, bac, baac, baaac, and so on. |
+ | At least one or more of the preceding characters or expressions. For example, ba+c matches bac, baac, baaac, but not bc. |
\{\} | Any sequence of characters between the escaped braces. For example, \{ju\}+fruit finds jufruit, jujufruit, jujujufruit, and so on. Note that it will not find jfruit, ufruit, or ujfruit, because the sequence ju is not in any of those strings. |
[^] | Any character except those following the caret (^) character in the brackets, or any of an ASCII range of characters separated by a hyphen (-). For example, x[^0-9] matches xa, xb, xc, and so on, but not x0, x1, x2, and so on. |
\ | Removes the pattern match characteristic in the expression. For example, 100$ matches 100 at the end of a line, but 100\$ matches the character string 100$ anywhere on a line. |
() | Used to delimit arguments. When used together these aren't counted as part of the search but can then be used in later matches to retrieve specific parts of the matching string (see special properties) |
This section provides an overview on how to extend the functionality of the General Scriptable Plugin, using the Run action and the Extension library.
Using the Run Action
Using the Extension Library
The Run action allows you to invoke external programs, enabling you to perform different tasks such as virus scanning with Virus Scanner . Please see the description of the Run action in the section Pre-Defined Actions in "Unsolicited Bulk Email (UBE) filter" above for details.
The General Scriptable Plugin filter supports an extension library. In a UNIX environment, the extension library is defined as a shared object (so), and in an NT environment it is referred to as a Dynamically Linked Library (DLL).
Specifying an extension_so option in the option file, extension_so:/etc/HostNameChecker.so, enables the filter to load the shared object /etc/HostNameChecker.so into memory.
If an extension library is present at the time that an action is to be executed, the Plugin will try to locate the action name in the extension library. If an entry point with the action name is found, the entry point is invoked. If no entry point with the action name is found, the built-in default action is invoked. If no built in default action is available for that action name, the nothing action is invoked and execution of the script continues.
Each entry point in the extension library should use the following prototype:
int (*ExtpFuncAct) ( const char *arg, char *control_file, char *header_file, char *body_file, int * result );The arg is the same argument in the instruction. Control_file, header_file and body_file are the filenames of the corresponding control_file, header_file and body_file for the incoming message. The output of the external function is stored (in $&), which can be referred to in the next line of script. The return value of 0 indicates that the script should continue to execute, and any value other than 0 will cause the script to stop executing.
You can write an extension to verify hostname, to reject relaying, to perform DNS lookup, and to perform virus checking, or any other task required.
IMPORTANT: When writing an extension library for UNIX, make sure that you put extern "C" {} around your function declaration. The function name must be text symbols, not C++ symbols. Verify that with nm shared_obj.so and see if it's of type T.