LICENSE

Copyright (c) 2016-2024 G.W. Haywood. All rights reserved. With thanks to all those who have trodden these paths before, including Copyright (c) 2002-2004 Todd Vierling. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notices, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notices, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. In the case of G.W. Haywood this permission is hereby now granted.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

SYNOPSIS

Sendmail::PMilter::Context - per-connection milter context

DESCRIPTION

A Sendmail::PMilter::Context is the context object passed to milter callback functions as the first argument, typically named "$ctx" for convenience. This document details the publicly accessible operations on this object.

METHODS

$ctx->getpriv

Returns the private data object for this milter instance, set by $ctx->setpriv() (see below). Returns undef if setpriv has never been called by this milter instance.

$ctx->getsymval(NAME)

(The word 'macro' in Sendmail parlance refers to named variables which are essentially text strings. They can be defined by the MTA, and populated as messages are processed, or by milters, or by the MTA's configuration files.)

The getsymval method retrieves the macro symbol named NAME from the macros available from the MTA for the current callback. NAME is either a one- character macro name, or a multi-character name enclosed in {curly braces}. If macro NAME is undefined when getsymval is called, it returns undef.

Some common macros are given below. The milter protocol was first implemented in the Sendmail MTA, so these macro names are those used by Sendmail itself; other MTAs e.g. Postfix may provide similar macros.

$ctx->getsymval('_')

The remote host name and address, in standard SMTP "name [address]" form.

$ctx->getsymval('i')

The MTA's queue ID for the current message.

$ctx->getsymval('j')

The MTA's idea of local host name.

$ctx->getsymval('{if_addr}')

The local address of the network interface upon which the connection was received.

$ctx->getsymval('{if_name}')

The local hostname of the network interface upon which the connection was received.

$ctx->getsymval('{mail_addr}')

The MAIL FROM: sender's address, canonicalized and angle bracket stripped. (This is typically not the same value as the second argument to the "envfrom" callback.) Will be defined to the empty string '' if the client issued a MAIL FROM:<> null return path command.

$ctx->getsymval('{rcpt_addr}')

The RCPT TO: recipient's address, canonicalized and angle bracket stripped. (This is typically not the same value as the second argument to the "envrcpt" callback.)

Not all macros may be available at all times. Some macros are only available after a specific phase is reached, and some macros may only be available from certain MTA implementations. Check returned values for 'undef'. This version of the Sendmail::PMilter package collects macro values only for the following callbacks:

CONNECT HELO ENVFROM ENVRCPT DATA EOH EOM

$ctx->setpriv(DATA)

This is the place to store milter-private data that is sensitive to the current SMTP client connection. Only one value can be stored, so typically an arrayref or hashref is initialized in the "connect" callback and set with $ctx->setpriv.

This value can be retrieved on subsequent callback runs with $ctx->getpriv.

$ctx->setreply(RCODE, XCODE, MESSAGE)

Set an extended SMTP status reply (before returning SMFIS_REJECT or SMFIS_TEMPFAIL). RCODE should be a short (4xx or 5xx) numeric reply code, XCODE should be a long ('4.x.y' or '5.x.y') ESMTP reply code. The first digit of RCODE must be the same as the first digit of XCODE. There is no such restriction on the other digits. In RCODE and XCODE, 'x' should be one decimal digit; in XCODE 'y' should be either one or two decimal digits. MESSAGE is the full text of the message to send. Refer to the appropriate RFCs for actual codes and suggested messages. Examples:

$ctx->setreply(451, '4.7.0', 'Cannot authenticate you right now');
return SMFIS_TEMPFAIL;

$ctx->setreply(550, '5.7.26', 'Multiple authentication failures');
return SMFIS_REJECT;

Note that after setting a reply with this method, the SMTP result code comes from RCODE, not from the symbolic constants SMFIS_REJECT and SMFIS_TEMPFAIL. However for consistency, callbacks that set a 4xx response code should use SMFIS_TEMPFAIL, and those that set a 5xx code should return SMFIS_REJECT.

Returns 1 on success, undef on failure. In the case of failure, which is typically only caused by bad parameters, a generic message will be sent based on the SMFIS_* return code.

$ctx->setmlreply(RCODE, XCODE, MESSAGES)

Set an extended SMTP status reply (before returning SMFIS_REJECT or SMFIS_TEMPFAIL). See setreply() above for more information about the reply codes RCODE and XCODE. MESSAGES is an array which contains a multi-line reply. This array must contain no less than two string elements. Sendmail dictates that it must contain no more than 32 elements, and that each string element must contain no more than 980 characters (although any of the strings may be NULL), and no string may contain a newline ("\n") or a carriage return ("\r") character.

Example:

$ctx->setmlreply(451, '4.7.0', \('Cannot authenticate sender.',
                  'Please refer to our published policies at',
                  'http://www.example.com/policies')
                );
return SMFIS_TEMPFAIL;

Note that after setting a reply with this method, the SMTP result code comes from RCODE, not from the symbolic constants SMFIS_REJECT and SMFIS_TEMPFAIL. However for consistency, callbacks that set a 4xx response code should use SMFIS_TEMPFAIL, and those that set a 5xx code should return SMFIS_REJECT.

Returns 1 on success, undef on failure. In the case of failure, which is typically caused by bad parameters, a generic message will be sent based on the SMFIS_* return code.

$ctx->shutdown()

A special case of $ctx->setreply() which sets the short numeric reply code to 421 and the ESMTP code to 4.7.0. Under Sendmail 8.13 and higher (and you should not be using any version of Sendmail older than that), this will close the MTA's communication channel quickly, which should immediately result in a "close" callback and end of milter execution.

Returns 1.

$ctx->addheader(HEADER, VALUE)

Add header HEADER with value VALUE to this mail. Does not change any existing headers with the same name. Only callable from the "eom" callback.

Returns 1 on success, undef on failure.

$ctx->insheader(HEADER, VALUE, POSITION)

Insert header HEADER at position POSITION with value VALUE to this mail. Does not change any existing headers with the same name. Only callable from the "eom" callback. HEADER and VALUE are requred, but POSITION is optional. A POSITION value of zero is acceptable and is the default if not supplied - this inserts the HEADER before all existing headers.

Returns 1 on success, undef on failure.

$ctx->chgheader(HEADER, INDEX, VALUE)

Change the INDEX'th header of name HEADER to the value VALUE. Only callable from the "eom" callback. If INDEX exceeds the number of existing headers of name HEADER, adds another header of that name.

Returns 1 on success, undef on failure.

$ctx->addrcpt(ADDRESS)

Add address ADDRESS to the list of recipients for this mail. Only callable from the "eom" callback.

Returns 1 on success, undef on failure.

$ctx->addrcpt_par(ADDRESS,PARAMS)

Add an address ADDRESS and its ESMTP arguments PARAMS to the list of recipients for this mail. Only callable from the "eom" callback.

Returns 1 on success, undef on failure.

$ctx->delrcpt(ADDRESS)

Remove address ADDRESS from the list of recipients for this mail. The ADDRESS argument must match a prior argument to the "envrcpt" callback exactly (case sensitive, and including angle brackets if present). Only callable from the "eom" callback.

Returns 1 on success, undef on failure. A success return means that the command was queued for processing. It does not necessarily mean that the recipient was successfully removed, that information is not available from Sendmail.

$ctx->progress()

Sends an asynchronous "progress" message to the MTA, to allow longer than normal operations such as extensive message body scanning or a deliberate delay. This command should only be issued during the EOM callback, it will fail (and return undef) if called at other times.

Returns 1 if the call is made during EOM and is permitted, else undef.

$ctx->quarantine(REASON)

Quarantine the current message in the MTA-defined quarantine area, using the given REASON as a text string describing the quarantine status. Only callable from the "eom" callback.

Returns 1 on success, undef on failure.

This method is an extension that is not available in the standard Sendmail::Milter package.

$ctx->replacebody(BUFFER)

Replace the message body with the data in BUFFER (a scalar). This method may be called multiple times, each call appending to the replacement buffer. End-of-line should be represented by CR-LF ("\r\n"). Only callable from the "eom" callback.

Returns 1 on success, undef on failure.

$ctx->chgfrom(ADDRESS) =item $ctx->setsender(ADDRESS) (Deprecated)

Replace the envelope sender address for the given mail message.

Returns 1 on success, undef on failure. Successful return means that the command was queued for processing. It does not necessarily mean that the operation was successfully completed, that information is not available from Sendmail.

SEE ALSO

Sendmail::PMilter