71f6fc1dff
Re-order plugin docs to appear in the order things generally get called Fix SMTP.pm to reflect what's documented in README.plugins :-) git-svn-id: https://svn.perl.org/qpsmtpd/trunk@471 958fd67b-6ff1-0310-b445-bb7760255be9
272 lines
7.3 KiB
Plaintext
272 lines
7.3 KiB
Plaintext
#
|
|
# read this with 'perldoc README.plugins' ...
|
|
#
|
|
|
|
=head1 qpsmtpd plugin system; developer documentation
|
|
|
|
See the examples in plugins/ and ask questions on the qpsmtpd
|
|
mailinglist; subscribe by sending mail to qpsmtpd-subscribe@perl.org.
|
|
|
|
=head1 General return codes
|
|
|
|
Each plugin must return an allowed constant for the hook and (usually)
|
|
optionally a "message".
|
|
|
|
Generally all plugins for a hook are processed until one returns
|
|
something other than "DECLINED".
|
|
|
|
Plugins are run in the order they are listed in the "plugins"
|
|
configuration.
|
|
|
|
=over 4
|
|
|
|
=item OK
|
|
|
|
Action allowed
|
|
|
|
=item DENY
|
|
|
|
Action denied
|
|
|
|
=item DENYSOFT
|
|
|
|
Action denied; return a temporary rejection code (say 450 instead of 550).
|
|
|
|
=item DENY_DISCONNECT
|
|
|
|
Action denied; return a permanent rejection code and disconnect the client.
|
|
Use this for "rude" clients. Note that you're not supposed to do this
|
|
according to the SMTP specs, but bad clients don't listen sometimes.
|
|
|
|
=item DENYSOFT_DISCONNECT
|
|
|
|
Action denied; return a temporary rejection code and disconnect the client.
|
|
|
|
=item DECLINED
|
|
|
|
Plugin declined work; proceed as usual. This return code is _always_
|
|
_allowed_ unless noted otherwise.
|
|
|
|
=item DONE
|
|
|
|
Finishing processing of the request. Usually used when the plugin
|
|
sent the response to the client.
|
|
|
|
=back
|
|
|
|
See more detailed description for each hook below.
|
|
|
|
=head1 Hooks
|
|
|
|
=head2 pre-connection
|
|
|
|
Called by a controlling process (e.g. forkserver or Apache::Qpsmtpd) after
|
|
accepting the remote server, but before beginning a new instance. Useful for
|
|
load-management and rereading large config files at some frequency less than
|
|
once per session. The hook doesn't have a predefined additional input value,
|
|
but one can be passed as a hash of name/value pairs.
|
|
|
|
=head2 post-connection
|
|
|
|
Like pre-connection only it can be called after an instance has been
|
|
completely finished (e.g. after the child process has ended in forkserver).
|
|
The hook doesn't have a predefined additional input value, but one can be
|
|
passed as a hash of name/value pairs.
|
|
|
|
|
|
=head2 connect
|
|
|
|
Allowed return codes:
|
|
|
|
OK - Stop processing plugins, give the default response
|
|
DECLINED - Process the next plugin
|
|
DONE - Stop processing plugins and don't give the default response
|
|
DENY - Return hard failure code and disconnect
|
|
DENYSOFT - Return soft failure code and disconnect
|
|
|
|
Note: DENY_DISCONNECT and DENYSOFT_DISCONNECT are not supported here due to
|
|
them having no meaning beyond what DENY and DENYSOFT already do.
|
|
|
|
|
|
=head2 helo
|
|
|
|
Called on "helo" from the client.
|
|
|
|
DENY - Return a 550 code
|
|
DENYSOFT - Return a 450 code
|
|
DENY_DISCONNECT & DENYSOFT_DISCONNECT - as above but with disconnect
|
|
DONE - Qpsmtpd won't do anything; the plugin sent the message
|
|
DECLINED - Qpsmtpd will send the standard HELO message
|
|
|
|
|
|
=head2 ehlo
|
|
|
|
Called on "ehlo" from the client.
|
|
|
|
DENY - Return a 550 code
|
|
DENYSOFT - Return a 450 code
|
|
DENY_DISCONNECT & DENYSOFT_DISCONNECT - as above but with disconnect
|
|
DONE - Qpsmtpd won't do anything; the plugin sent the message
|
|
DECLINED - Qpsmtpd will send the standard HELO message
|
|
|
|
|
|
=head2 mail
|
|
|
|
Called right after the envelope sender address is passed. The plugin
|
|
gets passed a Mail::Address object. Default is to allow the
|
|
recipient.
|
|
|
|
Allowed return codes
|
|
|
|
OK - sender allowed
|
|
DENY - Return a hard failure code
|
|
DENYSOFT - Return a soft failure code
|
|
DENY_DISCONNECT & DENYSOFT_DISCONNECT - as above but with disconnect
|
|
DONE - skip further processing
|
|
|
|
|
|
=head2 rcpt
|
|
|
|
Hook for the "rcpt" command. Defaults to deny the mail with a soft
|
|
error code.
|
|
|
|
Allowed return codes
|
|
|
|
OK - recipient allowed
|
|
DENY - Return a hard failure code
|
|
DENYSOFT - Return a soft failure code
|
|
DENY_DISCONNECT & DENYSOFT_DISCONNECT - as above but with disconnect
|
|
DONE - skip further processing
|
|
|
|
|
|
=head2 data
|
|
|
|
Hook for the "data" command. Defaults to '354, "go ahead"'.
|
|
|
|
DENY - Return a hard failure code
|
|
DENYSOFT - Return a soft failure code
|
|
DENY_DISCONNECT & DENYSOFT_DISCONNECT - as above but with disconnect
|
|
DONE - Plugin took care of receiving data and calling the queue (not
|
|
recommended)
|
|
|
|
|
|
=head2 data_post
|
|
|
|
Hook after receiving all data; just before the message is queued.
|
|
|
|
DENY - Return a hard failure code
|
|
DENYSOFT - Return a soft failure code
|
|
DENY_DISCONNECT & DENYSOFT_DISCONNECT - as above but with disconnect
|
|
DONE - skip further processing (message will not be queued)
|
|
|
|
All other codes and the message will be queued normally
|
|
|
|
|
|
=head2 queue
|
|
|
|
Called on completion of the DATA command, after the data_post hook.
|
|
|
|
DONE - skip further processing (plugin gave response code)
|
|
OK - Return success message
|
|
DENY - Return hard failure code
|
|
DENYSOFT - Return soft failure code
|
|
|
|
Any other code will return a soft failure code.
|
|
|
|
|
|
=head2 quit
|
|
|
|
Called on the "quit" command.
|
|
|
|
Allowed return codes:
|
|
|
|
DONE
|
|
|
|
Works like the "connect" hook.
|
|
|
|
|
|
=head2 unrecognized_command
|
|
|
|
Called when we get a command that isn't recognized.
|
|
|
|
DENY - Return 521 and disconnect the client
|
|
DONE - Qpsmtpd won't do anything; the plugin responded
|
|
Anything else - Return '500 Unrecognized command'
|
|
|
|
=head2 disconnect
|
|
|
|
Called just before we shutdown a connection.
|
|
|
|
The return code is ignored. If a plugin returns anything but DECLINED
|
|
the following plugins will not be run (like with all other hooks).
|
|
|
|
=head2 deny
|
|
|
|
Called when another hook returns DENY or DENYSOFT. First parameter is
|
|
the previous hook return code; the second parameter the message the
|
|
hook returned.
|
|
|
|
Returning DONE or OK will stop the next deny hook from being run.
|
|
DECLINED will make qpsmtpd run the remaining configured deny hooks.
|
|
|
|
=head2 vrfy
|
|
|
|
Hook for the "VRFY" command. Defaults to returning a message telling
|
|
the user to just try sending the message.
|
|
|
|
Allowed return codes:
|
|
|
|
OK - Recipient Exists
|
|
DENY - Return a hard failure code
|
|
DONE - Return nothing and move on
|
|
Anything Else - Return a 252
|
|
|
|
=head1 Return Values and Notes
|
|
|
|
Insert stuff here about how:
|
|
|
|
- if we're in a transaction, the results of a callback are stored
|
|
in
|
|
$self->transaction->notes( $code->{name})->{"hook_$hook"}->{return}
|
|
|
|
- if we're in a connection, store things in the connection notes instead.
|
|
|
|
|
|
=head1 Include Files
|
|
|
|
(put more about how the $Include stuff works here)
|
|
|
|
With the $Include stuff you order using the filename of the plugin.d
|
|
file. So if you have a plugin called xyz but want it to come early on,
|
|
you call it's config file 00_xyz, but that file still refers to the
|
|
plugin called xyz.
|
|
|
|
=head1 Temporary Files
|
|
|
|
The temporary file and directory functions can be used for plugin specific
|
|
workfiles and will automatically be deleted at the end of the current
|
|
transaction.
|
|
|
|
=over 4
|
|
|
|
=item temp_file()
|
|
|
|
Returns a unique name of a file located in the default spool directory, but
|
|
does not open that file (i.e. it is the name not a file handle).
|
|
|
|
=item temp_dir()
|
|
|
|
Returns the name of a unique directory located in the default spool
|
|
directory, after creating the directory with 0700 rights. If you need a
|
|
directory with different rights (say for an antivirus daemon), you will
|
|
need to use the base function $self->qp->temp_dir() which takes a single
|
|
parameter for the permissions requested (see L<mkdir> for details). A
|
|
directory created like this will B<not> be deleted when the transaction is
|
|
ended.
|
|
|
|
=item spool_dir()
|
|
|
|
Returns the configured system-wide spool directory.
|
|
|
|
=back
|