Provided by: libbobcat-dev_6.11.00-1_amd64 bug

NAME

       FBB::Milter - Interface to the sendmail mail filter facilities

SYNOPSIS

       #include <bobcat/milter>
       Linking option: -lmilter -lbobcat

DESCRIPTION

       Milter  defines  an  abtract  base  class interfacing to the sendmail mail filter (milter) facilities. It
       defines a C++ interface, based on the assumption that a single mail filter  program  does  not  implement
       multiple  mail filters. The traditional sendmail C-based Milter API uses a (SMFICTX) pointer representing
       a mail connection, and a pointer to connection-specific `private’ data, requiring the Milter  constructor
       to  perform  quite  a  few  administrative tasks. While acceptable in a C environment these administratve
       tasks distract from the main task: the Milter’s mail filtering functionality. The FBB::Milter class hides
       these administrative tasks from the programmer, who is then able to concentrate on  filtering  mail.  The
       main benefits of Milter are therefore

       o      Basic administration is performed by the Milter class

       o      The class’ interface is more C++ like than the raw C interface offered by the milter API.

       o      Administration, allocation and communicating of connection specific data is no longer required

       o      It  is  not  normally  necessary  to  use connection-specific data, like a pointer identifying the
              connection, anymore when implementing the Milter.

       o      Milter uses current-day design patterns enforcing principles of reuable software, thus simplifying
              the construction of the actual Milter.  To activate a milter from  the  sendmail.mc  configuration
              file,  use,  e.g.,  INPUT_MAIL_FILTER(`name’,  `S=socket’),  where  name is the milter’s name, and
              socket is the name of the socket. See also the setConnection member below.

NAMESPACE

       FBB
       All constructors, members, operators and manipulators, mentioned in this man-page,  are  defined  in  the
       namespace FBB.

INHERITS FROM

       -

ENUMERATIONS

       The  class defines four (public) enumerations. One enumeration is used to indicate the callback-functions
       that need to be called, the second one renames the flags that can be passed to sendmail to indicate which
       actions the milter is allowed to perform. The third one defines status values that may be used to  inform
       sendmail how to further process a message. The fourth one defines return values. The enumerations are:

       enum CallBack
       This enumeration holds the following values:

       o      CONNECT:
              Indicates  that  the  milter  defines  (overrides) the connection-functionality. This is the first
              callback function that can be called by sendmail;

       o      HELO:
              Indicates that the milter defines (overrides) the helo-functionality. This indicates that the helo
              function should be called by sendmail, providing the milter with information about the  connecting
              client;

       o      SENDER:
              Indicates  that  the  milter defines (overrides) the sender-functionality. This indicates that the
              sender function should be called by sendmail, providing the  milter  with  the  sender’s  envelope
              (initial From ... line) information;

       o      RECIPIENT:
              Indicates that the milter defines (overrides) the recipient-functionality. This indicates that the
              recipient  function  should  be  called  by  sendmail,  providing  the milter with the recipient’s
              envelope (To: ... header address) information;

       o      HEADER:
              Indicates that the milter defines (overrides) the header-functionality. This  indicates  that  the
              header function should be called by sendmail for each mail header that is used in the current mail
              message;

       o      EOH:
              Indicates that the milter defines (overrides) the end-of-header-functionality. This indicates that
              the eoh function should be called by sendmail once all header lines have been processed;

       o      BODY:
              Indicates that the milter defines (overrides) the body-functionality. This indicates that the body
              function should be called by sendmail, offering the mail-body to the milter;

       o      EOM:
              Indicates  that  the  milter  defines (overrides) the end-of-message-functionality. This indicates
              that the eom function should be called by sendmail, once all elements of the e-mail  message  have
              been processed;

       o      ABORT:
              Indicates  that  the milter defines (overrides) the abort-functionality. The abort function may be
              called by sendmail before eom is called. It should reclaim all resources used by the message,  but
              not delete any memory allocated by the milter, as this is close’s job;

       o      CLOSE:
              Indicates  that  the milter defines (overrides) the close-functionality. The close function should
              delete all (connection specific) memory allocated by the milter. It may be called  `out-of-order’,
              i.e. even before connect is called and developers should anticipate this possibility when crafting
              their  close  code.  In  particular, it is incorrect to assume the private context pointer will be
              something other than 0 in this callback;

       o      UNKNOWN:
              Currently not used. Reserved for versions exceeding version 2 of the sendmail milter API;

       o      DATA:
              Currently not used. Reserved for versions exceeding version 3 of the sendmail milter API;

       o      ALL_CALLBACKS:
              Shortcut to indicate all callback facilities.  The  CallBack  values  are  bit-flags.  The  bit_or
              operator  may  be used to combine them, and the bit_not operator may be used to remove a flag from
              ALL_CALLBACKS (e.g., ALL_CALLBACKS && ~ABORT).

       enum Flags
       This enumeration holds the following values:

       o      NO_FLAGS:
              No flags are defined;

       o      ADD_HEADERS:
              This flag indicates that the milter is allowed to add headers to the current e-mail message;

       o      ADD_RECIPIENTS:
              This flag indicates that the milter is allowed to add recipients to the current e-mail message;

       o      CHANGE_BODY:
              This flag indicates that the milter is allowed to modify the message’s body content;

       o      CHANGE_HEADERS:
              This flag indicates that the milter is allowed to change headers of the current e-mail message;

       o      DELETE_RECIPIENTS:
              This flag indicates that the milter is allowed  to  remove  recipients  from  the  current  e-mail
              message;

       o      QUARANTINE:
              This  flag  indicates  that  the  milter  is allowed to request sendmail to quarantine the current
              e-mail message;

       o      ALL_FLAGS:
              Shortcut to indicate all callback facilities. The Flags values are bit-flags. The bit_or  operator
              may  be used to combine them, and the bit_not operator may be used to remove a flag from ALL_FLAGS
              (e.g., ALL_FLAGS && ~QUARANTINE).

       Status
       This enumeration simplifies the extended SMFIS_ values used by the C API. These values  may  be  used  to
       return  sfsistat values:

       o      ACCEPT:
              This  value  is  equal  to SMFIS_ACCEPT, indicating that Sendmail should accept the message. For a
              connection-oriented callback (see below  at  PROTECTED  VIRTUAL  MEMBER  FUNCTIONS),  accept  this
              connection without further filter processing, call close (see below).  For other callbacks: accept
              this message without further filtering;

       o      CONTINUE:
              This  value  is equal to SMFIS_CONTINUE, indicating that Sendmail should continue processing. This
              is the default for all callback functions which are not  overridden  by  the  class  derived  from
              Milter;

       o      DISCARD:
              This value is equal to SMFIS_DISCARD, indicating that Sendmail should discard the mail message. It
              should  not  be  returned  by  a connection-oriented callback. For other callbacks: the message is
              accepted, but silently discarded;

       o      REJECT:
              This value is equal to SMFIS_REJECT, indicating that Sendmail should reject the mail message.  For
              a  connection-oriented  callback,  reject  this  connection;  call  close.  For a message-oriented
              callback (except for eom or abort, see below), reject  this  message.   For  a  recipient-oriented
              callback, reject the current recipient (but continue processing the current message);

       o      TEMPFAIL:
              This  value  is  equal  to  SMFIS_TEMPFAIL,  indicating  that  Sendmail should return a `temporary
              unavailable’ message to the sender of the mail message. For a  message-oriented  callback  (except
              sender,  see  below),  fail  for  this message.  For a connection-oriented callback, fail for this
              connection and call close.  For a recipient-oriented callback, only fail for the current recipient
              and continue message processing.

       Return
       This enumeration simplifies the extended MI_ values used by the C API. Most return  values  used  by  the
       Milter class, however, are bool values. The Return values are:

       o      FAILURE:
              This value is equal to MI_FAILURE, indicating that a C-api function failed to perform its task;

       o      SUCCESS:
              This  value  is  equal to MI_SUCCESS, indicating that a C-api function succeeded in performing its
              task.

CONSTRUCTOR/DESTRUCTOR

       o      Milter():
              The default constructor is available for derived classes. It performs no actions;

       o      virtual ~Milter():
              The (public) virtual destructor performs no actions: derived classes can override  the  destructor
              to suit their own needs.

       Overloaded assignment operators are not available.

PUBLIC STATIC MEMBER FUNCTIONS

       These functions form the heart of the Milter base-class. They can be called to initialize, start and stop
       the Milter.

       o      void  initialize(std::string  const  &name,  Milter  &milter,  callback_set  callbacks  = CONNECT,
              flag_set flags = NO_FLAGS):
              This function initializes the Milter’s administration. It expects the name of  the  mailfilter  as
              its  first  argument.  Its  second  argument is a reference to a Milter object. Since Milter is an
              abstract base class the actual object is always an object of a class  derived  from  Milter.   Its
              third  argument  specifies the callbacks to call for this milter. By default the connect and close
              callbacks are called. Starting bobcat version 6.04.00 the close callback is always called  once  a
              connection  ends:  it may be specified when specifying the callbacks argument, but if not then the
              close callback is  still  called.  The  last  argument  defines  flags,  specifying  the  Milter’s
              capabilities;

       o      std::string const &name():
              This function returns the milter’s name;

       o      bool start():
              This  member function calls smfi_main, controlling the milter’s event loop. It returns true if the
              event-loop is successfully terminated;

       o      void stop():
              This member function terminates the milter’s event loop, after finishing  all  threads.  Following
              this call start may be called again to continue the milter.

PROTECTED MEMBER FUNCTIONS

       The following members are non-virtual. They can be called by members of classes derived from Milter:

       o      bool addHeader(std::string const &hdrName, std::string const &hdrValue):
              This  member  may only be called from eom, and the flag ADD_HEADERS must have been specified or it
              will fail.  The hdrName and hdrValue must be non-empty strings. Each line of the  header  must  be
              under  2048 characters and should be under 998 characters. If longer headers are needed, make them
              multi-line. To make a multi-line header, insert  a  line  feed  (\n)  followed  by  at  least  one
              whitespace  character  such  as  a  space  or  tab (\t). The line feed should not be preceded by a
              carriage return. It is the  filter  writer’s  responsibility  to  ensure  that  no  standards  are
              violated;

       o      bool addRecipient(std::string const &rcptName):
              This  member  may only be called from eom, and the flag ADD_RECIPIENTS must have been specified or
              it will fail;

       o      bool changeHeader(std::string const &hdrName, size_t headerNr, std::string const &hdrValue):
              This member may only be called from eom, and the flag CHANGE_HEADERS must have been  specified  or
              it  will  fail.  See  addHeader  for  the header-requirements. The headerNr parameter is a 1-based
              header index value. A headerNr value of 1 will modify the  first  occurrence  of  a  header  named
              hdrValue.  If  headerNr  is greater than the number of times hdrName appears, a new hdrName-header
              will be added. If hdrValue is empty, the header is deleted;

       o      bool deleteRecipient(std::string const &rcptName):
              This member may only be called from eom, and the flag DELETE_RECIPIENTS must have  been  specified
              or it will fail.  This member removes the named recipient from the current message’s envelope;

       o      SMFICTX *id() const:
              This   member   may  be  called  by  the  Milter  object  to  obtain  a  pointer  identifying  its
              sendmail-connection. Normally it should not be necessary to call this member;

       o      bool insertHeader(size_t hdrIdx, std::string const &hdrName, std::string const &hdrValue):
              This member may only be called from eom, and the flag ADD_HEADERS must have been specified  or  it
              will  fail.  See  addHeader  for the header-requirements. The headerNr parameter is a header index
              value. A headerNr value of 0 will insert this header as the  first  of  the  hdrName  headers.  If
              headerNr is greater than the number of times hdrName appears, a new hdrName-header will be added;

       o      bool openSocket(bool removeIfTrue = true):
              This  member  should  be called before start is called.  This member attempts to create the socket
              specified by setConnection (see below). This allows the calling application  to  ensure  that  the
              socket  can  be created, possibly changing its protection (access rights) before the milter starts
              its work.  If this member is not called, it will be called implicitly  when  run  is  started.  It
              returns true if the socket could be created;

       o      bool quarantine(std::string const &reason):
              This  member  may  only be called from eom and causes the MTA to quarantines the message using the
              given reason;

       o      bool replaceBody(std::string const &body):
              This member may only be called from eom, and the flag CHANGE_BODY must have been specified  or  it
              will fail. It may be called multiple times in which case the various body content are concatenated
              in the final message. Newlines should be coded as CRLF;

       o      bool setBacklog(size_t backlog = 5):
              This  member  should  be  called before start is called.  Sets the incoming socket backlog used by
              listen(2).  If setBacklog is not called, the  operating  system  default  is  used.  The  function
              returns  false  if  the  backlog  could  not be set as requested.  It is the responsibility of the
              programmer not to call this function with a 0 argument;

       o      bool setConnection(std::string const &name):
              This member should be called before start is called.  Sets the socket  through  which  the  filter
              communicates with sendmail.  The socket may be specified using one of the following variants:
              {unix|local}:/path/to/file - A named pipe;
              net:port@{hostname|ip-address} - An IPV4 socket;
              inet6:port@{hostname|ip-address} - An IPV6 socket.

              If possible, filters should not run as root when communicating over unix/local domain sockets.

              Unix/local  sockets  should have their permissions set to 0600 (read/write permission only for the
              socket’s owner) or 0660 (read/write permission for the socket’s owner and group) which  is  useful
              if  the  sendmail  RunAsUser  option  is  used. The permissions for a unix/local domain socket are
              determined as usual by umask, which should be set to 007 or 077.

              Possible failure of this function cannot be determined from its return  value.  Rather,  run  will
              fail;

       o      setReply(std::string const &rcode, std::string const &xcode = "", std::string const &msg = ""):
              This  member  sets  the default SMTP error reply code.  It may be called from any callback member,
              except connect. The parameter rcode should be a he three-digit (RFC 821/2821) SMTP reply code  and
              it  must be a valid 4XX or 5XX reply code. The parameter xcode, when specified, must be a extended
              (RFC 1893/2034) reply code. The parameter msg may be an additional  textual  message.  The  Milter
              class has no member comparable to the libmilter API function smfi_setmlreply.  the Milter class;

       o      void setTimeout(size_t seconds = 7210):
              This  member  should  be called before start is called.  Sets the number of seconds libmilter will
              wait for an MTA connection before timing out a socket. If setTimeout  is  not  called,  a  default
              timeout  of  7210  seconds  is  used.  It is the responsibility of the programmer not to call this
              function with an argument equal to  0;

       o      char const *symval(std::string const &name) const:
              This member returns the value of a specific sendmail macro. The name parameter should be set to he
              name of a sendmail macro . Single letter macros can optionally be enclosed in braces  ({  and  }),
              longer  macro names must be enclosed in braces, just as in a sendmail.cf file.0 is returned if the
              macro is not defined.  By default, the following macros are valid in the given contexts:
              for connect: daemon_name, if_name, if_addr, j, _;
              for helo: tls_version, cipher, cipher_bits, cert_subject, cert_issuer;
              for sender: i, auth_type, auth_authen, auth_ssf, auth_author, mail_mailer, mail_host, mail_addr;
              for recipient: rcpt_mailer, rcpt_host, rcpt_addr.
              All macros stay in effect from the point they are received until the end of the connection for the
              first two sets, the end of the message for the third (sender), and just for each recipient for the
              final set (recipient).
              The following macros may be specified in the sendmail.mc configuration file:
              define(`confMILTER_MACROS_CONNECT’,    `m1’,    ...),    define(`confMILTER_MACROS_HELO’,    ...),
              define(`confMILTER_MACROS_ENVFROM’,  ...),  define(`confMILTER_MACROS_ENVRCPT’,  ...), where `m1’,
              ... represents a comma separated list of returnable macros.  Single letter macros  can  optionally
              be enclosed in braces ({ and }), longer macro names must be enclosed in braces;

       o      bool wait():
              This  member  may  only be called from eom and tells the MTA that the filter is still working on a
              message, causing the MTA to re-start its timeouts.

PRIVATE VIRTUAL MEMBER FUNCTIONS

       The remaining functionality of the class Milter is useful  only  for  Milter-implementations  in  classes
       derived  from Milter. The following members can be overridden by derived classes. Note that clone must be
       overridden. Except for clone, all the members in this sections are callback functions. I.e., the MTA will
       call them to process parts of the mail message. Recipient-, message-, and  connection-oriented  callbacks
       are distinguished.

       The recipient-oriented callback (recipient, see below) may affect the processing of a single message to a
       single  recipient.  Connection-oriented  callbacks (connect, helo and close) affect the processing of the
       entire connection (during which multiple messages may be delivered to multiple sets of  recipients).  The
       remaining  callbacks  are  message-oriented,  affecting  the  processing  of  a single message to all its
       recipients.

       o      virtual sfsistat abort():
              This message-oriented member may be called at any time during  message  processing  (i.e.  between
              some  message-oriented  routine  and  eom). abort reclaim any resources allocated on a per-message
              basis (which are not the connection specific data, which should be handled by the  derived  class’
              destructor),  and  must  be  tolerant  of being called between any two message-oriented callbacks.
              abort is only called if the message is aborted outside the filter’s control and the filter has not
              completed its message-oriented processing. For example, if a filter has already  returned  ACCEPT,
              REJECT,  or  DISCARD from a message-oriented routine, abort will not be called even if the message
              is later aborted outside its control;

       o      virtual sfsistat body(unsigned char *text, size_t length):
              This message-oriented member is called zero or more times between eoh and eom.  text points  to  a
              sequence  of  bytes.  It  is  not  necessarily  a 0-terminated. Moreover, the sequence may contain
              0-characters.  Since message bodies can be very large,  defining  body  can  significantly  impact
              filter  performance.   End-of-lines are represented as received from SMTP (normally CR/LF).  Later
              filters will see body changes made by earlier ones, and message bodies may  be  sent  in  multiple
              chunks, with one call to body per chunk;

       o      virtual Milter *clone() const = 0:
              This pure virtual function must be implemented by derived classes to return a newly allocated copy
              of  the derived object passed to the initialize static member. It is used by the standard `virtual
              constructor’ design pattern. The destruction of the allocated  object  is  the  responsibility  of
              clone’s caller;

       o      virtual sfsistat close():
              This  connection-oriented  member  is always called once at the end of each connection.  It may be
              called "out-of-order", i.e. before even the connect is called. After a connection  is  established
              by the MTA to the filter, if the MTA decides this connection’s traffic will be discarded (e.g. via
              an  access_db  result),  no data will be passed to the filter from the MTA until the client closes
              down. At that time, close is called. It can therefore be the only callback ever used for  a  given
              connection,  and developers should anticipate this possibility when crafting their close code. The
              member close is called on close even if the previous mail transaction  was  aborted.  The  default
              implementation of the member close is

                  sfsistat Milter::close()
                  {
                      smfi_setpriv(d_ctx, 0);         // delete this d_ctx data

                      return CONTINUE;
                  }

              By  calling  smfi_setpriv with second argumnt 0 any data associated with the current connection is
              deleted by the milter. Implementations overriding close should at least call smfi_setpriv, passing
              the value returned by the member id (cf. section PROTECTED MEMBER FUNCTIONS) as first argument and
              0 as second argument. Other data  managed  by  the  milter  and  specifically  associated  with  a
              connection  should  be accessed via the connection’s id (e.g., using a std::unordered_map using an
              SMFICTX * as key);

       o      virtual sfsistat connect(char *hostname, _SOCK_ADDR *hostaddr):
              This connection-oriented member may be called once, at the start  of  each  SMTP  connection.  The
              parameter hostname is he host name of the message sender, as determined by a reverse lookup on the
              host  address.  If the reverse lookup fails, hostname will contain the message sender’s IP address
              enclosed in square brackets (e.g. [a.b.c.d]). The parameter  hostaddr  is  the  host  address,  as
              determined  by  a  getpeername(2) call on the SMTP socket. It is 0 if the type is not supported in
              the current version or if the SMTP connection is made via stdin;

       o      virtual sfsistat data():
              Not yet supported. Will be available with libmilter versions beyond 3;

       o      virtual sfsistat eoh():
              This message-oriented member is called once after all headers have been processed;

       o      virtual sfsistat eom():
              This message-oriented member is called once after all calls to body for a given message have  been
              completed.  Note  that  only  in  this  function  modifications  to the message headers, body, and
              envelope can be made (see the add-, change- and delete- members listed below);

       o      virtual sfsistat header(char *headerf, char *headerv):
              This message-oriented member is called zero or more times between recipient and eoh, once for each
              e-mail header. The headerf parameter contains the  text  of  the  header,  the  headerv  parameter
              contains its value. E.g., if an e-mail message contains the following headers:

                  From: sender <f@example.com>
                  Subject:no

              then header will be called twice with the following values for, respectively headerf and headerv:

                  First header:   "From",     " sender <f@example.com>"
                  Second header:  "Subject",  "no"

              Further details about header information is given in RFC 882;

       o      virtual sfsistat helo(char *helohost):
              This  connection-oriented  member  is called whenever the client sends a HELO/EHLO command. It may
              therefore be called between zero and three times. The helohost parameter should be the domain name
              of the sending host (but is, in practice, anything the sending host wants to send);

       o      virtual sfsistat recipient(char **argv):
              This recipient-oriented member is called once per recipient (provided by the To: or Cc:  headers),
              hence  one  or  more  times  per  message,  immediately  after  sender.  The  parameter  argv is a
              0-terminated array of pointers to  SMTP  command  arguments;  argv[0]  is  guaranteed  to  be  the
              recipient address. Later arguments are the ESMTP arguments. TEMPFAIL may be returned indicate that
              sendmail  should  return a temporary failure for this particular recipient; further recipients may
              still be sent, abort is not  called.   REJECT  will  reject  this  particular  recipient;  further
              recipients may still be sent, abort is not called.  DISCARD will accept (but discard) the message,
              abort  will  be  called.   ACCEPT will accept recipient, abort will not be called. More details on
              ESTMP responses, are described in RFC 1869;

       o      virtual sfsistat sender(char **argv):
              This message-oriented member is called once at the beginning of each  message,  before  recipient.
              argv[0]  is  guaranteed to be the sender’s envelope address (provided in the e-mail’s initial From
              ... line). Later arguments are the ESMTP arguments.  TEMPFAIL may  be  returned,  indicating  that
              sendmail  should  return  a  temporary  failure  for this particular message, abort is not called.
              REJECT will reject this message, abort is not called.   DISCARD  will  accept  (but  discard)  the
              message,  abort  will  be  called.   ACCEPT  will accept recipient, abort will not be called. More
              details on ESTMP responses, are described in RFC 1869;

       o      virtual sfsistat unknown(char *ptr):
              Not yet supported. Will be available with libmilter versions beyond 2.

EXAMPLE

       To do

FILES

       bobcat/milter - defines the class interface

SEE ALSO

       bobcat(7), getpeername(2), listen(2),
       http://www.milter.org (e.g., http://www.milter.org/developers/api)
       http://sendmail.org/m4/readme.html
       http://rfc.net/rfc821.html
       http://rfc.net/rfc822.html
       http://rfc.net/rfc1869.html
       http://rfc.net/rfc1893.html
       http://rfc.net/rfc2034.html
       http://rfc.net/rfc2821.html
       /usr/include/libmilter/mfapi.h

BUGS

       -lmilter must be specified before -lbobcat.

BOBCAT PROJECT FILES

       o      https://fbb-git.gitlab.io/bobcat/: gitlab project page;

       Debian Bobcat project files:

       o      libbobcat6: debian package containing the shared library, changelog and copyright note;

       o      libbobcat-dev: debian package containing the static library, headers, manual pages, and  developer
              info;

BOBCAT

       Bobcat is an acronym of `Brokken’s Own Base Classes And Templates’.

COPYRIGHT

       This is free software, distributed under the terms of the GNU General Public License (GPL).

AUTHOR

       Frank B. Brokken (f.b.brokken@rug.nl).

libbobcat-dev_6.11.00                               2005-2025                               FBB::Milter(3bobcat)