Protocol Plug-in Programming Guide: Introducing the Protocol Level Plug-
Previous Next Contents Index


Chapter 1 Introducing the Protocol Level Plug- in API

This chapter explains how you can use protocol level plug-ins, tells how they work in Messaging Server, and describes building and installing protocol level plug-ins.

A Protocol Level SMTP plug-in, called a shared object or shared library, is written in the C/C++ language, using the Protocol Level Plug-in API. Your plug-in becomes part of the server address space.

The Protocol Level plug-in interface allows third-party developers to write plug-ins that detect and act on messages at the SMTP protocol level of message processing, before an incoming message is accepted and written to disk by SMTP. Protocol plug-ins can reject a message before it is received by your host, prevent delivery of UBE or other authorized messages to your site, or change or process a message as it is being received.

The chapter has the following sections:


How You Can Use Protocol Level Plug-ins
You can use the plug-ins you write using the Protocol Level plug-in API in a variety of ways to prevent UBE (Unsolicited Bulk Mail) problems.

Here's what you cannot do with the Protocol Level Plug-in API:

Note
The Protocol Level Plug-in API for Messaging Server 4.1 is available on the Solaris, HP-UX 11.00, DEC UX, SGI IRIX, and AIX platforms. §

For general information about the functionality and operation of Messaging Server, the way that plug-ins work in it, and the way that users can manipulate them through Netscape Console, see the Messaging Server 4.1 Administrator's Guide.


Protocol Level Plug-ins in Messaging Server 4.1
Two protocol level plug-ins are installed with Messaging Server 4.1, the Anti-Relay plug-in and the Tracer plug-in.


How Protocol Level Plug-ins Work
A protocol level plug-in is called at the PreSMTPAccept stage of message processing, before an incoming message has been accepted and written to disk by SMTP.

Note. You can also write plug-ins that act at the PostSMTPAccept stage (called immediately after the message is received) and at the PreSMTPDeliver stage (called just before the message is handed off to another host). For more information, see the Messaging Server Plug-in API Guide. §

Each protocol level plug-in module must export the functions in the Protocol Level Plug-in API. These functions are introduced in "Using Protocol Level Plug-in Functions."

At start-up time, Messaging Server loads and initializes the configured protocol level plug-in module or PPModule. When a connection to the server is established, a new protocol level plug-in session is created. Protocol plug-in modules are loaded in the stack in the order of initialization, with the first plug-in (ProtPlug) on the top and the default server at the bottom.

Each incoming command is passed to the top plug-in for processing. This plug-in can either pass control to the next protocol level plug-in down (defer), make a decision to act on the line in some way, or do nothing. Each plug-in in the calling hierarchy can prevent those below it from being called or change the information that it passes to them.

For example, if the server is configured with the plug-ins libPPMrcptcheck.so, libPPMauthhack.so, and libPPMgrammarstickler.so, the protocol line stack appears as in this diagram:

Figure 1.1    How plug-ins work

In this example, the plug-in libPPMrcptcheck.so is called first, since it is at the top of the stack. The line is passed to each plug-in in turn, until it reaches the default server. At this point, the plug-in calling sequence unwraps by returning to its calling plug-in successively until it reaches the top of the stack again.

In general, a protocol level plug-in should return PP_SKIP, unless the line is one that the plug-in needs to act upon. This return value means that the command was ignored, and subsequent lines for the command should not be sent to this ProtPlug. The plug-in's ProtPlug_ProcessLine function is not called again until this command has finished. This speeds up the SMTP DATA command.

If a protocol level plug-in decides to defer to the next plug-in on the stack, it should avoid changing the return value of its DeferLine function. For more information, see "Passing Control to the Next Plug-in."

Multithreading, Global Data, and Mutex
Messaging Server 4.1 is multithreaded; make sure that your plug-in code is thread-safe. In particular, the API functions PPModule_Init, PPModule_NewProtPlug, and ProtPlug_ProcessLine are called in a multi-threaded context.

If you decide to use global data, be sure to use the mutex synchronization object, represented by the PPMutex structure in this API. You handle this structure through the function pointers provided in the ProtPlugSystem structure. This structure is passed as a parameter to the PPModule_Init function. Be careful to delete any mutex object that you create. For more information, see PPMutex.

Warning. Before you write a protocol level plug-in, you should have a thorough understanding of global data and multithreaded programming. §

Memory Use
To allocate memory, you cannot use system routines that allocate their own memory, for example, strdup. You must write your own routine that uses the plug-in memory allocation routines. For example, the Anti-Relay plug-in uses a routine called ARStrdup.


Configuring Messaging Server
To allow the server to recognize and load your plug-in, you use the configutil utility to set the "service.smtp.protplugmodules" configuration option locally. This option specifies one or more plug-ins to be loaded by smtpd when it starts up.

For the option value, you enter a list of plug-ins or shared objects separated by dollar signs ($). Use the full path if the object is not in a directory that the server is already looking in as a default, such as bin/msg/lib, where the server resides. For example, the following command configures the server to load the Anti-Relay plug-in and another plug-in, more.so:

configutil -l -o service.smtp.protplugmodules 
-v 'antirelay.so$more.so'
The -l flag tells the server to run the plug-in locally. The -o and -v flags, when used with -l, specify that a configuration option value should be stored in the local server configuration file.

For information about configutil and its options, see Appendix A, "Command-line Utilities," in the Messaging Server 4.1 Administrator's Guide.

Before you run configutil, set the environment variable CONFIGROOT to the config directory for the server instance, for example, /usr/netscape/suitespot/msg-hostname/config.

To make it possible for configutil to find the shared libraries required by the plug-in, set a shared library path variable for your platform. For example, you could set a variable such as LD_LIBRARY_PATH to [server-root]/bin/msg/lib.

If your plug-in uses hostname-based rules, such as *.netscape.com, be sure to turn on hostname resolution in the SMTP server. Otherwise, the server cannot match the IP addresses to the hostname patterns and treats every host as untrusted.


Building Protocol Level Plug-ins
To build your protocol level plug-in shared library, you can write a makefile that includes build instructions or adapt the sample makefile that is included with the Anti-Relay plug-in. This makefile should be usable or easily adaptable to most Unix platforms. By default, the file uses GCC (Gnu Compiler); this is usually the easiest compiler package to get.

You may need to modify the values in the makefile to make it build on your particular platform. Make sure that the shared object you build contains position-independent code.

Once the makefile is configured for your platform, type this command:

gmake -f Makefile.antirelay
When the build is complete, copy the shared object, for example, antirelay.so, to the location where you want it to reside in your server installation.

If the plug-in is not working the way that you expect, for example, if the smtpd is crashing, try building the plug-in with debugging enabled to generate more verbose logging. To use debugging, uncomment the line in the makefile where FLAGS is defined to be -D_DEBUG. Rebuild the plug-in and copy the new shared object into place.

Now stop and start the server. Once the server is started, run your test and then go look at instance-dir/log/smtp/smtp. This location should contain log messages about the plug-in, generated by smtpd, and from the plug-in itself.

If you are building your plug-in shared library as a C++ application, make sure that the functions expected by the MTA are extern "C." This ensures that the MTA can find the function symbols.


Installation for Protocol Level Plug-in Users
When you write a protocol level plug-in for others to use, you are responsible for writing the installation routine that the user needs to install it in Messaging Server (along with any additional files the plug-in requires). To do this, you can simply write an installation script that calls configutil. See "Building Protocol Level Plug-ins."

For general information about installing protocol plug-ins, consult the directions for installing the Anti-Relay plug-in, a protocol level plug-in that comes with Messaging Server, in Chapter 7, "Working With SMTP Plug-Ins," in the Messaging Server 4.1 Administrator's Guide.

 

© Copyright 1999 Netscape Communications Corp., a subsidiary of America Online, Inc. All rights reserved.