Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / smtp / smtp_proto.c
blob7b762748f4663a3e8385b4e8dacd71da7ccdd96f
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* smtp_proto 3
6 /* SUMMARY
7 /* client SMTP/LMTP protocol
8 /* SYNOPSIS
9 /* #include "smtp.h"
11 /* int smtp_helo(state)
12 /* SMTP_STATE *state;
14 /* int smtp_xfer(state)
15 /* SMTP_STATE *state;
17 /* int smtp_rset(state)
18 /* SMTP_STATE *state;
20 /* int smtp_quit(state)
21 /* SMTP_STATE *state;
22 /* DESCRIPTION
23 /* In the subsequent text, SMTP implies LMTP.
24 /* This module implements the client side of the SMTP protocol.
26 /* smtp_helo() performs the initial handshake with the SMTP server.
27 /* When TLS is enabled, this includes STARTTLS negotiations.
29 /* smtp_xfer() sends message envelope information followed by the
30 /* message data, and finishes the SMTP conversation. These operations
31 /* are combined in one function, in order to implement SMTP pipelining.
32 /* Recipients are marked as "done" in the mail queue file when
33 /* bounced or delivered. The message delivery status is updated
34 /* accordingly.
36 /* smtp_rset() sends a single RSET command and waits for the
37 /* response. In case of a negative reply it sets the
38 /* CANT_RSET_THIS_SESSION flag.
40 /* smtp_quit() sends a single QUIT command and waits for the
41 /* response if configured to do so. It always turns off connection
42 /* caching.
43 /* DIAGNOSTICS
44 /* smtp_helo(), smtp_xfer(), smtp_rset() and smtp_quit() return
45 /* 0 in case of success, -1 in case of failure. For smtp_xfer(),
46 /* smtp_rset() and smtp_quit(), success means the ability to
47 /* perform an SMTP conversation, not necessarily the ability
48 /* to deliver mail, or the achievement of server happiness.
50 /* In case of a rejected or failed connection, a connection
51 /* is marked as "bad, do not cache". Otherwise, connection
52 /* caching may be turned off (without being marked "bad") at
53 /* the discretion of the code that implements the individual
54 /* protocol steps.
56 /* Warnings: corrupt message file. A corrupt message is marked
57 /* as "corrupt" by changing its queue file permissions.
58 /* BUGS
59 /* Some SMTP servers will abort when the number of recipients
60 /* for one message exceeds their capacity. This behavior violates
61 /* the SMTP protocol.
62 /* The only way around this is to limit the number of recipients
63 /* per transaction to an artificially-low value.
64 /* SEE ALSO
65 /* smtp(3h) internal data structures
66 /* smtp_chat(3) query/reply SMTP support
67 /* smtp_trouble(3) error handlers
68 /* LICENSE
69 /* .ad
70 /* .fi
71 /* The Secure Mailer license must be distributed with this software.
72 /* AUTHOR(S)
73 /* Wietse Venema
74 /* IBM T.J. Watson Research
75 /* P.O. Box 704
76 /* Yorktown Heights, NY 10598, USA
78 /* Pipelining code in cooperation with:
79 /* Jon Ribbens
80 /* Oaktree Internet Solutions Ltd.,
81 /* Internet House,
82 /* Canal Basin,
83 /* Coventry,
84 /* CV1 4LY, United Kingdom.
86 /* Connection caching in cooperation with:
87 /* Victor Duchovni
88 /* Morgan Stanley
90 /* TLS support originally by:
91 /* Lutz Jaenicke
92 /* BTU Cottbus
93 /* Allgemeine Elektrotechnik
94 /* Universitaetsplatz 3-4
95 /* D-03044 Cottbus, Germany
96 /*--*/
98 /* System library. */
100 #include <sys_defs.h>
101 #include <sys/stat.h>
102 #include <sys/socket.h> /* shutdown(2) */
103 #include <netinet/in.h> /* ntohs() */
104 #include <string.h>
105 #include <unistd.h>
106 #include <stdlib.h> /* 44BSD stdarg.h uses abort() */
107 #include <stdarg.h>
108 #include <time.h>
110 #ifdef STRCASECMP_IN_STRINGS_H
111 #include <strings.h>
112 #endif
114 /* Utility library. */
116 #include <msg.h>
117 #include <vstring.h>
118 #include <vstream.h>
119 #include <vstring_vstream.h>
120 #include <stringops.h>
121 #include <mymalloc.h>
122 #include <iostuff.h>
123 #include <split_at.h>
124 #include <name_code.h>
125 #include <name_mask.h>
127 /* Global library. */
129 #include <mail_params.h>
130 #include <smtp_stream.h>
131 #include <mail_queue.h>
132 #include <recipient_list.h>
133 #include <deliver_request.h>
134 #include <defer.h>
135 #include <bounce.h>
136 #include <record.h>
137 #include <rec_type.h>
138 #include <off_cvt.h>
139 #include <mark_corrupt.h>
140 #include <quote_821_local.h>
141 #include <quote_822_local.h>
142 #include <mail_proto.h>
143 #include <mime_state.h>
144 #include <ehlo_mask.h>
145 #include <maps.h>
146 #include <tok822.h>
147 #include <mail_addr_map.h>
148 #include <ext_prop.h>
149 #include <lex_822.h>
150 #include <dsn_mask.h>
151 #include <xtext.h>
153 /* Application-specific. */
155 #include "smtp.h"
156 #include "smtp_sasl.h"
159 * Sender and receiver state. A session does not necessarily go through a
160 * linear progression, but states are guaranteed to not jump backwards.
161 * Normal sessions go from MAIL->RCPT->DATA->DOT->QUIT->LAST. The states
162 * MAIL, RCPT, and DATA may also be followed by ABORT->QUIT->LAST.
164 * When connection caching is enabled, the QUIT state is suppressed. Normal
165 * sessions proceed as MAIL->RCPT->DATA->DOT->LAST, while aborted sessions
166 * end with ABORT->LAST. The connection is left open for a limited time. An
167 * RSET probe should be sent before attempting to reuse an open connection
168 * for a new transaction.
170 * The code to send an RSET probe is a special case with its own initial state
171 * and with its own dedicated state transitions. The session proceeds as
172 * RSET->LAST. This code is kept inside the main protocol engine for
173 * consistent error handling and error reporting. It is not to be confused
174 * with the code that sends RSET to abort a mail transaction in progress.
176 * The code to send QUIT without message delivery transaction jumps into the
177 * main state machine. If this introduces complications, then we should
178 * introduce a second QUIT state with its own dedicated state transitions,
179 * just like we did for RSET probes.
181 * By default, the receiver skips the QUIT response. Some SMTP servers
182 * disconnect after responding to ".", and some SMTP servers wait before
183 * responding to QUIT.
185 * Client states that are associated with sending mail (up to and including
186 * SMTP_STATE_DOT) must have smaller numerical values than the non-sending
187 * states (SMTP_STATE_ABORT .. SMTP_STATE_LAST).
189 #define SMTP_STATE_XFORWARD_NAME_ADDR 0
190 #define SMTP_STATE_XFORWARD_PROTO_HELO 1
191 #define SMTP_STATE_MAIL 2
192 #define SMTP_STATE_RCPT 3
193 #define SMTP_STATE_DATA 4
194 #define SMTP_STATE_DOT 5
195 #define SMTP_STATE_ABORT 6
196 #define SMTP_STATE_RSET 7
197 #define SMTP_STATE_QUIT 8
198 #define SMTP_STATE_LAST 9
200 int *xfer_timeouts[SMTP_STATE_LAST] = {
201 &var_smtp_xfwd_tmout, /* name/addr */
202 &var_smtp_xfwd_tmout, /* helo/proto */
203 &var_smtp_mail_tmout,
204 &var_smtp_rcpt_tmout,
205 &var_smtp_data0_tmout,
206 &var_smtp_data2_tmout,
207 &var_smtp_rset_tmout,
208 &var_smtp_rset_tmout,
209 &var_smtp_quit_tmout,
212 char *xfer_states[SMTP_STATE_LAST] = {
213 "sending XFORWARD name/address",
214 "sending XFORWARD protocol/helo_name",
215 "sending MAIL FROM",
216 "sending RCPT TO",
217 "sending DATA command",
218 "sending end of data -- message may be sent more than once",
219 "sending final RSET",
220 "sending RSET probe",
221 "sending QUIT",
224 char *xfer_request[SMTP_STATE_LAST] = {
225 "XFORWARD name/address command",
226 "XFORWARD helo/protocol command",
227 "MAIL FROM command",
228 "RCPT TO command",
229 "DATA command",
230 "end of DATA command",
231 "final RSET command",
232 "RSET probe",
233 "QUIT command",
236 #define SMTP_MIME_DOWNGRADE(session, request) \
237 (var_disable_mime_oconv == 0 \
238 && (session->features & SMTP_FEATURE_8BITMIME) == 0 \
239 && strcmp(request->encoding, MAIL_ATTR_ENC_7BIT) != 0)
241 static int smtp_start_tls(SMTP_STATE *);
244 * Call-back information for header/body checks. We don't provide call-backs
245 * for actions that change the message delivery time or destination.
247 static void smtp_hbc_logger(void *, const char *, const char *, const char *, const char *);
248 static void smtp_text_out(void *, int, const char *, ssize_t, off_t);
250 HBC_CALL_BACKS smtp_hbc_callbacks[1] = {
251 smtp_hbc_logger,
252 smtp_text_out,
255 /* smtp_helo - perform initial handshake with SMTP server */
257 int smtp_helo(SMTP_STATE *state)
259 const char *myname = "smtp_helo";
260 SMTP_SESSION *session = state->session;
261 DELIVER_REQUEST *request = state->request;
262 SMTP_RESP *resp;
263 SMTP_RESP fake;
264 int except;
265 char *lines;
266 char *words;
267 char *word;
268 int n;
269 static const NAME_CODE xforward_features[] = {
270 XFORWARD_NAME, SMTP_FEATURE_XFORWARD_NAME,
271 XFORWARD_ADDR, SMTP_FEATURE_XFORWARD_ADDR,
272 XFORWARD_PORT, SMTP_FEATURE_XFORWARD_PORT,
273 XFORWARD_PROTO, SMTP_FEATURE_XFORWARD_PROTO,
274 XFORWARD_HELO, SMTP_FEATURE_XFORWARD_HELO,
275 XFORWARD_DOMAIN, SMTP_FEATURE_XFORWARD_DOMAIN,
276 0, 0,
278 SOCKOPT_SIZE optlen;
279 int sndbufsize;
280 const char *ehlo_words;
281 int discard_mask;
282 static const NAME_MASK pix_bug_table[] = {
283 PIX_BUG_DISABLE_ESMTP, SMTP_FEATURE_PIX_NO_ESMTP,
284 PIX_BUG_DELAY_DOTCRLF, SMTP_FEATURE_PIX_DELAY_DOTCRLF,
287 const char *pix_bug_words;
288 const char *pix_bug_source;
289 int pix_bug_mask;
291 #ifdef USE_TLS
292 int saved_features = session->features;
293 int tls_helo_status;
295 #endif
296 const char *NOCLOBBER where;
299 * Prepare for disaster.
301 smtp_timeout_setup(state->session->stream, var_smtp_helo_tmout);
302 if ((except = vstream_setjmp(state->session->stream)) != 0)
303 return (smtp_stream_except(state, except, where));
306 * If not recursing after STARTTLS, examine the server greeting banner
307 * and decide if we are going to send EHLO as the next command.
309 if ((state->misc_flags & SMTP_MISC_FLAG_IN_STARTTLS) == 0) {
312 * Read and parse the server's SMTP greeting banner.
314 where = "receiving the initial server greeting";
315 switch ((resp = smtp_chat_resp(session))->code / 100) {
316 case 2:
317 break;
318 case 5:
319 if (var_smtp_skip_5xx_greeting)
320 STR(resp->dsn_buf)[0] = '4';
321 /* FALLTHROUGH */
322 default:
323 return (smtp_site_fail(state, session->host, resp,
324 "host %s refused to talk to me: %s",
325 session->namaddr,
326 translit(resp->str, "\n", " ")));
330 * If the policy table specifies a bogus TLS security level, fail
331 * now.
333 #ifdef USE_TLS
334 if (session->tls_level == TLS_LEV_INVALID)
335 /* Warning is already logged. */
336 return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
337 SMTP_RESP_FAKE(&fake, "4.7.0"),
338 "client TLS configuration problem"));
339 #endif
342 * XXX Some PIX firewall versions require flush before ".<CR><LF>" so
343 * it does not span a packet boundary. This hurts performance so it
344 * is not on by default.
346 if (resp->str[strspn(resp->str, "20 *\t\n")] == 0) {
347 if (smtp_pix_bug_maps != 0
348 && (pix_bug_words =
349 maps_find(smtp_pix_bug_maps,
350 state->session->addr, 0)) != 0) {
351 pix_bug_source = VAR_SMTP_PIX_BUG_MAPS;
352 } else {
353 pix_bug_words = var_smtp_pix_bug_words;
354 pix_bug_source = VAR_SMTP_PIX_BUG_WORDS;
356 if (*pix_bug_words) {
357 pix_bug_mask = name_mask_opt(pix_bug_source, pix_bug_table,
358 pix_bug_words, NAME_MASK_ANY_CASE);
359 msg_info("%s: enabling PIX workarounds: %s for %s",
360 request->queue_id,
361 str_name_mask("pix workaround bitmask",
362 pix_bug_table, pix_bug_mask),
363 session->namaddrport);
364 session->features |= pix_bug_mask;
369 * See if we are talking to ourself. This should not be possible with
370 * the way we implement DNS lookups. However, people are known to
371 * sometimes screw up the naming service. And, mailer loops are still
372 * possible when our own mailer routing tables are mis-configured.
374 words = resp->str;
375 (void) mystrtok(&words, "- \t\n");
376 for (n = 0; (word = mystrtok(&words, " \t\n")) != 0; n++) {
377 if (n == 0 && strcasecmp(word, var_myhostname) == 0) {
378 if (state->misc_flags & SMTP_MISC_FLAG_LOOP_DETECT)
379 msg_warn("host %s greeted me with my own hostname %s",
380 session->namaddrport, var_myhostname);
381 } else if (strcasecmp(word, "ESMTP") == 0)
382 session->features |= SMTP_FEATURE_ESMTP;
384 if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
385 if (var_smtp_always_ehlo
386 && (session->features & SMTP_FEATURE_PIX_NO_ESMTP) == 0)
387 session->features |= SMTP_FEATURE_ESMTP;
388 if (var_smtp_never_ehlo
389 || (session->features & SMTP_FEATURE_PIX_NO_ESMTP) != 0)
390 session->features &= ~SMTP_FEATURE_ESMTP;
391 } else {
392 session->features |= SMTP_FEATURE_ESMTP;
397 * If recursing after STARTTLS, there is no server greeting banner.
398 * Always send EHLO as the next command.
400 else {
401 session->features |= SMTP_FEATURE_ESMTP;
405 * Return the compliment. Fall back to SMTP if our ESMTP recognition
406 * heuristic failed.
408 if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
409 where = "performing the EHLO handshake";
410 if (session->features & SMTP_FEATURE_ESMTP) {
411 smtp_chat_cmd(session, "EHLO %s", var_smtp_helo_name);
412 if ((resp = smtp_chat_resp(session))->code / 100 != 2) {
413 if (resp->code == 421)
414 return (smtp_site_fail(state, session->host, resp,
415 "host %s refused to talk to me: %s",
416 session->namaddr,
417 translit(resp->str, "\n", " ")));
418 else
419 session->features &= ~SMTP_FEATURE_ESMTP;
422 if ((session->features & SMTP_FEATURE_ESMTP) == 0) {
423 where = "performing the HELO handshake";
424 smtp_chat_cmd(session, "HELO %s", var_smtp_helo_name);
425 if ((resp = smtp_chat_resp(session))->code / 100 != 2)
426 return (smtp_site_fail(state, session->host, resp,
427 "host %s refused to talk to me: %s",
428 session->namaddr,
429 translit(resp->str, "\n", " ")));
431 } else {
432 where = "performing the LHLO handshake";
433 smtp_chat_cmd(session, "LHLO %s", var_smtp_helo_name);
434 if ((resp = smtp_chat_resp(session))->code / 100 != 2)
435 return (smtp_site_fail(state, session->host, resp,
436 "host %s refused to talk to me: %s",
437 session->namaddr,
438 translit(resp->str, "\n", " ")));
442 * No early returns allowed, to ensure consistent handling of TLS and
443 * SASL policies.
445 if (session->features & SMTP_FEATURE_ESMTP) {
448 * Determine what server EHLO keywords to ignore, typically to avoid
449 * inter-operability problems.
451 if (smtp_ehlo_dis_maps == 0
452 || (ehlo_words = maps_find(smtp_ehlo_dis_maps,
453 state->session->addr, 0)) == 0)
454 ehlo_words = var_smtp_ehlo_dis_words;
455 discard_mask = ehlo_mask(ehlo_words);
456 if (discard_mask && !(discard_mask & EHLO_MASK_SILENT))
457 msg_info("discarding EHLO keywords: %s",
458 str_ehlo_mask(discard_mask));
461 * Pick up some useful features offered by the SMTP server. XXX Until
462 * we have a portable routine to convert from string to off_t with
463 * proper overflow detection, ignore the message size limit
464 * advertised by the SMTP server. Otherwise, we might do the wrong
465 * thing when the server advertises a really huge message size limit.
467 * XXX Allow for "code (SP|-) ehlo-keyword (SP|=) ehlo-param...",
468 * because MicroSoft implemented AUTH based on an old draft.
470 lines = resp->str;
471 for (n = 0; (words = mystrtok(&lines, "\n")) != 0; /* see below */ ) {
472 if (mystrtok(&words, "- ")
473 && (word = mystrtok(&words, " \t=")) != 0) {
474 if (n == 0) {
475 if (session->helo != 0)
476 myfree(session->helo);
479 * XXX: Keep the original case: we don't expect a single
480 * SMTP server to randomly change the case of its helo
481 * response. If different capitalization is detected, we
482 * should assume disjoint TLS caches.
484 session->helo = mystrdup(word);
485 if (strcasecmp(word, var_myhostname) == 0
486 && (state->misc_flags & SMTP_MISC_FLAG_LOOP_DETECT) != 0) {
487 msg_warn("host %s replied to HELO/EHLO"
488 " with my own hostname %s",
489 session->namaddrport, var_myhostname);
490 if (session->features & SMTP_FEATURE_BEST_MX)
491 return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
492 SMTP_RESP_FAKE(&fake, "5.4.6"),
493 "mail for %s loops back to myself",
494 request->nexthop));
495 else
496 return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
497 SMTP_RESP_FAKE(&fake, "4.4.6"),
498 "mail for %s loops back to myself",
499 request->nexthop));
501 } else if (strcasecmp(word, "8BITMIME") == 0) {
502 if ((discard_mask & EHLO_MASK_8BITMIME) == 0)
503 session->features |= SMTP_FEATURE_8BITMIME;
504 } else if (strcasecmp(word, "PIPELINING") == 0) {
505 if ((discard_mask & EHLO_MASK_PIPELINING) == 0)
506 session->features |= SMTP_FEATURE_PIPELINING;
507 } else if (strcasecmp(word, "XFORWARD") == 0) {
508 if ((discard_mask & EHLO_MASK_XFORWARD) == 0)
509 while ((word = mystrtok(&words, " \t")) != 0)
510 session->features |=
511 name_code(xforward_features,
512 NAME_CODE_FLAG_NONE, word);
513 } else if (strcasecmp(word, "SIZE") == 0) {
514 if ((discard_mask & EHLO_MASK_SIZE) == 0) {
515 session->features |= SMTP_FEATURE_SIZE;
516 if ((word = mystrtok(&words, " \t")) != 0) {
517 if (!alldig(word))
518 msg_warn("bad EHLO SIZE limit \"%s\" from %s",
519 word, session->namaddrport);
520 else
521 session->size_limit = off_cvt_string(word);
524 #ifdef USE_TLS
525 } else if (strcasecmp(word, "STARTTLS") == 0) {
526 /* Ignored later if we already sent STARTTLS. */
527 if ((discard_mask & EHLO_MASK_STARTTLS) == 0)
528 session->features |= SMTP_FEATURE_STARTTLS;
529 #endif
530 #ifdef USE_SASL_AUTH
531 } else if (var_smtp_sasl_enable
532 && strcasecmp(word, "AUTH") == 0) {
533 if ((discard_mask & EHLO_MASK_AUTH) == 0)
534 smtp_sasl_helo_auth(session, words);
535 #endif
536 } else if (strcasecmp(word, "DSN") == 0) {
537 if ((discard_mask & EHLO_MASK_DSN) == 0)
538 session->features |= SMTP_FEATURE_DSN;
540 n++;
544 if (msg_verbose)
545 msg_info("server features: 0x%x size %.0f",
546 session->features, (double) session->size_limit);
549 * We use SMTP command pipelining if the server said it supported it.
550 * Since we use blocking I/O, RFC 2197 says that we should inspect the
551 * TCP window size and not send more than this amount of information.
552 * Unfortunately this information is unavailable using the sockets
553 * interface. However, we *can* get the TCP send buffer size on the local
554 * TCP/IP stack. We should be able to fill this buffer without being
555 * blocked, and then the kernel will effectively do non-blocking I/O for
556 * us by automatically writing out the contents of its send buffer while
557 * we are reading in the responses. In addition to TCP buffering we have
558 * to be aware of application-level buffering by the vstream module,
559 * which is limited to a couple kbytes.
561 * XXX No need to do this before and after STARTTLS, but it's not a big deal
562 * if we do.
564 * XXX This critically depends on VSTREAM buffers to never be smaller than
565 * VSTREAM_BUFSIZE.
567 if (session->features & SMTP_FEATURE_PIPELINING) {
568 optlen = sizeof(sndbufsize);
569 if (getsockopt(vstream_fileno(session->stream), SOL_SOCKET,
570 SO_SNDBUF, (char *) &sndbufsize, &optlen) < 0)
571 msg_fatal("%s: getsockopt: %m", myname);
572 if (sndbufsize > VSTREAM_BUFSIZE)
573 sndbufsize = VSTREAM_BUFSIZE;
574 if (sndbufsize < VSTREAM_BUFSIZE) {
575 sndbufsize = VSTREAM_BUFSIZE;
576 if (setsockopt(vstream_fileno(session->stream), SOL_SOCKET,
577 SO_SNDBUF, (char *) &sndbufsize, optlen) < 0)
578 msg_fatal("%s: setsockopt: %m", myname);
580 if (msg_verbose)
581 msg_info("Using %s PIPELINING, TCP send buffer size is %d",
582 (state->misc_flags &
583 SMTP_MISC_FLAG_USE_LMTP) ? "LMTP" : "ESMTP",
584 sndbufsize);
586 #ifdef USE_TLS
589 * Skip this part if we already sent STARTTLS.
591 if ((state->misc_flags & SMTP_MISC_FLAG_IN_STARTTLS) == 0) {
594 * Optionally log unused STARTTLS opportunities.
596 if ((session->features & SMTP_FEATURE_STARTTLS) &&
597 var_smtp_tls_note_starttls_offer &&
598 session->tls_level <= TLS_LEV_NONE)
599 msg_info("Host offered STARTTLS: [%s]", session->host);
602 * Decide whether or not to send STARTTLS.
604 if ((session->features & SMTP_FEATURE_STARTTLS) != 0
605 && smtp_tls_ctx != 0 && session->tls_level >= TLS_LEV_MAY) {
608 * Prepare for disaster.
610 smtp_timeout_setup(state->session->stream, var_smtp_starttls_tmout);
611 if ((except = vstream_setjmp(state->session->stream)) != 0)
612 return (smtp_stream_except(state, except,
613 "receiving the STARTTLS response"));
616 * Send STARTTLS. Recurse when the server accepts STARTTLS, after
617 * resetting the SASL and EHLO features lists.
619 * Reset the SASL mechanism list to avoid spurious warnings.
621 * Use the smtp_sasl_tls_security_options feature to allow SASL
622 * mechanisms that may not be allowed with plain-text
623 * connections.
625 smtp_chat_cmd(session, "STARTTLS");
626 if ((resp = smtp_chat_resp(session))->code / 100 == 2) {
627 #ifdef USE_SASL_AUTH
628 if (session->features & SMTP_FEATURE_AUTH)
629 smtp_sasl_cleanup(session);
630 #endif
631 session->features = saved_features;
632 /* XXX Mix-up of per-session and per-request flags. */
633 state->misc_flags |= SMTP_MISC_FLAG_IN_STARTTLS;
634 tls_helo_status = smtp_start_tls(state);
635 state->misc_flags &= ~SMTP_MISC_FLAG_IN_STARTTLS;
636 return (tls_helo_status);
640 * Give up if we must use TLS but the server rejects STARTTLS
641 * although support for it was announced in the EHLO response.
643 session->features &= ~SMTP_FEATURE_STARTTLS;
644 if (session->tls_level >= TLS_LEV_ENCRYPT)
645 return (smtp_site_fail(state, session->host, resp,
646 "TLS is required, but host %s refused to start TLS: %s",
647 session->namaddr,
648 translit(resp->str, "\n", " ")));
649 /* Else try to continue in plain-text mode. */
653 * Give up if we must use TLS but can't for various reasons.
655 * 200412 Be sure to provide the default clause at the bottom of this
656 * block. When TLS is required we must never, ever, end up in
657 * plain-text mode.
659 if (session->tls_level >= TLS_LEV_ENCRYPT) {
660 if (!(session->features & SMTP_FEATURE_STARTTLS)) {
661 return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
662 SMTP_RESP_FAKE(&fake, "4.7.4"),
663 "TLS is required, but was not offered by host %s",
664 session->namaddr));
665 } else if (smtp_tls_ctx == 0) {
666 return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
667 SMTP_RESP_FAKE(&fake, "4.7.5"),
668 "TLS is required, but our TLS engine is unavailable"));
669 } else {
670 msg_warn("%s: TLS is required but unavailable, don't know why",
671 myname);
672 return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
673 SMTP_RESP_FAKE(&fake, "4.7.0"),
674 "TLS is required, but unavailable"));
678 #endif
679 #ifdef USE_SASL_AUTH
680 if (var_smtp_sasl_enable && (session->features & SMTP_FEATURE_AUTH))
681 return (smtp_sasl_helo_login(state));
682 #endif
684 return (0);
687 #ifdef USE_TLS
689 /* smtp_start_tls - turn on TLS and recurse into the HELO dialog */
691 static int smtp_start_tls(SMTP_STATE *state)
693 SMTP_SESSION *session = state->session;
694 TLS_CLIENT_START_PROPS tls_props;
695 VSTRING *serverid;
696 SMTP_RESP fake;
699 * Turn off SMTP connection caching. When the TLS handshake succeeds, we
700 * can't reuse the SMTP connection. Reason: we can't turn off TLS in one
701 * process, save the connection to the cache which is shared with all
702 * SMTP clients, migrate the connection to another SMTP client, and
703 * resume TLS there. When the TLS handshake fails, we can't reuse the
704 * SMTP connection either, because the conversation is in an unknown
705 * state.
707 DONT_CACHE_THIS_SESSION;
710 * As of Postfix 2.5, tls_client_start() tries hard to always complete
711 * the TLS handshake. It records the verification and match status in the
712 * resulting TLScontext. It is now up to the application to abort the TLS
713 * connection if it chooses.
715 * XXX When tls_client_start() fails then we don't know what state the SMTP
716 * connection is in, so we give up on this connection even if we are not
717 * required to use TLS.
719 * The following assumes sites that use TLS in a perverse configuration:
720 * multiple hosts per hostname, or even multiple hosts per IP address.
721 * All this without a shared TLS session cache, and they still want to
722 * use TLS session caching???
724 * The TLS session cache records the trust chain verification status of
725 * cached sessions. Different transports may have different CAfile or
726 * CApath settings, perhaps to allow authenticated connections to sites
727 * with private CA certs without trusting said private certs for other
728 * sites. So we cannot assume that a trust chain valid for one transport
729 * is valid for another. Therefore the client session id must include
730 * either the transport name or the values of CAfile and CApath. We use
731 * the transport name.
733 * XXX: We store only one session per lookup key. Ideally the the key maps
734 * 1-to-1 to a server TLS session cache. We use the IP address, port and
735 * ehlo response name to build a lookup key that works for split caches
736 * (that announce distinct names) behind a load balancer.
738 * XXX: The TLS library may salt the serverid with further details of the
739 * protocol and cipher requirements.
741 * Large parameter lists are error-prone, so we emulate a language feature
742 * that C does not have natively: named parameter lists.
744 serverid = vstring_alloc(10);
745 vstring_sprintf(serverid, "%s:%s:%u:%s", state->service, session->addr,
746 ntohs(session->port), session->helo ? session->helo : "");
747 session->tls_context =
748 TLS_CLIENT_START(&tls_props,
749 ctx = smtp_tls_ctx,
750 stream = session->stream,
751 log_level = var_smtp_tls_loglevel,
752 timeout = var_smtp_starttls_tmout,
753 tls_level = session->tls_level,
754 nexthop = session->tls_nexthop,
755 host = session->host,
756 namaddr = session->namaddrport,
757 serverid = vstring_str(serverid),
758 protocols = session->tls_protocols,
759 cipher_grade = session->tls_grade,
760 cipher_exclusions
761 = vstring_str(session->tls_exclusions),
762 matchargv = session->tls_matchargv,
763 fpt_dgst = var_smtp_tls_fpt_dgst);
764 vstring_free(serverid);
766 if (session->tls_context == 0) {
769 * We must avoid further I/O, the peer is in an undefined state.
771 (void) vstream_fpurge(session->stream, VSTREAM_PURGE_BOTH);
772 DONT_USE_DEAD_SESSION;
775 * If TLS is optional, try delivery to the same server over a
776 * plaintext connection. Otherwise we would defer mail forever with
777 * destinations that have no alternate MX host.
779 * Don't fall back to plaintext if we were willing to use SASL-over-TLS
780 * authentication. If the server doesn't announce SASL support over
781 * plaintext connections, then we don't want delivery to fail with
782 * "relay access denied".
784 if (session->tls_level == TLS_LEV_MAY
785 #ifdef USE_SASL_AUTH
786 && !(var_smtp_sasl_enable
787 && *var_smtp_sasl_passwd
788 && smtp_sasl_passwd_lookup(session))
789 #endif
791 RETRY_AS_PLAINTEXT;
792 return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
793 SMTP_RESP_FAKE(&fake, "4.7.5"),
794 "Cannot start TLS: handshake failure"));
798 * If we are verifying the server certificate and are not happy with the
799 * result, abort the delivery here. We have a usable TLS session with the
800 * server, so no need to disable I/O, ... we can even be polite and send
801 * "QUIT".
803 * See src/tls/tls_level.c. Levels above encrypt require matching. Levels >=
804 * verify require CA trust.
806 if (session->tls_level >= TLS_LEV_VERIFY)
807 if (!TLS_CERT_IS_TRUSTED(session->tls_context))
808 return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
809 SMTP_RESP_FAKE(&fake, "4.7.5"),
810 "Server certificate not trusted"));
811 if (session->tls_level > TLS_LEV_ENCRYPT)
812 if (!TLS_CERT_IS_MATCHED(session->tls_context))
813 return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
814 SMTP_RESP_FAKE(&fake, "4.7.5"),
815 "Server certificate not verified"));
818 * At this point we have to re-negotiate the "EHLO" to reget the
819 * feature-list.
821 return (smtp_helo(state));
824 #endif
826 /* smtp_hbc_logger - logging call-back for header/body checks */
828 static void smtp_hbc_logger(void *context, const char *action,
829 const char *where, const char *content,
830 const char *text)
832 const SMTP_STATE *state = (SMTP_STATE *) context;
834 if (*text) {
835 msg_info("%s: %s: %s %.60s: %s",
836 state->request->queue_id, action, where, content, text);
837 } else {
838 msg_info("%s: %s: %s %.60s",
839 state->request->queue_id, action, where, content);
843 /* smtp_text_out - output one header/body record */
845 static void smtp_text_out(void *context, int rec_type,
846 const char *text, ssize_t len,
847 off_t unused_offset)
849 SMTP_STATE *state = (SMTP_STATE *) context;
850 SMTP_SESSION *session = state->session;
851 ssize_t data_left;
852 const char *data_start;
855 * Deal with an impedance mismatch between Postfix queue files (record
856 * length <= $message_line_length_limit) and SMTP (DATA record length <=
857 * $smtp_line_length_limit). The code below does a little too much work
858 * when the SMTP line length limit is disabled, but it avoids code
859 * duplication, and thus, it avoids testing and maintenance problems.
861 data_left = len;
862 data_start = text;
863 do {
864 if (state->space_left == var_smtp_line_limit
865 && data_left > 0 && *data_start == '.')
866 smtp_fputc('.', session->stream);
867 if (var_smtp_line_limit > 0 && data_left >= state->space_left) {
868 smtp_fputs(data_start, state->space_left, session->stream);
869 data_start += state->space_left;
870 data_left -= state->space_left;
871 state->space_left = var_smtp_line_limit;
872 if (data_left > 0 || rec_type == REC_TYPE_CONT) {
873 smtp_fputc(' ', session->stream);
874 state->space_left -= 1;
876 } else {
877 if (rec_type == REC_TYPE_CONT) {
878 smtp_fwrite(data_start, data_left, session->stream);
879 state->space_left -= data_left;
880 } else {
881 smtp_fputs(data_start, data_left, session->stream);
882 state->space_left = var_smtp_line_limit;
884 break;
886 } while (data_left > 0);
889 /* smtp_format_out - output one header/body record */
891 static void PRINTFLIKE(3, 4) smtp_format_out(void *, int, const char *,...);
893 static void smtp_format_out(void *context, int rec_type, const char *fmt,...)
895 static VSTRING *vp;
896 va_list ap;
898 if (vp == 0)
899 vp = vstring_alloc(100);
900 va_start(ap, fmt);
901 vstring_vsprintf(vp, fmt, ap);
902 va_end(ap);
903 smtp_text_out(context, rec_type, vstring_str(vp), VSTRING_LEN(vp), 0);
906 /* smtp_header_out - output one message header */
908 static void smtp_header_out(void *context, int unused_header_class,
909 const HEADER_OPTS *unused_info,
910 VSTRING *buf, off_t offset)
912 char *start = vstring_str(buf);
913 char *line;
914 char *next_line;
917 * This code destroys the header. We could try to avoid clobbering it,
918 * but we're not going to use the data any further.
920 for (line = start; line; line = next_line) {
921 next_line = split_at(line, '\n');
922 smtp_text_out(context, REC_TYPE_NORM, line, next_line ?
923 next_line - line - 1 : strlen(line), offset);
927 /* smtp_header_rewrite - rewrite message header before output */
929 static void smtp_header_rewrite(void *context, int header_class,
930 const HEADER_OPTS *header_info,
931 VSTRING *buf, off_t offset)
933 SMTP_STATE *state = (SMTP_STATE *) context;
934 int did_rewrite = 0;
935 char *line;
936 char *start;
937 char *next_line;
938 char *end_line;
939 char *result;
942 * Apply optional header filtering.
944 if (smtp_header_checks) {
945 result = hbc_header_checks(context, smtp_header_checks, header_class,
946 header_info, buf, offset);
947 if (result == 0)
948 return;
949 if (result != STR(buf)) {
950 vstring_strcpy(buf, result);
951 myfree(result);
956 * Rewrite primary header addresses that match the smtp_generic_maps. The
957 * cleanup server already enforces that all headers have proper lengths
958 * and that all addresses are in proper form, so we don't have to repeat
959 * that.
961 if (smtp_generic_maps && header_info && header_class == MIME_HDR_PRIMARY
962 && (header_info->flags & (HDR_OPT_SENDER | HDR_OPT_RECIP)) != 0) {
963 TOK822 *tree;
964 TOK822 **addr_list;
965 TOK822 **tpp;
967 tree = tok822_parse(vstring_str(buf)
968 + strlen(header_info->name) + 1);
969 addr_list = tok822_grep(tree, TOK822_ADDR);
970 for (tpp = addr_list; *tpp; tpp++)
971 did_rewrite |= smtp_map11_tree(tpp[0], smtp_generic_maps,
972 smtp_ext_prop_mask & EXT_PROP_GENERIC);
973 if (did_rewrite) {
974 vstring_truncate(buf, strlen(header_info->name));
975 vstring_strcat(buf, ": ");
976 tok822_externalize(buf, tree, TOK822_STR_HEAD);
978 myfree((char *) addr_list);
979 tok822_free_tree(tree);
983 * Pass through unmodified headers without reconstruction.
985 if (did_rewrite == 0) {
986 smtp_header_out(context, header_class, header_info, buf, offset);
987 return;
991 * A rewritten address list contains one address per line. The code below
992 * replaces newlines by spaces, to fit as many addresses on a line as
993 * possible (without rearranging the order of addresses). Prepending
994 * white space to the beginning of lines is delegated to the output
995 * routine.
997 * Code derived from cleanup_fold_header().
999 for (line = start = vstring_str(buf); line != 0; line = next_line) {
1000 end_line = line + strcspn(line, "\n");
1001 if (line > start) {
1002 if (end_line - start < 70) { /* TAB counts as one */
1003 line[-1] = ' ';
1004 } else {
1005 start = line;
1008 next_line = *end_line ? end_line + 1 : 0;
1012 * Prepend a tab to continued header lines that went through the address
1013 * rewriting machinery. Just like smtp_header_out(), this code destroys
1014 * the header. We could try to avoid clobbering it, but we're not going
1015 * to use the data any further.
1017 * Code derived from cleanup_out_header().
1019 for (line = start = vstring_str(buf); line != 0; line = next_line) {
1020 next_line = split_at(line, '\n');
1021 if (line == start || IS_SPACE_TAB(*line)) {
1022 smtp_text_out(state, REC_TYPE_NORM, line, next_line ?
1023 next_line - line - 1 : strlen(line), offset);
1024 } else {
1025 smtp_format_out(state, REC_TYPE_NORM, "\t%s", line);
1030 /* smtp_body_rewrite - rewrite message body before output */
1032 static void smtp_body_rewrite(void *context, int type,
1033 const char *buf, ssize_t len,
1034 off_t offset)
1036 SMTP_STATE *state = (SMTP_STATE *) context;
1037 char *result;
1040 * Apply optional body filtering.
1042 if (smtp_body_checks) {
1043 result = hbc_body_checks(context, smtp_body_checks, buf, len, offset);
1044 if (result == buf) {
1045 smtp_text_out(state, type, buf, len, offset);
1046 } else if (result != 0) {
1047 smtp_text_out(state, type, result, strlen(result), offset);
1048 myfree(result);
1053 /* smtp_mime_fail - MIME problem */
1055 static void smtp_mime_fail(SMTP_STATE *state, int mime_errs)
1057 const MIME_STATE_DETAIL *detail;
1058 SMTP_RESP fake;
1060 detail = mime_state_detail(mime_errs);
1061 smtp_mesg_fail(state, DSN_BY_LOCAL_MTA,
1062 SMTP_RESP_FAKE(&fake, detail->dsn),
1063 "%s", detail->text);
1066 /* smtp_loop - exercise the SMTP protocol engine */
1068 static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
1069 NOCLOBBER int recv_state)
1071 const char *myname = "smtp_loop";
1072 DELIVER_REQUEST *request = state->request;
1073 SMTP_SESSION *session = state->session;
1074 SMTP_RESP *resp;
1075 RECIPIENT *rcpt;
1076 VSTRING *next_command = vstring_alloc(100);
1077 int *NOCLOBBER survivors = 0;
1078 NOCLOBBER int next_state;
1079 NOCLOBBER int next_rcpt;
1080 NOCLOBBER int send_rcpt;
1081 NOCLOBBER int recv_rcpt;
1082 NOCLOBBER int nrcpt;
1083 NOCLOBBER int recv_done;
1084 int except;
1085 int rec_type;
1086 NOCLOBBER int prev_type = 0;
1087 NOCLOBBER int mail_from_rejected;
1088 NOCLOBBER int downgrading;
1089 int mime_errs;
1090 SMTP_RESP fake;
1091 int fail_status;
1094 * Macros for readability.
1096 #define REWRITE_ADDRESS(dst, src) do { \
1097 vstring_strcpy(dst, src); \
1098 if (*(src) && smtp_generic_maps) \
1099 smtp_map11_internal(dst, smtp_generic_maps, \
1100 smtp_ext_prop_mask & EXT_PROP_GENERIC); \
1101 } while (0)
1103 #define QUOTE_ADDRESS(dst, src) do { \
1104 if (*(src) && var_smtp_quote_821_env) { \
1105 quote_821_local(dst, src); \
1106 } else { \
1107 vstring_strcpy(dst, src); \
1109 } while (0)
1111 /* Caution: changes to RETURN() also affect code outside the main loop. */
1113 #define RETURN(x) do { \
1114 if (recv_state != SMTP_STATE_LAST) \
1115 DONT_CACHE_THIS_SESSION; \
1116 vstring_free(next_command); \
1117 if (survivors) \
1118 myfree((char *) survivors); \
1119 if (session->mime_state) \
1120 session->mime_state = mime_state_free(session->mime_state); \
1121 return (x); \
1122 } while (0)
1124 #define SENDER_IS_AHEAD \
1125 (recv_state < send_state || recv_rcpt != send_rcpt)
1127 #define SENDER_IN_WAIT_STATE \
1128 (send_state == SMTP_STATE_DOT || send_state == SMTP_STATE_LAST)
1130 #define SENDING_MAIL \
1131 (recv_state <= SMTP_STATE_DOT)
1133 #define CANT_RSET_THIS_SESSION \
1134 (session->features |= SMTP_FEATURE_RSET_REJECTED)
1137 * Pipelining support requires two loops: one loop for sending and one
1138 * for receiving. Each loop has its own independent state. Most of the
1139 * time the sender can run ahead of the receiver by as much as the TCP
1140 * send buffer permits. There are only two places where the sender must
1141 * wait for status information from the receiver: once after sending DATA
1142 * and once after sending QUIT.
1144 * The sender state advances until the TCP send buffer would overflow, or
1145 * until the sender needs status information from the receiver. At that
1146 * point the receiver starts processing responses. Once the receiver has
1147 * caught up with the sender, the sender resumes sending commands. If the
1148 * receiver detects a serious problem (MAIL FROM rejected, all RCPT TO
1149 * commands rejected, DATA rejected) it forces the sender to abort the
1150 * SMTP dialog with RSET and QUIT.
1152 nrcpt = 0;
1153 next_rcpt = send_rcpt = recv_rcpt = recv_done = 0;
1154 mail_from_rejected = 0;
1157 * Prepare for disaster. This should not be needed because the design
1158 * guarantees that no output is flushed before smtp_chat_resp() is
1159 * called.
1161 * 1) Every SMTP command fits entirely in a VSTREAM output buffer.
1163 * 2) smtp_loop() never invokes smtp_chat_cmd() without making sure that
1164 * there is sufficient space for the command in the output buffer.
1166 * 3) smtp_loop() flushes the output buffer to avoid server timeouts.
1168 * Changing any of these would violate the design, and would likely break
1169 * SMTP pipelining.
1171 * We set up the error handler anyway (only upon entry to avoid wasting
1172 * resources) because 1) there is code below that expects that VSTREAM
1173 * timeouts are enabled, and 2) this allows us to detect if someone broke
1174 * Postfix by introducing spurious flush before read operations.
1176 if (send_state < SMTP_STATE_XFORWARD_NAME_ADDR
1177 || send_state > SMTP_STATE_QUIT)
1178 msg_panic("%s: bad sender state %d (receiver state %d)",
1179 myname, send_state, recv_state);
1180 smtp_timeout_setup(session->stream,
1181 *xfer_timeouts[send_state]);
1182 if ((except = vstream_setjmp(session->stream)) != 0) {
1183 msg_warn("smtp_proto: spurious flush before read in send state %d",
1184 send_state);
1185 RETURN(SENDING_MAIL ? smtp_stream_except(state, except,
1186 xfer_states[send_state]) : -1);
1190 * The main protocol loop.
1192 do {
1195 * Build the next command.
1197 switch (send_state) {
1200 * Sanity check.
1202 default:
1203 msg_panic("%s: bad sender state %d", myname, send_state);
1206 * Build the XFORWARD command. With properly sanitized
1207 * information, the command length stays within the 512 byte
1208 * command line length limit.
1210 case SMTP_STATE_XFORWARD_NAME_ADDR:
1211 vstring_strcpy(next_command, XFORWARD_CMD);
1212 if ((session->features & SMTP_FEATURE_XFORWARD_NAME)
1213 && DEL_REQ_ATTR_AVAIL(request->client_name)) {
1214 vstring_strcat(next_command, " " XFORWARD_NAME "=");
1215 xtext_quote_append(next_command, request->client_name, "");
1217 if ((session->features & SMTP_FEATURE_XFORWARD_ADDR)
1218 && DEL_REQ_ATTR_AVAIL(request->client_addr)) {
1219 vstring_strcat(next_command, " " XFORWARD_ADDR "=");
1220 xtext_quote_append(next_command, request->client_addr, "");
1222 if ((session->features & SMTP_FEATURE_XFORWARD_PORT)
1223 && DEL_REQ_ATTR_AVAIL(request->client_port)) {
1224 vstring_strcat(next_command, " " XFORWARD_PORT "=");
1225 xtext_quote_append(next_command, request->client_port, "");
1227 if (session->send_proto_helo)
1228 next_state = SMTP_STATE_XFORWARD_PROTO_HELO;
1229 else
1230 next_state = SMTP_STATE_MAIL;
1231 break;
1233 case SMTP_STATE_XFORWARD_PROTO_HELO:
1234 vstring_strcpy(next_command, XFORWARD_CMD);
1235 if ((session->features & SMTP_FEATURE_XFORWARD_PROTO)
1236 && DEL_REQ_ATTR_AVAIL(request->client_proto)) {
1237 vstring_strcat(next_command, " " XFORWARD_PROTO "=");
1238 xtext_quote_append(next_command, request->client_proto, "");
1240 if ((session->features & SMTP_FEATURE_XFORWARD_HELO)
1241 && DEL_REQ_ATTR_AVAIL(request->client_helo)) {
1242 vstring_strcat(next_command, " " XFORWARD_HELO "=");
1243 xtext_quote_append(next_command, request->client_helo, "");
1245 if ((session->features & SMTP_FEATURE_XFORWARD_DOMAIN)
1246 && DEL_REQ_ATTR_AVAIL(request->rewrite_context)) {
1247 vstring_strcat(next_command, " " XFORWARD_DOMAIN "=");
1248 xtext_quote_append(next_command,
1249 strcmp(request->rewrite_context, MAIL_ATTR_RWR_LOCAL) ?
1250 XFORWARD_DOM_REMOTE : XFORWARD_DOM_LOCAL, "");
1252 next_state = SMTP_STATE_MAIL;
1253 break;
1256 * Build the MAIL FROM command.
1258 case SMTP_STATE_MAIL:
1259 request->msg_stats.reuse_count = session->reuse_count;
1260 GETTIMEOFDAY(&request->msg_stats.conn_setup_done);
1261 REWRITE_ADDRESS(session->scratch2, request->sender);
1262 QUOTE_ADDRESS(session->scratch, vstring_str(session->scratch2));
1263 vstring_sprintf(next_command, "MAIL FROM:<%s>",
1264 vstring_str(session->scratch));
1265 /* XXX Don't announce SIZE if we're going to MIME downgrade. */
1266 if (session->features & SMTP_FEATURE_SIZE /* RFC 1870 */
1267 && !SMTP_MIME_DOWNGRADE(session, request))
1268 vstring_sprintf_append(next_command, " SIZE=%lu",
1269 request->data_size);
1270 if (session->features & SMTP_FEATURE_8BITMIME) { /* RFC 1652 */
1271 if (strcmp(request->encoding, MAIL_ATTR_ENC_8BIT) == 0)
1272 vstring_strcat(next_command, " BODY=8BITMIME");
1273 else if (strcmp(request->encoding, MAIL_ATTR_ENC_7BIT) == 0)
1274 vstring_strcat(next_command, " BODY=7BIT");
1275 else if (strcmp(request->encoding, MAIL_ATTR_ENC_NONE) != 0)
1276 msg_warn("%s: unknown content encoding: %s",
1277 request->queue_id, request->encoding);
1279 if (session->features & SMTP_FEATURE_DSN) {
1280 if (request->dsn_envid[0]) {
1281 vstring_sprintf_append(next_command, " ENVID=");
1282 xtext_quote_append(next_command, request->dsn_envid, "+=");
1284 if (request->dsn_ret)
1285 vstring_sprintf_append(next_command, " RET=%s",
1286 dsn_ret_str(request->dsn_ret));
1290 * We authenticate the local MTA only, but not the sender.
1292 #ifdef USE_SASL_AUTH
1293 if (var_smtp_sasl_enable
1294 && (session->features & SMTP_FEATURE_AUTH))
1295 vstring_strcat(next_command, " AUTH=<>");
1296 #endif
1297 next_state = SMTP_STATE_RCPT;
1298 break;
1301 * Build one RCPT TO command before we have seen the MAIL FROM
1302 * response.
1304 case SMTP_STATE_RCPT:
1305 rcpt = request->rcpt_list.info + send_rcpt;
1306 REWRITE_ADDRESS(session->scratch2, rcpt->address);
1307 QUOTE_ADDRESS(session->scratch, vstring_str(session->scratch2));
1308 vstring_sprintf(next_command, "RCPT TO:<%s>",
1309 vstring_str(session->scratch));
1310 if (session->features & SMTP_FEATURE_DSN) {
1311 /* XXX DSN xtext encode address value not type. */
1312 if (rcpt->dsn_orcpt[0]) {
1313 xtext_quote(session->scratch, rcpt->dsn_orcpt, "+=");
1314 vstring_sprintf_append(next_command, " ORCPT=%s",
1315 vstring_str(session->scratch));
1316 } else if (rcpt->orig_addr[0]) {
1317 quote_822_local(session->scratch, rcpt->orig_addr);
1318 vstring_sprintf(session->scratch2, "rfc822;%s",
1319 vstring_str(session->scratch));
1320 xtext_quote(session->scratch, vstring_str(session->scratch2), "+=");
1321 vstring_sprintf_append(next_command, " ORCPT=%s",
1322 vstring_str(session->scratch));
1324 if (rcpt->dsn_notify)
1325 vstring_sprintf_append(next_command, " NOTIFY=%s",
1326 dsn_notify_str(rcpt->dsn_notify));
1328 if ((next_rcpt = send_rcpt + 1) == SMTP_RCPT_LEFT(state))
1329 next_state = DEL_REQ_TRACE_ONLY(request->flags) ?
1330 SMTP_STATE_ABORT : SMTP_STATE_DATA;
1331 break;
1334 * Build the DATA command before we have seen all the RCPT TO
1335 * responses.
1337 case SMTP_STATE_DATA:
1338 vstring_strcpy(next_command, "DATA");
1339 next_state = SMTP_STATE_DOT;
1340 break;
1343 * Build the "." command after we have seen the DATA response
1344 * (DATA is a protocol synchronization point).
1346 * Changing the connection caching state here is safe because it
1347 * affects none of the not-yet processed replies to
1348 * already-generated commands.
1350 case SMTP_STATE_DOT:
1351 vstring_strcpy(next_command, ".");
1352 if (THIS_SESSION_IS_EXPIRED)
1353 DONT_CACHE_THIS_SESSION;
1354 next_state = THIS_SESSION_IS_CACHED ?
1355 SMTP_STATE_LAST : SMTP_STATE_QUIT;
1356 break;
1359 * The SMTP_STATE_ABORT sender state is entered by the sender
1360 * when it has verified all recipients; or it is entered by the
1361 * receiver when all recipients are verified or rejected, and is
1362 * then left before the bottom of the main loop.
1364 * Changing the connection caching state here is safe because there
1365 * are no not-yet processed replies to already-generated
1366 * commands.
1368 case SMTP_STATE_ABORT:
1369 vstring_strcpy(next_command, "RSET");
1370 if (THIS_SESSION_IS_EXPIRED)
1371 DONT_CACHE_THIS_SESSION;
1372 next_state = THIS_SESSION_IS_CACHED ?
1373 SMTP_STATE_LAST : SMTP_STATE_QUIT;
1374 break;
1377 * Build the RSET command. This is entered as initial state from
1378 * smtp_rset() and has its own dedicated state transitions. It is
1379 * used to find out the status of a cached session before
1380 * attempting mail delivery.
1382 case SMTP_STATE_RSET:
1383 vstring_strcpy(next_command, "RSET");
1384 next_state = SMTP_STATE_LAST;
1385 break;
1388 * Build the QUIT command before we have seen the "." or RSET
1389 * response. This is entered as initial state from smtp_quit(),
1390 * or is reached near the end of any non-cached session.
1392 * Changing the connection caching state here is safe. If this
1393 * command is pipelined together with a preceding command, then
1394 * connection caching was already turned off. Do not clobber the
1395 * "bad connection" flag.
1397 case SMTP_STATE_QUIT:
1398 vstring_strcpy(next_command, "QUIT");
1399 next_state = SMTP_STATE_LAST;
1400 if (THIS_SESSION_IS_CACHED)
1401 DONT_CACHE_THIS_SESSION;
1402 break;
1405 * The final sender state has no action associated with it.
1407 case SMTP_STATE_LAST:
1408 VSTRING_RESET(next_command);
1409 break;
1411 VSTRING_TERMINATE(next_command);
1414 * Process responses until the receiver has caught up. Vstreams
1415 * automatically flush buffered output when reading new data.
1417 * Flush unsent output if command pipelining is off or if no I/O
1418 * happened for a while. This limits the accumulation of client-side
1419 * delays in pipelined sessions.
1421 if (SENDER_IN_WAIT_STATE
1422 || (SENDER_IS_AHEAD
1423 && ((session->features & SMTP_FEATURE_PIPELINING) == 0
1424 || (VSTRING_LEN(next_command) + 2
1425 + vstream_bufstat(session->stream, VSTREAM_BST_OUT_PEND)
1426 > VSTREAM_BUFSIZE)
1427 || time((time_t *) 0)
1428 - vstream_ftime(session->stream) > 10))) {
1429 while (SENDER_IS_AHEAD) {
1432 * Sanity check.
1434 if (recv_state < SMTP_STATE_XFORWARD_NAME_ADDR
1435 || recv_state > SMTP_STATE_QUIT)
1436 msg_panic("%s: bad receiver state %d (sender state %d)",
1437 myname, recv_state, send_state);
1440 * Receive the next server response. Use the proper timeout,
1441 * and log the proper client state in case of trouble.
1443 * XXX If we lose the connection before sending end-of-data,
1444 * find out if the server sent a premature end-of-data reply.
1445 * If this read attempt fails, report "lost connection while
1446 * sending message body", not "lost connection while sending
1447 * end-of-data".
1449 * "except" becomes zero just above the protocol loop, and stays
1450 * zero or triggers an early return from the loop. In just
1451 * one case: loss of the connection when sending the message
1452 * body, we record the exception, and keep processing in the
1453 * hope of detecting a premature 5XX. We must be careful to
1454 * not clobber this non-zero value once it is set. The
1455 * variable need not survive longjmp() calls, since the only
1456 * setjmp() which does not return early is the one sets this
1457 * condition, subquent failures always return early.
1459 #define LOST_CONNECTION_INSIDE_DATA (except == SMTP_ERR_EOF)
1461 smtp_timeout_setup(session->stream,
1462 *xfer_timeouts[recv_state]);
1463 if (LOST_CONNECTION_INSIDE_DATA) {
1464 if (vstream_setjmp(session->stream) != 0)
1465 RETURN(smtp_stream_except(state, SMTP_ERR_EOF,
1466 "sending message body"));
1467 } else {
1468 if ((except = vstream_setjmp(session->stream)) != 0)
1469 RETURN(SENDING_MAIL ? smtp_stream_except(state, except,
1470 xfer_states[recv_state]) : -1);
1472 resp = smtp_chat_resp(session);
1475 * Process the response.
1477 switch (recv_state) {
1480 * Process the XFORWARD response.
1482 case SMTP_STATE_XFORWARD_NAME_ADDR:
1483 if (resp->code / 100 != 2)
1484 msg_warn("host %s said: %s (in reply to %s)",
1485 session->namaddrport,
1486 translit(resp->str, "\n", " "),
1487 xfer_request[SMTP_STATE_XFORWARD_NAME_ADDR]);
1488 if (session->send_proto_helo)
1489 recv_state = SMTP_STATE_XFORWARD_PROTO_HELO;
1490 else
1491 recv_state = SMTP_STATE_MAIL;
1492 break;
1494 case SMTP_STATE_XFORWARD_PROTO_HELO:
1495 if (resp->code / 100 != 2)
1496 msg_warn("host %s said: %s (in reply to %s)",
1497 session->namaddrport,
1498 translit(resp->str, "\n", " "),
1499 xfer_request[SMTP_STATE_XFORWARD_PROTO_HELO]);
1500 recv_state = SMTP_STATE_MAIL;
1501 break;
1504 * Process the MAIL FROM response. When the server
1505 * rejects the sender, set the mail_from_rejected flag so
1506 * that the receiver may apply a course correction.
1508 case SMTP_STATE_MAIL:
1509 if (resp->code / 100 != 2) {
1510 smtp_mesg_fail(state, session->host, resp,
1511 "host %s said: %s (in reply to %s)",
1512 session->namaddr,
1513 translit(resp->str, "\n", " "),
1514 xfer_request[SMTP_STATE_MAIL]);
1515 mail_from_rejected = 1;
1517 recv_state = SMTP_STATE_RCPT;
1518 break;
1521 * Process one RCPT TO response. If MAIL FROM was
1522 * rejected, ignore RCPT TO responses: all recipients are
1523 * dead already. When all recipients are rejected the
1524 * receiver may apply a course correction.
1526 * XXX 2821: Section 4.5.3.1 says that a 552 RCPT TO reply
1527 * must be treated as if the server replied with 452.
1528 * However, this causes "too much mail data" to be
1529 * treated as a recoverable error, which is wrong. I'll
1530 * stick with RFC 821.
1532 case SMTP_STATE_RCPT:
1533 if (!mail_from_rejected) {
1534 #ifdef notdef
1535 if (resp->code == 552) {
1536 resp->code = 452;
1537 resp->dsn[0] = '4';
1539 #endif
1540 rcpt = request->rcpt_list.info + recv_rcpt;
1541 if (resp->code / 100 == 2) {
1542 if (state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) {
1543 if (survivors == 0)
1544 survivors = (int *)
1545 mymalloc(request->rcpt_list.len
1546 * sizeof(int));
1547 survivors[nrcpt] = recv_rcpt;
1549 ++nrcpt;
1550 /* If trace-only, mark the recipient done. */
1551 if (DEL_REQ_TRACE_ONLY(request->flags)) {
1552 translit(resp->str, "\n", " ");
1553 smtp_rcpt_done(state, resp, rcpt);
1555 } else {
1556 smtp_rcpt_fail(state, rcpt, session->host, resp,
1557 "host %s said: %s (in reply to %s)",
1558 session->namaddr,
1559 translit(resp->str, "\n", " "),
1560 xfer_request[SMTP_STATE_RCPT]);
1563 /* If trace-only, send RSET instead of DATA. */
1564 if (++recv_rcpt == SMTP_RCPT_LEFT(state))
1565 recv_state = DEL_REQ_TRACE_ONLY(request->flags) ?
1566 SMTP_STATE_ABORT : SMTP_STATE_DATA;
1567 /* XXX Also: record if non-delivering session. */
1568 break;
1571 * Process the DATA response. When the server rejects
1572 * DATA, set nrcpt to a negative value so that the
1573 * receiver can apply a course correction.
1575 case SMTP_STATE_DATA:
1576 if (resp->code / 100 != 3) {
1577 if (nrcpt > 0)
1578 smtp_mesg_fail(state, session->host, resp,
1579 "host %s said: %s (in reply to %s)",
1580 session->namaddr,
1581 translit(resp->str, "\n", " "),
1582 xfer_request[SMTP_STATE_DATA]);
1583 nrcpt = -1;
1585 recv_state = SMTP_STATE_DOT;
1586 break;
1589 * Process the end of message response. Ignore the
1590 * response when no recipient was accepted: all
1591 * recipients are dead already, and the next receiver
1592 * state is SMTP_STATE_LAST/QUIT regardless. Otherwise,
1593 * if the message transfer fails, bounce all remaining
1594 * recipients, else cross off the recipients that were
1595 * delivered.
1597 case SMTP_STATE_DOT:
1598 GETTIMEOFDAY(&request->msg_stats.deliver_done);
1599 if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
1600 if (nrcpt > 0) {
1601 if (resp->code / 100 != 2) {
1602 smtp_mesg_fail(state, session->host, resp,
1603 "host %s said: %s (in reply to %s)",
1604 session->namaddr,
1605 translit(resp->str, "\n", " "),
1606 xfer_request[SMTP_STATE_DOT]);
1607 } else {
1608 for (nrcpt = 0; nrcpt < recv_rcpt; nrcpt++) {
1609 rcpt = request->rcpt_list.info + nrcpt;
1610 if (!SMTP_RCPT_ISMARKED(rcpt)) {
1611 translit(resp->str, "\n", " ");
1612 smtp_rcpt_done(state, resp, rcpt);
1620 * With LMTP we have one response per accepted RCPT TO
1621 * command. Stay in the SMTP_STATE_DOT state until we
1622 * have collected all responses.
1624 else {
1625 if (nrcpt > 0) {
1626 rcpt = request->rcpt_list.info
1627 + survivors[recv_done++];
1628 if (resp->code / 100 != 2) {
1629 smtp_rcpt_fail(state, rcpt, session->host, resp,
1630 "host %s said: %s (in reply to %s)",
1631 session->namaddr,
1632 translit(resp->str, "\n", " "),
1633 xfer_request[SMTP_STATE_DOT]);
1634 } else {
1635 translit(resp->str, "\n", " ");
1636 smtp_rcpt_done(state, resp, rcpt);
1639 if (msg_verbose)
1640 msg_info("%s: got %d of %d end-of-data replies",
1641 myname, recv_done, nrcpt);
1642 if (recv_done < nrcpt)
1643 break;
1647 * XXX Do not change the connection caching state here,
1648 * even if the connection caching timer expired between
1649 * generating the command and processing the reply,
1650 * otherwise the sender and receiver loops get out of
1651 * sync. The caller will call smtp_quit() if appropriate.
1653 if (var_skip_quit_resp || THIS_SESSION_IS_CACHED
1654 || LOST_CONNECTION_INSIDE_DATA)
1655 recv_state = SMTP_STATE_LAST;
1656 else
1657 recv_state = SMTP_STATE_QUIT;
1658 break;
1661 * Receive the RSET response.
1663 * The SMTP_STATE_ABORT sender state is entered by the
1664 * sender when it has verified all recipients; or it is
1665 * entered by the receiver when all recipients are
1666 * verified or rejected, and is then left before the
1667 * bottom of the main loop.
1669 * XXX Do not change the connection caching state here, even
1670 * if the server rejected RSET or if the connection
1671 * caching timer expired between generating the command
1672 * and processing the reply, otherwise the sender and
1673 * receiver loops get out of sync. The caller will call
1674 * smtp_quit() if appropriate.
1676 case SMTP_STATE_ABORT:
1677 recv_state = (var_skip_quit_resp || THIS_SESSION_IS_CACHED ?
1678 SMTP_STATE_LAST : SMTP_STATE_QUIT);
1679 break;
1682 * This is the initial receiver state from smtp_rset().
1683 * It is used to find out the status of a cached session
1684 * before attempting mail delivery.
1686 case SMTP_STATE_RSET:
1687 if (resp->code / 100 != 2)
1688 CANT_RSET_THIS_SESSION;
1689 recv_state = SMTP_STATE_LAST;
1690 break;
1693 * Receive, but otherwise ignore, the QUIT response.
1695 case SMTP_STATE_QUIT:
1696 recv_state = SMTP_STATE_LAST;
1697 break;
1702 * At this point, the sender and receiver are fully synchronized.
1706 * We know the server response to every command that was sent.
1707 * Apply a course correction if necessary: the sender wants to
1708 * send RCPT TO but MAIL FROM was rejected; the sender wants to
1709 * send DATA but all recipients were rejected; the sender wants
1710 * to deliver the message but DATA was rejected.
1712 if ((send_state == SMTP_STATE_RCPT && mail_from_rejected)
1713 || (send_state == SMTP_STATE_DATA && nrcpt == 0)
1714 || (send_state == SMTP_STATE_DOT && nrcpt < 0)) {
1715 send_state = recv_state = SMTP_STATE_ABORT;
1716 send_rcpt = recv_rcpt = 0;
1717 vstring_strcpy(next_command, "RSET");
1718 if (THIS_SESSION_IS_EXPIRED)
1719 DONT_CACHE_THIS_SESSION;
1720 next_state = THIS_SESSION_IS_CACHED ?
1721 SMTP_STATE_LAST : SMTP_STATE_QUIT;
1722 /* XXX Also: record if non-delivering session. */
1723 next_rcpt = 0;
1728 * Make the next sender state the current sender state.
1730 if (send_state == SMTP_STATE_LAST)
1731 continue;
1734 * Special case if the server accepted the DATA command. If the
1735 * server accepted at least one recipient send the entire message.
1736 * Otherwise, just send "." as per RFC 2197.
1738 * XXX If there is a hard MIME error while downgrading to 7-bit mail,
1739 * disconnect ungracefully, because there is no other way to cancel a
1740 * transaction in progress.
1742 if (send_state == SMTP_STATE_DOT && nrcpt > 0) {
1744 smtp_timeout_setup(session->stream,
1745 var_smtp_data1_tmout);
1747 if ((except = vstream_setjmp(session->stream)) == 0) {
1749 if (vstream_fseek(state->src, request->data_offset, SEEK_SET) < 0)
1750 msg_fatal("seek queue file: %m");
1752 downgrading = SMTP_MIME_DOWNGRADE(session, request);
1755 * XXX Don't downgrade just because generic_maps is turned
1756 * on.
1758 #define SMTP_ANY_CHECKS (smtp_header_checks || smtp_body_checks)
1760 if (downgrading || smtp_generic_maps || SMTP_ANY_CHECKS)
1761 session->mime_state = mime_state_alloc(downgrading ?
1762 MIME_OPT_DOWNGRADE
1763 | MIME_OPT_REPORT_NESTING :
1764 SMTP_ANY_CHECKS == 0 ?
1765 MIME_OPT_DISABLE_MIME :
1767 smtp_generic_maps
1768 || smtp_header_checks ?
1769 smtp_header_rewrite :
1770 smtp_header_out,
1771 (MIME_STATE_ANY_END) 0,
1772 smtp_body_checks ?
1773 smtp_body_rewrite :
1774 smtp_text_out,
1775 (MIME_STATE_ANY_END) 0,
1776 (MIME_STATE_ERR_PRINT) 0,
1777 (void *) state);
1778 state->space_left = var_smtp_line_limit;
1780 while ((rec_type = rec_get(state->src, session->scratch, 0)) > 0) {
1781 if (rec_type != REC_TYPE_NORM && rec_type != REC_TYPE_CONT)
1782 break;
1783 if (session->mime_state == 0) {
1784 smtp_text_out((void *) state, rec_type,
1785 vstring_str(session->scratch),
1786 VSTRING_LEN(session->scratch),
1787 (off_t) 0);
1788 } else {
1789 mime_errs =
1790 mime_state_update(session->mime_state, rec_type,
1791 vstring_str(session->scratch),
1792 VSTRING_LEN(session->scratch));
1793 if (mime_errs) {
1794 smtp_mime_fail(state, mime_errs);
1795 RETURN(0);
1798 prev_type = rec_type;
1801 if (session->mime_state) {
1804 * The cleanup server normally ends MIME content with a
1805 * normal text record. The following code is needed to
1806 * flush an internal buffer when someone submits 8-bit
1807 * mail not ending in newline via /usr/sbin/sendmail
1808 * while MIME input processing is turned off, and MIME
1809 * 8bit->7bit conversion is requested upon delivery.
1811 * Or some error while doing generic address mapping.
1813 mime_errs =
1814 mime_state_update(session->mime_state, rec_type, "", 0);
1815 if (mime_errs) {
1816 smtp_mime_fail(state, mime_errs);
1817 RETURN(0);
1819 } else if (prev_type == REC_TYPE_CONT) /* missing newline */
1820 smtp_fputs("", 0, session->stream);
1821 if ((session->features & SMTP_FEATURE_PIX_DELAY_DOTCRLF) != 0
1822 && request->msg_stats.incoming_arrival.tv_sec
1823 <= vstream_ftime(session->stream) - var_smtp_pix_thresh) {
1824 smtp_flush(session->stream);/* hurts performance */
1825 sleep(var_smtp_pix_delay); /* not to mention this */
1827 if (vstream_ferror(state->src))
1828 msg_fatal("queue file read error");
1829 if (rec_type != REC_TYPE_XTRA) {
1830 msg_warn("%s: bad record type: %d in message content",
1831 request->queue_id, rec_type);
1832 fail_status = smtp_mesg_fail(state, DSN_BY_LOCAL_MTA,
1833 SMTP_RESP_FAKE(&fake, "5.3.0"),
1834 "unreadable mail queue entry");
1835 /* Bailing out, abort stream with prejudice */
1836 (void) vstream_fpurge(session->stream, VSTREAM_PURGE_BOTH);
1837 DONT_USE_DEAD_SESSION;
1838 /* If bounce_append() succeeded, status is still 0 */
1839 if (state->status == 0)
1840 (void) mark_corrupt(state->src);
1841 /* Don't override smtp_mesg_fail() here. */
1842 RETURN(fail_status);
1844 } else {
1845 if (!LOST_CONNECTION_INSIDE_DATA)
1846 RETURN(smtp_stream_except(state, except,
1847 "sending message body"));
1850 * We will clear the stream error flag to try and read a
1851 * premature 5XX response, so it is important to flush any
1852 * unwritten data. Otherwise, we will try to flush it again
1853 * before reading, which may incur an unnecessary delay and
1854 * will prevent the reading of any response that is not
1855 * already buffered (bundled with the DATA 354 response).
1857 * Not much point in sending QUIT at this point, skip right to
1858 * SMTP_STATE_LAST. The read engine above will likewise avoid
1859 * looking for a QUIT response.
1861 (void) vstream_fpurge(session->stream, VSTREAM_PURGE_WRITE);
1862 next_state = SMTP_STATE_LAST;
1867 * Copy the next command to the buffer and update the sender state.
1869 if (except == 0) {
1870 smtp_chat_cmd(session, "%s", vstring_str(next_command));
1871 } else {
1872 DONT_CACHE_THIS_SESSION;
1874 send_state = next_state;
1875 send_rcpt = next_rcpt;
1876 } while (recv_state != SMTP_STATE_LAST);
1877 RETURN(0);
1880 /* smtp_xfer - send a batch of envelope information and the message data */
1882 int smtp_xfer(SMTP_STATE *state)
1884 DELIVER_REQUEST *request = state->request;
1885 SMTP_SESSION *session = state->session;
1886 SMTP_RESP fake;
1887 int send_state;
1888 int recv_state;
1889 int send_name_addr;
1890 int result;
1893 * Sanity check. Recipients should be unmarked at this point.
1895 if (SMTP_RCPT_LEFT(state) <= 0)
1896 msg_panic("smtp_xfer: bad recipient count: %d",
1897 SMTP_RCPT_LEFT(state));
1898 if (SMTP_RCPT_ISMARKED(request->rcpt_list.info))
1899 msg_panic("smtp_xfer: bad recipient status: %d",
1900 request->rcpt_list.info->u.status);
1903 * See if we should even try to send this message at all. This code sits
1904 * here rather than in the EHLO processing code, because of SMTP
1905 * connection caching.
1907 if (session->size_limit > 0 && session->size_limit < request->data_size) {
1908 smtp_mesg_fail(state, DSN_BY_LOCAL_MTA,
1909 SMTP_RESP_FAKE(&fake, "5.3.4"),
1910 "message size %lu exceeds size limit %.0f of server %s",
1911 request->data_size, (double) session->size_limit,
1912 session->namaddr);
1913 /* Redundant. We abort this delivery attempt. */
1914 state->misc_flags |= SMTP_MISC_FLAG_COMPLETE_SESSION;
1915 return (0);
1919 * Use XFORWARD to forward the origin of this email message across an
1920 * SMTP-based content filter. Send client attribute information only if
1921 * it exists (i.e. remote submission). Local submissions have no client
1922 * attributes; the mail will appear to originate from the content filter
1923 * which is acceptable.
1925 send_name_addr =
1926 var_smtp_send_xforward
1927 && (((session->features & SMTP_FEATURE_XFORWARD_NAME)
1928 && DEL_REQ_ATTR_AVAIL(request->client_name))
1929 || ((session->features & SMTP_FEATURE_XFORWARD_ADDR)
1930 && DEL_REQ_ATTR_AVAIL(request->client_addr))
1931 || ((session->features & SMTP_FEATURE_XFORWARD_PORT)
1932 && DEL_REQ_ATTR_AVAIL(request->client_port)));
1933 session->send_proto_helo =
1934 var_smtp_send_xforward
1935 && (((session->features & SMTP_FEATURE_XFORWARD_PROTO)
1936 && DEL_REQ_ATTR_AVAIL(request->client_proto))
1937 || ((session->features & SMTP_FEATURE_XFORWARD_HELO)
1938 && DEL_REQ_ATTR_AVAIL(request->client_helo))
1939 || ((session->features & SMTP_FEATURE_XFORWARD_DOMAIN)
1940 && DEL_REQ_ATTR_AVAIL(request->rewrite_context)));
1941 if (send_name_addr)
1942 recv_state = send_state = SMTP_STATE_XFORWARD_NAME_ADDR;
1943 else if (session->send_proto_helo)
1944 recv_state = send_state = SMTP_STATE_XFORWARD_PROTO_HELO;
1945 else
1946 recv_state = send_state = SMTP_STATE_MAIL;
1949 * Remember this session's "normal completion", even if the server 4xx-ed
1950 * some or all recipients. Connection or handshake errors with a later MX
1951 * host should not cause this destination be marked as unreachable.
1953 result = smtp_loop(state, send_state, recv_state);
1955 if (result == 0
1956 /* Just in case */
1957 && vstream_ferror(session->stream) == 0
1958 && vstream_feof(session->stream) == 0)
1959 state->misc_flags |= SMTP_MISC_FLAG_COMPLETE_SESSION;
1961 return (result);
1964 /* smtp_rset - send a lone RSET command */
1966 int smtp_rset(SMTP_STATE *state)
1970 * This works because SMTP_STATE_RSET is a dedicated sender/recipient
1971 * entry state, with SMTP_STATE_LAST as next sender/recipient state.
1973 return (smtp_loop(state, SMTP_STATE_RSET, SMTP_STATE_RSET));
1976 /* smtp_quit - send a lone QUIT command */
1978 int smtp_quit(SMTP_STATE *state)
1982 * This works because SMTP_STATE_QUIT is the last state with a sender
1983 * action, with SMTP_STATE_LAST as the next sender/recipient state.
1985 return (smtp_loop(state, SMTP_STATE_QUIT, var_skip_quit_resp ?
1986 SMTP_STATE_LAST : SMTP_STATE_QUIT));