Plugin Interfaces in Jsmtpd

General informations

Plugins are JavaBeans, that are loaded by a specialiased compononent, PluginLoader. Each public property must have at least a setter method associated, thus allowing the plugin loader to dynamicly configure them with informations taken from the XML configuration file. Plugins are instantiated once for all the application, but do not define any synchronisation mechanism, as most of the plugins don't need this. Plugins needing shared states must ensure themselves thread synchronisation, as long as they'll probably be used from multi-threaded environement.

IGenericPlugin

Any plugin in the server implements this interface. It's used to provide a common way for loading/unloading plugins.

public interface IGenericPlugin {
    public String getPluginName();
    public void initPlugin() throws PluginInitException;
    public void shutdownPlugin();
}

The getPluginName method should return a human understandable String, it is shown in the logg. The initPlugin mehtod is called by the PluginLoader upon statup, after setting the configuration properties. The shutdownPlugin method is called at server's shutdown, in case your plugin needs to save informations, close ressources, etc...

IACL

There is one ACL component running in Jsmtpd. It takes care of allowing or denying permissions in the deamon.

public interface IACL extends IGenericPlugin {
    public boolean isValidAddress(EmailAddress address);
    public boolean isValidAddressWildCard(EmailAddress e);
    public boolean isValidAddressStandardUser(EmailAddress e);
    public boolean isValidRelay(String hostIP);
}

isValidRelay tells the server wether to relay or not a particular host. isValidAddress tells if a given address is handled locally or not (local domain). It should return a or operation between wildcard and standard checks defined bellow. isValidAddressWildCard if a wildcard address has been defined for the domain, this test should be positive isValidAddressStandardUser indicates the address is a real user in the system.

IDeliveryService

This interface is implemented by mail delivery plugins. Jsmtpd comes with two basic implementations : a local mbox writer (writes mails for local users to mailbox format) and a remote smtp sender (delivers mails to remote smtp servers). Another possible implementation could be database mail writer by example.

public interface IDeliveryService extends IGenericPlugin {
    public void doDelivery(Email in, List rcpts);
}

The server prepares batches, it groups the recipients of a mail per domain, then invokes the apropriate delivery plugin with this list of recipients.

IDNSService

The IDNSService interface is implemented by DNS plugin providers, they convert names to network addresses.

public interface IDNSResolver extends IGenericPlugin {
    public LinkedList doMXLookup(String name);
    public boolean exists(String name);
    public InetAddress doLookupToIp(String name);
    public String doReverseLookup(InetAddress in);
}

This plugin is used by the remote SMTP Sender to determine the server to connect to, and by the RBL filter to query black list provider servers.

IFilter

This interface is implemented by mail content filter plugins. They scan the content of mail and return true or false. Filters are organised using a binary tree model. Finally, filters can alter/change the content of a mail.

public interface IFilter extends IGenericPlugin {
    public boolean doFilter(Email input) throws FilterTreeFailureException, FilterTreeSuccesException;
}

InputIPFilter

Filters implementing this interface are used upon connection, to determine if the remote host connecting to the service is an open relay or a well known spammer. The filters are linked in a chain model, any failure breaks the connection.

public interface IFilterIP extends IGenericPlugin {
    public boolean checkIP(InetAddress input);
}

ISmtpExtension

Theses plugins adds smtp functionalities to the basic RFC 821 smtp abilities of Jsmtpd.

public interface ISmtpExtension extends IGenericPlugin {
    public boolean smtpTrigger (String command, IProtocolHandler protocol) throws SmtpExtensionException, IOException, InputSizeToBig, IOException, BareLFException;
    public String getWelcome();
}

During the EHLO chat (when a client connects), Jsmtpd will expose the SMTP extensions loaded, by querying the getWelcome method on each smtp extension plugin, and returning the data to the client. When Jsmtpd's protocol handler does not known a command issued by the client, it passes the command received to each SMTP extension, and the instance of himslef. At that momment, the plugin takes control of the SMTP chat, an can remote drive the basic protocol handler. By example, if the client issues a STARTTLS command, the TLSSwitcher plugin takes control of the chat, changes the socket to a SSL wrapped one in the protocol handler, and indicates it the channel is secured.

Missing functionalities

A security service able to authentify user using a token, a login/password or whatever. Could be used by ACL, authentication smtp extensions, or a future embeded pop3 server.

The ISmtpExtension can't handle all the smtp extensions, some requires modifications to the core. This is not the perfect solution, but at least a simple way to handle the most common ones.

A ressource monitor/controler provider. To dynamicly increase/decrease the amount of simultaneous jobs depending on CPU and memmory usage.

A way to dynamcly inject dependancies between plugins, without messing the configuration files.