qpsmtpd Wiki

[[api:plugin_hooks]]

You are here: start » api » plugin_hooks

Login

You are currently not logged in! Enter your authentication credentials below to log in. You need to have cookies enabled to log in.

Login

You don't have an account yet? Just get one: Register

Forgotten your password? Get a new one: Set new password

Plugin hooks

This is the list of hooks that qpsmtpd provides.

You may also want to read about the Plug-in API.

For now, the best documentation available is README.plugins and plugins.pod

FIXME

Some hooks need review…. I recommend to read the plugins.pod, as it's more up to date. Changes will go there first…and if someone writes a pod2wiki converter changes would be here faster… Done that myself :)

vetinari 2006/03/14, 2007/12/15

Hooks

hook_pre_connection

  • called: after the connection is accepted, in case of qpsmtpd-forkserver right before the fork().

Note: this isn't available in plain qpsmtpd because the connection is already open when qpsmtpd starts.

  • return codes:
    • DENY / DENY_DISCONNECT: returns a 550 to the client and ends the connection
    • DENYSOFT / DENYSOFT_DISCONNECT: returns a 451 to the client and ends the connection
    • anything else: ignored
  • arguments:

qpsmtpd-forkserver:

    my ($self,$transaction,%args) = @_;
    # %args is:
    #  %args = ( remote_ip    => inet_ntoa($iaddr),
    #            remote_port  => $port,
    #            local_ip     => inet_ntoa($laddr),
    #            local_port   => $lport,
    #            max_conn_ip  => $MAXCONNIP,
    #            child_addrs  => [values %childstatus],
    #          );
  • example plugins:
    • hosts_allow (qpsmtpd-forkserver)
    • connection_time (qpsmtpd-forkserver)

hook_connect

  • called: at the start of a connection before the greeting is sent to the connecting client
  • 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, i.e. the plugin gave the response
  • DENY - Return hard failure code and disconnect
  • DENYSOFT - Return soft failure code and disconnect
  • arguments:

FIXME do we really have a $transaction object at this time? … or “just” a $connection?

  my ($self,$transaction) = @_;
  • example plugins:
    • tls

hook_post_connection

  • called:
    • directly before the connection is finished (for example, just before the qpsmtpd-forkserver instance exits)
    • if the client drops the connection without notice (without a QUIT).
  • return codes:
    • DECLINED - next plugin
  • arguments:

my ($self, @foo) = @_; FIXME

  • example plugins:
    • connection_time

hook_logging

  • called: when a log message is written, for example in a plugin it fires if someone calls
$self->log($level, $msg);
  • return codes:
    • DECLINED - next logging plugin
    • OK (not DONE, as some might expect!) - ok, plugin logged the message
  • arguments:
   my ($self, $transaction, $trace, $hook, $plugin, @log) = @_;
   # $trace: level of message, for example LOGWARN, LOGDEBUG, ...
   # $hook:  the hook in/for which this logging was called
   # $plugin: the plugin calling this hook
   # @log:   the log message
  • example plugins:
    • all logging/*

hook_config

  • called: when a config “file” is requested, for example in a plugin it fires if someone calls

my @cfg = $self→qp→config($cfg_name);

  • return codes:
    • DECLINED - plugin didn't find the requested value
    • OK - requested values as @list, example:
    return (OK, @{$config{$value}}) if exists $config{$value};
    return (DECLINED);
  • arguments:
  my ($self,$transaction,$value) = @_; # $value: the requested config item(s)
  • example plugins:
    • http_config (qpsmtpd distribution)

hook_helo / hook_ehlo

  • called: after the client sent EHLO (hook_ehlo) or HELO (hook_helo)
  • return codes:
    • 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 EHLO/HELO message
  • arguments:
  my ($self, $transaction, $host) = @_;
  # $host: the name the client sent in the (EH|HE)LO line

hook_reset_transaction

hook_mail

  • called: after the client sent the MAIL FROM: command, the given argument is parsed by Qpsmtpd::Address and then this hook is called.
  • 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
    • DECLINED - next plugin (if any)
    • DONE - skip further processing, plugin sent response
  • arguments:
  my ($self,$transaction, $sender) = @_;
  # $sender: an Qpsmtpd::Address object for sender of the message
  • expample plugins:
    • require_resolvable_fromhost
    • check_badmailfrom
  • notes:

According to the SMTP protocol, you can not reject until after the RCPT stage (except for protocol errors, i.e. syntax errors in address). So store it in an $transaction→note() and process it later in an rcpt hook.

hook_rcpt

  • called: after the client sent an RCPT TO: the given argument is parsed by Qpsmtpd::Address, then this hook is called.
  • return codes:
    • OK - recipient allowed
    • DENY - Return a hard failure code, for example for a “User does not exist here” message
    • DENYSOFT - Return a soft failure code, for example if the connect to a user lookup database failed
    • DENY_DISCONNECT & DENYSOFT_DISCONNECT - as above but with disconnect
    • DONE - skip further processing
  • arguments:
  my ($self, $transaction, $recipient) = @_;
  # $rcpt = Qpsmtpd::Address object with the given recipient address
  • example plugins:
    • rcpt_ok

hook_data

  • called: after the client sent the DATA command, before any data of the message was sent
  • return codes:
  • 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)
  • arguments:

my ($self, $transaction) = @_;

  • example plugins:
    • greylisting

hook_data_post

  • called: after the client sent the final ”.\r\n” of a message, before the mail is sent to the queue
  • return codes:
    • 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)
  • arguments:
  my ($self, $transaction) = @_;
  • example plugins:
    • spamassassin
    • virus/clamdscan

hook_queue_pre

  • notes: new in 0.33-dev

hook_queue

  • called: after the data_post hook, used to queue the message
  • return codes:
    • DONE - skip further processing (plugin gave response code)
    • OK - Return success message, i.e. tell the client the message was queued
    • DENY - Return hard failure code
    • DENYSOFT - Return soft failure code, i.e. if disk full or other temporary queuing problems
  • arguments:
  my ($self, $transaction) = @_;
  • example plugins:
    • all queue/*

hook_queue_post

  • notes: new in 0.33-dev

hook_quit

  • called: after the client sent a QUIT command, before the hook_disconnect
  • return codes:
    • DONE - plugin sent response
    • DECLINED - next plugin and / or qpsmtpd sends response
  • arguments:

my ($self) = (@_);

  • expample plugins:
    • quit_fortune

hook_disconnect

  • called:
    • after a plugin returned DENY(|SOFT)_DISCONNECT, before connection is disconnected
    • after the client sent the QUIT command, AFTER the quit hook and ONLY if no plugin hooking “hook_quit” returned DONE
  • return codes: none, i.e. they are ignored
  • arguments:
  my ($self) = (@_);
  • example plugins:
    • logging/file

hook_unrecognized_command

  • called: if the client sent a command unknown to the core of qpsmtpd. This can be used to implement new SMTP commands or just count the number of unknown commands from the client, see below for examples.
  • return codes:
    • DENY_DISCONNECT - Return 521 and disconnect the client
    • DENY - Return 500
    • DONE - Qpsmtpd won't do anything; the plugin responded, this is what you want to return, if you're implementing new commands
    • Anything else - Return '500 Unrecognized command'
  • arguments:
  my ($self, $transaction, $cmd, @args) = @_;
  # $cmd = the first "word" of the line sent by the client
  # @args = all the other "words" of the line sent by the client
  # "word(s)": white space split() line
  • example plugins:
    • tls

hook_vrfy

  • called: if the client sents the VRFY command, defaults to returning a message telling the user to just try sending the message.
  • return codes:
    • OK - Recipient Exists
    • DENY - Return a hard failure code
    • DONE - Return nothing and move on
    • Anything Else - Return a 252
  • arguments:

FIXME, probably:

my ($self, $address) = @_;
  • example plugins:

hook_deny

  • called: after a plugin returned DENY, DENYSOFT, DENY_DISCONNECT or DENYSOFT_DISCONNECT
  • return codes:
    • DECLINED - next plugin
  • arguments:
  my ($self, $transaction, $prev_hook, $return, $return_text) = @_;
  • example plugins:
    • logging/adaptive

hook_ok

  • called: after a plugin DID NOT return DENY, DENYSOFT, DENY_DISCONNECT or DENYSOFT_DISCONNECT
  • return codes: none, i.e. they are ignored
  • arguments:
  my ( $self, $transaction, $prev_hook, $return, $return_text ) = @_;
  • example plugins:

Authentication hooks

auth

auth-plain

auth-login

auth-cram-md5