5
/* client SMTP protocol
9
/* int smtp_helo(state)
12
/* int smtp_xfer(state)
15
/* This module implements the client side of the SMTP protocol.
17
/* smtp_helo() performs the initial handshake with the SMTP server.
19
/* smtp_xfer() sends message envelope information followed by the
20
/* message data, and finishes the SMTP conversation. These operations
21
/* are combined in one function, in order to implement SMTP pipelining.
22
/* Recipients are marked as "done" in the mail queue file when
23
/* bounced or delivered. The message delivery status is updated
26
/* smtp_helo() and smtp_xfer() return 0 in case of success, -1 in case
27
/* of failure. For smtp_xfer(), success means the ability to perform
28
/* an SMTP conversation, not necessarily the ability to deliver mail.
30
/* Warnings: corrupt message file. A corrupt message is marked
31
/* as "corrupt" by changing its queue file permissions.
33
/* Some SMTP servers will abort when the number of recipients
34
/* for one message exceeds their capacity. This behavior violates
36
/* The only way around this is to limit the number of recipients
37
/* per transaction to an artificially-low value.
39
/* smtp(3h) internal data structures
40
/* smtp_chat(3) query/reply SMTP support
41
/* smtp_trouble(3) error handlers
45
/* The Secure Mailer license must be distributed with this software.
48
/* IBM T.J. Watson Research
50
/* Yorktown Heights, NY 10598, USA
52
/* Pipelining code in cooperation with:
54
/* Oaktree Internet Solutions Ltd.,
58
/* CV1 4LY, United Kingdom.
66
#include <sys/socket.h> /* shutdown(2) */
69
#include <stdlib.h> /* 44BSD stdarg.h uses abort() */
73
#ifdef STRCASECMP_IN_STRINGS_H
77
/* Utility library. */
82
#include <vstring_vstream.h>
83
#include <stringops.h>
87
#include <name_code.h>
91
#include <mail_params.h>
92
#include <smtp_stream.h>
93
#include <mail_queue.h>
94
#include <recipient_list.h>
95
#include <deliver_request.h>
101
#include <mark_corrupt.h>
102
#include <quote_821_local.h>
103
#include <mail_proto.h>
104
#include <mime_state.h>
106
/* Application-specific. */
109
#include "smtp_sasl.h"
112
* Sender and receiver state. A session does not necessarily go through a
113
* linear progression, but states are guaranteed to not jump backwards.
114
* Normal sessions go from MAIL->RCPT->DATA->DOT->QUIT->LAST. The states
115
* MAIL, RCPT, and DATA may also be followed by ABORT->QUIT->LAST.
117
* By default, the receiver skips the QUIT response. Some SMTP servers
118
* disconnect after responding to ".", and some SMTP servers wait before
119
* responding to QUIT.
121
* Client states that are associated with sending mail (up to and including
122
* SMTP_STATE_DOT) must have smaller numerical values than the non-sending
123
* states (SMTP_STATE_ABORT .. SMTP_STATE_LAST).
125
#define SMTP_STATE_XFORWARD_NAME_ADDR 0
126
#define SMTP_STATE_XFORWARD_PROTO_HELO 1
127
#define SMTP_STATE_MAIL 2
128
#define SMTP_STATE_RCPT 3
129
#define SMTP_STATE_DATA 4
130
#define SMTP_STATE_DOT 5
131
#define SMTP_STATE_ABORT 6
132
#define SMTP_STATE_QUIT 7
133
#define SMTP_STATE_LAST 8
135
int *xfer_timeouts[SMTP_STATE_LAST] = {
136
&var_smtp_xfwd_tmout, /* name/addr */
137
&var_smtp_xfwd_tmout, /* helo/proto */
138
&var_smtp_mail_tmout,
139
&var_smtp_rcpt_tmout,
140
&var_smtp_data0_tmout,
141
&var_smtp_data2_tmout,
142
&var_smtp_rset_tmout,
143
&var_smtp_quit_tmout,
146
char *xfer_states[SMTP_STATE_LAST] = {
147
"sending XFORWARD name/address",
148
"sending XFORWARD protocol/helo_name",
151
"sending DATA command",
152
"sending end of data -- message may be sent more than once",
153
"sending final RSET",
157
char *xfer_request[SMTP_STATE_LAST] = {
158
"XFORWARD name/address command",
159
"XFORWARD helo/protocol command",
163
"end of DATA command",
164
"final RSET command",
168
/* smtp_helo - perform initial handshake with SMTP server */
170
int smtp_helo(SMTP_STATE *state, int misc_flags)
172
SMTP_SESSION *session = state->session;
173
DELIVER_REQUEST *request = state->request;
180
static NAME_CODE xforward_features[] = {
181
XFORWARD_NAME, SMTP_FEATURE_XFORWARD_NAME,
182
XFORWARD_ADDR, SMTP_FEATURE_XFORWARD_ADDR,
183
XFORWARD_PROTO, SMTP_FEATURE_XFORWARD_PROTO,
184
XFORWARD_HELO, SMTP_FEATURE_XFORWARD_HELO,
189
* Prepare for disaster.
191
smtp_timeout_setup(state->session->stream, var_smtp_helo_tmout);
192
if ((except = vstream_setjmp(state->session->stream)) != 0)
193
return (smtp_stream_except(state, except,
194
"receiving the initial SMTP greeting"));
197
* Read and parse the server's SMTP greeting banner.
199
switch ((resp = smtp_chat_resp(state))->code / 100) {
203
if (var_smtp_skip_5xx_greeting)
206
return (smtp_site_fail(state, resp->code,
207
"host %s refused to talk to me: %s",
209
translit(resp->str, "\n", " ")));
213
* XXX Some PIX firewall versions require flush before ".<CR><LF>" so it
214
* does not span a packet boundary. This hurts performance so it is not
217
if (resp->str[strspn(resp->str, "20 *\t\n")] == 0)
218
state->features |= SMTP_FEATURE_MAYBEPIX;
221
* See if we are talking to ourself. This should not be possible with the
222
* way we implement DNS lookups. However, people are known to sometimes
223
* screw up the naming service. And, mailer loops are still possible when
224
* our own mailer routing tables are mis-configured.
227
(void) mystrtok(&words, "- \t\n");
228
for (n = 0; (word = mystrtok(&words, " \t\n")) != 0; n++) {
229
if (n == 0 && strcasecmp(word, var_myhostname) == 0) {
230
if (misc_flags & SMTP_MISC_FLAG_LOOP_DETECT)
231
msg_warn("host %s greeted me with my own hostname %s",
232
session->namaddr, var_myhostname);
233
} else if (strcasecmp(word, "ESMTP") == 0)
234
state->features |= SMTP_FEATURE_ESMTP;
236
if (var_smtp_always_ehlo && (state->features & SMTP_FEATURE_MAYBEPIX) == 0)
237
state->features |= SMTP_FEATURE_ESMTP;
238
if (var_smtp_never_ehlo || (state->features & SMTP_FEATURE_MAYBEPIX) != 0)
239
state->features &= ~SMTP_FEATURE_ESMTP;
242
* Return the compliment. Fall back to SMTP if our ESMTP recognition
245
if (state->features & SMTP_FEATURE_ESMTP) {
246
smtp_chat_cmd(state, "EHLO %s", var_smtp_helo_name);
247
if ((resp = smtp_chat_resp(state))->code / 100 != 2)
248
state->features &= ~SMTP_FEATURE_ESMTP;
250
if ((state->features & SMTP_FEATURE_ESMTP) == 0) {
251
smtp_chat_cmd(state, "HELO %s", var_smtp_helo_name);
252
if ((resp = smtp_chat_resp(state))->code / 100 != 2)
253
return (smtp_site_fail(state, resp->code,
254
"host %s refused to talk to me: %s",
256
translit(resp->str, "\n", " ")));
261
* Pick up some useful features offered by the SMTP server. XXX Until we
262
* have a portable routine to convert from string to off_t with proper
263
* overflow detection, ignore the message size limit advertised by the
264
* SMTP server. Otherwise, we might do the wrong thing when the server
265
* advertises a really huge message size limit.
267
* XXX Allow for "code (SP|-) ehlo-keyword (SP|=) ehlo-param...", because
268
* MicroSoft implemented AUTH based on an old draft.
271
while ((words = mystrtok(&lines, "\n")) != 0) {
272
if (mystrtok(&words, "- ") && (word = mystrtok(&words, " \t=")) != 0) {
273
if (strcasecmp(word, "8BITMIME") == 0)
274
state->features |= SMTP_FEATURE_8BITMIME;
275
else if (strcasecmp(word, "PIPELINING") == 0)
276
state->features |= SMTP_FEATURE_PIPELINING;
277
else if (strcasecmp(word, "XFORWARD") == 0)
278
while ((word = mystrtok(&words, " \t")) != 0)
279
state->features |= name_code(xforward_features,
280
NAME_CODE_FLAG_NONE, word);
281
else if (strcasecmp(word, "SIZE") == 0) {
282
state->features |= SMTP_FEATURE_SIZE;
283
if ((word = mystrtok(&words, " \t")) != 0) {
285
msg_warn("bad size limit \"%s\" in EHLO reply from %s",
286
word, session->namaddr);
288
state->size_limit = off_cvt_string(word);
292
else if (var_smtp_sasl_enable && strcasecmp(word, "AUTH") == 0)
293
smtp_sasl_helo_auth(state, words);
295
else if (strcasecmp(word, var_myhostname) == 0) {
296
if (misc_flags & SMTP_MISC_FLAG_LOOP_DETECT) {
297
msg_warn("host %s replied to HELO/EHLO with my own hostname %s",
298
session->namaddr, var_myhostname);
299
return (smtp_site_fail(state, session->best ? 550 : 450,
300
"mail for %s loops back to myself",
307
msg_info("server features: 0x%x size %.0f",
308
state->features, (double) state->size_limit);
311
if (var_smtp_sasl_enable && (state->features & SMTP_FEATURE_AUTH))
312
return (smtp_sasl_helo_login(state));
318
/* smtp_text_out - output one header/body record */
320
static void smtp_text_out(void *context, int rec_type,
321
const char *text, int len,
324
SMTP_STATE *state = (SMTP_STATE *) context;
325
SMTP_SESSION *session = state->session;
327
const char *data_start;
330
* Deal with an impedance mismatch between Postfix queue files (record
331
* length <= $message_line_length_limit) and SMTP (DATA record length <=
332
* $smtp_line_length_limit). The code below does a little too much work
333
* when the SMTP line length limit is disabled, but it avoids code
334
* duplication, and thus, it avoids testing and maintenance problems.
339
if (state->space_left == var_smtp_line_limit
340
&& data_left > 0 && *data_start == '.')
341
smtp_fputc('.', session->stream);
342
if (var_smtp_line_limit > 0 && data_left >= state->space_left) {
343
smtp_fputs(data_start, state->space_left, session->stream);
344
data_start += state->space_left;
345
data_left -= state->space_left;
346
state->space_left = var_smtp_line_limit;
347
if (data_left > 0 || rec_type == REC_TYPE_CONT) {
348
smtp_fputc(' ', session->stream);
349
state->space_left -= 1;
352
if (rec_type == REC_TYPE_CONT) {
353
smtp_fwrite(data_start, data_left, session->stream);
354
state->space_left -= data_left;
356
smtp_fputs(data_start, data_left, session->stream);
357
state->space_left = var_smtp_line_limit;
361
} while (data_left > 0);
364
/* smtp_header_out - output one message header */
366
static void smtp_header_out(void *context, int unused_header_class,
367
HEADER_OPTS *unused_info, VSTRING *buf,
370
char *start = vstring_str(buf);
374
for (line = start; line; line = next_line) {
375
next_line = split_at(line, '\n');
376
smtp_text_out(context, REC_TYPE_NORM, line, next_line ?
377
next_line - line - 1 : strlen(line), offset);
381
/* smtp_xfer - send a batch of envelope information and the message data */
383
int smtp_xfer(SMTP_STATE *state)
385
char *myname = "smtp_xfer";
386
DELIVER_REQUEST *request = state->request;
387
SMTP_SESSION *session = state->session;
390
VSTRING *next_command = vstring_alloc(100);
391
NOCLOBBER int next_state;
392
NOCLOBBER int next_rcpt;
393
NOCLOBBER int send_state;
394
NOCLOBBER int recv_state;
395
NOCLOBBER int send_rcpt;
396
NOCLOBBER int recv_rcpt;
400
NOCLOBBER int prev_type = 0;
402
NOCLOBBER int sndbuffree;
403
SOCKOPT_SIZE optlen = sizeof(sndbufsize);
404
NOCLOBBER int mail_from_rejected;
405
NOCLOBBER int downgrading;
408
NOCLOBBER int send_proto_helo;
411
* Macros for readability.
413
#define REWRITE_ADDRESS(dst, mid, src) do { \
414
if (*(src) && var_smtp_quote_821_env) { \
415
quote_821_local(mid, src); \
416
smtp_unalias_addr(dst, vstring_str(mid)); \
418
vstring_strcpy(dst, src); \
422
#define QUOTE_ADDRESS(dst, src) do { \
423
if (*(src) && var_smtp_quote_821_env) { \
424
quote_821_local(dst, src); \
426
vstring_strcpy(dst, src); \
430
#define RETURN(x) do { \
431
vstring_free(next_command); \
432
if (state->mime_state) \
433
state->mime_state = mime_state_free(state->mime_state); \
437
#define SENDER_IS_AHEAD \
438
(recv_state < send_state || recv_rcpt != send_rcpt)
440
#define SENDER_IN_WAIT_STATE \
441
(send_state == SMTP_STATE_DOT || send_state == SMTP_STATE_LAST)
443
#define SENDING_MAIL \
444
(recv_state <= SMTP_STATE_DOT)
447
* Sanity check. Recipients should be unmarked at this point.
449
if (SMTP_RCPT_LEFT(state) <= 0)
450
msg_panic("smtp_xfer: bad recipient count: %d",
451
SMTP_RCPT_LEFT(state));
452
if (SMTP_RCPT_ISMARKED(request->rcpt_list.info))
453
msg_panic("smtp_xfer: bad recipient status: %d",
454
request->rcpt_list.info->status);
457
* See if we should even try to send this message at all. This code sits
458
* here rather than in the EHLO processing code, because of future SMTP
459
* connection caching.
461
if (state->size_limit > 0 && state->size_limit < request->data_size) {
462
smtp_mesg_fail(state, 552,
463
"message size %lu exceeds size limit %.0f of server %s",
464
request->data_size, (double) state->size_limit,
470
* We use SMTP command pipelining if the server said it supported it.
471
* Since we use blocking I/O, RFC 2197 says that we should inspect the
472
* TCP window size and not send more than this amount of information.
473
* Unfortunately this information is not available using the sockets
474
* interface. However, we *can* get the TCP send buffer size on the local
475
* TCP/IP stack. We should be able to fill this buffer without being
476
* blocked, and then the kernel will effectively do non-blocking I/O for
477
* us by automatically writing out the contents of its send buffer while
478
* we are reading in the responses. In addition to TCP buffering we have
479
* to be aware of application-level buffering by the vstream module,
480
* which is limited to a couple kbytes.
482
if (state->features & SMTP_FEATURE_PIPELINING) {
483
if (getsockopt(vstream_fileno(state->session->stream), SOL_SOCKET,
484
SO_SNDBUF, (char *) &sndbufsize, &optlen) < 0)
485
msg_fatal("%s: getsockopt: %m", myname);
486
if (sndbufsize > VSTREAM_BUFSIZE)
487
sndbufsize = VSTREAM_BUFSIZE;
488
if (sndbufsize == 0) {
489
sndbufsize = VSTREAM_BUFSIZE;
490
if (setsockopt(vstream_fileno(state->session->stream), SOL_SOCKET,
491
SO_SNDBUF, (char *) &sndbufsize, optlen) < 0)
492
msg_fatal("%s: setsockopt: %m", myname);
495
msg_info("Using ESMTP PIPELINING, TCP send buffer size is %d",
500
sndbuffree = sndbufsize;
503
* Pipelining support requires two loops: one loop for sending and one
504
* for receiving. Each loop has its own independent state. Most of the
505
* time the sender can run ahead of the receiver by as much as the TCP
506
* send buffer permits. There are only two places where the sender must
507
* wait for status information from the receiver: once after sending DATA
508
* and once after sending QUIT.
510
* The sender state advances until the TCP send buffer would overflow, or
511
* until the sender needs status information from the receiver. At that
512
* point the receiver starts processing responses. Once the receiver has
513
* caught up with the sender, the sender resumes sending commands. If the
514
* receiver detects a serious problem (MAIL FROM rejected, all RCPT TO
515
* commands rejected, DATA rejected) it forces the sender to abort the
516
* SMTP dialog with RSET and QUIT.
518
* Use the XFORWARD command to forward client attributes only when a minimal
519
* amount of information is available.
523
var_smtp_send_xforward
524
&& (((state->features & SMTP_FEATURE_XFORWARD_NAME)
525
&& DEL_REQ_ATTR_AVAIL(request->client_name))
526
|| ((state->features & SMTP_FEATURE_XFORWARD_ADDR)
527
&& DEL_REQ_ATTR_AVAIL(request->client_addr)));
529
var_smtp_send_xforward
530
&& (((state->features & SMTP_FEATURE_XFORWARD_PROTO)
531
&& DEL_REQ_ATTR_AVAIL(request->client_proto))
532
|| ((state->features & SMTP_FEATURE_XFORWARD_HELO)
533
&& DEL_REQ_ATTR_AVAIL(request->client_helo)));
535
recv_state = send_state = SMTP_STATE_XFORWARD_NAME_ADDR;
536
else if (send_proto_helo)
537
recv_state = send_state = SMTP_STATE_XFORWARD_PROTO_HELO;
539
recv_state = send_state = SMTP_STATE_MAIL;
540
next_rcpt = send_rcpt = recv_rcpt = 0;
541
mail_from_rejected = 0;
543
while (recv_state != SMTP_STATE_LAST) {
546
* Build the next command.
548
switch (send_state) {
554
msg_panic("%s: bad sender state %d", myname, send_state);
557
* Build the XFORWARD command. With properly sanitized
558
* information, the command length stays within the 512 byte
559
* command line length limit.
561
case SMTP_STATE_XFORWARD_NAME_ADDR:
562
vstring_strcpy(next_command, XFORWARD_CMD);
563
if (state->features & SMTP_FEATURE_XFORWARD_NAME)
564
vstring_sprintf_append(next_command, " %s=%s",
565
XFORWARD_NAME, DEL_REQ_ATTR_AVAIL(request->client_name) ?
566
request->client_name : XFORWARD_UNAVAILABLE);
567
if (state->features & SMTP_FEATURE_XFORWARD_ADDR)
568
vstring_sprintf_append(next_command, " %s=%s",
569
XFORWARD_ADDR, DEL_REQ_ATTR_AVAIL(request->client_addr) ?
570
request->client_addr : XFORWARD_UNAVAILABLE);
572
next_state = SMTP_STATE_XFORWARD_PROTO_HELO;
574
next_state = SMTP_STATE_MAIL;
577
case SMTP_STATE_XFORWARD_PROTO_HELO:
578
vstring_strcpy(next_command, XFORWARD_CMD);
579
if (state->features & SMTP_FEATURE_XFORWARD_PROTO)
580
vstring_sprintf_append(next_command, " %s=%s",
581
XFORWARD_PROTO, DEL_REQ_ATTR_AVAIL(request->client_proto) ?
582
request->client_proto : XFORWARD_UNAVAILABLE);
583
if (state->features & SMTP_FEATURE_XFORWARD_HELO)
584
vstring_sprintf_append(next_command, " %s=%s",
585
XFORWARD_HELO, DEL_REQ_ATTR_AVAIL(request->client_helo) ?
586
request->client_helo : XFORWARD_UNAVAILABLE);
587
next_state = SMTP_STATE_MAIL;
591
* Build the MAIL FROM command.
593
case SMTP_STATE_MAIL:
594
QUOTE_ADDRESS(state->scratch, request->sender);
595
vstring_sprintf(next_command, "MAIL FROM:<%s>",
596
vstring_str(state->scratch));
597
if (state->features & SMTP_FEATURE_SIZE) /* RFC 1870 */
598
vstring_sprintf_append(next_command, " SIZE=%lu",
600
if (state->features & SMTP_FEATURE_8BITMIME) { /* RFC 1652 */
601
if (strcmp(request->encoding, MAIL_ATTR_ENC_8BIT) == 0)
602
vstring_strcat(next_command, " BODY=8BITMIME");
603
else if (strcmp(request->encoding, MAIL_ATTR_ENC_7BIT) == 0)
604
vstring_strcat(next_command, " BODY=7BIT");
605
else if (strcmp(request->encoding, MAIL_ATTR_ENC_NONE) != 0)
606
msg_warn("%s: unknown content encoding: %s",
607
request->queue_id, request->encoding);
611
* We authenticate the local MTA only, but not the sender.
614
if (var_smtp_sasl_enable
615
&& (state->features & SMTP_FEATURE_AUTH)
616
&& state->sasl_passwd)
617
vstring_strcat(next_command, " AUTH=<>");
619
next_state = SMTP_STATE_RCPT;
623
* Build one RCPT TO command before we have seen the MAIL FROM
626
case SMTP_STATE_RCPT:
627
rcpt = request->rcpt_list.info + send_rcpt;
628
QUOTE_ADDRESS(state->scratch, rcpt->address);
629
vstring_sprintf(next_command, "RCPT TO:<%s>",
630
vstring_str(state->scratch));
631
if ((next_rcpt = send_rcpt + 1) == SMTP_RCPT_LEFT(state))
632
next_state = DEL_REQ_TRACE_ONLY(request->flags) ?
633
SMTP_STATE_ABORT : SMTP_STATE_DATA;
637
* Build the DATA command before we have seen all the RCPT TO
640
case SMTP_STATE_DATA:
641
vstring_strcpy(next_command, "DATA");
642
next_state = SMTP_STATE_DOT;
646
* Build the "." command before we have seen the DATA response.
649
vstring_strcpy(next_command, ".");
650
next_state = SMTP_STATE_QUIT;
654
* The SMTP_STATE_ABORT sender state is entered by sender when it
655
* has verified all recipients; or it is entered the receiver
656
* when all recipients are rejected and is then left before the
657
* bottom of the main loop.
659
case SMTP_STATE_ABORT:
660
vstring_strcpy(next_command, "RSET");
661
next_state = SMTP_STATE_QUIT;
665
* Build the QUIT command before we have seen the "." or RSET
668
case SMTP_STATE_QUIT:
669
vstring_strcpy(next_command, "QUIT");
670
next_state = SMTP_STATE_LAST;
674
* The final sender state has no action associated with it.
676
case SMTP_STATE_LAST:
677
VSTRING_RESET(next_command);
680
VSTRING_TERMINATE(next_command);
683
* Process responses until the receiver has caught up. Vstreams
684
* automatically flush buffered output when reading new data.
686
* Flush unsent output if command pipelining is off or if no I/O
687
* happened for a while. This limits the accumulation of client-side
688
* delays in pipelined sessions.
690
if (SENDER_IN_WAIT_STATE
692
&& (VSTRING_LEN(next_command) + 2 > sndbuffree
693
|| time((time_t *) 0) - vstream_ftime(session->stream) > 10))) {
694
while (SENDER_IS_AHEAD) {
699
if (recv_state < SMTP_STATE_XFORWARD_NAME_ADDR
700
|| recv_state > SMTP_STATE_QUIT)
701
msg_panic("%s: bad receiver state %d (sender state %d)",
702
myname, recv_state, send_state);
705
* Receive the next server response. Use the proper timeout,
706
* and log the proper client state in case of trouble.
708
smtp_timeout_setup(state->session->stream,
709
*xfer_timeouts[recv_state]);
710
if ((except = vstream_setjmp(state->session->stream)) != 0)
711
RETURN(SENDING_MAIL ? smtp_stream_except(state, except,
712
xfer_states[recv_state]) : -1);
713
resp = smtp_chat_resp(state);
716
* Process the response.
718
switch (recv_state) {
721
* Process the XFORWARD response.
723
case SMTP_STATE_XFORWARD_NAME_ADDR:
724
if (resp->code / 100 != 2)
725
msg_warn("host %s said: %s (in reply to %s)",
727
translit(resp->str, "\n", " "),
728
xfer_request[SMTP_STATE_XFORWARD_NAME_ADDR]);
730
recv_state = SMTP_STATE_XFORWARD_PROTO_HELO;
732
recv_state = SMTP_STATE_MAIL;
735
case SMTP_STATE_XFORWARD_PROTO_HELO:
736
if (resp->code / 100 != 2)
737
msg_warn("host %s said: %s (in reply to %s)",
739
translit(resp->str, "\n", " "),
740
xfer_request[SMTP_STATE_XFORWARD_PROTO_HELO]);
741
recv_state = SMTP_STATE_MAIL;
745
* Process the MAIL FROM response. When the server
746
* rejects the sender, set the mail_from_rejected flag so
747
* that the receiver may apply a course correction.
749
case SMTP_STATE_MAIL:
750
if (resp->code / 100 != 2) {
751
smtp_mesg_fail(state, resp->code,
752
"host %s said: %s (in reply to %s)",
754
translit(resp->str, "\n", " "),
755
xfer_request[SMTP_STATE_MAIL]);
756
mail_from_rejected = 1;
758
recv_state = SMTP_STATE_RCPT;
762
* Process one RCPT TO response. If MAIL FROM was
763
* rejected, ignore RCPT TO responses: all recipients are
764
* dead already. When all recipients are rejected the
765
* receiver may apply a course correction.
767
* XXX 2821: Section 4.5.3.1 says that a 552 RCPT TO reply
768
* must be treated as if the server replied with 452.
769
* However, this causes "too much mail data" to be
770
* treated as a recoverable error, which is wrong. I'll
771
* stick with RFC 821.
773
case SMTP_STATE_RCPT:
774
if (!mail_from_rejected) {
776
if (resp->code == 552)
779
rcpt = request->rcpt_list.info + recv_rcpt;
780
if (resp->code / 100 == 2) {
782
/* If trace-only, mark the recipient done. */
783
if (DEL_REQ_TRACE_ONLY(request->flags))
784
smtp_rcpt_done(state, resp->str, rcpt);
786
smtp_rcpt_fail(state, resp->code, rcpt,
787
"host %s said: %s (in reply to %s)",
789
translit(resp->str, "\n", " "),
790
xfer_request[SMTP_STATE_RCPT]);
793
/* If trace-only, send RSET instead of DATA. */
794
if (++recv_rcpt == SMTP_RCPT_LEFT(state))
795
recv_state = DEL_REQ_TRACE_ONLY(request->flags) ?
796
SMTP_STATE_ABORT : SMTP_STATE_DATA;
800
* Process the DATA response. When the server rejects
801
* DATA, set nrcpt to a negative value so that the
802
* receiver can apply a course correction.
804
case SMTP_STATE_DATA:
805
if (resp->code / 100 != 3) {
807
smtp_mesg_fail(state, resp->code,
808
"host %s said: %s (in reply to %s)",
810
translit(resp->str, "\n", " "),
811
xfer_request[SMTP_STATE_DATA]);
814
recv_state = SMTP_STATE_DOT;
818
* Process the end of message response. Ignore the
819
* response when no recipient was accepted: all
820
* recipients are dead already, and the next receiver
821
* state is SMTP_STATE_QUIT regardless. Otherwise, if the
822
* message transfer fails, bounce all remaining
823
* recipients, else cross off the recipients that were
828
if (resp->code / 100 != 2) {
829
smtp_mesg_fail(state, resp->code,
830
"host %s said: %s (in reply to %s)",
832
translit(resp->str, "\n", " "),
833
xfer_request[SMTP_STATE_DOT]);
835
for (nrcpt = 0; nrcpt < recv_rcpt; nrcpt++) {
836
rcpt = request->rcpt_list.info + nrcpt;
837
if (!SMTP_RCPT_ISMARKED(rcpt))
838
smtp_rcpt_done(state, resp->str, rcpt);
842
recv_state = (var_skip_quit_resp ?
843
SMTP_STATE_LAST : SMTP_STATE_QUIT);
847
* Ignore the RSET response.
849
case SMTP_STATE_ABORT:
850
recv_state = (var_skip_quit_resp ?
851
SMTP_STATE_LAST : SMTP_STATE_QUIT);
855
* Ignore the QUIT response.
857
case SMTP_STATE_QUIT:
858
recv_state = SMTP_STATE_LAST;
864
* At this point, the sender and receiver are fully synchronized,
865
* so that the entire TCP send buffer becomes available again.
867
sndbuffree = sndbufsize;
870
* We know the server response to every command that was sent.
871
* Apply a course correction if necessary: the sender wants to
872
* send RCPT TO but MAIL FROM was rejected; the sender wants to
873
* send DATA but all recipients were rejected; the sender wants
874
* to deliver the message but DATA was rejected.
876
if ((send_state == SMTP_STATE_RCPT && mail_from_rejected)
877
|| (send_state == SMTP_STATE_DATA && nrcpt == 0)
878
|| (send_state == SMTP_STATE_DOT && nrcpt < 0)) {
879
send_state = recv_state = SMTP_STATE_ABORT;
880
send_rcpt = recv_rcpt = 0;
881
vstring_strcpy(next_command, "RSET");
882
next_state = SMTP_STATE_QUIT;
888
* Make the next sender state the current sender state.
890
if (send_state == SMTP_STATE_LAST)
894
* Special case if the server accepted the DATA command. If the
895
* server accepted at least one recipient send the entire message.
896
* Otherwise, just send "." as per RFC 2197.
898
* XXX If there is a hard MIME error while downgrading to 7-bit mail,
899
* disconnect ungracefully, because there is no other way to cancel a
900
* transaction in progress.
902
if (send_state == SMTP_STATE_DOT && nrcpt > 0) {
904
(var_disable_mime_oconv == 0
905
&& (state->features & SMTP_FEATURE_8BITMIME) == 0
906
&& strcmp(request->encoding, MAIL_ATTR_ENC_7BIT) != 0);
908
state->mime_state = mime_state_alloc(MIME_OPT_DOWNGRADE
909
| MIME_OPT_REPORT_NESTING,
911
(MIME_STATE_ANY_END) 0,
913
(MIME_STATE_ANY_END) 0,
914
(MIME_STATE_ERR_PRINT) 0,
916
state->space_left = var_smtp_line_limit;
917
smtp_timeout_setup(state->session->stream,
918
var_smtp_data1_tmout);
919
if ((except = vstream_setjmp(state->session->stream)) != 0)
920
RETURN(smtp_stream_except(state, except,
921
"sending message body"));
923
if (vstream_fseek(state->src, request->data_offset, SEEK_SET) < 0)
924
msg_fatal("seek queue file: %m");
926
while ((rec_type = rec_get(state->src, state->scratch, 0)) > 0) {
927
if (rec_type != REC_TYPE_NORM && rec_type != REC_TYPE_CONT)
929
if (downgrading == 0) {
930
smtp_text_out((void *) state, rec_type,
931
vstring_str(state->scratch),
932
VSTRING_LEN(state->scratch),
936
mime_state_update(state->mime_state, rec_type,
937
vstring_str(state->scratch),
938
VSTRING_LEN(state->scratch));
940
smtp_mesg_fail(state, 554,
941
"MIME 7-bit conversion failed: %s",
942
mime_state_error(mime_errs));
946
prev_type = rec_type;
949
if (state->mime_state) {
952
* The cleanup server normally ends MIME content with a
953
* normal text record. The following code is needed to flush
954
* an internal buffer when someone submits 8-bit mail not
955
* ending in newline via /usr/sbin/sendmail while MIME input
956
* processing is turned off, and MIME 8bit->7bit conversion
957
* is requested upon delivery.
960
mime_state_update(state->mime_state, rec_type, "", 0);
962
smtp_mesg_fail(state, 554,
963
"MIME 7-bit conversion failed: %s",
964
mime_state_error(mime_errs));
967
} else if (prev_type == REC_TYPE_CONT) /* missing newline */
968
smtp_fputs("", 0, session->stream);
969
if ((state->features & SMTP_FEATURE_MAYBEPIX) != 0
970
&& request->arrival_time < vstream_ftime(session->stream)
971
- var_smtp_pix_thresh) {
972
msg_info("%s: enabling PIX <CRLF>.<CRLF> workaround for %s",
973
request->queue_id, session->namaddr);
974
vstream_fflush(session->stream);/* hurts performance */
975
sleep(var_smtp_pix_delay); /* not to mention this */
977
if (vstream_ferror(state->src))
978
msg_fatal("queue file read error");
979
if (rec_type != REC_TYPE_XTRA)
980
RETURN(mark_corrupt(state->src));
984
* Copy the next command to the buffer and update the sender state.
987
sndbuffree -= VSTRING_LEN(next_command) + 2;
988
smtp_chat_cmd(state, "%s", vstring_str(next_command));
989
send_state = next_state;
990
send_rcpt = next_rcpt;