Module: Milter

Defined in:
lib/milter.rb,
lib/milter/version.rb

Defined Under Namespace

Classes: Milter, MilterConnectionHandler

Constant Summary collapse

SMFI_PROT_VERSION =

“MTA - libmilter protocol version”

6
MILTER_LEN_BYTES =

“length of 32 bit integer in bytes”

4
SMFIC_ABORT =

Milter binary protocol commands

'A'
SMFIC_BODY =

“Abort”

'B'
SMFIC_CONNECT =

“Body chunk”

'C'
SMFIC_MACRO =

“Connection information”

'D'
SMFIC_BODYEOB =

“Define macro”

'E'
SMFIC_HELO =

“final body chunk (End)”

'H'
SMFIC_QUIT_NC =

“HELO/EHLO”

'K'
SMFIC_HEADER =

“QUIT but new connection follows”

'L'
SMFIC_MAIL =

“Header”

'M'
SMFIC_EOH =

“MAIL from”

'N'
SMFIC_OPTNEG =

“EOH”

'O'
SMFIC_QUIT =

“Option negotation”

'Q'
SMFIC_RCPT =

“QUIT”

'R'
SMFIC_DATA =

“RCPT to”

'T'
SMFIC_UNKNOWN =

“DATA”

'U'
COMMANDS =

mappings for Ruby callbacks

{
  SMFIC_ABORT   => :abort,
  SMFIC_BODY    => :body,
  SMFIC_CONNECT => :connect,
  SMFIC_MACRO   => :macro,
  SMFIC_BODYEOB => :end_body,
  SMFIC_HELO    => :helo,
  SMFIC_QUIT_NC => :quit_new_connection,
  SMFIC_HEADER  => :header,
  SMFIC_MAIL    => :mail_from,
  SMFIC_EOH     => :end_headers,
  SMFIC_OPTNEG  => :opt_neg,
  SMFIC_QUIT    => :quit,
  SMFIC_RCPT    => :rcpt_to,
  SMFIC_DATA    => :data,
  SMFIC_UNKNOWN => :unknown,
}
RESPONSE =

actions(replies)

{
  :addrcpt     => '+', # SMFIR_ADDRCPT     # "add recipient"
  :delrcpt     => '-', # SMFIR_DELRCPT     # "remove recipient"
  :addrcpt_par => '2', # SMFIR_ADDRCPT_PAR # "add recipient (incl. ESMTP args)"
  :shutdown    => '4', # SMFIR_SHUTDOWN    # "421: shutdown (internal to MTA)"
  :accept      => 'a', # SMFIR_ACCEPT      # "accept"
  :replbody    => 'b', # SMFIR_REPLBODY    # "replace body (chunk)"
  :continue    => 'c', # SMFIR_CONTINUE    # "continue"
  :discard     => 'd', # SMFIR_DISCARD     # "discard"
  :chgfrom     => 'e', # SMFIR_CHGFROM     # "change envelope sender (from)"
  :connfail    => 'f', # SMFIR_CONN_FAIL   # "cause a connection failure"
  :addheader   => 'h', # SMFIR_ADDHEADER   # "add header"
  :insheader   => 'i', # SMFIR_INSHEADER   # "insert header"
  :setsymlist  => 'l', # SMFIR_SETSYMLIST  # "set list of symbols (macros)"
  :chgheader   => 'm', # SMFIR_CHGHEADER   # "change header"
  :progress    => 'p', # SMFIR_PROGRESS    # "progress"
  :quarantine  => 'q', # SMFIR_QUARANTINE  # "quarantine"
  :reject      => 'r', # SMFIR_REJECT      # "reject"
  :skip        => 's', # SMFIR_SKIP        # "skip"
  :tempfail    => 't', # SMFIR_TEMPFAIL    # "tempfail"
  :replycode   => 'y', # SMFIR_REPLYCODE   # "reply code etc"
}
PROTOCOL_FLAGS =

What the MTA can send/filter wants in protocol

{
  :noconnect   => 0x000001, # SMFIP_NOCONNECT   # MTA should not send connect info
  :nohelo      => 0x000002, # SMFIP_NOHELO      # MTA should not send HELO info
  :nomail      => 0x000004, # SMFIP_NOMAIL      # MTA should not send MAIL info
  :norcpt      => 0x000008, # SMFIP_NORCPT      # MTA should not send RCPT info
  :nobody      => 0x000010, # SMFIP_NOBODY      # MTA should not send body
  :nohdrs      => 0x000020, # SMFIP_NOHDRS      # MTA should not send headers
  :noeoh       => 0x000040, # SMFIP_NOEOH       # MTA should not send EOH
  :nohrepl     => 0x000080, # SMFIP_NR_HDR      # No reply for headers
  :nounknown   => 0x000100, # SMFIP_NOUNKNOWN   # MTA should not send unknown commands
  :nodata      => 0x000200, # SMFIP_NODATA      # MTA should not send DATA
  :skip        => 0x000400, # SMFIP_SKIP        # MTA understands SMFIS_SKIP
  :rcpt_rej    => 0x000800, # SMFIP_RCPT_REJ    # MTA should also send rejected RCPTs
  :nr_conn     => 0x001000, # SMFIP_NR_CONN     # No reply for connect
  :nr_helo     => 0x002000, # SMFIP_NR_HELO     # No reply for HELO
  :nr_mail     => 0x004000, # SMFIP_NR_MAIL     # No reply for MAIL
  :nr_rcpt     => 0x008000, # SMFIP_NR_RCPT     # No reply for RCPT
  :nr_data     => 0x010000, # SMFIP_NR_DATA     # No reply for DATA
  :nr_unkn     => 0x020000, # SMFIP_NR_UNKN     # No reply for UNKN
  :nr_eoh      => 0x040000, # SMFIP_NR_EOH      # No reply for eoh
  :nr_body     => 0x080000, # SMFIP_NR_BODY     # No reply for body chunk
  :hrd_leadspc => 0x100000, # SMFIP_HDR_LEADSPC # header value leading space
}
ACTION_FLAGS =

What the filter might do – values to be ORed together (from mfapi.h)

{
  :none        => 0x000, # SMFIF_NONE        # no flags
  :addhdrs     => 0x001, # SMFIF_ADDHDRS     # filter may add headers
  :chgbody     => 0x002, # SMFIF_CHGBODY     # filter may replace body
  :addrcpt     => 0x004, # SMFIF_ADDRCPT     # filter may add recipients
  :delrcpt     => 0x008, # SMFIF_DELRCPT     # filter may delete recipients
  :chghdrs     => 0x010, # SMFIF_CHGHDRS     # filter may change/delete headers
  :quarantine  => 0x020, # SMFIF_QUARANTINE  # filter may quarantine envelope
  :chgfrom     => 0x040, # SMFIF_CHGFROM     # filter may change "from" (envelope sender)
  :addrcpt_par => 0x080, # SMFIF_ADDRCPT_PAR # add recipients incl. args
  :setsymlist  => 0x100, # SMFIF_SETSYMLIST  # filter can send set of symbols (macros) that it wants
  :set_curr    => 0x1FF, # SMFI_CURR_ACTS    # Set of all actions in the current milter version
}
VERSION =
"0.0.1"

Class Method Summary collapse

Class Method Details

.register(milter_class) ⇒ Object



318
319
320
# File 'lib/milter.rb', line 318

def register( milter_class )
  MilterConnectionHandler.register(milter_class)
end

.start(host = 'localhost', port = 8888) ⇒ Object



322
323
324
325
326
327
328
# File 'lib/milter.rb', line 322

def start( host = 'localhost', port = 8888 )
  EM.run do
    Signal.trap("INT")  { EventMachine.stop }
    Signal.trap("TERM") { EventMachine.stop }
    EM.start_server host, port, MilterConnectionHandler
  end
end