Provided by: tcllib_1.19-dfsg-2_all bug

NAME

       smtpd - Tcl SMTP server implementation

SYNOPSIS

       package require Tcl  8.3

       package require smtpd  ?1.5?

       ::smtpd::start ?myaddr? ?port?

       ::smtpd::stop

       ::smptd::configure ?option value? ?option value ...?

       ::smtpd::cget ?option?

_________________________________________________________________________________________________

DESCRIPTION

       The  smtpd  package provides a simple Tcl-only server library for the Simple Mail Transfer
       Protocol as described in RFC  821 (http://www.rfc-editor.org/rfc/rfc821.txt) and RFC  2821
       (http://www.rfc-editor.org/rfc/rfc2821.txt).   By  default  the  server  will  bind to the
       default network address and the standard SMTP port (25).

       This package was designed to permit testing of Mail User  Agent  code  from  a  developers
       workstation.  It  does not attempt to deliver  mail to your mailbox. Instead users of this
       package are expected to write a procedure that will be called when mail arrives. Once this
       procedure returns, the server has nothing further to do with the mail.

SECURITY

       On Unix platforms binding to the SMTP port requires root privileges. I would not recommend
       running any script-based server as root unless there is  some  method  for  dropping  root
       privileges  immediately  after  the  socket  is  bound. Under Windows platforms, it is not
       necessary to have root or administrator privileges to bind low numbered sockets.  However,
       security on these platforms is weak anyway.

       In  short,  this  code  should probably not be used as a permanently running Mail Transfer
       Agent on an Internet connected server, even though we are careful not to  evaluate  remote
       user  input.  There  are  many other well tested and security audited programs that can be
       used as mail servers for internet connected hosts.

TLS SECURITY CONSIDERATIONS

       This package uses the TLS package to handle the security for https urls and  other  socket
       connections.

       Policy  decisions like the set of protocols to support and what ciphers to use are not the
       responsibility of TLS, nor of  this  package  itself  however.   Such  decisions  are  the
       responsibility of whichever application is using the package, and are likely influenced by
       the set of servers the application will talk to as well.

       For      example,      in      light      of      the      recent      POODLE       attack
       [http://googleonlinesecurity.blogspot.co.uk/2014/10/this-poodle-bites-exploiting-
       ssl-30.html] discovered by  Google  many  servers  will  disable  support  for  the  SSLv3
       protocol.   To handle this change the applications using TLS must be patched, and not this
       package, nor TLS itself.  Such a patch may be  as  simple  as  generally  activating  tls1
       support, as shown in the example below.

                  package require tls
                  tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

                  ... your own application code ...

COMMANDS

       ::smtpd::start ?myaddr? ?port?
              Start the service listening on port or the default port 25. If myaddr is given as a
              domain-style name or numerical dotted-quad IP address then the server  socket  will
              be  bound  to that network interface. By default the server is bound to all network
              interfaces. For example:

                set sock [::smtpd::start [info hostname] 0]

       will bind to the hosts internet interface on the first available port.

       At present the package only supports a single instance of a SMTP  server.  This  could  be
       changed  if  required at the cost of making the package a little more complicated to read.
       If there is a good reason for  running  multiple  SMTP  services  then  it  will  only  be
       necessary to fix the options array and the ::smtpd::stopped variable usage.

       As  the server code uses fileevent(3tcl) handlers to process the input on sockets you will
       need to run the event loop. This means either you should be running from within wish(1) or
       you  should  vwait(3tcl)  on the ::smtpd::stopped variable which is set when the server is
       stopped.

       ::smtpd::stop
              Halt the server and release the listening  socket.  If  the  server  has  not  been
              started  then  this command does nothing.  The ::smtpd::stopped variable is set for
              use with vwait(3tcl).

              It should be noted that stopping the  server  does  not  disconnect  any  currently
              active sessions as these are operating over an independent channel. Only explicitly
              tracking and closing these sessions, or exiting the server process will close  down
              all  the  running sessions. This is similar to the usual unix daemon practice where
              the server performs a fork(2)  and  the  client  session  continues  on  the  child
              process.

       ::smptd::configure ?option value? ?option value ...?
              Set  configuration  options  for  the  SMTP  server.  Most values are the name of a
              callback procedure to be called at various points in the  SMTP  protocol.  See  the
              CALLBACKS section for details of the procedures.

              -banner text
                     Text  of  a custom banner message. The default banner is "tcllib smtpd 1.5".
                     Note that changing the banner does not affect the  bracketing  text  in  the
                     full greeting, printing status 220, server-address, and timestamp.

              -validate_host proc
                     Callback  to  authenticate  new  connections  based on the ip-address of the
                     client.

              -validate_sender proc
                     Callback to authenticate new connections based on the senders email address.

              -validate_recipient proc
                     Callback to validate and authorize a recipient email address

              -deliverMIME proc
                     Callback used to deliver mail as a mime token created  by  the  tcllib  mime
                     package.

              -deliver proc
                     Callback   used  to  deliver  email.  This  option  has  no  effect  if  the
                     -deliverMIME option has been set.

       ::smtpd::cget ?option?
              If no option is specified the command will return a list of all options  and  their
              current values. If an option is specified it will return the value of that option.

CALLBACKS

       validate_host callback
              This  procedure  is  called  with  the  clients  ip address as soon as a connection
              request has been accepted and before any protocol commands are  processed.  If  you
              wish  to  deny  access  to a specific host then an error should be returned by this
              callback. For example:

               proc validate_host {ipnum} {
                  if {[string match "192.168.1.*" $ipnum]} {
                     error "go away!"
                  }
               }

       If access is denied the client will receive a standard message that includes the  text  of
       your error, such as:

               550 Access denied: I hate you.

       As  per the SMTP protocol, the connection is not closed but we wait for the client to send
       a QUIT command. Any other commands cause a 503 Bad Sequence error.

       validate_sender callback
              The validate_sender callback  is  called  with  the  senders  mail  address  during
              processing  of  a MAIL command to allow you to accept or reject mail based upon the
              declared sender. To reject mail you should throw an error. For example,  to  reject
              mail from user "denied":

               proc validate_sender {address} {
                  eval array set addr [mime::parseaddress $address]
                  if {[string match "denied" $addr(local)]} {
                       error "mailbox $addr(local) denied"
                  }
                  return
               }

       The content of any error message will not be passed back to the client.

       validate_recipient callback
              The  validate_recipient  callback  is  similar  to the validate_sender callback and
              permits you to verify a local mailbox and accept mail  for  a  local  user  address
              during  RCPT  command  handling. To reject mail, throw an error as above. The error
              message is ignored.

       deliverMIME callback
              ] The deliverMIME callback is called once a  mail  message  has  been  successfully
              passed  to  the server. A mime token is constructed from the sender, recipients and
              data and the users procedure it called with this single  argument.  When  the  call
              returns,  the  mime  token is cleaned up so if the user wishes to preserve the data
              she must make a copy.

               proc deliverMIME {token} {
                   set sender [lindex [mime::getheader $token From] 0]
                   set recipients [lindex [mime::getheader $token To] 0]
                   set mail "From $sender [clock format [clock seconds]]"
                   append mail "\n" [mime::buildmessage $token]
                   puts $mail
               }

       deliver callback
              The deliver callback is called once a mail message has been successfully passed  to
              the  server  and  there is no -deliverMIME option set. The procedure is called with
              the sender, a list of recipients and the text of the mail as a list of  lines.  For
              example:

               proc deliver {sender recipients data} {
                  set mail "From $sender  [clock format [clock seconds]]"
                  append mail "\n" [join $data "\n"]
                  puts "$mail"
               }

       Note  that  the  DATA  command will return an error if no sender or recipient has yet been
       defined.

VARIABLES

       ::smtpd::stopped
              This variable is set to true during the ::smtpd::stop command to permit the use  of
              the vwait(3tcl) command.

AUTHOR

       Written by Pat Thoyts mailto:patthoyts@users.sourceforge.net.

LICENSE

       This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
       without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE.
       See the file "license.terms" for more details.

BUGS, IDEAS, FEEDBACK

       This  document,  and  the  package  it  describes, will undoubtedly contain bugs and other
       problems.   Please  report  such  in  the  category   smtpd   of   the   Tcllib   Trackers
       [http://core.tcl.tk/tcllib/reportlist].  Please also report any ideas for enhancements you
       may have for either package and/or documentation.

       When proposing code changes, please provide unified diffs, i.e the output of diff -u.

       Note further that attachments are strongly preferred over inlined patches. Attachments can
       be  made  by going to the Edit form of the ticket immediately after its creation, and then
       using the left-most button in the secondary navigation bar.

KEYWORDS

       rfc 2821, rfc 821, services, smtp, smtpd, socket, vwait

CATEGORY

       Networking

COPYRIGHT

       Copyright (c) Pat Thoyts <patthoyts@users.sourceforge.net>