Bug Summary

File:src/usr.sbin/smtpd/smtpd/../mta_session.c
Warning:line 1532, column 7
Although the value stored to 'len' is used in the enclosing expression, the value is never actually read from 'len'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name mta_session.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/smtpd/smtpd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/smtpd/smtpd/.. -D IO_TLS -D QUEUE_PROFILING -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/smtpd/smtpd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/smtpd/smtpd/../mta_session.c
1/* $OpenBSD: mta_session.c,v 1.144 2021/07/28 19:39:50 benno Exp $ */
2
3/*
4 * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
5 * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
6 * Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
7 * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22#include <sys/stat.h>
23
24#include <ctype.h>
25#include <errno(*__errno()).h>
26#include <inttypes.h>
27#include <stdlib.h>
28#include <string.h>
29#include <tls.h>
30#include <unistd.h>
31
32#include "smtpd.h"
33#include "log.h"
34
35#define MAX_TRYBEFOREDISABLE10 10
36
37#define MTA_HIWAT65535 65535
38
39enum mta_state {
40 MTA_INIT,
41 MTA_BANNER,
42 MTA_EHLO,
43 MTA_HELO,
44 MTA_LHLO,
45 MTA_STARTTLS,
46 MTA_AUTH,
47 MTA_AUTH_PLAIN,
48 MTA_AUTH_LOGIN,
49 MTA_AUTH_LOGIN_USER,
50 MTA_AUTH_LOGIN_PASS,
51 MTA_READY,
52 MTA_MAIL,
53 MTA_RCPT,
54 MTA_DATA,
55 MTA_BODY,
56 MTA_EOM,
57 MTA_LMTP_EOM,
58 MTA_RSET,
59 MTA_QUIT,
60};
61
62#define MTA_FORCE_ANYSSL0x0001 0x0001
63#define MTA_FORCE_SMTPS0x0002 0x0002
64#define MTA_FORCE_TLS0x0004 0x0004
65#define MTA_FORCE_PLAIN0x0008 0x0008
66#define MTA_WANT_SECURE0x0010 0x0010
67#define MTA_DOWNGRADE_PLAIN0x0080 0x0080
68
69#define MTA_TLS0x0100 0x0100
70#define MTA_TLS_VERIFIED0x0200 0x0200
71
72#define MTA_FREE0x0400 0x0400
73#define MTA_LMTP0x0800 0x0800
74#define MTA_WAIT0x1000 0x1000
75#define MTA_HANGON0x2000 0x2000
76#define MTA_RECONN0x4000 0x4000
77
78#define MTA_EXT_STARTTLS0x01 0x01
79#define MTA_EXT_PIPELINING0x02 0x02
80#define MTA_EXT_AUTH0x04 0x04
81#define MTA_EXT_AUTH_PLAIN0x08 0x08
82#define MTA_EXT_AUTH_LOGIN0x10 0x10
83#define MTA_EXT_SIZE0x20 0x20
84
85struct mta_session {
86 uint64_t id;
87 struct mta_relay *relay;
88 struct mta_route *route;
89 char *helo;
90 char *mxname;
91
92 char *username;
93
94 int flags;
95
96 int attempt;
97 int use_smtps;
98 int use_starttls;
99 int use_smtp_tls;
100 int ready;
101
102 struct event ev;
103 struct io *io;
104 int ext;
105
106 size_t ext_size;
107
108 size_t msgtried;
109 size_t msgcount;
110 size_t rcptcount;
111 int hangon;
112
113 enum mta_state state;
114 struct mta_task *task;
115 struct mta_envelope *currevp;
116 FILE *datafp;
117 size_t datalen;
118
119 size_t failures;
120
121 char replybuf[2048];
122};
123
124static void mta_session_init(void);
125static void mta_start(int fd, short ev, void *arg);
126static void mta_io(struct io *, int, void *);
127static void mta_free(struct mta_session *);
128static void mta_getnameinfo_cb(void *, int, const char *, const char *);
129static void mta_on_ptr(void *, void *, void *);
130static void mta_on_timeout(struct runq *, void *);
131static void mta_connect(struct mta_session *);
132static void mta_enter_state(struct mta_session *, int);
133static void mta_flush_task(struct mta_session *, int, const char *, size_t, int);
134static void mta_error(struct mta_session *, const char *, ...)
135 __attribute__((__format__ (printf, 2, 3)));
136static void mta_send(struct mta_session *, char *, ...)
137 __attribute__((__format__ (printf, 2, 3)));
138static ssize_t mta_queue_data(struct mta_session *);
139static void mta_response(struct mta_session *, char *);
140static const char * mta_strstate(int);
141static void mta_tls_init(struct mta_session *);
142static void mta_tls_started(struct mta_session *);
143static struct mta_session *mta_tree_pop(struct tree *, uint64_t);
144static const char * dsn_strret(enum dsn_ret);
145static const char * dsn_strnotify(uint8_t);
146
147void mta_hoststat_update(const char *, const char *);
148void mta_hoststat_reschedule(const char *);
149void mta_hoststat_cache(const char *, uint64_t);
150void mta_hoststat_uncache(const char *, uint64_t);
151
152
153static void mta_filter_begin(struct mta_session *);
154static void mta_filter_end(struct mta_session *);
155static void mta_connected(struct mta_session *);
156static void mta_disconnected(struct mta_session *);
157
158static void mta_report_link_connect(struct mta_session *, const char *, int,
159 const struct sockaddr_storage *,
160 const struct sockaddr_storage *);
161static void mta_report_link_greeting(struct mta_session *, const char *);
162static void mta_report_link_identify(struct mta_session *, const char *, const char *);
163static void mta_report_link_tls(struct mta_session *, const char *);
164static void mta_report_link_disconnect(struct mta_session *);
165static void mta_report_link_auth(struct mta_session *, const char *, const char *);
166static void mta_report_tx_reset(struct mta_session *, uint32_t);
167static void mta_report_tx_begin(struct mta_session *, uint32_t);
168static void mta_report_tx_mail(struct mta_session *, uint32_t, const char *, int);
169static void mta_report_tx_rcpt(struct mta_session *, uint32_t, const char *, int);
170static void mta_report_tx_envelope(struct mta_session *, uint32_t, uint64_t);
171static void mta_report_tx_data(struct mta_session *, uint32_t, int);
172static void mta_report_tx_commit(struct mta_session *, uint32_t, size_t);
173static void mta_report_tx_rollback(struct mta_session *, uint32_t);
174static void mta_report_protocol_client(struct mta_session *, const char *);
175static void mta_report_protocol_server(struct mta_session *, const char *);
176#if 0
177static void mta_report_filter_response(struct mta_session *, int, int, const char *);
178#endif
179static void mta_report_timeout(struct mta_session *);
180
181
182static struct tree wait_helo;
183static struct tree wait_ptr;
184static struct tree wait_fd;
185static struct tree wait_tls_init;
186static struct tree wait_tls_verify;
187
188static struct runq *hangon;
189
190#define SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername) \
191 ((s)->relay->dispatcher->u.remote.filtername)
192
193static void
194mta_session_init(void)
195{
196 static int init = 0;
197
198 if (!init) {
199 tree_init(&wait_helo)do { do { (&((&wait_helo)->tree))->sph_root = (
(void*)0); } while (0); (&wait_helo)->count = 0; } while
(0)
;
200 tree_init(&wait_ptr)do { do { (&((&wait_ptr)->tree))->sph_root = ((
void*)0); } while (0); (&wait_ptr)->count = 0; } while
(0)
;
201 tree_init(&wait_fd)do { do { (&((&wait_fd)->tree))->sph_root = ((void
*)0); } while (0); (&wait_fd)->count = 0; } while(0)
;
202 tree_init(&wait_tls_init)do { do { (&((&wait_tls_init)->tree))->sph_root
= ((void*)0); } while (0); (&wait_tls_init)->count = 0
; } while(0)
;
203 tree_init(&wait_tls_verify)do { do { (&((&wait_tls_verify)->tree))->sph_root
= ((void*)0); } while (0); (&wait_tls_verify)->count =
0; } while(0)
;
204 runq_init(&hangon, mta_on_timeout);
205 init = 1;
206 }
207}
208
209void
210mta_session(struct mta_relay *relay, struct mta_route *route, const char *mxname)
211{
212 struct mta_session *s;
213 struct timeval tv;
214
215 mta_session_init();
216
217 s = xcalloc(1, sizeof *s);
218 s->id = generate_uid();
219 s->relay = relay;
220 s->route = route;
221 s->mxname = xstrdup(mxname);
222
223 mta_filter_begin(s);
224
225 if (relay->flags & RELAY_LMTP0x80)
226 s->flags |= MTA_LMTP0x0800;
227 switch (relay->tls) {
228 case RELAY_TLS_SMTPS2:
229 s->flags |= MTA_FORCE_SMTPS0x0002;
230 s->flags |= MTA_WANT_SECURE0x0010;
231 break;
232 case RELAY_TLS_STARTTLS1:
233 s->flags |= MTA_FORCE_TLS0x0004;
234 s->flags |= MTA_WANT_SECURE0x0010;
235 break;
236 case RELAY_TLS_OPPORTUNISTIC0:
237 /* do not force anything, try tls then smtp */
238 break;
239 case RELAY_TLS_NO3:
240 s->flags |= MTA_FORCE_PLAIN0x0008;
241 break;
242 default:
243 fatalx("bad value for relay->tls: %d", relay->tls);
244 }
245
246 log_debug("debug: mta: %p: spawned for relay %s", s,
247 mta_relay_to_text(relay));
248 stat_increment("mta.session", 1);
249
250 if (route->dst->ptrname || route->dst->lastptrquery) {
251 /* We want to delay the connection since to always notify
252 * the relay asynchronously.
253 */
254 tv.tv_sec = 0;
255 tv.tv_usec = 0;
256 evtimer_set(&s->ev, mta_start, s)event_set(&s->ev, -1, 0, mta_start, s);
257 evtimer_add(&s->ev, &tv)event_add(&s->ev, &tv);
258 } else if (waitq_wait(&route->dst->ptrname, mta_on_ptr, s)) {
259 resolver_getnameinfo(s->route->dst->sa, NI_NUMERICSERV2,
260 mta_getnameinfo_cb, s);
261 }
262}
263
264void
265mta_session_imsg(struct mproc *p, struct imsg *imsg)
266{
267 struct mta_session *s;
268 struct msg m;
269 uint64_t reqid;
270 const char *name;
271 int status;
272 struct stat sb;
273
274 switch (imsg->hdr.type) {
275
276 case IMSG_MTA_OPEN_MESSAGE:
277 m_msg(&m, imsg);
278 m_get_id(&m, &reqid);
279 m_end(&m);
280
281 s = mta_tree_pop(&wait_fd, reqid);
282 if (s == NULL((void*)0)) {
283 if (imsg->fd != -1)
284 close(imsg->fd);
285 return;
286 }
287
288 if (imsg->fd == -1) {
289 log_debug("debug: mta: failed to obtain msg fd");
290 mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL,
291 "Could not get message fd", 0, 0);
292 mta_enter_state(s, MTA_READY);
293 return;
294 }
295
296 if ((s->ext & MTA_EXT_SIZE0x20) && s->ext_size != 0) {
297 if (fstat(imsg->fd, &sb) == -1) {
298 log_debug("debug: mta: failed to stat msg fd");
299 mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL,
300 "Could not stat message fd", 0, 0);
301 mta_enter_state(s, MTA_READY);
302 close(imsg->fd);
303 return;
304 }
305 if (sb.st_size > (off_t)s->ext_size) {
306 log_debug("debug: mta: message too large for peer");
307 mta_flush_task(s, IMSG_MTA_DELIVERY_PERMFAIL,
308 "message too large for peer", 0, 0);
309 mta_enter_state(s, MTA_READY);
310 close(imsg->fd);
311 return;
312 }
313 }
314
315 s->datafp = fdopen(imsg->fd, "r");
316 if (s->datafp == NULL((void*)0))
317 fatal("mta: fdopen");
318
319 mta_enter_state(s, MTA_MAIL);
320 return;
321
322 case IMSG_MTA_LOOKUP_HELO:
323 m_msg(&m, imsg);
324 m_get_id(&m, &reqid);
325 m_get_int(&m, &status);
326 if (status == LKA_OK)
327 m_get_string(&m, &name);
328 m_end(&m);
329
330 s = mta_tree_pop(&wait_helo, reqid);
331 if (s == NULL((void*)0))
332 return;
333
334 if (status == LKA_OK) {
335 s->helo = xstrdup(name);
336 mta_connect(s);
337 } else {
338 mta_source_error(s->relay, s->route,
339 "Failed to retrieve helo string");
340 mta_free(s);
341 }
342 return;
343
344 default:
345 fatalx("mta_session_imsg: unexpected %s imsg",
346 imsg_to_str(imsg->hdr.type));
347 }
348}
349
350static struct mta_session *
351mta_tree_pop(struct tree *wait, uint64_t reqid)
352{
353 struct mta_session *s;
354
355 s = tree_xpop(wait, reqid);
356 if (s->flags & MTA_FREE0x0400) {
357 log_debug("debug: mta: %p: zombie session", s);
358 mta_free(s);
359 return (NULL((void*)0));
360 }
361 s->flags &= ~MTA_WAIT0x1000;
362
363 return (s);
364}
365
366static void
367mta_free(struct mta_session *s)
368{
369 struct mta_relay *relay;
370 struct mta_route *route;
371
372 log_debug("debug: mta: %p: session done", s);
373
374 mta_disconnected(s);
375
376 if (s->ready)
377 s->relay->nconn_ready -= 1;
378
379 if (s->flags & MTA_HANGON0x2000) {
380 log_debug("debug: mta: %p: cancelling hangon timer", s);
381 runq_cancel(hangon, s);
382 }
383
384 if (s->io)
385 io_free(s->io);
386
387 if (s->task)
388 fatalx("current task should have been deleted already");
389 if (s->datafp) {
390 fclose(s->datafp);
391 s->datalen = 0;
392 }
393 free(s->helo);
394
395 relay = s->relay;
396 route = s->route;
397 free(s->username);
398 free(s->mxname);
399 free(s);
400 stat_decrement("mta.session", 1);
401 mta_route_collect(relay, route);
402}
403
404static void
405mta_getnameinfo_cb(void *arg, int gaierrno, const char *host, const char *serv)
406{
407 struct mta_session *s = arg;
408 struct mta_host *h;
409
410 h = s->route->dst;
411 h->lastptrquery = time(NULL((void*)0));
412 if (host)
413 h->ptrname = xstrdup(host);
414 waitq_run(&h->ptrname, h->ptrname);
415}
416
417static void
418mta_on_timeout(struct runq *runq, void *arg)
419{
420 struct mta_session *s = arg;
421
422 log_debug("mta: timeout for session hangon");
423
424 s->flags &= ~MTA_HANGON0x2000;
425 s->hangon++;
426
427 mta_enter_state(s, MTA_READY);
428}
429
430static void
431mta_on_ptr(void *tag, void *arg, void *data)
432{
433 struct mta_session *s = arg;
434
435 mta_connect(s);
436}
437
438static void
439mta_start(int fd, short ev, void *arg)
440{
441 struct mta_session *s = arg;
442
443 mta_connect(s);
444}
445
446static void
447mta_connect(struct mta_session *s)
448{
449 struct sockaddr_storage ss;
450 struct sockaddr *sa;
451 int portno;
452 const char *schema;
453
454 if (s->helo == NULL((void*)0)) {
455 if (s->relay->helotable && s->route->src->sa) {
456 m_create(p_lka, IMSG_MTA_LOOKUP_HELO, 0, 0, -1);
457 m_add_id(p_lka, s->id);
458 m_add_string(p_lka, s->relay->helotable);
459 m_add_sockaddr(p_lka, s->route->src->sa);
460 m_close(p_lka);
461 tree_xset(&wait_helo, s->id, s);
462 s->flags |= MTA_WAIT0x1000;
463 return;
464 }
465 else if (s->relay->heloname)
466 s->helo = xstrdup(s->relay->heloname);
467 else
468 s->helo = xstrdup(env->sc_hostname);
469 }
470
471 if (s->io) {
472 io_free(s->io);
473 s->io = NULL((void*)0);
474 }
475
476 s->use_smtps = s->use_starttls = s->use_smtp_tls = 0;
477
478 switch (s->attempt) {
479 case 0:
480 if (s->flags & MTA_FORCE_SMTPS0x0002)
481 s->use_smtps = 1; /* smtps */
482 else if (s->flags & (MTA_FORCE_TLS0x0004|MTA_FORCE_ANYSSL0x0001))
483 s->use_starttls = 1; /* tls, tls+smtps */
484 else if (!(s->flags & MTA_FORCE_PLAIN0x0008))
485 s->use_smtp_tls = 1;
486 break;
487 case 1:
488 if (s->flags & MTA_FORCE_ANYSSL0x0001) {
489 s->use_smtps = 1; /* tls+smtps */
490 break;
491 }
492 else if (s->flags & MTA_DOWNGRADE_PLAIN0x0080) {
493 /* smtp, with tls failure */
494 break;
495 }
496 default:
497 mta_free(s);
498 return;
499 }
500 portno = s->use_smtps ? 465 : 25;
501
502 /* Override with relay-specified port */
503 if (s->relay->port)
504 portno = s->relay->port;
505
506 memmove(&ss, s->route->dst->sa, s->route->dst->sa->sa_len);
507 sa = (struct sockaddr *)&ss;
508
509 if (sa->sa_family == AF_INET2)
510 ((struct sockaddr_in *)sa)->sin_port = htons(portno)(__uint16_t)(__builtin_constant_p(portno) ? (__uint16_t)(((__uint16_t
)(portno) & 0xffU) << 8 | ((__uint16_t)(portno) &
0xff00U) >> 8) : __swap16md(portno))
;
511 else if (sa->sa_family == AF_INET624)
512 ((struct sockaddr_in6 *)sa)->sin6_port = htons(portno)(__uint16_t)(__builtin_constant_p(portno) ? (__uint16_t)(((__uint16_t
)(portno) & 0xffU) << 8 | ((__uint16_t)(portno) &
0xff00U) >> 8) : __swap16md(portno))
;
513
514 s->attempt += 1;
515 if (s->use_smtp_tls)
516 schema = "smtp://";
517 else if (s->use_starttls)
518 schema = "smtp+tls://";
519 else if (s->use_smtps)
520 schema = "smtps://";
521 else if (s->flags & MTA_LMTP0x0800)
522 schema = "lmtp://";
523 else
524 schema = "smtp+notls://";
525
526 log_info("%016"PRIx64"llx"" mta "
527 "connecting address=%s%s:%d host=%s",
528 s->id, schema, sa_to_text(s->route->dst->sa),
529 portno, s->route->dst->ptrname);
530
531 mta_enter_state(s, MTA_INIT);
532 s->io = io_new();
533 io_set_callback(s->io, mta_io, s);
534 io_set_timeout(s->io, 300000);
535 if (io_connect(s->io, sa, s->route->src->sa) == -1) {
536 /*
537 * This error is most likely a "no route",
538 * so there is no need to try again.
539 */
540 log_debug("debug: mta: io_connect failed: %s", io_error(s->io));
541 if (errno(*__errno()) == EADDRNOTAVAIL49)
542 mta_source_error(s->relay, s->route, io_error(s->io));
543 else
544 mta_error(s, "Connection failed: %s", io_error(s->io));
545 mta_free(s);
546 }
547}
548
549static void
550mta_enter_state(struct mta_session *s, int newstate)
551{
552 struct mta_envelope *e;
553 size_t envid_sz;
554 int oldstate;
555 ssize_t q;
556 char ibuf[LINE_MAX2048];
557 char obuf[LINE_MAX2048];
558 int offset;
559 const char *srs_sender;
560
561again:
562 oldstate = s->state;
563
564 log_trace(TRACE_MTA, "mta: %p: %s -> %s", s,do { if (tracing & (0x0020)) log_trace0("mta: %p: %s -> %s"
, s, mta_strstate(oldstate), mta_strstate(newstate)); } while
(0)
565 mta_strstate(oldstate),do { if (tracing & (0x0020)) log_trace0("mta: %p: %s -> %s"
, s, mta_strstate(oldstate), mta_strstate(newstate)); } while
(0)
566 mta_strstate(newstate))do { if (tracing & (0x0020)) log_trace0("mta: %p: %s -> %s"
, s, mta_strstate(oldstate), mta_strstate(newstate)); } while
(0)
;
567
568 s->state = newstate;
569
570 memset(s->replybuf, 0, sizeof s->replybuf);
571
572 /* don't try this at home! */
573#define mta_enter_state(_s, _st) do { newstate = _st; goto again; } while (0)
574
575 switch (s->state) {
576 case MTA_INIT:
577 case MTA_BANNER:
578 break;
579
580 case MTA_EHLO:
581 s->ext = 0;
582 mta_send(s, "EHLO %s", s->helo);
583 mta_report_link_identify(s, "EHLO", s->helo);
584 break;
585
586 case MTA_HELO:
587 s->ext = 0;
588 mta_send(s, "HELO %s", s->helo);
589 mta_report_link_identify(s, "HELO", s->helo);
590 break;
591
592 case MTA_LHLO:
593 s->ext = 0;
594 mta_send(s, "LHLO %s", s->helo);
595 mta_report_link_identify(s, "LHLO", s->helo);
596 break;
597
598 case MTA_STARTTLS:
599 if (s->flags & MTA_DOWNGRADE_PLAIN0x0080)
600 mta_enter_state(s, MTA_AUTH);
601 if (s->flags & MTA_TLS0x0100) /* already started */
602 mta_enter_state(s, MTA_AUTH);
603 else if ((s->ext & MTA_EXT_STARTTLS0x01) == 0) {
604 if (s->flags & MTA_FORCE_TLS0x0004 || s->flags & MTA_WANT_SECURE0x0010) {
605 mta_error(s, "TLS required but not supported by remote host");
606 s->flags |= MTA_RECONN0x4000;
607 }
608 else
609 /* server doesn't support starttls, do not use it */
610 mta_enter_state(s, MTA_AUTH);
611 }
612 else
613 mta_send(s, "STARTTLS");
614 break;
615
616 case MTA_AUTH:
617 if (s->relay->secret && s->flags & MTA_TLS0x0100) {
618 if (s->ext & MTA_EXT_AUTH0x04) {
619 if (s->ext & MTA_EXT_AUTH_PLAIN0x08) {
620 mta_enter_state(s, MTA_AUTH_PLAIN);
621 break;
622 }
623 if (s->ext & MTA_EXT_AUTH_LOGIN0x10) {
624 mta_enter_state(s, MTA_AUTH_LOGIN);
625 break;
626 }
627 log_debug("debug: mta: %p: no supported AUTH method on session", s);
628 mta_error(s, "no supported AUTH method");
629 }
630 else {
631 log_debug("debug: mta: %p: AUTH not advertised on session", s);
632 mta_error(s, "AUTH not advertised");
633 }
634 }
635 else if (s->relay->secret) {
636 log_debug("debug: mta: %p: not using AUTH on non-TLS "
637 "session", s);
638 mta_error(s, "Refuse to AUTH over unsecure channel");
639 mta_connect(s);
640 } else {
641 mta_enter_state(s, MTA_READY);
642 }
643 break;
644
645 case MTA_AUTH_PLAIN:
646 memset(ibuf, 0, sizeof ibuf);
647 if (base64_decode(s->relay->secret, (unsigned char *)ibuf,
648 sizeof(ibuf)-1) == -1) {
649 log_debug("debug: mta: %p: credentials too large on session", s);
650 mta_error(s, "Credentials too large");
651 break;
652 }
653 s->username = xstrdup(ibuf+1);
654 mta_send(s, "AUTH PLAIN %s", s->relay->secret);
655 break;
656
657 case MTA_AUTH_LOGIN:
658 mta_send(s, "AUTH LOGIN");
659 break;
660
661 case MTA_AUTH_LOGIN_USER:
662 memset(ibuf, 0, sizeof ibuf);
663 if (base64_decode(s->relay->secret, (unsigned char *)ibuf,
664 sizeof(ibuf)-1) == -1) {
665 log_debug("debug: mta: %p: credentials too large on session", s);
666 mta_error(s, "Credentials too large");
667 break;
668 }
669 s->username = xstrdup(ibuf+1);
670
671 memset(obuf, 0, sizeof obuf);
672 base64_encode((unsigned char *)ibuf + 1, strlen(ibuf + 1), obuf, sizeof obuf);
673 mta_send(s, "%s", obuf);
674
675 memset(ibuf, 0, sizeof ibuf);
676 memset(obuf, 0, sizeof obuf);
677 break;
678
679 case MTA_AUTH_LOGIN_PASS:
680 memset(ibuf, 0, sizeof ibuf);
681 if (base64_decode(s->relay->secret, (unsigned char *)ibuf,
682 sizeof(ibuf)-1) == -1) {
683 log_debug("debug: mta: %p: credentials too large on session", s);
684 mta_error(s, "Credentials too large");
685 break;
686 }
687
688 offset = strlen(ibuf+1)+2;
689 memset(obuf, 0, sizeof obuf);
690 base64_encode((unsigned char *)ibuf + offset, strlen(ibuf + offset), obuf, sizeof obuf);
691 mta_send(s, "%s", obuf);
692
693 memset(ibuf, 0, sizeof ibuf);
694 memset(obuf, 0, sizeof obuf);
695 break;
696
697 case MTA_READY:
698 /* Ready to send a new mail */
699 if (s->ready == 0) {
700 s->ready = 1;
701 s->relay->nconn_ready += 1;
702 mta_route_ok(s->relay, s->route);
703 }
704
705 if (s->msgtried >= MAX_TRYBEFOREDISABLE10) {
706 log_info("%016"PRIx64"llx"" mta host-rejects-all-mails",
707 s->id);
708 mta_route_down(s->relay, s->route);
709 mta_enter_state(s, MTA_QUIT);
710 break;
711 }
712
713 if (s->msgcount >= s->relay->limits->max_mail_per_session) {
714 log_debug("debug: mta: "
715 "%p: cannot send more message to relay %s", s,
716 mta_relay_to_text(s->relay));
717 mta_enter_state(s, MTA_QUIT);
718 break;
719 }
720
721 /*
722 * When downgrading from opportunistic TLS, clear flag and
723 * possibly reuse the same task (forbidden in other cases).
724 */
725 if (s->flags & MTA_DOWNGRADE_PLAIN0x0080)
726 s->flags &= ~MTA_DOWNGRADE_PLAIN0x0080;
727 else if (s->task)
728 fatalx("task should be NULL at this point");
729
730 if (s->task == NULL((void*)0))
731 s->task = mta_route_next_task(s->relay, s->route);
732 if (s->task == NULL((void*)0)) {
733 log_debug("debug: mta: %p: no task for relay %s",
734 s, mta_relay_to_text(s->relay));
735
736 if (s->relay->nconn > 1 ||
737 s->hangon >= s->relay->limits->sessdelay_keepalive) {
738 mta_enter_state(s, MTA_QUIT);
739 break;
740 }
741
742 log_debug("mta: debug: last connection: hanging on for %llds",
743 (long long)(s->relay->limits->sessdelay_keepalive -
744 s->hangon));
745 s->flags |= MTA_HANGON0x2000;
746 runq_schedule(hangon, 1, s);
747 break;
748 }
749
750 log_debug("debug: mta: %p: handling next task for relay %s", s,
751 mta_relay_to_text(s->relay));
752
753 stat_increment("mta.task.running", 1);
754
755 m_create(p_queue, IMSG_MTA_OPEN_MESSAGE, 0, 0, -1);
756 m_add_id(p_queue, s->id);
757 m_add_msgid(p_queue, s->task->msgid);
758 m_close(p_queue);
759
760 tree_xset(&wait_fd, s->id, s);
761 s->flags |= MTA_WAIT0x1000;
762 break;
763
764 case MTA_MAIL:
765 s->currevp = TAILQ_FIRST(&s->task->envelopes)((&s->task->envelopes)->tqh_first);
766
767 e = s->currevp;
768 s->hangon = 0;
769 s->msgtried++;
770 envid_sz = strlen(e->dsn_envid);
771
772 /* SRS-encode if requested for the relay action, AND we're not
773 * bouncing, AND we have an RCPT which means we are forwarded,
774 * AND the RCPT has a '@' just for sanity check (will always).
775 */
776 if (env->sc_srs_key != NULL((void*)0) &&
777 s->relay->srs &&
778 strchr(s->task->sender, '@') &&
779 e->rcpt &&
780 strchr(e->rcpt, '@')) {
781 /* encode and replace task sender with new SRS-sender */
782 srs_sender = srs_encode(s->task->sender,
783 strchr(e->rcpt, '@') + 1);
784 if (srs_sender) {
785 free(s->task->sender);
786 s->task->sender = xstrdup(srs_sender);
787 }
788 }
789
790 if (s->ext & MTA_EXT_DSN0x400) {
791 mta_send(s, "MAIL FROM:<%s>%s%s%s%s",
792 s->task->sender,
793 e->dsn_ret ? " RET=" : "",
794 e->dsn_ret ? dsn_strret(e->dsn_ret) : "",
795 envid_sz ? " ENVID=" : "",
796 envid_sz ? e->dsn_envid : "");
797 } else
798 mta_send(s, "MAIL FROM:<%s>", s->task->sender);
799 break;
800
801 case MTA_RCPT:
802 if (s->currevp == NULL((void*)0))
803 s->currevp = TAILQ_FIRST(&s->task->envelopes)((&s->task->envelopes)->tqh_first);
804
805 e = s->currevp;
806 if (s->ext & MTA_EXT_DSN0x400) {
807 mta_send(s, "RCPT TO:<%s>%s%s%s%s",
808 e->dest,
809 e->dsn_notify ? " NOTIFY=" : "",
810 e->dsn_notify ? dsn_strnotify(e->dsn_notify) : "",
811 e->dsn_orcpt ? " ORCPT=rfc822;" : "",
812 e->dsn_orcpt ? e->dsn_orcpt : "");
813 } else
814 mta_send(s, "RCPT TO:<%s>", e->dest);
815
816 mta_report_tx_envelope(s, s->task->msgid, e->id);
817 s->rcptcount++;
818 break;
819
820 case MTA_DATA:
821 fseek(s->datafp, 0, SEEK_SET0);
822 mta_send(s, "DATA");
823 break;
824
825 case MTA_BODY:
826 if (s->datafp == NULL((void*)0)) {
827 log_trace(TRACE_MTA, "mta: %p: end-of-file", s)do { if (tracing & (0x0020)) log_trace0("mta: %p: end-of-file"
, s); } while (0)
;
828 mta_enter_state(s, MTA_EOM);
829 break;
830 }
831
832 if ((q = mta_queue_data(s)) == -1) {
833 s->flags |= MTA_FREE0x0400;
834 break;
835 }
836 if (q == 0) {
837 mta_enter_state(s, MTA_BODY);
838 break;
839 }
840
841 log_trace(TRACE_MTA, "mta: %p: >>> [...%zd bytes...]", s, q)do { if (tracing & (0x0020)) log_trace0("mta: %p: >>> [...%zd bytes...]"
, s, q); } while (0)
;
842 break;
843
844 case MTA_EOM:
845 mta_send(s, ".");
846 break;
847
848 case MTA_LMTP_EOM:
849 /* LMTP reports status of each delivery, so enable read */
850 io_set_read(s->io);
851 break;
852
853 case MTA_RSET:
854 if (s->datafp) {
855 fclose(s->datafp);
856 s->datafp = NULL((void*)0);
857 s->datalen = 0;
858 }
859 mta_send(s, "RSET");
860 break;
861
862 case MTA_QUIT:
863 mta_send(s, "QUIT");
864 break;
865
866 default:
867 fatalx("mta_enter_state: unknown state");
868 }
869#undef mta_enter_state
870}
871
872/*
873 * Handle a response to an SMTP command
874 */
875static void
876mta_response(struct mta_session *s, char *line)
877{
878 struct mta_envelope *e;
879 struct sockaddr_storage ss;
880 struct sockaddr *sa;
881 const char *domain;
882 char *pbuf;
883 socklen_t sa_len;
884 char buf[LINE_MAX2048];
885 int delivery;
886
887 switch (s->state) {
888
889 case MTA_BANNER:
890 if (line[0] != '2') {
891 mta_error(s, "BANNER rejected: %s", line);
892 s->flags |= MTA_FREE0x0400;
893 return;
894 }
895
896 pbuf = "";
897 if (strlen(line) > 4) {
898 (void)strlcpy(buf, line + 4, sizeof buf);
899 if ((pbuf = strchr(buf, ' ')))
900 *pbuf = '\0';
901 pbuf = valid_domainpart(buf) ? buf : "";
902 }
903 mta_report_link_greeting(s, pbuf);
904
905 if (s->flags & MTA_LMTP0x0800)
906 mta_enter_state(s, MTA_LHLO);
907 else
908 mta_enter_state(s, MTA_EHLO);
909 break;
910
911 case MTA_EHLO:
912 if (line[0] != '2') {
913 /* rejected at ehlo state */
914 if ((s->relay->flags & RELAY_AUTH0x08) ||
915 (s->flags & MTA_WANT_SECURE0x0010)) {
916 mta_error(s, "EHLO rejected: %s", line);
917 s->flags |= MTA_FREE0x0400;
918 return;
919 }
920 mta_enter_state(s, MTA_HELO);
921 return;
922 }
923 if (!(s->flags & MTA_FORCE_PLAIN0x0008))
924 mta_enter_state(s, MTA_STARTTLS);
925 else
926 mta_enter_state(s, MTA_READY);
927 break;
928
929 case MTA_HELO:
930 if (line[0] != '2') {
931 mta_error(s, "HELO rejected: %s", line);
932 s->flags |= MTA_FREE0x0400;
933 return;
934 }
935 mta_enter_state(s, MTA_READY);
936 break;
937
938 case MTA_LHLO:
939 if (line[0] != '2') {
940 mta_error(s, "LHLO rejected: %s", line);
941 s->flags |= MTA_FREE0x0400;
942 return;
943 }
944 mta_enter_state(s, MTA_READY);
945 break;
946
947 case MTA_STARTTLS:
948 if (line[0] != '2') {
949 if (!(s->flags & MTA_WANT_SECURE0x0010)) {
950 mta_enter_state(s, MTA_AUTH);
951 return;
952 }
953 /* XXX mark that the MX doesn't support STARTTLS */
954 mta_error(s, "STARTTLS rejected: %s", line);
955 s->flags |= MTA_FREE0x0400;
956 return;
957 }
958
959 mta_tls_init(s);
960 break;
961
962 case MTA_AUTH_PLAIN:
963 if (line[0] != '2') {
964 mta_error(s, "AUTH rejected: %s", line);
965 mta_report_link_auth(s, s->username, "fail");
966 s->flags |= MTA_FREE0x0400;
967 return;
968 }
969 mta_report_link_auth(s, s->username, "pass");
970 mta_enter_state(s, MTA_READY);
971 break;
972
973 case MTA_AUTH_LOGIN:
974 if (strncmp(line, "334 ", 4) != 0) {
975 mta_error(s, "AUTH rejected: %s", line);
976 mta_report_link_auth(s, s->username, "fail");
977 s->flags |= MTA_FREE0x0400;
978 return;
979 }
980 mta_enter_state(s, MTA_AUTH_LOGIN_USER);
981 break;
982
983 case MTA_AUTH_LOGIN_USER:
984 if (strncmp(line, "334 ", 4) != 0) {
985 mta_error(s, "AUTH rejected: %s", line);
986 mta_report_link_auth(s, s->username, "fail");
987 s->flags |= MTA_FREE0x0400;
988 return;
989 }
990 mta_enter_state(s, MTA_AUTH_LOGIN_PASS);
991 break;
992
993 case MTA_AUTH_LOGIN_PASS:
994 if (line[0] != '2') {
995 mta_error(s, "AUTH rejected: %s", line);
996 mta_report_link_auth(s, s->username, "fail");
997 s->flags |= MTA_FREE0x0400;
998 return;
999 }
1000 mta_report_link_auth(s, s->username, "pass");
1001 mta_enter_state(s, MTA_READY);
1002 break;
1003
1004 case MTA_MAIL:
1005 if (line[0] != '2') {
1006 if (line[0] == '5')
1007 delivery = IMSG_MTA_DELIVERY_PERMFAIL;
1008 else
1009 delivery = IMSG_MTA_DELIVERY_TEMPFAIL;
1010
1011 mta_flush_task(s, delivery, line, 0, 0);
1012 mta_enter_state(s, MTA_RSET);
1013 return;
1014 }
1015 mta_report_tx_begin(s, s->task->msgid);
1016 mta_report_tx_mail(s, s->task->msgid, s->task->sender, 1);
1017 mta_enter_state(s, MTA_RCPT);
1018 break;
1019
1020 case MTA_RCPT:
1021 e = s->currevp;
1022
1023 /* remove envelope from hosttat cache if there */
1024 if ((domain = strchr(e->dest, '@')) != NULL((void*)0)) {
1025 domain++;
1026 mta_hoststat_uncache(domain, e->id);
1027 }
1028
1029 s->currevp = TAILQ_NEXT(s->currevp, entry)((s->currevp)->entry.tqe_next);
1030 if (line[0] == '2') {
1031 s->failures = 0;
1032 /*
1033 * this host is up, reschedule envelopes that
1034 * were cached for reschedule.
1035 */
1036 if (domain)
1037 mta_hoststat_reschedule(domain);
1038 }
1039 else {
1040 mta_report_tx_rollback(s, s->task->msgid);
1041 mta_report_tx_reset(s, s->task->msgid);
1042 if (line[0] == '5')
1043 delivery = IMSG_MTA_DELIVERY_PERMFAIL;
1044 else
1045 delivery = IMSG_MTA_DELIVERY_TEMPFAIL;
1046 s->failures++;
1047
1048 /* remove failed envelope from task list */
1049 TAILQ_REMOVE(&s->task->envelopes, e, entry)do { if (((e)->entry.tqe_next) != ((void*)0)) (e)->entry
.tqe_next->entry.tqe_prev = (e)->entry.tqe_prev; else (
&s->task->envelopes)->tqh_last = (e)->entry.tqe_prev
; *(e)->entry.tqe_prev = (e)->entry.tqe_next; ; ; } while
(0)
;
1050 stat_decrement("mta.envelope", 1);
1051
1052 /* log right away */
1053 (void)snprintf(buf, sizeof(buf), "%s",
1054 mta_host_to_text(s->route->dst));
1055
1056 e->session = s->id;
1057 /* XXX */
1058 /*
1059 * getsockname() can only fail with ENOBUFS here
1060 * best effort, don't log source ...
1061 */
1062 sa_len = sizeof(ss);
1063 sa = (struct sockaddr *)&ss;
1064 if (getsockname(io_fileno(s->io), sa, &sa_len) == -1)
1065 mta_delivery_log(e, NULL((void*)0), buf, delivery, line);
1066 else
1067 mta_delivery_log(e, sa_to_text(sa),
1068 buf, delivery, line);
1069
1070 if (domain)
1071 mta_hoststat_update(domain, e->status);
1072 mta_delivery_notify(e);
1073
1074 if (s->relay->limits->max_failures_per_session &&
1075 s->failures == s->relay->limits->max_failures_per_session) {
1076 mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL,
1077 "Too many consecutive errors, closing connection", 0, 1);
1078 mta_enter_state(s, MTA_QUIT);
1079 break;
1080 }
1081
1082 /*
1083 * if no more envelopes, flush failed queue
1084 */
1085 if (TAILQ_EMPTY(&s->task->envelopes)(((&s->task->envelopes)->tqh_first) == ((void*)0
))
) {
1086 mta_flush_task(s, IMSG_MTA_DELIVERY_OK,
1087 "No envelope", 0, 0);
1088 mta_enter_state(s, MTA_RSET);
1089 break;
1090 }
1091 }
1092
1093 switch (line[0]) {
1094 case '2':
1095 mta_report_tx_rcpt(s,
1096 s->task->msgid, e->dest, 1);
1097 break;
1098 case '4':
1099 mta_report_tx_rcpt(s,
1100 s->task->msgid, e->dest, -1);
1101 break;
1102 case '5':
1103 mta_report_tx_rcpt(s,
1104 s->task->msgid, e->dest, 0);
1105 break;
1106 }
1107
1108 if (s->currevp == NULL((void*)0))
1109 mta_enter_state(s, MTA_DATA);
1110 else
1111 mta_enter_state(s, MTA_RCPT);
1112 break;
1113
1114 case MTA_DATA:
1115 if (line[0] == '2' || line[0] == '3') {
1116 mta_report_tx_data(s, s->task->msgid, 1);
1117 mta_enter_state(s, MTA_BODY);
1118 break;
1119 }
1120
1121 if (line[0] == '5')
1122 delivery = IMSG_MTA_DELIVERY_PERMFAIL;
1123 else
1124 delivery = IMSG_MTA_DELIVERY_TEMPFAIL;
1125 mta_report_tx_data(s, s->task->msgid,
1126 delivery == IMSG_MTA_DELIVERY_TEMPFAIL ? -1 : 0);
1127 mta_report_tx_rollback(s, s->task->msgid);
1128 mta_report_tx_reset(s, s->task->msgid);
1129 mta_flush_task(s, delivery, line, 0, 0);
1130 mta_enter_state(s, MTA_RSET);
1131 break;
1132
1133 case MTA_LMTP_EOM:
1134 case MTA_EOM:
1135 if (line[0] == '2') {
1136 delivery = IMSG_MTA_DELIVERY_OK;
1137 s->msgtried = 0;
1138 s->msgcount++;
1139 }
1140 else if (line[0] == '5')
1141 delivery = IMSG_MTA_DELIVERY_PERMFAIL;
1142 else
1143 delivery = IMSG_MTA_DELIVERY_TEMPFAIL;
1144 if (delivery != IMSG_MTA_DELIVERY_OK) {
1145 mta_report_tx_rollback(s, s->task->msgid);
1146 mta_report_tx_reset(s, s->task->msgid);
1147 }
1148 else {
1149 mta_report_tx_commit(s, s->task->msgid, s->datalen);
1150 mta_report_tx_reset(s, s->task->msgid);
1151 }
1152 mta_flush_task(s, delivery, line, (s->flags & MTA_LMTP0x0800) ? 1 : 0, 0);
1153 if (s->task) {
1154 s->rcptcount--;
1155 mta_enter_state(s, MTA_LMTP_EOM);
1156 } else {
1157 s->rcptcount = 0;
1158 if (s->relay->limits->sessdelay_transaction) {
1159 log_debug("debug: mta: waiting for %llds before next transaction",
1160 (long long int)s->relay->limits->sessdelay_transaction);
1161 s->hangon = s->relay->limits->sessdelay_transaction -1;
1162 s->flags |= MTA_HANGON0x2000;
1163 runq_schedule(hangon,
1164 s->relay->limits->sessdelay_transaction, s);
1165 }
1166 else
1167 mta_enter_state(s, MTA_READY);
1168 }
1169 break;
1170
1171 case MTA_RSET:
1172 s->rcptcount = 0;
1173
1174 if (s->task) {
1175 mta_report_tx_rollback(s, s->task->msgid);
1176 mta_report_tx_reset(s, s->task->msgid);
1177 }
1178 if (s->relay->limits->sessdelay_transaction) {
1179 log_debug("debug: mta: waiting for %llds after reset",
1180 (long long int)s->relay->limits->sessdelay_transaction);
1181 s->hangon = s->relay->limits->sessdelay_transaction -1;
1182 s->flags |= MTA_HANGON0x2000;
1183 runq_schedule(hangon,
1184 s->relay->limits->sessdelay_transaction, s);
1185 }
1186 else
1187 mta_enter_state(s, MTA_READY);
1188 break;
1189
1190 default:
1191 fatalx("mta_response() bad state");
1192 }
1193}
1194
1195static void
1196mta_io(struct io *io, int evt, void *arg)
1197{
1198 struct mta_session *s = arg;
1199 char *line, *msg, *p;
1200 size_t len;
1201 const char *error;
1202 int cont;
1203
1204 log_trace(TRACE_IO, "mta: %p: %s %s", s, io_strevent(evt),do { if (tracing & (0x0004)) log_trace0("mta: %p: %s %s",
s, io_strevent(evt), io_strio(io)); } while (0)
1205 io_strio(io))do { if (tracing & (0x0004)) log_trace0("mta: %p: %s %s",
s, io_strevent(evt), io_strio(io)); } while (0)
;
1206
1207 switch (evt) {
1208
1209 case IO_CONNECTED:
1210 mta_connected(s);
1211
1212 if (s->use_smtps) {
1213 io_set_write(io);
1214 mta_tls_init(s);
1215 }
1216 else {
1217 mta_enter_state(s, MTA_BANNER);
1218 io_set_read(io);
1219 }
1220 break;
1221
1222 case IO_TLSREADY:
1223 log_info("%016"PRIx64"llx"" mta tls ciphers=%s",
1224 s->id, tls_to_text(io_tls(s->io)));
1225 s->flags |= MTA_TLS0x0100;
1226 if (!s->relay->dispatcher->u.remote.tls_noverify)
1227 s->flags |= MTA_TLS_VERIFIED0x0200;
1228
1229 mta_tls_started(s);
1230 mta_report_link_tls(s,
1231 tls_to_text(io_tls(s->io)));
1232 break;
1233
1234 case IO_DATAIN:
1235 nextline:
1236 line = io_getline(s->io, &len);
1237 if (line == NULL((void*)0)) {
1238 if (io_datalen(s->io) >= LINE_MAX2048) {
1239 mta_error(s, "Input too long");
1240 mta_free(s);
1241 }
1242 return;
1243 }
1244
1245 /* Strip trailing '\r' */
1246 if (len && line[len - 1] == '\r')
1247 line[--len] = '\0';
1248
1249 log_trace(TRACE_MTA, "mta: %p: <<< %s", s, line)do { if (tracing & (0x0020)) log_trace0("mta: %p: <<< %s"
, s, line); } while (0)
;
1250 mta_report_protocol_server(s, line);
1251
1252 if ((error = parse_smtp_response(line, len, &msg, &cont))) {
1253 mta_error(s, "Bad response: %s", error);
1254 mta_free(s);
1255 return;
1256 }
1257
1258 /* read extensions */
1259 if (s->state == MTA_EHLO) {
1260 if (strcmp(msg, "STARTTLS") == 0)
1261 s->ext |= MTA_EXT_STARTTLS0x01;
1262 else if (strncmp(msg, "AUTH ", 5) == 0) {
1263 s->ext |= MTA_EXT_AUTH0x04;
1264 if ((p = strstr(msg, " PLAIN")) &&
1265 (*(p+6) == '\0' || *(p+6) == ' '))
1266 s->ext |= MTA_EXT_AUTH_PLAIN0x08;
1267 if ((p = strstr(msg, " LOGIN")) &&
1268 (*(p+6) == '\0' || *(p+6) == ' '))
1269 s->ext |= MTA_EXT_AUTH_LOGIN0x10;
1270 }
1271 else if (strcmp(msg, "PIPELINING") == 0)
1272 s->ext |= MTA_EXT_PIPELINING0x02;
1273 else if (strcmp(msg, "DSN") == 0)
1274 s->ext |= MTA_EXT_DSN0x400;
1275 else if (strncmp(msg, "SIZE ", 5) == 0) {
1276 s->ext_size = strtonum(msg+5, 0, UINT32_MAX0xffffffffU, &error);
1277 if (error == NULL((void*)0))
1278 s->ext |= MTA_EXT_SIZE0x20;
1279 }
1280 }
1281
1282 /* continuation reply, we parse out the repeating statuses and ESC */
1283 if (cont) {
1284 if (s->replybuf[0] == '\0')
1285 (void)strlcat(s->replybuf, line, sizeof s->replybuf);
1286 else if (len > 4) {
1287 p = line + 4;
1288 if (isdigit((unsigned char)p[0]) && p[1] == '.' &&
1289 isdigit((unsigned char)p[2]) && p[3] == '.' &&
1290 isdigit((unsigned char)p[4]) && isspace((unsigned char)p[5]))
1291 p += 5;
1292 (void)strlcat(s->replybuf, p, sizeof s->replybuf);
1293 }
1294 goto nextline;
1295 }
1296
1297 /* last line of a reply, check if we're on a continuation to parse out status and ESC.
1298 * if we overflow reply buffer or are not on continuation, log entire last line.
1299 */
1300 if (s->replybuf[0] == '\0')
1301 (void)strlcat(s->replybuf, line, sizeof s->replybuf);
1302 else if (len > 4) {
1303 p = line + 4;
1304 if (isdigit((unsigned char)p[0]) && p[1] == '.' &&
1305 isdigit((unsigned char)p[2]) && p[3] == '.' &&
1306 isdigit((unsigned char)p[4]) && isspace((unsigned char)p[5]))
1307 p += 5;
1308 if (strlcat(s->replybuf, p, sizeof s->replybuf) >= sizeof s->replybuf)
1309 (void)strlcpy(s->replybuf, line, sizeof s->replybuf);
1310 }
1311
1312 if (s->state == MTA_QUIT) {
1313 log_info("%016"PRIx64"llx"" mta disconnected reason=quit messages=%zu",
1314 s->id, s->msgcount);
1315 mta_free(s);
1316 return;
1317 }
1318 io_set_write(io);
1319 mta_response(s, s->replybuf);
1320 if (s->flags & MTA_FREE0x0400) {
1321 mta_free(s);
1322 return;
1323 }
1324 if (s->flags & MTA_RECONN0x4000) {
1325 s->flags &= ~MTA_RECONN0x4000;
1326 mta_connect(s);
1327 return;
1328 }
1329
1330 if (io_datalen(s->io)) {
1331 log_debug("debug: mta: remaining data in input buffer");
1332 mta_error(s, "Remote host sent too much data");
1333 if (s->flags & MTA_WAIT0x1000)
1334 s->flags |= MTA_FREE0x0400;
1335 else
1336 mta_free(s);
1337 }
1338 break;
1339
1340 case IO_LOWAT:
1341 if (s->state == MTA_BODY) {
1342 mta_enter_state(s, MTA_BODY);
1343 if (s->flags & MTA_FREE0x0400) {
1344 mta_free(s);
1345 return;
1346 }
1347 }
1348
1349 if (io_queued(s->io) == 0)
1350 io_set_read(io);
1351 break;
1352
1353 case IO_TIMEOUT:
1354 log_debug("debug: mta: %p: connection timeout", s);
1355 mta_error(s, "Connection timeout");
1356 mta_report_timeout(s);
1357 if (!s->ready)
1358 mta_connect(s);
1359 else
1360 mta_free(s);
1361 break;
1362
1363 case IO_ERROR:
1364 log_debug("debug: mta: %p: IO error: %s", s, io_error(io));
1365
1366 if (s->state == MTA_STARTTLS && s->use_smtp_tls) {
1367 /* error in non-strict SSL negotiation, downgrade to plain */
1368 log_info("smtp-out: Error on session %016"PRIx64"llx"
1369 ": opportunistic TLS failed, "
1370 "downgrading to plain", s->id);
1371 s->flags &= ~MTA_TLS0x0100;
1372 s->flags |= MTA_DOWNGRADE_PLAIN0x0080;
1373 mta_connect(s);
1374 break;
1375 }
1376
1377 mta_error(s, "IO Error: %s", io_error(io));
1378 mta_free(s);
1379 break;
1380
1381 case IO_DISCONNECTED:
1382 log_debug("debug: mta: %p: disconnected in state %s",
1383 s, mta_strstate(s->state));
1384 mta_error(s, "Connection closed unexpectedly");
1385 if (!s->ready)
1386 mta_connect(s);
1387 else
1388 mta_free(s);
1389 break;
1390
1391 default:
1392 fatalx("mta_io() bad event");
1393 }
1394}
1395
1396static void
1397mta_send(struct mta_session *s, char *fmt, ...)
1398{
1399 va_list ap;
1400 char *p;
1401 int len;
1402
1403 va_start(ap, fmt)__builtin_va_start(ap, fmt);
1404 if ((len = vasprintf(&p, fmt, ap)) == -1)
1405 fatal("mta: vasprintf");
1406 va_end(ap)__builtin_va_end(ap);
1407
1408 log_trace(TRACE_MTA, "mta: %p: >>> %s", s, p)do { if (tracing & (0x0020)) log_trace0("mta: %p: >>> %s"
, s, p); } while (0)
;
1409
1410 if (strncasecmp(p, "AUTH PLAIN ", 11) == 0)
1411 mta_report_protocol_client(s, "AUTH PLAIN ********");
1412 else if (s->state == MTA_AUTH_LOGIN_USER || s->state == MTA_AUTH_LOGIN_PASS)
1413 mta_report_protocol_client(s, "********");
1414 else
1415 mta_report_protocol_client(s, p);
1416
1417 io_xprintf(s->io, "%s\r\n", p);
1418
1419 free(p);
1420}
1421
1422/*
1423 * Queue some data into the input buffer
1424 */
1425static ssize_t
1426mta_queue_data(struct mta_session *s)
1427{
1428 char *ln = NULL((void*)0);
1429 size_t sz = 0, q;
1430 ssize_t len;
1431
1432 q = io_queued(s->io);
1433
1434 while (io_queued(s->io) < MTA_HIWAT65535) {
1435 if ((len = getline(&ln, &sz, s->datafp)) == -1)
1436 break;
1437 if (ln[len - 1] == '\n')
1438 ln[len - 1] = '\0';
1439 s->datalen += io_xprintf(s->io, "%s%s\r\n", *ln == '.' ? "." : "", ln);
1440 }
1441
1442 free(ln);
1443 if (ferror(s->datafp)(!__isthreaded ? (((s->datafp)->_flags & 0x0040) !=
0) : (ferror)(s->datafp))
) {
1444 mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL,
1445 "Error reading content file", 0, 0);
1446 return (-1);
1447 }
1448
1449 if (feof(s->datafp)(!__isthreaded ? (((s->datafp)->_flags & 0x0020) !=
0) : (feof)(s->datafp))
) {
1450 fclose(s->datafp);
1451 s->datafp = NULL((void*)0);
1452 }
1453
1454 return (io_queued(s->io) - q);
1455}
1456
1457static void
1458mta_flush_task(struct mta_session *s, int delivery, const char *error, size_t count,
1459 int cache)
1460{
1461 struct mta_envelope *e;
1462 char relay[LINE_MAX2048];
1463 size_t n;
1464 struct sockaddr_storage ss;
1465 struct sockaddr *sa;
1466 socklen_t sa_len;
1467 const char *domain;
1468
1469 (void)snprintf(relay, sizeof relay, "%s", mta_host_to_text(s->route->dst));
1470 n = 0;
1471 while ((e = TAILQ_FIRST(&s->task->envelopes)((&s->task->envelopes)->tqh_first))) {
1472
1473 if (count && n == count) {
1474 stat_decrement("mta.envelope", n);
1475 return;
1476 }
1477
1478 TAILQ_REMOVE(&s->task->envelopes, e, entry)do { if (((e)->entry.tqe_next) != ((void*)0)) (e)->entry
.tqe_next->entry.tqe_prev = (e)->entry.tqe_prev; else (
&s->task->envelopes)->tqh_last = (e)->entry.tqe_prev
; *(e)->entry.tqe_prev = (e)->entry.tqe_next; ; ; } while
(0)
;
1479
1480 /* we're about to log, associate session to envelope */
1481 e->session = s->id;
1482 e->ext = s->ext;
1483
1484 /* XXX */
1485 /*
1486 * getsockname() can only fail with ENOBUFS here
1487 * best effort, don't log source ...
1488 */
1489 sa = (struct sockaddr *)&ss;
1490 sa_len = sizeof(ss);
1491 if (getsockname(io_fileno(s->io), sa, &sa_len) == -1)
1492 mta_delivery_log(e, NULL((void*)0), relay, delivery, error);
1493 else
1494 mta_delivery_log(e, sa_to_text(sa),
1495 relay, delivery, error);
1496
1497 mta_delivery_notify(e);
1498
1499 domain = strchr(e->dest, '@');
1500 if (domain) {
1501 domain++;
1502 mta_hoststat_update(domain, error);
1503 if (cache)
1504 mta_hoststat_cache(domain, e->id);
1505 }
1506
1507 n++;
1508 }
1509
1510 free(s->task->sender);
1511 free(s->task);
1512 s->task = NULL((void*)0);
1513
1514 if (s->datafp) {
1515 fclose(s->datafp);
1516 s->datafp = NULL((void*)0);
1517 }
1518
1519 stat_decrement("mta.envelope", n);
1520 stat_decrement("mta.task.running", 1);
1521 stat_decrement("mta.task", 1);
1522}
1523
1524static void
1525mta_error(struct mta_session *s, const char *fmt, ...)
1526{
1527 va_list ap;
1528 char *error;
1529 int len;
1530
1531 va_start(ap, fmt)__builtin_va_start(ap, fmt);
1532 if ((len = vasprintf(&error, fmt, ap)) == -1)
Although the value stored to 'len' is used in the enclosing expression, the value is never actually read from 'len'
1533 fatal("mta: vasprintf");
1534 va_end(ap)__builtin_va_end(ap);
1535
1536 if (s->msgcount)
1537 log_info("smtp-out: Error on session %016"PRIx64"llx"
1538 " after %zu message%s sent: %s", s->id, s->msgcount,
1539 (s->msgcount > 1) ? "s" : "", error);
1540 else
1541 log_info("%016"PRIx64"llx"" mta error reason=%s",
1542 s->id, error);
1543
1544 /*
1545 * If not connected yet, and the error is not local, just ignore it
1546 * and try to reconnect.
1547 */
1548 if (s->state == MTA_INIT &&
1549 (errno(*__errno()) == ETIMEDOUT60 || errno(*__errno()) == ECONNREFUSED61)) {
1550 log_debug("debug: mta: not reporting route error yet");
1551 free(error);
1552 return;
1553 }
1554
1555 mta_route_error(s->relay, s->route);
1556
1557 if (s->task)
1558 mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL, error, 0, 0);
1559
1560 free(error);
1561}
1562
1563static void
1564mta_tls_init(struct mta_session *s)
1565{
1566 struct tls_config *tls_config;
1567 struct tls *tls;
1568
1569 if ((tls = tls_client()) == NULL((void*)0)) {
1570 log_info("%016"PRIx64"llx"" mta closing reason=tls-failure", s->id);
1571 mta_free(s);
1572 return;
1573 }
1574
1575 tls_config = s->relay->dispatcher->u.remote.tls_config;
1576 if (tls_configure(tls, tls_config) == -1) {
1577 log_info("%016"PRIx64"llx"" mta closing reason=tls-failure", s->id);
1578 tls_free(tls);
1579 mta_free(s);
1580 return;
1581 }
1582
1583 if (io_connect_tls(s->io, tls, s->mxname) == -1) {
1584 log_info("%016"PRIx64"llx"" mta closing reason=tls-connect-failed", s->id);
1585 tls_free(tls);
1586 mta_free(s);
1587 }
1588}
1589
1590static void
1591mta_tls_started(struct mta_session *s)
1592{
1593 if (tls_peer_cert_provided(io_tls(s->io))) {
1594 log_info("%016"PRIx64"llx"" mta "
1595 "cert-check result=\"%s\" fingerprint=\"%s\"",
1596 s->id,
1597 (s->flags & MTA_TLS_VERIFIED0x0200) ? "valid" : "unverified",
1598 tls_peer_cert_hash(io_tls(s->io)));
1599 }
1600 else {
1601 log_info("%016"PRIx64"llx"" smtp "
1602 "cert-check result=\"no certificate presented\"",
1603 s->id);
1604 }
1605
1606 if (s->use_smtps) {
1607 mta_enter_state(s, MTA_BANNER);
1608 io_set_read(s->io);
1609 }
1610 else
1611 mta_enter_state(s, MTA_EHLO);
1612}
1613
1614static const char *
1615dsn_strret(enum dsn_ret ret)
1616{
1617 if (ret == DSN_RETHDRS)
1618 return "HDRS";
1619 else if (ret == DSN_RETFULL)
1620 return "FULL";
1621 else {
1622 log_debug("mta: invalid ret %d", ret);
1623 return "???";
1624 }
1625}
1626
1627static const char *
1628dsn_strnotify(uint8_t arg)
1629{
1630 static char buf[32];
1631 size_t sz;
1632
1633 buf[0] = '\0';
1634 if (arg & DSN_SUCCESS0x01)
1635 (void)strlcat(buf, "SUCCESS,", sizeof(buf));
1636
1637 if (arg & DSN_FAILURE0x02)
1638 (void)strlcat(buf, "FAILURE,", sizeof(buf));
1639
1640 if (arg & DSN_DELAY0x04)
1641 (void)strlcat(buf, "DELAY,", sizeof(buf));
1642
1643 if (arg & DSN_NEVER0x08)
1644 (void)strlcat(buf, "NEVER,", sizeof(buf));
1645
1646 /* trim trailing comma */
1647 sz = strlen(buf);
1648 if (sz)
1649 buf[sz - 1] = '\0';
1650
1651 return (buf);
1652}
1653
1654#define CASE(x)case x : return "x" case x : return #x
1655
1656static const char *
1657mta_strstate(int state)
1658{
1659 switch (state) {
1660 CASE(MTA_INIT)case MTA_INIT : return "MTA_INIT";
1661 CASE(MTA_BANNER)case MTA_BANNER : return "MTA_BANNER";
1662 CASE(MTA_EHLO)case MTA_EHLO : return "MTA_EHLO";
1663 CASE(MTA_HELO)case MTA_HELO : return "MTA_HELO";
1664 CASE(MTA_STARTTLS)case MTA_STARTTLS : return "MTA_STARTTLS";
1665 CASE(MTA_AUTH)case MTA_AUTH : return "MTA_AUTH";
1666 CASE(MTA_AUTH_PLAIN)case MTA_AUTH_PLAIN : return "MTA_AUTH_PLAIN";
1667 CASE(MTA_AUTH_LOGIN)case MTA_AUTH_LOGIN : return "MTA_AUTH_LOGIN";
1668 CASE(MTA_AUTH_LOGIN_USER)case MTA_AUTH_LOGIN_USER : return "MTA_AUTH_LOGIN_USER";
1669 CASE(MTA_AUTH_LOGIN_PASS)case MTA_AUTH_LOGIN_PASS : return "MTA_AUTH_LOGIN_PASS";
1670 CASE(MTA_READY)case MTA_READY : return "MTA_READY";
1671 CASE(MTA_MAIL)case MTA_MAIL : return "MTA_MAIL";
1672 CASE(MTA_RCPT)case MTA_RCPT : return "MTA_RCPT";
1673 CASE(MTA_DATA)case MTA_DATA : return "MTA_DATA";
1674 CASE(MTA_BODY)case MTA_BODY : return "MTA_BODY";
1675 CASE(MTA_EOM)case MTA_EOM : return "MTA_EOM";
1676 CASE(MTA_LMTP_EOM)case MTA_LMTP_EOM : return "MTA_LMTP_EOM";
1677 CASE(MTA_RSET)case MTA_RSET : return "MTA_RSET";
1678 CASE(MTA_QUIT)case MTA_QUIT : return "MTA_QUIT";
1679 default:
1680 return "MTA_???";
1681 }
1682}
1683
1684static void
1685mta_filter_begin(struct mta_session *s)
1686{
1687 if (!SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1688 return;
1689
1690 m_create(p_lka, IMSG_FILTER_SMTP_BEGIN, 0, 0, -1);
1691 m_add_id(p_lka, s->id);
1692 m_add_string(p_lka, s->relay->dispatcher->u.remote.filtername);
1693 m_close(p_lka);
1694}
1695
1696static void
1697mta_filter_end(struct mta_session *s)
1698{
1699 if (!SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1700 return;
1701
1702 m_create(p_lka, IMSG_FILTER_SMTP_END, 0, 0, -1);
1703 m_add_id(p_lka, s->id);
1704 m_close(p_lka);
1705}
1706
1707static void
1708mta_connected(struct mta_session *s)
1709{
1710 struct sockaddr_storage sa_src;
1711 struct sockaddr_storage sa_dest;
1712 int sa_len;
1713
1714 log_info("%016"PRIx64"llx"" mta connected", s->id);
1715
1716 sa_len = sizeof sa_src;
1717 if (getsockname(io_fileno(s->io),
1718 (struct sockaddr *)&sa_src, &sa_len) == -1)
1719 bzero(&sa_src, sizeof sa_src);
1720 sa_len = sizeof sa_dest;
1721 if (getpeername(io_fileno(s->io),
1722 (struct sockaddr *)&sa_dest, &sa_len) == -1)
1723 bzero(&sa_dest, sizeof sa_dest);
1724
1725 mta_report_link_connect(s,
1726 s->route->dst->ptrname, 1,
1727 &sa_src,
1728 &sa_dest);
1729}
1730
1731static void
1732mta_disconnected(struct mta_session *s)
1733{
1734 mta_report_link_disconnect(s);
1735 mta_filter_end(s);
1736}
1737
1738
1739static void
1740mta_report_link_connect(struct mta_session *s, const char *rdns, int fcrdns,
1741 const struct sockaddr_storage *ss_src,
1742 const struct sockaddr_storage *ss_dest)
1743{
1744 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1745 return;
1746
1747 report_smtp_link_connect("smtp-out", s->id, rdns, fcrdns, ss_src, ss_dest);
1748}
1749
1750static void
1751mta_report_link_greeting(struct mta_session *s,
1752 const char *domain)
1753{
1754 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1755 return;
1756
1757 report_smtp_link_greeting("smtp-out", s->id, domain);
1758}
1759
1760static void
1761mta_report_link_identify(struct mta_session *s, const char *method, const char *identity)
1762{
1763 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1764 return;
1765
1766 report_smtp_link_identify("smtp-out", s->id, method, identity);
1767}
1768
1769static void
1770mta_report_link_tls(struct mta_session *s, const char *ssl)
1771{
1772 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1773 return;
1774
1775 report_smtp_link_tls("smtp-out", s->id, ssl);
1776}
1777
1778static void
1779mta_report_link_disconnect(struct mta_session *s)
1780{
1781 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1782 return;
1783
1784 report_smtp_link_disconnect("smtp-out", s->id);
1785}
1786
1787static void
1788mta_report_link_auth(struct mta_session *s, const char *user, const char *result)
1789{
1790 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1791 return;
1792
1793 report_smtp_link_auth("smtp-out", s->id, user, result);
1794}
1795
1796static void
1797mta_report_tx_reset(struct mta_session *s, uint32_t msgid)
1798{
1799 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1800 return;
1801
1802 report_smtp_tx_reset("smtp-out", s->id, msgid);
1803}
1804
1805static void
1806mta_report_tx_begin(struct mta_session *s, uint32_t msgid)
1807{
1808 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1809 return;
1810
1811 report_smtp_tx_begin("smtp-out", s->id, msgid);
1812}
1813
1814static void
1815mta_report_tx_mail(struct mta_session *s, uint32_t msgid, const char *address, int ok)
1816{
1817 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1818 return;
1819
1820 report_smtp_tx_mail("smtp-out", s->id, msgid, address, ok);
1821}
1822
1823static void
1824mta_report_tx_rcpt(struct mta_session *s, uint32_t msgid, const char *address, int ok)
1825{
1826 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1827 return;
1828
1829 report_smtp_tx_rcpt("smtp-out", s->id, msgid, address, ok);
1830}
1831
1832static void
1833mta_report_tx_envelope(struct mta_session *s, uint32_t msgid, uint64_t evpid)
1834{
1835 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1836 return;
1837
1838 report_smtp_tx_envelope("smtp-out", s->id, msgid, evpid);
1839}
1840
1841static void
1842mta_report_tx_data(struct mta_session *s, uint32_t msgid, int ok)
1843{
1844 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1845 return;
1846
1847 report_smtp_tx_data("smtp-out", s->id, msgid, ok);
1848}
1849
1850static void
1851mta_report_tx_commit(struct mta_session *s, uint32_t msgid, size_t msgsz)
1852{
1853 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1854 return;
1855
1856 report_smtp_tx_commit("smtp-out", s->id, msgid, msgsz);
1857}
1858
1859static void
1860mta_report_tx_rollback(struct mta_session *s, uint32_t msgid)
1861{
1862 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1863 return;
1864
1865 report_smtp_tx_rollback("smtp-out", s->id, msgid);
1866}
1867
1868static void
1869mta_report_protocol_client(struct mta_session *s, const char *command)
1870{
1871 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1872 return;
1873
1874 report_smtp_protocol_client("smtp-out", s->id, command);
1875}
1876
1877static void
1878mta_report_protocol_server(struct mta_session *s, const char *response)
1879{
1880 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1881 return;
1882
1883 report_smtp_protocol_server("smtp-out", s->id, response);
1884}
1885
1886#if 0
1887static void
1888mta_report_filter_response(struct mta_session *s, int phase, int response, const char *param)
1889{
1890 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1891 return;
1892
1893 report_smtp_filter_response("smtp-out", s->id, phase, response, param);
1894}
1895#endif
1896
1897static void
1898mta_report_timeout(struct mta_session *s)
1899{
1900 if (! SESSION_FILTERED(s)((s)->relay->dispatcher->u.remote.filtername))
1901 return;
1902
1903 report_smtp_timeout("smtp-out", s->id);
1904}