# Document miltermodule for Doxygen # ## @package milter # # A thin wrapper around libmilter. # ## Continue processing the current connection, message, or recipient. CONTINUE = 0 ## For a connection-oriented routine, reject this connection; # call Milter.Base.close(). For a message-oriented routine, except # Milter.Base.eom() or Milter.Base.abort(), reject this message. For a # recipient-oriented routine, reject the current recipient (but continue # processing the current message). REJECT = 1 ## For a message- or recipient-oriented routine, accept this message, but # silently discard it. SMFIS_DISCARD should not be returned by a # connection-oriented routine. DISCARD = 2 ## For a connection-oriented routine, accept this connection without further # filter processing; call Milter.Base.close(). For a message- or # recipient-oriented routine, accept this message without further filtering. ACCEPT = 3 ## Return a temporary failure, i.e., the corresponding SMTP command will return # an appropriate 4xx status code. For a message-oriented routine, except # Milter.Base.envfrom(), fail for this message. For a connection-oriented # routine, fail for this connection; call Milter.Base.close(). For a recipient-oriented # routine, only # fail for the current recipient; continue message processing. TEMPFAIL = 4 ## Skip further callbacks of the same type in this transaction. # Currently this return value is only allowed in Milter.Base.body(). It can be # used if a %milter has received sufficiently many body chunks to make a # decision, but still wants to invoke message modification functions that are # only allowed to be called from Milter.Base.eom(). Note: the %milter must # negotiate this behavior with the MTA, i.e., it must check whether the # protocol action SMFIP_SKIP is available and if so, the %milter must request # it. SKIP = 5 ## Do not send a reply back to the MTA. # The %milter must negotiate this behavior with the MTA, i.e., it must check # whether the appropriate protocol action P_NR_* is available and if so, # the %milter must request it. If you set the P_NR_* protocol action for a # callback, that callback must always reply with NOREPLY. Using any other # reply code is a violation of the API. If in some cases your callback may # return another value (e.g., due to some resource shortages), then you must # not set P_NR_* and you must use CONTINUE as the default return # code. (Alternatively you can try to delay reporting the problem to a later # callback for which P_NR_* is not set.) # # This is negotiated and returned automatically by the Milter.noreply # function decorator. NOREPLY = 6 ## Hold context for a %milter connection. # Each connection to sendmail creates a new SMFICTX struct within # libmilter. The milter module in turn creates a milterContext # tied to the SMFICTX struct via smfi_setpriv # to hold a PyThreadState and a user defined Python object for the connection. # # Most application interaction with libmilter takes places via # the milterContext object for the connection. It is passed to # callback functions as the first parameter. # # The Milter module creates a python class for each connection, # and converts function callbacks to instance method invocations. # class milterContext(object): ## Calls smfi_getsymval. def getsymval(self,sym): pass ## Calls # smfi_setreply or # # smfi_setmlreply. # @param rcode SMTP response code # @param xcode extended SMTP response code # @param msg one or more message lines. If the MTA does not support # multiline messages, only the first is used. def setreply(self,rcode,xcode,*msg): pass ## Calls smfi_addheader. def addheader(self,name,value,idx=-1): pass ## Calls smfi_chgheader. def chgheader(self,name,idx,value): pass ## Calls smfi_addrcpt. def addrcpt(self,rcpt,params=None): pass ## Calls smfi_delrcpt. def delrcpt(self,rcpt): pass ## Calls smfi_replacebody. def replacebody(self,data): pass ## Attach a Python object to this connection context. # @return the old value or None def setpriv(self,priv): pass ## Return the Python object attached to this connection context. def getpriv(self): pass ## Calls smfi_quarantine. def quarantine(self,reason): pass ## Calls smfi_progress. def progress(self): pass ## Calls smfi_chgfrom. def chgfrom(self,sender,param=None): pass ## Tell the MTA which macro values we are interested in for a given stage. # Of interest only when you need to squeeze a few more bytes of bandwidth. # It may only be called from the negotiate callback. # The protocol stages are # M_CONNECT, M_HELO, M_ENVFROM, M_ENVRCPT, M_DATA, M_EOM, M_EOH. # Calls smfi_setsymlist. # @param stage protocol stage in which the macro list should be used # @param macrolist a space separated list of macro names def setsymlist(self,stage,macrolist): pass class error(Exception): pass ## Enable optional %milter actions. # Certain %milter actions need to be enabled before calling main() # or they throw an exception. Pymilter enables them all by # default (since 0.9.2), but you may wish to disable unneeded # actions as an optimization. # @param flags Bit or mask of optional actions to enable def set_flags(flags): pass def set_connect_callback(cb): pass def set_helo_callback(cb): pass def set_envfrom_callback(cb): pass def set_envrcpt_callback(cb): pass def set_header_callback(cb): pass def set_eoh_callback(cb): pass def set_body_callback(cb): pass def set_abort_callback(cb): pass def set_close_callback(cb): pass ## Sets the return code for untrapped Python exceptions during a callback. # The default is TEMPFAIL. You should not depend on this handler. Your # application should have its own top level exception handler for each # callback. You can then choose your own reply message, log the stack track # were you please, and so on. However, if you miss one, this last ditch # handler will print a standard stack trace to sys.stderr, and return to # sendmail. # @param code one of #TEMPFAIL,#REJECT,#CONTINUE, or since 1.0, #ACCEPT def set_exception_policy(code): pass ## Register python %milter with libmilter. # The name we pass is used to identify the %milter in the MTA configuration. # Callback functions must be set using the set_*_callback() functions before # registering the %milter. # Three additional callbacks are specified as keyword parameters. These # were added by recent versions of libmilter. The keyword parameters is # a nicer way to do it, I think, since it makes clear that you have to do # it before registering. I may move all the callbacks in the future (perhaps # keeping the set functions for compatibility). Note that Milter.Base # automatically maps all callbacks to member functions, and negotiates which # member functions are actually overridden by an application class. # @param name the %milter name by which the MTA finds us # @param negotiate the # # xxfi_negotiate callback, called to negotiate supported # actions, callbacks, and protocol steps. # @param unknown the # # xxfi_unknown callback, called when for SMTP commands # not recognized by the MTA. (Extend SMTP in your milter!) # @param data the # # xxfi_data callback, called when the DATA # SMTP command is received. def register(name,negotiate=None,unknown=None,data=None): pass def opensocket(rmsock): pass ## Transfer control to libmilter. # Calls # smfi_main. def main(): pass ## Set the libmilter debugging level. # smfi_setdbg # sets the %milter library's internal debugging level to a new level # so that code details may be traced. A level of zero turns off debugging. The # greater (more positive) the level the more detailed the debugging. Six is the # current, highest, useful value. Must be called before calling main(). def setdbg(lev): pass ## Set timeout for MTA communication. # Calls # smfi_settimeout. Must be called before calling main(). def settimeout(secs): pass ## Set socket backlog. # Calls # smfi_setbacklog. Must be called before calling main(). def setbacklog(n): pass ## Set the socket used to communicate with the MTA. # The MTA can communicate with the milter by means of a # unix, inet, or inet6 socket. By default, a unix domain socket # is used. It must not exist, # and sendmail will throw warnings if, eg, the file is under a # group or world writable directory. #
# setconn('unix:/var/run/pythonfilter')
# setconn('inet:8800') 			# listen on ANY interface
# setconn('inet:7871@@publichost')	# listen on a specific interface
# setconn('inet6:8020')
# 
def setconn(s): pass ## Stop the %milter gracefully. def stop(): pass ## Retrieve diagnostic info. # Return a tuple with diagnostic info gathered by the milter module. # The first two fields are counts of milterContext objects created # and deleted. Additional fields may be added later. # @return a tuple of diagnostic data def getdiag(): pass ## Retrieve the runtime libmilter version. # Return the runtime libmilter version. This can be different # from the compile time version when sendmail or libmilter is upgraded # after pymilter is compiled. # @return a tuple of (major,minor,patchlevel) def getversion(): pass ## The compile time libmilter version. # Python code might need to deal with pymilter compiled # against various versions of libmilter. This module constant # contains the contents of the SMFI_VERSION macro when # the milter module was compiled. VERSION = 0x1000001