|
In Exchange
2000 Microsoft relies on the Simple Mail Transport Protocol
service (SMTP) includes with Windows 2000, which is part of IIS
5.0. This service has support to generate an event whenever a
new SMTP message is received. When this event,
OnArrival, is triggered
the message that triggered this event is accessible using
Microsoft Collaboration Data Objects (CDO). Via CDO an
application, or script, can access the data in the message and
set the status of the message that tells the SMTP service what
to do with the message. The three states the SMTP service
supports are continue sending the message, abort sending the
message and deleted it, and abort sending the message but save
it to the
BadMail.
In addition, a status can be returned to the SMTP service if the
message should be processed by other event sinks, if they exist,
or not.
In order to
have the message process by an application that application must
be registered with the SMTP service so it knows to send new
messages to the application when they are received, before
processing it further for delivery. This registration process
tells the SMTP service to make the message available to the
register CDO scripting object via a COM object.
Microsoft
provides a VBScript to register (add), remove, view, and update
event syncs on the SMTP service. This script is in the CDO
section of the Windows 2000 Platform SDK, it also been included
with this article for convenience. Using this script you can
register your own VBScript to check incoming SMTP e-mails to see
if they are spam or not. I will cover the registration process
later in this article.
Once the VBScript is registered to
process all incoming SMTP e-mails it will be passed the incoming
message, as an object. The script that processes the message is
expected to update the message if it shouldn?t be delivered and
return a status that will tell the SMTP service if it should run
any further events on this message.
Sub
ISMTPOnArrival_OnArrival(ByVal objMsg, EventStatus)
The line
above is the required sub in the VBScript that is being called
by the event sink. The
objMsg
contains the incoming SMTP message.
EventStatus is the variable
that is returned to the SMTP service that tells it if the
message should be processed by other event sinks or not. The
two supported values for
EventStatus are 0 (cdoRunNextSink)
which tells the SMTP sever to run the next event sync on the
message and 1 (cdoSkipRemainingSinks)
which lets the SMTP service know that the message is ready for
further processing.
In the script
the status of the message must be sent so the SMTP service knows
what to do with the message once the script is done running.
The
messagestatus field
(http://schemas.microsoft.com/cdo/SMTPenvelope/messagestatus,
note this is not a URL to a web page but the fully qualified
field name in the message object) supports three values. The
first value 0 (cdoStatSuccess)
informs the SMTP service to deliver the message, 2 (cdoStatAbortDelivery)
tells it to not deliver the message and delete it, and 3 (cdoStatBadMail)
tells it to not deliver the message but save a copy in the
BadMail directory on the
Exchange server. So in your script you have a choice of saving
the spam message for later referral, and I would recommend using
this option, but you need to make sure you clean out the
BadMail
directory on a regular basis to prevent the volume where it
exist on from being filled up. By default this
BadMail
directory is located on the same volume where your Exchange 2000
system files are installed under the
Exchsrv\Mailroot\vsi
1\BadMail directory.
Sub ISMTPOnArrival_OnArrival(ByVal
objMsg, EventStatus)
Set objFields = objMsg.EnvelopeFields
objFields.Item("http://schemas.microsoft.com/cdo/SMTPenvelope/messagestatus").Value
= 3
objFields.Update
EventStatus = 1
End Sub
In the above
code example the script is passed the new message and the first
line binds to the
EnvelopeFields
namespace in the message. This namespace contains a set of
fields that are present in the message while it is still in
transit.
The
messagestatus field is the
one that we will be setting in the script to control the deliver
of the message. In the example above we are setting it to 3
which will tell Exchange not to deliver the message and save it
in the
BadMail
directory.
Once this
value is set on
messagestatus the message
must be updated with the change which is done on the
objFields.Update line, this
is similar to doing a SetInfo with ADSI.
Finally we
set the
EventStatus variable to 1
which tells Exchange to skip any other event sinks and process
this message. At this point Exchange will look at the
messagestatus field to
determine what to do with the message.
The above
example if registered would prevent any incoming SMTP mail from
being delivered, which would get rid of 100% of your spam but
also would prevent 100% of all internet e-mail. So we need to
make the script do some checking to determine if the message is
spam and if it isn?t it should tell Exchange to continue
delivery of the message. |