1smtpd(n)                    Tcl SMTP Server Package                   smtpd(n)
2
3
4
5______________________________________________________________________________
6

NAME

8       smtpd - Tcl SMTP server implementation
9

SYNOPSIS

11       package require Tcl  8.3
12
13       package require smtpd  ?1.5?
14
15       ::smtpd::start ?myaddr? ?port?
16
17       ::smtpd::stop
18
19       ::smptd::configure ?option value? ?option value ...?
20
21       ::smtpd::cget ?option?
22
23______________________________________________________________________________
24

DESCRIPTION

26       The  smtpd  package  provides  a simple Tcl-only server library for the
27       Simple Mail Transfer Protocol as described in RFC  821 (http://www.rfc-
28       editor.org/rfc/rfc821.txt)    and    RFC    2821   (http://www.rfc-edi
29       tor.org/rfc/rfc2821.txt).  By default  the  server  will  bind  to  the
30       default network address and the standard SMTP port (25).
31
32       This  package  was  designed  to permit testing of Mail User Agent code
33       from a developers workstation. It does not attempt to deliver  mail  to
34       your  mailbox.  Instead  users  of this package are expected to write a
35       procedure that will be called when mail arrives.  Once  this  procedure
36       returns, the server has nothing further to do with the mail.
37

SECURITY

39       On  Unix platforms binding to the SMTP port requires root privileges. I
40       would not recommend running any  script-based  server  as  root  unless
41       there is some method for dropping root privileges immediately after the
42       socket is bound. Under Windows platforms, it is not necessary  to  have
43       root or administrator privileges to bind low numbered sockets. However,
44       security on these platforms is weak anyway.
45
46       In short, this code should probably not be used as a  permanently  run‐
47       ning  Mail  Transfer Agent on an Internet connected server, even though
48       we are careful not to evaluate remote user input. There are many  other
49       well  tested  and  security  audited  programs that can be used as mail
50       servers for internet connected hosts.
51

TLS SECURITY CONSIDERATIONS

53       This package uses the TLS package to handle the security for https urls
54       and other socket connections.
55
56       Policy  decisions like the set of protocols to support and what ciphers
57       to use are not the responsibility of TLS, nor of  this  package  itself
58       however.   Such  decisions are the responsibility of whichever applica‐
59       tion is using the package, and are likely  influenced  by  the  set  of
60       servers the application will talk to as well.
61
62       For  example,  in light of the recent POODLE attack [http://googleonli
63       nesecurity.blogspot.co.uk/2014/10/this-poodle-bites-exploiting-
64       ssl-30.html] discovered by Google many servers will disable support for
65       the SSLv3 protocol.  To handle this change the applications  using  TLS
66       must  be  patched,  and not this package, nor TLS itself.  Such a patch
67       may be as simple as generally activating tls1 support, as shown in  the
68       example below.
69
70
71                  package require tls
72                  tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol
73
74                  ... your own application code ...
75
76

COMMANDS

78       ::smtpd::start ?myaddr? ?port?
79              Start  the  service listening on port or the default port 25. If
80              myaddr is given as a domain-style name or numerical  dotted-quad
81              IP  address then the server socket will be bound to that network
82              interface. By default the server is bound to all network  inter‐
83              faces. For example:
84
85
86
87                set sock [::smtpd::start [info hostname] 0]
88
89
90       will bind to the hosts internet interface on the first available port.
91
92       At  present  the  package  only  supports  a  single instance of a SMTP
93       server. This could be changed if required at the  cost  of  making  the
94       package  a  little  more complicated to read. If there is a good reason
95       for running multiple SMTP services then it will only  be  necessary  to
96       fix the options array and the ::smtpd::stopped variable usage.
97
98       As  the  server code uses fileevent(n) handlers to process the input on
99       sockets you will need to run the event  loop.  This  means  either  you
100       should  be  running  from  within wish(1) or you should vwait(n) on the
101       ::smtpd::stopped variable which is set when the server is stopped.
102
103       ::smtpd::stop
104              Halt the server and release the listening socket. If the  server
105              has  not  been  started  then  this  command  does nothing.  The
106              ::smtpd::stopped variable is set for use with vwait(n).
107
108              It should be noted that stopping the server does not  disconnect
109              any  currently  active  sessions  as these are operating over an
110              independent channel. Only explicitly tracking and closing  these
111              sessions,  or exiting the server process will close down all the
112              running sessions. This is similar to the usual unix daemon prac‐
113              tice  where the server performs a fork(2) and the client session
114              continues on the child process.
115
116       ::smptd::configure ?option value? ?option value ...?
117              Set configuration options for the SMTP server. Most  values  are
118              the  name of a callback procedure to be called at various points
119              in the SMTP protocol. See the CALLBACKS section for  details  of
120              the procedures.
121
122              -banner text
123                     Text  of  a  custom banner message. The default banner is
124                     "tcllib smtpd 1.5".  Note that changing the  banner  does
125                     not  affect  the  bracketing  text  in the full greeting,
126                     printing status 220, server-address, and timestamp.
127
128              -validate_host proc
129                     Callback to authenticate new connections based on the ip-
130                     address of the client.
131
132              -validate_sender proc
133                     Callback  to  authenticate  new  connections based on the
134                     senders email address.
135
136              -validate_recipient proc
137                     Callback to validate  and  authorize  a  recipient  email
138                     address
139
140              -deliverMIME proc
141                     Callback  used to deliver mail as a mime token created by
142                     the tcllib mime package.
143
144              -deliver proc
145                     Callback used to deliver email. This option has no effect
146                     if the -deliverMIME option has been set.
147
148       ::smtpd::cget ?option?
149              If  no option is specified the command will return a list of all
150              options and their current values. If an option is  specified  it
151              will return the value of that option.
152

CALLBACKS

154       validate_host callback
155              This  procedure is called with the clients ip address as soon as
156              a connection request has been accepted and before  any  protocol
157              commands are processed. If you wish to deny access to a specific
158              host then an error should be  returned  by  this  callback.  For
159              example:
160
161
162
163               proc validate_host {ipnum} {
164                  if {[string match "192.168.1.*" $ipnum]} {
165                     error "go away!"
166                  }
167               }
168
169
170       If  access  is  denied  the client will receive a standard message that
171       includes the text of your error, such as:
172
173
174
175               550 Access denied: I hate you.
176
177
178       As per the SMTP protocol, the connection is not closed but we wait  for
179       the  client  to send a QUIT command. Any other commands cause a 503 Bad
180       Sequence error.
181
182       validate_sender callback
183              The validate_sender callback is called  with  the  senders  mail
184              address  during  processing  of  a  MAIL command to allow you to
185              accept or reject mail based upon the declared sender. To  reject
186              mail you should throw an error. For example, to reject mail from
187              user "denied":
188
189
190
191               proc validate_sender {address} {
192                  eval array set addr [mime::parseaddress $address]
193                  if {[string match "denied" $addr(local)]} {
194                       error "mailbox $addr(local) denied"
195                  }
196                  return
197               }
198
199
200       The content of any error message will not be passed back to the client.
201
202       validate_recipient callback
203              The  validate_recipient  callback  is  similar  to   the   vali‐
204              date_sender  callback  and permits you to verify a local mailbox
205              and accept mail for a local user  address  during  RCPT  command
206              handling.  To  reject  mail,  throw an error as above. The error
207              message is ignored.
208
209       deliverMIME callback
210              ] The deliverMIME callback is called once  a  mail  message  has
211              been  successfully  passed  to  the server. A mime token is con‐
212              structed from the sender, recipients and data and the users pro‐
213              cedure  it  called  with  this  single  argument.  When the call
214              returns, the mime token is cleaned up so if the user  wishes  to
215              preserve the data she must make a copy.
216
217
218
219               proc deliverMIME {token} {
220                   set sender [lindex [mime::getheader $token From] 0]
221                   set recipients [lindex [mime::getheader $token To] 0]
222                   set mail "From $sender [clock format [clock seconds]]"
223                   append mail "\n" [mime::buildmessage $token]
224                   puts $mail
225               }
226
227
228       deliver callback
229              The deliver callback is called once a mail message has been suc‐
230              cessfully passed to the server  and  there  is  no  -deliverMIME
231              option  set.  The procedure is called with the sender, a list of
232              recipients and the text of the mail as  a  list  of  lines.  For
233              example:
234
235
236
237               proc deliver {sender recipients data} {
238                  set mail "From $sender  [clock format [clock seconds]]"
239                  append mail "\n" [join $data "\n"]
240                  puts "$mail"
241               }
242
243
244       Note that the DATA command will return an error if no sender or recipi‐
245       ent has yet been defined.
246

VARIABLES

248       ::smtpd::stopped
249              This variable is set to true during the ::smtpd::stop command to
250              permit the use of the vwait(n) command.
251

AUTHOR

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

LICENSE

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

BUGS, IDEAS, FEEDBACK

262       This document, and the package it describes, will  undoubtedly  contain
263       bugs  and  other problems.  Please report such in the category smtpd of
264       the  Tcllib  Trackers  [http://core.tcl.tk/tcllib/reportlist].   Please
265       also  report any ideas for enhancements you may have for either package
266       and/or documentation.
267
268       When proposing code changes, please provide unified diffs, i.e the out‐
269       put of diff -u.
270
271       Note  further  that  attachments  are  strongly  preferred over inlined
272       patches. Attachments can be made by going  to  the  Edit  form  of  the
273       ticket  immediately  after  its  creation, and then using the left-most
274       button in the secondary navigation bar.
275

KEYWORDS

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

CATEGORY

280       Networking
281
283       Copyright (c) Pat Thoyts <patthoyts@users.sourceforge.net>
284
285
286
287
288tcllib                                1.5                             smtpd(n)
Impressum