1 // Copyright 2009 The Archiveopteryx Developers <info@aox.org>
2
3 #include "smtp.h"
4
5 #include "smtpmailrcpt.h"
6 #include "smtpcommand.h"
7 #include "transaction.h"
8 #include "eventloop.h"
9 #include "address.h"
10 #include "mailbox.h"
11 #include "buffer.h"
12 #include "query.h"
13 #include "scope.h"
14 #include "sieve.h"
15 #include "date.h"
16 #include "user.h"
17
18 // getpid()
19 #include <sys/types.h>
20 #include <unistd.h>
21
22
23 class SMTPData
24 : public Garbage
25 {
26 public:
SMTPData()27 SMTPData():
28 executing( false ), executeAgain( false ),
29 inputState( SMTP::Command ),
30 dialect( SMTP::Smtp ),
31 sieve( 0 ), user( 0 ), permittedAddresses( 0 ),
32 recipients( new List<SmtpRcptTo> ), now( 0 ) {}
33
34 bool executing;
35 bool executeAgain;
36 SMTP::InputState inputState;
37 SMTP::Dialect dialect;
38 Sieve * sieve;
39 List<SmtpCommand> commands;
40 EString heloName;
41 User * user;
42 List<Address> * permittedAddresses;
43 List<SmtpRcptTo> * recipients;
44 EString body;
45 Date * now;
46 EString id;
47
48 class AddressFinder
49 : public EventHandler
50 {
51 public:
AddressFinder(List<Address> * addresses)52 AddressFinder( List<Address> * addresses ) : q( 0 ), a( addresses ) {}
53 void execute();
54 Query * q;
55 private:
56 List<Address> * a;
57 };
58 };
59
60
61 /*! \class SMTP smtp.h
62 The SMTP class implements a basic SMTP server.
63
64 This is not a classic MTA. It implements all that's needed to
65 deliver to local users, and for local users to submit messages to
66 others. Nothing more.
67
68 This class implements SMTP as specified by RFC 2821, with the
69 extensions specified by RFC 1651 (EHLO), RFC 1652 (8BITMIME), RFC
70 2487 (STARTTLS), RFC 2554 (AUTH), RFC 3030 (BINARYMIME and
71 CHUNKING) and RFC 4468 (BURL).
72 */
73
74 /*! \class LMTP smtp.h
75 This subclass of SMTP implements LMTP (RFC 2033).
76 */
77
78 /*! \class SMTPSubmit smtp.h
79 This subclass of SMTP implements SMTP submission (RFC 4409).
80 */
81
82 /*! Constructs an (E)SMTP server for socket \a s, speaking \a dialect. */
83
SMTP(int s,Dialect dialect)84 SMTP::SMTP( int s, Dialect dialect )
85 : SaslConnection( s, Connection::SmtpServer ), d( new SMTPData )
86 {
87 Scope x( log() );
88 d->dialect = dialect;
89 switch( dialect ) {
90 case Smtp:
91 enqueue( "220 ESMTP " );
92 break;
93 case Lmtp:
94 enqueue( "220 LMTP " );
95 break;
96 case Submit:
97 enqueue( "220 SMTP Submission " );
98 break;
99 }
100 enqueue( Configuration::hostname() );
101 enqueue( "\r\n" );
102 setTimeoutAfter( 1800 );
103 EventLoop::global()->addConnection( this );
104 }
105
106
107 /*! Constructs an LMTP server of socket \a s. */
108
LMTP(int s)109 LMTP::LMTP( int s )
110 : SMTP( s, SMTP::Lmtp )
111 {
112 }
113
114
115 /*! Constructs a SMTP/submit server (see RFC 4409) for socket \a s. */
116
SMTPSubmit(int s)117 SMTPSubmit::SMTPSubmit( int s )
118 : SMTP( s, SMTP::Submit )
119 {
120 }
121
122
react(Event e)123 void SMTP::react( Event e )
124 {
125 switch ( e ) {
126 case Read:
127 setTimeoutAfter( 1800 );
128 parse();
129 break;
130
131 case Timeout:
132 log( "Idle timeout" );
133 enqueue( "421 Tempus fugit\r\n" );
134 Connection::setState( Closing );
135 break;
136
137 case Connect:
138 case Error:
139 case Close:
140 break;
141
142 case Shutdown:
143 enqueue( "421 Server shutdown\r\n" );
144 break;
145 }
146 execute();
147 }
148
149
150 /*! Parses the SMTP/LMTP input stream.
151 */
152
parse()153 void SMTP::parse()
154 {
155 Buffer * r = readBuffer();
156 bool progress = true;
157 while ( progress && Connection::state() == Connected ) {
158 uint n = r->size();
159 if ( inputState() == Command )
160 parseCommand();
161 else
162 d->commands.last()->execute();
163 if ( r->size() >= n )
164 progress = false;
165 }
166 }
167
168
169 /*! Reads a single SMTP/LMTP/Submit command from the client and
170 creates an execution object for it.
171
172 Line length is limited to 4096 (for SMTP commands, not for message
173 bodies): RFC 2821 section 4.5.3 says 512 is acceptable and various
174 SMTP extensions may increase it. RFC 2822 declares that line
175 lengths should be limited to 998 characters.
176 */
177
parseCommand()178 void SMTP::parseCommand()
179 {
180 Buffer * r = readBuffer();
181 EString * line = r->removeLine( 4096 );
182 if ( !line && r->size() > 4096 ) {
183 log( "Connection closed due to overlong line", Log::Error );
184 enqueue( "500 Line too long (legal maximum is 998 bytes)\r\n" );
185 Connection::setState( Closing );
186 return;
187 }
188 if ( !line )
189 return;
190
191 d->commands.append( SmtpCommand::create( this, *line ) );
192 }
193
194
195 /*! Runs all outstanding commands. When the oldest command is done,
196 execute() removes it from the list and sends its responses to the
197 client.
198 */
199
execute()200 void SMTP::execute()
201 {
202 // make sure we don't call execute() recursively.
203 if ( d->executing ) {
204 d->executeAgain = true;
205 return;
206 }
207 d->executing = true;
208 d->executeAgain = true;
209
210 // run each command, and do the whole loop again if execute() is
211 // called recursively meanwhile.
212 while ( d->executeAgain ) {
213 d->executeAgain = false;
214 List<SmtpCommand>::Iterator i( d->commands );
215 while ( i ) {
216 SmtpCommand * c = i;
217 ++i;
218 if ( !c->done() )
219 c->notify();
220 }
221
222 // see if any old commands may be retired
223 i = d->commands.first();
224 while ( i && i->done() ) {
225 d->executeAgain = true;
226 i->emitResponses();
227 d->commands.take( i );
228 }
229 }
230
231 // allow execute() to be called again
232 d->executing = false;
233 }
234
235
236 /*! Returns the dialect used, ie. SMTP, LMTP or SMTP/Submit. */
237
dialect() const238 SMTP::Dialect SMTP::dialect() const
239 {
240 return d->dialect;
241 }
242
243
244 /*! Records that the client claims to be called \a name. \a name isn't
245 used for anything, just logged and recorded in any received fields
246 generated.
247 */
248
setHeloName(const EString & name)249 void SMTP::setHeloName( const EString & name )
250 {
251 d->heloName = name;
252 }
253
254
255 /*! Returns the recorded HELO name, as recorded by setHeloName(). The
256 initial value is an empty string.
257 */
258
heloName() const259 EString SMTP::heloName() const
260 {
261 return d->heloName;
262 }
263
264
265 /*! Resets most transaction variables, so a new mail from/rcpt to/data
266 cycle can begin. Leaves the heloName() untouched, since some
267 clients do not resend helo/ehlo/lhlo.
268 */
269
reset()270 void SMTP::reset()
271 {
272 if ( d->sieve ||
273 ( d->recipients && !d->recipients->isEmpty() ) ||
274 !d->body.isEmpty() )
275 log( "State reset" );
276 d->sieve = 0;
277 d->recipients = new List<SmtpRcptTo>;
278 d->body.truncate();
279 d->id.truncate();
280 d->now = 0;
281 }
282
283
284 /*! Returns a pointer to the Sieve that manages local delivery for
285 this SMTP server.
286
287 */
288
sieve() const289 class Sieve * SMTP::sieve() const
290 {
291 if ( !d->sieve ) {
292 Scope x( log() );
293 d->sieve = new Sieve;
294 }
295 return d->sieve;
296 }
297
298
299 /*! Returns a pointer to the authenticated user, or a null pointer if
300 the connection is unauthenticated.
301 */
302
user() const303 class User * SMTP::user() const
304 {
305 return d->user;
306 }
307
308
309 /*! Sets this server's authenticated user to \a user. */
310
authenticated(User * user)311 void SMTP::authenticated( User * user )
312 {
313 d->user = user;
314 if ( !user )
315 return;
316
317 log( "Authenticated as " + user->login().ascii() );
318
319 d->permittedAddresses = new List<Address>;
320 d->permittedAddresses->append( d->user->address() );
321
322 SMTPData::AddressFinder * af
323 = new SMTPData::AddressFinder( d->permittedAddresses );
324 af->q = new Query( "select distinct a.localpart::text, a.domain::text "
325 "from addresses a "
326 "join aliases al on (a.id=al.address) "
327 "join mailboxes mb on (al.mailbox=mb.id) "
328 "where mb.owner=$1 or mb.id in"
329 "(select mailbox from permissions "
330 "where rights ilike '%p%' "
331 "and (identifier='anyone' or identifier=$2))",
332 af );
333 af->q->bind( 1, d->user->id() );
334 af->q->bind( 2, d->user->login() );
335 af->q->execute();
336 }
337
338
execute()339 void SMTPData::AddressFinder::execute()
340 {
341 Row * r = q->nextRow();
342 while ( r ) {
343 a->append( new Address( UString(),
344 r->getUString( "localpart" ),
345 r->getUString( "domain" ) ) );
346 r = q->nextRow();
347 }
348 }
349
350
351 /*! Returns a pointer to the list of addresses the currently
352 authenticated User is permitted to use, or a null pointer if the
353 list is not yet known.
354 */
355
permittedAddresses()356 List<Address> * SMTP::permittedAddresses()
357 {
358 return d->permittedAddresses;
359 }
360
361
362 /*! Returns the current input state, which is Command initially. */
363
inputState() const364 SMTP::InputState SMTP::inputState() const
365 {
366 return d->inputState;
367 }
368
369
370 /*! Notifies this SMTP server that its input state is now \a s. If the
371 state is anything other than Command, the SMTP server calls the
372 last SmtpCommand every time there's more input. Eventually, the
373 SmtpCommand has to call setInputState( Command ) again.
374
375 */
376
setInputState(InputState s)377 void SMTP::setInputState( InputState s )
378 {
379 d->inputState = s;
380 }
381
382
383 /*! Notifies this SMTP server that \a r is a valid rcpt to
384 command. SMTP records that so the LMTP SmtpData command can use
385 the list later.
386 */
387
addRecipient(SmtpRcptTo * r)388 void SMTP::addRecipient( SmtpRcptTo * r )
389 {
390 log( "Recipient: " + r->address()->lpdomain() );
391 d->recipients->append( r );
392 }
393
394
395 /*! Returns a list of all valid SmtpRcptTo commands. This is never a
396 null pointer, but may be an empty list.
397 */
398
rcptTo() const399 List<SmtpRcptTo> * SMTP::rcptTo() const
400 {
401 return d->recipients;
402 }
403
404
405 /*! Records \a b for later recall. reset() clears this. */
406
setBody(const EString & b)407 void SMTP::setBody( const EString & b )
408 {
409 d->body = b;
410 }
411
412
413 /*! Returns what setBody() set. Used for SmtpBdat instances to
414 coordinate the body.
415 */
416
body() const417 EString SMTP::body() const
418 {
419 return d->body;
420 }
421
422
423 /*! Returns true if \a c is the oldest command in the SMTP server's
424 queue of outstanding commands, and false if the queue is empty or
425 there is a command older than \a c in the queue.
426 */
427
isFirstCommand(SmtpCommand * c) const428 bool SMTP::isFirstCommand( SmtpCommand * c ) const
429 {
430 if ( c == d->commands.firstElement() )
431 return true;
432 return false;
433 }
434
435
436 class SMTPSData
437 : public Garbage
438 {
439 public:
SMTPSData()440 SMTPSData() : helper( 0 ) {}
441 EString banner;
442 class SmtpsHelper * helper;
443 };
444
445 class SmtpsHelper: public EventHandler
446 {
447 public:
SmtpsHelper(SMTPS * connection)448 SmtpsHelper( SMTPS * connection ) : c( connection ) {}
execute()449 void execute() { c->finish(); }
450
451 private:
452 SMTPS * c;
453 };
454
455 /*! \class SMTPS smtp.h
456
457 The SMTPS class implements the old wrapper trick still commonly
458 used on port 465. As befits a hack, it is a bit of a hack, and
459 depends on the ability to empty its writeBuffer().
460 */
461
462 /*! Constructs an SMTPS server on file descriptor \a s, and starts to
463 negotiate TLS immediately.
464 */
465
SMTPS(int s)466 SMTPS::SMTPS( int s )
467 : SMTPSubmit( s ), d( new SMTPSData )
468 {
469 EString * tmp = writeBuffer()->removeLine();
470 if ( tmp )
471 d->banner = *tmp;
472 startTls();
473 enqueue( d->banner + "\r\n" );
474 }
475
476
477 /*! Handles completion of TLS negotiation and sends the banner. */
478
finish()479 void SMTPS::finish()
480 {
481 }
482
483
484 /*! Uses \a id as transaction id for this message. Reset by rset. Used
485 for debugging.
486 */
487
setTransactionId(const EString & id)488 void SMTP::setTransactionId( const EString & id )
489 {
490 d->id = id;
491 }
492
493
494 /*! Return an ESMTP id, either based on an internal algorithm or on
495 something the client specified using an Archiveopteryx-specific
496 extension.
497
498 This function returns the same ID even if called several times.
499 Rset resets it.
500 */
501
transactionId()502 EString SMTP::transactionId()
503 {
504 if ( !d->id.isEmpty() )
505 return d->id;
506
507 Scope x( log() );
508 d->id = fn( transactionTime()->unixTime() );
509 d->id.append( '-' );
510 d->id.appendNumber( getpid() );
511 d->id.append( '-' );
512 d->id.append( log()->id() );
513 log( "Assigned transaction ID " + d->id );
514 return d->id;
515 }
516
517
518 /*! Records the current time, \a now. The rest of the SMTP transaction
519 will be considered to happen at the specified time. Used for
520 debugging, when we want mail to be injected at known times.
521 */
522
setTransactionTime(class Date * now)523 void SMTP::setTransactionTime( class Date * now )
524 {
525 d->now = now;
526 }
527
528
529 /*! Returns the current time and date, except that if you call it
530 more than once for the same object, it returns the same value.
531 */
532
transactionTime() const533 class Date * SMTP::transactionTime() const
534 {
535 if ( d->now )
536 return d->now;
537
538 d->now = new Date;
539 d->now->setCurrentTime();
540 return d->now;
541 }
542
543
sendChallenge(const EString & s)544 void SMTP::sendChallenge( const EString &s )
545 {
546 enqueue( "334 "+ s +"\r\n" );
547 }
548